1 /*
2 * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_flexio_uart.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /*<! @brief uart transfer state. */
16 enum _flexio_uart_transfer_states
17 {
18 kFLEXIO_UART_TxIdle, /* TX idle. */
19 kFLEXIO_UART_TxBusy, /* TX busy. */
20 kFLEXIO_UART_RxIdle, /* RX idle. */
21 kFLEXIO_UART_RxBusy /* RX busy. */
22 };
23
24 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
25 extern const clock_ip_name_t s_flexioClocks[];
26 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
27
28 extern FLEXIO_Type *const s_flexioBases[];
29
30 /*******************************************************************************
31 * Prototypes
32 ******************************************************************************/
33
34 extern uint32_t FLEXIO_GetInstance(FLEXIO_Type *base);
35
36 /*!
37 * @brief Get the length of received data in RX ring buffer.
38 *
39 * @param handle FLEXIO UART handle pointer.
40 * @return Length of received data in RX ring buffer.
41 */
42 static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle);
43
44 /*!
45 * @brief Check whether the RX ring buffer is full.
46 *
47 * @param handle FLEXIO UART handle pointer.
48 * @retval true RX ring buffer is full.
49 * @retval false RX ring buffer is not full.
50 */
51 static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle);
52
53 /*******************************************************************************
54 * Codes
55 ******************************************************************************/
56
FLEXIO_UART_GetInstance(FLEXIO_UART_Type * base)57 uint32_t FLEXIO_UART_GetInstance(FLEXIO_UART_Type *base)
58 {
59 return FLEXIO_GetInstance(base->flexioBase);
60 }
61
FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t * handle)62 static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle)
63 {
64 size_t size;
65
66 if (handle->rxRingBufferTail > handle->rxRingBufferHead)
67 {
68 size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail);
69 }
70 else
71 {
72 size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail);
73 }
74
75 return size;
76 }
77
FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t * handle)78 static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle)
79 {
80 bool full;
81
82 if (FLEXIO_UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
83 {
84 full = true;
85 }
86 else
87 {
88 full = false;
89 }
90
91 return full;
92 }
93
FLEXIO_UART_Init(FLEXIO_UART_Type * base,const flexio_uart_config_t * userConfig,uint32_t srcClock_Hz)94 status_t FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz)
95 {
96 assert(base && userConfig);
97
98 flexio_shifter_config_t shifterConfig;
99 flexio_timer_config_t timerConfig;
100 uint32_t ctrlReg = 0;
101 uint16_t timerDiv = 0;
102 uint16_t timerCmp = 0;
103 status_t result = kStatus_Success;
104
105 /* Clear the shifterConfig & timerConfig struct. */
106 memset(&shifterConfig, 0, sizeof(shifterConfig));
107 memset(&timerConfig, 0, sizeof(timerConfig));
108
109 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
110 /* Ungate flexio clock. */
111 CLOCK_EnableClock(s_flexioClocks[FLEXIO_UART_GetInstance(base)]);
112 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
113
114 /* Reset FLEXIO before configuration. */
115 FLEXIO_Reset(base->flexioBase);
116
117 /* Configure FLEXIO UART */
118 ctrlReg = base->flexioBase->CTRL;
119 ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
120 ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) |
121 FLEXIO_CTRL_FLEXEN(userConfig->enableUart));
122 if (!userConfig->enableInDoze)
123 {
124 ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
125 }
126
127 base->flexioBase->CTRL = ctrlReg;
128
129 /* Do hardware configuration. */
130 /* 1. Configure the shifter 0 for tx. */
131 shifterConfig.timerSelect = base->timerIndex[0];
132 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
133 shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
134 shifterConfig.pinSelect = base->TxPinIndex;
135 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
136 shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
137 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
138 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
139 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
140
141 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
142
143 /*2. Configure the timer 0 for tx. */
144 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
145 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
146 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
147 timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
148 timerConfig.pinSelect = base->TxPinIndex;
149 timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
150 timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
151 timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
152 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
153 timerConfig.timerReset = kFLEXIO_TimerResetNever;
154 timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
155 timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
156 timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
157 timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
158
159 timerDiv = srcClock_Hz / userConfig->baudRate_Bps;
160 timerDiv = timerDiv / 2 - 1;
161
162 if (timerDiv > 0xFFU)
163 {
164 result = kStatus_InvalidArgument;
165 }
166
167 timerCmp = ((uint32_t)(userConfig->bitCountPerChar * 2 - 1)) << 8U;
168 timerCmp |= timerDiv;
169
170 timerConfig.timerCompare = timerCmp;
171
172 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
173
174 /* 3. Configure the shifter 1 for rx. */
175 shifterConfig.timerSelect = base->timerIndex[1];
176 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
177 shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
178 shifterConfig.pinSelect = base->RxPinIndex;
179 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
180 shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
181 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
182 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
183 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
184
185 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
186
187 /* 4. Configure the timer 1 for rx. */
188 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->RxPinIndex);
189 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
190 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal;
191 timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
192 timerConfig.pinSelect = base->RxPinIndex;
193 timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
194 timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
195 timerConfig.timerOutput = kFLEXIO_TimerOutputOneAffectedByReset;
196 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
197 timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinRisingEdge;
198 timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
199 timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge;
200 timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
201 timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
202
203 timerConfig.timerCompare = timerCmp;
204
205 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
206
207 return result;
208 }
209
FLEXIO_UART_Deinit(FLEXIO_UART_Type * base)210 void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base)
211 {
212 /* Disable FLEXIO UART module. */
213 FLEXIO_UART_Enable(base, false);
214
215 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
216 /* Gate flexio clock. */
217 CLOCK_DisableClock(kCLOCK_Flexio0);
218 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
219 }
220
FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t * userConfig)221 void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig)
222 {
223 assert(userConfig);
224
225 userConfig->enableUart = true;
226 userConfig->enableInDoze = false;
227 userConfig->enableInDebug = true;
228 userConfig->enableFastAccess = false;
229 /* Default baud rate 115200. */
230 userConfig->baudRate_Bps = 115200U;
231 /* Default bit count at 8. */
232 userConfig->bitCountPerChar = kFLEXIO_UART_8BitsPerChar;
233 }
234
FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type * base,uint32_t mask)235 void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask)
236 {
237 if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable)
238 {
239 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
240 }
241 if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable)
242 {
243 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
244 }
245 }
246
FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type * base,uint32_t mask)247 void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask)
248 {
249 if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable)
250 {
251 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
252 }
253 if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable)
254 {
255 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
256 }
257 }
258
FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type * base)259 uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base)
260 {
261 uint32_t status = 0;
262 status =
263 ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
264 status |=
265 (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
266 << 1U);
267 status |=
268 (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
269 << 2U);
270 return status;
271 }
272
FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type * base,uint32_t mask)273 void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask)
274 {
275 if (mask & kFLEXIO_UART_TxDataRegEmptyFlag)
276 {
277 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
278 }
279 if (mask & kFLEXIO_UART_RxDataRegFullFlag)
280 {
281 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
282 }
283 if (mask & kFLEXIO_UART_RxOverRunFlag)
284 {
285 FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
286 }
287 }
288
FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type * base,const uint8_t * txData,size_t txSize)289 void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize)
290 {
291 assert(txData);
292 assert(txSize);
293
294 while (txSize--)
295 {
296 /* Wait until data transfer complete. */
297 while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))
298 {
299 }
300
301 base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *txData++;
302 }
303 }
304
FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type * base,uint8_t * rxData,size_t rxSize)305 void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize)
306 {
307 assert(rxData);
308 assert(rxSize);
309
310 while (rxSize--)
311 {
312 /* Wait until data transfer complete. */
313 while (!(FLEXIO_UART_GetStatusFlags(base) & kFLEXIO_UART_RxDataRegFullFlag))
314 {
315 }
316
317 *rxData++ = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]];
318 }
319 }
320
FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle,flexio_uart_transfer_callback_t callback,void * userData)321 status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base,
322 flexio_uart_handle_t *handle,
323 flexio_uart_transfer_callback_t callback,
324 void *userData)
325 {
326 assert(handle);
327
328 IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
329
330 /* Zero the handle. */
331 memset(handle, 0, sizeof(*handle));
332
333 /* Set the TX/RX state. */
334 handle->rxState = kFLEXIO_UART_RxIdle;
335 handle->txState = kFLEXIO_UART_TxIdle;
336
337 /* Set the callback and user data. */
338 handle->callback = callback;
339 handle->userData = userData;
340
341 /* Enable interrupt in NVIC. */
342 EnableIRQ(flexio_irqs[FLEXIO_UART_GetInstance(base)]);
343
344 /* Save the context in global variables to support the double weak mechanism. */
345 return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_UART_TransferHandleIRQ);
346 }
347
FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle,uint8_t * ringBuffer,size_t ringBufferSize)348 void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base,
349 flexio_uart_handle_t *handle,
350 uint8_t *ringBuffer,
351 size_t ringBufferSize)
352 {
353 assert(handle);
354
355 /* Setup the ringbuffer address */
356 if (ringBuffer)
357 {
358 handle->rxRingBuffer = ringBuffer;
359 handle->rxRingBufferSize = ringBufferSize;
360 handle->rxRingBufferHead = 0U;
361 handle->rxRingBufferTail = 0U;
362
363 /* Enable the interrupt to accept the data when user need the ring buffer. */
364 FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
365 }
366 }
367
FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle)368 void FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle)
369 {
370 assert(handle);
371
372 if (handle->rxState == kFLEXIO_UART_RxIdle)
373 {
374 FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
375 }
376
377 handle->rxRingBuffer = NULL;
378 handle->rxRingBufferSize = 0U;
379 handle->rxRingBufferHead = 0U;
380 handle->rxRingBufferTail = 0U;
381 }
382
FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle,flexio_uart_transfer_t * xfer)383 status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base,
384 flexio_uart_handle_t *handle,
385 flexio_uart_transfer_t *xfer)
386 {
387 status_t status;
388
389 /* Return error if xfer invalid. */
390 if ((0U == xfer->dataSize) || (NULL == xfer->data))
391 {
392 return kStatus_InvalidArgument;
393 }
394
395 /* Return error if current TX busy. */
396 if (kFLEXIO_UART_TxBusy == handle->txState)
397 {
398 status = kStatus_FLEXIO_UART_TxBusy;
399 }
400 else
401 {
402 handle->txData = xfer->data;
403 handle->txDataSize = xfer->dataSize;
404 handle->txDataSizeAll = xfer->dataSize;
405 handle->txState = kFLEXIO_UART_TxBusy;
406
407 /* Enable transmiter interrupt. */
408 FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable);
409
410 status = kStatus_Success;
411 }
412
413 return status;
414 }
415
FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle)416 void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle)
417 {
418 /* Disable the transmitter and disable the interrupt. */
419 FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable);
420
421 handle->txDataSize = 0;
422 handle->txState = kFLEXIO_UART_TxIdle;
423 }
424
FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle,size_t * count)425 status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count)
426 {
427 assert(handle);
428 assert(count);
429
430 if (kFLEXIO_UART_TxIdle == handle->txState)
431 {
432 return kStatus_NoTransferInProgress;
433 }
434
435 *count = handle->txDataSizeAll - handle->txDataSize;
436
437 return kStatus_Success;
438 }
439
FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle,flexio_uart_transfer_t * xfer,size_t * receivedBytes)440 status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base,
441 flexio_uart_handle_t *handle,
442 flexio_uart_transfer_t *xfer,
443 size_t *receivedBytes)
444 {
445 uint32_t i;
446 status_t status;
447 /* How many bytes to copy from ring buffer to user memory. */
448 size_t bytesToCopy = 0U;
449 /* How many bytes to receive. */
450 size_t bytesToReceive;
451 /* How many bytes currently have received. */
452 size_t bytesCurrentReceived;
453
454 /* Return error if xfer invalid. */
455 if ((0U == xfer->dataSize) || (NULL == xfer->data))
456 {
457 return kStatus_InvalidArgument;
458 }
459
460 /* How to get data:
461 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
462 to uart handle, enable interrupt to store received data to xfer->data. When
463 all data received, trigger callback.
464 2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
465 If there are enough data in ring buffer, copy them to xfer->data and return.
466 If there are not enough data in ring buffer, copy all of them to xfer->data,
467 save the xfer->data remained empty space to uart handle, receive data
468 to this empty space and trigger callback when finished. */
469
470 if (kFLEXIO_UART_RxBusy == handle->rxState)
471 {
472 status = kStatus_FLEXIO_UART_RxBusy;
473 }
474 else
475 {
476 bytesToReceive = xfer->dataSize;
477 bytesCurrentReceived = 0U;
478
479 /* If RX ring buffer is used. */
480 if (handle->rxRingBuffer)
481 {
482 /* Disable FLEXIO_UART RX IRQ, protect ring buffer. */
483 FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
484
485 /* How many bytes in RX ring buffer currently. */
486 bytesToCopy = FLEXIO_UART_TransferGetRxRingBufferLength(handle);
487
488 if (bytesToCopy)
489 {
490 bytesToCopy = MIN(bytesToReceive, bytesToCopy);
491
492 bytesToReceive -= bytesToCopy;
493
494 /* Copy data from ring buffer to user memory. */
495 for (i = 0U; i < bytesToCopy; i++)
496 {
497 xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
498
499 /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
500 if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
501 {
502 handle->rxRingBufferTail = 0U;
503 }
504 else
505 {
506 handle->rxRingBufferTail++;
507 }
508 }
509 }
510
511 /* If ring buffer does not have enough data, still need to read more data. */
512 if (bytesToReceive)
513 {
514 /* No data in ring buffer, save the request to UART handle. */
515 handle->rxData = xfer->data + bytesCurrentReceived;
516 handle->rxDataSize = bytesToReceive;
517 handle->rxDataSizeAll = bytesToReceive;
518 handle->rxState = kFLEXIO_UART_RxBusy;
519 }
520
521 /* Enable FLEXIO_UART RX IRQ if previously enabled. */
522 FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
523 }
524 /* Ring buffer not used. */
525 else
526 {
527 handle->rxData = xfer->data + bytesCurrentReceived;
528 handle->rxDataSize = bytesToReceive;
529 handle->rxDataSizeAll = bytesToReceive;
530 handle->rxState = kFLEXIO_UART_RxBusy;
531
532 /* Enable RX interrupt. */
533 FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
534 }
535
536 /* Return the how many bytes have read. */
537 if (receivedBytes)
538 {
539 *receivedBytes = bytesCurrentReceived;
540 }
541
542 status = kStatus_Success;
543 }
544
545 return status;
546 }
547
FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle)548 void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle)
549 {
550 /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
551 if (!handle->rxRingBuffer)
552 {
553 /* Disable RX interrupt. */
554 FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
555 }
556
557 handle->rxDataSize = 0U;
558 handle->rxState = kFLEXIO_UART_RxIdle;
559 }
560
FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type * base,flexio_uart_handle_t * handle,size_t * count)561 status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count)
562 {
563 assert(handle);
564 assert(count);
565
566 if (kFLEXIO_UART_RxIdle == handle->rxState)
567 {
568 return kStatus_NoTransferInProgress;
569 }
570
571 *count = handle->rxDataSizeAll - handle->rxDataSize;
572
573 return kStatus_Success;
574 }
575
FLEXIO_UART_TransferHandleIRQ(void * uartType,void * uartHandle)576 void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle)
577 {
578 uint8_t count = 1;
579 FLEXIO_UART_Type *base = (FLEXIO_UART_Type *)uartType;
580 flexio_uart_handle_t *handle = (flexio_uart_handle_t *)uartHandle;
581
582 /* Read the status back. */
583 uint8_t status = FLEXIO_UART_GetStatusFlags(base);
584
585 /* If RX overrun. */
586 if (kFLEXIO_UART_RxOverRunFlag & status)
587 {
588 /* Clear Overrun flag. */
589 FLEXIO_UART_ClearStatusFlags(base, kFLEXIO_UART_RxOverRunFlag);
590
591 /* Trigger callback. */
592 if (handle->callback)
593 {
594 handle->callback(base, handle, kStatus_FLEXIO_UART_RxHardwareOverrun, handle->userData);
595 }
596 }
597
598 /* Receive data register full */
599 if ((kFLEXIO_UART_RxDataRegFullFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[1])))
600 {
601 /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
602 if (handle->rxDataSize)
603 {
604 /* Using non block API to read the data from the registers. */
605 FLEXIO_UART_ReadByte(base, handle->rxData);
606 handle->rxDataSize--;
607 handle->rxData++;
608 count--;
609
610 /* If all the data required for upper layer is ready, trigger callback. */
611 if (!handle->rxDataSize)
612 {
613 handle->rxState = kFLEXIO_UART_RxIdle;
614
615 if (handle->callback)
616 {
617 handle->callback(base, handle, kStatus_FLEXIO_UART_RxIdle, handle->userData);
618 }
619 }
620 }
621
622 if (handle->rxRingBuffer)
623 {
624 if (count)
625 {
626 /* If RX ring buffer is full, trigger callback to notify over run. */
627 if (FLEXIO_UART_TransferIsRxRingBufferFull(handle))
628 {
629 if (handle->callback)
630 {
631 handle->callback(base, handle, kStatus_FLEXIO_UART_RxRingBufferOverrun, handle->userData);
632 }
633 }
634
635 /* If ring buffer is still full after callback function, the oldest data is overrided. */
636 if (FLEXIO_UART_TransferIsRxRingBufferFull(handle))
637 {
638 /* Increase handle->rxRingBufferTail to make room for new data. */
639 if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
640 {
641 handle->rxRingBufferTail = 0U;
642 }
643 else
644 {
645 handle->rxRingBufferTail++;
646 }
647 }
648
649 /* Read data. */
650 handle->rxRingBuffer[handle->rxRingBufferHead] = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]];
651
652 /* Increase handle->rxRingBufferHead. */
653 if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
654 {
655 handle->rxRingBufferHead = 0U;
656 }
657 else
658 {
659 handle->rxRingBufferHead++;
660 }
661 }
662 }
663 /* If no receive requst pending, stop RX interrupt. */
664 else if (!handle->rxDataSize)
665 {
666 FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
667 }
668 else
669 {
670 }
671 }
672
673 /* Send data register empty and the interrupt is enabled. */
674 if ((kFLEXIO_UART_TxDataRegEmptyFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[0])))
675 {
676 if (handle->txDataSize)
677 {
678 /* Using non block API to write the data to the registers. */
679 FLEXIO_UART_WriteByte(base, handle->txData);
680 handle->txData++;
681 handle->txDataSize--;
682 count--;
683
684 /* If all the data are written to data register, TX finished. */
685 if (!handle->txDataSize)
686 {
687 handle->txState = kFLEXIO_UART_TxIdle;
688
689 /* Disable TX register empty interrupt. */
690 FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable);
691
692 /* Trigger callback. */
693 if (handle->callback)
694 {
695 handle->callback(base, handle, kStatus_FLEXIO_UART_TxIdle, handle->userData);
696 }
697 }
698 }
699 }
700 }
701