check program for EPSON RX-8025NB and STM M41T62 external RTC library

Dependencies:   RX8025NB M41T62

Revision:
0:564965644ed2
Child:
1:0fd657a82160
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Aug 07 05:43:59 2020 +0000
@@ -0,0 +1,323 @@
+/*
+ * mbed Application program
+ *      External RTC test program
+ *
+ * Copyright (c) 2020 Kenji Arai / JH1PJL
+ *  http://www7b.biglobe.ne.jp/~kenjia/
+ *  https://os.mbed.com/users/kenjiArai/
+ *      Created: August     7th, 2020
+ *      Revised: August     7th, 2020
+ */
+
+// tested on Nucleo-L476RG board
+
+//  Select target RTC ----------------------------------------------------------
+//#define CHECK_RX8025
+#define CHECK_M41T62
+
+//  Include --------------------------------------------------------------------
+#include "mbed.h"
+#include "redirect_stdio.h"
+#if defined(CHECK_RX8025)
+#   include    "RX8025NB.h"
+#   define      RTC_NO  0
+#elif  defined(CHECK_M41T62)
+#   include    "m41t62_rtc.h"
+#   define      RTC_NO  1
+#endif
+
+
+//  Definition -----------------------------------------------------------------
+#define PUSHED_SW       0           // Active low
+
+#define SLEEP_TIME      2           // 2 minuts(minimum setting)
+
+//  Object ---------------------------------------------------------------------
+DigitalIn userSW(USER_BUTTON);
+DigitalOut myled(LED1);             // Indicate the sampling period
+I2C i2c(D14, D15);
+#if defined(CHECK_RX8025)
+RX8025  ex_rtc(i2c);                // EPSON RX-8025NB
+DigitalIn rtc_irq(A5, PullUp);      // will change to InterruptIn
+#elif  defined(CHECK_M41T62)
+M41T62  ex_rtc(i2c);                // STMicro M41T62
+DigitalIn rtc_irq(A4, PullUp);      // will change to InterruptIn
+#endif
+
+//  RAM ------------------------------------------------------------------------
+
+//  ROM / Constant data --------------------------------------------------------
+const char *const msg0 = "Is a time correct? If no, please hit any key. ";
+const char *const msg1 = "<Push USER SW then enter the Deep Sleep mode> ";
+const char *const rtc_name[2]  = {"RX-8025NB", "M41T62"};
+
+//  Function prototypes --------------------------------------------------------
+static void w_check_rtc_time(void);
+static void time_enter_mode(void);
+static void chk_and_set_time(char *ptr);
+static int32_t xatoi(char **str, int32_t *res);
+static void get_line(char *buff, int32_t len);
+static void rtc_interrut(void);
+
+extern void print_revision(void);
+
+//------------------------------------------------------------------------------
+//  Control Program
+//------------------------------------------------------------------------------
+int main()
+{
+    char buf[64];
+    time_t seconds;
+    uint8_t wait_counter = 0;
+
+    puts("\r\n\r\nTest Nucleo RTC Function.");
+    printf("External RTC is %s\r\n", rtc_name[RTC_NO]);
+    print_revision();
+    myled = !myled;
+    ThisThread::sleep_for(100ms);
+    myled = !myled;
+    ThisThread::sleep_for(100ms);
+    // RTC related preparation
+    //ex_rtc.set_sq_wave(RTC_SQW_NONE);
+    ex_rtc.clear_IRQ();
+    w_check_rtc_time();
+    while(true) {
+        seconds = time(NULL);
+        strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
+        printf("[Time] %s", buf);
+        printf("%s", msg0);
+        printf("%s", msg1);
+        puts("\r");
+        wait_counter = 0;
+        while (seconds == time(NULL)) {
+            if (readable() == 1) {      // Enter time from PC console
+                getc(); // dummy read
+                time_enter_mode();
+            }
+            if (userSW == PUSHED_SW) {  // goto sleep and wake up by RTC timer
+                while (userSW == PUSHED_SW) {
+                    ThisThread::sleep_for(10ms);
+                }
+                printf("Please wait %d minutes to wake-up(Reset).", SLEEP_TIME);
+                puts(" Entered the deep sleep mode. ");
+                ThisThread::sleep_for(1s);
+                myled = 0;
+#if defined(CHECK_RX8025)
+                InterruptIn rtc_irq(A5, PullUp);
+#elif  defined(CHECK_M41T62)
+                InterruptIn rtc_irq(A4, PullUp);
+#endif
+                rtc_irq.fall(&rtc_interrut);
+                ex_rtc.set_next_IRQ(SLEEP_TIME);
+                ThisThread::sleep_for(1s);
+                DigitalIn dmy0(LED1);
+                DigitalIn dmy1(USBTX);
+                DigitalIn dmy2(USBRX);
+                ThisThread::sleep_for(10000s);  // sleep long time
+            }
+            ThisThread::sleep_for(50ms);
+            if (++wait_counter > (2000 / 50)) {
+                break;
+            }
+        }
+        // delete previous strings
+        printf("\033[2A");
+        puts("");   // null
+        uint8_t n = strlen(msg0) + strlen(msg1);
+        memset(buf, ' ', 64);
+        if (n > 64) {
+            n -= 64;
+            puts_wo_cr(buf, 64);
+        }
+        if (n > 64) {
+            puts_wo_cr(buf, 64);
+        } else {
+            puts_wo_cr(buf, n);
+        }
+        printf("\033[G");
+        myled = !myled;
+    }
+}
+
+//  Check External RTC data
+static void w_check_rtc_time(void)
+{
+    time_t seconds_1st, seconds_2nd, diff;
+    struct tm t;
+
+    for (uint32_t i = 0; i < 5; i++) {
+        ex_rtc.read_rtc_std(&t);   // read External RTC data
+        printf("Year:%d ",t.tm_year);
+        printf("Month:%d ",t.tm_mon);
+        printf("Day:%d ",t.tm_mday);
+        printf("Hour:%d ",t.tm_hour);
+        printf("Min:%d ",t.tm_min);
+        printf("Sec: %d \r\n",t.tm_sec);
+        seconds_1st = mktime(&t);
+        ex_rtc.read_rtc_std(&t);   // read External RTC data again (make sure)
+        seconds_2nd = mktime(&t);
+        diff = seconds_2nd - seconds_1st;
+        if ((diff == 0) || (diff == 1)) {
+            break;
+        }
+    }
+    set_time(seconds_2nd);
+}
+
+//  Interrupt for wake up
+static void rtc_interrut(void)
+{
+    system_reset(); // restart from RESET condition
+}
+
+//  Time adjustment
+static void time_enter_mode(void)
+{
+    char *ptr;
+    char linebuf[64];
+
+    puts("Set time into RTC.");
+    puts(" e.g. >20 8 1 12 34 56 -> August 01,'20, 12:34:56");
+    puts(" If time is fine, just hit enter key.");
+    putc('>');
+    ptr = linebuf;
+    get_line(ptr, sizeof(linebuf));
+    puts("\r");
+    chk_and_set_time(ptr);
+}
+
+//  Change string -> integer
+static int32_t xatoi(char **str, int32_t *res)
+{
+    uint32_t val;
+    uint8_t c, radix, s = 0;
+
+    while ((c = **str) == ' ') (*str)++;
+    if (c == '-') {
+        s = 1;
+        c = *(++(*str));
+    }
+    if (c == '0') {
+        c = *(++(*str));
+        if (c <= ' ') {
+            *res = 0;
+            return 1;
+        }
+        if (c == 'x') {
+            radix = 16;
+            c = *(++(*str));
+        } else {
+            if (c == 'b') {
+                radix = 2;
+                c = *(++(*str));
+            } else {
+                if ((c >= '0')&&(c <= '9')) {
+                    radix = 8;
+                }   else {
+                    return 0;
+                }
+            }
+        }
+    } else {
+        if ((c < '1')||(c > '9')) {
+            return 0;
+        }
+        radix = 10;
+    }
+    val = 0;
+    while (c > ' ') {
+        if (c >= 'a') c -= 0x20;
+        c -= '0';
+        if (c >= 17) {
+            c -= 7;
+            if (c <= 9) return 0;
+        }
+        if (c >= radix) return 0;
+        val = val * radix + c;
+        c = *(++(*str));
+    }
+    if (s) val = -val;
+    *res = val;
+    return 1;
+}
+
+//  Get key input data
+static void get_line(char *buff, int32_t len)
+{
+    char c;
+    int32_t idx = 0;
+
+    for (;;) {
+        c = getc();
+        //printf("0x%x \r\n", c);
+        if ((c == '\r') || (c == '\n')) {
+            buff[idx++] = '\r';
+            break;
+        }
+        if ((c == '\b') && idx) {
+            idx--;
+            const char bf_bs[] =
+            {0x1b, '[', '1', 'D', ' ', 0x1b, '[', '1', 'D',0};
+            for(uint32_t i = 0; bf_bs[i] != 0; i++) {
+                putc(bf_bs[i]);
+            }
+        }
+        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
+            buff[idx++] = c;
+            putc(c);
+        }
+    }
+    buff[idx] = 0;
+    putc('\n');
+}
+
+//  Check key input strings and set time
+static void chk_and_set_time(char *ptr)
+{
+    int32_t p1;
+    struct tm t;
+    time_t seconds;
+
+    if (xatoi(&ptr, &p1)) {
+        t.tm_year       = (uint8_t)p1 + 100;
+        printf("Year:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_mon        = (uint8_t)p1 - 1;
+        printf("Month:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_mday       = (uint8_t)p1;
+        printf("Day:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_hour       = (uint8_t)p1;
+        printf("Hour:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_min        = (uint8_t)p1;
+        printf("Min:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_sec        = (uint8_t)p1;
+        printf("Sec: %d \r\n",p1);
+        seconds = mktime(&t);
+        set_time(seconds);
+    } else {
+        seconds = time(NULL);
+    }
+    seconds = time(NULL);
+    struct tm *time_ajd = localtime(&seconds);
+    ex_rtc.write_rtc_std(time_ajd);
+    // Show Time with several example
+    // ex.1
+    printf(
+        "Date: %04d/%02d/%02d, %02d:%02d:%02d\r\n",
+        t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec
+    );
+    char buf[64];
+    // ex.2
+    strftime(buf, 40, "%x %X", localtime(&seconds));
+    printf("Date: %s\r\n", buf);
+    // ex.3
+    strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds));
+    printf("Date: %s\r\n", buf);
+    // ex.4
+    strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds));
+    printf("Date: %s\r\n", buf);
+}