From a8693baa481e1c4d91379af08bbc9f459b1b4d56 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 10 Jan 2018 13:36:09 +0000 Subject: SPIv1 and SPIv2 circular mode added. Rework of RCC files and all dependencies inside STM32 drivers. Documentation fixes in some HAL modules. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11247 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c | 12 ++--- os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c | 73 ++++++++++++++++++++++-------- os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h | 18 ++++++++ 3 files changed, 79 insertions(+), 24 deletions(-) (limited to 'os/hal/ports/STM32/LLD/SPIv2') diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c b/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c index 33fe22ca5..54f6dd984 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c @@ -360,7 +360,7 @@ void i2s_lld_start(I2SDriver *i2sp) { bool b; /* Enabling I2S unit clock.*/ - rccEnableSPI1(FALSE); + rccEnableSPI1(false); #if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) b = dmaStreamAllocate(i2sp->dmarx, @@ -394,7 +394,7 @@ void i2s_lld_start(I2SDriver *i2sp) { bool b; /* Enabling I2S unit clock.*/ - rccEnableSPI2(FALSE); + rccEnableSPI2(false); #if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) b = dmaStreamAllocate(i2sp->dmarx, @@ -428,7 +428,7 @@ void i2s_lld_start(I2SDriver *i2sp) { bool b; /* Enabling I2S unit clock.*/ - rccEnableSPI3(FALSE); + rccEnableSPI3(false); #if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) b = dmaStreamAllocate(i2sp->dmarx, @@ -484,17 +484,17 @@ void i2s_lld_stop(I2SDriver *i2sp) { #if STM32_I2S_USE_SPI1 if (&I2SD1 == i2sp) - rccDisableSPI1(FALSE); + rccDisableSPI1(); #endif #if STM32_I2S_USE_SPI2 if (&I2SD2 == i2sp) - rccDisableSPI2(FALSE); + rccDisableSPI2(); #endif #if STM32_I2S_USE_SPI3 if (&I2SD3 == i2sp) - rccDisableSPI3(FALSE); + rccDisableSPI3(); #endif } } diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c index 6adc0b920..3d91bac46 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c @@ -140,13 +140,25 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { (void)flags; #endif - /* Stop everything.*/ - dmaStreamDisable(spip->dmatx); - dmaStreamDisable(spip->dmarx); + if (spip->config->circular) { + if ((flags & STM32_DMA_ISR_HTIF) != 0U) { + /* Half buffer interrupt.*/ + _spi_isr_code_half1(spip); + } + else { + /* End buffer interrupt.*/ + _spi_isr_code_half2(spip); + } + } + else { + /* Stopping DMAs.*/ + dmaStreamDisable(spip->dmatx); + dmaStreamDisable(spip->dmarx); - /* Portable SPI ISR code defined in the high level driver, note, it is - a macro.*/ - _spi_isr_code(spip); + /* Portable SPI ISR code defined in the high level driver, note, it is + a macro.*/ + _spi_isr_code(spip); + } } /** @@ -318,7 +330,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); osalDbgAssert(!b, "stream already allocated"); - rccEnableSPI1(FALSE); + rccEnableSPI1(false); } #endif #if STM32_SPI_USE_SPI2 @@ -334,7 +346,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); osalDbgAssert(!b, "stream already allocated"); - rccEnableSPI2(FALSE); + rccEnableSPI2(false); } #endif #if STM32_SPI_USE_SPI3 @@ -350,7 +362,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); osalDbgAssert(!b, "stream already allocated"); - rccEnableSPI3(FALSE); + rccEnableSPI3(false); } #endif #if STM32_SPI_USE_SPI4 @@ -366,7 +378,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); osalDbgAssert(!b, "stream already allocated"); - rccEnableSPI4(FALSE); + rccEnableSPI4(false); } #endif #if STM32_SPI_USE_SPI5 @@ -382,7 +394,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); osalDbgAssert(!b, "stream already allocated"); - rccEnableSPI5(FALSE); + rccEnableSPI5(false); } #endif #if STM32_SPI_USE_SPI6 @@ -398,7 +410,7 @@ void spi_lld_start(SPIDriver *spip) { (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); osalDbgAssert(!b, "stream already allocated"); - rccEnableSPI6(FALSE); + rccEnableSPI6(false); } #endif @@ -424,6 +436,15 @@ void spi_lld_start(SPIDriver *spip) { STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; } + if (spip->config->circular) { + spip->rxdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE); + spip->txdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE); + } + else { + spip->rxdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE); + spip->txdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE); + } + /* SPI setup and enable.*/ spip->spi->CR1 &= ~SPI_CR1_SPE; spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR; @@ -453,27 +474,27 @@ void spi_lld_stop(SPIDriver *spip) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) - rccDisableSPI1(FALSE); + rccDisableSPI1(); #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) - rccDisableSPI2(FALSE); + rccDisableSPI2(); #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) - rccDisableSPI3(FALSE); + rccDisableSPI3(); #endif #if STM32_SPI_USE_SPI4 if (&SPID4 == spip) - rccDisableSPI4(FALSE); + rccDisableSPI4(); #endif #if STM32_SPI_USE_SPI5 if (&SPID5 == spip) - rccDisableSPI5(FALSE); + rccDisableSPI5(); #endif #if STM32_SPI_USE_SPI6 if (&SPID6 == spip) - rccDisableSPI6(FALSE); + rccDisableSPI6(); #endif } } @@ -622,6 +643,22 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { dmaStreamEnable(spip->dmatx); } +#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__) +/** + * @brief Aborts the ongoing SPI operation, if any. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_abort(SPIDriver *spip) { + + /* Stopping DMAs.*/ + dmaStreamDisable(spip->dmatx); + dmaStreamDisable(spip->dmarx); +} +#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */ + /** * @brief Exchanges one frame using a polled wait. * @details This synchronous function exchanges one frame using a polled diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h index 1c7a5f4b4..de194f521 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h @@ -31,6 +31,11 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @brief Circular mode support flag. + */ +#define SPI_SUPPORTS_CIRCULAR TRUE + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -421,6 +426,12 @@ typedef void (*spicallback_t)(SPIDriver *spip); * @brief Driver configuration structure. */ typedef struct { +#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__) + /** + * @brief Enables the circular buffer mode. + */ + bool circular; +#endif /** * @brief Operation complete callback or @p NULL. */ @@ -550,11 +561,18 @@ extern "C" { void spi_lld_init(void); void spi_lld_start(SPIDriver *spip); void spi_lld_stop(SPIDriver *spip); +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) + void spi_lld_select(SPIDriver *spip); + void spi_lld_unselect(SPIDriver *spip); +#endif void spi_lld_ignore(SPIDriver *spip, size_t n); void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf); void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); +#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__) + void spi_lld_abort(SPIDriver *spip); +#endif uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); #ifdef __cplusplus } -- cgit v1.2.3