diff options
author | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2019-01-31 21:36:40 +0300 |
---|---|---|
committer | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2019-01-31 21:36:40 +0300 |
commit | fbce36388c455b9633a25eb4ce872940ae6f72fa (patch) | |
tree | 66302ed05bb2e3ce44d20cc85fe6713c65ea1734 | |
parent | 4ac1beba0e85c628482abfd69edc3a86bff3fa69 (diff) |
Updated FMC initialization code to match changes in FMC arbiter.
-rw-r--r-- | stm-fmc.c | 47 |
1 files changed, 25 insertions, 22 deletions
@@ -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; } |