/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
*   of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
*   list of conditions and the following disclaimer in the documentation and/or
*   other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
*   contributors may be used to endorse or promote products derived from this
*   software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "fsl_dspi.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
/*! @brief Typedef for master interrupt handler. */
typedef void (*dspi_master_isr_t)(SPI_Type *base, dspi_master_handle_t *handle);

/*! @brief Typedef for slave interrupt handler. */
typedef void (*dspi_slave_isr_t)(SPI_Type *base, dspi_slave_handle_t *handle);

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
/*!
 * @brief Get instance number for DSPI module.
 *
 * @param base DSPI peripheral base address.
 */
uint32_t DSPI_GetInstance(SPI_Type *base);

/*!
 * @brief Configures the DSPI peripheral chip select polarity.
 *
 * This function  takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and
 * configures the Pcs signal to operate with the desired characteristic.
 *
 * @param base DSPI peripheral address.
 * @param pcs The particular peripheral chip select (parameter value is of type dspi_which_pcs_t) for which we wish to
 *            apply the active high or active low characteristic.
 * @param activeLowOrHigh The setting for either "active high, inactive low (0)"  or "active low, inactive high(1)" of
 *                        type dspi_pcs_polarity_config_t.
 */
static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh);

/*!
 * @brief Master fill up the TX FIFO with data.
 * This is not a public API as it is called from other driver functions.
 */
static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle);

/*!
 * @brief Master finish up a transfer.
 * It would call back if there is callback function and set the state to idle.
 * This is not a public API as it is called from other driver functions.
 */
static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle);

/*!
 * @brief Slave fill up the TX FIFO with data.
 * This is not a public API as it is called from other driver functions.
 */
static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle);

/*!
 * @brief Slave finish up a transfer.
 * It would call back if there is callback function and set the state to idle.
 * This is not a public API as it is called from other driver functions.
 */
static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle);

/*!
 * @brief DSPI common interrupt handler.
 *
 * @param base DSPI peripheral address.
 * @param handle pointer to g_dspiHandle which stores the transfer state.
 */
static void DSPI_CommonIRQHandler(SPI_Type *base, void *param);

/*!
 * @brief Master prepare the transfer.
 * Basically it set up dspi_master_handle .
 * This is not a public API as it is called from other driver functions. fsl_dspi_edma.c also call this function.
 */
static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer);

/*******************************************************************************
 * Variables
 ******************************************************************************/

/* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
static const uint32_t s_baudratePrescaler[] = {2, 3, 5, 7};
static const uint32_t s_baudrateScaler[] = {2,   4,   6,    8,    16,   32,   64,    128,
                                            256, 512, 1024, 2048, 4096, 8192, 16384, 32768};

static const uint32_t s_delayPrescaler[] = {1, 3, 5, 7};
static const uint32_t s_delayScaler[] = {2,   4,    8,    16,   32,   64,    128,   256,
                                         512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};

/*! @brief Pointers to dspi bases for each instance. */
static SPI_Type *const s_dspiBases[] = SPI_BASE_PTRS;

/*! @brief Pointers to dspi IRQ number for each instance. */
static IRQn_Type const s_dspiIRQ[] = SPI_IRQS;

/*! @brief Pointers to dspi clocks for each instance. */
static clock_ip_name_t const s_dspiClock[] = DSPI_CLOCKS;

/*! @brief Pointers to dspi handles for each instance. */
static void *g_dspiHandle[FSL_FEATURE_SOC_DSPI_COUNT];

/*! @brief Pointer to master IRQ handler for each instance. */
static dspi_master_isr_t s_dspiMasterIsr;

/*! @brief Pointer to slave IRQ handler for each instance. */
static dspi_slave_isr_t s_dspiSlaveIsr;

/**********************************************************************************************************************
* Code
*********************************************************************************************************************/
uint32_t DSPI_GetInstance(SPI_Type *base)
{
    uint32_t instance;

    /* Find the instance index from base address mappings. */
    for (instance = 0; instance < FSL_FEATURE_SOC_DSPI_COUNT; instance++)
    {
        if (s_dspiBases[instance] == base)
        {
            break;
        }
    }

    assert(instance < FSL_FEATURE_SOC_DSPI_COUNT);

    return instance;
}

void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
{
    uint32_t temp;
    /* enable DSPI clock */
    CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);

    DSPI_Enable(base, true);
    DSPI_StopTransfer(base);

    DSPI_SetMasterSlaveMode(base, kDSPI_Master);

    temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK |
                          SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK));

    base->MCR = temp | SPI_MCR_CONT_SCKE(masterConfig->enableContinuousSCK) |
                SPI_MCR_MTFE(masterConfig->enableModifiedTimingFormat) |
                SPI_MCR_ROOE(masterConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(masterConfig->samplePoint) |
                SPI_MCR_DIS_TXF(false) | SPI_MCR_DIS_RXF(false);

    DSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow);

    if (0 == DSPI_MasterSetBaudRate(base, masterConfig->whichCtar, masterConfig->ctarConfig.baudRate, srcClock_Hz))
    {
        assert(false);
    }

    temp = base->CTAR[masterConfig->whichCtar] &
           ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK);

    base->CTAR[masterConfig->whichCtar] =
        temp | SPI_CTAR_FMSZ(masterConfig->ctarConfig.bitsPerFrame - 1) | SPI_CTAR_CPOL(masterConfig->ctarConfig.cpol) |
        SPI_CTAR_CPHA(masterConfig->ctarConfig.cpha) | SPI_CTAR_LSBFE(masterConfig->ctarConfig.direction);

    DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_PcsToSck, srcClock_Hz,
                             masterConfig->ctarConfig.pcsToSckDelayInNanoSec);
    DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_LastSckToPcs, srcClock_Hz,
                             masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec);
    DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_BetweenTransfer, srcClock_Hz,
                             masterConfig->ctarConfig.betweenTransferDelayInNanoSec);

    DSPI_StartTransfer(base);
}

