Example of UART-DMA transfers taken form the npx cmsis driver libary

Dependencies:   mbed

lpc17xx_uart.c

Committer:
dpslwk
Date:
2010-09-30
Revision:
0:7480abd3b63b

File content as of revision 0:7480abd3b63b:

/***********************************************************************//**
 * @file        lpc17xx_uart.c
 * @brief        Contains all functions support for UART firmware library on LPC17xx
 * @version        3.0
 * @date        18. June. 2010
 * @author        NXP MCU SW Application Team
 **************************************************************************
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 **********************************************************************/

/* Peripheral group ----------------------------------------------------------- */
/** @addtogroup UART
 * @{
 */

/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_uart.h"
#include "lpc17xx_clkpwr.h"

/* If this source file built with example, the LPC17xx FW library configuration
 * file in each example directory ("lpc17xx_libcfg.h") must be included,
 * otherwise the default FW library configuration file must be included instead
 */
#ifdef __BUILD_WITH_EXAMPLE__
#include "lpc17xx_libcfg.h"
#else
#include "lpc17xx_libcfg_default.h"
#endif /* __BUILD_WITH_EXAMPLE__ */


#ifdef _UART

/* Private Functions ---------------------------------------------------------- */

static Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate);


/*********************************************************************//**
 * @brief        Determines best dividers to get a target clock rate
 * @param[in]    UARTx    Pointer to selected UART peripheral, should be:
 *                 - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    baudrate Desired UART baud rate.
 * @return         Error status, could be:
 *                 - SUCCESS
 *                 - ERROR
 **********************************************************************/
static Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate)
{
    Status errorStatus = ERROR;

    uint32_t uClk = 0;
    uint32_t calcBaudrate = 0;
    uint32_t temp = 0;

    uint32_t mulFracDiv, dividerAddFracDiv;
    uint32_t diviser = 0 ;
    uint32_t mulFracDivOptimal = 1;
    uint32_t dividerAddOptimal = 0;
    uint32_t diviserOptimal = 0;

    uint32_t relativeError = 0;
    uint32_t relativeOptimalError = 100000;

    /* get UART block clock */
    if (UARTx == (LPC_UART_TypeDef *)LPC_UART0)
    {
        uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART0);
    }
    else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1)
    {
        uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART1);
    }
    else if (UARTx == LPC_UART2)
    {
        uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART2);
    }
    else if (UARTx == LPC_UART3)
    {
        uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART3);
    }


    uClk = uClk >> 4; /* div by 16 */
    /* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers
    * The formula is :
    * BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL)
    * It involves floating point calculations. That's the reason the formulae are adjusted with
    * Multiply and divide method.*/
    /* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
    * 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */
    for (mulFracDiv = 1 ; mulFracDiv <= 15 ;mulFracDiv++)
    {
    for (dividerAddFracDiv = 0 ; dividerAddFracDiv <= 15 ;dividerAddFracDiv++)
    {
      temp = (mulFracDiv * uClk) / ((mulFracDiv + dividerAddFracDiv));

      diviser = temp / baudrate;
      if ((temp % baudrate) > (baudrate / 2))
        diviser++;

      if (diviser > 2 && diviser < 65536)
      {
        calcBaudrate = temp / diviser;

        if (calcBaudrate <= baudrate)
          relativeError = baudrate - calcBaudrate;
        else
          relativeError = calcBaudrate - baudrate;

        if ((relativeError < relativeOptimalError))
        {
          mulFracDivOptimal = mulFracDiv ;
          dividerAddOptimal = dividerAddFracDiv;
          diviserOptimal = diviser;
          relativeOptimalError = relativeError;
          if (relativeError == 0)
            break;
        }
      } /* End of if */
    } /* end of inner for loop */
    if (relativeError == 0)
      break;
    } /* end of outer for loop  */

    if (relativeOptimalError < ((baudrate * UART_ACCEPTED_BAUDRATE_ERROR)/100))
    {
        if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
        {
            ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;
            ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);
            ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);
            /* Then reset DLAB bit */
            ((LPC_UART1_TypeDef *)UARTx)->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
            ((LPC_UART1_TypeDef *)UARTx)->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \
                    | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;
        }
        else
        {
            UARTx->LCR |= UART_LCR_DLAB_EN;
            UARTx->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);
            UARTx->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);
            /* Then reset DLAB bit */
            UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
            UARTx->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \
                    | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;
        }
        errorStatus = SUCCESS;
    }

    return errorStatus;
}

/* End of Private Functions ---------------------------------------------------- */


/* Public Functions ----------------------------------------------------------- */
/** @addtogroup UART_Public_Functions
 * @{
 */
/* UART Init/DeInit functions -------------------------------------------------*/
/********************************************************************//**
 * @brief        Initializes the UARTx peripheral according to the specified
 *               parameters in the UART_ConfigStruct.
 * @param[in]    UARTx    UART peripheral selected, should be:
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    UART_ConfigStruct Pointer to a UART_CFG_Type structure
*                    that contains the configuration information for the
*                    specified UART peripheral.
 * @return         None
 *********************************************************************/
