2024-02-08 01:43 AM - edited 2024-02-08 02:35 AM
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! :)
Solved! Go to Solution.
2024-02-12 03:42 AM
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
2024-02-08 05:45 AM - edited 2024-02-08 05:47 AM
> * 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.
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).
2024-02-12 01:10 AM
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! :)
2024-02-12 03:42 AM
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
2024-02-12 05:29 AM
> 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.