From ecf18e86fbc0a11d36ffd42f007f853db83e89a6 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 30 Dec 2019 15:05:56 +0000 Subject: [PATCH] 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. --- src/floppy.c | 20 +++++++++++++------- src/floppy_f1.c | 11 +++++------ src/floppy_f7.c | 8 +++----- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/floppy.c b/src/floppy.c index 463ae8f9..c94de41d 100644 --- a/src/floppy.c +++ b/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; diff --git a/src/floppy_f1.c b/src/floppy_f1.c index 668ea13e..a9d39771 100644 --- a/src/floppy_f1.c +++ b/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; } diff --git a/src/floppy_f7.c b/src/floppy_f7.c index 0d90f30d..4e861bee 100644 --- a/src/floppy_f7.c +++ b/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; }