cancel
Showing results for 
Search instead for 
Did you mean: 

DMA latency by fast ADC acquisition.

eg7963
Associate III
Posted on May 10, 2016 at 14:57

Hi there,

Im currently running into a problem with a stm32F334C8Tx controller.

The following data represent my program configuration.

_____________________________________________________

Data:

--------

System

- Clock 72MHz

ADC:

- 12Bits

- Sync Clock mode PRESCALE 1 ( 72MHz)

- 4 Regular Channels  ( fast channels  ADC1_AN1 -> ADC2_AN4), AN2 has an offset of 2050, no offset for the others

- No injected channels ( disabled)

- Sampling time 1.5cycles

- Acquisition Time 12.5 cycles

- Total Sampling rate 1.28MS/s/channel

- Scan mode enabled

- Continuous conversion enabled

- Overrun Data overwritten

- DMA continuous Request enabled

- No Interrupt enabled

DMA used with ADC:

- Channel 1

- Circular Mode

- Priority: high  (higher as other DMA channels)

- Interrupt Enabled ( Error, Half Transfer and Tranfer Complete)

- Buffer Size : uint16_t [1030]

- In Parralel:

- UART3 RX and TX are operating ( on a ''On Demand basis''), using DMA channels 2 and 3 ( lower priority)

- The FPU is used during the DMA Interrupt to calculate RMS values of the Acquired ones.

The Conversion is started once at the start of the device, and keeps acquiring data continuously.

The Buffer is use in a Ping-Pong way, data being used at each interrupt of the DMA Channel ( first

516 uints for HT interrupt , last 516 uints for the TC interrupt and so on)

The ADC is used to measure several signals based on a System running at up to 200kHz.

Our friend Niyquist states that i thus need at least 400KHz as min sampling frequency,

which would be met with the 1.28MS/s/Channel sampling rate.

_____________________________________________________

Problem:

--------

In normal Case , the data Structure in the Buffer should look like the following

with N being a natural integer ( N is function of my buffer size)

BUF[N + 0] = Val[Channel1_N]

BUF[N + 1] = Val[Channel2_N]

BUF[N + 2] = Val[Channel3_N]

BUF[N + 3] = Val[Channel4_N]

However there seem to be troubles in the data transfers from the ADC to DMA buffer during the operations,

as in some cases, there appears to be an offset introduced intto my buffer, being such that the buffer could look like the 3 following cases:

BUF[N + 0] = Val[Channel2_N] or Val[Channel3_N] or Val[Channel4_N]

BUF[N + 1] = Val[Channel3_N] or Val[Channel4_N] or Val[Channel1_N]

BUF[N + 2] = Val[Channel4_N] or Val[Channel1_N] or Val[Channel2_N]

BUF[N + 3] = Val[Channel1_N] or Val[Channel2_N] or Val[Channel_3N]

The most easy explanation would be that the DMA being busy , another conversion occurs in the ADC before the data has been moved to the memory location,

offseting the full future set of acquired datas from 1 or several steps into the buffer, and making the acquisition useless.

I suspect a timing problem too, maybe caused by the Round Robin priority scheme described in the AN4031- DMA controller description for access to the SRAM, though that

application note doesn't seem to apply directly to the STM32F3 but rather to F2 and F4 series.

As i'm not yet that deep into the Cortex M4 architecture, I was wondering if anybody has enough knowledge to enlight me on what could be happening into my processor, and if there is a work around or a fix to that problem.

All help is welcome.

Thanks

Eric

#stm32-dma-latency-adc
2 REPLIES 2
Posted on May 10, 2016 at 17:36

1030 is not divisible by 4, you mean 1032?

Does the problem persist if you drop the sample rate?

Not using the F3, does the DMA support a FIFO?

Can you use dual mode?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
eg7963
Associate III
Posted on May 11, 2016 at 10:40

Hi clive1,

Thanks for your reply.

    ''1030 is not divisible by 4, you mean 1032?''

    

Yeah sorry, that's only a careless mistake. The Buffer is actualy 1032 bytes wide (258 values/Channel)

which at the given sampling rate gives a DMA interrupt more or less every 100ms.

    ''Does the problem persist if you drop the sample rate?''

    

I tried that one thing yesterday and actually the sampling rate reduction reduces the problem.

Bringing the sampling time to 7.5cycles shows much less errors than shorter sampling times.

Dividing the ADC clock by 2 (using a prescaler of 2) seems to solve the problem

However that reduces the overall sampling rate, which cannot be limitless reduced.

    ''Not using the F3, does the DMA support a FIFO?''

    

The DMA on that controller doesn't support FIFO. This could maybe help indeed.

    

    ''Can you use dual mode?''

    

I might not have been totally precise in that way. I actually also use the second ADC (ADC2) to sample channels that only require very low samples rate (<10KHz)

The Second ADC has the following configuration, and is started once consecutivelly to the other:

ADC2:

- 12Bits

- Sync Clock mode PRESCALE 1 ( 72MHz) ( this clock CAN ONLY BE the same as the clock source for ADC1)

- 4 Regular Channels  ( fast channels  ADC1_AN1 -> ADC2_AN3, ADC2_AN12) no offset.

- No injected channels ( disabled)

- Sampling time 181.5cycles

- Acquisition Time 12.5 cycles

- Total Sampling rate 92kS/s/channel

- Scan mode enabled

- Continuous conversion enabled

- Overrun Data overwritten

- DMA continuous Request enabled

- No Interrupt enabled

DMA used with ADC2:

- Channel 4  

- Circular Mode

- Priority: medium  (smaller than DMA_ADC1 but higher than DMA_UART)

- Interrupt Disabled ( the buffer results are read once during the interrupt of ADC1_DMA-> HT and TC)

- Buffer Size : uint16_t [4]

Tha device only has 2 ADCs. Currently, both ADCs are configured in independant mode, which apparently isn't really a case covered by the datasheet, as several ADCs

usually have to be used inDUAL/Multimode.

The mode however doesn't seem to affect the acquisition on ADC1, as i tried disabling the ADC2, in order to test the ADC1 alone, and had no better success here.

Only reducing sampling rate brought some result.

I still believe that at some point the problem comes from the arbitration on the BusMatrix Level, but dont know if there is anythingto do there.

Using the interleaved mode would then maybe bring a solution, but i would have to stop the sampling at some point to measure my slow channels

or eventually use the injected channels. No idea yet how that will work out with the DMA.

Thanks anyway for asking

Eric