Skip to main content
Graduate II
January 26, 2024
Question

DMA is not working with SAI

  • January 26, 2024
  • 6 replies
  • 3491 views

hi,

I am using stm32h743zit6.

I am having problems with DMA in my code. First i have a code that is not mine that takes data from a peripheral (a microphone) using SAI and then via DMA inserts this data into an array (a buffer). To do this memory is modified to do this.

I am doing the same configuration in other code to try to do this, in the original one the data refreshes automatically and in my own code, it just takes the first read.

 

ALIGN_32BYTES (int32_t __attribute__((section (".dmapart"))) dmaArray[data]);
HAL_SAI_Receive_DMA(&hsai_BlockA3,(uint8_t)* dmaArray, (uint16_t) data);

 

All the GPIO is ok because i just copied the same code. SCB_EnableIcache() is written in the main..., I don't know why is not  updating the data in my array and is working well in the other code. Anyone have any idea why is not updating in my code?

If any of you need more info about the code tell me please. 

 

Thank you so much, i am desperating.

    This topic has been closed for replies.

    6 replies

    Super User
    January 26, 2024

    Hi,

    DMA -> in circular mode , for continuous data transfer. Did you set it to circular ?

    rubenlesAuthor
    Graduate II
    January 26, 2024

    Yes, it is configured as circular. @AScha.3 

    rubenles_1-1706261074520.png

     

     

    Technical Moderator
    January 26, 2024

    Hello @rubenles ,

    Maybe the issue is related to two things: memory layout on STM32H7 and internal data cache (D-Cache) of the Cortex-M7 core.

    Fore that, I recommend you to take a look to this FAQ: DMA is not working on STM32H7 devices .

    Thank you.

    Kaouthar

     

    rubenlesAuthor
    Graduate II
    January 29, 2024

    Hello @KDJEM.1 ,

    I tried to modify these memories, first in the .Id file:

     

    /* DMA Array data section */
     . = ALIGN(4);
     .dmaArray :
     {
     	_sdmaArray = .;
     	__dmaArray_start__ = _sdmaArray;
     	*(DMA)
     	. = ALIGN(4);
     KEEP(*(.dmaArray)) 	
     
     _edmaArray = .;
     __dmaArray_end__ = _edmaArray;
     } >RAM_D2 AT> FLASH
    MEMORY
    {
     DTCMRAM	(xrw)	: ORIGIN = 0x20000000,	LENGTH = 128K
     ITCMRAM	(xrw)	: ORIGIN = 0x00000000,	LENGTH = 64K
     RAM_D1_P	(xrw)	: ORIGIN = 0x24000000,	LENGTH = 4K
     RAM_D1 (xrw)	: ORIGIN = 0x24001000,	LENGTH = 508K
     RAM_D2	(xrw)	: ORIGIN = 0x30000000,	LENGTH = 288K
     RAM_D3	(xrw)	: ORIGIN = 0x38000000,	LENGTH = 64K
     FLASH	 (rx)	: ORIGIN = 0x08000000,	LENGTH = 1920K
     FLASH_P (xrw)	: ORIGIN = 0x081E0000,	LENGTH = 128K
     RAM_BCK	(w)		: ORIGIN = 0x38800000, LENGTH = 4K
    }
     ._user_heap_stack :
     {
     . = ALIGN(8);
     PROVIDE ( end = . );
     PROVIDE ( _end = . );
     . = . + _Min_Heap_Size;
     . = . + _Min_Stack_Size;
     . = ALIGN(8);
     } >RAM_D1 AT> FLASH

     

    After this, my array just save the first value and then stops, i need it refreshing all the time. I don't know where can i have the problem...

     

    Thank you so much for your time and help!

    Technical Moderator
    January 29, 2024

    Hi @rubenles ,

    Could you please check the initial stack definition?

    In some linkerscripts, the initial stack is defined separately. So you either need to update it with the section, or define it inside the section like:

    ._user_heap_stack : 
    { 
     . = ALIGN(8); 
     PROVIDE ( end = . ); 
     PROVIDE ( _end = . );
     . = . + _Min_Heap_Size;
     . = . + _Min_Stack_Size; 
     _estack = .; /* <<<< line added */
     . = ALIGN(8); 
    } >RAM_D1

    and remove the original _estack definition.

    Please let me know if the issue is solved or not.

    Thank you.

    Kaouthar

    rubenlesAuthor
    Graduate II
    January 29, 2024

    I tried it and still not working :frowning_face: Any possible modification y project settings or something like this?

     

    Thank you so much @KDJEM.1 

    Technical Moderator
    January 29, 2024

    Hi @rubenles ,

    Thank you for updating post.

    I advise you to take a look at the SAI examples in STM32CubeH7 and refer to them to check the SAI and the DMA configuration settings.

    • \STM32Cube_FW_H7_V1.11.1\Projects\STM32H743I-EVAL\Examples\SAI\SAI_AudioPlay
    • \STM32Cube_FW_H7_V1.11.1\Projects\STM32H743I-EVAL\Examples\SAI\SAI_AudioPlayback

     

    I hope this help you!

    Thank you.

    Kaouthar

    rubenlesAuthor
    Graduate II
    January 29, 2024

    Sorry for asking it but, where can i find these examples?? I am looking for it and i didn't find anything

     

    Thanks. @KDJEM.1 

    Technical Moderator
    January 29, 2024

    Hi @rubenles ,

    You can download the latest version of STM32CubeH7 package from this link: STM32CubeH7 - STM32Cube MCU Package for STM32H7 series (HAL, Low-Layer APIs and CMSIS, USB, TCP/IP, File system, RTOS, Graphic - and examples running on ST boards) - STMicroelectronics

     

    KDJEM1_1-1706534438164.png

     

    Then you can find these examples under these paths:

    • ....\STM32Cube_FW_H7_V1.11.1\Projects\STM32H743I-EVAL\Examples\SAI\SAI_AudioPlay
    • ....\STM32Cube_FW_H7_V1.11.1\Projects\STM32H743I-EVAL\Examples\SAI\SAI_AudioPlayback

    Also, the SAI_AudioPlay example is available in this link STM32CubeH7/Projects/STM32H743I-EVAL/Examples/SAI at master · STMicroelectronics/STM32CubeH7 · GitHub

    Thank you.

    Kaouthar

    rubenlesAuthor
    Graduate II
    January 30, 2024

    Found, i will answer you if i have any success, thank you so much @KDJEM.1 

    rubenlesAuthor
    Graduate II
    January 31, 2024

    The solution is to fix a line in the hal libraries because the code was deleting the configuration on CR  about double buffer. 

    Technical Moderator
    January 31, 2024

    Hello @rubenles ,

    Thank you for updating post and glad to know that you find the solution.

    Could you please give more detail about the solution this may help the community members who facing the same issue:

    Which line in HAL did you fix? And how?

    Thank you.

    Kaouthar

    rubenlesAuthor
    Graduate II
    February 1, 2024

    in stm32h7xx_hal_dma.c

    Line 1800 aprox

     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
     {
     /* Clear all interrupt flags at correct offset within the register */
     regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
    
     /* Clear DBM bit */
     //((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);<-----

    Last line delete CR using double buffer