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