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.

Revision:
1:834e9897e269
Parent:
0:a1b58e3c9fdb
--- a/DS130x_I2C.cpp	Wed Feb 09 13:43:21 2011 +0000
+++ b/DS130x_I2C.cpp	Fri Feb 11 10:16:20 2011 +0000
@@ -54,12 +54,12 @@
     DEBUG("CDS130X_I2C::Initialize: Set date format")
     // 1. Read hours
     unsigned char hoursRegister = 0xff;
-    if (Read(CDS130X_I2C::HoursAddress, &hoursRegister) == (unsigned char)0) {
+    if (Read(CDS130X_I2C::HoursAddress, &hoursRegister)) {
         DEBUG("CDS130X_I2C::Initialize: hours:%x", hoursRegister)
         // 2. Set bit 6 to 0
         hoursRegister &= 0xbf; // 1011 1111
         // 3. Write new value
-        if (Write(CDS130X_I2C::HoursAddress, hoursRegister)) {
+        if (!Write(CDS130X_I2C::HoursAddress, hoursRegister)) {
             DEBUG_ERROR("CDS130X_I2C::Initialize: Failed to set date format")
         }
     } else {
@@ -110,7 +110,7 @@
 } // End of method CDS130X_I2C::ControlClock
 
 bool CDS130X_I2C::Read(const RegisterEnum p_address, unsigned char * p_byte, const CDS130X_I2C::RegisterFormatEnum p_format) {
-    DEBUG_ENTER("CDS130X_I2C::Read")
+    DEBUG_ENTER("CDS130X_I2C::Read: %02x - %x", p_address, p_format)
 
     // 1. Read seconds
     char i2cBuffer[1];
@@ -122,6 +122,7 @@
         wait(0.02);
 
         // 3. Format convertion
+        DEBUG_ENTER("CDS130X_I2C::Read: check %02x - %02x", p_format, Binary)
         if (p_format == CDS130X_I2C::Binary) {
             switch ((RegisterEnum)p_address) {
                 case CDS130X_I2C::SecondsAddress:
@@ -135,7 +136,7 @@
                     *p_byte = ConvertBCDToHex(*p_byte & 0x3f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
                     break;
                 case CDS130X_I2C::DayOfWeekAddress:
-                    *p_byte = ConvertBCDToHex(*p_byte & 0x03); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                    *p_byte = ConvertBCDToHex(*p_byte & 0x07); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
                     break;
                 case CDS130X_I2C::MonthAddress:
                     *p_byte = ConvertBCDToHex(*p_byte & 0x1f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
@@ -146,17 +147,16 @@
             } // End of 'switch' statement
         } // else nothing to do
 
-        DEBUG_LEAVE("CDS130X_I2C::Read %d", (int)*p_byte)
+        DEBUG_LEAVE("CDS130X_I2C::Read %d/%02x", (int)*p_byte, *p_byte)
         return true;
     }
 
-
     DEBUG_LEAVE("CDS130X_I2C::Read (false)")
     return false;
 } // End of method CDS130X_I2C::Read
 
 bool CDS130X_I2C::Write(const RegisterEnum p_address, const unsigned char p_byte, const CDS130X_I2C::RegisterFormatEnum p_format) {
-    DEBUG_ENTER("CDS130X_I2C::Write")
+    DEBUG_ENTER("CDS130X_I2C::Write: %02x - %d - %x", p_address, (int)p_byte, p_format)
 
     // 1. Format convertion
     unsigned char value = p_byte;
@@ -173,7 +173,7 @@
                 value = ConvertHexToBCD(p_byte) & 0x3f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
                 break;
             case CDS130X_I2C::DayOfWeekAddress:
-                value = ConvertHexToBCD(p_byte) & 0x03; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                value = ConvertHexToBCD(p_byte) & 0x07; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
                 break;
             case CDS130X_I2C::MonthAddress:
                 value = ConvertHexToBCD(p_byte) & 0x1f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
@@ -182,6 +182,7 @@
                 value = ConvertHexToBCD(p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
                 break;
         } // End of 'switch' statement
+        DEBUG("CDS130X_I2C::Write: Convert binary %d into bcd %02x", (int)p_byte, value)
     } // else nothing to do
 
     // 2. Read seconds
@@ -210,7 +211,7 @@
     // Fill struct tm;
     struct tm t = {0};
     char wday[4] = {0};
-    scanf("%s %02d %02d %02d:%02d:%02d %04d", /* Www MM dd hh:mm:ss yyyy */
+    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 */
           wday,
           &t.tm_mon,
           &t.tm_mday,
@@ -218,17 +219,18 @@
           &t.tm_min,
           &t.tm_sec,
           &t.tm_year);
+    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);
 
-    DEBUG("CDS130X_I2C::SetTime: wday=%s - tm_wday=%d", wday, _dayOfWeek.find_first_of(wday) / 3);
-    t.tm_wday = _dayOfWeek.find_first_of(wday) / 3;
+    t.tm_wday = (_dayOfWeek.find(wday) / 3) + 1;
+    DEBUG("CDS130X_I2C::SetTime: wday=%s - _dayOfWeek:%s - tm_wday=%d", wday, _dayOfWeek.c_str(), t.tm_wday);
 
-    Write(CDS130X_I2C::SecondsAddress, t.tm_sec, Binary);
-    Write(CDS130X_I2C::MinutesAddress, t.tm_min, Binary);
-    Write(CDS130X_I2C::HoursAddress, t.tm_hour, Binary);
-    Write(CDS130X_I2C::DayOfWeekAddress, t.tm_wday, Binary);
-    Write(CDS130X_I2C::DayAddress, t.tm_mday, Binary);
-    Write(CDS130X_I2C::MonthAddress, t.tm_mon, Binary);
-    Write(CDS130X_I2C::YearAddress, t.tm_year, Binary);
+    Write(CDS130X_I2C::SecondsAddress, t.tm_sec, CDS130X_I2C::Binary);
+    Write(CDS130X_I2C::MinutesAddress, t.tm_min, CDS130X_I2C::Binary);
+    Write(CDS130X_I2C::HoursAddress, t.tm_hour, CDS130X_I2C::Binary);
+    Write(CDS130X_I2C::DayOfWeekAddress, t.tm_wday, CDS130X_I2C::Binary);
+    Write(CDS130X_I2C::DayAddress, t.tm_mday, CDS130X_I2C::Binary);
+    Write(CDS130X_I2C::MonthAddress, t.tm_mon, CDS130X_I2C::Binary);
+    Write(CDS130X_I2C::YearAddress, t.tm_year - 1900, CDS130X_I2C::Binary); // Years since 1900: 2011 becomes 111
 
     return true;
 } // End of method CDS130X_I2C::SetTime
@@ -236,31 +238,23 @@
 struct tm CDS130X_I2C::GetTime() {
     DEBUG_ENTER("CDS130X_I2C::GetTime")
 
-    struct tm t;
+    struct tm t = {0};
     unsigned char value;
     // Setup time structure from RTC
-    Read(CDS130X_I2C::SecondsAddress, &value, Binary);
-    t.tm_sec = value;
-    Read(CDS130X_I2C::MinutesAddress, &value, Binary);
-    t.tm_min = value;
-    Read(CDS130X_I2C::HoursAddress, &value, Binary);
-    t.tm_hour = value;
-    Read(CDS130X_I2C::DayOfWeekAddress, &value, Binary);
-    t.tm_wday = value;
-    Read(CDS130X_I2C::DayAddress, &value, Binary);
-    t.tm_mday = value;
-    Read(CDS130X_I2C::MonthAddress, &value, Binary);
-    t.tm_mon = value;
-    Read(CDS130X_I2C::YearAddress, &value, Binary);
-    t.tm_year = value;
-    DEBUG("CDS130X_I2C::GetTime: %02d %02d %02d %02d:%02d:%02d %04d", /* ww mm dd hh:mm:ss yyyy */
-          t.tm_wday,
-          t.tm_mon,
-          t.tm_mday,
-          t.tm_hour,
-          t.tm_min,
-          t.tm_sec,
-          t.tm_year);
+    Read(CDS130X_I2C::SecondsAddress, &value, CDS130X_I2C::Binary);
+    t.tm_sec = (int)value;
+    Read(CDS130X_I2C::MinutesAddress, &value, CDS130X_I2C::Binary);
+    t.tm_min = (int)value;
+    Read(CDS130X_I2C::HoursAddress, &value, CDS130X_I2C::Binary);
+    t.tm_hour = (int)value;
+    Read(CDS130X_I2C::DayOfWeekAddress, &value, CDS130X_I2C::Binary);
+    t.tm_wday = (int)value - 1;
+    Read(CDS130X_I2C::DayAddress, &value, CDS130X_I2C::Binary);
+    t.tm_mday = (int)value;
+    Read(CDS130X_I2C::MonthAddress, &value, CDS130X_I2C::Binary);
+    t.tm_mon = (int)value;
+    Read(CDS130X_I2C::YearAddress, &value, CDS130X_I2C::Binary);
+    t.tm_year = (int)value; // Years since 1900: 111 means 2011
 
     DEBUG_LEAVE("CDS130X_I2C::GetTime")
     return t;
@@ -294,7 +288,7 @@
 } // End of method CDS130X_I2C::WriteMemory
 
 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const short p_short, const CDS130X_I2C::Mode p_mode) {
-    DEBUG_ENTER("CDS130X_I2C::WriteMemory (short): Memory address:0x%02x, Mode:%d", p_address, p_mode)
+    DEBUG_ENTER("CDS130X_I2C::WriteMemory (short): Memory address:0x%02x, p_short:%04x, Mode:%d", p_address, p_short, p_mode)
 
     // 1.Prepare buffer
     char i2cBuffer[3]; // Memory address + one short (2 bytes)
@@ -309,7 +303,7 @@
         i2cBuffer[1] = (unsigned char)((unsigned char)p_short & 0xff);
         i2cBuffer[2] = (unsigned char)(p_short >> 8);
     }
