cancel
Showing results for 
Search instead for 
Did you mean: 

UART in DMA cause MCU crash

rhaja.1
Associate II

hi every one

i am trying to receive data with UART in DMA and Normal mode, but after about 10 times that I receive data correctly suddenly MCU stop working

I checked every thing but I don't know what's wrong :sad_but_relieved_face:

this is my Uart and DMA configuration :

void BSP_USART1_Init(uint32_t BaudRate)

{

   __HAL_RCC_USART1_CLK_ENABLE();

   uart1Handle.Instance               =      USART1;

   uart1Handle.Init.BaudRate          =      BaudRate;

   uart1Handle.Init.WordLength        =      USART1_WORD_LENGTH;

   uart1Handle.Init.StopBits          =      USART1_STOP_BITS;

   uart1Handle.Init.Parity            =      USART1_PARITY;

   uart1Handle.Init.Mode              =      USART1_MODE;

   uart1Handle.Init.HwFlowCtl         =      USART1_HWCONTROL;

   uart1Handle.Init.OverSampling      =      USART1_OVERSAMPLING;

   uart1Handle.Init.OneBitSampling    =      UART_ONE_BIT_SAMPLE_DISABLE;

   uart1Handle.Init.ClockPrescaler    =      UART_PRESCALER_DIV4;

   uart1Handle.AdvancedInit.AdvFeatureInit =  UART_ADVFEATURE_NO_INIT;

   uart1Handle.gState = HAL_UART_STATE_RESET;

   /* USART configuration */

   if(HAL_UART_Init(&uart1Handle) != HAL_OK)

   {

       Error_Handler();

   }

   USART1_DMA_Init(&uart1Handle);

   /* DMA1_Stream5_IRQn interrupt configuration */

   HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);

   HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);

   /* DMA1_Stream4_IRQn interrupt configuration */

   HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);

   HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);

}

/* *

 ************************* USART1 DMA initialize ******************************

 * */

void USART1_DMA_Init(UART_HandleTypeDef *huart)

{

   /* Deinitialize the Stream for new transfer */

   HAL_DMA_DeInit(&hdmaUart1Tx);

   /* Enable the DMA clock */

   __HAL_RCC_DMA1_CLK_ENABLE();

   hdmaUart1Tx.Instance                = DMA1_Stream5;

   /* Configure the hdma_uartTx handle parameters */  

   hdmaUart1Tx.Init.Request            = DMA_REQUEST_USART1_TX;

   hdmaUart1Tx.Init.Direction          = DMA_MEMORY_TO_PERIPH;

   hdmaUart1Tx.Init.PeriphInc          = DMA_PINC_DISABLE;

   hdmaUart1Tx.Init.MemInc             = DMA_MINC_ENABLE;

   hdmaUart1Tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

   hdmaUart1Tx.Init.MemDataAlignment   = DMA_MDATAALIGN_BYTE;

   hdmaUart1Tx.Init.Mode               = DMA_NORMAL;

   hdmaUart1Tx.Init.Priority           = DMA_PRIORITY_MEDIUM;

   hdmaUart1Tx.Init.FIFOMode           = DMA_FIFOMODE_DISABLE;        

   hdmaUart1Tx.Init.FIFOThreshold      = DMA_FIFO_THRESHOLD_FULL;

   hdmaUart1Tx.Init.MemBurst           = DMA_MBURST_SINGLE;

   hdmaUart1Tx.Init.PeriphBurst        = DMA_PBURST_SINGLE;

   /* Configure the DMA Stream */

   if(HAL_DMA_Init(&hdmaUart1Tx) != HAL_OK)

   {

     Error_Handler();

   }

   /* Associate the DMA handle */

   __HAL_LINKDMA(huart, hdmatx, hdmaUart1Tx);

   /* Deinitialize the Stream for new transfer */

   HAL_DMA_DeInit(&hdmaUart1Rx);

   hdmaUart1Rx.Instance                = DMA1_Stream4;

   /* Configure the hdma_uartRx handle parameters */  

   hdmaUart1Rx.Init.Request            = DMA_REQUEST_USART1_RX;

   hdmaUart1Rx.Init.Direction          = DMA_PERIPH_TO_MEMORY;

   hdmaUart1Rx.Init.PeriphInc          = DMA_PINC_DISABLE;

   hdmaUart1Rx.Init.MemInc             = DMA_MINC_ENABLE;

   hdmaUart1Rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

   hdmaUart1Rx.Init.MemDataAlignment   = DMA_MDATAALIGN_BYTE;

   hdmaUart1Rx.Init.Mode               = DMA_NORMAL;

   hdmaUart1Rx.Init.Priority           = DMA_PRIORITY_MEDIUM;

   hdmaUart1Rx.Init.FIFOMode           = DMA_FIFOMODE_DISABLE;        

   hdmaUart1Rx.Init.FIFOThreshold      = DMA_FIFO_THRESHOLD_FULL;

   hdmaUart1Rx.Init.MemBurst           = DMA_MBURST_SINGLE;

   hdmaUart1Rx.Init.PeriphBurst        = DMA_PBURST_SINGLE;

   /* Configure the DMA Stream */

   if(HAL_DMA_Init(&hdmaUart1Rx) != HAL_OK)

   {

     Error_Handler();

   }

   /* Associate the DMA handle */

   __HAL_LINKDMA(huart, hdmarx, hdmaUart1Rx);

}

/* *

 *************************** DMA_IRQHandler ************************************

 * */

void DMA1_Stream4_IRQHandler(void)

{

   HAL_DMA_IRQHandler(uart1Handle.hdmarx);

}

void main()

{

UART_ReadBuffer(&uart1Handle, usart1_periph_buff_rx, USART1_PRIPH_BUFF_SIZE);

While(1)

{

if(uart1Handle.RxState == HAL_UART_STATE_READY)

    {

     memcpy(usart1_buff_rx, usart1_periph_buff_rx, USART1_PRIPH_BUFF_SIZE);

       UART_ReadBuffer(&uart1Handle, usart1_periph_buff_rx, USART1_PRIPH_BUFF_SIZE);

   

        printf("RX:");

       for(int i=0; i<USART1_PRIPH_BUFF_SIZE; i++)

            printf("%x ", usart1_buff_rx[i]);

       printf("\r\n");

}

}

9 REPLIES 9
Uwe Bonnes
Principal II

"Crash" is quite genuine. Be more specific! Whta does your error handler tell?

Ozone
Lead

The exact MCU derivate and the DMA buffer addresses might be of interest, too.

Stop in debugger and see where it ended up. Check peripheral settings in this state also.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rhaja.1
Associate II

Hi every one

Thanks for your answers

by more test and debug I realize that my SAI peripheral that is set and uses DMA1 too , causes this events .

BUT I DO NOT KNOW WHY ?

I use SAI1 in DMA mode and Rx is Circular and Double buffer but Tx is just Circular.

when I receive in UART about 10 times while SAI is working , UART Rx DMA stop suddenly but DMA interrupt routine call periodically

Is there any issue in working two peripheral by DMA1 ??!!

I use these streams :

hdmaUart1Tx.Instance                = DMA1_Stream5;

hdmaUart1Rx.Instance                = DMA1_Stream4;

hdma_sai1_tx.Instance = DMA1_Stream1;

hdma_sai1_rx.Instance = DMA1_Stream0;

Did you check the fault reason in the SCB registers ?

Assuming "crash" means hardfault, or another core fault exception.

How can I check the fault reason in the SCB registers ?

I don't have Hardfault or any other core exception, As I mentioned above when I receive in UART about 10 times while SAI is working , UART Rx DMA stop suddenly but DMA interrupt routine call periodically

Is there any issue in working two peripheral by DMA1 ??!!

>>Is there any issue in working two peripheral by DMA1 ??!!

STM32H7 ?

Not that I'm aware of, multiple streams can be active concurrently

Need to make sure you use the correct memory regions that the DMA/Bus Matrix can address

Need to manage cache coherency

Be very careful invalidating memory, and the alignment there

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

> How can I check the fault reason in the SCB registers ?

With a debugger or an appropriate hardfault-handler that outputs them. If you have no hardfault, this is irrelevent.

As said your "crash" wording is ambiguous.

> As I mentioned above when I receive in UART about 10 times while SAI is working , UART Rx DMA stop suddenly but DMA interrupt routine call periodically

Perhaps some UART Rx error condition. Like a bus contention caused by other DMA, and an induced UART Rx overflow ?

SF??r
Associate III

Have you seen the newest erreta entry? Only for V rev. with UART and DMA in combination!