1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 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.iuart"
18 #endif
19 
20 /* UART transfer state. */
21 enum _uart_tansfer_states
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 peripheral base address. */
75 static UART_Type *const s_uartBases[] = UART_BASE_PTRS;
76 
77 /* Array of UART IRQ number. */
78 const IRQn_Type s_uartIRQ[] = UART_IRQS;
79 
80 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
81 /* Array of UART clock name. */
82 static const clock_ip_name_t s_uartClock[] = UART_CLOCKS;
83 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
84 
85 /* UART ISR for transactional APIs. */
86 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
87 uart_isr_t s_uartIsr = (uart_isr_t)DefaultISR;
88 #else
89 uart_isr_t s_uartIsr;
90 #endif
91 
92 void *s_uartHandle[ARRAY_SIZE(s_uartBases)];
93 
94 /*******************************************************************************
95  * Code
96  ******************************************************************************/
97 /*!
98  * brief Get the UART instance from peripheral base address.
99  *
100  * param base UART peripheral base address.
101  * return UART instance.
102  */
UART_GetInstance(UART_Type * base)103 uint32_t UART_GetInstance(UART_Type *base)
104 {
105     uint32_t instance;
106     uint32_t uartArrayCount = (sizeof(s_uartBases) / sizeof(s_uartBases[0]));
107 
108     /* Find the instance index from base address mappings. */
109     for (instance = 0; instance < uartArrayCount; instance++)
110     {
111         if (s_uartBases[instance] == base)
112         {
113             break;
114         }
115     }
116     assert(instance < uartArrayCount);
117 
118     return instance;
119 }
120 
121 /*!
122  * brief Get the length of received data in RX ring buffer.
123  *
124  * param handle UART handle pointer.
125  * return Length of received data in RX ring buffer.
126  */
UART_TransferGetRxRingBufferLength(uart_handle_t * handle)127 size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle)
128 {
129     assert(handle != NULL);
130 
131     size_t size;
132 
133     if (handle->rxRingBufferTail > handle->rxRingBufferHead)
134     {
135         size = (size_t)handle->rxRingBufferHead + handle->rxRingBufferSize - (size_t)handle->rxRingBufferTail;
136     }
137     else
138     {
139         size = (size_t)handle->rxRingBufferHead - (size_t)handle->rxRingBufferTail;
140     }
141 
142     return size;
143 }
144 
UART_TransferIsRxRingBufferFull(uart_handle_t * handle)145 static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle)
146 {
147     assert(handle != NULL);
148 
149     bool full;
150 
151     if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
152     {
153         full = true;
154     }
155     else
156     {
157         full = false;
158     }
159 
160     return full;
161 }
162 
163 /*!
164  * brief Initializes an UART instance with the user configuration structure and the peripheral clock.
165  *
166  * This function configures the UART module with user-defined settings. Call the UART_GetDefaultConfig() function
167  * to configure the configuration structure and get the default configuration.
168  * The example below shows how to use this API to configure the UART.
169  * code
170  *  uart_config_t uartConfig;
171  *  uartConfig.baudRate_Bps = 115200U;
172  *  uartConfig.parityMode = kUART_ParityDisabled;
173  *  uartConfig.dataBitsCount = kUART_EightDataBits;
174  *  uartConfig.stopBitCount = kUART_OneStopBit;
175  *  uartConfig.txFifoWatermark = 2;
176  *  uartConfig.rxFifoWatermark = 1;
177  *  uartConfig.rxRTSWatermark = 16;
178  *  uartConfig.enableAutoBaudrate = false;
179  *  uartConfig.enableTx = true;
180  *  uartConfig.enableRx = true;
181  *  uartConfig.enableRxRTS = false;
182  *  uartConfig.enableTxCTS = false;
183  *  UART_Init(UART1, &uartConfig, 24000000U);
184  * endcode
185  *
186  * param base UART peripheral base address.
187  * param config Pointer to a user-defined configuration structure.
188  * param srcClock_Hz UART clock source frequency in HZ.
189  * retval kStatus_Success UART initialize succeed
190  */
UART_Init(UART_Type * base,const uart_config_t * config,uint32_t srcClock_Hz)191 status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz)
192 {
193     /* Check argument */
194     assert(!((NULL == base) || (NULL == config) || (0U == srcClock_Hz)));
195 
196 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
197     /* Enable uart clock */
198     CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]);
199 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
200 
201     /* Disable UART Module. */
202     UART_Disable(base);
203     /* Reset the transmit and receive state machines, all FIFOs and register
204      * USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD and UTS[6-3]. */
205     UART_SoftwareReset(base);
206 
207     /* Set UART Module Register content to default value */
208     base->UCR1  = 0x0;
209     base->UCR2  = UART_UCR2_SRST_MASK;
210     base->UCR3  = UART_UCR3_DSR_MASK | UART_UCR3_DCD_MASK | UART_UCR3_RI_MASK;
211     base->UCR4  = UART_UCR4_CTSTL(32);
212     base->UFCR  = UART_UFCR_TXTL(2) | UART_UFCR_RXTL(1);
213     base->UESC  = UART_UESC_ESC_CHAR(0x2B);
214     base->UTIM  = 0x0;
215     base->ONEMS = 0x0;
216     base->UTS   = UART_UTS_TXEMPTY_MASK | UART_UTS_RXEMPTY_MASK;
217     base->UMCR  = 0x0;
218 
219     /* Set UART data word length, stop bit count, parity mode and communication
220      * direction according to uart init struct, disable RTS hardware flow control.
221      */
222     base->UCR2 |=
223         ((uint32_t)UART_UCR2_WS(config->dataBitsCount) | (uint32_t)UART_UCR2_STPB(config->stopBitCount) |
224          (((uint32_t)(config->parityMode) << UART_UCR2_PROE_SHIFT) & (UART_UCR2_PREN_MASK | UART_UCR2_PROE_MASK)) |
225          (uint32_t)UART_UCR2_TXEN(config->enableTx) | (uint32_t)UART_UCR2_RXEN(config->enableRx) |
226          (uint32_t)UART_UCR2_IRTS(!config->enableTxCTS) | (uint32_t)UART_UCR2_CTSC(config->enableRxRTS));
227 
228 #if (defined(FSL_FEATURE_IUART_RXDMUXSEL) && FSL_FEATURE_IUART_RXDMUXSEL)
229     /* For imx family device, UARTs are used in MUXED mode, so that this bit should always be set.*/
230     base->UCR3 |= UART_UCR3_RXDMUXSEL_MASK;
231 #endif /* FSL_FEATURE_IUART_RXDMUXSEL */
232 
233     /* Set TX/RX fifo water mark */
234     UART_SetTxFifoWatermark(base, config->txFifoWatermark);
235     UART_SetRxFifoWatermark(base, config->rxFifoWatermark);
236     UART_SetRxRTSWatermark(base, config->rxRTSWatermark);
237 
238     if (config->enableAutoBaudRate)
239     {
240         /* Start automatic baud rate detection */
241         UART_EnableAutoBaudRate(base, true);
242     }
243     else if (config->baudRate_Bps != 0U)
244     {
245         /* Stop automatic baud rate detection */
246         UART_EnableAutoBaudRate(base, false);
247         /* Set BaudRate according to uart initialize struct. Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)) */
248         if (kStatus_Success != UART_SetBaudRate(base, config->baudRate_Bps, srcClock_Hz))
249         {
250             return kStatus_UART_BaudrateNotSupport;
251         }
252     }
253     else
254     {
255         /* Stop automatic baud rate detection */
256         UART_EnableAutoBaudRate(base, false);
257     }
258 
259     /* Enable UART module */
260     UART_Enable(base);
261 
262     return kStatus_Success;
263 }
264 
265 /*!
266  * brief Deinitializes a UART instance.
267  *
268  * This function waits for transmit to complete, disables TX and RX, and disables the UART clock.
269  *
270  * param base UART peripheral base address.
271  */
UART_Deinit(UART_Type * base)272 void UART_Deinit(UART_Type *base)
273 {
274     /* Wait transmit FIFO buffer and shift register empty */
275     while (UART_USR2_TXDC_MASK != (base->USR2 & UART_USR2_TXDC_MASK))
276     {
277     }
278     /* Disable UART Module */
279     UART_Disable(base);
280 
281 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
282     /* Disable uart clock */
283     CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]);
284 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
285 }
286 
287 /*!l
288  * brief Gets the default configuration structure.
289  *
290  * This function initializes the UART configuration structure to a default value. The default
291  * values are:
292  *   uartConfig->baudRate_Bps = 115200U;
293  *   uartConfig->parityMode = kUART_ParityDisabled;
294  *   uartConfig->dataBitsCount = kUART_EightDataBits;
295  *   uartConfig->stopBitCount = kUART_OneStopBit;
296  *   uartConfig->txFifoWatermark = 2;
297  *   uartConfig->rxFifoWatermark = 1;
298  *   uartConfig->rxRTSWatermark = 16;
299  *   uartConfig->enableAutoBaudrate = flase;
300  *   uartConfig->enableTx = false;
301  *   uartConfig->enableRx = false;
302  *   uartConfig->enableRxRTS = false;
303  *   uartConfig->enableTxCTS = false;
304  *
305  * param config Pointer to a configuration structure.
306  */
UART_GetDefaultConfig(uart_config_t * config)307 void UART_GetDefaultConfig(uart_config_t *config)
308 {
309     assert(config != NULL);
310 
311     /* Initializes the configure structure to zero. */
312     (void)memset(config, 0, sizeof(*config));
313 
314     config->baudRate_Bps       = 115200U;
315     config->parityMode         = kUART_ParityDisabled;
316     config->dataBitsCount      = kUART_EightDataBits;
317     config->stopBitCount       = kUART_OneStopBit;
318     config->txFifoWatermark    = 2;
319     config->rxFifoWatermark    = 1;
320     config->rxRTSWatermark     = 16;
321     config->enableAutoBaudRate = false;
322     config->enableTx           = false;
323     config->enableRx           = false;
324     config->enableRxRTS        = false;
325     config->enableTxCTS        = false;
326 }
327 
328 /* This UART instantiation uses a slightly different baud rate calculation.
329  * Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)).
330  * To get a baud rate, three register need to be writen, UFCR,UBMR and UBIR
331  * At first, find the approximately maximum divisor of src_Clock and baudRate_Bps.
332  * If the numerator and denominator are larger then register maximum value(0xFFFF),
333  * both of numerator and denominator will be divided by the same value, which
334  * will ensure numerator and denominator range from 0~maximum value(0xFFFF).
335  * Then calculate UFCR and UBIR value from numerator, and get UBMR value from denominator.
336  */
337 /*!
338  * brief Sets the UART instance baud rate.
339  *
340  * This function configures the UART module baud rate. This function is used to update
341  * the UART module baud rate after the UART module is initialized by the UART_Init.
342  * code
343  *  UART_SetBaudRate(UART1, 115200U, 20000000U);
344  * endcode
345  *
346  * param base UART peripheral base address.
347  * param baudRate_Bps UART baudrate to be set.
348  * param srcClock_Hz UART clock source frequency in Hz.
349  * retval kStatus_UART_BaudrateNotSupport Baudrate is not support in the current clock source.
350  * retval kStatus_Success Set baudrate succeeded.
351  */
UART_SetBaudRate(UART_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)352 status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
353 {
354     uint32_t numerator       = 0u;
355     uint32_t denominator     = 0U;
356     uint32_t divisor         = 0U;
357     uint32_t refFreqDiv      = 0U;
358     uint32_t divider         = 1U;
359     uint64_t baudDiff        = 0U;
360     uint64_t tempNumerator   = 0U;
361     uint32_t tempDenominator = 0u;
362 
363     /* get the approximately maximum divisor */
364     numerator   = srcClock_Hz;
365     denominator = baudRate_Bps << 4U;
366     divisor     = 1U;
367 
368     while (denominator != 0U)
369     {
370         divisor     = denominator;
371         denominator = numerator % denominator;
372         numerator   = divisor;
373     }
374 
375     numerator   = srcClock_Hz / divisor;
376     denominator = (baudRate_Bps << 4U) / divisor;
377 
378     /* numerator ranges from 1 ~ 7 * 64k */
379     /* denominator ranges from 1 ~ 64k */
380     if ((numerator > (UART_UBIR_INC_MASK * 7U)) || (denominator > UART_UBIR_INC_MASK))
381     {
382         uint32_t m   = (numerator - 1U) / (UART_UBIR_INC_MASK * 7U) + 1U;
383         uint32_t n   = (denominator - 1U) / UART_UBIR_INC_MASK + 1U;
384         uint32_t max = m > n ? m : n;
385         numerator /= max;
386         denominator /= max;
387         if (0U == numerator)
388         {
389             numerator = 1U;
390         }
391         if (0U == denominator)
392         {
393             denominator = 1U;
394         }
395     }
396     divider = (numerator - 1U) / UART_UBIR_INC_MASK + 1U;
397 
398     switch (divider)
399     {
400         case 1:
401             refFreqDiv = 0x05U;
402             break;
403         case 2:
404             refFreqDiv = 0x04U;
405             break;
406         case 3:
407             refFreqDiv = 0x03U;
408             break;
409         case 4:
410             refFreqDiv = 0x02U;
411             break;
412         case 5:
413             refFreqDiv = 0x01U;
414             break;
415         case 6:
416             refFreqDiv = 0x00U;
417             break;
418         case 7:
419             refFreqDiv = 0x06U;
420             break;
421         default:
422             refFreqDiv = 0x05U;
423             break;
424     }
425     /* Compare the difference between baudRate_Bps and calculated baud rate.
426      * Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)).
427      * baudDiff = (srcClock_Hz/divider)/( 16 * ((numerator / divider)/ denominator).
428      */
429     tempNumerator   = (uint64_t)srcClock_Hz;
430     tempDenominator = (numerator << 4U);
431     divisor         = 1U;
432     /* get the approximately maximum divisor */
433     while (tempDenominator != 0U)
434     {
435         divisor         = tempDenominator;
436         tempDenominator = (uint32_t)(tempNumerator % tempDenominator);
437         tempNumerator   = (uint64_t)divisor;
438     }
439     tempNumerator   = (uint64_t)srcClock_Hz / (uint64_t)divisor;
440     tempDenominator = (numerator << 4U) / divisor;
441     baudDiff        = (tempNumerator * (uint64_t)denominator) / (uint64_t)tempDenominator;
442     baudDiff        = (baudDiff >= (uint64_t)baudRate_Bps) ? (baudDiff - (uint64_t)baudRate_Bps) :
443                                                       ((uint64_t)baudRate_Bps - baudDiff);
444 
445     if (baudDiff < ((uint64_t)baudRate_Bps / 100UL * 3UL))
446     {
447         base->UFCR &= ~UART_UFCR_RFDIV_MASK;
448         base->UFCR |= UART_UFCR_RFDIV(refFreqDiv);
449         base->UBIR  = UART_UBIR_INC(denominator - 1U);
450         base->UBMR  = UART_UBMR_MOD(numerator / divider - 1U);
451         base->ONEMS = UART_ONEMS_ONEMS(srcClock_Hz / (1000U * divider));
452 
453         return kStatus_Success;
454     }
455     else
456     {
457         return kStatus_UART_BaudrateNotSupport;
458     }
459 }
460 
461 /*!
462  * brief Enables UART interrupts according to the provided mask.
463  *
464  * This function enables the UART interrupts according to the provided mask. The mask
465  * is a logical OR of enumeration members. See ref _uart_interrupt_enable.
466  * For example, to enable TX empty interrupt and RX data ready interrupt, do the following.
467  * code
468  *     UART_EnableInterrupts(UART1,kUART_TxEmptyEnable | kUART_RxDataReadyEnable);
469  * endcode
470  *
471  * param base UART peripheral base address.
472  * param mask The interrupts to enable. Logical OR of ref _uart_interrupt_enable.
473  */
UART_EnableInterrupts(UART_Type * base,uint32_t mask)474 void UART_EnableInterrupts(UART_Type *base, uint32_t mask)
475 {
476     assert((0x7F3FF73FU & mask) != 0U);
477 
478     if ((0X3FU & mask) != 0U)
479     {
480         base->UCR1 |= ((mask << UART_UCR1_ADEN_SHIFT) & UART_UCR1_ADEN_MASK) |
481                       (((mask >> 1) << UART_UCR1_TRDYEN_SHIFT) & UART_UCR1_TRDYEN_MASK) |
482                       (((mask >> 2) << UART_UCR1_IDEN_SHIFT) & UART_UCR1_IDEN_MASK) |
483                       (((mask >> 3) << UART_UCR1_RRDYEN_SHIFT) & UART_UCR1_RRDYEN_MASK) |
484                       (((mask >> 4) << UART_UCR1_TXMPTYEN_SHIFT) & UART_UCR1_TXMPTYEN_MASK) |
485                       (((mask >> 5) << UART_UCR1_RTSDEN_SHIFT) & UART_UCR1_RTSDEN_MASK);
486     }
487     if ((0X700U & mask) != 0U)
488     {
489         base->UCR2 |= (((mask >> 8) << UART_UCR2_ESCI_SHIFT) & UART_UCR2_ESCI_MASK) |
490                       (((mask >> 9) << UART_UCR2_RTSEN_SHIFT) & UART_UCR2_RTSEN_MASK) |
491                       (((mask >> 10) << UART_UCR2_ATEN_SHIFT) & UART_UCR2_ATEN_MASK);
492     }
493     if ((0x3FF000U & mask) != 0U)
494     {
495         base->UCR3 |= (((mask >> 12) << UART_UCR3_DTREN_SHIFT) & UART_UCR3_DTREN_MASK) |
496                       (((mask >> 13) << UART_UCR3_PARERREN_SHIFT) & UART_UCR3_PARERREN_MASK) |
497                       (((mask >> 14) << UART_UCR3_FRAERREN_SHIFT) & UART_UCR3_FRAERREN_MASK) |
498                       (((mask >> 15) << UART_UCR3_DCD_SHIFT) & UART_UCR3_DCD_MASK) |
499                       (((mask >> 16) << UART_UCR3_RI_SHIFT) & UART_UCR3_RI_MASK) |
500                       (((mask >> 17) << UART_UCR3_RXDSEN_SHIFT) & UART_UCR3_RXDSEN_MASK) |
501                       (((mask >> 18) << UART_UCR3_AIRINTEN_SHIFT) & UART_UCR3_AIRINTEN_MASK) |
502                       (((mask >> 19) << UART_UCR3_AWAKEN_SHIFT) & UART_UCR3_AWAKEN_MASK) |
503                       (((mask >> 20) << UART_UCR3_DTRDEN_SHIFT) & UART_UCR3_DTRDEN_MASK) |
504                       (((mask >> 21) << UART_UCR3_ACIEN_SHIFT) & UART_UCR3_ACIEN_MASK);
505     }
506     if ((0x7F000000U & mask) != 0U)
507     {
508         base->UCR4 |= (((mask >> 24) << UART_UCR4_ENIRI_SHIFT) & UART_UCR4_ENIRI_MASK) |
509                       (((mask >> 25) << UART_UCR4_WKEN_SHIFT) & UART_UCR4_WKEN_MASK) |
510                       (((mask >> 26) << UART_UCR4_TCEN_SHIFT) & UART_UCR4_TCEN_MASK) |
511                       (((mask >> 27) << UART_UCR4_BKEN_SHIFT) & UART_UCR4_BKEN_MASK) |
512                       (((mask >> 28) << UART_UCR4_OREN_SHIFT) & UART_UCR4_OREN_MASK) |
513                       (((mask >> 29) << UART_UCR4_DREN_SHIFT) & UART_UCR4_DREN_MASK) |
514                       (((mask >> 30) << UART_UCR4_IDDMAEN_SHIFT) & UART_UCR4_IDDMAEN_MASK);
515     }
516 }
517 
518 /*!
519  * brief Disables the UART interrupts according to the provided mask.
520  *
521  * This function disables the UART interrupts according to the provided mask. The mask
522  * is a logical OR of enumeration members. See ref _uart_interrupt_enable.
523  * For example, to disable TX empty interrupt and RX data ready interrupt do the following.
524  * code
525  *     UART_EnableInterrupts(UART1,kUART_TxEmptyEnable | kUART_RxDataReadyEnable);
526  * endcode
527  *
528  * param base UART peripheral base address.
529  * param mask The interrupts to disable. Logical OR of ref _uart_interrupt_enable.
530  */
UART_DisableInterrupts(UART_Type * base,uint32_t mask)531 void UART_DisableInterrupts(UART_Type *base, uint32_t mask)
532 {
533     assert((0x7F3FF73FU & mask) != 0U);
534 
535     if ((0X3FU & mask) != 0U)
536     {
537         base->UCR1 &= ~(((mask << UART_UCR1_ADEN_SHIFT) & UART_UCR1_ADEN_MASK) |
538                         (((mask >> 1) << UART_UCR1_TRDYEN_SHIFT) & UART_UCR1_TRDYEN_MASK) |
539                         (((mask >> 2) << UART_UCR1_IDEN_SHIFT) & UART_UCR1_IDEN_MASK) |
540                         (((mask >> 3) << UART_UCR1_RRDYEN_SHIFT) & UART_UCR1_RRDYEN_MASK) |
541                         (((mask >> 4) << UART_UCR1_TXMPTYEN_SHIFT) & UART_UCR1_TXMPTYEN_MASK) |
542                         (((mask >> 5) << UART_UCR1_RTSDEN_SHIFT) & UART_UCR1_RTSDEN_MASK));
543     }
544     if ((0X700U & mask) != 0U)
545     {
546         base->UCR2 &= ~((((mask >> 8) << UART_UCR2_ESCI_SHIFT) & UART_UCR2_ESCI_MASK) |
547                         (((mask >> 9) << UART_UCR2_RTSEN_SHIFT) & UART_UCR2_RTSEN_MASK) |
548                         (((mask >> 10) << UART_UCR2_ATEN_SHIFT) & UART_UCR2_ATEN_MASK));
549     }
550     if ((0x3FF000U & mask) != 0U)
551     {
552         base->UCR3 &= ~((((mask >> 12) << UART_UCR3_DTREN_SHIFT) & UART_UCR3_DTREN_MASK) |
553                         (((mask >> 13) << UART_UCR3_PARERREN_SHIFT) & UART_UCR3_PARERREN_MASK) |
554                         (((mask >> 14) << UART_UCR3_FRAERREN_SHIFT) & UART_UCR3_FRAERREN_MASK) |
555                         (((mask >> 15) << UART_UCR3_DCD_SHIFT) & UART_UCR3_DCD_MASK) |
556                         (((mask >> 16) << UART_UCR3_RI_SHIFT) & UART_UCR3_RI_MASK) |
557                         (((mask >> 17) << UART_UCR3_RXDSEN_SHIFT) & UART_UCR3_RXDSEN_MASK) |
558                         (((mask >> 18) << UART_UCR3_AIRINTEN_SHIFT) & UART_UCR3_AIRINTEN_MASK) |
559                         (((mask >> 19) << UART_UCR3_AWAKEN_SHIFT) & UART_UCR3_AWAKEN_MASK) |
560                         (((mask >> 20) << UART_UCR3_DTRDEN_SHIFT) & UART_UCR3_DTRDEN_MASK) |
561                         (((mask >> 21) << UART_UCR3_ACIEN_SHIFT) & UART_UCR3_ACIEN_MASK));
562     }
563     if ((0x7F000000U & mask) != 0U)
564     {
565         base->UCR4 &= ~((((mask >> 24) << UART_UCR4_ENIRI_SHIFT) & UART_UCR4_ENIRI_MASK) |
566                         (((mask >> 25) << UART_UCR4_WKEN_SHIFT) & UART_UCR4_WKEN_MASK) |
567                         (((mask >> 26) << UART_UCR4_TCEN_SHIFT) & UART_UCR4_TCEN_MASK) |
568                         (((mask >> 27) << UART_UCR4_BKEN_SHIFT) & UART_UCR4_BKEN_MASK) |
569                         (((mask >> 28) << UART_UCR4_OREN_SHIFT) & UART_UCR4_OREN_MASK) |
570                         (((mask >> 29) << UART_UCR4_DREN_SHIFT) & UART_UCR4_DREN_MASK) |
571                         (((mask >> 30) << UART_UCR4_IDDMAEN_SHIFT) & UART_UCR4_IDDMAEN_MASK));
572     }
573 }
574 
575 /*!
576  * brief Gets enabled UART interrupts.
577  *
578  * This function gets the enabled UART interrupts. The enabled interrupts are returned
579  * as the logical OR value of the enumerators ref _uart_interrupt_enable. To check
580  * a specific interrupt enable status, compare the return value with enumerators
581  * in ref _uart_interrupt_enable.
582  * For example, to check whether the TX empty interrupt is enabled:
583  * code
584  *     uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1);
585  *
586  *     if (kUART_TxEmptyEnable & enabledInterrupts)
587  *     {
588  *         ...
589  *     }
590  * endcode
591  *
592  * param base UART peripheral base address.
593  * return UART interrupt flags which are logical OR of the enumerators in ref _uart_interrupt_enable.
594  */
UART_GetEnabledInterrupts(UART_Type * base)595 uint32_t UART_GetEnabledInterrupts(UART_Type *base)
596 {
597     assert(base != NULL);
598     uint32_t temp = 0U;
599     /* Get enabled interrupts from UCR1 */
600     temp |= ((base->UCR1 & UART_UCR1_ADEN_MASK) >> UART_UCR1_ADEN_SHIFT) |
601             (((base->UCR1 & UART_UCR1_TRDYEN_MASK) >> UART_UCR1_TRDYEN_SHIFT) << 1) |
602             (((base->UCR1 & UART_UCR1_IDEN_MASK) >> UART_UCR1_IDEN_SHIFT) << 2) |
603             (((base->UCR1 & UART_UCR1_RRDYEN_MASK) >> UART_UCR1_RRDYEN_SHIFT) << 3) |
604             (((base->UCR1 & UART_UCR1_TXMPTYEN_MASK) >> UART_UCR1_TXMPTYEN_SHIFT) << 4) |
605             (((base->UCR1 & UART_UCR1_RTSDEN_MASK) >> UART_UCR1_RTSDEN_SHIFT) << 5);
606     /* Get enabled interrupts from UCR2 */
607     temp |= (((base->UCR2 & UART_UCR2_ESCI_MASK) >> UART_UCR2_ESCI_SHIFT) << 8) |
608             (((base->UCR2 & UART_UCR2_RTSEN_MASK) >> UART_UCR2_RTSEN_SHIFT) << 9) |
609             (((base->UCR2 & UART_UCR2_ATEN_MASK) >> UART_UCR2_ATEN_SHIFT) << 10);
610     /* Get enabled interrupts from UCR3 */
611     temp |= (((base->UCR3 & UART_UCR3_DTREN_MASK) >> UART_UCR3_DTREN_SHIFT) << 12) |
612             (((base->UCR3 & UART_UCR3_PARERREN_MASK) >> UART_UCR3_PARERREN_SHIFT) << 13) |
613             (((base->UCR3 & UART_UCR3_FRAERREN_MASK) >> UART_UCR3_FRAERREN_SHIFT) << 14) |
614             (((base->UCR3 & UART_UCR3_DCD_MASK) >> UART_UCR3_DCD_SHIFT) << 15) |
615             (((base->UCR3 & UART_UCR3_RI_MASK) >> UART_UCR3_RI_SHIFT) << 16) |
616             (((base->UCR3 & UART_UCR3_RXDSEN_MASK) >> UART_UCR3_RXDSEN_SHIFT) << 17) |
617             (((base->UCR3 & UART_UCR3_AIRINTEN_MASK) >> UART_UCR3_AIRINTEN_SHIFT) << 18) |
618             (((base->UCR3 & UART_UCR3_AWAKEN_MASK) >> UART_UCR3_AWAKEN_SHIFT) << 19) |
619             (((base->UCR3 & UART_UCR3_DTRDEN_MASK) >> UART_UCR3_DTRDEN_SHIFT) << 20) |
620             (((base->UCR3 & UART_UCR3_ACIEN_MASK) >> UART_UCR3_ACIEN_SHIFT) << 21);
621     /* Get enabled interrupts from UCR4 */
622     temp |= (((base->UCR4 & UART_UCR4_ENIRI_MASK) >> UART_UCR4_ENIRI_SHIFT) << 24) |
623             (((base->UCR4 & UART_UCR4_WKEN_MASK) >> UART_UCR4_WKEN_SHIFT) << 25) |
624             (((base->UCR4 & UART_UCR4_TCEN_MASK) >> UART_UCR4_TCEN_SHIFT) << 26) |
625             (((base->UCR4 & UART_UCR4_BKEN_MASK) >> UART_UCR4_BKEN_SHIFT) << 27) |
626             (((base->UCR4 & UART_UCR4_OREN_MASK) >> UART_UCR4_OREN_SHIFT) << 28) |
627             (((base->UCR4 & UART_UCR4_DREN_MASK) >> UART_UCR4_DREN_SHIFT) << 29) |
628             (((base->UCR4 & UART_UCR4_IDDMAEN_MASK) >> UART_UCR4_IDDMAEN_SHIFT) << 30);
629 
630     return temp;
631 }
632 
633 /*!
634  * brief This function is used to get the current status of specific
635  *        UART status flag(including interrupt flag). The available
636  *        status flag can be select from ref uart_status_flag_t enumeration.
637  *
638  * param base UART base pointer.
639  * param flag Status flag to check.
640  * retval current state of corresponding status flag.
641  */
UART_GetStatusFlag(UART_Type * base,uint32_t flag)642 bool UART_GetStatusFlag(UART_Type *base, uint32_t flag)
643 {
644     volatile uint32_t *uart_reg;
645 
646     uart_reg = (uint32_t *)((uintptr_t)base + (flag >> 16));
647     return (bool)(((*uart_reg) >> (flag & 0x1FU)) & 0x1U);
648 }
649 
650 /*!
651  * brief This function is used to clear the current status
652  *        of specific UART status flag. The available status
653  *        flag can be select from ref uart_status_flag_t enumeration.
654  *
655  * param base UART base pointer.
656  * param flag Status flag to clear.
657  */
UART_ClearStatusFlag(UART_Type * base,uint32_t flag)658 void UART_ClearStatusFlag(UART_Type *base, uint32_t flag)
659 {
660     volatile uint32_t *uart_reg = NULL;
661     uint32_t uart_mask          = 0;
662 
663     uart_reg  = (uint32_t *)((uintptr_t)base + (flag >> 16));
664     uart_mask = (1UL << (flag & 0x0000001FU));
665 
666     *uart_reg = uart_mask;
667 }
668 
669 /*!
670  * brief Writes to the TX register using a blocking method.
671  *
672  * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
673  * to have room and writes data to the TX buffer.
674  *
675  * param base UART peripheral base address.
676  * param data Start address of the data to write.
677  * param length Size of the data to write.
678  * retval kStatus_UART_Timeout Transmission timed out and was aborted.
679  * retval kStatus_Success Successfully wrote all data.
680  */
UART_WriteBlocking(UART_Type * base,const uint8_t * data,size_t length)681 status_t UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length)
682 {
683     assert(data != NULL);
684 #if UART_RETRY_TIMES
685     uint32_t waitTimes;
686 #endif
687 
688     while (length-- != 0U)
689     {
690         /* Wait for TX fifo valid. */
691 #if UART_RETRY_TIMES
692         waitTimes = UART_RETRY_TIMES;
693         while ((0U == (base->USR1 & UART_USR1_TRDY_MASK)) && (0U != --waitTimes))
694 #else
695         while (0U == (base->USR1 & UART_USR1_TRDY_MASK))
696 #endif
697         {
698         }
699 #if UART_RETRY_TIMES
700         if (0U == waitTimes)
701         {
702             return kStatus_UART_Timeout;
703         }
704 #endif
705         UART_WriteByte(base, *(data++));
706     }
707 #if UART_RETRY_TIMES
708     waitTimes = UART_RETRY_TIMES;
709     while ((0U == (base->USR2 & UART_USR2_TXDC_MASK)) && (0U != --waitTimes))
710 #else
711     while (0U == (base->USR2 & UART_USR2_TXDC_MASK))
712 #endif
713     {
714     }
715 #if UART_RETRY_TIMES
716     if (0U == waitTimes)
717     {
718         return kStatus_UART_Timeout;
719     }
720 #endif
721     return kStatus_Success;
722 }
723 
724 /*!
725  * brief Read RX data register using a blocking method.
726  *
727  * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
728  * have data, and reads data from the TX register.
729  *
730  * param base UART peripheral base address.
731  * param data Start address of the buffer to store the received data.
732  * param length Size of the buffer.
733  * retval kStatus_UART_RxHardwareOverrun Receiver overrun occurred while receiving data.
734  * retval kStatus_UART_NoiseError A noise error occurred while receiving data.
735  * retval kStatus_UART_FramingError A framing error occurred while receiving data.
736  * retval kStatus_UART_ParityError A parity error occurred while receiving data.
737  * retval kStatus_UART_Timeout Transmission timed out and was aborted.
738  * retval kStatus_Success Successfully received all data.
739  */
UART_ReadBlocking(UART_Type * base,uint8_t * data,size_t length)740 status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length)
741 {
742     assert(data != NULL);
743     status_t status = kStatus_Success;
744 #if UART_RETRY_TIMES
745     uint32_t waitTimes;
746 #endif
747 
748     while (length-- != 0U)
749     {
750 #if UART_RETRY_TIMES
751         waitTimes = UART_RETRY_TIMES;
752 #endif
753         /* Wait for receive data in URXD register is ready */
754         while ((base->USR2 & UART_USR2_RDR_MASK) == 0U)
755         {
756 #if UART_RETRY_TIMES
757             if (--waitTimes == 0U)
758             {
759                 status = kStatus_UART_Timeout;
760                 break;
761             }
762 #endif
763             /* Over run check for receiving character */
764             if ((base->USR2 & UART_USR2_ORE_MASK) != 0U)
765             {
766                 UART_ClearStatusFlag(base, (uint32_t)kUART_RxOverrunFlag);
767                 status = kStatus_UART_RxHardwareOverrun;
768                 break;
769             }
770             /* Parity error check for receiving character */
771             if ((base->USR1 & UART_USR1_PARITYERR_MASK) != 0U)
772             {
773                 UART_ClearStatusFlag(base, (uint32_t)kUART_ParityErrorFlag);
774                 status = kStatus_UART_ParityError;
775             }
776             /* Framing error check for receiving character */
777             if ((base->USR1 & UART_USR1_FRAMERR_MASK) != 0U)
778             {
779                 UART_ClearStatusFlag(base, (uint32_t)kUART_FrameErrorFlag);
780                 status = kStatus_UART_FramingError;
781             }
782             if (status != kStatus_Success)
783             {
784                 break;
785             }
786         }
787         if (kStatus_Success == status)
788         {
789             /* Read data from URXD */
790             *(data++) = UART_ReadByte(base);
791         }
792         else
793         {
794             break;
795         }
796     }
797 
798     return status;
799 }
800 
UART_WriteNonBlocking(UART_Type * base,const uint8_t * data,size_t length)801 static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length)
802 {
803     assert(data != NULL);
804 
805     size_t i;
806 
807     /* The Non Blocking write data API assume user have ensured there is enough space in
808      * peripheral to write. UTXD register holds the parallel transmit data inputs. In 7-bit mode,
809      * D7 is ignored. In 8-bit mode, all bits are used.
810      */
811     for (i = 0; i < length; i++)
812     {
813         base->UTXD = (uint32_t)data[i] & UART_UTXD_TX_DATA_MASK;
814     }
815 }
816 
UART_ReadNonBlocking(UART_Type * base,uint8_t * data,size_t length)817 static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length)
818 {
819     assert(data != NULL);
820 
821     size_t i;
822 
823     /* The Non Blocking read data API assume user have ensured there is enough space in
824      * peripheral to write. The URXD holds the received character,In 7-bit mode,
825      * the most significant bit (MSB) is forced to 0.In 8-bit mode, all bits are active.
826      */
827     for (i = 0; i < length; i++)
828     {
829         data[i] = (uint8_t)((base->URXD & UART_URXD_RX_DATA_MASK) >> UART_URXD_RX_DATA_SHIFT);
830     }
831 }
832 
833 /*!
834  * brief Initializes the UART handle.
835  *
836  * This function initializes the UART handle which can be used for other UART
837  * transactional APIs. Usually, for a specified UART instance,
838  * call this API once to get the initialized handle.
839  *
840  * param base UART peripheral base address.
841  * param handle UART handle pointer.
842  * param callback The callback function.
843  * param userData The parameter of the callback function.
844  */
UART_TransferCreateHandle(UART_Type * base,uart_handle_t * handle,uart_transfer_callback_t callback,void * userData)845 void UART_TransferCreateHandle(UART_Type *base,
846                                uart_handle_t *handle,
847                                uart_transfer_callback_t callback,
848                                void *userData)
849 {
850     assert(handle != NULL);
851 
852     uint32_t instance;
853 
854     /* Zero the handle. */
855     (void)memset(handle, 0, sizeof(*handle));
856 
857     /* Set the TX/RX state. */
858     handle->rxState = (uint8_t)kUART_RxIdle;
859     handle->txState = (uint8_t)kUART_TxIdle;
860 
861     /* Set the callback and user data. */
862     handle->callback = callback;
863     handle->userData = userData;
864 
865     /* Get instance from peripheral base address. */
866     instance = UART_GetInstance(base);
867 
868     /* Save the handle in global variables to support the double weak mechanism. */
869     s_uartHandle[instance] = handle;
870 
871     s_uartIsr = UART_TransferHandleIRQ;
872 
873     /* Enable interrupt in NVIC. */
874     (void)EnableIRQ(s_uartIRQ[instance]);
875 }
876 
877 /*!
878  * brief Sets up the RX ring buffer.
879  *
880  * This function sets up the RX ring buffer to a specific UART handle.
881  *
882  * When the RX ring buffer is used, data received are stored into the ring buffer even when the
883  * user doesn't call the UART_TransferReceiveNonBlocking() API. If data is already received
884  * in the ring buffer, the user can get the received data from the ring buffer directly.
885  *
886  * note When using the RX ring buffer, one byte is reserved for internal use. In other
887  * words, if p ringBufferSize is 32, only 31 bytes are used for saving data.
888  *
889  * param base UART peripheral base address.
890  * param handle UART handle pointer.
891  * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
892  * param ringBufferSize Size of the ring buffer.
893  */
UART_TransferStartRingBuffer(UART_Type * base,uart_handle_t * handle,uint8_t * ringBuffer,size_t ringBufferSize)894 void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize)
895 {
896     assert(handle != NULL);
897     assert(ringBuffer != NULL);
898 
899     /* Setup the ringbuffer address */
900     handle->rxRingBuffer     = ringBuffer;
901     handle->rxRingBufferSize = ringBufferSize;
902     handle->rxRingBufferHead = 0U;
903     handle->rxRingBufferTail = 0U;
904 
905     /* Enable the interrupt to accept the data when user need the ring buffer. */
906     UART_EnableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable |
907                                     (uint32_t)kUART_RxOverrunEnable | (uint32_t)kUART_ParityErrorEnable |
908                                     (uint32_t)kUART_FrameErrorEnable);
909 }
910 
911 /*!
912  * brief Aborts the background transfer and uninstalls the ring buffer.
913  *
914  * This function aborts the background transfer and uninstalls the ring buffer.
915  *
916  * param base UART peripheral base address.
917  * param handle UART handle pointer.
918  */
UART_TransferStopRingBuffer(UART_Type * base,uart_handle_t * handle)919 void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle)
920 {
921     assert(handle != NULL);
922 
923     if (handle->rxState == (uint8_t)kUART_RxIdle)
924     {
925         UART_DisableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable |
926                                          (uint32_t)kUART_RxOverrunEnable | (uint32_t)kUART_ParityErrorEnable |
927                                          (uint32_t)kUART_FrameErrorEnable);
928     }
929 
930     handle->rxRingBuffer     = NULL;
931     handle->rxRingBufferSize = 0U;
932     handle->rxRingBufferHead = 0U;
933     handle->rxRingBufferTail = 0U;
934 }
935 
936 /*!
937  * brief Transmits a buffer of data using the interrupt method.
938  *
939  * This function sends data using an interrupt method. This is a non-blocking function, which
940  * returns directly without waiting for all data to be written to the TX register. When
941  * all data is written to the TX register in the ISR, the UART driver calls the callback
942  * function and passes the ref kStatus_UART_TxIdle as status parameter.
943  *
944  * note The kStatus_UART_TxIdle is passed to the upper layer when all data is written
945  * to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX,
946  * check the kUART_TransmissionCompleteFlag to ensure that the TX is finished.
947  *
948  * param base UART peripheral base address.
949  * param handle UART handle pointer.
950  * param xfer UART transfer structure. See  #uart_transfer_t.
951  * retval kStatus_Success Successfully start the data transmission.
952  * retval kStatus_UART_TxBusy Previous transmission still not finished; data not all written to TX register yet.
953  * retval kStatus_InvalidArgument Invalid argument.
954  */
UART_TransferSendNonBlocking(UART_Type * base,uart_handle_t * handle,uart_transfer_t * xfer)955 status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer)
956 {
957     assert(handle != NULL);
958     assert(xfer != NULL);
959     assert(xfer->dataSize != 0U);
960     assert(xfer->txData != NULL);
961 
962     status_t status;
963 
964     /* Return error if current TX busy. */
965     if ((uint8_t)kUART_TxBusy == handle->txState)
966     {
967         status = kStatus_UART_TxBusy;
968     }
969     else
970     {
971         handle->txData        = xfer->txData;
972         handle->txDataSize    = xfer->dataSize;
973         handle->txDataSizeAll = xfer->dataSize;
974         handle->txState       = (uint8_t)kUART_TxBusy;
975 
976         /* Enable transmiter interrupt. */
977         UART_EnableInterrupts(base, (uint32_t)kUART_TxReadyEnable);
978         status = kStatus_Success;
979     }
980 
981     return status;
982 }
983 
984 /*!
985  * brief Aborts the interrupt-driven data transmit.
986  *
987  * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
988  * how many bytes are not sent out.
989  *
990  * param base UART peripheral base address.
991  * param handle UART handle pointer.
992  */
UART_TransferAbortSend(UART_Type * base,uart_handle_t * handle)993 void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle)
994 {
995     assert(handle != NULL);
996 
997     UART_DisableInterrupts(base, (uint32_t)kUART_TxEmptyEnable);
998 
999     handle->txDataSize = 0;
1000     handle->txState    = (uint8_t)kUART_TxIdle;
1001 }
1002 
1003 /*!
1004  * brief Gets the number of bytes written to the UART TX register.
1005  *
1006  * This function gets the number of bytes written to the UART TX
1007  * register by using the interrupt method.
1008  *
1009  * param base UART peripheral base address.
1010  * param handle UART handle pointer.
1011  * param count Send bytes count.
1012  * retval kStatus_NoTransferInProgress No send in progress.
1013  * retval kStatus_InvalidArgument The parameter is invalid.
1014  * retval kStatus_Success Get successfully through the parameter \p count;
1015  */
UART_TransferGetSendCount(UART_Type * base,uart_handle_t * handle,uint32_t * count)1016 status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count)
1017 {
1018     assert(handle != NULL);
1019     assert(count != NULL);
1020 
1021     if ((uint8_t)kUART_TxIdle == handle->txState)
1022     {
1023         return kStatus_NoTransferInProgress;
1024     }
1025 
1026     *count = handle->txDataSizeAll - handle->txDataSize;
1027 
1028     return kStatus_Success;
1029 }
1030 
1031 /*!
1032  * brief Receives a buffer of data using an interrupt method.
1033  *
1034  * This function receives data using an interrupt method. This is a non-blocking function, which
1035  *  returns without waiting for all data to be received.
1036  * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
1037  * the parameter p receivedBytes shows how many bytes are copied from the ring buffer.
1038  * After copying, if the data in the ring buffer is not enough to read, the receive
1039  * request is saved by the UART driver. When the new data arrives, the receive request
1040  * is serviced first. When all data is received, the UART driver notifies the upper layer
1041  * through a callback function and passes the status parameter ref kStatus_UART_RxIdle.
1042  * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
1043  * The 5 bytes are copied to the xfer->data and this function returns with the
1044  * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
1045  * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies the upper layer.
1046  * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
1047  * to receive data to the xfer->data. When all data is received, the upper layer is notified.
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  * param receivedBytes Bytes received from the ring buffer directly.
1053  * retval kStatus_Success Successfully queue the transfer into transmit queue.
1054  * retval kStatus_UART_RxBusy Previous receive request is not finished.
1055  * retval kStatus_InvalidArgument Invalid argument.
1056  */
UART_TransferReceiveNonBlocking(UART_Type * base,uart_handle_t * handle,uart_transfer_t * xfer,size_t * receivedBytes)1057 status_t UART_TransferReceiveNonBlocking(UART_Type *base,
1058                                          uart_handle_t *handle,
1059                                          uart_transfer_t *xfer,
1060                                          size_t *receivedBytes)
1061 {
1062     assert(handle != NULL);
1063     assert(xfer != NULL);
1064     assert(xfer->rxData != NULL);
1065     assert(xfer->dataSize != 0U);
1066 
1067     uint32_t i;
1068     status_t status;
1069     /* How many bytes to copy from ring buffer to user memory. */
1070     size_t bytesToCopy = 0U;
1071     /* How many bytes to receive. */
1072     size_t bytesToReceive;
1073     /* How many bytes currently have received. */
1074     size_t bytesCurrentReceived;
1075 
1076     /* How to get data:
1077        1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
1078           to uart handle, enable interrupt to store received data to xfer->data. When
1079           all data received, trigger callback.
1080        2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
1081           If there are enough data in ring buffer, copy them to xfer->data and return.
1082           If there are not enough data in ring buffer, copy all of them to xfer->data,
1083           save the xfer->data remained empty space to uart handle, receive data
1084           to this empty space and trigger callback when finished. */
1085 
1086     if ((uint8_t)kUART_RxBusy == handle->rxState)
1087     {
1088         status = kStatus_UART_RxBusy;
1089     }
1090     else
1091     {
1092         bytesToReceive       = xfer->dataSize;
1093         bytesCurrentReceived = 0U;
1094 
1095         /* If RX ring buffer is used. */
1096         if (handle->rxRingBuffer != NULL)
1097         {
1098             /* Disable UART RX IRQ, protect ring buffer. */
1099             UART_DisableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable);
1100 
1101             /* How many bytes in RX ring buffer currently. */
1102             bytesToCopy = UART_TransferGetRxRingBufferLength(handle);
1103 
1104             if (bytesToCopy != 0U)
1105             {
1106                 bytesToCopy = MIN(bytesToReceive, bytesToCopy);
1107 
1108                 bytesToReceive -= bytesToCopy;
1109 
1110                 /* Copy data from ring buffer to user memory. */
1111                 for (i = 0U; i < bytesToCopy; i++)
1112                 {
1113                     xfer->rxData[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
1114 
1115                     /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
1116                     if (handle->rxRingBufferTail + 1U == (uint16_t)handle->rxRingBufferSize)
1117                     {
1118                         handle->rxRingBufferTail = 0U;
1119                     }
1120                     else
1121                     {
1122                         handle->rxRingBufferTail++;
1123                     }
1124                 }
1125             }
1126 
1127             /* If ring buffer does not have enough data, still need to read more data. */
1128             if (bytesToReceive != 0U)
1129             {
1130                 /* No data in ring buffer, save the request to UART handle. */
1131                 handle->rxData        = xfer->rxData + bytesCurrentReceived;
1132                 handle->rxDataSize    = bytesToReceive;
1133                 handle->rxDataSizeAll = xfer->dataSize;
1134                 handle->rxState       = (uint8_t)kUART_RxBusy;
1135             }
1136 
1137             /* Enable UART RX IRQ if previously enabled. */
1138             UART_EnableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable);
1139 
1140             /* Call user callback since all data are received. */
1141             if (0U == bytesToReceive)
1142             {
1143                 if ((handle->callback) != NULL)
1144                 {
1145                     handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData);
1146                 }
1147             }
1148         }
1149         /* Ring buffer not used. */
1150         else
1151         {
1152             handle->rxData        = xfer->rxData + bytesCurrentReceived;
1153             handle->rxDataSize    = bytesToReceive;
1154             handle->rxDataSizeAll = bytesToReceive;
1155             handle->rxState       = (uint8_t)kUART_RxBusy;
1156 
1157             /* Enable RX/Rx overrun/framing error interrupt. */
1158             UART_EnableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable |
1159                                             (uint32_t)kUART_RxOverrunEnable | (uint32_t)kUART_ParityErrorEnable |
1160                                             (uint32_t)kUART_FrameErrorEnable);
1161         }
1162 
1163         /* Return the how many bytes have read. */
1164         if (receivedBytes != NULL)
1165         {
1166             *receivedBytes = bytesCurrentReceived;
1167         }
1168 
1169         status = kStatus_Success;
1170     }
1171 
1172     return status;
1173 }
1174 
1175 /*!
1176  * brief Aborts the interrupt-driven data receiving.
1177  *
1178  * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
1179  * how many bytes are not received yet.
1180  *
1181  * param base UART peripheral base address.
1182  * param handle UART handle pointer.
1183  */
UART_TransferAbortReceive(UART_Type * base,uart_handle_t * handle)1184 void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle)
1185 {
1186     assert(handle != NULL);
1187 
1188     /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
1189     if (handle->rxRingBuffer == NULL)
1190     {
1191         /* Disable RX interrupt. */
1192         UART_DisableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable |
1193                                          (uint32_t)kUART_RxOverrunEnable | (uint32_t)kUART_ParityErrorEnable |
1194                                          (uint32_t)kUART_FrameErrorEnable);
1195     }
1196 
1197     handle->rxDataSize = 0U;
1198     handle->rxState    = (uint8_t)kUART_RxIdle;
1199 }
1200 
1201 /*!
1202  * brief Gets the number of bytes that have been received.
1203  *
1204  * This function gets the number of bytes that have been received.
1205  *
1206  * param base UART peripheral base address.
1207  * param handle UART handle pointer.
1208  * param count Receive bytes count.
1209  * retval kStatus_NoTransferInProgress No receive in progress.
1210  * retval kStatus_InvalidArgument Parameter is invalid.
1211  * retval kStatus_Success Get successfully through the parameter \p count;
1212  */
UART_TransferGetReceiveCount(UART_Type * base,uart_handle_t * handle,uint32_t * count)1213 status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count)
1214 {
1215     assert(handle != NULL);
1216     assert(count != NULL);
1217 
1218     if ((uint8_t)kUART_RxIdle == handle->rxState)
1219     {
1220         return kStatus_NoTransferInProgress;
1221     }
1222 
1223     if (count == NULL)
1224     {
1225         return kStatus_InvalidArgument;
1226     }
1227 
1228     *count = handle->rxDataSizeAll - handle->rxDataSize;
1229 
1230     return kStatus_Success;
1231 }
1232 
1233 /*!
1234  * brief UART IRQ handle function.
1235  *
1236  * This function handles the UART transmit and receive IRQ request.
1237  *
1238  * param base UART peripheral base address.
1239  * param irqHandle UART handle pointer.
1240  */
UART_TransferHandleIRQ(UART_Type * base,void * irqHandle)1241 void UART_TransferHandleIRQ(UART_Type *base, void *irqHandle)
1242 {
1243     assert(irqHandle != NULL);
1244 
1245     uint8_t count;
1246     uint8_t tempCount;
1247     uart_handle_t *handle = (uart_handle_t *)irqHandle;
1248 
1249     /* If RX framing error */
1250     if ((UART_USR1_FRAMERR_MASK & base->USR1) != 0U)
1251     {
1252         /* Write 1 to clear framing error flag */
1253         base->USR1 |= UART_USR1_FRAMERR_MASK;
1254 
1255         handle->rxState    = (uint8_t)kUART_RxFramingError;
1256         handle->rxDataSize = 0U;
1257         /* Trigger callback. */
1258         if ((handle->callback) != NULL)
1259         {
1260             handle->callback(base, handle, kStatus_UART_FramingError, handle->userData);
1261         }
1262     }
1263 
1264     /* If RX parity error */
1265     if ((UART_USR1_PARITYERR_MASK & base->USR1) != 0U)
1266     {
1267         /* Write 1 to clear parity error flag. */
1268         base->USR1 |= UART_USR1_PARITYERR_MASK;
1269 
1270         handle->rxState    = (uint8_t)kUART_RxParityError;
1271         handle->rxDataSize = 0U;
1272         /* Trigger callback. */
1273         if ((handle->callback) != NULL)
1274         {
1275             handle->callback(base, handle, kStatus_UART_ParityError, handle->userData);
1276         }
1277     }
1278 
1279     /* If RX overrun. */
1280     if ((UART_USR2_ORE_MASK & base->USR2) != 0U)
1281     {
1282         /* Write 1 to clear overrun flag. */
1283         base->USR2 |= UART_USR2_ORE_MASK;
1284         /* Trigger callback. */
1285         if ((handle->callback) != NULL)
1286         {
1287             handle->callback(base, handle, kStatus_UART_RxHardwareOverrun, handle->userData);
1288         }
1289     }
1290 
1291     /* Receive data FIFO buffer reach the trigger level */
1292     if (((UART_USR1_RRDY_MASK & base->USR1) != 0U) && ((UART_UCR1_RRDYEN_MASK & base->UCR1) != 0U))
1293     {
1294         /* Get the size that stored in receive FIFO buffer for this interrupt. */
1295         count = (uint8_t)((base->UFCR & UART_UFCR_RXTL_MASK) >> UART_UFCR_RXTL_SHIFT);
1296 
1297         /* If count and handle->rxDataSize are not 0, first save data to handle->rxData. */
1298         while ((count != 0U) && (handle->rxDataSize != 0U))
1299         {
1300             tempCount = (uint8_t)MIN(handle->rxDataSize, count);
1301             /* Using non block API to read the data from the registers. */
1302             UART_ReadNonBlocking(base, handle->rxData, tempCount);
1303             handle->rxData += tempCount;
1304             handle->rxDataSize -= tempCount;
1305             count -= tempCount;
1306 
1307             /* If all the data required for upper layer is ready, trigger callback. */
1308             if (handle->rxDataSize == 0U)
1309             {
1310                 handle->rxState = (uint8_t)kUART_RxIdle;
1311 
1312                 if ((handle->callback) != NULL)
1313                 {
1314                     handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData);
1315                 }
1316             }
1317         }
1318 
1319         /* If use RX ring buffer, receive data to ring buffer. */
1320         if (handle->rxRingBuffer != NULL)
1321         {
1322             while (count-- != 0U)
1323             {
1324                 /* If RX ring buffer is full, trigger callback to notify over run. */
1325                 if (UART_TransferIsRxRingBufferFull(handle))
1326                 {
1327                     if ((handle->callback) != NULL)
1328                     {
1329                         handle->callback(base, handle, kStatus_UART_RxRingBufferOverrun, handle->userData);
1330                     }
1331                 }
1332 
1333                 /* If ring buffer is still full after callback function, the oldest data is overridden. */
1334                 if (UART_TransferIsRxRingBufferFull(handle))
1335                 {
1336                     /* Increase handle->rxRingBufferTail to make room for new data. */
1337                     if (handle->rxRingBufferTail + 1U == (uint16_t)handle->rxRingBufferSize)
1338                     {
1339                         handle->rxRingBufferTail = 0U;
1340                     }
1341                     else
1342                     {
1343                         handle->rxRingBufferTail++;
1344                     }
1345                 }
1346 
1347                 /* Read data. */
1348                 handle->rxRingBuffer[handle->rxRingBufferHead] =
1349                     (uint8_t)((base->URXD & UART_URXD_RX_DATA_MASK) >> UART_URXD_RX_DATA_SHIFT);
1350 
1351                 /* Increase handle->rxRingBufferHead. */
1352                 if (handle->rxRingBufferHead + 1U == (uint16_t)handle->rxRingBufferSize)
1353                 {
1354                     handle->rxRingBufferHead = 0U;
1355                 }
1356                 else
1357                 {
1358                     handle->rxRingBufferHead++;
1359                 }
1360             }
1361         }
1362 
1363         else if (handle->rxDataSize == 0U)
1364         {
1365             /* Disable RX interrupt/overrun interrupt/framing error interrupt */
1366             UART_DisableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable |
1367                                              (uint32_t)kUART_RxOverrunEnable | (uint32_t)kUART_ParityErrorEnable |
1368                                              (uint32_t)kUART_FrameErrorEnable);
1369         }
1370         else
1371         {
1372         }
1373     }
1374     /* Receive FIFO buffer has been idle for a time of 8 characters, and FIFO data level
1375      * is less than RxFIFO threshold level.
1376      */
1377     if (((UART_USR1_AGTIM_MASK & base->USR1) != 0U) && ((UART_UCR2_ATEN_MASK & base->UCR2) != 0U))
1378     {
1379         /* If count and handle->rxDataSize are not 0, first save data to handle->rxData. */
1380         while (((base->USR2 & UART_USR2_RDR_MASK) != 0U) && (handle->rxDataSize != 0U))
1381         {
1382             /* Read one data from the URXD registers. */
1383             *handle->rxData = UART_ReadByte(base);
1384             handle->rxData += 1U;
1385             handle->rxDataSize -= 1U;
1386 
1387             /* If all the data required for upper layer is ready, trigger callback. */
1388             if (handle->rxDataSize == 0U)
1389             {
1390                 handle->rxState = (uint8_t)kUART_RxIdle;
1391 
1392                 if ((handle->callback) != NULL)
1393                 {
1394                     handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData);
1395                 }
1396             }
1397         }
1398 
1399         /* If use RX ring buffer, receive data to ring buffer. */
1400         if (handle->rxRingBuffer != NULL)
1401         {
1402             while ((base->USR2 & UART_USR2_RDR_MASK) != 0U)
1403             {
1404                 /* If RX ring buffer is full, trigger callback to notify over run. */
1405                 if (UART_TransferIsRxRingBufferFull(handle))
1406                 {
1407                     if ((handle->callback) != NULL)
1408                     {
1409                         handle->callback(base, handle, kStatus_UART_RxRingBufferOverrun, handle->userData);
1410                     }
1411                 }
1412 
1413                 /* If ring buffer is still full after callback function, the oldest data is overridden. */
1414                 if (UART_TransferIsRxRingBufferFull(handle))
1415                 {
1416                     /* Increase handle->rxRingBufferTail to make room for new data. */
1417                     if (handle->rxRingBufferTail + 1U == (uint16_t)handle->rxRingBufferSize)
1418                     {
1419                         handle->rxRingBufferTail = 0U;
1420                     }
1421                     else
1422                     {
1423                         handle->rxRingBufferTail++;
1424                     }
1425                 }
1426                 /* Read one data from URXD register. */
1427                 handle->rxRingBuffer[handle->rxRingBufferHead] = UART_ReadByte(base);
1428 
1429                 /* Increase handle->rxRingBufferHead. */
1430                 if (handle->rxRingBufferHead + 1U == (uint16_t)handle->rxRingBufferSize)
1431                 {
1432                     handle->rxRingBufferHead = 0U;
1433                 }
1434                 else
1435                 {
1436                     handle->rxRingBufferHead++;
1437                 }
1438             }
1439         }
1440         /* If ring buffer is not used and rxDataSize is 0 */
1441         else if (handle->rxDataSize == 0U)
1442         {
1443             /* Disable RX interrupt/overrun interrupt/framing error interrupt */
1444             UART_DisableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable |
1445                                              (uint32_t)kUART_RxOverrunEnable | (uint32_t)kUART_ParityErrorEnable |
1446                                              (uint32_t)kUART_FrameErrorEnable);
1447         }
1448         else
1449         {
1450         }
1451         /* Clear aging timer flag for next interrupt */
1452         UART_ClearStatusFlag(base, (uint32_t)kUART_AgingTimerFlag);
1453     }
1454     /* If frame error or parity error happened, stop the RX interrupt when use no ring buffer */
1455     if (((handle->rxState == (uint8_t)kUART_RxFramingError) || (handle->rxState == (uint8_t)kUART_RxParityError)) &&
1456         (handle->rxRingBuffer == NULL))
1457     {
1458         /* Disable Receive ready interrupt, aging timer interrupt, receive over run interrupt,
1459          * parity error interrupt and frame error interrupt.
1460          */
1461         UART_DisableInterrupts(base, (uint32_t)kUART_RxReadyEnable | (uint32_t)kUART_AgingTimerEnable |
1462                                          (uint32_t)kUART_RxOverrunEnable | (uint32_t)kUART_ParityErrorEnable |
1463                                          (uint32_t)kUART_FrameErrorEnable);
1464     }
1465 
1466     /* Send data register empty and the interrupt is enabled. */
1467     if (((UART_USR1_TRDY_MASK & base->USR1) != 0U) && ((UART_UCR1_TRDYEN_MASK & base->UCR1) != 0U))
1468     {
1469         /* Get the bytes that available at this moment. */
1470         if (0U != ((base->UFCR & UART_UFCR_TXTL_MASK) >> UART_UFCR_TXTL_SHIFT))
1471         {
1472             if ((UART_UTS_TXEMPTY_MASK & base->UTS) != 0U)
1473             {
1474                 count = FSL_FEATURE_IUART_FIFO_SIZEn(base);
1475             }
1476             else
1477             {
1478                 count = (uint8_t)FSL_FEATURE_IUART_FIFO_SIZEn(base) -
1479                         (uint8_t)((base->UFCR & UART_UFCR_TXTL_MASK) >> UART_UFCR_TXTL_SHIFT);
1480             }
1481         }
1482         else
1483         {
1484             count = 1U;
1485         }
1486 
1487         while ((count != 0U) && (handle->txDataSize != 0U))
1488         {
1489             if (0U != ((base->UFCR & UART_UFCR_TXTL_MASK) >> UART_UFCR_TXTL_SHIFT))
1490             {
1491                 tempCount = (uint8_t)MIN(handle->txDataSize, count);
1492             }
1493             else
1494             {
1495                 tempCount = 1U;
1496             }
1497             /* Using non block API to write the data to the registers. */
1498             UART_WriteNonBlocking(base, handle->txData, tempCount);
1499             handle->txData += tempCount;
1500             handle->txDataSize -= tempCount;
1501             count -= tempCount;
1502 
1503             /* If all the data are written to data register, TX finished. */
1504             if (handle->txDataSize == 0U)
1505             {
1506                 handle->txState = (uint8_t)kUART_TxIdle;
1507                 /* Disable TX FIFO buffer empty interrupt. */
1508                 UART_DisableInterrupts(base, (uint32_t)kUART_TxReadyEnable);
1509                 /* Enable TX complete interrupt. */
1510                 UART_EnableInterrupts(base, (uint32_t)kUART_TxCompleteEnable);
1511             }
1512         }
1513     }
1514 
1515     /* TX complete and the interrupt is enabled. */
1516     if ((0U != (UART_USR2_TXDC_MASK & base->USR2)) && (0U != (UART_UCR4_TCEN_MASK & base->UCR4)) &&
1517         (handle->txState == (uint8_t)kUART_TxIdle))
1518     {
1519         /* Disable TX complete interrupt. */
1520         UART_DisableInterrupts(base, (uint32_t)kUART_TxCompleteEnable);
1521 
1522         /* Trigger callback. */
1523         if ((handle->callback) != NULL)
1524         {
1525             handle->callback(base, handle, kStatus_UART_TxIdle, handle->userData);
1526         }
1527     }
1528 }
1529 
1530 #if defined(UART1)
1531 void UART1_DriverIRQHandler(void);
UART1_DriverIRQHandler(void)1532 void UART1_DriverIRQHandler(void)
1533 {
1534     s_uartIsr(UART1, s_uartHandle[1]);
1535     SDK_ISR_EXIT_BARRIER;
1536 }
1537 #endif
1538 
1539 #if defined(UART2)
1540 void UART2_DriverIRQHandler(void);
UART2_DriverIRQHandler(void)1541 void UART2_DriverIRQHandler(void)
1542 {
1543     s_uartIsr(UART2, s_uartHandle[2]);
1544     SDK_ISR_EXIT_BARRIER;
1545 }
1546 #endif
1547 
1548 #if defined(UART3)
1549 void UART3_DriverIRQHandler(void);
UART3_DriverIRQHandler(void)1550 void UART3_DriverIRQHandler(void)
1551 {
1552     s_uartIsr(UART3, s_uartHandle[3]);
1553     SDK_ISR_EXIT_BARRIER;
1554 }
1555 #endif
1556 
1557 #if defined(UART4)
1558 void UART4_DriverIRQHandler(void);
UART4_DriverIRQHandler(void)1559 void UART4_DriverIRQHandler(void)
1560 {
1561     s_uartIsr(UART4, s_uartHandle[4]);
1562     SDK_ISR_EXIT_BARRIER;
1563 }
1564 #endif
1565 
1566 #if defined(UART5)
1567 void UART5_DriverIRQHandler(void);
UART5_DriverIRQHandler(void)1568 void UART5_DriverIRQHandler(void)
1569 {
1570     s_uartIsr(UART5, s_uartHandle[5]);
1571     SDK_ISR_EXIT_BARRIER;
1572 }
1573 #endif
1574 
1575 #if defined(UART6)
1576 void UART6_DriverIRQHandler(void);
UART6_DriverIRQHandler(void)1577 void UART6_DriverIRQHandler(void)
1578 {
1579     s_uartIsr(UART6, s_uartHandle[6]);
1580     SDK_ISR_EXIT_BARRIER;
1581 }
1582 #endif
1583 
1584 #if defined(UART7)
1585 void UART7_DriverIRQHandler(void);
UART7_DriverIRQHandler(void)1586 void UART7_DriverIRQHandler(void)
1587 {
1588     s_uartIsr(UART7, s_uartHandle[7]);
1589     SDK_ISR_EXIT_BARRIER;
1590 }
1591 #endif
1592 
1593 #if defined(UART8)
1594 void UART8_DriverIRQHandler(void);
UART8_DriverIRQHandler(void)1595 void UART8_DriverIRQHandler(void)
1596 {
1597     s_uartIsr(UART8, s_uartHandle[8]);
1598     SDK_ISR_EXIT_BARRIER;
1599 }
1600 #endif
1601