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.h Source File

DS130x_I2C.h

00001 /* mbed simplified access to MAXIM DS130x Serial, I2C Real-Time Clock
00002  * Copyright (c) 2011 ygarcia
00003  *
00004  * of this software and associated documentation files (the "Software"), to deal
00005  * Permission is hereby granted, free of charge, to any person obtaining a copy
00006  * of this software and associated documentation files (the "Software"), to deal
00007  * in the Software without restriction, including without limitation the rights
00008  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009  * copies of the Software, and to permit persons to whom the Software is
00010  * furnished to do so, subject to the following conditions:
00011  *
00012  * The above copyright notice and this permission notice shall be included in
00013  * all copies or substantial portions of the Software.
00014  *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021  * THE SOFTWARE.
00022  */
00023 #if !defined(__DS130X_I2C_H__)
00024 #define __DS130X_I2C_H__
00025 
00026 #include <string>
00027 #include <vector>
00028 
00029 #include "Debug.h" // Include mbed header + debug primitives. See DebugLibrary
00030 
00031 namespace DS130X_I2C {
00032     /** This class provides simplified I2C access to a MAXIM DS130x Real-Time Clock device. V0.0.0.2
00033      *
00034      * 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).
00035      *
00036      * Note that if the LPC1768 is powered in 3.3V and MAXIM DS130x Real-Time Clock device should be powered at 5V.
00037      * 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)
00038      * MAXIM DS130x Real-Time Clock device reference: http://pdfserv.maxim-ic.com/en/ds/DS1307.pdf
00039      *
00040      * Note that for I2C details, please visit http://www.datelec.fr/fiches/I2C.htm
00041      *
00042      * Note that this header file include following headers:
00043      * - <string>
00044      * - <vector>
00045      * - <mbed.h>
00046      *
00047      * @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
00048      * @author Yann Garcia (Don't hesitate to contact me: garcia.yann@gmail.com)
00049      */
00050     class CDS130X_I2C : public I2C {
00051 
00052     public: // Enumerated
00053         /** OscillatorMode modes
00054          */
00055         enum OscillatorMode {
00056             One_Hz, //<! Oscillator set for 1Hz square signal generation
00057             Four_KHz, //<! Oscillator set for 4096Hz square signal generation
00058             Height_KHz, //<! Oscillator set for 8192Hz square signal generation
00059             ThirtyTwo_KHz, //<! Oscillator set for 32768Hz square signal generation
00060             Output //<! Oscillator is not used, @see _outputControlLevel for logocal outpout level
00061         };
00062 
00063         /** Time register format
00064          */
00065         enum RegisterFormatEnum {
00066             Binary, //<! Time register format is binary
00067             Bcd //<! Time register format is BCD
00068         };
00069 
00070         /** Memory storage mode
00071          */
00072         enum Mode {
00073             LittleEndian, //<! Little Endian mode: 0xA0B70708 is stored as 08: MSB and A0 LSB
00074             BigEndian //<! Little Endian mode: 0xA0B70708 is stored as AO: MSB and 08 LSB
00075         };
00076 
00077         /** Registers address
00078          */
00079         enum RegisterEnum {
00080             SecondsAddress = 0x00, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00081             MinutesAddress = 0x01, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00082             HoursAddress = 0x02, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00083             DayOfWeekAddress = 0x03, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00084             DayAddress = 0x04, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00085             MonthAddress = 0x05, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00086             YearAddress = 0x06, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00087             ControlRegisterAddress = 0x07, //<! The register addresses for DS1307 - See Datasheet - Table 2. Timekeeper Registers
00088             BaseMemoryAddress = 0x08 //<! First address of the memory area
00089         };
00090 
00091     private: // Internal data structures
00092 
00093         /** String used to convert day of week string into numerical value
00094          */
00095         std::string _dayOfWeek;
00096         
00097         /** This method controls the clock halting or starting it
00098          *
00099          * See datasheet - Clause CLOCK AND CALENDAR (CH bit)
00100          *
00101          * @param p_mode: true to restart the clock, false to halt it
00102          * @return true on success, false otherwise
00103          */
00104         bool ControlClock(bool p_mode);
00105 
00106         /** The slave address byte for DS130x - See Datasheet - Figure 4. Data Write-Slave Receiver Mode
00107          */
00108         unsigned char _slaveAddress;
00109         /** Enable/disable the oscillator output
00110          */
00111         CDS130X_I2C::OscillatorMode _oscillatorMode;
00112         /** This flag controls the output level of the SQW/OUT pin when the square-wave output is disabled
00113          * Set to true if OUT level should be logic level 1, false otherwise
00114          */
00115         bool _outputLevel;
00116 
00117     public: // Construction methods
00118         /** Ctor with Write Protect command pin wired
00119          *
00120          * @param p_slaveAddress: I2C device address
00121          * @param p_sda: MBed pin for SDA
00122          * @param p_scl: MBed pin for SCL
00123          * @param p_oscillatorMode Indicate the oscillator mode (pin 7 - SQW/OUT). Default: Output (oscillator not used)
00124          * @param p_outputLevel Indicate the output level (0V/Vdd) when oscillator mode is Output. Default: 0V
00125          * @param p_frequency: Frequency of the I2C interface (SCL), default value is 100KHz - See datasheet - Clause I2C DATA BUS
00126          */
00127         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);
00128     
00129         /** Dtor
00130          */
00131         virtual ~CDS130X_I2C();
00132 
00133         /** Initialize the module, configuring the module and starting the clock
00134          *
00135          * @return true on success, false otherwise
00136          */
00137         bool Initialize();
00138 
00139     public: // Time part
00140         /** This methods converts a packed BCD value < 99 into an hexadecimal value (e.g. 0x32 -> 0x10)
00141          *
00142          * @param p_hexaValue: The hexadecimal value to convert
00143          * @return The packed BCD value
00144          */
00145         inline unsigned char ConvertBCDToHex(const unsigned char p_bcdValue) {
00146             /*DEBUG("ConvertBCDToHex: %02x - %02x - %02x - %02x - %d", 
00147                 p_bcdValue, 
00148                 (unsigned char)(p_bcdValue >> 4), 
00149                 (unsigned char)((unsigned char)(p_bcdValue >> 4) * 10), 
00150                 (unsigned char)(p_bcdValue & 0x0f), 
00151                 (int)(
00152                     (unsigned char)((unsigned char)(p_bcdValue >> 4) * 10) | (unsigned char)(p_bcdValue & 0x0f)
00153                  )
00154             )*/
00155             return (unsigned char)((unsigned char)(p_bcdValue >> 4) * 10) | (unsigned char)(p_bcdValue & 0x0f);
00156         }
00157 
00158         /** This methods converts an hexadecimal value < 99 into a packed BCD (e.g. 0x20 -> 0x32)
00159          *
00160          * @param p_hexaValue: The hexadecimal value to convert
00161          * @return The packed BCD value
00162          */
00163         inline unsigned char ConvertHexToBCD(const unsigned char p_hexaValue) {
00164             //DEBUG("ConvertHexToBCD: %02x - %02x - %02x", p_hexaValue, (unsigned char)(p_hexaValue / 10 << 4), (unsigned char)(p_hexaValue % 10))
00165             return (unsigned char)(p_hexaValue / 10 << 4) | (unsigned char)(p_hexaValue % 10);
00166         }
00167 
00168         /** Restart the clock
00169          *
00170          * See datasheet - Clause CLOCK AND CALENDAR (CH bit)
00171          *
00172          * @return true on success, false otherwise
00173          */
00174         bool RestartClock();
00175         /** Halt the clock
00176          *
00177          * See datasheet - Clause CLOCK AND CALENDAR (CH bit)
00178          *
00179          * @return true on success, false otherwise
00180          */
00181         bool HaltClock();
00182 
00183         /** This method reads the DS130x time registers value in BCD or binary format
00184          *
00185          * See datasheet - Clause CLOCK AND CALENDAR
00186          *
00187          * @param p_address: The time register identifier the to read
00188          * @param p_byte: The register value in BDC format
00189          * @param p_format: The format of the value to return. Default is BCD
00190          * @return true on success, false otherwise
00191          * @see RegisterEnum
00192          * @see RegisterFormatEnum
00193          */
00194         bool Read(const RegisterEnum p_address, unsigned char * p_byte, const CDS130X_I2C::RegisterFormatEnum p_format = Bcd);
00195 
00196         /** This method writes a value (provided in BCD or binary format) into the specified DS130x register
00197          *
00198          * See datasheet - Clause CLOCK AND CALENDAR
00199          *
00200          * @param p_address: The time register identifier the to write
00201          * @param p_byte: The value to write in BCD format
00202          * @param p_format: The format of the value 'p_byte'. Default is BCD
00203          * @return true on success, false otherwise
00204          * @see RegisterEnum
00205          * @see RegisterFormatEnum
00206          */
00207         bool Write(const RegisterEnum p_address, const unsigned char p_byte, const CDS130X_I2C::RegisterFormatEnum p_format = Bcd);
00208 
00209         /** Set RTC time using string format "Www Mmm dd hh:mm:ss yyyy"
00210          *
00211          * @param p_utcTime: UTC string format
00212          * @return true on success, false otherwise
00213          */
00214         bool SetTime(const std::string p_utcTime);
00215 
00216         /** This methods returns the current time in string format "Www Mmm dd hh:mm:ss yyyy"
00217          *
00218          * @return The current time in C struct tm format
00219          */
00220         struct tm GetTime();
00221 
00222     public: // Memory part
00223         /** Erase of memory area starting at the specified address, using the specified pattern to fill the memory area
00224          *
00225          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00226          * Note that this method only access the memeory registered. The memory address starts from 0x00
00227          * @param p_startAddress The address of the memory area.
00228          * @param p_count The size of the memory area to erase
00229          * @param p_pattern The pattern value to use to fill the memory area. Defqult vqlue: 0x00
00230          * @return true on success, false otherwise
00231          * Exemple:
00232          * @code
00233          * ...
00234          * myRTC.EraseMemoryArea(0, 8); // Set to 0x00 the first heigh memory byte
00235          * ...
00236          * @endcode
00237          */
00238         bool EraseMemoryArea(const unsigned char p_startAddress, const int p_count, unsigned char const p_pattern = 0x00);
00239 
00240         /** Write a byte at the specified memory address
00241          *
00242          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00243          * Note that this method only access the memeory registered. The memory address starts from 0x00
00244          * @param p_startAddress The address of the memory area.
00245          * @param p_byte The byte value to save. The address start from 0.
00246          * @return true on success, false otherwise
00247          */
00248         bool WriteMemory(const unsigned char p_address, const unsigned char p_byte);
00249     
00250         /** Write a short at the specified memory address according to the specified mode
00251          *
00252          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00253          * Note that this method only access the memeory registered. The memory address starts from 0x00
00254          * @param p_startAddress The address of the memory area.
00255          * @param p_short The short value to save
00256          * @param p_mode The storage mode. Default value: BigEndian
00257          * @return true on success, false otherwise
00258          */
00259         bool WriteMemory(const unsigned char p_address, const short p_short, const CDS130X_I2C::Mode p_mode = BigEndian);
00260     
00261         /** Write an integer at the specified memory address according to the specified mode
00262          *
00263          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00264          * Note that this method only access the memeory registered. The memory address starts from 0x00
00265          * @param p_startAddress The address of the memory area.
00266          * @param p_int The integer value to save
00267          * @param p_mode The storage mode. Default value: BigEndian
00268          * @return true on success, false otherwise
00269          */
00270         bool WriteMemory(const unsigned char p_address, const int p_int, const CDS130X_I2C::Mode p_mode = BigEndian);
00271     
00272         /** Write a buffer of bytes at the specified memory address
00273          *
00274          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00275          * Note that this method only access the memeory registered. The memory address starts from 0x00
00276          * @param p_startAddress The address of the memory area.
00277          * @param p_datas The string to save
00278          * @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.
00279          * @param p_length2write The number of bytes to write, -1 for all characters. Default value: -1
00280          * @return true on success, false otherwise
00281          */
00282         bool WriteMemory(const unsigned char p_address, const std::vector<unsigned char> & p_datas, bool p_storeLength = true, const int p_length2write = -1);
00283     
00284         /** Write a buffer of bytes at the specified memory address
00285          *
00286          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00287          * Note that this method only access the memeory registered. The memory address starts from 0x00
00288          * @param p_startAddress The address of the memory area.
00289          * @param p_datas The buffer of bytes to save
00290          * @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.
00291          * @param p_length2write The number of bytes to write, -1 for all bytes. Default value: -1
00292          * @return true on success, false otherwise
00293          */
00294         bool WriteMemory(const unsigned char p_address, const unsigned char *p_datas, bool p_storeLength = true, const int p_length2write = -1);
00295     
00296         /** Write a string at the specified memory address
00297          *
00298          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00299          * Note that this method only access the memeory registered. The memory address starts from 0x00
00300          * @param p_startAddress The address of the memory area.
00301          * @param p_string The string to save
00302          * @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.
00303          * @param p_length2write The number of character to write, -1 for all characters
00304          * @return true on success, false otherwise
00305          */
00306         bool WriteMemory(const unsigned char p_address, const std::string & p_string, const bool p_storeLength = true, const int p_length2write = -1);
00307     
00308         /** Write a buffer of characters at the specified memory address
00309          *
00310          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00311          * Note that this method only access the memeory registered. The memory address starts from 0x00
00312          * Note that the length of the buffer is not saved and the string is saved in Big Endian mode
00313          * @param p_startAddress The address of the memory area.
00314          * @param p_datas The string to save
00315          * @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.
00316          * @param length2write The number of character to write, -1 for all characters
00317          * @return true on success, false otherwise
00318          */
00319         bool WriteMemory(const unsigned char p_address, const char *p_datas, const bool p_storeLength = true, const int p_length2write = -1);
00320     
00321         /** Read a byte from the specified memory address
00322          *
00323          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00324          * Note that this method only access the memeory registered. The memory address starts from 0x00
00325          * @param p_startAddress The address of the memory area.
00326          * @param p_byte The byte value to read
00327          * @return true on success, false otherwise
00328          */
00329         bool ReadMemory(const unsigned char p_address, unsigned char *p_value);
00330     
00331         /** Read a short from the specified memory address
00332          *
00333          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00334          * Note that this method only access the memeory registered. The memory address starts from 0x00
00335          * @param p_startAddress The address of the memory area.
00336          * @param p_short The short value to read
00337          * @return true on success, false otherwise
00338          */
00339         bool ReadMemory(const unsigned char p_address, short *p_short, const CDS130X_I2C::Mode p_mode = BigEndian);
00340     
00341         /** Read an integer from the specified memory address
00342          *
00343          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00344          * Note that this method only access the memeory registered. The memory address starts from 0x00
00345          * @param p_startAddress The address of the memory area.
00346          * @param p_int The integer value to read
00347          * @return true on success, false otherwise
00348          */
00349         bool ReadMemory(const unsigned char p_address, int *p_int, const CDS130X_I2C::Mode p_mode = BigEndian);
00350     
00351         /** Read a buffer of bytes from the specified memory address and store it into a std::vector<unsigned char> object
00352          *
00353          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00354          * Note that the size of the buffer object is used for the number of bytes to read
00355          * Note that this method only access the memeory registered. The memory address starts from 0x00
00356          * @param p_startAddress The address of the memory area.
00357          * @param p_datas The buffer to fill
00358          * @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
00359          * @param p_length2write The number of character to write, -1 to use the size of the string buffer
00360          * @return true on success, false otherwise
00361          * Exemple:
00362          * @code
00363          * std::vector<unsigned char> datas(bufferLength);
00364          * ...
00365          * myEEPROM.Read(memoryAddress, datas);
00366          * ...
00367          * @endcode
00368          */
00369         bool ReadMemory(const unsigned char p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst = true, const int p_length2write = -1);
00370     
00371         /** Read a buffer of characters from the specified memory address and store it into a string object
00372          *
00373          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00374          * Note that the size of the string object is used for the number of characters to read
00375          * Note that this method only access the memeory registered. The memory address starts from 0x00
00376          * @param p_startAddress The address of the memory area.
00377          * @param p_string The string buffer to fill
00378          * @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
00379          * @param p_length2write The number of character to write, -1 to use the size of the string buffer
00380          * @return true on success, false otherwise
00381          */
00382         bool ReadMemory(const unsigned char p_address, std::string & p_string, const bool p_readLengthFirst = true, const int p_length2write = -1);
00383     
00384 #if defined(__DEBUG)
00385         /** Dump a memory area
00386          * 
00387          * Note that for the DS1307, the memory segment is [08h, 3Fh]
00388          * Note that the size of the string object is used for the number of characters to read
00389          * Note that this method only access the memeory registered. The memory address starts from 0x00
00390          * @param p_startAddress The address of the memory area.
00391          * @param p_count The number of bytes toi dump
00392          * @return true on success, false otherwise
00393          */
00394         void DumpMemoryArea(const unsigned char p_address, const int p_count);
00395 #endif // _DEBUG
00396     }; // End of class CDS130X_I2C
00397 
00398 } // End of namespace DS130X_I2C
00399 
00400 using namespace DS130X_I2C;
00401 
00402 #endif // __DS130X_I2C_H__