void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig)
{
    masterConfig->whichCtar = kDSPI_Ctar0;
    masterConfig->ctarConfig.baudRate = 500000;
    masterConfig->ctarConfig.bitsPerFrame = 8;
    masterConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
    masterConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
    masterConfig->ctarConfig.direction = kDSPI_MsbFirst;

    masterConfig->ctarConfig.pcsToSckDelayInNanoSec = 1000;
    masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec = 1000;
    masterConfig->ctarConfig.betweenTransferDelayInNanoSec = 1000;

    masterConfig->whichPcs = kDSPI_Pcs0;
    masterConfig->pcsActiveHighOrLow = kDSPI_PcsActiveLow;

    masterConfig->enableContinuousSCK = false;
    masterConfig->enableRxFifoOverWrite = false;
    masterConfig->enableModifiedTimingFormat = false;
    masterConfig->samplePoint = kDSPI_SckToSin0Clock;
}

void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig)
{
    uint32_t temp = 0;

    /* enable DSPI clock */
    CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);

    DSPI_Enable(base, true);
    DSPI_StopTransfer(base);

    DSPI_SetMasterSlaveMode(base, kDSPI_Slave);

    temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK |
                          SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK));

    base->MCR = temp | SPI_MCR_CONT_SCKE(slaveConfig->enableContinuousSCK) |
                SPI_MCR_MTFE(slaveConfig->enableModifiedTimingFormat) |
                SPI_MCR_ROOE(slaveConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(slaveConfig->samplePoint) |
                SPI_MCR_DIS_TXF(false) | SPI_MCR_DIS_RXF(false);

    DSPI_SetOnePcsPolarity(base, kDSPI_Pcs0, kDSPI_PcsActiveLow);

    temp = base->CTAR[slaveConfig->whichCtar] &
           ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK);

    base->CTAR[slaveConfig->whichCtar] = temp | SPI_CTAR_SLAVE_FMSZ(slaveConfig->ctarConfig.bitsPerFrame - 1) |
                                         SPI_CTAR_SLAVE_CPOL(slaveConfig->ctarConfig.cpol) |
                                         SPI_CTAR_SLAVE_CPHA(slaveConfig->ctarConfig.cpha);

    DSPI_StartTransfer(base);
}

void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig)
{
    slaveConfig->whichCtar = kDSPI_Ctar0;
    slaveConfig->ctarConfig.bitsPerFrame = 8;
    slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
    slaveConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;

    slaveConfig->enableContinuousSCK = false;
    slaveConfig->enableRxFifoOverWrite = false;
    slaveConfig->enableModifiedTimingFormat = false;
    slaveConfig->samplePoint = kDSPI_SckToSin0Clock;
}

void DSPI_Deinit(SPI_Type *base)
{
    DSPI_StopTransfer(base);
    DSPI_Enable(base, false);

    /* disable DSPI clock */
    CLOCK_DisableClock(s_dspiClock[DSPI_GetInstance(base)]);
}

static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh)
{
    uint32_t temp;

    temp = base->MCR;

    if (activeLowOrHigh == kDSPI_PcsActiveLow)
    {
        temp |= SPI_MCR_PCSIS(pcs);
    }
    else
    {
        temp &= ~SPI_MCR_PCSIS(pcs);
    }

    base->MCR = temp;
}

uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
                                dspi_ctar_selection_t whichCtar,
                                uint32_t baudRate_Bps,
                                uint32_t srcClock_Hz)
{
    /* for master mode configuration, if slave mode detected, return 0*/
    if (!DSPI_IsMaster(base))
    {
        return 0;
    }
    uint32_t temp;
    uint32_t prescaler, bestPrescaler;
    uint32_t scaler, bestScaler;
    uint32_t dbr, bestDbr;
    uint32_t realBaudrate, bestBaudrate;
    uint32_t diff, min_diff;
    uint32_t baudrate = baudRate_Bps;

    /* find combination of prescaler and scaler resulting in baudrate closest to the requested value */
    min_diff = 0xFFFFFFFFU;
    bestPrescaler = 0;
    bestScaler = 0;
    bestDbr = 1;
    bestBaudrate = 0; /* required to avoid compilation warning */

    /* In all for loops, if min_diff = 0, the exit for loop*/
    for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++)
    {
        for (scaler = 0; (scaler < 16) && min_diff; scaler++)
        {
            for (dbr = 1; (dbr < 3) && min_diff; dbr++)
            {
                realBaudrate = ((srcClock_Hz * dbr) / (s_baudratePrescaler[prescaler] * (s_baudrateScaler[scaler])));

                /* calculate the baud rate difference based on the conditional statement that states that the calculated
                * baud rate must not exceed the desired baud rate.
                */
                if (baudrate >= realBaudrate)
                {
                    diff = baudrate - realBaudrate;
                    if (min_diff > diff)
                    {
                        /* a better match found */
                        min_diff = diff;
                        bestPrescaler = prescaler;
                        bestScaler = scaler;
                        bestBaudrate = realBaudrate;
                        bestDbr = dbr;
                    }
                }
            }
        }
    }

    /* write the best dbr, prescalar, and baud rate scalar to the CTAR */
    temp = base->CTAR[whichCtar] & ~(SPI_CTAR_DBR_MASK | SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK);

    base->CTAR[whichCtar] = temp | ((bestDbr - 1) << SPI_CTAR_DBR_SHIFT) | (bestPrescaler << SPI_CTAR_PBR_SHIFT) |
                            (bestScaler << SPI_CTAR_BR_SHIFT);

    /* return the actual calculated baud rate */
    return bestBaudrate;
}

void DSPI_MasterSetDelayScaler(
    SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay)
{
    /* these settings are only relevant in master mode */
    if (DSPI_IsMaster(base))
    {
        switch (whichDelay)
        {
            case kDSPI_PcsToSck:
                base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PCSSCK_MASK) & (~SPI_CTAR_CSSCK_MASK)) |
                                        SPI_CTAR_PCSSCK(prescaler) | SPI_CTAR_CSSCK(scaler);
                break;
            case kDSPI_LastSckToPcs:
                base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PASC_MASK) & (~SPI_CTAR_ASC_MASK)) |
                                        SPI_CTAR_PASC(prescaler) | SPI_CTAR_ASC(scaler);
                break;
            case kDSPI_BetweenTransfer:
                base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PDT_MASK) & (~SPI_CTAR_DT_MASK)) |
                                        SPI_CTAR_PDT(prescaler) | SPI_CTAR_DT(scaler);
                break;
            default:
                break;
        }
    }
}

uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
                                  dspi_ctar_selection_t whichCtar,
                                  dspi_delay_type_t whichDelay,
                                  uint32_t srcClock_Hz,
                                  uint32_t delayTimeInNanoSec)
{
    /* for master mode configuration, if slave mode detected, return 0 */
    if (!DSPI_IsMaster(base))
    {
        return 0;
    }

    uint32_t prescaler, bestPrescaler;
    uint32_t scaler, bestScaler;
    uint32_t realDelay, bestDelay;
    uint32_t diff, min_diff;
    uint32_t initialDelayNanoSec;

    /* find combination of prescaler and scaler resulting in the delay closest to the
    * requested value
    */
    min_diff = 0xFFFFFFFFU;
    /* Initialize prescaler and scaler to their max values to generate the max delay */
    bestPrescaler = 0x3;
    bestScaler = 0xF;
    bestDelay = (((1000000000U * 4) / srcClock_Hz) * s_delayPrescaler[bestPrescaler] * s_delayScaler[bestScaler]) / 4;

    /* First calculate the initial, default delay */
    initialDelayNanoSec = 1000000000U / srcClock_Hz * 2;

    /* If the initial, default delay is already greater than the desired delay, then
    * set the delays to their initial value (0) and return the delay. In other words,
    * there is no way to decrease the delay value further.
    */
    if (initialDelayNanoSec >= delayTimeInNanoSec)
    {
        DSPI_MasterSetDelayScaler(base, whichCtar, 0, 0, whichDelay);
        return initialDelayNanoSec;
    }

    /* In all for loops, if min_diff = 0, the exit for loop */
    for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++)
    {
        for (scaler = 0; (scaler < 16) && min_diff; scaler++)
        {
            realDelay = ((4000000000U / srcClock_Hz) * s_delayPrescaler[prescaler] * s_delayScaler[scaler]) / 4;

            /* calculate the delay difference based on the conditional statement
            * that states that the calculated delay must not be less then the desired delay
            */
            if (realDelay >= delayTimeInNanoSec)
            {
                diff = realDelay - delayTimeInNanoSec;
                if (min_diff > diff)
                {
                    /* a better match found */
                    min_diff = diff;
                    bestPrescaler = prescaler;
                    bestScaler = scaler;
                    bestDelay = realDelay;
                }
            }
        }
    }

    /* write the best dbr, prescalar, and baud rate scalar to the CTAR */
    DSPI_MasterSetDelayScaler(base, whichCtar, bestPrescaler, bestScaler, whichDelay);

    /* return the actual calculated baud rate */
    return bestDelay;
}

void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command)
{
    command->isPcsContinuous = false;
    command->whichCtar = kDSPI_Ctar0;
    command->whichPcs = kDSPI_Pcs0;
    command->isEndOfQueue = false;
    command->clearTransferCount = false;
}

void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data)
{
    /* First, clear Transmit Complete Flag (TCF) */
    DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag);

    while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
    {
        DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
    }

    base->PUSHR = SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) |
                  SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) |
                  SPI_PUSHR_CTCNT(command->clearTransferCount) | SPI_PUSHR_TXDATA(data);
    DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

    /* Wait till TCF sets */
    while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag))
    {
    }
}

void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data)
{
    /* First, clear Transmit Complete Flag (TCF) */
    DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag);

    while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
    {
        DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
    }

    base->PUSHR = data;

    DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

    /* Wait till TCF sets */
    while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag))
    {
    }
}

void DSPI_SlaveWriteDataBlocking(SPI_Type *base, uint32_t data)
{
    /* First, clear Transmit Complete Flag (TCF) */
    DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag);

    while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
    {
        DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
    }

    base->PUSHR_SLAVE = data;

    DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

    /* Wait till TCF sets */
    while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag))
    {
    }
}

void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask)
{
    if (mask & SPI_RSER_TFFF_RE_MASK)
    {
        base->RSER &= ~SPI_RSER_TFFF_DIRS_MASK;
    }
    if (mask & SPI_RSER_RFDF_RE_MASK)
    {
        base->RSER &= ~SPI_RSER_RFDF_DIRS_MASK;
    }
    base->RSER |= mask;
}

