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
00001 #include <iostream> 00002 00003 #include "DS130x_I2C.h" 00004 00005 namespace DS130X_I2C { 00006 00007 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") { 00008 DEBUG_ENTER("CDS130X_I2C::CDS130X_I2C: %02x - %x - %d", p_slaveAddress, p_oscillatorMode, p_frequency) 00009 00010 _slaveAddress = p_slaveAddress; 00011 frequency(p_frequency); // Set the frequency of the I2C interface 00012 _oscillatorMode = p_oscillatorMode; 00013 _outputLevel = p_outputLevel; 00014 00015 DEBUG_LEAVE("CDS130X_I2C::CDS130X_I2C") 00016 } 00017 00018 CDS130X_I2C::~CDS130X_I2C() { 00019 DEBUG_ENTER("~CDS130X_I2C") 00020 00021 DEBUG_LEAVE("~CDS130X_I2C") 00022 } 00023 00024 bool CDS130X_I2C::Initialize() { 00025 DEBUG_ENTER("CDS130X_I2C::Initialize") 00026 00027 // 1. Set control register 00028 unsigned char controlRegisterValue = 0x00; 00029 switch (_oscillatorMode) { // See Datasheet - Clause CONTROL REGISTER 00030 case CDS130X_I2C::One_Hz: 00031 controlRegisterValue = 0x10; 00032 break; 00033 case CDS130X_I2C::Four_KHz: 00034 controlRegisterValue = 0x11; 00035 break; 00036 case CDS130X_I2C::Height_KHz: 00037 controlRegisterValue = 0x12; 00038 break; 00039 case CDS130X_I2C::ThirtyTwo_KHz: 00040 controlRegisterValue = 0x13; 00041 break; 00042 case CDS130X_I2C::Output: 00043 controlRegisterValue = (_outputLevel == true) ? 0x80 : 0x00; 00044 break; 00045 } // End of 'switch' statement 00046 DEBUG("CDS130X_I2C::Initialize: controlRegisterValue = 0x%02x", controlRegisterValue) 00047 // Write the control register 00048 if (!Write(CDS130X_I2C::ControlRegisterAddress, controlRegisterValue)) { 00049 DEBUG_ERROR("CDS130X_I2C::Initialize: I2C write operation failed") 00050 return false; 00051 } // else continue 00052 00053 // 2. Set the date format: Hours<6> set to 0 for 24-hour mode - See datasheet - Table 2. Timekeeper Registers 00054 DEBUG("CDS130X_I2C::Initialize: Set date format") 00055 // 1. Read hours 00056 unsigned char hoursRegister = 0xff; 00057 if (Read(CDS130X_I2C::HoursAddress, &hoursRegister)) { 00058 DEBUG("CDS130X_I2C::Initialize: hours:%x", hoursRegister) 00059 // 2. Set bit 6 to 0 00060 hoursRegister &= 0xbf; // 1011 1111 00061 // 3. Write new value 00062 if (!Write(CDS130X_I2C::HoursAddress, hoursRegister)) { 00063 DEBUG_ERROR("CDS130X_I2C::Initialize: Failed to set date format") 00064 } 00065 } else { 00066 DEBUG_ERROR("CDS130X_I2C::Initialize: Failed to set date format") 00067 } 00068 00069 // 3. Set CH bit is Seconds register - See Datasheet - Clause CLOCK AND CALENDAR 00070 bool result = ControlClock(true); 00071 00072 DEBUG_LEAVE("CDS130X_I2C::Initialize: %x", result) 00073 return result; 00074 } // End of method CDS130X_I2C::Initialize 00075 00076 bool CDS130X_I2C::RestartClock() { 00077 return ControlClock(true); 00078 } // End of method CDS130X_I2C::RestartClock 00079 00080 bool CDS130X_I2C::HaltClock() { 00081 return ControlClock(false); 00082 } // End of method CDS130X_I2C::HaltClock 00083 00084 bool CDS130X_I2C::ControlClock(bool p_mode) { 00085 DEBUG_ENTER("CDS130X_I2C::ControlClock") 00086 00087 // 1. Read seconds 00088 unsigned char secondsRegister = 0x00; 00089 if (Read(CDS130X_I2C::SecondsAddress, &secondsRegister)) { 00090 DEBUG("CDS130X_I2C::ControlClock: seconds register = 0x%02x", secondsRegister) 00091 // 2. Set bit 00092 if (!p_mode) { 00093 secondsRegister |= 0x80; // Set CH bit to halt oscilator 00094 } else { 00095 secondsRegister &= 0x7f; // Unset CH bit to restart oscilator 00096 } 00097 DEBUG("CDS130X_I2C::ControlClock: seconds register (new value) = 0x%02x - mode: %x", secondsRegister, p_mode) 00098 // 3. Write new value 00099 if (Write(CDS130X_I2C::SecondsAddress, secondsRegister)) { 00100 DEBUG_LEAVE("CDS130X_I2C::ControlClock (true)") 00101 return true; 00102 } 00103 00104 DEBUG_LEAVE("CDS130X_I2C::ControlClock (false)") 00105 return false; 00106 } 00107 00108 DEBUG_LEAVE("CDS130X_I2C::ControlClock (false)") 00109 return false; 00110 } // End of method CDS130X_I2C::ControlClock 00111 00112 bool CDS130X_I2C::Read(const RegisterEnum p_address, unsigned char * p_byte, const CDS130X_I2C::RegisterFormatEnum p_format) { 00113 DEBUG_ENTER("CDS130X_I2C::Read: %02x - %x", p_address, p_format) 00114 00115 // 1. Read seconds 00116 char i2cBuffer[1]; 00117 i2cBuffer[0] = (char)(unsigned char)p_address; 00118 // Send I2C start + memory address 00119 if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { 00120 // 2. Read data + I2C stop 00121 int result = read(_slaveAddress, (char *)p_byte, 1); 00122 wait(0.02); 00123 00124 // 3. Format convertion 00125 DEBUG_ENTER("CDS130X_I2C::Read: check %02x - %02x", p_format, Binary) 00126 if (p_format == CDS130X_I2C::Binary) { 00127 switch ((RegisterEnum)p_address) { 00128 case CDS130X_I2C::SecondsAddress: 00129 //No break; 00130 case CDS130X_I2C::MinutesAddress: 00131 *p_byte = ConvertBCDToHex(*p_byte & 0x7f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00132 break; 00133 case CDS130X_I2C::HoursAddress: 00134 //No break; 00135 case CDS130X_I2C::DayAddress: 00136 *p_byte = ConvertBCDToHex(*p_byte & 0x3f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00137 break; 00138 case CDS130X_I2C::DayOfWeekAddress: 00139 *p_byte = ConvertBCDToHex(*p_byte & 0x07); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00140 break; 00141 case CDS130X_I2C::MonthAddress: 00142 *p_byte = ConvertBCDToHex(*p_byte & 0x1f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00143 break; 00144 case CDS130X_I2C::YearAddress: 00145 *p_byte = ConvertBCDToHex(*p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00146 break; 00147 } // End of 'switch' statement 00148 } // else nothing to do 00149 00150 DEBUG_LEAVE("CDS130X_I2C::Read %d/%02x", (int)*p_byte, *p_byte) 00151 return true; 00152 } 00153 00154 DEBUG_LEAVE("CDS130X_I2C::Read (false)") 00155 return false; 00156 } // End of method CDS130X_I2C::Read 00157 00158 bool CDS130X_I2C::Write(const RegisterEnum p_address, const unsigned char p_byte, const CDS130X_I2C::RegisterFormatEnum p_format) { 00159 DEBUG_ENTER("CDS130X_I2C::Write: %02x - %d - %x", p_address, (int)p_byte, p_format) 00160 00161 // 1. Format convertion 00162 unsigned char value = p_byte; 00163 if (p_format == CDS130X_I2C::Binary) { 00164 switch ((RegisterEnum)p_address) { 00165 case CDS130X_I2C::SecondsAddress: 00166 //No break; 00167 case CDS130X_I2C::MinutesAddress: 00168 value = ConvertHexToBCD(p_byte) & 0x7f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00169 break; 00170 case CDS130X_I2C::HoursAddress: // Force Hours<6> set to 0 for 24-hour mode - See datasheet - Table 2. Timekeeper Registers 00171 //No break; 00172 case CDS130X_I2C::DayAddress: 00173 value = ConvertHexToBCD(p_byte) & 0x3f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00174 break; 00175 case CDS130X_I2C::DayOfWeekAddress: 00176 value = ConvertHexToBCD(p_byte) & 0x07; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00177 break; 00178 case CDS130X_I2C::MonthAddress: 00179 value = ConvertHexToBCD(p_byte) & 0x1f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00180 break; 00181 case CDS130X_I2C::YearAddress: 00182 value = ConvertHexToBCD(p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers 00183 break; 00184 } // End of 'switch' statement 00185 DEBUG("CDS130X_I2C::Write: Convert binary %d into bcd %02x", (int)p_byte, value) 00186 } // else nothing to do 00187 00188 // 2. Read seconds 00189 char i2cBuffer[2]; 00190 i2cBuffer[0] = (char)(unsigned char)p_address; 00191 i2cBuffer[1] = value; 00192 // Send I2C start + memory address 00193 if (write(_slaveAddress, i2cBuffer, 2) == 0) { 00194 wait(0.02); 00195 DEBUG_LEAVE("CDS130X_I2C::Write (true)") 00196 return true; 00197 } 00198 00199 DEBUG_LEAVE("CDS130X_I2C::Write (false)") 00200 return false; 00201 } // End of method CDS130X_I2C::Write 00202 00203 bool CDS130X_I2C::SetTime(const std::string p_utcTime) { 00204 DEBUG_ENTER("CDS130X_I2C::SetTime: %s - %d", p_utcTime.c_str(), p_utcTime.length()) 00205 00206 // Sanity checks 00207 if (p_utcTime.length() != 23) { 00208 DEBUG_ERROR("CDS130X_I2C::SetTime: Wrong parameters") 00209 return false; 00210 } 00211 // Fill struct tm; 00212 struct tm t = {0}; 00213 char wday[4] = {0}; 00214 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 */ 00215 wday, 00216 &t.tm_mon, 00217 &t.tm_mday, 00218 &t.tm_hour, 00219 &t.tm_min, 00220 &t.tm_sec, 00221 &t.tm_year); 00222 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); 00223 00224 t.tm_wday = (_dayOfWeek.find(wday) / 3) + 1; 00225 DEBUG("CDS130X_I2C::SetTime: wday=%s - _dayOfWeek:%s - tm_wday=%d", wday, _dayOfWeek.c_str(), t.tm_wday); 00226 00227 Write(CDS130X_I2C::SecondsAddress, t.tm_sec, CDS130X_I2C::Binary); 00228 Write(CDS130X_I2C::MinutesAddress, t.tm_min, CDS130X_I2C::Binary); 00229 Write(CDS130X_I2C::HoursAddress, t.tm_hour, CDS130X_I2C::Binary); 00230 Write(CDS130X_I2C::DayOfWeekAddress, t.tm_wday, CDS130X_I2C::Binary); 00231 Write(CDS130X_I2C::DayAddress, t.tm_mday, CDS130X_I2C::Binary); 00232 Write(CDS130X_I2C::MonthAddress, t.tm_mon, CDS130X_I2C::Binary); 00233 Write(CDS130X_I2C::YearAddress, t.tm_year - 1900, CDS130X_I2C::Binary); // Years since 1900: 2011 becomes 111 00234 00235 return true; 00236 } // End of method CDS130X_I2C::SetTime 00237 00238 struct tm CDS130X_I2C::GetTime() { 00239 DEBUG_ENTER("CDS130X_I2C::GetTime") 00240 00241 struct tm t = {0}; 00242 unsigned char value; 00243 // Setup time structure from RTC 00244 Read(CDS130X_I2C::SecondsAddress, &value, CDS130X_I2C::Binary); 00245 t.tm_sec = (int)value; 00246 Read(CDS130X_I2C::MinutesAddress, &value, CDS130X_I2C::Binary); 00247 t.tm_min = (int)value; 00248 Read(CDS130X_I2C::HoursAddress, &value, CDS130X_I2C::Binary); 00249 t.tm_hour = (int)value; 00250 Read(CDS130X_I2C::DayOfWeekAddress, &value, CDS130X_I2C::Binary); 00251 t.tm_wday = (int)value - 1; 00252 Read(CDS130X_I2C::DayAddress, &value, CDS130X_I2C::Binary); 00253 t.tm_mday = (int)value; 00254 Read(CDS130X_I2C::MonthAddress, &value, CDS130X_I2C::Binary); 00255 t.tm_mon = (int)value; 00256 Read(CDS130X_I2C::YearAddress, &value, CDS130X_I2C::Binary); 00257 t.tm_year = (int)value; // Years since 1900: 111 means 2011 00258 00259 DEBUG_LEAVE("CDS130X_I2C::GetTime") 00260 return t; 00261 } // End of method CDS130X_I2C::GetTime 00262 00263 bool CDS130X_I2C::EraseMemoryArea(const unsigned char p_startAddress, const int p_count, const unsigned char p_pattern) { 00264 DEBUG_ENTER("CDS130X_I2C::EraseMemoryArea): 0x%02x - %d - 0x%02x", p_startAddress, p_count, p_pattern) 00265 00266 std::vector<unsigned char> eraseBuffer(p_count, p_pattern); 00267 return WriteMemory(p_startAddress, eraseBuffer, false); 00268 } 00269 00270 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const unsigned char p_byte) { 00271 DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte): Memory address: 0x%02x", p_address) 00272 00273 // 1.Prepare buffer 00274 char i2cBuffer[2]; // Memory address + one byte of data 00275 // 1.1. Memory address 00276 i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; 00277 DEBUG("CDS130X_I2C::WriteMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00278 // 1.2. Datas 00279 i2cBuffer[1] = p_byte; 00280 DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x", i2cBuffer[1]) 00281 00282 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop 00283 int result = write(_slaveAddress, i2cBuffer, 2); 00284 wait(0.02); 00285 00286 DEBUG_LEAVE("CDS130X_I2C::WriteMemory (byte) %x", (bool)(result == 0)) 00287 return (bool)(result == 0); 00288 } // End of method CDS130X_I2C::WriteMemory 00289 00290 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const short p_short, const CDS130X_I2C::Mode p_mode) { 00291 DEBUG_ENTER("CDS130X_I2C::WriteMemory (short): Memory address:0x%02x, p_short:%04x, Mode:%d", p_address, p_short, p_mode) 00292 00293 // 1.Prepare buffer 00294 char i2cBuffer[3]; // Memory address + one short (2 bytes) 00295 // 1.1. Memory address 00296 i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; 00297 DEBUG("CDS130X_I2C::WriteMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00298 // 1.2. Datas 00299 if (p_mode == BigEndian) { 00300 i2cBuffer[1] = (unsigned char)(p_short >> 8); 00301 i2cBuffer[2] = (unsigned char)((unsigned char)p_short & 0xff); 00302 } else { 00303 i2cBuffer[1] = (unsigned char)((unsigned char)p_short & 0xff); 00304 i2cBuffer[2] = (unsigned char)(p_short >> 8); 00305 } 00306 DEBUG("CDS130X_I2C::WriteMemory (short): value=0x%02x%02x", i2cBuffer[1], i2cBuffer[2]) 00307 00308 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop 00309 int result = write(_slaveAddress, i2cBuffer, 3); 00310 wait(0.02); 00311 00312 DEBUG_LEAVE("CDS130X_I2C::WriteMemory (short) %x", (bool)(result == 0)) 00313 return (bool)(result == 0); 00314 } // End of method CDS130X_I2C::WriteMemory 00315 00316 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const int p_int, const CDS130X_I2C::Mode p_mode) { 00317 DEBUG_ENTER("CDS130X_I2C::WriteMemory (int): Memory address:0x%02x, p_int:%d, Mode:%d", p_address, p_int, p_mode) 00318 00319 // 1.Prepare buffer 00320 char i2cBuffer[5]; // Memory address + one integer (4 bytes) 00321 // 1.1. Memory address 00322 i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; 00323 DEBUG("CDS130X_I2C::WriteMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00324 // 1.2. Datas 00325 if (p_mode == BigEndian) { 00326 i2cBuffer[1] = (unsigned char)(p_int >> 24); 00327 i2cBuffer[2] = (unsigned char)(p_int >> 16); 00328 i2cBuffer[3] = (unsigned char)(p_int >> 8); 00329 i2cBuffer[4] = (unsigned char)((unsigned char)p_int & 0xff); 00330 } else { 00331 i2cBuffer[1] = (unsigned char)((unsigned char)p_int & 0xff); 00332 i2cBuffer[2] = (unsigned char)(p_int >> 8); 00333 i2cBuffer[3] = (unsigned char)(p_int >> 16); 00334 i2cBuffer[4] = (unsigned char)(p_int >> 24); 00335 } 00336 DEBUG("CDS130X_I2C::WriteMemory (int): value=0x%02x%02x%02x%02x", i2cBuffer[1], i2cBuffer[2], i2cBuffer[3], i2cBuffer[4]) 00337 00338 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop 00339 int result = write(_slaveAddress, i2cBuffer, 5); 00340 wait(0.02); 00341 00342 DEBUG_LEAVE("CDS130X_I2C::WriteMemory (int) %x", (bool)(result == 0)) 00343 return (bool)(result == 0); 00344 } // End of method CDS130X_I2C::WriteMemory 00345 00346 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const std::string & p_string, const bool p_storeLength, const int p_length2write) { 00347 DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::string)") 00348 return WriteMemory(p_address, p_string.c_str(), p_storeLength, p_length2write); 00349 } // End of method CDS130X_I2C::WriteMemory 00350 00351 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const std::vector<unsigned char> & p_datas, const bool p_storeLength, const int p_length2write) { 00352 DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::vector)") 00353 00354 int length = (p_length2write == -1) ? p_datas.size() : p_length2write; 00355 unsigned char array[length]; 00356 std::copy(p_datas.begin(), p_datas.end(), array); 00357 bool result = WriteMemory(p_address, array, p_storeLength, length); 00358 wait(0.02); 00359 00360 DEBUG_LEAVE("CDS130X_I2C::WriteMemory (std::vector): %d", result) 00361 return result; 00362 } // End of method CDS130X_I2C::WriteMemory 00363 00364 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const char *p_datas, const bool p_storeLength, const int p_length2write) { 00365 DEBUG_ENTER("CDS130X_I2C::WriteMemory (char *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write) 00366 00367 // 1.Prepare buffer 00368 int length = (p_length2write == -1) ? strlen(p_datas) : p_length2write; 00369 if (p_storeLength) { 00370 length += 1; // Add one byte for the length 00371 } 00372 DEBUG("CDS130X_I2C::WriteMemory (char *): length:%d", length) 00373 00374 char i2cBuffer[1 + length]; 00375 // 1.1. Memory address 00376 i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; 00377 DEBUG("CDS130X_I2C::WriteMemory (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00378 // 1.2. Datas 00379 if (p_storeLength) { 00380 // Fill the length 00381 i2cBuffer[1] = (unsigned char)length; 00382 for (int i = 0; i < length; i++) { 00383 i2cBuffer[2 + i] = *(p_datas + i); 00384 } 00385 } else { // The length was not stored 00386 for (int i = 0; i < length; i++) { 00387 i2cBuffer[1 + i] = *(p_datas + i); 00388 } 00389 } 00390 00391 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop 00392 int result = write(_slaveAddress, i2cBuffer, 1 + length); 00393 wait(0.02); 00394 00395 DEBUG_LEAVE("CDS130X_I2C::WriteMemory (char *) %x", (bool)(result == 0)) 00396 return (bool)(result == 0); 00397 } // End of method CDS130X_I2C::WriteMemory 00398 00399 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const unsigned char *p_datas, const bool p_storeLength, const int p_length2write) { 00400 DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte *): Memory address: 0x%02x", p_address, p_storeLength, p_length2write) 00401 return WriteMemory(p_address, (const char *)p_datas, p_storeLength, p_length2write); 00402 } // End of method CDS130X_I2C::WriteMemory 00403 00404 bool CDS130X_I2C::ReadMemory(const unsigned char p_address, unsigned char * p_byte) { 00405 DEBUG_ENTER("CDS130X_I2C::ReadMemory (byte): Memory address:0x%02x", p_address) 00406 00407 // 1.Prepare buffer 00408 char i2cBuffer[1]; 00409 // 1.1. Memory address 00410 i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; 00411 DEBUG("CDS130X_I2C::ReadMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00412 00413 // 2. Send I2C start + memory address 00414 if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { 00415 // 2. Read data + I2C stop 00416 int result = read(_slaveAddress, (char *)p_byte, 1); 00417 wait(0.02); 00418 00419 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte): %x", (bool)(result == 0)) 00420 return (bool)(result == 0); 00421 } 00422 00423 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte) (false)") 00424 return false; 00425 } // End of method CDS130X_I2C::ReadMemory 00426 00427 bool CDS130X_I2C::ReadMemory(const unsigned char p_address, short *p_short, const CDS130X_I2C::Mode p_mode) { 00428 DEBUG_ENTER("CDS130X_I2C::ReadMemory (short): Memory address:0x%02x, Mode:%d", p_address, p_mode) 00429 00430 // 1.Prepare buffer 00431 char i2cBuffer[2]; 00432 // 1.1. Memory address 00433 i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; 00434 DEBUG("CDS130X_I2C::ReadMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00435 00436 // 2. Send I2C start + memory address 00437 if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { 00438 // 2. Read data + I2C stop 00439 int result = read(_slaveAddress, i2cBuffer, 2); 00440 wait(0.02); 00441 if (p_mode == BigEndian) { 00442 *p_short = (short)(i2cBuffer[0] << 8 | i2cBuffer[1]); 00443 } else { 00444 *p_short = (short)(i2cBuffer[1] << 8 | i2cBuffer[0]); 00445 } 00446 00447 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short): %x", (bool)(result == 0)) 00448 return (bool)(result == 0); 00449 } 00450 00451 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short) (false)") 00452 return false; 00453 } // End of method CDS130X_I2C::ReadMemory 00454 00455 bool CDS130X_I2C::ReadMemory(const unsigned char p_address, int *p_int, const CDS130X_I2C::Mode p_mode) { 00456 DEBUG_ENTER("CDS130X_I2C::ReadMemory (int): Memory address:0x%02x, Mode:%d", p_address, p_mode) 00457 00458 // 1.Prepare buffer 00459 char i2cBuffer[4]; 00460 // 1.1. Memory address 00461 i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address; 00462 DEBUG("CDS130X_I2C::ReadMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00463 00464 // 2. Send I2C start + memory address 00465 if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { 00466 // 2. Read data + I2C stop 00467 int result = read(_slaveAddress, i2cBuffer, 4); 00468 wait(0.02); 00469 if (p_mode == BigEndian) { 00470 *p_int = (int)(i2cBuffer[0] << 24 | i2cBuffer[1] << 16 | i2cBuffer[2] << 8 | i2cBuffer[3]); 00471 } else { 00472 *p_int = (int)(i2cBuffer[3] << 24 | i2cBuffer[2] << 16 | i2cBuffer[1] << 8 | i2cBuffer[0]); 00473 } 00474 00475 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int): %x", (bool)(result == 0)) 00476 return (bool)(result == 0); 00477 } 00478 00479 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int) (false)") 00480 return false; 00481 } // End of method CDS130X_I2C::ReadMemory 00482 00483 bool CDS130X_I2C::ReadMemory(const unsigned char p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst, const int p_length2write) { 00484 DEBUG_ENTER("CDS130X_I2C::ReadMemory (vector): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write) 00485 00486 // 1.Prepare buffer 00487 unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address; 00488 unsigned char length; 00489 if (p_readLengthFirst) { 00490 ReadMemory(address, (unsigned char *)&length); // Read the length in big endian mode 00491 address += 1; // Skip the length value 00492 length -= 1; // length is the size of (string length + string) 00493 } else { 00494 if (p_length2write == -1) { 00495 length = p_datas.size(); 00496 } else { 00497 length = p_length2write; 00498 } 00499 } 00500 00501 // 2. Memory address 00502 char i2cBuffer[1]; 00503 i2cBuffer[0] = address; 00504 DEBUG("CDS130X_I2C::ReadMemory (vector): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00505 00506 // 3. Send I2C start + memory address 00507 if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { 00508 // 4. read data + I2C stop 00509 unsigned char buffer[length]; 00510 int result = read(_slaveAddress, (char *)buffer, length); 00511 wait(0.02); 00512 if (result == 0) { 00513 p_datas.assign(buffer, buffer + length); 00514 00515 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector): %x", (bool)(result == 0)) 00516 return (bool)(result == 0); 00517 } 00518 } 00519 00520 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector) (false)") 00521 return false; 00522 } // End of method CDS130X_I2C::ReadMemory 00523 00524 bool CDS130X_I2C::ReadMemory(const unsigned char p_address, std::string & p_string, const bool p_readLengthFirst, const int p_length2write) { 00525 DEBUG_ENTER("CDS130X_I2C::ReadMemory (string): Memory address:0x%02x, readLength:%x, Length:%d", p_address, p_readLengthFirst, p_length2write) 00526 00527 // 1.Prepare buffer 00528 unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address; 00529 unsigned char length; 00530 if (p_readLengthFirst) { // The string was stored with its length 00531 if (!ReadMemory(p_address, (unsigned char *)&length)) { // Read the length in big endian mode 00532 DEBUG_ERROR("CDS130X_I2C::ReadMemory (string): Failed to read length") 00533 return false; 00534 } 00535 wait(0.02); 00536 address += 1; // Skip the length value size 00537 length -= 1; // length is the size of (string length + string) 00538 } else { // The string length is provided by p_length2write parameter 00539 if (p_length2write == -1) { 00540 length = p_string.size(); 00541 } else { 00542 length = p_length2write; 00543 p_string.resize(p_length2write); 00544 } 00545 } 00546 DEBUG("CDS130X_I2C::ReadMemory (string): Length=%d", length) 00547 00548 // 2. Memory address 00549 char i2cBuffer[1]; 00550 i2cBuffer[0] = address; 00551 DEBUG("CDS130X_I2C::ReadMemory (string): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00552 00553 // 3. Send I2C start + memory address 00554 if (write(_slaveAddress, i2cBuffer, 1, true) == 0) { 00555 // 4. Read data + I2C stop 00556 char buffer[length]; 00557 int result = read(_slaveAddress, (char *)buffer, length); 00558 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string): %d", result) 00559 if (result == 0) { 00560 p_string.assign(buffer, length); 00561 00562 return true; 00563 } 00564 } 00565 00566 DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string) (false)") 00567 return false; 00568 } // End of method CDS130X_I2C::ReadMemory 00569 00570 #if defined(__DEBUG) 00571 void CDS130X_I2C::DumpMemoryArea(const unsigned char p_address, const int p_count) { 00572 DEBUG_ENTER("CDS130X_I2C::DumpMemoryArea: %02x - %d", p_address, p_count) 00573 00574 DEBUG("CDS130X_I2C::DumpMemoryArea: Reading datas..."); 00575 std::vector<unsigned char> datas(p_count); 00576 if (!ReadMemory(p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call 00577 #ifdef __DEBUG 00578 DEBUG_FATAL("CDS130X_I2C::DumpMemoryArea: read failed") 00579 #else // __DEBUG 00580 std::cout << "CDS130X_I2C::DumpMemoryArea: read failed\r" << std::endl 00581 #endif // __DEBUG 00582 } else { 00583 std::cout << "CDS130X_I2C::DumpMemoryArea: Read bytes:\r" << std::endl; 00584 HEXADUMP(&datas[0], p_count); 00585 std::cout << "\r" << std::endl; 00586 } 00587 } // End of method CDS130X_I2C::DumpMemoryArea 00588 #endif // _DEBUG 00589 00590 } // End of namespace DS130X_I2C
Generated on Wed Jul 13 2022 00:52:02 by
1.7.2
Yann Garcia