Browse Source

STM32F7: Some timer+dma fixes for the read path.
1. Timers should be disabled before DMA. Else we can be left with
a DMA request pending.
2. Clear the Timer Counter before enabling DMA and Input Capture.

Keir Fraser 5 years ago
parent
commit
77d6582fce
3 changed files with 10 additions and 8 deletions
  1. 6 8
      src/floppy.c
  2. 2 0
      src/floppy_f1.c
  3. 2 0
      src/floppy_f7.c

+ 6 - 8
src/floppy.c

@@ -179,12 +179,6 @@ static void floppy_flux_end(void)
     write_pin(wgate, FALSE);
     configure_pin(wdata, GPO_bus);    
 
-    /* Turn off DMA. */
-    dma_rdata.cr &= ~DMA_CR_EN;
-    dma_wdata.cr &= ~DMA_CR_EN;
-    while ((dma_rdata.cr & DMA_CR_EN) || (dma_wdata.cr & DMA_CR_EN))
-        continue;
-
     /* Turn off timers. */
     tim_rdata->ccer = 0;
     tim_rdata->cr1 = 0;
@@ -192,6 +186,12 @@ static void floppy_flux_end(void)
     tim_wdata->ccer = 0;
     tim_wdata->cr1 = 0;
     tim_wdata->sr = 0; /* dummy, drains any pending DMA */
+
+    /* Turn off DMA. */
+    dma_rdata.cr &= ~DMA_CR_EN;
+    dma_wdata.cr &= ~DMA_CR_EN;
+    while ((dma_rdata.cr & DMA_CR_EN) || (dma_wdata.cr & DMA_CR_EN))
+        continue;
 }
 
 static void floppy_reset(void)
@@ -370,8 +370,6 @@ static uint8_t floppy_read_prep(struct gw_read_flux *rf)
     dma_rdata.mar = (uint32_t)(unsigned long)dma.buf;
     dma_rdata.ndtr = ARRAY_SIZE(dma.buf);    
     rdata_prep();
-    tim_rdata->egr = TIM_EGR_UG; /* update CNT, PSC, ARR */
-    tim_rdata->sr = 0; /* dummy write */
 
     /* DMA soft state. */
     dma.cons = 0;

+ 2 - 0
src/floppy_f1.c

@@ -94,6 +94,8 @@ static void rdata_prep(void)
     tim_rdata->ccmr1 = TIM_CCMR1_CC2S(TIM_CCS_INPUT_TI1);
     tim_rdata->dier = TIM_DIER_CC2DE;
     tim_rdata->cr2 = 0;
+    tim_rdata->egr = TIM_EGR_UG; /* update CNT, PSC, ARR */
+    tim_rdata->sr = 0; /* dummy write */
 
     /* RDATA DMA setup: From the RDATA Timer's CCRx into a circular buffer. */
     dma_rdata.par = (uint32_t)(unsigned long)&tim_rdata->ccr2;

+ 2 - 0
src/floppy_f7.c

@@ -95,6 +95,8 @@ static void rdata_prep(void)
     tim_rdata->ccmr1 = TIM_CCMR1_CC1S(TIM_CCS_INPUT_TI1);
     tim_rdata->dier = TIM_DIER_CC1DE;
     tim_rdata->cr2 = 0;
+    tim_rdata->egr = TIM_EGR_UG; /* update CNT, PSC, ARR */
+    tim_rdata->sr = 0; /* dummy write */
 
     /* RDATA DMA setup: From the RDATA Timer's CCRx into a circular buffer. */
     dma_rdata.par = (uint32_t)(unsigned long)&tim_rdata->ccr1;