mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
fix: set stm32u5x clock rate to default
The complex 160MHz PLL initialization was hanging the MCU. The fix: Replaced the entire PLL-based clock init with the MSI 4MHz default Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
@@ -7,14 +7,14 @@ import (
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
return 160000000
|
||||
return 4_000_000
|
||||
}
|
||||
|
||||
// Internal use: configured speed of the APB1 and APB2 timers, this should be kept
|
||||
// in sync with any changes to runtime package which configures the oscillators
|
||||
// and clock frequencies
|
||||
const APB1_TIM_FREQ = 160e6 // 160MHz
|
||||
const APB2_TIM_FREQ = 160e6 // 160MHz
|
||||
const APB1_TIM_FREQ = 4e6 // 4MHz (MSI default)
|
||||
const APB2_TIM_FREQ = 4e6 // 4MHz (MSI default)
|
||||
|
||||
//---------- UART related code
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"machine"
|
||||
)
|
||||
|
||||
@@ -24,78 +23,9 @@ func buffered() int {
|
||||
}
|
||||
|
||||
func initCLK() {
|
||||
// Initialize clock to 160MHz using PLL1 with HSI16 as source.
|
||||
// PLL1 configuration: HSI16 (16MHz) / PLLM(1) * PLLN(10) / PLLR(1) = 160MHz
|
||||
// VCO = 16 * 10 = 160MHz, PLLR = /1 -> 160MHz SYSCLK
|
||||
|
||||
// Enable PWR clock
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_CRSEN) // CRS enable not needed but ensures APB1 is clocked
|
||||
_ = stm32.RCC.APB1ENR1.Get()
|
||||
|
||||
// Set voltage scaling to Range 1 for 160MHz operation
|
||||
// On U5, voltage scaling is in PWR.VOSR register
|
||||
// VOS = 11 (Range 1, up to 160MHz)
|
||||
stm32.PWR.VOSR.ReplaceBits(stm32.PWR_VOSR_VOS_Range1, stm32.PWR_VOSR_VOS_Msk, 0)
|
||||
// Wait for VOS ready
|
||||
for !stm32.PWR.VOSR.HasBits(stm32.PWR_VOSR_VOSRDY) {
|
||||
}
|
||||
|
||||
// Enable EPOD booster for high performance (required for Range 1 >100MHz)
|
||||
stm32.PWR.VOSR.SetBits(stm32.PWR_VOSR_BOOSTEN)
|
||||
for !stm32.PWR.VOSR.HasBits(stm32.PWR_VOSR_BOOSTRDY) {
|
||||
}
|
||||
|
||||
// Enable HSI16
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION)
|
||||
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) {
|
||||
}
|
||||
|
||||
// Disable PLL1 before configuration
|
||||
stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLL1ON)
|
||||
for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLL1RDY) {
|
||||
}
|
||||
|
||||
// Configure PLL1:
|
||||
// Source = HSI16 (0x2)
|
||||
// PLLM = 0 (divide by 1)
|
||||
// PLL1RGE = 0x3 (input range 8-16MHz)
|
||||
// Enable PLLR output
|
||||
stm32.RCC.PLL1CFGR.Set(
|
||||
(stm32.RCC_PLL1CFGR_PLL1SRC_HSI16 << stm32.RCC_PLL1CFGR_PLL1SRC_Pos) |
|
||||
(stm32.RCC_PLL1CFGR_PLL1M_Div1 << stm32.RCC_PLL1CFGR_PLL1M_Pos) |
|
||||
(stm32.RCC_PLL1CFGR_PLL1RGE_Range2 << stm32.RCC_PLL1CFGR_PLL1RGE_Pos))
|
||||
|
||||
// Enable PLL1R output
|
||||
stm32.RCC.PLL1CFGR.SetBits(1 << stm32.RCC_PLL1CFGR_PLL1REN_Pos)
|
||||
|
||||
// Set PLL1 dividers in PLL1DIVR:
|
||||
// PLL1N = 10 (value - 1 = 9 in register)
|
||||
// PLL1R = 1 (value - 1 = 0 in register)
|
||||
// VCO = HSI16/1 * 10 = 160MHz
|
||||
// PLLR output = 160MHz / 1 = 160MHz
|
||||
stm32.RCC.SetPLL1DIVR_PLL1N(9) // N = 10, register value = N-1 = 9
|
||||
stm32.RCC.SetPLL1DIVR_PLL1R(0) // R = 1, register value = R-1 = 0
|
||||
|
||||
// Enable PLL1
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLL1ON)
|
||||
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLL1RDY) {
|
||||
}
|
||||
|
||||
// Set flash latency to 4 wait states (required for 160MHz in Range 1)
|
||||
const FLASH_LATENCY_4 = 4
|
||||
stm32.FLASH.ACR.ReplaceBits(FLASH_LATENCY_4, stm32.Flash_ACR_LATENCY_Msk, 0)
|
||||
for (stm32.FLASH.ACR.Get() & stm32.Flash_ACR_LATENCY_Msk) != FLASH_LATENCY_4 {
|
||||
}
|
||||
|
||||
// Set AHB prescaler to 1 (no division) in CFGR2
|
||||
stm32.RCC.CFGR2.ReplaceBits(stm32.RCC_CFGR2_HPRE_Div1, stm32.RCC_CFGR2_HPRE_Msk, 0)
|
||||
|
||||
// Set APB1 and APB2 prescalers to 1 (no division) in CFGR2
|
||||
stm32.RCC.CFGR2.ReplaceBits(stm32.RCC_CFGR2_PPRE1_Div1, stm32.RCC_CFGR2_PPRE1_Msk, 0)
|
||||
stm32.RCC.CFGR2.ReplaceBits(stm32.RCC_CFGR2_PPRE2_Div1, stm32.RCC_CFGR2_PPRE2_Msk, 0)
|
||||
|
||||
// Switch system clock to PLL1 (SW = 11 = PLL)
|
||||
stm32.RCC.CFGR1.ReplaceBits(stm32.RCC_CFGR1_SW_PLL, stm32.RCC_CFGR1_SW_Msk, 0)
|
||||
for (stm32.RCC.CFGR1.Get() & stm32.RCC_CFGR1_SWS_Msk) != (stm32.RCC_CFGR1_SWS_PLL << stm32.RCC_CFGR1_SWS_Pos) {
|
||||
}
|
||||
// Use MSI at 4MHz — the reset default clock configuration.
|
||||
// This matches the known-working bare-metal C configuration for
|
||||
// the Arduino Uno Q (STM32U585). The MCU boots with MSI at 4MHz,
|
||||
// VOS Range 4, and 0 flash wait states. No additional configuration
|
||||
// is needed.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user