This is a RTC additional function. This is only for Nucleo F401RE & F411RE mbed(Added L152RE, F334R8, L476RG & F746xx). If you connected battery backup circuit for internal RTC, you can make a power-off and reset condition. RTC still has proper time and date.

Dependents:   Nucleo_rtos_sample PB_Emma_Ethernet

Please refer following NOTE information.
/users/kenjiArai/notebook/nucleo-series-rtc-control-under-power-onoff-and-re/

Revision:
0:e4c20fd769f1
Child:
1:3129de8d50ea
Child:
2:765470eab2a6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SetRTC.cpp	Sat Feb 07 02:19:57 2015 +0000
@@ -0,0 +1,379 @@
+/*
+ * mbed Library program
+ *      Check & set RTC function and set proper clock if we can set
+ *      ONLY FOR "Nucleo Board"
+ *
+ *  Copyright (c) 2014-2015 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created:  October   24th, 2014
+ *      Revised:  Feburary   7th, 2015
+ *
+ * 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.
+ */
+
+#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE)
+
+//#define DEBUG         // use Communication with PC(UART)
+
+//  Include ---------------------------------------------------------------------------------------
+#include "mbed.h"
+#include "SetRTC.h"
+
+//  Definition ------------------------------------------------------------------------------------
+#ifdef DEBUG
+#define BAUD(x)         pcr.baud(x)
+#define GETC(x)         pcr.getc(x)
+#define PUTC(x)         pcr.putc(x)
+#define PRINTF(...)     pcr.printf(__VA_ARGS__)
+#define READABLE(x)     pcr.readable(x)
+#else
+#define BAUD(x)         {;}
+#define GETC(x)         {;}
+#define PUTC(x)         {;}
+#define PRINTF(...)     {;}
+#define READABLE(x)     {;}
+#endif
+
+//  Object ----------------------------------------------------------------------------------------
+Serial pcr(USBTX, USBRX);
+
+//  RAM -------------------------------------------------------------------------------------------
+
+//  ROM / Constant data ---------------------------------------------------------------------------
+
+//  Function prototypes ---------------------------------------------------------------------------
+static int32_t set_RTC_LSI(void);
+static int32_t set_RTC_LSE(void);
+static int32_t rtc_external_osc_init(void);
+static uint32_t read_RTC_reg(uint32_t RTC_BKP_DR);
+static uint32_t check_RTC_backup_reg( void );
+static int xatoi (char **str, unsigned long *res);
+static void get_line (char *buff, int len);
+
+//-------------------------------------------------------------------------------------------------
+//  Control Program
+//-------------------------------------------------------------------------------------------------
+int32_t SetRTC()
+{
+    if (rtc_external_osc_init() == OK) {
+        return OK;
+    } else {
+        return NG;
+    }
+}
+
+int32_t set_RTC_LSE(void)
+{
+    uint32_t timeout = 0;
+
+    //---------------------------- LSE Configuration -------------------------
+    // Enable Power Clock
+    __PWR_CLK_ENABLE();
+    // Enable write access to Backup domain
+    PWR->CR |= PWR_CR_DBP;
+    // Wait for Backup domain Write protection disable
+    timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
+    while((PWR->CR & PWR_CR_DBP) == RESET) {
+        if(HAL_GetTick() >= timeout) {
+            PRINTF("Time-Out 1\r\n");
+            return NG;
+        }
+    }
+    // Reset LSEON and LSEBYP bits before configuring the LSE ----------------
+    __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
+    // Get timeout
+    timeout = HAL_GetTick() + TIMEOUT;
+    // Wait till LSE is ready
+    while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) {
+        if(HAL_GetTick() >= timeout) {
+            PRINTF("Time-Out 2\r\n");
+            return NG;
+        }
+    }
+    // Set the new LSE configuration -----------------------------------------
+    __HAL_RCC_LSE_CONFIG(RCC_LSE_ON);
+    // Get timeout
+    timeout = HAL_GetTick() + TIMEOUT;
+    // Wait till LSE is ready
+    while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
+        if(HAL_GetTick() >= timeout) {
+            PRINTF("Time-Out 3\r\n");
+            return NG;
+        }
+    }
+    PRINTF("OK");
+    return OK;
+}
+
+int32_t set_RTC_LSI(void)
+{
+    uint32_t timeout = 0;
+
+    // Enable Power clock
+    __PWR_CLK_ENABLE();
+    // Enable access to Backup domain
+    HAL_PWR_EnableBkUpAccess();
+    // Reset Backup domain
+    __HAL_RCC_BACKUPRESET_FORCE();
+    __HAL_RCC_BACKUPRESET_RELEASE();
+    // Enable Power Clock
+    __PWR_CLK_ENABLE();
+    // Enable write access to Backup domain
+    PWR->CR |= PWR_CR_DBP;
+    // Wait for Backup domain Write protection disable
+    timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
+    while((PWR->CR & PWR_CR_DBP) == RESET) {
+        if(HAL_GetTick() >= timeout) {
+            return NG;
+        }
+    }
+    __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
+    // Enable LSI
+    __HAL_RCC_LSI_ENABLE();
+    timeout = HAL_GetTick() + TIMEOUT;
+    // Wait till LSI is ready
+    while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) {
+        if(HAL_GetTick() >= timeout) {
+            return NG;
+        }
+    }
+    // Connect LSI to RTC
+    __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
+    __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
+    return OK;
+}
+
+int32_t rtc_external_osc_init(void)
+{
+    // Enable Power clock
+    __PWR_CLK_ENABLE();
+    // Enable access to Backup domain
+    HAL_PWR_EnableBkUpAccess();
+    // Check backup condition
+    if ( check_RTC_backup_reg() ) {
+        return OK;
+    } else {
+        // Reset Backup domain
+        __HAL_RCC_BACKUPRESET_FORCE();
+        __HAL_RCC_BACKUPRESET_RELEASE();
+        // Enable LSE Oscillator
+        if (set_RTC_LSE() == OK) {
+            // Connect LSE to RTC
+            __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
+            __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
+            return OK;
+        } else {
+            set_RTC_LSI();
+            return NG;
+        }
+    }
+}
+
+uint32_t read_RTC_reg(uint32_t RTC_BKP_DR)
+{
+    __IO uint32_t tmp = 0;
+
+    // Check the parameters
+    assert_param(IS_RTC_BKP(RTC_BKP_DR));
+    tmp = RTC_BASE + 0x50;
+    tmp += (RTC_BKP_DR * 4);
+    // Read the specified register
+    return (*(__IO uint32_t *)tmp);
+}
+
+// Check RTC Backup registers contents
+uint32_t check_RTC_backup_reg( void )
+{
+    if ( read_RTC_reg( RTC_BKP_DR0 ) == RTC_DAT0 ) {
+        if ( read_RTC_reg( RTC_BKP_DR1 ) == RTC_DAT1 ) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void show_RTC_reg( void )
+{
+    // Show registers
+    pcr.printf( "\r\nShow RTC registers by JH1PJL\r\n" );
+    pcr.printf( " Reg0  =0x%08x, Reg1  =0x%08x\r\n",
+                read_RTC_reg( RTC_BKP_DR0 ),
+                read_RTC_reg( RTC_BKP_DR1 )
+              );
+    pcr.printf( " TR    =0x..%06x, DR    =0x..%06x, CR    =0x..%06x\r\n",
+                RTC->TR, RTC->DR, RTC->CR
+              );
+    pcr.printf( " ISR   =0x...%05x, PRER  =0x..%06x, WUTR  =0x....%04x\r\n",
+                RTC->ISR, RTC->PRER, RTC->WUTR
+              );
+    pcr.printf( " CALIBR=0x....%04x, ALRMAR=0x%08x, ALRMBR=0x%08x\r\n",
+                RTC->CALIBR, RTC->ALRMAR, RTC->ALRMBR
+              );
+    pcr.printf(
+        " WPR   =0x......%02x, SSR   =0x....%04x, SHIFTR=0x....%04x\r\n",
+        RTC->WPR, RTC->SSR, RTC->SHIFTR
+    );
+    pcr.printf(
+        " TSTR  =0x..%06x, TSDR  =0x....%04x, TSSSR =0x....%04x\r\n\r\n",
+        RTC->TSTR, RTC->TSDR, RTC->TSSSR
+    );
+}
+
+//  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 = pcr.getc();
+        if (c == '\r') {
+            buff[idx++] = c;
+            break;
+        }
+        if ((c == '\b') && idx) {
+            idx--;
+            pcr.putc(c);
+            pcr.putc(' ');
+            pcr.putc(c);
+        }
+        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
+            buff[idx++] = c;
+            pcr.putc(c);
+        }
+    }
+    buff[idx] = 0;
+    pcr.putc('\n');
+}
+
+
+// RTC related subroutines
+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;
+        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
+    pcr.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));
+    pcr.printf("Date: %s\r\n", buf);
+    // ex.3
+    strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds));
+    pcr.printf("Date: %s\r\n", buf);
+    // ex.4
+    strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds));
+    pcr.printf("Date: %s\r\n", buf);
+#endif
+}
+
+void time_enter_mode(void)
+{
+    char *ptr;
+    char linebuf[64];
+
+    pcr.printf("\r\nSet time into RTC\r\n");
+    pcr.printf(" e.g. >15 2 7 10 11 12 -> Feb. 7th, '15, 10:11:12\r\n");
+    pcr.printf(" If time is fine, just hit enter\r\n");
+    pcr.putc('>');
+    ptr = linebuf;
+    get_line(ptr, sizeof(linebuf));
+    pcr.printf("\r");
+    chk_and_set_time(ptr);
+}
+
+#else
+#error "No suport this mbed, only for Nucleo mbed"
+#endif
+// defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE)