cancel
Showing results for 
Search instead for 
Did you mean: 

fast consecutive ADC Sampling for large chunk of data

shahaf321
Associate III

Hi Everyone, in my previous posts i pretty much beat the bush around this subject and i did get some good support

but i keep getting stuck with this issue.

im using STM32H743ZI2 Evaluation board set to 32Mhz

the ADC is 16 bits and running on "fast channel" so therefore should be 1.2Mhz according to AN5354

What i need to accomplish is to sample a large ammount of data (around 1MB, but i can settle for 100kb at this point)

at a speed of atleast 1MSPS

and store it reliably in internal RAM or some other external Memory device via DMA

my issues are:

* RAM is limited and even though im supposed to have 1MB to my disposal i'm only managing to build the code for an array of about 220k half words
uint16_t adc_buffer[220000]

* now even when im using this "small" buffer when using DMA with it im only filling the first 65535 values.
and the rest are set to 0, according to the DMA Documentation im limited to 65535 requests.

* also i forgot to mention, i tested my sampling rate and it doesnt seem to be going above 23ksps for some reason, im testing it via toggling a GPIO and testing with a 200MHZ scope

it makes no sense to me that a device that can sample with up to 3.6Mhz (at the right packages)

and even up to 10.8Mhz combining all of it's 3 ADCs doesnt have an interface to properly save a large amount of data.

is there any way to acheive that? i prefer not to add external RAM if  possible, as most of myu GPIOs are already in use and i cant make any changes in favor of the "FMC".

is there a way to chain multiple DMA Streams together so that when one stops the other continues "Without" losing any data in between?

 

Any help is greatly appreciated! 🙂

 

shahaf321_1-1707384861260.png

 

shahaf321_0-1707384421185.png

 

1 ACCEPTED SOLUTION

Accepted Solutions
LCE
Principal

TDK has mentioned the probably only solution "double buffer mode": check the ref manual again for DMA DBM "double buffer mode".
I'm not sure if that's already supported by CubeMX / HAL.

It basically works like this:

- the DMA has 2 address registers M0 & M1 for memory addresses for your buffers

- in DMA's half-complete ISR you can set a new address into the currently non-active address register

- with smart buffer handling you can fill buffer by buffer without any copying

View solution in original post

4 REPLIES 4
TDK
Guru

> * RAM is limited and even though im supposed to have 1MB to my disposal i'm only managing to build the code for an array of about 220k half words

You have slightly more than 1 MB available, but it's split among different non-contiguous memories. Because of this, you can't have a single buffer of 1 MB.

TDK_0-1707399824143.png

External memory can be added if you need more.

> * now even when im using this "small" buffer when using DMA with it im only filling the first 65535 values.
and the rest are set to 0, according to the DMA Documentation im limited to 65535 requests.

If you need more than 65535 values, handle the half- and full-transfer complete callbacks and transfer them to the larger buffer.

You can also use double buffer mode and change the memory addresses as things fill up.

> * also i forgot to mention, i tested my sampling rate and it doesnt seem to be going above 23ksps for some reason, im testing it via toggling a GPIO and testing with a 200MHZ scope

Probably your testing method is insufficient.

Use a buffer of 50000 values, toggle a pin in the transfer complete callback. Should get a 12 Hz square wave output (for 1.2 Msps).

 

If you feel a post has answered your question, please click "Accept as Solution".

Hi thank you for clearing things up.

i didn't really find anything about "double buffer mode" but it sounds like that would be the solution for my case

also i just now realized that i wasn't able to use the ADC at it's full sampling speed because of the "sampling time" parameter which was set to around 800 (followed an example online)

i changed  it to 1.5 cycles now and now i am sampling at 2MSPS, which is also kind of odd considering i was supposed to be limited to 1.2MSPS?

maybe i looked into the wrong documentation.

regarding DMA, I'm not sure that switching DMA Stream mid sampling would solve my problem because i could lost some samples in the process right?, I'm looking into a solution using MDMA but again cant find any examples for my board.

Thanks! 🙂

 

 

LCE
Principal

TDK has mentioned the probably only solution "double buffer mode": check the ref manual again for DMA DBM "double buffer mode".
I'm not sure if that's already supported by CubeMX / HAL.

It basically works like this:

- the DMA has 2 address registers M0 & M1 for memory addresses for your buffers

- in DMA's half-complete ISR you can set a new address into the currently non-active address register

- with smart buffer handling you can fill buffer by buffer without any copying

> i changed  it to 1.5 cycles now and now i am sampling at 2MSPS, which is also kind of odd considering i was supposed to be limited to 1.2MSPS?

To achieve the stated accuracy in the datasheet, you should limit sampling to the rates given in that table. Nothing is preventing you from converting faster, but the accuracy will be limited. At that point you're better off using a lower resolution.

 

You don't lose data in double buffer mode. LCE provided a good overview.

If you feel a post has answered your question, please click "Accept as Solution".