STM32H747 DMA Linked List (or Double Buffering) and ADC Interleaved
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-31 7:50 AM
Hi all,
I'm implementing a DAQ (data acquisition chain), using STM32H747Xi Discovery board.
What I need to do is sample as fast as possible 1 adc channel and do some light processing on the data. I need to understand how to configure the system to get the best results.
So far here's my guess:
- ADC1 & 2 in interleaved mode (ADC 1 as master)
- ADCs in continuous mode
- Transfer data to Memory using DMA in Linked List (or Double Buffering)
What I would like to do is set up 2 buffers and having the M7 process the 1st while the 2nd is beeing filled by the DMA. And viceversa.
I think that using linked list is the right way to go, because it also allows to target 2 different memory banks to avoid collision.
I started off with this example from stm32cubeh7 repo, which shows ADC interleaved functioning and uses circular buffering. I also found this one on MDMA linked lists.
Now I need to understand how to "merge" them.
Here are my questions:
- How's the flow between sw, adc and dma? Should the ADC ask the DMA to start a transaction or the 2 should be started independently by sw?
- from stm32h7xx_hal_adc.h "In continuous mode, DMA must be configured in circular mode. Otherwise an overrun will be triggered when DMA buffer maximum pointer is reached." But I guess it is possible to use it in linked mode as well right?
- What do you think of the LinkedList approach as opposed to the circular buffer with HalfCompletion and Completion callback?
Any help/example on this topic would be of much help.
- Labels:
-
ADC
-
DMA
-
STM32H7 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-09-04 9:08 AM
Memory-to-memory is like Tx+Rx. Do cache cleaning for source memory like on Tx buffers and invalidation for destination memory like on Rx buffers. The only exception is DTCM, which is never cached and can be accessed by MDMA through the dedicated AHBS bus.
As Georgy said, you can always disable (actually just do not enable it) D-cache for debugging purposes. I-cache can still be left enabled.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-09-10 2:58 AM
@Piranha​ Thanks for the guidance.
Here's a diagram of what I implemented so far, hope that is clear.
(edit: spotted a typo, the 2° m2m callback invalidates the 2nd half)
At the moment I can see that the m2m callback is never called.
Here's my code for it:
static void m2mCallback(DMA_HandleTypeDef *_hdma);
HAL_DMA_RegisterCallback(&hdma_memtomem_dma2_stream0, HAL_DMA_XFER_CPLT_CB_ID, m2mCallback);
/* Track mem2mem complete */
void m2mCallback(DMA_HandleTypeDef *_hdma)
{
if(status == SECOND_HALF_COPY_STARTED)
{
/*Invalidate 2nd half of Rx Buffer (copied ADC values)*/
SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCDualConvertedValuesCopied[ADCCONVERTEDVALUES_BUFFER_SIZE/2], 4*ADCCONVERTEDVALUES_BUFFER_SIZE/2);
status = SECOND_HALF_COPY_COMPLETED;
BSP_LED_Off(LED_ORANGE);
} else if (status == FIRST_HALF_COPY_STARTED) {
/*Invalidate 1st half of Rx Buffer (copied ADC values)*/
SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCDualConvertedValuesCopied, 4*ADCCONVERTEDVALUES_BUFFER_SIZE/2);
status = FIRST_HALF_COPY_COMPLETED;
BSP_LED_On(LED_ORANGE);
}
}
HAL_DMA_RegisterCallback(&hdma_memtomem_dma2_stream0, HAL_DMA_XFER_CPLT_CB_ID, m2mCallback);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-09-10 7:20 AM
Make sure that MEM2MEM's "dma 2 stream 0" global interrupt is enabled. In my case it was "dma 1 stream 5 global interrupt":

- « Previous
-
- 1
- 2
- Next »