void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct)
{
    uint32_t tmp;

    // For debug mode
    CHECK_PARAM(PARAM_UARTx(UARTx));
    CHECK_PARAM(PARAM_UART_DATABIT(UART_ConfigStruct->Databits));
    CHECK_PARAM(PARAM_UART_STOPBIT(UART_ConfigStruct->Stopbits));
    CHECK_PARAM(PARAM_UART_PARITY(UART_ConfigStruct->Parity));

#ifdef _UART0
    if(UARTx == (LPC_UART_TypeDef *)LPC_UART0)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, ENABLE);
    }
#endif

#ifdef _UART1
    if(((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, ENABLE);
    }
#endif

#ifdef _UART2
    if(UARTx == LPC_UART2)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, ENABLE);
    }
#endif

#ifdef _UART3
    if(UARTx == LPC_UART3)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, ENABLE);
    }
#endif

    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        /* FIFOs are empty */
        ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN \
                | UART_FCR_RX_RS | UART_FCR_TX_RS);
        // Disable FIFO
        ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = 0;

        // Dummy reading
        while (((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_RDR)
        {
            tmp = ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR;
        }

        ((LPC_UART1_TypeDef *)UARTx)->TER = UART_TER_TXEN;
        // Wait for current transmit complete
        while (!(((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_THRE));
        // Disable Tx
        ((LPC_UART1_TypeDef *)UARTx)->TER = 0;

        // Disable interrupt
        ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER = 0;
        // Set LCR to default state
        ((LPC_UART1_TypeDef *)UARTx)->LCR = 0;
        // Set ACR to default state
        ((LPC_UART1_TypeDef *)UARTx)->ACR = 0;
        // Set Modem Control to default state
        ((LPC_UART1_TypeDef *)UARTx)->MCR = 0;
        // Set RS485 control to default state
        ((LPC_UART1_TypeDef *)UARTx)->RS485CTRL = 0;
        // Set RS485 delay timer to default state
        ((LPC_UART1_TypeDef *)UARTx)->RS485DLY = 0;
        // Set RS485 addr match to default state
        ((LPC_UART1_TypeDef *)UARTx)->ADRMATCH = 0;
        //Dummy Reading to Clear Status
        tmp = ((LPC_UART1_TypeDef *)UARTx)->MSR;
        tmp = ((LPC_UART1_TypeDef *)UARTx)->LSR;
    }
    else
    {
        /* FIFOs are empty */
        UARTx->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS);
        // Disable FIFO
        UARTx->/*IIFCR.*/FCR = 0;

        // Dummy reading
        while (UARTx->LSR & UART_LSR_RDR)
        {
            tmp = UARTx->/*RBTHDLR.*/RBR;
        }

        UARTx->TER = UART_TER_TXEN;
        // Wait for current transmit complete
        while (!(UARTx->LSR & UART_LSR_THRE));
        // Disable Tx
        UARTx->TER = 0;

        // Disable interrupt
        UARTx->/*DLIER.*/IER = 0;
        // Set LCR to default state
        UARTx->LCR = 0;
        // Set ACR to default state
        UARTx->ACR = 0;
        // Dummy reading
        tmp = UARTx->LSR;
    }

    if (UARTx == LPC_UART3)
    {
        // Set IrDA to default state
        UARTx->ICR = 0;
    }

    // Set Line Control register ----------------------------

    uart_set_divisors(UARTx, (UART_ConfigStruct->Baud_rate));

    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        tmp = (((LPC_UART1_TypeDef *)UARTx)->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \
                & UART_LCR_BITMASK;
    }
    else
    {
        tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK;
    }

    switch (UART_ConfigStruct->Databits){
    case UART_DATABIT_5:
        tmp |= UART_LCR_WLEN5;
        break;
    case UART_DATABIT_6:
        tmp |= UART_LCR_WLEN6;
        break;
    case UART_DATABIT_7:
        tmp |= UART_LCR_WLEN7;
        break;
    case UART_DATABIT_8:
    default:
        tmp |= UART_LCR_WLEN8;
        break;
    }

    if (UART_ConfigStruct->Parity == UART_PARITY_NONE)
    {
        // Do nothing...
    }
    else
    {
        tmp |= UART_LCR_PARITY_EN;
        switch (UART_ConfigStruct->Parity)
        {
        case UART_PARITY_ODD:
            tmp |= UART_LCR_PARITY_ODD;
            break;

        case UART_PARITY_EVEN:
            tmp |= UART_LCR_PARITY_EVEN;
            break;

        case UART_PARITY_SP_1:
            tmp |= UART_LCR_PARITY_F_1;
            break;

        case UART_PARITY_SP_0:
            tmp |= UART_LCR_PARITY_F_0;
            break;
        default:
            break;
        }
    }

    switch (UART_ConfigStruct->Stopbits){
    case UART_STOPBIT_2:
        tmp |= UART_LCR_STOPBIT_SEL;
        break;
    case UART_STOPBIT_1:
    default:
        // Do no thing
        break;
    }


    // Write back to LCR, configure FIFO and Disable Tx
    if (((LPC_UART1_TypeDef *)UARTx) ==  LPC_UART1)
    {
        ((LPC_UART1_TypeDef *)UARTx)->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
    }
    else
    {
        UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
    }
}

/*********************************************************************//**
 * @brief        De-initializes the UARTx peripheral registers to their
 *                  default reset values.
 * @param[in]    UARTx    UART peripheral selected, should be:
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @return         None
 **********************************************************************/
void UART_DeInit(LPC_UART_TypeDef* UARTx)
{
    // For debug mode
    CHECK_PARAM(PARAM_UARTx(UARTx));

    UART_TxCmd(UARTx, DISABLE);

#ifdef _UART0
    if (UARTx == (LPC_UART_TypeDef *)LPC_UART0)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, DISABLE);
    }
