/** * @brief Initialize RTC. * * @notapi */ void rtc_lld_init(void){ /* RSF bit must be cleared by software after an APB1 reset or an APB1 clock stop. Otherwise its value will not be actual. */ RTC->CRL &= ~RTC_CRL_RSF; /* Required because access to PRL.*/ rtc_lld_apb1_sync(); /* All interrupts initially disabled.*/ rtc_lld_wait_write(); RTC->CRH = 0; /* Callback initially disabled.*/ RTCD1.callback = NULL; /* IRQ vector permanently assigned to this driver.*/ nvicEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); }
/** * @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. * * @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 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 /* 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.*/ uint32_t tmo = (STM32_SYSCLK / 1000000) * 100; while (tmo--) ; preload = STM32_LSICLK - 1; #elif STM32_RTC == STM32_RTC_HSE preload = (STM32_HSICLK / 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 functioning.*/ RTC->CRL = 0; while (!(RTC->CRL & RTC_CRL_RSF)) ; /* Write preload register only if its value differs.*/ if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + (uint32_t)RTC->PRLL)) { rtc_lld_wait_write(); /* Enters configuration mode and writes PRLx registers then leaves the configuration mode.*/ RTC->CRL |= RTC_CRL_CNF; RTC->PRLH = (uint16_t)(preload >> 16); RTC->PRLL = (uint16_t)(preload & 0xFFFF); RTC->CRL &= ~RTC_CRL_CNF; }