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