uart.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. /* ****************************************************************************
  2. * Copyright (C) 2014-2018 Maxim Integrated Products, Inc., All Rights Reserved.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included
  12. * in all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  17. * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
  18. * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Except as contained in this notice, the name of Maxim Integrated
  23. * Products, Inc. shall not be used except as stated in the Maxim Integrated
  24. * Products, Inc. Branding Policy.
  25. *
  26. * The mere transfer of this software does not imply any licenses
  27. * of trade secrets, proprietary technology, copyrights, patents,
  28. * trademarks, maskwork rights, or any other form of intellectual
  29. * property whatsoever. Maxim Integrated Products, Inc. retains all
  30. * ownership rights.
  31. *
  32. * $Date: 2020-09-08 13:28:39 -0500 (Tue, 08 Sep 2020) $
  33. * $Revision: 55611 $
  34. *
  35. *************************************************************************** */
  36. /* **** Includes **** */
  37. #include <stdint.h>
  38. #include <string.h>
  39. #include "mxc_config.h"
  40. #include "mxc_assert.h"
  41. #include "uart_regs.h"
  42. #include "uart.h"
  43. #include "mxc_lock.h"
  44. #include "mxc_sys.h"
  45. /* **** Definitions **** */
  46. #define UART_ER_IF (MXC_F_UART_INT_FL_RX_FRAME_ERROR | \
  47. MXC_F_UART_INT_FL_RX_PARITY_ERROR | \
  48. MXC_F_UART_INT_FL_RX_OVERRUN)
  49. #define UART_ER_IE (MXC_F_UART_INT_EN_RX_FRAME_ERROR | \
  50. MXC_F_UART_INT_EN_RX_PARITY_ERROR | \
  51. MXC_F_UART_INT_EN_RX_OVERRUN )
  52. #define UART_RX_IF (MXC_F_UART_INT_FL_RX_FIFO_THRESH)
  53. #define UART_RX_IE (MXC_F_UART_INT_EN_RX_FIFO_THRESH)
  54. #define UART_TX_IF (MXC_F_UART_INT_FL_TX_FIFO_ALMOST_EMPTY | \
  55. MXC_F_UART_INT_FL_TX_FIFO_THRESH)
  56. #define UART_TX_IE (MXC_F_UART_INT_EN_TX_FIFO_ALMOST_EMPTY | \
  57. MXC_F_UART_INT_EN_TX_FIFO_THRESH)
  58. #if (TARGET == 32660) || (TARGET == 32665)
  59. #define MAX_FACTOR 3
  60. #else
  61. #define MAX_FACTOR 7
  62. #endif
  63. /* **** File Scope Data **** */
  64. // Saves the state of the non-blocking read requests.
  65. static uart_req_t *rx_states[MXC_UART_INSTANCES];
  66. // Saves the state of the non-blocking write requests.
  67. static uart_req_t *tx_states[MXC_UART_INSTANCES];
  68. /* **** Functions **** */
  69. static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num);
  70. static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num,
  71. uint32_t flags);
  72. static uint32_t uart_error_check(mxc_uart_regs_t *uart);
  73. static void uart_error_clear(mxc_uart_regs_t *uart);
  74. /* ************************************************************************* */
  75. uint32_t uart_error_check(mxc_uart_regs_t *uart)
  76. {
  77. return (uart->int_fl & UART_ER_IF);
  78. }
  79. /* ************************************************************************* */
  80. void uart_error_clear(mxc_uart_regs_t *uart)
  81. {
  82. UART_ClearFlags(uart,UART_ER_IF);
  83. }
  84. /* ************************************************************************* */
  85. int UART_Init(mxc_uart_regs_t *uart, const uart_cfg_t *cfg, const sys_cfg_uart_t* sys_cfg)
  86. {
  87. int err;
  88. int uart_num;
  89. uint32_t baud0 = 0, baud1 = 0,div;
  90. int32_t factor = -1;
  91. // Get the state array index
  92. uart_num = MXC_UART_GET_IDX(uart);
  93. if (uart_num == -1) {
  94. return E_BAD_PARAM;
  95. }
  96. if ((err = SYS_UART_Init(uart, sys_cfg)) != E_NO_ERROR) {
  97. return err;
  98. }
  99. // Initialize state pointers
  100. rx_states[uart_num] = NULL;
  101. tx_states[uart_num] = NULL;
  102. // Drain FIFOs, enable UART, and set configuration
  103. uart->ctrl = (MXC_F_UART_CTRL_ENABLE | cfg->parity | cfg->size | cfg->stop | cfg->flow | cfg->pol);
  104. // Set the baud rate
  105. // Calculate divisor
  106. #if (TARGET != 32660)
  107. uart->ctrl |= cfg->clksel;
  108. if (cfg->clksel == UART_CLKSEL_ALTERNATE) {
  109. div = UART_ALTERNATE_CLOCK_HZ / ((cfg->baud));
  110. } else {
  111. div = PeripheralClock / ((cfg->baud));
  112. }
  113. #else
  114. div = PeripheralClock / ((cfg->baud));
  115. #endif
  116. // Search for integer and fractional baud rate registers based on divisor
  117. do {
  118. factor += 1;
  119. baud0 = div >> (7-factor); // divide by 128,64,32,16 to extract integer part
  120. baud1 = ((div << factor) - (baud0 << 7)); //subtract factor corrected div - integer parts
  121. } while ((baud0 == 0) && (factor < MAX_FACTOR));
  122. uart->baud0 = ((factor << MXC_F_UART_BAUD0_FACTOR_POS) | baud0);
  123. #if (TARGET == 32660) || (TARGET == 32665) || (TARGET == 32650)
  124. /* Erratum:
  125. * Hardware bug causes exact baud rates to generate framing error. Slightly mis-adjust timing
  126. * to help avoid this bug.
  127. */
  128. if (baud1 > 3) {
  129. uart->baud1 = baud1 - 3;
  130. } else {
  131. uart->baud1 = baud1 + 3;
  132. }
  133. #else
  134. uart->baud1 = baud1;
  135. #endif
  136. // Clear pending requests
  137. rx_states[uart_num] = NULL;
  138. tx_states[uart_num] = NULL;
  139. return E_NO_ERROR;
  140. }
  141. /* ************************************************************************* */
  142. int UART_Shutdown(mxc_uart_regs_t *uart)
  143. {
  144. int uart_num;
  145. uart_req_t *temp_req;
  146. // Get the state array index
  147. uart_num = MXC_UART_GET_IDX(uart);
  148. if (uart_num < 0) {
  149. return E_BAD_PARAM;
  150. }
  151. // Disable interrupts
  152. uart->int_en = 0;
  153. // Flush RX and TX FIFOS
  154. uart->ctrl |= (MXC_F_UART_CTRL_TX_FLUSH | MXC_F_UART_CTRL_RX_FLUSH);
  155. // Call all of the pending callbacks for this UART
  156. if(rx_states[uart_num] != NULL) {
  157. // Save the request
  158. temp_req = rx_states[uart_num];
  159. // Unlock this UART to read
  160. mxc_free_lock((uint32_t*)&rx_states[uart_num]);
  161. // Callback if not NULL
  162. if (temp_req->callback != NULL) {
  163. temp_req->callback(temp_req, E_SHUTDOWN);
  164. }
  165. }
  166. if (tx_states[uart_num] != NULL) {
  167. // Save the request
  168. temp_req = tx_states[uart_num];
  169. // Unlock this UART to write
  170. mxc_free_lock((uint32_t*)&tx_states[uart_num]);
  171. // Callback if not NULL
  172. if (temp_req->callback != NULL) {
  173. temp_req->callback(temp_req, E_SHUTDOWN);
  174. }
  175. }
  176. // Wait for not busy
  177. while (uart->status & (MXC_F_UART_STATUS_TX_BUSY | MXC_F_UART_STATUS_RX_BUSY)) {
  178. }
  179. // Shutdown the UART
  180. uart->ctrl = 0;
  181. // Shutdown any system level setup
  182. SYS_UART_Shutdown(uart);
  183. // Clear pending requests
  184. rx_states[uart_num] = NULL;
  185. tx_states[uart_num] = NULL;
  186. return E_NO_ERROR;
  187. }
  188. /* ************************************************************************* */
  189. void UART_Handler(mxc_uart_regs_t *uart)
  190. {
  191. int uart_num; // Holds the current index of rx_states or tx_states
  192. uint32_t intst;
  193. // Get the state array index
  194. uart_num = MXC_UART_GET_IDX(uart);
  195. if (uart_num == -1) {
  196. return;
  197. }
  198. // Read and clear interrupts
  199. intst = uart->int_fl;
  200. uart->int_fl = intst;
  201. // Read interrupt
  202. if (intst & (UART_RX_IF | UART_ER_IF)) {
  203. UART_ReadHandler(uart, rx_states[uart_num], uart_num, intst);
  204. }
  205. // Write Interrupt
  206. if (intst & (UART_TX_IF | UART_ER_IF)) {
  207. UART_WriteHandler(uart, tx_states[uart_num], uart_num);
  208. }
  209. }
  210. /* ************************************************************************* */
  211. static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num)
  212. {
  213. int remain, avail;
  214. req = tx_states[uart_num];
  215. if (req == NULL) {
  216. // Nothing to do
  217. uart->int_en &= ~MXC_F_UART_INT_EN_TX_FIFO_ALMOST_EMPTY; // disable interrupt
  218. return;
  219. }
  220. // Refill the TX FIFO
  221. avail = UART_NumWriteAvail(uart);
  222. remain = req->len - req->num;
  223. while (avail && remain) {
  224. uart->fifo = req->data[req->num++];
  225. remain--;
  226. avail--;
  227. }
  228. // See if we've sent all of the characters
  229. if (req->len == req->num) {
  230. // Disable interrupts
  231. uart->int_en &= ~MXC_F_UART_INT_EN_TX_FIFO_ALMOST_EMPTY;
  232. // Deinit state before callback in case another is requested
  233. tx_states[uart_num] = NULL;
  234. mxc_free_lock((uint32_t*)&tx_states[uart_num]);
  235. // Callback when we've written all the characters
  236. if (req->callback != NULL) {
  237. req->callback(req, E_NO_ERROR);
  238. }
  239. }
  240. // Enable the interrupts
  241. uart->int_en |= UART_TX_IE | UART_ER_IE;
  242. }
  243. /* ************************************************************************* */
  244. static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num,
  245. uint32_t flags)
  246. {
  247. int remain, avail;
  248. if (req == NULL) {
  249. // Nothing to do
  250. uart->int_en &= ~(UART_RX_IE | UART_ER_IE); // disable interrupts
  251. return;
  252. }
  253. // Save the data in the FIFO while we still need data
  254. avail = UART_NumReadAvail(uart);
  255. remain = req->len - req->num;
  256. while (avail && remain) {
  257. req->data[req->num++] = uart->fifo;
  258. remain--;
  259. avail--;
  260. }
  261. // Check for errors
  262. if (flags & MXC_F_UART_INT_FL_RX_OVERRUN) {
  263. // Unlock this UART to read
  264. mxc_free_lock((uint32_t*)&rx_states[uart_num]);
  265. if (req->callback != NULL) {
  266. req->callback(req, E_OVERFLOW);
  267. }
  268. return;
  269. }
  270. if (flags & (MXC_F_UART_INT_FL_RX_FRAME_ERROR |
  271. MXC_F_UART_INT_FL_RX_PARITY_ERROR)) {
  272. // Unlock this UART to read
  273. mxc_free_lock((uint32_t*)&rx_states[uart_num]);
  274. if (req->callback != NULL) {
  275. req->callback(req, E_COMM_ERR);
  276. }
  277. return;
  278. }
  279. // Check to see if we've received all of the characters.
  280. if (req->num == req->len) {
  281. // Disable interrupts
  282. uart->int_en &= ~(UART_RX_IE | UART_ER_IE);
  283. // Deinit state before callback in case another is requested
  284. rx_states[uart_num] = NULL;
  285. // Call the callback function
  286. if (req->callback != NULL) {
  287. req->callback(req, E_NO_ERROR);
  288. }
  289. return;
  290. } else if (req->num > (req->len - MXC_UART_FIFO_DEPTH)) {
  291. // Set RX threshold less than FIFO_DEPTH characters if needed
  292. uart->thresh_ctrl = ((req->len - req->num)<<
  293. MXC_F_UART_THRESH_CTRL_RX_FIFO_THRESH_POS);
  294. } else {
  295. uart->thresh_ctrl = MXC_UART_FIFO_DEPTH<<
  296. MXC_F_UART_THRESH_CTRL_RX_FIFO_THRESH_POS;
  297. }
  298. }
  299. /* ************************************************************************* */
  300. int UART_Read(mxc_uart_regs_t *uart, uint8_t *data, int len, int *num)
  301. {
  302. int uart_num; // Holds the current index of rx_states
  303. int char_read = 0; // Holds the number of characters successfully read
  304. int error_code =0; // Holds the error to return while reading
  305. // Get the state array index
  306. uart_num = MXC_UART_GET_IDX(uart);
  307. if (uart_num < 0) {
  308. return E_BAD_PARAM;
  309. }
  310. // Check to make sure baud rate has been set
  311. if (uart->baud0 == 0) {
  312. return E_UNINITIALIZED;
  313. }
  314. // Check data pointer
  315. if (data == NULL) {
  316. return E_BAD_PARAM;
  317. }
  318. // Check if there is already a request in progress
  319. if (rx_states[uart_num] != NULL) {
  320. return E_BUSY;
  321. }
  322. // Lock this UART from reading
  323. while (mxc_get_lock((uint32_t*)&rx_states[uart_num], 1) != E_NO_ERROR) {
  324. }
  325. // Get bytes FIFO
  326. while (char_read < len) {
  327. // Wait for RXFIFO to not be empty
  328. while (uart->status & MXC_F_UART_STATUS_RX_EMPTY) {
  329. // Check for error
  330. if (uart_error_check(uart) != E_NO_ERROR) {
  331. if (uart->int_fl & MXC_F_UART_INT_FL_RX_OVERRUN) {
  332. error_code = E_OVERFLOW;
  333. } else {
  334. error_code = E_COMM_ERR;
  335. }
  336. uart_error_clear(uart);
  337. mxc_free_lock((uint32_t*)&rx_states[uart_num]);
  338. return error_code;
  339. }
  340. }
  341. data[char_read] = uart->fifo;
  342. char_read++;
  343. }
  344. if (num != NULL) {
  345. *num = char_read;
  346. }
  347. // Unlock this UART to read
  348. mxc_free_lock((uint32_t*)&rx_states[uart_num]);
  349. return char_read;
  350. }
  351. /* ************************************************************************* */
  352. uint8_t UART_ReadByte(mxc_uart_regs_t *uart)
  353. {
  354. while (uart->status & MXC_F_UART_STATUS_RX_EMPTY) {}
  355. return uart->fifo;
  356. }
  357. /* ************************************************************************* */
  358. int UART_Write(mxc_uart_regs_t *uart, const uint8_t *data, int len)
  359. {
  360. int uart_num; // Holds the current index of tx_states
  361. int char_written = 0; // Holds the number of characters successfully written
  362. // Get the state array index
  363. uart_num = MXC_UART_GET_IDX(uart);
  364. if (uart_num < 0) {
  365. return E_BAD_PARAM;
  366. }
  367. // Check to make sure baud rate has been set
  368. if (uart->baud0 == 0) {
  369. return E_UNINITIALIZED;
  370. }
  371. // Check data pointer
  372. if (data == NULL) {
  373. return E_BAD_PARAM;
  374. }
  375. // Check if there is already a request in progress
  376. if (tx_states[uart_num] != NULL) {
  377. return E_BUSY;
  378. }
  379. // Lock this UART from writing
  380. while (mxc_get_lock((uint32_t*)&tx_states[uart_num], 1) != E_NO_ERROR) {
  381. }
  382. // Clear errors
  383. uart_error_clear(uart);
  384. // Put bytes into FIFO
  385. while (char_written < len) {
  386. UART_WriteByte(uart,data[char_written]);
  387. char_written++;
  388. }
  389. // Unlock this UART to write
  390. mxc_free_lock((uint32_t*)&tx_states[uart_num]);
  391. return char_written;
  392. }
  393. /* ************************************************************************* */
  394. void UART_WriteByte(mxc_uart_regs_t *uart, uint8_t data)
  395. {
  396. // Wait for TXFIFO if full
  397. while (uart->status & MXC_F_UART_STATUS_TX_FULL) {
  398. }
  399. // Put data into fifo
  400. uart->fifo = data;
  401. }
  402. /* ************************************************************************* */
  403. int UART_ReadAsync(mxc_uart_regs_t *uart, uart_req_t *req)
  404. {
  405. int uart_num; // Holds the current index of tx_states
  406. uint32_t flags; // Holds the Interrupt flags
  407. // Check data pointer
  408. if (req == NULL) {
  409. return E_BAD_PARAM;
  410. }
  411. // Get the state array index
  412. uart_num = MXC_UART_GET_IDX(uart);
  413. if (uart_num < 0) {
  414. return E_BAD_PARAM;
  415. }
  416. if (req->data == NULL) {
  417. return E_NULL_PTR;
  418. }
  419. // Check to make sure baud rate has been set
  420. if (uart->baud0 == 0) {
  421. return E_UNINITIALIZED;
  422. }
  423. // Check if there is already a request in progress
  424. if (rx_states[uart_num] != NULL) {
  425. return E_BUSY;
  426. }
  427. if (!(req->len > 0)) {
  428. return E_NO_ERROR;
  429. }
  430. // Attempt to register this write request
  431. if (mxc_get_lock((uint32_t*)&rx_states[uart_num], (uint32_t)req) != E_NO_ERROR) {
  432. return E_BUSY;
  433. }
  434. // Clear the data counter
  435. req->num = 0;
  436. // Clear Interrupt Flags
  437. flags = uart->int_fl;
  438. uart->int_fl = flags;
  439. UART_ReadHandler(uart,req,uart_num,flags);
  440. // Enable the interrupts
  441. uart->int_en |= UART_RX_IE | UART_ER_IE;
  442. return E_NO_ERROR;
  443. }
  444. /* ************************************************************************* */
  445. int UART_WriteAsync(mxc_uart_regs_t *uart, uart_req_t *req)
  446. {
  447. int uart_num; // Holds the current index of tx_states
  448. // Check data pointer
  449. if (req == NULL) {
  450. return E_BAD_PARAM;
  451. }
  452. // Get the state array index
  453. uart_num = MXC_UART_GET_IDX(uart);
  454. if (uart_num < 0) {
  455. return E_BAD_PARAM;
  456. }
  457. if (req->data == NULL) {
  458. return E_NULL_PTR;
  459. }
  460. // Check to make sure baud rate has been set
  461. if (uart->baud0 == 0) {
  462. return E_UNINITIALIZED;
  463. }
  464. // Check if there is already a request in progress
  465. if (tx_states[uart_num] != NULL) {
  466. return E_BUSY;
  467. }
  468. if (!(req->len > 0)) {
  469. return E_NO_ERROR;
  470. }
  471. // Attempt to register this write request
  472. if (mxc_get_lock((uint32_t*)&tx_states[uart_num], (uint32_t)req) != E_NO_ERROR) {
  473. return E_BUSY;
  474. }
  475. // Clear the data counter
  476. req->num = 0;
  477. UART_WriteHandler(uart, req, uart_num);
  478. return E_NO_ERROR;
  479. }
  480. /* ************************************************************************* */
  481. int UART_Busy(mxc_uart_regs_t *uart)
  482. {
  483. int uart_num = MXC_UART_GET_IDX(uart); // Holds the current index of tx_states
  484. MXC_ASSERT(uart_num >= 0);
  485. if ((uart->status & MXC_F_UART_STATUS_TX_BUSY) || (uart->status & MXC_F_UART_STATUS_RX_BUSY)) {
  486. return E_BUSY;
  487. }
  488. // Check to see if there are any ongoing transactions and the UART has room in its FIFO
  489. if ((tx_states[uart_num] == NULL) &&
  490. !(uart->status & MXC_F_UART_STATUS_TX_FULL)) {
  491. return E_NO_ERROR;
  492. }
  493. return E_BUSY;
  494. }
  495. /* ************************************************************************* */
  496. int UART_PrepForSleep(mxc_uart_regs_t *uart)
  497. {
  498. if (UART_Busy(uart) != E_NO_ERROR) {
  499. return E_BUSY;
  500. }
  501. // Leave read interrupts enabled, if already enabled
  502. uart->int_en &= (UART_RX_IE | UART_ER_IE);
  503. return E_NO_ERROR;
  504. }
  505. /* ************************************************************************* */
  506. int UART_AbortAsync(uart_req_t *req)
  507. {
  508. int uart_num;
  509. // Figure out if this was a read or write request, find the request, set to NULL
  510. for (uart_num = 0; uart_num < MXC_UART_INSTANCES; uart_num++) {
  511. if (req == rx_states[uart_num]) {
  512. // Disable read interrupts, clear flags.
  513. MXC_UART_GET_UART(uart_num)->int_en &= ~(UART_RX_IE | UART_ER_IE);
  514. MXC_UART_GET_UART(uart_num)->int_fl = (UART_RX_IF | UART_ER_IF);
  515. // Unlock this UART to read
  516. mxc_free_lock((uint32_t*)&rx_states[uart_num]);
  517. // Callback if not NULL
  518. if (req->callback != NULL) {
  519. req->callback(req, E_ABORT);
  520. }
  521. return E_NO_ERROR;
  522. }
  523. if (req == tx_states[uart_num]) {
  524. // Disable write interrupts, clear flags.
  525. MXC_UART_GET_UART(uart_num)->int_en &= ~(UART_TX_IE | UART_ER_IE);
  526. MXC_UART_GET_UART(uart_num)->int_fl = (UART_TX_IF | UART_ER_IF);
  527. // Unlock this UART to write
  528. mxc_free_lock((uint32_t*)&tx_states[uart_num]);
  529. // Callback if not NULL
  530. if (req->callback != NULL) {
  531. req->callback(req, E_ABORT);
  532. }
  533. return E_NO_ERROR;
  534. }
  535. }
  536. return E_BAD_PARAM;
  537. }
  538. /* ************************************************************************* */
  539. unsigned UART_NumWriteAvail(mxc_uart_regs_t *uart)
  540. {
  541. return MXC_UART_FIFO_DEPTH - ((uart->status & MXC_F_UART_STATUS_TX_FIFO_CNT) >>
  542. MXC_F_UART_STATUS_TX_FIFO_CNT_POS);
  543. }
  544. /* ************************************************************************* */
  545. unsigned UART_NumReadAvail(mxc_uart_regs_t *uart)
  546. {
  547. return ((uart->status & MXC_F_UART_STATUS_RX_FIFO_CNT) >>
  548. MXC_F_UART_STATUS_RX_FIFO_CNT_POS);
  549. }
  550. /* ************************************************************************* */
  551. unsigned UART_GetFlags(mxc_uart_regs_t *uart)
  552. {
  553. return (uart->int_fl);
  554. }
  555. /* ************************************************************************* */
  556. void UART_ClearFlags(mxc_uart_regs_t *uart, uint32_t mask)
  557. {
  558. uart->int_fl = mask;
  559. }
  560. /* ************************************************************************* */
  561. void UART_Enable(mxc_uart_regs_t *uart)
  562. {
  563. uart->ctrl |= MXC_F_UART_CTRL_ENABLE;
  564. }
  565. /* ************************************************************************* */
  566. void UART_Disable(mxc_uart_regs_t *uart)
  567. {
  568. uart->ctrl &= ~MXC_F_UART_CTRL_ENABLE;
  569. }
  570. /* ************************************************************************* */
  571. void UART_DrainRX(mxc_uart_regs_t *uart)
  572. {
  573. uart->ctrl |= MXC_F_UART_CTRL_RX_FLUSH;
  574. }
  575. /* ************************************************************************* */
  576. void UART_DrainTX(mxc_uart_regs_t *uart)
  577. {
  578. uart->ctrl |= MXC_F_UART_CTRL_TX_FLUSH;
  579. }