cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo STM32L432KC ADC + DMA circular buffer, slower than expected?

JBeal.1
Associate II

I want to take readings from one ADC channel continually and use DMA to store them in a circular buffer. I do have working code which does this, see link below. However, the sampling happens more slowly than I expected.

My question is about the rate at which samples are stored in memory. The L432KC ADC is spec'd for 5 Msps. According to the "Clock Configuration" tab on my .ioc file in STM32CubeIDE, I have a 32 MHz clock going to the ADC, and my ADC (1 channel only) is set for a 6.5 Cycle sampling time (4.923 Msps raw sample rate), and the ADC is set for 4x oversampling. I calculate that should be 32 MHz / (6.5 x 4) = 1.231 Msps effective sample rate, if there was no overhead needed by the DMA engine per cycle.

So, how much overhead is there? I have one DMA channel active. It is for ADC1, mode: Circular,  Data width: half word, Increment Address: Memory only.  In the code, I set a GPIO pin high in HAL_ADC_ConvHalfCpltCallback() and low at HAL_ADC_ConvCpltCallback(), and my buffer array is uint16_t adc_buffer[4000]  so if I was actually getting a 1.231 Msps sample rate, I would expect the GPIO output frequency to be (1.231 MHz / 4000) = 307.7 Hz, but in fact I measure 105.4 Hz so it is about 1/3 the expected rate. Is that reasonable? Does having USB active cause DMA bus wait states? I am using serial-over-USB for output but only a few bytes every minute, so I wouldn't think that affects much. I don't know what the CubeIDE may be doing in the background automatically but I'm not actively trying to debug anything. The measured rate is the same whether or not CubeIDE is running.

My code is shown at the link below, if anyone is interested. Thanks for any replies!

https://github.com/jbeale1/STM32-ADC-DMA-test1/blob/main/Core/Src/main.c

1 ACCEPTED SOLUTION

Accepted Solutions
RomainR.
ST Employee

Hello @JBeal.1 
Yes absolutely, the ADC of the STM32L4 is 12-bit successive approximation, it is therefore necessary to take into account in the equation of TConv = Sampling Time + fixed fADC Cycles.

This is explained in the RM0394 in chapter 16.4.12 Channel-wise programmable sampling time (SMPR1, SMPR2).

Regards,

Romain,

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

2 REPLIES 2
JBeal.1
Associate II

Ah, nevermind. Somehow I was imagining "sampling time" to be the entire ADC conversion time, but actually reading the datasheet I see that the total time is (sampling time + conversion time) and the latter is 12.5 cycles for 12 bit resolution, which is 0.39 usec at 32 MHz ADC clock, so total time per conversion in my case would be (6.5 + 12.5) * 1/32E6 => 0.594 usec or 1.684 Msps, even without oversampling, or 1.684 / 4 = 421 ksps with 4x oversampling which means the 4k buffer is filled at a 105.3 Hz rate so it all works out correctly.

RomainR.
ST Employee

Hello @JBeal.1 
Yes absolutely, the ADC of the STM32L4 is 12-bit successive approximation, it is therefore necessary to take into account in the equation of TConv = Sampling Time + fixed fADC Cycles.

This is explained in the RM0394 in chapter 16.4.12 Channel-wise programmable sampling time (SMPR1, SMPR2).

Regards,

Romain,

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.