#endif

#ifdef _UART1
    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, DISABLE);
    }
#endif

#ifdef _UART2
    if (UARTx == LPC_UART2)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, DISABLE);
    }
#endif

#ifdef _UART3
    if (UARTx == LPC_UART3)
    {
        /* Set up clock and power for UART module */
        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, DISABLE);
    }
#endif
}

/*****************************************************************************//**
* @brief        Fills each UART_InitStruct member with its default value:
*                 - 9600 bps
*                 - 8-bit data
*                 - 1 Stopbit
*                 - None Parity
* @param[in]    UART_InitStruct Pointer to a UART_CFG_Type structure
*                    which will be initialized.
* @return        None
*******************************************************************************/
void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct)
{
    UART_InitStruct->Baud_rate = 9600;
    UART_InitStruct->Databits = UART_DATABIT_8;
    UART_InitStruct->Parity = UART_PARITY_NONE;
    UART_InitStruct->Stopbits = UART_STOPBIT_1;
}

/* UART Send/Recieve functions -------------------------------------------------*/
/*********************************************************************//**
 * @brief        Transmit a single data through UART peripheral
 * @param[in]    UARTx    UART peripheral selected, should be:
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    Data    Data to transmit (must be 8-bit long)
 * @return         None
 **********************************************************************/
void UART_SendByte(LPC_UART_TypeDef* UARTx, uint8_t Data)
{
    CHECK_PARAM(PARAM_UARTx(UARTx));

    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
    }
    else
    {
        UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
    }

}


/*********************************************************************//**
 * @brief        Receive a single data from UART peripheral
 * @param[in]    UARTx    UART peripheral selected, should be:
 *              - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @return         Data received
 **********************************************************************/
uint8_t UART_ReceiveByte(LPC_UART_TypeDef* UARTx)
{
    CHECK_PARAM(PARAM_UARTx(UARTx));

    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        return (((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);
    }
    else
    {
        return (UARTx->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);
    }
}

/*********************************************************************//**
 * @brief        Send a block of data via UART peripheral
 * @param[in]    UARTx    Selected UART peripheral used to send data, should be:
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    txbuf     Pointer to Transmit buffer
 * @param[in]    buflen     Length of Transmit buffer
 * @param[in]     flag     Flag used in  UART transfer, should be
 *                         NONE_BLOCKING or BLOCKING
 * @return         Number of bytes sent.
 *
 * Note: when using UART in BLOCKING mode, a time-out condition is used
 * via defined symbol UART_BLOCKING_TIMEOUT.
 **********************************************************************/
uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,
        uint32_t buflen, TRANSFER_BLOCK_Type flag)
{
    uint32_t bToSend, bSent, timeOut, fifo_cnt;
    uint8_t *pChar = txbuf;

    bToSend = buflen;

    // blocking mode
    if (flag == BLOCKING) {
        bSent = 0;
        while (bToSend){
            timeOut = UART_BLOCKING_TIMEOUT;
            // Wait for THR empty with timeout
            while (!(UARTx->LSR & UART_LSR_THRE)) {
                if (timeOut == 0) break;
                timeOut--;
            }
            // Time out!
            if(timeOut == 0) break;
            fifo_cnt = UART_TX_FIFO_SIZE;
            while (fifo_cnt && bToSend){
                UART_SendByte(UARTx, (*pChar++));
                fifo_cnt--;
                bToSend--;
                bSent++;
            }
        }
    }
    // None blocking mode
    else {
        bSent = 0;
        while (bToSend) {
            if (!(UARTx->LSR & UART_LSR_THRE)){
                break;
            }
            fifo_cnt = UART_TX_FIFO_SIZE;
            while (fifo_cnt && bToSend) {
                UART_SendByte(UARTx, (*pChar++));
                bToSend--;
                fifo_cnt--;
                bSent++;
            }
        }
    }
    return bSent;
}

/*********************************************************************//**
 * @brief        Receive a block of data via UART peripheral
 * @param[in]    UARTx    Selected UART peripheral used to send data,
 *                 should be:
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[out]    rxbuf     Pointer to Received buffer
 * @param[in]    buflen     Length of Received buffer
 * @param[in]     flag     Flag mode, should be NONE_BLOCKING or BLOCKING

 * @return         Number of bytes received
 *
 * Note: when using UART in BLOCKING mode, a time-out condition is used
 * via defined symbol UART_BLOCKING_TIMEOUT.
 **********************************************************************/
uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \
        uint32_t buflen, TRANSFER_BLOCK_Type flag)
{
    uint32_t bToRecv, bRecv, timeOut;
    uint8_t *pChar = rxbuf;

    bToRecv = buflen;

    // Blocking mode
    if (flag == BLOCKING) {
        bRecv = 0;
        while (bToRecv){
            timeOut = UART_BLOCKING_TIMEOUT;
            while (!(UARTx->LSR & UART_LSR_RDR)){
                if (timeOut == 0) break;
                timeOut--;
            }
            // Time out!
            if(timeOut == 0) break;
            // Get data from the buffer
            (*pChar++) = UART_ReceiveByte(UARTx);
            bToRecv--;
            bRecv++;
        }
    }
    // None blocking mode
    else {
        bRecv = 0;
        while (bToRecv) {
            if (!(UARTx->LSR & UART_LSR_RDR)) {
                break;
            } else {
                (*pChar++) = UART_ReceiveByte(UARTx);
                bRecv++;
                bToRecv--;
            }
        }
    }
    return bRecv;
}

/*********************************************************************//**
 * @brief        Force BREAK character on UART line, output pin UARTx TXD is
                forced to logic 0.
 * @param[in]    UARTx    UART peripheral selected, should be:
 *              - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @return         None
 **********************************************************************/
void UART_ForceBreak(LPC_UART_TypeDef* UARTx)
{
    CHECK_PARAM(PARAM_UARTx(UARTx));

    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_BREAK_EN;
    }
    else
    {
        UARTx->LCR |= UART_LCR_BREAK_EN;
    }
}


/********************************************************************//**
 * @brief         Enable or disable specified UART interrupt.
 * @param[in]    UARTx    UART peripheral selected, should be
 *              - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    UARTIntCfg    Specifies the interrupt flag,
 *                 should be one of the following:
                - UART_INTCFG_RBR     :  RBR Interrupt enable
                - UART_INTCFG_THRE     :  THR Interrupt enable
                - UART_INTCFG_RLS     :  RX line status interrupt enable
                - UART1_INTCFG_MS    :  Modem status interrupt enable (UART1 only)
                - UART1_INTCFG_CTS    :  CTS1 signal transition interrupt enable (UART1 only)
                - UART_INTCFG_ABEO     :  Enables the end of auto-baud interrupt
                - UART_INTCFG_ABTO     :  Enables the auto-baud time-out interrupt
 * @param[in]    NewState New state of specified UART interrupt type,
 *                 should be:
 *                 - ENALBE: Enable this UART interrupt type.
*                 - DISALBE: Disable this UART interrupt type.
 * @return         None
 *********************************************************************/
void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, FunctionalState NewState)
{
    uint32_t tmp = 0;

    CHECK_PARAM(PARAM_UARTx(UARTx));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));

    switch(UARTIntCfg){
        case UART_INTCFG_RBR:
            tmp = UART_IER_RBRINT_EN;
            break;
        case UART_INTCFG_THRE:
            tmp = UART_IER_THREINT_EN;
            break;
        case UART_INTCFG_RLS:
            tmp = UART_IER_RLSINT_EN;
            break;
        case UART1_INTCFG_MS:
            tmp = UART1_IER_MSINT_EN;
            break;
        case UART1_INTCFG_CTS:
            tmp = UART1_IER_CTSINT_EN;
            break;
        case UART_INTCFG_ABEO:
            tmp = UART_IER_ABEOINT_EN;
            break;
        case UART_INTCFG_ABTO:
            tmp = UART_IER_ABTOINT_EN;
            break;
    }

    if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
    {
        CHECK_PARAM((PARAM_UART_INTCFG(UARTIntCfg)) || (PARAM_UART1_INTCFG(UARTIntCfg)));
    }
    else
    {
        CHECK_PARAM(PARAM_UART_INTCFG(UARTIntCfg));
    }

    if (NewState == ENABLE)
    {
        if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
        {
            ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER |= tmp;
        }
        else
        {
            UARTx->/*DLIER.*/IER |= tmp;
        }
    }
    else
    {
        if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
        {
            ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER &= (~tmp) & UART1_IER_BITMASK;
        }
        else
        {
            UARTx->/*DLIER.*/IER &= (~tmp) & UART_IER_BITMASK;
        }
    }
}


/********************************************************************//**
 * @brief         Get current value of Line Status register in UART peripheral.
 * @param[in]    UARTx    UART peripheral selected, should be:
 *              - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @return        Current value of Line Status register in UART peripheral.
 * Note:    The return value of this function must be ANDed with each member in
 *             UART_LS_Type enumeration to determine current flag status
 *             corresponding to each Line status type. Because some flags in
 *             Line Status register will be cleared after reading, the next reading
 *             Line Status register could not be correct. So this function used to
 *             read Line status register in one time only, then the return value
 *             used to check all flags.
 *********************************************************************/
uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx)
{
    CHECK_PARAM(PARAM_UARTx(UARTx));

    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        return ((((LPC_UART1_TypeDef *)LPC_UART1)->LSR) & UART_LSR_BITMASK);
    }
    else
    {
        return ((UARTx->LSR) & UART_LSR_BITMASK);
    }
}

/********************************************************************//**
 * @brief         Get Interrupt Identification value
 * @param[in]    UARTx    UART peripheral selected, should be:
 *              - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @return        Current value of UART UIIR register in UART peripheral.
 *********************************************************************/
uint32_t UART_GetIntId(LPC_UART_TypeDef* UARTx)
{
    CHECK_PARAM(PARAM_UARTx(UARTx));
    return (UARTx->IIR & 0x03CF);
}

/*********************************************************************//**
 * @brief        Check whether if UART is busy or not
 * @param[in]    UARTx    UART peripheral selected, should be:
 *              - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @return        RESET if UART is not busy, otherwise return SET.
 **********************************************************************/
FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx)
{
    if (UARTx->LSR & UART_LSR_TEMT){
        return RESET;
    } else {
        return SET;
    }
}


/*********************************************************************//**
 * @brief        Configure FIFO function on selected UART peripheral
 * @param[in]    UARTx    UART peripheral selected, should be:
 *              - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    FIFOCfg    Pointer to a UART_FIFO_CFG_Type Structure that
 *                         contains specified information about FIFO configuration
 * @return         none
 **********************************************************************/
void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg)
{
    uint8_t tmp = 0;

    CHECK_PARAM(PARAM_UARTx(UARTx));
    CHECK_PARAM(PARAM_UART_FIFO_LEVEL(FIFOCfg->FIFO_Level));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_DMAMode));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetRxBuf));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetTxBuf));

    tmp |= UART_FCR_FIFO_EN;
    switch (FIFOCfg->FIFO_Level){
    case UART_FIFO_TRGLEV0:
        tmp |= UART_FCR_TRG_LEV0;
        break;
    case UART_FIFO_TRGLEV1:
        tmp |= UART_FCR_TRG_LEV1;
        break;
    case UART_FIFO_TRGLEV2:
        tmp |= UART_FCR_TRG_LEV2;
        break;
    case UART_FIFO_TRGLEV3:
    default:
        tmp |= UART_FCR_TRG_LEV3;
        break;
    }

    if (FIFOCfg->FIFO_ResetTxBuf == ENABLE)
    {
        tmp |= UART_FCR_TX_RS;
    }
    if (FIFOCfg->FIFO_ResetRxBuf == ENABLE)
    {
        tmp |= UART_FCR_RX_RS;
    }
    if (FIFOCfg->FIFO_DMAMode == ENABLE)
    {
        tmp |= UART_FCR_DMAMODE_SEL;
    }


    //write to FIFO control register
    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;
    }
    else
    {
        UARTx->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;
    }
}

/*****************************************************************************//**
* @brief        Fills each UART_FIFOInitStruct member with its default value:
*                 - FIFO_DMAMode = DISABLE
*                 - FIFO_Level = UART_FIFO_TRGLEV0
*                 - FIFO_ResetRxBuf = ENABLE
*                 - FIFO_ResetTxBuf = ENABLE
*                 - FIFO_State = ENABLE

* @param[in]    UART_FIFOInitStruct Pointer to a UART_FIFO_CFG_Type structure
*                    which will be initialized.
* @return        None
*******************************************************************************/
void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct)
{
    UART_FIFOInitStruct->FIFO_DMAMode = DISABLE;
    UART_FIFOInitStruct->FIFO_Level = UART_FIFO_TRGLEV0;
    UART_FIFOInitStruct->FIFO_ResetRxBuf = ENABLE;
    UART_FIFOInitStruct->FIFO_ResetTxBuf = ENABLE;
}


/*********************************************************************//**
 * @brief        Start/Stop Auto Baudrate activity
 * @param[in]    UARTx    UART peripheral selected, should be
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    ABConfigStruct    A pointer to UART_AB_CFG_Type structure that
 *                                 contains specified information about UART
 *                                 auto baudrate configuration
 * @param[in]    NewState New State of Auto baudrate activity, should be:
 *                 - ENABLE: Start this activity
 *                - DISABLE: Stop this activity
 * Note:        Auto-baudrate mode enable bit will be cleared once this mode
 *                 completed.
 * @return         none
 **********************************************************************/
