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@1:834e9897e269, 2011-02-11 (annotated)
- Committer:
- Yann
- Date:
- Fri Feb 11 10:16:20 2011 +0000
- Revision:
- 1:834e9897e269
- Parent:
- 0:a1b58e3c9fdb
V0.0.0.2
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 | 1:834e9897e269 | 57 | if (Read(CDS130X_I2C::HoursAddress, &hoursRegister)) { |
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 | 1:834e9897e269 | 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 | 1:834e9897e269 | 113 | DEBUG_ENTER("CDS130X_I2C::Read: %02x - %x", p_address, p_format) |
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 | 1:834e9897e269 | 125 | DEBUG_ENTER("CDS130X_I2C::Read: check %02x - %02x", p_format, Binary) |
Yann | 0:a1b58e3c9fdb | 126 | if (p_format == CDS130X_I2C::Binary) { |
Yann | 0:a1b58e3c9fdb | 127 | switch ((RegisterEnum)p_address) { |
Yann | 0:a1b58e3c9fdb | 128 | case CDS130X_I2C::SecondsAddress: |
Yann | 0:a1b58e3c9fdb | 129 | //No break; |
Yann | 0:a1b58e3c9fdb | 130 | case CDS130X_I2C::MinutesAddress: |
Yann | 0:a1b58e3c9fdb | 131 | *p_byte = ConvertBCDToHex(*p_byte & 0x7f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 132 | break; |
Yann | 0:a1b58e3c9fdb | 133 | case CDS130X_I2C::HoursAddress: |
Yann | 0:a1b58e3c9fdb | 134 | //No break; |
Yann | 0:a1b58e3c9fdb | 135 | case CDS130X_I2C::DayAddress: |
Yann | 0:a1b58e3c9fdb | 136 | *p_byte = ConvertBCDToHex(*p_byte & 0x3f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 137 | break; |
Yann | 0:a1b58e3c9fdb | 138 | case CDS130X_I2C::DayOfWeekAddress: |
Yann | 1:834e9897e269 | 139 | *p_byte = ConvertBCDToHex(*p_byte & 0x07); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 140 | break; |
Yann | 0:a1b58e3c9fdb | 141 | case CDS130X_I2C::MonthAddress: |
Yann | 0:a1b58e3c9fdb | 142 | *p_byte = ConvertBCDToHex(*p_byte & 0x1f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 143 | break; |
Yann | 0:a1b58e3c9fdb | 144 | case CDS130X_I2C::YearAddress: |
Yann | 0:a1b58e3c9fdb | 145 | *p_byte = ConvertBCDToHex(*p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers |
Yann | 0:a1b58e3c9fdb | 146 | break; |
Yann | 0:a1b58e3c9fdb | 147 | } // End of 'switch' statement |
Yann | 0:a1b58e3c9fdb | 148 | } // else nothing to do |
Yann | 0:a1b58e3c9fdb | 149 | |
Yann | 1:834e9897e269 | 150 | DEBUG_LEAVE("CDS130X_I2C::Read %d/%02x", (int)*p_byte, *p_byte) |
Yann | 0:a1b58e3c9fdb | 151 | return true; |
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 | 1:834e9897e269 | 159 | DEBUG_ENTER("CDS130X_I2C::Write: %02x - %d - %x", p_address, (int)p_byte, p_format) |
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 | 1:834e9897e269 | 176 | value = ConvertHexToBCD(p_byte) & 0x07; // 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 | 1:834e9897e269 | 185 | DEBUG("CDS130X_I2C::Write: Convert binary %d into bcd %02x", (int)p_byte, value) |
Yann | 0:a1b58e3c9fdb | 186 | } // else nothing to do |
Yann | 0:a1b58e3c9fdb | 187 | |
Yann | 0:a1b58e3c9fdb | 188 | // 2. Read seconds |
Yann | 0:a1b58e3c9fdb | 189 | char i2cBuffer[2]; |
Yann | 0:a1b58e3c9fdb | 190 | i2cBuffer[0] = (char)(unsigned char)p_address; |
Yann | 0:a1b58e3c9fdb | 191 | i2cBuffer[1] = value; |
Yann | 0:a1b58e3c9fdb | 192 | // Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 193 | if (write(_slaveAddress, i2cBuffer, 2) == 0) { |
Yann | 0:a1b58e3c9fdb | 194 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 195 | DEBUG_LEAVE("CDS130X_I2C::Write (true)") |
Yann | 0:a1b58e3c9fdb | 196 | return true; |
Yann | 0:a1b58e3c9fdb | 197 | } |
Yann | 0:a1b58e3c9fdb | 198 | |
Yann | 0:a1b58e3c9fdb | 199 | DEBUG_LEAVE("CDS130X_I2C::Write (false)") |
Yann | 0:a1b58e3c9fdb | 200 | return false; |
Yann | 0:a1b58e3c9fdb | 201 | } // End of method CDS130X_I2C::Write |
Yann | 0:a1b58e3c9fdb | 202 | |
Yann | 0:a1b58e3c9fdb | 203 | bool CDS130X_I2C::SetTime(const std::string p_utcTime) { |
Yann | 0:a1b58e3c9fdb | 204 | DEBUG_ENTER("CDS130X_I2C::SetTime: %s - %d", p_utcTime.c_str(), p_utcTime.length()) |
Yann | 0:a1b58e3c9fdb | 205 | |
Yann | 0:a1b58e3c9fdb | 206 | // Sanity checks |
Yann | 0:a1b58e3c9fdb | 207 | if (p_utcTime.length() != 23) { |
Yann | 0:a1b58e3c9fdb | 208 | DEBUG_ERROR("CDS130X_I2C::SetTime: Wrong parameters") |
Yann | 0:a1b58e3c9fdb | 209 | return false; |
Yann | 0:a1b58e3c9fdb | 210 | } |
Yann | 0:a1b58e3c9fdb | 211 | // Fill struct tm; |
Yann | 0:a1b58e3c9fdb | 212 | struct tm t = {0}; |
Yann | 0:a1b58e3c9fdb | 213 | char wday[4] = {0}; |
Yann | 1:834e9897e269 | 214 | sscanf(p_utcTime.c_str(), "%s %2d %2d %2d:%2d:%2d %4d", /* Www MM dd hh:mm:ss yyyy, e.g. Thu 02 10 07:13:29 2011 */ |
Yann | 0:a1b58e3c9fdb | 215 | wday, |
Yann | 0:a1b58e3c9fdb | 216 | &t.tm_mon, |
Yann | 0:a1b58e3c9fdb | 217 | &t.tm_mday, |
Yann | 0:a1b58e3c9fdb | 218 | &t.tm_hour, |
Yann | 0:a1b58e3c9fdb | 219 | &t.tm_min, |
Yann | 0:a1b58e3c9fdb | 220 | &t.tm_sec, |
Yann | 0:a1b58e3c9fdb | 221 | &t.tm_year); |
Yann | 1:834e9897e269 | 222 | DEBUG("CDS130X_I2C::SetTime: wday=%s - %d - %d - %d - %d - %d", wday, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); |
Yann | 0:a1b58e3c9fdb | 223 | |
Yann | 1:834e9897e269 | 224 | t.tm_wday = (_dayOfWeek.find(wday) / 3) + 1; |
Yann | 1:834e9897e269 | 225 | DEBUG("CDS130X_I2C::SetTime: wday=%s - _dayOfWeek:%s - tm_wday=%d", wday, _dayOfWeek.c_str(), t.tm_wday); |
Yann | 0:a1b58e3c9fdb | 226 | |
Yann | 1:834e9897e269 | 227 | Write(CDS130X_I2C::SecondsAddress, t.tm_sec, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 228 | Write(CDS130X_I2C::MinutesAddress, t.tm_min, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 229 | Write(CDS130X_I2C::HoursAddress, t.tm_hour, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 230 | Write(CDS130X_I2C::DayOfWeekAddress, t.tm_wday, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 231 | Write(CDS130X_I2C::DayAddress, t.tm_mday, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 232 | Write(CDS130X_I2C::MonthAddress, t.tm_mon, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 233 | Write(CDS130X_I2C::YearAddress, t.tm_year - 1900, CDS130X_I2C::Binary); // Years since 1900: 2011 becomes 111 |
Yann | 0:a1b58e3c9fdb | 234 | |
Yann | 0:a1b58e3c9fdb | 235 | return true; |
Yann | 0:a1b58e3c9fdb | 236 | } // End of method CDS130X_I2C::SetTime |
Yann | 0:a1b58e3c9fdb | 237 | |
Yann | 0:a1b58e3c9fdb | 238 | struct tm CDS130X_I2C::GetTime() { |
Yann | 0:a1b58e3c9fdb | 239 | DEBUG_ENTER("CDS130X_I2C::GetTime") |
Yann | 0:a1b58e3c9fdb | 240 | |
Yann | 1:834e9897e269 | 241 | struct tm t = {0}; |
Yann | 0:a1b58e3c9fdb | 242 | unsigned char value; |
Yann | 0:a1b58e3c9fdb | 243 | // Setup time structure from RTC |
Yann | 1:834e9897e269 | 244 | Read(CDS130X_I2C::SecondsAddress, &value, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 245 | t.tm_sec = (int)value; |
Yann | 1:834e9897e269 | 246 | Read(CDS130X_I2C::MinutesAddress, &value, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 247 | t.tm_min = (int)value; |
Yann | 1:834e9897e269 | 248 | Read(CDS130X_I2C::HoursAddress, &value, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 249 | t.tm_hour = (int)value; |
Yann | 1:834e9897e269 | 250 | Read(CDS130X_I2C::DayOfWeekAddress, &value, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 251 | t.tm_wday = (int)value - 1; |
Yann | 1:834e9897e269 | 252 | Read(CDS130X_I2C::DayAddress, &value, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 253 | t.tm_mday = (int)value; |
Yann | 1:834e9897e269 | 254 | Read(CDS130X_I2C::MonthAddress, &value, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 255 | t.tm_mon = (int)value; |
Yann | 1:834e9897e269 | 256 | Read(CDS130X_I2C::YearAddress, &value, CDS130X_I2C::Binary); |
Yann | 1:834e9897e269 | 257 | t.tm_year = (int)value; // Years since 1900: 111 means 2011 |
Yann | 0:a1b58e3c9fdb | 258 | |
Yann | 0:a1b58e3c9fdb | 259 | DEBUG_LEAVE("CDS130X_I2C::GetTime") |
Yann | 0:a1b58e3c9fdb | 260 | return t; |
Yann | 0:a1b58e3c9fdb | 261 | } // End of method CDS130X_I2C::GetTime |
Yann | 0:a1b58e3c9fdb | 262 | |
Yann | 0:a1b58e3c9fdb | 263 | bool CDS130X_I2C::EraseMemoryArea(const unsigned char p_startAddress, const int p_count, const unsigned char p_pattern) { |
Yann | 0:a1b58e3c9fdb | 264 | DEBUG_ENTER("CDS130X_I2C::EraseMemoryArea): 0x%02x - %d - 0x%02x", p_startAddress, p_count, p_pattern) |
Yann | 0:a1b58e3c9fdb | 265 | |
Yann | 0:a1b58e3c9fdb | 266 | std::vector<unsigned char> eraseBuffer(p_count, p_pattern); |
Yann | 0:a1b58e3c9fdb | 267 | return WriteMemory(p_startAddress, eraseBuffer, false); |
Yann | 0:a1b58e3c9fdb | 268 | } |
Yann | 0:a1b58e3c9fdb | 269 | |
Yann | 0:a1b58e3c9fdb | 270 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const unsigned char p_byte) { |
Yann | 0:a1b58e3c9fdb | 271 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte): Memory address: 0x%02x", p_address) |
Yann | 0:a1b58e3c9fdb | 272 | |
Yann | 0:a1b58e3c9fdb | 273 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 274 | char i2cBuffer[2]; // Memory address + one byte of data |
Yann | 0:a1b58e3c9fdb | 275 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 276 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 277 | DEBUG("CDS130X_I2C::WriteMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 278 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 279 | i2cBuffer[1] = p_byte; |
Yann | 0:a1b58e3c9fdb | 280 | DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x", i2cBuffer[1]) |
Yann | 0:a1b58e3c9fdb | 281 | |
Yann | 0:a1b58e3c9fdb | 282 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 283 | int result = write(_slaveAddress, i2cBuffer, 2); |
Yann | 0:a1b58e3c9fdb | 284 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 285 | |
Yann | 0:a1b58e3c9fdb | 286 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (byte) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 287 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 288 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 289 | |
Yann | 0:a1b58e3c9fdb | 290 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const short p_short, const CDS130X_I2C::Mode p_mode) { |
Yann | 1:834e9897e269 | 291 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (short): Memory address:0x%02x, p_short:%04x, Mode:%d", p_address, p_short, p_mode) |
Yann | 0:a1b58e3c9fdb | 292 | |
Yann | 0:a1b58e3c9fdb | 293 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 294 | char i2cBuffer[3]; // Memory address + one short (2 bytes) |
Yann | 0:a1b58e3c9fdb | 295 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 296 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 297 | DEBUG("CDS130X_I2C::WriteMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 298 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 299 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 300 | i2cBuffer[1] = (unsigned char)(p_short >> 8); |
Yann | 0:a1b58e3c9fdb | 301 | i2cBuffer[2] = (unsigned char)((unsigned char)p_short & 0xff); |
Yann | 0:a1b58e3c9fdb | 302 | } else { |
Yann | 0:a1b58e3c9fdb | 303 | i2cBuffer[1] = (unsigned char)((unsigned char)p_short & 0xff); |
Yann | 0:a1b58e3c9fdb | 304 | i2cBuffer[2] = (unsigned char)(p_short >> 8); |
Yann | 0:a1b58e3c9fdb | 305 | } |
Yann | 1:834e9897e269 | 306 | DEBUG("CDS130X_I2C::WriteMemory (short): value=0x%02x%02x", i2cBuffer[1], i2cBuffer[2]) |
Yann | 0:a1b58e3c9fdb | 307 | |
Yann | 0:a1b58e3c9fdb | 308 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 309 | int result = write(_slaveAddress, i2cBuffer, 3); |
Yann | 0:a1b58e3c9fdb | 310 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 311 | |
Yann | 0:a1b58e3c9fdb | 312 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (short) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 313 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 314 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 315 | |
Yann | 0:a1b58e3c9fdb | 316 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const int p_int, const CDS130X_I2C::Mode p_mode) { |
Yann | 1:834e9897e269 | 317 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (int): Memory address:0x%02x, p_int:%d, Mode:%d", p_address, p_int, p_mode) |
Yann | 0:a1b58e3c9fdb | 318 | |
Yann | 0:a1b58e3c9fdb | 319 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 320 | char i2cBuffer[5]; // Memory address + one integer (4 bytes) |
Yann | 0:a1b58e3c9fdb | 321 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 322 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 323 | DEBUG("CDS130X_I2C::WriteMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 324 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 325 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 326 | i2cBuffer[1] = (unsigned char)(p_int >> 24); |
Yann | 0:a1b58e3c9fdb | 327 | i2cBuffer[2] = (unsigned char)(p_int >> 16); |
Yann | 0:a1b58e3c9fdb | 328 | i2cBuffer[3] = (unsigned char)(p_int >> 8); |
Yann | 0:a1b58e3c9fdb | 329 | i2cBuffer[4] = (unsigned char)((unsigned char)p_int & 0xff); |
Yann | 0:a1b58e3c9fdb | 330 | } else { |
Yann | 0:a1b58e3c9fdb | 331 | i2cBuffer[1] = (unsigned char)((unsigned char)p_int & 0xff); |
Yann | 0:a1b58e3c9fdb | 332 | i2cBuffer[2] = (unsigned char)(p_int >> 8); |
Yann | 0:a1b58e3c9fdb | 333 | i2cBuffer[3] = (unsigned char)(p_int >> 16); |
Yann | 0:a1b58e3c9fdb | 334 | i2cBuffer[4] = (unsigned char)(p_int >> 24); |
Yann | 0:a1b58e3c9fdb | 335 | } |
Yann | 1:834e9897e269 | 336 | DEBUG("CDS130X_I2C::WriteMemory (int): value=0x%02x%02x%02x%02x", i2cBuffer[1], i2cBuffer[2], i2cBuffer[3], i2cBuffer[4]) |
Yann | 0:a1b58e3c9fdb | 337 | |
Yann | 0:a1b58e3c9fdb | 338 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 339 | int result = write(_slaveAddress, i2cBuffer, 5); |
Yann | 0:a1b58e3c9fdb | 340 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 341 | |
Yann | 0:a1b58e3c9fdb | 342 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (int) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 343 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 344 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 345 | |
Yann | 0:a1b58e3c9fdb | 346 | 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 | 347 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::string)") |
Yann | 0:a1b58e3c9fdb | 348 | return WriteMemory(p_address, p_string.c_str(), p_storeLength, p_length2write); |
Yann | 0:a1b58e3c9fdb | 349 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 350 | |
Yann | 0:a1b58e3c9fdb | 351 | 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 | 352 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::vector)") |
Yann | 0:a1b58e3c9fdb | 353 | |
Yann | 0:a1b58e3c9fdb | 354 | int length = (p_length2write == -1) ? p_datas.size() : p_length2write; |
Yann | 0:a1b58e3c9fdb | 355 | unsigned char array[length]; |
Yann | 0:a1b58e3c9fdb | 356 | std::copy(p_datas.begin(), p_datas.end(), array); |
Yann | 0:a1b58e3c9fdb | 357 | bool result = WriteMemory(p_address, array, p_storeLength, length); |
Yann | 0:a1b58e3c9fdb | 358 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 359 | |
Yann | 0:a1b58e3c9fdb | 360 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (std::vector): %d", result) |
Yann | 0:a1b58e3c9fdb | 361 | return result; |
Yann | 0:a1b58e3c9fdb | 362 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 363 | |
Yann | 0:a1b58e3c9fdb | 364 | bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const char *p_datas, const bool p_storeLength, const int p_length2write) { |
Yann | 0:a1b58e3c9fdb | 365 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (char *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write) |
Yann | 0:a1b58e3c9fdb | 366 | |
Yann | 0:a1b58e3c9fdb | 367 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 368 | int length = (p_length2write == -1) ? strlen(p_datas) : p_length2write; |
Yann | 0:a1b58e3c9fdb | 369 | if (p_storeLength) { |
Yann | 0:a1b58e3c9fdb | 370 | length += 1; // Add one byte for the length |
Yann | 0:a1b58e3c9fdb | 371 | } |
Yann | 0:a1b58e3c9fdb | 372 | DEBUG("CDS130X_I2C::WriteMemory (char *): length:%d", length) |
Yann | 0:a1b58e3c9fdb | 373 | |
Yann | 0:a1b58e3c9fdb | 374 | char i2cBuffer[1 + length]; |
Yann | 0:a1b58e3c9fdb | 375 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 376 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 377 | DEBUG("CDS130X_I2C::WriteMemory (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 378 | // 1.2. Datas |
Yann | 0:a1b58e3c9fdb | 379 | if (p_storeLength) { |
Yann | 0:a1b58e3c9fdb | 380 | // Fill the length |
Yann | 0:a1b58e3c9fdb | 381 | i2cBuffer[1] = (unsigned char)length; |
Yann | 0:a1b58e3c9fdb | 382 | for (int i = 0; i < length; i++) { |
Yann | 0:a1b58e3c9fdb | 383 | i2cBuffer[2 + i] = *(p_datas + i); |
Yann | 0:a1b58e3c9fdb | 384 | } |
Yann | 0:a1b58e3c9fdb | 385 | } else { // The length was not stored |
Yann | 0:a1b58e3c9fdb | 386 | for (int i = 0; i < length; i++) { |
Yann | 0:a1b58e3c9fdb | 387 | i2cBuffer[1 + i] = *(p_datas + i); |
Yann | 0:a1b58e3c9fdb | 388 | } |
Yann | 0:a1b58e3c9fdb | 389 | } |
Yann | 0:a1b58e3c9fdb | 390 | |
Yann | 0:a1b58e3c9fdb | 391 | // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop |
Yann | 0:a1b58e3c9fdb | 392 | int result = write(_slaveAddress, i2cBuffer, 1 + length); |
Yann | 0:a1b58e3c9fdb | 393 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 394 | |
Yann | 0:a1b58e3c9fdb | 395 | DEBUG_LEAVE("CDS130X_I2C::WriteMemory (char *) %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 396 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 397 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 398 | |
Yann | 0:a1b58e3c9fdb | 399 | 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 | 400 | DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte *): Memory address: 0x%02x", p_address, p_storeLength, p_length2write) |
Yann | 0:a1b58e3c9fdb | 401 | return WriteMemory(p_address, (const char *)p_datas, p_storeLength, p_length2write); |
Yann | 0:a1b58e3c9fdb | 402 | } // End of method CDS130X_I2C::WriteMemory |
Yann | 0:a1b58e3c9fdb | 403 | |
Yann | 0:a1b58e3c9fdb | 404 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, unsigned char * p_byte) { |
Yann | 0:a1b58e3c9fdb | 405 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (byte): Memory address:0x%02x", p_address) |
Yann | 0:a1b58e3c9fdb | 406 | |
Yann | 0:a1b58e3c9fdb | 407 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 408 | char i2cBuffer[1]; |
Yann | 0:a1b58e3c9fdb | 409 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 410 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 411 | DEBUG("CDS130X_I2C::ReadMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 412 | |
Yann | 0:a1b58e3c9fdb | 413 | // 2. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 414 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 415 | // 2. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 416 | int result = read(_slaveAddress, (char *)p_byte, 1); |
Yann | 0:a1b58e3c9fdb | 417 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 418 | |
Yann | 0:a1b58e3c9fdb | 419 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 420 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 421 | } |
Yann | 0:a1b58e3c9fdb | 422 | |
Yann | 0:a1b58e3c9fdb | 423 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte) (false)") |
Yann | 0:a1b58e3c9fdb | 424 | return false; |
Yann | 0:a1b58e3c9fdb | 425 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 426 | |
Yann | 0:a1b58e3c9fdb | 427 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, short *p_short, const CDS130X_I2C::Mode p_mode) { |
Yann | 0:a1b58e3c9fdb | 428 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (short): Memory address:0x%02x, Mode:%d", p_address, p_mode) |
Yann | 0:a1b58e3c9fdb | 429 | |
Yann | 0:a1b58e3c9fdb | 430 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 431 | char i2cBuffer[2]; |
Yann | 0:a1b58e3c9fdb | 432 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 433 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 434 | DEBUG("CDS130X_I2C::ReadMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 435 | |
Yann | 0:a1b58e3c9fdb | 436 | // 2. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 437 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 438 | // 2. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 439 | int result = read(_slaveAddress, i2cBuffer, 2); |
Yann | 0:a1b58e3c9fdb | 440 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 441 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 442 | *p_short = (short)(i2cBuffer[0] << 8 | i2cBuffer[1]); |
Yann | 0:a1b58e3c9fdb | 443 | } else { |
Yann | 0:a1b58e3c9fdb | 444 | *p_short = (short)(i2cBuffer[1] << 8 | i2cBuffer[0]); |
Yann | 0:a1b58e3c9fdb | 445 | } |
Yann | 0:a1b58e3c9fdb | 446 | |
Yann | 0:a1b58e3c9fdb | 447 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 448 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 449 | } |
Yann | 0:a1b58e3c9fdb | 450 | |
Yann | 0:a1b58e3c9fdb | 451 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short) (false)") |
Yann | 0:a1b58e3c9fdb | 452 | return false; |
Yann | 0:a1b58e3c9fdb | 453 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 454 | |
Yann | 0:a1b58e3c9fdb | 455 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, int *p_int, const CDS130X_I2C::Mode p_mode) { |
Yann | 0:a1b58e3c9fdb | 456 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (int): Memory address:0x%02x, Mode:%d", p_address, p_mode) |
Yann | 0:a1b58e3c9fdb | 457 | |
Yann | 0:a1b58e3c9fdb | 458 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 459 | char i2cBuffer[4]; |
Yann | 0:a1b58e3c9fdb | 460 | // 1.1. Memory address |
Yann | 0:a1b58e3c9fdb | 461 | i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 0:a1b58e3c9fdb | 462 | DEBUG("CDS130X_I2C::ReadMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 463 | |
Yann | 0:a1b58e3c9fdb | 464 | // 2. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 465 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 466 | // 2. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 467 | int result = read(_slaveAddress, i2cBuffer, 4); |
Yann | 0:a1b58e3c9fdb | 468 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 469 | if (p_mode == BigEndian) { |
Yann | 0:a1b58e3c9fdb | 470 | *p_int = (int)(i2cBuffer[0] << 24 | i2cBuffer[1] << 16 | i2cBuffer[2] << 8 | i2cBuffer[3]); |
Yann | 0:a1b58e3c9fdb | 471 | } else { |
Yann | 0:a1b58e3c9fdb | 472 | *p_int = (int)(i2cBuffer[3] << 24 | i2cBuffer[2] << 16 | i2cBuffer[1] << 8 | i2cBuffer[0]); |
Yann | 0:a1b58e3c9fdb | 473 | } |
Yann | 0:a1b58e3c9fdb | 474 | |
Yann | 0:a1b58e3c9fdb | 475 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 476 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 477 | } |
Yann | 0:a1b58e3c9fdb | 478 | |
Yann | 0:a1b58e3c9fdb | 479 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int) (false)") |
Yann | 0:a1b58e3c9fdb | 480 | return false; |
Yann | 0:a1b58e3c9fdb | 481 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 482 | |
Yann | 0:a1b58e3c9fdb | 483 | 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 | 484 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (vector): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write) |
Yann | 0:a1b58e3c9fdb | 485 | |
Yann | 0:a1b58e3c9fdb | 486 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 487 | unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 1:834e9897e269 | 488 | unsigned char length; |
Yann | 0:a1b58e3c9fdb | 489 | if (p_readLengthFirst) { |
Yann | 1:834e9897e269 | 490 | ReadMemory(address, (unsigned char *)&length); // Read the length in big endian mode |
Yann | 0:a1b58e3c9fdb | 491 | address += 1; // Skip the length value |
Yann | 0:a1b58e3c9fdb | 492 | length -= 1; // length is the size of (string length + string) |
Yann | 0:a1b58e3c9fdb | 493 | } else { |
Yann | 0:a1b58e3c9fdb | 494 | if (p_length2write == -1) { |
Yann | 0:a1b58e3c9fdb | 495 | length = p_datas.size(); |
Yann | 0:a1b58e3c9fdb | 496 | } else { |
Yann | 0:a1b58e3c9fdb | 497 | length = p_length2write; |
Yann | 0:a1b58e3c9fdb | 498 | } |
Yann | 0:a1b58e3c9fdb | 499 | } |
Yann | 0:a1b58e3c9fdb | 500 | |
Yann | 0:a1b58e3c9fdb | 501 | // 2. Memory address |
Yann | 0:a1b58e3c9fdb | 502 | char i2cBuffer[1]; |
Yann | 0:a1b58e3c9fdb | 503 | i2cBuffer[0] = address; |
Yann | 0:a1b58e3c9fdb | 504 | DEBUG("CDS130X_I2C::ReadMemory (vector): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 505 | |
Yann | 0:a1b58e3c9fdb | 506 | // 3. Send I2C start + memory address |
Yann | 0:a1b58e3c9fdb | 507 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 508 | // 4. read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 509 | unsigned char buffer[length]; |
Yann | 0:a1b58e3c9fdb | 510 | int result = read(_slaveAddress, (char *)buffer, length); |
Yann | 0:a1b58e3c9fdb | 511 | wait(0.02); |
Yann | 0:a1b58e3c9fdb | 512 | if (result == 0) { |
Yann | 0:a1b58e3c9fdb | 513 | p_datas.assign(buffer, buffer + length); |
Yann | 0:a1b58e3c9fdb | 514 | |
Yann | 0:a1b58e3c9fdb | 515 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector): %x", (bool)(result == 0)) |
Yann | 0:a1b58e3c9fdb | 516 | return (bool)(result == 0); |
Yann | 0:a1b58e3c9fdb | 517 | } |
Yann | 0:a1b58e3c9fdb | 518 | } |
Yann | 0:a1b58e3c9fdb | 519 | |
Yann | 0:a1b58e3c9fdb | 520 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector) (false)") |
Yann | 0:a1b58e3c9fdb | 521 | return false; |
Yann | 0:a1b58e3c9fdb | 522 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 523 | |
Yann | 0:a1b58e3c9fdb | 524 | bool CDS130X_I2C::ReadMemory(const unsigned char p_address, std::string & p_string, const bool p_readLengthFirst, const int p_length2write) { |
Yann | 1:834e9897e269 | 525 | DEBUG_ENTER("CDS130X_I2C::ReadMemory (string): Memory address:0x%02x, readLength:%x, Length:%d", p_address, p_readLengthFirst, p_length2write) |
Yann | 0:a1b58e3c9fdb | 526 | |
Yann | 0:a1b58e3c9fdb | 527 | // 1.Prepare buffer |
Yann | 0:a1b58e3c9fdb | 528 | unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address; |
Yann | 1:834e9897e269 | 529 | unsigned char length; |
Yann | 0:a1b58e3c9fdb | 530 | if (p_readLengthFirst) { // The string was stored with its length |
Yann | 1:834e9897e269 | 531 | if (!ReadMemory(p_address, (unsigned char *)&length)) { // Read the length in big endian mode |
Yann | 0:a1b58e3c9fdb | 532 | DEBUG_ERROR("CDS130X_I2C::ReadMemory (string): Failed to read length") |
Yann | 0:a1b58e3c9fdb | 533 | return false; |
Yann | 0:a1b58e3c9fdb | 534 | } |
Yann | 0:a1b58e3c9fdb | 535 | wait(0.02); |
Yann | 1:834e9897e269 | 536 | address += 1; // Skip the length value size |
Yann | 1:834e9897e269 | 537 | length -= 1; // length is the size of (string length + string) |
Yann | 0:a1b58e3c9fdb | 538 | } else { // The string length is provided by p_length2write parameter |
Yann | 0:a1b58e3c9fdb | 539 | if (p_length2write == -1) { |
Yann | 0:a1b58e3c9fdb | 540 | length = p_string.size(); |
Yann | 0:a1b58e3c9fdb | 541 | } else { |
Yann | 0:a1b58e3c9fdb | 542 | length = p_length2write; |
Yann | 0:a1b58e3c9fdb | 543 | p_string.resize(p_length2write); |
Yann | 0:a1b58e3c9fdb | 544 | } |
Yann | 0:a1b58e3c9fdb | 545 | } |
Yann | 0:a1b58e3c9fdb | 546 | DEBUG("CDS130X_I2C::ReadMemory (string): Length=%d", length) |
Yann | 0:a1b58e3c9fdb | 547 | |
Yann | 0:a1b58e3c9fdb | 548 | // 2. Memory address |
Yann | 1:834e9897e269 | 549 | char i2cBuffer[1]; |
Yann | 0:a1b58e3c9fdb | 550 | i2cBuffer[0] = address; |
Yann | 0:a1b58e3c9fdb | 551 | DEBUG("CDS130X_I2C::ReadMemory (string): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) |
Yann | 0:a1b58e3c9fdb | 552 | |
Yann | 0:a1b58e3c9fdb | 553 | // 3. Send I2C start + memory address |
Yann | 1:834e9897e269 | 554 | if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { |
Yann | 0:a1b58e3c9fdb | 555 | // 4. Read data + I2C stop |
Yann | 0:a1b58e3c9fdb | 556 | char buffer[length]; |
Yann | 0:a1b58e3c9fdb | 557 | int result = read(_slaveAddress, (char *)buffer, length); |
Yann | 0:a1b58e3c9fdb | 558 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string): %d", result) |
Yann | 0:a1b58e3c9fdb | 559 | if (result == 0) { |
Yann | 0:a1b58e3c9fdb | 560 | p_string.assign(buffer, length); |
Yann | 0:a1b58e3c9fdb | 561 | |
Yann | 0:a1b58e3c9fdb | 562 | return true; |
Yann | 0:a1b58e3c9fdb | 563 | } |
Yann | 0:a1b58e3c9fdb | 564 | } |
Yann | 0:a1b58e3c9fdb | 565 | |
Yann | 0:a1b58e3c9fdb | 566 | DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string) (false)") |
Yann | 0:a1b58e3c9fdb | 567 | return false; |
Yann | 0:a1b58e3c9fdb | 568 | } // End of method CDS130X_I2C::ReadMemory |
Yann | 0:a1b58e3c9fdb | 569 | |
Yann | 0:a1b58e3c9fdb | 570 | #if defined(__DEBUG) |
Yann | 0:a1b58e3c9fdb | 571 | void CDS130X_I2C::DumpMemoryArea(const unsigned char p_address, const int p_count) { |
Yann | 0:a1b58e3c9fdb | 572 | DEBUG_ENTER("CDS130X_I2C::DumpMemoryArea: %02x - %d", p_address, p_count) |
Yann | 0:a1b58e3c9fdb | 573 | |
Yann | 0:a1b58e3c9fdb | 574 | DEBUG("CDS130X_I2C::DumpMemoryArea: Reading datas..."); |
Yann | 0:a1b58e3c9fdb | 575 | std::vector<unsigned char> datas(p_count); |
Yann | 1:834e9897e269 | 576 | if (!ReadMemory(p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call |
Yann | 0:a1b58e3c9fdb | 577 | #ifdef __DEBUG |
Yann | 0:a1b58e3c9fdb | 578 | DEBUG_FATAL("CDS130X_I2C::DumpMemoryArea: read failed") |
Yann | 0:a1b58e3c9fdb | 579 | #else // __DEBUG |
Yann | 0:a1b58e3c9fdb | 580 | std::cout << "CDS130X_I2C::DumpMemoryArea: read failed\r" << std::endl |
Yann | 0:a1b58e3c9fdb | 581 | #endif // __DEBUG |
Yann | 0:a1b58e3c9fdb | 582 | } else { |
Yann | 0:a1b58e3c9fdb | 583 | std::cout << "CDS130X_I2C::DumpMemoryArea: Read bytes:\r" << std::endl; |
Yann | 0:a1b58e3c9fdb | 584 | HEXADUMP(&datas[0], p_count); |
Yann | 0:a1b58e3c9fdb | 585 | std::cout << "\r" << std::endl; |
Yann | 0:a1b58e3c9fdb | 586 | } |
Yann | 0:a1b58e3c9fdb | 587 | } // End of method CDS130X_I2C::DumpMemoryArea |
Yann | 0:a1b58e3c9fdb | 588 | #endif // _DEBUG |
Yann | 0:a1b58e3c9fdb | 589 | |
Yann | 0:a1b58e3c9fdb | 590 | } // End of namespace DS130X_I2C |