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.

Revision:
2:ee81f2c5a706
Parent:
1:64274190e842
Child:
3:e89d63f3342e
--- a/Rtc_Ds1307.cpp	Sun Jun 02 18:57:26 2013 +0000
+++ b/Rtc_Ds1307.cpp	Wed Jun 05 20:42:37 2013 +0000
@@ -37,24 +37,47 @@
 
 bool Rtc_Ds1307::setTime(Time& time, bool start, bool thm)
 {
-    INFO("Setting new time : %d:%d:%d\n", time.hour, time.min, time.sec);
-    
+    char buffer[7];
+    INFO("reading clock registers to write the new time : %d:%d:%d\n", time.hour, time.min, time.sec);
+    if (!read(0,buffer,7)) {
+        ERR("Failed to read from RTC\n");
+        return false;
+    }
+    //  Now update only the time part (saving the existing flags)
+    if (start) { buffer[0] &= 0x7F; } else { buffer[0] |= 0x80; }
+    buffer[0] = (buffer[0]&0x80) | (decimalToBcd(time.sec)& 0x7f);
+    buffer[1] = decimalToBcd(time.min);
+    if (thm) {
+        //  AM PM format
+        buffer[2] = (buffer[2]& 196) | (time.hour>12 ? (0x20 | ((decimalToBcd(time.hour-12)))) : decimalToBcd(time.hour));
+    }
+    else {
+        // 24 hours format
+        buffer[2] = (buffer[2]& 196) | (decimalToBcd(time.hour) & 0x3F);
+    }
+    buffer[3] = time.wday;
+    buffer[4] = decimalToBcd(time.date);
+    buffer[5] = decimalToBcd(time.mon);
+    buffer[6] = decimalToBcd(time.year-2000);
+    INFO("Writing new time and date data to RTC\n");
+    if (!write(0, buffer, 7) ) {
+        ERR("Failed to write the data to RTC!\n");
+        return false;
+    }
     return true;
 }
 
 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) {
+    if (!read(0, buffer, 7) ) {
         //  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]);
@@ -70,18 +93,89 @@
     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
+    time.year = Rtc_Ds1307::bcdToDecimal(buffer[6]) + 2000;   //  plus hundret is because RTC is giving the years since 2000, but std c struct tm needs years since 1900
+    
+    return true;
+}
+
+
+bool Rtc_Ds1307::startClock()
+{
+    char strtStop;
+    
+    INFO ("Reading clock start/stop register value\n");
+    if (!read(0, &strtStop, 1)) {
+        ERR("Failed to read clock start stop register !\n");
+        return false;
+    }
+    
+    strtStop &= 0x7F;
+    
+    INFO("Writing back start/stop register value\n");
+    if (!write(0, &strtStop, 1)) {
+        ERR("Failed to write the start stop register !\n");
+        return false;
+    }
+    
+    INFO("Start/stop register value successfully written\n");
+    return true;
+}
+
+bool Rtc_Ds1307::stopClock()
+{
+    char strtStop;
+    
+    INFO ("Reading clock start/stop register value\n");
+    if (!read(0, &strtStop, 1)) {
+        ERR("Failed to read clock start stop register !\n");
+        return false;
+    }
     
-    INFO("Clock is %s\n", bClock_halt ? "halted" : "running");
-    return false;
+    strtStop |= 0x80;
+    
+    INFO("Writing back start/stop register value\n");
+    if (!write(0, &strtStop, 1)) {
+        ERR("Failed to write the start stop register !\n");
+        return false;
+    }
+    
+    INFO("Start/stop register value successfully written\n");
+    return true;
 }
 
+bool Rtc_Ds1307::setSquareWaveOutput(bool ena, RateSelect_t rs)
+{
+    char reg;
+    INFO("Reading register value first\n");
+    
+    if (!read(7,&reg, 1)) {
+        ERR("Failed to read register value !\n");
+        return false;
+    }
+    INFO("[Reg:0x07] = %02x\n", reg); 
+    
+    //  preserve the OUT control bit while writing the frequency and enable bits
+    reg = (reg & 0x80) | (ena ? 0x10 : 0) | ((char)rs & 0x03);
+
+    INFO("Writing back register value\n");
+    INFO("[Reg:0x07] = %02x\n", reg); 
+    
+    if (!write(7, &reg, 1)) {
+        ERR("Failed to write register value !\n");
+        return false;
+    }
+    
+    INFO("Successfully changed the square wave output.\n");
+    return true;
+}
+
+
 
 bool Rtc_Ds1307::read(int address, char *buffer, int len)
 {
     char buffer2[2] = {(char)address, 0};
     
-    m_rtc->start();
+//    m_rtc->start();
     if (m_rtc->write(0xd0, buffer2, 1) != 0) {
         ERR("Failed to write register address on rtv!\n");
         m_rtc->stop();
@@ -104,7 +198,7 @@
     for (int i = 0 ; i < len ; i++)
         buffer2[i+1] = buffer[i];
 
-    m_rtc->start();        
+//    m_rtc->start();        
     if (m_rtc->write(0xd0, buffer2, len+1) != 0) {
         ERR("Failed to write data to rtc\n");
         m_rtc->stop();