How to perform continuous sending and reading with DMA ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 4:29 AM - edited ‎2023-12-05 4:44 AM
Hello,
I looked at an example of DMA on CubeMX and I got this code :
/* Infinite loop */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (transferErrorDetected == 1)
{
/* Toggle LED4 with a period of 200 ms */
BSP_LED_Toggle(LED4);
HAL_Delay(200);
}
if (transferCompleteDetected == 1)
{
/* Turn LED4 on*/
BSP_LED_On(LED4);
transferCompleteDetected = 0;
}
}
/* USER CODE END 3 */
}
It only works once, how to repeat this sending infinitely ?
/* Configure the source, destination and buffer size DMA fields and Start DMA Channel/Stream transfer */
/* Enable All the DMA interrupts */
if (HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1, (uint32_t)&aSRC_Const_Buffer, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
{
/* Transfer Error */
Error_Handler();
}
Do I have to stop the DMA, recover the data and restart the DMA each time ?
Thank you for your answer
- Labels:
-
DMA
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 4:51 AM
what type of DMA that you use?
Circular?
with address memory increasing?
and You had DMA Callback function too?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 5:09 AM - edited ‎2023-12-05 5:18 AM
Hi,
This is an example that I took from my STM32L552E-EV evaluation board. It's called DMA. No It's not circular after CubeIDE
After the readme file, it's only a transfer from Flash memory to RAM memory (after me).
Here is the address of the source and destination memory
static const uint32_t aSRC_Const_Buffer[BUFFER_SIZE] =
{
0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10,
0x11121314, 0x15161718, 0x191A1B1C, 0x1D1E1F20,
0x21222324, 0x25262728, 0x292A2B2C, 0x2D2E2F30,
0x31323334, 0x35363738, 0x393A3B3C, 0x3D3E3F40,
0x41424344, 0x45464748, 0x494A4B4C, 0x4D4E4F50,
0x51525354, 0x55565758, 0x595A5B5C, 0x5D5E5F60,
0x61626364, 0x65666768, 0x696A6B6C, 0x6D6E6F70,
0x71727374, 0x75767778, 0x797A7B7C, 0x7D7E7F80
};
static uint32_t aDST_Buffer[BUFFER_SIZE];
BUFFER_SIZE=32
Yes I the example has a DMA_callback function :
/* Select Callbacks functions called after Transfer complete and Transfer error */
HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1, HAL_DMA_XFER_CPLT_CB_ID, TransferComplete);
HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1, HAL_DMA_XFER_ERROR_CB_ID, TransferError);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 5:51 AM
if it's no Circular so it's going to stop at the end of address and you have to restart it again as usual.
when you use ADC or SPI with DMA and you set memory with many byte, it's going to stop at the end of address.
you should try with circular mode.
But I'm really unsure what feature do you want. So it may useless for you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 5:53 AM
You can either set it to circular mode so it transfers continuously, or you can restart the transfer after the transfer is complete within the TransferComplete callback.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 6:09 AM
Thank you for this information, to begin with, I would like to understand how DMA works using this example provided.
In fact when I say at the start of my topic, "how to repeat this sending infinitely ?" of course if I use with ADC, I'll have values ​​continually (this sounds a bit like what I'm saying sending the values ​​continuously also requires retrieving the values ​​continuously, right ?).
I know the circular mode, and I have already implemented it with an SAI (by looping the TX with the RX) and it works. But when I enter real values ​​I don't get anything back, that's why I use this DMA example.
With this example I am trying to understand the DMA mechanism. So my question is: How to send and retrieve continuously from this example which only works once ? With the code please no pharses, this will help me move forward.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 7:21 AM
@TDK wrote:or you can restart the transfer after the transfer is complete within the TransferComplete callback.
In the Main I have this Function :
/* USER CODE BEGIN 4 */
/**
* @brief DMA conversion complete callback
* @note This function is executed when the transfer complete interrupt
* is generated
* @retval None
*/
static void TransferComplete(DMA_HandleTypeDef *hdma_memtomem_dma1_channel1)
{
transferCompleteDetected = 1;
}
I think this function is call when the transfer is complete. How to restart the transfer since this function I only enter once. Or probably I'm wrong about the function "TransferComplete callback".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 10:36 AM
Is it possible that there is some error while DMA transferring so it go to Error_Handler and it won't do anything like as it stopped.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 10:47 AM
No, impossible because the LED4 is on
/* Infinite loop */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (transferErrorDetected == 1)
{
/* Toggle LED4 with a period of 200 ms */
BSP_LED_Toggle(LED4);
HAL_Delay(200);
}
if (transferCompleteDetected == 1)
{
/* Turn LED4 on*/
BSP_LED_On(LED4);
transferCompleteDetected = 0;
}
}
/* USER CODE END 3 */
}
and I never get into this error loop
/**
* @brief DMA conversion error callback
* @note This function is executed when the transfer error interrupt
* is generated during DMA transfer
* @retval None
*/
static void TransferError(DMA_HandleTypeDef *hdma_memtomem_dma1_channel1)
{
transferErrorDetected = 1;
}
After the while loop previously, if there is an error then LED 4 flashes per period of 200 ms but it's not the case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-12-05 7:35 PM
It can possible because the LED was turn ON at first transfer completely and if the error was occurred at second transfer at HAL_DMA_Start_IT so it go to Error Handler without turn OFF LED.
You can check it by debug and you should also add turn OFF LED before Error Handler.
