S32K144 UART receive bytes missing issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32K144 UART receive bytes missing issue

4,432 Views
xiaoyuwang
Contributor II

I am using S32K144 UART peripheral. RXD interrupt and TXD interrupt vector are the same one, so in interrupt handler, we have to check whether due to Rx or Tx that the ISR function is called.

My question 1 is : If ISR is entered due to Tx, at the same time, a Rx byte is shift to data register finished. whether the received byte will be affected?

My ISR function just like below:

void UARTSrv_isr(void)
{
      uint8_t lub_temp;

      /* For reception interrupt. */
      if(LPUART1->CTRL & 0X200000)
      {
            if(LPUART1->STAT & 0X200000)
            {
                  lub_temp = (uint8_t)LPUART1->DATA;
                  testTotalReceived += 1;
                  UARTSrv_Rx_isr(lub_temp);
             }
        }

         /* For transmission interrupt. */

         if(LPUART1->CTRL & 0X800000)
         {
               if(LPUART1->STAT & 0X800000)
               {
                     if(lpuart1_State.txSize > 0)
                     {
                           LPUART1->DATA = *lpuart1_State.txBuff;
                           ++lpuart1_State.txBuff;
                             --lpuart1_State.txSize;
                      }
                      else
                      {
                          /* Disable transmission complete interrupt */
                           LPUART_SetIntMode(LPUART1, LPUART_INT_TX_DATA_REG_EMPTY, false);

                           /* Update the information of the module driver state */
                           lpuart1_State.isTxBusy = false;
                           lpuart1_State.transmitStatus = STATUS_SUCCESS;
                       }
                }
          }

         /* For overruninterrupt. */

         if (LPUART1->STAT & 0X80000)
         {
               lpuart1_State.receiveStatus = STATUS_UART_RX_OVERRUN;
               /* Clear the flag, OR the rxDataRegFull will not be set any more */
               LPUART1->STAT |= 0X80000;
         }

}

User defined function "UARTSrv_Rx_isr" definition as below:

PRIVATE_FCT void UARTSrv_Rx_isr(uint8_t ch)
{
      pUART_rx_data_t pRx = &rs_rxData;

      if(FALSE == pRx->bufFull)
      {
            pRx->buf[pRx->inIndex] = ch;
            pRx->bufEmpty = FALSE;
            pRx->recBytes += 1u;
            pRx->inIndex += 1u;
            if(UART_RX_DATA_BUF_LEN <= pRx->inIndex)
            {
                  pRx->inIndex = 0u;
            }
            if(pRx->inIndex == pRx->outIndex)
            {
                  pRx->bufFull = TRUE;
            }
        }
}

But when I check my received data, I found that received bytes lost frequently. 

My question 2 is: whether my ISR has problem? or my issue is due to other possible reasons?

Thank you~~

Additionally: I check the UART receive overrun interrupt, it was entered frequently. How to avoid enter the overrun interrupt or how to process it?

Tags (1)
0 Kudos
Reply
7 Replies

3,158 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hi Xiaoyu,

For checking which one interrupt occur RX or TX, I checked the data buffers like below. Then I jumped into the proper interrupt routine.

void LPUART1_RxTx_IRQHandler(void)

 {

       if((LPUART1->STAT & LPUART_STAT_RDRF_MASK)>>LPUART_STAT_RDRF_SHIFT) // Checked Receive data buffer

              RxISR();

 

       if((LPUART1->STAT & LPUART_STAT_TDRE_MASK)>>LPUART_STAT_TDRE_SHIFT) // Checked Transmit data buffer

              TxISR();

 }

When overrun occurs and OR flag is set, no additional data is stored in the data buffer.

It happens when Rx buffer is not empty (not read) and further data are received. That’s why the data are lost.

 

There are some possibilities which can help you:

- Decrease the BaudRate value

- Set the higher priority of LPUART interrupt

- Choose the fastest clock source for the LPUART

- You can consider the use of FIFO register see 51.3.1.12 LPUART FIFO Register (FIFO) in the reference manual.

I hope it helps you.

Best regards,

Diana

0 Kudos
Reply

3,158 Views
harish_g2
Contributor II

Hi, 

Have you tried FIFO for UART. If yes please let me know how you configured.

Thanks..!

Harish

0 Kudos
Reply

3,002 Views
BiancaB
Contributor I

@harish_g2  Did you manage to make the communication using FIFO? 

0 Kudos
Reply

3,158 Views
jtpark
Contributor IV

Dear Diana,

I have a question.

When I deal with receive by UART in debug mode using break point, STATUS_UART_RX_OVERRUN occurred.
It was ok.
however, I want to know how to clear Error when STATUS_UART_RX_OVERRUN was occurred.

Do I deal with as below?

         /* For overruninterrupt. */

         if (LPUART1->STAT & 0X80000)
         {
               lpuart1_State.receiveStatus = STATUS_UART_RX_OVERRUN;
               /* Clear the flag, OR the rxDataRegFull will not be set any more */
               LPUART1->STAT |= 0X80000;
         }

Thanks.

0 Kudos
Reply

3,158 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello,

Yes, at first, check if the Receiver Overrun Flag is set and if yes, clear the flag.

  

Best Regards,

Diana

0 Kudos
Reply

3,158 Views
xiaoyuwang
Contributor II

Hello Diana Batrlova,

I have tried to set the priority of used LPUART to highest level of all interrupts I am using. It works!

Next step, I will try to improve my SW use FIFO.

Thank you for your solution~~

0 Kudos
Reply

3,158 Views
xiaoyuwang
Contributor II

hello Diana Batrlova, 

  I have tried to set the priority of LPUART I used to 

0 Kudos
Reply