stm32/spi: Add STM32WL5 SUBGHZ SPI peripheral.

This is a "normal" SPI peripheral with no external pins, to avoid having to
grow spi_obj[] for just this one board map it as SPI ID 3 (board has SPI
IDs 1,2 already).

Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
Angus Gratton 2022-07-08 12:46:27 +10:00 committed by Damien George
parent a18d62e067
commit e6cfb77342
4 changed files with 56 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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