cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 UART+DMA

ChrisH
Associate III
Posted on January 10, 2017 at 20:37

I have an RTOS app running with few tasks though I don't think it matters if you use OS or not anyway. Basically every now and then I get random errors like FE (framing error), ORE (overrun error), NF (noise flag set). There are two UARTS that have running DMA channels connected to both RXes in circular mode. I had a previous configuration that favoured one UART over the other giving it higher DMA priority. Correct me if I'm wrong, but could this potentially be an issue for the errors? 

10 REPLIES 10
Posted on January 10, 2017 at 21:09

Generally the DMA is orders of magnitude faster than USART rate, and it holds a whole character, so priority one vs the other is likely to be inconsequential. I'd focus on the signal itself.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal
Posted on January 10, 2017 at 21:21

If the code manipulating the dma or usart is not interrupt or task switch protected could wrek havok or worse recurse function call. Does not hurt to look into this aspect, especially if the same dma is used. Agreed with Clive comment, usart should not be a problem unless SYSCLK is low frequency or clock stop situations are present. Is the used RAM the internal DMA adressable.one?

ChrisH
Associate III
Posted on January 10, 2017 at 22:01

Yes I use internal RAM, specific UART is dedicated only to one task and one device, so this shouldn't be the case, I was thinking about signal issues for days and this might be the case but I can't do any better for this prototype(garbage wires), anyway similar solutions were working fine before.

At the moment I don't have any power saving features enabled on MCU as those are next steps, so clock issues are not the case. 

ChrisH
Associate III
Posted on January 11, 2017 at 04:58

One more thing there is AdvInitFeature on UART which allows to still receive data despite getting errors (RM0351 page 1233 DDRE bit). However, an IRQ Handler in HAL handles an error in a way that it doesn't care about this bit and will disable DMA request anyway. Is this how it supped to be (I don't think so?) or I am missing something?

/**

  * @brief Handle UART interrupt request.

  * @param huart: UART handle.

  * @retval None

  */

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)

{

  uint32_t isrflags   = READ_REG(huart->Instance->ISR);

  uint32_t cr1its     = READ_REG(huart->Instance->CR1);

  uint32_t cr3its;

  uint32_t errorflags;

  /* If no error occurs */

  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));

  if (errorflags == RESET)

  {

    /* UART in mode Receiver ---------------------------------------------------*/

    if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))

    {

      UART_Receive_IT(huart);

      return;

    }

  }  

  /* If some errors occur */

  cr3its = READ_REG(huart->Instance->CR3);

  if(   (errorflags != RESET)

     && (   ((cr3its & USART_CR3_EIE) != RESET)

         || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)) )

  {

    /* UART parity error interrupt occurred -------------------------------------*/

    if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))

    {

      __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);

      huart->ErrorCode |= HAL_UART_ERROR_PE;

    }

    /* UART frame error interrupt occurred --------------------------------------*/

    if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))

    {

      __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);

      huart->ErrorCode |= HAL_UART_ERROR_FE;

    }

    /* UART noise error interrupt occurred --------------------------------------*/

    if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))

    {

      __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);

      huart->ErrorCode |= HAL_UART_ERROR_NE;

    }

    

    /* UART Over-Run interrupt occurred -----------------------------------------*/

    if(((isrflags & USART_ISR_ORE) != RESET) &&

       (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))

    {

      __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);

      huart->ErrorCode |= HAL_UART_ERROR_ORE;

    }

    /* Call UART Error Call back function if need be --------------------------*/

    if(huart->ErrorCode != HAL_UART_ERROR_NONE)

    {

      /* UART in mode Receiver ---------------------------------------------------*/

      if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))

      {

        UART_Receive_IT(huart);

      }

      /* If Overrun error occurs, or if any error occurs in DMA mode reception,

         consider error as blocking */

      if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) ||

          (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))

      {  

        /* Blocking error : transfer is aborted

           Set the UART state ready to be able to start again the process,

           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */

        UART_EndRxTransfer(huart);

        /* Disable the UART DMA Rx request if enabled */

        if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))

        {

          CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);

          /* Abort the UART DMA Rx channel */

          if(huart->hdmarx != NULL)

          {

            /* Set the UART DMA Abort callback : 

               will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */

            huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;

            /* Abort DMA RX */

            if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)

            {

              /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */

              huart->hdmarx->XferAbortCallback(huart->hdmarx);

            }

          }

          else

          {

            /* Call user error callback */

            HAL_UART_ErrorCallback(huart);

          }

        }

        else

        {

          /* Call user error callback */

          HAL_UART_ErrorCallback(huart);

        }

      }

      else

      {

        /* Non Blocking error : transfer could go on. 

           Error is notified to user through user error callback */

        HAL_UART_ErrorCallback(huart);

        huart->ErrorCode = HAL_UART_ERROR_NONE;

      }

    }

    return;

  } /* End if some error occurs */

Posted on January 11, 2017 at 08:02

Basically every now and then I get random errors like FE (framing error), ORE (overrun error), NF (noise flag set).

How do you know?

JW

ChrisH
Associate III
Posted on January 11, 2017 at 19:06

Ok, so I believe that

Turvey.Clive.002

‌ is correct and I have crosstalk issues. Basically, this is a GSM Module connected with wires to Nucleo board. I think that during current spikes when ex. themodule is connecting to the network or turning on GPRS I get those errors. I modified HAL_IRQ so it won't disable transfer when DDRE bit is not set. I actually don't understand why ST engineers wrote this IRQ this way so it will always disable transfer no matter DDRE configuration.

Waclawek.Jan

‌ I have implemented ErrorCallback so I get alertedwhenever an error occurs. Anyway, I also checked ISR registers of particular UART which confirmed my assumptions.

Posted on January 11, 2017 at 19:26

If it is a 2g modem these could have big current spikes that may disturb the application or glitch the serial communication. To exclude this root cause, the modem supply should be separated from the nucleo during debug. 

JongOk Baek
Associate III
Posted on February 01, 2017 at 09:16

Dear ChrisH

I have same problem like you.

I use 6 uarts with DMA circular mode.

So, DMA was stoped from UART or DMA Handler.

I want to set priority each DMA, but it is impossible.

(priority exist 4 step.)

So, I don't want to operate UART and DMA interrupt.

I do disable UART and DMA interrupt.

How about you this method?

T J
Lead
Posted on February 07, 2017 at 22:34

Definitely you are getting noise on the Ground wire.

this is caused by the Transmitt pulse energy required for the RF transmitter.

You may want to add some real capacity to the power rail on the RF Transmitter.

use Nichon or United Chemi  3000uF 6.3V  2A ripple current on the 5V rail of the RF transmitter.

and beefup the Ground Wire  between the boards and power supply substantially.