2023-08-09 07:41 AM - edited 2023-08-14 06:36 AM
I am using the STM32G474 and have the following situation:
Ideally I want to keep the CPU asleep for this whole process; the CPU should only wake up at ~100 Hz to process the filtered data (i.e. FMAC output stored in memory) and perform other functions. However I'm unable to determine a method for de-interleaving the interleaved ADC samples from memory (step 6) without waking the CPU.
The perfect solution is if either DMA or FMAC allows me to set the 'stride length/address increment size' to 6, however this doesn't appear to be possible on the STM32G4.
Am I missing anything? What method(s) can I use to de-interleave a buffer of ADC samples from memory without CPU intervention? (or directly from ADC --> FMAC?)
Edit 2023/08/14: Reworded Step 3 for clarity, as per MasterT's comment.
Original text: "3. Upon completion of the sequence of conversions, DMA transfers the entire sequence to a buffer in memory"
Solved! Go to Solution.
2023-08-10 12:42 AM - edited 2023-08-16 06:15 AM
Thanks JW, this is exactly the kind of answer I was looking for :party_popper:
I don't think the proposed solution is entirely possible (only 1 DMA channel can be used per ADC on the STM32G4), however your idea helped trigger a similar solution that may be possible (edit: not possible, see note at the bottom).
My current de-interleaving plan:
Edit 2023/08/16: The above plan is not possible for the following reasons:
2023-08-09 09:07 AM
6. Some magic de-interleaving happens
Interesting to know that the STM32 can do magic.
2023-08-09 09:29 AM
There's no magic solution here. You need the CPU to de-interleave channels.
2023-08-09 11:22 AM
> 3. Upon completion of the sequence of conversions, DMA transfers the entire sequence to a buffer in memory
No. DMA transfers individually each sample when it's ready.
Instead of a DMA triggered from ADC, You can run 6 DMAs triggered from timers generating appropriately staggered signals, to transfer from ADC->DR each to its individual buffer in memory.
I don't use 'G4 so don't know if there's enough DMAs and timers to do this.
JW
2023-08-10 12:42 AM - edited 2023-08-16 06:15 AM
Thanks JW, this is exactly the kind of answer I was looking for :party_popper:
I don't think the proposed solution is entirely possible (only 1 DMA channel can be used per ADC on the STM32G4), however your idea helped trigger a similar solution that may be possible (edit: not possible, see note at the bottom).
My current de-interleaving plan:
Edit 2023/08/16: The above plan is not possible for the following reasons:
2023-08-11 07:49 AM
@Olly wrote:Thanks JW, this is exactly the kind of answer I was looking for :party_popper:
I don't think the proposed solution is entirely possible (only 1 DMA channel can be used per ADC on the STM32G4), however your idea helped trigger a similar solution that may be possible.
My current de-interleaving plan:
- ADC acquires a sequence of 6 samples
- ADC DMA transfers this sequence of samples to memory (buffer size of 6 samples, in circular mode)
- After the 6th sample is transferred to memory, the 'ADC DMA full/conversion complete' event is used to trigger 6 separate DMA channels to transfer from memory to memory (i.e. from the interleaved buffer to 6 individual de-interleaved buffers)
- These 6 DMA channels are configured as follows:
- Each DMA channel has a different start address within the interleaved buffer (i.e. each DMA channel is responsible for transferring the sample for a single ADC channel)
- Don't increment source address (interleaved buffer)
- Increment destination address (de-interleaved buffer)
- Steps 1-4 are repeated until the individual de-interleaved buffers are full
- DMA is used to pass each de-interleaved buffer to FMAC in turn
I see a deep flow in this statement, DMA doesn't worked on sequence frame, it's called after each sample out of 6 is converted. Otherwise DR of the ADC is overwritten by next sample in sequence.
Just assign 30kbytes of the buffer and do processing on 10 Hz base.
The issue may be if not sufficient memory available, than as Waclawek suggest, you can assign 6 DMA channels triggered by timers to transfer each sample to 6 different buffers. DMA wouldn't even know that data is comming from adc, for DMA data register of the ADC is no different than any memory cell. Though, correct sync requirent in this case to split 6 triggers into 6 phases synchronously with ADC sampling rate. HRTIM may be an option, but it looks overcomplicated solution in any way