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:
6:ef7d2c83034d
Parent:
5:1a8e7aed053d
Child:
7:fa32602e23ec
Child:
9:1af4e107ca7b
diff -r 1a8e7aed053d -r ef7d2c83034d SetRTC.cpp
--- a/SetRTC.cpp	Wed Feb 18 09:14:28 2015 +0000
+++ b/SetRTC.cpp	Thu Feb 19 02:56:12 2015 +0000
@@ -7,7 +7,7 @@
  *  http://www.page.sannet.ne.jp/kenjia/index.html
  *  http://mbed.org/users/kenjiArai/
  *      Created:  October   24th, 2014
- *      Revised:  Feburary  18th, 2015
+ *      Revised:  Feburary  19th, 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
@@ -61,11 +61,11 @@
 //-------------------------------------------------------------------------------------------------
 int32_t SetRTC()
 {
-    if (rtc_external_osc_init() == OK) {
+    if (rtc_external_osc_init() == 1) {
         set_5v_drop_detect();
-        return OK;
+        return 1;
     } else {
-        return NG;
+        return 0;
     }
 }
 
@@ -80,36 +80,50 @@
     PWR->CR |= PWR_CR_DBP;
     // Wait for Backup domain Write protection disable
     timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
+    PRINTF("Time-Out %d\r\n", timeout);
     while((PWR->CR & PWR_CR_DBP) == RESET) {
         if(HAL_GetTick() >= timeout) {
             PRINTF("Time-Out 1\r\n");
-            return NG;
+            return 0;
+        } else {
+            PRINTF("GetTick: %d\r\n",HAL_GetTick());
         }
     }
     // Reset LSEON and LSEBYP bits before configuring the LSE ----------------
     __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
     // Get timeout
     timeout = HAL_GetTick() + TIMEOUT;
+    PRINTF("Time-Out %d\r\n", 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;
+            return 0;
+        } else {
+            PRINTF("GetTick: %d\r\n",HAL_GetTick());
         }
     }
     // Set the new LSE configuration -----------------------------------------
     __HAL_RCC_LSE_CONFIG(RCC_LSE_ON);
     // Get timeout
     timeout = HAL_GetTick() + TIMEOUT;
+    PRINTF("Time-Out %d\r\n", timeout);
     // Wait till LSE is ready
+#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
+    while((RCC->BDCR & 0x02) != 2){
+#else
     while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
+#endif
+//    while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
         if(HAL_GetTick() >= timeout) {
             PRINTF("Time-Out 3\r\n");
-            return NG;
+            return 0;
+        } else {
+            PRINTF("GetTick: %d\r\n",HAL_GetTick());
         }
     }
-    PRINTF("OK");
-    return OK;
+    PRINTF("OK\r\n");
+    return 1;
 }
 
 int32_t set_RTC_LSI(void)
@@ -131,7 +145,7 @@
     timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
     while((PWR->CR & PWR_CR_DBP) == RESET) {
         if(HAL_GetTick() >= timeout) {
-            return NG;
+            return 0;
         }
     }
     __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
@@ -141,38 +155,63 @@
     // Wait till LSI is ready
     while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) {
         if(HAL_GetTick() >= timeout) {
-            return NG;
+            return 0;
         }
     }
     // Connect LSI to RTC
     __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
     __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
-    return OK;
+    return 1;
 }
 
 int32_t rtc_external_osc_init(void)
 {
+    uint32_t timeout = 0;
+    time_t seconds;
+    uint8_t external_ok = 1;
+
     // Enable Power clock
     __PWR_CLK_ENABLE();
     // Enable access to Backup domain
     HAL_PWR_EnableBkUpAccess();
     // Check backup condition
     if ( check_RTC_backup_reg() ) {
-        return OK;
+#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
+        if ((RCC->BDCR & 0x8307) == 0x8103){
+#else
+        if ((RCC->CSR & 0x430703) == 0x410300) {
+#endif
+        //if (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) {
+            timeout = HAL_GetTick() + TIMEOUT / 5;
+            seconds = time(NULL);
+            while (seconds == time(NULL)){
+                if(HAL_GetTick() >= timeout) {
+                    PRINTF("Not available External Xtal\r\n");
+                    external_ok = 0;
+                    break;
+                }
+            }
+            if (external_ok){
+                PRINTF("OK everything\r\n");
+                return 1;
+            }
+        }
+    }
+    PRINTF("Reset RTC LSE config.\r\n");
+    // Reset Backup domain
+    __HAL_RCC_BACKUPRESET_FORCE();
+    __HAL_RCC_BACKUPRESET_RELEASE();
+    // Enable LSE Oscillator
+    if (set_RTC_LSE() == 1) {
+        // Connect LSE to RTC
+        __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
+        __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
+        PRINTF("Set LSE/External\r\n");
+        return 1;
     } 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;
-        }
+        set_RTC_LSI();
+        PRINTF("Set LSI/Internal\r\n");
+        return 0;
     }
 }
 
@@ -202,7 +241,7 @@
 void show_RTC_reg( void )
 {
     // Show registers
-    pcr.printf( "\r\nShow RTC registers by JH1PJL\r\n" );
+    pcr.printf( "\r\nShow RTC registers\r\n" );
     pcr.printf( " Reg0  =0x%08x, Reg1  =0x%08x\r\n",
                 read_RTC_reg( RTC_BKP_DR0 ),
                 read_RTC_reg( RTC_BKP_DR1 )
@@ -221,9 +260,16 @@
         RTC->WPR, RTC->SSR, RTC->SHIFTR
     );
     pcr.printf(
-        " TSTR  =0x..%06x, TSDR  =0x....%04x, TSSSR =0x....%04x\r\n\r\n",
+        " TSTR  =0x..%06x, TSDR  =0x....%04x, TSSSR =0x....%04x\r\n",
         RTC->TSTR, RTC->TSDR, RTC->TSSSR
     );
+    pcr.printf( "Show RCC registers (only RTC Related reg.)\r\n" );
+#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
+    pcr.printf( " RCC_BDCR=0x...%05x\r\n", RCC->BDCR);
+#else
+    pcr.printf( " RCC_CSR =0x%08x\r\n", RCC->CSR);
+#endif
+    pcr.printf( "\r\n");
 }
 
 //  Change string -> integer