/*==================================================================================================
*   Project              : RTD AUTOSAR 4.4
*   Platform             : CORTEXM
*   Peripheral           : FLEXIO
*   Dependencies         : 
*
*   Autosar Version      : 4.4.0
*   Autosar Revision     : ASR_REL_4_4_REV_0000
*   Autosar Conf.Variant :
*   SW Version           : 0.9.0
*   Build Version        : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
*
*   (c) Copyright 2020 - 2021 NXP Semiconductors
*   All Rights Reserved.
*
*   NXP Confidential. This software is owned or controlled by NXP and may only be
*   used strictly in accordance with the applicable license terms. By expressly
*   accepting such terms or by downloading, installing, activating and/or otherwise
*   using the software, you are agreeing that you have read, and that you agree to
*   comply with and are bound by, such license terms. If you do not agree to be
*   bound by the applicable license terms, then you may not retain, install,
*   activate or otherwise use the software.
==================================================================================================*/
/**
*   @file     Lpuart_Uart_Ip.c
*   @defgroup lpuart_uart_ip Lpuart UART IPL
*   @addtogroup  lpuart_uart_ip Lpuart UART IPL
*   @{
*/

#ifdef __cplusplus
extern "C"{
#endif

/*==================================================================================================
*                                          INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/

#include "Lpuart_Uart_Ip.h"
#include "Lpuart_Uart_Ip_HwAccess.h"
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
    #include "Dma_Ip.h"
#endif

#ifdef LPUART_UART_IP_DEV_ERROR_DETECT
    #if (LPUART_UART_IP_DEV_ERROR_DETECT == STD_ON)
        #include "Devassert.h"
    #endif /* (STD_ON == LPUART_UART_IP_DEV_ERROR_DETECT) */
#endif /* idfef LPUART_UART_IP_DEV_ERROR_DETECT */

/*==================================================================================================
*                                 SOURCE FILE VERSION INFORMATION
==================================================================================================*/

#define LPUART_UART_IP_VENDOR_ID_C                      43
#define LPUART_UART_IP_AR_RELEASE_MAJOR_VERSION_C       4
#define LPUART_UART_IP_AR_RELEASE_MINOR_VERSION_C       4
#define LPUART_UART_IP_AR_RELEASE_REVISION_VERSION_C    0
#define LPUART_UART_IP_SW_MAJOR_VERSION_C               0
#define LPUART_UART_IP_SW_MINOR_VERSION_C               9
#define LPUART_UART_IP_SW_PATCH_VERSION_C               0

/*==================================================================================================
*                                       FILE VERSION CHECKS
==================================================================================================*/
/* Checks against Lpuart_Uart_Ip.h */
#if (LPUART_UART_IP_VENDOR_ID_C != LPUART_UART_IP_VENDOR_ID)
    #error "Lpuart_Uart_Ip.c and Lpuart_Uart_Ip.h have different vendor ids"
#endif
#if ((LPUART_UART_IP_AR_RELEASE_MAJOR_VERSION_C    != LPUART_UART_IP_AR_RELEASE_MAJOR_VERSION) || \
     (LPUART_UART_IP_AR_RELEASE_MINOR_VERSION_C    != LPUART_UART_IP_AR_RELEASE_MINOR_VERSION) || \
     (LPUART_UART_IP_AR_RELEASE_REVISION_VERSION_C != LPUART_UART_IP_AR_RELEASE_REVISION_VERSION))
     #error "AUTOSAR Version Numbers of Lpuart_Uart_Ip.c and Lpuart_Uart_Ip.h are different"
#endif
#if ((LPUART_UART_IP_SW_MAJOR_VERSION_C != LPUART_UART_IP_SW_MAJOR_VERSION) || \
     (LPUART_UART_IP_SW_MINOR_VERSION_C != LPUART_UART_IP_SW_MINOR_VERSION) || \
     (LPUART_UART_IP_SW_PATCH_VERSION_C != LPUART_UART_IP_SW_PATCH_VERSION))
    #error "Software Version Numbers of Lpuart_Uart_Ip.c and Lpuart_Uart_Ip.h are different"
#endif
/*==================================================================================================
*                           LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/

/*==================================================================================================
*                                          LOCAL MACROS
==================================================================================================*/

#ifdef LPUART_UART_IP_DEV_ERROR_DETECT
    #if (LPUART_UART_IP_DEV_ERROR_DETECT == STD_ON)
        #define LPUART_UART_DEV_ASSERT(x)      DevAssert(x)
    #else
        #define LPUART_UART_DEV_ASSERT(x)      (void)(x)
    #endif
#endif

/* @brief Address of the least significant byte or word in a 32-bit register (depends on endianness) */
#define LPUART_UART_IP_LSBW_ADDR(reg)  ((uint32)(&(reg)))

/*==================================================================================================
*                                         LOCAL CONSTANTS
==================================================================================================*/

#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
    #define LPUART_UART_DMA_CONFIG_LIST_DIMENSION             (10U)
    #define LPUART_UART_DMA_LEAST_CONFIG_LIST_DIMENSION       (2U)
#endif

/*==================================================================================================
*                                         LOCAL VARIABLES
==================================================================================================*/
#define UART_START_SEC_VAR_NO_INIT_UNSPECIFIED_NO_CACHEABLE
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

/** @brief Array of UART driver runtime state structures */
Lpuart_Uart_Ip_StateStructureType Lpuart_Uart_Ip_apStateStructure[LPUART_UART_IP_NUMBER_OF_INSTANCES];

#define UART_STOP_SEC_VAR_NO_INIT_UNSPECIFIED_NO_CACHEABLE
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

#define UART_START_SEC_VAR_NO_INIT_UNSPECIFIED
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

/* Pointer to lpuart runtime state structure */
static Lpuart_Uart_Ip_StateStructureType * Lpuart_Uart_Ip_apStateStructuresArray[LPUART_UART_IP_NUMBER_OF_INSTANCES];

/** @brief User config structure. */
const Lpuart_Uart_Ip_UserConfigType * Lpuart_Uart_Ip_apUserConfig[LPUART_UART_IP_NUMBER_OF_INSTANCES];

#define UART_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

#define UART_START_SEC_CONST_UNSPECIFIED
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

/* Table of base addresses for lpuart instances. */
static LPUART_Type * const Lpuart_Uart_Ip_apBases[LPUART_UART_IP_NUMBER_OF_INSTANCES] = FEATURE_LPUART_IP_SPECIFIC_BASE_PTR;

#define UART_STOP_SEC_CONST_UNSPECIFIED
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
#define UART_START_SEC_CONST_BOOLEAN
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

/** @brief Table storing DMA capabilities for LPUART instances. */
static const boolean Lpuart_Uart_Ip_InstHasDma[LPUART_UART_IP_NUMBER_OF_INSTANCES] = FEATURE_LPUART_IP_INST_HAS_DMA;

#define UART_STOP_SEC_CONST_BOOLEAN
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"
#endif


/*==================================================================================================
*                                        GLOBAL CONSTANTS
==================================================================================================*/

/*==================================================================================================
*                                        GLOBAL VARIABLES
==================================================================================================*/

/*==================================================================================================
*                                    LOCAL FUNCTION PROTOTYPES
==================================================================================================*/

/*==================================================================================================
*                                         LOCAL FUNCTIONS
==================================================================================================*/
#define UART_START_SEC_CODE
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingInt(uint32 u32Instance,
                                                 const uint8 * pTxBuff,
                                                 uint32 u32TxSize);
