Skip to main content
Visitor II
December 3, 2023
Solved

DMA RX complete interrupt sometimes not called in STM32L4

  • December 3, 2023
  • 1 reply
  • 1767 views

Hi everyone, I've done these steps before on STM32F0, STM32F1 and STM32F4 microcontrollers to detect when a circular DMA buffer for UART "wraps" (The counter finishes with the array and starts from the beginning again) with complete success

  1. Activated UART, then in STM32Cube activated DMA for RX, then set it to circular mode
  2. In the program, before main() I have called
         __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
  3. Then in the DMA interrupt handler in the stm32xx_it.c I have added this code to the interrupt handler of the relevant DMA channel (Here, DMA 1 and channel 5):

        void DMA1_Channel5_IRQHandler(void)
        {
          /* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
          if(DMA1_Channel5->CCR & DMA_IT_TC)
          {
            extern volatile uint8_t wrap1;
            wrap1++;
          }
          /* USER CODE END DMA1_Channel5_IRQn 0 */
          HAL_DMA_IRQHandler(&hdma_usart1_rx);
          /* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
          /* USER CODE END DMA1_Channel5_IRQn 1 */
    }


    So the "wrap1" variable would increment every time the circular buffer for the DMA wraps.

 

However when I implemented the steps above on a STM32L431RCT microcontroller, I've noticed that the interrupt only works 9 out of 10 times. This means that there are times that the buffer will wrap, but my variable wouldn't increment by one. This is very strange as the exact same code worked flawlessly on other families of STM32 microcontrollers that I had used such as STM32F0. I was not able to find the issue by looking at the reference manual and the HAL code, can anyone help me with this?

Thanks a lot

    This topic has been closed for replies.
    Best answer by TDK

    If DMA1_Channel5_IRQHandler is called for some other reason, say due to the HT flag or a flag other than TC, you have a race condition. If TC gets set after you check it, but before it's processed within HAL_DMA_IRQHandler, it will be cleared without your code being called. If you're going to use HAL, put the check in the RX complete callback instead.

    The RXNE interrupt shouldn't be enabled if you're handling it with DMA.

     

    1 reply

    TDKAnswer
    Super User
    December 3, 2023

    If DMA1_Channel5_IRQHandler is called for some other reason, say due to the HT flag or a flag other than TC, you have a race condition. If TC gets set after you check it, but before it's processed within HAL_DMA_IRQHandler, it will be cleared without your code being called. If you're going to use HAL, put the check in the RX complete callback instead.

    The RXNE interrupt shouldn't be enabled if you're handling it with DMA.