diff --git a/os/hal/include/i2s.h b/os/hal/include/i2s.h index afd605b26..c7143daec 100644 --- a/os/hal/include/i2s.h +++ b/os/hal/include/i2s.h @@ -118,9 +118,9 @@ typedef enum { * * @notapi */ -#define _i2S_isr_half_code(i2sp) { \ - if ((i2sp)->end_cb != NULL) { \ - (i2sp)->end_cb(i2sp, 0, (i2sp)->config->depth / 2); \ +#define _i2s_isr_half_code(i2sp) { \ + if ((i2sp)->config->end_cb != NULL) { \ + (i2sp)->config->end_cb(i2sp, 0, (i2sp)->config->size / 2); \ } \ } @@ -137,7 +137,7 @@ typedef enum { * * @notapi */ -#define _i2s_isr_code(i2sp) { \ +#define _i2s_isr_full_code(i2sp) { \ if ((i2sp)->config->end_cb) { \ (i2sp)->state = I2S_COMPLETE; \ (i2sp)->config->end_cb(i2sp, \ diff --git a/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c index a9523060c..e95ac27ba 100644 --- a/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.c @@ -118,22 +118,25 @@ I2SDriver I2SD3; */ static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) { + (void)i2sp; + /* DMA errors handling.*/ #if defined(STM32_I2S_DMA_ERROR_HOOK) if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { STM32_I2S_DMA_ERROR_HOOK(i2sp); } -#else - (void)flags; #endif - /* Stop everything.*/ - dmaStreamDisable(i2sp->dmatx); - dmaStreamDisable(i2sp->dmarx); - - /* Portable I2S ISR code defined in the high level driver, note, it is - a macro.*/ - _i2s_isr_code(i2sp); + /* Callbacks handling, note it is portable code defined in the high + level driver.*/ + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _i2s_isr_full_code(i2sp); + } + else if ((flags & STM32_DMA_ISR_HTIF) != 0) { + /* Half transfer processing.*/ + _i2s_isr_half_code(i2sp); + } } #endif @@ -147,15 +150,25 @@ static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) { */ static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) { + (void)i2sp; + /* DMA errors handling.*/ #if defined(STM32_I2S_DMA_ERROR_HOOK) - (void)i2sp; if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { STM32_I2S_DMA_ERROR_HOOK(i2sp); } -#else - (void)flags; #endif + + /* Callbacks handling, note it is portable code defined in the high + level driver.*/ + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + _i2s_isr_full_code(i2sp); + } + else if ((flags & STM32_DMA_ISR_HTIF) != 0) { + /* Half transfer processing.*/ + _i2s_isr_half_code(i2sp); + } } #endif @@ -333,7 +346,7 @@ void i2s_lld_start(I2SDriver *i2sp) { dmaStreamSetMode(i2sp->dmatx, i2sp->txdmamode | dmasize); } - /* I2S configuration.*/ + /* I2S (re)configuration.*/ i2sp->spi->I2SPR = i2sp->config->i2spr; i2sp->spi->I2SCFGR = i2sp->config->i2scfgr | i2sp->cfg | SPI_I2SCFGR_I2SMOD; } @@ -377,6 +390,22 @@ void i2s_lld_stop(I2SDriver *i2sp) { */ void i2s_lld_start_exchange(I2SDriver *i2sp) { + /* RX DMA setup.*/ + if (NULL != i2sp->dmarx) { + dmaStreamSetMemory0(i2sp->dmarx, i2sp->config->rx_buffer); + dmaStreamSetTransactionSize(i2sp->dmarx, i2sp->config->size); + dmaStreamEnable(i2sp->dmarx); + } + + /* TX DMA setup.*/ + if (NULL != i2sp->dmatx) { + dmaStreamSetMemory0(i2sp->dmatx, i2sp->config->tx_buffer); + dmaStreamSetTransactionSize(i2sp->dmatx, i2sp->config->size); + dmaStreamEnable(i2sp->dmatx); + } + + /* Starting transfer.*/ + i2sp->spi->I2SCFGR |= SPI_I2SCFGR_I2SE; } /** @@ -390,6 +419,14 @@ void i2s_lld_start_exchange(I2SDriver *i2sp) { */ void i2s_lld_stop_exchange(I2SDriver *i2sp) { + /* Stop DMAs.*/ + if (NULL != i2sp->dmatx) + dmaStreamDisable(i2sp->dmatx); + if (NULL != i2sp->dmarx) + dmaStreamDisable(i2sp->dmarx); + + /* Stop transfer.*/ + i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE; } #endif /* HAL_USE_I2S */ diff --git a/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h index ac1ff3d15..5c2fb1c32 100644 --- a/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv1/i2s_lld.h @@ -134,6 +134,16 @@ /* Derived constants and error checks. */ /*===========================================================================*/ +#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) && \ + STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE) +#error "I2S2 RX and TX mode not supported in this driver implementation" +#endif + +#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) && \ + STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE) +#error "I2S3 RX and TX mode not supported in this driver implementation" +#endif + #if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2 #error "SPI2 not present in the selected device" #endif