2020-02-19 08:41 PM
Suppose you want to get the max sample rate out of the ADC and you can not use DMA, how would you do that?
2020-02-19 09:23 PM
It depends on what MCU is that, why are all possible DMA channels taken, how much would it cost to rearrange the ports or change the MCU, what else is the MCU doing, etc.
Just noted that it's a STM32H7. With its flexible DMA channel assignment, it must be quite a busy system if all 16 (24 in case of ADC3) possible DMA channels are used.
Then I would just find the slowest of the 16/24 peripherals that are already using DMA, and change that driver to IRQ/polling mode.
2020-02-20 02:05 PM
I have DMA channels free, but I have to transfer 16 ADC samples or more at once using DMA or else the CPU is constantly servicing the DMA and ADC interrupt leaving no left over CPU cycles for my application. 16 sample latency is too high for my application.
2020-02-20 08:25 PM
You don't have to service any interrupts to use DMA.
Use a dual core (745/755/747/757) system, split the tasks so that one of the cores handles ADC data.
2020-02-20 09:20 PM
I think part of the issue is that the HAL ADC ISR is too heavy. I will trim the ISR code and just set registers directly and see if that improves things.
In my ADC ISR, I set a flag to indicate that new data is available. is there a way to do that without using an ISR or constant polling?
2020-02-20 11:58 PM
The more important question is, would it make sense ?
You would waste most of the time polling the EOC flag. Apart from injected mode, sucessive conversions overwrite previous results, there is only one result register.
What do you need the maximal sampling rate for anyway ?
2020-02-21 12:36 AM
Every single HAL function is too heavy. Remove every last trace of HAL from the application if you want decent processing speed. Don't even store the HAL sources on the same hard drive.
Example: Setting a GPIO (1 register write) and starting SPI (2 register writes) takes a microsecond with HAL.
If the only purpose of the interrupt handler is to set a flag to be polled in the main thread, then it doesn't make much sense to have an interrupt handler at all. The main loop can poll some hardware flag directly instead with the same effort. Even a pure do-nothing interrupt handler takes 20-25 cycles to execute, or more if it runs from flash.
DMA can still store samples in a circular buffer. The main loop can check the DMA NDTR register to get the position of the latest reading, and compare the previous value to see how much samples it has missed.
If you still require interrupts, moving the interrupt handlers and the whole vector table to ITCM memory can speed it up a lot.