hw_uart.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /*
  2. * @brief UART ROM API declarations and functions
  3. *
  4. * @note
  5. * Copyright(C) NXP Semiconductors, 2014
  6. * All rights reserved.
  7. *
  8. * @par
  9. * Software that is described herein is for illustrative purposes only
  10. * which provides customers with programming information regarding the
  11. * LPC products. This software is supplied "AS IS" without any warranties of
  12. * any kind, and NXP Semiconductors and its licensor disclaim any and
  13. * all warranties, express or implied, including all implied warranties of
  14. * merchantability, fitness for a particular purpose and non-infringement of
  15. * intellectual property rights. NXP Semiconductors assumes no responsibility
  16. * or liability for the use of the software, conveys no license or rights under any
  17. * patent, copyright, mask work right, or any other intellectual property rights in
  18. * or to any products. NXP Semiconductors reserves the right to make changes
  19. * in the software without notification. NXP Semiconductors also makes no
  20. * representation or warranty that such application will be suitable for the
  21. * specified use without further testing or modification.
  22. *
  23. * @par
  24. * Permission to use, copy, modify, and distribute this software and its
  25. * documentation is hereby granted, under NXP Semiconductors' and its
  26. * licensor's relevant copyrights in the software, without fee, provided that it
  27. * is used in conjunction with NXP Semiconductors microcontrollers. This
  28. * copyright, permission, and disclaimer notice must appear in all copies of
  29. * this code.
  30. */
  31. #include "error.h"
  32. #include "hw_uart_rom_api.h"
  33. #define UART_IDLE_FIX /* Remove once IDLE problem is fixed */
  34. /* UART Driver internal data structure */
  35. typedef struct {
  36. void *pUserData; /* Pointer to user data */
  37. UART_REGS_T *pREGS; /* Pointer to Registers */
  38. UART_DATA_T xfer[2]; /* TX/RX transfer data */
  39. #ifdef UART_IDLE_FIX
  40. uint32_t dly; /* Delay to count 1 bit time; REMOVE: when H/W is fixed */
  41. #endif
  42. void(*cbTable[UART_CB_RESERVED]) (UART_HANDLE_T, UART_EVENT_T, void *); /* Call-back index table */
  43. } UART_DRIVER_T;
  44. /* PRIVATE: Division logic to divide without integer overflow */
  45. static uint32_t _UART_DivClk(uint32_t pclk, uint32_t m)
  46. {
  47. uint32_t q, r, u = pclk >> 24, l = pclk << 8;
  48. m = m + 256;
  49. q = (1 << 24) / m;
  50. r = (1 << 24) - (q * m);
  51. return ((q * u) << 8) + (((r * u) << 8) + l) / m;
  52. }
  53. /* PRIVATE: Get highest Over sampling value */
  54. static uint32_t _UART_GetHighDiv(uint32_t val, uint8_t strict)
  55. {
  56. int32_t i, max = strict ? 16 : 5;
  57. for (i = 16; i >= max; i--) {
  58. if (!(val % i)) {
  59. return i;
  60. }
  61. }
  62. return 0;
  63. }
  64. /* PRIVATE: Queue a transfer in UART */
  65. static ErrorCode_t _UART_Xfer(UART_DRIVER_T *pUART, void *buff, uint16_t len, uint8_t op)
  66. {
  67. UART_DATA_T *xfr = &pUART->xfer[op];
  68. /* Xfer of 0 bytes in a UART should always be successful */
  69. if (!len) {
  70. return LPC_OK;
  71. }
  72. /* Check if a Xfer is alredy in progress */
  73. if (xfr->count > xfr->offset) {
  74. return ERR_BUSY;
  75. }
  76. xfr->buf = (void *) buff;
  77. xfr->count = len;
  78. xfr->offset = 0;
  79. xfr->state = UART_ST_BUSY;
  80. if (!op) {
  81. pUART->pREGS->INTENSET = UART_INT_TXRDY;
  82. }
  83. else {
  84. pUART->pREGS->INTENSET = UART_INT_RXRDY | UART_INT_FRMERR | UART_INT_RXNOISE | UART_INT_START | UART_INT_OVR;
  85. }
  86. return LPC_OK;
  87. }
  88. /* Calculate error difference */
  89. static int32_t _CalcErr(uint32_t n, uint32_t d, uint32_t *prev)
  90. {
  91. uint32_t err = n - (n / d) * d;
  92. uint32_t herr = ((n / d) + 1) * d - n;
  93. if (herr < err) {
  94. err = herr;
  95. }
  96. if (*prev <= err) {
  97. return 0;
  98. }
  99. *prev = err;
  100. return (herr == err) + 1;
  101. }
  102. /* Calculate the base DIV value */
  103. static ErrorCode_t _UART_CalcDiv(UART_BAUD_T *ub)
  104. {
  105. int32_t i = 0;
  106. uint32_t perr = ~0UL;
  107. if (!ub->div) {
  108. i = ub->ovr ? ub->ovr : 16;
  109. }
  110. for (; i > 4; i--) {
  111. int32_t tmp = _CalcErr(ub->clk, ub->baud * i, &perr);
  112. /* Continue when no improvement seen in err value */
  113. if (!tmp) {
  114. continue;
  115. }
  116. ub->div = tmp - 1;
  117. if (ub->ovr == i) {
  118. break;
  119. }
  120. ub->ovr = i;
  121. }
  122. if (!ub->ovr) {
  123. return ERR_UART_BAUDRATE;
  124. }
  125. ub->div += ub->clk / (ub->baud * ub->ovr);
  126. if (!ub->div) {
  127. return ERR_UART_BAUDRATE;
  128. }
  129. ub->baud = ub->clk / (ub->div * ub->ovr);
  130. return LPC_OK;
  131. }
  132. /* Calculate the best MUL value */
  133. static void _UART_CalcMul(UART_BAUD_T *ub)
  134. {
  135. uint32_t m, perr = ~0UL, pclk = ub->clk, ovr = ub->ovr;
  136. /* If clock is UART's base clock calculate only the divider */
  137. for (m = 0; m < 256; m++) {
  138. uint32_t ov = ovr, x, v, tmp;
  139. /* Get clock and calculate error */
  140. x = _UART_DivClk(pclk, m);
  141. tmp = _CalcErr(x, ub->baud, &perr);
  142. v = (x / ub->baud) + tmp - 1;
  143. /* Update if new error is better than previous best */
  144. if (!tmp || (ovr && (v % ovr)) ||
  145. (!ovr && ((ov = _UART_GetHighDiv(v, ovr)) == 0))) {
  146. continue;
  147. }
  148. ub->ovr = ov;
  149. ub->mul = m;
  150. ub->clk = x;
  151. ub->div = tmp - 1;
  152. }
  153. }
  154. /* PRIVATE: Invoke UART Call back functions */
  155. static void _UART_InvokeCB(UART_DRIVER_T *pUART, UART_EVENT_T event, void *arg)
  156. {
  157. void (*cbfn)(UART_HANDLE_T, UART_EVENT_T, void *);
  158. cbfn = pUART->cbTable[(uint32_t) event >> 1];
  159. if (cbfn != NULL) {
  160. cbfn((UART_HANDLE_T) pUART, event, arg);
  161. }
  162. }
  163. /* PRIVATE: Handler for data transfers */
  164. static void _UART_HandleTxRx(UART_HANDLE_T hUART, UART_EVENT_T event, void *arg)
  165. {
  166. UART_DATA_T *dat = (UART_DATA_T *) arg;
  167. UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
  168. uint16_t *buf16 = dat->buf;
  169. uint8_t *buf8 = dat->buf;
  170. /* Transmit data */
  171. if (event == UART_TX_DATA) {
  172. while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_TXRDY)) {
  173. if (dat->dwidth) {
  174. pUART->pREGS->TXDAT = *buf16++;
  175. }
  176. else {
  177. pUART->pREGS->TXDAT = *buf8++;
  178. }
  179. dat->count--;
  180. }
  181. return;
  182. }
  183. /* Receive data */
  184. while (dat->count && (pUART->pREGS->INTSTAT & UART_INT_RXRDY)) {
  185. if (dat->dwidth) {
  186. *buf16++ = pUART->pREGS->RXDAT & 0x1FF;
  187. }
  188. else {
  189. *buf8++ = pUART->pREGS->RXDAT & 0xFF;
  190. }
  191. dat->count--;
  192. }
  193. }
  194. /* Handle UART Receive event */
  195. static int32_t _UART_HandleXfer(UART_DRIVER_T *pUART, uint8_t op)
  196. {
  197. UART_DATA_T dat;
  198. UART_DATA_T *xfr = &pUART->xfer[op];
  199. /* See if the transfer is already complete */
  200. if (xfr->offset >= xfr->count) {
  201. return 2;
  202. }
  203. /* Fill the buffer data structure */
  204. dat.count = xfr->count - xfr->offset;
  205. dat.dwidth = ((pUART->pREGS->CFG >> 2) & 3) > 1;
  206. if (dat.dwidth) {
  207. dat.buf = &((uint16_t *) xfr->buf)[xfr->offset];
  208. }
  209. else {
  210. dat.buf = &((uint8_t *) xfr->buf)[xfr->offset];
  211. }
  212. if (!xfr->offset && xfr->count) {
  213. _UART_InvokeCB(pUART, UART_TX_START, xfr);
  214. }
  215. pUART->cbTable[UART_CB_DATA]((UART_HANDLE_T) pUART, (UART_EVENT_T) (UART_TX_DATA + op), &dat);
  216. xfr->offset = (xfr->count - dat.count);
  217. if (xfr->offset >= xfr->count) {
  218. if (!op) {
  219. pUART->pREGS->INTENCLR = UART_INT_TXRDY;
  220. }
  221. else {
  222. pUART->pREGS->INTENCLR = UART_INT_RXRDY;
  223. }
  224. _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_TX_DONE + op), xfr);
  225. if (xfr->state == UART_ST_BUSY) {
  226. xfr->state = UART_ST_DONE;
  227. }
  228. return 1;
  229. }
  230. return 0;
  231. }
  232. /* STOP Receive under progress */
  233. static void _UART_StopRx(UART_HANDLE_T hUART)
  234. {
  235. UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
  236. UART_DATA_T *rx = &pUART->xfer[1];
  237. volatile uint16_t *idx = (volatile uint16_t *) &rx->offset;
  238. if (*idx >= rx->count) {
  239. return;
  240. }
  241. /* Disable further receive interrupts */
  242. pUART->pREGS->INTENCLR = UART_INT_RXRDY;
  243. rx->count = *idx;
  244. _UART_InvokeCB(pUART, UART_RX_DONE, rx);
  245. }
  246. /* EXPROTED API: Returns memory required for UART ROM driver */
  247. uint32_t UART_GetMemSize(void)
  248. {
  249. return sizeof(UART_DRIVER_T);
  250. }
  251. /* EXPORTED API: Calculate UART Baudrate divisors */
  252. ErrorCode_t UART_CalculateBaud(UART_BAUD_T *ub)
  253. {
  254. if (!ub->mul) {
  255. _UART_CalcMul(ub);
  256. }
  257. return _UART_CalcDiv(ub);
  258. }
  259. /* EXPORTED API: UART Initialization function */
  260. UART_HANDLE_T UART_Init(void *mem, uint32_t base_addr, void *args)
  261. {
  262. UART_DRIVER_T *pUART;
  263. /* Check if the memory is word aligned */
  264. if ((uint32_t) mem & 0x3) {
  265. return NULL;
  266. }
  267. /* Assign memory provided by application */
  268. pUART = (UART_DRIVER_T *) mem;
  269. memset(pUART, 0, sizeof(UART_DRIVER_T));
  270. /* Assign the base address */
  271. pUART->pREGS = (UART_REGS_T *) base_addr;
  272. pUART->pUserData = args;
  273. /* Set default handler for TX and RX */
  274. pUART->cbTable[UART_CB_DATA] = _UART_HandleTxRx;
  275. return (UART_HANDLE_T) pUART;
  276. }
  277. /* EXPORTED API: Configure UART parameters */
  278. ErrorCode_t UART_Configure(UART_HANDLE_T hUART, const UART_CFG_T *cfg)
  279. {
  280. UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
  281. UART_REGS_T *pREGS = pUART->pREGS;
  282. if (((cfg->cfg & UART_PAR_MASK) == (1 << 4)) ||
  283. ( (cfg->cfg & UART_DATA_MASK) == (3 << 2)) ) {
  284. return ERR_UART_PARAM;
  285. }
  286. /* Enable parity error when parity is enabled */
  287. if ((cfg->cfg & UART_PAR_MASK) >> 4) {
  288. pREGS->INTENSET = UART_INT_PARERR;
  289. }
  290. if (((int32_t) cfg->div <= 0) || ((int32_t) cfg->ovr <= 0)) {
  291. return ERR_UART_PARAM;
  292. }
  293. pREGS->OSR = (cfg->ovr - 1) & 0x0F;
  294. pREGS->BRG = (cfg->div - 1) & 0xFFFF;
  295. pREGS->CFG = UART_CFG_ENABLE | (cfg->cfg & ~UART_CFG_RES);
  296. /* Enabled RX of BREAK event */
  297. if (cfg->cfg & UART_CFG_BRKRX) {
  298. pREGS->INTENSET = UART_INT_BREAK;
  299. }
  300. /* Enable CTS interrupt if requested */
  301. if (cfg->cfg & UART_CFG_CTSEV) {
  302. pREGS->INTENSET = UART_INT_CTS;
  303. }
  304. #ifdef UART_IDLE_FIX
  305. /* REMOVE: if/else block after H/W idle is fixed */
  306. if (cfg->res > 224) {
  307. pUART->dly = 3072 * (cfg->res - 224);
  308. }
  309. else {
  310. pUART->dly = cfg->res << 2;
  311. }
  312. #endif
  313. return LPC_OK;
  314. }
  315. /* EXPORTED API: UART setup special operation like BREAK etc. */
  316. void UART_SetControl(UART_HANDLE_T hUART, uint32_t cfg)
  317. {
  318. uint32_t en, dis;
  319. UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS;
  320. /* Get list of enabled and disabled options */
  321. en = ((cfg >> 16) & (cfg & 0xFFFF)) << 1;
  322. dis = ((cfg >> 16) & ~(cfg & 0xFFFF)) << 1;
  323. /* See if it is RX Stop request */
  324. if (cfg & UART_RX_STOP) {
  325. _UART_StopRx(hUART);
  326. }
  327. /* See if any IDLEs are enabled */
  328. if (cfg & (UART_IDLE_MASK << 16)) {
  329. pREGS->INTENSET = (en >> 1) & UART_IDLE_MASK;
  330. pREGS->INTENCLR = (dis >> 1) & UART_IDLE_MASK;
  331. }
  332. /* See if it is a request BREAK after TX */
  333. if (en & UART_CTL_TXDIS) {
  334. if (en & UART_CTL_TXBRKEN) {
  335. pREGS->CTL = (pREGS->CTL & ~UART_CTL_RES) | UART_CTL_TXDIS;
  336. while (!(pREGS->STAT & UART_INT_TXDIS)) {}
  337. #ifdef UART_IDLE_FIX
  338. if (1) {
  339. volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
  340. while (dly--) {}/* Provide some idling time H/W does not do this */
  341. }
  342. #endif
  343. }
  344. else {
  345. pREGS->INTENSET = UART_INT_TXDIS;
  346. }
  347. }
  348. /* See if we are releasing break and resume TX operation */
  349. if ((dis & UART_CTL_TXDIS) && (dis & UART_CTL_TXBRKEN)) {
  350. pREGS->CTL = pREGS->CTL & ~(UART_CTL_RES | UART_CTL_TXBRKEN);
  351. #ifdef UART_IDLE_FIX
  352. if (1) {
  353. volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
  354. while (dly--) {} /* Provide some idling time H/W does not do this */
  355. }
  356. #endif
  357. }
  358. /* Check for autobaud and enable autobaud err interrupt */
  359. if (en & UART_CTL_AUTOBAUD) {
  360. pREGS->INTENSET = UART_INT_ABAUDERR;
  361. }
  362. pREGS->CTL = ((pREGS->CTL | en) & ~dis) & ~UART_CTL_RES;
  363. }
  364. /* EXPORTED API: Register a call-back function */
  365. ErrorCode_t UART_RegisterCB(UART_HANDLE_T hUART,
  366. UART_CBINDEX_T idx,
  367. void (*cb_func)(UART_HANDLE_T, UART_EVENT_T, void *))
  368. {
  369. if (idx < UART_CB_RESERVED) {
  370. ((UART_DRIVER_T *) hUART)->cbTable[idx] = cb_func;
  371. }
  372. else {
  373. return ERR_UART_PARAM;
  374. }
  375. /* Restore internal data handlers when external ones are un-registered */
  376. if ((idx == UART_CB_DATA) && (cb_func == NULL)) {
  377. ((UART_DRIVER_T *) hUART)->cbTable[idx] = _UART_HandleTxRx;
  378. }
  379. return LPC_OK;
  380. }
  381. /* EXPORTED API: UART Event handler */
  382. void UART_Handler(UART_HANDLE_T hUART)
  383. {
  384. UART_DRIVER_T *pUART = (UART_DRIVER_T *) hUART;
  385. uint32_t flags = pUART->pREGS->INTENSET & pUART->pREGS->INTSTAT;
  386. if (flags & UART_INT_TXRDY) {
  387. _UART_HandleXfer(pUART, 0);
  388. }
  389. if (flags & UART_INT_FRMERR) {
  390. pUART->pREGS->STAT = UART_INT_FRMERR;
  391. if (pUART->xfer[1].state == UART_ST_BUSY) {
  392. pUART->xfer[1].state = UART_ST_ERRFRM;
  393. }
  394. _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_FRAME);
  395. }
  396. if (flags & UART_INT_PARERR) {
  397. pUART->pREGS->STAT = UART_INT_PARERR;
  398. if (pUART->xfer[1].state == UART_ST_BUSY) {
  399. pUART->xfer[1].state = UART_ST_ERRPAR;
  400. }
  401. _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_PARITY);
  402. }
  403. if (flags & UART_INT_ABAUDERR) {
  404. pUART->pREGS->STAT = UART_INT_ABAUDERR;
  405. if (pUART->xfer[1].state == UART_ST_BUSY) {
  406. pUART->xfer[1].state = UART_ST_ERR;
  407. }
  408. _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_AUTOBAUD);
  409. }
  410. if (flags & UART_INT_RXNOISE) {
  411. pUART->pREGS->STAT = UART_INT_RXNOISE;
  412. if (pUART->xfer[1].state == UART_ST_BUSY) {
  413. pUART->xfer[1].state = UART_ST_ERRNOISE;
  414. }
  415. _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_RXNOISE);
  416. }
  417. if (flags & UART_INT_OVR) {
  418. pUART->pREGS->STAT = UART_INT_OVR;
  419. if (pUART->xfer[1].state == UART_ST_BUSY) {
  420. pUART->xfer[1].state = UART_ST_ERROVR;
  421. }
  422. _UART_InvokeCB(pUART, UART_EV_ERROR, (void *) UART_ERROR_OVERRUN);
  423. }
  424. if (flags & UART_INT_RXRDY) {
  425. _UART_HandleXfer(pUART, 1);
  426. #ifdef UART_IDLE_FIX
  427. if (1) {
  428. volatile uint32_t dly = ((UART_DRIVER_T *) hUART)->dly;
  429. while ((pUART->pREGS->STAT & UART_STAT_RXIDLE) && dly--) {}
  430. }
  431. #else
  432. while (pUART->pREGS->STAT & UART_STAT_RXIDLE) {}
  433. #endif
  434. _UART_InvokeCB(pUART, (UART_EVENT_T) (UART_RX_INPROG + ((pUART->pREGS->STAT >> 1) & 1)), &pUART->xfer[1]);
  435. }
  436. if (flags & UART_INT_TXIDLE) {
  437. _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXIDLE);
  438. }
  439. if (flags & UART_INT_TXDIS) {
  440. pUART->pREGS->INTENCLR = UART_INT_TXDIS;/* Disable interrupt */
  441. _UART_InvokeCB(pUART, UART_EV_EVENT, (void *) UART_EVENT_TXPAUSED);
  442. }
  443. if (flags & UART_INT_CTS) {
  444. pUART->pREGS->STAT = UART_INT_CTS;
  445. _UART_InvokeCB(pUART, UART_EV_EVENT,
  446. (void *) ((pUART->pREGS->STAT & UART_STAT_CTS) ? UART_EVENT_CTSHI : UART_EVENT_CTSLO));
  447. }
  448. if (flags & UART_INT_BREAK) {
  449. pUART->pREGS->STAT = UART_INT_BREAK | UART_INT_FRMERR;
  450. _UART_InvokeCB(pUART, UART_EV_EVENT,
  451. (void *) ((pUART->pREGS->STAT & UART_STAT_BREAK) ? UART_EVENT_BREAK : UART_EVENT_NOBREAK));
  452. }
  453. if (flags & UART_INT_START) {
  454. pUART->pREGS->STAT = UART_INT_START;
  455. _UART_InvokeCB(pUART, UART_RX_START, &pUART->xfer[1]);
  456. }
  457. }
  458. /* EXPORTED API: UART Transmit API */
  459. ErrorCode_t UART_Tx(UART_HANDLE_T hUART, const void *buff, uint16_t len)
  460. {
  461. return _UART_Xfer((UART_DRIVER_T *) hUART, (void *) buff, len, 0);
  462. }
  463. /* EXPORTED API: UART Receive API */
  464. ErrorCode_t UART_Rx(UART_HANDLE_T hUART, void *buff, uint16_t len)
  465. {
  466. return _UART_Xfer((UART_DRIVER_T *) hUART, buff, len, 1);
  467. }
  468. /* EXPORTED API: Flush the TX buffer */
  469. void UART_WaitTX(UART_HANDLE_T hUART)
  470. {
  471. while (!_UART_HandleXfer(hUART, 0)) {}
  472. }
  473. /* EXPORTED API: Fetch the data from UART into RX buffer */
  474. void UART_WaitRX(UART_HANDLE_T hUART)
  475. {
  476. UART_REGS_T *pREGS = ((UART_DRIVER_T *) hUART)->pREGS;
  477. /* See if the data needs to be discarded */
  478. if (_UART_HandleXfer(hUART, 1) == 2) {
  479. volatile uint32_t dummy;
  480. while ((pREGS->STAT & UART_INT_RXRDY) || !(pREGS->STAT & UART_STAT_RXIDLE)) {
  481. dummy = pREGS->RXDAT;
  482. }
  483. }
  484. while (!_UART_HandleXfer(hUART, 1)) {}
  485. }
  486. /* EXPORTED API: Function to Get the firmware Version */
  487. uint32_t UART_GetDriverVersion(void)
  488. {
  489. return UART_DRIVER_VERSION;
  490. }
  491. /**
  492. * @brief Table of the addresses of all the UART ROM APIs
  493. * @note This table of function pointers is the API interface.
  494. */
  495. const ROM_UART_API_T uartrom_api = {
  496. UART_GetMemSize,
  497. UART_CalculateBaud,
  498. UART_Init,
  499. UART_Configure,
  500. UART_SetControl,
  501. UART_RegisterCB,
  502. UART_Handler,
  503. UART_Tx,
  504. UART_Rx,
  505. UART_WaitTX,
  506. UART_WaitRX,
  507. UART_GetDriverVersion,
  508. };