aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George2019-07-25 15:16:57 +1000
committerDamien George2019-07-25 16:48:26 +1000
commitb1129df4780abc5f140b473d10ebe5316793aac2 (patch)
tree6144b12bccb5fc53100c4f35d8b1bca4714caf76
parente9593d50755cfdd157d1bd67a02a1314f9ccedb5 (diff)
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).
-rw-r--r--ports/stm32/dma.c24
1 files changed, 24 insertions, 0 deletions
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;