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 
37 /* **** Includes **** */
38 #include <stdint.h>
39 #include <string.h>
40 #include "mxc_config.h"
41 #include "mxc_assert.h"
42 #include "uart_regs.h"
43 #include "uart.h"
44 #include "mxc_lock.h"
45 #include "mxc_sys.h"
46 
47 /* **** Definitions **** */
48 
49 #define UART_ER_IF (MXC_F_UART_INT_FL_RX_FRAME_ERROR | \
50                     MXC_F_UART_INT_FL_RX_PARITY_ERROR | \
51                     MXC_F_UART_INT_FL_RX_OVERRUN)
52 
53 #define UART_ER_IE (MXC_F_UART_INT_EN_RX_FRAME_ERROR | \
54                     MXC_F_UART_INT_EN_RX_PARITY_ERROR | \
55                     MXC_F_UART_INT_EN_RX_OVERRUN )
56 
57 #define UART_RX_IF (MXC_F_UART_INT_FL_RX_FIFO_THRESH)
58 
59 #define UART_RX_IE (MXC_F_UART_INT_EN_RX_FIFO_THRESH)
60 
61 #define UART_TX_IF (MXC_F_UART_INT_FL_TX_FIFO_ALMOST_EMPTY | \
62                     MXC_F_UART_INT_FL_TX_FIFO_THRESH)
63 
64 #define UART_TX_IE (MXC_F_UART_INT_EN_TX_FIFO_ALMOST_EMPTY | \
65                     MXC_F_UART_INT_EN_TX_FIFO_THRESH)
66 
67 #if (TARGET == 32660) || (TARGET == 32665)
68 #define MAX_FACTOR 3
69 #else
70 #define MAX_FACTOR 7
71 #endif
72 
73 /* **** File Scope Data **** */
74 
75 // Saves the state of the non-blocking read requests.
76 static uart_req_t *rx_states[MXC_UART_INSTANCES];
77 
78 // Saves the state of the non-blocking write requests.
79 static uart_req_t *tx_states[MXC_UART_INSTANCES];
80 
81 
82 /* **** Functions **** */
83 static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num);
84 static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num,
85                              uint32_t flags);
86 static uint32_t uart_error_check(mxc_uart_regs_t *uart);
87 static void uart_error_clear(mxc_uart_regs_t *uart);
88 
89 /* ************************************************************************* */
uart_error_check(mxc_uart_regs_t * uart)90 uint32_t uart_error_check(mxc_uart_regs_t *uart)
91 {
92     return (uart->int_fl & UART_ER_IF);
93 }
94 
95 /* ************************************************************************* */
uart_error_clear(mxc_uart_regs_t * uart)96 void uart_error_clear(mxc_uart_regs_t *uart)
97 {
98     UART_ClearFlags(uart,UART_ER_IF);
99 }
100 
101 /* ************************************************************************* */
UART_Init(mxc_uart_regs_t * uart,const uart_cfg_t * cfg,const sys_cfg_uart_t * sys_cfg)102 int UART_Init(mxc_uart_regs_t *uart, const uart_cfg_t *cfg, const sys_cfg_uart_t* sys_cfg)
103 {
104     int err;
105     int uart_num;
106 
107     uint32_t baud0 = 0, baud1 = 0,div;
108     int32_t factor = -1;
109 
110     // Get the state array index
111     uart_num = MXC_UART_GET_IDX(uart);
112     if (uart_num == -1) {
113         return E_BAD_PARAM;
114     }
115 
116     if ((err = SYS_UART_Init(uart, sys_cfg)) != E_NO_ERROR) {
117         return err;
118     }
119 
120     // Initialize state pointers
121     rx_states[uart_num] = NULL;
122     tx_states[uart_num] = NULL;
123 
124     // Drain FIFOs, enable UART, and set configuration
125     uart->ctrl = (MXC_F_UART_CTRL_ENABLE | cfg->parity | cfg->size | cfg->stop | cfg->flow | cfg->pol);
126 
127     // Set the baud rate
128     // Calculate divisor
129 #if (TARGET != 32660)
130     uart->ctrl |=  cfg->clksel;
131     if (cfg->clksel == UART_CLKSEL_ALTERNATE) {
132         div = UART_ALTERNATE_CLOCK_HZ / ((cfg->baud));
133     } else {
134         div = PeripheralClock / ((cfg->baud));
135     }
136 #else
137     div = PeripheralClock / ((cfg->baud));
138 #endif
139     // Search for integer and fractional baud rate registers based on divisor
140     do {
141 	factor += 1;
142 	baud0 = div >> (7-factor); // divide by 128,64,32,16 to extract integer part
143 	baud1 = ((div << factor) - (baud0 << 7)); //subtract factor corrected div - integer parts
144     } while ((baud0 == 0) && (factor < MAX_FACTOR));
145 
146     uart->baud0 = ((factor << MXC_F_UART_BAUD0_FACTOR_POS) | baud0);
147 #if (TARGET == 32660) || (TARGET == 32665) || (TARGET == 32650)
148     /* Erratum:
149      *   Hardware bug causes exact baud rates to generate framing error. Slightly mis-adjust timing
150      *   to help avoid this bug.
151      */
152     if (baud1 > 3) {
153 	uart->baud1 = baud1 - 3;
154     } else {
155 	uart->baud1 = baud1 + 3;
156     }
157 #else
158     uart->baud1 = baud1;
159 #endif
160 
161     // Clear pending requests
162     rx_states[uart_num] = NULL;
163     tx_states[uart_num] = NULL;
164 
165     return E_NO_ERROR;
166 }
167 
168 /* ************************************************************************* */
UART_Shutdown(mxc_uart_regs_t * uart)169 int UART_Shutdown(mxc_uart_regs_t *uart)
170 {
171     int uart_num;
172     uart_req_t *temp_req;
173 
174     // Get the state array index
175     uart_num = MXC_UART_GET_IDX(uart);
176     if (uart_num < 0) {
177         return E_BAD_PARAM;
178     }
179 
180     // Disable interrupts
181     uart->int_en = 0;
182 
183     // Flush RX and TX FIFOS
184     uart->ctrl |= (MXC_F_UART_CTRL_TX_FLUSH | MXC_F_UART_CTRL_RX_FLUSH);
185 
186     // Call all of the pending callbacks for this UART
187     if(rx_states[uart_num] != NULL) {
188 
189         // Save the request
190         temp_req = rx_states[uart_num];
191 
192         // Unlock this UART to read
193         mxc_free_lock((uint32_t*)&rx_states[uart_num]);
194 
195         // Callback if not NULL
196         if (temp_req->callback != NULL) {
197             temp_req->callback(temp_req, E_SHUTDOWN);
198         }
199     }
200 
201     if (tx_states[uart_num] != NULL) {
202 
203         // Save the request
204         temp_req = tx_states[uart_num];
205 
206         // Unlock this UART to write
207         mxc_free_lock((uint32_t*)&tx_states[uart_num]);
208 
209         // Callback if not NULL
210         if (temp_req->callback != NULL) {
211             temp_req->callback(temp_req, E_SHUTDOWN);
212         }
213     }
214     // Wait for not busy
215     while (uart->status & (MXC_F_UART_STATUS_TX_BUSY | MXC_F_UART_STATUS_RX_BUSY)) {
216 
217     }
218 
219     // Shutdown the UART
220     uart->ctrl = 0;
221 
222     // Shutdown any system level setup
223     SYS_UART_Shutdown(uart);
224 
225     // Clear pending requests
226     rx_states[uart_num] = NULL;
227     tx_states[uart_num] = NULL;
228 
229     return E_NO_ERROR;
230 }
231 
232 /* ************************************************************************* */
UART_Handler(mxc_uart_regs_t * uart)233 void UART_Handler(mxc_uart_regs_t *uart)
234 {
235     int uart_num; // Holds the current index of rx_states or tx_states
236     uint32_t intst;
237 
238     // Get the state array index
239     uart_num = MXC_UART_GET_IDX(uart);
240     if (uart_num == -1) {
241         return;
242     }
243 
244     // Read and clear interrupts
245     intst = uart->int_fl;
246     uart->int_fl = intst;
247 
248     // Read interrupt
249     if (intst & (UART_RX_IF | UART_ER_IF)) {
250         UART_ReadHandler(uart, rx_states[uart_num], uart_num, intst);
251     }
252 
253     // Write Interrupt
254     if (intst & (UART_TX_IF | UART_ER_IF)) {
255         UART_WriteHandler(uart, tx_states[uart_num], uart_num);
256     }
257 }
258 
259 /* ************************************************************************* */
UART_WriteHandler(mxc_uart_regs_t * uart,uart_req_t * req,int uart_num)260 static void UART_WriteHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num)
261 {
262     int remain, avail;
263     req = tx_states[uart_num];
264 
265     if (req == NULL) {
266         // Nothing to do
267         uart->int_en &= ~MXC_F_UART_INT_EN_TX_FIFO_ALMOST_EMPTY; // disable interrupt
268         return;
269     }
270 
271     // Refill the TX FIFO
272     avail = UART_NumWriteAvail(uart);
273     remain = req->len - req->num;
274 
275     while (avail && remain) {
276         uart->fifo = req->data[req->num++];
277         remain--;
278         avail--;
279     }
280 
281     // See if we've sent all of the characters
282     if (req->len == req->num) {
283         // Disable interrupts
284         uart->int_en &= ~MXC_F_UART_INT_EN_TX_FIFO_ALMOST_EMPTY;
285 
286         // Deinit state before callback in case another is requested
287         tx_states[uart_num] = NULL;
288         mxc_free_lock((uint32_t*)&tx_states[uart_num]);
289 
290         // Callback when we've written all the characters
291         if (req->callback != NULL) {
292             req->callback(req, E_NO_ERROR);
293         }
294     }
295     // Enable the interrupts
296     uart->int_en |= UART_TX_IE | UART_ER_IE;
297 
298 }
299 
300 /* ************************************************************************* */
UART_ReadHandler(mxc_uart_regs_t * uart,uart_req_t * req,int uart_num,uint32_t flags)301 static void UART_ReadHandler(mxc_uart_regs_t *uart, uart_req_t *req, int uart_num,
302                              uint32_t flags)
303 {
304     int remain, avail;
305 
306     if (req == NULL) {
307         // Nothing to do
308         uart->int_en &= ~(UART_RX_IE | UART_ER_IE); // disable interrupts
309         return;
310     }
311     // Save the data in the FIFO while we still need data
312     avail = UART_NumReadAvail(uart);
313     remain = req->len - req->num;
314     while (avail && remain) {
315         req->data[req->num++] = uart->fifo;
316         remain--;
317         avail--;
318     }
319     // Check for errors
320     if (flags & MXC_F_UART_INT_FL_RX_OVERRUN) {
321 
322         // Unlock this UART to read
323         mxc_free_lock((uint32_t*)&rx_states[uart_num]);
324 
325         if (req->callback != NULL) {
326             req->callback(req, E_OVERFLOW);
327         }
328 
329         return;
330     }
331     if (flags & (MXC_F_UART_INT_FL_RX_FRAME_ERROR |
332                 MXC_F_UART_INT_FL_RX_PARITY_ERROR)) {
333 
334         // Unlock this UART to read
335         mxc_free_lock((uint32_t*)&rx_states[uart_num]);
336 
337         if (req->callback != NULL)         {
338             req->callback(req, E_COMM_ERR);
339         }
340 
341         return;
342     }
343     // Check to see if we've received all of the characters.
344     if (req->num == req->len) {
345         // Disable interrupts
346         uart->int_en &= ~(UART_RX_IE | UART_ER_IE);
347 
348         // Deinit state before callback in case another is requested
349         rx_states[uart_num] = NULL;
350 
351         // Call the callback function
352         if (req->callback != NULL) {
353             req->callback(req, E_NO_ERROR);
354         }
355 
356         return;
357     } else if (req->num > (req->len - MXC_UART_FIFO_DEPTH)) {
358         // Set RX threshold less than FIFO_DEPTH characters if needed
359         uart->thresh_ctrl = ((req->len - req->num)<<
360                        MXC_F_UART_THRESH_CTRL_RX_FIFO_THRESH_POS);
361     } else {
362         uart->thresh_ctrl = MXC_UART_FIFO_DEPTH<<
363                       MXC_F_UART_THRESH_CTRL_RX_FIFO_THRESH_POS;
364     }
365 }
366 
367 /* ************************************************************************* */
UART_Read(mxc_uart_regs_t * uart,uint8_t * data,int len,int * num)368 int UART_Read(mxc_uart_regs_t *uart, uint8_t *data, int len, int *num)
369 {
370     int uart_num; // Holds the current index of rx_states
371     int char_read = 0; // Holds the number of characters successfully read
372     int error_code =0; // Holds the error to return while reading
373 
374     // Get the state array index
375     uart_num = MXC_UART_GET_IDX(uart);
376     if (uart_num < 0) {
377         return E_BAD_PARAM;
378     }
379 
380     // Check to make sure baud rate has been set
381     if (uart->baud0 == 0) {
382         return E_UNINITIALIZED;
383     }
384 
385     // Check data pointer
386     if (data == NULL) {
387         return E_BAD_PARAM;
388     }
389 
390     // Check if there is already a request in progress
391     if (rx_states[uart_num] != NULL) {
392         return E_BUSY;
393     }
394 
395     // Lock this UART from reading
396     while (mxc_get_lock((uint32_t*)&rx_states[uart_num], 1) != E_NO_ERROR) {
397 
398     }
399 
400     // Get bytes FIFO
401     while (char_read < len) {
402         // Wait for RXFIFO to not be empty
403         while (uart->status & MXC_F_UART_STATUS_RX_EMPTY) {
404             // Check for error
405             if (uart_error_check(uart) != E_NO_ERROR) {
406                 if (uart->int_fl & MXC_F_UART_INT_FL_RX_OVERRUN) {
407                     error_code = E_OVERFLOW;
408                 } else {
409                     error_code = E_COMM_ERR;
410                 }
411 
412                 uart_error_clear(uart);
413                 mxc_free_lock((uint32_t*)&rx_states[uart_num]);
414                 return error_code;
415             }
416         }
417         data[char_read] = uart->fifo;
418         char_read++;
419     }
420     if (num != NULL) {
421         *num = char_read;
422     }
423     // Unlock this UART to read
424     mxc_free_lock((uint32_t*)&rx_states[uart_num]);
425 
426     return char_read;
427 }
428 
429 /* ************************************************************************* */
UART_ReadByte(mxc_uart_regs_t * uart)430 uint8_t UART_ReadByte(mxc_uart_regs_t *uart)
431 {
432 
433     while (uart->status & MXC_F_UART_STATUS_RX_EMPTY) {}
434 
435     return uart->fifo;
436 }
437 
438 /* ************************************************************************* */
UART_Write(mxc_uart_regs_t * uart,const uint8_t * data,int len)439 int UART_Write(mxc_uart_regs_t *uart, const uint8_t *data, int len)
440 {
441     int uart_num; // Holds the current index of tx_states
442     int char_written = 0;  // Holds the number of characters successfully written
443 
444     // Get the state array index
445     uart_num = MXC_UART_GET_IDX(uart);
446     if (uart_num < 0) {
447         return E_BAD_PARAM;
448     }
449 
450     // Check to make sure baud rate has been set
451     if (uart->baud0 == 0) {
452         return E_UNINITIALIZED;
453     }
454 
455     // Check data pointer
456     if (data == NULL) {
457         return E_BAD_PARAM;
458     }
459 
460     // Check if there is already a request in progress
461     if (tx_states[uart_num] != NULL) {
462         return E_BUSY;
463     }
464 
465     // Lock this UART from writing
466     while (mxc_get_lock((uint32_t*)&tx_states[uart_num], 1) != E_NO_ERROR) {
467 
468     }
469 
470     // Clear errors
471     uart_error_clear(uart);
472 
473     // Put bytes into FIFO
474     while (char_written < len) {
475         UART_WriteByte(uart,data[char_written]);
476         char_written++;
477     }
478 
479     // Unlock this UART to write
480     mxc_free_lock((uint32_t*)&tx_states[uart_num]);
481 
482     return char_written;
483 }
484 
485 /* ************************************************************************* */
UART_WriteByte(mxc_uart_regs_t * uart,uint8_t data)486 void UART_WriteByte(mxc_uart_regs_t *uart, uint8_t data)
487 {
488 
489     // Wait for TXFIFO if full
490     while (uart->status & MXC_F_UART_STATUS_TX_FULL) {
491 
492     }
493 
494     // Put data into fifo
495     uart->fifo = data;
496 }
497 
498 /* ************************************************************************* */
UART_ReadAsync(mxc_uart_regs_t * uart,uart_req_t * req)499 int UART_ReadAsync(mxc_uart_regs_t *uart, uart_req_t *req)
500 {
501     int uart_num; // Holds the current index of tx_states
502     uint32_t flags;  // Holds the Interrupt flags
503 
504     // Check data pointer
505     if (req == NULL) {
506         return E_BAD_PARAM;
507     }
508 
509     // Get the state array index
510     uart_num = MXC_UART_GET_IDX(uart);
511     if (uart_num < 0) {
512         return E_BAD_PARAM;
513     }
514 
515     if (req->data == NULL) {
516         return E_NULL_PTR;
517     }
518     // Check to make sure baud rate has been set
519     if (uart->baud0 == 0) {
520         return E_UNINITIALIZED;
521     }
522 
523     // Check if there is already a request in progress
524     if (rx_states[uart_num] != NULL) {
525         return E_BUSY;
526     }
527 
528     if (!(req->len > 0)) {
529         return E_NO_ERROR;
530     }
531 
532     // Attempt to register this write request
533     if (mxc_get_lock((uint32_t*)&rx_states[uart_num], (uint32_t)req) != E_NO_ERROR) {
534         return E_BUSY;
535     }
536 
537     // Clear the data counter
538     req->num = 0;
539 
540     // Clear Interrupt Flags
541     flags = uart->int_fl;
542     uart->int_fl = flags;
543     UART_ReadHandler(uart,req,uart_num,flags);
544 
545     // Enable the interrupts
546     uart->int_en |= UART_RX_IE | UART_ER_IE;
547 
548     return E_NO_ERROR;
549 }
550 
551 /* ************************************************************************* */
UART_WriteAsync(mxc_uart_regs_t * uart,uart_req_t * req)552 int UART_WriteAsync(mxc_uart_regs_t *uart, uart_req_t *req)
553 {
554     int uart_num;  // Holds the current index of tx_states
555 
556     // Check data pointer
557     if (req == NULL) {
558         return E_BAD_PARAM;
559     }
560 
561     // Get the state array index
562     uart_num = MXC_UART_GET_IDX(uart);
563     if (uart_num < 0) {
564         return E_BAD_PARAM;
565     }
566 
567     if (req->data == NULL) {
568         return E_NULL_PTR;
569     }
570     // Check to make sure baud rate has been set
571     if (uart->baud0 == 0) {
572         return E_UNINITIALIZED;
573     }
574 
575     // Check if there is already a request in progress
576     if (tx_states[uart_num] != NULL) {
577         return E_BUSY;
578     }
579     if (!(req->len > 0)) {
580         return E_NO_ERROR;
581     }
582     // Attempt to register this write request
583     if (mxc_get_lock((uint32_t*)&tx_states[uart_num], (uint32_t)req) != E_NO_ERROR) {
584         return E_BUSY;
585     }
586 
587     // Clear the data counter
588     req->num = 0;
589     UART_WriteHandler(uart, req, uart_num);
590 
591     return E_NO_ERROR;
592 }
593 
594 /* ************************************************************************* */
UART_Busy(mxc_uart_regs_t * uart)595 int UART_Busy(mxc_uart_regs_t *uart)
596 {
597     int uart_num = MXC_UART_GET_IDX(uart);  // Holds the current index of tx_states
598     MXC_ASSERT(uart_num >= 0);
599     if ((uart->status & MXC_F_UART_STATUS_TX_BUSY) || (uart->status & MXC_F_UART_STATUS_RX_BUSY)) {
600         return E_BUSY;
601     }
602     // Check to see if there are any ongoing transactions and the UART has room in its FIFO
603     if ((tx_states[uart_num] == NULL) &&
604             !(uart->status & MXC_F_UART_STATUS_TX_FULL)) {
605 
606         return E_NO_ERROR;
607     }
608 
609     return E_BUSY;
610 }
611 
612 /* ************************************************************************* */
UART_PrepForSleep(mxc_uart_regs_t * uart)613 int UART_PrepForSleep(mxc_uart_regs_t *uart)
614 {
615     if (UART_Busy(uart) != E_NO_ERROR) {
616         return E_BUSY;
617     }
618 
619     // Leave read interrupts enabled, if already enabled
620     uart->int_en &= (UART_RX_IE | UART_ER_IE);
621 
622     return E_NO_ERROR;
623 }
624 
625 /* ************************************************************************* */
UART_AbortAsync(uart_req_t * req)626 int UART_AbortAsync(uart_req_t *req)
627 {
628     int uart_num;
629 
630     // Figure out if this was a read or write request, find the request, set to NULL
631     for (uart_num = 0; uart_num < MXC_UART_INSTANCES; uart_num++) {
632         if (req == rx_states[uart_num]) {
633 
634             // Disable read interrupts, clear flags.
635             MXC_UART_GET_UART(uart_num)->int_en &= ~(UART_RX_IE | UART_ER_IE);
636             MXC_UART_GET_UART(uart_num)->int_fl = (UART_RX_IF | UART_ER_IF);
637 
638             // Unlock this UART to read
639             mxc_free_lock((uint32_t*)&rx_states[uart_num]);
640 
641             // Callback if not NULL
642             if (req->callback != NULL) {
643                 req->callback(req, E_ABORT);
644             }
645 
646             return E_NO_ERROR;
647         }
648 
649         if (req == tx_states[uart_num]) {
650 
651             // Disable write interrupts, clear flags.
652             MXC_UART_GET_UART(uart_num)->int_en &= ~(UART_TX_IE | UART_ER_IE);
653             MXC_UART_GET_UART(uart_num)->int_fl = (UART_TX_IF | UART_ER_IF);
654 
655             // Unlock this UART to write
656             mxc_free_lock((uint32_t*)&tx_states[uart_num]);
657 
658             // Callback if not NULL
659             if (req->callback != NULL) {
660                 req->callback(req, E_ABORT);
661             }
662 
663             return E_NO_ERROR;
664         }
665     }
666 
667     return E_BAD_PARAM;
668 }
669 
670 /* ************************************************************************* */
UART_NumWriteAvail(mxc_uart_regs_t * uart)671 unsigned UART_NumWriteAvail(mxc_uart_regs_t *uart)
672 {
673     return MXC_UART_FIFO_DEPTH - ((uart->status & MXC_F_UART_STATUS_TX_FIFO_CNT) >>
674                                   MXC_F_UART_STATUS_TX_FIFO_CNT_POS);
675 }
676 
677 /* ************************************************************************* */
UART_NumReadAvail(mxc_uart_regs_t * uart)678 unsigned UART_NumReadAvail(mxc_uart_regs_t *uart)
679 {
680     return ((uart->status & MXC_F_UART_STATUS_RX_FIFO_CNT) >>
681             MXC_F_UART_STATUS_RX_FIFO_CNT_POS);
682 }
683 
684 /* ************************************************************************* */
UART_GetFlags(mxc_uart_regs_t * uart)685 unsigned UART_GetFlags(mxc_uart_regs_t *uart)
686 {
687     return (uart->int_fl);
688 }
689 
690 /* ************************************************************************* */
UART_ClearFlags(mxc_uart_regs_t * uart,uint32_t mask)691 void UART_ClearFlags(mxc_uart_regs_t *uart, uint32_t mask)
692 {
693     uart->int_fl = mask;
694 }
695 
696 /* ************************************************************************* */
UART_Enable(mxc_uart_regs_t * uart)697 void UART_Enable(mxc_uart_regs_t *uart)
698 {
699     uart->ctrl |= MXC_F_UART_CTRL_ENABLE;
700 }
701 
702 /* ************************************************************************* */
UART_Disable(mxc_uart_regs_t * uart)703 void UART_Disable(mxc_uart_regs_t *uart)
704 {
705     uart->ctrl &= ~MXC_F_UART_CTRL_ENABLE;
706 }
707 
708 /* ************************************************************************* */
UART_DrainRX(mxc_uart_regs_t * uart)709 void UART_DrainRX(mxc_uart_regs_t *uart)
710 {
711     uart->ctrl |= MXC_F_UART_CTRL_RX_FLUSH;
712 }
713 
714 /* ************************************************************************* */
UART_DrainTX(mxc_uart_regs_t * uart)715 void UART_DrainTX(mxc_uart_regs_t *uart)
716 {
717     uart->ctrl |= MXC_F_UART_CTRL_TX_FLUSH;
718 }
719