summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/Makefile6
-rw-r--r--ports/stm32/adc.h2
-rw-r--r--ports/stm32/boards/stm32wl55_af.csv45
-rw-r--r--ports/stm32/boards/stm32wl55xc.ld34
-rw-r--r--ports/stm32/boards/stm32wlxx_hal_conf_base.h78
-rw-r--r--ports/stm32/dma.c12
-rw-r--r--ports/stm32/dma.h2
-rw-r--r--ports/stm32/extint.c22
-rw-r--r--ports/stm32/extint.h2
-rw-r--r--ports/stm32/flash.c8
-rw-r--r--ports/stm32/machine_adc.c24
-rw-r--r--ports/stm32/machine_uart.c2
-rw-r--r--ports/stm32/modmachine.c2
-rw-r--r--ports/stm32/mpconfigboard_common.h10
-rw-r--r--ports/stm32/mphalport.c2
-rw-r--r--ports/stm32/powerctrl.c25
-rw-r--r--ports/stm32/powerctrlboot.c37
-rw-r--r--ports/stm32/rtc.c21
-rw-r--r--ports/stm32/stm32.mk3
-rw-r--r--ports/stm32/stm32_it.c2
-rw-r--r--ports/stm32/timer.c4
-rw-r--r--ports/stm32/uart.c33
-rw-r--r--ports/stm32/uart.h2
23 files changed, 316 insertions, 62 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile
index 4c90c6f1e..dd86f1e3f 100644
--- a/ports/stm32/Makefile
+++ b/ports/stm32/Makefile
@@ -353,8 +353,6 @@ HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
hal_flash_ex.c \
hal_gpio.c \
hal_i2c.c \
- hal_pcd.c \
- hal_pcd_ex.c \
hal_pwr.c \
hal_pwr_ex.c \
hal_rcc.c \
@@ -368,8 +366,10 @@ HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
ll_utils.c \
)
-ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7 l0 l4 wb))
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g4 h7 l0 l4 wb))
HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
+ hal_pcd.c \
+ hal_pcd_ex.c \
ll_usb.c \
)
endif
diff --git a/ports/stm32/adc.h b/ports/stm32/adc.h
index db706ea49..3b79dc01f 100644
--- a/ports/stm32/adc.h
+++ b/ports/stm32/adc.h
@@ -56,6 +56,8 @@ static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) {
adc_common = adc == ADC3 ? ADC3_COMMON : ADC12_COMMON;
#elif defined(STM32L4)
adc_common = __LL_ADC_COMMON_INSTANCE(0);
+ #elif defined(STM32WL)
+ adc_common = ADC_COMMON;
#endif
adc_common->CCR &= ~LL_ADC_PATH_INTERNAL_VBAT;
diff --git a/ports/stm32/boards/stm32wl55_af.csv b/ports/stm32/boards/stm32wl55_af.csv
new file mode 100644
index 000000000..219b8b08b
--- /dev/null
+++ b/ports/stm32/boards/stm32wl55_af.csv
@@ -0,0 +1,45 @@
+Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15,
+,,SYS_AF,TIM1/TIM2/LPTIM1,TIM1/TIM2,SPI2S2/TIM1/LPTIM3,I2C1/I2C2/I2C3,SPI1/SPI2S2,RF,USART1/USART2,LPUART1,,,,COMP1/COMP2/TIM1,DEBUG,TIM2/TIM16/TIM17/LPTIM2,EVENOUT,ADC
+PortA,PA0,,TIM2_CH1,,,I2C3_SMBA,I2S_CKIN,,USART2_CTS,,,,,COMP1_OUT,DEBUG_PWR_REGLP1S,TIM2_ETR,EVENTOUT,ADC123_IN0
+PortA,PA1,,TIM2_CH2,,LPTIM3_OUT,I2C1_SMBA,SPI1_SCK,,USART2_RTS,LPUART1_RTS,,,,,DEBUG_PWR_REGLP2S,,EVENTOUT,ADC123_IN1
+PortA,PA2,LSCO,TIM2_CH3,,,,,,USART2_TX,LPUART1_TX,,,,COMP2_OUT,DEBUG_PWR_LDORDY,,EVENTOUT,ADC123_IN2
+PortA,PA3,,TIM2_CH4,,,,I2S2_MCK,,USART2_RX,LPUART1_RX,,,,,,,EVENTOUT,ADC123_IN3
+PortA,PA4,RTC_OUT2,LPTIM1_OUT,,,,SPI1_NSS,,USART2_CK,,,,,,DEBUG_SUBGHZSPI_NSSOUT,LPTIM2_OUT,EVENTOUT,ADC12_IN4
+PortA,PA5,,TIM2_CH1,TIM2_ETR,SPI2_MISO,,SPI1_SCK,,,,,,,,DEBUG_SUBGHZSPI_SCKOUT,LPTIM2_ETR,EVENTOUT,ADC12_IN5
+PortA,PA6,,TIM1_BKIN,,,I2C2_SMBA,SPI1_MISO,,,LPUART1_CTS,,,,TIM1_BKIN,DEBUG_SUBGHZSPI_MISOOUT,TIM16_CH1,EVENTOUT,ADC12_IN6
+PortA,PA7,,TIM1_CH1N,,,I2C3_SCL,SPI1_MOSI,,,,,,,COMP2_OUT,DEBUG_SUBGHZSPI_MOSIOUT,TIM17_CH1,EVENTOUT,ADC12_IN7
+PortA,PA8,MCO,TIM1_CH1,,,,SPI2_SCK/I2S2_CK,,USART1_CK,,,,,,,LPTIM2_OUT,EVENTOUT,
+PortA,PA9,,TIM1_CH2,,SPI2_NSS/I2S2_WS,I2C1_SCL,SPI2_SCK/I2S2_CK,,USART1_TX,,,,,,,,EVENTOUT,
+PortA,PA10,RTC_REFIN,TIM1_CH3,,,I2C1_SDA,SPI2_MOSI/I2S2_SD,,USART1_RX,,,,,,DEBUG_RF_HSE32RDY,TIM17_BKIN,EVENTOUT,
+PortA,PA11,,TIM1_CH4,TIM1_BKIN2,LPTIM3_ETR,I2C2_SDA,SPI1_MISO,,USART1_CTS,,,,,TIM1_BKIN2,DEBUG_RF_NRESET,,EVENTOUT,
+PortA,PA12,,TIM1_ETR,,LPTIM3_IN1,I2C2_SCL,SPI1_MOSI,RF_BUSY,USART1_RTS,,,,,,,,EVENTOUT,
+PortA,PA13,JTMS/SWDIO,,,,I2C2_SMBA,,,,IR_OUT,,,,,,,EVENTOUT,
+PortA,PA14,JTCK/SWCLK,LPTIM1_OUT,,,I2C1_SMBA,,,,,,,,,,,EVENTOUT,
+PortA,PA15,JTDI,TIM2_CH1,TIM2_ETR,,I2C2_SDA,SPI1_NSS,,,,,,,,,,EVENTOUT,
+PortB,PB0,,,,,,,,,,,,,COMP1_OUT,,,EVENTOUT,ADC12_IN8
+PortB,PB1,,,,,,,,,LPUART1_RTS_DE,,,,,,LPTIM2_IN1,EVENTOUT,ADC12_IN9
+PortB,PB2,,LPTIM1_OUT,,,I2C3_SMBA,SPI1_NSS,,,,,,,,DEBUG_RF_SMPSRDY,,EVENTOUT,
+PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK,RF_IRQ0,USART1_RTS,,,,,,DEBUG_RF_DTB1,,EVENTOUT,
+PortB,PB4,NJTRST,,,,I2C3_SDA,SPI1_MISO,,USART1_CTS,,,,,,DEBUG_RF_LDORDY,TIM17_BKIN,EVENTOUT,
+PortB,PB5,,LPTIM1_IN1,,,I2C1_SMBA,SPI1_MOSI,RF_IRQ1,USART1_CK,,,,,COMP2_OUT,,TIM16_BKIN,EVENTOUT,
+PortB,PB6,,LPTIM1_ETR,,,I2C1_SCL,,,USART1_TX,,,,,,,TIM16_CH1N,EVENTOUT,
+PortB,PB7,,LPTIM1_IN2,,TIM1_BKIN,I2C1_SDA,,,USART1_RX,,,,,,,TIM17_CH1N,EVENTOUT,
+PortB,PB8,,TIM1_CH2N,,,I2C1_SCL,,RF_IRQ2,,,,,,,,TIM16_CH1,EVENTOUT,
+PortB,PB9,,TIM1_CH3N,,,I2C1_SDA,SPI2_NSS/I2S2_WS,,,IR_OUT,,,,,,TIM17_CH1,EVENTOUT,
+PortB,PB10,,TIM2_CH3,,,I2C3_SCL,SPI2_SCK/I2S2_CK,,,LPUART1_RX,,,,COMP1_OUT,,,EVENTOUT,
+PortB,PB11,,TIM2_CH4,,,I2C3_SDA,,,,LPUART1_TX,,,,COMP2_OUT,,,EVENTOUT,
+PortB,PB12,,TIM1_BKIN,,TIM1_BKIN,I2C3_SMBA,SPI2_NSS/I2S2_WS,,,LPUART1_RTS,,,,,,,EVENTOUT,
+PortB,PB13,,TIM1_CH1N,,,I2C3_SCL,SPI2_SCK/I2S2_CK,,,LPUART1_CTS,,,,,,,EVENTOUT,
+PortB,PB14,,TIM1_CH2N,,I2S2_MCK,I2C3_SDA,SPI2_MISO,,,,,,,,,,EVENTOUT,
+PortB,PB15,,TIM1_CH3N,,,I2C2_SCL,SPI2_MOSI/I2S2_SD,,,,,,,,,,EVENTOUT,
+PortC,PC0,,LPTIM1_IN1,,,I2C3_SCL,,,,LPUART1_RX,,,,,,LPTIM2_IN1,EVENTOUT,ADC123_IN10
+PortC,PC1,,LPTIM1_OUT,,SPI2_MOSI/I2S2_SD,I2C3_SDA,,,,LPUART1_TX,,,,,,,EVENTOUT,ADC123_IN11
+PortC,PC2,,LPTIM1_IN2,,,,SPI2_MISO,,,,,,,,,,EVENTOUT,ADC123_IN12
+PortC,PC3,,LPTIM1_ETR,,,,SPI2_MOSI/I2S2_SD,,,,,,,,,LPTIM2_ETR,EVENTOUT,ADC123_IN13
+PortC,PC4,,,,,,,,,,,,,,,,EVENTOUT,ADC12_IN14
+PortC,PC5,,,,,,,,,,,,,,,,EVENTOUT,ADC12_IN15
+PortC,PC6,,,,,,I2S2_MCK,,,,,,,,,,EVENTOUT,
+PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT,
+PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT,
+PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT,
+PortH,PH3,,,,,,,,,,,,,,,,EVENTOUT,
diff --git a/ports/stm32/boards/stm32wl55xc.ld b/ports/stm32/boards/stm32wl55xc.ld
new file mode 100644
index 000000000..109675bb5
--- /dev/null
+++ b/ports/stm32/boards/stm32wl55xc.ld
@@ -0,0 +1,34 @@
+/*
+ GNU linker script for STM32WL55xC
+*/
+
+/* Specify the memory areas */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K /* sectors 0-127 */
+ FLASH_APP (rx) : ORIGIN = 0x08000000, LENGTH = 232K /* sectors 0-115 */
+ FLASH_FS (r) : ORIGIN = 0x0803a000, LENGTH = 24K /* sectors 116-127 */
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* SRAM1+SRAM2 */
+}
+
+/* produce a link error if there is not this amount of RAM for these sections */
+_minimum_stack_size = 2K;
+_minimum_heap_size = 16K;
+
+/* RAM extents for the garbage collector */
+_ram_start = ORIGIN(RAM);
+_ram_end = ORIGIN(RAM) + LENGTH(RAM);
+
+_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(RAM) + LENGTH(RAM);
+_micropy_hw_internal_flash_storage_ram_cache_start = _micropy_hw_internal_flash_storage_ram_cache_end - 2K; /* fs cache = 2K */
+
+/* Define the stack. The stack is full descending so begins at the bottom of FS cache.
+ Note that EABI requires the stack to be 8-byte aligned for a call. */
+_estack = _micropy_hw_internal_flash_storage_ram_cache_start - _estack_reserve;
+_sstack = _estack - 6K;
+
+_heap_start = _ebss; /* heap starts just after statically allocated memory */
+_heap_end = _sstack;
+
+_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS);
+_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS);
diff --git a/ports/stm32/boards/stm32wlxx_hal_conf_base.h b/ports/stm32/boards/stm32wlxx_hal_conf_base.h
new file mode 100644
index 000000000..e98b0525b
--- /dev/null
+++ b/ports/stm32/boards/stm32wlxx_hal_conf_base.h
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MICROPY_INCLUDED_STM32WLXX_HAL_CONF_BASE_H
+#define MICROPY_INCLUDED_STM32WLXX_HAL_CONF_BASE_H
+
+// Include various HAL modules for convenience
+#include "stm32wlxx_hal_dma.h"
+#include "stm32wlxx_hal_adc.h"
+#include "stm32wlxx_hal_cortex.h"
+#include "stm32wlxx_hal_flash.h"
+#include "stm32wlxx_hal_gpio.h"
+#include "stm32wlxx_hal_i2c.h"
+#include "stm32wlxx_hal_pwr.h"
+#include "stm32wlxx_hal_rcc.h"
+#include "stm32wlxx_hal_rtc.h"
+#include "stm32wlxx_hal_spi.h"
+#include "stm32wlxx_hal_tim.h"
+#include "stm32wlxx_hal_uart.h"
+#include "stm32wlxx_hal_usart.h"
+#include "stm32wlxx_ll_adc.h"
+#include "stm32wlxx_ll_lpuart.h"
+#include "stm32wlxx_ll_rtc.h"
+#include "stm32wlxx_ll_usart.h"
+
+// Enable various HAL modules
+#define HAL_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_RTC_MODULE_ENABLED
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
+
+// Oscillator values in Hz
+#define MSI_VALUE (4000000)
+
+// SysTick has the highest priority
+#define TICK_INT_PRIORITY (0x00)
+
+// Miscellaneous HAL settings
+#define DATA_CACHE_ENABLE 1
+#define INSTRUCTION_CACHE_ENABLE 1
+#define PREFETCH_ENABLE 0
+#define USE_SPI_CRC 0
+#define USE_RTOS 0
+
+// HAL parameter assertions are disabled
+#define assert_param(expr) ((void)0)
+
+#endif // MICROPY_INCLUDED_STM32WLXX_HAL_CONF_BASE_H
diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c
index dc706e68a..75c34325d 100644
--- a/ports/stm32/dma.c
+++ b/ports/stm32/dma.c
@@ -74,7 +74,7 @@ typedef union {
struct _dma_descr_t {
#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
DMA_Stream_TypeDef *instance;
- #elif defined(STM32F0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32F0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
DMA_Channel_TypeDef *instance;
#else
#error "Unsupported Processor"
@@ -89,7 +89,7 @@ struct _dma_descr_t {
static const DMA_InitTypeDef dma_init_struct_spi_i2c = {
#if defined(STM32F4) || defined(STM32F7)
.Channel = 0,
- #elif defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
.Request = 0,
#endif
.Direction = 0,
@@ -467,7 +467,7 @@ static const uint8_t dma_irqn[NSTREAM] = {
DMA2_Channel7_IRQn,
};
-#elif defined(STM32WB)
+#elif defined(STM32WB) || defined(STM32WL)
#define NCONTROLLERS (2)
#define NSTREAMS_PER_CONTROLLER (7)
@@ -1152,7 +1152,7 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3
dma->Instance = dma_descr->instance;
dma->Init = *dma_descr->init;
dma->Init.Direction = dir;
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
dma->Init.Request = dma_descr->sub_instance;
#else
#if !defined(STM32F0)
@@ -1179,7 +1179,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir
dma_enable_clock(dma_id);
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
// Always reset and configure the H7 and L0/L4 DMA peripheral
// (dma->State is set to HAL_DMA_STATE_RESET by memset above)
// TODO: understand how L0/L4 DMA works so this is not needed
@@ -1353,7 +1353,7 @@ void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_a
dma->CCR |= DMA_CCR_EN;
}
-#elif defined(STM32WB)
+#elif defined(STM32WB) || defined(STM32WL)
// These functions are currently not implemented or needed for this MCU.
diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h
index 29d5c3d2e..9b0b4c77a 100644
--- a/ports/stm32/dma.h
+++ b/ports/stm32/dma.h
@@ -100,7 +100,7 @@ extern const dma_descr_t dma_I2C_2_RX;
extern const dma_descr_t dma_I2C_1_TX;
extern const dma_descr_t dma_I2C_1_RX;
-#elif defined(STM32L4) || defined(STM32WB)
+#elif defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
extern const dma_descr_t dma_ADC_1_RX;
extern const dma_descr_t dma_ADC_2_RX;
diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c
index bb26b00dd..55c9095f1 100644
--- a/ports/stm32/extint.c
+++ b/ports/stm32/extint.c
@@ -91,7 +91,7 @@
#define EXTI_SWIER_BB(line) (*(__IO uint32_t *)(PERIPH_BB_BASE + ((EXTI_OFFSET + offsetof(EXTI_TypeDef, SWIER)) * 32) + ((line) * 4)))
#endif
-#if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+#if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
// The L4 MCU supports 40 Events/IRQs lines of the type configurable and direct.
// Here we only support configurable line types. Details, see page 330 of RM0351, Rev 1.
// The USB_FS_WAKUP event is a direct type and there is no support for it.
@@ -181,6 +181,12 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
RTC_Alarm_IRQn,
TAMP_STAMP_LSECSS_IRQn,
RTC_WKUP_IRQn,
+ #elif defined(STM32WL)
+ PVD_PVM_IRQn,
+ RTC_Alarm_IRQn,
+ TAMP_STAMP_LSECSS_SSRU_IRQn, // SSRU
+ TAMP_STAMP_LSECSS_SSRU_IRQn, // TAMP, RTC_STAMP, LSE_CSS
+ RTC_WKUP_IRQn,
#else
#if defined(STM32G4) || defined(STM32L4)
PVD_PVM_IRQn,
@@ -308,7 +314,7 @@ void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_
pyb_extint_callback_arg[line] = MP_OBJ_FROM_PTR(pin);
// Route the GPIO to EXTI
- #if !defined(STM32WB)
+ #if !defined(STM32WB) && !defined(STM32WL)
__HAL_RCC_SYSCFG_CLK_ENABLE();
#endif
SYSCFG->EXTICR[line >> 2] =
@@ -345,7 +351,7 @@ void extint_set(const pin_obj_t *pin, uint32_t mode) {
pyb_extint_callback_arg[line] = MP_OBJ_FROM_PTR(pin);
// Route the GPIO to EXTI
- #if !defined(STM32WB)
+ #if !defined(STM32WB) && !defined(STM32WL)
__HAL_RCC_SYSCFG_CLK_ENABLE();
#endif
SYSCFG->EXTICR[line >> 2] =
@@ -385,7 +391,7 @@ void extint_enable(uint line) {
if (pyb_extint_mode[line] == EXTI_Mode_Interrupt) {
#if defined(STM32H7)
EXTI_D1->IMR1 |= (1 << line);
- #elif defined(STM32G4) || defined(STM32WB)
+ #elif defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 |= (1 << line);
#else
EXTI->IMR |= (1 << line);
@@ -393,7 +399,7 @@ void extint_enable(uint line) {
} else {
#if defined(STM32H7)
EXTI_D1->EMR1 |= (1 << line);
- #elif defined(STM32G4) || defined(STM32WB)
+ #elif defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
EXTI->EMR1 |= (1 << line);
#else
EXTI->EMR |= (1 << line);
@@ -419,7 +425,7 @@ void extint_disable(uint line) {
#if defined(STM32H7)
EXTI_D1->IMR1 &= ~(1 << line);
EXTI_D1->EMR1 &= ~(1 << line);
- #elif defined(STM32G4) || defined(STM32WB)
+ #elif defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 &= ~(1 << line);
EXTI->EMR1 &= ~(1 << line);
#else
@@ -441,7 +447,7 @@ void extint_swint(uint line) {
return;
}
// we need 0 to 1 transition to trigger the interrupt
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
EXTI->SWIER1 &= ~(1 << line);
EXTI->SWIER1 |= (1 << line);
#else
@@ -519,7 +525,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_swint_obj, extint_obj_swint);
/// \classmethod regs()
/// Dump the values of the EXTI registers.
STATIC mp_obj_t extint_regs(void) {
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
printf("EXTI_IMR1 %08x\n", (unsigned int)EXTI->IMR1);
printf("EXTI_IMR2 %08x\n", (unsigned int)EXTI->IMR2);
printf("EXTI_EMR1 %08x\n", (unsigned int)EXTI->EMR1);
diff --git a/ports/stm32/extint.h b/ports/stm32/extint.h
index 0cdf5024a..247852fa1 100644
--- a/ports/stm32/extint.h
+++ b/ports/stm32/extint.h
@@ -43,7 +43,7 @@
#endif
#define EXTI_ETH_WAKEUP (19)
#define EXTI_USB_OTG_HS_WAKEUP (20)
-#if defined(STM32F0) || defined(STM32G4) || defined(STM32L4)
+#if defined(STM32F0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WL)
#define EXTI_RTC_TIMESTAMP (19)
#define EXTI_RTC_WAKEUP (20)
#elif defined(STM32H7) || defined(STM32WB)
diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c
index eeeab5204..0c4d2cf5b 100644
--- a/ports/stm32/flash.c
+++ b/ports/stm32/flash.c
@@ -97,7 +97,7 @@ static const flash_layout_t flash_layout[] = {
};
#endif
-#elif defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+#elif defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
static const flash_layout_t flash_layout[] = {
{ (uint32_t)FLASH_BASE, (uint32_t)FLASH_PAGE_SIZE, 512 },
@@ -159,7 +159,7 @@ static uint32_t get_page(uint32_t addr) {
}
#endif
-#elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB)
+#elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB) || defined(STM32WL)
static uint32_t get_page(uint32_t addr) {
return (addr - FLASH_BASE) / FLASH_PAGE_SIZE;
@@ -263,7 +263,7 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = flash_dest;
EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
- #elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB)
+ #elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB) || defined(STM32WL)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = get_page(flash_dest);
@@ -370,7 +370,7 @@ int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
HAL_StatusTypeDef status = HAL_OK;
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
// program the flash uint64 by uint64
for (int i = 0; i < num_word32 / 2; i++) {
diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c
index 21b35cdcd..819fd3414 100644
--- a/ports/stm32/machine_adc.c
+++ b/ports/stm32/machine_adc.c
@@ -28,7 +28,7 @@
#include "py/mphal.h"
#include "adc.h"
-#if defined(STM32F0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+#if defined(STM32F0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
#define ADC_V2 (1)
#else
#define ADC_V2 (0)
@@ -42,7 +42,7 @@
#define ADCx_COMMON __LL_ADC_COMMON_INSTANCE(0)
#endif
-#if defined(STM32F0) || defined(STM32L0)
+#if defined(STM32F0) || defined(STM32L0) || defined(STM32WL)
#define ADC_STAB_DELAY_US (1)
#define ADC_TEMPSENSOR_DELAY_US (10)
#elif defined(STM32G4)
@@ -65,7 +65,7 @@
#elif defined(STM32H7)
#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_8CYCLES_5
#define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_387CYCLES_5
-#elif defined(STM32L0)
+#elif defined(STM32L0) || defined(STM32WL)
#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_12CYCLES_5
#define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_160CYCLES_5
#elif defined(STM32L4) || defined(STM32WB)
@@ -105,7 +105,7 @@ STATIC const uint8_t adc_cr_to_bits_table[] = {12, 10, 8, 6};
void adc_config(ADC_TypeDef *adc, uint32_t bits) {
// Configure ADC clock source and enable ADC clock
- #if defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);
__HAL_RCC_ADC_CLK_ENABLE();
#else
@@ -150,6 +150,8 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {
ADC1_COMMON->CCR = 0; // ADCPR=PCLK/2
#elif defined(STM32WB)
ADC1_COMMON->CCR = 0 << ADC_CCR_PRESC_Pos | 0 << ADC_CCR_CKMODE_Pos; // PRESC=1, MODE=ASYNC
+ #elif defined(STM32WL)
+ ADC_COMMON->CCR = 0 << ADC_CCR_PRESC_Pos; // PRESC=1
#endif
#if defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
@@ -158,7 +160,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {
}
#endif
- #if defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
if (!(adc->CR & ADC_CR_ADVREGEN)) {
adc->CR = ADC_CR_ADVREGEN; // enable VREG
#if defined(STM32H7)
@@ -172,7 +174,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {
#if ADC_V2
if (!(adc->CR & ADC_CR_ADEN)) {
// ADC isn't enabled so calibrate it now
- #if defined(STM32F0) || defined(STM32L0)
+ #if defined(STM32F0) || defined(STM32L0) || defined(STM32WL)
LL_ADC_StartCalibration(adc);
#elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED);
@@ -235,7 +237,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {
}
STATIC int adc_get_bits(ADC_TypeDef *adc) {
- #if defined(STM32F0) || defined(STM32L0)
+ #if defined(STM32F0) || defined(STM32L0) || defined(STM32WL)
uint32_t res = (adc->CFGR1 & ADC_CFGR1_RES) >> ADC_CFGR1_RES_Pos;
#elif defined(STM32F4) || defined(STM32F7)
uint32_t res = (adc->CR1 & ADC_CR1_RES) >> ADC_CR1_RES_Pos;
@@ -409,7 +411,11 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
uint32_t sample_time = ADC_SAMPLETIME_DEFAULT;
ADC_TypeDef *adc;
if (mp_obj_is_int(source)) {
+ #if defined(STM32WL)
+ adc = ADC;
+ #else
adc = ADC1;
+ #endif
channel = mp_obj_get_int(source);
if (channel == ADC_CHANNEL_VREFINT
#if defined(STM32G4)
@@ -426,7 +432,11 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
} else {
const pin_obj_t *pin = pin_find(source);
if (pin->adc_num & PIN_ADC1) {
+ #if defined(STM32WL)
+ adc = ADC;
+ #else
adc = ADC1;
+ #endif
#if defined(ADC2)
} else if (pin->adc_num & PIN_ADC2) {
adc = ADC2;
diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c
index 6a12fad32..681939094 100644
--- a/ports/stm32/machine_uart.c
+++ b/ports/stm32/machine_uart.c
@@ -459,7 +459,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_readchar_obj, pyb_uart_readchar);
// uart.sendbreak()
STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
self->uartx->RQR = USART_RQR_SBKRQ; // write-only register
#else
self->uartx->CR1 |= USART_CR1_SBK;
diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c
index f9026bc37..57b8ef5e6 100644
--- a/ports/stm32/modmachine.c
+++ b/ports/stm32/modmachine.c
@@ -63,7 +63,7 @@
#define RCC_CSR_BORRSTF RCC_CSR_PORRSTF
#endif
-#if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+#if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
// L4 does not have a POR, so use BOR instead
#define RCC_CSR_PORRSTF RCC_CSR_BORRSTF
#endif
diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h
index 17a4ad26e..7c8662318 100644
--- a/ports/stm32/mpconfigboard_common.h
+++ b/ports/stm32/mpconfigboard_common.h
@@ -404,6 +404,16 @@
#define MICROPY_HW_RFCORE_BLE_LL_ONLY (1) // use LL only, we provide the rest of the BLE stack
#endif
+// Configuration for STM32WL series
+#elif defined(STM32WL)
+
+#define MP_HAL_UNIQUE_ID_ADDRESS (UID_BASE)
+#define PYB_EXTI_NUM_VECTORS (21) // up to RTC_WKUP
+#define MICROPY_HW_MAX_I2C (3)
+#define MICROPY_HW_MAX_TIMER (17)
+#define MICROPY_HW_MAX_UART (2)
+#define MICROPY_HW_MAX_LPUART (1)
+
#else
#error Unsupported MCU series
#endif
diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c
index 2b98a620e..202538841 100644
--- a/ports/stm32/mphalport.c
+++ b/ports/stm32/mphalport.c
@@ -99,7 +99,7 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {
#elif defined(STM32L0)
#define AHBxENR IOPENR
#define AHBxENR_GPIOAEN_Pos RCC_IOPENR_IOPAEN_Pos
- #elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
#define AHBxENR AHB2ENR
#define AHBxENR_GPIOAEN_Pos RCC_AHB2ENR_GPIOAEN_Pos
#endif
diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c
index ad3a3ea4c..a2e3b5c71 100644
--- a/ports/stm32/powerctrl.c
+++ b/ports/stm32/powerctrl.c
@@ -151,7 +151,7 @@ void powerctrl_check_enter_bootloader(void) {
#endif
}
-#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32WB)
+#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32WB) && !defined(STM32WL)
typedef struct _sysclk_scaling_table_entry_t {
uint16_t mhz;
@@ -542,9 +542,15 @@ set_clk:
return 0;
}
-#elif defined(STM32WB)
+#elif defined(STM32WB) || defined(STM32WL)
+#if defined(STM32WB)
#include "stm32wbxx_ll_utils.h"
+#define FLASH_LATENCY_MAX LL_FLASH_LATENCY_3
+#else
+#include "stm32wlxx_ll_utils.h"
+#define FLASH_LATENCY_MAX LL_FLASH_LATENCY_2
+#endif
#define LPR_THRESHOLD (2000000)
#define VOS2_THRESHOLD (16000000)
@@ -605,8 +611,8 @@ int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t
} else if (sysclk_mode == SYSCLK_MODE_MSI) {
// Set flash latency to maximum to ensure the latency is large enough for
// both the current SYSCLK and the SYSCLK that will be selected below.
- LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
- while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3) {
+ LL_FLASH_SetLatency(FLASH_LATENCY_MAX);
+ while (LL_FLASH_GetLatency() != FLASH_LATENCY_MAX) {
}
// Before changing the MSIRANGE value, if MSI is on then it must also be ready.
@@ -686,7 +692,7 @@ void powerctrl_enter_stop_mode(void) {
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
#endif
- #if !defined(STM32F0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB)
+ #if !defined(STM32F0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB) && !defined(STM32WL)
// takes longer to wake but reduces stop current
HAL_PWREx_EnableFlashPowerDown();
#endif
@@ -765,7 +771,7 @@ void powerctrl_enter_stop_mode(void) {
#if defined(STM32H7)
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL1) {
}
- #elif defined(STM32WB)
+ #elif defined(STM32WB) || defined(STM32WL)
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) {
}
#else
@@ -861,7 +867,7 @@ void powerctrl_enter_standby_mode(void) {
#if defined(STM32F0) || defined(STM32L0)
#define CR_BITS (RTC_CR_ALRAIE | RTC_CR_WUTIE | RTC_CR_TSIE)
#define ISR_BITS (RTC_ISR_ALRAF | RTC_ISR_WUTF | RTC_ISR_TSF)
- #elif defined(STM32G4)
+ #elif defined(STM32G4) || defined(STM32WL)
#define CR_BITS (RTC_CR_ALRAIE | RTC_CR_ALRBIE | RTC_CR_WUTIE | RTC_CR_TSIE)
#define ISR_BITS (RTC_MISR_ALRAMF | RTC_MISR_ALRBMF | RTC_MISR_WUTMF | RTC_MISR_TSMF)
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
@@ -885,7 +891,7 @@ void powerctrl_enter_standby_mode(void) {
// clear RTC wake-up flags
#if defined(SR_BITS)
RTC->SR &= ~SR_BITS;
- #elif defined(STM32G4)
+ #elif defined(STM32G4) || defined(STM32WL)
RTC->MISR &= ~ISR_BITS;
#else
RTC->ISR &= ~ISR_BITS;
@@ -907,6 +913,9 @@ void powerctrl_enter_standby_mode(void) {
// clear all wake-up flags
PWR->SCR |= PWR_SCR_CWUF5 | PWR_SCR_CWUF4 | PWR_SCR_CWUF3 | PWR_SCR_CWUF2 | PWR_SCR_CWUF1;
// TODO
+ #elif defined(STM32WL)
+ // clear all wake-up flags
+ PWR->SCR |= PWR_SCR_CWUF3 | PWR_SCR_CWUF2 | PWR_SCR_CWUF1;
#else
// clear global wake-up flag
PWR->CR |= PWR_CR_CWUF;
diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c
index 41b56296e..4ecd83e2c 100644
--- a/ports/stm32/powerctrlboot.c
+++ b/ports/stm32/powerctrlboot.c
@@ -212,4 +212,41 @@ void SystemClock_Config(void) {
powerctrl_config_systick();
}
+#elif defined(STM32WL)
+
+#include "stm32wlxx_ll_utils.h"
+
+void SystemClock_Config(void) {
+ // Set flash latency
+ LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
+ while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) {
+ }
+
+ LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
+
+ // Enable MSI
+ LL_RCC_MSI_Enable();
+ while (!LL_RCC_MSI_IsReady()) {
+ }
+
+ // Configure MSI
+ LL_RCC_MSI_EnableRangeSelection();
+ LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_11);
+ LL_RCC_MSI_SetCalibTrimming(0);
+
+ // Select SYSCLK source
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
+ while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
+ }
+
+ // Set bus dividers
+ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
+ LL_RCC_SetAHB3Prescaler(LL_RCC_SYSCLK_DIV_1);
+ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
+ LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
+
+ SystemCoreClockUpdate();
+ powerctrl_config_systick();
+}
+
#endif
diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c
index 1164e71e0..e776f67bb 100644
--- a/ports/stm32/rtc.c
+++ b/ports/stm32/rtc.c
@@ -94,6 +94,11 @@ STATIC bool rtc_need_init_finalise = false;
#endif
void rtc_init_start(bool force_init) {
+ #if defined(STM32WL)
+ // Enable the RTC APB bus clock, to communicate with the RTC.
+ __HAL_RCC_RTCAPB_CLK_ENABLE();
+ #endif
+
RTCHandle.Instance = RTC;
/* Configure RTC prescaler and RTC data registers */
@@ -220,7 +225,7 @@ void rtc_init_finalise() {
// fresh reset; configure RTC Calendar
RTC_CalendarConfig();
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST) != RESET) {
#else
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) {
@@ -252,7 +257,7 @@ STATIC HAL_StatusTypeDef PYB_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct
/*------------------------------ LSE Configuration -------------------------*/
if ((RCC_OscInitStruct->OscillatorType & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) {
- #if !defined(STM32H7) && !defined(STM32WB)
+ #if !defined(STM32H7) && !defined(STM32WB) && !defined(STM32WL)
// Enable Power Clock
__HAL_RCC_PWR_CLK_ENABLE();
#endif
@@ -261,7 +266,7 @@ STATIC HAL_StatusTypeDef PYB_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct
HAL_PWR_EnableBkUpAccess();
uint32_t tickstart = HAL_GetTick();
- #if defined(STM32F7) || defined(STM32G4) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32F7) || defined(STM32G4) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
// __HAL_RCC_PWR_CLK_ENABLE();
// Enable write access to Backup domain
// PWR->CR1 |= PWR_CR1_DBP;
@@ -349,7 +354,7 @@ STATIC HAL_StatusTypeDef PYB_RTC_Init(RTC_HandleTypeDef *hrtc) {
#elif defined(STM32F7)
hrtc->Instance->OR &= (uint32_t) ~RTC_OR_ALARMTYPE;
hrtc->Instance->OR |= (uint32_t)(hrtc->Init.OutPutType);
- #elif defined(STM32G4)
+ #elif defined(STM32G4) || defined(STM32WL)
hrtc->Instance->CR &= (uint32_t) ~RTC_CR_TAMPALRM_TYPE_Msk;
hrtc->Instance->CR |= (uint32_t)(hrtc->Init.OutPutType);
#else
@@ -714,7 +719,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
RTC->WPR = 0xff;
// enable external interrupts on line EXTI_RTC_WAKEUP
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 |= 1 << EXTI_RTC_WAKEUP;
EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP;
#elif defined(STM32H7)
@@ -726,14 +731,14 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
#endif
// clear interrupt flags
- #if defined(STM32G4)
+ #if defined(STM32G4) || defined(STM32WL)
RTC->ICSR &= ~RTC_ICSR_WUTWF;
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
RTC->SR &= ~RTC_SR_WUTF;
#else
RTC->ISR &= ~RTC_ISR_WUTF;
#endif
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
EXTI->PR1 = 1 << EXTI_RTC_WAKEUP;
#elif defined(STM32H7)
EXTI_D1->PR1 = 1 << EXTI_RTC_WAKEUP;
@@ -753,7 +758,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
RTC->WPR = 0xff;
// disable external interrupts on line EXTI_RTC_WAKEUP
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 &= ~(1 << EXTI_RTC_WAKEUP);
#elif defined(STM32H7)
EXTI_D1->IMR1 |= 1 << EXTI_RTC_WAKEUP;
diff --git a/ports/stm32/stm32.mk b/ports/stm32/stm32.mk
index f17351cdc..4de101ce7 100644
--- a/ports/stm32/stm32.mk
+++ b/ports/stm32/stm32.mk
@@ -48,7 +48,7 @@ CFLAGS_CORTEX_M += -mfpu=fpv5-d16 -mfloat-abi=hard
SUPPORTS_HARDWARE_FP_SINGLE = 1
SUPPORTS_HARDWARE_FP_DOUBLE = 1
else
-ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 l0))
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 l0 wl))
CFLAGS_CORTEX_M += -msoft-float
else
CFLAGS_CORTEX_M += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
@@ -66,3 +66,4 @@ CFLAGS_MCU_l0 = $(CFLAGS_CORTEX_M) -mtune=cortex-m0plus -mcpu=cortex-m0plus
CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
CFLAGS_MCU_h7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7
CFLAGS_MCU_wb = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
+CFLAGS_MCU_wl = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c
index 84274e3c6..39229a143 100644
--- a/ports/stm32/stm32_it.c
+++ b/ports/stm32/stm32_it.c
@@ -529,7 +529,7 @@ void TAMP_STAMP_IRQHandler(void) {
void RTC_WKUP_IRQHandler(void) {
IRQ_ENTER(RTC_WKUP_IRQn);
- #if defined(STM32G4)
+ #if defined(STM32G4) || defined(STM32WL)
RTC->MISR &= ~RTC_MISR_WUTMF; // clear wakeup interrupt flag
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
RTC->SR &= ~RTC_SR_WUTF; // clear wakeup interrupt flag
diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c
index 57c8dc6c7..12f0515d4 100644
--- a/ports/stm32/timer.c
+++ b/ports/stm32/timer.c
@@ -873,14 +873,14 @@ STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {
#endif
#endif
#if defined(TIM16)
- #if defined(STM32F0) || defined(STM32H7)
+ #if defined(STM32F0) || defined(STM32H7) || defined(STM32WL)
TIM_ENTRY(16, TIM16_IRQn),
#else
TIM_ENTRY(16, TIM1_UP_TIM16_IRQn),
#endif
#endif
#if defined(TIM17)
- #if defined(STM32F0) || defined(STM32H7)
+ #if defined(STM32F0) || defined(STM32H7) || defined(STM32WL)
TIM_ENTRY(17, TIM17_IRQn),
#else
TIM_ENTRY(17, TIM1_TRG_COM_TIM17_IRQn),
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index 61e72999e..13e1667d2 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -41,16 +41,25 @@
#if defined(STM32F4)
#define UART_RXNE_IS_SET(uart) ((uart)->SR & USART_SR_RXNE)
#else
-#if defined(STM32H7)
+#if defined(STM32H7) || defined(STM32WL)
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#endif
#define UART_RXNE_IS_SET(uart) ((uart)->ISR & USART_ISR_RXNE)
#endif
+#if defined(STM32WL)
+#define UART_RXNE_IT_EN(uart) do { (uart)->CR1 |= USART_CR1_RXNEIE_RXFNEIE; } while (0)
+#define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE_RXFNEIE; } while (0)
+#else
#define UART_RXNE_IT_EN(uart) do { (uart)->CR1 |= USART_CR1_RXNEIE; } while (0)
#define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE; } while (0)
+#endif
+#if defined(STM32WL)
+#define USART_CR1_IE_BASE (USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | USART_CR1_IDLEIE)
+#else
#define USART_CR1_IE_BASE (USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | USART_CR1_IDLEIE)
+#endif
#define USART_CR2_IE_BASE (USART_CR2_LBDIE)
#define USART_CR3_IE_BASE (USART_CR3_CTSIE | USART_CR3_EIE)
@@ -92,7 +101,7 @@
#define USART_CR2_IE_ALL (USART_CR2_IE_BASE)
#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_WUFIE)
-#elif defined(STM32L4) || defined(STM32WB)
+#elif defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE)
#define USART_CR2_IE_ALL (USART_CR2_IE_BASE)
#if defined(USART_CR3_TCBGTIE)
@@ -113,9 +122,17 @@ typedef struct _pyb_uart_irq_map_t {
STATIC const pyb_uart_irq_map_t mp_uart_irq_map[] = {
{ USART_CR1_IDLEIE, UART_FLAG_IDLE}, // RX idle
{ USART_CR1_PEIE, UART_FLAG_PE}, // parity error
+ #if defined(STM32WL)
+ { USART_CR1_TXEIE_TXFNFIE, UART_FLAG_TXE}, // TX register empty
+ #else
{ USART_CR1_TXEIE, UART_FLAG_TXE}, // TX register empty
+ #endif
{ USART_CR1_TCIE, UART_FLAG_TC}, // TX complete
+ #if defined(STM32WL)
+ { USART_CR1_RXNEIE_RXFNEIE, UART_FLAG_RXNE}, // RX register not empty
+ #else
{ USART_CR1_RXNEIE, UART_FLAG_RXNE}, // RX register not empty
+ #endif
#if 0
// For now only IRQs selected by CR1 are supported
#if defined(STM32F4)
@@ -813,14 +830,14 @@ uint32_t uart_get_baudrate(pyb_uart_obj_t *self) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
return LL_LPUART_GetBaudRate(self->uartx, uart_get_source_freq(self)
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
, self->uartx->PRESC
#endif
);
}
#endif
return LL_USART_GetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
self->uartx->PRESC,
#endif
LL_USART_OVERSAMPLING_16);
@@ -830,7 +847,7 @@ void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
LL_LPUART_SetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
LL_LPUART_PRESCALER_DIV1,
#endif
baudrate);
@@ -838,7 +855,7 @@ void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
}
#endif
LL_USART_SetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
LL_USART_PRESCALER_DIV1,
#endif
LL_USART_OVERSAMPLING_16, baudrate);
@@ -889,7 +906,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
return data;
} else {
// no buffering
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
int data = self->uartx->RDR & self->char_mask;
self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set
return data;
@@ -1039,7 +1056,7 @@ void uart_irq_handler(mp_uint_t uart_id) {
uint16_t next_head = (self->read_buf_head + 1) % self->read_buf_len;
if (next_head != self->read_buf_tail) {
// only read data if room in buf
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
int data = self->uartx->RDR; // clears UART_FLAG_RXNE
#else
self->mp_irq_flags = self->uartx->SR; // resample to get any new flags since next read of DR will clear SR
diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h
index 0a268ad46..5fee841f8 100644
--- a/ports/stm32/uart.h
+++ b/ports/stm32/uart.h
@@ -102,7 +102,7 @@ void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
static inline bool uart_tx_avail(pyb_uart_obj_t *self) {
#if defined(STM32F4)
return self->uartx->SR & USART_SR_TXE;
- #elif defined(STM32H7)
+ #elif defined(STM32H7) || defined(STM32WL)
return self->uartx->ISR & USART_ISR_TXE_TXFNF;
#else
return self->uartx->ISR & USART_ISR_TXE;