NXP's driver library for LPC17xx, ported to mbed's online compiler. Not tested! I had to fix a lot of warings and found a couple of pretty obvious bugs, so the chances are there are more. Original: http://ics.nxp.com/support/documents/microcontrollers/zip/lpc17xx.cmsis.driver.library.zip

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lpc17xx_uart.c Source File

lpc17xx_uart.c

Go to the documentation of this file.
00001 /**
00002  * @file    : lpc17xx_uart.c
00003  * @brief    : Contains all functions support for UART firmware library on LPC17xx
00004  * @version    : 1.0
00005  * @date    : 18. Mar. 2009
00006  * @author    : HieuNguyen
00007  **************************************************************************
00008  * Software that is described herein is for illustrative purposes only
00009  * which provides customers with programming information regarding the
00010  * products. This software is supplied "AS IS" without any warranties.
00011  * NXP Semiconductors assumes no responsibility or liability for the
00012  * use of the software, conveys no license or title under any patent,
00013  * copyright, or mask work right to the product. NXP Semiconductors
00014  * reserves the right to make changes in the software without
00015  * notification. NXP Semiconductors also make no representation or
00016  * warranty that such application will be suitable for the specified
00017  * use without further testing or modification.
00018  **********************************************************************/
00019 
00020 /* Peripheral group ----------------------------------------------------------- */
00021 /** @addtogroup UART
00022  * @{
00023  */
00024 
00025 /* Includes ------------------------------------------------------------------- */
00026 #include "lpc17xx_uart.h"
00027 #include "lpc17xx_clkpwr.h"
00028 
00029 /* If this source file built with example, the LPC17xx FW library configuration
00030  * file in each example directory ("lpc17xx_libcfg.h") must be included,
00031  * otherwise the default FW library configuration file must be included instead
00032  */
00033 #ifdef __BUILD_WITH_EXAMPLE__
00034 #include "lpc17xx_libcfg.h"
00035 #else
00036 #include "lpc17xx_libcfg_default.h"
00037 #endif /* __BUILD_WITH_EXAMPLE__ */
00038 
00039 
00040 #ifdef _UART
00041 
00042 /* Private Types -------------------------------------------------------------- */
00043 /** @defgroup UART_Private_Types
00044  * @{
00045  */
00046 
00047 /**
00048  * @brief UART call-back function type definitions
00049  */
00050 typedef struct {
00051     fnTxCbs_Type *pfnTxCbs;     // Transmit callback
00052     fnRxCbs_Type *pfnRxCbs;        // Receive callback
00053     fnABCbs_Type *pfnABCbs;        // Auto-Baudrate callback
00054     fnErrCbs_Type *pfnErrCbs;    // Error callback
00055 } UART_CBS_Type;
00056 
00057 /**
00058  * @}
00059  */
00060 
00061 
00062 /* Private Variables ---------------------------------------------------------- */
00063 /** @defgroup UART_Private_Variables
00064  * @{
00065  */
00066 
00067 
00068 /** Call-back function pointer data */
00069 UART_CBS_Type uartCbsDat[4] = {
00070         {NULL, NULL, NULL, NULL},
00071         {NULL, NULL, NULL, NULL},
00072         {NULL, NULL, NULL, NULL},
00073         {NULL, NULL, NULL, NULL},
00074 };
00075 
00076 /** UART1 modem status interrupt callback pointer data */
00077 fnModemCbs_Type *pfnModemCbs = NULL;
00078 
00079 /**
00080  * @}
00081  */
00082 
00083 
00084 /* Private Functions ---------------------------------------------------------- */
00085 /** @defgroup UART_Private_Functions
00086  * @{
00087  */
00088 
00089 /**
00090  * @brief        Get UART number due to UART peripheral pointer
00091  * @param[in]    UARTx    UART pointer
00092  * @return        UART number
00093  */
00094 uint8_t getUartNum(LPC_UART_TypeDef *UARTx) {
00095     if (UARTx == (LPC_UART_TypeDef *)LPC_UART0) return (0);
00096     else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1) return (1);
00097     else if (UARTx == LPC_UART2) return (2);
00098     else return (3);
00099 }
00100 
00101 /*********************************************************************//**
00102  * @brief        Determines best dividers to get a target clock rate
00103  * @param[in]    UARTx    Pointer to selected UART peripheral, should be
00104  *                         UART0, UART1, UART2 or UART3.
00105  * @param[in]    baudrate Desired UART baud rate.
00106  * @return         Error status.
00107  **********************************************************************/
00108 
00109 Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate)
00110 {
00111     Status errorStatus = ERROR;
00112 
00113     uint32_t uClk=0;
00114     uint32_t calcBaudrate = 0;
00115     uint32_t temp = 0;
00116 
00117     uint32_t mulFracDiv, dividerAddFracDiv;
00118     uint32_t diviser = 0 ;
00119     uint32_t mulFracDivOptimal = 1;
00120     uint32_t dividerAddOptimal = 0;
00121     uint32_t diviserOptimal = 0;
00122 
00123     uint32_t relativeError = 0;
00124     uint32_t relativeOptimalError = 100000;
00125 
00126     /* get UART block clock */
00127     if (UARTx == (LPC_UART_TypeDef *)LPC_UART0)
00128     {
00129         uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART0);
00130     }
00131     else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1)
00132     {
00133         uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART1);
00134     }
00135     else if (UARTx == LPC_UART2)
00136     {
00137         uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART2);
00138     }
00139     else if (UARTx == LPC_UART3)
00140     {
00141         uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART3);
00142     }
00143 
00144 
00145     uClk = uClk >> 4; /* div by 16 */
00146     /* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers
00147     * The formula is :
00148     * BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL)
00149     * It involves floating point calculations. That's the reason the formulae are adjusted with
00150     * Multiply and divide method.*/
00151     /* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
00152     * 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */
00153     for (mulFracDiv = 1 ; mulFracDiv <= 15 ;mulFracDiv++)
00154     {
00155     for (dividerAddFracDiv = 0 ; dividerAddFracDiv <= 15 ;dividerAddFracDiv++)
00156     {
00157       temp = (mulFracDiv * uClk) / ((mulFracDiv + dividerAddFracDiv));
00158 
00159       diviser = temp / baudrate;
00160       if ((temp % baudrate) > (baudrate / 2))
00161         diviser++;
00162 
00163       if (diviser > 2 && diviser < 65536)
00164       {
00165         calcBaudrate = temp / diviser;
00166 
00167         if (calcBaudrate <= baudrate)
00168           relativeError = baudrate - calcBaudrate;
00169         else
00170           relativeError = calcBaudrate - baudrate;
00171 
00172         if ((relativeError < relativeOptimalError))
00173         {
00174           mulFracDivOptimal = mulFracDiv ;
00175           dividerAddOptimal = dividerAddFracDiv;
00176           diviserOptimal = diviser;
00177           relativeOptimalError = relativeError;
00178           if (relativeError == 0)
00179             break;
00180         }
00181       } /* End of if */
00182     } /* end of inner for loop */
00183     if (relativeError == 0)
00184       break;
00185     } /* end of outer for loop  */
00186 
00187     if (relativeOptimalError < ((baudrate * UART_ACCEPTED_BAUDRATE_ERROR)/100))
00188     {
00189         if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00190         {
00191             ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;
00192             ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);
00193             ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);
00194             /* Then reset DLAB bit */
00195             ((LPC_UART1_TypeDef *)UARTx)->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
00196             ((LPC_UART1_TypeDef *)UARTx)->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \
00197                     | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;
00198         }
00199         else
00200         {
00201             UARTx->LCR |= UART_LCR_DLAB_EN;
00202             UARTx->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);
00203             UARTx->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);
00204             /* Then reset DLAB bit */
00205             UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
00206             UARTx->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \
00207                     | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;
00208         }
00209         errorStatus = SUCCESS;
00210     }
00211 
00212     return errorStatus;
00213 }
00214 
00215 /*********************************************************************//**
00216  * @brief        General UART interrupt handler and router
00217  * @param[in]    UARTx    Selected UART peripheral, should be UART0..3
00218  * @return        None
00219  *
00220  * Note:
00221  * - Handles transmit, receive, and status interrupts for the UART.
00222  * Based on the interrupt status, routes the interrupt to the
00223  * respective call-back to be handled by the user application using
00224  * this driver.
00225  * - If callback is not installed, corresponding interrupt will be disabled
00226  * - All these interrupt source below will be checked:
00227  *           - Transmit Holding Register Empty.
00228  *             - Received Data Available and Character Time Out.
00229  *             - Receive Line Status (not implemented)
00230  *             - End of auto-baud interrupt (not implemented)
00231  *             - Auto-Baudrate Time-Out interrupt (not implemented)
00232  *             - Modem Status interrupt (UART0 Modem functionality)
00233  *             - CTS signal transition interrupt (UART0 Modem functionality)
00234  **********************************************************************/
00235 void UART_GenIntHandler(LPC_UART_TypeDef *UARTx)
00236 {
00237     uint8_t pUart, modemsts;
00238     uint32_t intsrc, tmp, tmp1;
00239 
00240     pUart = getUartNum(UARTx);
00241 
00242     /* Determine the interrupt source */
00243     intsrc = UARTx->IIR;
00244     tmp = intsrc & UART_IIR_INTID_MASK;
00245 
00246     /*
00247      * In case of using UART1 with full modem,
00248      * interrupt ID = 0 that means modem status interrupt has been detected
00249      */
00250     if (pUart == 1) {
00251         if (tmp == 0){
00252             // Check Modem status
00253             modemsts = LPC_UART1->MSR & UART1_MSR_BITMASK;
00254             // Call modem status call-back
00255             if (pfnModemCbs != NULL){
00256                 pfnModemCbs(modemsts);
00257             }
00258             // disable modem status interrupt and CTS status change interrupt
00259             // if its callback is not installed
00260             else {
00261                 LPC_UART1->IER &= ~(UART1_IER_MSINT_EN | UART1_IER_CTSINT_EN);
00262             }
00263         }
00264     }
00265 
00266     // Receive Line Status
00267     if (tmp == UART_IIR_INTID_RLS){
00268         // Check line status
00269         tmp1 = UARTx->LSR;
00270         // Mask out the Receive Ready and Transmit Holding empty status
00271         tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
00272                 | UART_LSR_BI | UART_LSR_RXFE);
00273         // If any error exist
00274         if (tmp1) {
00275             // Call Call-back function with error input value
00276             if (uartCbsDat[pUart].pfnErrCbs != NULL) {
00277                 uartCbsDat[pUart].pfnErrCbs(tmp1);
00278             }
00279             // Disable interrupt if its call-back is not install
00280             else {
00281                 UARTx->IER &= ~(UART_IER_RLSINT_EN);
00282             }
00283         }
00284     }
00285 
00286     // Receive Data Available or Character time-out
00287     if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)){
00288         // Call Rx call back function
00289         if (uartCbsDat[pUart].pfnRxCbs != NULL) {
00290             uartCbsDat[pUart].pfnRxCbs();
00291         }
00292         // Disable interrupt if its call-back is not install
00293         else {
00294             UARTx->IER &= ~(UART_IER_RBRINT_EN);
00295         }
00296     }
00297 
00298     // Transmit Holding Empty
00299     if (tmp == UART_IIR_INTID_THRE){
00300         // Call Tx call back function
00301         if (uartCbsDat[pUart].pfnTxCbs != NULL) {
00302             uartCbsDat[pUart].pfnTxCbs();
00303         }
00304         // Disable interrupt if its call-back is not install
00305         else {
00306             UARTx->IER &= ~(UART_IER_THREINT_EN);
00307         }
00308     }
00309 
00310     intsrc &= (UART_IIR_ABEO_INT | UART_IIR_ABTO_INT);
00311     // Check if End of auto-baudrate interrupt or Auto baudrate time out
00312     if (intsrc){
00313         // Clear interrupt pending
00314         UARTx->ACR |= ((intsrc & UART_IIR_ABEO_INT) ? UART_ACR_ABEOINT_CLR : 0) \
00315                         | ((intsrc & UART_IIR_ABTO_INT) ? UART_ACR_ABTOINT_CLR : 0);
00316         if (uartCbsDat[pUart].pfnABCbs != NULL) {
00317             uartCbsDat[pUart].pfnABCbs(intsrc);
00318         } else {
00319             // Disable End of AB interrupt
00320             UARTx->IER &= ~(UART_IER_ABEOINT_EN | UART_IER_ABTOINT_EN);
00321         }
00322     }
00323 }
00324 
00325 /**
00326  * @}
00327  */
00328 
00329 
00330 /* Public Functions ----------------------------------------------------------- */
00331 /** @addtogroup UART_Public_Functions
00332  * @{
00333  */
00334 
00335 /*********************************************************************//**
00336  * @brief        De-initializes the UARTx peripheral registers to their
00337 *                  default reset values.
00338  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00339  *                         UART2 or UART3.
00340  * @return         None
00341  **********************************************************************/
00342 void UART_DeInit(LPC_UART_TypeDef* UARTx)
00343 {
00344     // For debug mode
00345     CHECK_PARAM(PARAM_UARTx(UARTx));
00346 
00347     UART_TxCmd(UARTx, DISABLE);
00348 
00349 #ifdef _UART0
00350     if (UARTx == (LPC_UART_TypeDef *)LPC_UART0)
00351     {
00352         /* Set up clock and power for UART module */
00353         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, DISABLE);
00354     }
00355 #endif
00356 
00357 #ifdef _UART1
00358     if (UARTx == (LPC_UART_TypeDef *)LPC_UART1)
00359     {
00360         /* Set up clock and power for UART module */
00361         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, DISABLE);
00362     }
00363 #endif
00364 
00365 #ifdef _UART2
00366     if (UARTx == LPC_UART2)
00367     {
00368         /* Set up clock and power for UART module */
00369         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, DISABLE);
00370     }
00371 #endif
00372 
00373 #ifdef _UART3
00374     if (UARTx == LPC_UART3)
00375     {
00376         /* Set up clock and power for UART module */
00377         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, DISABLE);
00378     }
00379 #endif
00380 }
00381 
00382 /********************************************************************//**
00383  * @brief        Initializes the UARTx peripheral according to the specified
00384 *               parameters in the UART_ConfigStruct.
00385  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00386  *                         UART2 or UART3.
00387  * @param[in]    UART_ConfigStruct Pointer to a UART_CFG_Type structure
00388 *                    that contains the configuration information for the
00389 *                    specified UART peripheral.
00390  * @return         None
00391  *********************************************************************/
00392 void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct)
00393 {
00394     uint32_t tmp;
00395 
00396     // For debug mode
00397     CHECK_PARAM(PARAM_UARTx(UARTx));
00398     CHECK_PARAM(PARAM_UART_DATABIT(UART_ConfigStruct->Databits));
00399     CHECK_PARAM(PARAM_UART_STOPBIT(UART_ConfigStruct->Stopbits));
00400     CHECK_PARAM(PARAM_UART_PARITY(UART_ConfigStruct->Parity));
00401 
00402 #ifdef _UART0
00403     if(UARTx == (LPC_UART_TypeDef *)LPC_UART0)
00404     {
00405         /* Set up clock and power for UART module */
00406         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, ENABLE);
00407     }
00408 #endif
00409 
00410 #ifdef _UART1
00411     if(UARTx == (LPC_UART_TypeDef *)LPC_UART1)
00412     {
00413         /* Set up clock and power for UART module */
00414         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, ENABLE);
00415     }
00416 #endif
00417 
00418 #ifdef _UART2
00419     if(UARTx == LPC_UART2)
00420     {
00421         /* Set up clock and power for UART module */
00422         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, ENABLE);
00423     }
00424 #endif
00425 
00426 #ifdef _UART3
00427     if(UARTx == LPC_UART3)
00428     {
00429         /* Set up clock and power for UART module */
00430         CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, ENABLE);
00431     }
00432 #endif
00433 
00434     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00435     {
00436         /* FIFOs are empty */
00437         ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN \
00438                 | UART_FCR_RX_RS | UART_FCR_TX_RS);
00439         // Disable FIFO
00440         ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = 0;
00441 
00442         // Dummy reading
00443         while (((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_RDR)
00444         {
00445             tmp = ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR;
00446         }
00447 
00448         ((LPC_UART1_TypeDef *)UARTx)->TER = UART_TER_TXEN;
00449         // Wait for current transmit complete
00450         while (!(((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_THRE));
00451         // Disable Tx
00452         ((LPC_UART1_TypeDef *)UARTx)->TER = 0;
00453 
00454         // Disable interrupt
00455         ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER = 0;
00456         // Set LCR to default state
00457         ((LPC_UART1_TypeDef *)UARTx)->LCR = 0;
00458         // Set ACR to default state
00459         ((LPC_UART1_TypeDef *)UARTx)->ACR = 0;
00460         // Set Modem Control to default state
00461         ((LPC_UART1_TypeDef *)UARTx)->MCR = 0;
00462         // Set RS485 control to default state
00463         ((LPC_UART1_TypeDef *)UARTx)->RS485CTRL = 0;
00464         // Set RS485 delay timer to default state
00465         ((LPC_UART1_TypeDef *)UARTx)->RS485DLY = 0;
00466         // Set RS485 addr match to default state
00467         ((LPC_UART1_TypeDef *)UARTx)->ADRMATCH = 0;
00468         //Dummy Reading to Clear Status
00469         tmp = ((LPC_UART1_TypeDef *)UARTx)->MSR;
00470         tmp = ((LPC_UART1_TypeDef *)UARTx)->LSR;
00471     }
00472     else
00473     {
00474         /* FIFOs are empty */
00475         UARTx->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS);
00476         // Disable FIFO
00477         UARTx->/*IIFCR.*/FCR = 0;
00478 
00479         // Dummy reading
00480         while (UARTx->LSR & UART_LSR_RDR)
00481         {
00482             tmp = UARTx->/*RBTHDLR.*/RBR;
00483         }
00484 
00485         UARTx->TER = UART_TER_TXEN;
00486         // Wait for current transmit complete
00487         while (!(UARTx->LSR & UART_LSR_THRE));
00488         // Disable Tx
00489         UARTx->TER = 0;
00490 
00491         // Disable interrupt
00492         UARTx->/*DLIER.*/IER = 0;
00493         // Set LCR to default state
00494         UARTx->LCR = 0;
00495         // Set ACR to default state
00496         UARTx->ACR = 0;
00497         // Dummy reading
00498         tmp = UARTx->LSR;
00499     }
00500 
00501     if (UARTx == LPC_UART3)
00502     {
00503         // Set IrDA to default state
00504         UARTx->ICR = 0;
00505     }
00506 
00507     // Set Line Control register ----------------------------
00508 
00509     uart_set_divisors(UARTx, (UART_ConfigStruct->Baud_rate));
00510 
00511     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00512     {
00513         tmp = (((LPC_UART1_TypeDef *)UARTx)->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \
00514                 & UART_LCR_BITMASK;
00515     }
00516     else
00517     {
00518         tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK;
00519     }
00520 
00521     switch (UART_ConfigStruct->Databits){
00522     case UART_DATABIT_5 :
00523         tmp |= UART_LCR_WLEN5;
00524         break;
00525     case UART_DATABIT_6 :
00526         tmp |= UART_LCR_WLEN6;
00527         break;
00528     case UART_DATABIT_7 :
00529         tmp |= UART_LCR_WLEN7;
00530         break;
00531     case UART_DATABIT_8 :
00532     default:
00533         tmp |= UART_LCR_WLEN8;
00534         break;
00535     }
00536 
00537     if (UART_ConfigStruct->Parity == UART_PARITY_NONE )
00538     {
00539         // Do nothing...
00540     }
00541     else
00542     {
00543         tmp |= UART_LCR_PARITY_EN;
00544         switch (UART_ConfigStruct->Parity)
00545         {
00546         case UART_PARITY_ODD :
00547             tmp |= UART_LCR_PARITY_ODD;
00548             break;
00549 
00550         case UART_PARITY_EVEN :
00551             tmp |= UART_LCR_PARITY_EVEN;
00552             break;
00553 
00554         case UART_PARITY_SP_1 :
00555             tmp |= UART_LCR_PARITY_F_1;
00556             break;
00557 
00558         case UART_PARITY_SP_0 :
00559             tmp |= UART_LCR_PARITY_F_0;
00560             break;
00561         default:
00562             break;
00563         }
00564     }
00565 
00566     switch (UART_ConfigStruct->Stopbits){
00567     case UART_STOPBIT_2 :
00568         tmp |= UART_LCR_STOPBIT_SEL;
00569         break;
00570     case UART_STOPBIT_1 :
00571     default:
00572         // Do no thing
00573         break;
00574     }
00575 
00576 
00577     // Write back to LCR, configure FIFO and Disable Tx
00578     if (((LPC_UART1_TypeDef *)UARTx) ==  LPC_UART1)
00579     {
00580         ((LPC_UART1_TypeDef *)UARTx)->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
00581     }
00582     else
00583     {
00584         UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
00585     }
00586 }
00587 
00588 
00589 /*****************************************************************************//**
00590 * @brief        Fills each UART_InitStruct member with its default value:
00591 *                 9600 bps
00592 *                 8-bit data
00593 *                 1 Stopbit
00594 *                 None Parity
00595 * @param[in]    UART_InitStruct Pointer to a UART_CFG_Type structure
00596 *                    which will be initialized.
00597 * @return        None
00598 *******************************************************************************/
00599 void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct)
00600 {
00601     UART_InitStruct->Baud_rate = 9600;
00602     UART_InitStruct->Databits = UART_DATABIT_8 ;
00603     UART_InitStruct->Parity = UART_PARITY_NONE ;
00604     UART_InitStruct->Stopbits = UART_STOPBIT_1 ;
00605 }
00606 
00607 
00608 /*********************************************************************//**
00609  * @brief        Transmit a single data through UART peripheral
00610  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00611  *                         UART2 or UART3.
00612  * @param[in]    Data    Data to transmit (must be 8-bit long)
00613  * @return none
00614  **********************************************************************/
00615 void UART_SendData(LPC_UART_TypeDef* UARTx, uint8_t Data)
00616 {
00617     CHECK_PARAM(PARAM_UARTx(UARTx));
00618 
00619     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00620     {
00621         ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
00622     }
00623     else
00624     {
00625         UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
00626     }
00627 
00628 }
00629 
00630 
00631 /*********************************************************************//**
00632  * @brief        Receive a single data from UART peripheral
00633  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00634  *                         UART2 or UART3.
00635  * @return         Data received
00636  **********************************************************************/
00637 uint8_t UART_ReceiveData(LPC_UART_TypeDef* UARTx)
00638 {
00639     CHECK_PARAM(PARAM_UARTx(UARTx));
00640 
00641     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00642     {
00643         return (((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);
00644     }
00645     else
00646     {
00647         return (UARTx->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);
00648     }
00649 }
00650 
00651 
00652 /*********************************************************************//**
00653  * @brief        Force BREAK character on UART line, output pin UARTx TXD is
00654                 forced to logic 0.
00655  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00656  *                         UART2 or UART3.
00657  * @return none
00658  **********************************************************************/
00659 void UART_ForceBreak(LPC_UART_TypeDef* UARTx)
00660 {
00661     CHECK_PARAM(PARAM_UARTx(UARTx));
00662 
00663     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00664     {
00665         ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_BREAK_EN;
00666     }
00667     else
00668     {
00669         UARTx->LCR |= UART_LCR_BREAK_EN;
00670     }
00671 }
00672 
00673 
00674 #ifdef _UART3
00675 
00676 /*********************************************************************//**
00677  * @brief        Enable or disable inverting serial input function of IrDA
00678  *                 on UART peripheral.
00679  * @param[in]    UARTx UART peripheral selected, should be UART3 (only)
00680  * @param[in]    NewState New state of inverting serial input, should be:
00681  *                 - ENABLE: Enable this function.
00682  *                 - DISABLE: Disable this function.
00683  * @return none
00684  **********************************************************************/
00685 void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)
00686 {
00687     CHECK_PARAM(PARAM_UART_IrDA(UARTx));
00688     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
00689 
00690     if (NewState == ENABLE)
00691     {
00692         UARTx->ICR |= UART_ICR_IRDAINV;
00693     }
00694     else if (NewState == DISABLE)
00695     {
00696         UARTx->ICR &= (~UART_ICR_IRDAINV) & UART_ICR_BITMASK;
00697     }
00698 }
00699 
00700 
00701 /*********************************************************************//**
00702  * @brief        Enable or disable IrDA function on UART peripheral.
00703  * @param[in]    UARTx UART peripheral selected, should be UART3 (only)
00704  * @param[in]    NewState New state of IrDA function, should be:
00705  *                 - ENABLE: Enable this function.
00706  *                 - DISABLE: Disable this function.
00707  * @return none
00708  **********************************************************************/
00709 void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)
00710 {
00711     CHECK_PARAM(PARAM_UART_IrDA(UARTx));
00712     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
00713 
00714     if (NewState == ENABLE)
00715     {
00716         UARTx->ICR |= UART_ICR_IRDAEN;
00717     }
00718     else
00719     {
00720         UARTx->ICR &= (~UART_ICR_IRDAEN) & UART_ICR_BITMASK;
00721     }
00722 }
00723 
00724 
00725 /*********************************************************************//**
00726  * @brief        Configure Pulse divider for IrDA function on UART peripheral.
00727  * @param[in]    UARTx UART peripheral selected, should be UART3 (only)
00728  * @param[in]    PulseDiv Pulse Divider value from Peripheral clock,
00729  *                 should be one of the following:
00730                 - UART_IrDA_PULSEDIV2     : Pulse width = 2 * Tpclk
00731                 - UART_IrDA_PULSEDIV4     : Pulse width = 4 * Tpclk
00732                 - UART_IrDA_PULSEDIV8     : Pulse width = 8 * Tpclk
00733                 - UART_IrDA_PULSEDIV16     : Pulse width = 16 * Tpclk
00734                 - UART_IrDA_PULSEDIV32     : Pulse width = 32 * Tpclk
00735                 - UART_IrDA_PULSEDIV64     : Pulse width = 64 * Tpclk
00736                 - UART_IrDA_PULSEDIV128 : Pulse width = 128 * Tpclk
00737                 - UART_IrDA_PULSEDIV256 : Pulse width = 256 * Tpclk
00738 
00739  * @return none
00740  **********************************************************************/
00741 void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv)
00742 {
00743     uint32_t tmp, tmp1;
00744     CHECK_PARAM(PARAM_UART_IrDA(UARTx));
00745     CHECK_PARAM(PARAM_UART_IrDA_PULSEDIV(PulseDiv));
00746 
00747     tmp1 = UART_ICR_PULSEDIV(PulseDiv);
00748     tmp = UARTx->ICR & (~UART_ICR_PULSEDIV(7));
00749     tmp |= tmp1 | UART_ICR_FIXPULSE_EN;
00750     UARTx->ICR = tmp & UART_ICR_BITMASK;
00751 }
00752 
00753 #endif
00754 
00755 
00756 /********************************************************************//**
00757  * @brief         Enable or disable specified UART interrupt.
00758  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00759  *                         UART2 or UART3.
00760  * @param[in]    UARTIntCfg    Specifies the interrupt flag,
00761  *                 should be one of the following:
00762                 - UART_INTCFG_RBR     :  RBR Interrupt enable
00763                 - UART_INTCFG_THRE     :  THR Interrupt enable
00764                 - UART_INTCFG_RLS     :  RX line status interrupt enable
00765                 - UART1_INTCFG_MS    :  Modem status interrupt enable (UART1 only)
00766                 - UART1_INTCFG_CTS    :  CTS1 signal transition interrupt enable (UART1 only)
00767                 - UART_INTCFG_ABEO     :  Enables the end of auto-baud interrupt
00768                 - UART_INTCFG_ABTO     :  Enables the auto-baud time-out interrupt
00769  * @param[in]    NewState New state of specified UART interrupt type,
00770  *                 should be:
00771  *                 - ENALBE: Enable this UART interrupt type.
00772 *                 - DISALBE: Disable this UART interrupt type.
00773  * @return         None
00774  *********************************************************************/
00775 void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, FunctionalState NewState)
00776 {
00777     uint32_t tmp=0;
00778 
00779     CHECK_PARAM(PARAM_UARTx(UARTx));
00780     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
00781 
00782     switch(UARTIntCfg){
00783         case UART_INTCFG_RBR :
00784             tmp = UART_IER_RBRINT_EN;
00785             break;
00786         case UART_INTCFG_THRE :
00787             tmp = UART_IER_THREINT_EN;
00788             break;
00789         case UART_INTCFG_RLS :
00790             tmp = UART_IER_RLSINT_EN;
00791             break;
00792         case UART1_INTCFG_MS :
00793             tmp = UART1_IER_MSINT_EN;
00794             break;
00795         case UART1_INTCFG_CTS :
00796             tmp = UART1_IER_CTSINT_EN;
00797             break;
00798         case UART_INTCFG_ABEO :
00799             tmp = UART_IER_ABEOINT_EN;
00800             break;
00801         case UART_INTCFG_ABTO :
00802             tmp = UART_IER_ABTOINT_EN;
00803             break;
00804     }
00805 
00806     if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
00807     {
00808         CHECK_PARAM((PARAM_UART_INTCFG(UARTIntCfg)) || (PARAM_UART1_INTCFG(UARTIntCfg)));
00809     }
00810     else
00811     {
00812         CHECK_PARAM(PARAM_UART_INTCFG(UARTIntCfg));
00813     }
00814 
00815     if (NewState == ENABLE)
00816     {
00817         if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
00818         {
00819             ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER |= tmp;
00820         }
00821         else
00822         {
00823             UARTx->/*DLIER.*/IER |= tmp;
00824         }
00825     }
00826     else
00827     {
00828         if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
00829         {
00830             ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER &= (~tmp) & UART1_IER_BITMASK;
00831         }
00832         else
00833         {
00834             UARTx->/*DLIER.*/IER &= (~tmp) & UART_IER_BITMASK;
00835         }
00836     }
00837 }
00838 
00839 
00840 /********************************************************************//**
00841  * @brief         Get current value of Line Status register in UART peripheral.
00842  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00843  *                         UART2 or UART3.
00844  * @return        Current value of Line Status register in UART peripheral.
00845  * Note:    The return value of this function must be ANDed with each member in
00846  *             UART_LS_Type enumeration to determine current flag status
00847  *             corresponding to each Line status type. Because some flags in
00848  *             Line Status register will be cleared after reading, the next reading
00849  *             Line Status register could not be correct. So this function used to
00850  *             read Line status register in one time only, then the return value
00851  *             used to check all flags.
00852  *********************************************************************/
00853 uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx)
00854 {
00855     CHECK_PARAM(PARAM_UARTx(UARTx));
00856 
00857     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00858     {
00859         return ((((LPC_UART1_TypeDef *)LPC_UART1)->LSR) & UART_LSR_BITMASK);
00860     }
00861     else
00862     {
00863         return ((UARTx->LSR) & UART_LSR_BITMASK);
00864     }
00865 }
00866 
00867 /*********************************************************************//**
00868  * @brief        Check whether if UART is busy or not
00869  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00870  *                         UART2 or UART3.
00871  * @return        RESET if UART is not busy, otherwise return SET.
00872  **********************************************************************/
00873 FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx)
00874 {
00875     if (UARTx->LSR & UART_LSR_TEMT){
00876         return RESET;
00877     } else {
00878         return SET;
00879     }
00880 }
00881 
00882 
00883 /*********************************************************************//**
00884  * @brief        Configure FIFO function on selected UART peripheral
00885  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00886  *                         UART2 or UART3.
00887  * @param[in]    FIFOCfg    Pointer to a UART_FIFO_CFG_Type Structure that
00888  *                         contains specified information about FIFO configuration
00889  * @return         none
00890  **********************************************************************/
00891 void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg)
00892 {
00893     uint8_t tmp = 0;
00894 
00895     CHECK_PARAM(PARAM_UARTx(UARTx));
00896     CHECK_PARAM(PARAM_UART_FIFO_LEVEL(FIFOCfg->FIFO_Level));
00897     CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_DMAMode));
00898     CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetRxBuf));
00899     CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetTxBuf));
00900 
00901     tmp |= UART_FCR_FIFO_EN;
00902     switch (FIFOCfg->FIFO_Level){
00903     case UART_FIFO_TRGLEV0 :
00904         tmp |= UART_FCR_TRG_LEV0;
00905         break;
00906     case UART_FIFO_TRGLEV1 :
00907         tmp |= UART_FCR_TRG_LEV1;
00908         break;
00909     case UART_FIFO_TRGLEV2 :
00910         tmp |= UART_FCR_TRG_LEV2;
00911         break;
00912     case UART_FIFO_TRGLEV3 :
00913     default:
00914         tmp |= UART_FCR_TRG_LEV3;
00915         break;
00916     }
00917 
00918     if (FIFOCfg->FIFO_ResetTxBuf == ENABLE)
00919     {
00920         tmp |= UART_FCR_TX_RS;
00921     }
00922     if (FIFOCfg->FIFO_ResetRxBuf == ENABLE)
00923     {
00924         tmp |= UART_FCR_RX_RS;
00925     }
00926     if (FIFOCfg->FIFO_DMAMode == ENABLE)
00927     {
00928         tmp |= UART_FCR_DMAMODE_SEL;
00929     }
00930 
00931 
00932     //write to FIFO control register
00933     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00934     {
00935         ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;
00936     }
00937     else
00938     {
00939         UARTx->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;
00940     }
00941 
00942 }
00943 
00944 
00945 /*****************************************************************************//**
00946 * @brief        Fills each UART_FIFOInitStruct member with its default value:
00947 *                 - FIFO_DMAMode = DISABLE
00948 *                 - FIFO_Level = UART_FIFO_TRGLEV0
00949 *                 - FIFO_ResetRxBuf = ENABLE
00950 *                 - FIFO_ResetTxBuf = ENABLE
00951 *                 - FIFO_State = ENABLE
00952 
00953 * @param[in]    UART_FIFOInitStruct Pointer to a UART_FIFO_CFG_Type structure
00954 *                    which will be initialized.
00955 * @return        None
00956 *******************************************************************************/
00957 void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct)
00958 {
00959     UART_FIFOInitStruct->FIFO_DMAMode = DISABLE;
00960     UART_FIFOInitStruct->FIFO_Level = UART_FIFO_TRGLEV0 ;
00961     UART_FIFOInitStruct->FIFO_ResetRxBuf = ENABLE;
00962     UART_FIFOInitStruct->FIFO_ResetTxBuf = ENABLE;
00963 }
00964 
00965 
00966 /*********************************************************************//**
00967  * @brief        Start/Stop Auto Baudrate activity
00968  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
00969  *                         UART2 or UART3.
00970  * @param[in]    ABConfigStruct    A pointer to UART_AB_CFG_Type structure that
00971  *                                 contains specified information about UART
00972  *                                 auto baudrate configuration
00973  * @param[in]    NewState New State of Auto baudrate activity, should be:
00974  *                 - ENABLE: Start this activity
00975  *                - DISABLE: Stop this activity
00976  * Note:        Auto-baudrate mode enable bit will be cleared once this mode
00977  *                 completed.
00978  * @return         none
00979  **********************************************************************/
00980 void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \
00981                 FunctionalState NewState)
00982 {
00983     uint32_t tmp;
00984 
00985     CHECK_PARAM(PARAM_UARTx(UARTx));
00986     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
00987 
00988     tmp = 0;
00989     if (NewState == ENABLE) {
00990         if (ABConfigStruct->ABMode == UART_AUTOBAUD_MODE1){
00991             tmp |= UART_ACR_MODE;
00992         }
00993         if (ABConfigStruct->AutoRestart == ENABLE){
00994             tmp |= UART_ACR_AUTO_RESTART;
00995         }
00996     }
00997 
00998     if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
00999     {
01000         if (NewState == ENABLE)
01001         {
01002             // Clear DLL and DLM value
01003             ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;
01004             ((LPC_UART1_TypeDef *)UARTx)->DLL = 0;
01005             ((LPC_UART1_TypeDef *)UARTx)->DLM = 0;
01006             ((LPC_UART1_TypeDef *)UARTx)->LCR &= ~UART_LCR_DLAB_EN;
01007             // FDR value must be reset to default value
01008             ((LPC_UART1_TypeDef *)UARTx)->FDR = 0x10;
01009             ((LPC_UART1_TypeDef *)UARTx)->ACR = UART_ACR_START | tmp;
01010         }
01011         else
01012         {
01013             ((LPC_UART1_TypeDef *)UARTx)->ACR = 0;
01014         }
01015     }
01016     else
01017     {
01018         if (NewState == ENABLE)
01019         {
01020             // Clear DLL and DLM value
01021             UARTx->LCR |= UART_LCR_DLAB_EN;
01022             UARTx->DLL = 0;
01023             UARTx->DLM = 0;
01024             UARTx->LCR &= ~UART_LCR_DLAB_EN;
01025             // FDR value must be reset to default value
01026             UARTx->FDR = 0x10;
01027             UARTx->ACR = UART_ACR_START | tmp;
01028         }
01029         else
01030         {
01031             UARTx->ACR = 0;
01032         }
01033     }
01034 }
01035 
01036 
01037 /*********************************************************************//**
01038  * @brief        Enable/Disable transmission on UART TxD pin
01039  * @param[in]    UARTx    UART peripheral selected, should be UART0, UART1,
01040  *                         UART2 or UART3.
01041  * @param[in]    NewState New State of Tx transmission function, should be:
01042  *                 - ENABLE: Enable this function
01043                 - DISABLE: Disable this function
01044  * @return none
01045  **********************************************************************/
01046 void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState)
01047 {
01048     CHECK_PARAM(PARAM_UARTx(UARTx));
01049     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
01050 
01051     if (NewState == ENABLE)
01052     {
01053         if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
01054         {
01055             ((LPC_UART1_TypeDef *)UARTx)->TER |= UART_TER_TXEN;
01056         }
01057         else
01058         {
01059             UARTx->TER |= UART_TER_TXEN;
01060         }
01061     }
01062     else
01063     {
01064         if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
01065         {
01066             ((LPC_UART1_TypeDef *)UARTx)->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;
01067         }
01068         else
01069         {
01070             UARTx->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;
01071         }
01072     }
01073 }
01074 
01075 #ifdef _UART1
01076 
01077 /*********************************************************************//**
01078  * @brief        Force pin DTR/RTS corresponding to given state (Full modem mode)
01079  * @param[in]    UARTx    UART1 (only)
01080  * @param[in]    Pin    Pin that NewState will be applied to, should be:
01081  *                 - UART1_MODEM_PIN_DTR: DTR pin.
01082  *                 - UART1_MODEM_PIN_RTS: RTS pin.
01083  * @param[in]    NewState New State of DTR/RTS pin, should be:
01084  *                 - INACTIVE: Force the pin to inactive signal.
01085                 - ACTIVE: Force the pin to active signal.
01086  * @return none
01087  **********************************************************************/
01088 void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \
01089                             UART1_SignalState NewState)
01090 {
01091     uint8_t tmp = 0;
01092 
01093     CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
01094     CHECK_PARAM(PARAM_UART1_MODEM_PIN(Pin));
01095     CHECK_PARAM(PARAM_UART1_SIGNALSTATE(NewState));
01096 
01097     switch (Pin){
01098     case UART1_MODEM_PIN_DTR :
01099         tmp = UART1_MCR_DTR_CTRL;
01100         break;
01101     case UART1_MODEM_PIN_RTS :
01102         tmp = UART1_MCR_RTS_CTRL;
01103         break;
01104     default:
01105         break;
01106     }
01107 
01108     if (NewState == ACTIVE){
01109         UARTx->MCR |= tmp;
01110     } else {
01111         UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;
01112     }
01113 }
01114 
01115 
01116 /*********************************************************************//**
01117  * @brief        Configure Full Modem mode for UART peripheral
01118  * @param[in]    UARTx    UART1 (only)
01119  * @param[in]    Mode Full Modem mode, should be:
01120  *                 - UART1_MODEM_MODE_LOOPBACK: Loop back mode.
01121  *                 - UART1_MODEM_MODE_AUTO_RTS: Auto-RTS mode.
01122  *                 - UART1_MODEM_MODE_AUTO_CTS: Auto-CTS mode.
01123  * @param[in]    NewState New State of this mode, should be:
01124  *                 - ENABLE: Enable this mode.
01125                 - DISABLE: Disable this mode.
01126  * @return none
01127  **********************************************************************/
01128 void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \
01129                             FunctionalState NewState)
01130 {
01131     uint8_t tmp=0;
01132 
01133     CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
01134     CHECK_PARAM(PARAM_UART1_MODEM_MODE(Mode));
01135     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
01136 
01137     switch(Mode){
01138     case UART1_MODEM_MODE_LOOPBACK :
01139         tmp = UART1_MCR_LOOPB_EN;
01140         break;
01141     case UART1_MODEM_MODE_AUTO_RTS :
01142         tmp = UART1_MCR_AUTO_RTS_EN;
01143         break;
01144     case UART1_MODEM_MODE_AUTO_CTS :
01145         tmp = UART1_MCR_AUTO_CTS_EN;
01146         break;
01147     default:
01148         break;
01149     }
01150 
01151     if (NewState == ENABLE)
01152     {
01153         UARTx->MCR |= tmp;
01154     }
01155     else
01156     {
01157         UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;
01158     }
01159 }
01160 
01161 
01162 /*********************************************************************//**
01163  * @brief        Get current status of modem status register
01164  * @param[in]    UARTx    UART1 (only)
01165  * @return         Current value of modem status register
01166  * Note:    The return value of this function must be ANDed with each member
01167  *             UART_MODEM_STAT_type enumeration to determine current flag status
01168  *             corresponding to each modem flag status. Because some flags in
01169  *             modem status register will be cleared after reading, the next reading
01170  *             modem register could not be correct. So this function used to
01171  *             read modem status register in one time only, then the return value
01172  *             used to check all flags.
01173  **********************************************************************/
01174 uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx)
01175 {
01176     CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
01177     return ((UARTx->MSR) & UART1_MSR_BITMASK);
01178 }
01179 
01180 
01181 /*********************************************************************//**
01182  * @brief        Configure UART peripheral in RS485 mode according to the specified
01183 *               parameters in the RS485ConfigStruct.
01184  * @param[in]    UARTx    UART1 (only)
01185  * @param[in]    RS485ConfigStruct Pointer to a UART1_RS485_CTRLCFG_Type structure
01186 *                    that contains the configuration information for specified UART
01187 *                    in RS485 mode.
01188  * @return        None
01189  **********************************************************************/
01190 void UART_RS485Config(LPC_UART1_TypeDef *UARTx, UART1_RS485_CTRLCFG_Type *RS485ConfigStruct)
01191 {
01192     uint32_t tmp;
01193 
01194     CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
01195     CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoAddrDetect_State ));
01196     CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoDirCtrl_State ));
01197     CHECK_PARAM(PARAM_UART1_RS485_CFG_DELAYVALUE(RS485ConfigStruct->DelayValue ));
01198     CHECK_PARAM(PARAM_SETSTATE(RS485ConfigStruct->DirCtrlPol_Level ));
01199     CHECK_PARAM(PARAM_UART_RS485_DIRCTRL_PIN(RS485ConfigStruct->DirCtrlPin ));
01200     CHECK_PARAM(PARAM_UART1_RS485_CFG_MATCHADDRVALUE(RS485ConfigStruct->MatchAddrValue ));
01201     CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->NormalMultiDropMode_State ));
01202     CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->Rx_State ));
01203 
01204     tmp = 0;
01205     // If Auto Direction Control is enabled -  This function is used in Master mode
01206     if (RS485ConfigStruct->AutoDirCtrl_State  == ENABLE)
01207     {
01208         tmp |= UART1_RS485CTRL_DCTRL_EN;
01209 
01210         // Set polar
01211         if (RS485ConfigStruct->DirCtrlPol_Level  == SET)
01212         {
01213             tmp |= UART1_RS485CTRL_OINV_1;
01214         }
01215 
01216         // Set pin according to
01217         if (RS485ConfigStruct->DirCtrlPin  == UART1_RS485_DIRCTRL_DTR)
01218         {
01219             tmp |= UART1_RS485CTRL_SEL_DTR;
01220         }
01221 
01222         // Fill delay time
01223         UARTx->RS485DLY = RS485ConfigStruct->DelayValue  & UART1_RS485DLY_BITMASK;
01224     }
01225 
01226     // MultiDrop mode is enable
01227     if (RS485ConfigStruct->NormalMultiDropMode_State  == ENABLE)
01228     {
01229         tmp |= UART1_RS485CTRL_NMM_EN;
01230     }
01231 
01232     // Auto Address Detect function
01233     if (RS485ConfigStruct->AutoAddrDetect_State  == ENABLE)
01234     {
01235         tmp |= UART1_RS485CTRL_AADEN;
01236         // Fill Match Address
01237         UARTx->ADRMATCH = RS485ConfigStruct->MatchAddrValue  & UART1_RS485ADRMATCH_BITMASK;
01238     }
01239 
01240 
01241     // Receiver is disable
01242     if (RS485ConfigStruct->Rx_State  == DISABLE)
01243     {
01244         tmp |= UART1_RS485CTRL_RX_DIS;
01245     }
01246 
01247     // write back to RS485 control register
01248     UARTx->RS485CTRL = tmp & UART1_RS485CTRL_BITMASK;
01249 
01250     // Enable Parity function and leave parity in stick '0' parity as default
01251     UARTx->LCR |= (UART_LCR_PARITY_F_0 | UART_LCR_PARITY_EN);
01252 }
01253 
01254 
01255 /**
01256  * @brief         Enable/Disable receiver in RS485 module in UART1
01257  * @param[in]    UARTx         UART1 only.
01258  * @param[in]    NewState    New State of command, should be:
01259  *                             - ENABLE: Enable this function.
01260  *                             - DISABLE: Disable this function.
01261  * @return        None
01262  */
01263 void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState)
01264 {
01265     if (NewState == ENABLE){
01266         UARTx->RS485CTRL &= ~UART1_RS485CTRL_RX_DIS;
01267     } else {
01268         UARTx->RS485CTRL |= UART1_RS485CTRL_RX_DIS;
01269     }
01270 }
01271 
01272 
01273 /**
01274  * @brief         Send data on RS485 bus with specified parity stick value (9-bit mode).
01275  * @param[in]    UARTx         UART1 (only).
01276  * @param[in]    pDatFrm     Pointer to data frame.
01277  * @param[in]    size        Size of data.
01278  * @param[in]    ParityStick    Parity Stick value, should be 0 or 1.
01279  * @return        None.
01280  */
01281 uint32_t UART_RS485Send(LPC_UART1_TypeDef *UARTx, uint8_t *pDatFrm, \
01282                     uint32_t size, uint8_t ParityStick)
01283 {
01284     uint8_t tmp, save;
01285     uint32_t cnt;
01286 
01287     if (ParityStick){
01288         save = tmp = UARTx->LCR & UART_LCR_BITMASK;
01289         tmp &= ~(UART_LCR_PARITY_EVEN);
01290         UARTx->LCR = tmp;
01291         cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);
01292         while (!(UARTx->LSR & UART_LSR_TEMT));
01293         UARTx->LCR = save;
01294     } else {
01295         cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);
01296         while (!(UARTx->LSR & UART_LSR_TEMT));
01297     }
01298     return cnt;
01299 }
01300 
01301 
01302 /**
01303  * @brief         Send Slave address frames on RS485 bus.
01304  * @param[in]    UARTx UART1 (only).
01305  * @param[in]    SlvAddr Slave Address.
01306  * @return        None.
01307  */
01308 void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr)
01309 {
01310     UART_RS485Send(UARTx, &SlvAddr, 1, 1);
01311 }
01312 
01313 
01314 /**
01315  * @brief         Send Data frames on RS485 bus.
01316  * @param[in]    UARTx UART1 (only).
01317  * @param[in]    pData Pointer to data to be sent.
01318  * @param[in]    size Size of data frame to be sent.
01319  * @return        None.
01320  */
01321 uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size)
01322 {
01323     return (UART_RS485Send(UARTx, pData, size, 0));
01324 }
01325 
01326 #endif /* _UART1 */
01327 
01328 
01329 /* Additional driver APIs ----------------------------------------------------------------------- */
01330 
01331 /*********************************************************************//**
01332  * @brief        Send a block of data via UART peripheral
01333  * @param[in]    UARTx    Selected UART peripheral used to send data,
01334  *                 should be UART0, UART1, UART2 or UART3.
01335  * @param[in]    txbuf     Pointer to Transmit buffer
01336  * @param[in]    buflen     Length of Transmit buffer
01337  * @param[in]     flag     Flag used in  UART transfer, should be
01338  *                         NONE_BLOCKING or BLOCKING
01339  * @return         Number of bytes sent.
01340  *
01341  * Note: when using UART in BLOCKING mode, a time-out condition is used
01342  * via defined symbol UART_BLOCKING_TIMEOUT.
01343  **********************************************************************/
01344 uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,
01345         uint32_t buflen, TRANSFER_BLOCK_Type flag)
01346 {
01347     uint32_t bToSend, bSent, timeOut, fifo_cnt;
01348     uint8_t *pChar = txbuf;
01349 
01350     bToSend = buflen;
01351 
01352     // blocking mode
01353     if (flag == BLOCKING) {
01354         bSent = 0;
01355         while (bToSend){
01356             timeOut = UART_BLOCKING_TIMEOUT;
01357             // Wait for THR empty with timeout
01358             while (!(UARTx->LSR & UART_LSR_THRE)) {
01359                 if (timeOut == 0) break;
01360                 timeOut--;
01361             }
01362             // Time out!
01363             if(timeOut == 0) break;
01364             fifo_cnt = UART_TX_FIFO_SIZE;
01365             while (fifo_cnt && bToSend){
01366                 UART_SendData(UARTx, (*pChar++));
01367                 fifo_cnt--;
01368                 bToSend--;
01369                 bSent++;
01370             }
01371         }
01372     }
01373     // None blocking mode
01374     else {
01375         bSent = 0;
01376         while (bToSend) {
01377             if (!(UARTx->LSR & UART_LSR_THRE)){
01378                 break;
01379             }
01380             fifo_cnt = UART_TX_FIFO_SIZE;
01381             while (fifo_cnt && bToSend) {
01382                 UART_SendData(UARTx, (*pChar++));
01383                 bToSend--;
01384                 fifo_cnt--;
01385                 bSent++;
01386             }
01387         }
01388     }
01389     return bSent;
01390 }
01391 
01392 /*********************************************************************//**
01393  * @brief        Receive a block of data via UART peripheral
01394  * @param[in]    UARTx    Selected UART peripheral used to send data,
01395  *                 should be UART0, UART1, UART2 or UART3.
01396  * @param[out]    rxbuf     Pointer to Received buffer
01397  * @param[in]    buflen     Length of Received buffer
01398  * @param[in]     flag     Flag mode, should be NONE_BLOCKING or BLOCKING
01399 
01400  * @return         Number of bytes received
01401  *
01402  * Note: when using UART in BLOCKING mode, a time-out condition is used
01403  * via defined symbol UART_BLOCKING_TIMEOUT.
01404  **********************************************************************/
01405 uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \
01406         uint32_t buflen, TRANSFER_BLOCK_Type flag)
01407 {
01408     uint32_t bToRecv, bRecv, timeOut;
01409     uint8_t *pChar = rxbuf;
01410 
01411     bToRecv = buflen;
01412 
01413     // Blocking mode
01414     if (flag == BLOCKING) {
01415         bRecv = 0;
01416         while (bToRecv){
01417             timeOut = UART_BLOCKING_TIMEOUT;
01418             while (!(UARTx->LSR & UART_LSR_RDR)){
01419                 if (timeOut == 0) break;
01420                 timeOut--;
01421             }
01422             // Time out!
01423             if(timeOut == 0) break;
01424             // Get data from the buffer
01425             (*pChar++) = UART_ReceiveData(UARTx);
01426             bToRecv--;
01427             bRecv++;
01428         }
01429     }
01430     // None blocking mode
01431     else {
01432         bRecv = 0;
01433         while (bToRecv) {
01434             if (!(UARTx->LSR & UART_LSR_RDR)) {
01435                 break;
01436             } else {
01437                 (*pChar++) = UART_ReceiveData(UARTx);
01438                 bRecv++;
01439                 bToRecv--;
01440             }
01441         }
01442     }
01443     return bRecv;
01444 }
01445 
01446 
01447 /*********************************************************************//**
01448  * @brief        Setup call-back function for UART interrupt handler for each
01449  *                 UART peripheral
01450  * @param[in]    UARTx    Selected UART peripheral, should be UART0..3
01451  * @param[in]    CbType    Call-back type, should be:
01452  *                         0 - Receive Call-back
01453  *                         1 - Transmit Call-back
01454  *                         2 - Auto Baudrate Callback
01455  *                         3 - Error Call-back
01456  *                         4 - Modem Status Call-back (UART1 only)
01457  * @param[in]    pfnCbs    Pointer to Call-back function
01458  * @return        None
01459  **********************************************************************/
01460 void UART_SetupCbs(LPC_UART_TypeDef *UARTx, uint8_t CbType, void *pfnCbs)
01461 {
01462     uint8_t pUartNum;
01463 
01464     pUartNum = getUartNum(UARTx);
01465     switch(CbType){
01466     case 0:
01467         uartCbsDat[pUartNum].pfnRxCbs = (fnTxCbs_Type *)pfnCbs;
01468         break;
01469     case 1:
01470         uartCbsDat[pUartNum].pfnTxCbs = (fnRxCbs_Type *)pfnCbs;
01471         break;
01472     case 2:
01473         uartCbsDat[pUartNum].pfnABCbs = (fnABCbs_Type *)pfnCbs;
01474         break;
01475     case 3:
01476         uartCbsDat[pUartNum].pfnErrCbs = (fnErrCbs_Type *)pfnCbs;
01477         break;
01478     case 4:
01479         pfnModemCbs = (fnModemCbs_Type *)pfnCbs;
01480         break;
01481     default:
01482         break;
01483     }
01484 }
01485 
01486 /*********************************************************************//**
01487  * @brief        Standard UART0 interrupt handler
01488  * @param[in]    None
01489  * @return        None
01490  **********************************************************************/
01491 void UART0_StdIntHandler(void)
01492 {
01493     UART_GenIntHandler((LPC_UART_TypeDef *)LPC_UART0);
01494 }
01495 
01496 /*********************************************************************//**
01497  * @brief        Standard UART1 interrupt handler
01498  * @param[in]    None
01499  * @return        None
01500  **********************************************************************/
01501 void UART1_StdIntHandler(void)
01502 {
01503     UART_GenIntHandler((LPC_UART_TypeDef *)LPC_UART1);
01504 }
01505 
01506 /*********************************************************************//**
01507  * @brief        Standard UART2 interrupt handler
01508  * @param[in]    None
01509  * @return        None
01510  **********************************************************************/
01511 void UART2_StdIntHandler(void)
01512 {
01513     UART_GenIntHandler(LPC_UART2);
01514 }
01515 
01516 /*********************************************************************//**
01517  * @brief        Standard UART3 interrupt handler
01518  * @param[in]    None
01519  * @return
01520  **********************************************************************/
01521 void UART3_StdIntHandler(void)
01522 {
01523     UART_GenIntHandler(LPC_UART3);
01524 }
01525 
01526 /**
01527  * @}
01528  */
01529 
01530 
01531 #endif /* _UART */
01532 
01533 /**
01534  * @}
01535  */
01536 
01537 /* --------------------------------- End Of File ------------------------------ */
01538