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

Dependencies:   WakeUp_STM32

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Mbed Application program
00003  *  Check Standby Mode
00004  *
00005  * Copyright (c) 2020,'21 Kenji Arai / JH1PJL
00006  *  http://www7b.biglobe.ne.jp/~kenjia/
00007  *  https://os.mbed.com/users/kenjiArai/
00008  *      Revised:    March     12th, 2020
00009  *      Revised:    January   17th, 2021
00010  */
00011 
00012 /*
00013     Reference information:
00014         https://forums.mbed.com/t/how-to-deep-sleep/7551
00015         https://os.mbed.com/users/kenjiArai/code/Check_DeepSleep_os5/
00016         https://os.mbed.com/users/kenjiArai/code/Check_StandBy_os5/
00017 
00018     DEEP SLEEP MODE (Tested on with mbed-os6.6.0)
00019         https://os.mbed.com/users/kenjiArai/code/Check_DeepSleep_os6/
00020         Nucleo-L152RE       -> 4.22uA (Normal run = 4mA to 7mA)
00021         Nucleo-L476RG       -> 2.23uA (Normal run = 7mA to 10mA)
00022         Nucleo-F411RE       -> 1.65mA (not uA)(Normal run = 7mA to 10mA)
00023         Nucleo-F446RE       -> 1.76mA (not uA)(Normal run = 14mA to 16mA)
00024     STANDBY MODE (Tested on with mbed-os6.6.0)
00025         Nucleo-L152RE       -> 3.90uA (Normal run = 4mA to 7mA)
00026         Nucleo-L476RG       -> 0.62uA (Normal run = 7mA to 10mA)
00027         Nucleo-F411RE       -> 3.40uA (Normal run = 7mA to 9mA)
00028         Nucleo-F446RE       -> 3.42uA (Normal run = 14mA to 16mA)
00029         DISCO-L475VG-IOT01A -> 0.58uA (Normal run = 7mA to 9mA)
00030 
00031         Current Measurement:
00032          Nucleo board has IDD Jumper (JP6).
00033          I measured CPU current using Digital Multi-meter DCI mode.
00034  */
00035 
00036 //  Include --------------------------------------------------------------------
00037 #include "mbed.h"
00038 #include "WakeUp.h"
00039 
00040 //  Definition -----------------------------------------------------------------
00041 
00042 //  Constructor ----------------------------------------------------------------
00043 DigitalIn   my_sw(USER_BUTTON);
00044 #if defined(TARGET_DISCO_L475VG_IOT01A)
00045 DigitalOut  myled(LED2,0);
00046 #else
00047 DigitalOut  myled(LED1,1);
00048 #endif
00049 static BufferedSerial pc(USBTX, USBRX, 9600);
00050 AnalogIn    a_in(A0);
00051 Timer       t;
00052 
00053 //  RAM ------------------------------------------------------------------------
00054 
00055 //  ROM / Constant data --------------------------------------------------------
00056 
00057 //  Function prototypes --------------------------------------------------------
00058 static void time_enter_mode(void);
00059 static void chk_and_set_time(char *ptr);
00060 static int32_t xatoi (char **str, int32_t *res);
00061 static void get_line (char *buff, int32_t len);
00062 extern void print_revision(void);
00063 
00064 //------------------------------------------------------------------------------
00065 //  Control Program
00066 //------------------------------------------------------------------------------
00067 int main()
00068 {
00069     time_t seconds;
00070     char buf[64];
00071     uint32_t t_pass = 0;
00072     uint32_t loop_count = 1;
00073     float ain;
00074 
00075     printf("\r\nCheck current consumption at Standby mode.\r\n");
00076     print_revision();
00077     seconds = time(NULL);
00078     while (my_sw == 0) {;}
00079     ThisThread::sleep_for(10ms);
00080     while (true) {
00081         t.reset();
00082         t.start();
00083         if ((my_sw == 0) || (loop_count > 10)) {
00084             DigitalIn dmy0(LED1);
00085             DigitalIn dmy1(USBTX);
00086             DigitalIn dmy2(USBRX);
00087             WakeUp::standby_then_reset(20000);
00088             while(true) {;} // never executing this line
00089         }
00090         ain = a_in.read();
00091         myled = !myled;
00092         seconds = time(NULL);
00093         strftime(buf, 50, "%H:%M:%S -> ", localtime(&seconds));
00094         printf("%s", buf);
00095         printf(
00096             "analog = %4.3f, processing time=%3d, counter=%4d\r\n",
00097             ain, t_pass, loop_count++
00098         );
00099         t_pass = chrono::duration_cast<chrono::milliseconds>(
00100                                t.elapsed_time()).count();
00101         ThisThread::sleep_for(chrono::milliseconds(1000 - t_pass));
00102         if (pc.readable()) {
00103             strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
00104             printf("[Time] %s\r\n", buf);
00105             time_enter_mode();
00106         }
00107     }
00108 }
00109 
00110 
00111 static void time_enter_mode(void)
00112 {
00113     char *ptr;
00114     char linebuf[64];
00115 
00116     if (pc.readable()) {
00117         pc.read(linebuf, 1);    // dummy read
00118     }
00119     puts("\r\nSet time into RTC");
00120     puts(" e.g. >21 1 12 13 14 15 -> January 12,'21, 13:14:14");
00121     linebuf[0] = '>';
00122     pc.write(linebuf, 1);
00123     ptr = linebuf;
00124     get_line(ptr, sizeof(linebuf));
00125     puts("\r");
00126     chk_and_set_time(ptr);
00127 }
00128 
00129 //  Change string -> integer
00130 static int32_t xatoi(char **str, int32_t *res)
00131 {
00132     uint32_t val;
00133     uint8_t c, radix, s = 0;
00134 
00135     while ((c = **str) == ' ') (*str)++;
00136     if (c == '-') {
00137         s = 1;
00138         c = *(++(*str));
00139     }
00140     if (c == '0') {
00141         c = *(++(*str));
00142         if (c <= ' ') {
00143             *res = 0;
00144             return 1;
00145         }
00146         if (c == 'x') {
00147             radix = 16;
00148             c = *(++(*str));
00149         } else {
00150             if (c == 'b') {
00151                 radix = 2;
00152                 c = *(++(*str));
00153             } else {
00154                 if ((c >= '0')&&(c <= '9')) {
00155                     radix = 8;
00156                 }   else {
00157                     return 0;
00158                 }
00159             }
00160         }
00161     } else {
00162         if ((c < '1')||(c > '9')) {
00163             return 0;
00164         }
00165         radix = 10;
00166     }
00167     val = 0;
00168     while (c > ' ') {
00169         if (c >= 'a') c -= 0x20;
00170         c -= '0';
00171         if (c >= 17) {
00172             c -= 7;
00173             if (c <= 9) return 0;
00174         }
00175         if (c >= radix) return 0;
00176         val = val * radix + c;
00177         c = *(++(*str));
00178     }
00179     if (s) val = -val;
00180     *res = val;
00181     return 1;
00182 }
00183 
00184 //  Get key input data
00185 static void get_line(char *buff, int32_t len)
00186 {
00187     char c;
00188     char bf[8];
00189     int32_t idx = 0;
00190 
00191     for (;;) {
00192         pc.read(bf, 1);
00193         c = bf[0];
00194         //printf("0x%x \r\n", c);
00195         if (c == '\r') {
00196             buff[idx++] = c;
00197             break;
00198         }
00199         if ((c == '\b') && idx) {
00200             idx--;
00201             const char bf_bs[] =
00202             {0x1b, '[', '1', 'D', ' ', 0x1b, '[', '1', 'D'};
00203             pc.write(bf_bs, 9);
00204         }
00205         if (((uint8_t)c >= ' ') && (idx < len - 1)) {
00206             buff[idx++] = c;
00207             pc.write(bf, 1);
00208         }
00209     }
00210     buff[idx] = 0;
00211     bf[0] = '\n';
00212     pc.write(bf, 1);
00213 }
00214 
00215 //  Check key input strings and set time
00216 static void chk_and_set_time(char *ptr)
00217 {
00218     int32_t p1;
00219     struct tm t;
00220     time_t seconds;
00221 
00222     if (xatoi(&ptr, &p1)) {
00223         t.tm_year       = (uint8_t)p1 + 100;
00224         printf("Year:%d ",p1);
00225         xatoi( &ptr, &p1 );
00226         t.tm_mon        = (uint8_t)p1 - 1;
00227         printf("Month:%d ",p1);
00228         xatoi( &ptr, &p1 );
00229         t.tm_mday       = (uint8_t)p1;
00230         printf("Day:%d ",p1);
00231         xatoi( &ptr, &p1 );
00232         t.tm_hour       = (uint8_t)p1;
00233         printf("Hour:%d ",p1);
00234         xatoi( &ptr, &p1 );
00235         t.tm_min        = (uint8_t)p1;
00236         printf("Min:%d ",p1);
00237         xatoi( &ptr, &p1 );
00238         t.tm_sec        = (uint8_t)p1;
00239         printf("Sec: %d \r\n",p1);
00240     } else {
00241         return;
00242     }
00243     seconds = mktime(&t);
00244     set_time(seconds);
00245     // Show Time with several example
00246     // ex.1
00247     printf(
00248         "Date: %04d/%02d/%02d, %02d:%02d:%02d\r\n",
00249         t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec
00250     );
00251     char buf[64];
00252     // ex.2
00253     strftime(buf, 40, "%x %X", localtime(&seconds));
00254     printf("Date: %s\r\n", buf);
00255     // ex.3
00256     strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds));
00257     printf("Date: %s\r\n", buf);
00258     // ex.4
00259     strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds));
00260     printf("Date: %s\r\n", buf);
00261 }