aboutsummaryrefslogtreecommitdiff
path: root/stm-fmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'stm-fmc.c')
-rw-r--r--stm-fmc.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/stm-fmc.c b/stm-fmc.c
index c5086b4..58df6fe 100644
--- a/stm-fmc.c
+++ b/stm-fmc.c
@@ -115,7 +115,7 @@ void fmc_init(void)
_fmc_fpga_inst.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
// don't care in fixed latency mode
- _fmc_fpga_inst.Init.WaitSignalActive = FMC_WAIT_TIMING_DURING_WS;
+ _fmc_fpga_inst.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
// allow write access to fpga
_fmc_fpga_inst.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
@@ -155,12 +155,31 @@ void fmc_init(void)
// use smallest allowed divisor for best performance
fmc_timing.CLKDivision = 2;
- // stm is too slow to work with min allowed 2-cycle latency
- fmc_timing.DataLatency = 3;
+ // use min suitable for fastest transfer
+ fmc_timing.DataLatency = 4;
// don't care in sync mode
fmc_timing.AccessMode = FMC_ACCESS_MODE_A;
// initialize fmc
HAL_SRAM_Init(&_fmc_fpga_inst, &fmc_timing, NULL);
+
+ // STM32 only enables FMC clock right before the very first read/write
+ // access. FPGA takes certain time (<= 100 us) to lock its PLL to this frequency,
+ // so a certain number of initial FMC transactions may be missed. One read transaction
+ // takes ~0.1 us (9 ticks @ 90 MHz), so doing 1000 dummy reads will make sure, that FPGA
+ // has already locked its PLL and is ready. Another way around is to repeatedly read
+ // some register that is guaranteed to have known value until reading starts returning
+ // correct data.
+
+ // to prevent compiler from optimizing this away, we pretent we're calculating sum
+ int cyc;
+ uint32_t sum;
+ volatile uint32_t part;
+
+ for (cyc=0; cyc<1000; cyc++)
+ {
+ part = *(__IO uint32_t *)FMC_FPGA_BASE_ADDR;
+ sum += part;
+ }
}