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, committed 2011-02-11
- Comitter:
- Yann
- Date:
- Fri Feb 11 10:16:20 2011 +0000
- Parent:
- 0:a1b58e3c9fdb
- Commit message:
- V0.0.0.2
Changed in this revision
DS130x_I2C.cpp | Show annotated file Show diff for this revision Revisions of this file |
DS130x_I2C.h | Show annotated file Show diff for this revision Revisions of this file |
--- 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
--- a/DS130x_I2C.h Wed Feb 09 13:43:21 2011 +0000 +++ b/DS130x_I2C.h Fri Feb 11 10:16:20 2011 +0000 @@ -29,7 +29,7 @@ #include "Debug.h" // Include mbed header + debug primitives. See DebugLibrary namespace DS130X_I2C { - /** This class provides simplified I2C access to a MAXIM DS130x Real-Time Clock device. V0.0.0.1 + /** This class provides simplified I2C access to a MAXIM DS130x Real-Time Clock device. V0.0.0.2 * * A typical use case should be the Mbed which acts as a time server with an ethernet connection, it synchronyzes a RTC circuit for all other module (Microchip/ATiny MCUs). * @@ -143,7 +143,16 @@ * @return The packed BCD value */ inline unsigned char ConvertBCDToHex(const unsigned char p_bcdValue) { - return (unsigned char)((unsigned char)(p_bcdValue >> 4) * 10) + (unsigned char)(p_bcdValue & 0x0f); + /*DEBUG("ConvertBCDToHex: %02x - %02x - %02x - %02x - %d", + p_bcdValue, + (unsigned char)(p_bcdValue >> 4), + (unsigned char)((unsigned char)(p_bcdValue >> 4) * 10), + (unsigned char)(p_bcdValue & 0x0f), + (int)( + (unsigned char)((unsigned char)(p_bcdValue >> 4) * 10) | (unsigned char)(p_bcdValue & 0x0f) + ) + )*/ + return (unsigned char)((unsigned char)(p_bcdValue >> 4) * 10) | (unsigned char)(p_bcdValue & 0x0f); } /** This methods converts an hexadecimal value < 99 into a packed BCD (e.g. 0x20 -> 0x32) @@ -152,7 +161,8 @@ * @return The packed BCD value */ inline unsigned char ConvertHexToBCD(const unsigned char p_hexaValue) { - return (p_hexaValue / 10) << 4 + (p_hexaValue % 10); + //DEBUG("ConvertHexToBCD: %02x - %02x - %02x", p_hexaValue, (unsigned char)(p_hexaValue / 10 << 4), (unsigned char)(p_hexaValue % 10)) + return (unsigned char)(p_hexaValue / 10 << 4) | (unsigned char)(p_hexaValue % 10); } /** Restart the clock