From ff1d0020c724bfb39ae5792832f5836fb0739f0e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 5 Mar 2016 12:23:26 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9022 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/SPIv1/spi_lld.c | 80 ++++++++++++++++++++------ os/hal/ports/STM32/LLD/SPIv1/spi_lld.h | 11 +++- os/hal/ports/STM32/LLD/SPIv2/spi_lld.c | 80 ++++++++++++++++++++------ os/hal/ports/STM32/LLD/SPIv2/spi_lld.h | 9 +++ 4 files changed, 145 insertions(+), 35 deletions(-) diff --git a/os/hal/ports/STM32/LLD/SPIv1/spi_lld.c b/os/hal/ports/STM32/LLD/SPIv1/spi_lld.c index 3080f3436..89739453b 100644 --- a/os/hal/ports/STM32/LLD/SPIv1/spi_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv1/spi_lld.c @@ -117,7 +117,6 @@ SPIDriver SPID6; /*===========================================================================*/ static uint16_t dummytx; -static uint16_t dummyrx; /*===========================================================================*/ /* Driver local functions. */ @@ -144,6 +143,14 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { dmaStreamDisable(spip->dmatx); dmaStreamDisable(spip->dmarx); +#if STM32_SPI_USE_BIDIMODE + spip->spi->CR1 |= SPI_CR1_BIDIOE; +#endif + + /* Errors reset sequence.*/ + (void)spip->spi->DR; + (void)spip->spi->SR; + /* Portable SPI ISR code defined in the high level driver, note, it is a macro.*/ _spi_isr_code(spip); @@ -304,6 +311,12 @@ void spi_lld_init(void) { */ void spi_lld_start(SPIDriver *spip) { +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert(!(((spip->spi->CR1 & SPI_CR1_BIDIMODE) == 0) ^^ + ((spip->spi->CR1 & SPI_CR1_BIDIOE) == 0)), + "BIDIOE not set"); +#endif + /* If in stopped state then enables the SPI and DMA clocks.*/ if (spip->state == SPI_STOP) { #if STM32_SPI_USE_SPI1 @@ -514,15 +527,16 @@ void spi_lld_unselect(SPIDriver *spip) { */ void spi_lld_ignore(SPIDriver *spip, size_t n) { - dmaStreamSetMemory0(spip->dmarx, &dummyrx); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->rxdmamode); +#if STM32_SPI_USE_BIDIMODE + if ((spip->spi->CR1 & SPI_CR1_BIDIMODE) != 0) { + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); +#endif dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode); - dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); } @@ -544,6 +558,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIMODE) == 0, + "spiExchange() not possible with BIDIMODE"); +#endif + dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode| STM32_DMA_CR_MINC); @@ -571,15 +590,16 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - dmaStreamSetMemory0(spip->dmarx, &dummyrx); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->rxdmamode); +#if STM32_SPI_USE_BIDIMODE + if ((spip->spi->CR1 & SPI_CR1_BIDIMODE) != 0) { + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); +#endif dmaStreamSetMemory0(spip->dmatx, txbuf); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC); - dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); } @@ -598,16 +618,35 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - dmaStreamSetMemory0(spip->dmarx, rxbuf); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); - dmaStreamSetMemory0(spip->dmatx, &dummytx); - dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->txdmamode); + if ((spip->spi->CR1 & SPI_CR1_BIDIMODE) != 0) { + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); - dmaStreamEnable(spip->dmarx); - dmaStreamEnable(spip->dmatx); + dmaStreamEnable(spip->dmarx); + + spip->spi->CR1 &= ~SPI_CR1_BIDIOE; + } + else { +#else + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); + + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->txdmamode); + + dmaStreamEnable(spip->dmarx); + dmaStreamEnable(spip->dmatx); +#endif +#if STM32_SPI_USE_BIDIMODE + } +#endif } /** @@ -624,6 +663,13 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { */ uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIMODE) == 0, + "spiExchange() not possible with BIDIMODE"); + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); +#endif + spip->spi->DR = frame; while ((spip->spi->SR & SPI_SR_RXNE) == 0) ; diff --git a/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h b/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h index 2aab01daf..eba9f21e1 100644 --- a/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv1/spi_lld.h @@ -195,6 +195,15 @@ #define STM32_SPI_SPI6_DMA_PRIORITY 1 #endif +/** + * @brief Enables the SPI BIDIMODE support. + * @details If set to @p TRUE the support for BIDIMODE CR1 bit is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_SPI_USE_BIDIMODE) || defined(__DOXYGEN__) +#define STM32_SPI_USE_BIDIMODE FALSE +#endif + /** * @brief SPI DMA error hook. */ @@ -231,7 +240,7 @@ #error "SPI6 not present in the selected device" #endif -#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \ +#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 diff --git a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c index 167e28b4c..718ba7836 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c @@ -117,7 +117,6 @@ SPIDriver SPID6; /*===========================================================================*/ static const uint16_t dummytx = 0xFFFFU; -static uint16_t dummyrx; /*===========================================================================*/ /* Driver local functions. */ @@ -144,6 +143,14 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { dmaStreamDisable(spip->dmatx); dmaStreamDisable(spip->dmarx); +#if STM32_SPI_USE_BIDIMODE + spip->spi->CR1 |= SPI_CR1_BIDIOE; +#endif + + /* Errors reset sequence.*/ + (void)spip->spi->DR; + (void)spip->spi->SR; + /* Portable SPI ISR code defined in the high level driver, note, it is a macro.*/ _spi_isr_code(spip); @@ -303,6 +310,12 @@ void spi_lld_init(void) { void spi_lld_start(SPIDriver *spip) { uint32_t ds; +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert(!(((spip->spi->CR1 & SPI_CR1_BIDIMODE) == 0) ^^ + ((spip->spi->CR1 & SPI_CR1_BIDIOE) == 0)), + "BIDIOE not set"); +#endif + /* If in stopped state then enables the SPI and DMA clocks.*/ if (spip->state == SPI_STOP) { #if STM32_SPI_USE_SPI1 @@ -515,15 +528,16 @@ void spi_lld_unselect(SPIDriver *spip) { */ void spi_lld_ignore(SPIDriver *spip, size_t n) { - dmaStreamSetMemory0(spip->dmarx, &dummyrx); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->rxdmamode); +#if STM32_SPI_USE_BIDIMODE + if ((spip->spi->CR1 & SPI_CR1_BIDIMODE) != 0) { + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); +#endif dmaStreamSetMemory0(spip->dmatx, &dummytx); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode); - dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); } @@ -545,6 +559,11 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIMODE) == 0, + "spiExchange() not possible with BIDIMODE"); +#endif + dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); @@ -572,15 +591,16 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - dmaStreamSetMemory0(spip->dmarx, &dummyrx); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->rxdmamode); +#if STM32_SPI_USE_BIDIMODE + if ((spip->spi->CR1 & SPI_CR1_BIDIMODE) != 0) { + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); +#endif dmaStreamSetMemory0(spip->dmatx, txbuf); dmaStreamSetTransactionSize(spip->dmatx, n); dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC); - dmaStreamEnable(spip->dmarx); dmaStreamEnable(spip->dmatx); } @@ -599,16 +619,35 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - dmaStreamSetMemory0(spip->dmarx, rxbuf); - dmaStreamSetTransactionSize(spip->dmarx, n); - dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); - dmaStreamSetMemory0(spip->dmatx, &dummytx); - dmaStreamSetTransactionSize(spip->dmatx, n); - dmaStreamSetMode(spip->dmatx, spip->txdmamode); + if ((spip->spi->CR1 & SPI_CR1_BIDIMODE) != 0) { + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); - dmaStreamEnable(spip->dmarx); - dmaStreamEnable(spip->dmatx); + dmaStreamEnable(spip->dmarx); + + spip->spi->CR1 &= ~SPI_CR1_BIDIOE; + } + else { +#else + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); + + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->txdmamode); + + dmaStreamEnable(spip->dmarx); + dmaStreamEnable(spip->dmatx); +#endif +#if STM32_SPI_USE_BIDIMODE + } +#endif } /** @@ -625,6 +664,13 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { */ uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { +#if STM32_SPI_USE_BIDIMODE + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIMODE) == 0, + "spiExchange() not possible with BIDIMODE"); + osalDbgAssert((spip->spi->CR1 & SPI_CR1_BIDIOE) != 0, + "BIDIOE not set"); +#endif + /* * Data register must be accessed with the appropriate data size. * Byte size access (uint8_t *) for transactions that are <= 8-bit. diff --git a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h index e2bcb124e..795d753be 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.h @@ -195,6 +195,15 @@ #define STM32_SPI_SPI6_DMA_PRIORITY 1 #endif +/** + * @brief Enables the SPI BIDIMODE support. + * @details If set to @p TRUE the support for BIDIMODE CR1 bit is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_SPI_USE_BIDIMODE) || defined(__DOXYGEN__) +#define STM32_SPI_USE_BIDIMODE FALSE +#endif + /** * @brief SPI DMA error hook. */