static void Lpuart_Uart_Ip_CompleteSendDataUsingInt(uint32 u32Instance);
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingInt(uint32 u32Instance,
                                                    uint8 * pRxBuff,
                                                    uint32 u32RxSize);
static void Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(uint32 u32Instance);
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingDma(uint32 u32Instance,
                                                                      const uint8 * pTxBuff,
                                                                      uint32 u32TxSize);
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingDma(uint32 u32Instance,
                                                                         uint8 * pRxBuff,
                                                                         uint32 u32RxSize);
#endif
static void Lpuart_Uart_Ip_PutData(uint32 u32Instance);
static void Lpuart_Uart_Ip_GetData(uint32 u32Instance);
static void Lpuart_Uart_Ip_RxIrqHandler(uint32 u32Instance);
static void Lpuart_Uart_Ip_TxEmptyIrqHandler(uint32 u32Instance);
static void Lpuart_Uart_Ip_TxCompleteIrqHandler(uint32 u32Instance);
static void Lpuart_Uart_Ip_ErrIrqHandler(uint32 u32Instance);
static void Lpuart_Uart_Ip_StartGetData(LPUART_Type * pBase, uint32 u32Instance, uint32 u32StartTime);

/*==================================================================================================
*                                        GLOBAL FUNCTIONS
==================================================================================================*/

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_Init
 * Description   : This function initializes a LPUART instance for operation.
 * This function will initialize the run-time state structure to keep track of
 * the on-going transfers, ungate the clock to the LPUART module, initialize the
 * module to user defined settings and default settings, configure the IRQ state
 * structure and enable the module-level interrupt to the core, and enable the
 * LPUART module transmitter and receiver.
 *
 * Implements    : Lpuart_Uart_Ip_Init_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_Init_Activity*/
void Lpuart_Uart_Ip_Init(uint32 u32Instance, const Lpuart_Uart_Ip_UserConfigType * pUserConfig)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pUserConfig != NULL_PTR);
    /* Check if current instance is already initialized. */
    LPUART_UART_DEV_ASSERT(Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] == NULL_PTR);
    /* Check if Baudrate parameters are valid value */
    LPUART_UART_DEV_ASSERT(pUserConfig->u8BaudOverSamplingRatio <= 0x20U);
    LPUART_UART_DEV_ASSERT((pUserConfig->u32BaudRateDivisor <= 0x1FFFU) && \
                           (pUserConfig->u32BaudRateDivisor >= 1U));

    LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    Lpuart_Uart_Ip_StateStructureType *pUartStatePtr;
    uint32 u32Index;

    Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] = pUserConfig->pStateStruct;
    pUartStatePtr = Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    Lpuart_Uart_Ip_apUserConfig[u32Instance] =  pUserConfig;

#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
    /* In DMA mode, only 7-bits and 8-bits chars are supported */
    LPUART_UART_DEV_ASSERT((pUserConfig->eTransferType != LPUART_UART_IP_USING_DMA) || \
                           (((pUserConfig->eBitCountPerChar == LPUART_UART_IP_7_BITS_PER_CHAR) || \
                             (pUserConfig->eBitCountPerChar == LPUART_UART_IP_8_BITS_PER_CHAR)) && \
                           Lpuart_Uart_Ip_InstHasDma[u32Instance]));

#endif /* (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON) */


    /* For 10 bits per char, parity bit cannot be enabled */
    LPUART_UART_DEV_ASSERT((pUserConfig->eBitCountPerChar != LPUART_UART_IP_10_BITS_PER_CHAR) || \
               (pUserConfig->eParityMode == LPUART_UART_IP_PARITY_DISABLED));

    /* Clear the state struct for this instance. */
    uint8 *pClearStructPtr = (uint8 *)pUartStatePtr;
    for (u32Index = 0; u32Index < sizeof(Lpuart_Uart_Ip_StateStructureType); u32Index++)
    {
        pClearStructPtr[u32Index] = 0;
    }


    /* Initialize the LPUART instance */
    LPUART_Uart_Init(pBase);

    /* Check if osr is between 4x and 7x oversampling.
     * If so, then "BOTHEDGE" sampling must be turned on */
    if (pUserConfig->u8BaudOverSamplingRatio < 8U)
    {
        LPUART_Uart_EnableBothEdgeSamplingCmd(pBase);
    }

    /* Program the osr value (bit value is one less than actual value) */
    LPUART_Uart_SetOversamplingRatio(pBase, (uint32)(pUserConfig->u8BaudOverSamplingRatio - 1U));

    /* Write the sbr value to the BAUD registers */
    LPUART_Uart_SetBaudRateDivisor(pBase, pUserConfig->u32BaudRateDivisor);

    if (pUserConfig->eParityMode != LPUART_UART_IP_PARITY_DISABLED)
    {
        LPUART_Uart_SetBitCountPerChar(pBase, pUserConfig->eBitCountPerChar, TRUE);
    }
    else
    {
        LPUART_Uart_SetBitCountPerChar(pBase, pUserConfig->eBitCountPerChar, FALSE);
    }
    LPUART_Uart_SetParityMode(pBase, pUserConfig->eParityMode);
    LPUART_Uart_SetStopBitCount(pBase, pUserConfig->eStopBitsCount);

    /* Initialize last driver operation status */
    pUartStatePtr->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
    pUartStatePtr->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
    /* Set the initial baudrate from user's structure */
    pUartStatePtr->u32BaudRate = pUserConfig->u32BaudRate;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_Deinit
 * Description   : This function shuts down the UART by disabling interrupts and
 *                 transmitter/receiver.
 *
 * Implements    : Lpuart_Uart_Ip_Deinit_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_Deinit_Activity*/
