stm32: Add initial support for STM32WL MCUs.

Signed-off-by: Damien George <damien@micropython.org>
pull/7212/head
Damien George 2021-02-22 11:55:12 +11:00
rodzic 9127e63708
commit e0a0719416
23 zmienionych plików z 316 dodań i 62 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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,
1 Port AF0 AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AF9 AF10 AF11 AF12 AF13 AF14 AF15
2 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
3 PortA PA0 TIM2_CH1 I2C3_SMBA I2S_CKIN USART2_CTS COMP1_OUT DEBUG_PWR_REGLP1S TIM2_ETR EVENTOUT ADC123_IN0
4 PortA PA1 TIM2_CH2 LPTIM3_OUT I2C1_SMBA SPI1_SCK USART2_RTS LPUART1_RTS DEBUG_PWR_REGLP2S EVENTOUT ADC123_IN1
5 PortA PA2 LSCO TIM2_CH3 USART2_TX LPUART1_TX COMP2_OUT DEBUG_PWR_LDORDY EVENTOUT ADC123_IN2
6 PortA PA3 TIM2_CH4 I2S2_MCK USART2_RX LPUART1_RX EVENTOUT ADC123_IN3
7 PortA PA4 RTC_OUT2 LPTIM1_OUT SPI1_NSS USART2_CK DEBUG_SUBGHZSPI_NSSOUT LPTIM2_OUT EVENTOUT ADC12_IN4
8 PortA PA5 TIM2_CH1 TIM2_ETR SPI2_MISO SPI1_SCK DEBUG_SUBGHZSPI_SCKOUT LPTIM2_ETR EVENTOUT ADC12_IN5
9 PortA PA6 TIM1_BKIN I2C2_SMBA SPI1_MISO LPUART1_CTS TIM1_BKIN DEBUG_SUBGHZSPI_MISOOUT TIM16_CH1 EVENTOUT ADC12_IN6
10 PortA PA7 TIM1_CH1N I2C3_SCL SPI1_MOSI COMP2_OUT DEBUG_SUBGHZSPI_MOSIOUT TIM17_CH1 EVENTOUT ADC12_IN7
11 PortA PA8 MCO TIM1_CH1 SPI2_SCK/I2S2_CK USART1_CK LPTIM2_OUT EVENTOUT
12 PortA PA9 TIM1_CH2 SPI2_NSS/I2S2_WS I2C1_SCL SPI2_SCK/I2S2_CK USART1_TX EVENTOUT
13 PortA PA10 RTC_REFIN TIM1_CH3 I2C1_SDA SPI2_MOSI/I2S2_SD USART1_RX DEBUG_RF_HSE32RDY TIM17_BKIN EVENTOUT
14 PortA PA11 TIM1_CH4 TIM1_BKIN2 LPTIM3_ETR I2C2_SDA SPI1_MISO USART1_CTS TIM1_BKIN2 DEBUG_RF_NRESET EVENTOUT
15 PortA PA12 TIM1_ETR LPTIM3_IN1 I2C2_SCL SPI1_MOSI RF_BUSY USART1_RTS EVENTOUT
16 PortA PA13 JTMS/SWDIO I2C2_SMBA IR_OUT EVENTOUT
17 PortA PA14 JTCK/SWCLK LPTIM1_OUT I2C1_SMBA EVENTOUT
18 PortA PA15 JTDI TIM2_CH1 TIM2_ETR I2C2_SDA SPI1_NSS EVENTOUT
19 PortB PB0 COMP1_OUT EVENTOUT ADC12_IN8
20 PortB PB1 LPUART1_RTS_DE LPTIM2_IN1 EVENTOUT ADC12_IN9
21 PortB PB2 LPTIM1_OUT I2C3_SMBA SPI1_NSS DEBUG_RF_SMPSRDY EVENTOUT
22 PortB PB3 JTDO/TRACESWO TIM2_CH2 SPI1_SCK RF_IRQ0 USART1_RTS DEBUG_RF_DTB1 EVENTOUT
23 PortB PB4 NJTRST I2C3_SDA SPI1_MISO USART1_CTS DEBUG_RF_LDORDY TIM17_BKIN EVENTOUT
24 PortB PB5 LPTIM1_IN1 I2C1_SMBA SPI1_MOSI RF_IRQ1 USART1_CK COMP2_OUT TIM16_BKIN EVENTOUT
25 PortB PB6 LPTIM1_ETR I2C1_SCL USART1_TX TIM16_CH1N EVENTOUT
26 PortB PB7 LPTIM1_IN2 TIM1_BKIN I2C1_SDA USART1_RX TIM17_CH1N EVENTOUT
27 PortB PB8 TIM1_CH2N I2C1_SCL RF_IRQ2 TIM16_CH1 EVENTOUT
28 PortB PB9 TIM1_CH3N I2C1_SDA SPI2_NSS/I2S2_WS IR_OUT TIM17_CH1 EVENTOUT
29 PortB PB10 TIM2_CH3 I2C3_SCL SPI2_SCK/I2S2_CK LPUART1_RX COMP1_OUT EVENTOUT
30 PortB PB11 TIM2_CH4 I2C3_SDA LPUART1_TX COMP2_OUT EVENTOUT
31 PortB PB12 TIM1_BKIN TIM1_BKIN I2C3_SMBA SPI2_NSS/I2S2_WS LPUART1_RTS EVENTOUT
32 PortB PB13 TIM1_CH1N I2C3_SCL SPI2_SCK/I2S2_CK LPUART1_CTS EVENTOUT
33 PortB PB14 TIM1_CH2N I2S2_MCK I2C3_SDA SPI2_MISO EVENTOUT
34 PortB PB15 TIM1_CH3N I2C2_SCL SPI2_MOSI/I2S2_SD EVENTOUT
35 PortC PC0 LPTIM1_IN1 I2C3_SCL LPUART1_RX LPTIM2_IN1 EVENTOUT ADC123_IN10
36 PortC PC1 LPTIM1_OUT SPI2_MOSI/I2S2_SD I2C3_SDA LPUART1_TX EVENTOUT ADC123_IN11
37 PortC PC2 LPTIM1_IN2 SPI2_MISO EVENTOUT ADC123_IN12
38 PortC PC3 LPTIM1_ETR SPI2_MOSI/I2S2_SD LPTIM2_ETR EVENTOUT ADC123_IN13
39 PortC PC4 EVENTOUT ADC12_IN14
40 PortC PC5 EVENTOUT ADC12_IN15
41 PortC PC6 I2S2_MCK EVENTOUT
42 PortC PC13 EVENTOUT
43 PortC PC14 EVENTOUT
44 PortC PC15 EVENTOUT
45 PortH PH3 EVENTOUT

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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.

Wyświetl plik

@ -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;

Wyświetl plik

@ -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);

Wyświetl plik

@ -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)

Wyświetl plik

@ -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++) {

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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),

Wyświetl plik

@ -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

Wyświetl plik

@ -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;