DS3232M RTC demo program. Tested on the K64F (this example) and the KL25Z, but should work on any platform by changing the SDA and SCL pins. USB serial baud rate is 230400, tested on TeraTerm. Demo includes setting the DS3232's time, turning on and off the 32KHz and 1Hz outputs and accessing the DS3232's temperature. Also included are DS3232 user RAM access tests and user RAM CRC data calculations. Since user RAM is battery backed up, CRC routines are included to insure that the data stored in user RAM is intact.

Dependencies:   ds3232m mbed mbed-rtos

Revision:
1:c891c3930f4e
Parent:
0:8d18e427a06b
Child:
2:958004aa28a4
--- a/main.cpp	Mon Dec 08 23:11:15 2014 +0000
+++ b/main.cpp	Fri Dec 19 20:28:39 2014 +0000
@@ -1,7 +1,12 @@
 #include "mbed.h"
+//#include "rtos.h"                           //mbed rtos - uncomment to make RTOS available
 #include "ds3232m.h"                        //Maxim RTC
 
-Serial pc(USBTX, USBRX);
+RawSerial pc(USBTX, USBRX);                 //onsole interface
+
+#ifdef RTOS_H
+Mutex MutexI2C0;                            //lock/unlock I2C requests
+#endif  //RTOS_H
 
 #define SDA0        PTE25
 #define SCL0        PTE24
@@ -17,6 +22,7 @@
 char timebuf_dMyy[14];                      //local time format buffer - 01-Apr-2014
 char timebuf_dow[1];                        //local time format buffer - 5
 int StartTime = 0;                          //time we powered up
+bool allowDisplayTime = false;              //used to stop displaying date/time when entering data from the console
 
 //--------------------------------------------------------------------------------------------------------------------------------------//
 //Variables for USB Serial Port RX
@@ -34,6 +40,8 @@
 #define BS          0x08                    //ascii backspace
 #define CR          0x0d                    //ascii CR
 #define LF          0x0a                    //ascii LF
