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.

Files at this revision

API Documentation at this revision

Comitter:
Yann
Date:
Wed Feb 09 13:43:21 2011 +0000
Child:
1:834e9897e269
Commit message:
V0.0.0.1

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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS130x_I2C.cpp	Wed Feb 09 13:43:21 2011 +0000
@@ -0,0 +1,598 @@
+#include <iostream>
+
+#include "DS130x_I2C.h"
+
+namespace DS130X_I2C {
+
+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") {
+    DEBUG_ENTER("CDS130X_I2C::CDS130X_I2C: %02x - %x - %d", p_slaveAddress, p_oscillatorMode, p_frequency)
+
+    _slaveAddress = p_slaveAddress;
+    frequency(p_frequency); // Set the frequency of the I2C interface
+    _oscillatorMode = p_oscillatorMode;
+    _outputLevel = p_outputLevel;
+
+    DEBUG_LEAVE("CDS130X_I2C::CDS130X_I2C")
+}
+
+CDS130X_I2C::~CDS130X_I2C() {
+    DEBUG_ENTER("~CDS130X_I2C")
+
+    DEBUG_LEAVE("~CDS130X_I2C")
+}
+
+bool CDS130X_I2C::Initialize() {
+    DEBUG_ENTER("CDS130X_I2C::Initialize")
+
+    // 1. Set control register
+    unsigned char controlRegisterValue = 0x00;
+    switch (_oscillatorMode) { // See Datasheet - Clause CONTROL REGISTER
+        case CDS130X_I2C::One_Hz:
+            controlRegisterValue = 0x10;
+            break;
+        case CDS130X_I2C::Four_KHz:
+            controlRegisterValue = 0x11;
+            break;
+        case CDS130X_I2C::Height_KHz:
+            controlRegisterValue = 0x12;
+            break;
+        case CDS130X_I2C::ThirtyTwo_KHz:
+            controlRegisterValue = 0x13;
+            break;
+        case CDS130X_I2C::Output:
+            controlRegisterValue = (_outputLevel == true) ? 0x80 : 0x00;
+            break;
+    } // End of 'switch' statement
+    DEBUG("CDS130X_I2C::Initialize: controlRegisterValue = 0x%02x", controlRegisterValue)
+    // Write the control register
+    if (!Write(CDS130X_I2C::ControlRegisterAddress, controlRegisterValue)) {
+        DEBUG_ERROR("CDS130X_I2C::Initialize: I2C write operation failed")
+        return false;
+    } // else continue
+
+    // 2. Set the date format: Hours<6> set to 0 for 24-hour mode - See datasheet - Table 2. Timekeeper Registers
+    DEBUG("CDS130X_I2C::Initialize: Set date format")
+    // 1. Read hours
+    unsigned char hoursRegister = 0xff;
+    if (Read(CDS130X_I2C::HoursAddress, &hoursRegister) == (unsigned char)0) {
+        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)) {
+            DEBUG_ERROR("CDS130X_I2C::Initialize: Failed to set date format")
+        }
+    } else {
+        DEBUG_ERROR("CDS130X_I2C::Initialize: Failed to set date format")
+    }
+
+    // 3. Set CH bit is Seconds register - See Datasheet - Clause CLOCK AND CALENDAR
+    bool result = ControlClock(true);
+
+    DEBUG_LEAVE("CDS130X_I2C::Initialize: %x", result)
+    return result;
+} // End of method CDS130X_I2C::Initialize
+
+bool CDS130X_I2C::RestartClock() {
+    return ControlClock(true);
+} // End of method CDS130X_I2C::RestartClock
+
+bool CDS130X_I2C::HaltClock() {
+    return ControlClock(false);
+} // End of method CDS130X_I2C::HaltClock
+
+bool CDS130X_I2C::ControlClock(bool p_mode) {
+    DEBUG_ENTER("CDS130X_I2C::ControlClock")
+
+    // 1. Read seconds
+    unsigned char secondsRegister = 0x00;
+    if (Read(CDS130X_I2C::SecondsAddress, &secondsRegister)) {
+        DEBUG("CDS130X_I2C::ControlClock: seconds register = 0x%02x", secondsRegister)
+        // 2. Set bit
+        if (!p_mode) {
+            secondsRegister |= 0x80; // Set CH bit to halt oscilator
+        } else {
+            secondsRegister &= 0x7f; // Unset CH bit to restart oscilator
+        }
+        DEBUG("CDS130X_I2C::ControlClock: seconds register (new value) = 0x%02x - mode: %x", secondsRegister, p_mode)
+        // 3. Write new value
+        if (Write(CDS130X_I2C::SecondsAddress, secondsRegister)) {
+            DEBUG_LEAVE("CDS130X_I2C::ControlClock (true)")
+            return true;
+        }
+
+        DEBUG_LEAVE("CDS130X_I2C::ControlClock (false)")
+        return false;
+    }
+
+    DEBUG_LEAVE("CDS130X_I2C::ControlClock (false)")
+    return false;
+} // 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")
+
+    // 1. Read seconds
+    char i2cBuffer[1];
+    i2cBuffer[0] = (char)(unsigned char)p_address;
+    // Send I2C start + memory address
+    if (write(_slaveAddress, i2cBuffer, 1, true) == 0) {
+        // 2. Read data + I2C stop
+        int result = read(_slaveAddress, (char *)p_byte, 1);
+        wait(0.02);
+
+        // 3. Format convertion
+        if (p_format == CDS130X_I2C::Binary) {
+            switch ((RegisterEnum)p_address) {
+                case CDS130X_I2C::SecondsAddress:
+                    //No break;
+                case CDS130X_I2C::MinutesAddress:
+                    *p_byte = ConvertBCDToHex(*p_byte & 0x7f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                    break;
+                case CDS130X_I2C::HoursAddress:
+                    //No break;
+                case CDS130X_I2C::DayAddress:
+                    *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
+                    break;
+                case CDS130X_I2C::MonthAddress:
+                    *p_byte = ConvertBCDToHex(*p_byte & 0x1f); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                    break;
+                case CDS130X_I2C::YearAddress:
+                    *p_byte = ConvertBCDToHex(*p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                    break;
+            } // End of 'switch' statement
+        } // else nothing to do
+
+        DEBUG_LEAVE("CDS130X_I2C::Read %d", (int)*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")
+
+    // 1. Format convertion
+    unsigned char value = p_byte;
+    if (p_format == CDS130X_I2C::Binary) {
+        switch ((RegisterEnum)p_address) {
+            case CDS130X_I2C::SecondsAddress:
+                //No break;
+            case CDS130X_I2C::MinutesAddress:
+                value = ConvertHexToBCD(p_byte) & 0x7f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                break;
+            case CDS130X_I2C::HoursAddress: // Force Hours<6> set to 0 for 24-hour mode - See datasheet - Table 2. Timekeeper Registers
+                //No break;
+            case CDS130X_I2C::DayAddress:
+                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
+                break;
+            case CDS130X_I2C::MonthAddress:
+                value = ConvertHexToBCD(p_byte) & 0x1f; // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                break;
+            case CDS130X_I2C::YearAddress:
+                value = ConvertHexToBCD(p_byte); // Convert hex to BCD - See datasheet - Table 2. Timekeeper Registers
+                break;
+        } // End of 'switch' statement
+    } // else nothing to do
+
+    // 2. Read seconds
+    char i2cBuffer[2];
+    i2cBuffer[0] = (char)(unsigned char)p_address;
+    i2cBuffer[1] = value;
+    // Send I2C start + memory address
+    if (write(_slaveAddress, i2cBuffer, 2) == 0) {
+        wait(0.02);
+        DEBUG_LEAVE("CDS130X_I2C::Write (true)")
+        return true;
+    }
+
+    DEBUG_LEAVE("CDS130X_I2C::Write (false)")
+    return false;
+} // End of method CDS130X_I2C::Write
+
+bool CDS130X_I2C::SetTime(const std::string p_utcTime) {
+    DEBUG_ENTER("CDS130X_I2C::SetTime: %s - %d", p_utcTime.c_str(), p_utcTime.length())
+
+    // Sanity checks
+    if (p_utcTime.length() != 23) {
+        DEBUG_ERROR("CDS130X_I2C::SetTime: Wrong parameters")
+        return false;
+    }
+    // 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 */
+          wday,
+          &t.tm_mon,
+          &t.tm_mday,
+          &t.tm_hour,
+          &t.tm_min,
+          &t.tm_sec,
+          &t.tm_year);
+
+    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;
+
+    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);
+
+    return true;
+} // End of method CDS130X_I2C::SetTime
+
+struct tm CDS130X_I2C::GetTime() {
+    DEBUG_ENTER("CDS130X_I2C::GetTime")
+
+    struct tm t;
+    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);
+
+    DEBUG_LEAVE("CDS130X_I2C::GetTime")
+    return t;
+} // End of method CDS130X_I2C::GetTime
+
+bool CDS130X_I2C::EraseMemoryArea(const unsigned char p_startAddress, const int p_count, const unsigned char p_pattern) {
+    DEBUG_ENTER("CDS130X_I2C::EraseMemoryArea): 0x%02x - %d - 0x%02x", p_startAddress, p_count, p_pattern)
+
+    std::vector<unsigned char> eraseBuffer(p_count, p_pattern);
+    return WriteMemory(p_startAddress, eraseBuffer, false);
+}
+
+bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const unsigned char p_byte) {
+    DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte): Memory address: 0x%02x", p_address)
+
+    // 1.Prepare buffer
+    char i2cBuffer[2]; // Memory address + one byte of data
+    // 1.1. Memory address
+    i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address;
+    DEBUG("CDS130X_I2C::WriteMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+    // 1.2. Datas
+    i2cBuffer[1] = p_byte;
+    DEBUG("CDS130X_I2C::WriteMemory (byte): value=0x%02x", i2cBuffer[1])
+
+    // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
+    int result = write(_slaveAddress, i2cBuffer, 2);
+    wait(0.02);
+
+    DEBUG_LEAVE("CDS130X_I2C::WriteMemory (byte) %x", (bool)(result == 0))
+    return (bool)(result == 0);
+} // 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)
+
+    // 1.Prepare buffer
+    char i2cBuffer[3]; // Memory address + one short (2 bytes)
+    // 1.1. Memory address
+    i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address;
+    DEBUG("CDS130X_I2C::WriteMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+    // 1.2. Datas
+    if (p_mode == BigEndian) {
+        i2cBuffer[1] = (unsigned char)(p_short >> 8);
+        i2cBuffer[2] = (unsigned char)((unsigned char)p_short & 0xff);
+    } else {
+        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])
+
+    // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
+    int result = write(_slaveAddress, i2cBuffer, 3);
+    wait(0.02);
+
+    DEBUG_LEAVE("CDS130X_I2C::WriteMemory (short) %x", (bool)(result == 0))
+    return (bool)(result == 0);
+} // 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)
+
+    // 1.Prepare buffer
+    char i2cBuffer[5]; // Memory address + one integer (4 bytes)
+    // 1.1. Memory address
+    i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address;
+    DEBUG("CDS130X_I2C::WriteMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+    // 1.2. Datas
+    if (p_mode == BigEndian) {
+        i2cBuffer[1] = (unsigned char)(p_int >> 24);
+        i2cBuffer[2] = (unsigned char)(p_int >> 16);
+        i2cBuffer[3] = (unsigned char)(p_int >> 8);
+        i2cBuffer[4] = (unsigned char)((unsigned char)p_int & 0xff);
+    } else {
+        i2cBuffer[1] = (unsigned char)((unsigned char)p_int & 0xff);
+        i2cBuffer[2] = (unsigned char)(p_int >> 8);
+        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])
+
+    // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
+    int result = write(_slaveAddress, i2cBuffer, 5);
+    wait(0.02);
+
+    DEBUG_LEAVE("CDS130X_I2C::WriteMemory (int) %x", (bool)(result == 0))
+    return (bool)(result == 0);
+} // End of method CDS130X_I2C::WriteMemory
+
+bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const std::string & p_string, const bool p_storeLength, const int p_length2write) {
+    DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::string)")
+    return WriteMemory(p_address, p_string.c_str(), p_storeLength, p_length2write);
+} // End of method CDS130X_I2C::WriteMemory
+
+bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const std::vector<unsigned char> & p_datas, const bool p_storeLength, const int p_length2write) {
+    DEBUG_ENTER("CDS130X_I2C::WriteMemory (std::vector)")
+
+    int length = (p_length2write == -1) ? p_datas.size() : p_length2write;
+    unsigned char array[length];
+    std::copy(p_datas.begin(), p_datas.end(), array);
+    bool result = WriteMemory(p_address, array, p_storeLength, length);
+    wait(0.02);
+
+    DEBUG_LEAVE("CDS130X_I2C::WriteMemory (std::vector): %d", result)
+    return result;
+} // End of method CDS130X_I2C::WriteMemory
+
+bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const char *p_datas, const bool p_storeLength, const int p_length2write) {
+    DEBUG_ENTER("CDS130X_I2C::WriteMemory (char *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write)
+
+    // 1.Prepare buffer
+    int length = (p_length2write == -1) ? strlen(p_datas) : p_length2write;
+    if (p_storeLength) {
+        length += 1; // Add one byte for the length
+    }
+    DEBUG("CDS130X_I2C::WriteMemory (char *): length:%d", length)
+
+    char i2cBuffer[1 + length];
+    // 1.1. Memory address
+    i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address;
+    DEBUG("CDS130X_I2C::WriteMemory (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+    // 1.2. Datas
+    if (p_storeLength) {
+        // Fill the length
+        i2cBuffer[1] = (unsigned char)length;
+        for (int i = 0; i < length; i++) {
+            i2cBuffer[2 + i] = *(p_datas + i);
+        }
+    } else { // The length was not stored
+        for (int i = 0; i < length; i++) {
+            i2cBuffer[1 + i] = *(p_datas + i);
+        }
+    }
+
+    // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
+    int result = write(_slaveAddress, i2cBuffer, 1 + length);
+    wait(0.02);
+
+    DEBUG_LEAVE("CDS130X_I2C::WriteMemory (char *) %x", (bool)(result == 0))
+    return (bool)(result == 0);
+} // End of method CDS130X_I2C::WriteMemory
+
+bool CDS130X_I2C::WriteMemory(const unsigned char p_address, const unsigned char *p_datas, const bool p_storeLength, const int p_length2write) {
+    DEBUG_ENTER("CDS130X_I2C::WriteMemory (byte *): Memory address: 0x%02x", p_address, p_storeLength, p_length2write)
+    return WriteMemory(p_address, (const char *)p_datas, p_storeLength, p_length2write);
+} // End of method CDS130X_I2C::WriteMemory
+
+bool CDS130X_I2C::ReadMemory(const unsigned char p_address, unsigned char * p_byte) {
+    DEBUG_ENTER("CDS130X_I2C::ReadMemory (byte): Memory address:0x%02x", p_address)
+
+    // 1.Prepare buffer
+    char i2cBuffer[1];
+    // 1.1. Memory address
+    i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address;
+    DEBUG("CDS130X_I2C::ReadMemory (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+
+    // 2. Send I2C start + memory address
+    if (write(_slaveAddress, i2cBuffer, 1, true) == 0) {
+        // 2. Read data + I2C stop
+        int result = read(_slaveAddress, (char *)p_byte, 1);
+        wait(0.02);
+
+        DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte): %x", (bool)(result == 0))
+        return (bool)(result == 0);
+    }
+
+    DEBUG_LEAVE("CDS130X_I2C::ReadMemory (byte) (false)")
+    return false;
+} // End of method CDS130X_I2C::ReadMemory
+
+bool CDS130X_I2C::ReadMemory(const unsigned char p_address, short *p_short, const CDS130X_I2C::Mode p_mode) {
+    DEBUG_ENTER("CDS130X_I2C::ReadMemory (short): Memory address:0x%02x, Mode:%d", p_address, p_mode)
+
+    // 1.Prepare buffer
+    char i2cBuffer[2];
+    // 1.1. Memory address
+    i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address;
+    DEBUG("CDS130X_I2C::ReadMemory (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+
+    // 2. Send I2C start + memory address
+    if (write(_slaveAddress, i2cBuffer, 1, true) == 0) {
+        // 2. Read data + I2C stop
+        int result = read(_slaveAddress, i2cBuffer, 2);
+        wait(0.02);
+        if (p_mode ==  BigEndian) {
+            *p_short = (short)(i2cBuffer[0] << 8 | i2cBuffer[1]);
+        } else {
+            *p_short = (short)(i2cBuffer[1] << 8 | i2cBuffer[0]);
+        }
+
+        DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short): %x", (bool)(result == 0))
+        return (bool)(result == 0);
+    }
+
+    DEBUG_LEAVE("CDS130X_I2C::ReadMemory (short) (false)")
+    return false;
+} // End of method CDS130X_I2C::ReadMemory
+
+bool CDS130X_I2C::ReadMemory(const unsigned char p_address, int *p_int, const CDS130X_I2C::Mode p_mode) {
+    DEBUG_ENTER("CDS130X_I2C::ReadMemory (int): Memory address:0x%02x, Mode:%d", p_address, p_mode)
+
+    // 1.Prepare buffer
+    char i2cBuffer[4];
+    // 1.1. Memory address
+    i2cBuffer[0] = CDS130X_I2C::BaseMemoryAddress + p_address;
+    DEBUG("CDS130X_I2C::ReadMemory (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+
+    // 2. Send I2C start + memory address
+    if (write(_slaveAddress, i2cBuffer, 1, true) == 0) {
+        // 2. Read data + I2C stop
+        int result = read(_slaveAddress, i2cBuffer, 4);
+        wait(0.02);
+        if (p_mode ==  BigEndian) {
+            *p_int = (int)(i2cBuffer[0] << 24 | i2cBuffer[1] << 16 | i2cBuffer[2] << 8 | i2cBuffer[3]);
+        } else {
+            *p_int = (int)(i2cBuffer[3] << 24 | i2cBuffer[2] << 16 | i2cBuffer[1] << 8 | i2cBuffer[0]);
+        }
+
+        DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int): %x", (bool)(result == 0))
+        return (bool)(result == 0);
+    }
+
+    DEBUG_LEAVE("CDS130X_I2C::ReadMemory (int) (false)")
+    return false;
+} // End of method CDS130X_I2C::ReadMemory
+
+bool CDS130X_I2C::ReadMemory(const unsigned char p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst, const int p_length2write) {
+    DEBUG_ENTER("CDS130X_I2C::ReadMemory (vector): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write)
+
+    // 1.Prepare buffer
+    unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address;
+    int length;
+    if (p_readLengthFirst) {
+        ReadMemory(address, &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 {
+        if (p_length2write == -1) {
+            length = p_datas.size();
+        } else {
+            length = p_length2write;
+        }
+    }
+
+    // 2. Memory address
+    char i2cBuffer[1];
+    i2cBuffer[0] = address;
+    DEBUG("CDS130X_I2C::ReadMemory (vector): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
+
+    // 3. Send I2C start + memory address
+    if (write(_slaveAddress, i2cBuffer, 1, true) == 0) {
+        // 4. read data + I2C stop
+        unsigned char buffer[length];
+        int result = read(_slaveAddress, (char *)buffer, length);
+        wait(0.02);
+        if (result == 0) {
+            p_datas.assign(buffer, buffer + length);
+
+            DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector): %x", (bool)(result == 0))
+            return (bool)(result == 0);
+        }
+    }
+
+    DEBUG_LEAVE("CDS130X_I2C::ReadMemory (vector) (false)")
+    return false;
+} // 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)
+
+    // 1.Prepare buffer
+    unsigned char address = CDS130X_I2C::BaseMemoryAddress + p_address;
+    int length;
+    if (p_readLengthFirst) { // The string was stored with its length
+        if (!ReadMemory(address, &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)
+    } else { // The string length is provided by p_length2write parameter
+        if (p_length2write == -1) {
+            length = p_string.size();
+        } else {
+            length = p_length2write;
+            p_string.resize(p_length2write);
+        }
+    }
+    DEBUG("CDS130X_I2C::ReadMemory (string): Length=%d", length)
+
+    // 2. Memory address
+    char i2cBuffer[2];
+    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) {
+        // 4. Read data + I2C stop
+        char buffer[length];
+        int result = read(_slaveAddress, (char *)buffer, length);
+        DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string): %d", result)
+        if (result == 0) {
+            p_string.assign(buffer, length);
+
+            return true;
+        }
+    }
+
+    DEBUG_LEAVE("CDS130X_I2C::ReadMemory (string) (false)")
+    return false;
+} // End of method CDS130X_I2C::ReadMemory
+
+#if defined(__DEBUG)
+void CDS130X_I2C::DumpMemoryArea(const unsigned char p_address, const int p_count) {
+    DEBUG_ENTER("CDS130X_I2C::DumpMemoryArea: %02x - %d", p_address, p_count)
+
+    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
+#ifdef __DEBUG
+        DEBUG_FATAL("CDS130X_I2C::DumpMemoryArea: read failed")
+#else // __DEBUG
+        std::cout << "CDS130X_I2C::DumpMemoryArea: read failed\r" << std::endl
+#endif // __DEBUG
+    } else {
+        std::cout << "CDS130X_I2C::DumpMemoryArea: Read bytes:\r" << std::endl;
+        HEXADUMP(&datas[0], p_count);
+        std::cout << "\r" << std::endl;
+    }
+} // End of method CDS130X_I2C::DumpMemoryArea
+#endif // _DEBUG
+
+} // End of namespace DS130X_I2C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS130x_I2C.h	Wed Feb 09 13:43:21 2011 +0000
@@ -0,0 +1,392 @@
+/* mbed simplified access to MAXIM DS130x Serial, I2C Real-Time Clock
+ * Copyright (c) 2011 ygarcia
+ *
+ * of this software and associated documentation files (the "Software"), to deal
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#if !defined(__DS130X_I2C_H__)
+#define __DS130X_I2C_H__
+
+#include <string>
+#include <vector>
+
+#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
+     *
+     * 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).
+     *
+     * Note that if the LPC1768 is powered in 3.3V and MAXIM DS130x Real-Time Clock device should be powered at 5V.
+     * In this case, you shall use a bi-directional level shifter for I2C-bus. Please refer to AN97055 (http://ics.nxp.com/support/documents/interface/pdf/an97055.pdf)
+     * MAXIM DS130x Real-Time Clock device reference: http://pdfserv.maxim-ic.com/en/ds/DS1307.pdf
+     *
+     * Note that for I2C details, please visit http://www.datelec.fr/fiches/I2C.htm
+     *
+     * Note that this header file include following headers:
+     * - <string>
+     * - <vector>
+     * - <mbed.h>
+     *
+     * @remark This class was validated with Tektronix TDS2014 oscilloscope in 3.3V and in mixte power mode 3.3V for mbed and 5V for the MAXIM DS130x Real-Time Clock device
+     * @author Yann Garcia (Don't hesitate to contact me: garcia.yann@gmail.com)
+     */
+    class CDS130X_I2C : public I2C {
+
+    public: // Enumerated
+        /** OscillatorMode modes
+         */
+        enum OscillatorMode {
+            One_Hz, //<! Oscillator set for 1Hz square signal generation
+            Four_KHz, //<! Oscillator set for 4096Hz square signal generation
+            Height_KHz, //<! Oscillator set for 8192Hz square signal generation
+            ThirtyTwo_KHz, //<! Oscillator set for 32768Hz square signal generation
+            Output //<! Oscillator is not used, @see _outputControlLevel for logocal outpout level
+        };
+
+        /** Time register format
+         */
+        enum RegisterFormatEnum {
+            Binary, //<! Time register format is binary
+            Bcd //<! Time register format is BCD
+        };
+
+        /** Memory storage mode
+         */
+        enum Mode {
+            LittleEndian, //<! Little Endian mode: 0xA0B70708 is stored as 08: MSB and A0 LSB
+            BigEndian //<! Little Endian mode: 0xA0B70708 is stored as AO: MSB and 08 LSB
+        };
+
+        /** Registers address
+         */
+        enum RegisterEnum {
+            SecondsAddress = 0x00, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            MinutesAddress = 0x01, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            HoursAddress = 0x02, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            DayOfWeekAddress = 0x03, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            DayAddress = 0x04, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            MonthAddress = 0x05, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            YearAddress = 0x06, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            ControlRegisterAddress = 0x07, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
+            BaseMemoryAddress = 0x08 //<! First address of the memory area
+        };
+
+    private: // Internal data structures
+
+        /** String used to convert day of week string into numerical value
+         */
+        std::string _dayOfWeek;
+        
+        /** This method controls the clock halting or starting it
+         *
+         * See datasheet - Clause CLOCK AND CALENDAR (CH bit)
+         *
+         * @param p_mode: true to restart the clock, false to halt it
+         * @return true on success, false otherwise
+         */
+        bool ControlClock(bool p_mode);
+
+        /** The slave address byte for DS130x - See Datasheet - Figure 4. Data Write-Slave Receiver Mode
+         */
+        unsigned char _slaveAddress;
+        /** Enable/disable the oscillator output
+         */
+        CDS130X_I2C::OscillatorMode _oscillatorMode;
+        /** This flag controls the output level of the SQW/OUT pin when the square-wave output is disabled
+         * Set to true if OUT level should be logic level 1, false otherwise
+         */
+        bool _outputLevel;
+
+    public: // Construction methods
+        /** Ctor with Write Protect command pin wired
+         *
+         * @param p_slaveAddress: I2C device address
+         * @param p_sda: MBed pin for SDA
+         * @param p_scl: MBed pin for SCL
+         * @param p_oscillatorMode Indicate the oscillator mode (pin 7 - SQW/OUT). Default: Output (oscillator not used)
+         * @param p_outputLevel Indicate the output level (0V/Vdd) when oscillator mode is Output. Default: 0V
+         * @param p_frequency: Frequency of the I2C interface (SCL), default value is 100KHz - See datasheet - Clause I2C DATA BUS
+         */
+        CDS130X_I2C(const unsigned char p_slaveAddress, const PinName p_sda, const PinName p_scl, const CDS130X_I2C::OscillatorMode p_oscillatorMode = Output, const bool p_outputLevel = false, const int p_frequency = 400000);
+    
+        /** Dtor
+         */
+        virtual ~CDS130X_I2C();
+
+        /** Initialize the module, configuring the module and starting the clock
+         *
+         * @return true on success, false otherwise
+         */
+        bool Initialize();
+
+    public: // Time part
+        /** This methods converts a packed BCD value < 99 into an hexadecimal value (e.g. 0x32 -> 0x10)
+         *
+         * @param p_hexaValue: The hexadecimal value to convert
+         * @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);
+        }
+
+        /** This methods converts an hexadecimal value < 99 into a packed BCD (e.g. 0x20 -> 0x32)
+         *
+         * @param p_hexaValue: The hexadecimal value to convert
+         * @return The packed BCD value
+         */
+        inline unsigned char ConvertHexToBCD(const unsigned char p_hexaValue) {
+            return (p_hexaValue / 10) << 4 + (p_hexaValue % 10);
+        }
+
+        /** Restart the clock
+         *
+         * See datasheet - Clause CLOCK AND CALENDAR (CH bit)
+         *
+         * @return true on success, false otherwise
+         */
+        bool RestartClock();
+        /** Halt the clock
+         *
+         * See datasheet - Clause CLOCK AND CALENDAR (CH bit)
+         *
+         * @return true on success, false otherwise
+         */
+        bool HaltClock();
+
+        /** This method reads the DS130x time registers value in BCD or binary format
+         *
+         * See datasheet - Clause CLOCK AND CALENDAR
+         *
+         * @param p_address: The time register identifier the to read
+         * @param p_byte: The register value in BDC format
+         * @param p_format: The format of the value to return. Default is BCD
+         * @return true on success, false otherwise
+         * @see RegisterEnum
+         * @see RegisterFormatEnum
+         */
+        bool Read(const RegisterEnum p_address, unsigned char * p_byte, const CDS130X_I2C::RegisterFormatEnum p_format = Bcd);
+
+        /** This method writes a value (provided in BCD or binary format) into the specified DS130x register
+         *
+         * See datasheet - Clause CLOCK AND CALENDAR
+         *
+         * @param p_address: The time register identifier the to write
+         * @param p_byte: The value to write in BCD format
+         * @param p_format: The format of the value 'p_byte'. Default is BCD
+         * @return true on success, false otherwise
+         * @see RegisterEnum
+         * @see RegisterFormatEnum
+         */
+        bool Write(const RegisterEnum p_address, const unsigned char p_byte, const CDS130X_I2C::RegisterFormatEnum p_format = Bcd);
+
+        /** Set RTC time using string format "Www Mmm dd hh:mm:ss yyyy"
+         *
+         * @param p_utcTime: UTC string format
+         * @return true on success, false otherwise
+         */
+        bool SetTime(const std::string p_utcTime);
+
+        /** This methods returns the current time in string format "Www Mmm dd hh:mm:ss yyyy"
+         *
+         * @return The current time in C struct tm format
+         */
+        struct tm GetTime();
+
+    public: // Memory part
+        /** Erase of memory area starting at the specified address, using the specified pattern to fill the memory area
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_count The size of the memory area to erase
+         * @param p_pattern The pattern value to use to fill the memory area. Defqult vqlue: 0x00
+         * @return true on success, false otherwise
+         * Exemple:
+         * @code
+         * ...
+         * myRTC.EraseMemoryArea(0, 8); // Set to 0x00 the first heigh memory byte
+         * ...
+         * @endcode
+         */
+        bool EraseMemoryArea(const unsigned char p_startAddress, const int p_count, unsigned char const p_pattern = 0x00);
+
+        /** Write a byte at the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_byte The byte value to save. The address start from 0.
+         * @return true on success, false otherwise
+         */
+        bool WriteMemory(const unsigned char p_address, const unsigned char p_byte);
+    
+        /** Write a short at the specified memory address according to the specified mode
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_short The short value to save
+         * @param p_mode The storage mode. Default value: BigEndian
+         * @return true on success, false otherwise
+         */
+        bool WriteMemory(const unsigned char p_address, const short p_short, const CDS130X_I2C::Mode p_mode = BigEndian);
+    
+        /** Write an integer at the specified memory address according to the specified mode
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_int The integer value to save
+         * @param p_mode The storage mode. Default value: BigEndian
+         * @return true on success, false otherwise
+         */
+        bool WriteMemory(const unsigned char p_address, const int p_int, const CDS130X_I2C::Mode p_mode = BigEndian);
+    
+        /** Write a buffer of bytes at the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_datas The string to save
+         * @param p_storeLength If true, store also the length of the buffer in Big Endian mode, otherwise the length will be provided by p_length2write parameter. Default value: true.
+         * @param p_length2write The number of bytes to write, -1 for all characters. Default value: -1
+         * @return true on success, false otherwise
+         */
+        bool WriteMemory(const unsigned char p_address, const std::vector<unsigned char> & p_datas, bool p_storeLength = true, const int p_length2write = -1);
+    
+        /** Write a buffer of bytes at the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_datas The buffer of bytes to save
+         * @param p_storeLength If true, store also the length of the buffer in Big Endian mode, otherwise the length will be provided by p_length2write parameter. Default value: true.
+         * @param p_length2write The number of bytes to write, -1 for all bytes. Default value: -1
+         * @return true on success, false otherwise
+         */
+        bool WriteMemory(const unsigned char p_address, const unsigned char *p_datas, bool p_storeLength = true, const int p_length2write = -1);
+    
+        /** Write a string at the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_string The string to save
+         * @param p_storeLength If true, store also the length of the string in Big Endian mode, otherwise the length will be provided by p_length2write parameter. Default value: true.
+         * @param p_length2write The number of character to write, -1 for all characters
+         * @return true on success, false otherwise
+         */
+        bool WriteMemory(const unsigned char p_address, const std::string & p_string, const bool p_storeLength = true, const int p_length2write = -1);
+    
+        /** Write a buffer of characters at the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * Note that the length of the buffer is not saved and the string is saved in Big Endian mode
+         * @param p_startAddress The address of the memory area.
+         * @param p_datas The string to save
+         * @param p_storeLength If true, store also the length of the string in Big Endian mode, otherwise the length will be provided by p_length2write parameter. Default value: true.
+         * @param length2write The number of character to write, -1 for all characters
+         * @return true on success, false otherwise
+         */
+        bool WriteMemory(const unsigned char p_address, const char *p_datas, const bool p_storeLength = true, const int p_length2write = -1);
+    
+        /** Read a byte from the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_byte The byte value to read
+         * @return true on success, false otherwise
+         */
+        bool ReadMemory(const unsigned char p_address, unsigned char *p_value);
+    
+        /** Read a short from the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_short The short value to read
+         * @return true on success, false otherwise
+         */
+        bool ReadMemory(const unsigned char p_address, short *p_short, const CDS130X_I2C::Mode p_mode = BigEndian);
+    
+        /** Read an integer from the specified memory address
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_int The integer value to read
+         * @return true on success, false otherwise
+         */
+        bool ReadMemory(const unsigned char p_address, int *p_int, const CDS130X_I2C::Mode p_mode = BigEndian);
+    
+        /** Read a buffer of bytes from the specified memory address and store it into a std::vector<unsigned char> object
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that the size of the buffer object is used for the number of bytes to read
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_datas The buffer to fill
+         * @param p_readLengthFirst If true, read the length first and p_length2write parameter is ignored, otherwise the length is provided by p_length2write parameter. Default value: true
+         * @param p_length2write The number of character to write, -1 to use the size of the string buffer
+         * @return true on success, false otherwise
+         * Exemple:
+         * @code
+         * std::vector<unsigned char> datas(bufferLength);
+         * ...
+         * myEEPROM.Read(memoryAddress, datas);
+         * ...
+         * @endcode
+         */
+        bool ReadMemory(const unsigned char p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst = true, const int p_length2write = -1);
+    
+        /** Read a buffer of characters from the specified memory address and store it into a string object
+         *
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that the size of the string object is used for the number of characters to read
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_string The string buffer to fill
+         * @param p_readLengthFirst If true, read the length first and p_length2write parameter is ignored, otherwise the length is provided by p_length2write parameter. Default value: true
+         * @param p_length2write The number of character to write, -1 to use the size of the string buffer
+         * @return true on success, false otherwise
+         */
+        bool ReadMemory(const unsigned char p_address, std::string & p_string, const bool p_readLengthFirst = true, const int p_length2write = -1);
+    
+#if defined(__DEBUG)
+        /** Dump a memory area
+         * 
+         * Note that for the DS1307, the memory segment is [08h, 3Fh]
+         * Note that the size of the string object is used for the number of characters to read
+         * Note that this method only access the memeory registered. The memory address starts from 0x00
+         * @param p_startAddress The address of the memory area.
+         * @param p_count The number of bytes toi dump
+         * @return true on success, false otherwise
+         */
+        void DumpMemoryArea(const unsigned char p_address, const int p_count);
+#endif // _DEBUG
+    }; // End of class CDS130X_I2C
+
+} // End of namespace DS130X_I2C
+
+using namespace DS130X_I2C;
+
+#endif // __DS130X_I2C_H__