S32 SDK
flexio_uart_driver.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
19 #include "flexio_uart_driver.h"
20 #include "flexio_hal.h"
21 #include "flexio_common.h"
22 #include "clock_manager.h"
23 
84 /*******************************************************************************
85  * Variables
86  ******************************************************************************/
87 
90 /* Constraints used for baud rate computation */
91 /* Divider minimum value is 0 for UART, so there is no point defining it */
92 #define DIVIDER_MAX_VALUE 0xFFU
93 
94 /* Shifters/Timers used for UART simulation The parameter x represents the
95  resourceIndex value for the current driver instance */
96 #define TX_SHIFTER(x) (x)
97 #define RX_SHIFTER(x) (x)
98 #define TX_TIMER(x) (x)
99 #define RX_TIMER(x) (x)
100 
101 /*******************************************************************************
102  * Private Functions
103  ******************************************************************************/
104 
105 
106 /*FUNCTION**********************************************************************
107  *
108  * Function Name : FLEXIO_UART_DRV_ComputeBaudRateDivider
109  * Description : Computes the baud rate divider for a target baud rate
110  *
111  *END**************************************************************************/
112 static void FLEXIO_UART_DRV_ComputeBaudRateDivider(flexio_uart_state_t *state,
113  uint32_t baudRate,
114  uint16_t *divider,
115  uint32_t inputClock)
116 {
117  uint32_t tmpDiv;
118 
119  (void)state;
120  /* Compute divider: ((input_clock / baud_rate) / 2) - 1. Round to nearest integer */
121  tmpDiv = ((inputClock + baudRate) / (2U * baudRate)) - 1U;
122  /* Enforce upper limit; lower limit is 0 for UART */
123  if (tmpDiv > DIVIDER_MAX_VALUE)
124  {
125  tmpDiv = DIVIDER_MAX_VALUE;
126  }
127 
128  *divider = (uint16_t)tmpDiv;
129 }
130 
131 
132 /*FUNCTION**********************************************************************
133  *
134  * Function Name : FLEXIO_UART_DRV_Configure
135  * Description : configures the FLEXIO module for UART
136  *
137  *END**************************************************************************/
138 static void FLEXIO_UART_DRV_ConfigureTx(flexio_uart_state_t *state,
139  const flexio_uart_user_config_t * userConfigPtr,
140  uint32_t inputClock)
141 {
142  FLEXIO_Type *baseAddr;
143  uint16_t divider;
144  uint16_t bits;
145  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
146 
147  baseAddr = g_flexioBase[state->flexioCommon.instance];
148  resourceIndex = state->flexioCommon.resourceIndex;
149 
150  /* Compute divider. */
151  FLEXIO_UART_DRV_ComputeBaudRateDivider(state, userConfigPtr->baudRate, &divider, inputClock);
152  bits = userConfigPtr->bitCount;
153 
154  /* Configure tx shifter */
156  TX_SHIFTER(resourceIndex),
161  TX_SHIFTER(resourceIndex),
163  userConfigPtr->dataPin, /* output on tx pin */
166  TX_TIMER(resourceIndex),
168 
169  /* Configure tx timer */
170  FLEXIO_HAL_SetTimerCompare(baseAddr, TX_TIMER(resourceIndex), (uint16_t)((((bits << 1U) - 1U) << 8U) + divider));
171  FLEXIO_HAL_SetTimerConfig(baseAddr,
172  TX_TIMER(resourceIndex),
175  FLEXIO_TIMER_ENABLE_TRG_HIGH, /* enable when Tx data is available */
178  FLEXIO_TIMER_DECREMENT_CLK_SHIFT_TMR, /* decrement on FlexIO clock */
181  TX_TIMER(resourceIndex),
182  (uint8_t)((TX_SHIFTER(resourceIndex) << 2U) + 1U), /* trigger on tx shifter status flag */
185  0U, /* pin unused */
189  /* disable Tx shifter */
190  FLEXIO_HAL_SetShifterMode(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_DISABLED);
191 }
192 
193 
194 
195 /*FUNCTION**********************************************************************
196  *
197  * Function Name : FLEXIO_UART_DRV_Configure
198  * Description : configures the FLEXIO module for UART
199  *
200  *END**************************************************************************/
201 static void FLEXIO_UART_DRV_ConfigureRx(flexio_uart_state_t *state,
202  const flexio_uart_user_config_t * userConfigPtr,
203  uint32_t inputClock)
204 {
205  FLEXIO_Type *baseAddr;
206  uint16_t divider;
207  uint16_t bits;
208  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
209 
210  baseAddr = g_flexioBase[state->flexioCommon.instance];
211  resourceIndex = state->flexioCommon.resourceIndex;
212 
213  /* Compute divider. */
214  FLEXIO_UART_DRV_ComputeBaudRateDivider(state, userConfigPtr->baudRate, &divider, inputClock);
215  bits = userConfigPtr->bitCount;
216 
217  /* Configure rx shifter */
219  RX_SHIFTER(resourceIndex),
224  RX_SHIFTER(resourceIndex),
226  userConfigPtr->dataPin, /* input from rx pin */
229  RX_TIMER(resourceIndex),
231 
232  /* Configure rx timer */
233  FLEXIO_HAL_SetTimerCompare(baseAddr, RX_TIMER(resourceIndex), (uint16_t)((((bits << 1U) - 1U) << 8U) + divider));
234  FLEXIO_HAL_SetTimerConfig(baseAddr,
235  RX_TIMER(resourceIndex),
238  FLEXIO_TIMER_ENABLE_PIN_POSEDGE, /* enable when data is available */
241  FLEXIO_TIMER_DECREMENT_CLK_SHIFT_TMR, /* decrement on FlexIO clock */
244  RX_TIMER(resourceIndex),
245  0U, /* trigger unused */
248  userConfigPtr->dataPin, /* input from rx pin */
252 }
253 
254 
255 /*FUNCTION**********************************************************************
256  *
257  * Function Name : FLEXIO_UART_DRV_EndTransfer
258  * Description : End the current transfer
259  *
260  *END**************************************************************************/
261 static void FLEXIO_UART_DRV_EndTransfer(flexio_uart_state_t *state)
262 {
263  FLEXIO_Type *baseAddr;
264  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
265 
266  baseAddr = g_flexioBase[state->flexioCommon.instance];
267  resourceIndex = state->flexioCommon.resourceIndex;
268 
269  /* Disable transfer engine */
270  switch (state->driverType)
271  {
273  /* Disable interrupts for Rx / Tx shifter */
274  FLEXIO_HAL_SetShifterInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), false);
275  FLEXIO_HAL_SetShifterErrorInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), false);
276  /* disable timer interrupt */
277  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << TX_TIMER(resourceIndex)), false);
278  break;
280  /* Nothing to do here */
281  break;
283  /* for Tx we need to disable timer interrupt */
284  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << TX_TIMER(resourceIndex)), false);
285  /* Stop DMA channels */
286  (void)EDMA_DRV_StopChannel(state->dmaChannel);
287  /* Disable the FlexIO DMA request */
288  FLEXIO_HAL_SetShifterDMARequest(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), false);
289  break;
290  default:
291  /* Impossible type - do nothing */
292  break;
293  }
294 
295  state->driverIdle = true;
296  /* Signal transfer end for blocking transfers */
297  if (state->blocking == true)
298  {
299  (void)OSIF_SemaPost(&(state->idleSemaphore));
300  }
301 }
302 
303 
304 /*FUNCTION**********************************************************************
305  *
306  * Function Name : FLEXIO_UART_DRV_EnableTransfer
307  * Description : Enables timers and shifters to start a transfer
308  *
309  *END**************************************************************************/
310 static void FLEXIO_UART_DRV_EnableTransfer(flexio_uart_state_t *state)
311 {
312  FLEXIO_Type *baseAddr;
313  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
314 
315  resourceIndex = state->flexioCommon.resourceIndex;
316  baseAddr = g_flexioBase[state->flexioCommon.instance];
317 
318  /* Enable timers and shifters */
319  if (state->direction == FLEXIO_UART_DIRECTION_TX)
320  {
321  /* In tx mode restore start bit in case it was changed for end of transmission detection */
322  FLEXIO_HAL_SetShifterStartBit(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_START_BIT_0);
323  FLEXIO_HAL_SetShifterMode(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_TRANSMIT);
324  }
325  else
326  {
327  /* In rx mode, discard any leftover rx. data */
328  FLEXIO_HAL_ClearShifterStatus(baseAddr, RX_SHIFTER(resourceIndex));
329  FLEXIO_HAL_SetShifterMode(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_RECEIVE);
330  }
331  FLEXIO_HAL_SetTimerMode(baseAddr, TX_TIMER(resourceIndex), FLEXIO_TIMER_MODE_8BIT_BAUD);
332 }
333 
334 
335 /*FUNCTION**********************************************************************
336  *
337  * Function Name : FLEXIO_UART_DRV_StopTransfer
338  * Description : Forcefully stops the current transfer
339  *
340  *END**************************************************************************/
341 static void FLEXIO_UART_DRV_StopTransfer(flexio_uart_state_t *state)
342 {
343  FLEXIO_Type *baseAddr;
344  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
345 
346  resourceIndex = state->flexioCommon.resourceIndex;
347  baseAddr = g_flexioBase[state->flexioCommon.instance];
348 
349  /* disable and re-enable timers and shifters to reset them */
350  FLEXIO_HAL_SetShifterMode(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_DISABLED);
351  FLEXIO_HAL_SetTimerMode(baseAddr, TX_TIMER(resourceIndex), FLEXIO_TIMER_MODE_DISABLED);
352 
353  /* clear any leftover error flags */
354  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, TX_SHIFTER(resourceIndex));
355 
356  /* end the transfer */
357  FLEXIO_UART_DRV_EndTransfer(state);
358 }
359 
360 
361 /*FUNCTION**********************************************************************
362  *
363  * Function Name : FLEXIO_UART_DRV_WaitTransferEnd
364  * Description : waits for the end of a blocking transfer
365  *
366  *END**************************************************************************/
367 static status_t FLEXIO_UART_DRV_WaitTransferEnd(flexio_uart_state_t *state, uint32_t timeout)
368 {
369  status_t osifError = STATUS_SUCCESS;
370 
371  switch (state->driverType)
372  {
374  /* Wait for transfer to be completed by the IRQ */
375  osifError = OSIF_SemaWait(&(state->idleSemaphore), timeout);
376  break;
378  /* Call FLEXIO_UART_DRV_GetStatus() to do the transfer */
379  while (FLEXIO_UART_DRV_GetStatus(state, NULL) == STATUS_BUSY) {}
380  break;
382  /* Wait for transfer completion to be signaled by the DMA or IRQ */
383  osifError = OSIF_SemaWait(&(state->idleSemaphore), timeout);
384  break;
385  default:
386  /* Impossible type - do nothing */
387  break;
388  }
389 
390  /* blocking transfer is over */
391  state->blocking = false;
392  if (osifError == STATUS_TIMEOUT)
393  {
394  /* abort current transfer */
395  state->status = STATUS_TIMEOUT;
396  FLEXIO_UART_DRV_StopTransfer(state);
397  }
398 
399  return state->status;
400 }
401 
402 
403 /*FUNCTION**********************************************************************
404  *
405  * Function Name : FLEXIO_UART_DRV_ReadData
406  * Description : reads data received by the module
407  *
408  *END**************************************************************************/
409 static void FLEXIO_UART_DRV_ReadData(flexio_uart_state_t *state)
410 {
411  const FLEXIO_Type *baseAddr;
412  uint32_t data;
413  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
414 
415  DEV_ASSERT(state->remainingBytes > 0U);
416  DEV_ASSERT(state->data != NULL);
417 
418  baseAddr = g_flexioBase[state->flexioCommon.instance];
419  resourceIndex = state->flexioCommon.resourceIndex;
420 
421  /* Read data from shifter buffer */
422  data = FLEXIO_HAL_ReadShifterBuffer(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_RW_MODE_NORMAL);
423  data >>= 32U - (uint32_t)(state->bitCount);
424 
425  if (state->bitCount <= 8U)
426  {
427  *(uint8_t *)state->data = (uint8_t)data;
428  /* Update rx buffer pointer and remaining bytes count */
429  state->data ++;
430  state->remainingBytes -= 1U;
431  }
432  else
433  {
434  /* for more than 8 bits per word 2 bytes are needed */
435  *(uint16_t *)state->data = (uint16_t)data;
436  /* Update rx buffer pointer and remaining bytes count */
437  state->data = &state->data[2U];
438  state->remainingBytes -= 2U;
439  }
440 }
441 
442 
443 /*FUNCTION**********************************************************************
444  *
445  * Function Name : FLEXIO_UART_DRV_WriteData
446  * Description : writes data to be transmitted by the module
447  *
448  *END**************************************************************************/
449 static void FLEXIO_UART_DRV_WriteData(flexio_uart_state_t *state)
450 {
451  FLEXIO_Type *baseAddr;
452  uint32_t data;
453  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
454 
455  DEV_ASSERT(state->data != NULL);
456 
457  baseAddr = g_flexioBase[state->flexioCommon.instance];
458  resourceIndex = state->flexioCommon.resourceIndex;
459 
460  if (state->remainingBytes == 0U)
461  {
462  /* Done transmitting */
463  return;
464  }
465  /* Read data from user buffer and update tx buffer pointer and remaining bytes count */
466  if (state->bitCount <= 8U)
467  {
468  data = (uint32_t)(*(uint8_t *)state->data);
469  state->data++;
470  state->remainingBytes -= 1U;
471  }
472  else
473  {
474  /* for more than 8 bits per word 2 bytes are needed */
475  data = (uint32_t)(*(uint16_t *)state->data);
476  state->data = &state->data[2U];
477  state->remainingBytes -= 2U;
478  }
479 
480  FLEXIO_HAL_WriteShifterBuffer(baseAddr, TX_SHIFTER(resourceIndex), data, FLEXIO_SHIFTER_RW_MODE_NORMAL);
481 }
482 
483 
484 /*FUNCTION**********************************************************************
485  *
486  * Function Name : FLEXIO_UART_DRV_CheckStatusTx
487  * Description : Check status of the UART transmission. This function can be
488  * called either in an interrupt routine or directly in polling
489  * mode to advance the transfer.
490  *
491  *END**************************************************************************/
492 static void FLEXIO_UART_DRV_CheckStatusTx(void *stateStruct)
493 {
494  FLEXIO_Type *baseAddr;
495  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
496  flexio_uart_state_t *state;
497 
498  DEV_ASSERT(stateStruct != NULL);
499 
500  state = (flexio_uart_state_t *)stateStruct;
501  baseAddr = g_flexioBase[state->flexioCommon.instance];
502  resourceIndex = state->flexioCommon.resourceIndex;
503 
504  /* No need to check for Tx underflow since timer is controlled by the shifter status flag */
505  /* Check for transfer end */
506  if (state->remainingBytes == 0U)
507  {
508  if (FLEXIO_HAL_GetTimerStatus(baseAddr, TX_TIMER(resourceIndex)))
509  {
510  /* Clear timer status */
511  FLEXIO_HAL_ClearTimerStatus(baseAddr, TX_TIMER(resourceIndex));
512  state->txFlush--;
513  if (state->txFlush == 0U)
514  {
515  /* Done flushing the Tx buffer, end transfer */
516  /* Record success if there was no error */
517  if (state->status == STATUS_BUSY)
518  {
519  state->status = STATUS_SUCCESS;
520  }
521  FLEXIO_UART_DRV_StopTransfer(state);
522  /* Call callback to announce the end transfer event to the user */
523  if (state->callback != NULL)
524  {
525  state->callback(state, FLEXIO_EVENT_END_TRANSFER, state->callbackParam);
526  }
527  }
528  else if (FLEXIO_HAL_GetShifterStatus(baseAddr, TX_SHIFTER(resourceIndex)))
529  {
530  /* txFlush == 1, but last byte was already transferred from buffer to shifter. There is a
531  danger that the transmission is over and we end up never reporting the end event.
532  To avoid this, send one extra dummy byte */
533  /* set start bit to 1 and send an 0xFF byte, this way the line will appear idle */
534  FLEXIO_HAL_SetShifterStartBit(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_START_BIT_1);
535  FLEXIO_HAL_WriteShifterBuffer(baseAddr, TX_SHIFTER(resourceIndex), 0xFFFFFFFFUL, FLEXIO_SHIFTER_RW_MODE_NORMAL);
536  }
537  else
538  {
539  /* txFlush == 1, and last byte was not yet transferred from buffer to shifter.
540  No need to do anything, just wait for the next timer event. */
541  }
542  }
543  }
544  /* Check if transmitter needs more data */
545  else if (FLEXIO_HAL_GetShifterStatus(baseAddr, TX_SHIFTER(resourceIndex)) && (state->remainingBytes > 0U))
546  {
547  FLEXIO_UART_DRV_WriteData(state);
548  if (state->remainingBytes == 0U)
549  {
550  /* Out of data, call callback to allow user to provide a new buffer */
551  if (state->callback != NULL)
552  {
553  state->callback(state, FLEXIO_EVENT_TX_EMPTY, state->callbackParam);
554  }
555  }
556  if (state->remainingBytes == 0U)
557  {
558  /* No more data, transmission will stop after the last bytes are sent.
559  The timer event will indicate when the send is complete */
560  /* clear any previous timer events */
561  FLEXIO_HAL_ClearTimerStatus(baseAddr, TX_TIMER(resourceIndex));
562  if (state->driverType == FLEXIO_DRIVER_TYPE_INTERRUPTS)
563  {
564  /* transmission completed; disable interrupt */
565  FLEXIO_HAL_SetShifterInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), false);
566  /* enable timer interrupt to ensure that transfer is completed */
567  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << TX_TIMER(resourceIndex)), true);
568  }
569  }
570  }
571  else
572  {
573  /* No relevant events - nothing to do */
574  }
575 
576 }
577 
578 /*FUNCTION**********************************************************************
579  *
580  * Function Name : FLEXIO_UART_DRV_CheckStatusRx
581  * Description : Check status of the UART reception. This function can be
582  * called either in an interrupt routine or directly in polling
583  * mode to advance the transfer.
584  *
585  *END**************************************************************************/
586 static void FLEXIO_UART_DRV_CheckStatusRx(void *stateStruct)
587 {
588  FLEXIO_Type *baseAddr;
589  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
590  flexio_uart_state_t *state;
591 
592  DEV_ASSERT(stateStruct != NULL);
593 
594  state = (flexio_uart_state_t *)stateStruct;
595  baseAddr = g_flexioBase[state->flexioCommon.instance];
596  resourceIndex = state->flexioCommon.resourceIndex;
597 
598  /* Check for errors */
599  if (FLEXIO_HAL_GetShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex)))
600  {
601  state->status = STATUS_UART_RX_OVERRUN;
602  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex));
603  state->remainingBytes = 0U;
604  /* Continue processing events */
605  }
606  /* Check if data was received */
607  else if (FLEXIO_HAL_GetShifterStatus(baseAddr, RX_SHIFTER(resourceIndex)))
608  {
609  FLEXIO_UART_DRV_ReadData(state);
610  if (state->remainingBytes == 0U)
611  {
612  /* Out of data, call callback to allow user to provide a new buffer */
613  if (state->callback != NULL)
614  {
615  state->callback(state, FLEXIO_EVENT_RX_FULL, state->callbackParam);
616  }
617  }
618  }
619  else
620  {
621  /* No events - nothing to do */
622  }
623  /* Check if transfer is over */
624  if (state->remainingBytes == 0U)
625  {
626  /* Record success if there was no error */
627  if (state->status == STATUS_BUSY)
628  {
629  state->status = STATUS_SUCCESS;
630  }
631  /* discard any leftover rx. data */
632  FLEXIO_HAL_ClearShifterStatus(baseAddr, RX_SHIFTER(resourceIndex));
633  /* End transfer */
634  FLEXIO_UART_DRV_StopTransfer(state);
635  /* Call callback to announce the event to the user */
636  if (state->callback != NULL)
637  {
638  state->callback(state, FLEXIO_EVENT_END_TRANSFER, state->callbackParam);
639  }
640  }
641 }
642 
643 /*FUNCTION**********************************************************************
644  *
645  * Function Name : FLEXIO_UART_DRV_CheckStatus
646  * Description : Check status of the UART transfer. This function can be
647  * called either in an interrupt routine or directly in polling
648  * mode to advance the transfer.
649  *
650  *END**************************************************************************/
651 static void FLEXIO_UART_DRV_CheckStatus(void *stateStruct)
652 {
653  const flexio_uart_state_t *state;
654 
655  DEV_ASSERT(stateStruct != NULL);
656 
657  state = (flexio_uart_state_t *)stateStruct;
658  if (state->direction == FLEXIO_UART_DIRECTION_TX)
659  {
660  FLEXIO_UART_DRV_CheckStatusTx(stateStruct);
661  }
662  else
663  {
664  FLEXIO_UART_DRV_CheckStatusRx(stateStruct);
665  }
666 }
667 
668 
669 /*FUNCTION**********************************************************************
670  *
671  * Function Name : FLEXIO_UART_DRV_EndDmaTxTransfer
672  * Description : function called at the end of a DMA Tx transfer
673  *
674  *END**************************************************************************/
675 static void FLEXIO_UART_DRV_EndDmaTxTransfer(void *stateStruct, edma_chn_status_t status)
676 {
677  flexio_uart_state_t *state;
678  uint8_t dmaChn;
679  DMA_Type *edmaBase;
680  uint32_t byteCount;
681  FLEXIO_Type *baseAddr;
682 
683  DEV_ASSERT(stateStruct != NULL);
684 
685  (void)status;
686  state = (flexio_uart_state_t *)stateStruct;
687  baseAddr = g_flexioBase[state->flexioCommon.instance];
688 
689  /* Call callback to allow user to provide a new buffer */
690  if (state->callback != NULL)
691  {
692  state->callback(state, FLEXIO_EVENT_TX_EMPTY, state->callbackParam);
693  }
694  if (state->remainingBytes == 0U)
695  {
696  /* No more data to transmit, transmission will stop */
697  /* enable timer interrupt to let IRQ ensure that transfer is completed */
698  FLEXIO_HAL_ClearTimerStatus(baseAddr, TX_TIMER(state->flexioCommon.resourceIndex));
699  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << TX_TIMER(state->flexioCommon.resourceIndex)), true);
700  }
701  else
702  {
703  /* There is more data to transfer, restart DMA channel */
704  /* Update buffer address and size */
705  dmaChn = state->dmaChannel;
706  edmaBase = g_edmaBase[0U];
707  if (state->bitCount <= 8U)
708  {
709  byteCount = 1U;
710  }
711  else
712  {
713  byteCount = 2U;
714  }
715  EDMA_HAL_TCDSetSrcAddr(edmaBase, dmaChn, (uint32_t)(state->data));
716  EDMA_HAL_TCDSetMajorCount(edmaBase, dmaChn, state->remainingBytes / byteCount);
717  /* Now that this tx is set up, clear remaining bytes count */
718  state->remainingBytes = 0U;
719  /* Start the channel */
720  (void)EDMA_DRV_StartChannel(dmaChn);
721  }
722 }
723 
724 
725 /*FUNCTION**********************************************************************
726  *
727  * Function Name : FLEXIO_UART_DRV_EndDmaRxTransfer
728  * Description : function called at the end of a DMA Rx transfer
729  *
730  *END**************************************************************************/
731 static void FLEXIO_UART_DRV_EndDmaRxTransfer(void *stateStruct, edma_chn_status_t status)
732 {
733  flexio_uart_state_t *state;
734  uint8_t dmaChn;
735  DMA_Type *edmaBase;
736  uint32_t byteCount;
737 
738  DEV_ASSERT(stateStruct != NULL);
739 
740  (void)status;
741  state = (flexio_uart_state_t *)stateStruct;
742 
743  /* Call callback to allow user to provide a new buffer */
744  if (state->callback != NULL)
745  {
746  state->callback(state, FLEXIO_EVENT_RX_FULL, state->callbackParam);
747  }
748  if (state->remainingBytes == 0U)
749  {
750  /* No more data to transmit, reception will stop */
751  state->status = STATUS_SUCCESS;
752  FLEXIO_UART_DRV_StopTransfer(state);
753  /* Call callback to announce the event to the user */
754  if (state->callback != NULL)
755  {
756  state->callback(state, FLEXIO_EVENT_END_TRANSFER, state->callbackParam);
757  }
758  }
759  else
760  {
761  /* There is more data to transfer, restart DMA channel */
762  /* Update buffer address and size */
763  dmaChn = state->dmaChannel;
764  edmaBase = g_edmaBase[0U];
765  if (state->bitCount <= 8U)
766  {
767  byteCount = 1U;
768  }
769  else
770  {
771  byteCount = 2U;
772  }
773  EDMA_HAL_TCDSetDestAddr(edmaBase, dmaChn, (uint32_t)(state->data));
774  EDMA_HAL_TCDSetMajorCount(edmaBase, dmaChn, state->remainingBytes / byteCount);
775  /* Now that this tx is set up, clear remaining bytes count */
776  state->remainingBytes = 0U;
777  /* Start the channel */
778  (void)EDMA_DRV_StartChannel(dmaChn);
779  }
780 }
781 
782 
783 
784 /*FUNCTION**********************************************************************
785  *
786  * Function Name : FLEXIO_UART_DRV_ComputeTxRegAddr
787  * Description : Computes the address of the register used for DMA tx transfer
788  *
789  *END**************************************************************************/
790 static uint32_t FLEXIO_UART_DRV_ComputeTxRegAddr(const flexio_uart_state_t *state)
791 {
792  uint32_t addr;
793  const FLEXIO_Type *baseAddr;
794  uint8_t shifter;
795 
796  baseAddr = g_flexioBase[state->flexioCommon.instance];
797  shifter = TX_SHIFTER(state->flexioCommon.resourceIndex);
798  addr = (uint32_t)(&(baseAddr->SHIFTBUF[shifter]));
799  return addr;
800 }
801 
802 
803 /*FUNCTION**********************************************************************
804  *
805  * Function Name : FLEXIO_UART_DRV_ComputeRxRegAddr
806  * Description : Computes the address of the register used for DMA rx transfer
807  *
808  *END**************************************************************************/
809 static uint32_t FLEXIO_UART_DRV_ComputeRxRegAddr(const flexio_uart_state_t *state)
810 {
811  uint32_t addr;
812  const FLEXIO_Type *baseAddr;
813  uint8_t shifter;
814  uint32_t byteCount;
815 
816  if (state->bitCount <= 8U)
817  {
818  byteCount = 1U;
819  }
820  else
821  {
822  byteCount = 2U;
823  }
824  baseAddr = g_flexioBase[state->flexioCommon.instance];
825  shifter = RX_SHIFTER(state->flexioCommon.resourceIndex);
826  addr = (uint32_t)(&(baseAddr->SHIFTBUF[shifter])) + (sizeof(uint32_t) - byteCount);
827  return addr;
828 }
829 
830 
831 /*FUNCTION**********************************************************************
832  *
833  * Function Name : FLEXIO_UART_DRV_StartTxDmaTransfer
834  * Description : Starts a Tx DMA transfer
835  *
836  *END**************************************************************************/
837 static void FLEXIO_UART_DRV_StartTxDmaTransfer(flexio_uart_state_t *state)
838 {
839  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
840  DMA_Type *edmaBase = g_edmaBase[0U];
841  FLEXIO_Type *baseAddr;
842  edma_transfer_size_t dmaTransferSize;
843  uint32_t byteCount;
844 
845  baseAddr = g_flexioBase[state->flexioCommon.instance];
846  resourceIndex = state->flexioCommon.resourceIndex;
847 
848  /* Configure the transfer control descriptor for the previously allocated channel */
849  if (state->bitCount <= 8U)
850  {
851  dmaTransferSize = EDMA_TRANSFER_SIZE_1B;
852  byteCount = 1U;
853  }
854  else
855  {
856  dmaTransferSize = EDMA_TRANSFER_SIZE_2B;
857  byteCount = 2U;
858  }
859  (void)EDMA_DRV_ConfigSingleBlockTransfer(state->dmaChannel,
861  (uint32_t)(state->data),
862  FLEXIO_UART_DRV_ComputeTxRegAddr(state),
863  dmaTransferSize,
864  byteCount);
865  EDMA_HAL_TCDSetMajorCount(edmaBase, state->dmaChannel, state->remainingBytes / byteCount);
866  EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBase, state->dmaChannel, true);
867  /* Now that this transfer is set up, clear remaining bytes count */
868  state->remainingBytes = 0U;
869 
870  /* Setup callback for DMA tx transfer end */
871  (void)EDMA_DRV_InstallCallback(state->dmaChannel,
872  (edma_callback_t)(FLEXIO_UART_DRV_EndDmaTxTransfer),
873  (void*)(state));
874  /* Start tx DMA channel */
875  (void)EDMA_DRV_StartChannel(state->dmaChannel);
876 
877  /* Enable FlexIO DMA requests */
878  FLEXIO_HAL_SetShifterDMARequest(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), true);
879 }
880 
881 
882 /*FUNCTION**********************************************************************
883  *
884  * Function Name : FLEXIO_UART_DRV_StartRxDmaTransfer
885  * Description : Starts an Rx DMA transfer
886  *
887  *END**************************************************************************/
888 static void FLEXIO_UART_DRV_StartRxDmaTransfer(flexio_uart_state_t *state)
889 {
890  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
891  DMA_Type *edmaBase = g_edmaBase[0U];
892  FLEXIO_Type *baseAddr;
893  edma_transfer_size_t dmaTransferSize;
894  uint32_t byteCount;
895 
896  baseAddr = g_flexioBase[state->flexioCommon.instance];
897  resourceIndex = state->flexioCommon.resourceIndex;
898 
899  /* Configure the transfer control descriptor for the previously allocated channel */
900  if (state->bitCount <= 8U)
901  {
902  dmaTransferSize = EDMA_TRANSFER_SIZE_1B;
903  byteCount = 1U;
904  }
905  else
906  {
907  dmaTransferSize = EDMA_TRANSFER_SIZE_2B;
908  byteCount = 2U;
909  }
910  (void)EDMA_DRV_ConfigSingleBlockTransfer(state->dmaChannel,
912  FLEXIO_UART_DRV_ComputeRxRegAddr(state),
913  (uint32_t)(state->data),
914  dmaTransferSize,
915  byteCount);
916  EDMA_HAL_TCDSetMajorCount(edmaBase, state->dmaChannel, state->remainingBytes / byteCount);
917  EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBase, state->dmaChannel, true);
918  /* Now that this transfer is set up, clear remaining bytes count */
919  state->remainingBytes = 0U;
920 
921  /* Setup callback for DMA tx transfer end */
922  (void)EDMA_DRV_InstallCallback(state->dmaChannel,
923  (edma_callback_t)(FLEXIO_UART_DRV_EndDmaRxTransfer),
924  (void*)(state));
925  /* Start tx DMA channel */
926  (void)EDMA_DRV_StartChannel(state->dmaChannel);
927 
928  /* Enable FlexIO DMA requests */
929  FLEXIO_HAL_SetShifterDMARequest(baseAddr, (uint8_t)(1U << RX_SHIFTER(resourceIndex)), true);
930 }
931 
934 /*******************************************************************************
935  * Code
936  ******************************************************************************/
937 
938 /*FUNCTION**********************************************************************
939  *
940  * Function Name : FLEXIO_UART_DRV_Init
941  * Description : Initialize the FLEXIO_UART driver
942  * Implements : FLEXIO_UART_DRV_Init_Activity
943  *
944  *END**************************************************************************/
945 status_t FLEXIO_UART_DRV_Init(uint32_t instance,
946  const flexio_uart_user_config_t * userConfigPtr,
947  flexio_uart_state_t * state)
948 {
949  uint32_t inputClock;
950  status_t clkErr;
951  status_t retCode;
952  status_t osifError = STATUS_SUCCESS;
953  uint8_t dmaReq;
954 
955  DEV_ASSERT(state != NULL);
956  DEV_ASSERT(instance < FLEXIO_INSTANCE_COUNT);
957  /* Check that device was initialized */
958  DEV_ASSERT(g_flexioDeviceStatePtr[instance] != NULL);
959 
960  /* Get the protocol clock frequency */
961  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[instance], &inputClock);
962  DEV_ASSERT(clkErr == STATUS_SUCCESS);
963  DEV_ASSERT(inputClock > 0U);
964 
965 
966  /* Instruct the resource allocator that we need one shifter/timer */
967  state->flexioCommon.resourceCount = 1U;
968  /* Common FlexIO driver initialization */
969  retCode = FLEXIO_DRV_InitDriver(instance, (flexio_common_state_t *)state);
970  if (retCode != STATUS_SUCCESS)
971  { /* Initialization failed, not enough resources */
972  return retCode;
973  }
974  /* Initialize the semaphore */
975  if (userConfigPtr->driverType != FLEXIO_DRIVER_TYPE_POLLING)
976  {
977  osifError = OSIF_SemaCreate(&(state->idleSemaphore), 0U);
978  DEV_ASSERT(osifError == STATUS_SUCCESS);
979  }
980 
981  /* Initialize driver-specific context structure */
982  state->data = NULL;
983  state->remainingBytes = 0U;
984  state->callback = userConfigPtr->callback;
985  state->callbackParam = userConfigPtr->callbackParam;
986  state->blocking = false;
987  state->driverType = userConfigPtr->driverType;
988  state->direction = userConfigPtr->direction;
989  state->status = STATUS_SUCCESS;
990  state->driverIdle = true;
991  state->bitCount = userConfigPtr->bitCount;
992 
993  if (state->direction == FLEXIO_UART_DIRECTION_TX)
994  {
995  /* Configure device for UART Tx mode */
996  FLEXIO_UART_DRV_ConfigureTx(state, userConfigPtr, inputClock);
997  }
998  else
999  {
1000  /* Configure device for UART Rx mode */
1001  FLEXIO_UART_DRV_ConfigureRx(state, userConfigPtr, inputClock);
1002  }
1003 
1004  /* Set up transfer engine */
1005  switch (state->driverType)
1006  {
1008  if (state->direction == FLEXIO_UART_DIRECTION_TX)
1009  {
1010  state->flexioCommon.isr = FLEXIO_UART_DRV_CheckStatusTx;
1011  }
1012  else
1013  {
1014  state->flexioCommon.isr = FLEXIO_UART_DRV_CheckStatusRx;
1015  }
1016  break;
1018  /* Nothing to do here, FLEXIO_UART_DRV_GetStatus() will handle the transfer */
1019  break;
1021  /* Store DMA channel number */
1022  state->dmaChannel = userConfigPtr->dmaChannel;
1023  /* Configure DMA request source */
1024  dmaReq = g_flexioDMASrc[instance][TX_SHIFTER(state->flexioCommon.resourceIndex)];
1025  DMAMUX_HAL_SetChannelSource(g_dmamuxBase[0U], userConfigPtr->dmaChannel, dmaReq);
1026  /* For Tx we will still need interrupt to signal end of transfer */
1027  if (state->direction == FLEXIO_UART_DIRECTION_TX)
1028  {
1029  state->flexioCommon.isr = FLEXIO_UART_DRV_CheckStatusTx;
1030  }
1031  break;
1032  default:
1033  /* Impossible type - do nothing */
1034  break;
1035  }
1036 
1037  (void)clkErr;
1038  (void)osifError;
1039  return STATUS_SUCCESS;
1040 }
1041 
1042 
1043 /*FUNCTION**********************************************************************
1044  *
1045  * Function Name : FLEXIO_UART_DRV_Deinit
1046  * Description : De-initialize the FLEXIO_UART driver
1047  * Implements : FLEXIO_UART_DRV_Deinit_Activity
1048  *
1049  *END**************************************************************************/
1051 {
1052  DEV_ASSERT(state != NULL);
1053 
1054  /* Check if driver is busy */
1055  DEV_ASSERT(state->driverIdle);
1056 
1057  /* Destroy the semaphore */
1058  if (state->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1059  {
1060  (void)OSIF_SemaDestroy(&(state->idleSemaphore));
1061  }
1062 
1063  return FLEXIO_DRV_DeinitDriver((flexio_common_state_t *)state);
1064 }
1065 
1066 
1067 /*FUNCTION**********************************************************************
1068  *
1069  * Function Name : FLEXIO_UART_DRV_SetConfig
1070  * Description : Set the baud rate and bit width for any subsequent UART transfer
1071  * Implements : FLEXIO_UART_DRV_SetConfig_Activity
1072  *
1073  *END**************************************************************************/
1075  uint32_t baudRate,
1076  uint8_t bitCount)
1077 {
1078  FLEXIO_Type *baseAddr;
1079  uint16_t divider;
1080  uint32_t inputClock;
1081  status_t clkErr;
1082  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1083 
1084  DEV_ASSERT(state != NULL);
1085  DEV_ASSERT(baudRate > 0U);
1086  DEV_ASSERT(bitCount > 0U);
1087  DEV_ASSERT(bitCount <= 16U);
1088  /* for DMA transfers bitCount must 8 */
1089  DEV_ASSERT(!((state->driverType == FLEXIO_DRIVER_TYPE_DMA) && (bitCount != 8U)));
1090 
1091  baseAddr = g_flexioBase[state->flexioCommon.instance];
1092  resourceIndex = state->flexioCommon.resourceIndex;
1093 
1094  /* Check if driver is busy */
1095  DEV_ASSERT(state->driverIdle);
1096  /* Get the protocol clock frequency */
1097  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[state->flexioCommon.instance], &inputClock);
1098  DEV_ASSERT(clkErr == STATUS_SUCCESS);
1099  DEV_ASSERT(inputClock > 0U);
1100 
1101  /* Compute divider */
1102  FLEXIO_UART_DRV_ComputeBaudRateDivider(state, baudRate, &divider, inputClock);
1103 
1104  if (state->direction == FLEXIO_UART_DIRECTION_TX)
1105  {
1106  /* Configure tx timer */
1107  FLEXIO_HAL_SetTimerCompare(baseAddr, TX_TIMER(resourceIndex), (uint16_t)(((((uint16_t)bitCount << 1U) - 1U) << 8U) + divider));
1108  }
1109  else
1110  {
1111  /* Configure rx timer */
1112  FLEXIO_HAL_SetTimerCompare(baseAddr, RX_TIMER(resourceIndex), (uint16_t)(((((uint16_t)bitCount << 1U) - 1U) << 8U) + divider));
1113  }
1114 
1115  state->bitCount = bitCount;
1116 
1117  (void)clkErr;
1118  return STATUS_SUCCESS;
1119 }
1120 
1121 
1122 /*FUNCTION**********************************************************************
1123  *
1124  * Function Name : FLEXIO_UART_DRV_GetBaudRate
1125  * Description : Get the currently configured baud rate
1126  * Implements : FLEXIO_UART_DRV_GetBaudRate_Activity
1127  *
1128  *END**************************************************************************/
1130 {
1131  const FLEXIO_Type *baseAddr;
1132  uint32_t inputClock;
1133  uint16_t divider;
1134  uint16_t timerCmp;
1135  status_t clkErr;
1136  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1137 
1138  DEV_ASSERT(state != NULL);
1139 
1140  baseAddr = g_flexioBase[state->flexioCommon.instance];
1141  resourceIndex = state->flexioCommon.resourceIndex;
1142 
1143  /* Get the protocol clock frequency */
1144  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[state->flexioCommon.instance], &inputClock);
1145  DEV_ASSERT(clkErr == STATUS_SUCCESS);
1146  DEV_ASSERT(inputClock > 0U);
1147 
1148  /* Get the currently configured divider */
1149  timerCmp = FLEXIO_HAL_GetTimerCompare(baseAddr, TX_TIMER(resourceIndex));
1150  divider = (uint16_t)(timerCmp & 0x00FFU);
1151 
1152  /* Compute baud rate: input_clock / (2 * (divider + 1)). Round to nearest integer */
1153  *baudRate = (inputClock + (uint32_t)divider + 1U) / (2U * ((uint32_t)divider + 1U));
1154 
1155  (void)clkErr;
1156  return STATUS_SUCCESS;
1157 }
1158 
1159 
1160 
1161 /*FUNCTION**********************************************************************
1162  *
1163  * Function Name : FLEXIO_UART_DRV_SendData
1164  * Description : Perform a non-blocking UART transmission
1165  * Implements : FLEXIO_UART_DRV_SendData_Activity
1166  *
1167  *END**************************************************************************/
1169  const uint8_t * txBuff,
1170  uint32_t txSize)
1171 {
1172  FLEXIO_Type *baseAddr;
1173  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1174 
1175  DEV_ASSERT(state != NULL);
1176  DEV_ASSERT(txBuff != NULL);
1177  DEV_ASSERT(txSize > 0U);
1178  DEV_ASSERT(state->direction == FLEXIO_UART_DIRECTION_TX);
1179 
1180  baseAddr = g_flexioBase[state->flexioCommon.instance];
1181  resourceIndex = state->flexioCommon.resourceIndex;
1182 
1183  /* Check if driver is busy */
1184  DEV_ASSERT(state->driverIdle);
1185 
1186  state->data = (uint8_t *)txBuff;
1187  state->remainingBytes = txSize;
1188  state->status = STATUS_BUSY;
1189  state->driverIdle = false;
1190  /* number of bytes to flush after the last byte is copied in the tx shifter buffer */
1191  state->txFlush = (uint8_t)((txSize == 1U) ? 1U : 2U);
1192 
1193  /* Enable timers and shifters */
1194  FLEXIO_UART_DRV_EnableTransfer(state);
1195  /* Enable transfer engine */
1196  switch (state->driverType)
1197  {
1199  /* Enable interrupts for Tx shifter */
1200  FLEXIO_HAL_SetShifterInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), true);
1201  FLEXIO_HAL_SetShifterErrorInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), true);
1202  break;
1204  /* Call FLEXIO_UART_DRV_CheckStatus once to send the first byte */
1205  FLEXIO_UART_DRV_CheckStatus(state);
1206  break;
1208  FLEXIO_UART_DRV_StartTxDmaTransfer(state);
1209  break;
1210  default:
1211  /* Impossible type - do nothing */
1212  break;
1213  }
1214 
1215  return STATUS_SUCCESS;
1216 }
1217 
1218 
1219 /*FUNCTION**********************************************************************
1220  *
1221  * Function Name : FLEXIO_UART_DRV_SendDataBlocking
1222  * Description : Perform a blocking UART transmission
1223  * Implements : FLEXIO_UART_DRV_SendDataBlocking_Activity
1224  *
1225  *END**************************************************************************/
1227  const uint8_t * txBuff,
1228  uint32_t txSize,
1229  uint32_t timeout)
1230 {
1231  status_t status;
1232 
1233  /* mark transfer as blocking */
1234  if (state->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1235  {
1236  state->blocking = true;
1237  }
1238  /* Call FLEXIO_UART_DRV_SendData to start transfer */
1239  status = FLEXIO_UART_DRV_SendData(state, txBuff, txSize);
1240  if (status != STATUS_SUCCESS)
1241  {
1242  /* Transfer could not be started */
1243  state->blocking = false;
1244  return status;
1245  }
1246 
1247  /* Wait for transfer to end */
1248  return FLEXIO_UART_DRV_WaitTransferEnd(state, timeout);
1249 }
1250 
1251 
1252 /*FUNCTION**********************************************************************
1253  *
1254  * Function Name : FLEXIO_UART_DRV_ReceiveData
1255  * Description : Perform a non-blocking UART reception
1256  * Implements : FLEXIO_UART_DRV_ReceiveData_Activity
1257  *
1258  *END**************************************************************************/
1260  uint8_t * rxBuff,
1261  uint32_t rxSize)
1262 {
1263  FLEXIO_Type *baseAddr;
1264  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1265 
1266  DEV_ASSERT(state != NULL);
1267  DEV_ASSERT(rxBuff != NULL);
1268  DEV_ASSERT(rxSize > 0U);
1269  DEV_ASSERT(state->direction == FLEXIO_UART_DIRECTION_RX);
1270 
1271  baseAddr = g_flexioBase[state->flexioCommon.instance];
1272  resourceIndex = state->flexioCommon.resourceIndex;
1273 
1274  /* Check if driver is busy */
1275  DEV_ASSERT(state->driverIdle);
1276 
1277  state->data = rxBuff;
1278  state->remainingBytes = rxSize;
1279  state->status = STATUS_BUSY;
1280  state->driverIdle = false;
1281 
1282  /* Enable timers and shifters */
1283  FLEXIO_UART_DRV_EnableTransfer(state);
1284  /* Enable transfer engine */
1285  switch (state->driverType)
1286  {
1288  /* Enable interrupts for Rx shifter */
1289  FLEXIO_HAL_SetShifterInterrupt(baseAddr, (uint8_t)(1U << RX_SHIFTER(resourceIndex)), true);
1290  FLEXIO_HAL_SetShifterErrorInterrupt(baseAddr, (uint8_t)(1U << RX_SHIFTER(resourceIndex)), true);
1291  break;
1293  /* Call FLEXIO_UART_DRV_CheckStatus once to send the first byte */
1294  FLEXIO_UART_DRV_CheckStatus(state);
1295  break;
1297  FLEXIO_UART_DRV_StartRxDmaTransfer(state);
1298  break;
1299  default:
1300  /* Impossible type - do nothing */
1301  break;
1302  }
1303 
1304  return STATUS_SUCCESS;
1305 }
1306 
1307 
1308 /*FUNCTION**********************************************************************
1309  *
1310  * Function Name : FLEXIO_UART_DRV_ReceiveDataBlocking
1311  * Description : Perform a blocking UART reception
1312  * Implements : FLEXIO_UART_DRV_ReceiveDataBlocking_Activity
1313  *
1314  *END**************************************************************************/
1316  uint8_t * rxBuff,
1317  uint32_t rxSize,
1318  uint32_t timeout)
1319 {
1320  status_t status;
1321 
1322  /* mark transfer as blocking */
1323  if (state->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1324  {
1325  state->blocking = true;
1326  }
1327  /* Call FLEXIO_UART_DRV_ReceiveData to start transfer */
1328  status = FLEXIO_UART_DRV_ReceiveData(state, rxBuff, rxSize);
1329  if (status != STATUS_SUCCESS)
1330  {
1331  /* Transfer could not be started */
1332  state->blocking = false;
1333  return status;
1334  }
1335 
1336  /* Wait for transfer to end */
1337  return FLEXIO_UART_DRV_WaitTransferEnd(state, timeout);
1338 }
1339 
1340 
1341 /*FUNCTION**********************************************************************
1342  *
1343  * Function Name : FLEXIO_UART_DRV_TransferAbort
1344  * Description : Aborts a non-blocking UART transfer
1345  * Implements : FLEXIO_UART_DRV_TransferAbort_Activity
1346  *
1347  *END**************************************************************************/
1349 {
1350  DEV_ASSERT(state != NULL);
1351 
1352  state->status = STATUS_UART_ABORTED;
1353  FLEXIO_UART_DRV_StopTransfer(state);
1354 
1355  return STATUS_SUCCESS;
1356 }
1357 
1358 
1359 /*FUNCTION**********************************************************************
1360  *
1361  * Function Name : FLEXIO_UART_DRV_GetStatus
1362  * Description : Get the status of the current non-blocking UART transaction
1363  * Implements : FLEXIO_UART_DRV_GetStatus_Activity
1364  *
1365  *END**************************************************************************/
1366 status_t FLEXIO_UART_DRV_GetStatus(flexio_uart_state_t *state, uint32_t *bytesRemaining)
1367 {
1368  DEV_ASSERT(state != NULL);
1369 
1370  if ((!state->driverIdle) && (state->driverType == FLEXIO_DRIVER_TYPE_POLLING))
1371  {
1372  /* In polling mode advance the UART transfer here */
1373  FLEXIO_UART_DRV_CheckStatus(state);
1374  }
1375 
1376  if (bytesRemaining != NULL)
1377  {
1378  *bytesRemaining = state->remainingBytes;
1379  }
1380 
1381  if (!state->driverIdle)
1382  {
1383  return STATUS_BUSY;
1384  }
1385  else
1386  {
1387  return state->status;
1388  }
1389 }
1390 
1391 
1392 /*FUNCTION**********************************************************************
1393  *
1394  * Function Name : FLEXIO_UART_DRV_SetRxBuffer
1395  * Description : Provide a buffer for receiving data.
1396  * Implements : FLEXIO_UART_DRV_SetRxBuffer_Activity
1397  *
1398  *END**************************************************************************/
1400  uint8_t * rxBuff,
1401  uint32_t rxSize)
1402 {
1403  DEV_ASSERT(state != NULL);
1404  DEV_ASSERT(rxBuff != NULL);
1405  DEV_ASSERT(rxSize > 0U);
1406 
1407  state->data = rxBuff;
1408  state->remainingBytes = rxSize;
1409 
1410  return STATUS_SUCCESS;
1411 }
1412 
1413 
1414 /*FUNCTION**********************************************************************
1415  *
1416  * Function Name : FLEXIO_UART_DRV_SetTxBuffer
1417  * Description : Provide a buffer for transmitting data.
1418  * Implements : FLEXIO_UART_DRV_SetTxBuffer_Activity
1419  *
1420  *END**************************************************************************/
1422  const uint8_t * txBuff,
1423  uint32_t txSize)
1424 {
1425  DEV_ASSERT(state != NULL);
1426  DEV_ASSERT(txBuff != NULL);
1427  DEV_ASSERT(txSize > 0U);
1428 
1429  state->data = (uint8_t *)txBuff;
1430  state->remainingBytes = txSize;
1431  /* in case of continuous transmission there are always 2 bytes to flush */
1432  state->txFlush = 2;
1433 
1434  return STATUS_SUCCESS;
1435 }
1436 
1437 
1438 /*******************************************************************************
1439  * EOF
1440  ******************************************************************************/
static void EDMA_HAL_TCDSetSrcAddr(DMA_Type *base, uint32_t channel, uint32_t address)
Configures the source address for the hardware TCD.
Definition: edma_hal.h:794
__IO uint32_t SHIFTBUF[FLEXIO_SHIFTBUF_COUNT]
Definition: S32K144.h:3491
static void FLEXIO_HAL_SetShifterInterrupt(FLEXIO_Type *baseAddr, uint8_t interruptMask, bool enable)
Enables or disables the shifter interrupts.
Definition: flexio_hal.h:823
static void FLEXIO_HAL_SetShifterMode(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_mode_t mode)
Sets the mode of the specified shifter.
Definition: flexio_hal.h:1198
static uint16_t FLEXIO_HAL_GetTimerCompare(const FLEXIO_Type *baseAddr, uint8_t timer)
Returns the compare value of the specified timer.
Definition: flexio_hal.h:2091
DMAMUX_Type *const g_dmamuxBase[DMAMUX_INSTANCE_COUNT]
Array for DMAMUX module register base address.
Definition: edma_common.c:50
static void FLEXIO_HAL_SetTimerControl(FLEXIO_Type *baseAddr, uint8_t timer, uint8_t trigger, flexio_trigger_polarity_t triggerPolarity, flexio_trigger_source_t triggerSource, uint8_t pin, flexio_pin_polarity_t pinPolarity, flexio_pin_config_t pinConfig, flexio_timer_mode_t mode)
Sets all control settings for specified timer.
Definition: flexio_hal.h:1689
status_t OSIF_SemaDestroy(const semaphore_t *const pSem)
Destroys a previously created semaphore.
static bool FLEXIO_HAL_GetTimerStatus(const FLEXIO_Type *baseAddr, uint8_t timer)
Returns the current status of the specified timer.
Definition: flexio_hal.h:724
static void FLEXIO_HAL_SetTimerMode(FLEXIO_Type *baseAddr, uint8_t timer, flexio_timer_mode_t mode)
Sets the mode of the specified timer.
Definition: flexio_hal.h:1658
status_t FLEXIO_UART_DRV_ReceiveData(flexio_uart_state_t *state, uint8_t *rxBuff, uint32_t rxSize)
Perform a non-blocking UART reception.
FLEXIO_Type *const g_flexioBase[FLEXIO_INSTANCE_COUNT]
Definition: flexio_common.c:56
status_t FLEXIO_UART_DRV_SetTxBuffer(flexio_uart_state_t *state, const uint8_t *txBuff, uint32_t txSize)
Provide a buffer for transmitting data.
status_t EDMA_DRV_StopChannel(uint8_t channel)
Stops the eDMA channel.
Definition: edma_driver.c:790
#define FLEXIO_INSTANCE_COUNT
Definition: S32K144.h:3507
void EDMA_HAL_TCDSetMajorCount(DMA_Type *base, uint32_t channel, uint32_t count)
Sets the major iteration count according to minor loop channel link setting.
Definition: edma_hal.c:388
static void FLEXIO_HAL_WriteShifterBuffer(FLEXIO_Type *baseAddr, uint8_t shifter, uint32_t value, flexio_shifter_buffer_mode_t mode)
Writes a value in the specified shifter buffer.
Definition: flexio_hal.h:1465
static void FLEXIO_HAL_SetShifterStartBit(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_start_t start)
Configures the start bit of the specified shifter.
Definition: flexio_hal.h:1369
static void FLEXIO_HAL_ClearTimerStatus(FLEXIO_Type *baseAddr, uint8_t timer)
Clears the status of the specified timer.
Definition: flexio_hal.h:767
status_t FLEXIO_UART_DRV_SetConfig(flexio_uart_state_t *state, uint32_t baudRate, uint8_t bitCount)
Set the baud rate and bit width for any subsequent UART communication.
status_t OSIF_SemaCreate(semaphore_t *const pSem, const uint8_t initValue)
Creates a semaphore with a given value.
static void FLEXIO_HAL_SetTimerInterrupt(FLEXIO_Type *baseAddr, uint8_t interruptMask, bool enable)
Enables or disables the timer interrupts.
Definition: flexio_hal.h:959
static void FLEXIO_HAL_SetShifterConfig(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_start_t start, flexio_shifter_stop_t stop, flexio_shifter_source_t source)
Sets all configuration settings for specified shifter.
Definition: flexio_hal.h:1396
status_t FLEXIO_DRV_DeinitDriver(const flexio_common_state_t *driver)
static uint32_t FLEXIO_HAL_ReadShifterBuffer(const FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_buffer_mode_t mode)
Reads the value from the specified shifter buffer.
Definition: flexio_hal.h:1421
status_t FLEXIO_UART_DRV_SendData(flexio_uart_state_t *state, const uint8_t *txBuff, uint32_t txSize)
Perform a non-blocking UART transmission.
#define DEV_ASSERT(x)
Definition: devassert.h:78
status_t FLEXIO_UART_DRV_SendDataBlocking(flexio_uart_state_t *state, const uint8_t *txBuff, uint32_t txSize, uint32_t timeout)
Perform a blocking UART transmission.
edma_chn_status_t
Channel status for eDMA channel.
Definition: edma_driver.h:125
static void EDMA_HAL_TCDSetDestAddr(DMA_Type *base, uint32_t channel, uint32_t address)
Configures the destination address for the TCD.
Definition: edma_hal.h:968
flexio_uart_driver_direction_t direction
status_t FLEXIO_UART_DRV_ReceiveDataBlocking(flexio_uart_state_t *state, uint8_t *rxBuff, uint32_t rxSize, uint32_t timeout)
Perform a blocking UART reception.
status_t FLEXIO_UART_DRV_GetBaudRate(flexio_uart_state_t *state, uint32_t *baudRate)
Get the currently configured baud rate.
static void FLEXIO_HAL_SetShifterControl(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_mode_t mode, uint8_t pin, flexio_pin_polarity_t pinPolarity, flexio_pin_config_t pinConfig, uint8_t timer, flexio_timer_polarity_t timerPolarity)
Sets all control settings for the specified shifter.
Definition: flexio_hal.h:1228
status_t CLOCK_SYS_GetFreq(clock_names_t clockName, uint32_t *frequency)
Gets the clock frequency for a specific clock name.
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
status_t FLEXIO_UART_DRV_GetStatus(flexio_uart_state_t *state, uint32_t *bytesRemaining)
Get the status of the current non-blocking UART transfer.
status_t FLEXIO_UART_DRV_SetRxBuffer(flexio_uart_state_t *state, uint8_t *rxBuff, uint32_t rxSize)
Provide a buffer for receiving data.
const uint8_t g_flexioDMASrc[FLEXIO_INSTANCE_COUNT][FEATURE_FLEXIO_MAX_SHIFTER_COUNT]
Definition: flexio_common.c:68
Driver internal context structure.
status_t FLEXIO_UART_DRV_Deinit(flexio_uart_state_t *state)
De-initialize the FLEXIO_UART driver.
static void FLEXIO_HAL_SetTimerCompare(FLEXIO_Type *baseAddr, uint8_t timer, uint16_t value)
Configures the compare value for the specified timer.
Definition: flexio_hal.h:2118
edma_transfer_size_t
eDMA transfer configuration Implements : edma_transfer_size_t_Class
Definition: edma_hal.h:132
status_t FLEXIO_UART_DRV_TransferAbort(flexio_uart_state_t *state)
Aborts a non-blocking UART transfer.
status_t FLEXIO_DRV_InitDriver(uint32_t instance, flexio_common_state_t *driver)
static void FLEXIO_HAL_SetTimerConfig(FLEXIO_Type *baseAddr, uint8_t timer, flexio_timer_start_t start, flexio_timer_stop_t stop, flexio_timer_enable_t enable, flexio_timer_disable_t disable, flexio_timer_reset_t reset, flexio_timer_decrement_t decrement, flexio_timer_output_t output)
Sets all configuration settings for specified timer.
Definition: flexio_hal.h:2060
static void EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(DMA_Type *base, uint32_t channel, bool disable)
Disables/Enables the DMA request after the major loop completes for the TCD.
Definition: edma_hal.h:1117
status_t OSIF_SemaWait(semaphore_t *const pSem, const uint32_t timeout)
Decrement a semaphore with timeout.
status_t EDMA_DRV_StartChannel(uint8_t channel)
Starts an eDMA channel.
Definition: edma_driver.c:765
status_t OSIF_SemaPost(semaphore_t *const pSem)
Increment a semaphore.
flexio_device_state_t * g_flexioDeviceStatePtr[FLEXIO_INSTANCE_COUNT]
Definition: flexio_common.c:59
DMA_Type *const g_edmaBase[DMA_INSTANCE_COUNT]
Array for the eDMA module register base address.
Definition: edma_common.c:47
static bool FLEXIO_HAL_GetShifterStatus(const FLEXIO_Type *baseAddr, uint8_t shifter)
Returns the current status of the specified shifter.
Definition: flexio_hal.h:593
static void FLEXIO_HAL_ClearShifterErrorStatus(FLEXIO_Type *baseAddr, uint8_t shifter)
Clears the error status of the specified shifter.
Definition: flexio_hal.h:699
static void DMAMUX_HAL_SetChannelSource(DMAMUX_Type *base, uint32_t channel, uint8_t source)
Configures the DMA request for the DMAMUX channel.
Definition: dmamux_hal.h:108
static void FLEXIO_HAL_SetShifterErrorInterrupt(FLEXIO_Type *baseAddr, uint8_t interruptMask, bool enable)
Enables or disables the shifter error interrupts.
Definition: flexio_hal.h:891
void(* edma_callback_t)(void *parameter, edma_chn_status_t status)
Definition for the eDMA channel callback function.
Definition: edma_driver.h:137
static bool FLEXIO_HAL_GetShifterErrorStatus(const FLEXIO_Type *baseAddr, uint8_t shifter)
Returns the current error status of the specified shifter.
Definition: flexio_hal.h:658
const clock_names_t g_flexioClock[FLEXIO_INSTANCE_COUNT]
Definition: flexio_common.c:65
status_t EDMA_DRV_ConfigSingleBlockTransfer(uint8_t channel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t dataBufferSize)
Configures a simple single block data transfer with DMA.
Definition: edma_driver.c:487
flexio_driver_type_t driverType
Driver configuration structure.
status_t FLEXIO_UART_DRV_Init(uint32_t instance, const flexio_uart_user_config_t *userConfigPtr, flexio_uart_state_t *state)
Initialize the FLEXIO_UART driver.
status_t EDMA_DRV_InstallCallback(uint8_t channel, edma_callback_t callback, void *parameter)
Registers the callback function and the parameter for eDMA channel.
Definition: edma_driver.c:285
static void FLEXIO_HAL_ClearShifterStatus(FLEXIO_Type *baseAddr, uint8_t shifter)
Clears the status of the specified shifter.
Definition: flexio_hal.h:635
static void FLEXIO_HAL_SetShifterDMARequest(FLEXIO_Type *baseAddr, uint8_t requestMask, bool enable)
Enables or disables the shifter DMA requests.
Definition: flexio_hal.h:1010