mbed library sources for GR-PEACH rev.B.

Fork of mbed-src by mbed official

Revision:
174:8bb9f3a33240
Parent:
129:0182c99221bc
Child:
216:577900467c9e
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/rtc_api.c	Mon Apr 28 18:15:06 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/rtc_api.c	Tue Apr 29 11:15:07 2014 +0100
@@ -29,36 +29,63 @@
  */
 #include "rtc_api.h"
 
+#if DEVICE_RTC
+
+#include "wait_api.h"
+
+#define LSE_STARTUP_TIMEOUT ((uint16_t)400) // 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_RTCAccessCmd(ENABLE); // Enable access to RTC
+    PWR_RTCAccessCmd(ENABLE); // Enable access to Backup domain
+
+    // Reset RTC and Backup registers
+    RCC_RTCResetCmd(ENABLE);
+    RCC_RTCResetCmd(DISABLE);
+
+    // Enable LSE clock
+    RCC_LSEConfig(RCC_LSE_ON);
 
-    // Note: the LSI is used as RTC source clock
-    // The RTC Clock may vary due to LSI frequency dispersion.  
-   
-    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_RTCCLKCmd(ENABLE); // Enable RTC Clock 
-      
-    RTC_WaitForSynchro(); // Wait for RTC registers synchronization
+    // Wait till LSE is ready
+    do {
+        LSEStatus = RCC_GetFlagStatus(RCC_FLAG_LSERDY);
+        wait_ms(1);
+        StartUpCounter++;
+    } while ((LSEStatus == 0) && (StartUpCounter <= LSE_STARTUP_TIMEOUT));
 
-    uint32_t lsi_freq = 40000; // [TODO] To be measured precisely using a timer input capture
+    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 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;
+    }
 
     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_RTCAccessCmd(DISABLE); // Disable access to RTC
-      
+
+    RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
+
+    RTC_WaitForSynchro(); // Wait for RTC registers synchronization
+
+    PWR_RTCAccessCmd(DISABLE); // Disable access to Backup domain
+
     rtc_inited = 1;
 }
 
@@ -92,11 +119,11 @@
     RTC_DateTypeDef dateStruct;
     RTC_TimeTypeDef timeStruct;
     struct tm timeinfo;
-        
+
     // Read actual date and time
     RTC_GetTime(RTC_Format_BIN, &timeStruct);
     RTC_GetDate(RTC_Format_BIN, &dateStruct);
-    
+
     // Setup a tm structure based on the RTC
     timeinfo.tm_wday = dateStruct.RTC_WeekDay;
     timeinfo.tm_mon  = dateStruct.RTC_Month - 1;
@@ -105,11 +132,11 @@
     timeinfo.tm_hour = timeStruct.RTC_Hours;
     timeinfo.tm_min  = timeStruct.RTC_Minutes;
     timeinfo.tm_sec  = timeStruct.RTC_Seconds;
-    
+
     // Convert to timestamp
     time_t t = mktime(&timeinfo);
-    
-    return t;    
+
+    return t;
 }
 
 void rtc_write(time_t t) {
@@ -118,7 +145,7 @@
 
     // Convert the time into a tm
     struct tm *timeinfo = localtime(&t);
-    
+
     // Fill RTC structures
     dateStruct.RTC_WeekDay = timeinfo->tm_wday;
     dateStruct.RTC_Month   = timeinfo->tm_mon + 1;
@@ -128,10 +155,12 @@
     timeStruct.RTC_Minutes = timeinfo->tm_min;
     timeStruct.RTC_Seconds = timeinfo->tm_sec;
     timeStruct.RTC_H12     = RTC_HourFormat_24;
-    
+
     // Change the RTC current date/time
-    PWR_RTCAccessCmd(ENABLE); // Enable access to RTC    
+    PWR_RTCAccessCmd(ENABLE); // Enable access to Backup domain
     RTC_SetDate(RTC_Format_BIN, &dateStruct);
-    RTC_SetTime(RTC_Format_BIN, &timeStruct);    
-    PWR_RTCAccessCmd(DISABLE); // Disable access to RTC
+    RTC_SetTime(RTC_Format_BIN, &timeStruct);
+    PWR_RTCAccessCmd(DISABLE); // Disable access to Backup domain
 }
+
+#endif