stm32: Add initial support for STM32WBxx MCUs.
This new series of MCUs is similar to the L4 series with an additional Cortex-M0 coprocessor. The firmware for the wireless stack must be managed separately and MicroPython does not currently interface to it. Supported features so far include: RTC, UART, USB, internal flash filesystem.
This commit is contained in:
parent
d42392b9a7
commit
59b7166d87
|
@ -79,6 +79,7 @@ CFLAGS_MCU_f7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7
|
|||
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 = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA)
|
||||
CFLAGS += -D$(CMSIS_MCU)
|
||||
|
@ -335,7 +336,7 @@ SRC_HAL = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
|
|||
hal_uart.c \
|
||||
)
|
||||
|
||||
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7 l0 l4))
|
||||
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7 l0 l4 wb))
|
||||
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
|
||||
ll_usb.c \
|
||||
)
|
||||
|
@ -361,7 +362,7 @@ endif
|
|||
ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx))
|
||||
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_fdcan.c)
|
||||
else
|
||||
ifneq ($(MCU_SERIES),$(filter $(MCU_SERIES),l0))
|
||||
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 f4 f7 h7 l4))
|
||||
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_can.c)
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -34,6 +34,18 @@
|
|||
#include "dma.h"
|
||||
#include "irq.h"
|
||||
|
||||
#if defined(STM32WB)
|
||||
|
||||
// DMA is currently not implemented for this MCU
|
||||
|
||||
void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir, void *data) {
|
||||
}
|
||||
|
||||
void dma_deinit(const dma_descr_t *dma_descr) {
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define DMA_IDLE_ENABLED() (dma_idle.enabled != 0)
|
||||
#define DMA_SYSTICK_LOG2 (3)
|
||||
#define DMA_SYSTICK_MASK ((1 << DMA_SYSTICK_LOG2) - 1)
|
||||
|
@ -919,3 +931,5 @@ void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_a
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // defined(STM32WB)
|
||||
|
|
|
@ -73,7 +73,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)
|
||||
#elif defined(STM32L4) || defined(STM32WB)
|
||||
|
||||
extern const dma_descr_t dma_ADC_1_RX;
|
||||
extern const dma_descr_t dma_ADC_2_RX;
|
||||
|
|
|
@ -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(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
// 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.
|
||||
|
@ -140,6 +140,7 @@ STATIC mp_obj_t pyb_extint_callback_arg[EXTI_NUM_VECTORS];
|
|||
|
||||
STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
|
||||
#if defined(STM32F0) || defined(STM32L0)
|
||||
|
||||
EXTI0_1_IRQn, EXTI0_1_IRQn, EXTI2_3_IRQn, EXTI2_3_IRQn,
|
||||
EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn,
|
||||
|
@ -155,11 +156,19 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
|
|||
RTC_IRQn,
|
||||
ADC1_COMP_IRQn,
|
||||
ADC1_COMP_IRQn,
|
||||
|
||||
#else
|
||||
|
||||
EXTI0_IRQn, EXTI1_IRQn, EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn,
|
||||
EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn,
|
||||
EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn,
|
||||
EXTI15_10_IRQn,
|
||||
#if defined(STM32WB)
|
||||
PVD_PVM_IRQn,
|
||||
RTC_Alarm_IRQn,
|
||||
TAMP_STAMP_LSECSS_IRQn,
|
||||
RTC_WKUP_IRQn,
|
||||
#else
|
||||
#if defined(STM32L4)
|
||||
PVD_PVM_IRQn,
|
||||
#else
|
||||
|
@ -177,6 +186,8 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
|
|||
TAMP_STAMP_IRQn,
|
||||
RTC_WKUP_IRQn,
|
||||
#endif
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// Set override_callback_obj to true if you want to unconditionally set the
|
||||
|
@ -285,7 +296,9 @@ 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)
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
#endif
|
||||
SYSCFG->EXTICR[line >> 2] =
|
||||
(SYSCFG->EXTICR[line >> 2] & ~(0x0f << (4 * (line & 0x03))))
|
||||
| ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (4 * (line & 0x03)));
|
||||
|
@ -320,7 +333,9 @@ 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)
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
#endif
|
||||
SYSCFG->EXTICR[line >> 2] =
|
||||
(SYSCFG->EXTICR[line >> 2] & ~(0x0f << (4 * (line & 0x03))))
|
||||
| ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (4 * (line & 0x03)));
|
||||
|
@ -358,12 +373,16 @@ void extint_enable(uint line) {
|
|||
if (pyb_extint_mode[line] == EXTI_Mode_Interrupt) {
|
||||
#if defined(STM32H7)
|
||||
EXTI_D1->IMR1 |= (1 << line);
|
||||
#elif defined(STM32WB)
|
||||
EXTI->IMR1 |= (1 << line);
|
||||
#else
|
||||
EXTI->IMR |= (1 << line);
|
||||
#endif
|
||||
} else {
|
||||
#if defined(STM32H7)
|
||||
EXTI_D1->EMR1 |= (1 << line);
|
||||
#elif defined(STM32WB)
|
||||
EXTI->EMR1 |= (1 << line);
|
||||
#else
|
||||
EXTI->EMR |= (1 << line);
|
||||
#endif
|
||||
|
@ -388,6 +407,9 @@ void extint_disable(uint line) {
|
|||
#if defined(STM32H7)
|
||||
EXTI_D1->IMR1 &= ~(1 << line);
|
||||
EXTI_D1->EMR1 &= ~(1 << line);
|
||||
#elif defined(STM32WB)
|
||||
EXTI->IMR1 &= ~(1 << line);
|
||||
EXTI->EMR1 &= ~(1 << line);
|
||||
#else
|
||||
EXTI->IMR &= ~(1 << line);
|
||||
EXTI->EMR &= ~(1 << line);
|
||||
|
@ -407,7 +429,7 @@ void extint_swint(uint line) {
|
|||
return;
|
||||
}
|
||||
// we need 0 to 1 transition to trigger the interrupt
|
||||
#if defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
|
||||
EXTI->SWIER1 &= ~(1 << line);
|
||||
EXTI->SWIER1 |= (1 << line);
|
||||
#else
|
||||
|
@ -485,7 +507,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(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
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);
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#if defined(STM32F0) || defined(STM32L4)
|
||||
#define EXTI_RTC_TIMESTAMP (19)
|
||||
#define EXTI_RTC_WAKEUP (20)
|
||||
#elif defined(STM32H7)
|
||||
#elif defined(STM32H7) || defined(STM32WB)
|
||||
#define EXTI_RTC_TIMESTAMP (18)
|
||||
#define EXTI_RTC_WAKEUP (19)
|
||||
#else
|
||||
|
|
|
@ -68,7 +68,7 @@ static const flash_layout_t flash_layout[] = {
|
|||
{ 0x08040000, 0x40000, 3 },
|
||||
};
|
||||
|
||||
#elif defined(STM32L0) || defined(STM32L4)
|
||||
#elif defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
|
||||
|
||||
static const flash_layout_t flash_layout[] = {
|
||||
{ (uint32_t)FLASH_BASE, (uint32_t)FLASH_PAGE_SIZE, 512 },
|
||||
|
@ -122,7 +122,7 @@ static uint32_t get_page(uint32_t addr) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#elif defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)
|
||||
#elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB)
|
||||
|
||||
static uint32_t get_page(uint32_t addr) {
|
||||
return (addr - FLASH_BASE) / FLASH_PAGE_SIZE;
|
||||
|
@ -175,7 +175,7 @@ void 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)
|
||||
#elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB)
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInitStruct.Page = get_page(flash_dest);
|
||||
|
@ -247,7 +247,7 @@ void flash_erase_it(uint32_t flash_dest, uint32_t num_word32) {
|
|||
*/
|
||||
|
||||
void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
|
||||
#if defined(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
|
||||
// program the flash uint64 by uint64
|
||||
for (int i = 0; i < num_word32 / 2; i++) {
|
||||
|
|
|
@ -105,7 +105,8 @@ STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k
|
|||
|
||||
#elif defined(STM32L432xx) || \
|
||||
defined(STM32L451xx) || defined(STM32L452xx) || defined(STM32L462xx) || \
|
||||
defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L496xx)
|
||||
defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L496xx) || \
|
||||
defined(STM32WB)
|
||||
|
||||
// The STM32L4xx doesn't have CCRAM, so we use SRAM2 for this, although
|
||||
// actual location and size is defined by the linker script.
|
||||
|
|
|
@ -489,7 +489,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(STM32L0) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
|
||||
self->uartx->RQR = USART_RQR_SBKRQ; // write-only register
|
||||
#else
|
||||
self->uartx->CR1 |= USART_CR1_SBK;
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
#define RCC_CSR_BORRSTF RCC_CSR_PORRSTF
|
||||
#endif
|
||||
|
||||
#if defined(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
// L4 does not have a POR, so use BOR instead
|
||||
#define RCC_CSR_PORRSTF RCC_CSR_BORRSTF
|
||||
#endif
|
||||
|
@ -305,7 +305,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
|||
return mp_obj_new_tuple(MP_ARRAY_SIZE(tuple), tuple);
|
||||
} else {
|
||||
// set
|
||||
#if defined(STM32F0) || defined(STM32L0) || defined(STM32L4)
|
||||
#if defined(STM32F0) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
|
||||
mp_raise_NotImplementedError("machine.freq set not supported yet");
|
||||
#else
|
||||
mp_int_t sysclk = mp_obj_get_int(args[0]);
|
||||
|
|
|
@ -202,6 +202,15 @@
|
|||
#define MICROPY_HW_MAX_TIMER (17)
|
||||
#define MICROPY_HW_MAX_UART (6)
|
||||
|
||||
// Configuration for STM32WB series
|
||||
#elif defined(STM32WB)
|
||||
|
||||
#define MP_HAL_UNIQUE_ID_ADDRESS (UID_BASE)
|
||||
#define PYB_EXTI_NUM_VECTORS (20)
|
||||
#define MICROPY_HW_MAX_I2C (3)
|
||||
#define MICROPY_HW_MAX_TIMER (17)
|
||||
#define MICROPY_HW_MAX_UART (1)
|
||||
|
||||
#else
|
||||
#error Unsupported MCU series
|
||||
#endif
|
||||
|
|
|
@ -122,7 +122,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(STM32L4)
|
||||
#elif defined(STM32L4) || defined(STM32WB)
|
||||
#define AHBxENR AHB2ENR
|
||||
#define AHBxENR_GPIOAEN_Pos RCC_AHB2ENR_GPIOAEN_Pos
|
||||
#endif
|
||||
|
|
|
@ -76,7 +76,7 @@ void powerctrl_check_enter_bootloader(void) {
|
|||
if ((bl_addr & 0xfff) == 0 && (RCC->RCC_SR & RCC_SR_SFTRSTF)) {
|
||||
// Reset by NVIC_SystemReset with bootloader data set -> branch to bootloader
|
||||
RCC->RCC_SR = RCC_SR_RMVF;
|
||||
#if defined(STM32F0) || defined(STM32F4) || defined(STM32L4)
|
||||
#if defined(STM32F0) || defined(STM32F4) || defined(STM32L4) || defined(STM32WB)
|
||||
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
|
||||
#endif
|
||||
uint32_t r0 = BL_STATE[0];
|
||||
|
@ -84,7 +84,7 @@ void powerctrl_check_enter_bootloader(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(STM32F0) && !defined(STM32L0)
|
||||
#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32WB)
|
||||
|
||||
// Assumes that PLL is used as the SYSCLK source
|
||||
int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk_mhz, bool need_pllsai) {
|
||||
|
@ -158,7 +158,7 @@ int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk
|
|||
|
||||
#endif
|
||||
|
||||
#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32L4)
|
||||
#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB)
|
||||
|
||||
STATIC uint32_t calc_ahb_div(uint32_t wanted_div) {
|
||||
if (wanted_div <= 1) { return RCC_SYSCLK_DIV1; }
|
||||
|
@ -333,7 +333,7 @@ void powerctrl_enter_stop_mode(void) {
|
|||
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
|
||||
#endif
|
||||
|
||||
#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32L4)
|
||||
#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB)
|
||||
// takes longer to wake but reduces stop current
|
||||
HAL_PWREx_EnableFlashPowerDown();
|
||||
#endif
|
||||
|
@ -380,6 +380,9 @@ void powerctrl_enter_stop_mode(void) {
|
|||
#if defined(STM32H7)
|
||||
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL1) {
|
||||
}
|
||||
#elif defined(STM32WB)
|
||||
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) {
|
||||
}
|
||||
#else
|
||||
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) {
|
||||
}
|
||||
|
@ -450,7 +453,7 @@ void powerctrl_enter_standby_mode(void) {
|
|||
PWR->CR2 |= PWR_CR2_CWUPF6 | PWR_CR2_CWUPF5 | PWR_CR2_CWUPF4 | PWR_CR2_CWUPF3 | PWR_CR2_CWUPF2 | PWR_CR2_CWUPF1;
|
||||
#elif defined(STM32H7)
|
||||
// TODO
|
||||
#elif defined(STM32L4)
|
||||
#elif defined(STM32L4) || defined(STM32WB)
|
||||
// clear all wake-up flags
|
||||
PWR->SCR |= PWR_SCR_CWUF5 | PWR_SCR_CWUF4 | PWR_SCR_CWUF3 | PWR_SCR_CWUF2 | PWR_SCR_CWUF1;
|
||||
// TODO
|
||||
|
|
|
@ -131,4 +131,50 @@ void SystemClock_Config(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#elif defined(STM32WB)
|
||||
|
||||
void SystemClock_Config(void) {
|
||||
// Enable the 32MHz external oscillator
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR & RCC_CR_HSERDY)) {
|
||||
}
|
||||
|
||||
// Use HSE and the PLL to get a 64MHz SYSCLK
|
||||
#define PLLM (HSE_VALUE / 8000000) // VCO input is 8MHz
|
||||
#define PLLN (24) // 24*8MHz = 192MHz
|
||||
#define PLLQ (4) // f_Q = 48MHz
|
||||
#define PLLR (3) // f_R = 64MHz
|
||||
RCC->PLLCFGR =
|
||||
(PLLR - 1) << RCC_PLLCFGR_PLLR_Pos | RCC_PLLCFGR_PLLREN
|
||||
| (PLLQ - 1) << RCC_PLLCFGR_PLLQ_Pos | RCC_PLLCFGR_PLLQEN
|
||||
| PLLN << RCC_PLLCFGR_PLLN_Pos
|
||||
| (PLLM - 1) << RCC_PLLCFGR_PLLM_Pos
|
||||
| 3 << RCC_PLLCFGR_PLLSRC_Pos;
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR & RCC_CR_PLLRDY)) {
|
||||
// Wait for PLL to lock
|
||||
}
|
||||
const uint32_t sysclk_src = 3;
|
||||
|
||||
// Set divider for HCLK2 to 2 so f_HCLK2 = 32MHz
|
||||
RCC->EXTCFGR = 8 << RCC_EXTCFGR_C2HPRE_Pos;
|
||||
|
||||
// Set flash latency to 3 because SYSCLK > 54MHz
|
||||
FLASH->ACR |= 3 << FLASH_ACR_LATENCY_Pos;
|
||||
|
||||
// Select SYSCLK source
|
||||
RCC->CFGR |= sysclk_src << RCC_CFGR_SW_Pos;
|
||||
while (((RCC->CFGR >> RCC_CFGR_SWS_Pos) & 0x3) != sysclk_src) {
|
||||
// Wait for SYSCLK source to change
|
||||
}
|
||||
|
||||
// Select PLLQ as 48MHz source for USB and RNG
|
||||
RCC->CCIPR = 2 << RCC_CCIPR_CLK48SEL_Pos;
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
|
||||
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,14 @@
|
|||
#include "rtc.h"
|
||||
#include "irq.h"
|
||||
|
||||
#if defined(STM32WB)
|
||||
#define RCC_CSR_LSION RCC_CSR_LSI1ON
|
||||
#define RCC_FLAG_LSIRDY RCC_FLAG_LSI1RDY
|
||||
#define RCC_OSCILLATORTYPE_LSI RCC_OSCILLATORTYPE_LSI1
|
||||
#define __HAL_RCC_LSI_ENABLE __HAL_RCC_LSI1_ENABLE
|
||||
#define __HAL_RCC_LSI_DISABLE __HAL_RCC_LSI1_DISABLE
|
||||
#endif
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class RTC - real time clock
|
||||
///
|
||||
|
@ -177,7 +185,7 @@ void rtc_init_finalise() {
|
|||
|
||||
// fresh reset; configure RTC Calendar
|
||||
RTC_CalendarConfig();
|
||||
#if defined(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
if(__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST) != RESET) {
|
||||
#else
|
||||
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) {
|
||||
|
@ -209,7 +217,7 @@ STATIC HAL_StatusTypeDef PYB_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruc
|
|||
|
||||
/*------------------------------ LSE Configuration -------------------------*/
|
||||
if ((RCC_OscInitStruct->OscillatorType & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) {
|
||||
#if !defined(STM32H7)
|
||||
#if !defined(STM32H7) && !defined(STM32WB)
|
||||
// Enable Power Clock
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
#endif
|
||||
|
@ -218,7 +226,7 @@ STATIC HAL_StatusTypeDef PYB_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruc
|
|||
HAL_PWR_EnableBkUpAccess();
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
|
||||
#if defined(STM32F7) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32F7) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
|
||||
//__HAL_RCC_PWR_CLK_ENABLE();
|
||||
// Enable write access to Backup domain
|
||||
//PWR->CR1 |= PWR_CR1_DBP;
|
||||
|
@ -298,7 +306,7 @@ STATIC HAL_StatusTypeDef PYB_RTC_Init(RTC_HandleTypeDef *hrtc) {
|
|||
// Exit Initialization mode
|
||||
hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
|
||||
|
||||
#if defined(STM32L0) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
|
||||
hrtc->Instance->OR &= (uint32_t)~RTC_OR_ALARMOUTTYPE;
|
||||
hrtc->Instance->OR |= (uint32_t)(hrtc->Init.OutPutType);
|
||||
#elif defined(STM32F7)
|
||||
|
@ -649,7 +657,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(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
EXTI->IMR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||
EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||
#elif defined(STM32H7)
|
||||
|
@ -662,7 +670,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
|
|||
|
||||
// clear interrupt flags
|
||||
RTC->ISR &= ~RTC_ISR_WUTF;
|
||||
#if defined(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
EXTI->PR1 = 1 << EXTI_RTC_WAKEUP;
|
||||
#elif defined(STM32H7)
|
||||
EXTI_D1->PR1 = 1 << EXTI_RTC_WAKEUP;
|
||||
|
@ -682,7 +690,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(STM32L4)
|
||||
#if defined(STM32L4) || defined(STM32WB)
|
||||
EXTI->IMR1 &= ~(1 << EXTI_RTC_WAKEUP);
|
||||
#elif defined(STM32H7)
|
||||
EXTI_D1->IMR1 |= 1 << EXTI_RTC_WAKEUP;
|
||||
|
|
|
@ -306,6 +306,14 @@ void USB_IRQHandler(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#elif defined(STM32WB)
|
||||
|
||||
#if MICROPY_HW_USB_FS
|
||||
void USB_LP_IRQHandler(void) {
|
||||
HAL_PCD_IRQHandler(&pcd_fs_handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
|
|
|
@ -78,6 +78,8 @@
|
|||
#include "py/mphal.h"
|
||||
#include "powerctrl.h"
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32L4)
|
||||
|
||||
void __fatal_error(const char *msg);
|
||||
|
||||
/**
|
||||
|
@ -392,3 +394,5 @@ void SystemClock_Config(void)
|
|||
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, TICK_INT_PRIORITY, 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -81,7 +81,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)
|
||||
#elif defined(STM32L4) || defined(STM32WB)
|
||||
#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)
|
||||
|
@ -439,11 +439,13 @@ void uart_deinit(pyb_uart_obj_t *self) {
|
|||
__HAL_RCC_USART1_FORCE_RESET();
|
||||
__HAL_RCC_USART1_RELEASE_RESET();
|
||||
__HAL_RCC_USART1_CLK_DISABLE();
|
||||
#if defined(USART2)
|
||||
} else if (self->uart_id == 2) {
|
||||
HAL_NVIC_DisableIRQ(USART2_IRQn);
|
||||
__HAL_RCC_USART2_FORCE_RESET();
|
||||
__HAL_RCC_USART2_RELEASE_RESET();
|
||||
__HAL_RCC_USART2_CLK_DISABLE();
|
||||
#endif
|
||||
#if defined(USART3)
|
||||
} else if (self->uart_id == 3) {
|
||||
#if !defined(STM32F0)
|
||||
|
@ -653,7 +655,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
|
|||
return data;
|
||||
} else {
|
||||
// no buffering
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
|
||||
int data = self->uartx->RDR & self->char_mask;
|
||||
self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set
|
||||
return data;
|
||||
|
@ -779,7 +781,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(STM32L0) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB)
|
||||
int data = self->uartx->RDR; // clears UART_FLAG_RXNE
|
||||
self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set
|
||||
#else
|
||||
|
|
|
@ -142,7 +142,7 @@ int8_t usbd_cdc_control(usbd_cdc_state_t *cdc_in, uint8_t cmd, uint8_t* pbuf, ui
|
|||
// configure its serial port (in most cases to disable local echo)
|
||||
cdc->connect_state = USBD_CDC_CONNECT_STATE_CONNECTING;
|
||||
usbd_cdc_connect_tx_timer = 8; // wait for 8 SOF IRQs
|
||||
#if defined(STM32L0)
|
||||
#if defined(STM32L0) || defined(STM32WB)
|
||||
USB->CNTR |= USB_CNTR_SOFM;
|
||||
#else
|
||||
PCD_HandleTypeDef *hpcd = cdc->base.usbd->pdev->pData;
|
||||
|
@ -219,7 +219,7 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
|
|||
--usbd_cdc_connect_tx_timer;
|
||||
} else {
|
||||
usbd_cdc_msc_hid_state_t *usbd = ((USBD_HandleTypeDef*)hpcd->pData)->pClassData;
|
||||
#if defined(STM32L0)
|
||||
#if defined(STM32L0) || defined(STM32WB)
|
||||
USB->CNTR &= ~USB_CNTR_SOFM;
|
||||
#else
|
||||
hpcd->Instance->GINTMSK &= ~USB_OTG_GINTMSK_SOFM;
|
||||
|
|
|
@ -44,7 +44,7 @@ PCD_HandleTypeDef pcd_fs_handle;
|
|||
PCD_HandleTypeDef pcd_hs_handle;
|
||||
#endif
|
||||
|
||||
#if defined(STM32L0)
|
||||
#if defined(STM32L0) || defined(STM32WB)
|
||||
// The STM32L0xx has a single USB device-only instance
|
||||
#define USB_OTG_FS USB
|
||||
#endif
|
||||
|
@ -64,6 +64,8 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
|
|||
const uint32_t otg_alt = GPIO_AF10_OTG1_FS;
|
||||
#elif defined(STM32L0)
|
||||
const uint32_t otg_alt = GPIO_AF0_USB;
|
||||
#elif defined(STM32WB)
|
||||
const uint32_t otg_alt = GPIO_AF10_USB;
|
||||
#else
|
||||
const uint32_t otg_alt = GPIO_AF10_OTG_FS;
|
||||
#endif
|
||||
|
@ -90,7 +92,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
|
|||
#endif
|
||||
|
||||
// Enable USB FS Clocks
|
||||
#if defined(STM32L0)
|
||||
#if defined(STM32L0) || defined(STM32WB)
|
||||
__HAL_RCC_USB_CLK_ENABLE();
|
||||
#else
|
||||
__USB_OTG_FS_CLK_ENABLE();
|
||||
|
@ -111,6 +113,9 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
|
|||
#if defined(STM32L0)
|
||||
NVIC_SetPriority(USB_IRQn, IRQ_PRI_OTG_FS);
|
||||
HAL_NVIC_EnableIRQ(USB_IRQn);
|
||||
#elif defined(STM32WB)
|
||||
NVIC_SetPriority(USB_LP_IRQn, IRQ_PRI_OTG_FS);
|
||||
HAL_NVIC_EnableIRQ(USB_LP_IRQn);
|
||||
#else
|
||||
NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS);
|
||||
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
|
@ -190,7 +195,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
|
|||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) {
|
||||
#if defined(STM32L0)
|
||||
#if defined(STM32L0) || defined(STM32WB)
|
||||
__HAL_RCC_USB_CLK_DISABLE();
|
||||
#else
|
||||
|
||||
|
@ -354,6 +359,10 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) {
|
|||
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
|
||||
#if MICROPY_HW_USB_FS
|
||||
if (pdev->id == USB_PHY_FS_ID) {
|
||||
#if defined(STM32WB)
|
||||
PWR->CR2 |= PWR_CR2_USV; // USB supply is valid
|
||||
#endif
|
||||
|
||||
// Set LL Driver parameters
|
||||
pcd_fs_handle.Instance = USB_OTG_FS;
|
||||
#if MICROPY_HW_USB_CDC_NUM == 2
|
||||
|
@ -370,7 +379,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
|
|||
pcd_fs_handle.Init.lpm_enable = DISABLE;
|
||||
pcd_fs_handle.Init.battery_charging_enable = DISABLE;
|
||||
#endif
|
||||
#if !defined(STM32L0)
|
||||
#if !defined(STM32L0) && !defined(STM32WB)
|
||||
pcd_fs_handle.Init.use_dedicated_ep1 = 0;
|
||||
pcd_fs_handle.Init.dma_enable = 0;
|
||||
#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
|
||||
|
@ -387,7 +396,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
|
|||
// Initialize LL Driver
|
||||
HAL_PCD_Init(&pcd_fs_handle);
|
||||
|
||||
#if defined(STM32L0)
|
||||
#if defined(STM32L0) || defined(STM32WB)
|
||||
// We have 512 16-bit words it total to use here (when using PCD_SNG_BUF)
|
||||
HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x00, PCD_SNG_BUF, 64); // EP0
|
||||
HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x80, PCD_SNG_BUF, 128); // EP0
|
||||
|
|
Loading…
Reference in New Issue