I have a STM32F303RE Nucleo board with Mecrisp-Stellaris Forth. The Forth console goes through USART2, the interface connected to the ST-Link part of the Nucleo board (changed from default USART1). The MCU gets an 8 MHz clock input from the ST-Link, and I'm trying to use the PLL to get a higher clock rate up to the rated maximum of 72 MHz. This works fine up to 40 MHz (PLL x5), but at higher clock rates (PLL x6 and higher), the system becomes unresponsive immediately after the clock switch. When I put the system clock on an output pin and measure with a scope, I see the expected frequency all the way up to 72 MHz, so I'm not sure if the MCU has actually crashed or if it's just a communications problem. The USART is configured to use the HSI clock, so it shouldn't be affected by the clock switch.
Specifically, here's what I do:
- Change USART2 clock to HSI
- Start up HSE with external 8 MHz clock (HSEBYP)
- Set up GPIOA to output system clock at MCO pin
- Set up PLL source from HSE and desired multiplier
- Enable PLL, wait until ready
- Switch system clock to PLL
At this point, everything works as expected for multipliers <= 5, but the console freezes for multipliers >= 6. The frequency measured at the MCO pin is (multiplier * 8 MHz), for all multipliers <= 9.
Forth code for completeness:
: setup-gpioa $20000 RCC_AHBENR bis! $0F GPIOA_AFRH bic! $20400 GPIOA_MODER bis! $04000000 RCC_CFGR bis! ; : toggle-led 32 GPIOA_ODR xor! ; : delay 1000 0 do nop loop ; : wait-for ( mask a-addr -- ) begin 2dup bit@ 0= while delay repeat 2drop ; : wait-clear ( mask a-addr -- ) begin 2dup bit@ while delay repeat 2drop ; : usart2-hsi ( -- ) $30000 RCC_CFGR3 bis! ; : start-hse ( -- ) $50000 RCC_CR bis! $20000 RCC_CR wait-for ; : start-pll ( pllmul -- ) 18 lshift $04010000 or RCC_CFGR ! $1000000 RCC_CR bis! $2000000 RCC_CR wait-for ; : stop-pll ( -- ) $1000000 RCC_CR bic! $2000000 RCC_CR wait-clear ; : sysclk-pll ( -- ) RCC_CFGR @ $FFFFFFFC and 2 or RCC_CFGR ! ; : sysclk-hsi ( -- ) RCC_CFGR @ $FFFFFFFC and RCC_CFGR ! ; : setup usart2-hsi sysclk-hsi start-hse setup-gpioa ; : test-pllclk ( pllmul -- ) sysclk-hsi stop-pll start-pll sysclk-pll ; setup 3 test-pllclk ( for multiplier 5, works ) 4 test-pllclk ( for multiplier 6, freezes )
How can I make the MCU run at full speed without freezing?