/*Transactional APIs -- Master*/

void DSPI_MasterTransferCreateHandle(SPI_Type *base,
                                     dspi_master_handle_t *handle,
                                     dspi_master_transfer_callback_t callback,
                                     void *userData)
{
    assert(handle);

    /* Zero the handle. */
    memset(handle, 0, sizeof(*handle));

    g_dspiHandle[DSPI_GetInstance(base)] = handle;

    handle->callback = callback;
    handle->userData = userData;
}

status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
{
    assert(transfer);

    uint16_t wordToSend = 0;
    uint16_t wordReceived = 0;
    uint8_t dummyData = DSPI_DUMMY_DATA;
    uint8_t bitsPerFrame;

    uint32_t command;
    uint32_t lastCommand;

    uint8_t *txData;
    uint8_t *rxData;
    uint32_t remainingSendByteCount;
    uint32_t remainingReceiveByteCount;

    uint32_t fifoSize;
    dspi_command_data_config_t commandStruct;

    /* If the transfer count is zero, then return immediately.*/
    if (transfer->dataSize == 0)
    {
        return kStatus_InvalidArgument;
    }

    DSPI_StopTransfer(base);
    DSPI_DisableInterrupts(base, kDSPI_AllInterruptEnable);
    DSPI_FlushFifo(base, true, true);
    DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);

    /*Calculate the command and lastCommand*/
    commandStruct.whichPcs =
        (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
    commandStruct.isEndOfQueue = false;
    commandStruct.clearTransferCount = false;
    commandStruct.whichCtar =
        (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
    commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous);

    command = DSPI_MasterGetFormattedCommand(&(commandStruct));

    commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
    lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));

    /*Calculate the bitsPerFrame*/
    bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1;

    txData = transfer->txData;
    rxData = transfer->rxData;
    remainingSendByteCount = transfer->dataSize;
    remainingReceiveByteCount = transfer->dataSize;

    if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK))
    {
        fifoSize = 1;
    }
    else
    {
        fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
    }

    DSPI_StartTransfer(base);

    if (bitsPerFrame <= 8)
    {
        while (remainingSendByteCount > 0)
        {
            if (remainingSendByteCount == 1)
            {
                while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize)
                {
                    if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
                    {
                        if (rxData != NULL)
                        {
                            *(rxData) = DSPI_ReadData(base);
                            rxData++;
                        }
                        else
                        {
                            DSPI_ReadData(base);
                        }
                        remainingReceiveByteCount--;

                        DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
                    }
                }

                while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
                {
                    DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
                }

                if (txData != NULL)
                {
                    base->PUSHR = (*txData) | (lastCommand);
                    txData++;
                }
                else
                {
                    base->PUSHR = (lastCommand) | (dummyData);
                }
                DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
                remainingSendByteCount--;

                while (remainingReceiveByteCount > 0)
                {
                    if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
                    {
                        if (rxData != NULL)
                        {
                            /* Read data from POPR*/
                            *(rxData) = DSPI_ReadData(base);
                            rxData++;
                        }
                        else
                        {
                            DSPI_ReadData(base);
                        }
                        remainingReceiveByteCount--;

                        DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
                    }
                }
            }
            else
            {
                /*Wait until Tx Fifo is not full*/
                while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
                {
                    DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
                }
                if (txData != NULL)
                {
                    base->PUSHR = command | (uint16_t)(*txData);
                    txData++;
                }
                else
                {
                    base->PUSHR = command | dummyData;
                }
                remainingSendByteCount--;

                DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

                if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
                {
                    if (rxData != NULL)
                    {
                        *(rxData) = DSPI_ReadData(base);
                        rxData++;
                    }
                    else
                    {
                        DSPI_ReadData(base);
                    }
                    remainingReceiveByteCount--;

                    DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
                }
            }
        }
    }
    else
    {
        while (remainingSendByteCount > 0)
        {
            if (remainingSendByteCount <= 2)
            {
                while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize)
                {
                    if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
                    {
                        wordReceived = DSPI_ReadData(base);

                        if (rxData != NULL)
                        {
                            *rxData = wordReceived;
                            ++rxData;
                            *rxData = wordReceived >> 8;
                            ++rxData;
                        }
                        remainingReceiveByteCount -= 2;

                        DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
                    }
                }

                while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
                {
                    DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
                }

                if (txData != NULL)
                {
                    wordToSend = *(txData);
                    ++txData;

                    if (remainingSendByteCount > 1)
                    {
                        wordToSend |= (unsigned)(*(txData)) << 8U;
                        ++txData;
                    }
                }
                else
                {
                    wordToSend = dummyData;
                }

                base->PUSHR = lastCommand | wordToSend;

                DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
                remainingSendByteCount = 0;

                while (remainingReceiveByteCount > 0)
                {
                    if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
                    {
                        wordReceived = DSPI_ReadData(base);

                        if (remainingReceiveByteCount != 1)
                        {
                            if (rxData != NULL)
                            {
                                *(rxData) = wordReceived;
                                ++rxData;
                                *(rxData) = wordReceived >> 8;
                                ++rxData;
                            }
                            remainingReceiveByteCount -= 2;
                        }
                        else
                        {
                            if (rxData != NULL)
                            {
                                *(rxData) = wordReceived;
                                ++rxData;
                            }
                            remainingReceiveByteCount--;
                        }
                        DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
                    }
                }
            }
            else
            {
                /*Wait until Tx Fifo is not full*/
                while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
                {
                    DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
                }

                if (txData != NULL)
                {
                    wordToSend = *(txData);
                    ++txData;
                    wordToSend |= (unsigned)(*(txData)) << 8U;
                    ++txData;
                }
                else
                {
                    wordToSend = dummyData;
                }
                base->PUSHR = command | wordToSend;
                remainingSendByteCount -= 2;

                DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

                if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
                {
                    wordReceived = DSPI_ReadData(base);

                    if (rxData != NULL)
                    {
                        *rxData = wordReceived;
                        ++rxData;
                        *rxData = wordReceived >> 8;
                        ++rxData;
                    }
                    remainingReceiveByteCount -= 2;

                    DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
                }
            }
        }
    }

    return kStatus_Success;
}

