Enter Standby mode then wake up(only restart) by RTC timer

Dependencies:   WakeUp_STM32

/users/kenjiArai/notebook/standby-mode-current-consumption-on-nucleo-f446re/

IDD Jumper(JP6)
ModeMbed-OSBoardIDD Current(sleep)IDD Current(Normal(*1))
DeepSleep0s5.15.1Nucleo-L152RE4.23uA5mA to 8mA
^0s6.6.0^4.22uA4mA to 7mA
StandBy0s5.15.1^3.90uA4mA to 7mA
^0s6.6.0^3.90uA4mA to 7mA
DeepSleep0s5.15.1Nucleo-L476RG2.13uA7mA to 10mA
^0s6.6.0^2.23uA7mA to 10mA
StandBy0s5.15.1^-uA(*2)-mA(*2)
^0s6.6.0^-uA(*2)-mA(*2)
DeepSleep0s5.15.1Nucleo-F411RE1.91mA(*3)7mA to 10mA
^0s6.6.0^1.65mA(*3)7mA to 10mA
StandBy0s5.15.1^3.35uA7mA to 10mA
^0s6.6.0^3.40uA7mA to 9mA
DeepSleep0s5.15.1Nucleo-F446RE1.67mA(*3)14mA to 17mA
^0s6.6.0^1.76mA(*3)14mA to 16mA
StandBy0s5.15.1^3.42uA14mA to 17mA
^0s6.6.0^3.42uA14mA to 16mA

(*1)-> LED1 Blinky every 1sec and change LED1 current
(*2)-> Could NOT make proper program and could NOT measure
(*3)-> NOT uA but mA
All Nucleo boards are stand alone condition(not additional circuit).
Equipment: DMM6500

/users/kenjiArai/code/Check_DeepSleep_os5/
/users/kenjiArai/code/Check_DeepSleep_os6/
/users/kenjiArai/code/Check_StandBy_os5/
/users/kenjiArai/code/Check_StandBy_os6/

Revision:
4:bee93f6bae20
Parent:
3:4cdb02c5bd94
Child:
5:37c4c47a5546
--- a/main.cpp	Fri Mar 13 03:33:37 2020 +0000
+++ b/main.cpp	Sat Jan 16 06:13:48 2021 +0000
@@ -1,25 +1,35 @@
 /*
  * Mbed Application program
- *  Check Deep Sleep Mode
+ *  Check Standby Mode
  *
- * Copyright (c) 2020 Kenji Arai / JH1PJL
+ * Copyright (c) 2020,'21 Kenji Arai / JH1PJL
  *  http://www7b.biglobe.ne.jp/~kenjia/
  *  https://os.mbed.com/users/kenjiArai/
  *      Revised:    March     12th, 2020
- *      Revised:    March     13th, 2020
+ *      Revised:    January   16th, 2021
  */
 
 /*
     Reference information:
         https://forums.mbed.com/t/how-to-deep-sleep/7551
+        https://os.mbed.com/users/kenjiArai/code/Check_DeepSleep_os5/
+        https://os.mbed.com/users/kenjiArai/code/Check_StandBy_os5/
 
-    Tested on
-        Nucleo-F401RE
-        Nucleo-F411RE
-        Nucleo-F446RE
-        Nucleo-L053R8   only os2
-        Nucleo-L073RZ   only os2
-        Nucleo-L152RE
+    DEEP SLEEP MODE (Tested on with mbed-os6.6.0)
+        https://os.mbed.com/users/kenjiArai/code/Check_DeepSleep_os6/
+        Nucleo-L152RE       -> 4.22uA (Normal run = 4mA to 7mA)
+        Nucleo-L476RG       -> 2.23uA (Normal run = 7mA to 10mA)
+        Nucleo-F411RE       -> 1.65mA (not uA)(Normal run = 7mA to 10mA)
+        Nucleo-F446RE       -> 1.76mA (not uA)(Normal run = 14mA to 16mA)
+    STANDBY MODE (Tested on with mbed-os6.6.0)
+        Nucleo-L152RE       -> 3.90uA (Normal run = 4mA to 7mA)
+        Nucleo-L476RG       -> not work until today
+        Nucleo-F411RE       -> 3.40uA (Normal run = 7mA to 9mA)
+        Nucleo-F446RE       -> 3.42uA (Normal run = 14mA to 16mA)
+
+        Current Measurement:
+         Nucleo board has IDD Jumper (JP6).
+         I measured CPU current using Digital Multi-meter DCI mode.
  */
 
 //  Include --------------------------------------------------------------------
