Explorar el Código

STM32F7: Fix all time values to be in units of the sample clock, not the sysclk.
Sysclk just happened to be correct for F1, but is 3x too fast for F7.

Keir Fraser hace 5 años
padre
commit
ecf18e86fb
Se han modificado 3 ficheros con 21 adiciones y 18 borrados
  1. 13 7
      src/floppy.c
  2. 5 6
      src/floppy_f1.c
  3. 3 5
      src/floppy_f7.c

+ 13 - 7
src/floppy.c

@@ -18,6 +18,12 @@
 #define configure_pin(pin, type) \
     gpio_configure_pin(gpio_##pin, pin_##pin, type)
 
+#define SAMPLE_MHZ 72
+#define TIM_PSC (SYSCLK_MHZ / SAMPLE_MHZ)
+#define sample_ns(x) (((x) * SAMPLE_MHZ) / 1000)
+#define sample_us(x) ((x) * SAMPLE_MHZ)
+#define time_from_samples(x) ((x) * TIME_MHZ / SAMPLE_MHZ)
+
 #if STM32F == 1
 #include "floppy_f1.c"
 #elif STM32F == 7
@@ -348,9 +354,9 @@ static void rdata_encode_flux(void)
      * flux timestamp. */
     if (sizeof(timcnt_t) == sizeof(uint16_t)) {
         curr = tim_rdata->cnt - prev;
-        if (unlikely(curr > sysclk_us(400))) {
-            prev += sysclk_us(200);
-            ticks += sysclk_us(200);
+        if (unlikely(curr > sample_us(400))) {
+            prev += sample_us(200);
+            ticks += sample_us(200);
         }
     }
 
@@ -475,7 +481,7 @@ static unsigned int _wdata_decode_flux(timcnt_t *tbuf, unsigned int nr)
         return 0;
 
     if (rw.no_flux_area) {
-        unsigned int nfa_pulse = sysclk_ns(1250);
+        unsigned int nfa_pulse = sample_ns(1250);
         while (ticks >= nfa_pulse) {
             *tbuf++ = nfa_pulse - 1;
             ticks -= nfa_pulse;
@@ -514,10 +520,10 @@ static unsigned int _wdata_decode_flux(timcnt_t *tbuf, unsigned int nr)
         }
 
         ticks += x;
-        if (ticks < sysclk_ns(800))
+        if (ticks < sample_ns(800))
             continue;
 
-        if (ticks > sysclk_us(150)) {
+        if (ticks > sample_us(150)) {
             rw.no_flux_area = TRUE;
             goto out;
         }
@@ -599,7 +605,7 @@ static uint8_t floppy_write_prep(struct gw_write_flux *wf)
     memset(&rw, 0, sizeof(rw));
     rw.status = ACK_OKAY;
 
-    index.delay = time_sysclk(wf->index_delay_ticks);
+    index.delay = time_from_samples(wf->index_delay_ticks);
     rw.terminate_at_index = wf->terminate_at_index;
 
     return ACK_OKAY;

+ 5 - 6
src/floppy_f1.c

@@ -53,7 +53,6 @@ static unsigned int GPI_bus;
 #define dma_wdata   (dma1->ch3)
 
 typedef uint16_t timcnt_t;
-#define TIM_PSC 0
 
 #define irq_index 23
 void IRQ_23(void) __attribute__((alias("IRQ_INDEX_changed"))); /* EXTI9_5 */
@@ -83,13 +82,13 @@ static void floppy_mcu_init(void)
 static void rdata_prep(void)
 {
     /* RDATA Timer setup: 
-     * The counter runs from 0x0000-0xFFFF inclusive at full SYSCLK rate.
+     * The counter runs from 0x0000-0xFFFF inclusive at SAMPLE rate.
      *  
      * Ch.2 (RDATA) is in Input Capture mode, sampling on every clock and with
      * no input prescaling or filtering. Samples are captured on the falling 
      * edge of the input (CCxP=1). DMA is used to copy the sample into a ring
      * buffer for batch processing in the DMA-completion ISR. */
-    tim_rdata->psc = 0;
+    tim_rdata->psc = TIM_PSC-1;
     tim_rdata->arr = 0xffff;
     tim_rdata->ccmr1 = TIM_CCMR1_CC2S(TIM_CCS_INPUT_TI1);
     tim_rdata->dier = TIM_DIER_CC2DE;
@@ -113,17 +112,17 @@ static void rdata_prep(void)
 static void wdata_prep(void)
 {
     /* WDATA Timer setup:
-     * The counter is incremented at full SYSCLK rate. 
+     * The counter is incremented at SAMPLE rate. 
      *  
      * Ch.1 (WDATA) is in PWM mode 1. It outputs O_TRUE for 400ns and then 
      * O_FALSE until the counter reloads. By changing the ARR via DMA we alter
      * the time between (fixed-width) O_TRUE pulses, mimicking floppy drive 
      * timings. */
-    tim_wdata->psc = 0;
+    tim_wdata->psc = TIM_PSC-1;
     tim_wdata->ccmr1 = (TIM_CCMR1_CC1S(TIM_CCS_OUTPUT) |
                         TIM_CCMR1_OC1M(TIM_OCM_PWM1));
     tim_wdata->ccer = TIM_CCER_CC1E | ((O_TRUE==0) ? TIM_CCER_CC1P : 0);
-    tim_wdata->ccr1 = sysclk_ns(400);
+    tim_wdata->ccr1 = sample_ns(400);
     tim_wdata->dier = TIM_DIER_UDE;
     tim_wdata->cr2 = 0;
 }

+ 3 - 5
src/floppy_f7.c

@@ -57,7 +57,6 @@
 #define dma_wdata   (dma1->str[1])
 
 typedef uint32_t timcnt_t;
-#define TIM_PSC (SYSCLK_MHZ/72)
 
 #define irq_index 8
 void IRQ_8(void) __attribute__((alias("IRQ_INDEX_changed"))); /* EXTI2 */
@@ -83,8 +82,7 @@ static void floppy_mcu_init(void)
 static void rdata_prep(void)
 {
     /* RDATA Timer setup: 
-     * The counter runs from 0x00000000-0xFFFFFFFF inclusive.
-     * The prescaler is used to reduce the clock rate to 72MHz.
+     * The counter runs from 0x00000000-0xFFFFFFFF inclusive at SAMPLE rate.
      *  
      * Ch.1 (RDATA) is in Input Capture mode, sampling on every clock and with
      * no input prescaling or filtering. Samples are captured on the falling 
@@ -115,7 +113,7 @@ static void rdata_prep(void)
 static void wdata_prep(void)
 {
     /* WDATA Timer setup:
-     * The counter is incremented at 72MHz.
+     * The counter is incremented at SAMPLE rate.
      *  
      * Ch.3 (WDATA) is in PWM mode 1. It outputs O_TRUE for 400ns and then 
      * O_FALSE until the counter reloads. By changing the ARR via DMA we alter
@@ -125,7 +123,7 @@ static void wdata_prep(void)
     tim_wdata->ccmr2 = (TIM_CCMR2_CC3S(TIM_CCS_OUTPUT) |
                         TIM_CCMR2_OC3M(TIM_OCM_PWM1));
     tim_wdata->ccer = TIM_CCER_CC3E | ((O_TRUE==0) ? TIM_CCER_CC3P : 0);
-    tim_wdata->ccr3 = sysclk_ns(400) / TIM_PSC;
+    tim_wdata->ccr3 = sample_ns(400);
     tim_wdata->dier = TIM_DIER_UDE;
     tim_wdata->cr2 = 0;
 }