From fbce36388c455b9633a25eb4ce872940ae6f72fa Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Thu, 31 Jan 2019 21:36:40 +0300 Subject: Updated FMC initialization code to match changes in FMC arbiter. --- stm-fmc.c | 47 +++++++++++++++++++++++++---------------------- 1 file 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; } -- cgit v1.2.3