void Lpuart_Uart_Ip_Deinit(uint32 u32Instance)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    uint32 u32StartTime;
    LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];

    /* Check if current instance is already de-initialized or is gated.*/
    LPUART_UART_DEV_ASSERT(Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] != NULL_PTR);

    u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);
    /* Wait until the data is completely shifted out of shift register */
    while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_COMPLETE) && \
           !LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
    {}
    /* Disble  Tx data register empty and transmission complete interrupt */

    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, FALSE);

    /* Disble  Rx data register full */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, FALSE);

    /* Disable error interrupts */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, FALSE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, FALSE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, FALSE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, FALSE);

    /* Clear our saved pointer to the state structure */
    Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] = NULL_PTR;

}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_SyncSend
 * Description   : Send out multiple bytes of data using polling method.
 *
 * Implements    : Lpuart_Uart_Ip_SyncSend_Activity
 *END**************************************************************************/
 /* implements     Lpuart_Uart_Ip_SyncSend_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SyncSend(uint32 u32Instance,
                                                  const uint8 *pTxBuff,
                                                  uint32 u32TxSize)
{
    /* Check the validity of the parameters */
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pTxBuff != NULL_PTR);
    LPUART_UART_DEV_ASSERT(u32TxSize > 0U);

    LPUART_Type * pBase;
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    uint32 u32StartTime;
    boolean bIsReturn = FALSE;
    Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);

    SchM_Enter_Uart_UART_EXCLUSIVE_AREA_00();
    /* Check driver is not busy transmitting data from a previous asynchronous call */
    if (pUartState->bIsTxBusy)
    {
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_00();
        retVal = LPUART_UART_IP_STATUS_BUSY;
        bIsReturn = TRUE;
    }
    if(!bIsReturn)
    {
        pUartState->bIsTxBusy = TRUE;
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_00();
        pUartState->pTxBuff = pTxBuff;
        pUartState->u32TxSize = u32TxSize;

        pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_BUSY;

        /* Disble  Tx data register empty and transmission complete interrupt */
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, FALSE);

        /* Enable the LPUART transmitter */
        LPUART_Uart_SetTransmitterCmd(pBase, TRUE);
        u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);

        while ((pUartState->u32TxSize > 0U) && \
                !LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
        {
            Lpuart_Uart_Ip_PutData(u32Instance);
            while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_DATA_REG_EMPTY)  && \
                   !LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
            {}
        }

        /* Disable the LPUART transmitter */
        LPUART_Uart_SetTransmitterCmd(pBase, FALSE);

        /* Check if Timeout occur */
        if(pUartState->u32TxSize > 0U)
        {
            pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_TIMEOUT;
        }else /* The transmit process is complete */
        {
            pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
        }
        pUartState->bIsTxBusy = FALSE;
        retVal = pUartState->eTransmitStatus;
    }
    return retVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_AsyncSend
 * Description   : This function sends data out through the LPUART module using
 * non-blocking method. The function will return immediately after calling this
 * function.
 *
 * Implements    : Lpuart_Uart_Ip_AsyncSend_Activity
 *END**************************************************************************/
 /* implements     Lpuart_Uart_Ip_AsyncSend_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AsyncSend(uint32 u32Instance,
                                                   const uint8 * pTxBuff,
                                                   uint32 u32TxSize)
{
    /* Check the validity of the parameters */
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pTxBuff != NULL_PTR);
    LPUART_UART_DEV_ASSERT(u32TxSize > 0U);
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    boolean bIsReturn = FALSE;

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);

    SchM_Enter_Uart_UART_EXCLUSIVE_AREA_01();
    /* Check it's not busy transmitting data from a previous function call */
    if (pUartState->bIsTxBusy)
    {
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_01();
        retVal = LPUART_UART_IP_STATUS_BUSY;
        bIsReturn = TRUE;
    }
    if(!bIsReturn)
    {
        pUartState->bIsTxBusy = TRUE;
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_01();

        LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
        LPUART_UART_DEV_ASSERT((pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS) ||
                               (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_DMA));
        if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
        {
            /* Start the transmission process using interrupts */
            retVal = Lpuart_Uart_Ip_StartSendDataUsingInt(u32Instance, pTxBuff, u32TxSize);
        }
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
        else
        {
            /* Start the transmission process using DMA */
            retVal = Lpuart_Uart_Ip_StartSendDataUsingDma(u32Instance, pTxBuff, u32TxSize);
        }
#endif
    }
    return retVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_GetTransmitStatus
 * Description   : This function returns whether the previous LPUART transmit has
 * finished. When performing non-blocking transmit, the user can call this
 * function to ascertain the state of the current transmission:
 * in progress (or busy) or complete (success). In addition, if the transmission
 * is still in progress, the user can obtain the number of words that have been
 * currently transferred.
 *
 * Implements    : Lpuart_Uart_Ip_GetTransmitStatus_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_GetTransmitStatus_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_GetTransmitStatus(uint32 u32Instance, uint32 * pBytesRemaining)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
    const Dma_Ip_LogicChannelInfoParamType eDmaLogicChnParam = DMA_IP_CH_GET_CURRENT_ITER_COUNT;
#endif
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
    LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);

    if (pBytesRemaining != NULL_PTR)
    {
        if (pUartState->bIsTxBusy)
        {
            /* Fill in the bytes not transferred yet. */
            if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
            {
                /* In interrupt-based communication, the remaining bytes are retrieved
                 * from the state structure
                 */
                *pBytesRemaining = pUartState->u32TxSize;;
            }
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
            else
            {
                /* In DMA-based communication, the remaining bytes are retrieved
                 * from the current DMA major loop count
                 */
                Dma_Ip_GetLogicChannelParam(pUartUserCfg->u8TxDMAChannel, eDmaLogicChnParam, pBytesRemaining);
            }
#endif
        }
        else
        {
            *pBytesRemaining = 0;
        }
    }

    return pUartState->eTransmitStatus;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_AbortSendingData
 * Description   : This function terminates an non-blocking LPUART transmission
 * early. During a non-blocking LPUART transmission, the user has the option to
 * terminate the transmission early if the transmission is still in progress.
 *
 * Implements    : Lpuart_Uart_Ip_AbortSendingData_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_AbortSendingData_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AbortSendingData(uint32 u32Instance)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);

    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    boolean bIsReturn = FALSE;
    Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
    LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);

    /* Check if a transfer is running. */
    if (!pUartState->bIsTxBusy)
    {
        retVal = LPUART_UART_IP_STATUS_SUCCESS;
        bIsReturn = TRUE;
    }
    if(!bIsReturn)
    {
        /* Update the tx status */
        pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_ABORTED;

        /* Stop the running transfer. */
        if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
        {
            Lpuart_Uart_Ip_CompleteSendDataUsingInt(u32Instance);
        }
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
        else
        {
            /* Release the DMA channel */
            (void)Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
            Lpuart_Uart_Ip_CompleteSendUsingDma(u32Instance);
        }
#endif
        /* Flush the Tx Buffer */
        LPUART_Uart_FlushTxBuffer(pBase);
        retVal = LPUART_UART_IP_STATUS_SUCCESS;
    }
    return retVal;
}