void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \
                FunctionalState NewState)
{
    uint32_t tmp;

    CHECK_PARAM(PARAM_UARTx(UARTx));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));

    tmp = 0;
    if (NewState == ENABLE) {
        if (ABConfigStruct->ABMode == UART_AUTOBAUD_MODE1){
            tmp |= UART_ACR_MODE;
        }
        if (ABConfigStruct->AutoRestart == ENABLE){
            tmp |= UART_ACR_AUTO_RESTART;
        }
    }

    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        if (NewState == ENABLE)
        {
            // Clear DLL and DLM value
            ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;
            ((LPC_UART1_TypeDef *)UARTx)->DLL = 0;
            ((LPC_UART1_TypeDef *)UARTx)->DLM = 0;
            ((LPC_UART1_TypeDef *)UARTx)->LCR &= ~UART_LCR_DLAB_EN;
            // FDR value must be reset to default value
            ((LPC_UART1_TypeDef *)UARTx)->FDR = 0x10;
            ((LPC_UART1_TypeDef *)UARTx)->ACR = UART_ACR_START | tmp;
        }
        else
        {
            ((LPC_UART1_TypeDef *)UARTx)->ACR = 0;
        }
    }
    else
    {
        if (NewState == ENABLE)
        {
            // Clear DLL and DLM value
            UARTx->LCR |= UART_LCR_DLAB_EN;
            UARTx->DLL = 0;
            UARTx->DLM = 0;
            UARTx->LCR &= ~UART_LCR_DLAB_EN;
            // FDR value must be reset to default value
            UARTx->FDR = 0x10;
            UARTx->ACR = UART_ACR_START | tmp;
        }
        else
        {
            UARTx->ACR = 0;
        }
    }
}

/*********************************************************************//**
 * @brief        Clear Autobaud Interrupt Pending
 * @param[in]    UARTx    UART peripheral selected, should be
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    ABIntType    type of auto-baud interrupt, should be:
 *                 - UART_AUTOBAUD_INTSTAT_ABEO: End of Auto-baud interrupt
 *                 - UART_AUTOBAUD_INTSTAT_ABTO: Auto-baud time out interrupt
 * @return         none
 **********************************************************************/
void UART_ABClearIntPending(LPC_UART_TypeDef *UARTx, UART_ABEO_Type ABIntType)
{
    CHECK_PARAM(PARAM_UARTx(UARTx));
    if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
    {
        UARTx->ACR |= ABIntType;
    }
    else
        UARTx->ACR |= ABIntType;
}

/*********************************************************************//**
 * @brief        Enable/Disable transmission on UART TxD pin
 * @param[in]    UARTx    UART peripheral selected, should be:
 *               - LPC_UART0: UART0 peripheral
 *                 - LPC_UART1: UART1 peripheral
 *                 - LPC_UART2: UART2 peripheral
 *                 - LPC_UART3: UART3 peripheral
 * @param[in]    NewState New State of Tx transmission function, should be:
 *                 - ENABLE: Enable this function
                - DISABLE: Disable this function
 * @return none
 **********************************************************************/
void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState)
{
    CHECK_PARAM(PARAM_UARTx(UARTx));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));

    if (NewState == ENABLE)
    {
        if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
        {
            ((LPC_UART1_TypeDef *)UARTx)->TER |= UART_TER_TXEN;
        }
        else
        {
            UARTx->TER |= UART_TER_TXEN;
        }
    }
    else
    {
        if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
        {
            ((LPC_UART1_TypeDef *)UARTx)->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;
        }
        else
        {
            UARTx->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;
        }
    }
}

/* UART IrDA functions ---------------------------------------------------*/

#ifdef _UART3

/*********************************************************************//**
 * @brief        Enable or disable inverting serial input function of IrDA
 *                 on UART peripheral.
 * @param[in]    UARTx UART peripheral selected, should be LPC_UART3 (only)
 * @param[in]    NewState New state of inverting serial input, should be:
 *                 - ENABLE: Enable this function.
 *                 - DISABLE: Disable this function.
 * @return none
 **********************************************************************/
void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)
{
    CHECK_PARAM(PARAM_UART_IrDA(UARTx));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));

    if (NewState == ENABLE)
    {
        UARTx->ICR |= UART_ICR_IRDAINV;
    }
    else if (NewState == DISABLE)
    {
        UARTx->ICR &= (~UART_ICR_IRDAINV) & UART_ICR_BITMASK;
    }
}


/*********************************************************************//**
 * @brief        Enable or disable IrDA function on UART peripheral.
 * @param[in]    UARTx UART peripheral selected, should be LPC_UART3 (only)
 * @param[in]    NewState New state of IrDA function, should be:
 *                 - ENABLE: Enable this function.
 *                 - DISABLE: Disable this function.
 * @return none
 **********************************************************************/
void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)
{
    CHECK_PARAM(PARAM_UART_IrDA(UARTx));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));

    if (NewState == ENABLE)
    {
        UARTx->ICR |= UART_ICR_IRDAEN;
    }
    else
    {
        UARTx->ICR &= (~UART_ICR_IRDAEN) & UART_ICR_BITMASK;
    }
}


/*********************************************************************//**
 * @brief        Configure Pulse divider for IrDA function on UART peripheral.
 * @param[in]    UARTx UART peripheral selected, should be LPC_UART3 (only)
 * @param[in]    PulseDiv Pulse Divider value from Peripheral clock,
 *                 should be one of the following:
                - UART_IrDA_PULSEDIV2     : Pulse width = 2 * Tpclk
                - UART_IrDA_PULSEDIV4     : Pulse width = 4 * Tpclk
                - UART_IrDA_PULSEDIV8     : Pulse width = 8 * Tpclk
                - UART_IrDA_PULSEDIV16     : Pulse width = 16 * Tpclk
                - UART_IrDA_PULSEDIV32     : Pulse width = 32 * Tpclk
                - UART_IrDA_PULSEDIV64     : Pulse width = 64 * Tpclk
                - UART_IrDA_PULSEDIV128 : Pulse width = 128 * Tpclk
                - UART_IrDA_PULSEDIV256 : Pulse width = 256 * Tpclk

 * @return none
 **********************************************************************/