@@ -27,19 +37,11 @@
 #include "WakeUp.h"
 
 //  Definition -----------------------------------------------------------------
-//      https://keisan.casio.jp/exec/system/1526003938
-#define DATE_20200222_222222    1582377742      // 2020/2/22 22:22:22 
-
-#if (MBED_MAJOR_VERSION == 5)
-#define WAIT_MS(x)  ThisThread::sleep_for(x)
-#else
-#define WAIT_MS(x)  wait_ms(x)
-#endif
 
 //  Constructor ----------------------------------------------------------------
 DigitalIn   my_sw(USER_BUTTON);
 DigitalOut  myled(LED1,1);
-Serial      pc(USBTX, USBRX);
+static BufferedSerial pc(USBTX, USBRX, 9600);
 AnalogIn    a_in(A0);
 Timer       t;
 
@@ -48,12 +50,11 @@
 //  ROM / Constant data --------------------------------------------------------
 
 //  Function prototypes --------------------------------------------------------
-void sw_irq(void);
-void time_enter_mode(void);
-void chk_and_set_time(char *ptr);
-int32_t  xatoi (char **str, int32_t *res);
-void get_line (char *buff, int len);
-void print_revision(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);
+extern void print_revision(void);
 
 //------------------------------------------------------------------------------
 //  Control Program
@@ -66,20 +67,15 @@
     uint32_t loop_count = 1;
     float ain;
 
-    printf("\r\nCheck current consumption at Deep-sleep mode.\r\n");
+    printf("\r\nCheck current consumption at Standby mode.\r\n");
     print_revision();
     seconds = time(NULL);
-    if (seconds < DATE_20200222_222222) {
-        strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
-        pc.printf("[Time] %s\r\n", buf);
-        time_enter_mode();
-    }
     while (my_sw == 0) {;}
