Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:59

0001 /*
0002  * Copyright (c) 2015, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2020, 2022 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_flexio_spi_edma.h"
0010 
0011 /*******************************************************************************
0012  * Definitions
0013  ******************************************************************************/
0014 
0015 /* Component ID definition, used by tools. */
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.flexio_spi_edma"
0018 #endif
0019 
0020 /*<! Structure definition for spi_edma_private_handle_t. The structure is private. */
0021 typedef struct _flexio_spi_master_edma_private_handle
0022 {
0023     FLEXIO_SPI_Type *base;
0024     flexio_spi_master_edma_handle_t *handle;
0025 } flexio_spi_master_edma_private_handle_t;
0026 
0027 /*******************************************************************************
0028  * Prototypes
0029  ******************************************************************************/
0030 
0031 /*!
0032  * @brief EDMA callback function for FLEXIO SPI send transfer.
0033  *
0034  * @param handle EDMA handle pointer.
0035  * @param param Callback function parameter.
0036  */
0037 static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
0038 
0039 /*!
0040  * @brief EDMA callback function for FLEXIO SPI receive transfer.
0041  *
0042  * @param handle EDMA handle pointer.
0043  * @param param Callback function parameter.
0044  */
0045 static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
0046 
0047 /*!
0048  * @brief EDMA config for FLEXIO SPI transfer.
0049  *
0050  * @param base pointer to FLEXIO_SPI_Type structure.
0051  * @param handle pointer to flexio_spi_master_edma_handle_t structure to store the transfer state.
0052  * @param xfer Pointer to flexio spi transfer structure.
0053  * @retval kStatus_Success Successfully create the handle.
0054  * @retval kStatus_InvalidArgument The transfer size is not supported.
0055  */
0056 static status_t FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base,
0057                                       flexio_spi_master_edma_handle_t *handle,
0058                                       flexio_spi_transfer_t *xfer);
0059 
0060 /*******************************************************************************
0061  * Variables
0062  ******************************************************************************/
0063 
0064 /* Dummy data used to send */
0065 static const uint32_t s_dummyData = FLEXIO_SPI_DUMMYDATA;
0066 
0067 /*< @brief user configurable flexio spi handle count. */
0068 #define FLEXIO_SPI_HANDLE_COUNT 2
0069 
0070 /*<! Private handle only used for internally. */
0071 static flexio_spi_master_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_SPI_HANDLE_COUNT];
0072 
0073 /*******************************************************************************
0074  * Code
0075  ******************************************************************************/
0076 
0077 static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
0078 {
0079     tcds                                                      = tcds;
0080     flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param;
0081 
0082     /* Disable Tx DMA */
0083     if (transferDone)
0084     {
0085         FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, (uint32_t)kFLEXIO_SPI_TxDmaEnable, false);
0086 
0087         /* change the state */
0088         spiPrivateHandle->handle->txInProgress = false;
0089 
0090         /* All finished, call the callback */
0091         if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
0092         {
0093             if (spiPrivateHandle->handle->callback != NULL)
0094             {
0095                 (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
0096                                                      spiPrivateHandle->handle->userData);
0097             }
0098         }
0099     }
0100 }
0101 
0102 static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
0103 {
0104     tcds                                                      = tcds;
0105     flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param;
0106 
0107     if (transferDone)
0108     {
0109         /* Disable Rx dma */
0110         FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, (uint32_t)kFLEXIO_SPI_RxDmaEnable, false);
0111 
0112         /* change the state */
0113         spiPrivateHandle->handle->rxInProgress = false;
0114 
0115         /* All finished, call the callback */
0116         if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
0117         {
0118             if (spiPrivateHandle->handle->callback != NULL)
0119             {
0120                 (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
0121                                                      spiPrivateHandle->handle->userData);
0122             }
0123         }
0124     }
0125 }
0126 
0127 static status_t FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base,
0128                                       flexio_spi_master_edma_handle_t *handle,
0129                                       flexio_spi_transfer_t *xfer)
0130 {
0131     edma_transfer_config_t xferConfig      = {0};
0132     flexio_spi_shift_direction_t direction = kFLEXIO_SPI_MsbFirst;
0133     uint8_t bytesPerFrame;
0134     uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
0135 
0136     /* Configure the values in handle. */
0137     switch (dataFormat)
0138     {
0139         case (uint8_t)kFLEXIO_SPI_8bitMsb:
0140             bytesPerFrame = 1U;
0141             direction     = kFLEXIO_SPI_MsbFirst;
0142             break;
0143         case (uint8_t)kFLEXIO_SPI_8bitLsb:
0144             bytesPerFrame = 1U;
0145             direction     = kFLEXIO_SPI_LsbFirst;
0146             break;
0147         case (uint8_t)kFLEXIO_SPI_16bitMsb:
0148             bytesPerFrame = 2U;
0149             direction     = kFLEXIO_SPI_MsbFirst;
0150             break;
0151         case (uint8_t)kFLEXIO_SPI_16bitLsb:
0152             bytesPerFrame = 2U;
0153             direction     = kFLEXIO_SPI_LsbFirst;
0154             break;
0155         case (uint8_t)kFLEXIO_SPI_32bitMsb:
0156             bytesPerFrame = 4U;
0157             direction     = kFLEXIO_SPI_MsbFirst;
0158             break;
0159         case (uint8_t)kFLEXIO_SPI_32bitLsb:
0160             bytesPerFrame = 4U;
0161             direction     = kFLEXIO_SPI_LsbFirst;
0162             break;
0163         default:
0164             bytesPerFrame = 1U;
0165             direction     = kFLEXIO_SPI_MsbFirst;
0166             assert(true);
0167             break;
0168     }
0169 
0170     /* Transfer size should be bytesPerFrame divisible. */
0171     if ((xfer->dataSize % bytesPerFrame) != 0U)
0172     {
0173         return kStatus_InvalidArgument;
0174     }
0175 
0176     /* Save total transfer size. */
0177     handle->transferSize = xfer->dataSize;
0178 
0179     /* Configure tx transfer EDMA. */
0180     xferConfig.destAddr   = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction);
0181     xferConfig.destOffset = 0;
0182     if (bytesPerFrame == 1U)
0183     {
0184         xferConfig.srcTransferSize  = kEDMA_TransferSize1Bytes;
0185         xferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
0186         xferConfig.minorLoopBytes   = 1U;
0187     }
0188     else if (bytesPerFrame == 2U)
0189     {
0190         if (direction == kFLEXIO_SPI_MsbFirst)
0191         {
0192             xferConfig.destAddr -= 1U;
0193         }
0194         xferConfig.srcTransferSize  = kEDMA_TransferSize2Bytes;
0195         xferConfig.destTransferSize = kEDMA_TransferSize2Bytes;
0196         xferConfig.minorLoopBytes   = 2U;
0197     }
0198     else
0199     {
0200         if (direction == kFLEXIO_SPI_MsbFirst)
0201         {
0202             xferConfig.destAddr -= 3U;
0203         }
0204         xferConfig.srcTransferSize  = kEDMA_TransferSize4Bytes;
0205         xferConfig.destTransferSize = kEDMA_TransferSize4Bytes;
0206         xferConfig.minorLoopBytes   = 4U;
0207     }
0208 
0209     /* Configure DMA channel. */
0210     if (xfer->txData != NULL)
0211     {
0212         xferConfig.srcOffset = (int16_t)bytesPerFrame;
0213         xferConfig.srcAddr   = (uint32_t)(xfer->txData);
0214     }
0215     else
0216     {
0217         /* Disable the source increasement and source set to dummyData. */
0218         xferConfig.srcOffset = 0;
0219         xferConfig.srcAddr   = (uint32_t)(&s_dummyData);
0220     }
0221 
0222     xferConfig.majorLoopCounts = (xfer->dataSize / xferConfig.minorLoopBytes);
0223 
0224     /* Store the initially configured eDMA minor byte transfer count into the FLEXIO SPI handle */
0225     handle->nbytes = (uint8_t)xferConfig.minorLoopBytes;
0226 
0227     if (handle->txHandle != NULL)
0228     {
0229         (void)EDMA_SubmitTransfer(handle->txHandle, &xferConfig);
0230     }
0231 
0232     /* Configure rx transfer EDMA. */
0233     if (xfer->rxData != NULL)
0234     {
0235         xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction);
0236         if (bytesPerFrame == 2U)
0237         {
0238             if (direction == kFLEXIO_SPI_LsbFirst)
0239             {
0240                 xferConfig.srcAddr -= 1U;
0241             }
0242         }
0243         else if (bytesPerFrame == 4U)
0244         {
0245             if (direction == kFLEXIO_SPI_LsbFirst)
0246             {
0247                 xferConfig.srcAddr -= 3U;
0248             }
0249         }
0250         else
0251         {
0252         }
0253         xferConfig.srcOffset  = 0;
0254         xferConfig.destAddr   = (uint32_t)(xfer->rxData);
0255         xferConfig.destOffset = (int16_t)bytesPerFrame;
0256         (void)EDMA_SubmitTransfer(handle->rxHandle, &xferConfig);
0257         handle->rxInProgress = true;
0258         FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_RxDmaEnable, true);
0259         EDMA_StartTransfer(handle->rxHandle);
0260     }
0261 
0262     /* Always start tx transfer. */
0263     if (handle->txHandle != NULL)
0264     {
0265         handle->txInProgress = true;
0266         FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_TxDmaEnable, true);
0267         EDMA_StartTransfer(handle->txHandle);
0268     }
0269 
0270     return kStatus_Success;
0271 }
0272 
0273 /*!
0274  * brief Initializes the FlexIO SPI master eDMA handle.
0275  *
0276  * This function initializes the FlexIO SPI master eDMA handle which can be used for other FlexIO SPI master
0277  * transactional
0278  * APIs.
0279  * For a specified FlexIO SPI instance, call this API once to get the initialized handle.
0280  *
0281  * param base Pointer to FLEXIO_SPI_Type structure.
0282  * param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state.
0283  * param callback SPI callback, NULL means no callback.
0284  * param userData callback function parameter.
0285  * param txHandle User requested eDMA handle for FlexIO SPI RX eDMA transfer.
0286  * param rxHandle User requested eDMA handle for FlexIO SPI TX eDMA transfer.
0287  * retval kStatus_Success Successfully create the handle.
0288  * retval kStatus_OutOfRange The FlexIO SPI eDMA type/handle table out of range.
0289  */
0290 status_t FLEXIO_SPI_MasterTransferCreateHandleEDMA(FLEXIO_SPI_Type *base,
0291                                                    flexio_spi_master_edma_handle_t *handle,
0292                                                    flexio_spi_master_edma_transfer_callback_t callback,
0293                                                    void *userData,
0294                                                    edma_handle_t *txHandle,
0295                                                    edma_handle_t *rxHandle)
0296 {
0297     assert(handle != NULL);
0298 
0299     uint8_t index = 0;
0300 
0301     /* Find the an empty handle pointer to store the handle. */
0302     for (index = 0U; index < (uint8_t)FLEXIO_SPI_HANDLE_COUNT; index++)
0303     {
0304         if (s_edmaPrivateHandle[index].base == NULL)
0305         {
0306             s_edmaPrivateHandle[index].base   = base;
0307             s_edmaPrivateHandle[index].handle = handle;
0308             break;
0309         }
0310     }
0311 
0312     if (index == (uint16_t)FLEXIO_SPI_HANDLE_COUNT)
0313     {
0314         return kStatus_OutOfRange;
0315     }
0316 
0317     /* Set spi base to handle. */
0318     handle->txHandle = txHandle;
0319     handle->rxHandle = rxHandle;
0320 
0321     /* Register callback and userData. */
0322     handle->callback = callback;
0323     handle->userData = userData;
0324 
0325     /* Set SPI state to idle. */
0326     handle->txInProgress = false;
0327     handle->rxInProgress = false;
0328 
0329     /* Install callback for Tx/Rx dma channel. */
0330     if (handle->txHandle != NULL)
0331     {
0332         EDMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxEDMACallback, &s_edmaPrivateHandle[index]);
0333     }
0334     if (handle->rxHandle != NULL)
0335     {
0336         EDMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxEDMACallback, &s_edmaPrivateHandle[index]);
0337     }
0338 
0339     return kStatus_Success;
0340 }
0341 
0342 /*!
0343  * brief Performs a non-blocking FlexIO SPI transfer using eDMA.
0344  *
0345  * note This interface returns immediately after transfer initiates. Call
0346  * FLEXIO_SPI_MasterGetTransferCountEDMA to poll the transfer status and check
0347  * whether the FlexIO SPI transfer is finished.
0348  *
0349  * param base Pointer to FLEXIO_SPI_Type structure.
0350  * param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state.
0351  * param xfer Pointer to FlexIO SPI transfer structure.
0352  * retval kStatus_Success Successfully start a transfer.
0353  * retval kStatus_InvalidArgument Input argument is invalid.
0354  * retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer.
0355  */
0356 status_t FLEXIO_SPI_MasterTransferEDMA(FLEXIO_SPI_Type *base,
0357                                        flexio_spi_master_edma_handle_t *handle,
0358                                        flexio_spi_transfer_t *xfer)
0359 {
0360     assert(handle != NULL);
0361     assert(xfer != NULL);
0362 
0363     uint32_t dataMode  = 0;
0364     uint16_t timerCmp  = (uint16_t)base->flexioBase->TIMCMP[base->timerIndex[0]];
0365     uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
0366 
0367     timerCmp &= 0x00FFU;
0368 
0369     /* Check if the device is busy. */
0370     if ((handle->txInProgress) || (handle->rxInProgress))
0371     {
0372         return kStatus_FLEXIO_SPI_Busy;
0373     }
0374 
0375     /* Check if input parameter invalid. */
0376     if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
0377     {
0378         return kStatus_InvalidArgument;
0379     }
0380 
0381     /* Timer1 controls the CS signal which enables/disables(asserts/deasserts) when timer0 enable/disable. Timer0
0382        enables when tx shifter is written and disables when timer compare. The timer compare event causes the
0383        transmit shift registers to load which generates a tx register empty event. Since when timer stop bit is
0384        disabled, a timer enable condition can be detected in the same cycle as a timer disable condition, so if
0385        software writes the tx register upon the detection of tx register empty event, the timer enable condition
0386        is triggered again, then the CS signal can remain low until software no longer writes the tx register. */
0387     if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
0388     {
0389         base->flexioBase->TIMCFG[base->timerIndex[0]] =
0390             (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
0391             FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled);
0392     }
0393     else
0394     {
0395         base->flexioBase->TIMCFG[base->timerIndex[0]] =
0396             (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
0397             FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable);
0398     }
0399 
0400     /* configure data mode. */
0401     if ((dataFormat == (uint8_t)kFLEXIO_SPI_8bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_8bitLsb))
0402     {
0403         dataMode = (8UL * 2UL - 1UL) << 8U;
0404     }
0405     else if ((dataFormat == (uint8_t)kFLEXIO_SPI_16bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_16bitLsb))
0406     {
0407         dataMode = (16UL * 2UL - 1UL) << 8U;
0408     }
0409     else if ((dataFormat == (uint8_t)kFLEXIO_SPI_32bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_32bitLsb))
0410     {
0411         dataMode = (32UL * 2UL - 1UL) << 8U;
0412     }
0413     else
0414     {
0415         dataMode = (8UL * 2UL - 1UL) << 8U;
0416     }
0417 
0418     dataMode |= timerCmp;
0419 
0420     base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
0421 
0422     return FLEXIO_SPI_EDMAConfig(base, handle, xfer);
0423 }
0424 
0425 /*!
0426  * brief Gets the remaining bytes for FlexIO SPI eDMA transfer.
0427  *
0428  * param base Pointer to FLEXIO_SPI_Type structure.
0429  * param handle FlexIO SPI eDMA handle pointer.
0430  * param count Number of bytes transferred so far by the non-blocking transaction.
0431  */
0432 status_t FLEXIO_SPI_MasterTransferGetCountEDMA(FLEXIO_SPI_Type *base,
0433                                                flexio_spi_master_edma_handle_t *handle,
0434                                                size_t *count)
0435 {
0436     assert(handle != NULL);
0437 
0438     if (NULL == count)
0439     {
0440         return kStatus_InvalidArgument;
0441     }
0442 
0443     if (handle->rxInProgress)
0444     {
0445         *count =
0446             (handle->transferSize - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(
0447                                                                    handle->rxHandle->base, handle->rxHandle->channel));
0448     }
0449     else
0450     {
0451         *count =
0452             (handle->transferSize - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(
0453                                                                    handle->txHandle->base, handle->txHandle->channel));
0454     }
0455 
0456     return kStatus_Success;
0457 }
0458 
0459 /*!
0460  * brief Aborts a FlexIO SPI transfer using eDMA.
0461  *
0462  * param base Pointer to FLEXIO_SPI_Type structure.
0463  * param handle FlexIO SPI eDMA handle pointer.
0464  */
0465 void FLEXIO_SPI_MasterTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_master_edma_handle_t *handle)
0466 {
0467     assert(handle != NULL);
0468 
0469     /* Disable dma. */
0470     EDMA_AbortTransfer(handle->txHandle);
0471     EDMA_AbortTransfer(handle->rxHandle);
0472 
0473     /* Disable DMA enable bit. */
0474     FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_DmaAllEnable, false);
0475 
0476     /* Set the handle state. */
0477     handle->txInProgress = false;
0478     handle->rxInProgress = false;
0479 }
0480 
0481 /*!
0482  * brief Performs a non-blocking FlexIO SPI transfer using eDMA.
0483  *
0484  * note This interface returns immediately after transfer initiates. Call
0485  * FLEXIO_SPI_SlaveGetTransferCountEDMA to poll the transfer status and
0486  * check whether the FlexIO SPI transfer is finished.
0487  *
0488  * param base Pointer to FLEXIO_SPI_Type structure.
0489  * param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state.
0490  * param xfer Pointer to FlexIO SPI transfer structure.
0491  * retval kStatus_Success Successfully start a transfer.
0492  * retval kStatus_InvalidArgument Input argument is invalid.
0493  * retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer.
0494  */
0495 status_t FLEXIO_SPI_SlaveTransferEDMA(FLEXIO_SPI_Type *base,
0496                                       flexio_spi_slave_edma_handle_t *handle,
0497                                       flexio_spi_transfer_t *xfer)
0498 {
0499     assert(handle != NULL);
0500     assert(xfer != NULL);
0501 
0502     uint32_t dataMode  = 0U;
0503     uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
0504 
0505     /* Check if the device is busy. */
0506     if ((handle->txInProgress) || (handle->rxInProgress))
0507     {
0508         return kStatus_FLEXIO_SPI_Busy;
0509     }
0510 
0511     /* SCK timer use CS pin as inverted trigger so timer should be disbaled on trigger falling edge(CS re-asserts). */
0512     /* However if CPHA is first edge mode, timer will restart each time right after timer compare event occur and
0513        before CS pin re-asserts, which triggers another shifter load. To avoid this, when in CS dis-continuous mode,
0514        timer should disable in timer compare rather than trigger falling edge(CS re-asserts), and in CS continuous mode,
0515        tx/rx shifters should be flushed after transfer finishes and before next transfer starts. */
0516     FLEXIO_SPI_FlushShifters(base);
0517     if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
0518     {
0519         base->flexioBase->TIMCFG[base->timerIndex[0]] |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
0520     }
0521     else
0522     {
0523         if ((base->flexioBase->SHIFTCTL[base->shifterIndex[0]] & FLEXIO_SHIFTCTL_TIMPOL_MASK) ==
0524             FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnNegitive))
0525         {
0526             base->flexioBase->TIMCFG[base->timerIndex[0]] =
0527                 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
0528                 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
0529         }
0530         else
0531         {
0532             base->flexioBase->TIMCFG[base->timerIndex[0]] =
0533                 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
0534                 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
0535         }
0536     }
0537 
0538     /* Check if input parameter invalid. */
0539     if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
0540     {
0541         return kStatus_InvalidArgument;
0542     }
0543 
0544     /* configure data mode. */
0545     if ((dataFormat == (uint8_t)kFLEXIO_SPI_8bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_8bitLsb))
0546     {
0547         dataMode = 8U * 2U - 1U;
0548     }
0549     else if ((dataFormat == (uint8_t)kFLEXIO_SPI_16bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_16bitLsb))
0550     {
0551         dataMode = 16U * 2U - 1U;
0552     }
0553     else if ((dataFormat == (uint8_t)kFLEXIO_SPI_32bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_32bitLsb))
0554     {
0555         dataMode = 32UL * 2UL - 1UL;
0556     }
0557     else
0558     {
0559         dataMode = 8U * 2U - 1U;
0560     }
0561 
0562     base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
0563 
0564     return FLEXIO_SPI_EDMAConfig(base, handle, xfer);
0565 }