From b1129df4780abc5f140b473d10ebe5316793aac2 Mon Sep 17 00:00:00 2001 From: Damien George <damien.p.george@gmail.com> Date: Thu, 25 Jul 2019 15:16:57 +1000 Subject: [PATCH] stm32/dma: Fix re-start of DMA stream by clearing all event flags. As per the datasheet, all event flags for a stream must be cleared before enabling it. Fixes issue #4944 (with DAC.write_timed). --- ports/stm32/dma.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 8a3f743fe..3d275684d 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -922,6 +922,30 @@ void dma_nohal_deinit(const dma_descr_t *descr) { } void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_addr, uint16_t len) { + // Must clear all event flags for this stream before enabling it + DMA_TypeDef *dma_ctrl; + uint32_t ch = descr->id; + if (ch < NSTREAMS_PER_CONTROLLER) { + dma_ctrl = DMA1; + } else { + dma_ctrl = DMA2; + ch -= NSTREAMS_PER_CONTROLLER; + } + __IO uint32_t *ifcr; + if (ch <= 3) { + ifcr = &dma_ctrl->LIFCR; + } else { + ifcr = &dma_ctrl->HIFCR; + ch -= 4; + } + if (ch <= 1) { + ch = ch * 6; + } else { + ch = 4 + ch * 6; + } + *ifcr = 0x3d << ch; + + // Configure and enable stream DMA_Stream_TypeDef *dma = descr->instance; dma->CR &= ~DMA_SxCR_DBM; dma->NDTR = len; -- GitLab