-    WAIT_MS(10);
+    ThisThread::sleep_for(10ms);
     while (true) {
         t.reset();
         t.start();
-        if ((my_sw == 0) || (loop_count > 20)) {
+        if ((my_sw == 0) || (loop_count > 10)) {
             DigitalIn dmy0(LED1);
             DigitalIn dmy1(USBTX);
             DigitalIn dmy2(USBRX);
@@ -90,99 +86,48 @@
         myled = !myled;
         seconds = time(NULL);
         strftime(buf, 50, "%H:%M:%S -> ", localtime(&seconds));
-        pc.printf("%s", buf);
-        pc.printf(
-            "analog = %4.3f, loop_time=%3d, counter=%4d\r\n",
+        printf("%s", buf);
+        printf(
+            "analog = %4.3f, processing time=%3d, counter=%4d\r\n",
             ain, t_pass, loop_count++
         );
-        t_pass = t.read_ms();
-        WAIT_MS(1000 - t_pass);
+        t_pass = chrono::duration_cast<chrono::milliseconds>(
+                               t.elapsed_time()).count();
+        ThisThread::sleep_for(chrono::milliseconds(1000 - t_pass));
+        if (pc.readable()) {
+            strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
+            printf("[Time] %s\r\n", buf);
+            time_enter_mode();
+        }
     }
 }
 
-void time_enter_mode(void)
+
+static void time_enter_mode(void)
 {
     char *ptr;
     char linebuf[64];
 
-    pc.printf("\r\nSet time into RTC\r\n");
-    pc.printf(" e.g. >20 2 22 22 22 22 -> February 22,'20, 22:22:22\r\n");
-    pc.putc('>');
+    if (pc.readable()) {
+        pc.read(linebuf, 1);    // dummy read
+    }
+    puts("\r\nSet time into RTC");
+    puts(" e.g. >21 1 12 13 14 15 -> January 12,'21, 13:14:14");
+    linebuf[0] = '>';
+    pc.write(linebuf, 1);
     ptr = linebuf;
     get_line(ptr, sizeof(linebuf));
-    pc.printf("\r");
+    puts("\r");
     chk_and_set_time(ptr);
 }
 
-void get_line (char *buff, int len)
-{
-    char c;
-    uint32_t idx = 0;
-
-    while(true) {
-        c = pc.getc();
-        if (c == '\r') {
-            buff[idx++] = c;
-            break;
-        }
-        if ((c == '\b') && idx) {
-            idx--;
-            pc.putc(c);
-            pc.putc(' ');
-            pc.putc(c);
-        }
-        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
-            buff[idx++] = c;
-            pc.putc(c);
-        }
-    }
-    buff[idx] = 0;
-    pc.puts("\r\n");
-}
-
-void chk_and_set_time(char *ptr)
+//  Change string -> integer
+static int32_t xatoi(char **str, int32_t *res)
 {
-    int32_t p1;
-    struct tm t;
-    time_t seconds;
-
-    if (xatoi(&ptr, &p1)) {
-        t.tm_year       = (uint8_t)p1 + 100;
-        pc.printf("Year:%d ",p1);
-        xatoi( &ptr, &p1 );
-        t.tm_mon        = (uint8_t)p1 - 1;
-        pc.printf("Month:%d ",p1);
-        xatoi( &ptr, &p1 );
-        t.tm_mday       = (uint8_t)p1;
-        pc.printf("Day:%d ",p1);
-        xatoi( &ptr, &p1 );
-        t.tm_hour       = (uint8_t)p1;
-        pc.printf("Hour:%d ",p1);
-        xatoi( &ptr, &p1 );
-        t.tm_min        = (uint8_t)p1;
-        pc.printf("Min:%d ",p1);
-        xatoi( &ptr, &p1 );
-        t.tm_sec        = (uint8_t)p1;
-        pc.printf("Sec: %d \r\n",p1);
-    } else {
-        return;
-    }
-    seconds = mktime(&t);
-    set_time(seconds);
-    pc.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
-    );
-}
-
-int32_t xatoi (char **str, int32_t *res)
-{
-    int32_t val;
+    uint32_t val;
     uint8_t c, radix, s = 0;
 
-    while ((c = **str) == ' ') {
-        (*str)++;
-    }
+    while ((c = **str) == ' ') (*str)++;
     if (c == '-') {
         s = 1;
         c = *(++(*str));
@@ -203,7 +148,7 @@
             } else {
                 if ((c >= '0')&&(c <= '9')) {
                     radix = 8;
-                } else {
+                }   else {
                     return 0;
                 }
             }
@@ -216,25 +161,96 @@
     }
     val = 0;
     while (c > ' ') {
-        if (c >= 'a') {
-            c -= 0x20;
-        }
+        if (c >= 'a') c -= 0x20;
         c -= '0';
         if (c >= 17) {
             c -= 7;
-            if (c <= 9) {
-                return 0;
-            }
+            if (c <= 9) return 0;
         }
-        if (c >= radix) {
-            return 0;
-        }
+        if (c >= radix) return 0;
         val = val * radix + c;
         c = *(++(*str));
     }
-    if (s) {
-        val = -val;
-    }
+    if (s) val = -val;
     *res = val;
     return 1;
 }
+
+//  Get key input data
+static void get_line(char *buff, int32_t len)
+{
+    char c;
+    char bf[8];
+    int32_t idx = 0;
+
+    for (;;) {
+        pc.read(bf, 1);
+        c = bf[0];
+        //printf("0x%x \r\n", c);
+        if (c == '\r') {
+            buff[idx++] = c;
+            break;
+        }
+        if ((c == '\b') && idx) {
+            idx--;
+            const char bf_bs[] =
+            {0x1b, '[', '1', 'D', ' ', 0x1b, '[', '1', 'D'};
+            pc.write(bf_bs, 9);
+        }
+        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
+            buff[idx++] = c;
+            pc.write(bf, 1);
+        }
+    }
+    buff[idx] = 0;
+    bf[0] = '\n';
+    pc.write(bf, 1);
+}
+
+//  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);
+    } else {
+        return;
+    }
+    seconds = mktime(&t);
+    set_time(seconds);
+    // 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);
+}