stm32/powerctrlboot: Support STM32WL system clock from HSE+PLL.

Switches default on the NUCLEO_WL55 board to use the HSE oscillator powered
from PB0_VDDTCXO pin.

Build-time configuration can select from MSI internal oscillator (previous
default), HSE via crystal, or HSE bypass with TCXO powered from PB0_VDDTCXO
pin (new default)

Signed-off-by: Angus Gratton <angus@redyak.com.au>
pull/9130/head
Angus Gratton 2023-08-16 14:11:26 +10:00 zatwierdzone przez Damien George
rodzic e6cfb77342
commit 2c62adb42c
4 zmienionych plików z 74 dodań i 2 usunięć

Wyświetl plik

@ -28,6 +28,13 @@
#define MICROPY_HW_RTC_USE_LSE (1)
#define MICROPY_HW_RTC_USE_US (1)
// Use external 32MHz TCXO + PLL as system clock source
// (If unset, board will use the internal MSI oscillator instead.)
#define MICROPY_HW_CLK_USE_HSE (1)
// HSE bypass for STM32WL5x means TCXO is powered from PB0_VDDTCXO pin
#define MICROPY_HW_CLK_USE_BYPASS (1)
// UART buses
#define MICROPY_HW_UART1_TX (pin_B6) // Arduino D1, pin 7 on CN9
#define MICROPY_HW_UART1_RX (pin_B7) // Arduino D0, pin 8 on CN9

Wyświetl plik

@ -14,7 +14,8 @@
,PA13
,PA14
,PA15
,PB0
# in the default board configuration, PB0 must stay muxed to analog for HSE VDDTCXO function
,-PB0
,PB1
,PB2
,PB3

1 PA0
14 PA13
15 PA14
16 PA15
17 # in the default board configuration PB0 PB0 must stay muxed to analog for HSE VDDTCXO function
18 -PB0
19 PB1
20 PB2
21 PB3

Wyświetl plik

@ -471,8 +471,12 @@
#define MICROPY_HW_RCC_HSI_STATE (RCC_HSI_OFF)
#define MICROPY_HW_RCC_FLAG_HSxRDY (RCC_FLAG_HSERDY)
#if MICROPY_HW_CLK_USE_BYPASS
#if !defined(STM32WL)
#define MICROPY_HW_RCC_HSE_STATE (RCC_HSE_BYPASS)
#else
#define MICROPY_HW_RCC_HSE_STATE (RCC_HSE_BYPASS_PWR)
#endif
#else
#define MICROPY_HW_RCC_HSE_STATE (RCC_HSE_ON)
#endif
#endif

Wyświetl plik

@ -460,13 +460,71 @@ void SystemClock_Config(void) {
#include "stm32wlxx_ll_utils.h"
void SystemClock_Config(void) {
// Set flash latency
// Set flash latency (2 wait states, sysclk > 36MHz)
LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) {
}
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
#if MICROPY_HW_CLK_USE_HSE
// Enable the 32MHz external oscillator and 48MHZ SYSCLK via PLL
#if MICROPY_HW_CLK_USE_BYPASS
// Use "bypass power" option, port PB0_VDDTCXO supplies TCXO
// (STM32WL5x has no other HSE bypass mode.)
// "PB0 must be configured in analog mode prior enabling the HSE"
//
// Note: PB0 analog mode muxes PB0_VDDTCXO pin to the VDDTCXO regulator, set
// to default voltage of 1.7V. Changing this voltage requires initializing
// the SUBGHZ radio and sending a Set_Tcxo command to it.
//
// For the Nucelo-WL55 board, ST uses the NDK "NT2016SF-32M-END5875A" TCXO
// which has no publicly available datasheet. However, the ST code for this
// board always keeps the pin at the default 1.7V voltage level so changing
// the level would only be needed if a different TCXO is used.
//
// (Note also that setting pin PB0 as a push-pull GPIO output is technically
// possible too, but 3.3V will be too high for many TCXOs.)
mp_hal_pin_config(pin_B0, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0);
LL_RCC_HSE_EnableTcxo();
#endif // MICROPY_HW_CLK_USE_BYPASS
LL_RCC_HSE_Enable();
while (!LL_RCC_HSE_IsReady()) {
// Wait for HSE Ready signal
}
// Configure PLL for a 48MHz SYSCLK
#define PLLM (HSE_VALUE / 16000000) // VCO input 16MHz (recommended in ST docs)
#define PLLN (6) // 7*8MHz = 96MHz
#define PLLP (2) // f_P = 48MHz
#define PLLQ (2) // f_Q = 48MHz
#define PLLR (2) // f_R = 48MHz
RCC->PLLCFGR =
(PLLR - 1) << RCC_PLLCFGR_PLLR_Pos | RCC_PLLCFGR_PLLREN
| (PLLQ - 1) << RCC_PLLCFGR_PLLQ_Pos | RCC_PLLCFGR_PLLQEN
| (PLLP - 1) << RCC_PLLCFGR_PLLP_Pos | RCC_PLLCFGR_PLLPEN
| PLLN << RCC_PLLCFGR_PLLN_Pos
| (PLLM - 1) << RCC_PLLCFGR_PLLM_Pos
| LL_RCC_PLLSOURCE_HSE;
LL_RCC_PLL_Enable();
LL_RCC_PLL_EnableDomain_SYS();
while (!LL_RCC_PLL_IsReady()) {
// Wait for PLL to lock
}
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
// Wait for system clock source to switch
}
#else // Use MSI as 48MHz source for SYSCLK
// Enable MSI
LL_RCC_MSI_Enable();
while (!LL_RCC_MSI_IsReady()) {
@ -482,6 +540,8 @@ void SystemClock_Config(void) {
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
}
#endif // MICROPY_HW_CLK_USE_HSE
// Set bus dividers
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAHB3Prescaler(LL_RCC_SYSCLK_DIV_1);