+#define ticC        0x03                    //ascii control C
+#define DEGC_DEGF_FLOAT         9.0 / 5.0 + 32.0
 
 void PcRxChar(char inchar) {
     if(inchar == CR) pc.printf(" %c %c", BS, BS);   //NOTE: Bug in K64F has issue with CR and/or LF, these 2 lines are needed
@@ -49,6 +57,8 @@
     } else if((inchar == CR) || (inchar == LF)) { 
         pcRxLine = true;
         pc.printf("\r\n");
+    } else if(inchar == ticC) {
+        NVIC_SystemReset();
     } else {
         if(pcRxQty < (sizeof(pcRxBuffer) - 2)) {
             pcRxBuffer[pcRxQty] = inchar;
@@ -63,10 +73,9 @@
 }
 
 //--------------------------------------------------------------------------------------------------------------------------------------//
-// Read received chars from USB UART
+// Read received chars from USB UART interrupt
 
-void PcRxIRQnoRTOS(void){
-
+void PcRxIRQ(void){
 #if defined(TARGET_KL25Z)
     NVIC_DisableIRQ(UART0_IRQn);        // n=0, 1 or 2  Disable Rx interrupt on kl25z
 #endif
@@ -79,7 +88,6 @@
     while (pc.readable()) {
         inchar = pc.getc();             //<<<<< broken here!!!!     //read data from USB
         PcRxChar(inchar);               //go process char
-
     }
 #if defined(TARGET_KL25Z)
     NVIC_EnableIRQ(UART0_IRQn);         // n=0, 1 or 2  Re-enable Rx interrupt on kl25z
@@ -93,7 +101,7 @@
 }
 
 //--------------------------------------------------------------------------------------------------------------------------------------//
-//clear RxData buffer with all 00's
+//clear RxData buffer with all 00's and clear flags
 
 void pcClrLineBuf() {
     pcRxQty = 0;                                                            // data counter/pointer
@@ -103,7 +111,7 @@
 }
 
 //--------------------------------------------------------------------------------------------------------------------------------------//
-// Update time
+// Update time display values
 
 void UpdateTimeRegs() {
     strftime(timebuf_dMyy, 14, "%d-%b-%Y", localtime(&ctTime));
@@ -120,7 +128,7 @@
 // display current local date and time
 
 void PrintDateTime() {
-    pc.printf("Date: %s   ", timebuf_dMyy);
+    pc.printf("%sDate: %s   ",  DOUPONELINE, timebuf_dMyy);
     pc.printf("Time: %s \r\n", timebuf_hms);
 }
 
@@ -137,7 +145,11 @@
      
     //wait for string above
     do{
+#ifdef RTOS_H
+        Thread::wait(10);
+#else
         wait_ms(10);
+#endif
     } while((pcRxLine == false) && (pcRxEOB == false));
     
     //load up the time structure
@@ -154,11 +166,11 @@
     t.tm_wday = t.tm_wday & 7;
     
     //if error exists, exit without changing time
-    if(t.tm_year < 113) return(1);
-    if(t.tm_mon > 12) return(1); 
-    if(t.tm_mday > 31) return(1);  
-    if(t.tm_hour > 23) return(1); 
-    if(t.tm_min > 59) return(1); 
+    if(t.tm_year < 113) return(32);
+    if(t.tm_mon > 12) return(16); 
+    if(t.tm_mday > 31) return(8);  
+    if(t.tm_hour > 23) return(4); 
+    if(t.tm_min > 59) return(2); 
     if(t.tm_sec > 59) return(1); 
     
     //set up the DS3232's RTC
@@ -215,36 +227,121 @@
     //wait for DS3232 temperature conversion to finish
     int i = 80;
     for(i = 80; i > 0; i--) {
+#ifdef RTOS_H
+        Thread::wait(20);
+#else
         wait_ms(20);
+#endif
         if((rtc.checkTempBusy()) == true) break;
     }
         
     //timed out or display temperature
     if(i > 0) {
-        pc.printf(" - DS3232M Temperature: %.2f\r\n", rtc.getTemperature());
+        float ds3232tempC = rtc.getTemperature();
+        pc.printf(" - DS3232M Temperature: %.2fC  %.1fF\r\n", ds3232tempC, ds3232tempC * DEGC_DEGF_FLOAT);
     } else {
         pc.printf("*** DS3232M Temperature timeout!!!!\r\n");
     }
 }
 
 //--------------------------------------------------------------------------------------------------------------------------------------//
+// Checking for characters to execute commands from.  It's a thread if RTOS is used.
+
+#ifdef RTOS_H
+void cli_thread(void const *argument) {
+    pc.printf(" - Starting CLI RTOS thread\r\n");
+    while (true) {      //while loop only for RTOS
+        Thread::wait(73);
+#else
+void cli_thread() {
+#endif
+        if(pcRxQty != 0) {
+            pc.printf("\r\n");
+            if(pcRxBuffer[0] == 'A') rtc.set32KhzOutput(true, false);   //turn on 32KHz output
+            if(pcRxBuffer[0] == 'a') rtc.set32KhzOutput(false, false);  //turn off 32KHz output
+            if(pcRxBuffer[0] == 'B') rtc.set1hzOutput(true, false);   //turn on 1Hz output
+            if(pcRxBuffer[0] == 'b') rtc.set1hzOutput(false, false);  //turn off 1Hz output
+            if(pcRxBuffer[0] == 'c') {
+                allowDisplayTime = true;
+                SetRTC();  //change DS3232 time
+                allowDisplayTime = false;
+                pcRxBuffer[0] = 'c';
+            }
+            if(pcRxBuffer[0] == 'g') {  //get and display stored data string
+                if(rtc.getUserRAM(pcRxBuffer, 128, 126) != 0) {
+                    pc.printf("Get user RAM error!!\r\n");
+                } else if(pcRxBuffer[0] == NULL) {
+                    pc.printf("User RAM empty!!\r\n");
+                } else {
+                    //pcRxBuffer[31] = NULL;    //guarantee that the string max length is 32 bytes
+                    pc.printf("%s\r\n", pcRxBuffer);
+                }
+                pcRxBuffer[0] = 'g';
+            }
+            if(pcRxBuffer[0] == 's') {  //save data string
+                allowDisplayTime = true;
+                pc.printf("Enter text string to save: ");
+                pcClrLineBuf();
+                do {
+#ifdef RTOS_H
+                    Thread::wait(20);
+#else
+                    wait_ms(20);
+#endif
+                } while((pcRxLine == false) && (pcRxEOB == false));
+                if(rtc.putUserRAM(pcRxBuffer, 128, pcRxQty + 2) != 0) {
+                    pc.printf("Put user RAM error!!\r\n");
+                }
+                allowDisplayTime = false;
+                pcRxBuffer[0] = 's';
+            }
+            if(pcRxBuffer[0] == 't') Get3232Temp();  //display the DS3232's temperature
+            if(pcRxBuffer[0] == 'z') {  
+                rtc.LoadRTCRam();
+                pc.printf("CRC16 value: 0x%04X\r\n", rtc.calculateCRC16(rtc.RTCbuffer, 0x14, 0xea));
+            }
+            if((pcRxBuffer[0] != 'a') && (pcRxBuffer[0] != 'A') && (pcRxBuffer[0] != 'b') 
+                && (pcRxBuffer[0] != 'B') && (pcRxBuffer[0] != 'c') && (pcRxBuffer[0] != 'g') 
+                && (pcRxBuffer[0] != 's') && (pcRxBuffer[0] != 't') && (pcRxBuffer[0] != 'z')) pc.printf("Entry Error!!\r\n");
+            pc.printf("\r\n");
+            pcClrLineBuf();
+        }
+#ifdef RTOS_H
+    }   //RTOS while loop
+#endif
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
 
 int main() {
     pc.baud(230400);
     ctTime = time(NULL);
     StartTime = ctTime;                     //get time we started up
-    pc.printf("\r\n\r\nDS3232M demo  08-DEC-2014  K. Braun\r\n");
+    pc.printf("\r\n\r\nDS3232M demo  19-DEC-2014  K. Braun\r\n");
     
+    //check for RTOS operation
+#ifdef RTOS_H
+    pc.printf("RTOS installed...\r\n");
+#else
+    pc.printf("not using RTOS...\r\n");
+#endif
+
     //pc RX character callback interrupt
     pc.printf("Initializing Serial Port Rx Interrupt...   \r\n");
-    pc.attach(&PcRxIRQnoRTOS, pc.RxIrq);
+    pc.attach(&PcRxIRQ, pc.RxIrq);
     
     pc.printf("Checking the mbed's RTC...\r\n");
-    wait_ms(1.5);
+#ifdef RTOS_H
+    Thread::wait(1500);
+#else
+    wait_ms(1500);
+#endif
+
     ctTime = time(NULL);
     
     //first, see if K64F's RTC already running
     if((StartTime == ctTime) || (ctTime <= 1000000000)) {
+        pc.printf("*** mbed's local RTC is not initialized\r\n");
         loadRTC();
         StartTime = ctTime;
         
@@ -269,30 +366,38 @@
     //get the DS3232's temperature
     Get3232Temp();
     
+#ifdef RTOS_H
+    //turn on the rest of the os threads
+    pc.printf("Initializing os threads...\r\n");
+    Thread th3(cli_thread, NULL, osPriorityNormal);
+    Thread::wait(300);
+#endif
+    
     int CheckTime = ctTime;
     pc.printf("Hit 'A' or 'a' key to turn on/off the 32KHz output\r\n");
     pc.printf("Hit 'B' or 'b' key to turn on/off the 1Hz output (1Hz pin needs pull-up)\r\n");
+    pc.printf("Hit 'c' key to change the time in the DS3232's\r\n");
+    pc.printf("Hit 'g' key to get the data string from DS3232 user RAM\r\n");
+    pc.printf("Hit 's' key to store a data string in the DS3232 user RAM\r\n");
     pc.printf("Hit 't' key to get the DS3232's temperature\r\n");
-    pc.printf("Hit any other key to change the RTC\r\n\r\n");
+    pc.printf("Hit 'z' key to get the user RAM CRC data\r\n");
+    pc.printf("Hit '^C' key to reboot\r\n");
+    pc.printf("\r\n");
     
     //Ready!!
     while (true) {
-        wait_ms(200);
+#ifdef RTOS_H
+        Thread::wait(50);
+#else
+        wait_ms(50);
+#endif
         UpdateTime();
         if(CheckTime != ctTime) {
             CheckTime = ctTime;
-            pc.printf("%s", DOUPONELINE);
-            PrintDateTime();
+            if(allowDisplayTime == false) PrintDateTime();
         }
-        if(pcRxQty != 0) {
-            if(pcRxBuffer[0] == 'A') rtc.set32KhzOutput(true, false);   //turn on 32KHz output
-            if(pcRxBuffer[0] == 'a') rtc.set32KhzOutput(false, false);  //turn off 32KHz output
-            if(pcRxBuffer[0] == 'B') rtc.set1hzOutput(true, false);   //turn on 1Hz output
-            if(pcRxBuffer[0] == 'b') rtc.set1hzOutput(false, false);  //turn off 1Hz output
-            if(pcRxBuffer[0] == 't') Get3232Temp();  //display the DS3232's temperature
-            if((pcRxBuffer[0] != 'a') && (pcRxBuffer[0] != 'A') && (pcRxBuffer[0] != 'b') && (pcRxBuffer[0] != 'B') && (pcRxBuffer[0] != 't') && (SetRTC() != 0)) pc.printf("Entry Error!!");
-            pc.printf("\r\n\r\n");
-            pcClrLineBuf();
-        }
+#ifndef RTOS_H
+        cli_thread();
+#endif      
     }
 }
\ No newline at end of file