lpc17xx_uart.c (41777B)
1 /********************************************************************** 2 * $Id$ lpc17xx_uart.c 2011-06-06 3 *//** 4 * @file lpc17xx_uart.c 5 * @brief Contains all functions support for UART firmware library 6 * on LPC17xx 7 * @version 3.2 8 * @date 25. July. 2011 9 * @author NXP MCU SW Application Team 10 * 11 * Copyright(C) 2011, NXP Semiconductor 12 * All rights reserved. 13 * 14 *********************************************************************** 15 * Software that is described herein is for illustrative purposes only 16 * which provides customers with programming information regarding the 17 * products. This software is supplied "AS IS" without any warranties. 18 * NXP Semiconductors assumes no responsibility or liability for the 19 * use of the software, conveys no license or title under any patent, 20 * copyright, or mask work right to the product. NXP Semiconductors 21 * reserves the right to make changes in the software without 22 * notification. NXP Semiconductors also make no representation or 23 * warranty that such application will be suitable for the specified 24 * use without further testing or modification. 25 * Permission to use, copy, modify, and distribute this software and its 26 * documentation is hereby granted, under NXP Semiconductors' 27 * relevant copyright in the software, without fee, provided that it 28 * is used in conjunction with NXP Semiconductors microcontrollers. This 29 * copyright, permission, and disclaimer notice must appear in all copies of 30 * this code. 31 **********************************************************************/ 32 33 /* Peripheral group ----------------------------------------------------------- */ 34 /** @addtogroup UART 35 * @{ 36 */ 37 38 /* Includes ------------------------------------------------------------------- */ 39 #include "lpc17xx_uart.h" 40 #include "lpc17xx_clkpwr.h" 41 42 /* If this source file built with example, the LPC17xx FW library configuration 43 * file in each example directory ("lpc17xx_libcfg.h") must be included, 44 * otherwise the default FW library configuration file must be included instead 45 */ 46 #ifdef __BUILD_WITH_EXAMPLE__ 47 #include "lpc17xx_libcfg.h" 48 #else 49 #include "lpc17xx_libcfg_default.h" 50 #endif /* __BUILD_WITH_EXAMPLE__ */ 51 52 53 #ifdef _UART 54 55 /* Private Functions ---------------------------------------------------------- */ 56 57 static Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate); 58 59 60 /*********************************************************************//** 61 * @brief Determines best dividers to get a target clock rate 62 * @param[in] UARTx Pointer to selected UART peripheral, should be: 63 * - LPC_UART0: UART0 peripheral 64 * - LPC_UART1: UART1 peripheral 65 * - LPC_UART2: UART2 peripheral 66 * - LPC_UART3: UART3 peripheral 67 * @param[in] baudrate Desired UART baud rate. 68 * @return Error status, could be: 69 * - SUCCESS 70 * - ERROR 71 **********************************************************************/ 72 static Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate) 73 { 74 Status errorStatus = ERROR; 75 76 uint32_t uClk = 0; 77 uint32_t d, m, bestd, bestm, tmp; 78 uint64_t best_divisor, divisor; 79 uint32_t current_error, best_error; 80 uint32_t recalcbaud; 81 82 /* get UART block clock */ 83 if (UARTx == (LPC_UART_TypeDef *)LPC_UART0) 84 { 85 uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART0); 86 } 87 else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1) 88 { 89 uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART1); 90 } 91 else if (UARTx == LPC_UART2) 92 { 93 uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART2); 94 } 95 else if (UARTx == LPC_UART3) 96 { 97 uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART3); 98 } 99 100 101 /* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers 102 * The formula is : 103 * BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL) 104 * It involves floating point calculations. That's the reason the formulae are adjusted with 105 * Multiply and divide method.*/ 106 /* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions: 107 * 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */ 108 best_error = 0xFFFFFFFF; /* Worst case */ 109 bestd = 0; 110 bestm = 0; 111 best_divisor = 0; 112 for (m = 1 ; m <= 15 ;m++) 113 { 114 for (d = 0 ; d < m ; d++) 115 { 116 divisor = ((uint64_t)uClk<<28)*m/(baudrate*(m+d)); 117 current_error = divisor & 0xFFFFFFFF; 118 119 tmp = divisor>>32; 120 121 /* Adjust error */ 122 if(current_error > ((uint32_t)1<<31)){ 123 current_error = -current_error; 124 tmp++; 125 } 126 127 if(tmp<1 || tmp>65536) /* Out of range */ 128 continue; 129 130 if( current_error < best_error){ 131 best_error = current_error; 132 best_divisor = tmp; 133 bestd = d; 134 bestm = m; 135 if(best_error == 0) break; 136 } 137 } /* end of inner for loop */ 138 139 if (best_error == 0) 140 break; 141 } /* end of outer for loop */ 142 143 if(best_divisor == 0) return ERROR; /* can not find best match */ 144 145 recalcbaud = (uClk>>4) * bestm/(best_divisor * (bestm + bestd)); 146 147 /* reuse best_error to evaluate baud error*/ 148 if(baudrate>recalcbaud) best_error = baudrate - recalcbaud; 149 else best_error = recalcbaud -baudrate; 150 151 best_error = best_error * 100 / baudrate; 152 153 if (best_error < UART_ACCEPTED_BAUDRATE_ERROR) 154 { 155 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 156 { 157 ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN; 158 ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/DLM = UART_LOAD_DLM(best_divisor); 159 ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/DLL = UART_LOAD_DLL(best_divisor); 160 /* Then reset DLAB bit */ 161 ((LPC_UART1_TypeDef *)UARTx)->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK; 162 ((LPC_UART1_TypeDef *)UARTx)->FDR = (UART_FDR_MULVAL(bestm) \ 163 | UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK; 164 } 165 else 166 { 167 UARTx->LCR |= UART_LCR_DLAB_EN; 168 UARTx->/*DLIER.*/DLM = UART_LOAD_DLM(best_divisor); 169 UARTx->/*RBTHDLR.*/DLL = UART_LOAD_DLL(best_divisor); 170 /* Then reset DLAB bit */ 171 UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK; 172 UARTx->FDR = (UART_FDR_MULVAL(bestm) \ 173 | UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK; 174 } 175 errorStatus = SUCCESS; 176 } 177 178 return errorStatus; 179 } 180 181 /* End of Private Functions ---------------------------------------------------- */ 182 183 184 /* Public Functions ----------------------------------------------------------- */ 185 /** @addtogroup UART_Public_Functions 186 * @{ 187 */ 188 /* UART Init/DeInit functions -------------------------------------------------*/ 189 /********************************************************************//** 190 * @brief Initializes the UARTx peripheral according to the specified 191 * parameters in the UART_ConfigStruct. 192 * @param[in] UARTx UART peripheral selected, should be: 193 * - LPC_UART0: UART0 peripheral 194 * - LPC_UART1: UART1 peripheral 195 * - LPC_UART2: UART2 peripheral 196 * - LPC_UART3: UART3 peripheral 197 * @param[in] UART_ConfigStruct Pointer to a UART_CFG_Type structure 198 * that contains the configuration information for the 199 * specified UART peripheral. 200 * @return None 201 *********************************************************************/ 202 void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct) 203 { 204 uint32_t tmp; 205 206 // For debug mode 207 CHECK_PARAM(PARAM_UARTx(UARTx)); 208 CHECK_PARAM(PARAM_UART_DATABIT(UART_ConfigStruct->Databits)); 209 CHECK_PARAM(PARAM_UART_STOPBIT(UART_ConfigStruct->Stopbits)); 210 CHECK_PARAM(PARAM_UART_PARITY(UART_ConfigStruct->Parity)); 211 212 #ifdef _UART0 213 if(UARTx == (LPC_UART_TypeDef *)LPC_UART0) 214 { 215 /* Set up clock and power for UART module */ 216 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, ENABLE); 217 } 218 #endif 219 220 #ifdef _UART1 221 if(((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 222 { 223 /* Set up clock and power for UART module */ 224 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, ENABLE); 225 } 226 #endif 227 228 #ifdef _UART2 229 if(UARTx == LPC_UART2) 230 { 231 /* Set up clock and power for UART module */ 232 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, ENABLE); 233 } 234 #endif 235 236 #ifdef _UART3 237 if(UARTx == LPC_UART3) 238 { 239 /* Set up clock and power for UART module */ 240 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, ENABLE); 241 } 242 #endif 243 244 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 245 { 246 /* FIFOs are empty */ 247 ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN \ 248 | UART_FCR_RX_RS | UART_FCR_TX_RS); 249 // Disable FIFO 250 ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = 0; 251 252 // Dummy reading 253 while (((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_RDR) 254 { 255 tmp = ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR; 256 } 257 258 ((LPC_UART1_TypeDef *)UARTx)->TER = UART_TER_TXEN; 259 // Wait for current transmit complete 260 while (!(((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_THRE)); 261 // Disable Tx 262 ((LPC_UART1_TypeDef *)UARTx)->TER = 0; 263 264 // Disable interrupt 265 ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER = 0; 266 // Set LCR to default state 267 ((LPC_UART1_TypeDef *)UARTx)->LCR = 0; 268 // Set ACR to default state 269 ((LPC_UART1_TypeDef *)UARTx)->ACR = 0; 270 // Set Modem Control to default state 271 ((LPC_UART1_TypeDef *)UARTx)->MCR = 0; 272 // Set RS485 control to default state 273 ((LPC_UART1_TypeDef *)UARTx)->RS485CTRL = 0; 274 // Set RS485 delay timer to default state 275 ((LPC_UART1_TypeDef *)UARTx)->RS485DLY = 0; 276 // Set RS485 addr match to default state 277 ((LPC_UART1_TypeDef *)UARTx)->ADRMATCH = 0; 278 //Dummy Reading to Clear Status 279 tmp = ((LPC_UART1_TypeDef *)UARTx)->MSR; 280 tmp = ((LPC_UART1_TypeDef *)UARTx)->LSR; 281 } 282 else 283 { 284 /* FIFOs are empty */ 285 UARTx->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS); 286 // Disable FIFO 287 UARTx->/*IIFCR.*/FCR = 0; 288 289 // Dummy reading 290 while (UARTx->LSR & UART_LSR_RDR) 291 { 292 tmp = UARTx->/*RBTHDLR.*/RBR; 293 } 294 295 UARTx->TER = UART_TER_TXEN; 296 // Wait for current transmit complete 297 while (!(UARTx->LSR & UART_LSR_THRE)); 298 // Disable Tx 299 UARTx->TER = 0; 300 301 // Disable interrupt 302 UARTx->/*DLIER.*/IER = 0; 303 // Set LCR to default state 304 UARTx->LCR = 0; 305 // Set ACR to default state 306 UARTx->ACR = 0; 307 // Dummy reading 308 tmp = UARTx->LSR; 309 } 310 311 if (UARTx == LPC_UART3) 312 { 313 // Set IrDA to default state 314 UARTx->ICR = 0; 315 } 316 317 // Set Line Control register ---------------------------- 318 319 uart_set_divisors(UARTx, (UART_ConfigStruct->Baud_rate)); 320 321 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 322 { 323 tmp = (((LPC_UART1_TypeDef *)UARTx)->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \ 324 & UART_LCR_BITMASK; 325 } 326 else 327 { 328 tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK; 329 } 330 331 switch (UART_ConfigStruct->Databits){ 332 case UART_DATABIT_5: 333 tmp |= UART_LCR_WLEN5; 334 break; 335 case UART_DATABIT_6: 336 tmp |= UART_LCR_WLEN6; 337 break; 338 case UART_DATABIT_7: 339 tmp |= UART_LCR_WLEN7; 340 break; 341 case UART_DATABIT_8: 342 default: 343 tmp |= UART_LCR_WLEN8; 344 break; 345 } 346 347 if (UART_ConfigStruct->Parity == UART_PARITY_NONE) 348 { 349 // Do nothing... 350 } 351 else 352 { 353 tmp |= UART_LCR_PARITY_EN; 354 switch (UART_ConfigStruct->Parity) 355 { 356 case UART_PARITY_ODD: 357 tmp |= UART_LCR_PARITY_ODD; 358 break; 359 360 case UART_PARITY_EVEN: 361 tmp |= UART_LCR_PARITY_EVEN; 362 break; 363 364 case UART_PARITY_SP_1: 365 tmp |= UART_LCR_PARITY_F_1; 366 break; 367 368 case UART_PARITY_SP_0: 369 tmp |= UART_LCR_PARITY_F_0; 370 break; 371 default: 372 break; 373 } 374 } 375 376 switch (UART_ConfigStruct->Stopbits){ 377 case UART_STOPBIT_2: 378 tmp |= UART_LCR_STOPBIT_SEL; 379 break; 380 case UART_STOPBIT_1: 381 default: 382 // Do no thing 383 break; 384 } 385 386 387 // Write back to LCR, configure FIFO and Disable Tx 388 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 389 { 390 ((LPC_UART1_TypeDef *)UARTx)->LCR = (uint8_t)(tmp & UART_LCR_BITMASK); 391 } 392 else 393 { 394 UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK); 395 } 396 } 397 398 /*********************************************************************//** 399 * @brief De-initializes the UARTx peripheral registers to their 400 * default reset values. 401 * @param[in] UARTx UART peripheral selected, should be: 402 * - LPC_UART0: UART0 peripheral 403 * - LPC_UART1: UART1 peripheral 404 * - LPC_UART2: UART2 peripheral 405 * - LPC_UART3: UART3 peripheral 406 * @return None 407 **********************************************************************/ 408 void UART_DeInit(LPC_UART_TypeDef* UARTx) 409 { 410 // For debug mode 411 CHECK_PARAM(PARAM_UARTx(UARTx)); 412 413 UART_TxCmd(UARTx, DISABLE); 414 415 #ifdef _UART0 416 if (UARTx == (LPC_UART_TypeDef *)LPC_UART0) 417 { 418 /* Set up clock and power for UART module */ 419 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, DISABLE); 420 } 421 #endif 422 423 #ifdef _UART1 424 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 425 { 426 /* Set up clock and power for UART module */ 427 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, DISABLE); 428 } 429 #endif 430 431 #ifdef _UART2 432 if (UARTx == LPC_UART2) 433 { 434 /* Set up clock and power for UART module */ 435 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, DISABLE); 436 } 437 #endif 438 439 #ifdef _UART3 440 if (UARTx == LPC_UART3) 441 { 442 /* Set up clock and power for UART module */ 443 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, DISABLE); 444 } 445 #endif 446 } 447 448 /*****************************************************************************//** 449 * @brief Fills each UART_InitStruct member with its default value: 450 * - 9600 bps 451 * - 8-bit data 452 * - 1 Stopbit 453 * - None Parity 454 * @param[in] UART_InitStruct Pointer to a UART_CFG_Type structure 455 * which will be initialized. 456 * @return None 457 *******************************************************************************/ 458 void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct) 459 { 460 UART_InitStruct->Baud_rate = 9600; 461 UART_InitStruct->Databits = UART_DATABIT_8; 462 UART_InitStruct->Parity = UART_PARITY_NONE; 463 UART_InitStruct->Stopbits = UART_STOPBIT_1; 464 } 465 466 /* UART Send/Recieve functions -------------------------------------------------*/ 467 /*********************************************************************//** 468 * @brief Transmit a single data through UART peripheral 469 * @param[in] UARTx UART peripheral selected, should be: 470 * - LPC_UART0: UART0 peripheral 471 * - LPC_UART1: UART1 peripheral 472 * - LPC_UART2: UART2 peripheral 473 * - LPC_UART3: UART3 peripheral 474 * @param[in] Data Data to transmit (must be 8-bit long) 475 * @return None 476 **********************************************************************/ 477 void UART_SendByte(LPC_UART_TypeDef* UARTx, uint8_t Data) 478 { 479 CHECK_PARAM(PARAM_UARTx(UARTx)); 480 481 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 482 { 483 ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT; 484 } 485 else 486 { 487 UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT; 488 } 489 490 } 491 492 493 /*********************************************************************//** 494 * @brief Receive a single data from UART peripheral 495 * @param[in] UARTx UART peripheral selected, should be: 496 * - LPC_UART0: UART0 peripheral 497 * - LPC_UART1: UART1 peripheral 498 * - LPC_UART2: UART2 peripheral 499 * - LPC_UART3: UART3 peripheral 500 * @return Data received 501 **********************************************************************/ 502 uint8_t UART_ReceiveByte(LPC_UART_TypeDef* UARTx) 503 { 504 CHECK_PARAM(PARAM_UARTx(UARTx)); 505 506 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 507 { 508 return (((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT); 509 } 510 else 511 { 512 return (UARTx->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT); 513 } 514 } 515 516 /*********************************************************************//** 517 * @brief Send a block of data via UART peripheral 518 * @param[in] UARTx Selected UART peripheral used to send data, should be: 519 * - LPC_UART0: UART0 peripheral 520 * - LPC_UART1: UART1 peripheral 521 * - LPC_UART2: UART2 peripheral 522 * - LPC_UART3: UART3 peripheral 523 * @param[in] txbuf Pointer to Transmit buffer 524 * @param[in] buflen Length of Transmit buffer 525 * @param[in] flag Flag used in UART transfer, should be 526 * NONE_BLOCKING or BLOCKING 527 * @return Number of bytes sent. 528 * 529 * Note: when using UART in BLOCKING mode, a time-out condition is used 530 * via defined symbol UART_BLOCKING_TIMEOUT. 531 **********************************************************************/ 532 uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf, 533 uint32_t buflen, TRANSFER_BLOCK_Type flag) 534 { 535 uint32_t bToSend, bSent, timeOut, fifo_cnt; 536 uint8_t *pChar = txbuf; 537 538 bToSend = buflen; 539 540 // blocking mode 541 if (flag == BLOCKING) { 542 bSent = 0; 543 while (bToSend){ 544 timeOut = UART_BLOCKING_TIMEOUT; 545 // Wait for THR empty with timeout 546 while (!(UARTx->LSR & UART_LSR_THRE)) { 547 if (timeOut == 0) break; 548 timeOut--; 549 } 550 // Time out! 551 if(timeOut == 0) break; 552 fifo_cnt = UART_TX_FIFO_SIZE; 553 while (fifo_cnt && bToSend){ 554 UART_SendByte(UARTx, (*pChar++)); 555 fifo_cnt--; 556 bToSend--; 557 bSent++; 558 } 559 } 560 } 561 // None blocking mode 562 else { 563 bSent = 0; 564 while (bToSend) { 565 if (!(UARTx->LSR & UART_LSR_THRE)){ 566 break; 567 } 568 fifo_cnt = UART_TX_FIFO_SIZE; 569 while (fifo_cnt && bToSend) { 570 UART_SendByte(UARTx, (*pChar++)); 571 bToSend--; 572 fifo_cnt--; 573 bSent++; 574 } 575 } 576 } 577 return bSent; 578 } 579 580 /*********************************************************************//** 581 * @brief Receive a block of data via UART peripheral 582 * @param[in] UARTx Selected UART peripheral used to send data, 583 * should be: 584 * - LPC_UART0: UART0 peripheral 585 * - LPC_UART1: UART1 peripheral 586 * - LPC_UART2: UART2 peripheral 587 * - LPC_UART3: UART3 peripheral 588 * @param[out] rxbuf Pointer to Received buffer 589 * @param[in] buflen Length of Received buffer 590 * @param[in] flag Flag mode, should be NONE_BLOCKING or BLOCKING 591 592 * @return Number of bytes received 593 * 594 * Note: when using UART in BLOCKING mode, a time-out condition is used 595 * via defined symbol UART_BLOCKING_TIMEOUT. 596 **********************************************************************/ 597 uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \ 598 uint32_t buflen, TRANSFER_BLOCK_Type flag) 599 { 600 uint32_t bToRecv, bRecv, timeOut; 601 uint8_t *pChar = rxbuf; 602 603 bToRecv = buflen; 604 605 // Blocking mode 606 if (flag == BLOCKING) { 607 bRecv = 0; 608 while (bToRecv){ 609 timeOut = UART_BLOCKING_TIMEOUT; 610 while (!(UARTx->LSR & UART_LSR_RDR)){ 611 if (timeOut == 0) break; 612 timeOut--; 613 } 614 // Time out! 615 if(timeOut == 0) break; 616 // Get data from the buffer 617 (*pChar++) = UART_ReceiveByte(UARTx); 618 bToRecv--; 619 bRecv++; 620 } 621 } 622 // None blocking mode 623 else { 624 bRecv = 0; 625 while (bToRecv) { 626 if (!(UARTx->LSR & UART_LSR_RDR)) { 627 break; 628 } else { 629 (*pChar++) = UART_ReceiveByte(UARTx); 630 bRecv++; 631 bToRecv--; 632 } 633 } 634 } 635 return bRecv; 636 } 637 638 /*********************************************************************//** 639 * @brief Force BREAK character on UART line, output pin UARTx TXD is 640 forced to logic 0. 641 * @param[in] UARTx UART peripheral selected, should be: 642 * - LPC_UART0: UART0 peripheral 643 * - LPC_UART1: UART1 peripheral 644 * - LPC_UART2: UART2 peripheral 645 * - LPC_UART3: UART3 peripheral 646 * @return None 647 **********************************************************************/ 648 void UART_ForceBreak(LPC_UART_TypeDef* UARTx) 649 { 650 CHECK_PARAM(PARAM_UARTx(UARTx)); 651 652 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 653 { 654 ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_BREAK_EN; 655 } 656 else 657 { 658 UARTx->LCR |= UART_LCR_BREAK_EN; 659 } 660 } 661 662 663 /********************************************************************//** 664 * @brief Enable or disable specified UART interrupt. 665 * @param[in] UARTx UART peripheral selected, should be 666 * - LPC_UART0: UART0 peripheral 667 * - LPC_UART1: UART1 peripheral 668 * - LPC_UART2: UART2 peripheral 669 * - LPC_UART3: UART3 peripheral 670 * @param[in] UARTIntCfg Specifies the interrupt flag, 671 * should be one of the following: 672 - UART_INTCFG_RBR : RBR Interrupt enable 673 - UART_INTCFG_THRE : THR Interrupt enable 674 - UART_INTCFG_RLS : RX line status interrupt enable 675 - UART1_INTCFG_MS : Modem status interrupt enable (UART1 only) 676 - UART1_INTCFG_CTS : CTS1 signal transition interrupt enable (UART1 only) 677 - UART_INTCFG_ABEO : Enables the end of auto-baud interrupt 678 - UART_INTCFG_ABTO : Enables the auto-baud time-out interrupt 679 * @param[in] NewState New state of specified UART interrupt type, 680 * should be: 681 * - ENALBE: Enable this UART interrupt type. 682 * - DISALBE: Disable this UART interrupt type. 683 * @return None 684 *********************************************************************/ 685 void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, FunctionalState NewState) 686 { 687 uint32_t tmp = 0; 688 689 CHECK_PARAM(PARAM_UARTx(UARTx)); 690 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 691 692 switch(UARTIntCfg){ 693 case UART_INTCFG_RBR: 694 tmp = UART_IER_RBRINT_EN; 695 break; 696 case UART_INTCFG_THRE: 697 tmp = UART_IER_THREINT_EN; 698 break; 699 case UART_INTCFG_RLS: 700 tmp = UART_IER_RLSINT_EN; 701 break; 702 case UART1_INTCFG_MS: 703 tmp = UART1_IER_MSINT_EN; 704 break; 705 case UART1_INTCFG_CTS: 706 tmp = UART1_IER_CTSINT_EN; 707 break; 708 case UART_INTCFG_ABEO: 709 tmp = UART_IER_ABEOINT_EN; 710 break; 711 case UART_INTCFG_ABTO: 712 tmp = UART_IER_ABTOINT_EN; 713 break; 714 } 715 716 if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1) 717 { 718 CHECK_PARAM((PARAM_UART_INTCFG(UARTIntCfg)) || (PARAM_UART1_INTCFG(UARTIntCfg))); 719 } 720 else 721 { 722 CHECK_PARAM(PARAM_UART_INTCFG(UARTIntCfg)); 723 } 724 725 if (NewState == ENABLE) 726 { 727 if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1) 728 { 729 ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER |= tmp; 730 } 731 else 732 { 733 UARTx->/*DLIER.*/IER |= tmp; 734 } 735 } 736 else 737 { 738 if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1) 739 { 740 ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER &= (~tmp) & UART1_IER_BITMASK; 741 } 742 else 743 { 744 UARTx->/*DLIER.*/IER &= (~tmp) & UART_IER_BITMASK; 745 } 746 } 747 } 748 749 750 /********************************************************************//** 751 * @brief Get current value of Line Status register in UART peripheral. 752 * @param[in] UARTx UART peripheral selected, should be: 753 * - LPC_UART0: UART0 peripheral 754 * - LPC_UART1: UART1 peripheral 755 * - LPC_UART2: UART2 peripheral 756 * - LPC_UART3: UART3 peripheral 757 * @return Current value of Line Status register in UART peripheral. 758 * Note: The return value of this function must be ANDed with each member in 759 * UART_LS_Type enumeration to determine current flag status 760 * corresponding to each Line status type. Because some flags in 761 * Line Status register will be cleared after reading, the next reading 762 * Line Status register could not be correct. So this function used to 763 * read Line status register in one time only, then the return value 764 * used to check all flags. 765 *********************************************************************/ 766 uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx) 767 { 768 CHECK_PARAM(PARAM_UARTx(UARTx)); 769 770 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 771 { 772 return ((((LPC_UART1_TypeDef *)LPC_UART1)->LSR) & UART_LSR_BITMASK); 773 } 774 else 775 { 776 return ((UARTx->LSR) & UART_LSR_BITMASK); 777 } 778 } 779 780 /********************************************************************//** 781 * @brief Get Interrupt Identification value 782 * @param[in] UARTx UART peripheral selected, should be: 783 * - LPC_UART0: UART0 peripheral 784 * - LPC_UART1: UART1 peripheral 785 * - LPC_UART2: UART2 peripheral 786 * - LPC_UART3: UART3 peripheral 787 * @return Current value of UART UIIR register in UART peripheral. 788 *********************************************************************/ 789 uint32_t UART_GetIntId(LPC_UART_TypeDef* UARTx) 790 { 791 CHECK_PARAM(PARAM_UARTx(UARTx)); 792 return (UARTx->IIR & 0x03CF); 793 } 794 795 /*********************************************************************//** 796 * @brief Check whether if UART is busy or not 797 * @param[in] UARTx UART peripheral selected, should be: 798 * - LPC_UART0: UART0 peripheral 799 * - LPC_UART1: UART1 peripheral 800 * - LPC_UART2: UART2 peripheral 801 * - LPC_UART3: UART3 peripheral 802 * @return RESET if UART is not busy, otherwise return SET. 803 **********************************************************************/ 804 FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx) 805 { 806 if (UARTx->LSR & UART_LSR_TEMT){ 807 return RESET; 808 } else { 809 return SET; 810 } 811 } 812 813 814 /*********************************************************************//** 815 * @brief Configure FIFO function on selected UART peripheral 816 * @param[in] UARTx UART peripheral selected, should be: 817 * - LPC_UART0: UART0 peripheral 818 * - LPC_UART1: UART1 peripheral 819 * - LPC_UART2: UART2 peripheral 820 * - LPC_UART3: UART3 peripheral 821 * @param[in] FIFOCfg Pointer to a UART_FIFO_CFG_Type Structure that 822 * contains specified information about FIFO configuration 823 * @return none 824 **********************************************************************/ 825 void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg) 826 { 827 uint8_t tmp = 0; 828 829 CHECK_PARAM(PARAM_UARTx(UARTx)); 830 CHECK_PARAM(PARAM_UART_FIFO_LEVEL(FIFOCfg->FIFO_Level)); 831 CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_DMAMode)); 832 CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetRxBuf)); 833 CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetTxBuf)); 834 835 tmp |= UART_FCR_FIFO_EN; 836 switch (FIFOCfg->FIFO_Level){ 837 case UART_FIFO_TRGLEV0: 838 tmp |= UART_FCR_TRG_LEV0; 839 break; 840 case UART_FIFO_TRGLEV1: 841 tmp |= UART_FCR_TRG_LEV1; 842 break; 843 case UART_FIFO_TRGLEV2: 844 tmp |= UART_FCR_TRG_LEV2; 845 break; 846 case UART_FIFO_TRGLEV3: 847 default: 848 tmp |= UART_FCR_TRG_LEV3; 849 break; 850 } 851 852 if (FIFOCfg->FIFO_ResetTxBuf == ENABLE) 853 { 854 tmp |= UART_FCR_TX_RS; 855 } 856 if (FIFOCfg->FIFO_ResetRxBuf == ENABLE) 857 { 858 tmp |= UART_FCR_RX_RS; 859 } 860 if (FIFOCfg->FIFO_DMAMode == ENABLE) 861 { 862 tmp |= UART_FCR_DMAMODE_SEL; 863 } 864 865 866 //write to FIFO control register 867 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 868 { 869 ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK; 870 } 871 else 872 { 873 UARTx->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK; 874 } 875 } 876 877 /*****************************************************************************//** 878 * @brief Fills each UART_FIFOInitStruct member with its default value: 879 * - FIFO_DMAMode = DISABLE 880 * - FIFO_Level = UART_FIFO_TRGLEV0 881 * - FIFO_ResetRxBuf = ENABLE 882 * - FIFO_ResetTxBuf = ENABLE 883 * - FIFO_State = ENABLE 884 885 * @param[in] UART_FIFOInitStruct Pointer to a UART_FIFO_CFG_Type structure 886 * which will be initialized. 887 * @return None 888 *******************************************************************************/ 889 void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct) 890 { 891 UART_FIFOInitStruct->FIFO_DMAMode = DISABLE; 892 UART_FIFOInitStruct->FIFO_Level = UART_FIFO_TRGLEV0; 893 UART_FIFOInitStruct->FIFO_ResetRxBuf = ENABLE; 894 UART_FIFOInitStruct->FIFO_ResetTxBuf = ENABLE; 895 } 896 897 898 /*********************************************************************//** 899 * @brief Start/Stop Auto Baudrate activity 900 * @param[in] UARTx UART peripheral selected, should be 901 * - LPC_UART0: UART0 peripheral 902 * - LPC_UART1: UART1 peripheral 903 * - LPC_UART2: UART2 peripheral 904 * - LPC_UART3: UART3 peripheral 905 * @param[in] ABConfigStruct A pointer to UART_AB_CFG_Type structure that 906 * contains specified information about UART 907 * auto baudrate configuration 908 * @param[in] NewState New State of Auto baudrate activity, should be: 909 * - ENABLE: Start this activity 910 * - DISABLE: Stop this activity 911 * Note: Auto-baudrate mode enable bit will be cleared once this mode 912 * completed. 913 * @return none 914 **********************************************************************/ 915 void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \ 916 FunctionalState NewState) 917 { 918 uint32_t tmp; 919 920 CHECK_PARAM(PARAM_UARTx(UARTx)); 921 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 922 923 tmp = 0; 924 if (NewState == ENABLE) { 925 if (ABConfigStruct->ABMode == UART_AUTOBAUD_MODE1){ 926 tmp |= UART_ACR_MODE; 927 } 928 if (ABConfigStruct->AutoRestart == ENABLE){ 929 tmp |= UART_ACR_AUTO_RESTART; 930 } 931 } 932 933 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 934 { 935 if (NewState == ENABLE) 936 { 937 // Clear DLL and DLM value 938 ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN; 939 ((LPC_UART1_TypeDef *)UARTx)->DLL = 0; 940 ((LPC_UART1_TypeDef *)UARTx)->DLM = 0; 941 ((LPC_UART1_TypeDef *)UARTx)->LCR &= ~UART_LCR_DLAB_EN; 942 // FDR value must be reset to default value 943 ((LPC_UART1_TypeDef *)UARTx)->FDR = 0x10; 944 ((LPC_UART1_TypeDef *)UARTx)->ACR = UART_ACR_START | tmp; 945 } 946 else 947 { 948 ((LPC_UART1_TypeDef *)UARTx)->ACR = 0; 949 } 950 } 951 else 952 { 953 if (NewState == ENABLE) 954 { 955 // Clear DLL and DLM value 956 UARTx->LCR |= UART_LCR_DLAB_EN; 957 UARTx->DLL = 0; 958 UARTx->DLM = 0; 959 UARTx->LCR &= ~UART_LCR_DLAB_EN; 960 // FDR value must be reset to default value 961 UARTx->FDR = 0x10; 962 UARTx->ACR = UART_ACR_START | tmp; 963 } 964 else 965 { 966 UARTx->ACR = 0; 967 } 968 } 969 } 970 971 /*********************************************************************//** 972 * @brief Clear Autobaud Interrupt Pending 973 * @param[in] UARTx UART peripheral selected, should be 974 * - LPC_UART0: UART0 peripheral 975 * - LPC_UART1: UART1 peripheral 976 * - LPC_UART2: UART2 peripheral 977 * - LPC_UART3: UART3 peripheral 978 * @param[in] ABIntType type of auto-baud interrupt, should be: 979 * - UART_AUTOBAUD_INTSTAT_ABEO: End of Auto-baud interrupt 980 * - UART_AUTOBAUD_INTSTAT_ABTO: Auto-baud time out interrupt 981 * @return none 982 **********************************************************************/ 983 void UART_ABClearIntPending(LPC_UART_TypeDef *UARTx, UART_ABEO_Type ABIntType) 984 { 985 CHECK_PARAM(PARAM_UARTx(UARTx)); 986 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 987 { 988 UARTx->ACR |= ABIntType; 989 } 990 else 991 UARTx->ACR |= ABIntType; 992 } 993 994 /*********************************************************************//** 995 * @brief Enable/Disable transmission on UART TxD pin 996 * @param[in] UARTx UART peripheral selected, should be: 997 * - LPC_UART0: UART0 peripheral 998 * - LPC_UART1: UART1 peripheral 999 * - LPC_UART2: UART2 peripheral 1000 * - LPC_UART3: UART3 peripheral 1001 * @param[in] NewState New State of Tx transmission function, should be: 1002 * - ENABLE: Enable this function 1003 - DISABLE: Disable this function 1004 * @return none 1005 **********************************************************************/ 1006 void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState) 1007 { 1008 CHECK_PARAM(PARAM_UARTx(UARTx)); 1009 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 1010 1011 if (NewState == ENABLE) 1012 { 1013 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 1014 { 1015 ((LPC_UART1_TypeDef *)UARTx)->TER |= UART_TER_TXEN; 1016 } 1017 else 1018 { 1019 UARTx->TER |= UART_TER_TXEN; 1020 } 1021 } 1022 else 1023 { 1024 if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) 1025 { 1026 ((LPC_UART1_TypeDef *)UARTx)->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK; 1027 } 1028 else 1029 { 1030 UARTx->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK; 1031 } 1032 } 1033 } 1034 1035 /* UART IrDA functions ---------------------------------------------------*/ 1036 1037 #ifdef _UART3 1038 1039 /*********************************************************************//** 1040 * @brief Enable or disable inverting serial input function of IrDA 1041 * on UART peripheral. 1042 * @param[in] UARTx UART peripheral selected, should be LPC_UART3 (only) 1043 * @param[in] NewState New state of inverting serial input, should be: 1044 * - ENABLE: Enable this function. 1045 * - DISABLE: Disable this function. 1046 * @return none 1047 **********************************************************************/ 1048 void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState) 1049 { 1050 CHECK_PARAM(PARAM_UART_IrDA(UARTx)); 1051 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 1052 1053 if (NewState == ENABLE) 1054 { 1055 UARTx->ICR |= UART_ICR_IRDAINV; 1056 } 1057 else if (NewState == DISABLE) 1058 { 1059 UARTx->ICR &= (~UART_ICR_IRDAINV) & UART_ICR_BITMASK; 1060 } 1061 } 1062 1063 1064 /*********************************************************************//** 1065 * @brief Enable or disable IrDA function on UART peripheral. 1066 * @param[in] UARTx UART peripheral selected, should be LPC_UART3 (only) 1067 * @param[in] NewState New state of IrDA function, should be: 1068 * - ENABLE: Enable this function. 1069 * - DISABLE: Disable this function. 1070 * @return none 1071 **********************************************************************/ 1072 void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState) 1073 { 1074 CHECK_PARAM(PARAM_UART_IrDA(UARTx)); 1075 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 1076 1077 if (NewState == ENABLE) 1078 { 1079 UARTx->ICR |= UART_ICR_IRDAEN; 1080 } 1081 else 1082 { 1083 UARTx->ICR &= (~UART_ICR_IRDAEN) & UART_ICR_BITMASK; 1084 } 1085 } 1086 1087 1088 /*********************************************************************//** 1089 * @brief Configure Pulse divider for IrDA function on UART peripheral. 1090 * @param[in] UARTx UART peripheral selected, should be LPC_UART3 (only) 1091 * @param[in] PulseDiv Pulse Divider value from Peripheral clock, 1092 * should be one of the following: 1093 - UART_IrDA_PULSEDIV2 : Pulse width = 2 * Tpclk 1094 - UART_IrDA_PULSEDIV4 : Pulse width = 4 * Tpclk 1095 - UART_IrDA_PULSEDIV8 : Pulse width = 8 * Tpclk 1096 - UART_IrDA_PULSEDIV16 : Pulse width = 16 * Tpclk 1097 - UART_IrDA_PULSEDIV32 : Pulse width = 32 * Tpclk 1098 - UART_IrDA_PULSEDIV64 : Pulse width = 64 * Tpclk 1099 - UART_IrDA_PULSEDIV128 : Pulse width = 128 * Tpclk 1100 - UART_IrDA_PULSEDIV256 : Pulse width = 256 * Tpclk 1101 1102 * @return none 1103 **********************************************************************/ 1104 void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv) 1105 { 1106 uint32_t tmp, tmp1; 1107 CHECK_PARAM(PARAM_UART_IrDA(UARTx)); 1108 CHECK_PARAM(PARAM_UART_IrDA_PULSEDIV(PulseDiv)); 1109 1110 tmp1 = UART_ICR_PULSEDIV(PulseDiv); 1111 tmp = UARTx->ICR & (~UART_ICR_PULSEDIV(7)); 1112 tmp |= tmp1 | UART_ICR_FIXPULSE_EN; 1113 UARTx->ICR = tmp & UART_ICR_BITMASK; 1114 } 1115 1116 #endif 1117 1118 1119 /* UART1 FullModem function ---------------------------------------------*/ 1120 1121 #ifdef _UART1 1122 1123 /*********************************************************************//** 1124 * @brief Force pin DTR/RTS corresponding to given state (Full modem mode) 1125 * @param[in] UARTx LPC_UART1 (only) 1126 * @param[in] Pin Pin that NewState will be applied to, should be: 1127 * - UART1_MODEM_PIN_DTR: DTR pin. 1128 * - UART1_MODEM_PIN_RTS: RTS pin. 1129 * @param[in] NewState New State of DTR/RTS pin, should be: 1130 * - INACTIVE: Force the pin to inactive signal. 1131 - ACTIVE: Force the pin to active signal. 1132 * @return none 1133 **********************************************************************/ 1134 void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \ 1135 UART1_SignalState NewState) 1136 { 1137 uint8_t tmp = 0; 1138 1139 CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); 1140 CHECK_PARAM(PARAM_UART1_MODEM_PIN(Pin)); 1141 CHECK_PARAM(PARAM_UART1_SIGNALSTATE(NewState)); 1142 1143 switch (Pin){ 1144 case UART1_MODEM_PIN_DTR: 1145 tmp = UART1_MCR_DTR_CTRL; 1146 break; 1147 case UART1_MODEM_PIN_RTS: 1148 tmp = UART1_MCR_RTS_CTRL; 1149 break; 1150 default: 1151 break; 1152 } 1153 1154 if (NewState == ACTIVE){ 1155 UARTx->MCR |= tmp; 1156 } else { 1157 UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK; 1158 } 1159 } 1160 1161 1162 /*********************************************************************//** 1163 * @brief Configure Full Modem mode for UART peripheral 1164 * @param[in] UARTx LPC_UART1 (only) 1165 * @param[in] Mode Full Modem mode, should be: 1166 * - UART1_MODEM_MODE_LOOPBACK: Loop back mode. 1167 * - UART1_MODEM_MODE_AUTO_RTS: Auto-RTS mode. 1168 * - UART1_MODEM_MODE_AUTO_CTS: Auto-CTS mode. 1169 * @param[in] NewState New State of this mode, should be: 1170 * - ENABLE: Enable this mode. 1171 - DISABLE: Disable this mode. 1172 * @return none 1173 **********************************************************************/ 1174 void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \ 1175 FunctionalState NewState) 1176 { 1177 uint8_t tmp = 0; 1178 1179 CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); 1180 CHECK_PARAM(PARAM_UART1_MODEM_MODE(Mode)); 1181 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 1182 1183 switch(Mode){ 1184 case UART1_MODEM_MODE_LOOPBACK: 1185 tmp = UART1_MCR_LOOPB_EN; 1186 break; 1187 case UART1_MODEM_MODE_AUTO_RTS: 1188 tmp = UART1_MCR_AUTO_RTS_EN; 1189 break; 1190 case UART1_MODEM_MODE_AUTO_CTS: 1191 tmp = UART1_MCR_AUTO_CTS_EN; 1192 break; 1193 default: 1194 break; 1195 } 1196 1197 if (NewState == ENABLE) 1198 { 1199 UARTx->MCR |= tmp; 1200 } 1201 else 1202 { 1203 UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK; 1204 } 1205 } 1206 1207 1208 /*********************************************************************//** 1209 * @brief Get current status of modem status register 1210 * @param[in] UARTx LPC_UART1 (only) 1211 * @return Current value of modem status register 1212 * Note: The return value of this function must be ANDed with each member 1213 * UART_MODEM_STAT_type enumeration to determine current flag status 1214 * corresponding to each modem flag status. Because some flags in 1215 * modem status register will be cleared after reading, the next reading 1216 * modem register could not be correct. So this function used to 1217 * read modem status register in one time only, then the return value 1218 * used to check all flags. 1219 **********************************************************************/ 1220 uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx) 1221 { 1222 CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); 1223 return ((UARTx->MSR) & UART1_MSR_BITMASK); 1224 } 1225 1226 1227 /* UART RS485 functions --------------------------------------------------------------*/ 1228 1229 /*********************************************************************//** 1230 * @brief Configure UART peripheral in RS485 mode according to the specified 1231 * parameters in the RS485ConfigStruct. 1232 * @param[in] UARTx LPC_UART1 (only) 1233 * @param[in] RS485ConfigStruct Pointer to a UART1_RS485_CTRLCFG_Type structure 1234 * that contains the configuration information for specified UART 1235 * in RS485 mode. 1236 * @return None 1237 **********************************************************************/ 1238 void UART_RS485Config(LPC_UART1_TypeDef *UARTx, UART1_RS485_CTRLCFG_Type *RS485ConfigStruct) 1239 { 1240 uint32_t tmp; 1241 1242 CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); 1243 CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoAddrDetect_State)); 1244 CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoDirCtrl_State)); 1245 CHECK_PARAM(PARAM_UART1_RS485_CFG_DELAYVALUE(RS485ConfigStruct->DelayValue)); 1246 CHECK_PARAM(PARAM_SETSTATE(RS485ConfigStruct->DirCtrlPol_Level)); 1247 CHECK_PARAM(PARAM_UART_RS485_DIRCTRL_PIN(RS485ConfigStruct->DirCtrlPin)); 1248 CHECK_PARAM(PARAM_UART1_RS485_CFG_MATCHADDRVALUE(RS485ConfigStruct->MatchAddrValue)); 1249 CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->NormalMultiDropMode_State)); 1250 CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->Rx_State)); 1251 1252 tmp = 0; 1253 // If Auto Direction Control is enabled - This function is used in Master mode 1254 if (RS485ConfigStruct->AutoDirCtrl_State == ENABLE) 1255 { 1256 tmp |= UART1_RS485CTRL_DCTRL_EN; 1257 1258 // Set polar 1259 if (RS485ConfigStruct->DirCtrlPol_Level == SET) 1260 { 1261 tmp |= UART1_RS485CTRL_OINV_1; 1262 } 1263 1264 // Set pin according to 1265 if (RS485ConfigStruct->DirCtrlPin == UART1_RS485_DIRCTRL_DTR) 1266 { 1267 tmp |= UART1_RS485CTRL_SEL_DTR; 1268 } 1269 1270 // Fill delay time 1271 UARTx->RS485DLY = RS485ConfigStruct->DelayValue & UART1_RS485DLY_BITMASK; 1272 } 1273 1274 // MultiDrop mode is enable 1275 if (RS485ConfigStruct->NormalMultiDropMode_State == ENABLE) 1276 { 1277 tmp |= UART1_RS485CTRL_NMM_EN; 1278 } 1279 1280 // Auto Address Detect function 1281 if (RS485ConfigStruct->AutoAddrDetect_State == ENABLE) 1282 { 1283 tmp |= UART1_RS485CTRL_AADEN; 1284 // Fill Match Address 1285 UARTx->ADRMATCH = RS485ConfigStruct->MatchAddrValue & UART1_RS485ADRMATCH_BITMASK; 1286 } 1287 1288 1289 // Receiver is disable 1290 if (RS485ConfigStruct->Rx_State == DISABLE) 1291 { 1292 tmp |= UART1_RS485CTRL_RX_DIS; 1293 } 1294 1295 // write back to RS485 control register 1296 UARTx->RS485CTRL = tmp & UART1_RS485CTRL_BITMASK; 1297 1298 // Enable Parity function and leave parity in stick '0' parity as default 1299 UARTx->LCR |= (UART_LCR_PARITY_F_0 | UART_LCR_PARITY_EN); 1300 } 1301 1302 /*********************************************************************//** 1303 * @brief Enable/Disable receiver in RS485 module in UART1 1304 * @param[in] UARTx LPC_UART1 (only) 1305 * @param[in] NewState New State of command, should be: 1306 * - ENABLE: Enable this function. 1307 * - DISABLE: Disable this function. 1308 * @return None 1309 **********************************************************************/ 1310 void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState) 1311 { 1312 if (NewState == ENABLE){ 1313 UARTx->RS485CTRL &= ~UART1_RS485CTRL_RX_DIS; 1314 } else { 1315 UARTx->RS485CTRL |= UART1_RS485CTRL_RX_DIS; 1316 } 1317 } 1318 1319 /*********************************************************************//** 1320 * @brief Send data on RS485 bus with specified parity stick value (9-bit mode). 1321 * @param[in] UARTx LPC_UART1 (only) 1322 * @param[in] pDatFrm Pointer to data frame. 1323 * @param[in] size Size of data. 1324 * @param[in] ParityStick Parity Stick value, should be 0 or 1. 1325 * @return None 1326 **********************************************************************/ 1327 static uint32_t UART_RS485Send(LPC_UART1_TypeDef *UARTx, uint8_t *pDatFrm, \ 1328 uint32_t size, uint8_t ParityStick) 1329 { 1330 uint8_t tmp, save; 1331 uint32_t cnt; 1332 1333 if (ParityStick){ 1334 save = tmp = UARTx->LCR & UART_LCR_BITMASK; 1335 tmp &= ~(UART_LCR_PARITY_EVEN); 1336 UARTx->LCR = tmp; 1337 cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING); 1338 while (!(UARTx->LSR & UART_LSR_TEMT)); 1339 UARTx->LCR = save; 1340 } else { 1341 cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING); 1342 while (!(UARTx->LSR & UART_LSR_TEMT)); 1343 } 1344 return cnt; 1345 } 1346 1347 /*********************************************************************//** 1348 * @brief Send Slave address frames on RS485 bus. 1349 * @param[in] UARTx LPC_UART1 (only) 1350 * @param[in] SlvAddr Slave Address. 1351 * @return None 1352 **********************************************************************/ 1353 void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr) 1354 { 1355 UART_RS485Send(UARTx, &SlvAddr, 1, 1); 1356 } 1357 1358 /*********************************************************************//** 1359 * @brief Send Data frames on RS485 bus. 1360 * @param[in] UARTx LPC_UART1 (only) 1361 * @param[in] pData Pointer to data to be sent. 1362 * @param[in] size Size of data frame to be sent. 1363 * @return None 1364 **********************************************************************/ 1365 uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size) 1366 { 1367 return (UART_RS485Send(UARTx, pData, size, 0)); 1368 } 1369 1370 #endif /* _UART1 */ 1371 1372 #endif /* _UART */ 1373 1374 /** 1375 * @} 1376 */ 1377 1378 /** 1379 * @} 1380 */ 1381 /* --------------------------------- End Of File ------------------------------ */ 1382