void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv)
{
    uint32_t tmp, tmp1;
    CHECK_PARAM(PARAM_UART_IrDA(UARTx));
    CHECK_PARAM(PARAM_UART_IrDA_PULSEDIV(PulseDiv));

    tmp1 = UART_ICR_PULSEDIV(PulseDiv);
    tmp = UARTx->ICR & (~UART_ICR_PULSEDIV(7));
    tmp |= tmp1 | UART_ICR_FIXPULSE_EN;
    UARTx->ICR = tmp & UART_ICR_BITMASK;
}

#endif


/* UART1 FullModem function ---------------------------------------------*/

#ifdef _UART1

/*********************************************************************//**
 * @brief        Force pin DTR/RTS corresponding to given state (Full modem mode)
 * @param[in]    UARTx    LPC_UART1 (only)
 * @param[in]    Pin    Pin that NewState will be applied to, should be:
 *                 - UART1_MODEM_PIN_DTR: DTR pin.
 *                 - UART1_MODEM_PIN_RTS: RTS pin.
 * @param[in]    NewState New State of DTR/RTS pin, should be:
 *                 - INACTIVE: Force the pin to inactive signal.
                - ACTIVE: Force the pin to active signal.
 * @return none
 **********************************************************************/
void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \
                            UART1_SignalState NewState)
{
    uint8_t tmp = 0;

    CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
    CHECK_PARAM(PARAM_UART1_MODEM_PIN(Pin));
    CHECK_PARAM(PARAM_UART1_SIGNALSTATE(NewState));

    switch (Pin){
    case UART1_MODEM_PIN_DTR:
        tmp = UART1_MCR_DTR_CTRL;
        break;
    case UART1_MODEM_PIN_RTS:
        tmp = UART1_MCR_RTS_CTRL;
        break;
    default:
        break;
    }

    if (NewState == ACTIVE){
        UARTx->MCR |= tmp;
    } else {
        UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;
    }
}


/*********************************************************************//**
 * @brief        Configure Full Modem mode for UART peripheral
 * @param[in]    UARTx    LPC_UART1 (only)
 * @param[in]    Mode Full Modem mode, should be:
 *                 - UART1_MODEM_MODE_LOOPBACK: Loop back mode.
 *                 - UART1_MODEM_MODE_AUTO_RTS: Auto-RTS mode.
 *                 - UART1_MODEM_MODE_AUTO_CTS: Auto-CTS mode.
 * @param[in]    NewState New State of this mode, should be:
 *                 - ENABLE: Enable this mode.
                - DISABLE: Disable this mode.
 * @return none
 **********************************************************************/
void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \
                            FunctionalState NewState)
{
    uint8_t tmp = 0;

    CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
    CHECK_PARAM(PARAM_UART1_MODEM_MODE(Mode));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));

    switch(Mode){
    case UART1_MODEM_MODE_LOOPBACK:
        tmp = UART1_MCR_LOOPB_EN;
        break;
    case UART1_MODEM_MODE_AUTO_RTS:
        tmp = UART1_MCR_AUTO_RTS_EN;
        break;
    case UART1_MODEM_MODE_AUTO_CTS:
        tmp = UART1_MCR_AUTO_CTS_EN;
        break;
    default:
        break;
    }

    if (NewState == ENABLE)
    {
        UARTx->MCR |= tmp;
    }
    else
    {
        UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;
    }
}


/*********************************************************************//**
 * @brief        Get current status of modem status register
 * @param[in]    UARTx    LPC_UART1 (only)
 * @return         Current value of modem status register
 * Note:    The return value of this function must be ANDed with each member
 *             UART_MODEM_STAT_type enumeration to determine current flag status
 *             corresponding to each modem flag status. Because some flags in
 *             modem status register will be cleared after reading, the next reading
 *             modem register could not be correct. So this function used to
 *             read modem status register in one time only, then the return value
 *             used to check all flags.
 **********************************************************************/
uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx)
{
    CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
    return ((UARTx->MSR) & UART1_MSR_BITMASK);
}


/* UART RS485 functions --------------------------------------------------------------*/

/*********************************************************************//**
 * @brief        Configure UART peripheral in RS485 mode according to the specified
*               parameters in the RS485ConfigStruct.
 * @param[in]    UARTx    LPC_UART1 (only)
 * @param[in]    RS485ConfigStruct Pointer to a UART1_RS485_CTRLCFG_Type structure
*                    that contains the configuration information for specified UART
*                    in RS485 mode.
 * @return        None
 **********************************************************************/
