From 8824a54e5efd1cc239bd7af2f8cbe12481d7a247 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 10 Jan 2012 18:14:24 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3783 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/RTCv1/rtc_lld.c | 84 ++++++-------------------- os/hal/platforms/STM32/RTCv1/rtc_lld.h | 5 +- os/hal/platforms/STM32F1xx/hal_lld.c | 67 ++++++++++++++------ os/hal/platforms/STM32F1xx/hal_lld_f100.h | 20 +++++- os/hal/platforms/STM32F1xx/hal_lld_f103.h | 20 +++++- os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 20 +++++- os/hal/platforms/STM32F2xx/hal_lld.c | 48 ++++++++++++++- os/hal/platforms/STM32F2xx/hal_lld.h | 12 ++-- os/hal/platforms/STM32F4xx/hal_lld.c | 48 ++++++++++++++- os/hal/platforms/STM32F4xx/hal_lld.h | 22 +++++-- os/hal/platforms/STM32L1xx/hal_lld.c | 48 ++++++++++++++- os/kernel/include/chthreads.h | 2 +- 12 files changed, 285 insertions(+), 111 deletions(-) (limited to 'os') diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index 1249b7554..3bac2e05b 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -87,7 +87,7 @@ static void rtc_lld_serve_interrupt(RTCDriver *rtcp) { static void rtc_lld_wait_write(void) { /* Waits registers write completion.*/ - while (!(RTC->CRL & RTC_CRL_RTOFF)) + while ((RTC->CRL & RTC_CRL_RTOFF) == 0) ; } @@ -122,50 +122,6 @@ CH_IRQ_HANDLER(RTC_IRQHandler) { * @notapi */ void rtc_lld_init(void){ - uint32_t preload; - - rccEnableBKPInterface(FALSE); - - /* Enables access to BKP registers.*/ - PWR->CR |= PWR_CR_DBP; - - /* If the RTC is not enabled then performs a reset of the backup domain.*/ - if (!(RCC->BDCR & RCC_BDCR_RTCEN)) { - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_RTC == STM32_RTC_LSE -#define RTC_CLK STM32_LSECLK - if (!(RCC->BDCR & RCC_BDCR_LSEON)) { - RCC->BDCR |= RCC_BDCR_LSEON; - while (!(RCC->BDCR & RCC_BDCR_LSERDY)) - ; - } - preload = STM32_LSECLK - 1; -#elif STM32_RTC == STM32_RTC_LSI -#define RTC_CLK STM32_LSICLK - /* TODO: Move the LSI clock initialization in the HAL low level driver.*/ - RCC->CSR |= RCC_CSR_LSION; - while (!(RCC->CSR & RCC_CSR_LSIRDY)) - ; - /* According to errata sheet we must wait additional 100 uS for - stabilization. - TODO: Change this code, software loops are not reliable.*/ - volatile uint32_t tmo = (STM32_SYSCLK / 1000000) * 100; - while (tmo--) - ; - preload = STM32_LSICLK - 1; -#elif STM32_RTC == STM32_RTC_HSE -#define RTC_CLK (STM32_HSECLK / 128) - preload = (STM32_HSECLK / 128) - 1; -#endif - - /* Selects clock source (previously enabled and stabilized).*/ - RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTC; - - /* RTC enabled regardless its previous status.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling clocking on APB1, because these values only update when APB1 @@ -175,15 +131,15 @@ void rtc_lld_init(void){ ; /* Write preload register only if its value differs.*/ - if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + (uint32_t)RTC->PRLL)) { - - rtc_lld_wait_write(); + if (STM32_RTCCLK != (((uint32_t)(RTC->PRLH)) << 16) + + ((uint32_t)RTC->PRLL) + 1) { /* Enters configuration mode and writes PRLx registers then leaves the configuration mode.*/ + rtc_lld_wait_write(); RTC->CRL |= RTC_CRL_CNF; - RTC->PRLH = (uint16_t)(preload >> 16); - RTC->PRLL = (uint16_t)(preload & 0xFFFF); + RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16); + RTC->PRLL = (uint16_t)((STM32_RTCCLK - 1) & 0xFFFF); RTC->CRL &= ~RTC_CRL_CNF; } @@ -209,7 +165,6 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec) { (void)rtcp; rtc_lld_wait_write(); - RTC->CRL |= RTC_CRL_CNF; RTC->CNTH = (uint16_t)(timespec->tv_sec >> 16); RTC->CNTL = (uint16_t)(timespec->tv_sec & 0xFFFF); @@ -229,17 +184,15 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) { uint32_t time_frac; -READ_REGISTERS: - timespec->tv_sec = ((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL; - time_frac = (((uint32_t)RTC->DIVH) << 16) + (uint32_t)RTC->DIVL; - - /* If second counter updated between reading of integer and fractional parts - * we must reread both values. */ - if((timespec->tv_sec) != (((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL)){ - goto READ_REGISTERS; - } + /* The read is repeated until we are able to do it twice and obtain the + same result.*/ + do { + timespec->tv_sec = ((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL; + time_frac = (((uint32_t)RTC->DIVH) << 16) + (uint32_t)RTC->DIVL; + } while ((timespec->tv_sec) != (((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL)); - timespec->tv_msec = (uint16_t)(((RTC_CLK - 1 - time_frac) * 1000) / RTC_CLK); + timespec->tv_msec = (uint16_t)(((STM32_RTCCLK - 1 - time_frac) * 1000) / + STM32_RTCCLK); } /** @@ -260,10 +213,10 @@ void rtc_lld_set_alarm(RTCDriver *rtcp, (void)rtcp; (void)alarm; - rtc_lld_wait_write(); /* Enters configuration mode and writes ALRHx registers then leaves the configuration mode.*/ + rtc_lld_wait_write(); RTC->CRL |= RTC_CRL_CNF; if (alarmspec != NULL) { RTC->ALRH = (uint16_t)(alarmspec->tv_sec >> 16); @@ -315,17 +268,14 @@ void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { rtcp->callback = callback; /* Interrupts are enabled only after setting up the callback, this - way there is no need to check for the NULL callback pointer inside - the IRQ handler.*/ - rtc_lld_wait_write(); + way there is no need to check for the NULL callback pointer inside + the IRQ handler.*/ RTC->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF); - rtc_lld_wait_write(); nvicEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); RTC->CRH |= RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE; } else { nvicDisableVector(RTC_IRQn); - rtc_lld_wait_write(); RTC->CRL = 0; RTC->CRH = 0; } diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index 1fb12d490..aaf639492 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -61,9 +61,8 @@ #error "RTC not present in the selected device" #endif -#if !(STM32_RTC == STM32_RTC_LSE) && !(STM32_RTC == STM32_RTC_LSI) && \ - !(STM32_RTC == STM32_RTC_HSE) -#error "invalid source selected for RTC clock" +#if STM32_RTCCLK == 0 +#error "RTC clock not enabled" #endif /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld.c b/os/hal/platforms/STM32F1xx/hal_lld.c index 653201363..bf3baca8a 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.c +++ b/os/hal/platforms/STM32F1xx/hal_lld.c @@ -41,6 +41,47 @@ /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Initializes the backup domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled during initialization.*/ + PWR->CR |= PWR_CR_DBP; + + /* RTC clock initialization.*/ +#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK + /* RTC clock not required, backup domain reset as initialization.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; +#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if (!(RCC->BDCR & RCC_BDCR_LSEON)) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= RCC_BDCR_LSEON; + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + + /* Selects clock source.*/ + RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL; + + /* RTC enabled regardless its previous status, this will also prevent + successive initializations.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + + /* Backup domain access disabled for operations safety.*/ + PWR->CR &= ~PWR_CR_DBP; +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -70,13 +111,19 @@ void hal_lld_init(void) { /* DWT cycle counter enable.*/ DWT_CTRL |= DWT_CTRL_CYCCNTENA; + /* PWR and BD clocks enabled.*/ + rccEnablePWRInterface(FALSE); + rccEnableBKPInterface(FALSE); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + #if defined(STM32_DMA_REQUIRED) dmaInit(); #endif /* Programmable voltage detector enable.*/ #if STM32_PVD_ENABLE - rccEnablePWRInterface(FALSE); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); #endif /* STM32_PVD_ENABLE */ } @@ -122,15 +169,6 @@ void stm32_clock_init(void) { ; /* Waits until LSI is stable. */ #endif -#if STM32_LSE_ENABLED - /* LSE activation, have to unlock the register.*/ - PWR->CR |= PWR_CR_DBP; - RCC->BDCR |= RCC_BDCR_LSEON; - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ - PWR->CR &= ~PWR_CR_DBP; -#endif - #if STM32_ACTIVATE_PLL /* PLL activation.*/ RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; @@ -193,15 +231,6 @@ void stm32_clock_init(void) { ; /* Waits until LSI is stable. */ #endif -#if STM32_LSE_ENABLED - /* LSE activation, have to unlock the register.*/ - PWR->CR |= PWR_CR_DBP; - RCC->BDCR |= RCC_BDCR_LSEON; - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ - PWR->CR &= ~PWR_CR_DBP; -#endif - /* Settings of various dividers and multipliers in CFGR2.*/ RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 | STM32_PREDIV1 | STM32_PREDIV1SRC; diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 13823e978..766e9e48a 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -648,8 +648,9 @@ #error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" #endif -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) #error "HSI not enabled, required by STM32_MCOSEL" #endif @@ -870,6 +871,21 @@ #error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #endif +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 128) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + /** * @brief ADC frequency. */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index a536dcf33..39b13cf38 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -981,8 +981,9 @@ #error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" #endif -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) #error "HSI not enabled, required by STM32_MCOSEL" #endif @@ -1204,6 +1205,21 @@ #error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #endif +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 128) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + /** * @brief ADC frequency. */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 157741431..8e63ebaf3 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -596,8 +596,9 @@ #error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" #endif -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) #error "HSI not enabled, required by STM32_MCOSEL" #endif @@ -956,6 +957,21 @@ #error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #endif +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 128) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + /** * @brief ADC frequency. */ diff --git a/os/hal/platforms/STM32F2xx/hal_lld.c b/os/hal/platforms/STM32F2xx/hal_lld.c index 9b9359090..b517795f2 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.c +++ b/os/hal/platforms/STM32F2xx/hal_lld.c @@ -41,6 +41,47 @@ /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Initializes the backup domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled during initialization.*/ + PWR->CR |= PWR_CR_DBP; + + /* RTC clock initialization.*/ +#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK + /* RTC clock not required, backup domain reset as initialization.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; +#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if (!(RCC->BDCR & RCC_BDCR_LSEON)) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= RCC_BDCR_LSEON; + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + + /* Selects clock source.*/ + RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL; + + /* RTC enabled regardless its previous status, this will also prevent + successive initializations.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + + /* Backup domain access disabled for operations safety.*/ + PWR->CR &= ~PWR_CR_DBP; +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -74,13 +115,18 @@ void hal_lld_init(void) { /* DWT cycle counter enable.*/ DWT_CTRL |= DWT_CTRL_CYCCNTENA; + /* PWR clock enabled.*/ + rccEnablePWRInterface(FALSE); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + #if defined(STM32_DMA_REQUIRED) dmaInit(); #endif /* Programmable voltage detector enable.*/ #if STM32_PVD_ENABLE - rccEnablePWRInterface(FALSE); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); #endif /* STM32_PVD_ENABLE */ } diff --git a/os/hal/platforms/STM32F2xx/hal_lld.h b/os/hal/platforms/STM32F2xx/hal_lld.h index 84861fa33..b9186bb8b 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.h +++ b/os/hal/platforms/STM32F2xx/hal_lld.h @@ -1230,21 +1230,21 @@ #endif /** - * @brief HSE divider toward RTC clock. + * @brief RTC HSE divider setting. */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) #else #error "invalid STM32_RTCPRE value specified" #endif /** - * @brief RTC HSE divider setting. + * @brief HSE divider toward RTC clock. */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ defined(__DOXYGEN__) -#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) #else #error "invalid STM32_RTCPRE value specified" #endif diff --git a/os/hal/platforms/STM32F4xx/hal_lld.c b/os/hal/platforms/STM32F4xx/hal_lld.c index 02905b6bd..a655231cd 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.c +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -41,6 +41,47 @@ /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Initializes the backup domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled during initialization.*/ + PWR->CR |= PWR_CR_DBP; + + /* RTC clock initialization.*/ +#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK + /* RTC clock not required, backup domain reset as initialization.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; +#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if (!(RCC->BDCR & RCC_BDCR_LSEON)) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= RCC_BDCR_LSEON; + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + + /* Selects clock source.*/ + RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL; + + /* RTC enabled regardless its previous status, this will also prevent + successive initializations.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + + /* Backup domain access disabled for operations safety.*/ + PWR->CR &= ~PWR_CR_DBP; +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -74,13 +115,18 @@ void hal_lld_init(void) { /* DWT cycle counter enable.*/ DWT_CTRL |= DWT_CTRL_CYCCNTENA; + /* PWR clock enabled.*/ + rccEnablePWRInterface(FALSE); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + #if defined(STM32_DMA_REQUIRED) dmaInit(); #endif /* Programmable voltage detector enable.*/ #if STM32_PVD_ENABLE - rccEnablePWRInterface(FALSE); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); #endif /* STM32_PVD_ENABLE */ } diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 1e5d4947b..2837939a6 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -1250,21 +1250,21 @@ #endif /** - * @brief HSE divider toward RTC clock. + * @brief RTC HSE divider setting. */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) #else #error "invalid STM32_RTCPRE value specified" #endif /** - * @brief RTC HSE divider setting. + * @brief HSE divider toward RTC clock. */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ defined(__DOXYGEN__) -#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) #else #error "invalid STM32_RTCPRE value specified" #endif @@ -1284,6 +1284,16 @@ #error "invalid STM32_RTCSEL value specified" #endif +/** + * @brief RTC HSE divider setting. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + /** * @brief 48MHz frequency. */ diff --git a/os/hal/platforms/STM32L1xx/hal_lld.c b/os/hal/platforms/STM32L1xx/hal_lld.c index f4b1b80e7..b87620293 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.c +++ b/os/hal/platforms/STM32L1xx/hal_lld.c @@ -41,6 +41,47 @@ /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Initializes the backup domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled during initialization.*/ + PWR->CR |= PWR_CR_DBP; + + /* RTC clock initialization.*/ +#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK + /* RTC clock not required, backup domain reset as initialization.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; +#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if (!(RCC->BDCR & RCC_BDCR_LSEON)) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= RCC_BDCR_LSEON; + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + + /* Selects clock source.*/ + RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL; + + /* RTC enabled regardless its previous status, this will also prevent + successive initializations.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ + + /* Backup domain access disabled for operations safety.*/ + PWR->CR &= ~PWR_CR_DBP; +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -71,13 +112,18 @@ void hal_lld_init(void) { /* DWT cycle counter enable.*/ DWT_CTRL |= DWT_CTRL_CYCCNTENA; + /* PWR clock enabled.*/ + rccEnablePWRInterface(FALSE); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + #if defined(STM32_DMA_REQUIRED) dmaInit(); #endif /* Programmable voltage detector enable.*/ #if STM32_PVD_ENABLE - rccEnablePWRInterface(FALSE); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); #endif /* STM32_PVD_ENABLE */ } diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h index 5848d5643..bcb15d456 100644 --- a/os/kernel/include/chthreads.h +++ b/os/kernel/include/chthreads.h @@ -125,7 +125,7 @@ struct Thread { #if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__) /** * @brief Thread consumed time in ticks. - * @note This field can overflow. + * @note This field can overflow. */ volatile systime_t p_time; #endif -- cgit v1.2.3