/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_SyncReceive
 * Description   : Receive multiple bytes of data using polling method.
 *
 * Implements    : Lpuart_Uart_Ip_SyncReceive_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_SyncReceive_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SyncReceive(uint32 u32Instance,
                                                     uint8 *pRxBuff,
                                                     uint32 u32RxSize)
{
    /* Check the validity of the parameters */
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pRxBuff != NULL_PTR);
    LPUART_UART_DEV_ASSERT(u32RxSize > 0U);

    LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    uint32 u32StartTime;
    uint32 u32ElapsedTime;
    uint32 u32TimeoutTicks;
    boolean bIsReturn = FALSE;
    Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);

    SchM_Enter_Uart_UART_EXCLUSIVE_AREA_02();
    /* Check driver is not busy receiving data from a previous asynchronous call */
    if (pUartState->bIsRxBusy)
    {
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_02();
        retVal = LPUART_UART_IP_STATUS_BUSY;
        bIsReturn = TRUE;
    }
    if(!bIsReturn)
    {
        pUartState->bIsRxBusy = TRUE;
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_02();
        pUartState->pRxBuff = pRxBuff;
        pUartState->u32RxSize = u32RxSize;
        pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_BUSY;

        /* Disble  Rx data register full */
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, FALSE);
        /* Enable the LPUART receiver */
        LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, TRUE);

        u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);

        Lpuart_Uart_Ip_StartGetData(pBase, u32Instance, u32StartTime);

        u32ElapsedTime  = OsIf_GetElapsed(&u32StartTime, LPUART_UART_IP_TIMEOUT_TYPE);
        u32TimeoutTicks = OsIf_MicrosToTicks((uint32)LPUART_UART_IP_TIMEOUT_VALUE_US, LPUART_UART_IP_TIMEOUT_TYPE);

        /* Check if Timeout occur */
        if (u32ElapsedTime >= u32TimeoutTicks)
        {
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_TIMEOUT;
        }

        /* Check other success receiving case*/
        if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
        {
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
        }

        if ((pUartState->u32RxSize == 0U) && (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_RX_OVERRUN))
        {
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
        }

        /* Disable the LPUART receiver */
        LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);

        pUartState->bIsRxBusy = FALSE;

        /* Read dummy to clear RDRF flag */
        (void)LPUART_Uart_Getchar(pBase);

        retVal = pUartState->eReceiveStatus;
    }
    return retVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_StartGetData
 * Description   : Start Getting Data in SyncReceive mode
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_StartGetData(LPUART_Type * pBase, uint32 u32Instance, uint32 u32StartTime)
{
        Lpuart_Uart_Ip_StateStructureType * pUartState;
        pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
        while ((pUartState->u32RxSize > 0U) && \
                !LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
        {
            /* Wait until data reception flag is set or timeout occurs if there is an error during reception */
            while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_DATA_REG_FULL)  && \
                   !LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
            {}

            /* Check for errors on received data */
            if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN))
            {
                pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_RX_OVERRUN;
                /* Disable the LPUART receiver */
                LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
                /* Clear the flag */
                LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN);
                break;
            }
            else if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR))
            {
                pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_FRAMING_ERROR;
                /* Disable the LPUART receiver */
                LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
                /* Clear the flag */
                LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR);
                break;
            }
            else if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT))
            {
                pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_NOISE_ERROR;
                /* Disable the LPUART receiver */
                LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
                /* Clear the flag */
                LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT);
                break;
            }
            else if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR))
            {
                pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_PARITY_ERROR;
                /* Disable the LPUART receiver */
                LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
                /* Clear the flag */
                LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR);
                break;
            }
            else
            {
                /* Get received data */
                Lpuart_Uart_Ip_GetData(u32Instance);
            }
        }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_ReceiveData
 * Description   : This function receives data from LPUART module using
 * non-blocking method.  This function returns immediately after initiating the
 * receive function. The application has to get the receive status to see when
 * the receive is complete. In other words, after calling non-blocking get
 * function, the application must get the receive status to check if receive
 * is completed or not.
 *
 * Implements    : Lpuart_Uart_Ip_ReceiveData_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_AsyncReceive_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AsyncReceive(uint32 u32Instance,
                                                      uint8 * pRxBuff,
                                                      uint32 u32RxSize)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pRxBuff != NULL_PTR);
    LPUART_UART_DEV_ASSERT(u32RxSize > 0U);

    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    boolean bIsReturn = FALSE;

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);

    SchM_Enter_Uart_UART_EXCLUSIVE_AREA_03();
    /* Check it's not busy receiving data from a previous function call */
    if (pUartState->bIsRxBusy)
    {
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_03();
        retVal = LPUART_UART_IP_STATUS_BUSY;
        bIsReturn = TRUE;
    }
    if(!bIsReturn)
    {
        pUartState->bIsRxBusy = TRUE;
        SchM_Exit_Uart_UART_EXCLUSIVE_AREA_03();

        LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
        LPUART_UART_DEV_ASSERT((pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS) ||
                   (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_DMA));

        if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
        {
            /* Start the reception process using interrupts */
            retVal = Lpuart_Uart_Ip_StartReceiveDataUsingInt(u32Instance, pRxBuff, u32RxSize);
        }
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
        else
        {
            /* Start the reception process using DMA */
            retVal = Lpuart_Uart_Ip_StartReceiveDataUsingDma(u32Instance, pRxBuff, u32RxSize);
        }
#endif
    }
    return retVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_GetReceiveStatus
 * Description   : This function returns whether the previous LPUART receive is
 * complete. When performing a non-blocking receive, the user can call this
 * function to ascertain the state of the current receive progress: in progress
 * or complete. In addition, if the receive is still in progress, the user can
 * obtain the number of words that have been currently received.
 *
 * Implements    : Lpuart_Uart_Ip_GetReceiveStatus_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_GetReceiveStatus_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_GetReceiveStatus(uint32 u32Instance, uint32 * pBytesRemaining)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
    const Dma_Ip_LogicChannelInfoParamType eDmaLogicChnParam = DMA_IP_CH_GET_CURRENT_ITER_COUNT;
#endif
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
    LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);

    if (pBytesRemaining != NULL_PTR)
    {
        if (pUartState->bIsRxBusy)
        {
            /* Fill in the bytes transferred. */
            if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
            {
                /* In interrupt-based communication, the remaining bytes are retrieved
                 * from the state structure
                 */
                *pBytesRemaining = pUartState->u32RxSize;
            }
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
            else
            {
                /* In DMA-based communication, the remaining bytes are retrieved
                 * from the current DMA major loop count
                 */
                Dma_Ip_GetLogicChannelParam(pUartUserCfg->u8RxDMAChannel, eDmaLogicChnParam, pBytesRemaining);
            }
#endif
        }
        else
        {
            *pBytesRemaining = 0;
        }
    }

    return pUartState->eReceiveStatus;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_AbortReceivingData
 * Description   : Terminates a non-blocking receive early.
 *
 * Implements    : Lpuart_Uart_Ip_AbortReceivingData_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_AbortReceivingData_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AbortReceivingData(uint32 u32Instance)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);

    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
    LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
    boolean bIsReturn = FALSE;
    Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_ERROR;

    /* Check if a transfer is running. */
    if (!pUartState->bIsRxBusy)
    {
        retVal = LPUART_UART_IP_STATUS_SUCCESS;
        bIsReturn = TRUE;
    }

    if(!bIsReturn)
    {
        /* Update the rx status */
        pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_ABORTED;

        /* Stop the running transfer. */
        if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
        {
            Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(u32Instance);
        }
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
        else
        {
            /* Release the DMA channel */
            (void)Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
            Lpuart_Uart_Ip_CompleteReceiveUsingDma(u32Instance);
        }
#endif
        /* Clear all the error flags */
        LPUART_Uart_ClearErrorFlags(pBase);
        /* Flush the Rx Buffer */
        LPUART_Uart_FlushRxBuffer(pBase);
        retVal = LPUART_UART_IP_STATUS_SUCCESS;
    }
    return retVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_SetBaudRate
 * Description   : Configures the LPUART baud rate.
 * In some LPUART instances the user must disable the transmitter/receiver
 * before calling this function.
 * Generally, this may be applied to all LPUARTs to ensure safe operation.
 *
 * Implements    : Lpuart_Uart_Ip_SetBaudRate_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_SetBaudRate_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SetBaudRate(uint32 u32Instance,
                                                     Lpuart_Uart_Ip_BaudrateType u32DesiredBaudrate,
                                                     uint32 u32ClockFrequency)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);

    uint16 sbr, sbrTemp, i;
    uint32 osr, tempDiff, calculatedBaud, baudDiff, maxOsr;
    LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    boolean bIsReturn = FALSE;
    Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_ERROR;

    if (pUartState != NULL_PTR)
    {
        /* Check if there is an ongoing transfer */
        if (pUartState->bIsTxBusy == TRUE)
        {
            retVal = LPUART_UART_IP_STATUS_BUSY;
            bIsReturn = TRUE;
        }
        if ((pUartState->bIsRxBusy == TRUE) && (bIsReturn == FALSE))
        {
            retVal = LPUART_UART_IP_STATUS_BUSY;
            bIsReturn = TRUE;
        }
    }
    if(!bIsReturn)
    {
        /* Check if current instance is clock gated off. */
        LPUART_UART_DEV_ASSERT(u32ClockFrequency > 0U);
        /* Check if the desired baud rate can be configured with the current protocol clock. */
        LPUART_UART_DEV_ASSERT(u32ClockFrequency >= (u32DesiredBaudrate * 5U));

        /* This lpuart instantiation uses a slightly different baud rate calculation
         * The idea is to use the best OSR (over-sampling rate) possible
         * Note, osr is typically hard-set to 16 in other lpuart instantiations
         * First calculate the baud rate using the minimum OSR possible (4) */
        osr = 4;
        sbr = (uint16)(u32ClockFrequency / (u32DesiredBaudrate * osr));
        calculatedBaud = (u32ClockFrequency / (osr * sbr));
        if (calculatedBaud > u32DesiredBaudrate)
        {
            baudDiff = calculatedBaud - u32DesiredBaudrate;
        }
        else
        {
            baudDiff = u32DesiredBaudrate - calculatedBaud;
        }
        /* find maximum osr */
        maxOsr = u32ClockFrequency / u32DesiredBaudrate;
        if (maxOsr > 32U)
        {
            maxOsr = 32U;
        }
        /* loop to find the best osr value possible, one that generates minimum baudDiff
         * iterate through the rest of the supported values of osr */
        if (maxOsr >= 5U)
        {
            for (i = 5U; i <= maxOsr; i++)
            {
                /* calculate the temporary sbr value   */
                sbrTemp = (uint16)(u32ClockFrequency / (u32DesiredBaudrate * i));
                /* calculate the baud rate based on the temporary osr and sbr values */
                calculatedBaud = (u32ClockFrequency / (i * sbrTemp));

                if (calculatedBaud > u32DesiredBaudrate)
                {
                    tempDiff = calculatedBaud - u32DesiredBaudrate;
                }
                else
                {
                    tempDiff = u32DesiredBaudrate - calculatedBaud;
                }

                if (tempDiff <= baudDiff)
                {
                    baudDiff = tempDiff;
                    osr = i;  /* update and store the best osr value calculated */
                    sbr = sbrTemp;  /* update store the best sbr value calculated */
                }
            }
        }
        /* Check if osr is between 4x and 7x oversampling.
         * If so, then "BOTHEDGE" sampling must be turned on */
        if (osr < 8U)
        {
            LPUART_Uart_EnableBothEdgeSamplingCmd(pBase);
        }

        /* program the osr value (bit value is one less than actual value) */
        LPUART_Uart_SetOversamplingRatio(pBase, (osr - 1U));

        /* write the sbr value to the BAUD registers */
        LPUART_Uart_SetBaudRateDivisor(pBase, sbr);

        pUartState->u32BaudRate = calculatedBaud;

        retVal = LPUART_UART_IP_STATUS_SUCCESS;
    }
    return retVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_GetBaudRate
 * Description   : Returns the LPUART configured baud rate.
 *
 * Implements    : Lpuart_Uart_Ip_GetBaudRate_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_GetBaudRate_Activity*/
void Lpuart_Uart_Ip_GetBaudRate(uint32 u32Instance, uint32 * pConfiguredBaudRate)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pConfiguredBaudRate != NULL_PTR);
    Lpuart_Uart_Ip_StateStructureType * pUartState;

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];


    *pConfiguredBaudRate = pUartState->u32BaudRate;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_SetTxBuffer
 * Description   : Sets the driver internal reference to the tx buffer.
 *                 Can be called from the tx callback to provide a different
 *                 buffer for continuous transmission.
 *
 * Implements    : Lpuart_Uart_Ip_SetTxBuffer_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_SetTxBuffer_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SetTxBuffer(uint32 u32Instance,
                                                     const uint8 * pTxBuff,
                                                     uint32 u32TxSize)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pTxBuff != NULL_PTR);
    LPUART_UART_DEV_ASSERT(u32TxSize > 0U);
    Lpuart_Uart_Ip_StateStructureType * pUartState;

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];

    pUartState->pTxBuff = pTxBuff;
    pUartState->u32TxSize = u32TxSize;

    return LPUART_UART_IP_STATUS_SUCCESS;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_SetRxBuffer
 * Description   : Sets the driver internal reference to the rx buffer.
 *                 Can be called from the rx callback to provide a different
 *                 buffer for continuous reception.
 *
 * Implements    : Lpuart_Uart_Ip_SetRxBuffer_Activity
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_SetRxBuffer_Activity*/
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SetRxBuffer(uint32 u32Instance,
                                                     uint8 * pRxBuff,
                                                     uint32 u32RxSize)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
    LPUART_UART_DEV_ASSERT(pRxBuff != NULL_PTR);
    LPUART_UART_DEV_ASSERT(u32RxSize > 0U);
    Lpuart_Uart_Ip_StateStructureType * pUartState;

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartState->pRxBuff = pRxBuff;
    pUartState->u32RxSize = u32RxSize;

    return LPUART_UART_IP_STATUS_SUCCESS;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_IRQHandler
 * Description   : Interrupt handler for LPUART.
 * This handler uses the buffers stored in the Lpuart_Uart_Ip_StateStructureType structs to transfer
 * data. This is not a public API as it is called by IRQ whenever an interrupt
 * occurs.
 *
 *END**************************************************************************/
/* implements     Lpuart_Uart_Ip_IRQHandler_Activity*/
void Lpuart_Uart_Ip_IRQHandler(uint32 u32Instance)
{
    LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);

    LPUART_Type * pBase;
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    boolean bIsReturn = FALSE;
    /* Case of spurious interrupt when driver is not at all initialized or it is not in transmit/receive process*/
    if (pUartState == NULL_PTR)
    {
        /* Read dummy to clear RDRF flag if it is set*/
        (void)LPUART_Uart_Getchar(pBase);
        /* Clear all the error flags */
        LPUART_Uart_ClearErrorFlags(pBase);
        /* Transmit flags can not be cleared, return to exit */
    }
    else
    {
        Lpuart_Uart_Ip_ErrIrqHandler(u32Instance);
        /* Handle receive data full interrupt */
        if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_DATA_REG_FULL))
        {
            if (LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL))
            {
                Lpuart_Uart_Ip_RxIrqHandler(u32Instance);
            }
            /* Case of spurious interrupt when the interupt enable flag is not set and respective interrupt status flag is set */
            else
            {
                /* Read dummy to clear RDRF flag */
                (void)LPUART_Uart_Getchar(pBase);
            }
            bIsReturn = TRUE;
        }
        /* Handle transmitter data register empty interrupt */
        if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_DATA_REG_EMPTY) && (bIsReturn == FALSE))
        {
            if (LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY))
            {
                Lpuart_Uart_Ip_TxEmptyIrqHandler(u32Instance);
                bIsReturn = TRUE;
            }
            /* Case of spurious interrupt when the interupt enable flag is not set and respective interrupt status flag is set */
            else
            {
                /* Do nothing, because TDRE can not clear without affecting to normal operation*/
            }
        }
        /* Handle transmission complete interrupt */
        if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_COMPLETE)  && (bIsReturn == FALSE))
        {
            if (LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE))
            {
                Lpuart_Uart_Ip_TxCompleteIrqHandler(u32Instance);
            }
            /* Case of spurious interrupt when the interupt enable flag is not set and respective interrupt status flag is set */
            else
            {
                /* Do nothing, because TC can not clear without affecting to normal operation*/
            }
        }
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_RxIrqHandler
 * Description   : Rx Interrupt handler for LPUART.
 * This function treats the rx full interrupt.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_RxIrqHandler(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    /* Get data and put in receive buffer  */
    Lpuart_Uart_Ip_GetData(u32Instance);

    /* Check if this was the last byte in the current buffer */
    if (pUartState->u32RxSize == 0U)
    {
        /* Invoke callback if there is one (callback may reset the rx buffer for continuous reception) */
        if (pUartUserCfg->pfRxCallback != NULL_PTR)
        {
            pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_RX_FULL, pUartUserCfg->pRxCallbackParam);
        }
    }

    /* Finish reception if this was the last byte received */
    if (pUartState->u32RxSize == 0U)
    {
        /* Complete transfer (disable rx logic) */
        Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(u32Instance);

        /* Invoke callback if there is one */
        if (pUartUserCfg->pfRxCallback != NULL_PTR)
        {
            pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pRxCallbackParam);
        }
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_TxEmptyIrqHandler
 * Description   : Tx Empty Interrupt handler for LPUART.
 * This function treats the tx empty interrupt.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_TxEmptyIrqHandler(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    /* Check if there are any more bytes to send */
    if (pUartState->u32TxSize > 0U)
    {
        /* Transmit the data */
        Lpuart_Uart_Ip_PutData(u32Instance);

        /* Check if this was the last byte in the current buffer */
        if ((pUartState->u32TxSize == 0U) && (pUartUserCfg->pfTxCallback != NULL_PTR))
        {
            /* Invoke callback if there is one (callback may reset the tx buffer for continuous transmission)*/
            pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_TX_EMPTY, pUartUserCfg->pTxCallbackParam);
        }
        /* If there's no new data, disable tx empty interrupt and enable transmission complete interrupt */
        if (pUartState->u32TxSize == 0U)
        {
            LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
            LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, TRUE);
        }
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_TxCompleteIrqHandler
 * Description   : Tx Complete Interrupt handler for LPUART.
 * This function treats the tx complete interrupt.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_TxCompleteIrqHandler(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;

    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    if (pUartState->u32TxSize == 0U)
    {
        if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
        {
            /* Complete the interrupt based transfer */
            Lpuart_Uart_Ip_CompleteSendDataUsingInt(u32Instance);
        }
        /* Invoke callback if there is one */
        if (pUartUserCfg->pfTxCallback != NULL_PTR)
        {
            pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pTxCallbackParam);
        }
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_ErrIrqHandler
 * Description   : Error Interrupt handler for LPUART.
 * This function treats the error interrupts.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_ErrIrqHandler(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;
    boolean bIsError = FALSE;
    boolean bIsReturn = FALSE;
    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    /* Handle receive overrun interrupt */
    if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN))
    {
        /* Clear the flag */
        LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN);
        /* Case of spurious interrupt when interrupt enable bit is not set*/
        if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN))
        {
            bIsReturn = TRUE;
        }
        else
        {
            /* Update the status */
            bIsError = TRUE;
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_RX_OVERRUN;
        }
    }
    /* Handle framing error interrupt */
    if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR) && (bIsReturn == FALSE))
    {
        /* Clear the flag */
        LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR);
        /* Case of spurious interrupt when interrupt enable bit is not set*/
        if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG))
        {
            bIsReturn = TRUE;
        }
        else
        {
            /* Update the status */
            bIsError = TRUE;
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_FRAMING_ERROR;
        }
    }
    /* Handle parity error interrupt */
    if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR) && (bIsReturn == FALSE))
    {
        /* Clear the flag */
        LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR);
        /* Case of spurious interrupt when interrupt enable bit is not set*/
        if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG))
        {
            bIsReturn = TRUE;
        }
        else
        {
            /* Update the status */
            bIsError = TRUE;
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_PARITY_ERROR;
        }
    }
    /* Handle noise error interrupt */
    if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT) && (bIsReturn == FALSE))
    {
        /* Clear the flag */
        LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT);
        /* Case of spurious interrupt when interrupt enable bit is not set*/
        if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG))
        {
            bIsReturn = TRUE;
        }
        else
        {
            /* Update the internal status */
            bIsError = TRUE;
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_NOISE_ERROR;
        }
    }
    if(bIsReturn == FALSE)
    {
        if (bIsError == TRUE)
        {
            if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
            {
                /* Complete the transfer (disable rx logic) */
                Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(u32Instance);
            }
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
            else
            {
                /* Complete the transfer (stop DMA channel) */
                (void)Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
                Lpuart_Uart_Ip_CompleteReceiveUsingDma(u32Instance);
            }
#endif
            /* Invoke callback if there is one */
            if (pUartUserCfg->pfErrorCallback != NULL_PTR)
            {
                pUartUserCfg->pfErrorCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_ERROR, pUartUserCfg->pErrorCallbackParam);
            }
        }
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_StartSendDataUsingInt
 * Description   : Initiate (start) a transmit by beginning the process of
 * sending data and enabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingInt(uint32 u32Instance,
                                                                      const uint8 * pTxBuff,
                                                                      uint32 u32TxSize)
{
    LPUART_Type * pBase;
    Lpuart_Uart_Ip_StateStructureType * pUartState;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];

    /* initialize the module driver state structure */
    pUartState->pTxBuff = pTxBuff;
    pUartState->u32TxSize = u32TxSize;
    pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_BUSY;

    /* Enable the LPUART transmitter */
    LPUART_Uart_SetTransmitterCmd(pBase, TRUE);

    /* Enable tx empty interrupt */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, TRUE);

    return LPUART_UART_IP_STATUS_SUCCESS;
}

#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_StartSendDataUsingDma
 * Description   : Initiate (start) a transmit by beginning the process of
 * sending data using DMA transfers.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingDma(uint32 u32Instance,
                                                                      const uint8 * pTxBuff,
                                                                      uint32 u32TxSize)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;
    Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
    Dma_Ip_ReturnType eDmaReturnStatus;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
    dmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
    dmaTransferList[0].Value = (uint32)pTxBuff;
    dmaTransferList[1].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
    dmaTransferList[1].Value = LPUART_UART_IP_LSBW_ADDR(pBase->DATA);
    dmaTransferList[2].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
    dmaTransferList[2].Value = 1;
    dmaTransferList[3].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
    dmaTransferList[3].Value = 0;
    dmaTransferList[4].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
    dmaTransferList[4].Value = u32TxSize;
    dmaTransferList[5].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
    dmaTransferList[5].Value = 1;
    dmaTransferList[6].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
    dmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
    dmaTransferList[7].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
    dmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
    dmaTransferList[8].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
    dmaTransferList[8].Value = 1;
    dmaTransferList[9].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
    dmaTransferList[9].Value = 1;

    /* Update state structure */
    pUartState->pTxBuff = pTxBuff;
    pUartState->u32TxSize = 0U;
    pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_BUSY;

    /* Configure the transfer control descriptor for the DMA channel */
    eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8TxDMAChannel, dmaTransferList, LPUART_UART_DMA_CONFIG_LIST_DIMENSION);
    LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);

    /* Start the DMA channel */
    eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
    LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
    /* Enable the LPUART transmitter */
    LPUART_Uart_SetTransmitterCmd(pBase, TRUE);

    /* Enable tx DMA requests for the current instance */
    LPUART_Uart_SetTxDmaCmd(pBase, TRUE);

    return LPUART_UART_IP_STATUS_SUCCESS;
}
#endif

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_CompleteSendDataUsingInt
 * Description   : Finish up a transmit by completing the process of sending
 * data and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_CompleteSendDataUsingInt(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    LPUART_Type * pBase;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];

    if (pUartState->eTransmitStatus == LPUART_UART_IP_STATUS_BUSY)
    {
        /* If the transfer is completed, update the transmit status */
        pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
    }
    else
    {
        /* If the transfer is aborted or timed out, disable tx empty interrupt */
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
    }

    /* Disable transmission complete interrupt */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, FALSE);

    /* Disable transmitter */
    LPUART_Uart_SetTransmitterCmd(pBase, FALSE);

    /* Update the internal busy flag */
    pUartState->bIsTxBusy = FALSE;
}

#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_CompleteSendUsingDma
 * Description   : Finish up a transmit by completing the process of sending
 * data and disabling the DMA requests. This is a callback for DMA major loop
 * completion, so it must match the DMA callback signature.
 *
 *END**************************************************************************/
void Lpuart_Uart_Ip_CompleteSendUsingDma(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;
    Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
    Dma_Ip_ReturnType eDmaReturnStatus;
    Dma_Ip_LogicChannelStatusType dmaStatus;
    uint32 u32StartTime;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    /* Get Dma Ip Logic Channel Status */
    (void)Dma_Ip_GetLogicChannelStatus(pUartUserCfg->u8TxDMAChannel, &dmaStatus);
    if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
    {
        /* Reset the Dma Channel Error status. */
        eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_CLEAR_ERROR);

        LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
        /* Update transmit status */
        pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_ERROR;
        /* Invoke callback if there is one */
        if (pUartUserCfg->pfErrorCallback != NULL_PTR)
        {
            pUartUserCfg->pfErrorCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_ERROR, pUartUserCfg->pErrorCallbackParam);
        }
    }

    /* Invoke the callback when the buffer is finished;
     * Application can provide another buffer inside the callback by calling Lpuart_Uart_Ip_SetTxBuffer */
    if (pUartState->eTransmitStatus == LPUART_UART_IP_STATUS_BUSY)
    {
        /* Invoke callback if there is one (callback may reset the tx buffer for continuous transmission)*/
        if (pUartUserCfg->pfTxCallback != NULL_PTR)
        {
            pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_TX_EMPTY, pUartUserCfg->pTxCallbackParam);
        }
    }

    /* If the callback has updated the tx buffer, update the DMA descriptor to continue the transfer;
     * otherwise, stop the current transfer.
     */
    if ((pUartState->u32TxSize > 0U) && (pUartState->eTransmitStatus != LPUART_UART_IP_STATUS_ERROR))
    {
        /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
        dmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
        dmaTransferList[0].Value = (uint32)(pUartState->pTxBuff);
        /* Update tx size and major loop count parameters for Dma_Ip_LogicChannelTransferListType */
        dmaTransferList[1].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
        dmaTransferList[1].Value = pUartState->u32TxSize;

        /* Re-configure the transfer control descriptor for the DMA channel */
        eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8TxDMAChannel, dmaTransferList, LPUART_UART_DMA_LEAST_CONFIG_LIST_DIMENSION);
        LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);

        /* Now that this tx is set up, clear remaining bytes count */
        pUartState->u32TxSize = 0U;

        /* Re-start the channel */
        eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
        LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
    }
    else
    {
        /* In Abort case, the transmission need to stop instantly */
        if (pUartState->eTransmitStatus != LPUART_UART_IP_STATUS_ABORTED)
        {
            /* Wait until the last transmission complete */
            u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);
            while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_COMPLETE) && \
               !LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
            {}
        }
        /* Disable tx DMA requests for the current instance */
        LPUART_Uart_SetTxDmaCmd(pBase, FALSE);

        /* Disable the transmitter */
        LPUART_Uart_SetTransmitterCmd(pBase, FALSE);

        /* Update the busy flag */
        pUartState->bIsTxBusy = FALSE;

        /* If the current reception hasn't been aborted, update the status */
        if (pUartState->eTransmitStatus == LPUART_UART_IP_STATUS_BUSY)
        {
            pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
            /* Invoke callback if there is one */
            if (pUartUserCfg->pfTxCallback != NULL_PTR)
            {
                pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pTxCallbackParam);
            }
        }
    }
}
#endif

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_StartReceiveDataUsingInt
 * Description   : Initiate (start) a receive by beginning the process of
 * receiving data and enabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingInt(uint32 u32Instance,
                                                                         uint8 * pRxBuff,
                                                                         uint32 u32RxSize)
{
    LPUART_Type * pBase;
    Lpuart_Uart_Ip_StateStructureType * pUartState;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];

    /* Initialize the module driver state struct to indicate transfer in progress
     * and with the buffer and byte count data. */
    pUartState->bIsRxBusy = TRUE;
    pUartState->pRxBuff = pRxBuff;
    pUartState->u32RxSize = u32RxSize;
    pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_BUSY;

    /* Clear all the error flags */
    LPUART_Uart_ClearErrorFlags(pBase);
    /* Flush the Tx Buffer */
    LPUART_Uart_FlushRxBuffer(pBase);

    /* Enable the receiver */
    LPUART_Uart_SetReceiverCmd(pBase, TRUE);

    /* Enable error interrupts */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, TRUE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, TRUE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, TRUE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, TRUE);

    /* Enable receive data full interrupt */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, TRUE);

    return LPUART_UART_IP_STATUS_SUCCESS;
}

#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_StartReceiveDataUsingDma
 * Description   : Initiate (start) a receive by beginning the process of
 * receiving data using DMA transfers.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingDma(uint32 u32Instance,
                                                                         uint8 * pRxBuff,
                                                                         uint32 u32RxSize)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;
    Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
    Dma_Ip_ReturnType eDmaReturnStatus;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    /* Clear all the error flags */
    LPUART_Uart_ClearErrorFlags(pBase);
    /* Flush the Tx Buffer */
    LPUART_Uart_FlushRxBuffer(pBase);

    /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
    dmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
    dmaTransferList[0].Value = LPUART_UART_IP_LSBW_ADDR(pBase->DATA);
    dmaTransferList[1].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
    dmaTransferList[1].Value = (uint32)pRxBuff;
    dmaTransferList[2].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
    dmaTransferList[2].Value = 0;
    dmaTransferList[3].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
    dmaTransferList[3].Value = 1;
    dmaTransferList[4].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
    dmaTransferList[4].Value = u32RxSize;
    dmaTransferList[5].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
    dmaTransferList[5].Value = 1;
    dmaTransferList[6].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
    dmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
    dmaTransferList[7].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
    dmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
    dmaTransferList[8].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
    dmaTransferList[8].Value = 1;
    dmaTransferList[9].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
    dmaTransferList[9].Value = 1;

    /* Update the state structure */
    pUartState->pRxBuff = pRxBuff;
    pUartState->u32RxSize = 0U;
    pUartState->bIsRxBusy = TRUE;
    pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_BUSY;

    /* Configure the transfer control descriptor for the DMA channel */
    eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8RxDMAChannel, dmaTransferList, LPUART_UART_DMA_CONFIG_LIST_DIMENSION);
    LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);

    /* Start the DMA channel */
    eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
    LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);

    /* Enable the receiver */
    LPUART_Uart_SetReceiverCmd(pBase, TRUE);

    /* Enable error interrupts */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, TRUE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, TRUE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, TRUE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, TRUE);

    /* Enable rx DMA requests for the current instance */
    LPUART_Uart_SetRxDmaCmd(pBase, TRUE);

    return LPUART_UART_IP_STATUS_SUCCESS;
}
#endif

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_CompleteReceiveDataUsingInt
 * Description   : Finish up a receive by completing the process of receiving data
 * and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(uint32 u32Instance)
{
    LPUART_Type * pBase;
    Lpuart_Uart_Ip_StateStructureType * pUartState;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];

    /* Disable receiver */
    LPUART_Uart_SetReceiverCmd(pBase, FALSE);

    /* Disable all error interrupts */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, FALSE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, FALSE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, FALSE);
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, FALSE);

    /* Disable receive data full and rx overrun interrupt. */
    LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, FALSE);

    /* Read dummy to clear RDRF flag */
    (void)LPUART_Uart_Getchar(pBase);

    /* Update the information of the module driver state */
    pUartState->bIsRxBusy = FALSE;
    if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
    {
        pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
    }
}

#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_CompleteReceiveUsingDma
 * Description   : Finish up a receive by completing the process of receiving data
 * and disabling the DMA requests. This is a callback for DMA major loop
 * completion, so it must match the DMA callback signature.
 *
 *END**************************************************************************/
void Lpuart_Uart_Ip_CompleteReceiveUsingDma(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;
    Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
    Dma_Ip_ReturnType eDmaReturnStatus;
    Dma_Ip_LogicChannelStatusType dmaStatus;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    /* Get Dma Ip Logic Channel Status */
    (void)Dma_Ip_GetLogicChannelStatus(pUartUserCfg->u8RxDMAChannel, &dmaStatus);

    if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
    {
        /* Reset the Dma Channel Error status. */
        eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_CLEAR_ERROR);

        LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
        /* Update transmit status */
        pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_ERROR;
        /* Invoke callback if there is one */
        if (pUartUserCfg->pfErrorCallback != NULL_PTR)
        {
            pUartUserCfg->pfErrorCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_ERROR, pUartUserCfg->pErrorCallbackParam);
        }
    }

    /* Invoke the callback when the buffer is finished */
    if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
    {
        /* Application can provide another buffer inside the callback by calling Lpuart_Uart_Ip_SetRxBuffer */
        if (pUartUserCfg->pfRxCallback != NULL_PTR)
        {
            pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_RX_FULL, pUartUserCfg->pRxCallbackParam);
        }
    }

    /* If the callback has updated the rx buffer, update the DMA descriptor to continue the transfer;
     * otherwise, stop the current transfer.
     */
    if ((pUartState->u32RxSize > 0U) && (pUartState->eReceiveStatus != LPUART_UART_IP_STATUS_ERROR))
    {
        /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
        dmaTransferList[0].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
        dmaTransferList[0].Value = (uint32)(pUartState->pRxBuff);
        dmaTransferList[1].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
        dmaTransferList[1].Value = pUartState->u32RxSize;

        /* Re-configure the transfer control descriptor for the DMA channel */
        eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8RxDMAChannel, dmaTransferList, LPUART_UART_DMA_LEAST_CONFIG_LIST_DIMENSION);
        LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);

        /* Now that this rx is set up, clear remaining bytes count */
        pUartState->u32RxSize = 0U;

        /* Re-start the channel */
        eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
        LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
    }
    else
    {
        /* Disable receiver */
        LPUART_Uart_SetReceiverCmd(pBase, FALSE);

        /* Disable error interrupts */
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, FALSE);
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, FALSE);
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, FALSE);
        LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, FALSE);

        /* Disable rx DMA requests for the current instance */
        LPUART_Uart_SetRxDmaCmd(pBase, FALSE);

        /* Read dummy to clear RDRF flag */
        (void)LPUART_Uart_Getchar(pBase);

        /* Update the information of the module driver state */
        pUartState->bIsRxBusy = FALSE;

        /* If the current reception hasn't been aborted, update the status and call the callback */
        if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
        {
            pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;

            /* Call the callback to notify application that the transfer is complete */
            if (pUartUserCfg->pfRxCallback != NULL_PTR)
            {
                pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pRxCallbackParam);
            }
        }
    }
}
#endif

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_PutData
 * Description   : Write data to the buffer register, according to configured
 * word length.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_PutData(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;
    uint16 u16Data;
    uint8 u8Data;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    if ((LPUART_UART_IP_7_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar) || (LPUART_UART_IP_8_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar))
    {
        u8Data = *(pUartState->pTxBuff);
        /* Update the state structure */
        ++pUartState->pTxBuff;
        --pUartState->u32TxSize;
        /* Transmit the data */
        LPUART_Uart_Putchar(pBase, u8Data);
    }
    else
    {
        u16Data = (uint16)(*pUartState->pTxBuff);
        /* Update the state structure */
        if(pUartState->u32TxSize == 1U)
        {
            ++pUartState->pTxBuff;
            --pUartState->u32TxSize;
        }
        else
        {
            ++pUartState->pTxBuff;
            u16Data |= (uint16)(((uint16)(*pUartState->pTxBuff)) << 8U);

            ++pUartState->pTxBuff;
            pUartState->u32TxSize -= 2U;
        }

        /* Transmit the data */
        if (pUartUserCfg->eBitCountPerChar == LPUART_UART_IP_9_BITS_PER_CHAR)
        {
            LPUART_Uart_Putchar9(pBase, u16Data);
        }
        else
        {
            LPUART_Uart_Putchar10(pBase, u16Data);
        }
    }
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Lpuart_Uart_Ip_GetData
 * Description   : Read data from the buffer register, according to configured
 * word length.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void Lpuart_Uart_Ip_GetData(uint32 u32Instance)
{
    Lpuart_Uart_Ip_StateStructureType * pUartState;
    const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
    LPUART_Type * pBase;
    uint16 u16Data;

    pBase = Lpuart_Uart_Ip_apBases[u32Instance];
    pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
    pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];

    if ((LPUART_UART_IP_7_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar) || (LPUART_UART_IP_8_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar))
    {
        /* Receive the data */
        *(pUartState->pRxBuff) = LPUART_Uart_Getchar(pBase);
        if (LPUART_UART_IP_7_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar)
        {
            *(pUartState->pRxBuff) &= 0x7FU;
        }
        /* Update the state structure */
        ++pUartState->pRxBuff;
        --pUartState->u32RxSize;
    }
    else
    {
        if (pUartUserCfg->eBitCountPerChar == LPUART_UART_IP_9_BITS_PER_CHAR)
        {
            u16Data = LPUART_Uart_Getchar9(pBase);
        }
        else
        {
            u16Data = LPUART_Uart_Getchar10(pBase);
        }
        /* Get the data and update state structure */
        if(pUartState->u32RxSize == 1U)
        {
            *(pUartState->pRxBuff) = (uint8)u16Data;
            ++pUartState->pRxBuff;
            --pUartState->u32RxSize;
        }
        else
        {
            /* Write the least significant bits to the receive buffer */
            *(pUartState->pRxBuff) = (uint8)(u16Data & 0xFFU);
            ++pUartState->pRxBuff;
            /* Write the ninth bit to the subsequent byte in the rx buffer */
            *pUartState->pRxBuff = (uint8)(u16Data >> 8U);
            ++pUartState->pRxBuff;
            pUartState->u32RxSize -= 2U;
        }
    }
}

#define UART_STOP_SEC_CODE
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
#include "Uart_MemMap.h"

#ifdef __cplusplus
}

/** @} */

#endif
