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/

main.cpp

Committer:
kenjiArai
Date:
2017-09-21
Revision:
1:abe49c3395cd
Parent:
0:1672d0903bdc
Child:
2:281dbfae5cd0

File content as of revision 1:abe49c3395cd:

/*
 * Mbed Application program / check StandBy function
 *
 * Copyright (c) 2017 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created:    September 19th, 2017
 *      Revised:    September 21st, 2017
 */

#if defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F411RE)\
 || defined(TARGET_NUCLEO_F401RE)\
 || defined(TARGET_NUCLEO_L152RE) || defined(TARGET_NUCLEO_L073RZ)\
 || defined(TARGET_NUCLEO_L053R8)
#else
#error "This program does NOT run your target!"
#endif

//  Include --------------------------------------------------------------------
#include "mbed.h"
#include "WakeUp.h"
 
//  Definition -----------------------------------------------------------------
#define TRY_STANDBY_MODE

//  Object ---------------------------------------------------------------------
DigitalOut  myled(LED1);
DigitalOut  out(D7);
Serial      pc(USBTX, USBRX);       // Communication with Host

//  RAM ------------------------------------------------------------------------

//  ROM / Constant data --------------------------------------------------------
char *const msg0  = "Is a time correct? If no, please hit any key. ";
char *const msg1  = "<Push USER SW then enter sleep mode> ";

//  Function prototypes --------------------------------------------------------
static void time_enter_mode(void);
static void chk_and_set_time(char *ptr);
static int  xatoi (char **str, unsigned long *res);
static void get_line (char *buff, int len);
#ifndef TRY_STANDBY_MODE
static void wakeup_action(void);
#endif

//------------------------------------------------------------------------------
//  Control Program
//------------------------------------------------------------------------------
int main() {
    char buf[64];               // data buffer for text
    time_t seconds;
    uint32_t count = 0;

    pc.printf("\r\nStart program\r\n");
    while(true){
        seconds = time(NULL);
        strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
        pc.printf("[Time] %s", buf);
        pc.printf(msg0);
        pc.printf("%s\r", msg1);
        while (seconds == time(NULL)){;}
        if (pc.readable() == 1){
            buf[0] = pc.getc();  // dummy read
            time_enter_mode();
            break;
        }
        uint8_t n = strlen(msg0) + strlen(msg1);
        for (uint8_t i = 0; i < n; i++){
            pc.putc(' ');
        }
        pc.printf("      \r"); // Not use '\n'
        if(++count >= 9){
            break;
        }
    }
    seconds = time(NULL);
    strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
    pc.printf("[Time] %s", buf);
#ifdef TRY_STANDBY_MODE
    pc.printf("Check Stand-By function using internal RTC\r\n");
#else
    pc.printf("Check Deep Sleep function using internal RTC\r\n");
#endif
    wait(1);
#ifdef TRY_STANDBY_MODE
    while(true){
        WakeUp::standby_then_reset(10000);
        // not come to here
        while(true){;}
    }
#else
    WakeUp::attach(wakeup_action);
    uint32_t n = 0;
    while(true){
        pc.printf("main_Step(%u)\r\n", __LINE__);
        myled = 0;
        WakeUp::set_ms(6000);
        deepsleep();
        myled = 1;
        wait(4);
        pc.printf("\r\nmain_Step(%u)\r\n", __LINE__);
        if (++n >= 5){
            NVIC_SystemReset();
        }
    }
#endif
}

#ifndef TRY_STANDBY_MODE
void wakeup_action()
{
    out = !out;
}
#endif

void time_enter_mode(void)
{
    char *ptr;
    char linebuf[64];

    pc.printf("\r\nSet time into RTC\r\n");
    pc.printf(" e.g. >17 1 16 20 55 23 -> January 16th,'17, 20:55:23\r\n");
    pc.printf(" If time is fine, just hit enter\r\n");
    pc.putc('>');
    ptr = linebuf;
    get_line(ptr, sizeof(linebuf));
    pc.printf("\r");
    chk_and_set_time(ptr);
}

//  Get key input data
void get_line (char *buff, int len)
{
    char c;
    int idx = 0;

    for (;;) {
        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.putc('\n');
}

void chk_and_set_time(char *ptr)
{
    unsigned long 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
    );
}

//  Change string -> integer
int xatoi (char **str, unsigned long *res)
{
    unsigned long val;
    unsigned char 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;
}