summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Mason <c.mason@inchipdesign.com.au>2019-09-21 18:20:12 +1000
committerDamien George <damien.p.george@gmail.com>2019-09-26 17:32:22 +1000
commitf16e4be3fa16a3532bb93ccf88e867d27fe2ff20 (patch)
tree08923a78f24688cf8454d9ccba82b02af6e6b0e6
parent3328b7d71f2758d6e278cd5f3c230d427f46ff01 (diff)
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.
-rw-r--r--ports/stm32/powerctrlboot.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c
index 8884f596e..0579853ee 100644
--- a/ports/stm32/powerctrlboot.c
+++ b/ports/stm32/powerctrlboot.c
@@ -38,11 +38,15 @@ void SystemClock_Config(void) {
#if MICROPY_HW_CLK_USE_HSI48
// 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;
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
// 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->CFGR2 = 0; // Input clock not divided
+
+ #endif
+
RCC->CR |= RCC_CR_PLLON; // Turn PLL on
while ((RCC->CR & RCC_CR_PLLRDY) == 0) {
// Wait for PLL to lock
}
const uint32_t sysclk_src = 2;
- #endif
-
// Select SYSCLK source
RCC->CFGR |= sysclk_src << RCC_CFGR_SW_Pos;
while (((RCC->CFGR >> RCC_CFGR_SWS_Pos) & 0x3) != sysclk_src) {