Skip to main content
Explorer
December 5, 2023
Question

How to perform continuous sending and reading with DMA ?

  • December 5, 2023
  • 3 replies
  • 4232 views

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

    This topic has been closed for replies.

    3 replies

    Graduate II
    December 5, 2023

    what type of DMA that you use?
    Circular?

    with address memory increasing?

    and You had DMA Callback function too?

    DYann.1Author
    Explorer
    December 5, 2023

    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

    DYann1_0-1701781230975.png

    After the readme file, it's only a transfer from Flash memory to RAM memory (after me).

    DYann1_1-1701781374573.png

    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);

     

    Graduate II
    December 5, 2023

    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.

    DYann.1Author
    Explorer
    December 5, 2023

    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.

     

     

     

    Super User
    December 5, 2023

    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.

     

    DYann.1Author
    Explorer
    December 5, 2023

    @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".

    Graduate II
    December 5, 2023

    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.