RTC. Driver improvements
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3352 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
9ced1d4e65
commit
31a099cb10
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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))
|
||||
;
|
||||
RCC->BDCR |= RCC_BDCR_RTCEN; /* run clock */
|
||||
|
||||
/* 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))
|
||||
;
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue