AnsweredAssumed Answered

K64F infinite UART IRQ loop

Question asked by Julian Heni on Mar 12, 2020
Latest reply on Apr 7, 2020 by Sabina Bruce

Hey guys,

I'm using the SDK's UART RX and TX Functions in order to send or receive data

 

UART_TransferReceiveNonBlocking()

and

UART_TransferSendNonBlocking()

 

The IRQ Callback sets a finnish Eventbit (or a failure eventbit).

 

So far for the theory

 

However there are some reasons where I end up in an infinite IRQ loop. From Debugging I found out that

void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle)

{

 

//some other checks

/* Receive data register full */
    if ((((uint32_t)kUART_RxDataRegFullFlag & status) != 0U) && ((UART_C2_RIE_MASK & base->C2) != 0U))
    {
/* Get the size that can be stored into buffer for this interrupt. */
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
        count = base->RCFIFO;
#else
        count = 1;
#endif

//in the infinite loop I end up here where RX is Full but count = 0

        /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
        while ((count != 0U) && (handle->rxDataSize != 0U))
        {
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
            tempCount = (uint8_t)MIN(handle->rxDataSize, (uint32_t)count);
#else
            tempCount = 1;
#endif

 

            /* Using non block API to read the data from the registers. */
            UART_ReadNonBlocking(base, handle->rxData, tempCount);
            handle->rxData += tempCount;
            handle->rxDataSize -= tempCount;
            count -= tempCount;

 

            /* If all the data required for upper layer is ready, trigger callback. */
            if (0U == handle->rxDataSize)
            {
                handle->rxState = (uint8_t)kUART_RxIdle;

 

                if (handle->callback != NULL)
                {
                    handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData);
                }
            }
        }

 

        /* If use RX ring buffer, receive data to ring buffer. */
        if (handle->rxRingBuffer != NULL)
        {
            while (0U != count--)
            {
                /* If RX ring buffer is full, trigger callback to notify over run. */
                if (UART_TransferIsRxRingBufferFull(handle))
                {
                    if (handle->callback != NULL)
                    {
                        handle->callback(base, handle, kStatus_UART_RxRingBufferOverrun, handle->userData);
                    }
                }

 

                /* If ring buffer is still full after callback function, the oldest data is overridden. */
                if (UART_TransferIsRxRingBufferFull(handle))
                {
                    /* Increase handle->rxRingBufferTail to make room for new data. */
                    if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
                    {
                        handle->rxRingBufferTail = 0U;
                    }
                    else
                    {
                        handle->rxRingBufferTail++;
                    }
                }

 

                /* Read data. */
                tmpdata                                        = base->D;
                handle->rxRingBuffer[handle->rxRingBufferHead] = tmpdata;

 

                /* Increase handle->rxRingBufferHead. */
                if ((size_t)handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
                {
                    handle->rxRingBufferHead = 0U;
                }
                else
                {
                    handle->rxRingBufferHead++;
                }
            }
        }

 

        else if (0U == handle->rxDataSize)
        {
            /* Disable RX interrupt/overrun interrupt/fram error/idle line detected interrupt */
            UART_DisableInterrupts(base, (uint32_t)kUART_RxDataRegFullInterruptEnable |
                                             (uint32_t)kUART_RxOverrunInterruptEnable |
                                             (uint32_t)kUART_FramingErrorInterruptEnable);

 

            /* Disable parity error interrupt when parity mode is enable*/
            if ((UART_C1_PE_MASK & base->C1) != 0U)
            {
                UART_DisableInterrupts(base, (uint32_t)kUART_ParityErrorInterruptEnable);
            }
        }
        else
        {
        }
    }

//.... some further Checks

}

 

 

Do you know How I could avoid this sittuation where kUART_RxDataRegFullFlag is full but count = 0? I looks like the SDK does not use the UART RX FIFO. To me that sounds like there is nothing in the RX register (or only garbage) but the interupt was triggerd.

How can i clear the kUART_RxDataRegFullFlag  Interrupt Pending flag?

 

Or, if it is not possible to clear the kUART_RxDataRegFullFlag  IRQ Pending flag, how can i shoot down the whole UARTX IRQ Vector.

I tried the following

 

UART_DisableInterrupts(pMyUart,kUART_AllInterruptsEnable);

UART_EnableRx(pMyUart,false);
 UART_EnableTx(pMyUart,false);

 UART_Deinit(pMyUart);

 

 

do you have a suggestion for me?

BTW: I couldn't find a code formating option. Is there any?

 

kind regards Julian

Outcomes