1 /*
2  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_lpuart.h"
10 
11 /*
12  * $Coverage Justification Reference$
13  *
14  * $Justification fsl_lpuart_c_ref_1$
15  * (osr > 3) (false) can't be not covered, because osr(osrTemp) is increased from 4U.
16  *
17  * $Justification fsl_lpuart_c_ref_2$
18  * The flag is cleared successfully during test.
19  */
20 /*******************************************************************************
21  * Definitions
22  ******************************************************************************/
23 
24 /* Component ID definition, used by tools. */
25 #ifndef FSL_COMPONENT_ID
26 #define FSL_COMPONENT_ID "platform.drivers.lpuart"
27 #endif
28 
29 /* LPUART transfer state. */
30 enum
31 {
32     kLPUART_TxIdle, /*!< TX idle. */
33     kLPUART_TxBusy, /*!< TX busy. */
34     kLPUART_RxIdle, /*!< RX idle. */
35     kLPUART_RxBusy  /*!< RX busy. */
36 };
37 
38 #if defined(LPUART_RSTS)
39 #define LPUART_RESETS_ARRAY LPUART_RSTS
40 #endif
41 
42 /*******************************************************************************
43  * Prototypes
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 address 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  * @brief Write to TX register using non-blocking method in 9bit or 10bit mode.
71  *
72  * The 10bit of data will be writen to TX register DATA.
73  * Please make sure data 10bit is valid and other bit is 0.
74  *
75  * @note This function only support 9bit or 10bit transfer.
76  *
77  * @param base LPUART peripheral base address.
78  * @param data Start address of the data to write.
79  * @param length Size of the buffer to be sent.
80  */
81 static void LPUART_WriteNonBlocking16bit(LPUART_Type *base, const uint16_t *data, size_t length);
82 
83 /*!
84  * @brief Read RX register using non-blocking method.
85  *
86  * This function reads data from the TX register directly, upper layer must make
87  * sure the RX register is full or TX FIFO has data before calling this function.
88  *
89  * @param base LPUART peripheral base address.
90  * @param data Start address of the buffer to store the received data.
91  * @param length Size of the buffer.
92  */
93 static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length);
94 /*!
95  * @brief Read RX register using non-blocking method in 9bit or 10bit mode.
96  *
97  * This function reads 10bit data from the RX register directly and stores to 16bit data.
98  *
99  * @note This function only support 9bit or 10bit transfer.
100  *
101  * @param base LPUART peripheral base address.
102  * @param data Start address of the buffer to store the received data.
103  * @param length Size of the buffer.
104  */
105 static void LPUART_ReadNonBlocking16bit(LPUART_Type *base, uint16_t *data, size_t length);
106 /*!
107  * @brief LPUART_TransferHandleIDLEIsReady handle function.
108  * This function handles when IDLE is ready.
109  *
110  * @param base LPUART peripheral base address.
111  * @param irqHandle LPUART handle pointer.
112  */
113 static void LPUART_TransferHandleIDLEReady(LPUART_Type *base, lpuart_handle_t *handle);
114 
115 /*!
116  * @brief LPUART_TransferHandleReceiveDataIsFull handle function.
117  * This function handles when receive data is full.
118  *
119  * @param base LPUART peripheral base address.
120  * @param handle LPUART handle pointer.
121  */
122 static void LPUART_TransferHandleReceiveDataFull(LPUART_Type *base, lpuart_handle_t *handle);
123 
124 /*!
125  * @brief LPUART_TransferHandleSendDataIsEmpty handle function.
126  * This function handles when send data is empty.
127  *
128  * @param base LPUART peripheral base address.
129  * @param irqHandle LPUART handle pointer.
130  */
131 static void LPUART_TransferHandleSendDataEmpty(LPUART_Type *base, lpuart_handle_t *handle);
132 
133 /*!
134  * @brief LPUART_TransferHandleTransmissionIsComplete handle function.
135  * This function handles Transmission complete and the interrupt is enabled.
136  *
137  * @param base LPUART peripheral base address.
138  * @param irqHandle LPUART handle pointer.
139  */
140 static void LPUART_TransferHandleTransmissionComplete(LPUART_Type *base, lpuart_handle_t *handle);
141 
142 /*******************************************************************************
143  * Variables
144  ******************************************************************************/
145 #if defined(LPUART_BASE_PTRS_NS)
146 static LPUART_Type *const s_lpuartBases_ns[] = LPUART_BASE_PTRS_NS;
147 #endif
148 /* Array of LPUART peripheral base address. */
149 static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS;
150 /* Array of LPUART handle. */
151 void *s_lpuartHandle[ARRAY_SIZE(s_lpuartBases)];
152 /* Array of LPUART IRQ number. */
153 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
154 static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS;
155 const IRQn_Type s_lpuartTxIRQ[]        = LPUART_TX_IRQS;
156 #else
157 const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS;
158 #endif
159 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
160 /* Array of LPUART clock name. */
161 static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS;
162 
163 #if defined(LPUART_PERIPH_CLOCKS)
164 /* Array of LPUART functional clock name. */
165 static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS;
166 #endif
167 
168 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
169 
170 /* LPUART ISR for transactional APIs. */
171 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
172 lpuart_isr_t s_lpuartIsr[ARRAY_SIZE(s_lpuartBases)] = {[0 ...(ARRAY_SIZE(s_lpuartBases) - 1)] =
173                                                            (lpuart_isr_t)DefaultISR};
174 #else
175 lpuart_isr_t s_lpuartIsr[ARRAY_SIZE(s_lpuartBases)];
176 #endif
177 
178 #if defined(LPUART_RESETS_ARRAY)
179 /* Reset array */
180 static const reset_ip_name_t s_lpuartResets[] = LPUART_RESETS_ARRAY;
181 #endif
182 
183 /*******************************************************************************
184  * Code
185  ******************************************************************************/
186 /*!
187  * brief Get the LPUART instance from peripheral base address.
188  *
189  * param base LPUART peripheral base address.
190  * return LPUART instance.
191  */
LPUART_GetInstance(LPUART_Type * base)192 uint32_t LPUART_GetInstance(LPUART_Type *base)
193 {
194     uint32_t instance;
195 
196     /* Find the instance index from base address mappings. */
197     for (instance = 0U; instance < ARRAY_SIZE(s_lpuartBases); instance++)
198     {
199         if (s_lpuartBases[instance] == base)
200         {
201             return instance;
202         }
203     }
204 #if defined(LPUART_BASE_PTRS_NS)
205     /* Find the instance index from base address mappings. */
206     for (instance = 0U; instance < ARRAY_SIZE(s_lpuartBases_ns); instance++)
207     {
208         if (s_lpuartBases_ns[instance] == base)
209         {
210             return instance;
211         }
212     }
213     assert(instance < ARRAY_SIZE(s_lpuartBases_ns));
214 #else
215     assert(instance < ARRAY_SIZE(s_lpuartBases));
216 #endif
217 
218     return instance;
219 }
220 
221 /*!
222  * brief Get the length of received data in RX ring buffer.
223  *
224  * userData handle LPUART handle pointer.
225  * return Length of received data in RX ring buffer.
226  */
LPUART_TransferGetRxRingBufferLength(LPUART_Type * base,lpuart_handle_t * handle)227 size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle)
228 {
229     assert(NULL != handle);
230 
231     size_t size;
232     size_t tmpRxRingBufferSize   = handle->rxRingBufferSize;
233     uint16_t tmpRxRingBufferTail = handle->rxRingBufferTail;
234     uint16_t tmpRxRingBufferHead = handle->rxRingBufferHead;
235 
236     if (tmpRxRingBufferTail > tmpRxRingBufferHead)
237     {
238         size = ((size_t)tmpRxRingBufferHead + tmpRxRingBufferSize - (size_t)tmpRxRingBufferTail);
239     }
240     else
241     {
242         size = ((size_t)tmpRxRingBufferHead - (size_t)tmpRxRingBufferTail);
243     }
244 
245     return size;
246 }
247 
LPUART_TransferIsRxRingBufferFull(LPUART_Type * base,lpuart_handle_t * handle)248 static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle)
249 {
250     assert(NULL != handle);
251 
252     bool full;
253 
254     if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U))
255     {
256         full = true;
257     }
258     else
259     {
260         full = false;
261     }
262     return full;
263 }
264 
LPUART_WriteNonBlocking(LPUART_Type * base,const uint8_t * data,size_t length)265 static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
266 {
267     assert(NULL != data);
268 
269     size_t i;
270 
271     /* The Non Blocking write data API assume user have ensured there is enough space in
272     peripheral to write. */
273     for (i = 0; i < length; i++)
274     {
275         base->DATA = data[i];
276     }
277 }
LPUART_WriteNonBlocking16bit(LPUART_Type * base,const uint16_t * data,size_t length)278 static void LPUART_WriteNonBlocking16bit(LPUART_Type *base, const uint16_t *data, size_t length)
279 {
280     assert(NULL != data);
281 
282     size_t i;
283 
284     /* The Non Blocking write data API assume user have ensured there is enough space in
285     peripheral to write. */
286     for (i = 0; i < length; i++)
287     {
288         base->DATA = data[i];
289     }
290 }
291 
LPUART_ReadNonBlocking(LPUART_Type * base,uint8_t * data,size_t length)292 static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length)
293 {
294     assert(NULL != data);
295 
296     size_t i;
297 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
298     uint32_t ctrl        = base->CTRL;
299     bool isSevenDataBits = (((ctrl & LPUART_CTRL_M7_MASK) != 0U) ||
300                             (((ctrl & LPUART_CTRL_M_MASK) == 0U) && ((ctrl & LPUART_CTRL_PE_MASK) != 0U)));
301 #endif
302 
303     /* The Non Blocking read data API assume user have ensured there is enough space in
304     peripheral to write. */
305     for (i = 0; i < length; i++)
306     {
307 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
308         if (isSevenDataBits)
309         {
310             data[i] = (uint8_t)(base->DATA & 0x7FU);
311         }
312         else
313         {
314             data[i] = (uint8_t)base->DATA;
315         }
316 #else
317         data[i] = (uint8_t)(base->DATA);
318 #endif
319     }
320 }
321 
LPUART_ReadNonBlocking16bit(LPUART_Type * base,uint16_t * data,size_t length)322 static void LPUART_ReadNonBlocking16bit(LPUART_Type *base, uint16_t *data, size_t length)
323 {
324     assert(NULL != data);
325 
326     size_t i;
327     /* The Non Blocking read data API assume user have ensured there is enough space in
328     peripheral to write. */
329     for (i = 0; i < length; i++)
330     {
331         data[i] = (uint16_t)(base->DATA & 0x03FFU);
332     }
333 }
334 
335 /*!
336  * brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
337  *
338  * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
339  * to configure the configuration structure and get the default configuration.
340  * The example below shows how to use this API to configure the LPUART.
341  * code
342  *  lpuart_config_t lpuartConfig;
343  *  lpuartConfig.baudRate_Bps = 115200U;
344  *  lpuartConfig.parityMode = kLPUART_ParityDisabled;
345  *  lpuartConfig.dataBitsCount = kLPUART_EightDataBits;
346  *  lpuartConfig.isMsb = false;
347  *  lpuartConfig.stopBitCount = kLPUART_OneStopBit;
348  *  lpuartConfig.txFifoWatermark = 0;
349  *  lpuartConfig.rxFifoWatermark = 1;
350  *  LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
351  * endcode
352  *
353  * param base LPUART peripheral base address.
354  * param config Pointer to a user-defined configuration structure.
355  * param srcClock_Hz LPUART clock source frequency in HZ.
356  * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source.
357  * retval kStatus_Success LPUART initialize succeed
358  */
LPUART_Init(LPUART_Type * base,const lpuart_config_t * config,uint32_t srcClock_Hz)359 status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz)
360 {
361     assert(NULL != config);
362     assert(0U < config->baudRate_Bps);
363 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
364     assert((uint8_t)FSL_FEATURE_LPUART_FIFO_SIZEn(base) > config->txFifoWatermark);
365     assert((uint8_t)FSL_FEATURE_LPUART_FIFO_SIZEn(base) > config->rxFifoWatermark);
366 #endif
367 
368     status_t status = kStatus_Success;
369     uint32_t temp;
370     uint16_t sbr, sbrTemp;
371     uint8_t osr, osrTemp;
372     uint32_t tempDiff, calculatedBaud, baudDiff;
373 
374     /* This LPUART instantiation uses a slightly different baud rate calculation
375      * The idea is to use the best OSR (over-sampling rate) possible
376      * Note, OSR is typically hard-set to 16 in other LPUART instantiations
377      * loop to find the best OSR value possible, one that generates minimum baudDiff
378      * iterate through the rest of the supported values of OSR */
379 
380     baudDiff = config->baudRate_Bps;
381     osr      = 0U;
382     sbr      = 0U;
383     for (osrTemp = 4U; osrTemp <= 32U; osrTemp++)
384     {
385         /* calculate the temporary sbr value   */
386         sbrTemp = (uint16_t)((srcClock_Hz * 2U / (config->baudRate_Bps * (uint32_t)osrTemp) + 1U) / 2U);
387         /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
388         if (sbrTemp == 0U)
389         {
390             sbrTemp = 1U;
391         }
392         else if (sbrTemp > LPUART_BAUD_SBR_MASK)
393         {
394             sbrTemp = LPUART_BAUD_SBR_MASK;
395         }
396         else
397         {
398             /* Avoid MISRA 15.7 */
399         }
400         /* Calculate the baud rate based on the temporary OSR and SBR values */
401         calculatedBaud = (srcClock_Hz / ((uint32_t)osrTemp * (uint32_t)sbrTemp));
402         tempDiff       = calculatedBaud > config->baudRate_Bps ? (calculatedBaud - config->baudRate_Bps) :
403                                                                  (config->baudRate_Bps - calculatedBaud);
404 
405         if (tempDiff <= baudDiff)
406         {
407             baudDiff = tempDiff;
408             osr      = osrTemp; /* update and store the best OSR value calculated */
409             sbr      = sbrTemp; /* update store the best SBR value calculated */
410         }
411     }
412 
413     /* Check to see if actual baud rate is within 3% of desired baud rate
414      * based on the best calculate OSR value */
415     if (baudDiff > ((config->baudRate_Bps / 100U) * 3U))
416     {
417         /* Unacceptable baud rate difference of more than 3%*/
418         status = kStatus_LPUART_BaudrateNotSupport;
419     }
420     else
421     {
422 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
423 
424         uint32_t instance = LPUART_GetInstance(base);
425 
426         /* Enable lpuart clock */
427         (void)CLOCK_EnableClock(s_lpuartClock[instance]);
428 #if defined(LPUART_PERIPH_CLOCKS)
429         (void)CLOCK_EnableClock(s_lpuartPeriphClocks[instance]);
430 #endif
431 
432 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
433 
434 #if defined(LPUART_RESETS_ARRAY)
435         RESET_ReleasePeripheralReset(s_lpuartResets[LPUART_GetInstance(base)]);
436 #endif
437 
438 #if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
439         /*Reset all internal logic and registers, except the Global Register */
440         LPUART_SoftwareReset(base);
441 #else
442         /* Disable LPUART TX RX before setting. */
443         base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
444 #endif
445 
446         temp = base->BAUD;
447 
448         /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
449          * If so, then "BOTHEDGE" sampling must be turned on */
450         /*
451          * $Branch Coverage Justification$
452          * $ref fsl_lpuart_c_ref_1$
453          */
454         if ((osr > 3U) && (osr < 8U))
455         {
456             temp |= LPUART_BAUD_BOTHEDGE_MASK;
457         }
458 
459         /* program the osr value (bit value is one less than actual value) */
460         temp &= ~LPUART_BAUD_OSR_MASK;
461         temp |= LPUART_BAUD_OSR((uint32_t)osr - 1UL);
462 
463         /* write the sbr value to the BAUD registers */
464         temp &= ~LPUART_BAUD_SBR_MASK;
465         base->BAUD = temp | LPUART_BAUD_SBR(sbr);
466 
467         /* Set bit count and parity mode. */
468         base->BAUD &= ~LPUART_BAUD_M10_MASK;
469 
470         temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK |
471                               LPUART_CTRL_IDLECFG_MASK);
472 
473         temp |= (uint8_t)config->parityMode | LPUART_CTRL_IDLECFG(config->rxIdleConfig) |
474                 LPUART_CTRL_ILT(config->rxIdleType);
475 
476 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
477         if (kLPUART_SevenDataBits == config->dataBitsCount)
478         {
479             if (kLPUART_ParityDisabled != config->parityMode)
480             {
481                 temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */
482             }
483             else
484             {
485                 temp |= LPUART_CTRL_M7_MASK;
486             }
487         }
488         else
489 #endif
490         {
491             if (kLPUART_ParityDisabled != config->parityMode)
492             {
493                 temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */
494             }
495         }
496 
497         base->CTRL = temp;
498 
499 #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
500         /* set stop bit per char */
501         temp       = base->BAUD & ~LPUART_BAUD_SBNS_MASK;
502         base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount);
503 #endif
504 
505 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
506         /* Set tx/rx WATER watermark
507            Note:
508            Take care of the RX FIFO, RX interrupt request only assert when received bytes
509            equal or more than RX water mark, there is potential issue if RX water
510            mark larger than 1.
511            For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
512            5 bytes are received. the last byte will be saved in FIFO but not trigger
513            RX interrupt because the water mark is 2.
514          */
515         base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16U) | config->txFifoWatermark);
516 
517         /* Enable tx/rx FIFO */
518         base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK);
519 
520         /* Flush FIFO */
521         base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK);
522 #endif
523 
524         /* Clear all status flags */
525         temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
526                 LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
527 
528 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
529         temp |= LPUART_STAT_LBKDIF_MASK;
530 #endif
531 
532 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
533         temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
534 #endif
535 
536 #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
537         /* Set the CTS configuration/TX CTS source. */
538         base->MODIR |= LPUART_MODIR_TXCTSC(config->txCtsConfig) | LPUART_MODIR_TXCTSSRC(config->txCtsSource);
539         if (true == config->enableRxRTS)
540         {
541             /* Enable the receiver RTS(request-to-send) function. */
542             base->MODIR |= LPUART_MODIR_RXRTSE_MASK;
543         }
544         if (true == config->enableTxCTS)
545         {
546             /* Enable the CTS(clear-to-send) function. */
547             base->MODIR |= LPUART_MODIR_TXCTSE_MASK;
548         }
549 #endif
550 
551         /* Set data bits order. */
552         if (true == config->isMsb)
553         {
554             temp |= LPUART_STAT_MSBF_MASK;
555         }
556         else
557         {
558             temp &= ~LPUART_STAT_MSBF_MASK;
559         }
560 
561         base->STAT |= temp;
562 
563         /* Enable TX/RX base on configure structure. */
564         temp = base->CTRL;
565         if (true == config->enableTx)
566         {
567             temp |= LPUART_CTRL_TE_MASK;
568         }
569 
570         if (true == config->enableRx)
571         {
572             temp |= LPUART_CTRL_RE_MASK;
573         }
574 
575         base->CTRL = temp;
576     }
577 
578     return status;
579 }
580 /*!
581  * brief Deinitializes a LPUART instance.
582  *
583  * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock.
584  *
585  * param base LPUART peripheral base address.
586  */
LPUART_Deinit(LPUART_Type * base)587 void LPUART_Deinit(LPUART_Type *base)
588 {
589     uint32_t temp;
590 
591 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
592     /* Wait tx FIFO send out*/
593     while (0U != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT))
594     {
595     }
596 #endif
597     /* Wait last char shift out */
598     while (0U == (base->STAT & LPUART_STAT_TC_MASK))
599     {
600     }
601 
602     /* Clear all status flags */
603     temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
604             LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
605 
606 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
607     temp |= LPUART_STAT_LBKDIF_MASK;
608 #endif
609 
610 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
611     temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
612 #endif
613 
614     base->STAT |= temp;
615 
616     /* Disable the module. */
617     base->CTRL = 0U;
618 
619 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
620     uint32_t instance = LPUART_GetInstance(base);
621 
622     /* Disable lpuart clock */
623     (void)CLOCK_DisableClock(s_lpuartClock[instance]);
624 
625 #if defined(LPUART_PERIPH_CLOCKS)
626     (void)CLOCK_DisableClock(s_lpuartPeriphClocks[instance]);
627 #endif
628 
629 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
630 }
631 
632 /*!
633  * brief Gets the default configuration structure.
634  *
635  * This function initializes the LPUART configuration structure to a default value. The default
636  * values are:
637  *   lpuartConfig->baudRate_Bps = 115200U;
638  *   lpuartConfig->parityMode = kLPUART_ParityDisabled;
639  *   lpuartConfig->dataBitsCount = kLPUART_EightDataBits;
640  *   lpuartConfig->isMsb = false;
641  *   lpuartConfig->stopBitCount = kLPUART_OneStopBit;
642  *   lpuartConfig->txFifoWatermark = 0;
643  *   lpuartConfig->rxFifoWatermark = 1;
644  *   lpuartConfig->rxIdleType = kLPUART_IdleTypeStartBit;
645  *   lpuartConfig->rxIdleConfig = kLPUART_IdleCharacter1;
646  *   lpuartConfig->enableTx = false;
647  *   lpuartConfig->enableRx = false;
648  *
649  * param config Pointer to a configuration structure.
650  */
LPUART_GetDefaultConfig(lpuart_config_t * config)651 void LPUART_GetDefaultConfig(lpuart_config_t *config)
652 {
653     assert(NULL != config);
654 
655     /* Initializes the configure structure to zero. */
656     (void)memset(config, 0, sizeof(*config));
657 
658     config->baudRate_Bps  = 115200U;
659     config->parityMode    = kLPUART_ParityDisabled;
660     config->dataBitsCount = kLPUART_EightDataBits;
661     config->isMsb         = false;
662 #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
663     config->stopBitCount = kLPUART_OneStopBit;
664 #endif
665 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
666     config->txFifoWatermark = 0U;
667     config->rxFifoWatermark = 0U;
668 #endif
669 #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
670     config->enableRxRTS = false;
671     config->enableTxCTS = false;
672     config->txCtsConfig = kLPUART_CtsSampleAtStart;
673     config->txCtsSource = kLPUART_CtsSourcePin;
674 #endif
675     config->rxIdleType   = kLPUART_IdleTypeStartBit;
676     config->rxIdleConfig = kLPUART_IdleCharacter1;
677     config->enableTx     = false;
678     config->enableRx     = false;
679 }
680 
681 /*!
682  * brief Sets the LPUART instance baudrate.
683  *
684  * This function configures the LPUART module baudrate. This function is used to update
685  * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init.
686  * code
687  *  LPUART_SetBaudRate(LPUART1, 115200U, 20000000U);
688  * endcode
689  *
690  * param base LPUART peripheral base address.
691  * param baudRate_Bps LPUART baudrate to be set.
692  * param srcClock_Hz LPUART clock source frequency in HZ.
693  * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source.
694  * retval kStatus_Success Set baudrate succeeded.
695  */
LPUART_SetBaudRate(LPUART_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)696 status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
697 {
698     assert(0U < baudRate_Bps);
699 
700     status_t status = kStatus_Success;
701     uint32_t temp, oldCtrl;
702     uint16_t sbr, sbrTemp;
703     uint8_t osr, osrTemp;
704     uint32_t tempDiff, calculatedBaud, baudDiff;
705 
706     /* This LPUART instantiation uses a slightly different baud rate calculation
707      * The idea is to use the best OSR (over-sampling rate) possible
708      * Note, OSR is typically hard-set to 16 in other LPUART instantiations
709      * loop to find the best OSR value possible, one that generates minimum baudDiff
710      * iterate through the rest of the supported values of OSR */
711 
712     baudDiff = baudRate_Bps;
713     osr      = 0U;
714     sbr      = 0U;
715     for (osrTemp = 4U; osrTemp <= 32U; osrTemp++)
716     {
717         /* calculate the temporary sbr value   */
718         sbrTemp = (uint16_t)((srcClock_Hz * 2U / (baudRate_Bps * (uint32_t)osrTemp) + 1U) / 2U);
719         /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
720         if (sbrTemp == 0U)
721         {
722             sbrTemp = 1U;
723         }
724         else if (sbrTemp > LPUART_BAUD_SBR_MASK)
725         {
726             sbrTemp = LPUART_BAUD_SBR_MASK;
727         }
728         else
729         {
730             /* Avoid MISRA 15.7 */
731         }
732         /* Calculate the baud rate based on the temporary OSR and SBR values */
733         calculatedBaud = srcClock_Hz / ((uint32_t)osrTemp * (uint32_t)sbrTemp);
734 
735         tempDiff = calculatedBaud > baudRate_Bps ? (calculatedBaud - baudRate_Bps) : (baudRate_Bps - calculatedBaud);
736 
737         if (tempDiff <= baudDiff)
738         {
739             baudDiff = tempDiff;
740             osr      = osrTemp; /* update and store the best OSR value calculated */
741             sbr      = sbrTemp; /* update store the best SBR value calculated */
742         }
743     }
744 
745     /* Check to see if actual baud rate is within 3% of desired baud rate
746      * based on the best calculate OSR value */
747     if (baudDiff < (uint32_t)((baudRate_Bps / 100U) * 3U))
748     {
749         /* Store CTRL before disable Tx and Rx */
750         oldCtrl = base->CTRL;
751 
752         /* Disable LPUART TX RX before setting. */
753         base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
754 
755         temp = base->BAUD;
756 
757         /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
758          * If so, then "BOTHEDGE" sampling must be turned on */
759         /*
760          * $Branch Coverage Justification$
761          * $ref fsl_lpuart_c_ref_1$
762          */
763         if ((osr > 3U) && (osr < 8U))
764         {
765             temp |= LPUART_BAUD_BOTHEDGE_MASK;
766         }
767 
768         /* program the osr value (bit value is one less than actual value) */
769         temp &= ~LPUART_BAUD_OSR_MASK;
770         temp |= LPUART_BAUD_OSR((uint32_t)osr - 1UL);
771 
772         /* write the sbr value to the BAUD registers */
773         temp &= ~LPUART_BAUD_SBR_MASK;
774         base->BAUD = temp | LPUART_BAUD_SBR(sbr);
775 
776         /* Restore CTRL. */
777         base->CTRL = oldCtrl;
778     }
779     else
780     {
781         /* Unacceptable baud rate difference of more than 3%*/
782         status = kStatus_LPUART_BaudrateNotSupport;
783     }
784 
785     return status;
786 }
787 
788 /*!
789  * brief Enable 9-bit data mode for LPUART.
790  *
791  * This function set the 9-bit mode for LPUART module. The 9th bit is not used for parity thus can be modified by user.
792  *
793  * param base LPUART peripheral base address.
794  * param enable true to enable, flase to disable.
795  */
LPUART_Enable9bitMode(LPUART_Type * base,bool enable)796 void LPUART_Enable9bitMode(LPUART_Type *base, bool enable)
797 {
798     assert(base != NULL);
799 
800     uint32_t temp = 0U;
801 
802     if (enable)
803     {
804         /* Set LPUART_CTRL_M for 9-bit mode, clear LPUART_CTRL_PE to disable parity. */
805         temp = base->CTRL & ~((uint32_t)LPUART_CTRL_PE_MASK | (uint32_t)LPUART_CTRL_M_MASK);
806         temp |= (uint32_t)LPUART_CTRL_M_MASK;
807         base->CTRL = temp;
808     }
809     else
810     {
811         /* Clear LPUART_CTRL_M. */
812         base->CTRL &= ~(uint32_t)LPUART_CTRL_M_MASK;
813     }
814 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
815     /* Clear LPUART_CTRL_M7 to disable 7-bit mode. */
816     base->CTRL &= ~(uint32_t)LPUART_CTRL_M7_MASK;
817 #endif
818 #if defined(FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT
819     /* Clear LPUART_BAUD_M10 to disable 10-bit mode. */
820     base->BAUD &= ~(uint32_t)LPUART_BAUD_M10_MASK;
821 #endif
822 }
823 
824 /*!
825  * brief Transmit an address frame in 9-bit data mode.
826  *
827  * param base LPUART peripheral base address.
828  * param address LPUART slave address.
829  */
LPUART_SendAddress(LPUART_Type * base,uint8_t address)830 void LPUART_SendAddress(LPUART_Type *base, uint8_t address)
831 {
832     assert(base != NULL);
833 
834     uint32_t temp = base->DATA & 0xFFFFFC00UL;
835     temp |= ((uint32_t)address | (1UL << LPUART_DATA_R8T8_SHIFT));
836     base->DATA = temp;
837 }
838 
839 /*!
840  * brief Enables LPUART interrupts according to a provided mask.
841  *
842  * This function enables the LPUART interrupts according to a provided mask. The mask
843  * is a logical OR of enumeration members. See the ref _lpuart_interrupt_enable.
844  * This examples shows how to enable TX empty interrupt and RX full interrupt:
845  * code
846  *     LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
847  * endcode
848  *
849  * param base LPUART peripheral base address.
850  * param mask The interrupts to enable. Logical OR of ref _lpuart_interrupt_enable.
851  */
LPUART_EnableInterrupts(LPUART_Type * base,uint32_t mask)852 void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask)
853 {
854     uint32_t s_atomicOldInt;
855     /* Only consider the real interrupt enable bits. */
856     mask &= (uint32_t)kLPUART_AllInterruptEnable;
857 
858     /* Check int enable bits in base->BAUD */
859     uint32_t baudRegMask = 0UL;
860 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
861     baudRegMask |= ((mask << 8U) & LPUART_BAUD_LBKDIE_MASK);
862     /* Clear bit 7 from mask */
863     mask &= ~(uint32_t)kLPUART_LinBreakInterruptEnable;
864 #endif
865     baudRegMask |= ((mask << 8U) & LPUART_BAUD_RXEDGIE_MASK);
866     /* Clear bit 6 from mask */
867     mask &= ~(uint32_t)kLPUART_RxActiveEdgeInterruptEnable;
868 
869     s_atomicOldInt = DisableGlobalIRQ();
870     base->BAUD |= baudRegMask;
871     EnableGlobalIRQ(s_atomicOldInt);
872 
873 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
874     /* Check int enable bits in base->FIFO */
875 
876     s_atomicOldInt = DisableGlobalIRQ();
877     base->FIFO     = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) |
878                  (mask & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
879     EnableGlobalIRQ(s_atomicOldInt);
880 
881     /* Clear bit 9 and bit 8 from mask */
882     mask &= ~((uint32_t)kLPUART_TxFifoOverflowInterruptEnable | (uint32_t)kLPUART_RxFifoUnderflowInterruptEnable);
883 #endif
884 
885     /* Set int enable bits in base->CTRL */
886     s_atomicOldInt = DisableGlobalIRQ();
887     base->CTRL |= mask;
888     EnableGlobalIRQ(s_atomicOldInt);
889 }
890 
891 /*!
892  * brief Disables  LPUART interrupts according to a provided mask.
893  *
894  * This function disables the LPUART interrupts according to a provided mask. The mask
895  * is a logical OR of enumeration members. See ref _lpuart_interrupt_enable.
896  * This example shows how to disable the TX empty interrupt and RX full interrupt:
897  * code
898  *     LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
899  * endcode
900  *
901  * param base LPUART peripheral base address.
902  * param mask The interrupts to disable. Logical OR of ref _lpuart_interrupt_enable.
903  */
LPUART_DisableInterrupts(LPUART_Type * base,uint32_t mask)904 void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask)
905 {
906     uint32_t s_atomicOldInt;
907     /* Only consider the real interrupt enable bits. */
908     mask &= (uint32_t)kLPUART_AllInterruptEnable;
909 
910     /* Clear int enable bits in base->BAUD */
911     uint32_t baudRegMask = 0UL;
912 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
913     baudRegMask |= ((mask << 8U) & LPUART_BAUD_LBKDIE_MASK);
914     /* Clear bit 7 from mask */
915     mask &= ~(uint32_t)kLPUART_LinBreakInterruptEnable;
916 #endif
917     baudRegMask |= ((mask << 8U) & LPUART_BAUD_RXEDGIE_MASK);
918     /* Clear bit 6 from mask */
919     mask &= ~(uint32_t)kLPUART_RxActiveEdgeInterruptEnable;
920 
921     s_atomicOldInt = DisableGlobalIRQ();
922     base->BAUD &= ~baudRegMask;
923     EnableGlobalIRQ(s_atomicOldInt);
924 
925 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
926     /* Clear int enable bits in base->FIFO */
927 
928     s_atomicOldInt = DisableGlobalIRQ();
929     base->FIFO     = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) &
930                  ~(mask & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
931     EnableGlobalIRQ(s_atomicOldInt);
932     /* Clear bit 9 and bit 8 from mask */
933     mask &= ~((uint32_t)kLPUART_TxFifoOverflowInterruptEnable | (uint32_t)kLPUART_RxFifoUnderflowInterruptEnable);
934 #endif
935 
936     /* Clear int enable bits in base->CTRL */
937     s_atomicOldInt = DisableGlobalIRQ();
938     base->CTRL &= ~mask;
939     EnableGlobalIRQ(s_atomicOldInt);
940 }
941 
942 /*!
943  * brief Gets enabled LPUART interrupts.
944  *
945  * This function gets the enabled LPUART interrupts. The enabled interrupts are returned
946  * as the logical OR value of the enumerators ref _lpuart_interrupt_enable. To check
947  * a specific interrupt enable status, compare the return value with enumerators
948  * in ref _lpuart_interrupt_enable.
949  * For example, to check whether the TX empty interrupt is enabled:
950  * code
951  *     uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1);
952  *
953  *     if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)
954  *     {
955  *         ...
956  *     }
957  * endcode
958  *
959  * param base LPUART peripheral base address.
960  * return LPUART interrupt flags which are logical OR of the enumerators in ref _lpuart_interrupt_enable.
961  */
LPUART_GetEnabledInterrupts(LPUART_Type * base)962 uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base)
963 {
964     /* Check int enable bits in base->CTRL */
965     uint32_t temp = (uint32_t)(base->CTRL & (uint32_t)kLPUART_AllInterruptEnable);
966 
967     /* Check int enable bits in base->BAUD */
968     temp = (temp & ~(uint32_t)kLPUART_RxActiveEdgeInterruptEnable) | ((base->BAUD & LPUART_BAUD_RXEDGIE_MASK) >> 8U);
969 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
970     temp = (temp & ~(uint32_t)kLPUART_LinBreakInterruptEnable) | ((base->BAUD & LPUART_BAUD_LBKDIE_MASK) >> 8U);
971 #endif
972 
973 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
974     /* Check int enable bits in base->FIFO */
975     temp =
976         (temp & ~((uint32_t)kLPUART_TxFifoOverflowInterruptEnable | (uint32_t)kLPUART_RxFifoUnderflowInterruptEnable)) |
977         (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
978 #endif
979 
980     return temp;
981 }
982 
983 /*!
984  * brief Gets LPUART status flags.
985  *
986  * This function gets all LPUART status flags. The flags are returned as the logical
987  * OR value of the enumerators ref _lpuart_flags. To check for a specific status,
988  * compare the return value with enumerators in the ref _lpuart_flags.
989  * For example, to check whether the TX is empty:
990  * code
991  *     if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1))
992  *     {
993  *         ...
994  *     }
995  * endcode
996  *
997  * param base LPUART peripheral base address.
998  * return LPUART status flags which are ORed by the enumerators in the _lpuart_flags.
999  */
LPUART_GetStatusFlags(LPUART_Type * base)1000 uint32_t LPUART_GetStatusFlags(LPUART_Type *base)
1001 {
1002     uint32_t temp;
1003     temp = base->STAT;
1004 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1005     temp |= (base->FIFO &
1006              (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >>
1007             16U;
1008 #endif
1009     /* Only keeps the status bits */
1010     temp &= (uint32_t)kLPUART_AllFlags;
1011     return temp;
1012 }
1013 
1014 /*!
1015  * brief Clears status flags with a provided mask.
1016  *
1017  * This function clears LPUART status flags with a provided mask. Automatically cleared flags
1018  * can't be cleared by this function.
1019  * Flags that can only cleared or set by hardware are:
1020  *    kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag,
1021  *    kLPUART_RxActiveFlag, kLPUART_NoiseErrorFlag, kLPUART_ParityErrorFlag,
1022  *    kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag
1023  * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects.
1024  *
1025  * param base LPUART peripheral base address.
1026  * param mask the status flags to be cleared. The user can use the enumerators in the
1027  *  _lpuart_status_flag_t to do the OR operation and get the mask.
1028  * return 0 succeed, others failed.
1029  * retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but
1030  *         it is cleared automatically by hardware.
1031  * retval kStatus_Success Status in the mask are cleared.
1032  */
LPUART_ClearStatusFlags(LPUART_Type * base,uint32_t mask)1033 status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask)
1034 {
1035     uint32_t temp;
1036     status_t status;
1037 
1038     /* Only deal with the clearable flags */
1039     mask &= (uint32_t)kLPUART_AllClearFlags;
1040 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1041     /* Status bits in FIFO register */
1042     if ((mask & ((uint32_t)kLPUART_TxFifoOverflowFlag | (uint32_t)kLPUART_RxFifoUnderflowFlag)) != 0U)
1043     {
1044         /* Get the FIFO register value and mask the rx/tx FIFO flush bits and the status bits that can be W1C in case
1045            they are written 1 accidentally. */
1046         temp = (uint32_t)base->FIFO;
1047         temp &= (uint32_t)(~(LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK | LPUART_FIFO_TXOF_MASK |
1048                              LPUART_FIFO_RXUF_MASK));
1049         temp |= (mask << 16U) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK);
1050         base->FIFO = temp;
1051     }
1052 #endif
1053     /* Status bits in STAT register */
1054     /* First get the STAT register value and mask all the bits that not represent status, then OR with the status bit
1055      * that is to be W1C */
1056     temp       = (base->STAT & 0x3E000000UL) | mask;
1057     base->STAT = temp;
1058     /* If some flags still pending. */
1059     if (0U != (mask & LPUART_GetStatusFlags(base)))
1060     {
1061         status = kStatus_LPUART_FlagCannotClearManually;
1062     }
1063     else
1064     {
1065         status = kStatus_Success;
1066     }
1067 
1068     return status;
1069 }
1070 
1071 /*!
1072  * brief Writes to the transmitter register using a blocking method.
1073  *
1074  * This function polls the transmitter register, first waits for the register to be empty or TX FIFO to have room,
1075  * and writes data to the transmitter buffer, then waits for the data to be sent out to bus.
1076  *
1077  * param base LPUART peripheral base address.
1078  * param data Start address of the data to write.
1079  * param length Size of the data to write.
1080  * retval kStatus_LPUART_Timeout Transmission timed out and was aborted.
1081  * retval kStatus_Success Successfully wrote all data.
1082  */
LPUART_WriteBlocking(LPUART_Type * base,const uint8_t * data,size_t length)1083 status_t LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
1084 {
1085     assert(NULL != data);
1086 
1087     const uint8_t *dataAddress = data;
1088     size_t transferSize        = length;
1089 
1090 #if UART_RETRY_TIMES
1091     uint32_t waitTimes;
1092 #endif
1093 
1094     while (0U != transferSize)
1095     {
1096 #if UART_RETRY_TIMES
1097         waitTimes = UART_RETRY_TIMES;
1098         while ((0U == (base->STAT & LPUART_STAT_TDRE_MASK)) && (0U != --waitTimes))
1099 #else
1100         while (0U == (base->STAT & LPUART_STAT_TDRE_MASK))
1101 #endif
1102         {
1103         }
1104 #if UART_RETRY_TIMES
1105         if (0U == waitTimes)
1106         {
1107             return kStatus_LPUART_Timeout;
1108         }
1109 #endif
1110         base->DATA = *(dataAddress);
1111         dataAddress++;
1112         transferSize--;
1113     }
1114     /* Ensure all the data in the transmit buffer are sent out to bus. */
1115 #if UART_RETRY_TIMES
1116     waitTimes = UART_RETRY_TIMES;
1117     while ((0U == (base->STAT & LPUART_STAT_TC_MASK)) && (0U != --waitTimes))
1118 #else
1119     while (0U == (base->STAT & LPUART_STAT_TC_MASK))
1120 #endif
1121     {
1122     }
1123 #if UART_RETRY_TIMES
1124     if (0U == waitTimes)
1125     {
1126         return kStatus_LPUART_Timeout;
1127     }
1128 #endif
1129     return kStatus_Success;
1130 }
1131 /*!
1132  * brief Writes to the transmitter register using a blocking method in 9bit or 10bit mode.
1133  *
1134  * note This function only support 9bit or 10bit transfer.
1135  *       Please make sure only 10bit of data is valid and other bits are 0.
1136  *
1137  * param base LPUART peripheral base address.
1138  * param data Start address of the data to write.
1139  * param length Size of the data to write.
1140  * retval kStatus_LPUART_Timeout Transmission timed out and was aborted.
1141  * retval kStatus_Success Successfully wrote all data.
1142  */
LPUART_WriteBlocking16bit(LPUART_Type * base,const uint16_t * data,size_t length)1143 status_t LPUART_WriteBlocking16bit(LPUART_Type *base, const uint16_t *data, size_t length)
1144 {
1145     assert(NULL != data);
1146 
1147     const uint16_t *dataAddress = data;
1148     size_t transferSize         = length;
1149 
1150 #if UART_RETRY_TIMES
1151     uint32_t waitTimes;
1152 #endif
1153 
1154     while (0U != transferSize)
1155     {
1156 #if UART_RETRY_TIMES
1157         waitTimes = UART_RETRY_TIMES;
1158         while ((0U == (base->STAT & LPUART_STAT_TDRE_MASK)) && (0U != --waitTimes))
1159 #else
1160         while (0U == (base->STAT & LPUART_STAT_TDRE_MASK))
1161 #endif
1162         {
1163         }
1164 #if UART_RETRY_TIMES
1165         if (0U == waitTimes)
1166         {
1167             return kStatus_LPUART_Timeout;
1168         }
1169 #endif
1170         base->DATA = *(dataAddress);
1171         dataAddress++;
1172         transferSize--;
1173     }
1174     /* Ensure all the data in the transmit buffer are sent out to bus. */
1175 #if UART_RETRY_TIMES
1176     waitTimes = UART_RETRY_TIMES;
1177     while ((0U == (base->STAT & LPUART_STAT_TC_MASK)) && (0U != --waitTimes))
1178 #else
1179     while (0U == (base->STAT & LPUART_STAT_TC_MASK))
1180 #endif
1181     {
1182     }
1183 #if UART_RETRY_TIMES
1184     if (0U == waitTimes)
1185     {
1186         return kStatus_LPUART_Timeout;
1187     }
1188 #endif
1189     return kStatus_Success;
1190 }
1191 
1192 /*!
1193  * brief Reads the receiver data register using a blocking method.
1194  *
1195  * This function polls the receiver register, waits for the receiver register full or receiver FIFO
1196  * has data, and reads data from the TX register.
1197  *
1198  * param base LPUART peripheral base address.
1199  * param data Start address of the buffer to store the received data.
1200  * param length Size of the buffer.
1201  * retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data.
1202  * retval kStatus_LPUART_NoiseError Noise error happened while receiving data.
1203  * retval kStatus_LPUART_FramingError Framing error happened while receiving data.
1204  * retval kStatus_LPUART_ParityError Parity error happened while receiving data.
1205  * retval kStatus_LPUART_Timeout Transmission timed out and was aborted.
1206  * retval kStatus_Success Successfully received all data.
1207  */
LPUART_ReadBlocking(LPUART_Type * base,uint8_t * data,size_t length)1208 status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)
1209 {
1210     assert(NULL != data);
1211 
1212     status_t status = kStatus_Success;
1213     uint32_t statusFlag;
1214     uint8_t *dataAddress = data;
1215 
1216 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
1217     uint32_t ctrl        = base->CTRL;
1218     bool isSevenDataBits = (((ctrl & LPUART_CTRL_M7_MASK) != 0U) ||
1219                             (((ctrl & LPUART_CTRL_M_MASK) == 0U) && ((ctrl & LPUART_CTRL_PE_MASK) != 0U)));
1220 #endif
1221 
1222 #if UART_RETRY_TIMES
1223     uint32_t waitTimes;
1224 #endif
1225 
1226     while (0U != (length--))
1227     {
1228 #if UART_RETRY_TIMES
1229         waitTimes = UART_RETRY_TIMES;
1230 #endif
1231 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1232         while (0U == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT))
1233 #else
1234         while (0U == (base->STAT & LPUART_STAT_RDRF_MASK))
1235 #endif
1236         {
1237 #if UART_RETRY_TIMES
1238             if (0U == --waitTimes)
1239             {
1240                 status = kStatus_LPUART_Timeout;
1241                 break;
1242             }
1243 #endif
1244             statusFlag = LPUART_GetStatusFlags(base);
1245 
1246             if (0U != (statusFlag & (uint32_t)kLPUART_RxOverrunFlag))
1247             {
1248                 /*
1249                  * $Branch Coverage Justification$
1250                  * $ref fsl_lpuart_c_ref_2$.
1251                  */
1252                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_RxOverrunFlag)) ?
1253                               (kStatus_LPUART_RxHardwareOverrun) :
1254                               (kStatus_LPUART_FlagCannotClearManually));
1255                 /* Other error flags(FE, NF, and PF) are prevented from setting once OR is set, no need to check other
1256                  * error flags*/
1257                 break;
1258             }
1259 
1260             if (0U != (statusFlag & (uint32_t)kLPUART_ParityErrorFlag))
1261             {
1262                 /*
1263                  * $Branch Coverage Justification$
1264                  * $ref fsl_lpuart_c_ref_2$.
1265                  */
1266                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_ParityErrorFlag)) ?
1267                               (kStatus_LPUART_ParityError) :
1268                               (kStatus_LPUART_FlagCannotClearManually));
1269             }
1270 
1271             if (0U != (statusFlag & (uint32_t)kLPUART_FramingErrorFlag))
1272             {
1273                 /*
1274                  * $Branch Coverage Justification$
1275                  * $ref fsl_lpuart_c_ref_2$.
1276                  */
1277                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_FramingErrorFlag)) ?
1278                               (kStatus_LPUART_FramingError) :
1279                               (kStatus_LPUART_FlagCannotClearManually));
1280             }
1281 
1282             if (0U != (statusFlag & (uint32_t)kLPUART_NoiseErrorFlag))
1283             {
1284                 /*
1285                  * $Branch Coverage Justification$
1286                  * $ref fsl_lpuart_c_ref_2$.
1287                  */
1288                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_NoiseErrorFlag)) ?
1289                               (kStatus_LPUART_NoiseError) :
1290                               (kStatus_LPUART_FlagCannotClearManually));
1291             }
1292             if (kStatus_Success != status)
1293             {
1294                 break;
1295             }
1296         }
1297 
1298         if (kStatus_Success == status)
1299         {
1300 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
1301             if (isSevenDataBits)
1302             {
1303                 *(dataAddress) = (uint8_t)(base->DATA & 0x7FU);
1304                 dataAddress++;
1305             }
1306             else
1307             {
1308                 *(dataAddress) = (uint8_t)base->DATA;
1309                 dataAddress++;
1310             }
1311 #else
1312             *(dataAddress) = (uint8_t)base->DATA;
1313             dataAddress++;
1314 #endif
1315         }
1316         else
1317         {
1318             break;
1319         }
1320     }
1321 
1322     return status;
1323 }
1324 /*!
1325  * brief Reads the receiver data register in 9bit or 10bit mode.
1326  *
1327  * note This function only support 9bit or 10bit transfer.
1328  *
1329  * param base LPUART peripheral base address.
1330  * param data Start address of the buffer to store the received data by 16bit, only 10bit is valid.
1331  * param length Size of the buffer.
1332  * retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data.
1333  * retval kStatus_LPUART_NoiseError Noise error happened while receiving data.
1334  * retval kStatus_LPUART_FramingError Framing error happened while receiving data.
1335  * retval kStatus_LPUART_ParityError Parity error happened while receiving data.
1336  * retval kStatus_LPUART_Timeout Transmission timed out and was aborted.
1337  * retval kStatus_Success Successfully received all data.
1338  */
LPUART_ReadBlocking16bit(LPUART_Type * base,uint16_t * data,size_t length)1339 status_t LPUART_ReadBlocking16bit(LPUART_Type *base, uint16_t *data, size_t length)
1340 {
1341     assert(NULL != data);
1342 
1343     status_t status = kStatus_Success;
1344     uint32_t statusFlag;
1345     uint16_t *dataAddress = data;
1346 
1347 #if UART_RETRY_TIMES
1348     uint32_t waitTimes;
1349 #endif
1350 
1351     while (0U != (length--))
1352     {
1353 #if UART_RETRY_TIMES
1354         waitTimes = UART_RETRY_TIMES;
1355 #endif
1356 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1357         while (0U == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT))
1358 #else
1359         while (0U == (base->STAT & LPUART_STAT_RDRF_MASK))
1360 #endif
1361         {
1362 #if UART_RETRY_TIMES
1363             if (0U == --waitTimes)
1364             {
1365                 status = kStatus_LPUART_Timeout;
1366                 break;
1367             }
1368 #endif
1369             statusFlag = LPUART_GetStatusFlags(base);
1370 
1371             if (0U != (statusFlag & (uint32_t)kLPUART_RxOverrunFlag))
1372             {
1373                 /*
1374                  * $Branch Coverage Justification$
1375                  * $ref fsl_lpuart_c_ref_2$.
1376                  */
1377                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_RxOverrunFlag)) ?
1378                               (kStatus_LPUART_RxHardwareOverrun) :
1379                               (kStatus_LPUART_FlagCannotClearManually));
1380                 /* Other error flags(FE, NF, and PF) are prevented from setting once OR is set, no need to check other
1381                  * error flags*/
1382                 break;
1383             }
1384 
1385             if (0U != (statusFlag & (uint32_t)kLPUART_ParityErrorFlag))
1386             {
1387                 /*
1388                  * $Branch Coverage Justification$
1389                  * $ref fsl_lpuart_c_ref_2$.
1390                  */
1391                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_ParityErrorFlag)) ?
1392                               (kStatus_LPUART_ParityError) :
1393                               (kStatus_LPUART_FlagCannotClearManually));
1394             }
1395 
1396             if (0U != (statusFlag & (uint32_t)kLPUART_FramingErrorFlag))
1397             {
1398                 /*
1399                  * $Branch Coverage Justification$
1400                  * $ref fsl_lpuart_c_ref_2$.
1401                  */
1402                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_FramingErrorFlag)) ?
1403                               (kStatus_LPUART_FramingError) :
1404                               (kStatus_LPUART_FlagCannotClearManually));
1405             }
1406 
1407             if (0U != (statusFlag & (uint32_t)kLPUART_NoiseErrorFlag))
1408             {
1409                 /*
1410                  * $Branch Coverage Justification$
1411                  * $ref fsl_lpuart_c_ref_2$.
1412                  */
1413                 status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_NoiseErrorFlag)) ?
1414                               (kStatus_LPUART_NoiseError) :
1415                               (kStatus_LPUART_FlagCannotClearManually));
1416             }
1417             if (kStatus_Success != status)
1418             {
1419                 break;
1420             }
1421         }
1422         if (kStatus_Success == status)
1423         {
1424             *(dataAddress) = (uint16_t)(base->DATA & 0x03FFU);
1425             dataAddress++;
1426         }
1427         else
1428         {
1429             break;
1430         }
1431     }
1432 
1433     return status;
1434 }
1435 
1436 /*!
1437  * brief Initializes the LPUART handle.
1438  *
1439  * This function initializes the LPUART handle, which can be used for other LPUART
1440  * transactional APIs. Usually, for a specified LPUART instance,
1441  * call this API once to get the initialized handle.
1442  *
1443  * The LPUART driver supports the "background" receiving, which means that user can set up
1444  * an RX ring buffer optionally. Data received is stored into the ring buffer even when the
1445  * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received
1446  * in the ring buffer, the user can get the received data from the ring buffer directly.
1447  * The ring buffer is disabled if passing NULL as p ringBuffer.
1448  *
1449  * param base LPUART peripheral base address.
1450  * param handle LPUART handle pointer.
1451  * param callback Callback function.
1452  * param userData User data.
1453  */
LPUART_TransferCreateHandle(LPUART_Type * base,lpuart_handle_t * handle,lpuart_transfer_callback_t callback,void * userData)1454 void LPUART_TransferCreateHandle(LPUART_Type *base,
1455                                  lpuart_handle_t *handle,
1456                                  lpuart_transfer_callback_t callback,
1457                                  void *userData)
1458 {
1459     assert(NULL != handle);
1460 
1461     uint32_t instance;
1462 
1463 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
1464     uint32_t ctrl        = base->CTRL;
1465     bool isSevenDataBits = (((ctrl & LPUART_CTRL_M7_MASK) != 0U) ||
1466                             (((ctrl & LPUART_CTRL_M_MASK) == 0U) && ((ctrl & LPUART_CTRL_PE_MASK) != 0U)));
1467 #endif
1468 
1469     /* Zero the handle. */
1470     (void)memset(handle, 0, sizeof(lpuart_handle_t));
1471 
1472     /* Set the TX/RX state. */
1473     handle->rxState = (uint8_t)kLPUART_RxIdle;
1474     handle->txState = (uint8_t)kLPUART_TxIdle;
1475 
1476     /* Set the callback and user data. */
1477     handle->callback = callback;
1478     handle->userData = userData;
1479 
1480 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
1481     /* Initial seven data bits flag */
1482     handle->isSevenDataBits = isSevenDataBits;
1483 #endif
1484     handle->is16bitData = false;
1485 
1486     /* Get instance from peripheral base address. */
1487     instance = LPUART_GetInstance(base);
1488 
1489     /* Save the handle in global variables to support the double weak mechanism. */
1490     s_lpuartHandle[instance] = handle;
1491 
1492     s_lpuartIsr[instance] = LPUART_TransferHandleIRQ;
1493 
1494 /* Enable interrupt in NVIC. */
1495 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
1496     (void)EnableIRQ(s_lpuartRxIRQ[instance]);
1497     (void)EnableIRQ(s_lpuartTxIRQ[instance]);
1498 #else
1499     (void)EnableIRQ(s_lpuartIRQ[instance]);
1500 #endif
1501 }
1502 
1503 /*!
1504  * brief Sets up the RX ring buffer.
1505  *
1506  * This function sets up the RX ring buffer to a specific UART handle.
1507  *
1508  * When the RX ring buffer is used, data received is stored into the ring buffer even when
1509  * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received
1510  * in the ring buffer, the user can get the received data from the ring buffer directly.
1511  *
1512  * note When using RX ring buffer, one byte is reserved for internal use. In other
1513  * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data.
1514  *
1515  * param base LPUART peripheral base address.
1516  * param handle LPUART handle pointer.
1517  * param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer.
1518  * param ringBufferSize size of the ring buffer.
1519  */
LPUART_TransferStartRingBuffer(LPUART_Type * base,lpuart_handle_t * handle,uint8_t * ringBuffer,size_t ringBufferSize)1520 void LPUART_TransferStartRingBuffer(LPUART_Type *base,
1521                                     lpuart_handle_t *handle,
1522                                     uint8_t *ringBuffer,
1523                                     size_t ringBufferSize)
1524 {
1525     assert(NULL != handle);
1526     assert(NULL != ringBuffer);
1527 
1528     /* Setup the ring buffer address */
1529     handle->rxRingBuffer = ringBuffer;
1530     if (!handle->is16bitData)
1531     {
1532         handle->rxRingBufferSize = ringBufferSize;
1533     }
1534     else
1535     {
1536         handle->rxRingBufferSize = ringBufferSize / 2U;
1537     }
1538     handle->rxRingBufferHead = 0U;
1539     handle->rxRingBufferTail = 0U;
1540 
1541     /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte. */
1542     uint32_t irqMask = DisableGlobalIRQ();
1543     /* Enable the interrupt to accept the data when user need the ring buffer. */
1544     base->CTRL |= (uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ORIE_MASK);
1545     EnableGlobalIRQ(irqMask);
1546 }
1547 
1548 /*!
1549  * brief Aborts the background transfer and uninstalls the ring buffer.
1550  *
1551  * This function aborts the background transfer and uninstalls the ring buffer.
1552  *
1553  * param base LPUART peripheral base address.
1554  * param handle LPUART handle pointer.
1555  */
LPUART_TransferStopRingBuffer(LPUART_Type * base,lpuart_handle_t * handle)1556 void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle)
1557 {
1558     assert(NULL != handle);
1559 
1560     if (handle->rxState == (uint8_t)kLPUART_RxIdle)
1561     {
1562         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1563          */
1564         uint32_t irqMask = DisableGlobalIRQ();
1565         base->CTRL &= ~(uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ORIE_MASK);
1566         EnableGlobalIRQ(irqMask);
1567     }
1568 
1569     handle->rxRingBuffer     = NULL;
1570     handle->rxRingBufferSize = 0U;
1571     handle->rxRingBufferHead = 0U;
1572     handle->rxRingBufferTail = 0U;
1573 }
1574 
1575 /*!
1576  * brief Transmits a buffer of data using the interrupt method.
1577  *
1578  * This function send data using an interrupt method. This is a non-blocking function, which
1579  * returns directly without waiting for all data written to the transmitter register. When
1580  * all data is written to the TX register in the ISR, the LPUART driver calls the callback
1581  * function and passes the ref kStatus_LPUART_TxIdle as status parameter.
1582  *
1583  * note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written
1584  * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX,
1585  * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished.
1586  *
1587  * param base LPUART peripheral base address.
1588  * param handle LPUART handle pointer.
1589  * param xfer LPUART transfer structure, see #lpuart_transfer_t.
1590  * retval kStatus_Success Successfully start the data transmission.
1591  * retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register.
1592  * retval kStatus_InvalidArgument Invalid argument.
1593  */
LPUART_TransferSendNonBlocking(LPUART_Type * base,lpuart_handle_t * handle,lpuart_transfer_t * xfer)1594 status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer)
1595 {
1596     assert(NULL != handle);
1597     assert(NULL != xfer);
1598     assert(NULL != xfer->txData);
1599     assert(0U != xfer->dataSize);
1600 
1601     status_t status;
1602 
1603     /* Return error if current TX busy. */
1604     if ((uint8_t)kLPUART_TxBusy == handle->txState)
1605     {
1606         status = kStatus_LPUART_TxBusy;
1607     }
1608     else
1609     {
1610         if (!handle->is16bitData)
1611         {
1612             handle->txData = xfer->txData;
1613         }
1614         else
1615         {
1616             handle->txData16 = xfer->txData16;
1617         }
1618         handle->txDataSize    = xfer->dataSize;
1619         handle->txDataSizeAll = xfer->dataSize;
1620         handle->txState       = (uint8_t)kLPUART_TxBusy;
1621 
1622         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1623          */
1624         uint32_t irqMask = DisableGlobalIRQ();
1625         /* Enable transmitter interrupt. */
1626         base->CTRL |= (uint32_t)LPUART_CTRL_TIE_MASK;
1627         EnableGlobalIRQ(irqMask);
1628 
1629         status = kStatus_Success;
1630     }
1631 
1632     return status;
1633 }
1634 
1635 /*!
1636  * brief Aborts the interrupt-driven data transmit.
1637  *
1638  * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
1639  * how many bytes are not sent out.
1640  *
1641  * param base LPUART peripheral base address.
1642  * param handle LPUART handle pointer.
1643  */
LPUART_TransferAbortSend(LPUART_Type * base,lpuart_handle_t * handle)1644 void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle)
1645 {
1646     assert(NULL != handle);
1647 
1648     /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte. */
1649     uint32_t irqMask = DisableGlobalIRQ();
1650     base->CTRL &= ~(uint32_t)(LPUART_CTRL_TIE_MASK | LPUART_CTRL_TCIE_MASK);
1651     EnableGlobalIRQ(irqMask);
1652 
1653     handle->txDataSize = 0;
1654     handle->txState    = (uint8_t)kLPUART_TxIdle;
1655 }
1656 
1657 /*!
1658  * brief Gets the number of bytes that have been sent out to bus.
1659  *
1660  * This function gets the number of bytes that have been sent out to bus by an interrupt method.
1661  *
1662  * param base LPUART peripheral base address.
1663  * param handle LPUART handle pointer.
1664  * param count Send bytes count.
1665  * retval kStatus_NoTransferInProgress No send in progress.
1666  * retval kStatus_InvalidArgument Parameter is invalid.
1667  * retval kStatus_Success Get successfully through the parameter \p count;
1668  */
LPUART_TransferGetSendCount(LPUART_Type * base,lpuart_handle_t * handle,uint32_t * count)1669 status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
1670 {
1671     assert(NULL != handle);
1672     assert(NULL != count);
1673 
1674     status_t status      = kStatus_Success;
1675     size_t tmptxDataSize = handle->txDataSize;
1676 
1677     if ((uint8_t)kLPUART_TxIdle == handle->txState)
1678     {
1679         status = kStatus_NoTransferInProgress;
1680     }
1681     else
1682     {
1683 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1684         *count = handle->txDataSizeAll - tmptxDataSize -
1685                  ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT);
1686 #else
1687         if ((base->STAT & (uint32_t)kLPUART_TxDataRegEmptyFlag) != 0U)
1688         {
1689             *count = handle->txDataSizeAll - tmptxDataSize;
1690         }
1691         else
1692         {
1693             *count = handle->txDataSizeAll - tmptxDataSize - 1U;
1694         }
1695 #endif
1696     }
1697 
1698     return status;
1699 }
1700 
1701 /*!
1702  * brief Receives a buffer of data using the interrupt method.
1703  *
1704  * This function receives data using an interrupt method. This is a non-blocking function
1705  * which returns without waiting to ensure that all data are received.
1706  * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
1707  * the parameter p receivedBytes shows how many bytes are copied from the ring buffer.
1708  * After copying, if the data in the ring buffer is not enough for read, the receive
1709  * request is saved by the LPUART driver. When the new data arrives, the receive request
1710  * is serviced first. When all data is received, the LPUART driver notifies the upper layer
1711  * through a callback function and passes a status parameter ref kStatus_UART_RxIdle.
1712  * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer.
1713  * The 5 bytes are copied to xfer->data, which returns with the
1714  * parameter p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is
1715  * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer.
1716  * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
1717  * to receive data to xfer->data. When all data is received, the upper layer is notified.
1718  *
1719  * param base LPUART peripheral base address.
1720  * param handle LPUART handle pointer.
1721  * param xfer LPUART transfer structure, see #uart_transfer_t.
1722  * param receivedBytes Bytes received from the ring buffer directly.
1723  * retval kStatus_Success Successfully queue the transfer into the transmit queue.
1724  * retval kStatus_LPUART_RxBusy Previous receive request is not finished.
1725  * retval kStatus_InvalidArgument Invalid argument.
1726  */
LPUART_TransferReceiveNonBlocking(LPUART_Type * base,lpuart_handle_t * handle,lpuart_transfer_t * xfer,size_t * receivedBytes)1727 status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
1728                                            lpuart_handle_t *handle,
1729                                            lpuart_transfer_t *xfer,
1730                                            size_t *receivedBytes)
1731 {
1732     assert(NULL != handle);
1733     assert(NULL != xfer);
1734     assert(NULL != xfer->rxData);
1735     assert(0U != xfer->dataSize);
1736 
1737     uint32_t i;
1738     status_t status;
1739     uint32_t irqMask;
1740     /* How many bytes to copy from ring buffer to user memory. */
1741     size_t bytesToCopy = 0U;
1742     /* How many bytes to receive. */
1743     size_t bytesToReceive;
1744     /* How many bytes currently have received. */
1745     size_t bytesCurrentReceived;
1746 
1747     /* How to get data:
1748        1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
1749           to lpuart handle, enable interrupt to store received data to xfer->data. When
1750           all data received, trigger callback.
1751        2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
1752           If there are enough data in ring buffer, copy them to xfer->data and return.
1753           If there are not enough data in ring buffer, copy all of them to xfer->data,
1754           save the xfer->data remained empty space to lpuart handle, receive data
1755           to this empty space and trigger callback when finished. */
1756 
1757     if ((uint8_t)kLPUART_RxBusy == handle->rxState)
1758     {
1759         status = kStatus_LPUART_RxBusy;
1760     }
1761     else
1762     {
1763         bytesToReceive       = xfer->dataSize;
1764         bytesCurrentReceived = 0;
1765 
1766         /* If RX ring buffer is used. */
1767         if (NULL != handle->rxRingBuffer)
1768         {
1769             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1770              * read-modify-wrte. */
1771             irqMask = DisableGlobalIRQ();
1772             /* Disable LPUART RX IRQ, protect ring buffer. */
1773             base->CTRL &= ~(uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ORIE_MASK);
1774             EnableGlobalIRQ(irqMask);
1775 
1776             /* How many bytes in RX ring buffer currently. */
1777             bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle);
1778 
1779             if (0U != bytesToCopy)
1780             {
1781                 bytesToCopy = MIN(bytesToReceive, bytesToCopy);
1782 
1783                 bytesToReceive -= bytesToCopy;
1784 
1785                 /* Copy data from ring buffer to user memory. */
1786                 for (i = 0U; i < bytesToCopy; i++)
1787                 {
1788                     if (!handle->is16bitData)
1789                     {
1790                         xfer->rxData[bytesCurrentReceived] = handle->rxRingBuffer[handle->rxRingBufferTail];
1791                     }
1792                     else
1793                     {
1794                         xfer->rxData16[bytesCurrentReceived] = handle->rxRingBuffer16[handle->rxRingBufferTail];
1795                     }
1796                     bytesCurrentReceived++;
1797 
1798                     /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
1799                     if (((uint32_t)handle->rxRingBufferTail + 1U) == handle->rxRingBufferSize)
1800                     {
1801                         handle->rxRingBufferTail = 0U;
1802                     }
1803                     else
1804                     {
1805                         handle->rxRingBufferTail++;
1806                     }
1807                 }
1808             }
1809 
1810             /* If ring buffer does not have enough data, still need to read more data. */
1811             if (0U != bytesToReceive)
1812             {
1813                 /* No data in ring buffer, save the request to LPUART handle. */
1814 
1815                 if (!handle->is16bitData)
1816                 {
1817                     handle->rxData = &xfer->rxData[bytesCurrentReceived];
1818                 }
1819                 else
1820                 {
1821                     handle->rxData16 = &xfer->rxData16[bytesCurrentReceived];
1822                 }
1823                 handle->rxDataSize    = bytesToReceive;
1824                 handle->rxDataSizeAll = xfer->dataSize;
1825                 handle->rxState       = (uint8_t)kLPUART_RxBusy;
1826             }
1827 
1828             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1829              * read-modify-wrte. */
1830             irqMask = DisableGlobalIRQ();
1831             /* Re-enable LPUART RX IRQ. */
1832             base->CTRL |= (uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ORIE_MASK);
1833             EnableGlobalIRQ(irqMask);
1834 
1835             /* Call user callback since all data are received. */
1836             if (0U == bytesToReceive)
1837             {
1838                 if (NULL != handle->callback)
1839                 {
1840                     handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
1841                 }
1842             }
1843         }
1844         /* Ring buffer not used. */
1845         else
1846         {
1847             if (!handle->is16bitData)
1848             {
1849                 handle->rxData = &xfer->rxData[bytesCurrentReceived];
1850             }
1851             else
1852             {
1853                 handle->rxData16 = &xfer->rxData16[bytesCurrentReceived];
1854             }
1855             handle->rxDataSize    = bytesToReceive;
1856             handle->rxDataSizeAll = bytesToReceive;
1857             handle->rxState       = (uint8_t)kLPUART_RxBusy;
1858 
1859             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1860              * read-modify-wrte. */
1861             irqMask = DisableGlobalIRQ();
1862             /* Enable RX interrupt. */
1863             base->CTRL |= (uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ILIE_MASK | LPUART_CTRL_ORIE_MASK);
1864             EnableGlobalIRQ(irqMask);
1865         }
1866 
1867         /* Return the how many bytes have read. */
1868         if (NULL != receivedBytes)
1869         {
1870             *receivedBytes = bytesCurrentReceived;
1871         }
1872 
1873         status = kStatus_Success;
1874     }
1875 
1876     return status;
1877 }
1878 
1879 /*!
1880  * brief Aborts the interrupt-driven data receiving.
1881  *
1882  * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
1883  * how many bytes not received yet.
1884  *
1885  * param base LPUART peripheral base address.
1886  * param handle LPUART handle pointer.
1887  */
LPUART_TransferAbortReceive(LPUART_Type * base,lpuart_handle_t * handle)1888 void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle)
1889 {
1890     assert(NULL != handle);
1891 
1892     /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
1893     if (NULL == handle->rxRingBuffer)
1894     {
1895         /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
1896          */
1897         uint32_t irqMask = DisableGlobalIRQ();
1898         /* Disable RX interrupt. */
1899         base->CTRL &= ~(uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ILIE_MASK | LPUART_CTRL_ORIE_MASK);
1900         EnableGlobalIRQ(irqMask);
1901     }
1902 
1903     handle->rxDataSize = 0U;
1904     handle->rxState    = (uint8_t)kLPUART_RxIdle;
1905 }
1906 
1907 /*!
1908  * brief Gets the number of bytes that have been received.
1909  *
1910  * This function gets the number of bytes that have been received.
1911  *
1912  * param base LPUART peripheral base address.
1913  * param handle LPUART handle pointer.
1914  * param count Receive bytes count.
1915  * retval kStatus_NoTransferInProgress No receive in progress.
1916  * retval kStatus_InvalidArgument Parameter is invalid.
1917  * retval kStatus_Success Get successfully through the parameter \p count;
1918  */
LPUART_TransferGetReceiveCount(LPUART_Type * base,lpuart_handle_t * handle,uint32_t * count)1919 status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
1920 {
1921     assert(NULL != handle);
1922     assert(NULL != count);
1923 
1924     status_t status      = kStatus_Success;
1925     size_t tmprxDataSize = handle->rxDataSize;
1926 
1927     if ((uint8_t)kLPUART_RxIdle == handle->rxState)
1928     {
1929         status = kStatus_NoTransferInProgress;
1930     }
1931     else
1932     {
1933         *count = handle->rxDataSizeAll - tmprxDataSize;
1934     }
1935 
1936     return status;
1937 }
1938 
LPUART_TransferHandleIDLEReady(LPUART_Type * base,lpuart_handle_t * handle)1939 static void LPUART_TransferHandleIDLEReady(LPUART_Type *base, lpuart_handle_t *handle)
1940 {
1941     uint32_t irqMask;
1942 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
1943     uint8_t count;
1944     uint8_t tempCount;
1945     count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT));
1946 
1947     while ((0U != handle->rxDataSize) && (0U != count))
1948     {
1949         tempCount = (uint8_t)MIN(handle->rxDataSize, count);
1950         /* Using non block API to read the data from the registers. */
1951         if (!handle->is16bitData)
1952         {
1953             LPUART_ReadNonBlocking(base, handle->rxData, tempCount);
1954             handle->rxData = &handle->rxData[tempCount];
1955         }
1956         else
1957         {
1958             LPUART_ReadNonBlocking16bit(base, handle->rxData16, tempCount);
1959             handle->rxData16 = &handle->rxData16[tempCount];
1960         }
1961         handle->rxDataSize -= tempCount;
1962         count -= tempCount;
1963 
1964         /* If rxDataSize is 0, invoke rx idle callback.*/
1965         if (0U == (handle->rxDataSize))
1966         {
1967             handle->rxState = (uint8_t)kLPUART_RxIdle;
1968 
1969             if (NULL != handle->callback)
1970             {
1971                 handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
1972             }
1973         }
1974     }
1975 #endif
1976     /* Clear IDLE flag.*/
1977     base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_IDLE_MASK);
1978 
1979     /* If rxDataSize is 0, disable rx ready, overrun and idle line interrupt.*/
1980     if (0U == handle->rxDataSize)
1981     {
1982         /* Disable and re-enable the global interrupt to protect the interrupt enable register during
1983          * read-modify-wrte. */
1984         irqMask = DisableGlobalIRQ();
1985         base->CTRL &= ~(uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ILIE_MASK | LPUART_CTRL_ORIE_MASK);
1986         EnableGlobalIRQ(irqMask);
1987     }
1988     /* Invoke callback if callback is not NULL and rxDataSize is not 0. */
1989     else if (NULL != handle->callback)
1990     {
1991         handle->callback(base, handle, kStatus_LPUART_IdleLineDetected, handle->userData);
1992     }
1993     else
1994     {
1995         /* Avoid MISRA 15.7 */
1996     }
1997 }
1998 
LPUART_TransferHandleReceiveDataFull(LPUART_Type * base,lpuart_handle_t * handle)1999 static void LPUART_TransferHandleReceiveDataFull(LPUART_Type *base, lpuart_handle_t *handle)
2000 {
2001     uint8_t count;
2002     uint8_t tempCount;
2003     uint16_t tpmRxRingBufferHead;
2004     uint32_t tpmData;
2005     uint32_t irqMask;
2006 
2007     /* Get the size that can be stored into buffer for this interrupt. */
2008 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
2009     count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT));
2010 #else
2011     count = 1;
2012 #endif
2013 
2014     /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
2015     while ((0U != handle->rxDataSize) && (0U != count))
2016     {
2017 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
2018         tempCount = (uint8_t)MIN(handle->rxDataSize, count);
2019 #else
2020         tempCount = 1;
2021 #endif
2022 
2023         /* Using non block API to read the data from the registers. */
2024         if (!handle->is16bitData)
2025         {
2026             LPUART_ReadNonBlocking(base, handle->rxData, tempCount);
2027             handle->rxData = &handle->rxData[tempCount];
2028         }
2029         else
2030         {
2031             LPUART_ReadNonBlocking16bit(base, handle->rxData16, tempCount);
2032             handle->rxData16 = &handle->rxData16[tempCount];
2033         }
2034         handle->rxDataSize -= tempCount;
2035         count -= tempCount;
2036 
2037         /* If all the data required for upper layer is ready, trigger callback. */
2038         if (0U == handle->rxDataSize)
2039         {
2040             handle->rxState = (uint8_t)kLPUART_RxIdle;
2041 
2042             if (NULL != handle->callback)
2043             {
2044                 handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
2045             }
2046         }
2047     }
2048 
2049     /* If use RX ring buffer, receive data to ring buffer. */
2050     if (NULL != handle->rxRingBuffer)
2051     {
2052         while (0U != count--)
2053         {
2054             /* If RX ring buffer is full, trigger callback to notify over run. */
2055             if (LPUART_TransferIsRxRingBufferFull(base, handle))
2056             {
2057                 if (NULL != handle->callback)
2058                 {
2059                     handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData);
2060                 }
2061             }
2062 
2063             /* If ring buffer is still full after callback function, the oldest data is overridden. */
2064             if (LPUART_TransferIsRxRingBufferFull(base, handle))
2065             {
2066                 /* Increase handle->rxRingBufferTail to make room for new data. */
2067                 if (((uint32_t)handle->rxRingBufferTail + 1U) == handle->rxRingBufferSize)
2068                 {
2069                     handle->rxRingBufferTail = 0U;
2070                 }
2071                 else
2072                 {
2073                     handle->rxRingBufferTail++;
2074                 }
2075             }
2076 
2077             /* Read data. */
2078             tpmRxRingBufferHead = handle->rxRingBufferHead;
2079             tpmData             = base->DATA;
2080 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
2081             if (handle->isSevenDataBits)
2082             {
2083                 handle->rxRingBuffer[tpmRxRingBufferHead] = (uint8_t)(tpmData & 0x7FU);
2084             }
2085             else
2086             {
2087                 if (!handle->is16bitData)
2088                 {
2089                     handle->rxRingBuffer[tpmRxRingBufferHead] = (uint8_t)tpmData;
2090                 }
2091                 else
2092                 {
2093                     handle->rxRingBuffer16[tpmRxRingBufferHead] = (uint16_t)(tpmData & 0x3FFU);
2094                 }
2095             }
2096 #else
2097             if (!handle->is16bitData)
2098             {
2099                 handle->rxRingBuffer[tpmRxRingBufferHead] = (uint8_t)tpmData;
2100             }
2101             else
2102             {
2103                 handle->rxRingBuffer16[tpmRxRingBufferHead] = (uint16_t)(tpmData & 0x3FFU);
2104             }
2105 #endif
2106 
2107             /* Increase handle->rxRingBufferHead. */
2108             if (((uint32_t)handle->rxRingBufferHead + 1U) == handle->rxRingBufferSize)
2109             {
2110                 handle->rxRingBufferHead = 0U;
2111             }
2112             else
2113             {
2114                 handle->rxRingBufferHead++;
2115             }
2116         }
2117     }
2118     /* If no receive requst pending, stop RX interrupt. */
2119     else if (0U == handle->rxDataSize)
2120     {
2121         /* Disable and re-enable the global interrupt to protect the interrupt enable register during
2122          * read-modify-wrte. */
2123         irqMask = DisableGlobalIRQ();
2124         base->CTRL &= ~(uint32_t)(LPUART_CTRL_RIE_MASK | LPUART_CTRL_ORIE_MASK | LPUART_CTRL_ILIE_MASK);
2125         EnableGlobalIRQ(irqMask);
2126     }
2127     else
2128     {
2129         /* Avoid MISRA C-2012 15.7 voiation */
2130         return;
2131     }
2132 }
2133 
LPUART_TransferHandleSendDataEmpty(LPUART_Type * base,lpuart_handle_t * handle)2134 static void LPUART_TransferHandleSendDataEmpty(LPUART_Type *base, lpuart_handle_t *handle)
2135 {
2136     uint8_t count;
2137     uint8_t tempCount;
2138     uint32_t irqMask;
2139 /* Get the bytes that available at this moment. */
2140 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
2141     count = (uint8_t)FSL_FEATURE_LPUART_FIFO_SIZEn(base) -
2142             (uint8_t)((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT);
2143 #else
2144     count = 1;
2145 #endif
2146 
2147     while ((0U != handle->txDataSize) && (0U != count))
2148     {
2149 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
2150         tempCount = (uint8_t)MIN(handle->txDataSize, count);
2151 #else
2152         tempCount = 1;
2153 #endif
2154 
2155         /* Using non block API to write the data to the registers. */
2156         if (!handle->is16bitData)
2157         {
2158             LPUART_WriteNonBlocking(base, handle->txData, tempCount);
2159             handle->txData = &handle->txData[tempCount];
2160         }
2161         else
2162         {
2163             LPUART_WriteNonBlocking16bit(base, handle->txData16, tempCount);
2164             handle->txData16 = &handle->txData16[tempCount];
2165         }
2166         handle->txDataSize -= tempCount;
2167         count -= tempCount;
2168 
2169         /* If all the data are written to data register, notify user with the callback, then TX finished. */
2170         if (0U == handle->txDataSize)
2171         {
2172             /* Disable and re-enable the global interrupt to protect the interrupt enable register during
2173              * read-modify-wrte. */
2174             irqMask = DisableGlobalIRQ();
2175             /* Disable TX register empty interrupt and enable transmission completion interrupt. */
2176             base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK) | LPUART_CTRL_TCIE_MASK;
2177             EnableGlobalIRQ(irqMask);
2178         }
2179     }
2180 }
2181 
LPUART_TransferHandleTransmissionComplete(LPUART_Type * base,lpuart_handle_t * handle)2182 static void LPUART_TransferHandleTransmissionComplete(LPUART_Type *base, lpuart_handle_t *handle)
2183 {
2184     uint32_t irqMask;
2185     /* Set txState to idle only when all data has been sent out to bus. */
2186     handle->txState = (uint8_t)kLPUART_TxIdle;
2187 
2188     /* Disable and re-enable the global interrupt to protect the interrupt enable register during read-modify-wrte.
2189      */
2190     irqMask = DisableGlobalIRQ();
2191     /* Disable transmission complete interrupt. */
2192     base->CTRL &= ~(uint32_t)LPUART_CTRL_TCIE_MASK;
2193     EnableGlobalIRQ(irqMask);
2194 
2195     /* Trigger callback. */
2196     if (NULL != handle->callback)
2197     {
2198         handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData);
2199     }
2200 }
2201 
2202 /*!
2203  * brief LPUART IRQ handle function.
2204  *
2205  * This function handles the LPUART transmit and receive IRQ request.
2206  *
2207  * param base LPUART peripheral base address.
2208  * param irqHandle LPUART handle pointer.
2209  */
LPUART_TransferHandleIRQ(LPUART_Type * base,void * irqHandle)2210 void LPUART_TransferHandleIRQ(LPUART_Type *base, void *irqHandle)
2211 {
2212     assert(NULL != irqHandle);
2213 
2214     uint32_t status            = LPUART_GetStatusFlags(base);
2215     uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(base);
2216 
2217     lpuart_handle_t *handle = (lpuart_handle_t *)irqHandle;
2218 
2219     /* If RX overrun. */
2220     if ((uint32_t)kLPUART_RxOverrunFlag == ((uint32_t)kLPUART_RxOverrunFlag & status))
2221     {
2222         /* Clear overrun flag, otherwise the RX does not work. */
2223         base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK);
2224 
2225         /* Trigger callback. */
2226         if (NULL != (handle->callback))
2227         {
2228             handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData);
2229         }
2230     }
2231 
2232     /* If IDLE flag is set and the IDLE interrupt is enabled. */
2233     if ((0U != ((uint32_t)kLPUART_IdleLineFlag & status)) &&
2234         (0U != ((uint32_t)kLPUART_IdleLineInterruptEnable & enabledInterrupts)))
2235     {
2236         LPUART_TransferHandleIDLEReady(base, handle);
2237     }
2238     /* Receive data register full */
2239     if ((0U != ((uint32_t)kLPUART_RxDataRegFullFlag & status)) &&
2240         (0U != ((uint32_t)kLPUART_RxDataRegFullInterruptEnable & enabledInterrupts)))
2241     {
2242         LPUART_TransferHandleReceiveDataFull(base, handle);
2243     }
2244 
2245     /* Send data register empty and the interrupt is enabled. */
2246     if ((0U != ((uint32_t)kLPUART_TxDataRegEmptyFlag & status)) &&
2247         (0U != ((uint32_t)kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)))
2248     {
2249         LPUART_TransferHandleSendDataEmpty(base, handle);
2250     }
2251 
2252     /* Transmission complete and the interrupt is enabled. */
2253     if ((0U != ((uint32_t)kLPUART_TransmissionCompleteFlag & status)) &&
2254         (0U != ((uint32_t)kLPUART_TransmissionCompleteInterruptEnable & enabledInterrupts)))
2255     {
2256         LPUART_TransferHandleTransmissionComplete(base, handle);
2257     }
2258 }
2259 
2260 /*!
2261  * brief LPUART Error IRQ handle function.
2262  *
2263  * This function handles the LPUART error IRQ request.
2264  *
2265  * param base LPUART peripheral base address.
2266  * param irqHandle LPUART handle pointer.
2267  */
LPUART_TransferHandleErrorIRQ(LPUART_Type * base,void * irqHandle)2268 void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, void *irqHandle)
2269 {
2270     /* To be implemented by User. */
2271 }
2272 #if defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1
2273 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2274 void LPUART0_LPUART1_RX_DriverIRQHandler(void);
LPUART0_LPUART1_RX_DriverIRQHandler(void)2275 void LPUART0_LPUART1_RX_DriverIRQHandler(void)
2276 {
2277     /* If handle is registered, treat the transfer function is enabled. */
2278     if (NULL != s_lpuartHandle[0])
2279     {
2280         s_lpuartIsr[0](LPUART0, s_lpuartHandle[0]);
2281     }
2282     if (NULL != s_lpuartHandle[1])
2283     {
2284         s_lpuartIsr[1](LPUART1, s_lpuartHandle[1]);
2285     }
2286     SDK_ISR_EXIT_BARRIER;
2287 }
2288 void LPUART0_LPUART1_TX_DriverIRQHandler(void);
LPUART0_LPUART1_TX_DriverIRQHandler(void)2289 void LPUART0_LPUART1_TX_DriverIRQHandler(void)
2290 {
2291     /* If handle is registered, treat the transfer function is enabled. */
2292     if (NULL != s_lpuartHandle[0])
2293     {
2294         s_lpuartIsr[0](LPUART0, s_lpuartHandle[0]);
2295     }
2296     if (NULL != s_lpuartHandle[1])
2297     {
2298         s_lpuartIsr[1](LPUART1, s_lpuartHandle[1]);
2299     }
2300     SDK_ISR_EXIT_BARRIER;
2301 }
2302 #else
2303 void LPUART0_LPUART1_DriverIRQHandler(void);
LPUART0_LPUART1_DriverIRQHandler(void)2304 void LPUART0_LPUART1_DriverIRQHandler(void)
2305 {
2306     /* If handle is registered, treat the transfer function is enabled. */
2307     if (NULL != s_lpuartHandle[0])
2308     {
2309         s_lpuartIsr[0](LPUART0, s_lpuartHandle[0]);
2310     }
2311     if (NULL != s_lpuartHandle[1])
2312     {
2313         s_lpuartIsr[1](LPUART1, s_lpuartHandle[1]);
2314     }
2315     SDK_ISR_EXIT_BARRIER;
2316 }
2317 #endif
2318 #endif
2319 
2320 #if defined(LPUART0)
2321 #if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1)
2322 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2323 void LPUART0_TX_DriverIRQHandler(void);
LPUART0_TX_DriverIRQHandler(void)2324 void LPUART0_TX_DriverIRQHandler(void)
2325 {
2326     s_lpuartIsr[0](LPUART0, s_lpuartHandle[0]);
2327     SDK_ISR_EXIT_BARRIER;
2328 }
2329 void LPUART0_RX_DriverIRQHandler(void);
LPUART0_RX_DriverIRQHandler(void)2330 void LPUART0_RX_DriverIRQHandler(void)
2331 {
2332     s_lpuartIsr[0](LPUART0, s_lpuartHandle[0]);
2333     SDK_ISR_EXIT_BARRIER;
2334 }
2335 #else
2336 void LPUART0_DriverIRQHandler(void);
LPUART0_DriverIRQHandler(void)2337 void LPUART0_DriverIRQHandler(void)
2338 {
2339     s_lpuartIsr[0](LPUART0, s_lpuartHandle[0]);
2340     SDK_ISR_EXIT_BARRIER;
2341 }
2342 #endif
2343 #endif
2344 #endif
2345 
2346 #if defined(LPUART1)
2347 #if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1)
2348 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2349 void LPUART1_TX_DriverIRQHandler(void);
LPUART1_TX_DriverIRQHandler(void)2350 void LPUART1_TX_DriverIRQHandler(void)
2351 {
2352     s_lpuartIsr[1](LPUART1, s_lpuartHandle[1]);
2353     SDK_ISR_EXIT_BARRIER;
2354 }
2355 void LPUART1_RX_DriverIRQHandler(void);
LPUART1_RX_DriverIRQHandler(void)2356 void LPUART1_RX_DriverIRQHandler(void)
2357 {
2358     s_lpuartIsr[1](LPUART1, s_lpuartHandle[1]);
2359     SDK_ISR_EXIT_BARRIER;
2360 }
2361 #else
2362 void LPUART1_DriverIRQHandler(void);
LPUART1_DriverIRQHandler(void)2363 void LPUART1_DriverIRQHandler(void)
2364 {
2365     s_lpuartIsr[1](LPUART1, s_lpuartHandle[1]);
2366     SDK_ISR_EXIT_BARRIER;
2367 }
2368 #endif
2369 #endif
2370 #endif
2371 
2372 #if defined(LPUART2)
2373 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2374 void LPUART2_TX_DriverIRQHandler(void);
LPUART2_TX_DriverIRQHandler(void)2375 void LPUART2_TX_DriverIRQHandler(void)
2376 {
2377     s_lpuartIsr[2](LPUART2, s_lpuartHandle[2]);
2378     SDK_ISR_EXIT_BARRIER;
2379 }
2380 void LPUART2_RX_DriverIRQHandler(void);
LPUART2_RX_DriverIRQHandler(void)2381 void LPUART2_RX_DriverIRQHandler(void)
2382 {
2383     s_lpuartIsr[2](LPUART2, s_lpuartHandle[2]);
2384     SDK_ISR_EXIT_BARRIER;
2385 }
2386 #else
2387 void LPUART2_DriverIRQHandler(void);
LPUART2_DriverIRQHandler(void)2388 void LPUART2_DriverIRQHandler(void)
2389 {
2390     s_lpuartIsr[2](LPUART2, s_lpuartHandle[2]);
2391     SDK_ISR_EXIT_BARRIER;
2392 }
2393 #endif
2394 #endif
2395 
2396 #if defined(LPUART3)
2397 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2398 void LPUART3_TX_DriverIRQHandler(void);
LPUART3_TX_DriverIRQHandler(void)2399 void LPUART3_TX_DriverIRQHandler(void)
2400 {
2401     s_lpuartIsr[3](LPUART3, s_lpuartHandle[3]);
2402     SDK_ISR_EXIT_BARRIER;
2403 }
2404 void LPUART3_RX_DriverIRQHandler(void);
LPUART3_RX_DriverIRQHandler(void)2405 void LPUART3_RX_DriverIRQHandler(void)
2406 {
2407     s_lpuartIsr[3](LPUART3, s_lpuartHandle[3]);
2408     SDK_ISR_EXIT_BARRIER;
2409 }
2410 #else
2411 void LPUART3_DriverIRQHandler(void);
LPUART3_DriverIRQHandler(void)2412 void LPUART3_DriverIRQHandler(void)
2413 {
2414     s_lpuartIsr[3](LPUART3, s_lpuartHandle[3]);
2415     SDK_ISR_EXIT_BARRIER;
2416 }
2417 #endif
2418 #endif
2419 
2420 #if defined(LPUART4)
2421 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2422 void LPUART4_TX_DriverIRQHandler(void);
LPUART4_TX_DriverIRQHandler(void)2423 void LPUART4_TX_DriverIRQHandler(void)
2424 {
2425     s_lpuartIsr[4](LPUART4, s_lpuartHandle[4]);
2426     SDK_ISR_EXIT_BARRIER;
2427 }
2428 void LPUART4_RX_DriverIRQHandler(void);
LPUART4_RX_DriverIRQHandler(void)2429 void LPUART4_RX_DriverIRQHandler(void)
2430 {
2431     s_lpuartIsr[4](LPUART4, s_lpuartHandle[4]);
2432     SDK_ISR_EXIT_BARRIER;
2433 }
2434 #else
2435 void LPUART4_DriverIRQHandler(void);
LPUART4_DriverIRQHandler(void)2436 void LPUART4_DriverIRQHandler(void)
2437 {
2438     s_lpuartIsr[4](LPUART4, s_lpuartHandle[4]);
2439     SDK_ISR_EXIT_BARRIER;
2440 }
2441 #endif
2442 #endif
2443 
2444 #if defined(LPUART5)
2445 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2446 void LPUART5_TX_DriverIRQHandler(void);
LPUART5_TX_DriverIRQHandler(void)2447 void LPUART5_TX_DriverIRQHandler(void)
2448 {
2449     s_lpuartIsr[5](LPUART5, s_lpuartHandle[5]);
2450     SDK_ISR_EXIT_BARRIER;
2451 }
2452 void LPUART5_RX_DriverIRQHandler(void);
LPUART5_RX_DriverIRQHandler(void)2453 void LPUART5_RX_DriverIRQHandler(void)
2454 {
2455     s_lpuartIsr[5](LPUART5, s_lpuartHandle[5]);
2456     SDK_ISR_EXIT_BARRIER;
2457 }
2458 #else
2459 void LPUART5_DriverIRQHandler(void);
LPUART5_DriverIRQHandler(void)2460 void LPUART5_DriverIRQHandler(void)
2461 {
2462     s_lpuartIsr[5](LPUART5, s_lpuartHandle[5]);
2463     SDK_ISR_EXIT_BARRIER;
2464 }
2465 #endif
2466 #endif
2467 
2468 #if defined(LPUART6)
2469 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2470 void LPUART6_TX_DriverIRQHandler(void);
LPUART6_TX_DriverIRQHandler(void)2471 void LPUART6_TX_DriverIRQHandler(void)
2472 {
2473     s_lpuartIsr[6](LPUART6, s_lpuartHandle[6]);
2474     SDK_ISR_EXIT_BARRIER;
2475 }
2476 void LPUART6_RX_DriverIRQHandler(void);
LPUART6_RX_DriverIRQHandler(void)2477 void LPUART6_RX_DriverIRQHandler(void)
2478 {
2479     s_lpuartIsr[6](LPUART6, s_lpuartHandle[6]);
2480     SDK_ISR_EXIT_BARRIER;
2481 }
2482 #else
2483 void LPUART6_DriverIRQHandler(void);
LPUART6_DriverIRQHandler(void)2484 void LPUART6_DriverIRQHandler(void)
2485 {
2486     s_lpuartIsr[6](LPUART6, s_lpuartHandle[6]);
2487     SDK_ISR_EXIT_BARRIER;
2488 }
2489 #endif
2490 #endif
2491 
2492 #if defined(LPUART7)
2493 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2494 void LPUART7_TX_DriverIRQHandler(void);
LPUART7_TX_DriverIRQHandler(void)2495 void LPUART7_TX_DriverIRQHandler(void)
2496 {
2497     s_lpuartIsr[7](LPUART7, s_lpuartHandle[7]);
2498     SDK_ISR_EXIT_BARRIER;
2499 }
2500 void LPUART7_RX_DriverIRQHandler(void);
LPUART7_RX_DriverIRQHandler(void)2501 void LPUART7_RX_DriverIRQHandler(void)
2502 {
2503     s_lpuartIsr[7](LPUART7, s_lpuartHandle[7]);
2504     SDK_ISR_EXIT_BARRIER;
2505 }
2506 #else
2507 void LPUART7_DriverIRQHandler(void);
LPUART7_DriverIRQHandler(void)2508 void LPUART7_DriverIRQHandler(void)
2509 {
2510     s_lpuartIsr[7](LPUART7, s_lpuartHandle[7]);
2511     SDK_ISR_EXIT_BARRIER;
2512 }
2513 #endif
2514 #endif
2515 
2516 #if defined(LPUART8)
2517 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2518 void LPUART8_TX_DriverIRQHandler(void);
LPUART8_TX_DriverIRQHandler(void)2519 void LPUART8_TX_DriverIRQHandler(void)
2520 {
2521     s_lpuartIsr[8](LPUART8, s_lpuartHandle[8]);
2522     SDK_ISR_EXIT_BARRIER;
2523 }
2524 void LPUART8_RX_DriverIRQHandler(void);
LPUART8_RX_DriverIRQHandler(void)2525 void LPUART8_RX_DriverIRQHandler(void)
2526 {
2527     s_lpuartIsr[8](LPUART8, s_lpuartHandle[8]);
2528     SDK_ISR_EXIT_BARRIER;
2529 }
2530 #else
2531 void LPUART8_DriverIRQHandler(void);
LPUART8_DriverIRQHandler(void)2532 void LPUART8_DriverIRQHandler(void)
2533 {
2534     s_lpuartIsr[8](LPUART8, s_lpuartHandle[8]);
2535     SDK_ISR_EXIT_BARRIER;
2536 }
2537 #endif
2538 #endif
2539 
2540 #if defined(LPUART9)
2541 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2542 void LPUART9_TX_DriverIRQHandler(void);
LPUART9_TX_DriverIRQHandler(void)2543 void LPUART9_TX_DriverIRQHandler(void)
2544 {
2545     s_lpuartIsr[9](LPUART9, s_lpuartHandle[9]);
2546     SDK_ISR_EXIT_BARRIER;
2547 }
2548 void LPUART9_RX_DriverIRQHandler(void);
LPUART9_RX_DriverIRQHandler(void)2549 void LPUART9_RX_DriverIRQHandler(void)
2550 {
2551     s_lpuartIsr[9](LPUART9, s_lpuartHandle[9]);
2552     SDK_ISR_EXIT_BARRIER;
2553 }
2554 #else
2555 void LPUART9_DriverIRQHandler(void);
LPUART9_DriverIRQHandler(void)2556 void LPUART9_DriverIRQHandler(void)
2557 {
2558     s_lpuartIsr[9](LPUART9, s_lpuartHandle[9]);
2559     SDK_ISR_EXIT_BARRIER;
2560 }
2561 #endif
2562 #endif
2563 
2564 #if defined(LPUART10)
2565 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2566 void LPUART10_TX_DriverIRQHandler(void);
LPUART10_TX_DriverIRQHandler(void)2567 void LPUART10_TX_DriverIRQHandler(void)
2568 {
2569     s_lpuartIsr[10](LPUART10, s_lpuartHandle[10]);
2570     SDK_ISR_EXIT_BARRIER;
2571 }
2572 void LPUART10_RX_DriverIRQHandler(void);
LPUART10_RX_DriverIRQHandler(void)2573 void LPUART10_RX_DriverIRQHandler(void)
2574 {
2575     s_lpuartIsr[10](LPUART10, s_lpuartHandle[10]);
2576     SDK_ISR_EXIT_BARRIER;
2577 }
2578 #else
2579 void LPUART10_DriverIRQHandler(void);
LPUART10_DriverIRQHandler(void)2580 void LPUART10_DriverIRQHandler(void)
2581 {
2582     s_lpuartIsr[10](LPUART10, s_lpuartHandle[10]);
2583     SDK_ISR_EXIT_BARRIER;
2584 }
2585 #endif
2586 #endif
2587 
2588 #if defined(LPUART11)
2589 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2590 void LPUART11_TX_DriverIRQHandler(void);
LPUART11_TX_DriverIRQHandler(void)2591 void LPUART11_TX_DriverIRQHandler(void)
2592 {
2593     s_lpuartIsr[11](LPUART11, s_lpuartHandle[11]);
2594     SDK_ISR_EXIT_BARRIER;
2595 }
2596 void LPUART11_RX_DriverIRQHandler(void);
LPUART11_RX_DriverIRQHandler(void)2597 void LPUART11_RX_DriverIRQHandler(void)
2598 {
2599     s_lpuartIsr[11](LPUART11, s_lpuartHandle[11]);
2600     SDK_ISR_EXIT_BARRIER;
2601 }
2602 #else
2603 void LPUART11_DriverIRQHandler(void);
LPUART11_DriverIRQHandler(void)2604 void LPUART11_DriverIRQHandler(void)
2605 {
2606     s_lpuartIsr[11](LPUART11, s_lpuartHandle[11]);
2607     SDK_ISR_EXIT_BARRIER;
2608 }
2609 #endif
2610 #endif
2611 
2612 #if defined(LPUART12)
2613 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
2614 void LPUART12_TX_DriverIRQHandler(void);
LPUART12_TX_DriverIRQHandler(void)2615 void LPUART12_TX_DriverIRQHandler(void)
2616 {
2617     s_lpuartIsr[12](LPUART12, s_lpuartHandle[12]);
2618     SDK_ISR_EXIT_BARRIER;
2619 }
2620 void LPUART12_RX_DriverIRQHandler(void);
LPUART12_RX_DriverIRQHandler(void)2621 void LPUART12_RX_DriverIRQHandler(void)
2622 {
2623     s_lpuartIsr[12](LPUART12, s_lpuartHandle[12]);
2624     SDK_ISR_EXIT_BARRIER;
2625 }
2626 #else
2627 void LPUART12_DriverIRQHandler(void);
LPUART12_DriverIRQHandler(void)2628 void LPUART12_DriverIRQHandler(void)
2629 {
2630     s_lpuartIsr[12](LPUART12, s_lpuartHandle[12]);
2631     SDK_ISR_EXIT_BARRIER;
2632 }
2633 #endif
2634 #endif
2635 
2636 #if defined(CM4_0__LPUART)
2637 void M4_0_LPUART_DriverIRQHandler(void);
M4_0_LPUART_DriverIRQHandler(void)2638 void M4_0_LPUART_DriverIRQHandler(void)
2639 {
2640     s_lpuartIsr[LPUART_GetInstance(CM4_0__LPUART)](CM4_0__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_0__LPUART)]);
2641     SDK_ISR_EXIT_BARRIER;
2642 }
2643 #endif
2644 
2645 #if defined(CM4_1__LPUART)
2646 void M4_1_LPUART_DriverIRQHandler(void);
M4_1_LPUART_DriverIRQHandler(void)2647 void M4_1_LPUART_DriverIRQHandler(void)
2648 {
2649     s_lpuartIsr[LPUART_GetInstance(CM4_1__LPUART)](CM4_1__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_1__LPUART)]);
2650     SDK_ISR_EXIT_BARRIER;
2651 }
2652 #endif
2653 
2654 #if defined(CM4__LPUART)
2655 void M4_LPUART_DriverIRQHandler(void);
M4_LPUART_DriverIRQHandler(void)2656 void M4_LPUART_DriverIRQHandler(void)
2657 {
2658     s_lpuartIsr[LPUART_GetInstance(CM4__LPUART)](CM4__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4__LPUART)]);
2659     SDK_ISR_EXIT_BARRIER;
2660 }
2661 #endif
2662 
2663 #if defined(DMA__LPUART0)
2664 void DMA_UART0_INT_DriverIRQHandler(void);
DMA_UART0_INT_DriverIRQHandler(void)2665 void DMA_UART0_INT_DriverIRQHandler(void)
2666 {
2667     s_lpuartIsr[LPUART_GetInstance(DMA__LPUART0)](DMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART0)]);
2668     SDK_ISR_EXIT_BARRIER;
2669 }
2670 #endif
2671 
2672 #if defined(DMA__LPUART1)
2673 void DMA_UART1_INT_DriverIRQHandler(void);
DMA_UART1_INT_DriverIRQHandler(void)2674 void DMA_UART1_INT_DriverIRQHandler(void)
2675 {
2676     s_lpuartIsr[LPUART_GetInstance(DMA__LPUART1)](DMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART1)]);
2677     SDK_ISR_EXIT_BARRIER;
2678 }
2679 #endif
2680 
2681 #if defined(DMA__LPUART2)
2682 void DMA_UART2_INT_DriverIRQHandler(void);
DMA_UART2_INT_DriverIRQHandler(void)2683 void DMA_UART2_INT_DriverIRQHandler(void)
2684 {
2685     s_lpuartIsr[LPUART_GetInstance(DMA__LPUART2)](DMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART2)]);
2686     SDK_ISR_EXIT_BARRIER;
2687 }
2688 #endif
2689 
2690 #if defined(DMA__LPUART3)
2691 void DMA_UART3_INT_DriverIRQHandler(void);
DMA_UART3_INT_DriverIRQHandler(void)2692 void DMA_UART3_INT_DriverIRQHandler(void)
2693 {
2694     s_lpuartIsr[LPUART_GetInstance(DMA__LPUART3)](DMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART3)]);
2695     SDK_ISR_EXIT_BARRIER;
2696 }
2697 #endif
2698 
2699 #if defined(DMA__LPUART4)
2700 void DMA_UART4_INT_DriverIRQHandler(void);
DMA_UART4_INT_DriverIRQHandler(void)2701 void DMA_UART4_INT_DriverIRQHandler(void)
2702 {
2703     s_lpuartIsr[LPUART_GetInstance(DMA__LPUART4)](DMA__LPUART4, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART4)]);
2704     SDK_ISR_EXIT_BARRIER;
2705 }
2706 #endif
2707 
2708 #if defined(ADMA__LPUART0)
2709 void ADMA_UART0_INT_DriverIRQHandler(void);
ADMA_UART0_INT_DriverIRQHandler(void)2710 void ADMA_UART0_INT_DriverIRQHandler(void)
2711 {
2712     s_lpuartIsr[LPUART_GetInstance(ADMA__LPUART0)](ADMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART0)]);
2713     SDK_ISR_EXIT_BARRIER;
2714 }
2715 #endif
2716 
2717 #if defined(ADMA__LPUART1)
2718 void ADMA_UART1_INT_DriverIRQHandler(void);
ADMA_UART1_INT_DriverIRQHandler(void)2719 void ADMA_UART1_INT_DriverIRQHandler(void)
2720 {
2721     s_lpuartIsr[LPUART_GetInstance(ADMA__LPUART1)](ADMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART1)]);
2722     SDK_ISR_EXIT_BARRIER;
2723 }
2724 #endif
2725 
2726 #if defined(ADMA__LPUART2)
2727 void ADMA_UART2_INT_DriverIRQHandler(void);
ADMA_UART2_INT_DriverIRQHandler(void)2728 void ADMA_UART2_INT_DriverIRQHandler(void)
2729 {
2730     s_lpuartIsr[LPUART_GetInstance(ADMA__LPUART2)](ADMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART2)]);
2731     SDK_ISR_EXIT_BARRIER;
2732 }
2733 #endif
2734 
2735 #if defined(ADMA__LPUART3)
2736 void ADMA_UART3_INT_DriverIRQHandler(void);
ADMA_UART3_INT_DriverIRQHandler(void)2737 void ADMA_UART3_INT_DriverIRQHandler(void)
2738 {
2739     s_lpuartIsr[LPUART_GetInstance(ADMA__LPUART3)](ADMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART3)]);
2740     SDK_ISR_EXIT_BARRIER;
2741 }
2742 #endif
2743