/** * @brief Low level HAL driver initialization. * * @notapi */ void hal_lld_init(void) { /* Reset of all peripherals.*/ rccResetAPB1(0xFFFFFFFF); rccResetAPB2(0xFFFFFFFF); /* PWR and BD clocks enabled.*/ rccEnablePWRInterface(true); rccEnableBKPInterface(true); /* Initializes the backup domain.*/ hal_lld_backup_domain_init(); /* DMA subsystems initialization.*/ #if defined(STM32_DMA_REQUIRED) dmaInit(); #endif /* IRQ subsystem initialization.*/ irqInit(); /* Programmable voltage detector enable.*/ #if STM32_PVD_ENABLE PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); #endif /* STM32_PVD_ENABLE */ }
/** * @brief Low level HAL driver initialization. * * @notapi */ void hal_lld_init(void) { /* Reset of all peripherals.*/ rccResetAPB1(0xFFFFFFFF); rccResetAPB2(0xFFFFFFFF); /* SysTick initialization using the system clock.*/ SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; SysTick->VAL = 0; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk; /* DWT cycle counter enable.*/ SCS_DEMCR |= SCS_DEMCR_TRCENA; 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 PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); #endif /* STM32_PVD_ENABLE */ }
/** * @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; }