drivers/i2s_ll_stm32.c: (FIX) use dma_reload() to re-start the DMA
Fix issue #14618. The I2S controller may generate an underrun/overrun error whenever the current sample in the Data Register (DR) has not been read/written yet when a new one needs to be sent/received. When the DMA operation is completed there is no much time to re-enable it for a new transfer. For example, in the case of a PDM microphone clocked at 2MHz we only have 8us to re-program the DMA to receive the new 16-bit sample. Doing a complete DMA configuration using the dma_config() API is an operation that is consuming too much time and driver is close to the limit. Instead, the dma_reload() routine only programs the minimum needed information (src, dst, len) for the new transfer in order to restart the DMA. Signed-off-by: Armando Visconti <armando.visconti@st.com>
This commit is contained in:
parent
c0ffa6f2b7
commit
455829248f
1 changed files with 19 additions and 2 deletions
|
@ -421,6 +421,23 @@ static const struct i2s_driver_api i2s_stm32_driver_api = {
|
|||
static struct device *active_dma_rx_channel[STM32_DMA_NUM_CHANNELS];
|
||||
static struct device *active_dma_tx_channel[STM32_DMA_NUM_CHANNELS];
|
||||
|
||||
static int reload_dma(struct device *dev_dma, u32_t channel,
|
||||
struct dma_config *dcfg, void *src, void *dst,
|
||||
u32_t blk_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dma_reload(dev_dma, channel, (u32_t)src, (u32_t)dst,
|
||||
blk_size / sizeof(u16_t));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dma_start(dev_dma, channel);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int start_dma(struct device *dev_dma, u32_t channel,
|
||||
struct dma_config *dcfg, void *src, void *dst,
|
||||
u32_t blk_size)
|
||||
|
@ -483,7 +500,7 @@ static void dma_rx_callback(void *arg, u32_t channel, int status)
|
|||
goto rx_disable;
|
||||
}
|
||||
|
||||
ret = start_dma(dev_data->dev_dma, stream->dma_channel,
|
||||
ret = reload_dma(dev_data->dev_dma, stream->dma_channel,
|
||||
&stream->dma_cfg,
|
||||
(void *)LL_SPI_DMA_GetRegAddr(cfg->i2s),
|
||||
stream->mem_block,
|
||||
|
@ -566,7 +583,7 @@ static void dma_tx_callback(void *arg, u32_t channel, int status)
|
|||
/* Assure cache coherency before DMA read operation */
|
||||
DCACHE_CLEAN(stream->mem_block, mem_block_size);
|
||||
|
||||
ret = start_dma(dev_data->dev_dma, stream->dma_channel,
|
||||
ret = reload_dma(dev_data->dev_dma, stream->dma_channel,
|
||||
&stream->dma_cfg,
|
||||
stream->mem_block,
|
||||
(void *)LL_SPI_DMA_GetRegAddr(cfg->i2s),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue