From 7e1edd8d16ef8552da032804e91a7730caa2c0de Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 8 Dec 2012 18:24:20 +0000 Subject: STM32. RTCv1. Fixed wasting of BKP registers in RTCv1 driver (bug 3594005) git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4890 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/RTCv1/rtc_lld.c | 40 +++++++++++++++------------------- os/hal/platforms/STM32/RTCv1/rtc_lld.h | 1 + os/hal/platforms/STM32F1xx/hal_lld.c | 3 +++ 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index 0fb538c2d..72b91a28c 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -126,10 +126,24 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { /*===========================================================================*/ /** - * @brief Enable access to registers and initialize RTC if BKP domain - * was previously reseted. - * @note: Cold start time of LSE oscillator on STM32 platform - * takes about 3 seconds. + * @brief Load value of RTCCLK to prescaler registers. + * @note The pre-scaler must not be set on every reset as RTC clock + * counts are lost when it is set. + * @note This function designed to be called from + * hal_lld_backup_domain_init(). Because there is only place + * where possible to detect BKP domain reset event reliably. + * + * @notapi + */ +void rtc_lld_set_prescaler(void){ + rtc_lld_acquire(); + RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16) & 0x000F; + RTC->PRLL = (uint16_t)(((STM32_RTCCLK - 1)) & 0xFFFF); + rtc_lld_release(); +} + +/** + * @brief Initialize RTC. * * @notapi */ @@ -142,24 +156,6 @@ void rtc_lld_init(void){ /* Required because access to PRL.*/ rtc_lld_apb1_sync(); - /* - * Writes preload register only if its value is not equal to desired value. - * - * Ref CD00171190: RM0008 Reference manual Cls 18.4.3 The RTC->PRL registers - * are write only. We must store the value for the pre-scaler in BKP->DR1 - * and BKP->DR1 so we know it has been set. - * The pre-scaler must not be set on every reset as RTC clock counts are - * lost when it is set. - */ - if ((STM32_RTCCLK - 1) != ((((uint32_t)BKP->DR1) << 16) | BKP->DR2)){ - rtc_lld_acquire(); - RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16) & 0x000F; - BKP->DR1 = (uint16_t)((STM32_RTCCLK - 1) >> 16) & 0x000F; - RTC->PRLL = (uint16_t)(((STM32_RTCCLK - 1)) & 0xFFFF); - BKP->DR2 = (uint16_t)(((STM32_RTCCLK - 1)) & 0xFFFF); - rtc_lld_release(); - } - /* All interrupts initially disabled.*/ rtc_lld_wait_write(); RTC->CRH = 0; diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index c0ad92525..050f66d5e 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -168,6 +168,7 @@ extern RTCDriver RTCD1; #ifdef __cplusplus extern "C" { #endif + void rtc_lld_set_prescaler(void); void rtc_lld_init(void); void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec); void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec); diff --git a/os/hal/platforms/STM32F1xx/hal_lld.c b/os/hal/platforms/STM32F1xx/hal_lld.c index 9fda0b3e7..bcb7d3f47 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.c +++ b/os/hal/platforms/STM32F1xx/hal_lld.c @@ -74,6 +74,9 @@ static void hal_lld_backup_domain_init(void) { /* RTC clock enabled.*/ RCC->BDCR |= RCC_BDCR_RTCEN; + + /* Prescaler value loaded in registers.*/ + rtc_lld_set_prescaler(); } #endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ } -- cgit v1.2.3