1 /*
2  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2021 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_uart.h"
10 
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.uart"
18 #endif
19 
20 /* UART transfer state. */
21 enum
22 {
23     kUART_TxIdle,         /* TX idle. */
24     kUART_TxBusy,         /* TX busy. */
25     kUART_RxIdle,         /* RX idle. */
26     kUART_RxBusy,         /* RX busy. */
27     kUART_RxFramingError, /* Rx framing error */
28     kUART_RxParityError   /* Rx parity error */
29 };
30 
31 /*******************************************************************************
32  * Prototypes
33  ******************************************************************************/
34 /*!
35  * @brief Check whether the RX ring buffer is full.
36  *
37  * @param handle UART handle pointer.
38  * @retval true  RX ring buffer is full.
39  * @retval false RX ring buffer is not full.
40  */
41 static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle);
42 
43 /*!
44  * @brief Read RX register using non-blocking method.
45  *
46  * This function reads data from the TX register directly, upper layer must make
47  * sure the RX register is full or TX FIFO has data before calling this function.
48  *
49  * @param base UART peripheral base address.
50  * @param data Start address of the buffer to store the received data.
51  * @param length Size of the buffer.
52  */
53 static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length);
54 
55 /*!
56  * @brief Write to TX register using non-blocking method.
57  *
58  * This function writes data to the TX register directly, upper layer must make
59  * sure the TX register is empty or TX FIFO has empty room before calling this function.
60  *
61  * @note This function does not check whether all the data has been sent out to bus,
62  * so before disable TX, check kUART_TransmissionCompleteFlag to ensure the TX is
63  * finished.
64  *
65  * @param base UART peripheral base address.
66  * @param data Start address of the data to write.
67  * @param length Size of the buffer to be sent.
68  */
69 static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length);
70 
71 /*******************************************************************************
72  * Variables
73  ******************************************************************************/
74 /* Array of UART handle. */
75 #if (defined(UART5))
76 #define UART_HANDLE_ARRAY_SIZE 6
77 #else /* UART5 */
78 #if (defined(UART4))
79 #define UART_HANDLE_ARRAY_SIZE 5
80 #else /* UART4 */
81 #if (defined(UART3))
82 #define UART_HANDLE_ARRAY_SIZE 4
83 #else /* UART3 */
84 #if (defined(UART2))
85 #define UART_HANDLE_ARRAY_SIZE 3
86 #else /* UART2 */
87 #if (defined(UART1))
88 #define UART_HANDLE_ARRAY_SIZE 2
89 #else /* UART1 */
90 #if (defined(UART0))
91 #define UART_HANDLE_ARRAY_SIZE 1
92 #else /* UART0 */
93 #error No UART instance.
94 #endif /* UART 0 */
95 #endif /* UART 1 */
96 #endif /* UART 2 */
97 #endif /* UART 3 */
98 #endif /* UART 4 */
99 #endif /* UART 5 */
100 void *s_uartHandle[UART_HANDLE_ARRAY_SIZE];
101 /* Array of UART peripheral base address. */
102 static UART_Type *const s_uartBases[] = UART_BASE_PTRS;
103 
104 /* Array of UART IRQ number. */
105 const IRQn_Type s_uartIRQ[] = UART_RX_TX_IRQS;
106 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
107 /* Array of UART clock name. */
108 static const clock_ip_name_t s_uartClock[] = UART_CLOCKS;
109 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
110 
111 /* UART ISR for transactional APIs. */
112 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
113 uart_isr_t s_uartIsr = (uart_isr_t)DefaultISR;
114 #else
115 uart_isr_t s_uartIsr;
116 #endif
117 
118 /*******************************************************************************
119  * Code
120  ******************************************************************************/
121 
122 /*!
123  * brief Get the UART instance from peripheral base address.
124  *
125  * param base UART peripheral base address.
126  * return UART instance.
127  */
UART_GetInstance(UART_Type * base)128 uint32_t UART_GetInstance(UART_Type *base)
129 {
130     uint32_t instance;
131     uint32_t uartArrayCount = (sizeof(s_uartBases) / sizeof(s_uartBases[0]));
132 
133     /* Find the instance index from base address mappings. */
134     for (instance = 0; instance < uartArrayCount; instance++)
135     {
136         if (s_uartBases[instance] == base)
137         {
138             break;
139         }
140     }
141 
142     assert(instance < uartArrayCount);
143 
144     return instance;
145 }
146 
147 /*!
148  * brief Get the length of received data in RX ring buffer.
149  *
150  * param handle UART handle pointer.
151  * return Length of received data in RX ring buffer.
152  */
UART_TransferGetRxRingBufferLength(uart_handle_t * handle)153 size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle)
154 {
155     assert(handle != NULL);
156 
157     size_t size;
158     uint16_t rxRingBufferHead = handle->rxRingBufferHead;
159     uint16_t rxRingBufferTail = handle->rxRingBufferTail;
160 
161     if (rxRingBufferTail > rxRingBufferHead)
162     {
163         size = (size_t)rxRingBufferHead + handle->rxRingBufferSize - (size_t)rxRingBufferTail;
164     }
165     else
166     {
167         size = (size_t)rxRingBufferHead - (size_t)rxRingBufferTail;
168     }
169 
170     return size;
171 }
172 
UART_TransferIsRxRingBufferFull(uart_handle_t * handle)173 static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle)
174 {
175     assert(handle != NULL);
176 
177     bool full;
178 
179     if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
180     {
181         full = true;
182     }
183     else
184     {
185         full = false;
186     }
187 
188     return full;
189 }
190 
191 /*!
192  * brief Initializes a UART instance with a user configuration structure and peripheral clock.
193  *
194  * This function configures the UART module with the user-defined settings. The user can configure the configuration
195  * structure and also get the default configuration by using the UART_GetDefaultConfig() function.
196  * The example below shows how to use this API to configure UART.
197  * code
198  *  uart_config_t uartConfig;
199  *  uartConfig.baudRate_Bps = 115200U;
200  *  uartConfig.parityMode = kUART_ParityDisabled;
201  *  uartConfig.stopBitCount = kUART_OneStopBit;
202  *  uartConfig.txFifoWatermark = 0;
203  *  uartConfig.rxFifoWatermark = 1;
204  *  UART_Init(UART1, &uartConfig, 20000000U);
205  * endcode
206  *
207  * param base UART peripheral base address.
208  * param config Pointer to the user-defined configuration structure.
209  * param srcClock_Hz UART clock source frequency in HZ.
210  * retval kStatus_UART_BaudrateNotSupport Baudrate is not support in current clock source.
211  * retval kStatus_Success Status UART initialize succeed
212  */
UART_Init(UART_Type * base,const uart_config_t * config,uint32_t srcClock_Hz)213 status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz)
214 {
215     assert(config != NULL);
216     assert(config->baudRate_Bps != 0U);
217 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
218     assert((uint8_t)FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->txFifoWatermark);
219     assert((uint8_t)FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->rxFifoWatermark);
220 #endif
221 
222     uint32_t sbr      = 0U;
223     uint8_t temp      = 0U;
224     uint32_t baudDiff = 0U;
225 
226     /* Calculate the baud rate modulo divisor, sbr*/
227     sbr = srcClock_Hz / (config->baudRate_Bps * 16U);
228     /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */
229     if (sbr == 0U)
230     {
231         sbr = 1U;
232     }
233 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT
234     /* Determine if a fractional divider is needed to fine tune closer to the
235      * desired baud, each value of brfa is in 1/32 increments,
236      * hence the multiply-by-32. */
237     uint32_t tempBaud = 0U;
238 
239     uint32_t brfa = (2U * srcClock_Hz / (config->baudRate_Bps)) - 32U * sbr;
240 
241     /* Calculate the baud rate based on the temporary SBR values and BRFA */
242     tempBaud = srcClock_Hz * 2U / (sbr * 32U + brfa);
243     baudDiff =
244         (tempBaud > config->baudRate_Bps) ? (tempBaud - config->baudRate_Bps) : (config->baudRate_Bps - tempBaud);
245 
246 #else
247     /* Calculate the baud rate based on the temporary SBR values */
248     baudDiff = (srcClock_Hz / (sbr * 16U)) - config->baudRate_Bps;
249 
250     /* Select the better value between sbr and (sbr + 1) */
251     if (baudDiff > (config->baudRate_Bps - (srcClock_Hz / (16U * ((uint32_t)sbr + 1U)))))
252     {
253         baudDiff = config->baudRate_Bps - (srcClock_Hz / (16U * ((uint32_t)sbr + 1U)));
254         sbr++;
255     }
256 #endif
257 
258     /* next, check to see if actual baud rate is within 3% of desired baud rate
259      * based on the calculate SBR value */
260     if (baudDiff > ((config->baudRate_Bps / 100U) * 3U))
261     {
262         /* Unacceptable baud rate difference of more than 3%*/
263         return kStatus_UART_BaudrateNotSupport;
264     }
265 
266 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
267     /* Enable uart clock */
268     CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]);
269 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
270 
271     /* Disable UART TX RX before setting. */
272     base->C2 &= ~((uint8_t)UART_C2_TE_MASK | (uint8_t)UART_C2_RE_MASK);
273 
274     /* Write the sbr value to the BDH and BDL registers*/
275     base->BDH = (base->BDH & ~(uint8_t)UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8);
276     base->BDL = (uint8_t)sbr;
277 
278 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT
279     /* Write the brfa value to the register*/
280     base->C4 = (base->C4 & ~(uint8_t)UART_C4_BRFA_MASK) | ((uint8_t)brfa & UART_C4_BRFA_MASK);
281 #endif
282 
283     /* Set bit count/parity mode/idle type. */
284     temp = base->C1 &
285            ~((uint8_t)UART_C1_PE_MASK | (uint8_t)UART_C1_PT_MASK | (uint8_t)UART_C1_M_MASK | (uint8_t)UART_C1_ILT_MASK);
286 
287     temp |= UART_C1_ILT(config->idleType);
288 
289     if (kUART_ParityDisabled != config->parityMode)
290     {
291         temp |= (UART_C1_M_MASK | (uint8_t)config->parityMode);
292     }
293 
294     base->C1 = temp;
295 
296 #if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT
297     /* Set stop bit per char */
298     base->BDH = (base->BDH & ~(uint8_t)UART_BDH_SBNS_MASK) | (uint8_t)UART_BDH_SBNS((uint8_t)config->stopBitCount);
299 #endif
300 
301 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
302     /* Set tx/rx FIFO watermark
303        Note:
304        Take care of the RX FIFO, RX interrupt request only assert when received bytes
305        equal or more than RX water mark, there is potential issue if RX water
306        mark larger than 1.
307        For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
308        5 bytes are received. the last byte will be saved in FIFO but not trigger
309        RX interrupt because the water mark is 2.
310      */
311     base->TWFIFO = config->txFifoWatermark;
312     base->RWFIFO = config->rxFifoWatermark;
313 
314     /* Enable tx/rx FIFO */
315     base->PFIFO |= (UART_PFIFO_TXFE_MASK | UART_PFIFO_RXFE_MASK);
316 
317     /* Flush FIFO */
318     base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK);
319 #endif
320 #if defined(FSL_FEATURE_UART_HAS_MODEM_SUPPORT) && FSL_FEATURE_UART_HAS_MODEM_SUPPORT
321     if (config->enableRxRTS)
322     {
323         /* Enable receiver RTS(request-to-send) function. */
324         base->MODEM |= UART_MODEM_RXRTSE_MASK;
325     }
326     if (config->enableTxCTS)
327     {
328         /* Enable transmitter CTS(clear-to-send) function. */
329         base->MODEM |= UART_MODEM_TXCTSE_MASK;
330     }
331 #endif
332 
333     /* Enable TX/RX base on configure structure. */
334     temp = base->C2;
335 
336     if (config->enableTx)
337     {
338         temp |= UART_C2_TE_MASK;
339     }
340 
341     if (config->enableRx)
342     {
343         temp |= UART_C2_RE_MASK;
344     }
345 
346     base->C2 = temp;
347 
348     return kStatus_Success;
349 }
350 
351 /*!
352  * brief Deinitializes a UART instance.
353  *
354  * This function waits for TX complete, disables TX and RX, and disables the UART clock.
355  *
356  * param base UART peripheral base address.
357  */
UART_Deinit(UART_Type * base)358 void UART_Deinit(UART_Type *base)
359 {
360 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
361     /* Wait tx FIFO send out*/
362     while (0U != base->TCFIFO)
363     {
364     }
365 #endif
366     /* Wait last char shoft out */
367     while (0U == (base->S1 & UART_S1_TC_MASK))
368     {
369     }
370 
371     /* Disable the module. */
372     base->C2 = 0;
373 
374 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
375     /* Disable uart clock */
376     CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]);
377 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
378 }
379 
380 /*!
381  * brief Gets the default configuration structure.
382  *
383  * This function initializes the UART configuration structure to a default value. The default
384  * values are as follows.
385  *   uartConfig->baudRate_Bps = 115200U;
386  *   uartConfig->bitCountPerChar = kUART_8BitsPerChar;
387  *   uartConfig->parityMode = kUART_ParityDisabled;
388  *   uartConfig->stopBitCount = kUART_OneStopBit;
389  *   uartConfig->txFifoWatermark = 0;
390  *   uartConfig->rxFifoWatermark = 1;
391  *   uartConfig->idleType = kUART_IdleTypeStartBit;
392  *   uartConfig->enableTx = false;
393  *   uartConfig->enableRx = false;
394  *
395  * param config Pointer to configuration structure.
396  */
UART_GetDefaultConfig(uart_config_t * config)397 void UART_GetDefaultConfig(uart_config_t *config)
398 {
399     assert(config != NULL);
400 
401     /* Initializes the configure structure to zero. */
402     (void)memset(config, 0, sizeof(*config));
403 
404     config->baudRate_Bps = 115200U;
405     config->parityMode   = kUART_ParityDisabled;
406 #if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT
407     config->stopBitCount = kUART_OneStopBit;
408 #endif
409 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
410     config->txFifoWatermark = 0;
411     config->rxFifoWatermark = 1;
412 #endif
413 #if defined(FSL_FEATURE_UART_HAS_MODEM_SUPPORT) && FSL_FEATURE_UART_HAS_MODEM_SUPPORT
414     config->enableRxRTS = false;
415     config->enableTxCTS = false;
416 #endif
417     config->idleType = kUART_IdleTypeStartBit;
418     config->enableTx = false;
419     config->enableRx = false;
420 }
421 
422 /*!
423  * brief Sets the UART instance baud rate.
424  *
425  * This function configures the UART module baud rate. This function is used to update
426  * the UART module baud rate after the UART module is initialized by the UART_Init.
427  * code
428  *  UART_SetBaudRate(UART1, 115200U, 20000000U);
429  * endcode
430  *
431  * param base UART peripheral base address.
432  * param baudRate_Bps UART baudrate to be set.
433  * param srcClock_Hz UART clock source frequency in Hz.
434  * retval kStatus_UART_BaudrateNotSupport Baudrate is not support in the current clock source.
435  * retval kStatus_Success Set baudrate succeeded.
436  */
UART_SetBaudRate(UART_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)437 status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
438 {
439     assert(baudRate_Bps != 0U);
440 
441     uint32_t sbr      = 0;
442     uint32_t baudDiff = 0;
443     uint8_t oldCtrl;
444 
445     /* Calculate the baud rate modulo divisor, sbr*/
446     sbr = srcClock_Hz / (baudRate_Bps * 16U);
447     /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */
448     if (sbr == 0U)
449     {
450         sbr = 1U;
451     }
452 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT
453     /* Determine if a fractional divider is needed to fine tune closer to the
454      * desired baud, each value of brfa is in 1/32 increments,
455      * hence the multiply-by-32. */
456     uint32_t tempBaud = 0U;
457 
458     uint32_t brfa = (2U * srcClock_Hz / (baudRate_Bps)) - 32U * sbr;
459 
460     /* Calculate the baud rate based on the temporary SBR values and BRFA */
461     tempBaud = (srcClock_Hz * 2U / ((sbr * 32U + brfa)));
462     baudDiff = (tempBaud > baudRate_Bps) ? (tempBaud - baudRate_Bps) : (baudRate_Bps - tempBaud);
463 #else
464     /* Calculate the baud rate based on the temporary SBR values */
465     baudDiff = (srcClock_Hz / (sbr * 16U)) - baudRate_Bps;
466 
467     /* Select the better value between sbr and (sbr + 1) */
468     if (baudDiff > (baudRate_Bps - (srcClock_Hz / (16U * (sbr + 1U)))))
469     {
470         baudDiff = baudRate_Bps - (srcClock_Hz / (16U * (sbr + 1U)));
471         sbr++;
472     }
473 #endif
474 
475     /* next, check to see if actual baud rate is within 3% of desired baud rate
476      * based on the calculate SBR value */
477     if (baudDiff < ((baudRate_Bps / 100U) * 3U))
478     {
479         /* Store C2 before disable Tx and Rx */
480         oldCtrl = base->C2;
481 
482         /* Disable UART TX RX before setting. */
483         base->C2 &= ~((uint8_t)UART_C2_TE_MASK | (uint8_t)UART_C2_RE_MASK);
484 
485         /* Write the sbr value to the BDH and BDL registers*/
486         base->BDH = (base->BDH & ~(uint8_t)UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8);
487         base->BDL = (uint8_t)sbr;
488 
489 #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT
490         /* Write the brfa value to the register*/
491         base->C4 = (base->C4 & ~(uint8_t)UART_C4_BRFA_MASK) | ((uint8_t)brfa & (uint8_t)UART_C4_BRFA_MASK);
492 #endif
493         /* Restore C2. */
494         base->C2 = oldCtrl;
495 
496         return kStatus_Success;
497     }
498     else
499     {
500         /* Unacceptable baud rate difference of more than 3%*/
501         return kStatus_UART_BaudrateNotSupport;
502     }
503 }
504 
505 /*!
506  * brief Enable 9-bit data mode for UART.
507  *
508  * This function set the 9-bit mode for UART module. The 9th bit is not used for parity thus can be modified by user.
509  *
510  * param base UART peripheral base address.
511  * param enable true to enable, flase to disable.
512  */
UART_Enable9bitMode(UART_Type * base,bool enable)513 void UART_Enable9bitMode(UART_Type *base, bool enable)
514 {
515     assert(base != NULL);
516 
517     uint8_t temp = 0U;
518 
519     if (enable)
520     {
521         /* Set UART_C1_M for 9-bit mode, clear UART_C1_PT and UART_C1_PE to disable parity. */
522         temp = base->C1 & ~((uint8_t)UART_C1_PE_MASK | (uint8_t)UART_C1_PT_MASK | (uint8_t)UART_C1_M_MASK);
523         temp |= (uint8_t)UART_C1_M_MASK;
524         base->C1 = temp;
525     }
526     else
527     {
528         /* Clear UART_C1_M. */
529         base->C1 &= ~(uint8_t)UART_C1_M_MASK;
530     }
531 }
532 
533 #if defined(FSL_FEATURE_UART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_UART_HAS_ADDRESS_MATCHING
534 /*!
535  * brief Transmit an address frame in 9-bit data mode.
536  *
537  * param base UART peripheral base address.
538  * param address UART slave address.
539  */
UART_SendAddress(UART_Type * base,uint8_t address)540 void UART_SendAddress(UART_Type *base, uint8_t address)
541 {
542     assert(base != NULL);
543 
544     /* Set address mark. */
545     UART_Set9thTransmitBit(base);
546     /* Send address. */
547     UART_WriteByte(base, address);
548     /* Clear address mark for following data transfer. */
549     UART_Clear9thTransmitBit(base);
550 }
551 #endif
552 
553 /*!
554  * brief Enables UART interrupts according to the provided mask.
555  *
556  * This function enables the UART interrupts according to the provided mask. The mask
557  * is a logical OR of enumeration members. See ref _uart_interrupt_enable.
558  * For example, to enable TX empty interrupt and RX full interrupt, do the following.
559  * code
560  *     UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable);
561  * endcode
562  *
563  * param base UART peripheral base address.
564  * param mask The interrupts to enable. Logical OR of ref _uart_interrupt_enable.
565  */
UART_EnableInterrupts(UART_Type * base,uint32_t mask)566 void UART_EnableInterrupts(UART_Type *base, uint32_t mask)
567 {
568     mask &= (uint32_t)kUART_AllInterruptsEnable;
569 
570     /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH))
571      */
572     base->BDH |= (uint8_t)mask;
573     base->C2 |= (uint8_t)(mask >> 8);
574     base->C3 |= (uint8_t)(mask >> 16);
575 
576 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
577     base->CFIFO |= (uint8_t)(mask >> 24);
578 #endif
579 }
580 
581 /*!
582  * brief Disables the UART interrupts according to the provided mask.
583  *
584  * This function disables the UART interrupts according to the provided mask. The mask
585  * is a logical OR of enumeration members. See ref _uart_interrupt_enable.
586  * For example, to disable TX empty interrupt and RX full interrupt do the following.
587  * code
588  *     UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable);
589  * endcode
590  *
591  * param base UART peripheral base address.
592  * param mask The interrupts to disable. Logical OR of ref _uart_interrupt_enable.
593  */
UART_DisableInterrupts(UART_Type * base,uint32_t mask)594 void UART_DisableInterrupts(UART_Type *base, uint32_t mask)
595 {
596     mask &= (uint32_t)kUART_AllInterruptsEnable;
597 
598     /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH))
599      */
600     base->BDH &= ~(uint8_t)mask;
601     base->C2 &= ~(uint8_t)(mask >> 8);
602     base->C3 &= ~(uint8_t)(mask >> 16);
603 
604 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
605     base->CFIFO &= ~(uint8_t)(mask >> 24);
606 #endif
607 }
608 
609 /*!
610  * brief Gets the enabled UART interrupts.
611  *
612  * This function gets the enabled UART interrupts. The enabled interrupts are returned
613  * as the logical OR value of the enumerators ref _uart_interrupt_enable. To check
614  * a specific interrupts enable status, compare the return value with enumerators
615  * in ref _uart_interrupt_enable.
616  * For example, to check whether TX empty interrupt is enabled, do the following.
617  * code
618  *     uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1);
619  *
620  *     if (kUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)
621  *     {
622  *         ...
623  *     }
624  * endcode
625  *
626  * param base UART peripheral base address.
627  * return UART interrupt flags which are logical OR of the enumerators in ref _uart_interrupt_enable.
628  */
UART_GetEnabledInterrupts(UART_Type * base)629 uint32_t UART_GetEnabledInterrupts(UART_Type *base)
630 {
631     uint32_t temp;
632 
633     temp = (uint32_t)base->BDH;
634     temp |= ((uint32_t)(base->C2) << 8);
635     temp |= ((uint32_t)(base->C3) << 16);
636 
637 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
638     temp |= ((uint32_t)(base->CFIFO) << 24);
639 #endif
640 
641     return temp & (uint32_t)kUART_AllInterruptsEnable;
642 }
643 
644 /*!
645  * brief Gets UART status flags.
646  *
647  * This function gets all UART status flags. The flags are returned as the logical
648  * OR value of the enumerators ref _uart_flags. To check a specific status,
649  * compare the return value with enumerators in ref _uart_flags.
650  * For example, to check whether the TX is empty, do the following.
651  * code
652  *     if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1))
653  *     {
654  *         ...
655  *     }
656  * endcode
657  *
658  * param base UART peripheral base address.
659  * return UART status flags which are ORed by the enumerators in the _uart_flags.
660  */
UART_GetStatusFlags(UART_Type * base)661 uint32_t UART_GetStatusFlags(UART_Type *base)
662 {
663     uint32_t status_flag;
664 
665     status_flag = (uint32_t)base->S1;
666     status_flag |= ((uint32_t)(base->S2) << 8);
667 
668 #if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS
669     status_flag |= ((uint32_t)(base->ED) << 16);
670 #endif
671 
672 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
673     status_flag |= ((uint32_t)(base->SFIFO) << 24);
674 #endif
675 
676     return status_flag;
677 }
678 
679 /*!
680  * brief Clears status flags with the provided mask.
681  *
682  * This function clears UART status flags with a provided mask. An automatically cleared flag
683  * can't be cleared by this function.
684  * These flags can only be cleared or set by hardware.
685  *    kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag,
686  *    kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag,
687  *    kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag
688  * Note that this API should be called when the Tx/Rx is idle. Otherwise it has no effect.
689  *
690  * param base UART peripheral base address.
691  * param mask The status flags to be cleared; it is logical OR value of ref _uart_flags.
692  * retval kStatus_UART_FlagCannotClearManually The flag can't be cleared by this function but
693  *         it is cleared automatically by hardware.
694  * retval kStatus_Success Status in the mask is cleared.
695  */
UART_ClearStatusFlags(UART_Type * base,uint32_t mask)696 status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask)
697 {
698     uint8_t reg = base->S2;
699     status_t status;
700 
701 #if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT
702     reg &= ~((uint8_t)UART_S2_RXEDGIF_MASK | (uint8_t)UART_S2_LBKDIF_MASK);
703 #else
704     reg &= ~(uint8_t)UART_S2_RXEDGIF_MASK;
705 #endif
706 
707     base->S2 = reg | (uint8_t)(mask >> 8);
708 
709 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
710     base->SFIFO = (uint8_t)(mask >> 24);
711 #endif
712 
713     if ((mask & ((uint32_t)kUART_IdleLineFlag | (uint32_t)kUART_NoiseErrorFlag | (uint32_t)kUART_FramingErrorFlag |
714                  (uint32_t)kUART_ParityErrorFlag | (uint32_t)kUART_RxOverrunFlag)) != 0u)
715     {
716         /* Read base->S1 and base->D to clear the flags. */
717         (void)base->S1;
718         (void)base->D;
719 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
720         /* Read base->D may cause receiver underflow when there are no valid data.
721            Clear receiver underflow flag */
722         base->SFIFO = UART_SFIFO_RXUF_MASK;
723         /* Flush FIFO data. Otherwise FIFO pointer will be in unknown state. */
724         base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
725 #endif
726     }
727 
728     /* If some flags still pending. */
729     if ((mask & UART_GetStatusFlags(base)) != 0U)
730     {
731         /* Some flags can only clear or set by the hardware itself, these flags are: kUART_TxDataRegEmptyFlag,
732         kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag,
733         kUART_ParityErrorInRxDataRegFlag, kUART_TxFifoEmptyFlag, kUART_RxFifoEmptyFlag. */
734         status = kStatus_UART_FlagCannotClearManually;
735     }
736     else
737     {
738         status = kStatus_Success;
739     }
740 
741     return status;
742 }
743 
744 /*!
745  * brief Writes to the TX register using a blocking method.
746  *
747  * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
748  * to have room and writes data to the TX buffer.
749  *
750  * param base UART peripheral base address.
751  * param data Start address of the data to write.
752  * param length Size of the data to write.
753  * retval kStatus_UART_Timeout Transmission timed out and was aborted.
754  * retval kStatus_Success Successfully wrote all data.
755  */
UART_WriteBlocking(UART_Type * base,const uint8_t * data,size_t length)756 status_t UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length)
757 {
758 #if UART_RETRY_TIMES
759     uint32_t waitTimes;
760 #endif
761     while (0U != length--)
762     {
763 #if UART_RETRY_TIMES
764         waitTimes = UART_RETRY_TIMES;
765         while ((0U == (base->S1 & UART_S1_TDRE_MASK)) && (0U != --waitTimes))
766 #else
767         while (0U == (base->S1 & UART_S1_TDRE_MASK))
768 #endif
769         {
770         }
771 #if UART_RETRY_TIMES
772         if (waitTimes == 0U)
773         {
774             return kStatus_LPUART_Timeout;
775         }
776 #endif
777         base->D = *(data++);
778     }
779 
780     /* Ensure all the data in the transmit buffer are sent out to bus. */
781 #if UART_RETRY_TIMES
782     waitTimes = UART_RETRY_TIMES;
783     while ((0U == (base->S1 & UART_S1_TC_MASK)) && (0U != --waitTimes))
784 #else
785     while (0U == (base->S1 & UART_S1_TC_MASK))
786 #endif
787     {
788     }
789 #if UART_RETRY_TIMES
790     if (waitTimes == 0U)
791     {
792         return kStatus_LPUART_Timeout;
793     }
794 #endif
795     return kStatus_Success;
796 }
797 
UART_WriteNonBlocking(UART_Type * base,const uint8_t * data,size_t length)798 static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length)
799 {
800     assert(data != NULL);
801 
802     size_t i;
803 
804     /* The Non Blocking write data API assume user have ensured there is enough space in
805     peripheral to write. */
806     for (i = 0; i < length; i++)
807     {
808         base->D = data[i];
809     }
810 }
811 
812 /*!
813  * brief Read RX data register using a blocking method.
814  *
815  * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
816  * have data, and reads data from the TX register.
817  *
818  * param base UART peripheral base address.
819  * param data Start address of the buffer to store the received data.
820  * param length Size of the buffer.
821  * retval kStatus_UART_RxHardwareOverrun Receiver overrun occurred while receiving data.
822  * retval kStatus_UART_NoiseError A noise error occurred while receiving data.
823  * retval kStatus_UART_FramingError A framing error occurred while receiving data.
824  * retval kStatus_UART_ParityError A parity error occurred while receiving data.
825  * retval kStatus_UART_Timeout Transmission timed out and was aborted.
826  * retval kStatus_Success Successfully received all data.
827  */
UART_ReadBlocking(UART_Type * base,uint8_t * data,size_t length)828 status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length)
829 {
830     assert(data != NULL);
831 
832     status_t status = kStatus_Success;
833     uint32_t statusFlag;
834 #if UART_RETRY_TIMES
835     uint32_t waitTimes;
836 #endif
837 
838     while (length-- != 0U)
839     {
840 #if UART_RETRY_TIMES
841         waitTimes = UART_RETRY_TIMES;
842 #endif
843 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
844         while (base->RCFIFO == 0U)
845 #else
846         while ((base->S1 & UART_S1_RDRF_MASK) == 0U)
847 #endif
848         {
849 #if UART_RETRY_TIMES
850             if (0U == --waitTimes)
851             {
852                 status = kStatus_LPUART_Timeout;
853                 break;
854             }
855 #endif
856             statusFlag = UART_GetStatusFlags(base);
857 
858             if (0U != (statusFlag & (uint32_t)kUART_RxOverrunFlag))
859             {
860                 status = ((kStatus_Success == UART_ClearStatusFlags(base, (uint32_t)kUART_RxOverrunFlag)) ?
861                               (status_t)(kStatus_UART_RxHardwareOverrun) :
862                               (status_t)(kStatus_UART_FlagCannotClearManually));
863                 /* If the OR bit is set all the other error flags are prevented from setting,
864                    no need to check other status flags. */
865                 break;
866             }
867 
868             if (0U != (statusFlag & (uint32_t)kUART_ParityErrorFlag))
869             {
870                 status = ((kStatus_Success == UART_ClearStatusFlags(base, (uint32_t)kUART_ParityErrorFlag)) ?
871                               (status_t)(kStatus_UART_ParityError) :
872                               (status_t)(kStatus_UART_FlagCannotClearManually));
873             }
874 
875             if (0U != (statusFlag & (uint32_t)kUART_FramingErrorFlag))
876             {
877                 status = ((kStatus_Success == UART_ClearStatusFlags(base, (uint32_t)kUART_FramingErrorFlag)) ?
878                               (status_t)(kStatus_UART_FramingError) :
879                               (status_t)(kStatus_UART_FlagCannotClearManually));
880             }
881 
882             if (0U != (statusFlag & (uint32_t)kUART_NoiseErrorFlag))
883             {
884                 status = ((kStatus_Success == UART_ClearStatusFlags(base, (uint32_t)kUART_NoiseErrorFlag)) ?
885                               (status_t)(kStatus_UART_NoiseError) :
886                               (status_t)(kStatus_UART_FlagCannotClearManually));
887             }
888             if (kStatus_Success != status)
889             {
890                 break;
891             }
892         }
893         if (kStatus_Success == status)
894         {
895             *(data++) = base->D;
896         }
897         else
898         {
899             break;
900         }
901     }
902 
903     return status;
904 }
905 
UART_ReadNonBlocking(UART_Type * base,uint8_t * data,size_t length)906 static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length)
907 {
908     assert(data != NULL);
909 
910     size_t i;
911 
912     /* The Non Blocking read data API assume user have ensured there is enough space in
913     peripheral to write. */
914     for (i = 0; i < length; i++)
915     {
916         data[i] = base->D;
917     }
918 }
919 
920 /*!
921  * brief Initializes the UART handle.
922  *
923  * This function initializes the UART handle which can be used for other UART
924  * transactional APIs. Usually, for a specified UART instance,
925  * call this API once to get the initialized handle.
926  *
927  * param base UART peripheral base address.
928  * param handle UART handle pointer.
929  * param callback The callback function.
930  * param userData The parameter of the callback function.
931  */
UART_TransferCreateHandle(UART_Type * base,uart_handle_t * handle,uart_transfer_callback_t callback,void * userData)932 void UART_TransferCreateHandle(UART_Type *base,
933                                uart_handle_t *handle,
934                                uart_transfer_callback_t callback,
935                                void *userData)
936 {
937     assert(handle != NULL);
938 
939     uint32_t instance;
940 
941     /* Zero the handle. */
942     (void)memset(handle, 0, sizeof(*handle));
943 
944     /* Set the TX/RX state. */
945     handle->rxState = (uint8_t)kUART_RxIdle;
946     handle->txState = (uint8_t)kUART_TxIdle;
947 
948     /* Set the callback and user data. */
949     handle->callback = callback;
950     handle->userData = userData;
951 
952     /* Get instance from peripheral base address. */
953     instance = UART_GetInstance(base);
954 
955     /* Save the handle in global variables to support the double weak mechanism. */
956     s_uartHandle[instance] = handle;
957 
958     s_uartIsr = UART_TransferHandleIRQ;
959     /* Enable interrupt in NVIC. */
960     (void)EnableIRQ(s_uartIRQ[instance]);
961 }
962 
963 /*!
964  * brief Sets up the RX ring buffer.
965  *
966  * This function sets up the RX ring buffer to a specific UART handle.
967  *
968  * When the RX ring buffer is used, data received are stored into the ring buffer even when the
969  * user doesn't call the UART_TransferReceiveNonBlocking() API. If data is already received
970  * in the ring buffer, the user can get the received data from the ring buffer directly.
971  *
972  * note When using the RX ring buffer, one byte is reserved for internal use. In other
973  * words, if p ringBufferSize is 32, only 31 bytes are used for saving data.
974  *
975  * param base UART peripheral base address.
976  * param handle UART handle pointer.
977  * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
978  * param ringBufferSize Size of the ring buffer.
979  */
UART_TransferStartRingBuffer(UART_Type * base,uart_handle_t * handle,uint8_t * ringBuffer,size_t ringBufferSize)980 void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize)
981 {
982     assert(handle != NULL);
983     assert(ringBuffer != NULL);
984 
985     /* Setup the ringbuffer address */
986     handle->rxRingBuffer     = ringBuffer;
987     handle->rxRingBufferSize = ringBufferSize;
988     handle->rxRingBufferHead = 0U;
989     handle->rxRingBufferTail = 0U;
990 
991     /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte. */
992     uint32_t irqMask = DisableGlobalIRQ();
993     /* Enable the interrupt to accept the data when user need the ring buffer. */
994     base->C2 |= (uint8_t)UART_C2_RIE_MASK;
995     base->C3 |= ((uint8_t)UART_C3_ORIE_MASK | (uint8_t)UART_C3_FEIE_MASK);
996     /* Enable parity error interrupt when parity mode is enable*/
997     if (((uint8_t)UART_C1_PE_MASK & base->C1) != 0U)
998     {
999         base->C3 |= (uint8_t)UART_C3_PEIE_MASK;
1000     }
1001     EnableGlobalIRQ(irqMask);
1002 }
1003 
1004 /*!
1005  * brief Aborts the background transfer and uninstalls the ring buffer.
1006  *
1007  * This function aborts the background transfer and uninstalls the ring buffer.
1008  *
1009  * param base UART peripheral base address.
1010  * param handle UART handle pointer.
1011  */
UART_TransferStopRingBuffer(UART_Type * base,uart_handle_t * handle)1012 void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle)
1013 {
1014     assert(handle != NULL);
1015 
1016     if (handle->rxState == (uint8_t)kUART_RxIdle)
1017     {
1018         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1019          */
1020         uint32_t irqMask = DisableGlobalIRQ();
1021         base->C2 &= ~(uint8_t)UART_C2_RIE_MASK;
1022         base->C3 &= ~((uint8_t)UART_C3_ORIE_MASK | (uint8_t)UART_C3_FEIE_MASK);
1023         /* Disable parity error interrupt when parity mode is enable*/
1024         if (((uint8_t)UART_C1_PE_MASK & base->C1) != 0U)
1025         {
1026             base->C3 &= ~(uint8_t)UART_C3_PEIE_MASK;
1027         }
1028         EnableGlobalIRQ(irqMask);
1029     }
1030 
1031     handle->rxRingBuffer     = NULL;
1032     handle->rxRingBufferSize = 0U;
1033     handle->rxRingBufferHead = 0U;
1034     handle->rxRingBufferTail = 0U;
1035 }
1036 
1037 /*!
1038  * brief Transmits a buffer of data using the interrupt method.
1039  *
1040  * This function sends data using an interrupt method. This is a non-blocking function, which
1041  * returns directly without waiting for all data to be written to the TX register. When
1042  * all data is written to the TX register in the ISR, the UART driver calls the callback
1043  * function and passes the ref kStatus_UART_TxIdle as status parameter.
1044  *
1045  * note The kStatus_UART_TxIdle is passed to the upper layer when all data is written
1046  * to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX,
1047  * check the kUART_TransmissionCompleteFlag to ensure that the TX is finished.
1048  *
1049  * param base UART peripheral base address.
1050  * param handle UART handle pointer.
1051  * param xfer UART transfer structure. See  #uart_transfer_t.
1052  * retval kStatus_Success Successfully start the data transmission.
1053  * retval kStatus_UART_TxBusy Previous transmission still not finished; data not all written to TX register yet.
1054  * retval kStatus_InvalidArgument Invalid argument.
1055  */
UART_TransferSendNonBlocking(UART_Type * base,uart_handle_t * handle,uart_transfer_t * xfer)1056 status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer)
1057 {
1058     assert(handle != NULL);
1059     assert(xfer != NULL);
1060     assert(xfer->dataSize != 0U);
1061     assert(xfer->txData != NULL);
1062 
1063     status_t status;
1064 
1065     /* Return error if current TX busy. */
1066     if ((uint8_t)kUART_TxBusy == handle->txState)
1067     {
1068         status = kStatus_UART_TxBusy;
1069     }
1070     else
1071     {
1072         handle->txData        = xfer->txData;
1073         handle->txDataSize    = xfer->dataSize;
1074         handle->txDataSizeAll = xfer->dataSize;
1075         handle->txState       = (uint8_t)kUART_TxBusy;
1076 
1077         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1078          */
1079         uint32_t irqMask = DisableGlobalIRQ();
1080         /* Enable transmitter interrupt. */
1081         base->C2 |= (uint8_t)UART_C2_TIE_MASK;
1082         EnableGlobalIRQ(irqMask);
1083 
1084         status = kStatus_Success;
1085     }
1086 
1087     return status;
1088 }
1089 
1090 /*!
1091  * brief Aborts the interrupt-driven data transmit.
1092  *
1093  * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
1094  * how many bytes are not sent out.
1095  *
1096  * param base UART peripheral base address.
1097  * param handle UART handle pointer.
1098  */
UART_TransferAbortSend(UART_Type * base,uart_handle_t * handle)1099 void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle)
1100 {
1101     assert(handle != NULL);
1102 
1103     /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte. */
1104     uint32_t irqMask = DisableGlobalIRQ();
1105     base->C2 &= ~((uint8_t)UART_C2_TIE_MASK | (uint8_t)UART_C2_TCIE_MASK);
1106     EnableGlobalIRQ(irqMask);
1107 
1108     handle->txDataSize = 0;
1109     handle->txState    = (uint8_t)kUART_TxIdle;
1110 }
1111 
1112 /*!
1113  * brief Gets the number of bytes sent out to bus.
1114  *
1115  * This function gets the number of bytes sent out to bus by using the interrupt method.
1116  *
1117  * param base UART peripheral base address.
1118  * param handle UART handle pointer.
1119  * param count Send bytes count.
1120  * retval kStatus_NoTransferInProgress No send in progress.
1121  * retval kStatus_InvalidArgument The parameter is invalid.
1122  * retval kStatus_Success Get successfully through the parameter \p count;
1123  */
UART_TransferGetSendCount(UART_Type * base,uart_handle_t * handle,uint32_t * count)1124 status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count)
1125 {
1126     assert(handle != NULL);
1127     assert(count != NULL);
1128 
1129     if ((uint8_t)kUART_TxIdle == handle->txState)
1130     {
1131         return kStatus_NoTransferInProgress;
1132     }
1133 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1134     *count = handle->txDataSizeAll - handle->txDataSize - base->TCFIFO;
1135 #else
1136     if ((base->S1 & (uint8_t)kUART_TxDataRegEmptyFlag) != 0U)
1137     {
1138         *count = handle->txDataSizeAll - handle->txDataSize;
1139     }
1140     else
1141     {
1142         *count = handle->txDataSizeAll - handle->txDataSize - 1U;
1143     }
1144 #endif /* FSL_FEATURE_UART_HAS_FIFO */
1145 
1146     return kStatus_Success;
1147 }
1148 
1149 /*!
1150  * brief Receives a buffer of data using an interrupt method.
1151  *
1152  * This function receives data using an interrupt method. This is a non-blocking function, which
1153  *  returns without waiting for all data to be received.
1154  * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
1155  * the parameter p receivedBytes shows how many bytes are copied from the ring buffer.
1156  * After copying, if the data in the ring buffer is not enough to read, the receive
1157  * request is saved by the UART driver. When the new data arrives, the receive request
1158  * is serviced first. When all data is received, the UART driver notifies the upper layer
1159  * through a callback function and passes the status parameter ref kStatus_UART_RxIdle.
1160  * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
1161  * The 5 bytes are copied to the xfer->data and this function returns with the
1162  * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
1163  * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies the upper layer.
1164  * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
1165  * to receive data to the xfer->data. When all data is received, the upper layer is notified.
1166  *
1167  * param base UART peripheral base address.
1168  * param handle UART handle pointer.
1169  * param xfer UART transfer structure, see #uart_transfer_t.
1170  * param receivedBytes Bytes received from the ring buffer directly.
1171  * retval kStatus_Success Successfully queue the transfer into transmit queue.
1172  * retval kStatus_UART_RxBusy Previous receive request is not finished.
1173  * retval kStatus_InvalidArgument Invalid argument.
1174  */
UART_TransferReceiveNonBlocking(UART_Type * base,uart_handle_t * handle,uart_transfer_t * xfer,size_t * receivedBytes)1175 status_t UART_TransferReceiveNonBlocking(UART_Type *base,
1176                                          uart_handle_t *handle,
1177                                          uart_transfer_t *xfer,
1178                                          size_t *receivedBytes)
1179 {
1180     assert(handle != NULL);
1181     assert(xfer != NULL);
1182     assert(xfer->rxData != NULL);
1183     assert(xfer->dataSize != 0U);
1184 
1185     uint32_t i;
1186     status_t status;
1187     /* How many bytes to copy from ring buffer to user memory. */
1188     size_t bytesToCopy = 0U;
1189     /* How many bytes to receive. */
1190     size_t bytesToReceive;
1191     /* How many bytes currently have received. */
1192     size_t bytesCurrentReceived;
1193     uint32_t irqMask;
1194 
1195     /* How to get data:
1196        1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
1197           to uart handle, enable interrupt to store received data to xfer->data. When
1198           all data received, trigger callback.
1199        2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
1200           If there are enough data in ring buffer, copy them to xfer->data and return.
1201           If there are not enough data in ring buffer, copy all of them to xfer->data,
1202           save the xfer->data remained empty space to uart handle, receive data
1203           to this empty space and trigger callback when finished. */
1204 
1205     if ((uint8_t)kUART_RxBusy == handle->rxState)
1206     {
1207         status = kStatus_UART_RxBusy;
1208     }
1209     else
1210     {
1211         bytesToReceive       = xfer->dataSize;
1212         bytesCurrentReceived = 0U;
1213 
1214         /* If RX ring buffer is used. */
1215         if (handle->rxRingBuffer != NULL)
1216         {
1217             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1218              * read-modify-wrte. */
1219             irqMask = DisableGlobalIRQ();
1220             /* Disable UART RX IRQ, protect ring buffer. */
1221             base->C2 &= ~(uint8_t)UART_C2_RIE_MASK;
1222             EnableGlobalIRQ(irqMask);
1223 
1224             /* How many bytes in RX ring buffer currently. */
1225             bytesToCopy = UART_TransferGetRxRingBufferLength(handle);
1226 
1227             if (bytesToCopy != 0U)
1228             {
1229                 bytesToCopy = MIN(bytesToReceive, bytesToCopy);
1230 
1231                 bytesToReceive -= bytesToCopy;
1232 
1233                 /* Copy data from ring buffer to user memory. */
1234                 for (i = 0U; i < bytesToCopy; i++)
1235                 {
1236                     xfer->rxData[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
1237 
1238                     /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
1239                     if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
1240                     {
1241                         handle->rxRingBufferTail = 0U;
1242                     }
1243                     else
1244                     {
1245                         handle->rxRingBufferTail++;
1246                     }
1247                 }
1248             }
1249 
1250             /* If ring buffer does not have enough data, still need to read more data. */
1251             if (bytesToReceive != 0U)
1252             {
1253                 /* No data in ring buffer, save the request to UART handle. */
1254                 handle->rxData        = xfer->rxData + bytesCurrentReceived;
1255                 handle->rxDataSize    = bytesToReceive;
1256                 handle->rxDataSizeAll = xfer->dataSize;
1257                 handle->rxState       = (uint8_t)kUART_RxBusy;
1258             }
1259 
1260             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1261              * read-modify-wrte. */
1262             irqMask = DisableGlobalIRQ();
1263             /* Re-enable UART RX IRQ. */
1264             base->C2 |= (uint8_t)UART_C2_RIE_MASK;
1265             EnableGlobalIRQ(irqMask);
1266 
1267             /* Call user callback since all data are received. */
1268             if (0U == bytesToReceive)
1269             {
1270                 if (handle->callback != NULL)
1271                 {
1272                     handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData);
1273                 }
1274             }
1275         }
1276         /* Ring buffer not used. */
1277         else
1278         {
1279             handle->rxData        = xfer->rxData + bytesCurrentReceived;
1280             handle->rxDataSize    = bytesToReceive;
1281             handle->rxDataSizeAll = bytesToReceive;
1282             handle->rxState       = (uint8_t)kUART_RxBusy;
1283 
1284             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1285              * read-modify-wrte. */
1286             irqMask = DisableGlobalIRQ();
1287             /* Enable RX/Rx overrun/framing error/idle line interrupt. */
1288             base->C2 |= ((uint8_t)UART_C2_RIE_MASK | (uint8_t)UART_C2_ILIE_MASK);
1289             base->C3 |= ((uint8_t)UART_C3_ORIE_MASK | (uint8_t)UART_C3_FEIE_MASK);
1290 
1291             /* Enable parity error interrupt when parity mode is enable*/
1292             if (((uint8_t)UART_C1_PE_MASK & base->C1) != 0U)
1293             {
1294                 base->C3 |= (uint8_t)UART_C3_PEIE_MASK;
1295             }
1296             EnableGlobalIRQ(irqMask);
1297         }
1298 
1299         /* Return the how many bytes have read. */
1300         if (receivedBytes != NULL)
1301         {
1302             *receivedBytes = bytesCurrentReceived;
1303         }
1304 
1305         status = kStatus_Success;
1306     }
1307 
1308     return status;
1309 }
1310 
1311 /*!
1312  * brief Aborts the interrupt-driven data receiving.
1313  *
1314  * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
1315  * how many bytes are not received yet.
1316  *
1317  * param base UART peripheral base address.
1318  * param handle UART handle pointer.
1319  */
UART_TransferAbortReceive(UART_Type * base,uart_handle_t * handle)1320 void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle)
1321 {
1322     assert(handle != NULL);
1323 
1324     /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
1325     if (NULL == handle->rxRingBuffer)
1326     {
1327         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1328          */
1329         uint32_t irqMask = DisableGlobalIRQ();
1330         /* Disable RX interrupt. */
1331         base->C2 &= ~((uint8_t)UART_C2_RIE_MASK | (uint8_t)UART_C2_ILIE_MASK);
1332         base->C3 &= ~((uint8_t)UART_C3_ORIE_MASK | (uint8_t)UART_C3_FEIE_MASK);
1333         /* Disable parity error interrupt when parity mode is enable*/
1334         if (((uint8_t)UART_C1_PE_MASK & base->C1) != 0U)
1335         {
1336             base->C3 &= ~(uint8_t)UART_C3_PEIE_MASK;
1337         }
1338         EnableGlobalIRQ(irqMask);
1339     }
1340 
1341     handle->rxDataSize = 0U;
1342     handle->rxState    = (uint8_t)kUART_RxIdle;
1343 }
1344 
1345 /*!
1346  * brief Gets the number of bytes that have been received.
1347  *
1348  * This function gets the number of bytes that have been received.
1349  *
1350  * param base UART peripheral base address.
1351  * param handle UART handle pointer.
1352  * param count Receive bytes count.
1353  * retval kStatus_NoTransferInProgress No receive in progress.
1354  * retval kStatus_InvalidArgument Parameter is invalid.
1355  * retval kStatus_Success Get successfully through the parameter \p count;
1356  */
UART_TransferGetReceiveCount(UART_Type * base,uart_handle_t * handle,uint32_t * count)1357 status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count)
1358 {
1359     assert(handle != NULL);
1360     assert(count != NULL);
1361 
1362     if ((uint8_t)kUART_RxIdle == handle->rxState)
1363     {
1364         return kStatus_NoTransferInProgress;
1365     }
1366 
1367     if (NULL == count)
1368     {
1369         return kStatus_InvalidArgument;
1370     }
1371 
1372     *count = handle->rxDataSizeAll - handle->rxDataSize;
1373 
1374     return kStatus_Success;
1375 }
1376 
1377 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1378 /*!
1379  * @brief Enables or disables the UART Tx FIFO.
1380  *
1381  * This function enables or disables the UART Tx FIFO.
1382  *
1383  * param base UART peripheral base address.
1384  * param enable true to enable, false to disable.
1385  * retval kStatus_Success Successfully turn on or turn off Tx FIFO.
1386  * retval kStatus_Fail Fail to turn on or turn off Tx FIFO.
1387  */
UART_EnableTxFIFO(UART_Type * base,bool enable)1388 status_t UART_EnableTxFIFO(UART_Type *base, bool enable)
1389 {
1390     uint8_t sfifo = 0;
1391     uint8_t temp  = 0;
1392 
1393     sfifo = base->SFIFO;
1394     temp  = base->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK);
1395     /* The Tx FIFO must be empty */
1396     if ((sfifo & UART_SFIFO_TXEMPT_MASK) == UART_SFIFO_TXEMPT_MASK)
1397     {
1398         /* Disable UART TX RX before setting */
1399         base->C2 &= ~((uint8_t)UART_C2_TE_MASK | (uint8_t)UART_C2_RE_MASK);
1400         /* Flush FIFO */
1401         base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK);
1402 
1403         if (enable)
1404         {
1405             base->PFIFO |= (uint8_t)UART_PFIFO_TXFE_MASK;
1406         }
1407         else
1408         {
1409             base->PFIFO &= ~(uint8_t)UART_PFIFO_TXFE_MASK;
1410         }
1411 
1412         /* Flush FIFO */
1413         base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK);
1414         base->C2 |= temp;
1415         return kStatus_Success;
1416     }
1417     else
1418     {
1419         return kStatus_Fail;
1420     }
1421 }
1422 
1423 /*!
1424  * @brief Enables or disables the UART Rx FIFO.
1425  *
1426  * This function enables or disables the UART Rx FIFO.
1427  *
1428  * param base UART peripheral base address.
1429  * param enable true to enable, false to disable.
1430  * retval kStatus_Success Successfully turn on or turn off Rx FIFO.
1431  * retval kStatus_Fail Fail to turn on or turn off Rx FIFO.
1432  */
UART_EnableRxFIFO(UART_Type * base,bool enable)1433 status_t UART_EnableRxFIFO(UART_Type *base, bool enable)
1434 {
1435     uint8_t sfifo = 0;
1436     uint8_t temp  = 0;
1437 
1438     sfifo = base->SFIFO;
1439     temp  = base->C2 & ((uint8_t)UART_C2_RE_MASK | (uint8_t)UART_C2_TE_MASK);
1440     /* The Rx FIFO must be empty */
1441     if ((sfifo & UART_SFIFO_RXEMPT_MASK) == UART_SFIFO_RXEMPT_MASK)
1442     {
1443         /* Disable UART TX RX before setting */
1444         base->C2 &= ~((uint8_t)UART_C2_TE_MASK | (uint8_t)UART_C2_RE_MASK);
1445         /* Flush FIFO */
1446         base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK);
1447 
1448         if (enable)
1449         {
1450             base->PFIFO |= (uint8_t)UART_PFIFO_RXFE_MASK;
1451         }
1452         else
1453         {
1454             base->PFIFO &= ~(uint8_t)UART_PFIFO_RXFE_MASK;
1455         }
1456         /* Flush FIFO */
1457         base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK);
1458         base->C2 |= temp;
1459         return kStatus_Success;
1460     }
1461     else
1462     {
1463         return kStatus_Fail;
1464     }
1465 }
1466 #endif /* FSL_FEATURE_UART_HAS_FIFO */
1467 
1468 /*!
1469  * brief UART IRQ handle function.
1470  *
1471  * This function handles the UART transmit and receive IRQ request.
1472  *
1473  * param base UART peripheral base address.
1474  * param irqHandle UART handle pointer.
1475  */
UART_TransferHandleIRQ(UART_Type * base,void * irqHandle)1476 void UART_TransferHandleIRQ(UART_Type *base, void *irqHandle)
1477 {
1478     assert(irqHandle != NULL);
1479 
1480     uint8_t count;
1481     uint8_t tempCount;
1482     uint32_t status = UART_GetStatusFlags(base);
1483     uint8_t tmpdata;
1484     uint32_t irqMask;
1485     uart_handle_t *handle = (uart_handle_t *)irqHandle;
1486 
1487     /* If RX framing error */
1488     if (((uint32_t)kUART_FramingErrorFlag & status) != 0U)
1489     {
1490         /* Read base->D to clear framing error flag, otherwise the RX does not work. */
1491         while ((base->S1 & UART_S1_RDRF_MASK) != 0U)
1492         {
1493             (void)base->D;
1494         }
1495 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1496         /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
1497         base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
1498 #endif
1499 
1500         handle->rxState    = (uint8_t)kUART_RxFramingError;
1501         handle->rxDataSize = 0U;
1502         /* Trigger callback. */
1503         if (handle->callback != NULL)
1504         {
1505             handle->callback(base, handle, kStatus_UART_FramingError, handle->userData);
1506         }
1507     }
1508 
1509     /* If RX parity error */
1510     if (((uint32_t)kUART_ParityErrorFlag & status) != 0U)
1511     {
1512         /* Read base->D to clear parity error flag, otherwise the RX does not work. */
1513         while ((base->S1 & UART_S1_RDRF_MASK) != 0U)
1514         {
1515             (void)base->D;
1516         }
1517 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1518         /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
1519         base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
1520 #endif
1521 
1522         handle->rxState    = (uint8_t)kUART_RxParityError;
1523         handle->rxDataSize = 0U;
1524         /* Trigger callback. */
1525         if (handle->callback != NULL)
1526         {
1527             handle->callback(base, handle, kStatus_UART_ParityError, handle->userData);
1528         }
1529     }
1530 
1531     /* If RX overrun. */
1532     if (((uint32_t)kUART_RxOverrunFlag & status) != 0U)
1533     {
1534         /* Read base->D to clear overrun flag, otherwise the RX does not work. */
1535         while ((base->S1 & UART_S1_RDRF_MASK) != 0U)
1536         {
1537             (void)base->D;
1538         }
1539 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1540         /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
1541         base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
1542 #endif
1543         /* Trigger callback. */
1544         if (handle->callback != NULL)
1545         {
1546             handle->callback(base, handle, kStatus_UART_RxHardwareOverrun, handle->userData);
1547         }
1548     }
1549 
1550     /* If IDLE line was detected. */
1551     if ((((uint32_t)kUART_IdleLineFlag & status) != 0U) && ((UART_C2_ILIE_MASK & base->C2) != 0U))
1552     {
1553 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1554         /* If still some data in the FIFO, read out these data to user data buffer. */
1555         count = base->RCFIFO;
1556         /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
1557         while ((count != 0U) && (handle->rxDataSize != 0U))
1558         {
1559             tempCount = (uint8_t)MIN(handle->rxDataSize, (uint32_t)count);
1560 
1561             /* Using non block API to read the data from the registers. */
1562             UART_ReadNonBlocking(base, handle->rxData, tempCount);
1563             handle->rxData += tempCount;
1564             handle->rxDataSize -= tempCount;
1565             count -= tempCount;
1566 
1567             /* If all the data required for upper layer is ready, trigger callback. */
1568             if (0U == handle->rxDataSize)
1569             {
1570                 handle->rxState = (uint8_t)kUART_RxIdle;
1571 
1572                 /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1573                  * read-modify-wrte. */
1574                 irqMask = DisableGlobalIRQ();
1575                 /* Disable RX interrupt/overrun interrupt/fram error/idle line detected interrupt */
1576                 base->C2 &= ~(uint8_t)UART_C2_RIE_MASK;
1577                 base->C3 &= ~((uint8_t)UART_C3_ORIE_MASK | (uint8_t)UART_C3_FEIE_MASK);
1578                 /* Disable parity error interrupt when parity mode is enabled */
1579                 if (((uint8_t)UART_C1_PE_MASK & base->C1) != 0U)
1580                 {
1581                     base->C3 &= ~(uint8_t)UART_C3_PEIE_MASK;
1582                 }
1583                 EnableGlobalIRQ(irqMask);
1584 
1585                 if (handle->callback != NULL)
1586                 {
1587                     handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData);
1588                 }
1589             }
1590         }
1591 #endif
1592         /* To clear IDLE, read UART status S1 with IDLE set and then read D.*/
1593         while ((UART_S1_IDLE_MASK & base->S1) != 0U)
1594         {
1595             (void)base->D;
1596         }
1597 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1598         /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
1599         base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
1600 #endif
1601         /* If rxDataSize is 0, disable idle line interrupt.*/
1602         if (0U == (handle->rxDataSize))
1603         {
1604             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1605              * read-modify-wrte. */
1606             irqMask = DisableGlobalIRQ();
1607             base->C2 &= ~(uint8_t)UART_C2_ILIE_MASK;
1608             EnableGlobalIRQ(irqMask);
1609         }
1610         /* If callback is not NULL and rxDataSize is not 0. */
1611         if ((handle->callback != NULL) && (handle->rxDataSize != 0U))
1612         {
1613             handle->callback(base, handle, kStatus_UART_IdleLineDetected, handle->userData);
1614         }
1615     }
1616     /* Receive data register full */
1617     if ((((uint32_t)kUART_RxDataRegFullFlag & status) != 0U) && ((UART_C2_RIE_MASK & base->C2) != 0U))
1618     {
1619 /* Get the size that can be stored into buffer for this interrupt. */
1620 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1621         count = base->RCFIFO;
1622 #else
1623         count = 1;
1624 #endif
1625 
1626         /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
1627         while ((count != 0U) && (handle->rxDataSize != 0U))
1628         {
1629 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1630             tempCount = (uint8_t)MIN(handle->rxDataSize, (uint32_t)count);
1631 #else
1632             tempCount = 1;
1633 #endif
1634 
1635             /* Using non block API to read the data from the registers. */
1636             UART_ReadNonBlocking(base, handle->rxData, tempCount);
1637             handle->rxData += tempCount;
1638             handle->rxDataSize -= tempCount;
1639             count -= tempCount;
1640 
1641             /* If all the data required for upper layer is ready, trigger callback. */
1642             if (0U == handle->rxDataSize)
1643             {
1644                 handle->rxState = (uint8_t)kUART_RxIdle;
1645 
1646                 if (handle->callback != NULL)
1647                 {
1648                     handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData);
1649                 }
1650             }
1651         }
1652 
1653         /* If use RX ring buffer, receive data to ring buffer. */
1654         if (handle->rxRingBuffer != NULL)
1655         {
1656             while (0U != count--)
1657             {
1658                 /* If RX ring buffer is full, trigger callback to notify over run. */
1659                 if (UART_TransferIsRxRingBufferFull(handle))
1660                 {
1661                     if (handle->callback != NULL)
1662                     {
1663                         handle->callback(base, handle, kStatus_UART_RxRingBufferOverrun, handle->userData);
1664                     }
1665                 }
1666 
1667                 /* If ring buffer is still full after callback function, the oldest data is overridden. */
1668                 if (UART_TransferIsRxRingBufferFull(handle))
1669                 {
1670                     /* Increase handle->rxRingBufferTail to make room for new data. */
1671                     if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
1672                     {
1673                         handle->rxRingBufferTail = 0U;
1674                     }
1675                     else
1676                     {
1677                         handle->rxRingBufferTail++;
1678                     }
1679                 }
1680 
1681                 /* Read data. */
1682                 tmpdata                                        = base->D;
1683                 handle->rxRingBuffer[handle->rxRingBufferHead] = tmpdata;
1684 
1685                 /* Increase handle->rxRingBufferHead. */
1686                 if ((size_t)handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
1687                 {
1688                     handle->rxRingBufferHead = 0U;
1689                 }
1690                 else
1691                 {
1692                     handle->rxRingBufferHead++;
1693                 }
1694             }
1695         }
1696 
1697         else if (0U == handle->rxDataSize)
1698         {
1699             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1700              * read-modify-wrte. */
1701             irqMask = DisableGlobalIRQ();
1702             /* Disable RX interrupt/overrun interrupt/fram error/idle line detected interrupt */
1703             base->C2 &= ~(uint8_t)UART_C2_RIE_MASK;
1704             base->C3 &= ~((uint8_t)UART_C3_ORIE_MASK | (uint8_t)UART_C3_FEIE_MASK);
1705             /* Disable parity error interrupt when parity mode is enabled */
1706             if (((uint8_t)UART_C1_PE_MASK & base->C1) != 0U)
1707             {
1708                 base->C3 &= ~(uint8_t)UART_C3_PEIE_MASK;
1709             }
1710             EnableGlobalIRQ(irqMask);
1711         }
1712         else
1713         {
1714         }
1715     }
1716 
1717     /* If framing error or parity error happened, stop the RX interrupt when use no ring buffer */
1718     if (((handle->rxState == (uint8_t)kUART_RxFramingError) || (handle->rxState == (uint8_t)kUART_RxParityError)) &&
1719         (NULL == handle->rxRingBuffer))
1720     {
1721         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1722          */
1723         irqMask = DisableGlobalIRQ();
1724         /* Enable RX/Rx overrun/framing error/idle line interrupt. */
1725         base->C2 |= ((uint8_t)UART_C2_RIE_MASK | (uint8_t)UART_C2_ILIE_MASK);
1726         base->C3 |= ((uint8_t)UART_C3_ORIE_MASK | (uint8_t)UART_C3_FEIE_MASK);
1727 
1728         /* Enable parity error interrupt when parity mode is enable*/
1729         if (((uint8_t)UART_C1_PE_MASK & base->C1) != 0U)
1730         {
1731             base->C3 |= (uint8_t)UART_C3_PEIE_MASK;
1732         }
1733         EnableGlobalIRQ(irqMask);
1734     }
1735 
1736     /* Send data register empty and the interrupt is enabled. */
1737     if ((((uint32_t)kUART_TxDataRegEmptyFlag & status) != 0U) && ((base->C2 & UART_C2_TIE_MASK) != 0U))
1738     {
1739 /* Get the bytes that available at this moment. */
1740 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1741         count = (uint8_t)FSL_FEATURE_UART_FIFO_SIZEn(base) - base->TCFIFO;
1742 #else
1743         count = 1;
1744 #endif
1745 
1746         while ((count != 0U) && (handle->txDataSize != 0U))
1747         {
1748 #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
1749             tempCount = (uint8_t)MIN(handle->txDataSize, (uint32_t)count);
1750 #else
1751             tempCount = 1;
1752 #endif
1753 
1754             /* Using non block API to write the data to the registers. */
1755             UART_WriteNonBlocking(base, handle->txData, tempCount);
1756             handle->txData += tempCount;
1757             handle->txDataSize -= tempCount;
1758             count -= tempCount;
1759 
1760             /* If all the data are written to data register, TX finished. */
1761             if (0U == handle->txDataSize)
1762             {
1763                 /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1764                  * read-modify-wrte. */
1765                 irqMask = DisableGlobalIRQ();
1766                 /* Disable TX register empty interrupt and enable transmission complete interrupt. */
1767                 base->C2 = (base->C2 & ~(uint8_t)UART_C2_TIE_MASK) | (uint8_t)UART_C2_TCIE_MASK;
1768                 EnableGlobalIRQ(irqMask);
1769             }
1770         }
1771     }
1772 
1773     /* Transmission complete and the interrupt is enabled. */
1774     if ((0U != ((uint32_t)kUART_TransmissionCompleteFlag & status)) && (0U != (base->C2 & UART_C2_TCIE_MASK)))
1775     {
1776         /* Set txState to idle only when all data has been sent out to bus. */
1777         handle->txState = (uint8_t)kUART_TxIdle;
1778 
1779         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1780          */
1781         irqMask = DisableGlobalIRQ();
1782         /* Disable transmission complete interrupt. */
1783         base->C2 &= ~(uint8_t)UART_C2_TCIE_MASK;
1784         EnableGlobalIRQ(irqMask);
1785 
1786         /* Trigger callback. */
1787         if (handle->callback != NULL)
1788         {
1789             handle->callback(base, handle, kStatus_UART_TxIdle, handle->userData);
1790         }
1791     }
1792 }
1793 
1794 /*!
1795  * brief UART Error IRQ handle function.
1796  *
1797  * This function handles the UART error IRQ request.
1798  *
1799  * param base UART peripheral base address.
1800  * param irqHandle UART handle pointer.
1801  */
UART_TransferHandleErrorIRQ(UART_Type * base,void * irqHandle)1802 void UART_TransferHandleErrorIRQ(UART_Type *base, void *irqHandle)
1803 {
1804     /* To be implemented by User. */
1805 }
1806 
1807 #if defined(FSL_FEATURE_UART_HAS_SHARED_IRQ0_IRQ1_IRQ2_IRQ3) && FSL_FEATURE_UART_HAS_SHARED_IRQ0_IRQ1_IRQ2_IRQ3
1808 void UART0_UART1_UART2_UART3_DriverIRQHandler(void);
UART0_UART1_UART2_UART3_DriverIRQHandler(void)1809 void UART0_UART1_UART2_UART3_DriverIRQHandler(void)
1810 {
1811     for (uint32_t instance = 0U; instance < 4U; instance++)
1812     {
1813         if (s_uartHandle[instance] != NULL)
1814         {
1815             s_uartIsr(s_uartBases[instance], s_uartHandle[instance]);
1816         }
1817     }
1818 }
1819 #else
1820 #if defined(FSL_FEATURE_UART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_UART_HAS_SHARED_IRQ0_IRQ1
1821 void UART0_UART1_DriverIRQHandler(void);
UART0_UART1_DriverIRQHandler(void)1822 void UART0_UART1_DriverIRQHandler(void)
1823 {
1824     for (uint32_t instance = 0U; instance < 2U; instance++)
1825     {
1826         if (s_uartHandle[instance] != NULL)
1827         {
1828             s_uartIsr(s_uartBases[instance], s_uartHandle[instance]);
1829         }
1830     }
1831 }
1832 #else /* FSL_FEATURE_UART_HAS_SHARED_IRQ0_IRQ1 */
1833 #if defined(UART0)
1834 #if ((!(defined(FSL_FEATURE_SOC_LPSCI_COUNT))) || \
1835      ((defined(FSL_FEATURE_SOC_LPSCI_COUNT)) && (FSL_FEATURE_SOC_LPSCI_COUNT == 0)))
1836 void UART0_DriverIRQHandler(void);
UART0_DriverIRQHandler(void)1837 void UART0_DriverIRQHandler(void)
1838 {
1839     s_uartIsr(UART0, s_uartHandle[0]);
1840     SDK_ISR_EXIT_BARRIER;
1841 }
1842 
1843 void UART0_RX_TX_DriverIRQHandler(void);
UART0_RX_TX_DriverIRQHandler(void)1844 void UART0_RX_TX_DriverIRQHandler(void)
1845 {
1846     UART0_DriverIRQHandler();
1847     SDK_ISR_EXIT_BARRIER;
1848 }
1849 #endif /* FSL_FEATURE_SOC_LPSCI_COUNT */
1850 #endif /* UART0 */
1851 
1852 #if defined(UART1)
1853 void UART1_DriverIRQHandler(void);
UART1_DriverIRQHandler(void)1854 void UART1_DriverIRQHandler(void)
1855 {
1856     s_uartIsr(UART1, s_uartHandle[1]);
1857     SDK_ISR_EXIT_BARRIER;
1858 }
1859 
1860 void UART1_RX_TX_DriverIRQHandler(void);
UART1_RX_TX_DriverIRQHandler(void)1861 void UART1_RX_TX_DriverIRQHandler(void)
1862 {
1863     UART1_DriverIRQHandler();
1864     SDK_ISR_EXIT_BARRIER;
1865 }
1866 #endif /* UART1 */
1867 #endif /* FSL_FEATURE_UART_HAS_SHARED_IRQ0_IRQ1 */
1868 
1869 #if defined(FSL_FEATURE_UART_HAS_SHARED_IRQ2_IRQ3) && FSL_FEATURE_UART_HAS_SHARED_IRQ2_IRQ3
1870 void UART2_UART3_DriverIRQHandler(void);
UART2_UART3_DriverIRQHandler(void)1871 void UART2_UART3_DriverIRQHandler(void)
1872 {
1873     for (uint32_t instance = 2U; instance < 4U; instance++)
1874     {
1875         if (s_uartHandle[instance] != NULL)
1876         {
1877             s_uartIsr(s_uartBases[instance], s_uartHandle[instance]);
1878         }
1879     }
1880 }
1881 #else /* FSL_FEATURE_UART_HAS_SHARED_IRQ2_IRQ3 */
1882 #if defined(UART2)
1883 void UART2_DriverIRQHandler(void);
UART2_DriverIRQHandler(void)1884 void UART2_DriverIRQHandler(void)
1885 {
1886     s_uartIsr(UART2, s_uartHandle[2]);
1887     SDK_ISR_EXIT_BARRIER;
1888 }
1889 
1890 void UART2_RX_TX_DriverIRQHandler(void);
UART2_RX_TX_DriverIRQHandler(void)1891 void UART2_RX_TX_DriverIRQHandler(void)
1892 {
1893     UART2_DriverIRQHandler();
1894     SDK_ISR_EXIT_BARRIER;
1895 }
1896 #endif /* UART2 */
1897 
1898 #if defined(UART3)
1899 void UART3_DriverIRQHandler(void);
UART3_DriverIRQHandler(void)1900 void UART3_DriverIRQHandler(void)
1901 {
1902     s_uartIsr(UART3, s_uartHandle[3]);
1903     SDK_ISR_EXIT_BARRIER;
1904 }
1905 
1906 void UART3_RX_TX_DriverIRQHandler(void);
UART3_RX_TX_DriverIRQHandler(void)1907 void UART3_RX_TX_DriverIRQHandler(void)
1908 {
1909     UART3_DriverIRQHandler();
1910     SDK_ISR_EXIT_BARRIER;
1911 }
1912 #endif /* UART3 */
1913 #endif /* FSL_FEATURE_UART_HAS_SHARED_IRQ2_IRQ3 */
1914 #endif /* FSL_FEATURE_UART_HAS_SHARED_IRQ0_IRQ1_IRQ2_IRQ3 */
1915 
1916 #if defined(UART4)
1917 void UART4_DriverIRQHandler(void);
UART4_DriverIRQHandler(void)1918 void UART4_DriverIRQHandler(void)
1919 {
1920     s_uartIsr(UART4, s_uartHandle[4]);
1921     SDK_ISR_EXIT_BARRIER;
1922 }
1923 
1924 void UART4_RX_TX_DriverIRQHandler(void);
UART4_RX_TX_DriverIRQHandler(void)1925 void UART4_RX_TX_DriverIRQHandler(void)
1926 {
1927     UART4_DriverIRQHandler();
1928     SDK_ISR_EXIT_BARRIER;
1929 }
1930 #endif
1931 
1932 #if defined(UART5)
1933 void UART5_DriverIRQHandler(void);
UART5_DriverIRQHandler(void)1934 void UART5_DriverIRQHandler(void)
1935 {
1936     s_uartIsr(UART5, s_uartHandle[5]);
1937     SDK_ISR_EXIT_BARRIER;
1938 }
1939 
1940 void UART5_RX_TX_DriverIRQHandler(void);
UART5_RX_TX_DriverIRQHandler(void)1941 void UART5_RX_TX_DriverIRQHandler(void)
1942 {
1943     UART5_DriverIRQHandler();
1944     SDK_ISR_EXIT_BARRIER;
1945 }
1946 #endif
1947