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.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"
0018 #endif
0019 
0020 /*! @brief FLEXIO SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */
0021 enum _flexio_spi_transfer_states
0022 {
0023     kFLEXIO_SPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver's queue. */
0024     kFLEXIO_SPI_Busy,        /*!< Transmiter/Receive's queue is not finished. */
0025 };
0026 
0027 /*******************************************************************************
0028  * Prototypes
0029  ******************************************************************************/
0030 
0031 /*!
0032  * @brief Send a piece of data for SPI.
0033  *
0034  * This function computes the number of data to be written into D register or Tx FIFO,
0035  * and write the data into it. At the same time, this function updates the values in
0036  * master handle structure.
0037  *
0038  * @param base pointer to FLEXIO_SPI_Type structure
0039  * @param handle Pointer to SPI master handle structure.
0040  */
0041 static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
0042 
0043 /*!
0044  * @brief Receive a piece of data for SPI master.
0045  *
0046  * This function computes the number of data to receive from D register or Rx FIFO,
0047  * and write the data to destination address. At the same time, this function updates
0048  * the values in master handle structure.
0049  *
0050  * @param base pointer to FLEXIO_SPI_Type structure
0051  * @param handle Pointer to SPI master handle structure.
0052  */
0053 static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
0054 
0055 /*******************************************************************************
0056  * Variables
0057  ******************************************************************************/
0058 
0059 /*******************************************************************************
0060  * Codes
0061  ******************************************************************************/
0062 
0063 static uint32_t FLEXIO_SPI_GetInstance(FLEXIO_SPI_Type *base)
0064 {
0065     return FLEXIO_GetInstance(base->flexioBase);
0066 }
0067 
0068 static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
0069 {
0070     uint32_t tmpData = FLEXIO_SPI_DUMMYDATA;
0071 
0072     if (handle->txData != NULL)
0073     {
0074         /* Transmit data and update tx size/buff. */
0075         if (handle->bytePerFrame == 1U)
0076         {
0077             tmpData = (uint32_t) * (handle->txData);
0078             handle->txData++;
0079         }
0080         else if (handle->bytePerFrame == 2U)
0081         {
0082             if (handle->direction == kFLEXIO_SPI_MsbFirst)
0083             {
0084                 tmpData = (uint32_t)(handle->txData[0]) << 8U;
0085                 tmpData += (uint32_t)handle->txData[1];
0086             }
0087             else
0088             {
0089                 tmpData = (uint32_t)(handle->txData[1]) << 8U;
0090                 tmpData += (uint32_t)handle->txData[0];
0091             }
0092             handle->txData += 2U;
0093         }
0094         else
0095         {
0096             if (handle->direction == kFLEXIO_SPI_MsbFirst)
0097             {
0098                 tmpData = (uint32_t)(handle->txData[0]) << 24U;
0099                 tmpData += (uint32_t)(handle->txData[1]) << 16U;
0100                 tmpData += (uint32_t)(handle->txData[2]) << 8U;
0101                 tmpData += (uint32_t)handle->txData[3];
0102             }
0103             else
0104             {
0105                 tmpData = (uint32_t)(handle->txData[3]) << 24U;
0106                 tmpData += (uint32_t)(handle->txData[2]) << 16U;
0107                 tmpData += (uint32_t)(handle->txData[1]) << 8U;
0108                 tmpData += (uint32_t)handle->txData[0];
0109             }
0110             handle->txData += 4U;
0111         }
0112     }
0113     else
0114     {
0115         tmpData = FLEXIO_SPI_DUMMYDATA;
0116     }
0117 
0118     handle->txRemainingBytes -= handle->bytePerFrame;
0119 
0120     FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
0121 
0122     if (0U == handle->txRemainingBytes)
0123     {
0124         FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
0125     }
0126 }
0127 
0128 static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
0129 {
0130     uint32_t tmpData;
0131 
0132     tmpData = FLEXIO_SPI_ReadData(base, handle->direction);
0133 
0134     if (handle->rxData != NULL)
0135     {
0136         if (handle->bytePerFrame == 1U)
0137         {
0138             *handle->rxData = (uint8_t)tmpData;
0139         }
0140         else if (handle->bytePerFrame == 2U)
0141         {
0142             if (handle->direction == kFLEXIO_SPI_LsbFirst)
0143             {
0144                 *handle->rxData = (uint8_t)(tmpData >> 8);
0145                 handle->rxData++;
0146                 *handle->rxData = (uint8_t)tmpData;
0147             }
0148             else
0149             {
0150                 *handle->rxData = (uint8_t)tmpData;
0151                 handle->rxData++;
0152                 *handle->rxData = (uint8_t)(tmpData >> 8);
0153             }
0154         }
0155         else
0156         {
0157             if (handle->direction == kFLEXIO_SPI_LsbFirst)
0158             {
0159                 *handle->rxData = (uint8_t)(tmpData >> 24U);
0160                 handle->rxData++;
0161                 *handle->rxData = (uint8_t)(tmpData >> 16U);
0162                 handle->rxData++;
0163                 *handle->rxData = (uint8_t)(tmpData >> 8U);
0164                 handle->rxData++;
0165                 *handle->rxData = (uint8_t)tmpData;
0166             }
0167             else
0168             {
0169                 *handle->rxData = (uint8_t)tmpData;
0170                 handle->rxData++;
0171                 *handle->rxData = (uint8_t)(tmpData >> 8U);
0172                 handle->rxData++;
0173                 *handle->rxData = (uint8_t)(tmpData >> 16U);
0174                 handle->rxData++;
0175                 *handle->rxData = (uint8_t)(tmpData >> 24U);
0176             }
0177         }
0178         handle->rxData++;
0179     }
0180     handle->rxRemainingBytes -= handle->bytePerFrame;
0181 }
0182 
0183 /*!
0184  * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI master hardware,
0185  * and configures the FlexIO SPI with FlexIO SPI master configuration. The
0186  * configuration structure can be filled by the user, or be set with default values
0187  * by the FLEXIO_SPI_MasterGetDefaultConfig().
0188  *
0189  * note 1.FlexIO SPI master only support CPOL = 0, which means clock inactive low.
0190  *      2.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time
0191  *        is 2.5 clock cycles. So if FlexIO SPI master communicates with other spi IPs, the maximum baud
0192  *        rate is FlexIO clock frequency divided by 2*2=4. If FlexIO SPI master communicates with FlexIO
0193  *        SPI slave, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8.
0194  *
0195  * Example
0196    code
0197    FLEXIO_SPI_Type spiDev = {
0198    .flexioBase = FLEXIO,
0199    .SDOPinIndex = 0,
0200    .SDIPinIndex = 1,
0201    .SCKPinIndex = 2,
0202    .CSnPinIndex = 3,
0203    .shifterIndex = {0,1},
0204    .timerIndex = {0,1}
0205    };
0206    flexio_spi_master_config_t config = {
0207    .enableMaster = true,
0208    .enableInDoze = false,
0209    .enableInDebug = true,
0210    .enableFastAccess = false,
0211    .baudRate_Bps = 500000,
0212    .phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
0213    .direction = kFLEXIO_SPI_MsbFirst,
0214    .dataMode = kFLEXIO_SPI_8BitMode
0215    };
0216    FLEXIO_SPI_MasterInit(&spiDev, &config, srcClock_Hz);
0217    endcode
0218  *
0219  * param base Pointer to the FLEXIO_SPI_Type structure.
0220  * param masterConfig Pointer to the flexio_spi_master_config_t structure.
0221  * param srcClock_Hz FlexIO source clock in Hz.
0222 */
0223 void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz)
0224 {
0225     assert(base != NULL);
0226     assert(masterConfig != NULL);
0227 
0228     flexio_shifter_config_t shifterConfig;
0229     flexio_timer_config_t timerConfig;
0230     uint32_t ctrlReg  = 0;
0231     uint16_t timerDiv = 0;
0232     uint16_t timerCmp = 0;
0233 
0234     /* Clear the shifterConfig & timerConfig struct. */
0235     (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
0236     (void)memset(&timerConfig, 0, sizeof(timerConfig));
0237 
0238 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0239     /* Ungate flexio clock. */
0240     CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]);
0241 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0242 
0243     /* Configure FLEXIO SPI Master */
0244     ctrlReg = base->flexioBase->CTRL;
0245     ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
0246     ctrlReg |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
0247                 FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
0248     if (!masterConfig->enableInDoze)
0249     {
0250         ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
0251     }
0252 
0253     base->flexioBase->CTRL = ctrlReg;
0254 
0255     /* Do hardware configuration. */
0256     /* 1. Configure the shifter 0 for tx. */
0257     shifterConfig.timerSelect = base->timerIndex[0];
0258     shifterConfig.pinConfig   = kFLEXIO_PinConfigOutput;
0259     shifterConfig.pinSelect   = base->SDOPinIndex;
0260     shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
0261     shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
0262     shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
0263     if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
0264     {
0265         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
0266         shifterConfig.shifterStop   = kFLEXIO_ShifterStopBitDisable;
0267         shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
0268     }
0269     else
0270     {
0271         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
0272         shifterConfig.shifterStop   = kFLEXIO_ShifterStopBitLow;
0273         shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
0274     }
0275 
0276     FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
0277 
0278     /* 2. Configure the shifter 1 for rx. */
0279     shifterConfig.timerSelect  = base->timerIndex[0];
0280     shifterConfig.pinConfig    = kFLEXIO_PinConfigOutputDisabled;
0281     shifterConfig.pinSelect    = base->SDIPinIndex;
0282     shifterConfig.pinPolarity  = kFLEXIO_PinActiveHigh;
0283     shifterConfig.shifterMode  = kFLEXIO_ShifterModeReceive;
0284     shifterConfig.inputSource  = kFLEXIO_ShifterInputFromPin;
0285     shifterConfig.shifterStop  = kFLEXIO_ShifterStopBitDisable;
0286     shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
0287     if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
0288     {
0289         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
0290     }
0291     else
0292     {
0293         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
0294     }
0295 
0296     FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
0297 
0298     /*3. Configure the timer 0 for SCK. */
0299     timerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
0300     timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
0301     timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
0302     timerConfig.pinConfig       = kFLEXIO_PinConfigOutput;
0303     timerConfig.pinSelect       = base->SCKPinIndex;
0304     timerConfig.pinPolarity     = kFLEXIO_PinActiveHigh;
0305     timerConfig.timerMode       = kFLEXIO_TimerModeDual8BitBaudBit;
0306     timerConfig.timerOutput     = kFLEXIO_TimerOutputZeroNotAffectedByReset;
0307     timerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
0308     timerConfig.timerReset      = kFLEXIO_TimerResetNever;
0309     timerConfig.timerDisable    = kFLEXIO_TimerDisableOnTimerCompare;
0310     timerConfig.timerEnable     = kFLEXIO_TimerEnableOnTriggerHigh;
0311     timerConfig.timerStop       = kFLEXIO_TimerStopBitEnableOnTimerDisable;
0312     timerConfig.timerStart      = kFLEXIO_TimerStartBitEnabled;
0313     /* Low 8-bits are used to configure baudrate. */
0314     timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps);
0315     timerDiv = timerDiv / 2U - 1U;
0316     /* High 8-bits are used to configure shift clock edges(transfer width). */
0317     timerCmp = ((uint16_t)masterConfig->dataMode * 2U - 1U) << 8U;
0318     timerCmp |= timerDiv;
0319 
0320     timerConfig.timerCompare = timerCmp;
0321 
0322     FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
0323 
0324     /* 4. Configure the timer 1 for CSn. */
0325     timerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->timerIndex[0]);
0326     timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
0327     timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
0328     timerConfig.pinConfig       = kFLEXIO_PinConfigOutput;
0329     timerConfig.pinSelect       = base->CSnPinIndex;
0330     timerConfig.pinPolarity     = kFLEXIO_PinActiveLow;
0331     timerConfig.timerMode       = kFLEXIO_TimerModeSingle16Bit;
0332     timerConfig.timerOutput     = kFLEXIO_TimerOutputOneNotAffectedByReset;
0333     timerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
0334     timerConfig.timerReset      = kFLEXIO_TimerResetNever;
0335     timerConfig.timerDisable    = kFLEXIO_TimerDisableOnPreTimerDisable;
0336     timerConfig.timerEnable     = kFLEXIO_TimerEnableOnPrevTimerEnable;
0337     timerConfig.timerStop       = kFLEXIO_TimerStopBitDisabled;
0338     timerConfig.timerStart      = kFLEXIO_TimerStartBitDisabled;
0339 
0340     timerConfig.timerCompare = 0xFFFFU; /* Never compare. */
0341 
0342     FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
0343 }
0344 
0345 /*!
0346  * brief Resets the FlexIO SPI timer and shifter config.
0347  *
0348  * param base Pointer to the FLEXIO_SPI_Type.
0349  */
0350 void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base)
0351 {
0352     base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
0353     base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
0354     base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
0355     base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
0356     base->flexioBase->TIMCFG[base->timerIndex[0]]     = 0;
0357     base->flexioBase->TIMCMP[base->timerIndex[0]]     = 0;
0358     base->flexioBase->TIMCTL[base->timerIndex[0]]     = 0;
0359     base->flexioBase->TIMCFG[base->timerIndex[1]]     = 0;
0360     base->flexioBase->TIMCMP[base->timerIndex[1]]     = 0;
0361     base->flexioBase->TIMCTL[base->timerIndex[1]]     = 0;
0362 }
0363 
0364 /*!
0365  * brief Gets the default configuration to configure the FlexIO SPI master. The configuration
0366  * can be used directly by calling the FLEXIO_SPI_MasterConfigure().
0367  * Example:
0368    code
0369    flexio_spi_master_config_t masterConfig;
0370    FLEXIO_SPI_MasterGetDefaultConfig(&masterConfig);
0371    endcode
0372  * param masterConfig Pointer to the flexio_spi_master_config_t structure.
0373 */
0374 void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig)
0375 {
0376     assert(masterConfig != NULL);
0377 
0378     /* Initializes the configure structure to zero. */
0379     (void)memset(masterConfig, 0, sizeof(*masterConfig));
0380 
0381     masterConfig->enableMaster     = true;
0382     masterConfig->enableInDoze     = false;
0383     masterConfig->enableInDebug    = true;
0384     masterConfig->enableFastAccess = false;
0385     /* Default baud rate 500kbps. */
0386     masterConfig->baudRate_Bps = 500000U;
0387     /* Default CPHA = 0. */
0388     masterConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
0389     /* Default bit count at 8. */
0390     masterConfig->dataMode = kFLEXIO_SPI_8BitMode;
0391 }
0392 
0393 /*!
0394  * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI slave hardware
0395  * configuration, and configures the FlexIO SPI with FlexIO SPI slave configuration. The
0396  * configuration structure can be filled by the user, or be set with default values
0397  * by the FLEXIO_SPI_SlaveGetDefaultConfig().
0398  *
0399  * note 1.Only one timer is needed in the FlexIO SPI slave. As a result, the second timer index is ignored.
0400  *      2.FlexIO SPI slave only support CPOL = 0, which means clock inactive low.
0401  *      3.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time
0402  *        is 2.5 clock cycles. So if FlexIO SPI slave communicates with other spi IPs, the maximum baud
0403  *        rate is FlexIO clock frequency divided by 3*2=6. If FlexIO SPI slave communicates with FlexIO
0404  *        SPI master, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8.
0405  * Example
0406    code
0407    FLEXIO_SPI_Type spiDev = {
0408    .flexioBase = FLEXIO,
0409    .SDOPinIndex = 0,
0410    .SDIPinIndex = 1,
0411    .SCKPinIndex = 2,
0412    .CSnPinIndex = 3,
0413    .shifterIndex = {0,1},
0414    .timerIndex = {0}
0415    };
0416    flexio_spi_slave_config_t config = {
0417    .enableSlave = true,
0418    .enableInDoze = false,
0419    .enableInDebug = true,
0420    .enableFastAccess = false,
0421    .phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
0422    .direction = kFLEXIO_SPI_MsbFirst,
0423    .dataMode = kFLEXIO_SPI_8BitMode
0424    };
0425    FLEXIO_SPI_SlaveInit(&spiDev, &config);
0426    endcode
0427  * param base Pointer to the FLEXIO_SPI_Type structure.
0428  * param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
0429 */
0430 void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig)
0431 {
0432     assert((base != NULL) && (slaveConfig != NULL));
0433 
0434     flexio_shifter_config_t shifterConfig;
0435     flexio_timer_config_t timerConfig;
0436     uint32_t ctrlReg = 0;
0437 
0438     /* Clear the shifterConfig & timerConfig struct. */
0439     (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
0440     (void)memset(&timerConfig, 0, sizeof(timerConfig));
0441 
0442 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0443     /* Ungate flexio clock. */
0444     CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]);
0445 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0446 
0447     /* Configure FLEXIO SPI Slave */
0448     ctrlReg = base->flexioBase->CTRL;
0449     ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
0450     ctrlReg |= (FLEXIO_CTRL_DBGE(slaveConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(slaveConfig->enableFastAccess) |
0451                 FLEXIO_CTRL_FLEXEN(slaveConfig->enableSlave));
0452     if (!slaveConfig->enableInDoze)
0453     {
0454         ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
0455     }
0456 
0457     base->flexioBase->CTRL = ctrlReg;
0458 
0459     /* Do hardware configuration. */
0460     /* 1. Configure the shifter 0 for tx. */
0461     shifterConfig.timerSelect = base->timerIndex[0];
0462     shifterConfig.pinConfig   = kFLEXIO_PinConfigOutput;
0463     shifterConfig.pinSelect   = base->SDOPinIndex;
0464     shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
0465     shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
0466     shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
0467     shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
0468     if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
0469     {
0470         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
0471         shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
0472     }
0473     else
0474     {
0475         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
0476         shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
0477     }
0478 
0479     FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
0480 
0481     /* 2. Configure the shifter 1 for rx. */
0482     shifterConfig.timerSelect  = base->timerIndex[0];
0483     shifterConfig.pinConfig    = kFLEXIO_PinConfigOutputDisabled;
0484     shifterConfig.pinSelect    = base->SDIPinIndex;
0485     shifterConfig.pinPolarity  = kFLEXIO_PinActiveHigh;
0486     shifterConfig.shifterMode  = kFLEXIO_ShifterModeReceive;
0487     shifterConfig.inputSource  = kFLEXIO_ShifterInputFromPin;
0488     shifterConfig.shifterStop  = kFLEXIO_ShifterStopBitDisable;
0489     shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
0490     if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
0491     {
0492         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
0493     }
0494     else
0495     {
0496         shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
0497     }
0498 
0499     FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
0500 
0501     /*3. Configure the timer 0 for shift clock. */
0502     timerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->CSnPinIndex);
0503     timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
0504     timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
0505     timerConfig.pinConfig       = kFLEXIO_PinConfigOutputDisabled;
0506     timerConfig.pinSelect       = base->SCKPinIndex;
0507     timerConfig.pinPolarity     = kFLEXIO_PinActiveHigh;
0508     timerConfig.timerMode       = kFLEXIO_TimerModeSingle16Bit;
0509     timerConfig.timerOutput     = kFLEXIO_TimerOutputZeroNotAffectedByReset;
0510     timerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
0511     timerConfig.timerReset      = kFLEXIO_TimerResetNever;
0512     timerConfig.timerEnable     = kFLEXIO_TimerEnableOnTriggerRisingEdge;
0513     timerConfig.timerStop       = kFLEXIO_TimerStopBitDisabled;
0514     if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
0515     {
0516         timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
0517         timerConfig.timerStart   = kFLEXIO_TimerStartBitDisabled;
0518     }
0519     else
0520     {
0521         timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge;
0522         timerConfig.timerStart   = kFLEXIO_TimerStartBitEnabled;
0523     }
0524 
0525     timerConfig.timerCompare = (uint32_t)slaveConfig->dataMode * 2U - 1U;
0526 
0527     FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
0528 }
0529 
0530 /*!
0531  * brief Gates the FlexIO clock.
0532  *
0533  * param base Pointer to the FLEXIO_SPI_Type.
0534  */
0535 void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base)
0536 {
0537     FLEXIO_SPI_MasterDeinit(base);
0538 }
0539 
0540 /*!
0541  * brief Gets the default configuration to configure the FlexIO SPI slave. The configuration
0542  * can be used directly for calling the FLEXIO_SPI_SlaveConfigure().
0543  * Example:
0544    code
0545    flexio_spi_slave_config_t slaveConfig;
0546    FLEXIO_SPI_SlaveGetDefaultConfig(&slaveConfig);
0547    endcode
0548  * param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
0549 */
0550 void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig)
0551 {
0552     assert(slaveConfig != NULL);
0553 
0554     /* Initializes the configure structure to zero. */
0555     (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
0556 
0557     slaveConfig->enableSlave      = true;
0558     slaveConfig->enableInDoze     = false;
0559     slaveConfig->enableInDebug    = true;
0560     slaveConfig->enableFastAccess = false;
0561     /* Default CPHA = 0. */
0562     slaveConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
0563     /* Default bit count at 8. */
0564     slaveConfig->dataMode = kFLEXIO_SPI_8BitMode;
0565 }
0566 
0567 /*!
0568  * brief Enables the FlexIO SPI interrupt.
0569  *
0570  * This function enables the FlexIO SPI interrupt.
0571  *
0572  * param base Pointer to the FLEXIO_SPI_Type structure.
0573  * param mask interrupt source. The parameter can be any combination of the following values:
0574  *        arg kFLEXIO_SPI_RxFullInterruptEnable
0575  *        arg kFLEXIO_SPI_TxEmptyInterruptEnable
0576  */
0577 void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
0578 {
0579     if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U)
0580     {
0581         FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
0582     }
0583     if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U)
0584     {
0585         FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
0586     }
0587 }
0588 
0589 /*!
0590  * brief Disables the FlexIO SPI interrupt.
0591  *
0592  * This function disables the FlexIO SPI interrupt.
0593  *
0594  * param base Pointer to the FLEXIO_SPI_Type structure.
0595  * param mask interrupt source The parameter can be any combination of the following values:
0596  *        arg kFLEXIO_SPI_RxFullInterruptEnable
0597  *        arg kFLEXIO_SPI_TxEmptyInterruptEnable
0598  */
0599 void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
0600 {
0601     if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U)
0602     {
0603         FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
0604     }
0605     if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U)
0606     {
0607         FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
0608     }
0609 }
0610 
0611 /*!
0612  * brief Enables/disables the FlexIO SPI transmit DMA. This function enables/disables the FlexIO SPI Tx DMA,
0613  * which means that asserting the kFLEXIO_SPI_TxEmptyFlag does/doesn't trigger the DMA request.
0614  *
0615  * param base Pointer to the FLEXIO_SPI_Type structure.
0616  * param mask SPI DMA source.
0617  * param enable True means enable DMA, false means disable DMA.
0618  */
0619 void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable)
0620 {
0621     if ((mask & (uint32_t)kFLEXIO_SPI_TxDmaEnable) != 0U)
0622     {
0623         FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[0], enable);
0624     }
0625 
0626     if ((mask & (uint32_t)kFLEXIO_SPI_RxDmaEnable) != 0U)
0627     {
0628         FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[1], enable);
0629     }
0630 }
0631 
0632 /*!
0633  * brief Gets FlexIO SPI status flags.
0634  *
0635  * param base Pointer to the FLEXIO_SPI_Type structure.
0636  * return status flag; Use the status flag to AND the following flag mask and get the status.
0637  *          arg kFLEXIO_SPI_TxEmptyFlag
0638  *          arg kFLEXIO_SPI_RxEmptyFlag
0639  */
0640 
0641 uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base)
0642 {
0643     uint32_t shifterStatus = FLEXIO_GetShifterStatusFlags(base->flexioBase);
0644     uint32_t status        = 0;
0645 
0646     status = ((shifterStatus & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]);
0647     status |= (((shifterStatus & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) << 1U);
0648 
0649     return status;
0650 }
0651 
0652 /*!
0653  * brief Clears FlexIO SPI status flags.
0654  *
0655  * param base Pointer to the FLEXIO_SPI_Type structure.
0656  * param mask status flag
0657  *      The parameter can be any combination of the following values:
0658  *          arg kFLEXIO_SPI_TxEmptyFlag
0659  *          arg kFLEXIO_SPI_RxEmptyFlag
0660  */
0661 
0662 void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask)
0663 {
0664     if ((mask & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U)
0665     {
0666         FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]);
0667     }
0668     if ((mask & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U)
0669     {
0670         FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
0671     }
0672 }
0673 
0674 /*!
0675  * brief Sets baud rate for the FlexIO SPI transfer, which is only used for the master.
0676  *
0677  * param base Pointer to the FLEXIO_SPI_Type structure.
0678  * param baudRate_Bps Baud Rate needed in Hz.
0679  * param srcClockHz SPI source clock frequency in Hz.
0680  */
0681 void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz)
0682 {
0683     uint16_t timerDiv       = 0;
0684     uint16_t timerCmp       = 0;
0685     FLEXIO_Type *flexioBase = base->flexioBase;
0686 
0687     /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
0688     timerDiv = (uint16_t)(srcClockHz / baudRate_Bps);
0689     timerDiv = timerDiv / 2U - 1U;
0690 
0691     timerCmp = (uint16_t)(flexioBase->TIMCMP[base->timerIndex[0]]);
0692     timerCmp &= 0xFF00U;
0693     timerCmp |= timerDiv;
0694 
0695     flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
0696 }
0697 
0698 /*!
0699  * brief Sends a buffer of data bytes.
0700  *
0701  * note This function blocks using the polling method until all bytes have been sent.
0702  *
0703  * param base Pointer to the FLEXIO_SPI_Type structure.
0704  * param direction Shift direction of MSB first or LSB first.
0705  * param buffer The data bytes to send.
0706  * param size The number of data bytes to send.
0707  * retval kStatus_Success Successfully create the handle.
0708  * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
0709  */
0710 status_t FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base,
0711                                   flexio_spi_shift_direction_t direction,
0712                                   const uint8_t *buffer,
0713                                   size_t size)
0714 {
0715     assert(buffer != NULL);
0716     assert(size != 0U);
0717 
0718 #if SPI_RETRY_TIMES
0719     uint32_t waitTimes;
0720 #endif
0721 
0722     while (0U != size--)
0723     {
0724         /* Wait until data transfer complete. */
0725 #if SPI_RETRY_TIMES
0726         waitTimes = SPI_RETRY_TIMES;
0727         while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) &&
0728                (0U != --waitTimes))
0729 #else
0730         while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag))
0731 #endif
0732         {
0733         }
0734 #if SPI_RETRY_TIMES
0735         if (waitTimes == 0U)
0736         {
0737             return kStatus_FLEXIO_SPI_Timeout;
0738         }
0739 #endif
0740         FLEXIO_SPI_WriteData(base, direction, *buffer++);
0741     }
0742 
0743     return kStatus_Success;
0744 }
0745 
0746 /*!
0747  * brief Receives a buffer of bytes.
0748  *
0749  * note This function blocks using the polling method until all bytes have been received.
0750  *
0751  * param base Pointer to the FLEXIO_SPI_Type structure.
0752  * param direction Shift direction of MSB first or LSB first.
0753  * param buffer The buffer to store the received bytes.
0754  * param size The number of data bytes to be received.
0755  * param direction Shift direction of MSB first or LSB first.
0756  * retval kStatus_Success Successfully create the handle.
0757  * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
0758  */
0759 status_t FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base,
0760                                  flexio_spi_shift_direction_t direction,
0761                                  uint8_t *buffer,
0762                                  size_t size)
0763 {
0764     assert(buffer != NULL);
0765     assert(size != 0U);
0766 
0767 #if SPI_RETRY_TIMES
0768     uint32_t waitTimes;
0769 #endif
0770 
0771     while (0U != size--)
0772     {
0773         /* Wait until data transfer complete. */
0774 #if SPI_RETRY_TIMES
0775         waitTimes = SPI_RETRY_TIMES;
0776         while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) &&
0777                (0U != --waitTimes))
0778 #else
0779         while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag))
0780 #endif
0781         {
0782         }
0783 #if SPI_RETRY_TIMES
0784         if (waitTimes == 0U)
0785         {
0786             return kStatus_FLEXIO_SPI_Timeout;
0787         }
0788 #endif
0789         *buffer++ = (uint8_t)FLEXIO_SPI_ReadData(base, direction);
0790     }
0791 
0792     return kStatus_Success;
0793 }
0794 
0795 /*!
0796  * brief Receives a buffer of bytes.
0797  *
0798  * note This function blocks via polling until all bytes have been received.
0799  *
0800  * param base pointer to FLEXIO_SPI_Type structure
0801  * param xfer FlexIO SPI transfer structure, see #flexio_spi_transfer_t.
0802  * retval kStatus_Success Successfully create the handle.
0803  * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
0804  */
0805 status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer)
0806 {
0807     flexio_spi_shift_direction_t direction;
0808     uint8_t bytesPerFrame;
0809     uint32_t dataMode  = 0;
0810     uint16_t timerCmp  = (uint16_t)(base->flexioBase->TIMCMP[base->timerIndex[0]]);
0811     uint32_t tmpData   = FLEXIO_SPI_DUMMYDATA;
0812     uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
0813 #if SPI_RETRY_TIMES
0814     uint32_t waitTimes;
0815 #endif
0816 
0817     timerCmp &= 0x00FFU;
0818 
0819     if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
0820     {
0821         base->flexioBase->TIMCFG[base->timerIndex[0]] =
0822             (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
0823             FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled);
0824     }
0825     else
0826     {
0827         base->flexioBase->TIMCFG[base->timerIndex[0]] =
0828             (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
0829             FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable);
0830     }
0831 
0832     /* Configure the values in handle. */
0833     switch (dataFormat)
0834     {
0835         case (uint8_t)kFLEXIO_SPI_8bitMsb:
0836             dataMode      = (8UL * 2UL - 1UL) << 8U;
0837             bytesPerFrame = 1U;
0838             direction     = kFLEXIO_SPI_MsbFirst;
0839             break;
0840 
0841         case (uint8_t)kFLEXIO_SPI_8bitLsb:
0842             dataMode      = (8UL * 2UL - 1UL) << 8U;
0843             bytesPerFrame = 1U;
0844             direction     = kFLEXIO_SPI_LsbFirst;
0845             break;
0846 
0847         case (uint8_t)kFLEXIO_SPI_16bitMsb:
0848             dataMode      = (16UL * 2UL - 1UL) << 8U;
0849             bytesPerFrame = 2U;
0850             direction     = kFLEXIO_SPI_MsbFirst;
0851             break;
0852 
0853         case (uint8_t)kFLEXIO_SPI_16bitLsb:
0854             dataMode      = (16UL * 2UL - 1UL) << 8U;
0855             bytesPerFrame = 2U;
0856             direction     = kFLEXIO_SPI_LsbFirst;
0857             break;
0858 
0859         case (uint8_t)kFLEXIO_SPI_32bitMsb:
0860             dataMode      = (32UL * 2UL - 1UL) << 8U;
0861             bytesPerFrame = 4U;
0862             direction     = kFLEXIO_SPI_MsbFirst;
0863             break;
0864 
0865         case (uint8_t)kFLEXIO_SPI_32bitLsb:
0866             dataMode      = (32UL * 2UL - 1UL) << 8U;
0867             bytesPerFrame = 4U;
0868             direction     = kFLEXIO_SPI_LsbFirst;
0869             break;
0870 
0871         default:
0872             dataMode      = (8UL * 2UL - 1UL) << 8U;
0873             bytesPerFrame = 1U;
0874             direction     = kFLEXIO_SPI_MsbFirst;
0875             assert(true);
0876             break;
0877     }
0878 
0879     dataMode |= timerCmp;
0880 
0881     /* Transfer size should be bytesPerFrame divisible. */
0882     if ((xfer->dataSize % bytesPerFrame) != 0U)
0883     {
0884         return kStatus_InvalidArgument;
0885     }
0886 
0887     /* Configure transfer size. */
0888     base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
0889 
0890     while (xfer->dataSize != 0U)
0891     {
0892         /* Wait until data transfer complete. */
0893 #if SPI_RETRY_TIMES
0894         waitTimes = SPI_RETRY_TIMES;
0895         while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) &&
0896                (0U != --waitTimes))
0897 #else
0898         while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag))
0899 #endif
0900         {
0901         }
0902 #if SPI_RETRY_TIMES
0903         if (waitTimes == 0U)
0904         {
0905             return kStatus_FLEXIO_SPI_Timeout;
0906         }
0907 #endif
0908         if (xfer->txData != NULL)
0909         {
0910             /* Transmit data and update tx size/buff. */
0911             if (bytesPerFrame == 1U)
0912             {
0913                 tmpData = (uint32_t) * (xfer->txData);
0914                 xfer->txData++;
0915             }
0916             else if (bytesPerFrame == 2U)
0917             {
0918                 if (direction == kFLEXIO_SPI_MsbFirst)
0919                 {
0920                     tmpData = (uint32_t)(xfer->txData[0]) << 8U;
0921                     tmpData += (uint32_t)xfer->txData[1];
0922                 }
0923                 else
0924                 {
0925                     tmpData = (uint32_t)(xfer->txData[1]) << 8U;
0926                     tmpData += (uint32_t)xfer->txData[0];
0927                 }
0928                 xfer->txData += 2U;
0929             }
0930             else
0931             {
0932                 if (direction == kFLEXIO_SPI_MsbFirst)
0933                 {
0934                     tmpData = (uint32_t)(xfer->txData[0]) << 24U;
0935                     tmpData += (uint32_t)(xfer->txData[1]) << 16U;
0936                     tmpData += (uint32_t)(xfer->txData[2]) << 8U;
0937                     tmpData += (uint32_t)xfer->txData[3];
0938                 }
0939                 else
0940                 {
0941                     tmpData = (uint32_t)(xfer->txData[3]) << 24U;
0942                     tmpData += (uint32_t)(xfer->txData[2]) << 16U;
0943                     tmpData += (uint32_t)(xfer->txData[1]) << 8U;
0944                     tmpData += (uint32_t)xfer->txData[0];
0945                 }
0946                 xfer->txData += 4U;
0947             }
0948         }
0949         else
0950         {
0951             tmpData = FLEXIO_SPI_DUMMYDATA;
0952         }
0953 
0954         xfer->dataSize -= bytesPerFrame;
0955 
0956         FLEXIO_SPI_WriteData(base, direction, tmpData);
0957 
0958 #if SPI_RETRY_TIMES
0959         waitTimes = SPI_RETRY_TIMES;
0960         while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) &&
0961                (0U != --waitTimes))
0962 #else
0963         while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag))
0964 #endif
0965         {
0966         }
0967 #if SPI_RETRY_TIMES
0968         if (waitTimes == 0U)
0969         {
0970             return kStatus_FLEXIO_SPI_Timeout;
0971         }
0972 #endif
0973         tmpData = FLEXIO_SPI_ReadData(base, direction);
0974 
0975         if (xfer->rxData != NULL)
0976         {
0977             if (bytesPerFrame == 1U)
0978             {
0979                 *xfer->rxData = (uint8_t)tmpData;
0980             }
0981             else if (bytesPerFrame == 2U)
0982             {
0983                 if (direction == kFLEXIO_SPI_LsbFirst)
0984                 {
0985                     *xfer->rxData = (uint8_t)(tmpData >> 8);
0986                     xfer->rxData++;
0987                     *xfer->rxData = (uint8_t)tmpData;
0988                 }
0989                 else
0990                 {
0991                     *xfer->rxData = (uint8_t)tmpData;
0992                     xfer->rxData++;
0993                     *xfer->rxData = (uint8_t)(tmpData >> 8);
0994                 }
0995             }
0996             else
0997             {
0998                 if (direction == kFLEXIO_SPI_LsbFirst)
0999                 {
1000                     *xfer->rxData = (uint8_t)(tmpData >> 24U);
1001                     xfer->rxData++;
1002                     *xfer->rxData = (uint8_t)(tmpData >> 16U);
1003                     xfer->rxData++;
1004                     *xfer->rxData = (uint8_t)(tmpData >> 8U);
1005                     xfer->rxData++;
1006                     *xfer->rxData = (uint8_t)tmpData;
1007                 }
1008                 else
1009                 {
1010                     *xfer->rxData = (uint8_t)tmpData;
1011                     xfer->rxData++;
1012                     *xfer->rxData = (uint8_t)(tmpData >> 8U);
1013                     xfer->rxData++;
1014                     *xfer->rxData = (uint8_t)(tmpData >> 16U);
1015                     xfer->rxData++;
1016                     *xfer->rxData = (uint8_t)(tmpData >> 24U);
1017                 }
1018             }
1019             xfer->rxData++;
1020         }
1021     }
1022 
1023     return kStatus_Success;
1024 }
1025 
1026 /*!
1027  * brief Initializes the FlexIO SPI Master handle, which is used in transactional functions.
1028  *
1029  * param base Pointer to the FLEXIO_SPI_Type structure.
1030  * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1031  * param callback The callback function.
1032  * param userData The parameter of the callback function.
1033  * retval kStatus_Success Successfully create the handle.
1034  * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
1035  */
1036 status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base,
1037                                                flexio_spi_master_handle_t *handle,
1038                                                flexio_spi_master_transfer_callback_t callback,
1039                                                void *userData)
1040 {
1041     assert(handle != NULL);
1042 
1043     IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
1044 
1045     /* Zero the handle. */
1046     (void)memset(handle, 0, sizeof(*handle));
1047 
1048     /* Register callback and userData. */
1049     handle->callback = callback;
1050     handle->userData = userData;
1051 
1052     /* Clear pending NVIC IRQ before enable NVIC IRQ. */
1053     NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1054     /* Enable interrupt in NVIC. */
1055     (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1056 
1057     /* Save the context in global variables to support the double weak mechanism. */
1058     return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_MasterTransferHandleIRQ);
1059 }
1060 
1061 /*!
1062  * brief Master transfer data using IRQ.
1063  *
1064  * This function sends data using IRQ. This is a non-blocking function, which returns
1065  * right away. When all data is sent out/received, the callback function is called.
1066  *
1067  * param base Pointer to the FLEXIO_SPI_Type structure.
1068  * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1069  * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
1070  * retval kStatus_Success Successfully start a transfer.
1071  * retval kStatus_InvalidArgument Input argument is invalid.
1072  * retval kStatus_FLEXIO_SPI_Busy SPI is not idle, is running another transfer.
1073  */
1074 status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base,
1075                                               flexio_spi_master_handle_t *handle,
1076                                               flexio_spi_transfer_t *xfer)
1077 {
1078     assert(handle != NULL);
1079     assert(xfer != NULL);
1080 
1081     uint32_t dataMode  = 0;
1082     uint16_t timerCmp  = (uint16_t)base->flexioBase->TIMCMP[base->timerIndex[0]];
1083     uint32_t tmpData   = FLEXIO_SPI_DUMMYDATA;
1084     uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
1085 
1086     timerCmp &= 0x00FFU;
1087 
1088     /* Check if SPI is busy. */
1089     if (handle->state == (uint32_t)kFLEXIO_SPI_Busy)
1090     {
1091         return kStatus_FLEXIO_SPI_Busy;
1092     }
1093 
1094     /* Check if the argument is legal. */
1095     if ((xfer->txData == NULL) && (xfer->rxData == NULL))
1096     {
1097         return kStatus_InvalidArgument;
1098     }
1099 
1100     /* Timer1 controls the CS signal which enables/disables(asserts/deasserts) when timer0 enable/disable. Timer0
1101        enables when tx shifter is written and disables when timer compare. The timer compare event causes the
1102        transmit shift registers to load which generates a tx register empty event. Since when timer stop bit is
1103        disabled, a timer enable condition can be detected in the same cycle as a timer disable condition, so if
1104        software writes the tx register upon the detection of tx register empty event, the timer enable condition
1105        is triggered again, then the CS signal can remain low until software no longer writes the tx register. */
1106     if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
1107     {
1108         base->flexioBase->TIMCFG[base->timerIndex[0]] =
1109             (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
1110             FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled);
1111     }
1112     else
1113     {
1114         base->flexioBase->TIMCFG[base->timerIndex[0]] =
1115             (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
1116             FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable);
1117     }
1118 
1119     /* Configure the values in handle */
1120     switch (dataFormat)
1121     {
1122         case (uint8_t)kFLEXIO_SPI_8bitMsb:
1123             dataMode             = (8UL * 2UL - 1UL) << 8U;
1124             handle->bytePerFrame = 1U;
1125             handle->direction    = kFLEXIO_SPI_MsbFirst;
1126             break;
1127         case (uint8_t)kFLEXIO_SPI_8bitLsb:
1128             dataMode             = (8UL * 2UL - 1UL) << 8U;
1129             handle->bytePerFrame = 1U;
1130             handle->direction    = kFLEXIO_SPI_LsbFirst;
1131             break;
1132         case (uint8_t)kFLEXIO_SPI_16bitMsb:
1133             dataMode             = (16UL * 2UL - 1UL) << 8U;
1134             handle->bytePerFrame = 2U;
1135             handle->direction    = kFLEXIO_SPI_MsbFirst;
1136             break;
1137         case (uint8_t)kFLEXIO_SPI_16bitLsb:
1138             dataMode             = (16UL * 2UL - 1UL) << 8U;
1139             handle->bytePerFrame = 2U;
1140             handle->direction    = kFLEXIO_SPI_LsbFirst;
1141             break;
1142         case (uint8_t)kFLEXIO_SPI_32bitMsb:
1143             dataMode             = (32UL * 2UL - 1UL) << 8U;
1144             handle->bytePerFrame = 4U;
1145             handle->direction    = kFLEXIO_SPI_MsbFirst;
1146             break;
1147         case (uint8_t)kFLEXIO_SPI_32bitLsb:
1148             dataMode             = (32UL * 2UL - 1UL) << 8U;
1149             handle->bytePerFrame = 4U;
1150             handle->direction    = kFLEXIO_SPI_LsbFirst;
1151             break;
1152         default:
1153             dataMode             = (8UL * 2UL - 1UL) << 8U;
1154             handle->bytePerFrame = 1U;
1155             handle->direction    = kFLEXIO_SPI_MsbFirst;
1156             assert(true);
1157             break;
1158     }
1159 
1160     dataMode |= timerCmp;
1161 
1162     /* Transfer size should be bytesPerFrame divisible. */
1163     if ((xfer->dataSize % handle->bytePerFrame) != 0U)
1164     {
1165         return kStatus_InvalidArgument;
1166     }
1167 
1168     /* Configure transfer size. */
1169     base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
1170 
1171     handle->state            = (uint32_t)kFLEXIO_SPI_Busy;
1172     handle->txData           = xfer->txData;
1173     handle->rxData           = xfer->rxData;
1174     handle->rxRemainingBytes = xfer->dataSize;
1175 
1176     /* Save total transfer size. */
1177     handle->transferSize = xfer->dataSize;
1178 
1179     /* Send first byte of data to trigger the rx interrupt. */
1180     if (handle->txData != NULL)
1181     {
1182         /* Transmit data and update tx size/buff. */
1183         if (handle->bytePerFrame == 1U)
1184         {
1185             tmpData = (uint32_t) * (handle->txData);
1186             handle->txData++;
1187         }
1188         else if (handle->bytePerFrame == 2U)
1189         {
1190             if (handle->direction == kFLEXIO_SPI_MsbFirst)
1191             {
1192                 tmpData = (uint32_t)(handle->txData[0]) << 8U;
1193                 tmpData += (uint32_t)handle->txData[1];
1194             }
1195             else
1196             {
1197                 tmpData = (uint32_t)(handle->txData[1]) << 8U;
1198                 tmpData += (uint32_t)handle->txData[0];
1199             }
1200             handle->txData += 2U;
1201         }
1202         else
1203         {
1204             if (handle->direction == kFLEXIO_SPI_MsbFirst)
1205             {
1206                 tmpData = (uint32_t)(handle->txData[0]) << 24U;
1207                 tmpData += (uint32_t)(handle->txData[1]) << 16U;
1208                 tmpData += (uint32_t)(handle->txData[2]) << 8U;
1209                 tmpData += (uint32_t)handle->txData[3];
1210             }
1211             else
1212             {
1213                 tmpData = (uint32_t)(handle->txData[3]) << 24U;
1214                 tmpData += (uint32_t)(handle->txData[2]) << 16U;
1215                 tmpData += (uint32_t)(handle->txData[1]) << 8U;
1216                 tmpData += (uint32_t)handle->txData[0];
1217             }
1218             handle->txData += 4U;
1219         }
1220     }
1221     else
1222     {
1223         tmpData = FLEXIO_SPI_DUMMYDATA;
1224     }
1225 
1226     handle->txRemainingBytes = xfer->dataSize - handle->bytePerFrame;
1227 
1228     FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
1229 
1230     /* Enable transmit and receive interrupt to handle rx. */
1231     FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
1232 
1233     return kStatus_Success;
1234 }
1235 
1236 /*!
1237  * brief Gets the data transfer status which used IRQ.
1238  *
1239  * param base Pointer to the FLEXIO_SPI_Type structure.
1240  * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1241  * param count Number of bytes transferred so far by the non-blocking transaction.
1242  * retval kStatus_InvalidArgument count is Invalid.
1243  * retval kStatus_Success Successfully return the count.
1244  */
1245 status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count)
1246 {
1247     assert(handle != NULL);
1248 
1249     if (NULL == count)
1250     {
1251         return kStatus_InvalidArgument;
1252     }
1253 
1254     /* Return remaing bytes in different cases. */
1255     if (handle->rxData != NULL)
1256     {
1257         *count = handle->transferSize - handle->rxRemainingBytes;
1258     }
1259     else
1260     {
1261         *count = handle->transferSize - handle->txRemainingBytes;
1262     }
1263 
1264     return kStatus_Success;
1265 }
1266 
1267 /*!
1268  * brief Aborts the master data transfer, which used IRQ.
1269  *
1270  * param base Pointer to the FLEXIO_SPI_Type structure.
1271  * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1272  */
1273 void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
1274 {
1275     assert(handle != NULL);
1276 
1277     FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
1278     FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
1279 
1280     /* Transfer finished, set the state to idle. */
1281     handle->state = (uint32_t)kFLEXIO_SPI_Idle;
1282 
1283     /* Clear the internal state. */
1284     handle->rxRemainingBytes = 0;
1285     handle->txRemainingBytes = 0;
1286 }
1287 
1288 /*!
1289  * brief FlexIO SPI master IRQ handler function.
1290  *
1291  * param spiType Pointer to the FLEXIO_SPI_Type structure.
1292  * param spiHandle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1293  */
1294 void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle)
1295 {
1296     assert(spiHandle != NULL);
1297 
1298     flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
1299     FLEXIO_SPI_Type *base;
1300     uint32_t status;
1301 
1302     if (handle->state == (uint32_t)kFLEXIO_SPI_Idle)
1303     {
1304         return;
1305     }
1306 
1307     base   = (FLEXIO_SPI_Type *)spiType;
1308     status = FLEXIO_SPI_GetStatusFlags(base);
1309 
1310     /* Handle rx. */
1311     if (((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) && (handle->rxRemainingBytes != 0U))
1312     {
1313         FLEXIO_SPI_TransferReceiveTransaction(base, handle);
1314     }
1315 
1316     /* Handle tx. */
1317     if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U))
1318     {
1319         FLEXIO_SPI_TransferSendTransaction(base, handle);
1320     }
1321 
1322     /* All the transfer finished. */
1323     if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
1324     {
1325         FLEXIO_SPI_MasterTransferAbort(base, handle);
1326         if (handle->callback != NULL)
1327         {
1328             (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
1329         }
1330     }
1331 }
1332 
1333 /*!
1334  * brief Initializes the FlexIO SPI Slave handle, which is used in transactional functions.
1335  *
1336  * param base Pointer to the FLEXIO_SPI_Type structure.
1337  * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
1338  * param callback The callback function.
1339  * param userData The parameter of the callback function.
1340  * retval kStatus_Success Successfully create the handle.
1341  * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
1342  */
1343 status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base,
1344                                               flexio_spi_slave_handle_t *handle,
1345                                               flexio_spi_slave_transfer_callback_t callback,
1346                                               void *userData)
1347 {
1348     assert(handle != NULL);
1349 
1350     IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
1351 
1352     /* Zero the handle. */
1353     (void)memset(handle, 0, sizeof(*handle));
1354 
1355     /* Register callback and userData. */
1356     handle->callback = callback;
1357     handle->userData = userData;
1358 
1359     /* Clear pending NVIC IRQ before enable NVIC IRQ. */
1360     NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1361     /* Enable interrupt in NVIC. */
1362     (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1363 
1364     /* Save the context in global variables to support the double weak mechanism. */
1365     return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_SlaveTransferHandleIRQ);
1366 }
1367 
1368 /*!
1369  * brief Slave transfer data using IRQ.
1370  *
1371  * This function sends data using IRQ. This is a non-blocking function, which returns
1372  * right away. When all data is sent out/received, the callback function is called.
1373  * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
1374  *
1375  * param base Pointer to the FLEXIO_SPI_Type structure.
1376  * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
1377  * retval kStatus_Success Successfully start a transfer.
1378  * retval kStatus_InvalidArgument Input argument is invalid.
1379  * retval kStatus_FLEXIO_SPI_Busy SPI is not idle; it is running another transfer.
1380  */
1381 status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base,
1382                                              flexio_spi_slave_handle_t *handle,
1383                                              flexio_spi_transfer_t *xfer)
1384 {
1385     assert(handle != NULL);
1386     assert(xfer != NULL);
1387 
1388     uint32_t dataMode  = 0;
1389     uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
1390 
1391     /* Check if SPI is busy. */
1392     if (handle->state == (uint32_t)kFLEXIO_SPI_Busy)
1393     {
1394         return kStatus_FLEXIO_SPI_Busy;
1395     }
1396 
1397     /* Check if the argument is legal. */
1398     if ((xfer->txData == NULL) && (xfer->rxData == NULL))
1399     {
1400         return kStatus_InvalidArgument;
1401     }
1402 
1403     /* SCK timer use CS pin as inverted trigger so timer should be disbaled on trigger falling edge(CS re-asserts). */
1404     /* However if CPHA is first edge mode, timer will restart each time right after timer compare event occur and
1405        before CS pin re-asserts, which triggers another shifter load. To avoid this, when in CS dis-continuous mode,
1406        timer should disable in timer compare rather than trigger falling edge(CS re-asserts), and in CS continuous mode,
1407        tx/rx shifters should be flushed after transfer finishes and before next transfer starts. */
1408     FLEXIO_SPI_FlushShifters(base);
1409     if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
1410     {
1411         base->flexioBase->TIMCFG[base->timerIndex[0]] |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
1412     }
1413     else
1414     {
1415         if ((base->flexioBase->SHIFTCTL[base->shifterIndex[0]] & FLEXIO_SHIFTCTL_TIMPOL_MASK) ==
1416             FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnNegitive))
1417         {
1418             base->flexioBase->TIMCFG[base->timerIndex[0]] =
1419                 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
1420                 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
1421         }
1422         else
1423         {
1424             base->flexioBase->TIMCFG[base->timerIndex[0]] =
1425                 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
1426                 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
1427         }
1428     }
1429 
1430     /* Configure the values in handle */
1431     switch (dataFormat)
1432     {
1433         case (uint8_t)kFLEXIO_SPI_8bitMsb:
1434             dataMode             = 8U * 2U - 1U;
1435             handle->bytePerFrame = 1U;
1436             handle->direction    = kFLEXIO_SPI_MsbFirst;
1437             break;
1438         case (uint8_t)kFLEXIO_SPI_8bitLsb:
1439             dataMode             = 8U * 2U - 1U;
1440             handle->bytePerFrame = 1U;
1441             handle->direction    = kFLEXIO_SPI_LsbFirst;
1442             break;
1443         case (uint8_t)kFLEXIO_SPI_16bitMsb:
1444             dataMode             = 16U * 2U - 1U;
1445             handle->bytePerFrame = 2U;
1446             handle->direction    = kFLEXIO_SPI_MsbFirst;
1447             break;
1448         case (uint8_t)kFLEXIO_SPI_16bitLsb:
1449             dataMode             = 16U * 2U - 1U;
1450             handle->bytePerFrame = 2U;
1451             handle->direction    = kFLEXIO_SPI_LsbFirst;
1452             break;
1453         case (uint8_t)kFLEXIO_SPI_32bitMsb:
1454             dataMode             = 32UL * 2UL - 1UL;
1455             handle->bytePerFrame = 4U;
1456             handle->direction    = kFLEXIO_SPI_MsbFirst;
1457             break;
1458         case (uint8_t)kFLEXIO_SPI_32bitLsb:
1459             dataMode             = 32UL * 2UL - 1UL;
1460             handle->bytePerFrame = 4U;
1461             handle->direction    = kFLEXIO_SPI_LsbFirst;
1462             break;
1463         default:
1464             dataMode             = 8UL * 2UL - 1UL;
1465             handle->bytePerFrame = 1U;
1466             handle->direction    = kFLEXIO_SPI_MsbFirst;
1467             assert(true);
1468             break;
1469     }
1470 
1471     /* Transfer size should be bytesPerFrame divisible. */
1472     if ((xfer->dataSize % handle->bytePerFrame) != 0U)
1473     {
1474         return kStatus_InvalidArgument;
1475     }
1476 
1477     /* Configure transfer size. */
1478     base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
1479 
1480     handle->state            = (uint32_t)kFLEXIO_SPI_Busy;
1481     handle->txData           = xfer->txData;
1482     handle->rxData           = xfer->rxData;
1483     handle->txRemainingBytes = xfer->dataSize;
1484     handle->rxRemainingBytes = xfer->dataSize;
1485 
1486     /* Save total transfer size. */
1487     handle->transferSize = xfer->dataSize;
1488 
1489     /* Enable transmit and receive interrupt to handle tx and rx. */
1490     FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
1491     FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
1492 
1493     return kStatus_Success;
1494 }
1495 
1496 /*!
1497  * brief FlexIO SPI slave IRQ handler function.
1498  *
1499  * param spiType Pointer to the FLEXIO_SPI_Type structure.
1500  * param spiHandle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
1501  */
1502 void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle)
1503 {
1504     assert(spiHandle != NULL);
1505 
1506     flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
1507     FLEXIO_SPI_Type *base;
1508     uint32_t status;
1509 
1510     if (handle->state == (uint32_t)kFLEXIO_SPI_Idle)
1511     {
1512         return;
1513     }
1514 
1515     base   = (FLEXIO_SPI_Type *)spiType;
1516     status = FLEXIO_SPI_GetStatusFlags(base);
1517 
1518     /* Handle tx. */
1519     if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U))
1520     {
1521         FLEXIO_SPI_TransferSendTransaction(base, handle);
1522     }
1523 
1524     /* Handle rx. */
1525     if (((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) && (handle->rxRemainingBytes != 0U))
1526     {
1527         FLEXIO_SPI_TransferReceiveTransaction(base, handle);
1528     }
1529 
1530     /* All the transfer finished. */
1531     if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
1532     {
1533         FLEXIO_SPI_SlaveTransferAbort(base, handle);
1534         if (handle->callback != NULL)
1535         {
1536             (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
1537         }
1538     }
1539 }
1540 
1541 /*!
1542  * brief Flush tx/rx shifters.
1543  *
1544  * param base Pointer to the FLEXIO_SPI_Type structure.
1545  */
1546 void FLEXIO_SPI_FlushShifters(FLEXIO_SPI_Type *base)
1547 {
1548     /* Disable then re-enable to flush the tx shifter. */
1549     base->flexioBase->SHIFTCTL[base->shifterIndex[0]] &= ~FLEXIO_SHIFTCTL_SMOD_MASK;
1550     base->flexioBase->SHIFTCTL[base->shifterIndex[0]] |= FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeTransmit);
1551     /* Read to flush the rx shifter. */
1552     (void)base->flexioBase->SHIFTBUF[base->shifterIndex[1]];
1553 }