drivers: dma: stm32: do not clear busy flag in cyclic mode

The STM32 DMA driver supports cyclic mode by setting source_reload_en
and dest_reload_en. This causes the dma_callback to be called twice per
buffer run-through, at half-time and when wrapping back to the start of
the buffer.

However, the current implementation only calls dma_callback twice. When
wrapping the first time, it sets stream->busy to false and ignores
subsequent interrupts.

With this change, the busy flag is only cleared in non-cyclic mode.

Signed-off-by: Marco Widmer <marco.widmer@bytesatwork.ch>
This commit is contained in:
Marco Widmer 2023-03-20 11:23:04 +01:00 committed by Carles Cufí
parent 6fa5d1e6a5
commit 32b4388ba8
2 changed files with 9 additions and 3 deletions

View file

@ -123,7 +123,10 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id)
stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_BLOCK);
} else if (stm32_dma_is_tc_irq_active(dma, id)) {
#ifdef CONFIG_DMAMUX_STM32
stream->busy = false;
/* Circular buffer never stops receiving as long as peripheral is enabled */
if (!stream->cyclic) {
stream->busy = false;
}
#endif
/* Let HAL DMA handle flags on its own */
if (!stream->hal_override) {
@ -312,6 +315,7 @@ DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev,
stream->hal_override = true;
stream->dma_callback = config->dma_callback;
stream->user_data = config->user_data;
stream->cyclic = false;
return 0;
}
@ -361,6 +365,7 @@ DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev,
stream->user_data = config->user_data;
stream->src_size = config->source_data_size;
stream->dst_size = config->dest_data_size;
stream->cyclic = config->head_block->source_reload_en;
/* Check dest or source memory address, warn if 0 */
if (config->head_block->source_address == 0) {
@ -432,7 +437,7 @@ DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev,
LOG_DBG("Channel (%d) peripheral inc (%x).",
id, DMA_InitStruct.PeriphOrM2MSrcIncMode);
if (config->head_block->source_reload_en) {
if (stream->cyclic) {
DMA_InitStruct.Mode = LL_DMA_MODE_CIRCULAR;
} else {
DMA_InitStruct.Mode = LL_DMA_MODE_NORMAL;
@ -494,7 +499,7 @@ DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev,
LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id));
/* Enable Half-Transfer irq if circular mode is enabled */
if (config->head_block->source_reload_en) {
if (stream->cyclic) {
LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id));
}

View file

@ -27,6 +27,7 @@ struct dma_stm32_stream {
uint32_t dst_size;
void *user_data; /* holds the client data */
dma_callback_t dma_callback;
bool cyclic;
};
struct dma_stm32_data {