lpc17xx_debug.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /*
  2. * Copyright (C) 2012 by Ole Reinhardt (ole.reinhardt@embedded-it.de)
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*
  35. * \verbatim
  36. * $Id: $
  37. * \endverbatim
  38. */
  39. #include <inttypes.h>
  40. #include <cfg/clock.h>
  41. #include <dev/debug.h>
  42. #include <dev/gpio.h>
  43. #if defined(MCU_LPC176x)
  44. #include <arch/cm3/nxp/lpc176x.h>
  45. #include <arch/cm3/nxp/lpc176x_clk.h>
  46. #include <arch/cm3/nxp/lpc176x_gpio.h>
  47. #elif defined(MCU_LPC177x_8x)
  48. #include <arch/cm3/nxp/lpc177x_8x.h>
  49. #include <arch/cm3/nxp/lpc177x_8x_clk.h>
  50. #include <arch/cm3/nxp/lpc177x_8x_gpio.h>
  51. #elif defined(MCU_LPC407x_8x)
  52. #include <arch/cm3/nxp/lpc407x_8x.h>
  53. #include <arch/cm3/nxp/lpc407x_8x_clk.h>
  54. #include <arch/cm3/nxp/lpc177x_8x_gpio.h>
  55. #else
  56. #warning "Unknown LPC familiy"
  57. #endif
  58. #include <arch/cm3/nxp/lpc17xx_usart.h>
  59. /*!
  60. * \addtogroup xgNutArchArmLpc17xxDebug
  61. */
  62. /*@{*/
  63. /* USART default speed if not preset by nutconfig */
  64. #ifndef DEBUG_INIT_BAUTRATE
  65. #define DEBUG_INIT_BAUTRATE 115200
  66. #endif
  67. /*!
  68. * \brief Carefully enable USART hardware functions.
  69. *
  70. * Always enabale transmitter and receiver, even on read-only or
  71. * write-only mode.
  72. */
  73. static void Lpc17xxDevDebugEnable(void)
  74. {
  75. /* Enable UART transmitter. The receiver can not be enabled seperately on
  76. the LPC architecture. We just could disable the RX FIFOs, is this a
  77. good idea?
  78. */
  79. USARTn->TER = UART_TER_TXEN;
  80. }
  81. /*!
  82. * \brief Carefully disable USART hardware functions.
  83. *
  84. * TODO: Beschreibung anpassen
  85. * This routine is called before changing cruical settings like
  86. * baudrate, frame format etc.
  87. *
  88. * The previous version uses a 10ms delay to make sure, that any
  89. * incoming or outgoing character is processed. However, this time
  90. * depends on the baudrate.
  91. *
  92. * In fact we do not need to take care of incoming characters,
  93. * when changing such settings.
  94. *
  95. * For outgoing characters however, settings may be changed on
  96. * the fly and we should wait, until the last character transmitted
  97. * with the old settings has left the shift register. While TXRDY
  98. * is set when the holding register is empty, TXEMPTY is set when the
  99. * shift register is empty. The bad news is, that both are zero, if
  100. * the transmitter is disabled. We are not able to determine this
  101. * state. So we check TXRDY first and, if set, wait for any character
  102. * currently in the shift register.
  103. */
  104. static void Lpc17xxDevDebugDisable(void)
  105. {
  106. /* If the transmitter is enabled, wait until all bits had been shifted out. */
  107. if (USARTn->TER & UART_TER_TXEN) {
  108. while ((USARTn->LSR & UART_LSR_TEMT) == 0);
  109. }
  110. /* Disable Transmitter, receiver can not be disabled on the LPC
  111. architecture. We just could disable the RX FIFOs, is this a good idea?
  112. */
  113. USARTn->TER = 0;
  114. }
  115. /*!
  116. * \brief Set the USART hardware bit rate.
  117. *
  118. * This function is called by ioctl function of the upper level USART
  119. * driver through the USARTDCB jump table.
  120. *
  121. * \param rate Number of bits per second.
  122. *
  123. * \return 0 on success, -1 otherwise.
  124. */
  125. static int Lpc17xxDevDebugSetSpeed(uint32_t baudrate)
  126. {
  127. uint32_t uart_clock;
  128. uint32_t calcBaudrate = 0;
  129. uint32_t temp = 0;
  130. uint32_t mulFracDiv, dividerAddFracDiv;
  131. uint32_t diviser = 0 ;
  132. uint32_t bestm = 1;
  133. uint32_t bestd = 0;
  134. uint32_t best_divisor = 0;
  135. uint32_t relativeError = 0;
  136. uint32_t best_error = 100000;
  137. /* get UART block clock */
  138. uart_clock = NutArchClockGet(NUT_HWCLK_PCLK);
  139. #if defined(MCU_LPC176x)
  140. if ((LPC_UART_TypeDef*)USARTn == LPC_UART0) {
  141. uart_clock /= Lpc176x_PclkDivGet(CLKPWR_PCLKSEL_UART0);
  142. } else
  143. if ((LPC_UART1_TypeDef*)USARTn == LPC_UART1) {
  144. uart_clock /= Lpc176x_PclkDivGet(CLKPWR_PCLKSEL_UART1);
  145. } else
  146. if ((LPC_UART_TypeDef*)USARTn == LPC_UART2) {
  147. uart_clock /= Lpc176x_PclkDivGet(CLKPWR_PCLKSEL_UART2);
  148. } else
  149. if ((LPC_UART_TypeDef*)USARTn == LPC_UART3) {
  150. uart_clock /= Lpc176x_PclkDivGet(CLKPWR_PCLKSEL_UART3);
  151. }
  152. #endif
  153. uart_clock = uart_clock >> 4; /* div by 16 */
  154. /* Baudrate calculation is done according the following formula:
  155. BaudRate= uart_clock * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL)
  156. To avoid floating point calculation the formulae is adjusted with the
  157. multiply and divide method.
  158. The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
  159. 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15
  160. */
  161. for (mulFracDiv = 1 ; mulFracDiv <= 15 ;mulFracDiv++)
  162. {
  163. for (dividerAddFracDiv = 0 ; dividerAddFracDiv <= 15 ;dividerAddFracDiv++)
  164. {
  165. temp = (mulFracDiv * uart_clock) / ((mulFracDiv + dividerAddFracDiv));
  166. diviser = temp / baudrate;
  167. if ((temp % baudrate) > (baudrate / 2))
  168. diviser++;
  169. if (diviser > 2 && diviser < 65536)
  170. {
  171. calcBaudrate = temp / diviser;
  172. if (calcBaudrate <= baudrate) {
  173. relativeError = baudrate - calcBaudrate;
  174. } else {
  175. relativeError = calcBaudrate - baudrate;
  176. }
  177. if ((relativeError < best_error))
  178. {
  179. bestm = mulFracDiv ;
  180. bestd = dividerAddFracDiv;
  181. best_divisor = diviser;
  182. best_error = relativeError;
  183. if (relativeError == 0) {
  184. break;
  185. }
  186. }
  187. }
  188. }
  189. if (relativeError == 0) {
  190. break;
  191. }
  192. }
  193. Lpc17xxDevDebugDisable();
  194. if (best_error < ((baudrate * UART_ACCEPTED_BAUDRATE_ERROR) / 100)) {
  195. /* Set DLAB bit */
  196. CM3BBSET(USARTnBase, LPC_UART_TypeDef, LCR, UART_LCR_DLAB_EN_POS);
  197. USARTn->DLM = UART_LOAD_DLM(best_divisor);
  198. USARTn->DLL = UART_LOAD_DLL(best_divisor);
  199. /* Reset DLAB bit */
  200. CM3BBCLR(USARTnBase, LPC_UART_TypeDef, LCR, UART_LCR_DLAB_EN_POS);
  201. USARTn->FDR = (UART_FDR_MULVAL(bestm) | UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK;
  202. } else {
  203. return -1;
  204. }
  205. Lpc17xxDevDebugEnable();
  206. return 0;
  207. }
  208. /*!
  209. * \brief Set the USART hardware to the number of data bits.
  210. *
  211. * This function is called by ioctl function of the upper level USART
  212. * driver through the USARTDCB jump table.
  213. *
  214. * \return 0 on success, -1 otherwise.
  215. */
  216. static int Lpc17xxDevDebugSetDataBits(uint8_t bits)
  217. {
  218. int rc = 0;
  219. uint32_t lcr;
  220. Lpc17xxDevDebugDisable();
  221. lcr = USARTn->LCR & ~UART_LCR_WLEN_BITMASK;
  222. switch (bits)
  223. {
  224. case 5:
  225. lcr |= UART_LCR_WLEN5;
  226. break;
  227. case 6:
  228. lcr |= UART_LCR_WLEN6;
  229. break;
  230. case 7:
  231. lcr |= UART_LCR_WLEN7;
  232. break;
  233. case 8:
  234. lcr |= UART_LCR_WLEN8;
  235. break;
  236. default:
  237. Lpc17xxDevDebugEnable();
  238. return -1;
  239. }
  240. USARTn->LCR = lcr & UART_LCR_BITMASK;
  241. Lpc17xxDevDebugEnable();
  242. return rc;
  243. }
  244. /*!
  245. * \brief Set the USART hardware to the specified parity mode.
  246. *
  247. * This routine is called by ioctl function of the upper level USART
  248. * driver through the USARTDCB jump table.
  249. *
  250. * \param mode 0 (disabled), 1 (odd), 2 (even) 3 (mark) or 4(space)
  251. *
  252. * \return 0 on success, -1 otherwise.
  253. */
  254. static int Lpc17xxDevDebugSetParity(uint8_t mode)
  255. {
  256. uint32_t lcr;
  257. Lpc17xxDevDebugDisable();
  258. lcr = USARTn->LCR & ~UART_LCR_PARITY_BITMASK;
  259. switch (mode) {
  260. case 0:
  261. /* Parity disabled, do nothing */
  262. break;
  263. case 1:
  264. lcr |= UART_LCR_PARITY_EN | UART_LCR_PARITY_ODD;
  265. break;
  266. case 2:
  267. lcr |= UART_LCR_PARITY_EN | UART_LCR_PARITY_EVEN;
  268. break;
  269. case 3:
  270. lcr |= UART_LCR_PARITY_EN | UART_LCR_PARITY_F_1;
  271. break;
  272. case 4:
  273. lcr |= UART_LCR_PARITY_EN | UART_LCR_PARITY_F_0;
  274. break;
  275. default:
  276. Lpc17xxDevDebugEnable();
  277. return -1;
  278. }
  279. USARTn->LCR = lcr & UART_LCR_BITMASK;
  280. Lpc17xxDevDebugEnable();
  281. return 0;
  282. }
  283. /*!
  284. * \brief Set the USART hardware to the number of stop bits.
  285. *
  286. * This routine is called by ioctl function of the upper level USART
  287. * driver through the USARTDCB jump table.
  288. *
  289. * \param bits The number of stop bits set, either 1, 2 or 3 (1.5 bits).
  290. *
  291. * \return 0 on success, -1 otherwise.
  292. */
  293. static int Lpc17xxDevDebugSetStopBits(uint8_t bits)
  294. {
  295. Lpc17xxDevDebugDisable();
  296. switch (bits) {
  297. case 1:
  298. CM3BBCLR(USARTnBase, LPC_UART_TypeDef, LCR, UART_LCR_STOPBIT_SEL_POS);
  299. break;
  300. case 2:
  301. CM3BBSET(USARTnBase, LPC_UART_TypeDef, LCR, UART_LCR_STOPBIT_SEL_POS);
  302. break;
  303. case 3:
  304. if ((USARTn->LCR & UART_LCR_WLEN_BITMASK) == UART_LCR_WLEN5) {
  305. CM3BBSET(USARTnBase, LPC_UART_TypeDef, LCR, UART_LCR_STOPBIT_SEL_POS);
  306. } else {
  307. Lpc17xxDevDebugEnable();
  308. return -1;
  309. }
  310. break;
  311. default:
  312. Lpc17xxDevDebugEnable();
  313. return -1;
  314. }
  315. Lpc17xxDevDebugEnable();
  316. return 0;
  317. }
  318. /*!
  319. * \brief Open debug device.
  320. *
  321. * \param dev Pointer to a previously registered \ref NUTDEVICE structure.
  322. * \param name Ignored, typically points to an empty string.
  323. * \param mode Ignored, operation mode.
  324. * \param acc Ignored, should be zero.
  325. *
  326. * \return Pointer to a static NUTFILE structure.
  327. */
  328. NUTFILE *Lpc17xxDevDebugOpen(NUTDEVICE * dev, const char *name, int mode, int acc)
  329. {
  330. NUTFILE *fp = (NUTFILE *) (dev->dev_dcb);
  331. fp->nf_dev = dev;
  332. fp->nf_fcb = NULL;
  333. return fp;
  334. }
  335. /*!
  336. * \brief Close debug device.
  337. *
  338. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a previous
  339. * call to LpcDevDebugOpen().
  340. *
  341. * \return Always 0.
  342. */
  343. int Lpc17xxDevDebugClose(NUTFILE * fp)
  344. {
  345. return 0;
  346. }
  347. /*!
  348. * \brief Send a single character to debug device.
  349. *
  350. * A newline character will be automatically prepended by a carriage
  351. * return.
  352. */
  353. static void DebugPut(const NUTDEVICE * dev, char ch)
  354. {
  355. if (ch == '\n') {
  356. DebugPut(dev, '\r');
  357. }
  358. while ((USARTn->LSR & UART_LSR_THRE) == 0);
  359. USARTn->THR = ch;
  360. }
  361. /*!
  362. * \brief Send characters to debug device 0.
  363. *
  364. * This function is called by the low level input routines of the
  365. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_write
  366. * entry.
  367. *
  368. * A newline character will be automatically prepended by a carriage
  369. * return.
  370. *
  371. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a previous
  372. * call to LpcDevDebugOpen().
  373. *
  374. * \return Number of characters sent.
  375. */
  376. static int Lpc17xxDevDebugWrite(NUTFILE * fp, const void *buffer, int len)
  377. {
  378. int c = len;
  379. const char *cp = buffer;
  380. while (c--) {
  381. DebugPut(fp->nf_dev, *cp++);
  382. }
  383. return len;
  384. }
  385. #ifdef NUT_DEV_DEBUG_READ
  386. /*!
  387. * \brief Read characters from debug device.
  388. *
  389. * This function is called by the low level input routines of the
  390. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_read
  391. * entry.
  392. *
  393. * The function will block the calling thread until at least one
  394. * character has been received.
  395. *
  396. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a
  397. * previous call to LpcDevDebugOpen().
  398. * \param buffer Pointer to the buffer that receives the data. If zero,
  399. * then all characters in the input buffer will be
  400. * removed.
  401. * \param size Maximum number of bytes to read.
  402. *
  403. * \return The number of bytes read, which may be less than the number
  404. * of bytes specified. A return value of -1 indicates an error,
  405. * while zero is returned in case of a timeout.
  406. */
  407. static int Lpc17xxDevDebugRead(NUTFILE * fp, void *buffer, int size)
  408. {
  409. int rc;
  410. unsigned int ch;
  411. char *bp = (char *) buffer;
  412. /* Wait for the first character, forever. */
  413. for (rc = 0; rc < size; rc++) {
  414. while ((USARTn->LSR & UART_LSR_RDR) == 0) {
  415. NutSleep(1);
  416. if ((rc || bp == NULL) &&
  417. (USARTn->LSR & UART_LSR_RDR) == 0) {
  418. return rc;
  419. }
  420. }
  421. ch = USARTn->RBR;
  422. if (bp) {
  423. if (ch == '\r') {
  424. *bp++ = '\n';
  425. } else {
  426. *bp++ = (char) ch;
  427. }
  428. }
  429. }
  430. return rc;
  431. }
  432. /*!
  433. * \brief Retrieves the number of characters in input buffer.
  434. *
  435. * This function is called by the low level size routine of the C runtime
  436. * library, using the _NUTDEVICE::dev_size entry.
  437. *
  438. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a previous
  439. * call to LpcDevDebugOpen().
  440. *
  441. * \return The number of bytes currently stored in input buffer.
  442. */
  443. static long Lpc17xxDevDebugSize(NUTFILE *fp)
  444. {
  445. if (USARTn->LSR & UART_LSR_RDR) {
  446. return 1;
  447. }
  448. return 0;
  449. }
  450. #endif /* NUT_DEV_DEBUG_READ */
  451. /*!
  452. * \brief Handle I/O controls for debug device 2.
  453. *
  454. * The debug device supports UART_SETSPEED, UART_SETDATABITS,
  455. * UART_SETPARITY and UART_SETSTOPBITS.
  456. *
  457. * \return 0 on success, -1 otherwise.
  458. */
  459. static int Lpc17xxDevDebugIOCtl(NUTDEVICE * dev, int req, void *conf)
  460. {
  461. int rc = -1;
  462. switch(req) {
  463. case UART_SETSPEED:
  464. rc = Lpc17xxDevDebugSetSpeed(*((uint32_t *)conf));
  465. break;
  466. case UART_SETDATABITS:
  467. rc = Lpc17xxDevDebugSetDataBits(*((uint32_t *)conf));
  468. break;
  469. case UART_SETPARITY:
  470. rc = Lpc17xxDevDebugSetParity(*((uint32_t *)conf));
  471. break;
  472. case UART_SETSTOPBITS:
  473. rc = Lpc17xxDevDebugSetStopBits(*((uint32_t *)conf));
  474. break;
  475. default:
  476. break;
  477. }
  478. return rc;
  479. }
  480. /*
  481. * \brief Initialize the USART hardware driver.
  482. *
  483. * This function is called during device registration by the upper level
  484. * USART driver through the USARTDCB jump table.
  485. *
  486. * \return 0 on success, -1 otherwise.
  487. */
  488. static int Lpc17xxDevDebugInit(NUTDEVICE * dev)
  489. {
  490. /* Enable UART clock and power */
  491. #if defined(MCU_LPC176x)
  492. if((LPC_UART_TypeDef*)USARTn == LPC_UART0) {
  493. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART0);
  494. } else
  495. if((LPC_UART1_TypeDef*)USARTn == LPC_UART1) {
  496. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART1);
  497. } else
  498. if((LPC_UART_TypeDef*)USARTn == LPC_UART2) {
  499. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART2);
  500. } else
  501. if((LPC_UART_TypeDef*)USARTn == LPC_UART3) {
  502. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART3);
  503. }
  504. #elif defined(MCU_LPC177x_8x) || defined(MCU_LPC407x_8x)
  505. if((LPC_UART_TypeDef*)USARTn == LPC_UART0) {
  506. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART0);
  507. SysCtlPeripheralResetEnable(CLKPWR_RSTCON0_UART0);
  508. SysCtlPeripheralResetDisable(CLKPWR_RSTCON0_UART0);
  509. } else
  510. if((LPC_UART1_TypeDef*)USARTn == LPC_UART1) {
  511. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART1);
  512. SysCtlPeripheralResetEnable(CLKPWR_RSTCON0_UART1);
  513. SysCtlPeripheralResetDisable(CLKPWR_RSTCON0_UART1);
  514. } else
  515. if((LPC_UART_TypeDef*)USARTn == LPC_UART2) {
  516. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART2);
  517. SysCtlPeripheralResetEnable(CLKPWR_RSTCON0_UART2);
  518. SysCtlPeripheralResetDisable(CLKPWR_RSTCON0_UART2);
  519. } else
  520. if((LPC_UART_TypeDef*)USARTn == LPC_UART3) {
  521. SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCUART3);
  522. SysCtlPeripheralResetEnable(CLKPWR_RSTCON0_UART3);
  523. SysCtlPeripheralResetDisable(CLKPWR_RSTCON0_UART3);
  524. }
  525. #endif
  526. /* Disable IRQs */
  527. USARTn->IER = 0;
  528. /* Clear FIFOs */
  529. USARTn->FCR |= UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS;
  530. /* Dummy reading */
  531. while (USARTn->LSR & UART_LSR_RDR) {
  532. (volatile uint32_t)USARTn->RBR;
  533. }
  534. /* Enable transmitter */
  535. USARTn->TER = UART_TER_TXEN;
  536. /* Wait for current transmit complete */
  537. while (!(USARTn->LSR & UART_LSR_THRE));
  538. /* Disable transmitter */
  539. USARTn->TER = 0;
  540. /* Set LCR to default state */
  541. USARTn->LCR = 0;
  542. /* Set ACR to default state */
  543. USARTn->ACR = 0;
  544. #if defined(MCU_LPC176x)
  545. if((LPC_UART1_TypeDef*)USARTn == LPC_UART1) {
  546. /* Set RS485 control to default state */
  547. ((LPC_UART1_TypeDef*)USARTn)->RS485CTRL = 0;
  548. /* Set RS485 delay timer to default state */
  549. ((LPC_UART1_TypeDef*)USARTn)->RS485DLY = 0;
  550. /* Set RS485 addr match to default state */
  551. ((LPC_UART1_TypeDef*)USARTn)->ADRMATCH = 0;
  552. }
  553. #elif defined(MCU_LPC177x_8x) || defined(MCU_LPC407x_8x)
  554. /* Set RS485 control to default state */
  555. USARTn->RS485CTRL = 0;
  556. /* Set RS485 delay timer to default state */
  557. USARTn->RS485DLY = 0;
  558. /* Set RS485 addr match to default state */
  559. USARTn->ADRMATCH = 0;
  560. #endif
  561. /* Dummy reading to clear bits */
  562. (volatile uint32_t)USARTn->LSR;
  563. if(((LPC_UART1_TypeDef *)USARTn) == LPC_UART1) {
  564. /* Set Modem Control to default state */
  565. ((LPC_UART1_TypeDef *)USARTn)->MCR = 0;
  566. /* Dummy Reading to Clear Status */
  567. (volatile uint32_t)((LPC_UART1_TypeDef *)USARTn)->MSR;
  568. }
  569. #if defined(MCU_LPC177x_8x) || defined(MCU_LPC407x_8x)
  570. if(((LPC_UART4_TypeDef *)USARTn) == LPC_UART4) {
  571. /* Set IrDA to default state for all UART other than UART1 */
  572. ((LPC_UART4_TypeDef *)USARTn)->ICR = 0;
  573. }
  574. #endif
  575. /* Configure USART Tx as alternate function push-pull */
  576. GpioPinConfigSet( TX_GPIO_PORT, TX_GPIO_PIN, TX_GPIO_PIN_CFG);
  577. /* Configure USART Rx as input floating */
  578. GpioPinConfigSet( RX_GPIO_PORT, RX_GPIO_PIN, RX_GPIO_PIN_CFG);
  579. #if defined(RTS_GPIO_PORT) && defined(RTS_GPIO_PIN)
  580. /* Configure USART RTS as alternate function push-pull */
  581. GpioPinConfigSet( RTS_GPIO_PORT, RTS_GPIO_PIN, RTS_GPIO_PIN_CFG);
  582. #endif
  583. #if defined(CTS_GPIO_PORT) && defined(CTS_GPIO_PIN)
  584. /* Configure USART CTS as input floating */
  585. GpioPinConfigSet( CTS_GPIO_PORT, CTS_GPIO_PIN, CTS_GPIO_PIN_CFG);
  586. #endif
  587. /* Configure UART communication parameters */
  588. Lpc17xxDevDebugSetSpeed(DEBUG_INIT_BAUTRATE);
  589. Lpc17xxDevDebugSetDataBits(8);
  590. Lpc17xxDevDebugSetStopBits(1);
  591. Lpc17xxDevDebugSetParity(0);
  592. return 0;
  593. }
  594. /*@}*/