-    DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x%02x", i2cBuffer[1], i2cBuffer[2])
+    DEBUG("CDS130X_I2C::WriteMemory (short): value=0x%02x%02x", i2cBuffer[1], i2cBuffer[2])
 
     // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
     int result = write(_slaveAddress, i2cBuffer, 3);
@@ -320,7 +314,7 @@
 } // End of method CDS130X_I2C::WriteMemory
 
 bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const int p_int, const CDS130X_I2C::Mode p_mode) {
-    DEBUG_ENTER("CDS130X_I2C::WriteMemory (int): Memory address:0x%02x, Mode:%d", p_address, p_mode)
+    DEBUG_ENTER("CDS130X_I2C::WriteMemory (int): Memory address:0x%02x, p_int:%d, Mode:%d", p_address, p_int, p_mode)
 
     // 1.Prepare buffer
     char i2cBuffer[5]; // Memory address + one integer (4 bytes)
@@ -339,7 +333,7 @@
         i2cBuffer[3] = (unsigned char)(p_int >> 16);
         i2cBuffer[4] = (unsigned char)(p_int >> 24);
     }
-    DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x%02x%02x%02x", i2cBuffer[1], i2cBuffer[2], i2cBuffer[3], i2cBuffer[4])
+    DEBUG("CDS130X_I2C::WriteMemory (int): value=0x%02x%02x%02x%02x", i2cBuffer[1], i2cBuffer[2], i2cBuffer[3], i2cBuffer[4])
 
     // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
     int result = write(_slaveAddress, i2cBuffer, 5);