static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
{
    dspi_command_data_config_t commandStruct;

    DSPI_StopTransfer(base);
    DSPI_FlushFifo(base, true, true);
    DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);

    commandStruct.whichPcs =
        (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
    commandStruct.isEndOfQueue = false;
    commandStruct.clearTransferCount = false;
    commandStruct.whichCtar =
        (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
    commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous);
    handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));

    commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
    handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));

    handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1;

    if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK))
    {
        handle->fifoSize = 1;
    }
    else
    {
        handle->fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
    }
    handle->txData = transfer->txData;
    handle->rxData = transfer->rxData;
    handle->remainingSendByteCount = transfer->dataSize;
    handle->remainingReceiveByteCount = transfer->dataSize;
    handle->totalByteCount = transfer->dataSize;
}

status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
{
    assert(handle && transfer);

    /* If the transfer count is zero, then return immediately.*/
    if (transfer->dataSize == 0)
    {
        return kStatus_InvalidArgument;
    }

    /* Check that we're not busy.*/
    if (handle->state == kDSPI_Busy)
    {
        return kStatus_DSPI_Busy;
    }

    handle->state = kDSPI_Busy;

    DSPI_MasterTransferPrepare(base, handle, transfer);
    DSPI_StartTransfer(base);

    /* Enable the NVIC for DSPI peripheral. */
    EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]);

    DSPI_MasterTransferFillUpTxFifo(base, handle);

    /* RX FIFO Drain request: RFDF_RE to enable RFDF interrupt
    * Since SPI is a synchronous interface, we only need to enable the RX interrupt.
    * The IRQ handler will get the status of RX and TX interrupt flags.
    */
    s_dspiMasterIsr = DSPI_MasterTransferHandleIRQ;

    DSPI_EnableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable);

    return kStatus_Success;
}

status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count)
{
    assert(handle);

    if (!count)
    {
        return kStatus_InvalidArgument;
    }

    /* Catch when there is not an active transfer. */
    if (handle->state != kDSPI_Busy)
    {
        *count = 0;
        return kStatus_NoTransferInProgress;
    }

    *count = handle->totalByteCount - handle->remainingReceiveByteCount;
    return kStatus_Success;
}

static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle)
{
    /* Disable interrupt requests*/
    DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable);

    status_t status = 0;
    if (handle->state == kDSPI_Error)
    {
        status = kStatus_DSPI_Error;
    }
    else
    {
        status = kStatus_Success;
    }

    if (handle->callback)
    {
        handle->callback(base, handle, status, handle->userData);
    }

    /* The transfer is complete.*/
    handle->state = kDSPI_Idle;
}

static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle)
{
    uint16_t wordToSend = 0;
    uint8_t dummyData = DSPI_DUMMY_DATA;

    /* If bits/frame is greater than one byte */
    if (handle->bitsPerFrame > 8)
    {
        /* Fill the fifo until it is full or until the send word count is 0 or until the difference
        * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
        * The reason for checking the difference is to ensure we only send as much as the
        * RX FIFO can receive.
        * For this case where bitsPerFrame > 8, each entry in the FIFO contains 2 bytes of the
        * send data, hence the difference between the remainingReceiveByteCount and
        * remainingSendByteCount must be divided by 2 to convert this difference into a
        * 16-bit (2 byte) value.
        */
        while ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) &&
               ((handle->remainingReceiveByteCount - handle->remainingSendByteCount) / 2 < handle->fifoSize))
        {
            if (handle->remainingSendByteCount <= 2)
            {
                if (handle->txData)
                {
                    if (handle->remainingSendByteCount == 1)
                    {
                        wordToSend = *(handle->txData);
                    }
                    else
                    {
                        wordToSend = *(handle->txData);
                        ++handle->txData; /* increment to next data byte */
                        wordToSend |= (unsigned)(*(handle->txData)) << 8U;
                    }
                }
                else
                {
                    wordToSend = dummyData;
                }
                handle->remainingSendByteCount = 0;
                base->PUSHR = handle->lastCommand | wordToSend;
            }
            /* For all words except the last word */
            else
            {
                if (handle->txData)
                {
                    wordToSend = *(handle->txData);
                    ++handle->txData; /* increment to next data byte */
                    wordToSend |= (unsigned)(*(handle->txData)) << 8U;
                    ++handle->txData; /* increment to next data byte */
                }
                else
                {
                    wordToSend = dummyData;
                }
                handle->remainingSendByteCount -= 2; /* decrement remainingSendByteCount by 2 */
                base->PUSHR = handle->command | wordToSend;
            }

            /* Try to clear the TFFF; if the TX FIFO is full this will clear */
            DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

            /* exit loop if send count is zero, else update local variables for next loop */
            if (handle->remainingSendByteCount == 0)
            {
                break;
            }
        } /* End of TX FIFO fill while loop */
    }
    /* Optimized for bits/frame less than or equal to one byte. */
    else
    {
        /* Fill the fifo until it is full or until the send word count is 0 or until the difference
        * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
        * The reason for checking the difference is to ensure we only send as much as the
        * RX FIFO can receive.
        */
        while ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) &&
               ((handle->remainingReceiveByteCount - handle->remainingSendByteCount) < handle->fifoSize))
        {
            if (handle->txData)
            {
                wordToSend = *(handle->txData);
                ++handle->txData;
            }
            else
            {
                wordToSend = dummyData;
            }

            if (handle->remainingSendByteCount == 1)
            {
                base->PUSHR = handle->lastCommand | wordToSend;
            }
            else
            {
                base->PUSHR = handle->command | wordToSend;
            }

            /* Try to clear the TFFF; if the TX FIFO is full this will clear */
            DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

            --handle->remainingSendByteCount;

            /* exit loop if send count is zero, else update local variables for next loop */
            if (handle->remainingSendByteCount == 0)
            {
                break;
            }
        }
    }
}