void UART_RS485Config(LPC_UART1_TypeDef *UARTx, UART1_RS485_CTRLCFG_Type *RS485ConfigStruct)
{
    uint32_t tmp;

    CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoAddrDetect_State));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoDirCtrl_State));
    CHECK_PARAM(PARAM_UART1_RS485_CFG_DELAYVALUE(RS485ConfigStruct->DelayValue));
    CHECK_PARAM(PARAM_SETSTATE(RS485ConfigStruct->DirCtrlPol_Level));
    CHECK_PARAM(PARAM_UART_RS485_DIRCTRL_PIN(RS485ConfigStruct->DirCtrlPin));
    CHECK_PARAM(PARAM_UART1_RS485_CFG_MATCHADDRVALUE(RS485ConfigStruct->MatchAddrValue));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->NormalMultiDropMode_State));
    CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->Rx_State));

    tmp = 0;
    // If Auto Direction Control is enabled -  This function is used in Master mode
    if (RS485ConfigStruct->AutoDirCtrl_State == ENABLE)
    {
        tmp |= UART1_RS485CTRL_DCTRL_EN;

        // Set polar
        if (RS485ConfigStruct->DirCtrlPol_Level == SET)
        {
            tmp |= UART1_RS485CTRL_OINV_1;
        }

        // Set pin according to
        if (RS485ConfigStruct->DirCtrlPin == UART1_RS485_DIRCTRL_DTR)
        {
            tmp |= UART1_RS485CTRL_SEL_DTR;
        }

        // Fill delay time
        UARTx->RS485DLY = RS485ConfigStruct->DelayValue & UART1_RS485DLY_BITMASK;
    }

    // MultiDrop mode is enable
    if (RS485ConfigStruct->NormalMultiDropMode_State == ENABLE)
    {
        tmp |= UART1_RS485CTRL_NMM_EN;
    }

    // Auto Address Detect function
    if (RS485ConfigStruct->AutoAddrDetect_State == ENABLE)
    {
        tmp |= UART1_RS485CTRL_AADEN;
        // Fill Match Address
        UARTx->ADRMATCH = RS485ConfigStruct->MatchAddrValue & UART1_RS485ADRMATCH_BITMASK;
    }


    // Receiver is disable
    if (RS485ConfigStruct->Rx_State == DISABLE)
    {
        tmp |= UART1_RS485CTRL_RX_DIS;
    }

    // write back to RS485 control register
    UARTx->RS485CTRL = tmp & UART1_RS485CTRL_BITMASK;

    // Enable Parity function and leave parity in stick '0' parity as default
    UARTx->LCR |= (UART_LCR_PARITY_F_0 | UART_LCR_PARITY_EN);
}

/*********************************************************************//**
 * @brief        Enable/Disable receiver in RS485 module in UART1
 * @param[in]    UARTx    LPC_UART1 (only)
 * @param[in]    NewState    New State of command, should be:
 *                             - ENABLE: Enable this function.
 *                             - DISABLE: Disable this function.
 * @return        None
 **********************************************************************/
void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState)
{
    if (NewState == ENABLE){
        UARTx->RS485CTRL &= ~UART1_RS485CTRL_RX_DIS;
    } else {
        UARTx->RS485CTRL |= UART1_RS485CTRL_RX_DIS;
    }
}

/*********************************************************************//**
 * @brief        Send data on RS485 bus with specified parity stick value (9-bit mode).
 * @param[in]    UARTx    LPC_UART1 (only)
 * @param[in]    pDatFrm     Pointer to data frame.
 * @param[in]    size        Size of data.
 * @param[in]    ParityStick    Parity Stick value, should be 0 or 1.
 * @return        None
 **********************************************************************/
uint32_t UART_RS485Send(LPC_UART1_TypeDef *UARTx, uint8_t *pDatFrm, \
                    uint32_t size, uint8_t ParityStick)
{
    uint8_t tmp, save;
    uint32_t cnt;

    if (ParityStick){
        save = tmp = UARTx->LCR & UART_LCR_BITMASK;
        tmp &= ~(UART_LCR_PARITY_EVEN);
        UARTx->LCR = tmp;
        cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);
        while (!(UARTx->LSR & UART_LSR_TEMT));
        UARTx->LCR = save;
    } else {
        cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);
        while (!(UARTx->LSR & UART_LSR_TEMT));
    }
    return cnt;
}

/*********************************************************************//**
 * @brief        Send Slave address frames on RS485 bus.
 * @param[in]    UARTx    LPC_UART1 (only)
 * @param[in]    SlvAddr Slave Address.
 * @return        None
 **********************************************************************/
void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr)
{
    UART_RS485Send(UARTx, &SlvAddr, 1, 1);
}

/*********************************************************************//**
 * @brief        Send Data frames on RS485 bus.
 * @param[in]    UARTx    LPC_UART1 (only)
 * @param[in]    pData Pointer to data to be sent.
 * @param[in]    size Size of data frame to be sent.
 * @return        None
 **********************************************************************/
uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size)
{
    return (UART_RS485Send(UARTx, pData, size, 0));
}

#endif /* _UART1 */

#endif /* _UART */

/**
 * @}
 */

/**
 * @}
 */
/* --------------------------------- End Of File ------------------------------ */