aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-01-31 21:36:40 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-01-31 21:36:40 +0300
commitfbce36388c455b9633a25eb4ce872940ae6f72fa (patch)
tree66302ed05bb2e3ce44d20cc85fe6713c65ea1734
parent4ac1beba0e85c628482abfd69edc3a86bff3fa69 (diff)
Updated FMC initialization code to match changes in FMC arbiter.
-rw-r--r--stm-fmc.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/stm-fmc.c b/stm-fmc.c
index 58df6fe..62b6433 100644
--- a/stm-fmc.c
+++ b/stm-fmc.c
@@ -62,7 +62,7 @@ void fmc_init(void)
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
fmc_af_gpio(GPIOE, GPIO_PIN_2
@@ -152,10 +152,10 @@ void fmc_init(void)
// not needed, since nwait will be polled manually
fmc_timing.BusTurnAroundDuration = 0;
- // use smallest allowed divisor for best performance
- fmc_timing.CLKDivision = 2;
+ // use 45 MHz to match what FMC arbiter in the FPGA expects
+ fmc_timing.CLKDivision = 4;
- // use min suitable for fastest transfer
+ // use 4 to match what FMC arbiter in the FPGA expects
fmc_timing.DataLatency = 4;
// don't care in sync mode
@@ -164,22 +164,25 @@ void fmc_init(void)
// 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;
- }
+ // 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.22 us (10 ticks @ 45 MHz), so doing ~500 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 = 0;
+ volatile uint32_t part;
+
+ for (cyc=0; cyc<500; cyc++)
+ {
+ part = *(__IO uint32_t *)FMC_FPGA_BASE_ADDR;
+ sum += part;
+ }
+
+ // dummy write to read-only address to not let the compiler remove the above loop
+ *(__IO uint32_t *)FMC_FPGA_BASE_ADDR = sum;
}