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
lpc17xx_uart.c
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
Generated on Tue Jul 12 2022 17:06:02 by 1.7.2