stm32/powerctrlboot: Fix clock and PLL selection for HSI48 on F0 MCUs.
Before this patch the UART baudrate on F0 MCUs was wrong because the stm32lib SystemCoreClockUpdate sets SystemCoreClock to 8MHz instead of 48MHz if HSI48 is routed directly to SYSCLK. The workaround is to use HSI48 -> PREDIV (/2) -> PLL (*2) -> SYSCLK. Fixes issue #5049.
This commit is contained in:
parent
3328b7d71f
commit
f16e4be3fa
@ -38,11 +38,15 @@ void SystemClock_Config(void) {
|
|||||||
|
|
||||||
#if MICROPY_HW_CLK_USE_HSI48
|
#if MICROPY_HW_CLK_USE_HSI48
|
||||||
// Use the 48MHz internal oscillator
|
// Use the 48MHz internal oscillator
|
||||||
|
// HAL does not support RCC CFGR SW=3 (HSI48 direct to SYSCLK)
|
||||||
|
// so use HSI48 -> PREDIV(divide by 2) -> PLL (mult by 2) -> SYSCLK.
|
||||||
|
|
||||||
RCC->CR2 |= RCC_CR2_HSI48ON;
|
RCC->CR2 |= RCC_CR2_HSI48ON;
|
||||||
while ((RCC->CR2 & RCC_CR2_HSI48RDY) == 0) {
|
while ((RCC->CR2 & RCC_CR2_HSI48RDY) == 0) {
|
||||||
|
// Wait for HSI48 to be ready
|
||||||
}
|
}
|
||||||
const uint32_t sysclk_src = 3;
|
RCC->CFGR = 0 << RCC_CFGR_PLLMUL_Pos | 3 << RCC_CFGR_PLLSRC_Pos; // PLL mult by 2, src = HSI48/PREDIV
|
||||||
|
RCC->CFGR2 = 1; // Input clock divided by 2
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// Use HSE and the PLL to get a 48MHz SYSCLK
|
// Use HSE and the PLL to get a 48MHz SYSCLK
|
||||||
@ -56,14 +60,15 @@ void SystemClock_Config(void) {
|
|||||||
}
|
}
|
||||||
RCC->CFGR = ((48000000 / HSE_VALUE) - 2) << RCC_CFGR_PLLMUL_Pos | 2 << RCC_CFGR_PLLSRC_Pos;
|
RCC->CFGR = ((48000000 / HSE_VALUE) - 2) << RCC_CFGR_PLLMUL_Pos | 2 << RCC_CFGR_PLLSRC_Pos;
|
||||||
RCC->CFGR2 = 0; // Input clock not divided
|
RCC->CFGR2 = 0; // Input clock not divided
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
RCC->CR |= RCC_CR_PLLON; // Turn PLL on
|
RCC->CR |= RCC_CR_PLLON; // Turn PLL on
|
||||||
while ((RCC->CR & RCC_CR_PLLRDY) == 0) {
|
while ((RCC->CR & RCC_CR_PLLRDY) == 0) {
|
||||||
// Wait for PLL to lock
|
// Wait for PLL to lock
|
||||||
}
|
}
|
||||||
const uint32_t sysclk_src = 2;
|
const uint32_t sysclk_src = 2;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Select SYSCLK source
|
// Select SYSCLK source
|
||||||
RCC->CFGR |= sysclk_src << RCC_CFGR_SW_Pos;
|
RCC->CFGR |= sysclk_src << RCC_CFGR_SW_Pos;
|
||||||
while (((RCC->CFGR >> RCC_CFGR_SWS_Pos) & 0x3) != sysclk_src) {
|
while (((RCC->CFGR >> RCC_CFGR_SWS_Pos) & 0x3) != sysclk_src) {
|
||||||
|
Loading…
Reference in New Issue
Block a user