From 4fda1c3f3079358f1239e9cdd489c25250e8ef7e Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 5 Aug 2015 13:59:26 +0000 Subject: [PATCH] Added support for SPI4...SPI6 to the STM32 SPIv2 SPI driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8162 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/SPIv2/spi_lld.c | 153 +++++++++++++++++++++ os/hal/ports/STM32/LLD/SPIv2/spi_lld.h | 180 ++++++++++++++++++++++++- readme.txt | 1 + 3 files changed, 333 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c index fec4b2fba..cc4635122 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c @@ -54,6 +54,30 @@ STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \ STM32_SPI3_TX_DMA_CHN) +#define SPI4_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_RX_DMA_STREAM, \ + STM32_SPI4_RX_DMA_CHN) + +#define SPI4_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_TX_DMA_STREAM, \ + STM32_SPI4_TX_DMA_CHN) + +#define SPI5_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_RX_DMA_STREAM, \ + STM32_SPI5_RX_DMA_CHN) + +#define SPI5_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_TX_DMA_STREAM, \ + STM32_SPI5_TX_DMA_CHN) + +#define SPI6_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_RX_DMA_STREAM, \ + STM32_SPI6_RX_DMA_CHN) + +#define SPI6_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_TX_DMA_STREAM, \ + STM32_SPI6_TX_DMA_CHN) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -73,6 +97,21 @@ SPIDriver SPID2; SPIDriver SPID3; #endif +/** @brief SPI4 driver identifier.*/ +#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__) +SPIDriver SPID4; +#endif + +/** @brief SPI5 driver identifier.*/ +#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__) +SPIDriver SPID5; +#endif + +/** @brief SPI6 driver identifier.*/ +#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__) +SPIDriver SPID6; +#endif + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -200,6 +239,60 @@ void spi_lld_init(void) { STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif + +#if STM32_SPI_USE_SPI4 + spiObjectInit(&SPID4); + SPID4.spi = SPI4; + SPID4.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI4_RX_DMA_STREAM); + SPID4.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI4_TX_DMA_STREAM); + SPID4.rxdmamode = STM32_DMA_CR_CHSEL(SPI4_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | + STM32_DMA_CR_DMEIE | + STM32_DMA_CR_TEIE; + SPID4.txdmamode = STM32_DMA_CR_CHSEL(SPI4_TX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_DMEIE | + STM32_DMA_CR_TEIE; +#endif + +#if STM32_SPI_USE_SPI5 + spiObjectInit(&SPID3); + SPID5.spi = SPI5; + SPID5.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI5_RX_DMA_STREAM); + SPID5.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI5_TX_DMA_STREAM); + SPID5.rxdmamode = STM32_DMA_CR_CHSEL(SPI5_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | + STM32_DMA_CR_DMEIE | + STM32_DMA_CR_TEIE; + SPID5.txdmamode = STM32_DMA_CR_CHSEL(SPI5_TX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_DMEIE | + STM32_DMA_CR_TEIE; +#endif + +#if STM32_SPI_USE_SPI6 + spiObjectInit(&SPID6); + SPID6.spi = SPI6; + SPID6.dmarx = STM32_DMA_STREAM(STM32_SPI_SPI6_RX_DMA_STREAM); + SPID6.dmatx = STM32_DMA_STREAM(STM32_SPI_SPI6_TX_DMA_STREAM); + SPID6.rxdmamode = STM32_DMA_CR_CHSEL(SPI6_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | + STM32_DMA_CR_DMEIE | + STM32_DMA_CR_TEIE; + SPID6.txdmamode = STM32_DMA_CR_CHSEL(SPI6_TX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_DMEIE | + STM32_DMA_CR_TEIE; +#endif } /** @@ -262,6 +355,54 @@ void spi_lld_start(SPIDriver *spip) { rccEnableSPI3(FALSE); } #endif +#if STM32_SPI_USE_SPI4 + if (&SPID4 == spip) { + bool b; + b = dmaStreamAllocate(spip->dmarx, + STM32_SPI_SPI4_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(spip->dmatx, + STM32_SPI_SPI4_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + osalDbgAssert(!b, "stream already allocated"); + rccEnableSPI4(FALSE); + } +#endif +#if STM32_SPI_USE_SPI5 + if (&SPID5 == spip) { + bool b; + b = dmaStreamAllocate(spip->dmarx, + STM32_SPI_SPI5_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(spip->dmatx, + STM32_SPI_SPI5_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + osalDbgAssert(!b, "stream already allocated"); + rccEnableSPI5(FALSE); + } +#endif +#if STM32_SPI_USE_SPI6 + if (&SPID6 == spip) { + bool b; + b = dmaStreamAllocate(spip->dmarx, + STM32_SPI_SPI6_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(spip->dmatx, + STM32_SPI_SPI6_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + osalDbgAssert(!b, "stream already allocated"); + rccEnableSPI6(FALSE); + } +#endif /* DMA setup.*/ dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); @@ -322,6 +463,18 @@ void spi_lld_stop(SPIDriver *spip) { #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) rccDisableSPI3(FALSE); +#endif +#if STM32_SPI_USE_SPI4 + if (&SPID4 == spip) + rccDisableSPI4(FALSE); +#endif +#if STM32_SPI_USE_SPI5 + if (&SPID5 == spip) + rccDisableSPI5(FALSE); +#endif +#if STM32_SPI_USE_SPI6 + if (&SPID6 == spip) + rccDisableSPI6(FALSE); #endif } } diff --git a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h index bf7ddf700..235341e35 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h @@ -66,6 +66,33 @@ #define STM32_SPI_USE_SPI3 FALSE #endif +/** + * @brief SPI4 driver enable switch. + * @details If set to @p TRUE the support for SPI4 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__) +#define STM32_SPI_USE_SPI4 FALSE +#endif + +/** + * @brief SPI5 driver enable switch. + * @details If set to @p TRUE the support for SPI5 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__) +#define STM32_SPI_USE_SPI5 FALSE +#endif + +/** + * @brief SPI6 driver enable switch. + * @details If set to @p TRUE the support for SPI6 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__) +#define STM32_SPI_USE_SPI6 FALSE +#endif + /** * @brief SPI1 interrupt priority level setting. */ @@ -87,6 +114,27 @@ #define STM32_SPI_SPI3_IRQ_PRIORITY 10 #endif +/** + * @brief SPI4 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI4_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI5 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI5_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI6 interrupt priority level setting. + */ +#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI6_IRQ_PRIORITY 10 +#endif + /** * @brief SPI1 DMA priority (0..3|lowest..highest). * @note The priority level is used for both the TX and RX DMA streams but @@ -117,6 +165,36 @@ #define STM32_SPI_SPI3_DMA_PRIORITY 1 #endif +/** + * @brief SPI4 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI4_DMA_PRIORITY 1 +#endif + +/** + * @brief SPI5 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI5_DMA_PRIORITY 1 +#endif + +/** + * @brief SPI6 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SPI_SPI6_DMA_PRIORITY 1 +#endif + /** * @brief SPI DMA error hook. */ @@ -141,7 +219,20 @@ #error "SPI3 not present in the selected device" #endif -#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 +#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4 +#error "SPI4 not present in the selected device" +#endif + +#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5 +#error "SPI5 not present in the selected device" +#endif + +#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6 +#error "SPI6 not present in the selected device" +#endif + +#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \ + !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6 #error "SPI driver activated but no SPI peripheral assigned" #endif @@ -160,6 +251,21 @@ #error "Invalid IRQ priority assigned to SPI3" #endif +#if STM32_SPI_USE_SPI4 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI4" +#endif + +#if STM32_SPI_USE_SPI5 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI5" +#endif + +#if STM32_SPI_USE_SPI6 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI6" +#endif + #if STM32_SPI_USE_SPI1 && \ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY) #error "Invalid DMA priority assigned to SPI1" @@ -175,6 +281,21 @@ #error "Invalid DMA priority assigned to SPI3" #endif +#if STM32_SPI_USE_SPI4 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI4" +#endif + +#if STM32_SPI_USE_SPI5 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI5" +#endif + +#if STM32_SPI_USE_SPI6 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI6" +#endif + /* The following checks are only required when there is a DMA able to reassign streams to different channels.*/ #if STM32_ADVANCED_DMA @@ -194,6 +315,21 @@ #error "SPI3 DMA streams not defined" #endif +#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \ + !defined(STM32_SPI_SPI4_TX_DMA_STREAM)) +#error "SPI4 DMA streams not defined" +#endif + +#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \ + !defined(STM32_SPI_SPI5_TX_DMA_STREAM)) +#error "SPI5 DMA streams not defined" +#endif + +#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_DMA_STREAM) || \ + !defined(STM32_SPI_SPI6_TX_DMA_STREAM)) +#error "SPI6 DMA streams not defined" +#endif + /* Check on the validity of the assigned DMA channels.*/ #if STM32_SPI_USE_SPI1 && \ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK) @@ -224,6 +360,36 @@ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK) #error "invalid DMA stream associated to SPI3 TX" #endif + +#if STM32_SPI_USE_SPI4 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI4_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI4 RX" +#endif + +#if STM32_SPI_USE_SPI4 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI4_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI4 TX" +#endif + +#if STM32_SPI_USE_SPI5 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI5_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI5 RX" +#endif + +#if STM32_SPI_USE_SPI5 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI5_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI5 TX" +#endif + +#if STM32_SPI_USE_SPI6 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI6_RX_DMA_MSK) +#error "invalid DMA stream associated to SPI6 RX" +#endif + +#if STM32_SPI_USE_SPI6 && \ + !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI6_TX_DMA_MSK) +#error "invalid DMA stream associated to SPI6 TX" +#endif #endif /* STM32_ADVANCED_DMA */ #if !defined(STM32_DMA_REQUIRED) @@ -344,6 +510,18 @@ extern SPIDriver SPID2; extern SPIDriver SPID3; #endif +#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__) +extern SPIDriver SPID4; +#endif + +#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__) +extern SPIDriver SPID5; +#endif + +#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__) +extern SPIDriver SPID6; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/readme.txt b/readme.txt index 2f91b3d3e..62cb6f9c8 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** 3.1.0 *** +- HAL: Added support for SPI4...SPI6 to the STM32 SPIv2 SPI driver. - HAL: Added support for UART4...UART8 to the STM32 UARTv2 UART driver. - HAL: Added support for UART7 and UART8 to the STM32 UARTv2 serial driver. - HAL: STM32F2xx, STM32F4xx and STM32F7xx devices now share the same ADCv2