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