mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Revision:
172:2f4f8c56b261
Parent:
125:23cc3068a9e4
Child:
185:e752b4ee7de1
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/rtc_api.c	Fri Apr 25 14:45:06 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/rtc_api.c	Mon Apr 28 16:00:08 2014 +0100
@@ -28,7 +28,9 @@
  *******************************************************************************
  */
 #include "rtc_api.h"
-#include "stm32f4xx_hal.h"
+
+#if DEVICE_RTC
+
 #include "error.h"
 
 static int rtc_inited = 0;
@@ -36,6 +38,9 @@
 static RTC_HandleTypeDef RtcHandle;
 
 void rtc_init(void) {
+    RCC_OscInitTypeDef RCC_OscInitStruct;
+    uint32_t rtc_freq = 0;
+
     if (rtc_inited) return;
     rtc_inited = 1;
 
@@ -44,41 +49,51 @@
     // Enable Power clock
     __PWR_CLK_ENABLE();
 
-    // Allow access to RTC
+    // Enable access to Backup domain
     HAL_PWR_EnableBkUpAccess();
 
     // Reset Backup domain
-    __HAL_RCC_BACKUPRESET_FORCE(); 
+    __HAL_RCC_BACKUPRESET_FORCE();
     __HAL_RCC_BACKUPRESET_RELEASE();
-  
-    // Enable LSI clock
-    RCC_OscInitTypeDef RCC_OscInitStruct;
-    RCC_OscInitStruct.OscillatorType =  RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
-    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
-    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
-    RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
-    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
-        error("RTC error: LSI clock initialization failed."); 
+
+    // Enable LSE Oscillator
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
+    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */
+    RCC_OscInitStruct.LSEState       = RCC_LSE_ON; /* External 32.768 kHz clock on OSC_IN/OSC_OUT */
+    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK)
+    {
+        // Connect LSE to RTC
+        __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
+        __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
+        rtc_freq = LSE_VALUE;
+    } else {
+        // Enable LSI clock
+        RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
+        RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
+        RCC_OscInitStruct.LSEState       = RCC_LSE_OFF;
+        RCC_OscInitStruct.LSIState       = RCC_LSI_ON;
+        if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
+            error("RTC error: LSI clock initialization failed.");
+        }
+        // Connect LSI to RTC
+        __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
+        __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
+        // [TODO] This value is LSI typical value. To be measured precisely using a timer input capture
+        rtc_freq = 32000;
     }
-    
-    // Connect LSI to RTC
-    __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
-    __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
-    
-    // Enable RTC clock
+
+    // Enable RTC
     __HAL_RCC_RTC_ENABLE();
-    
-    // [TODO] This value is LSI typical value. To be measured precisely using a timer input capture
-    uint32_t lsi_freq = 32000;
-    
+
     RtcHandle.Init.HourFormat     = RTC_HOURFORMAT_24;
     RtcHandle.Init.AsynchPrediv   = 127;
-    RtcHandle.Init.SynchPrediv    = (lsi_freq / 128) - 1;
+    RtcHandle.Init.SynchPrediv    = (rtc_freq / 128) - 1;
     RtcHandle.Init.OutPut         = RTC_OUTPUT_DISABLE;
     RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
     RtcHandle.Init.OutPutType     = RTC_OUTPUT_TYPE_OPENDRAIN;
+
     if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
-        error("RTC error: RTC initialization failed."); 
+        error("RTC error: RTC initialization failed.");
     }
 }
 
@@ -86,20 +101,24 @@
     // Enable Power clock
     __PWR_CLK_ENABLE();
 
-    // Allow access to RTC
+    // Enable access to Backup domain
     HAL_PWR_EnableBkUpAccess();
 
     // Reset Backup domain
-    __HAL_RCC_BACKUPRESET_FORCE(); 
+    __HAL_RCC_BACKUPRESET_FORCE();
     __HAL_RCC_BACKUPRESET_RELEASE();
 
-    // Disable LSI clock
+    // Disable access to Backup domain
+    HAL_PWR_DisableBkUpAccess();
+
+    // Disable LSI and LSE clocks
     RCC_OscInitTypeDef RCC_OscInitStruct;
-    RCC_OscInitStruct.OscillatorType =  RCC_OSCILLATORTYPE_LSI;
-    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
-    RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
+    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
+    RCC_OscInitStruct.LSIState       = RCC_LSI_OFF;
+    RCC_OscInitStruct.LSEState       = RCC_LSE_OFF;
     HAL_RCC_OscConfig(&RCC_OscInitStruct);
-    
+
     rtc_inited = 0;
 }
 
@@ -128,14 +147,14 @@
     RTC_DateTypeDef dateStruct;
     RTC_TimeTypeDef timeStruct;
     struct tm timeinfo;
-        
+
     RtcHandle.Instance = RTC;
-  
+
     // Read actual date and time
     // Warning: the time must be read first!
     HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
     HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
-    
+
     // Setup a tm structure based on the RTC
     timeinfo.tm_wday = dateStruct.WeekDay;
     timeinfo.tm_mon  = dateStruct.Month - 1;
@@ -144,11 +163,11 @@
     timeinfo.tm_hour = timeStruct.Hours;
     timeinfo.tm_min  = timeStruct.Minutes;
     timeinfo.tm_sec  = timeStruct.Seconds;
-    
+
     // Convert to timestamp
     time_t t = mktime(&timeinfo);
-    
-    return t;    
+
+    return t;
 }
 
 void rtc_write(time_t t) {
@@ -156,10 +175,10 @@
     RTC_TimeTypeDef timeStruct;
 
     RtcHandle.Instance = RTC;
-  
+
     // Convert the time into a tm
     struct tm *timeinfo = localtime(&t);
-    
+
     // Fill RTC structures
     dateStruct.WeekDay        = timeinfo->tm_wday;
     dateStruct.Month          = timeinfo->tm_mon + 1;
@@ -171,8 +190,10 @@
     timeStruct.TimeFormat     = RTC_HOURFORMAT12_PM;
     timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
     timeStruct.StoreOperation = RTC_STOREOPERATION_RESET;
-  
+
     // Change the RTC current date/time
     HAL_RTC_SetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
     HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
 }
+
+#endif