In the past, you need modify rtc_api.c in mbed-dev source code. From this revision, you can just use RTC function all of conditions (Normal, Reset, Stand-by, Power OFF).
Note
From now on, you do NOT need any modification for mbed-dev library because STM team updates rtc_api.c source code and support RTC function under reset & standby condition includes power off condition (You need additional VBAT back-up hardware).
Please refer following NOTE information.
/users/kenjiArai/notebook/nucleo-series-rtc-control-under-power-onoff-and-re/
Revision 9:6a64b0207f72, committed 2017-01-16
- Comitter:
- kenjiArai
- Date:
- Mon Jan 16 09:38:03 2017 +0000
- Parent:
- 8:bf593344668e
- Child:
- 10:806cfec92eb6
- Commit message:
- mbed supports RTC function during RESET & Power ON/OFF. You don't need any modification for mbed library source code. You can just check RTC!!
Changed in this revision
--- a/SetRTC.lib Sat Jul 02 03:08:52 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/users/kenjiArai/code/SetRTC/#78e453d7bb85
--- a/TextLCD.lib Sat Jul 02 03:08:52 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/users/wim/code/TextLCD/#111ca62e8a59
--- a/main.cpp Sat Jul 02 03:08:52 2016 +0000 +++ b/main.cpp Mon Jan 16 09:38:03 2017 +0000 @@ -2,96 +2,88 @@ * mbed Application program * RTC (inside STM32x CPU) test program * - * Copyright (c) 2015,'16 Kenji Arai / JH1PJL + * Copyright (c) 2015,'16,'17 Kenji Arai / JH1PJL * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Created: January 17th, 2015 - * Revised: July 2nd, 2016 + * Revised: January 16th, 2017 * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* mbed library now suports RTC continuous operation at Reset & Power ON/OFF + -------------------------------------------------------------------------- + In the past, rtc_api.c (inside mbed) alway made a reset RTC registers + when user push a reset buttom or terninate a power. + Even if user configures a back-up circuit for RTC, mbed board could not + keep proper time. + I have checked mbed rev.133 and mbed-dev rev.155. */ -// Include --------------------------------------------------------------------------------------- -#include "mbed.h" -#include "TextLCD.h" - // MUST -> need to modify rtc_api.c, please refer SetRTC.h file [CAUTION] and modify_info_xxx.h -#include "SetRTC.h" - -// Definition ------------------------------------------------------------------------------------ -//#define USE_LCD +/* + ----- Tested board ----- + / Reset: / Stanby: / power off and restart: + Nucleo-F401RE / ok / ok / ok (need following Back-up Circuit) + Nucleo-F411RE / ok / ok / ok (need following Back-up Circuit) + Nucleo-F446RE / ok / ok / ok (need following Back-up Circuit) + Nucleo-F334R8 / ok / ok / ok (need following Back-up Circuit) + Nucleo-L476RG / ok / ok / ok (need following Back-up Circuit) + Nucleo-L152RE / ok / ok / no check (Need additional hardware) + Nucleo-L073RZ / ok / ok / no check (Need additional hardware) + Nucleo-L053R8 / ok / ok / no check (Need additional hardware) -#if (defined(TARGET_STM32F401RE) || defined(TARGET_STM32F411RE) \ - || defined(TARGET_STM32L152RE) || defined(TARGET_STM32F334R8) \ - || defined(TARGET_STM32L476RG) \ - || defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) ) -#else -#error "Target is only Nucleo F401RE, F411RE, F334R8, F746xx, L476RG and L152RE" -#endif + < Back-up circuit > + CN7 VIN <- SBD <- 330 Ohm <- CR2032 + - -> CN7 GND + Remove SB45 Zero Ohm resistor + */ +// Include -------------------------------------------------------------------- +#include "mbed.h" + +// Definition ----------------------------------------------------------------- #if (defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG)) #define PUSHED_SW 1 // Active high #else #define PUSHED_SW 0 // Active low #endif -// Object ---------------------------------------------------------------------------------------- +// Object --------------------------------------------------------------------- DigitalIn userSW(USER_BUTTON); DigitalOut myled(LED1); // Indicate the sampling period Serial pc(USBTX, USBRX); -#if defined(USE_LCD) -I2C i2c(D14,D15); // SDA, SCL -TextLCD_I2C_N lcd(&i2c, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) -#endif -DigitalOut pwr_onoff(PA_9); -// RAM ------------------------------------------------------------------------------------------- +// RAM ------------------------------------------------------------------------ -// ROM / Constant data --------------------------------------------------------------------------- +// 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> "; char *const msg2 = "\r\nEnter Standby Mode, please push RESET to wake-up\r\n"; -char *const msg3 = "Time was not updated! External Xtal does NOT oscillate.\r\n"; -char *const msg4 = "Time was not updated! LSI does NOT work.\r\n"; - -// Function prototypes --------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- +// Function prototypes -------------------------------------------------------- +static void time_enter_mode(void); +static void chk_and_set_time(char *ptr); +static void goto_standby(void); +static int xatoi (char **str, unsigned long *res); +static void get_line (char *buff, int len); + +//------------------------------------------------------------------------------ // Control Program -//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ int main() { char buf[64]; // data buffer for text time_t seconds; uint8_t wait_counter = 0; - uint8_t xtal = 0; - pwr_onoff = 1; wait(2.0); -#if defined(USE_LCD) - // lcd - lcd.locate(0, 0); // 1st line top - // 12345678 - lcd.printf(" RTC "); - lcd.locate(0, 1); // 2nd line top - // 12345678 - lcd.puts(" JH1PJL "); - lcd.setContrast(0x14); -#endif pc.printf("\r\n\r\nTest Nucleo RTC Function\r\n"); myled = !myled; - if (SetRTC(0) == 1) { - pc.printf("External"); - xtal = 1; - } else { - pc.printf("Internal"); - xtal = 0; - } - pc.printf(" Xtal for RTC\r\n"); - show_RTC_reg(); // only for debug purpose // waiting for Initial screen myled = 1; wait(1.0); @@ -100,19 +92,7 @@ while(1) { seconds = time(NULL); strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds)); - if (xtal){ - pc.printf("[Time] %s", buf); - } else { - pc.printf("[Time by Internal Clock] %s", buf); - } -#if defined(USE_LCD) - lcd.locate(0, 0); // 1st line top - strftime(buf, 40, "%b%d'%y", localtime(&seconds)); - lcd.printf(buf); - lcd.locate(0, 1); // 2nd line top - strftime(buf, 10, "%H:%M:%S", localtime(&seconds)); - lcd.printf(buf); -#endif + pc.printf("[Time] %s", buf); pc.printf(msg0); pc.printf("%s\r", msg1); wait_counter = 0; @@ -122,14 +102,6 @@ time_enter_mode(); } if (userSW == PUSHED_SW){ -#if defined(USE_LCD) - lcd.locate(0, 0); // 1st line top - // 12345678 - lcd.printf(" Enter "); - lcd.locate(0, 1); // 2nd line top - // 12345678 - lcd.printf(" Sleep " ); -#endif pc.printf(msg2); wait(1.0); myled = 0; @@ -137,11 +109,6 @@ } wait(0.05); if (++wait_counter > (2000 / 50)){ - if (xtal){ - pc.printf(msg3); - } else { - pc.printf(msg4); - } break; } } @@ -153,3 +120,157 @@ myled = !myled; } } + +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); +} + +void goto_standby(void) +{ + deepsleep(); // Not Standby Mode but Deep Sleep Mode +} + +// 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; +} + +// 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); + // Show Time with several example + // ex.1 + 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 + ); +#if 0 + time_t seconds; + char buf[40]; + + seconds = mktime(&t); + // ex.2 + strftime(buf, 40, "%x %X", localtime(&seconds)); + pc.printf("Date: %s\r\n", buf); + // ex.3 + strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds)); + pc.printf("Date: %s\r\n", buf); + // ex.4 + strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds)); + pc.printf("Date: %s\r\n", buf); +#endif +}
--- a/mbed-dev.lib Sat Jul 02 03:08:52 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/mbed-dev/#d6373279a6f1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jan 16 09:38:03 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/99b5ccf27215 \ No newline at end of file
--- a/readme_1st.txt Sat Jul 02 03:08:52 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -Please modify source code in mbed-dev library before using the program. -Refer /SetRTC/modify_info_F4xx.h, modify_info_F334.h, modify_info_L476.h, - modify_info_F746.h and modify_info_L152.h - by JH1PJL \ No newline at end of file