@@ -491,9 +485,9 @@
 
     // 1.Prepare buffer
     unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address;
-    int length;
+    unsigned char length;
     if (p_readLengthFirst) {
-        ReadMemory(address, &length); // Read the length in big endian mode
+        ReadMemory(address, (unsigned char *)&length); // Read the length in big endian mode
         address += 1; // Skip the length value
         length -= 1; // length is the size of (string length + string)
     } else {
@@ -528,19 +522,19 @@
 } // End of method CDS130X_I2C::ReadMemory
 
 bool CDS130X_I2C::ReadMemory(const unsigned char p_address, std::string & p_string, const bool p_readLengthFirst, const int p_length2write) {
-    DEBUG_ENTER("CDS130X_I2C::ReadMemory (string): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write)
+    DEBUG_ENTER("CDS130X_I2C::ReadMemory (string): Memory address:0x%02x, readLength:%x, Length:%d", p_address, p_readLengthFirst, p_length2write)
 
     // 1.Prepare buffer
     unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address;
-    int length;
+    unsigned char length;
     if (p_readLengthFirst) { // The string was stored with its length
-        if (!ReadMemory(address, &length)) { // Read the length in big endian mode
+        if (!ReadMemory(p_address, (unsigned char *)&length)) { // Read the length in big endian mode
             DEBUG_ERROR("CDS130X_I2C::ReadMemory (string): Failed to read length")
             return false;
         }
         wait(0.02);
-        address += 4; // Skip the length value size
-        length -= 4; // length is the size of (string length + string)
+        address += 1; // Skip the length value size
+        length -= 1; // length is the size of (string length + string)
     } else { // The string length is provided by p_length2write parameter
         if (p_length2write == -1) {
             length = p_string.size();
@@ -552,14 +546,12 @@
     DEBUG("CDS130X_I2C::ReadMemory (string): Length=%d", length)
 
     // 2. Memory address
-    char i2cBuffer[2];
+    char i2cBuffer[1];
     i2cBuffer[0] = address;
     DEBUG("CDS130X_I2C::ReadMemory (string): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
-    i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
-    DEBUG("CDS130X_I2C::ReadMemory (string): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
 
     // 3. Send I2C start + memory address
-    if (write(_slaveAddress, i2cBuffer, 2, true) == 0) {
+    if (write(_slaveAddress, i2cBuffer, 1, true) == 0) {
         // 4. Read data + I2C stop
         char buffer[length];
         int result = read(_slaveAddress, (char *)buffer, length);
@@ -581,7 +573,7 @@
 
     DEBUG("CDS130X_I2C::DumpMemoryArea: Reading datas...");
     std::vector<unsigned char> datas(p_count);
-    if (!ReadMemory((unsigned char)CDS130X_I2C::BaseMemoryAddress + p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call
+    if (!ReadMemory(p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call
 #ifdef __DEBUG
         DEBUG_FATAL("CDS130X_I2C::DumpMemoryArea: read failed")
 #else // __DEBUG