Solution how to fix broken RTC on Nucleo_F103RB / STM32F103 BluePill etc..

Dependencies:   mbed-dev

Fork of Nucleo_RTC_battery_bkup_pwr_off_okay by Kenji Arai

Experimental fork https://os.mbed.com/users/kenjiArai/code/Nucleo_RTC_battery_bkup_pwr_off_okay/ to fix broken RTC on Nucleo_F103RB / STM32F103 BluePill etc..

At this moment (7/11/17) use forked mbed-dev https://os.mbed.com/users/maxxir/code/mbed-dev/.

Or require patch for ./mbed-dev/targets/TARGET_STM/rtc_api.c.

You can manual add to your project fresh mbed-dev and change file mbed-dev\targets\TARGET_STM\rtc_api.c from root project patched rtc_api.c.stm32f10x.txt.

Exploring origin errors, I saw that something wrong with HAL API on STM32F1xx with this functions:

 HAL_RTC_GetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN);

 HAL_RTC_GetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN);


 HAL_RTC_SetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN);

 HAL_RTC_SetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN);

Look here (as I understand it possible broken on STM32CUBE HAL level now):

https://community.st.com/thread/43218-stm32f103-loss-rtc-date-when-reset

So I use direct RTC register manipulation for STM32F1xx:

rtc_read(), rtc_write() (native rtc_init() - works good).

Also added stub for non-working on STM32F1xx rtc_read_subseconds().

Now the stm32F103 can survive power off, and allows you to get and set the time.

Tested OK on boards:

NUCLEO STM32F103RB, DIY STM32F100CB (forked from DISCO_F100RB)

Happy coding!

maxxir

10/11/17

Revision:
1:7a48c475bbd2
Parent:
0:0751c92c0f71
Child:
2:77ec44bf1fa5
--- a/main.cpp	Sat Feb 07 03:18:40 2015 +0000
+++ b/main.cpp	Sat Feb 14 11:35:34 2015 +0000
@@ -6,7 +6,7 @@
  *  http://www.page.sannet.ne.jp/kenjia/index.html
  *  http://mbed.org/users/kenjiArai/
  *      Created: January   17th, 2015
- *      Revised: Feburary   7th, 2015
+ *      Revised: Feburary  14th, 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
@@ -18,6 +18,7 @@
 //  Include ---------------------------------------------------------------------------------------
 #include "mbed.h"
 #include "TextLCD.h"
+ // MUST -> need to modify rtc_api.c, please refer SetRTC.h file [CATION] and modify_info_xxx.h
 #include "SetRTC.h"
 
 //  Definition ------------------------------------------------------------------------------------
@@ -25,6 +26,11 @@
 
 #define USE_LCD
 
+#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE)
+#else
+#error "Target is only Nucleo F401RE, F411RE and L152RE"
+#endif
+
 //  Object ----------------------------------------------------------------------------------------
 DigitalIn userSW(USER_BUTTON);
 DigitalOut myled(LED1);         // Indicate the sampling period
@@ -73,7 +79,7 @@
     }
     show_RTC_reg(); // only for debug purpose
     while(1) {
-        myled = !myled;
+        myled = 1;
         seconds = time(NULL);
         strftime(buf, 40, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
         pc.printf("[Time] %s", buf);
@@ -88,7 +94,7 @@
         if (counter){
             --counter;
             //      012345678901234567890123456789012345678901234567890123456789012
-            pc.printf("Is time correct? If okay, nothing. If not, please hit any key.\r");
+            pc.printf("Is time correct? If no, hit any key.\r");
             wait(1.0);
             if (pc.readable() == 1){
                 buf[0] = pc.getc();  // dummy read
@@ -110,7 +116,8 @@
 #endif
             pc.printf("\r\nEnter Deep Sleep Mode, please push RESET to wake-up\r\n");
             wait(1.0);
-            myled = 0;       
+            myled = 0;
+            deepsleep_preparation();      
             deepsleep();
         }
     }