diff --git a/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h b/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h index 51700ba8a536..4087ba4fbc3c 100644 --- a/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_WL55/mpconfigboard.h @@ -48,6 +48,10 @@ #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 5 on CN5 #define MICROPY_HW_SPI1_MOSI (pin_A7) // Arduino D11, pin 4 on CN5 +// SUBGHZSPI Internal radio SPI BUS +#define MICROPY_HW_SUBGHZSPI_NAME "SUBGHZ" +#define MICROPY_HW_SUBGHZSPI_ID 3 + // User switch; pressing the button makes the input go low #define MICROPY_HW_USRSW_PIN (pin_A0) #define MICROPY_HW_USRSW_PULL (GPIO_PULLUP) diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index cdbb90e5d8b3..b2ba787ce694 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -558,6 +558,10 @@ const dma_descr_t dma_SPI_1_RX = { DMA1_Channel1, DMA_REQUEST_SPI1_RX, dma_id_0, const dma_descr_t dma_SPI_1_TX = { DMA1_Channel2, DMA_REQUEST_SPI1_TX, dma_id_1, &dma_init_struct_spi_i2c }; const dma_descr_t dma_SPI_2_RX = { DMA1_Channel3, DMA_REQUEST_SPI2_RX, dma_id_2, &dma_init_struct_spi_i2c }; const dma_descr_t dma_SPI_2_TX = { DMA1_Channel4, DMA_REQUEST_SPI2_TX, dma_id_3, &dma_init_struct_spi_i2c }; +#if defined(STM32WL) +const dma_descr_t dma_SPI_SUBGHZ_RX = { DMA1_Channel5, DMA_REQUEST_SUBGHZSPI_RX, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_SUBGHZ_TX = { DMA1_Channel6, DMA_REQUEST_SUBGHZSPI_TX, dma_id_5, &dma_init_struct_spi_i2c }; +#endif static const uint8_t dma_irqn[NSTREAM] = { DMA1_Channel1_IRQn, diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h index 92d5db6c0a71..2afc94754187 100644 --- a/ports/stm32/dma.h +++ b/ports/stm32/dma.h @@ -136,6 +136,8 @@ extern const dma_descr_t dma_SPI_3_TX; extern const dma_descr_t dma_SDIO_0; extern const dma_descr_t dma_I2C_4_TX; extern const dma_descr_t dma_I2C_4_RX; +extern const dma_descr_t dma_SPI_SUBGHZ_TX; +extern const dma_descr_t dma_SPI_SUBGHZ_RX; #endif diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index 11a9a74ea3ba..1f5996165ebe 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -62,6 +62,9 @@ STATIC SPI_HandleTypeDef SPIHandle5 = {.Instance = NULL}; #if defined(MICROPY_HW_SPI6_SCK) STATIC SPI_HandleTypeDef SPIHandle6 = {.Instance = NULL}; #endif +#if defined(MICROPY_HW_SUBGHZSPI_ID) +static SPI_HandleTypeDef SPIHandleSubGhz = {.Instance = NULL}; +#endif const spi_t spi_obj[6] = { #if defined(MICROPY_HW_SPI1_SCK) @@ -76,6 +79,8 @@ const spi_t spi_obj[6] = { #endif #if defined(MICROPY_HW_SPI3_SCK) {&SPIHandle3, &dma_SPI_3_TX, &dma_SPI_3_RX}, + #elif MICROPY_HW_SUBGHZSPI_ID == 3 + {&SPIHandleSubGhz, &dma_SPI_SUBGHZ_TX, &dma_SPI_SUBGHZ_RX}, #else {NULL, NULL, NULL}, #endif @@ -96,6 +101,10 @@ const spi_t spi_obj[6] = { #endif }; +#if defined(MICROPY_HW_SUBGHZSPI_ID) && MICROPY_HW_SUBGHZSPI_ID != 3 +#error "spi_obj needs updating for new value of MICROPY_HW_SUBGHZSPI_ID" +#endif + #if defined(STM32H5) || defined(STM32H7) // STM32H5/H7 HAL requires SPI IRQs to be enabled and handled. #if defined(MICROPY_HW_SPI1_SCK) @@ -163,6 +172,9 @@ void spi_init0(void) { #if defined(MICROPY_HW_SPI6_SCK) SPIHandle6.Instance = SPI6; #endif + #if defined(MICROPY_HW_SUBGHZSPI_ID) + SPIHandleSubGhz.Instance = SUBGHZSPI; + #endif } int spi_find_index(mp_obj_t id) { @@ -195,6 +207,10 @@ int spi_find_index(mp_obj_t id) { } else if (strcmp(port, MICROPY_HW_SPI6_NAME) == 0) { spi_id = 6; #endif + #ifdef MICROPY_HW_SUBGHZSPI_NAME + } else if (strcmp(port, MICROPY_HW_SUBGHZSPI_NAME) == 0) { + spi_id = MICROPY_HW_SUBGHZSPI_ID; + #endif } else { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%s) doesn't exist"), port); } @@ -239,7 +255,7 @@ STATIC uint32_t spi_get_source_freq(SPI_HandleTypeDef *spi) { } else { return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6); } - #else + #else // !STM32F0, !STM32G0, !STM32H #if defined(SPI2) if (spi->Instance == SPI2) { // SPI2 is on APB1 @@ -252,11 +268,20 @@ STATIC uint32_t spi_get_source_freq(SPI_HandleTypeDef *spi) { return HAL_RCC_GetPCLK1Freq(); } else #endif + #if defined(MICROPY_HW_SUBGHZSPI_ID) + if (spi->Instance == SUBGHZSPI) { + // In STM32WL5x, SUBGHZSPI is PCLK3 which is same as HCLK3, no HCLK3->PCLK3 divider exists in clock tree + #if !defined(LL_APB3_GRP1_PERIPH_SUBGHZSPI) + #error "SPI needs updating for new SUBGHZSPI clock configuration" + #endif + return HAL_RCC_GetHCLK3Freq(); + } else + #endif { // SPI1, SPI4, SPI5 and SPI6 are on APB2 return HAL_RCC_GetPCLK2Freq(); } - #endif + #endif // STM32F0, STM32G0, STM32H } // sets the parameters in the SPI_InitTypeDef struct @@ -411,6 +436,12 @@ int spi_init(const spi_t *self, bool enable_nss_pin) { // enable the SPI clock __HAL_RCC_SPI6_CLK_ENABLE(); #endif + #if defined(MICROPY_HW_SUBGHZSPI_ID) + } else if (spi->Instance == SUBGHZSPI) { + irqn = SUBGHZSPI_IRQn; + // pins remain all NULL, internal bus has no GPIO mappings + __HAL_RCC_SUBGHZSPI_CLK_ENABLE(); + #endif } else { // SPI does not exist for this board (shouldn't get here, should be checked by caller) return -MP_EINVAL; @@ -502,6 +533,14 @@ void spi_deinit(const spi_t *spi_obj) { __HAL_RCC_SPI6_CLK_DISABLE(); HAL_NVIC_DisableIRQ(SPI6_IRQn); #endif + #if defined(MICROPY_HW_SUBGHZSPI_ID) + } else if (spi->Instance == SUBGHZSPI) { + __HAL_RCC_SUBGHZSPI_FORCE_RESET(); + __HAL_RCC_SUBGHZSPI_RELEASE_RESET(); + __HAL_RCC_SUBGHZSPI_CLK_DISABLE(); + HAL_NVIC_DisableIRQ(SUBGHZSPI_IRQn); + + #endif } } @@ -661,6 +700,11 @@ void spi_print(const mp_print_t *print, const spi_t *spi_obj, bool legacy) { spi_num = 6; } #endif + #if defined(MICROPY_HW_SUBGHZSPI_ID) + else if (spi->Instance == SUBGHZSPI) { + spi_num = MICROPY_HW_SUBGHZSPI_ID; + } + #endif mp_printf(print, "SPI(%u", spi_num); if (spi->State != HAL_SPI_STATE_RESET) {