This class provides simplified I2C access to a MAXIM DS130x Real-Time Clock device, even if the LPC1768 has an embedded RTC module. My objective is to share the same RTC with Microchip 18F MCU.
DS130x_I2C.cpp@0:a1b58e3c9fdb, 2011-02-09 (annotated)
- Committer:
- Yann
- Date:
- Wed Feb 09 13:43:21 2011 +0000
- Revision:
- 0:a1b58e3c9fdb
- Child:
- 1:834e9897e269
V0.0.0.1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Yann | 0:a1b58e3c9fdb | 1 | #include <iostream> |
Yann | 0:a1b58e3c9fdb | 2 | |
Yann | 0:a1b58e3c9fdb | 3 | #include "DS130x_I2C.h" |
Yann | 0:a1b58e3c9fdb | 4 | |
Yann | 0:a1b58e3c9fdb | 5 | namespace DS130X_I2C { |
Yann | 0:a1b58e3c9fdb | 6 | |
Yann | 0:a1b58e3c9fdb | 7 | CDS130X_I2C::CDS130X_I2C(const unsigned char p_slaveAddress, const PinName p_sda, const PinName p_scl, const CDS130X_I2C::OscillatorMode p_oscillatorMode, const bool p_outputLevel, const int p_frequency) : I2C(p_sda, p_scl, "DS130X_I2C"), _dayOfWeek("SunMonTueWedThuFriSat") { |
Yann | 0:a1b58e3c9fdb | 8 | DEBUG_ENTER("CDS130X_I2C::CDS130X_I2C: %02x - %x - %d", p_slaveAddress, p_oscillatorMode, p_frequency) |
Yann | 0:a1b58e3c9fdb | 9 | |
Yann | 0:a1b58e3c9fdb | 10 | _slaveAddress = p_slaveAddress; |
Yann | 0:a1b58e3c9fdb | 11 | frequency(p_frequency); // Set the frequency of the I2C interface |
Yann | 0:a1b58e3c9fdb | 12 | _oscillatorMode = p_oscillatorMode; |
Yann | 0:a1b58e3c9fdb | 13 | _outputLevel = p_outputLevel; |
Yann | 0:a1b58e3c9fdb | 14 | |
Yann | 0:a1b58e3c9fdb | 15 | DEBUG_LEAVE("CDS130X_I2C::CDS130X_I2C") |
Yann | 0:a1b58e3c9fdb | 16 | } |
Yann | 0:a1b58e3c9fdb | 17 | |
Yann | 0:a1b58e3c9fdb | 18 | CDS130X_I2C::~CDS130X_I2C() { |
Yann | 0:a1b58e3c9fdb | 19 | DEBUG_ENTER("~CDS130X_I2C") |
Yann | 0:a1b58e3c9fdb | 20 | |
Yann | 0:a1b58e3c9fdb | 21 | DEBUG_LEAVE("~CDS130X_I2C") |
Yann | 0:a1b58e3c9fdb | 22 | } |
Yann | 0:a1b58e3c9fdb | 23 | |
Yann | 0:a1b58e3c9fdb | 24 | bool CDS130X_I2C::Initialize() { |
Yann | 0:a1b58e3c9fdb | 25 | DEBUG_ENTER("CDS130X_I2C::Initialize") |
Yann | 0:a1b58e3c9fdb | 26 | |
Yann | 0:a1b58e3c9fdb | 27 | // 1. Set control register |
Yann | 0:a1b58e3c9fdb | 28 | unsigned char controlRegisterValue = 0x00; |
Yann | 0:a1b58e3c9fdb | 29 | switch (_oscillatorMode) { // See Datasheet - Clause CONTROL REGISTER |
Yann | 0:a1b58e3c9fdb | 30 | case CDS130X_I2C::One_Hz: |
Yann | 0:a1b58e3c9fdb | 31 | controlRegisterValue = 0x10; |
Yann | 0:a1b58e3c9fdb | 32 | break; |
Yann | 0:a1b58e3c9fdb | 33 | case CDS130X_I2C::Four_KHz: |
Yann | 0:a1b58e3c9fdb | 34 | controlRegisterValue = 0x11; |
Yann | 0:a1b58e3c9fdb | 35 | break; |
Yann | 0:a1b58e3c9fdb | 36 | case CDS130X_I2C::Height_KHz: |
Yann | 0:a1b58e3c9fdb | 37 | controlRegisterValue = 0x12; |
Yann | 0:a1b58e3c9fdb | 38 | break; |
Yann | 0:a1b58e3c9fdb | 39 | case CDS130X_I2C::ThirtyTwo_KHz: |
Yann | 0:a1b58e3c9fdb | 40 | controlRegisterValue = 0x13; |
Yann | 0:a1b58e3c9fdb | 41 | break; |
Yann | 0:a1b58e3c9fdb | 42 | case CDS130X_I2C::Output: |
Yann | 0:a1b58e3c9fdb | 43 | controlRegisterValue = (_outputLevel == true) ? 0x80 : 0x00; |
Yann | 0:a1b58e3c9fdb | 44 | break; |
Yann | 0:a1b58e3c9fdb | 45 | } // End of 'switch' statement |
Yann | 0:a1b58e3c9fdb | 46 | DEBUG("CDS130X_I2C::Initialize: controlRegisterValue = 0x%02x", controlRegisterValue) |
Yann | 0:a1b58e3c9fdb | 47 | // Write the control register |
Yann | 0:a1b58e3c9fdb | 48 | if (!Write(CDS130X_I2C::ControlRegisterAddress, controlRegisterValue)) { |
Yann | 0:a1b58e3c9fdb | 49 | DEBUG_ERROR("CDS130X_I2C::Initialize: I2C write operation failed") |
Yann | 0:a1b58e3c9fdb | 50 | return false; |
Yann | 0:a1b58e3c9fdb | 51 | } // else continue |
Yann | 0:a1b58e3c9fdb | 52 | |
Yann | 0:a1b58e3c9fdb | 53 | // 2. Set the date format: Hours<6> set to 0 for 24-hour mode - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 54 | DEBUG("CDS130X_I2C::Initialize: Set date format") |
Yann | 0:a1b58e3c9fdb | 55 | // 1. Read hours |
Yann | 0:a1b58e3c9fdb | 56 | unsigned char hoursRegister = 0xff; |
Yann | 0:a1b58e3c9fdb | 57 | if (Read(CDS130X_I2C::HoursAddress, &hoursRegister) == (unsigned char)0) { |
Yann | 0:a1b58e3c9fdb | 58 | DEBUG("CDS130X_I2C::Initialize: hours:%x", hoursRegister) |
Yann | 0:a1b58e3c9fdb | 59 | // 2. Set bit 6 to 0 |
Yann | 0:a1b58e3c9fdb | 60 | hoursRegister &= 0xbf; // 1011 1111 |
Yann | 0:a1b58e3c9fdb | 61 | // 3. Write new value |
Yann | 0:a1b58e3c9fdb | 62 | if (Write(CDS130X_I2C::HoursAddress, hoursRegister)) { |
Yann | 0:a1b58e3c9fdb | 63 | DEBUG_ERROR("CDS130X_I2C::Initialize: Failed to set date format") |
Yann | 0:a1b58e3c9fdb | 64 | } |
Yann | 0:a1b58e3c9fdb | 65 | } else { |
Yann | 0:a1b58e3c9fdb | 66 | DEBUG_ERROR("CDS130X_I2C::Initialize: Failed to set date format") |
Yann | 0:a1b58e3c9fdb | 67 | } |
Yann | 0:a1b58e3c9fdb | 68 | |
Yann | 0:a1b58e3c9fdb | 69 | // 3. Set CH bit is Seconds register - See Datasheet - Clause CLOCK AND CALENDAR |
Yann | 0:a1b58e3c9fdb | 70 | bool result = ControlClock(true); |
Yann | 0:a1b58e3c9fdb | 71 | |
Yann | 0:a1b58e3c9fdb | 72 | DEBUG_LEAVE("CDS130X_I2C::Initialize: %x", result) |
Yann | 0:a1b58e3c9fdb | 73 | return result; |
Yann | 0:a1b58e3c9fdb | 74 | } // End of method CDS130X_I2C::Initialize |
Yann | 0:a1b58e3c9fdb | 75 | |
Yann | 0:a1b58e3c9fdb | 76 | bool CDS130X_I2C::RestartClock() { |
Yann | 0:a1b58e3c9fdb | 77 | return ControlClock(true); |
Yann | 0:a1b58e3c9fdb | 78 | } // End of method CDS130X_I2C::RestartClock |
Yann | 0:a1b58e3c9fdb | 79 | |
Yann | 0:a1b58e3c9fdb | 80 | bool CDS130X_I2C::HaltClock() { |
Yann | 0:a1b58e3c9fdb | 81 | return ControlClock(false); |
Yann | 0:a1b58e3c9fdb | 82 | } // End of method CDS130X_I2C::HaltClock |
Yann | 0:a1b58e3c9fdb | 83 | |
Yann | 0:a1b58e3c9fdb | 84 | bool CDS130X_I2C::ControlClock(bool p_mode) { |
Yann | 0:a1b58e3c9fdb | 85 | DEBUG_ENTER("CDS130X_I2C::ControlClock") |
Yann | 0:a1b58e3c9fdb | 86 | |
Yann | 0:a1b58e3c9fdb | 87 | // 1. Read seconds |
Yann | 0:a1b58e3c9fdb | 88 | unsigned char secondsRegister = 0x00; |
Yann | 0:a1b58e3c9fdb | 89 | if (Read(CDS130X_I2C::SecondsAddress, &secondsRegister)) { |
Yann | 0:a1b58e3c9fdb | 90 | DEBUG("CDS130X_I2C::ControlClock: seconds register = 0x%02x", secondsRegister) |
Yann | 0:a1b58e3c9fdb | 91 | // 2. Set bit |
Yann | 0:a1b58e3c9fdb | 92 | if (!p_mode) { |
Yann | 0:a1b58e3c9fdb | 93 | secondsRegister |= 0x80; // Set CH bit to halt oscilator |
Yann | 0:a1b58e3c9fdb | 94 | } else { |
Yann | 0:a1b58e3c9fdb | 95 | secondsRegister &= 0x7f; // Unset CH bit to restart oscilator |
Yann | 0:a1b58e3c9fdb | 96 | } |
Yann | 0:a1b58e3c9fdb | 97 | DEBUG("CDS130X_I2C::ControlClock: seconds register (new value) = 0x%02x - mode: %x", secondsRegister, p_mode) |
Yann | 0:a1b58e3c9fdb | 98 | // 3. Write new value |
Yann | 0:a1b58e3c9fdb | 99 | if (Write(CDS130X_I2C::SecondsAddress, secondsRegister)) { |
Yann | 0:a1b58e3c9fdb | 100 | DEBUG_LEAVE("CDS130X_I2C::ControlClock (true)") |
Yann | 0:a1b58e3c9fdb | 101 | return true; |
Yann | 0:a1b58e3c9fdb | 102 | } |
Yann | 0:a1b58e3c9fdb | 103 | |
Yann | 0:a1b58e3c9fdb | 104 | DEBUG_LEAVE("CDS130X_I2C::ControlClock (false)") |
Yann | 0:a1b58e3c9fdb | 105 | return false; |
Yann | 0:a1b58e3c9fdb | 106 | } |
Yann | 0:a1b58e3c9fdb | 107 | |
Yann | 0:a1b58e3c9fdb | 108 | DEBUG_LEAVE("CDS130X_I2C::ControlClock (false)") |
Yann | 0:a1b58e3c9fdb | 109 | return false; |
Yann | 0:a1b58e3c9fdb | 110 | } // End of method CDS130X_I2C::ControlClock |
Yann | 0:a1b58e3c9fdb | 111 | |
Yann | 0:a1b58e3c9fdb | 112 | bool CDS130X_I2C::Read(const RegisterEnum p_address, unsigned char * p_byte, const CDS130X_I2C::RegisterFormatEnum p_format) { |
Yann | 0:a1b58e3c9fdb | 113 | DEBUG_ENTER("CDS130X_I2C::Read") |
Yann | 0:a1b58e3c9fdb | 114 | |
Yann | 0:a1b58e3c9fdb | 115 | // 1. Read seconds |
Yann | 0:a1b58e3c9fdb | 116 | char i2cBuffer[1]; |
Yann | 0:a1b58e3c9fdb | 117 | i2cBuffer[0] = (char)(unsigned char)p_address; |
Yann | 0:a1b58e3c9fdb | 118 | // Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 119 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 120 | // 2. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 121 | int result = read(_slaveAddress, (char *)p_byte, 1); |
Yann | 0:a1b58e3c9fdb | 122 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 123 | |
Yann | 0:a1b58e3c9fdb | 124 | // 3. Format convertion |
Yann | 0:a1b58e3c9fdb | 125 | if (p_format == CDS130X_I2C::Binary) { |
Yann | 0:a1b58e3c9fdb | 126 | switch ((RegisterEnum)p_address) { |
Yann | 0:a1b58e3c9fdb | 127 | case CDS130X_I2C::SecondsAddress: |
Yann | 0:a1b58e3c9fdb | 128 | //No break; |
Yann | 0:a1b58e3c9fdb | 129 | case CDS130X_I2C::MinutesAddress: |
Yann | 0:a1b58e3c9fdb | 130 | *p_byte = ConvertBCDToHex(*p_byte & 0x7f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 131 | break; |
Yann | 0:a1b58e3c9fdb | 132 | case CDS130X_I2C::HoursAddress: |
Yann | 0:a1b58e3c9fdb | 133 | //No break; |
Yann | 0:a1b58e3c9fdb | 134 | case CDS130X_I2C::DayAddress: |
Yann | 0:a1b58e3c9fdb | 135 | *p_byte = ConvertBCDToHex(*p_byte & 0x3f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 136 | break; |
Yann | 0:a1b58e3c9fdb | 137 | case CDS130X_I2C::DayOfWeekAddress: |
Yann | 0:a1b58e3c9fdb | 138 | *p_byte = ConvertBCDToHex(*p_byte & 0x03); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 139 | break; |
Yann | 0:a1b58e3c9fdb | 140 | case CDS130X_I2C::MonthAddress: |
Yann | 0:a1b58e3c9fdb | 141 | *p_byte = ConvertBCDToHex(*p_byte & 0x1f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 142 | break; |
Yann | 0:a1b58e3c9fdb | 143 | case CDS130X_I2C::YearAddress: |
Yann | 0:a1b58e3c9fdb | 144 | *p_byte = ConvertBCDToHex(*p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 145 | break; |
Yann | 0:a1b58e3c9fdb | 146 | } // End of 'switch' statement |
Yann | 0:a1b58e3c9fdb | 147 | } // else nothing to do |
Yann | 0:a1b58e3c9fdb | 148 | |
Yann | 0:a1b58e3c9fdb | 149 | DEBUG_LEAVE("CDS130X_I2C::Read %d", (int)*p_byte) |
Yann | 0:a1b58e3c9fdb | 150 | return true; |
Yann | 0:a1b58e3c9fdb | 151 | } |
Yann | 0:a1b58e3c9fdb | 152 | |
Yann | 0:a1b58e3c9fdb | 153 | |
Yann | 0:a1b58e3c9fdb | 154 | DEBUG_LEAVE("CDS130X_I2C::Read (false)") |
Yann | 0:a1b58e3c9fdb | 155 | return false; |
Yann | 0:a1b58e3c9fdb | 156 | } // End of method CDS130X_I2C::Read |
Yann | 0:a1b58e3c9fdb | 157 | |
Yann | 0:a1b58e3c9fdb | 158 | bool CDS130X_I2C::Write(const RegisterEnum p_address, const unsigned char p_byte, const CDS130X_I2C::RegisterFormatEnum p_format) { |
Yann | 0:a1b58e3c9fdb | 159 | DEBUG_ENTER("CDS130X_I2C::Write") |
Yann | 0:a1b58e3c9fdb | 160 | |
Yann | 0:a1b58e3c9fdb | 161 | // 1. Format convertion |
Yann | 0:a1b58e3c9fdb | 162 | unsigned char value = p_byte; |
Yann | 0:a1b58e3c9fdb | 163 | if (p_format == CDS130X_I2C::Binary) { |
Yann | 0:a1b58e3c9fdb | 164 | switch ((RegisterEnum)p_address) { |
Yann | 0:a1b58e3c9fdb | 165 | case CDS130X_I2C::SecondsAddress: |
Yann | 0:a1b58e3c9fdb | 166 | //No break; |
Yann | 0:a1b58e3c9fdb | 167 | case CDS130X_I2C::MinutesAddress: |
Yann | 0:a1b58e3c9fdb | 168 | value = ConvertHexToBCD(p_byte) & 0x7f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 169 | break; |
Yann | 0:a1b58e3c9fdb | 170 | case CDS130X_I2C::HoursAddress: // Force Hours<6> set to 0 for 24-hour mode - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 171 | //No break; |
Yann | 0:a1b58e3c9fdb | 172 | case CDS130X_I2C::DayAddress: |
Yann | 0:a1b58e3c9fdb | 173 | value = ConvertHexToBCD(p_byte) & 0x3f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 174 | break; |
Yann | 0:a1b58e3c9fdb | 175 | case CDS130X_I2C::DayOfWeekAddress: |
Yann | 0:a1b58e3c9fdb | 176 | value = ConvertHexToBCD(p_byte) & 0x03; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 177 | break; |
Yann | 0:a1b58e3c9fdb | 178 | case CDS130X_I2C::MonthAddress: |
Yann | 0:a1b58e3c9fdb | 179 | value = ConvertHexToBCD(p_byte) & 0x1f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 180 | break; |
Yann | 0:a1b58e3c9fdb | 181 | case CDS130X_I2C::YearAddress: |
Yann | 0:a1b58e3c9fdb | 182 | value = ConvertHexToBCD(p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 183 | break; |
Yann | 0:a1b58e3c9fdb | 184 | } // End of 'switch' statement |
Yann | 0:a1b58e3c9fdb | 185 | } // else nothing to do |
Yann | 0:a1b58e3c9fdb | 186 | |
Yann | 0:a1b58e3c9fdb | 187 | // 2. Read seconds |
Yann | 0:a1b58e3c9fdb | 188 | char i2cBuffer[2]; |
Yann | 0:a1b58e3c9fdb | 189 | i2cBuffer[0] = (char)(unsigned char)p_address; |
Yann | 0:a1b58e3c9fdb | 190 | i2cBuffer[1] = value; |
Yann | 0:a1b58e3c9fdb | 191 | // Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 192 | if (write(_slaveAddress, i2cBuffer, 2) == 0) { |
Yann | 0:a1b58e3c9fdb | 193 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 194 | DEBUG_LEAVE("CDS130X_I2C::Write (true)") |
Yann | 0:a1b58e3c9fdb | 195 | return true; |
Yann | 0:a1b58e3c9fdb | 196 | } |
Yann | 0:a1b58e3c9fdb | 197 | |
Yann | 0:a1b58e3c9fdb | 198 | DEBUG_LEAVE("CDS130X_I2C::Write (false)") |
Yann | 0:a1b58e3c9fdb | 199 | return false; |
Yann | 0:a1b58e3c9fdb | 200 | } // End of method CDS130X_I2C::Write |
Yann | 0:a1b58e3c9fdb | 201 | |
Yann | 0:a1b58e3c9fdb | 202 | bool CDS130X_I2C::SetTime(const std::string p_utcTime) { |
Yann | 0:a1b58e3c9fdb | 203 | DEBUG_ENTER("CDS130X_I2C::SetTime: %s - %d", p_utcTime.c_str(), p_utcTime.length()) |
Yann | 0:a1b58e3c9fdb | 204 | |
Yann | 0:a1b58e3c9fdb | 205 | // Sanity checks |
Yann | 0:a1b58e3c9fdb | 206 | if (p_utcTime.length() != 23) { |
Yann | 0:a1b58e3c9fdb | 207 | DEBUG_ERROR("CDS130X_I2C::SetTime: Wrong parameters") |
Yann | 0:a1b58e3c9fdb | 208 | return false; |
Yann | 0:a1b58e3c9fdb | 209 | } |
Yann | 0:a1b58e3c9fdb | 210 | // Fill struct tm; |
Yann | 0:a1b58e3c9fdb | 211 | struct tm t = {0}; |
Yann | 0:a1b58e3c9fdb | 212 | char wday[4] = {0}; |
Yann | 0:a1b58e3c9fdb | 213 | scanf("%s %02d %02d %02d:%02d:%02d %04d", /* Www MM dd hh:mm:ss yyyy */ |
Yann | 0:a1b58e3c9fdb | 214 | wday, |
Yann | 0:a1b58e3c9fdb | 215 | &t.tm_mon, |
Yann | 0:a1b58e3c9fdb | 216 | &t.tm_mday, |
Yann | 0:a1b58e3c9fdb | 217 | &t.tm_hour, |
Yann | 0:a1b58e3c9fdb | 218 | &t.tm_min, |
Yann | 0:a1b58e3c9fdb | 219 | &t.tm_sec, |
Yann | 0:a1b58e3c9fdb | 220 | &t.tm_year); |
Yann | 0:a1b58e3c9fdb | 221 | |
Yann | 0:a1b58e3c9fdb | 222 | DEBUG("CDS130X_I2C::SetTime: wday=%s - tm_wday=%d", wday, _dayOfWeek.find_first_of(wday) / 3); |
Yann | 0:a1b58e3c9fdb | 223 | t.tm_wday = _dayOfWeek.find_first_of(wday) / 3; |
Yann | 0:a1b58e3c9fdb | 224 | |
Yann | 0:a1b58e3c9fdb | 225 | Write(CDS130X_I2C::SecondsAddress, t.tm_sec, Binary); |
Yann | 0:a1b58e3c9fdb | 226 | Write(CDS130X_I2C::MinutesAddress, t.tm_min, Binary); |
Yann | 0:a1b58e3c9fdb | 227 | Write(CDS130X_I2C::HoursAddress, t.tm_hour, Binary); |
Yann | 0:a1b58e3c9fdb | 228 | Write(CDS130X_I2C::DayOfWeekAddress, t.tm_wday, Binary); |
Yann | 0:a1b58e3c9fdb | 229 | Write(CDS130X_I2C::DayAddress, t.tm_mday, Binary); |
Yann | 0:a1b58e3c9fdb | 230 | Write(CDS130X_I2C::MonthAddress, t.tm_mon, Binary); |
Yann | 0:a1b58e3c9fdb | 231 | Write(CDS130X_I2C::YearAddress, t.tm_year, Binary); |
Yann | 0:a1b58e3c9fdb | 232 | |
Yann | 0:a1b58e3c9fdb | 233 | return true; |
Yann | 0:a1b58e3c9fdb | 234 | } // End of method CDS130X_I2C::SetTime |
Yann | 0:a1b58e3c9fdb | 235 | |
Yann | 0:a1b58e3c9fdb | 236 | struct tm CDS130X_I2C::GetTime() { |
Yann | 0:a1b58e3c9fdb | 237 | DEBUG_ENTER("CDS130X_I2C::GetTime") |
Yann | 0:a1b58e3c9fdb | 238 | |
Yann | 0:a1b58e3c9fdb | 239 | struct tm t; |
Yann | 0:a1b58e3c9fdb | 240 | unsigned char value; |
Yann | 0:a1b58e3c9fdb | 241 | // Setup time structure from RTC |
Yann | 0:a1b58e3c9fdb | 242 | Read(CDS130X_I2C::SecondsAddress, &value, Binary); |
Yann | 0:a1b58e3c9fdb | 243 | t.tm_sec = value; |
Yann | 0:a1b58e3c9fdb | 244 | Read(CDS130X_I2C::MinutesAddress, &value, Binary); |
Yann | 0:a1b58e3c9fdb | 245 | t.tm_min = value; |
Yann | 0:a1b58e3c9fdb | 246 | Read(CDS130X_I2C::HoursAddress, &value, Binary); |
Yann | 0:a1b58e3c9fdb | 247 | t.tm_hour = value; |
Yann | 0:a1b58e3c9fdb | 248 | Read(CDS130X_I2C::DayOfWeekAddress, &value, Binary); |
Yann | 0:a1b58e3c9fdb | 249 | t.tm_wday = value; |
Yann | 0:a1b58e3c9fdb | 250 | Read(CDS130X_I2C::DayAddress, &value, Binary); |
Yann | 0:a1b58e3c9fdb | 251 | t.tm_mday = value; |
Yann | 0:a1b58e3c9fdb | 252 | Read(CDS130X_I2C::MonthAddress, &value, Binary); |
Yann | 0:a1b58e3c9fdb | 253 | t.tm_mon = value; |
Yann | 0:a1b58e3c9fdb | 254 | Read(CDS130X_I2C::YearAddress, &value, Binary); |
Yann | 0:a1b58e3c9fdb | 255 | t.tm_year = value; |
Yann | 0:a1b58e3c9fdb | 256 | DEBUG("CDS130X_I2C::GetTime: %02d %02d %02d %02d:%02d:%02d %04d", /* ww mm dd hh:mm:ss yyyy */ |
Yann | 0:a1b58e3c9fdb | 257 | t.tm_wday, |
Yann | 0:a1b58e3c9fdb | 258 | t.tm_mon, |
Yann | 0:a1b58e3c9fdb | 259 | t.tm_mday, |
Yann | 0:a1b58e3c9fdb | 260 | t.tm_hour, |
Yann | 0:a1b58e3c9fdb | 261 | t.tm_min, |
Yann | 0:a1b58e3c9fdb | 262 | t.tm_sec, |
Yann | 0:a1b58e3c9fdb | 263 | t.tm_year); |
Yann | 0:a1b58e3c9fdb | 264 | |
Yann | 0:a1b58e3c9fdb | 265 | DEBUG_LEAVE("CDS130X_I2C::GetTime") |
Yann | 0:a1b58e3c9fdb | 266 | return t; |
Yann | 0:a1b58e3c9fdb | 267 | } // End of method CDS130X_I2C::GetTime |
Yann | 0:a1b58e3c9fdb | 268 | |
Yann | 0:a1b58e3c9fdb | 269 | bool CDS130X_I2C::EraseMemoryArea(const unsigned char p_startAddress, const int p_count, const unsigned char p_pattern) { |
Yann | 0:a1b58e3c9fdb | 270 | DEBUG_ENTER("CDS130X_I2C::EraseMemoryArea): 0x%02x - %d - 0x%02x", p_startAddress, p_count, p_pattern) |
Yann | 0:a1b58e3c9fdb | 271 | |
Yann | 0:a1b58e3c9fdb | 272 | std::vector<unsigned char> eraseBuffer(p_count, p_pattern); |
Yann | 0:a1b58e3c9fdb | 273 | return WriteMemory(p_startAddress, eraseBuffer, false); |
Yann | 0:a1b58e3c9fdb | 274 | } |
Yann | 0:a1b58e3c9fdb | 275 | |
Yann | 0:a1b58e3c9fdb | 276 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const unsigned char p_byte) { |
Yann | 0:a1b58e3c9fdb | 277 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte): Memory address: 0x%02x", p_address) |
Yann | 0:a1b58e3c9fdb | 278 | |
Yann | 0:a1b58e3c9fdb | 279 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 280 | char i2cBuffer[2]; // Memory address + one byte of data |
Yann | 0:a1b58e3c9fdb | 281 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 282 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 283 | DEBUG("CDS130X_I2C::WriteMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 284 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 285 | i2cBuffer[1] = p_byte; |
Yann | 0:a1b58e3c9fdb | 286 | DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x", i2cBuffer[1]) |
Yann | 0:a1b58e3c9fdb | 287 | |
Yann | 0:a1b58e3c9fdb | 288 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 289 | int result = write(_slaveAddress, i2cBuffer, 2); |
Yann | 0:a1b58e3c9fdb | 290 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 291 | |
Yann | 0:a1b58e3c9fdb | 292 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (byte) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 293 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 294 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 295 | |
Yann | 0:a1b58e3c9fdb | 296 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const short p_short, const CDS130X_I2C::Mode p_mode) { |
Yann | 0:a1b58e3c9fdb | 297 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (short): Memory address:0x%02x, Mode:%d", p_address, p_mode) |
Yann | 0:a1b58e3c9fdb | 298 | |
Yann | 0:a1b58e3c9fdb | 299 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 300 | char i2cBuffer[3]; // Memory address + one short (2 bytes) |
Yann | 0:a1b58e3c9fdb | 301 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 302 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 303 | DEBUG("CDS130X_I2C::WriteMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 304 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 305 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 306 | i2cBuffer[1] = (unsigned char)(p_short >> 8); |
Yann | 0:a1b58e3c9fdb | 307 | i2cBuffer[2] = (unsigned char)((unsigned char)p_short & 0xff); |
Yann | 0:a1b58e3c9fdb | 308 | } else { |
Yann | 0:a1b58e3c9fdb | 309 | i2cBuffer[1] = (unsigned char)((unsigned char)p_short & 0xff); |
Yann | 0:a1b58e3c9fdb | 310 | i2cBuffer[2] = (unsigned char)(p_short >> 8); |
Yann | 0:a1b58e3c9fdb | 311 | } |
Yann | 0:a1b58e3c9fdb | 312 | DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x%02x", i2cBuffer[1], i2cBuffer[2]) |
Yann | 0:a1b58e3c9fdb | 313 | |
Yann | 0:a1b58e3c9fdb | 314 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 315 | int result = write(_slaveAddress, i2cBuffer, 3); |
Yann | 0:a1b58e3c9fdb | 316 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 317 | |
Yann | 0:a1b58e3c9fdb | 318 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (short) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 319 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 320 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 321 | |
Yann | 0:a1b58e3c9fdb | 322 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const int p_int, const CDS130X_I2C::Mode p_mode) { |
Yann | 0:a1b58e3c9fdb | 323 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (int): Memory address:0x%02x, Mode:%d", p_address, p_mode) |
Yann | 0:a1b58e3c9fdb | 324 | |
Yann | 0:a1b58e3c9fdb | 325 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 326 | char i2cBuffer[5]; // Memory address + one integer (4 bytes) |
Yann | 0:a1b58e3c9fdb | 327 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 328 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 329 | DEBUG("CDS130X_I2C::WriteMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 330 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 331 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 332 | i2cBuffer[1] = (unsigned char)(p_int >> 24); |
Yann | 0:a1b58e3c9fdb | 333 | i2cBuffer[2] = (unsigned char)(p_int >> 16); |
Yann | 0:a1b58e3c9fdb | 334 | i2cBuffer[3] = (unsigned char)(p_int >> 8); |
Yann | 0:a1b58e3c9fdb | 335 | i2cBuffer[4] = (unsigned char)((unsigned char)p_int & 0xff); |
Yann | 0:a1b58e3c9fdb | 336 | } else { |
Yann | 0:a1b58e3c9fdb | 337 | i2cBuffer[1] = (unsigned char)((unsigned char)p_int & 0xff); |
Yann | 0:a1b58e3c9fdb | 338 | i2cBuffer[2] = (unsigned char)(p_int >> 8); |
Yann | 0:a1b58e3c9fdb | 339 | i2cBuffer[3] = (unsigned char)(p_int >> 16); |
Yann | 0:a1b58e3c9fdb | 340 | i2cBuffer[4] = (unsigned char)(p_int >> 24); |
Yann | 0:a1b58e3c9fdb | 341 | } |
Yann | 0:a1b58e3c9fdb | 342 | DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x%02x%02x%02x", i2cBuffer[1], i2cBuffer[2], i2cBuffer[3], i2cBuffer[4]) |
Yann | 0:a1b58e3c9fdb | 343 | |
Yann | 0:a1b58e3c9fdb | 344 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 345 | int result = write(_slaveAddress, i2cBuffer, 5); |
Yann | 0:a1b58e3c9fdb | 346 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 347 | |
Yann | 0:a1b58e3c9fdb | 348 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (int) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 349 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 350 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 351 | |
Yann | 0:a1b58e3c9fdb | 352 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const std::string & p_string, const bool p_storeLength, const int p_length2write) { |
Yann | 0:a1b58e3c9fdb | 353 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::string)") |
Yann | 0:a1b58e3c9fdb | 354 | return WriteMemory(p_address, p_string.c_str(), p_storeLength, p_length2write); |
Yann | 0:a1b58e3c9fdb | 355 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 356 | |
Yann | 0:a1b58e3c9fdb | 357 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const std::vector<unsigned char> & p_datas, const bool p_storeLength, const int p_length2write) { |
Yann | 0:a1b58e3c9fdb | 358 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::vector)") |
Yann | 0:a1b58e3c9fdb | 359 | |
Yann | 0:a1b58e3c9fdb | 360 | int length = (p_length2write == -1) ? p_datas.size() : p_length2write; |
Yann | 0:a1b58e3c9fdb | 361 | unsigned char array[length]; |
Yann | 0:a1b58e3c9fdb | 362 | std::copy(p_datas.begin(), p_datas.end(), array); |
Yann | 0:a1b58e3c9fdb | 363 | bool result = WriteMemory(p_address, array, p_storeLength, length); |
Yann | 0:a1b58e3c9fdb | 364 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 365 | |
Yann | 0:a1b58e3c9fdb | 366 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (std::vector): %d", result) |
Yann | 0:a1b58e3c9fdb | 367 | return result; |
Yann | 0:a1b58e3c9fdb | 368 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 369 | |
Yann | 0:a1b58e3c9fdb | 370 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const char *p_datas, const bool p_storeLength, const int p_length2write) { |
Yann | 0:a1b58e3c9fdb | 371 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (char *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write) |
Yann | 0:a1b58e3c9fdb | 372 | |
Yann | 0:a1b58e3c9fdb | 373 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 374 | int length = (p_length2write == -1) ? strlen(p_datas) : p_length2write; |
Yann | 0:a1b58e3c9fdb | 375 | if (p_storeLength) { |
Yann | 0:a1b58e3c9fdb | 376 | length += 1; // Add one byte for the length |
Yann | 0:a1b58e3c9fdb | 377 | } |
Yann | 0:a1b58e3c9fdb | 378 | DEBUG("CDS130X_I2C::WriteMemory (char *): length:%d", length) |
Yann | 0:a1b58e3c9fdb | 379 | |
Yann | 0:a1b58e3c9fdb | 380 | char i2cBuffer[1 + length]; |
Yann | 0:a1b58e3c9fdb | 381 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 382 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 383 | DEBUG("CDS130X_I2C::WriteMemory (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 384 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 385 | if (p_storeLength) { |
Yann | 0:a1b58e3c9fdb | 386 | // Fill the length |
Yann | 0:a1b58e3c9fdb | 387 | i2cBuffer[1] = (unsigned char)length; |
Yann | 0:a1b58e3c9fdb | 388 | for (int i = 0; i < length; i++) { |
Yann | 0:a1b58e3c9fdb | 389 | i2cBuffer[2 + i] = *(p_datas + i); |
Yann | 0:a1b58e3c9fdb | 390 | } |
Yann | 0:a1b58e3c9fdb | 391 | } else { // The length was not stored |
Yann | 0:a1b58e3c9fdb | 392 | for (int i = 0; i < length; i++) { |
Yann | 0:a1b58e3c9fdb | 393 | i2cBuffer[1 + i] = *(p_datas + i); |
Yann | 0:a1b58e3c9fdb | 394 | } |
Yann | 0:a1b58e3c9fdb | 395 | } |
Yann | 0:a1b58e3c9fdb | 396 | |
Yann | 0:a1b58e3c9fdb | 397 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 398 | int result = write(_slaveAddress, i2cBuffer, 1 + length); |
Yann | 0:a1b58e3c9fdb | 399 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 400 | |
Yann | 0:a1b58e3c9fdb | 401 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (char *) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 402 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 403 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 404 | |
Yann | 0:a1b58e3c9fdb | 405 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const unsigned char *p_datas, const bool p_storeLength, const int p_length2write) { |
Yann | 0:a1b58e3c9fdb | 406 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte *): Memory address: 0x%02x", p_address, p_storeLength, p_length2write) |
Yann | 0:a1b58e3c9fdb | 407 | return WriteMemory(p_address, (const char *)p_datas, p_storeLength, p_length2write); |
Yann | 0:a1b58e3c9fdb | 408 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 409 | |
Yann | 0:a1b58e3c9fdb | 410 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, unsigned char * p_byte) { |
Yann | 0:a1b58e3c9fdb | 411 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (byte): Memory address:0x%02x", p_address) |
Yann | 0:a1b58e3c9fdb | 412 | |
Yann | 0:a1b58e3c9fdb | 413 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 414 | char i2cBuffer[1]; |
Yann | 0:a1b58e3c9fdb | 415 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 416 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 417 | DEBUG("CDS130X_I2C::ReadMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 418 | |
Yann | 0:a1b58e3c9fdb | 419 | // 2. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 420 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 421 | // 2. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 422 | int result = read(_slaveAddress, (char *)p_byte, 1); |
Yann | 0:a1b58e3c9fdb | 423 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 424 | |
Yann | 0:a1b58e3c9fdb | 425 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 426 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 427 | } |
Yann | 0:a1b58e3c9fdb | 428 | |
Yann | 0:a1b58e3c9fdb | 429 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte) (false)") |
Yann | 0:a1b58e3c9fdb | 430 | return false; |
Yann | 0:a1b58e3c9fdb | 431 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 432 | |
Yann | 0:a1b58e3c9fdb | 433 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, short *p_short, const CDS130X_I2C::Mode p_mode) { |
Yann | 0:a1b58e3c9fdb | 434 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (short): Memory address:0x%02x, Mode:%d", p_address, p_mode) |
Yann | 0:a1b58e3c9fdb | 435 | |
Yann | 0:a1b58e3c9fdb | 436 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 437 | char i2cBuffer[2]; |
Yann | 0:a1b58e3c9fdb | 438 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 439 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 440 | DEBUG("CDS130X_I2C::ReadMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 441 | |
Yann | 0:a1b58e3c9fdb | 442 | // 2. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 443 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 444 | // 2. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 445 | int result = read(_slaveAddress, i2cBuffer, 2); |
Yann | 0:a1b58e3c9fdb | 446 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 447 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 448 | *p_short = (short)(i2cBuffer[0] << 8 | i2cBuffer[1]); |
Yann | 0:a1b58e3c9fdb | 449 | } else { |
Yann | 0:a1b58e3c9fdb | 450 | *p_short = (short)(i2cBuffer[1] << 8 | i2cBuffer[0]); |
Yann | 0:a1b58e3c9fdb | 451 | } |
Yann | 0:a1b58e3c9fdb | 452 | |
Yann | 0:a1b58e3c9fdb | 453 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 454 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 455 | } |
Yann | 0:a1b58e3c9fdb | 456 | |
Yann | 0:a1b58e3c9fdb | 457 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short) (false)") |
Yann | 0:a1b58e3c9fdb | 458 | return false; |
Yann | 0:a1b58e3c9fdb | 459 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 460 | |
Yann | 0:a1b58e3c9fdb | 461 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, int *p_int, const CDS130X_I2C::Mode p_mode) { |
Yann | 0:a1b58e3c9fdb | 462 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (int): Memory address:0x%02x, Mode:%d", p_address, p_mode) |
Yann | 0:a1b58e3c9fdb | 463 | |
Yann | 0:a1b58e3c9fdb | 464 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 465 | char i2cBuffer[4]; |
Yann | 0:a1b58e3c9fdb | 466 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 467 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 468 | DEBUG("CDS130X_I2C::ReadMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 469 | |
Yann | 0:a1b58e3c9fdb | 470 | // 2. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 471 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 472 | // 2. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 473 | int result = read(_slaveAddress, i2cBuffer, 4); |
Yann | 0:a1b58e3c9fdb | 474 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 475 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 476 | *p_int = (int)(i2cBuffer[0] << 24 | i2cBuffer[1] << 16 | i2cBuffer[2] << 8 | i2cBuffer[3]); |
Yann | 0:a1b58e3c9fdb | 477 | } else { |
Yann | 0:a1b58e3c9fdb | 478 | *p_int = (int)(i2cBuffer[3] << 24 | i2cBuffer[2] << 16 | i2cBuffer[1] << 8 | i2cBuffer[0]); |
Yann | 0:a1b58e3c9fdb | 479 | } |
Yann | 0:a1b58e3c9fdb | 480 | |
Yann | 0:a1b58e3c9fdb | 481 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 482 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 483 | } |
Yann | 0:a1b58e3c9fdb | 484 | |
Yann | 0:a1b58e3c9fdb | 485 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int) (false)") |
Yann | 0:a1b58e3c9fdb | 486 | return false; |
Yann | 0:a1b58e3c9fdb | 487 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 488 | |
Yann | 0:a1b58e3c9fdb | 489 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst, const int p_length2write) { |
Yann | 0:a1b58e3c9fdb | 490 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (vector): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write) |
Yann | 0:a1b58e3c9fdb | 491 | |
Yann | 0:a1b58e3c9fdb | 492 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 493 | unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 494 | int length; |
Yann | 0:a1b58e3c9fdb | 495 | if (p_readLengthFirst) { |
Yann | 0:a1b58e3c9fdb | 496 | ReadMemory(address, &length); // Read the length in big endian mode |
Yann | 0:a1b58e3c9fdb | 497 | address += 1; // Skip the length value |
Yann | 0:a1b58e3c9fdb | 498 | length -= 1; // length is the size of (string length + string) |
Yann | 0:a1b58e3c9fdb | 499 | } else { |
Yann | 0:a1b58e3c9fdb | 500 | if (p_length2write == -1) { |
Yann | 0:a1b58e3c9fdb | 501 | length = p_datas.size(); |
Yann | 0:a1b58e3c9fdb | 502 | } else { |
Yann | 0:a1b58e3c9fdb | 503 | length = p_length2write; |
Yann | 0:a1b58e3c9fdb | 504 | } |
Yann | 0:a1b58e3c9fdb | 505 | } |
Yann | 0:a1b58e3c9fdb | 506 | |
Yann | 0:a1b58e3c9fdb | 507 | // 2. Memory address |
Yann | 0:a1b58e3c9fdb | 508 | char i2cBuffer[1]; |
Yann | 0:a1b58e3c9fdb | 509 | i2cBuffer[0] = address; |
Yann | 0:a1b58e3c9fdb | 510 | DEBUG("CDS130X_I2C::ReadMemory (vector): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 511 | |
Yann | 0:a1b58e3c9fdb | 512 | // 3. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 513 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 514 | // 4. read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 515 | unsigned char buffer[length]; |
Yann | 0:a1b58e3c9fdb | 516 | int result = read(_slaveAddress, (char *)buffer, length); |
Yann | 0:a1b58e3c9fdb | 517 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 518 | if (result == 0) { |
Yann | 0:a1b58e3c9fdb | 519 | p_datas.assign(buffer, buffer + length); |
Yann | 0:a1b58e3c9fdb | 520 | |
Yann | 0:a1b58e3c9fdb | 521 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 522 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 523 | } |
Yann | 0:a1b58e3c9fdb | 524 | } |
Yann | 0:a1b58e3c9fdb | 525 | |
Yann | 0:a1b58e3c9fdb | 526 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector) (false)") |
Yann | 0:a1b58e3c9fdb | 527 | return false; |
Yann | 0:a1b58e3c9fdb | 528 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 529 | |
Yann | 0:a1b58e3c9fdb | 530 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, std::string & p_string, const bool p_readLengthFirst, const int p_length2write) { |
Yann | 0:a1b58e3c9fdb | 531 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (string): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write) |
Yann | 0:a1b58e3c9fdb | 532 | |
Yann | 0:a1b58e3c9fdb | 533 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 534 | unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 535 | int length; |
Yann | 0:a1b58e3c9fdb | 536 | if (p_readLengthFirst) { // The string was stored with its length |
Yann | 0:a1b58e3c9fdb | 537 | if (!ReadMemory(address, &length)) { // Read the length in big endian mode |
Yann | 0:a1b58e3c9fdb | 538 | DEBUG_ERROR("CDS130X_I2C::ReadMemory (string): Failed to read length") |
Yann | 0:a1b58e3c9fdb | 539 | return false; |
Yann | 0:a1b58e3c9fdb | 540 | } |
Yann | 0:a1b58e3c9fdb | 541 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 542 | address += 4; // Skip the length value size |
Yann | 0:a1b58e3c9fdb | 543 | length -= 4; // length is the size of (string length + string) |
Yann | 0:a1b58e3c9fdb | 544 | } else { // The string length is provided by p_length2write parameter |
Yann | 0:a1b58e3c9fdb | 545 | if (p_length2write == -1) { |
Yann | 0:a1b58e3c9fdb | 546 | length = p_string.size(); |
Yann | 0:a1b58e3c9fdb | 547 | } else { |
Yann | 0:a1b58e3c9fdb | 548 | length = p_length2write; |
Yann | 0:a1b58e3c9fdb | 549 | p_string.resize(p_length2write); |
Yann | 0:a1b58e3c9fdb | 550 | } |
Yann | 0:a1b58e3c9fdb | 551 | } |
Yann | 0:a1b58e3c9fdb | 552 | DEBUG("CDS130X_I2C::ReadMemory (string): Length=%d", length) |
Yann | 0:a1b58e3c9fdb | 553 | |
Yann | 0:a1b58e3c9fdb | 554 | // 2. Memory address |
Yann | 0:a1b58e3c9fdb | 555 | char i2cBuffer[2]; |
Yann | 0:a1b58e3c9fdb | 556 | i2cBuffer[0] = address; |
Yann | 0:a1b58e3c9fdb | 557 | DEBUG("CDS130X_I2C::ReadMemory (string): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 558 | i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); |
Yann | 0:a1b58e3c9fdb | 559 | DEBUG("CDS130X_I2C::ReadMemory (string): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) |
Yann | 0:a1b58e3c9fdb | 560 | |
Yann | 0:a1b58e3c9fdb | 561 | // 3. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 562 | if (write(_slaveAddress, i2cBuffer, 2, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 563 | // 4. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 564 | char buffer[length]; |
Yann | 0:a1b58e3c9fdb | 565 | int result = read(_slaveAddress, (char *)buffer, length); |
Yann | 0:a1b58e3c9fdb | 566 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string): %d", result) |
Yann | 0:a1b58e3c9fdb | 567 | if (result == 0) { |
Yann | 0:a1b58e3c9fdb | 568 | p_string.assign(buffer, length); |
Yann | 0:a1b58e3c9fdb | 569 | |
Yann | 0:a1b58e3c9fdb | 570 | return true; |
Yann | 0:a1b58e3c9fdb | 571 | } |
Yann | 0:a1b58e3c9fdb | 572 | } |
Yann | 0:a1b58e3c9fdb | 573 | |
Yann | 0:a1b58e3c9fdb | 574 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string) (false)") |
Yann | 0:a1b58e3c9fdb | 575 | return false; |
Yann | 0:a1b58e3c9fdb | 576 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 577 | |
Yann | 0:a1b58e3c9fdb | 578 | #if defined(__DEBUG) |
Yann | 0:a1b58e3c9fdb | 579 | void CDS130X_I2C::DumpMemoryArea(const unsigned char p_address, const int p_count) { |
Yann | 0:a1b58e3c9fdb | 580 | DEBUG_ENTER("CDS130X_I2C::DumpMemoryArea: %02x - %d", p_address, p_count) |
Yann | 0:a1b58e3c9fdb | 581 | |
Yann | 0:a1b58e3c9fdb | 582 | DEBUG("CDS130X_I2C::DumpMemoryArea: Reading datas..."); |
Yann | 0:a1b58e3c9fdb | 583 | std::vector<unsigned char> datas(p_count); |
Yann | 0:a1b58e3c9fdb | 584 | if (!ReadMemory((unsigned char)CDS130X_I2C::BaseMemoryAddress + p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call |
Yann | 0:a1b58e3c9fdb | 585 | #ifdef __DEBUG |
Yann | 0:a1b58e3c9fdb | 586 | DEBUG_FATAL("CDS130X_I2C::DumpMemoryArea: read failed") |
Yann | 0:a1b58e3c9fdb | 587 | #else // __DEBUG |
Yann | 0:a1b58e3c9fdb | 588 | std::cout << "CDS130X_I2C::DumpMemoryArea: read failed\r" << std::endl |
Yann | 0:a1b58e3c9fdb | 589 | #endif // __DEBUG |
Yann | 0:a1b58e3c9fdb | 590 | } else { |
Yann | 0:a1b58e3c9fdb | 591 | std::cout << "CDS130X_I2C::DumpMemoryArea: Read bytes:\r" << std::endl; |
Yann | 0:a1b58e3c9fdb | 592 | HEXADUMP(&datas[0], p_count); |
Yann | 0:a1b58e3c9fdb | 593 | std::cout << "\r" << std::endl; |
Yann | 0:a1b58e3c9fdb | 594 | } |
Yann | 0:a1b58e3c9fdb | 595 | } // End of method CDS130X_I2C::DumpMemoryArea |
Yann | 0:a1b58e3c9fdb | 596 | #endif // _DEBUG |
Yann | 0:a1b58e3c9fdb | 597 | |
Yann | 0:a1b58e3c9fdb | 598 | } // End of namespace DS130X_I2C |