void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle)
{
    DSPI_StopTransfer(base);

    /* Disable interrupt requests*/
    DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable);

    handle->state = kDSPI_Idle;
}

void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle)
{
    /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */
    if (handle->remainingReceiveByteCount)
    {
        /* Check read buffer.*/
        uint16_t wordReceived; /* Maximum supported data bit length in master mode is 16-bits */

        /* If bits/frame is greater than one byte */
        if (handle->bitsPerFrame > 8)
        {
            while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
            {
                wordReceived = DSPI_ReadData(base);
                /* clear the rx fifo drain request, needed for non-DMA applications as this flag
                * will remain set even if the rx fifo is empty. By manually clearing this flag, it
                * either remain clear if no more data is in the fifo, or it will set if there is
                * more data in the fifo.
                */
                DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);

                /* Store read bytes into rx buffer only if a buffer pointer was provided */
                if (handle->rxData)
                {
                    /* For the last word received, if there is an extra byte due to the odd transfer
                    * byte count, only save the the last byte and discard the upper byte
                    */
                    if (handle->remainingReceiveByteCount == 1)
                    {
                        *handle->rxData = wordReceived; /* Write first data byte */
                        --handle->remainingReceiveByteCount;
                    }
                    else
                    {
                        *handle->rxData = wordReceived;      /* Write first data byte */
                        ++handle->rxData;                    /* increment to next data byte */
                        *handle->rxData = wordReceived >> 8; /* Write second data byte */
                        ++handle->rxData;                    /* increment to next data byte */
                        handle->remainingReceiveByteCount -= 2;
                    }
                }
                else
                {
                    if (handle->remainingReceiveByteCount == 1)
                    {
                        --handle->remainingReceiveByteCount;
                    }
                    else
                    {
                        handle->remainingReceiveByteCount -= 2;
                    }
                }
                if (handle->remainingReceiveByteCount == 0)
                {
                    break;
                }
            } /* End of RX FIFO drain while loop */
        }
        /* Optimized for bits/frame less than or equal to one byte. */
        else
        {
            while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
            {
                wordReceived = DSPI_ReadData(base);
                /* clear the rx fifo drain request, needed for non-DMA applications as this flag
                * will remain set even if the rx fifo is empty. By manually clearing this flag, it
                * either remain clear if no more data is in the fifo, or it will set if there is
                * more data in the fifo.
                */
                DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);

                /* Store read bytes into rx buffer only if a buffer pointer was provided */
                if (handle->rxData)
                {
                    *handle->rxData = wordReceived;
                    ++handle->rxData;
                }

                --handle->remainingReceiveByteCount;

                if (handle->remainingReceiveByteCount == 0)
                {
                    break;
                }
            } /* End of RX FIFO drain while loop */
        }
    }

    /* Check write buffer. We always have to send a word in order to keep the transfer
    * moving. So if the caller didn't provide a send buffer, we just send a zero.
    */
    if (handle->remainingSendByteCount)
    {
        DSPI_MasterTransferFillUpTxFifo(base, handle);
    }

    /* Check if we're done with this transfer.*/
    if ((handle->remainingSendByteCount == 0) && (handle->remainingReceiveByteCount == 0))
    {
        /* Complete the transfer and disable the interrupts */
        DSPI_MasterTransferComplete(base, handle);
    }
}

/*Transactional APIs -- Slave*/
void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
                                    dspi_slave_handle_t *handle,
                                    dspi_slave_transfer_callback_t callback,
                                    void *userData)
{
    assert(handle);

    /* Zero the handle. */
    memset(handle, 0, sizeof(*handle));

    g_dspiHandle[DSPI_GetInstance(base)] = handle;

    handle->callback = callback;
    handle->userData = userData;
}

