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.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS130x_I2C.cpp Source File

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