mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Revision:
241:ffe41b0c8126
Parent:
157:90e3acc479a2
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F303VC/rtc_api.c	Thu Jun 26 09:45:08 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_DISCO_F303VC/rtc_api.c	Thu Jun 26 10:30:09 2014 +0100
@@ -29,42 +29,77 @@
  */
 #include "rtc_api.h"
 
+#if DEVICE_RTC
+
+#include "wait_api.h"
+
+#define LSE_STARTUP_TIMEOUT ((uint16_t)500) // delay in ms
+
 static int rtc_inited = 0;
 
 void rtc_init(void) {
+    uint32_t StartUpCounter = 0;
+    uint32_t LSEStatus = 0;
+    uint32_t rtc_freq = 0;
+
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock
 
-    PWR_BackupAccessCmd(ENABLE); // Enable access to RTC
+    PWR_BackupAccessCmd(ENABLE); // Enable access to Backup domain
 
-    // Be sure to start correctly
+    // Reset back up registers
     RCC_BackupResetCmd(ENABLE);
     RCC_BackupResetCmd(DISABLE);
   
-    // Note: the LSI is used as RTC source clock
+    // Enable LSE clock
+    RCC_LSEConfig(RCC_LSE_ON);
+
+    // Wait till LSE is ready
+    do {
+        LSEStatus = RCC_GetFlagStatus(RCC_FLAG_LSERDY);
+        wait_ms(1);
+        StartUpCounter++;
+    } while ((LSEStatus == 0) && (StartUpCounter <= LSE_STARTUP_TIMEOUT));
+
+    if (StartUpCounter > LSE_STARTUP_TIMEOUT) {
+        // The LSE has not started, use LSI instead.
     // The RTC Clock may vary due to LSI frequency dispersion.
+        RCC_LSEConfig(RCC_LSE_OFF);
     RCC_LSICmd(ENABLE); // Enable LSI
-  
     while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready
-    
-    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source
+        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select the RTC Clock Source
+        rtc_freq = 40000; // [TODO] To be measured precisely using a timer input capture
+    } else {
+        // The LSE has correctly started
+        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select the RTC Clock Source
+        rtc_freq = LSE_VALUE;
+    }
   
     RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock 
       
     RTC_WaitForSynchro(); // Wait for RTC registers synchronization
 
-    uint32_t lsi_freq = 40000; // [TODO] To be measured precisely using a timer input capture
-
     RTC_InitTypeDef RTC_InitStructure;
     RTC_InitStructure.RTC_AsynchPrediv = 127;
-    RTC_InitStructure.RTC_SynchPrediv	 = (lsi_freq / 128) - 1;
+    RTC_InitStructure.RTC_SynchPrediv    = (rtc_freq / 128) - 1;
     RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
     RTC_Init(&RTC_InitStructure);
     
+    PWR_BackupAccessCmd(DISABLE); // Disable access to Backup domain
+
     rtc_inited = 1;
 }
 
 void rtc_free(void) {
-    RCC_DeInit(); // Resets the RCC clock configuration to the default reset state
+    // Reset RTC
+    PWR_BackupAccessCmd(ENABLE); // Enable access to Backup Domain
+    RTC_DeInit();
+    RCC_BackupResetCmd(ENABLE);
+    RCC_BackupResetCmd(DISABLE);
+    // Disable RTC, LSE and LSI clocks
+    RCC_RTCCLKCmd(DISABLE);
+    RCC_LSEConfig(RCC_LSE_OFF);
+    RCC_LSICmd(DISABLE);
+
     rtc_inited = 0;
 }
 
@@ -136,3 +171,5 @@
     RTC_SetTime(RTC_Format_BIN, &timeStruct);    
     PWR_BackupAccessCmd(DISABLE); // Disable access to RTC
 }
+
+#endif