Working Version of the Real Time Clock module DS1307.

Dependents:   Rtc_Ds1307_Sample TAREA_5_PROCESADORES Rtc_Ds1307_lcd_alarma Rtc_Ds1307_Reloj_con_alarma_aplazable ... more

This is my implementation of the DS1307.

I plan to add functionality which will make use of the OSC Input and which will increment the time continuously. A query to the module will then only have to be made when the MBED has been powered down.

Files at this revision

API Documentation at this revision

Comitter:
leihen
Date:
Sun Jun 02 18:57:26 2013 +0000
Parent:
0:3940f0ad2ca5
Child:
2:ee81f2c5a706
Commit message:
First complete Version - untested.

Changed in this revision

Rtc_Ds1307.cpp Show annotated file Show diff for this revision Revisions of this file
Rtc_Ds1307.h Show annotated file Show diff for this revision Revisions of this file
--- a/Rtc_Ds1307.cpp	Sun Jun 02 09:59:39 2013 +0000
+++ b/Rtc_Ds1307.cpp	Sun Jun 02 18:57:26 2013 +0000
@@ -2,7 +2,7 @@
 
 #include "Rtc_Ds1307.h"
 
-#define _DEBUG 0
+#define _DEBUG 1
 
 
 #if (_DEBUG && !defined(TARGET_LPC11U24))
@@ -15,7 +15,7 @@
 #define ERR(x, ...)
 #endif
 
-
+const char *Rtc_Ds1307::m_weekDays[] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };    
 
 
 Rtc_Ds1307::Rtc_Ds1307(PinName sda, PinName scl)
@@ -24,6 +24,9 @@
     m_rtc = new I2C(sda, scl);
     if (m_rtc == NULL)
         error("Rtc_Ds1307");
+        
+    // Set the frequency to standard 100kHz
+    m_rtc->frequency(100000);
 }
 
 Rtc_Ds1307::~Rtc_Ds1307()
@@ -32,14 +35,81 @@
         delete m_rtc;
 }
 
-bool Rtc_Ds1307::setTime(tm& time)
+bool Rtc_Ds1307::setTime(Time& time, bool start, bool thm)
 {
-    INFO("Setting new time : %d:%d:%d\n", time.tm_hour, time.tm_min, time.tm_sec);
+    INFO("Setting new time : %d:%d:%d\n", time.hour, time.min, time.sec);
     
     return true;
 }
 
-bool Rtc_Ds1307::getTime(tm& time)
+bool Rtc_Ds1307::getTime(Time& time)
 {
+    char buffer[7];
+    bool bClock_halt = false;
+    bool thm = false;
+    
+    INFO("Getting time from RTC\n");
+    if (read(0, buffer, 7) != 0) {
+        //  Failed to read
+        ERR("Failed to read from RTC\n");
+        return false;
+    }
+    bClock_halt = ((buffer[0] & 128) == 128);
+    thm = ((buffer[2] & 64) == 64);
+    time.sec = bcdToDecimal(buffer[0]&0x7F);
+    time.min = bcdToDecimal(buffer[1]);
+    if (thm) {
+        // in 12-hour-mode, we need to add 12 hours if PM bit is set
+        time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 31 );
+        if ((buffer[2] & 32) == 32)
+            time.hour += 12;
+    }
+    else {
+        time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 63 );
+    }  
+    time.wday = buffer[3]; 
+    time.date = Rtc_Ds1307::bcdToDecimal( buffer[4]);
+    time.mon = Rtc_Ds1307::bcdToDecimal( buffer[5]);
+    time.year = Rtc_Ds1307::bcdToDecimal(buffer[6]) + 100;   //  plus hundret is because RTC is giving the years since 2000, but std c struct tm needs years since 1900
+    
+    INFO("Clock is %s\n", bClock_halt ? "halted" : "running");
     return false;
 }
+
+
+bool Rtc_Ds1307::read(int address, char *buffer, int len)
+{
+    char buffer2[2] = {(char)address, 0};
+    
+    m_rtc->start();
+    if (m_rtc->write(0xd0, buffer2, 1) != 0) {
+        ERR("Failed to write register address on rtv!\n");
+        m_rtc->stop();
+        return false;
+    }
+    if (m_rtc->read(0xd0, buffer, len) != 0) {
+        ERR("Failed to read register !\n");
+        return false;
+    }
+    m_rtc->stop();
+    
+    INFO("Successfully read %d registers from RTC\n", len);
+    return true;
+}
+
+bool Rtc_Ds1307::write(int address, char *buffer, int len)
+{
+    char buffer2[10];
+    buffer2[0] = address&0xFF;
+    for (int i = 0 ; i < len ; i++)
+        buffer2[i+1] = buffer[i];
+
+    m_rtc->start();        
+    if (m_rtc->write(0xd0, buffer2, len+1) != 0) {
+        ERR("Failed to write data to rtc\n");
+        m_rtc->stop();
+        return false;
+    }
+    m_rtc->stop();
+    return true;
+}
\ No newline at end of file
--- a/Rtc_Ds1307.h	Sun Jun 02 09:59:39 2013 +0000
+++ b/Rtc_Ds1307.h	Sun Jun 02 18:57:26 2013 +0000
@@ -25,6 +25,15 @@
 
 #include "mbed.h"
 
+typedef struct {
+    int sec;
+    int min;
+    int hour;
+    int wday;
+    int date;
+    int mon;
+    int year;
+} Time;
 
 /** Class Rtc_Ds1307 implements the real time clock module DS1307
  *
@@ -35,7 +44,9 @@
 class Rtc_Ds1307
 {
         I2C*    m_rtc;
-
+        
+        static const char *m_weekDays[];    
+        
     public:
         /** public constructor which creates the real time clock object
          *
@@ -48,9 +59,47 @@
         
         ~Rtc_Ds1307();
 
-        bool getTime(tm& time);
+        /** Read the current time from RTC chip
+         *
+         * @param time : reference to a struct tm which will be filled with the time from rtc
+         *
+         * @returns true if successful, otherwise an acknowledge error occured
+         */
+        bool getTime(Time& time);
+        
+        /** Write the given time onto the RTC chip
+         *
+         * @param time : refereence to a struct which contains valid date and time information
+         *
+         * @param start : contains true if the clock shall start (or keep on running).
+         *
+         * @param thm : 12-hour-mode if set to true, otherwise 24-hour-mode will be set.
+         *
+         * @returns true if successful, otherwise an acknowledge error occured
+         */
+        bool setTime(Time& time, bool start, bool thm);        
+        
         
-        bool setTime(tm& time);        
+        /** Service function to convert a weekday into a string representation
+         *
+         * @param wday : day of week to convert (starting with sunday = 1, monday = 2, ..., saturday = 7
+         *
+         * @returns the corresponding string representation
+         */
+        const char* weekdayToString( int wday )
+        { return m_weekDays[wday%7]; }
+
+    private:
+        bool read(int address, char* buffer, int len);
+        bool write(int address, char* buffer, int len);
+        
+        static int bcdToDecimal(int bcd)
+        { return ((bcd&0xF0)>>4)*10 + (bcd&0x0F); }
+        
+        static int decimalToBcd(int dec)
+        { return (dec%10) + ((dec/10)<<4); }
+
+
 };