From 31a099cb104ea4d7d957bb65bbdc7e8edbdbe636 Mon Sep 17 00:00:00 2001 From: barthess 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(-) (limited to 'os') 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