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