diff options
author | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2020-01-21 11:52:36 +0300 |
---|---|---|
committer | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2020-01-21 11:52:36 +0300 |
commit | 39f2d7ec4f35191884978db447bd97638b283d1d (patch) | |
tree | 93b519bf4e8b0e34016b60d7651bd6c198bd1b66 | |
parent | e203f797dddfcd03419e7ac336a86a6186fce0c1 (diff) | |
parent | 723766c08127d3f489d90ea94bc090d9481bbebb (diff) |
Merge branch 'fmc_clk'
-rw-r--r-- | stm-fmc.c | 61 |
1 files changed, 27 insertions, 34 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 @@ -149,25 +149,14 @@ void fmc_init(void) // don't care in sync mode fmc_timing.DataSetupTime = 255; - // not needed, since nwait will be polled manually + // not needed fmc_timing.BusTurnAroundDuration = 0; - // use smallest allowed divisor for best performance - // - // FMC_CLK = HCLK / CLKDivision, HCLK is 180 MHz - // - // Allowed values for CLKDivision are integers >= 2. - // - // Division == 2: FMC_CLK = 180 / 2 = 90 MHz (highest allowed frequency) - // Division == 3: FMC_CLK = 180 / 3 = 60 MHz (one step below) - // ... - // + // use 45 MHz to match what FMC arbiter in the FPGA expects + fmc_timing.CLKDivision = 4; // 180/4 -// fmc_timing.CLKDivision = 2; // 90 MHz - fmc_timing.CLKDivision = 3; // 60 MHz - - // use min suitable for fastest transfer - fmc_timing.DataLatency = 4; + // use 6 to match what FMC arbiter in the FPGA expects + fmc_timing.DataLatency = 6; // don't care in sync mode fmc_timing.AccessMode = FMC_ACCESS_MODE_A; @@ -175,21 +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; } |