From 12ac530cd9d25dae33fac9afb62d73238bd7ad1d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 3 Dec 2013 14:22:47 +0000 Subject: Added SPI4/SPI5/SPI6 support to the STM32v1 SPIv1 low level driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@6530 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/SPIv1/spi_lld.c | 153 +++++++++++++++++++++++ os/hal/platforms/STM32/SPIv1/spi_lld.h | 219 ++++++++++++++++++++++++++++++++- 2 files changed, 371 insertions(+), 1 deletion(-) (limited to 'os/hal/platforms/STM32') diff --git a/os/hal/platforms/STM32/SPIv1/spi_lld.c b/os/hal/platforms/STM32/SPIv1/spi_lld.c index dad91c6a8..e3ac56503 100644 --- a/os/hal/platforms/STM32/SPIv1/spi_lld.c +++ b/os/hal/platforms/STM32/SPIv1/spi_lld.c @@ -55,6 +55,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. */ /*===========================================================================*/ @@ -74,6 +98,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. */ /*===========================================================================*/ @@ -201,6 +240,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(&SPID5); + 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_t b; + b = dmaStreamAllocate(spip->dmarx, + STM32_SPI_SPI4_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #7", "stream already allocated"); + b = dmaStreamAllocate(spip->dmatx, + STM32_SPI_SPI4_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #8", "stream already allocated"); + rccEnableSPI4(FALSE); + } +#endif +#if STM32_SPI_USE_SPI5 + if (&SPID5 == spip) { + bool_t b; + b = dmaStreamAllocate(spip->dmarx, + STM32_SPI_SPI5_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #9", "stream already allocated"); + b = dmaStreamAllocate(spip->dmatx, + STM32_SPI_SPI5_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #10", "stream already allocated"); + rccEnableSPI5(FALSE); + } +#endif +#if STM32_SPI_USE_SPI6 + if (&SPID6 == spip) { + bool_t b; + b = dmaStreamAllocate(spip->dmarx, + STM32_SPI_SPI6_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #11", "stream already allocated"); + b = dmaStreamAllocate(spip->dmatx, + STM32_SPI_SPI6_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #12", "stream already allocated"); + rccEnableSPI6(FALSE); + } +#endif /* DMA setup.*/ dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); @@ -320,6 +461,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/platforms/STM32/SPIv1/spi_lld.h b/os/hal/platforms/STM32/SPIv1/spi_lld.h index fe37c8f66..29d2b9982 100644 --- a/os/hal/platforms/STM32/SPIv1/spi_lld.h +++ b/os/hal/platforms/STM32/SPIv1/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 TRUE. + */ +#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 TRUE. + */ +#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 TRUE. + */ +#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. */ @@ -174,6 +252,54 @@ #define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) #endif +/** + * @brief DMA stream used for SPI4 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI4_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#endif + +/** + * @brief DMA stream used for SPI4 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI4_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#endif + +/** + * @brief DMA stream used for SPI5 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI5_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#endif + +/** + * @brief DMA stream used for SPI5 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI5_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#endif + +/** + * @brief DMA stream used for SPI6 RX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI6_RX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#endif + +/** + * @brief DMA stream used for SPI6 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_SPI_SPI6_TX_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_SPI_SPI6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#endif + #else /* !STM32_ADVANCED_DMA */ /* Fixed streams for platforms using the old DMA peripheral, the values are @@ -184,6 +310,12 @@ #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) #define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_SPI_SPI6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) #endif /* !STM32_ADVANCED_DMA*/ /** @} */ @@ -204,7 +336,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 @@ -223,6 +368,21 @@ #error "Invalid IRQ priority assigned to SPI3" #endif +#if STM32_SPI_USE_SPI4 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI4" +#endif + +#if STM32_SPI_USE_SPI5 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI5" +#endif + +#if STM32_SPI_USE_SPI6 && \ + !CORTEX_IS_VALID_KERNEL_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" @@ -238,6 +398,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 + #if STM32_SPI_USE_SPI1 && \ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK) #error "invalid DMA stream associated to SPI1 RX" @@ -268,6 +443,36 @@ #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 + #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED #endif @@ -386,6 +591,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 -- cgit v1.2.3