]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RISC-V_RV32M1_Vega_GCC_Eclipse/common/rv32m1_sdk_riscv/devices/RV32M1/drivers/fsl_lpuart.c
Move the 'generic' version of freertos_risc_v_chip_specific_extensions.h back to...
[freertos] / FreeRTOS / Demo / RISC-V_RV32M1_Vega_GCC_Eclipse / common / rv32m1_sdk_riscv / devices / RV32M1 / drivers / fsl_lpuart.c
1 /*
2  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  * 
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8
9 #include "fsl_lpuart.h"
10
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 /* LPUART transfer state. */
15 enum _lpuart_transfer_states
16 {
17     kLPUART_TxIdle, /*!< TX idle. */
18     kLPUART_TxBusy, /*!< TX busy. */
19     kLPUART_RxIdle, /*!< RX idle. */
20     kLPUART_RxBusy  /*!< RX busy. */
21 };
22
23 /* Typedef for interrupt handler. */
24 typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle);
25
26 /*******************************************************************************
27  * Prototypes
28  ******************************************************************************/
29 /*!
30  * @brief Get the LPUART instance from peripheral base address.
31  *
32  * @param base LPUART peripheral base address.
33  * @return LPUART instance.
34  */
35 uint32_t LPUART_GetInstance(LPUART_Type *base);
36
37 /*!
38  * @brief Get the length of received data in RX ring buffer.
39  *
40  * @userData handle LPUART handle pointer.
41  * @return Length of received data in RX ring buffer.
42  */
43 static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle);
44
45 /*!
46  * @brief Check whether the RX ring buffer is full.
47  *
48  * @userData handle LPUART handle pointer.
49  * @retval true  RX ring buffer is full.
50  * @retval false RX ring buffer is not full.
51  */
52 static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle);
53
54 /*!
55  * @brief Write to TX register using non-blocking method.
56  *
57  * This function writes data to the TX register directly, upper layer must make
58  * sure the TX register is empty or TX FIFO has empty room before calling this function.
59  *
60  * @note This function does not check whether all the data has been sent out to bus,
61  * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is
62  * finished.
63  *
64  * @param base LPUART peripheral base address.
65  * @param data Start addresss of the data to write.
66  * @param length Size of the buffer to be sent.
67  */
68 static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
69
70 /*!
71  * @brief Read RX register using non-blocking method.
72  *
73  * This function reads data from the TX register directly, upper layer must make
74  * sure the RX register is full or TX FIFO has data before calling this function.
75  *
76  * @param base LPUART peripheral base address.
77  * @param data Start addresss of the buffer to store the received data.
78  * @param length Size of the buffer.
79  */
80 static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length);
81
82 /*******************************************************************************
83  * Variables
84  ******************************************************************************/
85 /* Array of LPUART handle. */
86 static lpuart_handle_t *s_lpuartHandle[FSL_FEATURE_SOC_LPUART_COUNT];
87 /* Array of LPUART peripheral base address. */
88 static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS;
89 /* Array of LPUART IRQ number. */
90 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
91 static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS;
92 static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS;
93 #else
94 static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS;
95 #endif
96 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
97 /* Array of LPUART clock name. */
98 static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS;
99
100 #if defined(LPUART_PERIPH_CLOCKS)
101 /* Array of LPUART functional clock name. */
102 static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS;
103 #endif
104
105 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
106
107 /* LPUART ISR for transactional APIs. */
108 static lpuart_isr_t s_lpuartIsr;
109
110 /*******************************************************************************
111  * Code
112  ******************************************************************************/
113 uint32_t LPUART_GetInstance(LPUART_Type *base)
114 {
115     uint32_t instance;
116
117     /* Find the instance index from base address mappings. */
118     for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++)
119     {
120         if (s_lpuartBases[instance] == base)
121         {
122             break;
123         }
124     }
125
126     assert(instance < ARRAY_SIZE(s_lpuartBases));
127
128     return instance;
129 }
130
131 static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle)
132 {
133     assert(handle);
134
135     size_t size;
136
137     if (handle->rxRingBufferTail > handle->rxRingBufferHead)
138     {
139         size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail);
140     }
141     else
142     {
143         size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail);
144     }
145
146     return size;
147 }
148
149 static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle)
150 {
151     assert(handle);
152
153     bool full;
154
155     if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U))
156     {
157         full = true;
158     }
159     else
160     {
161         full = false;
162     }
163     return full;
164 }
165
166 static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
167 {
168     assert(data);
169
170     size_t i;
171
172     /* The Non Blocking write data API assume user have ensured there is enough space in
173     peripheral to write. */
174     for (i = 0; i < length; i++)
175     {
176         base->DATA = data[i];
177     }
178 }
179
180 static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length)
181 {
182     assert(data);
183
184     size_t i;
185 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
186     uint32_t ctrl = base->CTRL;
187     bool isSevenDataBits =
188         ((ctrl & LPUART_CTRL_M7_MASK) ||
189          ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
190 #endif
191
192     /* The Non Blocking read data API assume user have ensured there is enough space in
193     peripheral to write. */
194     for (i = 0; i < length; i++)
195     {
196 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
197         if (isSevenDataBits)
198         {
199             data[i] = (base->DATA & 0x7F);
200         }
201         else
202         {
203             data[i] = base->DATA;
204         }
205 #else
206         data[i] = base->DATA;
207 #endif
208     }
209 }
210
211 status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz)
212 {
213     assert(config);
214     assert(config->baudRate_Bps);
215 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
216     assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark);
217     assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark);
218 #endif
219
220     uint32_t temp;
221     uint16_t sbr, sbrTemp;
222     uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
223
224     /* This LPUART instantiation uses a slightly different baud rate calculation
225      * The idea is to use the best OSR (over-sampling rate) possible
226      * Note, OSR is typically hard-set to 16 in other LPUART instantiations
227      * loop to find the best OSR value possible, one that generates minimum baudDiff
228      * iterate through the rest of the supported values of OSR */
229
230     baudDiff = config->baudRate_Bps;
231     osr = 0;
232     sbr = 0;
233     for (osrTemp = 4; osrTemp <= 32; osrTemp++)
234     {
235         /* calculate the temporary sbr value   */
236         sbrTemp = (srcClock_Hz / (config->baudRate_Bps * osrTemp));
237         /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
238         if (sbrTemp == 0)
239         {
240             sbrTemp = 1;
241         }
242         /* Calculate the baud rate based on the temporary OSR and SBR values */
243         calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp));
244
245         tempDiff = calculatedBaud - config->baudRate_Bps;
246
247         /* Select the better value between srb and (sbr + 1) */
248         if (tempDiff > (config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)))))
249         {
250             tempDiff = config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)));
251             sbrTemp++;
252         }
253
254         if (tempDiff <= baudDiff)
255         {
256             baudDiff = tempDiff;
257             osr = osrTemp; /* update and store the best OSR value calculated */
258             sbr = sbrTemp; /* update store the best SBR value calculated */
259         }
260     }
261
262     /* Check to see if actual baud rate is within 3% of desired baud rate
263      * based on the best calculate OSR value */
264     if (baudDiff > ((config->baudRate_Bps / 100) * 3))
265     {
266         /* Unacceptable baud rate difference of more than 3%*/
267         return kStatus_LPUART_BaudrateNotSupport;
268     }
269
270 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
271
272     uint32_t instance = LPUART_GetInstance(base);
273
274     /* Enable lpuart clock */
275     CLOCK_EnableClock(s_lpuartClock[instance]);
276 #if defined(LPUART_PERIPH_CLOCKS)
277     CLOCK_EnableClock(s_lpuartPeriphClocks[instance]);
278 #endif
279
280 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
281
282 #if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
283     /*Reset all internal logic and registers, except the Global Register */
284     LPUART_SoftwareReset(base);
285 #else
286     /* Disable LPUART TX RX before setting. */
287     base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
288 #endif
289
290     temp = base->BAUD;
291
292     /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
293      * If so, then "BOTHEDGE" sampling must be turned on */
294     if ((osr > 3) && (osr < 8))
295     {
296         temp |= LPUART_BAUD_BOTHEDGE_MASK;
297     }
298
299     /* program the osr value (bit value is one less than actual value) */
300     temp &= ~LPUART_BAUD_OSR_MASK;
301     temp |= LPUART_BAUD_OSR(osr - 1);
302
303     /* write the sbr value to the BAUD registers */
304     temp &= ~LPUART_BAUD_SBR_MASK;
305     base->BAUD = temp | LPUART_BAUD_SBR(sbr);
306
307     /* Set bit count and parity mode. */
308     base->BAUD &= ~LPUART_BAUD_M10_MASK;
309
310     temp = base->CTRL &
311            ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK |
312              LPUART_CTRL_IDLECFG_MASK);
313
314     temp |=
315         (uint8_t)config->parityMode | LPUART_CTRL_IDLECFG(config->rxIdleConfig) | LPUART_CTRL_ILT(config->rxIdleType);
316
317 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
318     if (kLPUART_SevenDataBits == config->dataBitsCount)
319     {
320         if (kLPUART_ParityDisabled != config->parityMode)
321         {
322             temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */
323         }
324         else
325         {
326             temp |= LPUART_CTRL_M7_MASK;
327         }
328     }
329     else
330 #endif
331     {
332         if (kLPUART_ParityDisabled != config->parityMode)
333         {
334             temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */
335         }
336     }
337
338     base->CTRL = temp;
339
340 #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
341     /* set stop bit per char */
342     temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK;
343     base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount);
344 #endif
345
346 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
347     /* Set tx/rx WATER watermark
348        Note:
349        Take care of the RX FIFO, RX interrupt request only assert when received bytes
350        equal or more than RX water mark, there is potential issue if RX water
351        mark larger than 1.
352        For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
353        5 bytes are received. the last byte will be saved in FIFO but not trigger
354        RX interrupt because the water mark is 2.
355      */
356     base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16) | config->txFifoWatermark);
357
358     /* Enable tx/rx FIFO */
359     base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK);
360
361     /* Flush FIFO */
362     base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK);
363 #endif
364
365     /* Clear all status flags */
366     temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
367             LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
368
369 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
370     temp |= LPUART_STAT_LBKDIF_MASK;
371 #endif
372
373 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
374     temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
375 #endif
376
377 #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
378     /* Set the CTS configuration/TX CTS source. */
379     base->MODIR |= LPUART_MODIR_TXCTSC(config->txCtsConfig) | LPUART_MODIR_TXCTSSRC(config->txCtsSource);
380     if (config->enableRxRTS)
381     {
382         /* Enable the receiver RTS(request-to-send) function. */
383         base->MODIR |= LPUART_MODIR_RXRTSE_MASK;
384     }
385     if (config->enableTxCTS)
386     {
387         /* Enable the CTS(clear-to-send) function. */
388         base->MODIR |= LPUART_MODIR_TXCTSE_MASK;
389     }
390 #endif
391
392     /* Set data bits order. */
393     if (config->isMsb)
394     {
395         temp |= LPUART_STAT_MSBF_MASK;
396     }
397     else
398     {
399         temp &= ~LPUART_STAT_MSBF_MASK;
400     }
401
402     base->STAT |= temp;
403
404     /* Enable TX/RX base on configure structure. */
405     temp = base->CTRL;
406     if (config->enableTx)
407     {
408         temp |= LPUART_CTRL_TE_MASK;
409     }
410
411     if (config->enableRx)
412     {
413         temp |= LPUART_CTRL_RE_MASK;
414     }
415
416     base->CTRL = temp;
417
418     return kStatus_Success;
419 }
420 void LPUART_Deinit(LPUART_Type *base)
421 {
422     uint32_t temp;
423
424 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
425     /* Wait tx FIFO send out*/
426     while (0 != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT))
427     {
428     }
429 #endif
430     /* Wait last char shoft out */
431     while (0 == (base->STAT & LPUART_STAT_TC_MASK))
432     {
433     }
434
435     /* Clear all status flags */
436     temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
437             LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
438
439 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
440     temp |= LPUART_STAT_LBKDIF_MASK;
441 #endif
442
443 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
444     temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
445 #endif
446
447     base->STAT |= temp;
448
449     /* Disable the module. */
450     base->CTRL = 0;
451
452 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
453     uint32_t instance = LPUART_GetInstance(base);
454
455     /* Disable lpuart clock */
456     CLOCK_DisableClock(s_lpuartClock[instance]);
457
458 #if defined(LPUART_PERIPH_CLOCKS)
459     CLOCK_DisableClock(s_lpuartPeriphClocks[instance]);
460 #endif
461
462 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
463 }
464
465 void LPUART_GetDefaultConfig(lpuart_config_t *config)
466 {
467     assert(config);
468
469     config->baudRate_Bps = 115200U;
470     config->parityMode = kLPUART_ParityDisabled;
471     config->dataBitsCount = kLPUART_EightDataBits;
472     config->isMsb = false;
473 #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
474     config->stopBitCount = kLPUART_OneStopBit;
475 #endif
476 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
477     config->txFifoWatermark = 0;
478     config->rxFifoWatermark = 0;
479 #endif
480 #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
481     config->enableRxRTS = false;
482     config->enableTxCTS = false;
483     config->txCtsConfig = kLPUART_CtsSampleAtStart;
484     config->txCtsSource = kLPUART_CtsSourcePin;
485 #endif
486     config->rxIdleType = kLPUART_IdleTypeStartBit;
487     config->rxIdleConfig = kLPUART_IdleCharacter1;
488     config->enableTx = false;
489     config->enableRx = false;
490 }
491
492 status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
493 {
494     assert(baudRate_Bps);
495
496     uint32_t temp, oldCtrl;
497     uint16_t sbr, sbrTemp;
498     uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
499
500     /* This LPUART instantiation uses a slightly different baud rate calculation
501      * The idea is to use the best OSR (over-sampling rate) possible
502      * Note, OSR is typically hard-set to 16 in other LPUART instantiations
503      * loop to find the best OSR value possible, one that generates minimum baudDiff
504      * iterate through the rest of the supported values of OSR */
505
506     baudDiff = baudRate_Bps;
507     osr = 0;
508     sbr = 0;
509     for (osrTemp = 4; osrTemp <= 32; osrTemp++)
510     {
511         /* calculate the temporary sbr value   */
512         sbrTemp = (srcClock_Hz / (baudRate_Bps * osrTemp));
513         /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
514         if (sbrTemp == 0)
515         {
516             sbrTemp = 1;
517         }
518         /* Calculate the baud rate based on the temporary OSR and SBR values */
519         calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp));
520
521         tempDiff = calculatedBaud - baudRate_Bps;
522
523         /* Select the better value between srb and (sbr + 1) */
524         if (tempDiff > (baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)))))
525         {
526             tempDiff = baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)));
527             sbrTemp++;
528         }
529
530         if (tempDiff <= baudDiff)
531         {
532             baudDiff = tempDiff;
533             osr = osrTemp; /* update and store the best OSR value calculated */
534             sbr = sbrTemp; /* update store the best SBR value calculated */
535         }
536     }
537
538     /* Check to see if actual baud rate is within 3% of desired baud rate
539      * based on the best calculate OSR value */
540     if (baudDiff < ((baudRate_Bps / 100) * 3))
541     {
542         /* Store CTRL before disable Tx and Rx */
543         oldCtrl = base->CTRL;
544
545         /* Disable LPUART TX RX before setting. */
546         base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
547
548         temp = base->BAUD;
549
550         /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
551          * If so, then "BOTHEDGE" sampling must be turned on */
552         if ((osr > 3) && (osr < 8))
553         {
554             temp |= LPUART_BAUD_BOTHEDGE_MASK;
555         }
556
557         /* program the osr value (bit value is one less than actual value) */
558         temp &= ~LPUART_BAUD_OSR_MASK;
559         temp |= LPUART_BAUD_OSR(osr - 1);
560
561         /* write the sbr value to the BAUD registers */
562         temp &= ~LPUART_BAUD_SBR_MASK;
563         base->BAUD = temp | LPUART_BAUD_SBR(sbr);
564
565         /* Restore CTRL. */
566         base->CTRL = oldCtrl;
567
568         return kStatus_Success;
569     }
570     else
571     {
572         /* Unacceptable baud rate difference of more than 3%*/
573         return kStatus_LPUART_BaudrateNotSupport;
574     }
575 }
576
577 void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask)
578 {
579     base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
580 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
581     base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) |
582                  ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
583 #endif
584     mask &= 0xFFFFFF00U;
585     base->CTRL |= mask;
586 }
587
588 void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask)
589 {
590     base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
591 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
592     base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) &
593                  ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
594 #endif
595     mask &= 0xFFFFFF00U;
596     base->CTRL &= ~mask;
597 }
598
599 uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base)
600 {
601     uint32_t temp;
602     temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8;
603 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
604     temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8;
605 #endif
606     temp |= (base->CTRL & 0xFF0C000);
607
608     return temp;
609 }
610
611 uint32_t LPUART_GetStatusFlags(LPUART_Type *base)
612 {
613     uint32_t temp;
614     temp = base->STAT;
615 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
616     temp |= (base->FIFO &
617              (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >>
618             16;
619 #endif
620     return temp;
621 }
622
623 status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask)
624 {
625     uint32_t temp;
626     status_t status;
627 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
628     temp = (uint32_t)base->FIFO;
629     temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK));
630     temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK);
631     base->FIFO = temp;
632 #endif
633     temp = (uint32_t)base->STAT;
634 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
635     temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK));
636     temp |= mask & LPUART_STAT_LBKDIF_MASK;
637 #endif
638     temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
639                          LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK));
640     temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
641                     LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
642 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
643     temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK));
644     temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK);
645 #endif
646     base->STAT = temp;
647     /* If some flags still pending. */
648     if (mask & LPUART_GetStatusFlags(base))
649     {
650         /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag,
651         kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag,
652         kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag,
653         kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */
654         status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */
655     }
656     else
657     {
658         status = kStatus_Success;
659     }
660
661     return status;
662 }
663
664 void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
665 {
666     assert(data);
667
668     /* This API can only ensure that the data is written into the data buffer but can't
669     ensure all data in the data buffer are sent into the transmit shift buffer. */
670     while (length--)
671     {
672         while (!(base->STAT & LPUART_STAT_TDRE_MASK))
673         {
674         }
675         base->DATA = *(data++);
676     }
677 }
678
679 status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)
680 {
681     assert(data);
682
683     uint32_t statusFlag;
684 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
685     uint32_t ctrl = base->CTRL;
686     bool isSevenDataBits =
687         ((ctrl & LPUART_CTRL_M7_MASK) ||
688          ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
689 #endif
690
691     while (length--)
692     {
693 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
694         while (0 == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT))
695 #else
696         while (!(base->STAT & LPUART_STAT_RDRF_MASK))
697 #endif
698         {
699             statusFlag = LPUART_GetStatusFlags(base);
700
701             if (statusFlag & kLPUART_RxOverrunFlag)
702             {
703                 LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag);
704                 return kStatus_LPUART_RxHardwareOverrun;
705             }
706
707             if (statusFlag & kLPUART_NoiseErrorFlag)
708             {
709                 LPUART_ClearStatusFlags(base, kLPUART_NoiseErrorFlag);
710                 return kStatus_LPUART_NoiseError;
711             }
712
713             if (statusFlag & kLPUART_FramingErrorFlag)
714             {
715                 LPUART_ClearStatusFlags(base, kLPUART_FramingErrorFlag);
716                 return kStatus_LPUART_FramingError;
717             }
718
719             if (statusFlag & kLPUART_ParityErrorFlag)
720             {
721                 LPUART_ClearStatusFlags(base, kLPUART_ParityErrorFlag);
722                 return kStatus_LPUART_ParityError;
723             }
724         }
725 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
726         if (isSevenDataBits)
727         {
728             *(data++) = (base->DATA & 0x7F);
729         }
730         else
731         {
732             *(data++) = base->DATA;
733         }
734 #else
735         *(data++) = base->DATA;
736 #endif
737     }
738
739     return kStatus_Success;
740 }
741
742 void LPUART_TransferCreateHandle(LPUART_Type *base,
743                                  lpuart_handle_t *handle,
744                                  lpuart_transfer_callback_t callback,
745                                  void *userData)
746 {
747     assert(handle);
748
749     uint32_t instance;
750 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
751     uint32_t ctrl = base->CTRL;
752     bool isSevenDataBits =
753         ((ctrl & LPUART_CTRL_M7_MASK) ||
754          ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
755 #endif
756
757     /* Zero the handle. */
758     memset(handle, 0, sizeof(lpuart_handle_t));
759
760     /* Set the TX/RX state. */
761     handle->rxState = kLPUART_RxIdle;
762     handle->txState = kLPUART_TxIdle;
763
764     /* Set the callback and user data. */
765     handle->callback = callback;
766     handle->userData = userData;
767
768 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
769     /* Initial seven data bits flag */
770     handle->isSevenDataBits = isSevenDataBits;
771 #endif
772
773     /* Get instance from peripheral base address. */
774     instance = LPUART_GetInstance(base);
775
776     /* Save the handle in global variables to support the double weak mechanism. */
777     s_lpuartHandle[instance] = handle;
778
779     s_lpuartIsr = LPUART_TransferHandleIRQ;
780
781 /* Enable interrupt in NVIC. */
782 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
783     EnableIRQ(s_lpuartRxIRQ[instance]);
784     EnableIRQ(s_lpuartTxIRQ[instance]);
785 #else
786     EnableIRQ(s_lpuartIRQ[instance]);
787 #endif
788 }
789
790 void LPUART_TransferStartRingBuffer(LPUART_Type *base,
791                                     lpuart_handle_t *handle,
792                                     uint8_t *ringBuffer,
793                                     size_t ringBufferSize)
794 {
795     assert(handle);
796     assert(ringBuffer);
797
798     /* Setup the ring buffer address */
799     handle->rxRingBuffer = ringBuffer;
800     handle->rxRingBufferSize = ringBufferSize;
801     handle->rxRingBufferHead = 0U;
802     handle->rxRingBufferTail = 0U;
803
804     /* Enable the interrupt to accept the data when user need the ring buffer. */
805     LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
806 }
807
808 void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle)
809 {
810     assert(handle);
811
812     if (handle->rxState == kLPUART_RxIdle)
813     {
814         LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
815     }
816
817     handle->rxRingBuffer = NULL;
818     handle->rxRingBufferSize = 0U;
819     handle->rxRingBufferHead = 0U;
820     handle->rxRingBufferTail = 0U;
821 }
822
823 status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer)
824 {
825     assert(handle);
826     assert(xfer);
827     assert(xfer->data);
828     assert(xfer->dataSize);
829
830     status_t status;
831
832     /* Return error if current TX busy. */
833     if (kLPUART_TxBusy == handle->txState)
834     {
835         status = kStatus_LPUART_TxBusy;
836     }
837     else
838     {
839         handle->txData = xfer->data;
840         handle->txDataSize = xfer->dataSize;
841         handle->txDataSizeAll = xfer->dataSize;
842         handle->txState = kLPUART_TxBusy;
843
844         /* Enable transmiter interrupt. */
845         LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable);
846
847         status = kStatus_Success;
848     }
849
850     return status;
851 }
852
853 void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle)
854 {
855     assert(handle);
856
857     LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable);
858
859     handle->txDataSize = 0;
860     handle->txState = kLPUART_TxIdle;
861 }
862
863 status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
864 {
865     assert(handle);
866     assert(count);
867
868     if (kLPUART_TxIdle == handle->txState)
869     {
870         return kStatus_NoTransferInProgress;
871     }
872
873     *count = handle->txDataSizeAll - handle->txDataSize;
874
875     return kStatus_Success;
876 }
877
878 status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
879                                            lpuart_handle_t *handle,
880                                            lpuart_transfer_t *xfer,
881                                            size_t *receivedBytes)
882 {
883     assert(handle);
884     assert(xfer);
885     assert(xfer->data);
886     assert(xfer->dataSize);
887
888     uint32_t i;
889     status_t status;
890     /* How many bytes to copy from ring buffer to user memory. */
891     size_t bytesToCopy = 0U;
892     /* How many bytes to receive. */
893     size_t bytesToReceive;
894     /* How many bytes currently have received. */
895     size_t bytesCurrentReceived;
896
897     /* How to get data:
898        1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
899           to lpuart handle, enable interrupt to store received data to xfer->data. When
900           all data received, trigger callback.
901        2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
902           If there are enough data in ring buffer, copy them to xfer->data and return.
903           If there are not enough data in ring buffer, copy all of them to xfer->data,
904           save the xfer->data remained empty space to lpuart handle, receive data
905           to this empty space and trigger callback when finished. */
906
907     if (kLPUART_RxBusy == handle->rxState)
908     {
909         status = kStatus_LPUART_RxBusy;
910     }
911     else
912     {
913         bytesToReceive = xfer->dataSize;
914         bytesCurrentReceived = 0;
915
916         /* If RX ring buffer is used. */
917         if (handle->rxRingBuffer)
918         {
919             /* Disable LPUART RX IRQ, protect ring buffer. */
920             LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
921
922             /* How many bytes in RX ring buffer currently. */
923             bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle);
924
925             if (bytesToCopy)
926             {
927                 bytesToCopy = MIN(bytesToReceive, bytesToCopy);
928
929                 bytesToReceive -= bytesToCopy;
930
931                 /* Copy data from ring buffer to user memory. */
932                 for (i = 0U; i < bytesToCopy; i++)
933                 {
934                     xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
935
936                     /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
937                     if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
938                     {
939                         handle->rxRingBufferTail = 0U;
940                     }
941                     else
942                     {
943                         handle->rxRingBufferTail++;
944                     }
945                 }
946             }
947
948             /* If ring buffer does not have enough data, still need to read more data. */
949             if (bytesToReceive)
950             {
951                 /* No data in ring buffer, save the request to LPUART handle. */
952                 handle->rxData = xfer->data + bytesCurrentReceived;
953                 handle->rxDataSize = bytesToReceive;
954                 handle->rxDataSizeAll = bytesToReceive;
955                 handle->rxState = kLPUART_RxBusy;
956             }
957             /* Enable LPUART RX IRQ if previously enabled. */
958             LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
959
960             /* Call user callback since all data are received. */
961             if (0 == bytesToReceive)
962             {
963                 if (handle->callback)
964                 {
965                     handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
966                 }
967             }
968         }
969         /* Ring buffer not used. */
970         else
971         {
972             handle->rxData = xfer->data + bytesCurrentReceived;
973             handle->rxDataSize = bytesToReceive;
974             handle->rxDataSizeAll = bytesToReceive;
975             handle->rxState = kLPUART_RxBusy;
976
977             /* Enable RX interrupt. */
978             LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable |
979                                               kLPUART_IdleLineInterruptEnable);
980         }
981
982         /* Return the how many bytes have read. */
983         if (receivedBytes)
984         {
985             *receivedBytes = bytesCurrentReceived;
986         }
987
988         status = kStatus_Success;
989     }
990
991     return status;
992 }
993
994 void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle)
995 {
996     assert(handle);
997
998     /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
999     if (!handle->rxRingBuffer)
1000     {
1001         /* Disable RX interrupt. */
1002         LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable |
1003                                            kLPUART_IdleLineInterruptEnable);
1004     }
1005
1006     handle->rxDataSize = 0U;
1007     handle->rxState = kLPUART_RxIdle;
1008 }
1009
1010 status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
1011 {
1012     assert(handle);
1013     assert(count);
1014
1015     if (kLPUART_RxIdle == handle->rxState)
1016     {
1017         return kStatus_NoTransferInProgress;
1018     }
1019
1020     *count = handle->rxDataSizeAll - handle->rxDataSize;
1021
1022     return kStatus_Success;
1023 }
1024
1025 void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle)
1026 {
1027     assert(handle);
1028
1029     uint8_t count;
1030     uint8_t tempCount;
1031
1032     /* If RX overrun. */
1033     if (LPUART_STAT_OR_MASK & base->STAT)
1034     {
1035         /* Clear overrun flag, otherwise the RX does not work. */
1036         base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK);
1037
1038         /* Trigger callback. */
1039         if (handle->callback)
1040         {
1041             handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData);
1042         }
1043     }
1044
1045     /* If IDLE flag is set and the IDLE interrupt is enabled. */
1046     if ((LPUART_STAT_IDLE_MASK & base->STAT) && (LPUART_CTRL_ILIE_MASK & base->CTRL))
1047     {
1048 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1049         count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT));
1050
1051         while ((count) && (handle->rxDataSize))
1052         {
1053             tempCount = MIN(handle->rxDataSize, count);
1054
1055             /* Using non block API to read the data from the registers. */
1056             LPUART_ReadNonBlocking(base, handle->rxData, tempCount);
1057             handle->rxData += tempCount;
1058             handle->rxDataSize -= tempCount;
1059             count -= tempCount;
1060
1061             /* If rxDataSize is 0, disable idle line interrupt.*/
1062             if (!(handle->rxDataSize))
1063             {
1064                 handle->rxState = kLPUART_RxIdle;
1065
1066                 LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
1067                 if (handle->callback)
1068                 {
1069                     handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
1070                 }
1071             }
1072         }
1073 #endif
1074         /* Clear IDLE flag.*/
1075         base->STAT |= LPUART_STAT_IDLE_MASK;
1076
1077         /* If rxDataSize is 0, disable idle line interrupt.*/
1078         if (!(handle->rxDataSize))
1079         {
1080             LPUART_DisableInterrupts(base, kLPUART_IdleLineInterruptEnable);
1081         }
1082         /* If callback is not NULL and rxDataSize is not 0. */
1083         if ((handle->callback) && (handle->rxDataSize))
1084         {
1085             handle->callback(base, handle, kStatus_LPUART_IdleLineDetected, handle->userData);
1086         }
1087     }
1088     /* Receive data register full */
1089     if ((LPUART_STAT_RDRF_MASK & base->STAT) && (LPUART_CTRL_RIE_MASK & base->CTRL))
1090     {
1091 /* Get the size that can be stored into buffer for this interrupt. */
1092 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1093         count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT));
1094 #else
1095         count = 1;
1096 #endif
1097
1098         /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
1099         while ((count) && (handle->rxDataSize))
1100         {
1101 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1102             tempCount = MIN(handle->rxDataSize, count);
1103 #else
1104             tempCount = 1;
1105 #endif
1106
1107             /* Using non block API to read the data from the registers. */
1108             LPUART_ReadNonBlocking(base, handle->rxData, tempCount);
1109             handle->rxData += tempCount;
1110             handle->rxDataSize -= tempCount;
1111             count -= tempCount;
1112
1113             /* If all the data required for upper layer is ready, trigger callback. */
1114             if (!handle->rxDataSize)
1115             {
1116                 handle->rxState = kLPUART_RxIdle;
1117
1118                 if (handle->callback)
1119                 {
1120                     handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
1121                 }
1122             }
1123         }
1124
1125         /* If use RX ring buffer, receive data to ring buffer. */
1126         if (handle->rxRingBuffer)
1127         {
1128             while (count--)
1129             {
1130                 /* If RX ring buffer is full, trigger callback to notify over run. */
1131                 if (LPUART_TransferIsRxRingBufferFull(base, handle))
1132                 {
1133                     if (handle->callback)
1134                     {
1135                         handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData);
1136                     }
1137                 }
1138
1139                 /* If ring buffer is still full after callback function, the oldest data is overrided. */
1140                 if (LPUART_TransferIsRxRingBufferFull(base, handle))
1141                 {
1142                     /* Increase handle->rxRingBufferTail to make room for new data. */
1143                     if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
1144                     {
1145                         handle->rxRingBufferTail = 0U;
1146                     }
1147                     else
1148                     {
1149                         handle->rxRingBufferTail++;
1150                     }
1151                 }
1152
1153 /* Read data. */
1154 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
1155                 if (handle->isSevenDataBits)
1156                 {
1157                     handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F);
1158                 }
1159                 else
1160                 {
1161                     handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
1162                 }
1163 #else
1164                 handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
1165 #endif
1166
1167                 /* Increase handle->rxRingBufferHead. */
1168                 if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
1169                 {
1170                     handle->rxRingBufferHead = 0U;
1171                 }
1172                 else
1173                 {
1174                     handle->rxRingBufferHead++;
1175                 }
1176             }
1177         }
1178         /* If no receive requst pending, stop RX interrupt. */
1179         else if (!handle->rxDataSize)
1180         {
1181             LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
1182         }
1183         else
1184         {
1185         }
1186     }
1187
1188     /* Send data register empty and the interrupt is enabled. */
1189     if ((base->STAT & LPUART_STAT_TDRE_MASK) && (base->CTRL & LPUART_CTRL_TIE_MASK))
1190     {
1191 /* Get the bytes that available at this moment. */
1192 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1193         count = FSL_FEATURE_LPUART_FIFO_SIZEn(base) -
1194                 ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT);
1195 #else
1196         count = 1;
1197 #endif
1198
1199         while ((count) && (handle->txDataSize))
1200         {
1201 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1202             tempCount = MIN(handle->txDataSize, count);
1203 #else
1204             tempCount = 1;
1205 #endif
1206
1207             /* Using non block API to write the data to the registers. */
1208             LPUART_WriteNonBlocking(base, handle->txData, tempCount);
1209             handle->txData += tempCount;
1210             handle->txDataSize -= tempCount;
1211             count -= tempCount;
1212
1213             /* If all the data are written to data register, notify user with the callback, then TX finished. */
1214             if (!handle->txDataSize)
1215             {
1216                 handle->txState = kLPUART_TxIdle;
1217
1218                 /* Disable TX register empty interrupt. */
1219                 base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK);
1220
1221                 /* Trigger callback. */
1222                 if (handle->callback)
1223                 {
1224                     handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData);
1225                 }
1226             }
1227         }
1228     }
1229 }
1230
1231 void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle)
1232 {
1233     /* To be implemented by User. */
1234 }
1235 #if defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1
1236 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1237 void LPUART0_LPUART1_RX_DriverIRQHandler(void)
1238 {
1239     if (CLOCK_isEnabledClock(s_lpuartClock[0]))
1240     {
1241         if ((LPUART_STAT_OR_MASK & LPUART0->STAT) ||
1242             ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL)))
1243         {
1244             s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
1245         }
1246     }
1247     if (CLOCK_isEnabledClock(s_lpuartClock[1]))
1248     {
1249         if ((LPUART_STAT_OR_MASK & LPUART1->STAT) ||
1250             ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL)))
1251         {
1252             s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
1253         }
1254     }
1255 }
1256 void LPUART0_LPUART1_TX_DriverIRQHandler(void)
1257 {
1258     if (CLOCK_isEnabledClock(s_lpuartClock[0]))
1259     {
1260         if ((LPUART_STAT_OR_MASK & LPUART0->STAT) ||
1261             ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK)))
1262         {
1263             s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
1264         }
1265     }
1266     if (CLOCK_isEnabledClock(s_lpuartClock[1]))
1267     {
1268         if ((LPUART_STAT_OR_MASK & LPUART1->STAT) ||
1269             ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK)))
1270         {
1271             s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
1272         }
1273     }
1274 }
1275 #else
1276 void LPUART0_LPUART1_DriverIRQHandler(void)
1277 {
1278     if (CLOCK_isEnabledClock(s_lpuartClock[0]))
1279     {
1280         if ((LPUART_STAT_OR_MASK & LPUART0->STAT) ||
1281             ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL)) ||
1282             ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK)))
1283         {
1284             s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
1285         }
1286     }
1287     if (CLOCK_isEnabledClock(s_lpuartClock[1]))
1288     {
1289         if ((LPUART_STAT_OR_MASK & LPUART1->STAT) ||
1290             ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL)) ||
1291             ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK)))
1292         {
1293             s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
1294         }
1295     }
1296 }
1297 #endif
1298 #endif
1299
1300 #if defined(LPUART0)
1301 #if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1)
1302 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1303 void LPUART0_TX_DriverIRQHandler(void)
1304 {
1305     s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
1306 }
1307 void LPUART0_RX_DriverIRQHandler(void)
1308 {
1309     s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
1310 }
1311 #else
1312 void LPUART0_DriverIRQHandler(void)
1313 {
1314     s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
1315 }
1316 #endif
1317 #endif
1318 #endif
1319
1320 #if defined(LPUART1)
1321 #if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1)
1322 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1323 void LPUART1_TX_DriverIRQHandler(void)
1324 {
1325     s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
1326 }
1327 void LPUART1_RX_DriverIRQHandler(void)
1328 {
1329     s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
1330 }
1331 #else
1332 void LPUART1_DriverIRQHandler(void)
1333 {
1334     s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
1335 }
1336 #endif
1337 #endif
1338 #endif
1339
1340 #if defined(LPUART2)
1341 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1342 void LPUART2_TX_DriverIRQHandler(void)
1343 {
1344     s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
1345 }
1346 void LPUART2_RX_DriverIRQHandler(void)
1347 {
1348     s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
1349 }
1350 #else
1351 void LPUART2_DriverIRQHandler(void)
1352 {
1353     s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
1354 }
1355 #endif
1356 #endif
1357
1358 #if defined(LPUART3)
1359 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1360 void LPUART3_TX_DriverIRQHandler(void)
1361 {
1362     s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
1363 }
1364 void LPUART3_RX_DriverIRQHandler(void)
1365 {
1366     s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
1367 }
1368 #else
1369 void LPUART3_DriverIRQHandler(void)
1370 {
1371     s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
1372 }
1373 #endif
1374 #endif
1375
1376 #if defined(LPUART4)
1377 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1378 void LPUART4_TX_DriverIRQHandler(void)
1379 {
1380     s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
1381 }
1382 void LPUART4_RX_DriverIRQHandler(void)
1383 {
1384     s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
1385 }
1386 #else
1387 void LPUART4_DriverIRQHandler(void)
1388 {
1389     s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
1390 }
1391 #endif
1392 #endif
1393
1394 #if defined(LPUART5)
1395 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1396 void LPUART5_TX_DriverIRQHandler(void)
1397 {
1398     s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
1399 }
1400 void LPUART5_RX_DriverIRQHandler(void)
1401 {
1402     s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
1403 }
1404 #else
1405 void LPUART5_DriverIRQHandler(void)
1406 {
1407     s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
1408 }
1409 #endif
1410 #endif
1411
1412 #if defined(CM4_0_LPUART)
1413 void M4_0_LPUART_DriverIRQHandler(void)
1414 {
1415     s_lpuartIsr(CM4_0_LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_0_LPUART)]);
1416 }
1417 #endif
1418
1419 #if defined(CM4_1_LPUART)
1420 void M4_1_LPUART_DriverIRQHandler(void)
1421 {
1422     s_lpuartIsr(CM4_1_LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_1_LPUART)]);
1423 }
1424 #endif
1425
1426 #if defined(DMA_LPUART0)
1427 void DMA_UART0_INT_IRQHandler(void)
1428 {
1429     s_lpuartIsr(DMA_LPUART0, s_lpuartHandle[LPUART_GetInstance(DMA_LPUART0)]);
1430 }
1431 #endif
1432
1433 #if defined(DMA_LPUART1)
1434 void DMA_UART1_INT_IRQHandler(void)
1435 {
1436     s_lpuartIsr(DMA_LPUART1, s_lpuartHandle[LPUART_GetInstance(DMA_LPUART1)]);
1437 }
1438 #endif
1439
1440 #if defined(DMA_LPUART2)
1441 void DMA_UART2_INT_IRQHandler(void)
1442 {
1443     s_lpuartIsr(DMA_LPUART2, s_lpuartHandle[LPUART_GetInstance(DMA_LPUART2)]);
1444 }
1445 #endif
1446
1447 #if defined(DMA_LPUART3)
1448 void DMA_UART3_INT_IRQHandler(void)
1449 {
1450     s_lpuartIsr(DMA_LPUART3, s_lpuartHandle[LPUART_GetInstance(DMA_LPUART3)]);
1451 }
1452 #endif
1453
1454 #if defined(DMA_LPUART4)
1455 void DMA_UART4_INT_IRQHandler(void)
1456 {
1457     s_lpuartIsr(DMA_LPUART4, s_lpuartHandle[LPUART_GetInstance(DMA_LPUART4)]);
1458 }
1459 #endif