S32 SDK
flexio_spi_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_spi_driver.h"
20 #include "flexio_hal.h"
21 #include "flexio_common.h"
22 #include "clock_manager.h"
23 
77 /*******************************************************************************
78  * Variables
79  ******************************************************************************/
80 
83  /* Constraints used for baud rate computation */
84 #define DIVIDER_MIN_VALUE 1U
85 #define DIVIDER_MAX_VALUE 0xFFU
86 
87  /* Shifters/Timers used for SPI simulation. The parameter x represents the
88  resourceIndex value for the current driver instance */
89 #define TX_SHIFTER(x) (x)
90 #define RX_SHIFTER(x) (uint8_t)((x) + 1U)
91 #define SCK_TIMER(x) (x)
92 #define SS_TIMER(x) (uint8_t)((x) + 1U)
93 
94  /* Dummy data to send when user provides no data */
95 #define FLEXIO_SPI_DUMMYDATA (0xFFFFFFFFU)
96 
97 /*******************************************************************************
98  * Private Functions
99  ******************************************************************************/
100 
101 /*FUNCTION**********************************************************************
102  *
103  * Function Name : FLEXIO_SPI_DRV_MasterComputeBaudRateDivider
104  * Description : Computes the baud rate divider for a target baud rate
105  *
106  *END**************************************************************************/
107 static void FLEXIO_SPI_DRV_MasterComputeBaudRateDivider(uint32_t baudRate,
108  uint16_t *divider,
109  uint32_t inputClock)
110 {
111  uint32_t tmpDiv;
112 
113  /* Compute divider: ((input_clock / baud_rate) / 2) - 1. Round to nearest integer */
114  tmpDiv = ((inputClock + baudRate) / (2U * baudRate)) - 1U;
115  /* Enforce upper/lower limits */
116  if (tmpDiv < DIVIDER_MIN_VALUE)
117  {
118  tmpDiv = DIVIDER_MIN_VALUE;
119  }
120  if (tmpDiv > DIVIDER_MAX_VALUE)
121  {
122  tmpDiv = DIVIDER_MAX_VALUE;
123  }
124 
125  *divider = (uint16_t)tmpDiv;
126 }
127 
128 
129 /*FUNCTION**********************************************************************
130  *
131  * Function Name : FLEXIO_SPI_DRV_MasterConfigure
132  * Description : configures the FLEXIO module as SPI master
133  *
134  *END**************************************************************************/
135 static void FLEXIO_SPI_DRV_MasterConfigure(const flexio_spi_master_state_t *master,
136  const flexio_spi_master_user_config_t * userConfigPtr,
137  uint32_t inputClock)
138 {
139  FLEXIO_Type *baseAddr;
140  flexio_pin_polarity_t clockPolarity; /* Polarity of clock signal */
141  flexio_timer_polarity_t txShifterPolarity; /* Polarity of MOSI shifter */
142  flexio_timer_polarity_t rxShifterPolarity; /* Polarity of MISO shifter */
143  uint16_t divider;
144  flexio_shifter_stop_t stopBit;
145  flexio_shifter_start_t startBit;
146  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
147 
148  baseAddr = g_flexioBase[master->flexioCommon.instance];
149  resourceIndex = master->flexioCommon.resourceIndex;
150  /* Compute divider.*/
151  FLEXIO_SPI_DRV_MasterComputeBaudRateDivider(userConfigPtr->baudRate, &divider, inputClock);
152  /* add number of bits in the upper 8 bits of the divider. Formula is: TIMCMP[15:8] = (number of bits x 2) - 1 */
153  divider += (uint16_t)((((uint16_t)(userConfigPtr->transferSize) * 8U * 2U) - 1U) << 8U);
154 
155  if (userConfigPtr->clockPolarity == 0U)
156  {
157  /* CPOL = 0 */
158  clockPolarity = FLEXIO_PIN_POLARITY_HIGH;
159  }
160  else
161  {
162  /* CPOL = 1 */
163  clockPolarity = FLEXIO_PIN_POLARITY_LOW;
164  }
165 
166  if (userConfigPtr->clockPhase == 0U)
167  {
168  /* CPHA = 0 */
169  txShifterPolarity = FLEXIO_TIMER_POLARITY_NEGEDGE;
170  rxShifterPolarity = FLEXIO_TIMER_POLARITY_POSEDGE;
173  }
174  else
175  {
176  /* CPHA = 1 */
177  txShifterPolarity = FLEXIO_TIMER_POLARITY_POSEDGE;
178  rxShifterPolarity = FLEXIO_TIMER_POLARITY_NEGEDGE;
179  stopBit = FLEXIO_SHIFTER_STOP_BIT_0;
181  }
182 
183  /* Configure Tx shifter (MOSI) */
185  TX_SHIFTER(resourceIndex),
187  userConfigPtr->mosiPin,
190  SCK_TIMER(resourceIndex),
191  txShifterPolarity);
193  TX_SHIFTER(resourceIndex),
194  startBit,
195  stopBit,
197 
198  /* Configure Rx shifter (MISO) */
200  RX_SHIFTER(resourceIndex),
202  userConfigPtr->misoPin,
205  SCK_TIMER(resourceIndex),
206  rxShifterPolarity);
208  RX_SHIFTER(resourceIndex),
212 
213  /* Configure sck timer */
214  FLEXIO_HAL_SetTimerCompare(baseAddr, SCK_TIMER(resourceIndex), divider); /* set baud rate, and number of bits */
215  FLEXIO_HAL_SetTimerConfig(baseAddr,
216  SCK_TIMER(resourceIndex),
225  SCK_TIMER(resourceIndex),
226  (uint8_t)((TX_SHIFTER(resourceIndex) << 2U) + 1U), /* trigger on tx shifter status flag */
229  userConfigPtr->sckPin, /* output on clock pin */
230  clockPolarity, /* used configured polarity */
233 
234  /* Configure SS timer */
235  FLEXIO_HAL_SetTimerCompare(baseAddr, SS_TIMER(resourceIndex), 0xFFFFU);
236  FLEXIO_HAL_SetTimerConfig(baseAddr,
237  SS_TIMER(resourceIndex),
240  FLEXIO_TIMER_ENABLE_TIM_ENABLE, /* enable when SCK timer is enabled */
241  FLEXIO_TIMER_DISABLE_TIM_DISABLE, /* disable when SCK timer is disabled */
246  SS_TIMER(resourceIndex),
247  0U, /* trigger not used, using defaults */
250  userConfigPtr->ssPin,
254 }
255 
256 
257 /*FUNCTION**********************************************************************
258  *
259  * Function Name : FLEXIO_SPI_DRV_MasterEndTransfer
260  * Description : end a transfer
261  *
262  *END**************************************************************************/
263 static void FLEXIO_SPI_DRV_MasterEndTransfer(flexio_spi_master_state_t *master)
264 {
265  FLEXIO_Type *baseAddr;
266  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
267 
268  DEV_ASSERT(master != NULL);
269 
270  baseAddr = g_flexioBase[master->flexioCommon.instance];
271  resourceIndex = master->flexioCommon.resourceIndex;
272 
273  /* Disable transfer engine */
274  switch (master->driverType)
275  {
277  /* Disable interrupts for Rx and Tx shifters */
279  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
280  false);
282  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
283  false);
284  break;
286  /* Nothing to do here */
287  break;
289  /* Stop DMA channels */
290  (void)EDMA_DRV_StopChannel(master->txDMAChannel);
291  (void)EDMA_DRV_StopChannel(master->rxDMAChannel);
292  /* Disable FlexIO DMA requests for both shifters */
294  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
295  false);
296  break;
297  default:
298  /* Impossible type - do nothing */
299  break;
300  }
301 
302  master->driverIdle = true;
303  master->txRemainingBytes = 0U;
304  master->rxRemainingBytes = 0U;
305 
306  /* Signal transfer end for blocking transfers */
307  if (master->blocking == true)
308  {
309  (void)OSIF_SemaPost(&(master->idleSemaphore));
310  }
311 }
312 
313 
314 /*FUNCTION**********************************************************************
315  *
316  * Function Name : FLEXIO_SPI_DRV_MasterEnableTransfer
317  * Description : Enables timers and shifters to start a transfer
318  *
319  *END**************************************************************************/
320 static void FLEXIO_SPI_DRV_MasterEnableTransfer(flexio_spi_master_state_t *master)
321 {
322  FLEXIO_Type *baseAddr;
323  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
324 
325  resourceIndex = master->flexioCommon.resourceIndex;
326  baseAddr = g_flexioBase[master->flexioCommon.instance];
327 
328  /* enable timers and shifters */
329  FLEXIO_HAL_SetShifterMode(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_TRANSMIT);
330  FLEXIO_HAL_SetShifterMode(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_RECEIVE);
331  if (master->master)
332  {
333  FLEXIO_HAL_SetTimerMode(baseAddr, SCK_TIMER(resourceIndex), FLEXIO_TIMER_MODE_8BIT_BAUD);
334  FLEXIO_HAL_SetTimerMode(baseAddr, SS_TIMER(resourceIndex), FLEXIO_TIMER_MODE_16BIT);
335  }
336  else
337  {
338  FLEXIO_HAL_SetTimerMode(baseAddr, SCK_TIMER(resourceIndex), FLEXIO_TIMER_MODE_16BIT);
339  }
340 }
341 
342 
343 /*FUNCTION**********************************************************************
344  *
345  * Function Name : FLEXIO_SPI_DRV_MasterStopTransfer
346  * Description : Forcefully stops the current transfer
347  *
348  *END**************************************************************************/
349 static void FLEXIO_SPI_DRV_MasterStopTransfer(flexio_spi_master_state_t *master)
350 {
351  FLEXIO_Type *baseAddr;
352  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
353 
354  resourceIndex = master->flexioCommon.resourceIndex;
355  baseAddr = g_flexioBase[master->flexioCommon.instance];
356 
357  /* disable and re-enable timers and shifters to reset them */
358  FLEXIO_HAL_SetShifterMode(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_DISABLED);
359  FLEXIO_HAL_SetShifterMode(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_DISABLED);
360  FLEXIO_HAL_SetTimerMode(baseAddr, SCK_TIMER(resourceIndex), FLEXIO_TIMER_MODE_DISABLED);
361  FLEXIO_HAL_SetTimerMode(baseAddr, SS_TIMER(resourceIndex), FLEXIO_TIMER_MODE_DISABLED);
362 
363  /* clear any leftover error flags */
364  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, TX_SHIFTER(resourceIndex));
365  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex));
366  /* discard any leftover rx. data */
367  FLEXIO_HAL_ClearShifterStatus(baseAddr, RX_SHIFTER(resourceIndex));
368 
369  /* end the transfer */
370  FLEXIO_SPI_DRV_MasterEndTransfer(master);
371 }
372 
373 
374 /*FUNCTION**********************************************************************
375  *
376  * Function Name : FLEXIO_SPI_DRV_MasterWaitTransferEnd
377  * Description : waits for the end of a blocking transfer
378  *
379  *END**************************************************************************/
380 static status_t FLEXIO_SPI_DRV_MasterWaitTransferEnd(flexio_spi_master_state_t *master, uint32_t timeout)
381 {
382  status_t osifError = STATUS_SUCCESS;
383 
384  DEV_ASSERT(master != NULL);
385 
386  switch (master->driverType)
387  {
389  /* Wait for transfer to be completed by the IRQ */
390  osifError = OSIF_SemaWait(&(master->idleSemaphore), timeout);
391  break;
393  /* Call FLEXIO_SPI_DRV_MasterGetStatus() to do the transfer */
394  while (FLEXIO_SPI_DRV_MasterGetStatus(master, NULL) == STATUS_BUSY)
395  {
396  }
397  break;
399  osifError = OSIF_SemaWait(&(master->idleSemaphore), timeout);
400  break;
401  default:
402  /* Impossible type - do nothing */
403  break;
404  }
405 
406  /* blocking transfer is over */
407  master->blocking = false;
408  if (osifError == STATUS_TIMEOUT)
409  {
410  /* abort current transfer */
411  master->status = STATUS_TIMEOUT;
412  FLEXIO_SPI_DRV_MasterStopTransfer(master);
413  }
414 
415  return master->status;
416 }
417 
418 
419 /*FUNCTION**********************************************************************
420  *
421  * Function Name : FLEXIO_SPI_DRV_MasterEndDmaTransfer
422  * Description : end a DMA transfer
423  *
424  *END**************************************************************************/
425 static void FLEXIO_SPI_DRV_MasterEndDmaTransfer(void *stateStruct, edma_chn_status_t status)
426 {
428 
429  DEV_ASSERT(stateStruct != NULL);
430 
431  master = (flexio_spi_master_state_t *)stateStruct;
432 
433  /* Record success if there was no error */
434  if (status == EDMA_CHN_ERROR)
435  {
436  master->status = STATUS_ERROR;
437  }
438  else
439  {
440  master->status = STATUS_SUCCESS;
441  }
442  FLEXIO_SPI_DRV_MasterStopTransfer(master);
443  /* Call callback to announce the event to the user */
444  if (master->callback != NULL)
445  {
446  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
447  }
448 }
449 
450 
451 /*FUNCTION**********************************************************************
452  *
453  * Function Name : FLEXIO_SPI_DRV_SlaveConfigure
454  * Description : configures the FLEXIO module as SPI slave
455  *
456  *END**************************************************************************/
457 static void FLEXIO_SPI_DRV_SlaveConfigure(const flexio_spi_slave_state_t *slave,
458  const flexio_spi_slave_user_config_t * userConfigPtr)
459 {
460  FLEXIO_Type *baseAddr;
461  flexio_pin_polarity_t clockPolarity; /* Polarity of clock signal */
462  flexio_timer_polarity_t txShifterPolarity; /* Polarity of MISO shifter */
463  flexio_timer_polarity_t rxShifterPolarity; /* Polarity of MOSI shifter */
464  flexio_shifter_start_t startBit;
465  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
466 
467  baseAddr = g_flexioBase[slave->flexioCommon.instance];
468  resourceIndex = slave->flexioCommon.resourceIndex;
469 
470  if (userConfigPtr->clockPolarity == 0U)
471  {
472  /* CPOL = 0 */
473  clockPolarity = FLEXIO_PIN_POLARITY_HIGH;
474  }
475  else
476  {
477  /* CPOL = 1 */
478  clockPolarity = FLEXIO_PIN_POLARITY_LOW;
479  }
480 
481  if (userConfigPtr->clockPhase == 0U)
482  {
483  /* CPHA = 0 */
484  txShifterPolarity = FLEXIO_TIMER_POLARITY_NEGEDGE;
485  rxShifterPolarity = FLEXIO_TIMER_POLARITY_POSEDGE;
487  }
488  else
489  {
490  /* CPHA = 1 */
491  txShifterPolarity = FLEXIO_TIMER_POLARITY_POSEDGE;
492  rxShifterPolarity = FLEXIO_TIMER_POLARITY_NEGEDGE;
494  }
495 
496  /* Configure Slave Tx shifter (MISO) */
498  TX_SHIFTER(resourceIndex),
500  userConfigPtr->misoPin,
503  SCK_TIMER(resourceIndex),
504  txShifterPolarity);
506  TX_SHIFTER(resourceIndex),
507  startBit,
510 
511  /* Configure Slave Rx shifter (MOSI) */
513  RX_SHIFTER(resourceIndex),
515  userConfigPtr->mosiPin,
518  SCK_TIMER(resourceIndex),
519  rxShifterPolarity);
521  RX_SHIFTER(resourceIndex),
525 
526  /* Configure sck timer */
527  FLEXIO_HAL_SetTimerCompare(baseAddr, SCK_TIMER(resourceIndex), 0xFFFFU);
528  FLEXIO_HAL_SetTimerConfig(baseAddr,
529  SCK_TIMER(resourceIndex),
532  FLEXIO_TIMER_ENABLE_TRG_POSEDGE, /* enable on SS pin rising edge */
533  FLEXIO_TIMER_DISABLE_TRG, /* disable on SS pin falling edge */
535  FLEXIO_TIMER_DECREMENT_PIN_SHIFT_PIN, /* decrement on input pin - SCK */
538  SCK_TIMER(resourceIndex),
539  (uint8_t)(userConfigPtr->ssPin << 1U), /* trigger on SS pin edge */
542  userConfigPtr->sckPin, /* use SCK pin as input pin */
543  clockPolarity,
546 }
547 
548 
549 /*FUNCTION**********************************************************************
550  *
551  * Function Name : FLEXIO_SPI_DRV_ReadData
552  * Description : reads data received by the module
553  *
554  *END**************************************************************************/
555 static void FLEXIO_SPI_DRV_ReadData(flexio_spi_master_state_t *master)
556 {
557  const FLEXIO_Type *baseAddr;
558  uint32_t data;
559  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
560 
561  baseAddr = g_flexioBase[master->flexioCommon.instance];
562  resourceIndex = master->flexioCommon.resourceIndex;
563 
564  /* Read data from shifter buffer */
565  if (master->bitOrder == FLEXIO_SPI_TRANSFER_LSB_FIRST)
566  {
567  /* For data size < 4 bytes our data is in the upper part of the buffer and must be shifted */
568  data = FLEXIO_HAL_ReadShifterBuffer(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_RW_MODE_NORMAL);
569  data >>= (32U - (8U * (uint32_t)(master->transferSize)));
570  }
571  else
572  {
573  data = FLEXIO_HAL_ReadShifterBuffer(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_RW_MODE_BIT_SWAP);
574  }
575 
576  if ((master->rxRemainingBytes > 0U) && (master->rxData != NULL))
577  {
578  switch (master->transferSize)
579  {
581  *(uint8_t *)master->rxData = (uint8_t)data;
582  break;
584  *(uint16_t *)master->rxData = (uint16_t)data;
585  break;
587  *(uint32_t *)master->rxData = (uint32_t)data;
588  break;
589  default:
590  /* Not possible */
591  break;
592  }
593  /* Update rx buffer pointer and remaining bytes count */
594  master->rxData = &master->rxData[(master->transferSize)];
595  master->rxRemainingBytes -= (uint32_t)(master->transferSize);
596  }
597  else
598  {
599  /* No data to receive, just ignore the read data */
600  }
601 }
602 
603 
604 /*FUNCTION**********************************************************************
605  *
606  * Function Name : FLEXIO_SPI_DRV_WriteData
607  * Description : writes data to be transmitted by the module
608  *
609  *END**************************************************************************/
610 static void FLEXIO_SPI_DRV_WriteData(flexio_spi_master_state_t *master)
611 {
612  FLEXIO_Type *baseAddr;
613  uint32_t data = FLEXIO_SPI_DUMMYDATA;
614  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
615 
616  baseAddr = g_flexioBase[master->flexioCommon.instance];
617  resourceIndex = master->flexioCommon.resourceIndex;
618 
619  if (master->txRemainingBytes == 0U)
620  {
621  /* Done transmitting */
622  return;
623  }
624 
625  if ((master->txRemainingBytes > 0U) && (master->txData != NULL))
626  {
627  /* Read data from user buffer */
628  switch (master->transferSize)
629  {
631  data = (uint32_t)(*(const uint8_t *)master->txData);
632  break;
634  data = (uint32_t)(*(const uint16_t *)master->txData);
635  break;
637  data = (uint32_t)(*(const uint32_t *)master->txData);
638  break;
639  default:
640  /* Not possible */
641  break;
642  }
643  /* Update tx buffer pointer and remaining bytes count */
644  master->txData = &master->txData[master->transferSize];
645  master->txRemainingBytes -= (uint32_t)(master->transferSize);
646  /* Write data to shifter buffer */
647  if (master->bitOrder == FLEXIO_SPI_TRANSFER_LSB_FIRST)
648  {
649  FLEXIO_HAL_WriteShifterBuffer(baseAddr, TX_SHIFTER(resourceIndex), data, FLEXIO_SHIFTER_RW_MODE_NORMAL);
650  }
651  else
652  {
653  /* Shift data before bit-swapping it to get the relevant bits in the lower part of the shifter */
654  data <<= 32U - (8U * (uint32_t)(master->transferSize));
655  FLEXIO_HAL_WriteShifterBuffer(baseAddr, TX_SHIFTER(resourceIndex), data, FLEXIO_SHIFTER_RW_MODE_BIT_SWAP);
656  }
657  }
658  else
659  {
660  /* Nothing to send, write dummy data in buffer */
661  FLEXIO_HAL_WriteShifterBuffer(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SPI_DUMMYDATA, FLEXIO_SHIFTER_RW_MODE_NORMAL);
662  }
663 }
664 
665 
666 
667 /*FUNCTION**********************************************************************
668  *
669  * Function Name : FLEXIO_SPI_DRV_MasterCheckStatus
670  * Description : Check status of SPI master transfer. This function can be
671  * called either in an interrupt routine or directly in polling
672  * mode to advance the SPI transfer.
673  *
674  *END**************************************************************************/
675 static void FLEXIO_SPI_DRV_MasterCheckStatus(void *stateStruct)
676 {
678  FLEXIO_Type *baseAddr;
679  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
680 
681  DEV_ASSERT(stateStruct != NULL);
682 
683  master = (flexio_spi_master_state_t *)stateStruct;
684  baseAddr = g_flexioBase[master->flexioCommon.instance];
685  resourceIndex = master->flexioCommon.resourceIndex;
686 
687  /* Check for errors */
688  if (FLEXIO_HAL_GetShifterErrorStatus(baseAddr, TX_SHIFTER(resourceIndex)))
689  {
690  master->status = STATUS_SPI_TX_UNDERRUN;
691  /* Force the transfer to stop */
692  FLEXIO_SPI_DRV_MasterStopTransfer(master);
693  /* Call callback to announce the event to the user */
694  if (master->callback != NULL)
695  {
696  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
697  }
698  return;
699  }
700  if (FLEXIO_HAL_GetShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex)))
701  {
702  master->status = STATUS_SPI_RX_OVERRUN;
703  /* Force the transfer to stop */
704  FLEXIO_SPI_DRV_MasterStopTransfer(master);
705  /* Call callback to announce the event to the user */
706  if (master->callback != NULL)
707  {
708  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
709  }
710  return;
711  }
712  /* Check if data was received */
713  if (FLEXIO_HAL_GetShifterStatus(baseAddr, RX_SHIFTER(resourceIndex)))
714  {
715  FLEXIO_SPI_DRV_ReadData(master);
716  }
717  /* Check if transmitter needs more data */
718  if (FLEXIO_HAL_GetShifterStatus(baseAddr, TX_SHIFTER(resourceIndex)))
719  {
720  FLEXIO_SPI_DRV_WriteData(master);
721  if (master->txRemainingBytes == 0U)
722  {
723  /* No more data to transmit, disable tx interrupts */
724  FLEXIO_HAL_SetShifterInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), false);
725  FLEXIO_HAL_SetShifterErrorInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), false);
726  }
727  }
728 
729  /* Check there is any data left */
730  if ((master->txRemainingBytes == 0U) && (master->rxRemainingBytes == 0U))
731  {
732  /* Record success if there was no error */
733  if (master->status == STATUS_BUSY)
734  {
735  master->status = STATUS_SUCCESS;
736  }
737  /* End transfer */
738  FLEXIO_SPI_DRV_MasterStopTransfer(master);
739  /* Call callback to announce the event to the user */
740  if (master->callback != NULL)
741  {
742  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
743  }
744  }
745 }
746 
747 
748 /*FUNCTION**********************************************************************
749  *
750  * Function Name : FLEXIO_SPI_DRV_MasterComputeTxRegAddr
751  * Description : Computes the address of the register used for DMA tx transfer
752  *
753  *END**************************************************************************/
754 static uint32_t FLEXIO_SPI_DRV_MasterComputeTxRegAddr(const flexio_spi_master_state_t *master)
755 {
756  uint32_t addr;
757  const FLEXIO_Type *baseAddr;
758  uint8_t shifter;
759 
760  baseAddr = g_flexioBase[master->flexioCommon.instance];
761  shifter = TX_SHIFTER(master->flexioCommon.resourceIndex);
762  if (master->bitOrder == FLEXIO_SPI_TRANSFER_LSB_FIRST)
763  {
764  addr = (uint32_t)(&(baseAddr->SHIFTBUF[shifter]));
765  }
766  else
767  {
768  addr = (uint32_t)(&(baseAddr->SHIFTBUFBIS[shifter])) + (sizeof(uint32_t) - (uint32_t)master->transferSize);
769  }
770  return addr;
771 }
772 
773 
774 /*FUNCTION**********************************************************************
775  *
776  * Function Name : FLEXIO_SPI_DRV_MasterComputeRxRegAddr
777  * Description : Computes the address of the register used for DMA rx transfer
778  *
779  *END**************************************************************************/
780 static uint32_t FLEXIO_SPI_DRV_MasterComputeRxRegAddr(const flexio_spi_master_state_t *master)
781 {
782  uint32_t addr;
783  const FLEXIO_Type *baseAddr;
784  uint8_t shifter;
785 
786  baseAddr = g_flexioBase[master->flexioCommon.instance];
787  shifter = RX_SHIFTER(master->flexioCommon.resourceIndex);
788  if (master->bitOrder == FLEXIO_SPI_TRANSFER_LSB_FIRST)
789  {
790  addr = (uint32_t)(&(baseAddr->SHIFTBUF[shifter])) + (sizeof(uint32_t) - (uint32_t)master->transferSize);
791  }
792  else
793  {
794  addr = (uint32_t)(&(baseAddr->SHIFTBUFBIS[shifter]));
795  }
796  return addr;
797 }
798 
799 
800 /*FUNCTION**********************************************************************
801  *
802  * Function Name : FLEXIO_SPI_DRV_MasterStartDmaTransfer
803  * Description : Starts a DMA transfer
804  *
805  *END**************************************************************************/
806 static void FLEXIO_SPI_DRV_MasterStartDmaTransfer(flexio_spi_master_state_t *master)
807 {
808  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
809  DMA_Type *edmaBase = g_edmaBase[0U];
810  FLEXIO_Type *baseAddr;
811  uint32_t addr;
812  /* Table to map flexio_spi transfer sizes to EDMA transfer sizes */
813  static const edma_transfer_size_t dmaTransferSize[FLEXIO_SPI_TRANSFER_4BYTE] =
815 
816 
817  baseAddr = g_flexioBase[master->flexioCommon.instance];
818  resourceIndex = master->flexioCommon.resourceIndex;
819 
820  if (master->txData != NULL)
821  {
822  addr = (uint32_t)(master->txData);
823  }
824  else
825  {
826  /* if there is no data to transmit, use dummy data as source for DMA transfer */
827  master->dummyDmaData = FLEXIO_SPI_DUMMYDATA;
828  addr = (uint32_t)(&(master->dummyDmaData));
829  }
830 
831  /* Configure the transfer control descriptor for the Tx channel */
832  (void)EDMA_DRV_ConfigSingleBlockTransfer(master->txDMAChannel,
834  addr,
835  FLEXIO_SPI_DRV_MasterComputeTxRegAddr(master),
836  dmaTransferSize[(uint32_t)master->transferSize - 1U],
837  (uint32_t)master->transferSize);
838  if (master->txData == NULL)
839  {
840  /* if there is no data to transmit, don't increment source offset */
841  EDMA_HAL_TCDSetSrcOffset(edmaBase, master->txDMAChannel, 0);
842  }
843  EDMA_HAL_TCDSetMajorCount(edmaBase, master->txDMAChannel, master->txRemainingBytes / (uint32_t)master->transferSize);
844  EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBase, master->txDMAChannel, true);
845 
846  if (master->rxData != NULL)
847  {
848  addr = (uint32_t)(master->rxData);
849  }
850  else
851  {
852  /* if there is no data to receive, use dummy data as destination for DMA transfer */
853  addr = (uint32_t)(&(master->dummyDmaData));
854  }
855 
856  /* Configure the transfer control descriptor for the Rx channel */
857  (void)EDMA_DRV_ConfigSingleBlockTransfer(master->rxDMAChannel,
859  FLEXIO_SPI_DRV_MasterComputeRxRegAddr(master),
860  addr,
861  dmaTransferSize[(uint32_t)master->transferSize - 1U],
862  (uint32_t)master->transferSize);
863  if (master->rxData == NULL)
864  {
865  /* if there is no data to receive, don't increment destination offset */
866  EDMA_HAL_TCDSetDestOffset(edmaBase, master->rxDMAChannel, 0);
867  }
868  EDMA_HAL_TCDSetMajorCount(edmaBase, master->rxDMAChannel, master->rxRemainingBytes / (uint32_t)master->transferSize);
869  EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBase, master->rxDMAChannel, true);
870  /* Setup callback for DMA transfer end */
871  (void)EDMA_DRV_InstallCallback(master->rxDMAChannel,
872  (edma_callback_t)(FLEXIO_SPI_DRV_MasterEndDmaTransfer),
873  (void*)(master));
874 
875  /* Start both DMA channels */
876  (void)EDMA_DRV_StartChannel(master->txDMAChannel);
877  (void)EDMA_DRV_StartChannel(master->rxDMAChannel);
878 
879  /* Enable FlexIO DMA requests for both shifters */
880  FLEXIO_HAL_SetShifterDMARequest(baseAddr, (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))), true);
881 }
882 
883 
886 /*******************************************************************************
887  * Code
888  ******************************************************************************/
889 
890 /*FUNCTION**********************************************************************
891  *
892  * Function Name : FLEXIO_SPI_DRV_MasterInit
893  * Description : Initialize the FLEXIO_SPI master mode driver
894  *
895  * Implements : FLEXIO_SPI_DRV_MasterInit_Activity
896  *END**************************************************************************/
898  const flexio_spi_master_user_config_t * userConfigPtr,
899  flexio_spi_master_state_t * master)
900 {
901  status_t retCode;
902  uint32_t inputClock;
903  status_t clkErr;
904  status_t osifError = STATUS_SUCCESS;
905  uint8_t dmaReqTx;
906  uint8_t dmaReqRx;
907 
908  DEV_ASSERT(master != NULL);
909  DEV_ASSERT(instance < FLEXIO_INSTANCE_COUNT);
910  /* Check that device was initialized */
911  DEV_ASSERT(g_flexioDeviceStatePtr[instance] != NULL);
912  DEV_ASSERT((userConfigPtr->transferSize == FLEXIO_SPI_TRANSFER_1BYTE) ||
913  (userConfigPtr->transferSize == FLEXIO_SPI_TRANSFER_2BYTE) ||
914  (userConfigPtr->transferSize == FLEXIO_SPI_TRANSFER_4BYTE));
915 
916  /* Get the protocol clock frequency */
917  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[instance], &inputClock);
918  DEV_ASSERT(clkErr == STATUS_SUCCESS);
919  DEV_ASSERT(inputClock > 0U);
920 
921  /* Instruct the resource allocator that we need two shifters/timers */
922  master->flexioCommon.resourceCount = 2U;
923  /* Common FlexIO driver initialization */
924  retCode = FLEXIO_DRV_InitDriver(instance, &(master->flexioCommon));
925  if (retCode != STATUS_SUCCESS)
926  { /* Initialization failed, not enough resources */
927  return retCode;
928  }
929  /* Initialize the semaphore */
930  if (userConfigPtr->driverType != FLEXIO_DRIVER_TYPE_POLLING)
931  {
932  osifError = OSIF_SemaCreate(&(master->idleSemaphore), 0U);
933  DEV_ASSERT(osifError == STATUS_SUCCESS);
934  }
935 
936  /* Initialize driver-specific context structure */
937  master->driverType = userConfigPtr->driverType;
938  master->bitOrder = userConfigPtr->bitOrder;
939  master->transferSize = userConfigPtr->transferSize;
940  master->callback = userConfigPtr->callback;
941  master->callbackParam = userConfigPtr->callbackParam;
942  master->blocking = false;
943  master->driverIdle = true;
944  master->master = true;
945  master->status = STATUS_SUCCESS;
946 
947  /* Configure device for SPI mode */
948  FLEXIO_SPI_DRV_MasterConfigure(master, userConfigPtr, inputClock);
949 
950  /* Set up transfer engine */
951  switch (userConfigPtr->driverType)
952  {
954  master->flexioCommon.isr = FLEXIO_SPI_DRV_MasterCheckStatus;
955  break;
957  /* Nothing to do here, FLEXIO_SPI_DRV_MasterGetStatus() will handle the transfer */
958  break;
960  /* Store DMA channel numbers */
961  master->rxDMAChannel = userConfigPtr->rxDMAChannel;
962  master->txDMAChannel = userConfigPtr->txDMAChannel;
963  /* Configure DMA request sources */
964  dmaReqTx = g_flexioDMASrc[instance][TX_SHIFTER(master->flexioCommon.resourceIndex)];
965  dmaReqRx = g_flexioDMASrc[instance][RX_SHIFTER(master->flexioCommon.resourceIndex)];
966  DMAMUX_HAL_SetChannelSource(g_dmamuxBase[0U], userConfigPtr->txDMAChannel, dmaReqTx);
967  DMAMUX_HAL_SetChannelSource(g_dmamuxBase[0U], userConfigPtr->rxDMAChannel, dmaReqRx);
968  break;
969  default:
970  /* Impossible type - do nothing */
971  break;
972  }
973 
974  (void)clkErr;
975  (void)osifError;
976  return STATUS_SUCCESS;
977 }
978 
979 /*FUNCTION**********************************************************************
980  *
981  * Function Name : FLEXIO_SPI_DRV_MasterDeinit
982  * Description : De-initialize the FLEXIO_SPI master mode driver
983  *
984  * Implements : FLEXIO_SPI_DRV_MasterDeinit_Activity
985  *END**************************************************************************/
987 {
988  DEV_ASSERT(master != NULL);
989 
990  /* Check if driver is busy */
991  DEV_ASSERT(master->driverIdle);
992 
993  /* Destroy the semaphore */
994  if (master->driverType != FLEXIO_DRIVER_TYPE_POLLING)
995  {
996  (void)OSIF_SemaDestroy(&(master->idleSemaphore));
997  }
998 
999  return FLEXIO_DRV_DeinitDriver(&(master->flexioCommon));
1000 }
1001 
1002 
1003 /*FUNCTION**********************************************************************
1004  *
1005  * Function Name : FLEXIO_SPI_DRV_MasterSetBaudRate
1006  * Description : Set the baud rate for any subsequent SPI communication
1007  *
1008  * Implements : FLEXIO_SPI_DRV_MasterSetBaudRate_Activity
1009  *END**************************************************************************/
1011 {
1012  FLEXIO_Type *baseAddr;
1013  uint16_t divider;
1014  uint16_t timerCmp;
1015  uint32_t inputClock;
1016  status_t clkErr;
1017  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1018 
1019  DEV_ASSERT(master != NULL);
1020 
1021  baseAddr = g_flexioBase[master->flexioCommon.instance];
1022  resourceIndex = master->flexioCommon.resourceIndex;
1023 
1024  /* Check if driver is busy */
1025  DEV_ASSERT(master->driverIdle);
1026  /* Get the protocol clock frequency */
1027  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[master->flexioCommon.instance], &inputClock);
1028  DEV_ASSERT(clkErr == STATUS_SUCCESS);
1029  DEV_ASSERT(inputClock > 0U);
1030 
1031  /* Compute divider */
1032  FLEXIO_SPI_DRV_MasterComputeBaudRateDivider(baudRate, &divider, inputClock);
1033 
1034  /* Configure timer divider in the lower 8 bits of TIMCMP[CMP] */
1035  timerCmp = FLEXIO_HAL_GetTimerCompare(baseAddr, SCK_TIMER(resourceIndex));
1036  timerCmp = (uint16_t)((timerCmp & 0xFF00U) | divider);
1037  FLEXIO_HAL_SetTimerCompare(baseAddr, SCK_TIMER(resourceIndex), timerCmp);
1038 
1039  (void)clkErr;
1040  return STATUS_SUCCESS;
1041 }
1042 
1043 
1044 
1045 /*FUNCTION**********************************************************************
1046  *
1047  * Function Name : FLEXIO_SPI_DRV_MasterGetBaudRate
1048  * Description : Get the currently configured baud rate
1049  *
1050  * Implements : FLEXIO_SPI_DRV_MasterGetBaudRate_Activity
1051  *END**************************************************************************/
1053 {
1054  const FLEXIO_Type *baseAddr;
1055  uint16_t divider;
1056  uint16_t timerCmp;
1057  uint32_t inputClock;
1058  status_t clkErr;
1059  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1060 
1061  DEV_ASSERT(master != NULL);
1062 
1063  baseAddr = g_flexioBase[master->flexioCommon.instance];
1064  resourceIndex = master->flexioCommon.resourceIndex;
1065 
1066  /* Get the protocol clock frequency */
1067  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[master->flexioCommon.instance], &inputClock);
1068  DEV_ASSERT(clkErr == STATUS_SUCCESS);
1069  DEV_ASSERT(inputClock > 0U);
1070 
1071  /* Get the currently configured divider */
1072  timerCmp = FLEXIO_HAL_GetTimerCompare(baseAddr, SCK_TIMER(resourceIndex));
1073  divider = (uint16_t)(timerCmp & 0x00FFU);
1074 
1075  /* Compute baud rate: input_clock / (2 * (divider + 1)). Round to nearest integer */
1076  *baudRate = (inputClock + divider + 1U) / (2U * ((uint32_t)divider + 1U));
1077 
1078  (void)clkErr;
1079  return STATUS_SUCCESS;
1080 }
1081 
1082 
1083 
1084 
1085 /*FUNCTION**********************************************************************
1086  *
1087  * Function Name : FLEXIO_SPI_DRV_MasterTransfer
1088  * Description : Perform an SPI master non-blocking transaction
1089  *
1090  * Implements : FLEXIO_SPI_DRV_MasterTransfer_Activity
1091  *END**************************************************************************/
1093  const uint8_t *txData,
1094  uint8_t *rxData,
1095  uint32_t dataSize)
1096 {
1097  FLEXIO_Type *baseAddr;
1098  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1099 
1100  DEV_ASSERT(master != NULL);
1101  DEV_ASSERT((dataSize % (uint32_t)(master->transferSize)) == 0U);
1102  DEV_ASSERT((txData != NULL) || (rxData != NULL));
1103 
1104  baseAddr = g_flexioBase[master->flexioCommon.instance];
1105  resourceIndex = master->flexioCommon.resourceIndex;
1106 
1107  /* Check if driver is busy */
1108  DEV_ASSERT(master->driverIdle);
1109  /* Initialize transfer data */
1110  master->txData = txData;
1111  master->rxData = rxData;
1112  master->txRemainingBytes = dataSize;
1113  master->rxRemainingBytes = dataSize;
1114  master->driverIdle = false;
1115  master->status = STATUS_BUSY;
1116 
1117  /* Enable timers and shifters */
1118  FLEXIO_SPI_DRV_MasterEnableTransfer(master);
1119  /* Enable transfer engine */
1120  switch (master->driverType)
1121  {
1123  /* Enable interrupts for Rx and Tx shifters */
1125  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
1126  true);
1128  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
1129  true);
1130  break;
1132  /* Call FLEXIO_SPI_DRV_MasterCheckStatus once to send the first byte */
1133  FLEXIO_SPI_DRV_MasterCheckStatus(master);
1134  break;
1136  FLEXIO_SPI_DRV_MasterStartDmaTransfer(master);
1137  break;
1138  default:
1139  /* Impossible type - do nothing */
1140  break;
1141  }
1142 
1143  return STATUS_SUCCESS;
1144 }
1145 
1146 
1147 /*FUNCTION**********************************************************************
1148  *
1149  * Function Name : FLEXIO_SPI_DRV_MasterTransferBlocking
1150  * Description : Perform an SPI master blocking transaction
1151  *
1152  * Implements : FLEXIO_SPI_DRV_MasterTransferBlocking_Activity
1153  *END**************************************************************************/
1155  const uint8_t *txData,
1156  uint8_t *rxData,
1157  uint32_t dataSize,
1158  uint32_t timeout)
1159 {
1160  status_t status;
1161 
1162  /* mark transfer as blocking */
1163  if (master->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1164  {
1165  master->blocking = true;
1166  }
1167  status = FLEXIO_SPI_DRV_MasterTransfer(master, txData, rxData, dataSize);
1168  if (status != STATUS_SUCCESS)
1169  {
1170  /* Transfer could not be started */
1171  master->blocking = false;
1172  return status;
1173  }
1174 
1175  /* Wait for transfer to end */
1176  return FLEXIO_SPI_DRV_MasterWaitTransferEnd(master, timeout);
1177 }
1178 
1179 
1180 /*FUNCTION**********************************************************************
1181  *
1182  * Function Name : FLEXIO_SPI_DRV_MasterTransferAbort
1183  * Description : Aborts a non-blocking SPI master transaction
1184  *
1185  * Implements : FLEXIO_SPI_DRV_MasterTransferAbort_Activity
1186  *END**************************************************************************/
1188 {
1189  DEV_ASSERT(master != NULL);
1190 
1191  master->status = STATUS_SPI_ABORTED;
1192  FLEXIO_SPI_DRV_MasterStopTransfer(master);
1193 
1194  return STATUS_SUCCESS;
1195 }
1196 
1197 
1198 /*FUNCTION**********************************************************************
1199  *
1200  * Function Name : FLEXIO_SPI_DRV_MasterGetStatus
1201  * Description : Get the status of the current non-blocking SPI master transaction
1202  *
1203  * Implements : FLEXIO_SPI_DRV_MasterGetStatus_Activity
1204  *END**************************************************************************/
1206 {
1207  DEV_ASSERT(master != NULL);
1208 
1209  if ((!master->driverIdle) && (master->driverType == FLEXIO_DRIVER_TYPE_POLLING))
1210  {
1211  /* In polling mode advance the SPI transfer here */
1212  FLEXIO_SPI_DRV_MasterCheckStatus(master);
1213  }
1214 
1215  if (bytesRemaining != NULL)
1216  {
1217  *bytesRemaining = master->txRemainingBytes;
1218  }
1219 
1220  return master->status;
1221 }
1222 
1223 
1224 
1225 /*FUNCTION**********************************************************************
1226  *
1227  * Function Name : FLEXIO_SPI_DRV_SlaveInit
1228  * Description : Initialize the FLEXIO_SPI slave mode driver
1229  *
1230  * Implements : FLEXIO_SPI_DRV_SlaveInit_Activity
1231  *END**************************************************************************/
1233  const flexio_spi_slave_user_config_t * userConfigPtr,
1234  flexio_spi_slave_state_t * slave)
1235 {
1236  status_t retCode;
1237  status_t osifError = STATUS_SUCCESS;
1238  uint8_t dmaReqTx;
1239  uint8_t dmaReqRx;
1240 
1241  DEV_ASSERT(slave != NULL);
1242  DEV_ASSERT(instance < FLEXIO_INSTANCE_COUNT);
1243  /* Check that device was initialized */
1244  DEV_ASSERT(g_flexioDeviceStatePtr[instance] != NULL);
1245 
1246  /* Instruct the resource allocator that we need two shifters/timers */
1247  slave->flexioCommon.resourceCount = 2U;
1248  /* Common FlexIO driver initialization */
1249  retCode = FLEXIO_DRV_InitDriver(instance, &(slave->flexioCommon));
1250  if (retCode != STATUS_SUCCESS)
1251  { /* Initialization failed, not enough resources */
1252  return retCode;
1253  }
1254  /* Initialize the semaphore */
1255  if (userConfigPtr->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1256  {
1257  osifError = OSIF_SemaCreate(&(slave->idleSemaphore), 0U);
1258  DEV_ASSERT(osifError == STATUS_SUCCESS);
1259  }
1260 
1261  /* Initialize driver context structure */
1262  slave->driverType = userConfigPtr->driverType;
1263  slave->bitOrder = userConfigPtr->bitOrder;
1264  slave->transferSize = userConfigPtr->transferSize;
1265  slave->callback = userConfigPtr->callback;
1266  slave->callbackParam = userConfigPtr->callbackParam;
1267  slave->blocking = false;
1268  slave->driverIdle = true;
1269  slave->master = false;
1270  slave->status = STATUS_SUCCESS;
1271 
1272  /* Configure device for SPI mode */
1273  FLEXIO_SPI_DRV_SlaveConfigure(slave, userConfigPtr);
1274 
1275  /* Set up transfer engine */
1276  switch (userConfigPtr->driverType)
1277  {
1279  slave->flexioCommon.isr = FLEXIO_SPI_DRV_MasterCheckStatus;
1280  break;
1282  /* Nothing to do here, FLEXIO_SPI_DRV_MasterGetStatus() will handle the transfer */
1283  break;
1285  /* Store DMA channel numbers */
1286  slave->rxDMAChannel = userConfigPtr->rxDMAChannel;
1287  slave->txDMAChannel = userConfigPtr->txDMAChannel;
1288  /* Configure DMA request sources */
1289  dmaReqTx = g_flexioDMASrc[instance][TX_SHIFTER(slave->flexioCommon.resourceIndex)];
1290  dmaReqRx = g_flexioDMASrc[instance][RX_SHIFTER(slave->flexioCommon.resourceIndex)];
1291  DMAMUX_HAL_SetChannelSource(g_dmamuxBase[0U], userConfigPtr->txDMAChannel, dmaReqTx);
1292  DMAMUX_HAL_SetChannelSource(g_dmamuxBase[0U], userConfigPtr->rxDMAChannel, dmaReqRx);
1293  break;
1294  default:
1295  /* Impossible type - do nothing */
1296  break;
1297  }
1298 
1299  (void)osifError;
1300  return STATUS_SUCCESS;
1301 }
1302 
1303 
1304 
1305 /*******************************************************************************
1306  * EOF
1307  ******************************************************************************/
status_t FLEXIO_SPI_DRV_MasterGetBaudRate(flexio_spi_master_state_t *master, uint32_t *baudRate)
Get the currently configured baud rate.
__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
flexio_timer_polarity_t
Shift clock polarity options Implements : flexio_timer_polarity_t_Class.
Definition: flexio_hal.h:76
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
flexio_spi_transfer_size_t transferSize
status_t OSIF_SemaDestroy(const semaphore_t *const pSem)
Destroys a previously created semaphore.
status_t FLEXIO_SPI_DRV_MasterTransferBlocking(flexio_spi_master_state_t *master, const uint8_t *txData, uint8_t *rxData, uint32_t dataSize, uint32_t timeout)
Perform a blocking SPI master transaction.
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
FLEXIO_Type *const g_flexioBase[FLEXIO_INSTANCE_COUNT]
Definition: flexio_common.c:56
status_t FLEXIO_SPI_DRV_MasterTransfer(flexio_spi_master_state_t *master, const uint8_t *txData, uint8_t *rxData, uint32_t dataSize)
Perform a non-blocking SPI master transaction.
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
flexio_shifter_start_t
Timer start bit options - for Transmit, Receive or Match Store modes only Implements : flexio_shifter...
Definition: flexio_hal.h:251
flexio_spi_transfer_bit_order_t bitOrder
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
status_t OSIF_SemaCreate(semaphore_t *const pSem, const uint8_t initValue)
Creates a semaphore with a given value.
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
#define DEV_ASSERT(x)
Definition: devassert.h:78
status_t FLEXIO_SPI_DRV_MasterGetStatus(flexio_spi_master_state_t *master, uint32_t *bytesRemaining)
Get the status of the current non-blocking SPI master transaction.
Slave configuration structure.
flexio_driver_type_t driverType
static void EDMA_HAL_TCDSetSrcOffset(DMA_Type *base, uint32_t channel, int16_t offset)
Configures the source address signed offset for the hardware TCD.
Definition: edma_hal.h:813
edma_chn_status_t
Channel status for eDMA channel.
Definition: edma_driver.h:125
__IO uint32_t SHIFTBUFBIS[FLEXIO_SHIFTBUFBIS_COUNT]
Definition: S32K144.h:3493
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.
flexio_spi_transfer_size_t transferSize
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
Master configuration structure.
status_t FLEXIO_SPI_DRV_MasterSetBaudRate(flexio_spi_master_state_t *master, uint32_t baudRate)
Set the baud rate for any subsequent SPI communication.
const uint8_t g_flexioDMASrc[FLEXIO_INSTANCE_COUNT][FEATURE_FLEXIO_MAX_SHIFTER_COUNT]
Definition: flexio_common.c:68
status_t FLEXIO_SPI_DRV_SlaveInit(uint32_t instance, const flexio_spi_slave_user_config_t *userConfigPtr, flexio_spi_slave_state_t *slave)
Initialize the FLEXIO_SPI slave mode 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
flexio_spi_transfer_bit_order_t bitOrder
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
static void EDMA_HAL_TCDSetDestOffset(DMA_Type *base, uint32_t channel, int16_t offset)
Configures the destination address signed offset for the TCD.
Definition: edma_hal.h:987
status_t FLEXIO_SPI_DRV_MasterInit(uint32_t instance, const flexio_spi_master_user_config_t *userConfigPtr, flexio_spi_master_state_t *master)
Initialize the FLEXIO_SPI master mode driver.
status_t OSIF_SemaPost(semaphore_t *const pSem)
Increment a semaphore.
flexio_pin_polarity_t
Pin polarity options Implements : flexio_pin_polarity_t_Class.
Definition: flexio_hal.h:85
flexio_shifter_stop_t
Timer stop bit options - for Transmit, Receive or Match Store modes only Implements : flexio_shifter_...
Definition: flexio_hal.h:241
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
status_t FLEXIO_SPI_DRV_MasterDeinit(flexio_spi_master_state_t *master)
De-initialize the FLEXIO_SPI master mode driver.
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
status_t FLEXIO_SPI_DRV_MasterTransferAbort(flexio_spi_master_state_t *master)
Aborts a non-blocking SPI master transaction.
Master internal context structure.
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
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