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