status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer)
{
    assert(handle && transfer);

    /* If receive length is zero */
    if (transfer->dataSize == 0)
    {
        return kStatus_InvalidArgument;
    }

    /* If both send buffer and receive buffer is null */
    if ((!(transfer->txData)) && (!(transfer->rxData)))
    {
        return kStatus_InvalidArgument;
    }

    /* Check that we're not busy.*/
    if (handle->state == kDSPI_Busy)
    {
        return kStatus_DSPI_Busy;
    }
    handle->state = kDSPI_Busy;

    /* Enable the NVIC for DSPI peripheral. */
    EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]);

    /* Store transfer information */
    handle->txData = transfer->txData;
    handle->rxData = transfer->rxData;
    handle->remainingSendByteCount = transfer->dataSize;
    handle->remainingReceiveByteCount = transfer->dataSize;
    handle->totalByteCount = transfer->dataSize;

    handle->errorCount = 0;

    uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT;
    handle->bitsPerFrame =
        (((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1;

    DSPI_StopTransfer(base);

    DSPI_FlushFifo(base, true, true);
    DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);

    DSPI_StartTransfer(base);

    /* Prepare data to transmit */
    DSPI_SlaveTransferFillUpTxFifo(base, handle);

    s_dspiSlaveIsr = DSPI_SlaveTransferHandleIRQ;

    /* Enable RX FIFO drain request, the slave only use this interrupt */
    DSPI_EnableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable);

    if (handle->rxData)
    {
        /* RX FIFO overflow request enable */
        DSPI_EnableInterrupts(base, kDSPI_RxFifoOverflowInterruptEnable);
    }
    if (handle->txData)
    {
        /* TX FIFO underflow request enable */
        DSPI_EnableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable);
    }

    return kStatus_Success;
}

status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count)
{
    assert(handle);

    if (!count)
    {
        return kStatus_InvalidArgument;
    }

    /* Catch when there is not an active transfer. */
    if (handle->state != kDSPI_Busy)
    {
        *count = 0;
        return kStatus_NoTransferInProgress;
    }

    *count = handle->totalByteCount - handle->remainingReceiveByteCount;
    return kStatus_Success;
}

static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle)
{
    uint16_t transmitData = 0;
    uint8_t dummyPattern = DSPI_DUMMY_DATA;

    /* Service the transmitter, if transmit buffer provided, transmit the data,
    * else transmit dummy pattern
    */
    while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)
    {
        /* Transmit data */
        if (handle->remainingSendByteCount > 0)
        {
            /* Have data to transmit, update the transmit data and push to FIFO */
            if (handle->bitsPerFrame <= 8)
            {
                /* bits/frame is 1 byte */
                if (handle->txData)
                {
                    /* Update transmit data and transmit pointer */
                    transmitData = *handle->txData;
                    handle->txData++;
                }
                else
                {
                    transmitData = dummyPattern;
                }

                /* Decrease remaining dataSize */
                --handle->remainingSendByteCount;
            }
            /* bits/frame is 2 bytes */
            else
            {
                /* With multibytes per frame transmission, the transmit frame contains data from
                * transmit buffer until sent dataSize matches user request. Other bytes will set to
                * dummy pattern value.
                */
                if (handle->txData)
                {
                    /* Update first byte of transmit data and transmit pointer */
                    transmitData = *handle->txData;
                    handle->txData++;

                    if (handle->remainingSendByteCount == 1)
                    {
                        /* Decrease remaining dataSize */
                        --handle->remainingSendByteCount;
                        /* Update second byte of transmit data to second byte of dummy pattern */
                        transmitData = transmitData | (uint16_t)(((uint16_t)dummyPattern) << 8);
                    }
                    else
                    {
                        /* Update second byte of transmit data and transmit pointer */
                        transmitData = transmitData | (uint16_t)((uint16_t)(*handle->txData) << 8);
                        handle->txData++;
                        handle->remainingSendByteCount -= 2;
                    }
                }
                else
                {
                    if (handle->remainingSendByteCount == 1)
                    {
                        --handle->remainingSendByteCount;
                    }
                    else
                    {
                        handle->remainingSendByteCount -= 2;
                    }
                    transmitData = (uint16_t)((uint16_t)(dummyPattern) << 8) | dummyPattern;
                }
            }
        }
        else
        {
            break;
        }

        /* Write the data to the DSPI data register */
        base->PUSHR_SLAVE = transmitData;

        /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */
        DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
    }
}

static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle)
{
    /* Disable interrupt requests */
    DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable |
                                     kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable);

    /* The transfer is complete. */
    handle->txData = NULL;
    handle->rxData = NULL;
    handle->remainingReceiveByteCount = 0;
    handle->remainingSendByteCount = 0;

    status_t status = 0;
    if (handle->state == kDSPI_Error)
    {
        status = kStatus_DSPI_Error;
    }
    else
    {
        status = kStatus_Success;
    }

    if (handle->callback)
    {
        handle->callback(base, handle, status, handle->userData);
    }

    handle->state = kDSPI_Idle;
}

void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle)
{
    DSPI_StopTransfer(base);

    /* Disable interrupt requests */
    DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable |
                                     kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable);

    handle->state = kDSPI_Idle;
    handle->remainingSendByteCount = 0;
    handle->remainingReceiveByteCount = 0;
}

