From 31a099cb104ea4d7d957bb65bbdc7e8edbdbe636 Mon Sep 17 00:00:00 2001
From: barthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>
Date: Mon, 19 Sep 2011 13:54:07 +0000
Subject: RTC. Driver improvements

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3352 35acf78f-673a-0410-8e92-d51de3d6d3f4
---
 os/hal/dox/rtc.dox                     |  9 ++++++++
 os/hal/platforms/STM32/rtc_lld.c       | 41 ++++++++++++++++++++--------------
 os/hal/platforms/STM32F1xx/stm32_rcc.h | 17 +++++++++-----
 3 files changed, 45 insertions(+), 22 deletions(-)

diff --git a/os/hal/dox/rtc.dox b/os/hal/dox/rtc.dox
index 3572aca18..dc49c8bb0 100644
--- a/os/hal/dox/rtc.dox
+++ b/os/hal/dox/rtc.dox
@@ -30,5 +30,14 @@
  * @pre     In order to use the RTC driver the @p HAL_USE_RTC option
  *          must be enabled in @p halconf.h. 
  *
+ * @note    STM32 Errata notes:
+ *          Description
+ *          When the LSIRDY flag is set, the clock may still be out of the 
+ *          specified frequency range (fLSI parameter, see LSI oscillator 
+ *          characteristics in the product datasheet).
+ *          Workaround
+ *          To have a fully stabilized clock in the specified range, a 
+ *          software temporization of 100 uS should be added.
+ *          
  * @ingroup IO
  */
diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c
index 62e114e66..875dc464c 100644
--- a/os/hal/platforms/STM32/rtc_lld.c
+++ b/os/hal/platforms/STM32/rtc_lld.c
@@ -112,29 +112,42 @@ CH_IRQ_HANDLER(RTC_IRQHandler) {
  * @notapi
  */
 void rtc_lld_init(void){
-  rccEnableBKP(FALSE);                                      /* enable interface clocking */
-  PWR->CR |= PWR_CR_DBP;                                    /* enable access */
+  rccEnableBKPInterface(FALSE);
 
-  if (!(RCC->BDCR & (RCC_BDCR_RTCEN | RCC_BDCR_LSEON))){    /* BKP domain was reseted */
-    RCC->BDCR |= RTC_CLOCK_SOURCE;                          /* select clocking from LSE */
-    RCC->BDCR |= RCC_BDCR_LSEON;                            /* switch LSE on */
-    while(!(RCC->BDCR & RCC_BDCR_LSEON))                    /* wait for stabilization */
+  /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling
+   * clocking on APB1, because these values only update when APB1 functioning.*/
+  RTC->CRL &= ~(RTC_CRL_RSF);
+  while (!(RTC->CRL & RTC_CRL_RSF))
+    ;
+
+  /* enable access to BKP registers */
+  PWR->CR |= PWR_CR_DBP;
+
+  if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){
+    RCC->BDCR |= RTC_CLOCK_SOURCE;
+
+    /* for LSE source we must wait until source became stable */
+    #if defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSE)
+    RCC->BDCR |= RCC_BDCR_LSEON;
+    while(!(RCC->BDCR & RCC_BDCR_LSERDY))
       ;
-    RCC->BDCR |= RCC_BDCR_RTCEN;                            /* run clock */
+    #endif
+
+    RCC->BDCR |= RCC_BDCR_RTCEN;
   }
 
   #if defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSE)
-    uint32_t preload = STM32_LSECLK - 1UL;
+    uint32_t preload = STM32_LSECLK - 1;
   #elif defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_LSI)
-    uint32_t preload = STM32_LSICLK - 1UL;
+    uint32_t preload = STM32_LSICLK - 1;
   #elif defined(RTC_CLOCK_SOURCE) == defined(RCC_BDCR_RTCSEL_HSE)
-    uint32_t preload = (STM32_HSICLK / 128UL) - 1UL;
+    uint32_t preload = (STM32_HSICLK / 128) - 1;
   #else
     #error "RTC clock source not selected"
   #endif /* RTC_CLOCK_SOURCE == RCC_BDCR_RTCSEL_LSE */
 
   /* Write preload register only if value changed */
-  if (preload != (((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLH){
+  if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){
     while(!(RTC->CRL & RTC_CRL_RTOFF))
       ;
 
@@ -147,12 +160,6 @@ void rtc_lld_init(void){
       ;
   }
 
-  /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling
-   * clocking on APB1, because these values only update when APB1 functioning.*/
-  RTC->CRL &= ~(RTC_CRL_RSF);
-  while (!(RTC->CRL & RTC_CRL_RSF))
-    ;
-
   /* disable all interrupts and clear all even flags just to be safe */
   RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE);
   RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF);
diff --git a/os/hal/platforms/STM32F1xx/stm32_rcc.h b/os/hal/platforms/STM32F1xx/stm32_rcc.h
index 7f215a720..9ca1140e9 100644
--- a/os/hal/platforms/STM32F1xx/stm32_rcc.h
+++ b/os/hal/platforms/STM32F1xx/stm32_rcc.h
@@ -203,7 +203,7 @@
 /** @} */
 
 /**
- * @brief   Bakup domain interface specific RCC operations
+ * @brief   Backup domain interface specific RCC operations
  * @{
  */
 /**
@@ -214,7 +214,7 @@
  *
  * @api
  */
-#define rccEnableBKP(lp) \
+#define rccEnableBKPInterface(lp) \
   rccEnableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp);
 
 /**
@@ -225,15 +225,22 @@
  *
  * @api
  */
-#define rccDisableBKP(lp) \
+#define rccDisableBKPInterface(lp) \
     rccDisableAPB1((RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN), lp);
 
 /**
- * @brief   Resets the Backup Domain.
+ * @brief   Resets the Backup Domain interface.
  *
  * @api
  */
-#define rccResetBKP(lp) rccResetAPB1(RCC_APB1ENR_BKPRST);
+#define rccResetBKPInterface() rccResetAPB1(RCC_APB1ENR_BKPRST);
+
+/**
+ * @brief   Resets the entire Backup Domain.
+ *
+ * @api
+ */
+#define rccResetBKP() (RCC->BDCR |= RCC_BDCR_BDRST);
 /** @} */
 
 /**
-- 
cgit v1.2.3