2015-09-08 08:49 AM
I'm working on a sound-reactive project with the STM32F405 that samples ADC for FFT. I'm currently using double-buffered DMA triggered by TIM3 TRGO. Everything is working but it's very rough around the edges and I think I'm going about this wrong given my requirements. Some of the documentation still goes over my head in this area.
The trouble comes in that the FFT isn't the primary role of the device and I can't process each buffer (128 samples) as quickly as they're currently filled. My current workaround is to stop the timer as soon as the transfer complete interrupt fires and then enable it again once I get around to processing the buffer. It seems that I'm still getting some samples slipping into the buffer between the time the TC interrupt fires and the time I disable the timer. When it's re-enabled elsewhere the AC waveform doesn't match up and I end up with a lot of false low frequency information in the frequency domain.In my mind I just want 128 samples that sit around and wait until processed. Once processed, I just need another 128. It's not at all important that the two buffers are contiguous samples -- only that the data they represent is close enough to visually represent the current audio input.Can someone suggest an appropriate high level timer/adc/dma configuration to achieve what I'm looking for?2015-09-08 10:01 AM
Figure out what rate the FFT can sustain, if it's 1/10th of the rate the data's filling the buffers, then every 10 DMA interrupts, copy the data to a snap-shot buffer, and do the FFT processing on that, outside this interrupt. Let the TIM/ADC/DMA continue to do their job unfettered.
2015-09-08 03:00 PM
That sounds like a great approach. I don't even need DMA double-buffering then and I think it was somewhat clouding my ability to come up with a solution in this case.
Thanks for responding. Even though it seems simple it helps me a lot.2015-09-08 03:52 PM
Double buffering means different things in different contexts. The STM32 has a two buffer scheme which allows two distinct buffers to be used, it also has a method of using a singular buffer, and interrupting half way through. This method allows you to use the HT/TC interrupts to create a ping-pong buffer, you can access the first half while the second half is filled, and the data won't change underneath you, provided the FFT can operate in the time it takes to fill the second half the math will be correct. In the ping-pong mode you'd make the buffer twice as large, ie 256 samples, so that each half would hold your normal 128 sample payload.
I would tend to use the ping-pong method, even if I was just memcpy'ing the content to a static snap-shot buffer, as it would be significantly more immune to interrupt latency, and rapid ADC acquisition.