void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
{
    uint8_t dummyPattern = DSPI_DUMMY_DATA;
    uint32_t dataReceived;
    uint32_t dataSend = 0;

    /* Because SPI protocol is synchronous, the number of bytes that that slave received from the
    * master is the actual number of bytes that the slave transmitted to the master. So we only
    * monitor the received dataSize to know when the transfer is complete.
    */
    if (handle->remainingReceiveByteCount > 0)
    {
        while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
        {
            /* Have received data in the buffer. */
            dataReceived = base->POPR;
            /*Clear the rx fifo drain request, needed for non-DMA applications as this flag
            * will remain set even if the rx fifo is empty. By manually clearing this flag, it
            * either remain clear if no more data is in the fifo, or it will set if there is
            * more data in the fifo.
            */
            DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);

            /* If bits/frame is one byte */
            if (handle->bitsPerFrame <= 8)
            {
                if (handle->rxData)
                {
                    /* Receive buffer is not null, store data into it */
                    *handle->rxData = dataReceived;
                    ++handle->rxData;
                }
                /* Descrease remaining receive byte count */
                --handle->remainingReceiveByteCount;

                if (handle->remainingSendByteCount > 0)
                {
                    if (handle->txData)
                    {
                        dataSend = *handle->txData;
                        ++handle->txData;
                    }
                    else
                    {
                        dataSend = dummyPattern;
                    }

                    --handle->remainingSendByteCount;
                    /* Write the data to the DSPI data register */
                    base->PUSHR_SLAVE = dataSend;
                }
            }
            else /* If bits/frame is 2 bytes */
            {
                /* With multibytes frame receiving, we only receive till the received dataSize
                * matches user request. Other bytes will be ignored.
                */
                if (handle->rxData)
                {
                    /* Receive buffer is not null, store first byte into it */
                    *handle->rxData = dataReceived;
                    ++handle->rxData;

                    if (handle->remainingReceiveByteCount == 1)
                    {
                        /* Decrease remaining receive byte count */
                        --handle->remainingReceiveByteCount;
                    }
                    else
                    {
                        /* Receive buffer is not null, store second byte into it */
                        *handle->rxData = dataReceived >> 8;
                        ++handle->rxData;
                        handle->remainingReceiveByteCount -= 2;
                    }
                }
                /* If no handle->rxData*/
                else
                {
                    if (handle->remainingReceiveByteCount == 1)
                    {
                        /* Decrease remaining receive byte count */
                        --handle->remainingReceiveByteCount;
                    }
                    else
                    {
                        handle->remainingReceiveByteCount -= 2;
                    }
                }

                if (handle->remainingSendByteCount > 0)
                {
                    if (handle->txData)
                    {
                        dataSend = *handle->txData;
                        ++handle->txData;

                        if (handle->remainingSendByteCount == 1)
                        {
                            --handle->remainingSendByteCount;
                            dataSend |= (uint16_t)((uint16_t)(dummyPattern) << 8);
                        }
                        else
                        {
                            dataSend |= (uint32_t)(*handle->txData) << 8;
                            ++handle->txData;
                            handle->remainingSendByteCount -= 2;
                        }
                    }
                    /* If no handle->txData*/
                    else
                    {
                        if (handle->remainingSendByteCount == 1)
                        {
                            --handle->remainingSendByteCount;
                        }
                        else
                        {
                            handle->remainingSendByteCount -= 2;
                        }
                        dataSend = (uint16_t)((uint16_t)(dummyPattern) << 8) | dummyPattern;
                    }
                    /* Write the data to the DSPI data register */
                    base->PUSHR_SLAVE = dataSend;
                }
            }
            /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */
            DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);

            if (handle->remainingReceiveByteCount == 0)
            {
                break;
            }
        }
    }
    /* Check if remaining receive byte count matches user request */
    if ((handle->remainingReceiveByteCount == 0) || (handle->state == kDSPI_Error))
    {
        /* Other cases, stop the transfer. */
        DSPI_SlaveTransferComplete(base, handle);
        return;
    }

    /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */
    if ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoUnderflowFlag) && (base->RSER & SPI_RSER_TFUF_RE_MASK))
    {
        DSPI_ClearStatusFlags(base, kDSPI_TxFifoUnderflowFlag);
        /* Change state to error and clear flag */
        if (handle->txData)
        {
            handle->state = kDSPI_Error;
        }
        handle->errorCount++;
    }
    /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */
    if ((DSPI_GetStatusFlags(base) & kDSPI_RxFifoOverflowFlag) && (base->RSER & SPI_RSER_RFOF_RE_MASK))
    {
        DSPI_ClearStatusFlags(base, kDSPI_RxFifoOverflowFlag);
        /* Change state to error and clear flag */
        if (handle->txData)
        {
            handle->state = kDSPI_Error;
        }
        handle->errorCount++;
    }
}

static void DSPI_CommonIRQHandler(SPI_Type *base, void *param)
{
    if (DSPI_IsMaster(base))
    {
        s_dspiMasterIsr(base, (dspi_master_handle_t *)param);
    }
    else
    {
        s_dspiSlaveIsr(base, (dspi_slave_handle_t *)param);
    }
}

#if defined(SPI0)
void SPI0_DriverIRQHandler(void)
{
    assert(g_dspiHandle[0]);
    DSPI_CommonIRQHandler(SPI0, g_dspiHandle[0]);
}
#endif

#if defined(SPI1)
void SPI1_DriverIRQHandler(void)
{
    assert(g_dspiHandle[1]);
    DSPI_CommonIRQHandler(SPI1, g_dspiHandle[1]);
}
#endif

#if defined(SPI2)
void SPI2_DriverIRQHandler(void)
{
    assert(g_dspiHandle[2]);
    DSPI_CommonIRQHandler(SPI2, g_dspiHandle[2]);
}
#endif

#if defined(SPI3)
void SPI3_DriverIRQHandler(void)
{
    assert(g_dspiHandle[3]);
    DSPI_CommonIRQHandler(SPI3, g_dspiHandle[3]);
}
#endif

#if defined(SPI4)
void SPI4_DriverIRQHandler(void)
{
    assert(g_dspiHandle[4]);
    DSPI_CommonIRQHandler(SPI4, g_dspiHandle[4]);
}
#endif

#if defined(SPI5)
void SPI5_DriverIRQHandler(void)
{
    assert(g_dspiHandle[5]);
    DSPI_CommonIRQHandler(SPI5, g_dspiHandle[5]);
}
#endif

#if (FSL_FEATURE_SOC_DSPI_COUNT > 6)
#error "Should write the SPIx_DriverIRQHandler function that instance greater than 5 !"
#endif
