I have two parallel usages of the FMC on an STM32F4 processor:
- One that writes to SDRAM with DMA2 Stream 1
- One that reads from an external ADC (FMC NOR Flash/PSRAM controller) with DMA2 Stream 2
How can I force the FMC into pausing an ongoing SDRAM write and service an ADC read quickly?
I have two parallel concurrent usages of the FMC on an STM32F429ZITx processor:
- #1 that writes 1024 bytes from SRAM to SDRAM with DMA2 Stream 1 (low DMA priority). The FMC is writing 2 bytes at a time to SDRAM (16 bits data bus).
- #2 that reads data from an external ADC using the FMC NOR Flash/PSRAM controller and copies to SRAM, with DMA2 Stream 2 (highest DMA priority), one byte at a time triggered by a timer every 404.8ns. Every time the timer triggers a DMA request, it also toggles a pin that’s connected to the ADC’s “ADCCLK” input. The ADC outputs the next byte at every ADCCLK edge.
I would like for the #2 to interrupt any ongoing #1 as fast as possible, so that the byte is read in time from the ADC before the next ADCCLK edge.
If the #2 is the only DMA/FMC task, I have a consistent 52ns delay between any ADCCLK edge and its subsequent FmcNEAdc rising edge. The FMC samples the ADC data at FmcNEAdc rising edges, because per the processor’s reference manual RM0090 ““The FMC always samples the data before de-asserting the Chip Select signal NE”.
With added parallel #1 usage, I have measured a max delay of 405ns, which is an extra 405 – 52 = 353ns. During these 353ns, I see that:
- the “FmcNESdram” signal is at low, i.e. the FMC is writing data to SDRAM.
- The FMC A0 line is toggled 26 times, i.e. the FMC wrote 52 bytes to SDRAM.
The processor’s reference manual indicates that the FMC has a “Write Data FIFO with 16 x33-bit depth” and a “Write Address FIFO with 16x30-bit depth”. So the FMC write data FIFO has a size of 16 * 4 = 64 bytes. If the DMA fills the FMC fifo faster than the FMC drains it to SDRAM, I suppose the fifo could get filled up. If the FMC must drain that fifo to SDRAM before it can service an ADC read request, then it could mean an ADC read delay of up to ((64 / NbBytesWrittenPerSdramClockPeriod) * SdramClock period) = ((64/2) * 11.9ns) = 381ns. This roughly matches with my measured max delay of 353ns.
Would anybody have some suggestion for reducing that delay and forcing the FMC into servicing the ADC read requests faster?
Much thanks for your time & effort in helping me with this.
PS: Please see attachment for oscilloscope timing capture, code excerpts and runtime register captures