From 3b92472c02ec76f22683cde6b904c088798cc94f Mon Sep 17 00:00:00 2001 From: Peter Lawrence <12226419+majbthrd@users.noreply.github.com> Date: Sun, 14 Aug 2022 12:32:58 -0500 Subject: [PATCH] feat: add the STM32WL SUBGHZSPI to the SPI library Signed-off-by: Peter Lawrence <12226419+majbthrd@users.noreply.github.com> Co-authored-by: Frederic Pillon --- libraries/SPI/src/SPI.cpp | 38 +++++++++++++++++++++ libraries/SPI/src/SPI.h | 20 +++++++++++ libraries/SPI/src/utility/spi_com.c | 52 ++++++++++++++++++++++------- 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 0d836a0295..afbf276f73 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -421,3 +421,41 @@ void SPIClass::detachInterrupt(void) { // Should be disableInterrupt() } + +#if defined(SUBGHZSPI_BASE) +SUBGHZSPIClass SubGHZ_SPI; + +void SUBGHZSPIClass::begin(uint8_t _pin) +{ + if (_pin != CS_PIN_CONTROLLED_BY_USER) { + LL_PWR_SelectSUBGHZSPI_NSS(); + } + SPIClass::begin(_pin); + if (_pin != CS_PIN_CONTROLLED_BY_USER) { + LL_PWR_UnselectSUBGHZSPI_NSS(); + } +} + +byte SUBGHZSPIClass::transfer(uint8_t _pin, uint8_t _data, SPITransferMode _mode) +{ + byte res; + if (_pin != CS_PIN_CONTROLLED_BY_USER) { + LL_PWR_SelectSUBGHZSPI_NSS(); + } + res = SPIClass::transfer(_pin, _data, _mode); + if (_pin != CS_PIN_CONTROLLED_BY_USER) { + LL_PWR_UnselectSUBGHZSPI_NSS(); + } + return res; +} + +void SUBGHZSPIClass::enableDebugPins(void) +{ + spi_t* obj = getSpiObj(); + /* Configure SPI GPIO pins */ + pinmap_pinout(obj->pin_mosi, PinMap_SPI_MOSI); + pinmap_pinout(obj->pin_miso, PinMap_SPI_MISO); + pinmap_pinout(obj->pin_sclk, PinMap_SPI_SCLK); + pinmap_pinout(obj->pin_ssel, PinMap_SPI_SSEL); +} +#endif diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index 72f6d59fda..3b8b9c0409 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -227,6 +227,12 @@ class SPIClass { void attachInterrupt(void); void detachInterrupt(void); + spi_t* getSpiObj(void) + { + return &_spi; + } + + // Could be used to mix Arduino API and STM32Cube HAL API (ex: DMA). Use at your own risk. SPI_HandleTypeDef *getHandle(void) { @@ -304,4 +310,18 @@ class SPIClass { extern SPIClass SPI; +#if defined(SUBGHZSPI_BASE) +class SUBGHZSPIClass : public SPIClass { + public: + SUBGHZSPIClass(): SPIClass{SUBGHZSPI_MOSI, SUBGHZSPI_MISO, SUBGHZSPI_SCLK, SUBGHZSPI_SS} {} + + void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER); + byte transfer(uint8_t _pin, uint8_t _data, SPITransferMode _mode = SPI_LAST); + + void enableDebugPins(void); +}; + +extern SUBGHZSPIClass SubGHZ_SPI; #endif + +#endif /* _SPI_H_INCLUDED */ diff --git a/libraries/SPI/src/utility/spi_com.c b/libraries/SPI/src/utility/spi_com.c index 32d46261dc..b1768e9746 100644 --- a/libraries/SPI/src/utility/spi_com.c +++ b/libraries/SPI/src/utility/spi_com.c @@ -159,6 +159,12 @@ uint32_t spi_getClkFreqInst(SPI_TypeDef *spi_inst) } } #endif // SPI6_BASE +#if defined(SUBGHZSPI_BASE) + if (spi_inst == SUBGHZSPI) { + /* Source CLK is APB3 (PCLK3) is derived from AHB3 clock */ + spi_freq = HAL_RCC_GetHCLK3Freq(); + } +#endif // SUBGHZSPI_BASE #endif } return spi_freq; @@ -259,6 +265,7 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb) handle->Init.Mode = SPI_MODE_MASTER; spi_freq = spi_getClkFreqInst(obj->spi); + /* For SUBGHZSPI, 'SPI_BAUDRATEPRESCALER_*' == 'SUBGHZSPI_BAUDRATEPRESCALER_*' */ if (speed >= (spi_freq / SPI_SPEED_CLOCK_DIV2_MHZ)) { handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; } else if (speed >= (spi_freq / SPI_SPEED_CLOCK_DIV4_MHZ)) { @@ -318,18 +325,23 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb) handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* Recommended setting to avoid glitches */ #endif - /* Configure SPI GPIO pins */ - pinmap_pinout(obj->pin_mosi, PinMap_SPI_MOSI); - pinmap_pinout(obj->pin_miso, PinMap_SPI_MISO); - pinmap_pinout(obj->pin_sclk, PinMap_SPI_SCLK); - /* - * According the STM32 Datasheet for SPI peripheral we need to PULLDOWN - * or PULLUP the SCK pin according the polarity used. - */ - pull = (handle->Init.CLKPolarity == SPI_POLARITY_LOW) ? GPIO_PULLDOWN : GPIO_PULLUP; - pin_PullConfig(get_GPIO_Port(STM_PORT(obj->pin_sclk)), STM_LL_GPIO_PIN(obj->pin_sclk), pull); - pinmap_pinout(obj->pin_ssel, PinMap_SPI_SSEL); - +#if defined(SUBGHZSPI_BASE) + if (handle->Instance != SUBGHZSPI) { +#endif + /* Configure SPI GPIO pins */ + pinmap_pinout(obj->pin_mosi, PinMap_SPI_MOSI); + pinmap_pinout(obj->pin_miso, PinMap_SPI_MISO); + pinmap_pinout(obj->pin_sclk, PinMap_SPI_SCLK); + /* + * According the STM32 Datasheet for SPI peripheral we need to PULLDOWN + * or PULLUP the SCK pin according the polarity used. + */ + pull = (handle->Init.CLKPolarity == SPI_POLARITY_LOW) ? GPIO_PULLDOWN : GPIO_PULLUP; + pin_PullConfig(get_GPIO_Port(STM_PORT(obj->pin_sclk)), STM_LL_GPIO_PIN(obj->pin_sclk), pull); + pinmap_pinout(obj->pin_ssel, PinMap_SPI_SSEL); +#if defined(SUBGHZSPI_BASE) + } +#endif #if defined SPI1_BASE // Enable SPI clock if (handle->Instance == SPI1) { @@ -379,6 +391,14 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb) } #endif +#if defined SUBGHZSPI_BASE + if (handle->Instance == SUBGHZSPI) { + __HAL_RCC_SUBGHZSPI_CLK_ENABLE(); + __HAL_RCC_SUBGHZSPI_FORCE_RESET(); + __HAL_RCC_SUBGHZSPI_RELEASE_RESET(); + } +#endif + HAL_SPI_Init(handle); /* In order to set correctly the SPI polarity we need to enable the peripheral */ @@ -448,6 +468,14 @@ void spi_deinit(spi_t *obj) __HAL_RCC_SPI6_CLK_DISABLE(); } #endif + +#if defined SUBGHZSPI_BASE + if (handle->Instance == SUBGHZSPI) { + __HAL_RCC_SUBGHZSPI_FORCE_RESET(); + __HAL_RCC_SUBGHZSPI_RELEASE_RESET(); + __HAL_RCC_SUBGHZSPI_CLK_DISABLE(); + } +#endif } /**