USART1_USART_IRQHANDLER vs. USART_TransferCreateHandle callback?

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

USART1_USART_IRQHANDLER vs. USART_TransferCreateHandle callback?

658 Views
nxp19
Contributor II

Where is the difference between the interrupt handler defined by the peripheral configuration tool and the callback function in USART_TransferCreateHandle?

Labels (2)
0 Kudos
1 Reply

593 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Burghard,

Generally, the callback function is called in the interrupt service routine usart1_usart_irqhandler(). The USART_TransferCreateHandle() function just initialize the handler-callback so that the callback function is assigned to a the handler variable.

Pls refer to the line in the following code:

handle->callback(base, handle, kStatus_USART_RxError, handle->userData);

Obviously, the USART_TransferCreateHandle()  function assigned the callback function to the handle->callback variable.

 Hope it can help you

BR

XiangJun Rong

void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle)
{
    /* Check arguments */
    assert((NULL != base) && (NULL != handle));

    bool receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL));
    bool sendEnabled    = (handle->txDataSize != 0U);
    uint8_t rxdata;
    size_t tmpsize;

    /* If RX overrun. */
    if ((base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK) != 0U)
    {
        /* Clear rx error state. */
        base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
        /* clear rxFIFO */
        base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
        /* Trigger callback. */
        if (handle->callback != NULL)
        {
            handle->callback(base, handle, kStatus_USART_RxError, handle->userData);
        }
    }
    while ((receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)) ||
           (sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U)))
    {
        /* Receive data */
        if (receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U))
        {
            /* Receive to app bufffer if app buffer is present */
            if (handle->rxDataSize != 0U)
            {
                rxdata          = (uint8_t)base->FIFORD;
                *handle->rxData = rxdata;
                handle->rxDataSize--;
                handle->rxData++;
                receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL));
                if (0U == handle->rxDataSize)
                {
                    if (NULL == handle->rxRingBuffer)
                    {
                        base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
                    }
                    handle->rxState = (uint8_t)kUSART_RxIdle;
                    if (handle->callback != NULL)
                    {
                        handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
                    }
                }
            }
            /* Otherwise receive to ring buffer if ring buffer is present */
            else
            {
                if (handle->rxRingBuffer != NULL)
                {
                    /* If RX ring buffer is full, trigger callback to notify over run. */
                    if (USART_TransferIsRxRingBufferFull(handle))
                    {
                        if (handle->callback != NULL)
                        {
                            handle->callback(base, handle, kStatus_USART_RxRingBufferOverrun, handle->userData);
                        }
                    }
                    /* If ring buffer is still full after callback function, the oldest data is overridden. */
                    if (USART_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. */
                    rxdata                                         = (uint8_t)base->FIFORD;
                    handle->rxRingBuffer[handle->rxRingBufferHead] = rxdata;
                    /* Increase handle->rxRingBufferHead. */
                    if ((size_t)handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
                    {
                        handle->rxRingBufferHead = 0U;
                    }
                    else
                    {
                        handle->rxRingBufferHead++;
                    }
                }
            }
        }
        /* Send data */
        if (sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U))
        {
            base->FIFOWR = *handle->txData;
            handle->txDataSize--;
            handle->txData++;
            sendEnabled = handle->txDataSize != 0U;
            if (!sendEnabled)
            {
                base->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK;
                handle->txState    = (uint8_t)kUSART_TxIdle;

                base->INTENSET |= USART_INTENSET_TXIDLEEN_MASK;
            }
        }
    }

    /* Tx idle and the interrupt is enabled. */
    if ((0U != (base->INTENSET & USART_INTENSET_TXIDLEEN_MASK)) &&
        (0U != (base->INTSTAT & USART_INTSTAT_TXIDLE_MASK)) && (handle->txState == (uint8_t)kUSART_TxIdle))
    {
        /* Disable tx idle interrupt */
        base->INTENCLR |= USART_INTENCLR_TXIDLECLR_MASK;
        /* Trigger callback. */
        if (handle->callback != NULL)
        {
            handle->callback(base, handle, kStatus_USART_TxIdle, handle->userData);
        }
    }

    /* ring buffer is not used */
    if (NULL == handle->rxRingBuffer)
    {
        tmpsize = handle->rxDataSize;

        /* restore if rx transfer ends and rxLevel is different from default value */
        if ((tmpsize == 0U) && (USART_FIFOTRIG_RXLVL_GET(base) != handle->rxWatermark))
        {
            base->FIFOTRIG =
                (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | USART_FIFOTRIG_RXLVL(handle->rxWatermark);
        }
        /* decrease level if rx transfer is bellow */
        if ((tmpsize != 0U) && (tmpsize < (USART_FIFOTRIG_RXLVL_GET(base) + 1U)))
        {
            base->FIFOTRIG = (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | (USART_FIFOTRIG_RXLVL(tmpsize - 1U));
        }
    }
}

0 Kudos