summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h7
-rw-r--r--ports/stm32/boards/NUCLEO_WL55/pins.csv3
-rw-r--r--ports/stm32/mpconfigboard_common.h4
-rw-r--r--ports/stm32/powerctrlboot.c62
4 files changed, 74 insertions, 2 deletions
diff --git a/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h b/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h
index 4087ba4fb..ec5904a35 100644
--- a/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h
+++ b/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h
@@ -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
diff --git a/ports/stm32/boards/NUCLEO_WL55/pins.csv b/ports/stm32/boards/NUCLEO_WL55/pins.csv
index afcf34df1..78a0ef8d0 100644
--- a/ports/stm32/boards/NUCLEO_WL55/pins.csv
+++ b/ports/stm32/boards/NUCLEO_WL55/pins.csv
@@ -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
diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h
index 149d2ae73..3331b3840 100644
--- a/ports/stm32/mpconfigboard_common.h
+++ b/ports/stm32/mpconfigboard_common.h
@@ -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
diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c
index 51b740a80..b075073a5 100644
--- a/ports/stm32/powerctrlboot.c
+++ b/ports/stm32/powerctrlboot.c
@@ -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);