Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:00

0001 /*
0002  * Copyright (c) 2015, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2022 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_lpspi.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.lpspi"
0018 #endif
0019 
0020 /*!
0021  * @brief Default watermark values.
0022  *
0023  * The default watermarks are set to zero.
0024  */
0025 enum _lpspi_default_watermarks
0026 {
0027     kLpspiDefaultTxWatermark = 0,
0028     kLpspiDefaultRxWatermark = 0,
0029 };
0030 
0031 /*
0032  * <! Structure definition for variables that passed as parameters in LPSPI_MasterTransferBlocking.
0033  *  The structure is private.
0034  */
0035 typedef struct _lpspi_transfer_blocking_param
0036 {
0037     bool isTxMask;
0038     bool isPcsContinuous;
0039     uint8_t bytesEachWrite;
0040     uint8_t bytesEachRead;
0041     uint32_t rxRemainingByteCount;
0042 } lpspi_transfer_blocking_param_t;
0043 
0044 /*! @brief Typedef for master interrupt handler. */
0045 typedef void (*lpspi_master_isr_t)(LPSPI_Type *base, lpspi_master_handle_t *handle);
0046 
0047 /*! @brief Typedef for slave interrupt handler. */
0048 typedef void (*lpspi_slave_isr_t)(LPSPI_Type *base, lpspi_slave_handle_t *handle);
0049 
0050 /*******************************************************************************
0051  * Prototypes
0052  ******************************************************************************/
0053 
0054 /*!
0055  * @brief Configures the LPSPI peripheral chip select polarity.
0056  *
0057  * This function  takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and
0058  * configures the Pcs signal to operate with the desired characteristic.
0059  *
0060  * @param base LPSPI peripheral address.
0061  * @param pcs The particular peripheral chip select (parameter value is of type lpspi_which_pcs_t) for which we wish to
0062  *            apply the active high or active low characteristic.
0063  * @param activeLowOrHigh The setting for either "active high, inactive low (0)"  or "active low, inactive high(1)" of
0064  *                        type lpspi_pcs_polarity_config_t.
0065  */
0066 static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
0067                                     lpspi_which_pcs_t pcs,
0068                                     lpspi_pcs_polarity_config_t activeLowOrHigh);
0069 
0070 /*!
0071  * @brief Combine the write data for 1 byte to 4 bytes.
0072  * This is not a public API.
0073  */
0074 static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap);
0075 
0076 /*!
0077  * @brief Separate the read data for 1 byte to 4 bytes.
0078  * This is not a public API.
0079  */
0080 static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap);
0081 
0082 /*!
0083  * @brief Wait for tx FIFO to be empty.
0084  * This is not a public API.
0085  * @param base LPSPI peripheral address.
0086  * @return true for the tx FIFO is ready, false is not.
0087  */
0088 static bool LPSPI_TxFifoReady(LPSPI_Type *base);
0089 
0090 /*!
0091  * @brief Master fill up the TX FIFO with data.
0092  * This is not a public API.
0093  */
0094 static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle);
0095 
0096 /*!
0097  * @brief Master finish up a transfer.
0098  * It would call back if there is callback function and set the state to idle.
0099  * This is not a public API.
0100  */
0101 static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle);
0102 
0103 /*!
0104  * @brief Slave fill up the TX FIFO with data.
0105  * This is not a public API.
0106  */
0107 static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle);
0108 
0109 /*!
0110  * @brief Slave finish up a transfer.
0111  * It would call back if there is callback function and set the state to idle.
0112  * This is not a public API.
0113  */
0114 static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle);
0115 
0116 /*!
0117  * @brief LPSPI common interrupt handler.
0118  *
0119  * @param handle pointer to s_lpspiHandle which stores the transfer state.
0120  */
0121 static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param);
0122 
0123 /*!
0124  * @brief introduce function static bool LPSPI_MasterTransferWriteAllTxData.
0125  * This function was deal with write all Txdata.
0126  *
0127  * @param base LPSPI peripheral address.
0128  * @param stateParams Pass the address of the parent function variable.
0129  *
0130  * @return default is true when No abnormality.
0131  * @return false when time out.
0132  */
0133 static bool LPSPI_MasterTransferWriteAllTxData(LPSPI_Type *base,
0134                                                lpspi_transfer_t *transfer,
0135                                                lpspi_transfer_blocking_param_t *stateParams);
0136 
0137 /*!
0138  * @brief introduce function LPSPI_MasterTransferClearTCR.
0139  * This function was deal with clear TCR.
0140  *
0141  * @param base LPSPI peripheral address.
0142  * @param stateParams Pass the address of the parent function variable.
0143  *
0144  * @return default is true when No abnormality.
0145  * @return false when time out.
0146  */
0147 static bool LPSPI_MasterTransferClearTCR(LPSPI_Type *base, lpspi_transfer_blocking_param_t *stateParams);
0148 
0149 /*!
0150  * @brief introduce function LPSPI_MasterTransferReadDataInFifo.
0151  * This function was deal with read data in fifo.
0152  *
0153  * @param base LPSPI peripheral address.
0154  * @param stateParams Pass the address of the parent function variable.
0155  *
0156  * @return default is true when No abnormality.
0157  * @return false when time out.
0158  */
0159 static bool LPSPI_MasterTransferReadDataInFifo(LPSPI_Type *base,
0160                                                lpspi_transfer_t *transfer,
0161                                                lpspi_transfer_blocking_param_t *stateParams);
0162 
0163 /*!
0164  * @brief introduce function LPSPI_MasterTransferReadDataInFifoNoBuf.
0165  * This function was deal with no buf in fifo.
0166  *
0167  * @param base LPSPI peripheral address.
0168  * @param stateParams Pass the address of the parent function variable.
0169  *
0170  * @return default is true when No abnormality.
0171  * @return false when time out.
0172  */
0173 static bool LPSPI_MasterTransferReadDataInFifoNoBuf(LPSPI_Type *base, lpspi_transfer_blocking_param_t *stateParams);
0174 
0175 /*******************************************************************************
0176  * Variables
0177  ******************************************************************************/
0178 
0179 /* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
0180 static const uint8_t s_baudratePrescaler[] = {1, 2, 4, 8, 16, 32, 64, 128};
0181 
0182 /*! @brief Pointers to lpspi bases for each instance. */
0183 static LPSPI_Type *const s_lpspiBases[] = LPSPI_BASE_PTRS;
0184 
0185 /*! @brief Pointers to lpspi IRQ number for each instance. */
0186 static const IRQn_Type s_lpspiIRQ[] = LPSPI_IRQS;
0187 
0188 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0189 /*! @brief Pointers to lpspi clocks for each instance. */
0190 static const clock_ip_name_t s_lpspiClocks[] = LPSPI_CLOCKS;
0191 
0192 #if defined(LPSPI_PERIPH_CLOCKS)
0193 static const clock_ip_name_t s_LpspiPeriphClocks[] = LPSPI_PERIPH_CLOCKS;
0194 #endif
0195 
0196 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0197 
0198 /*! @brief Pointers to lpspi handles for each instance. */
0199 static void *s_lpspiHandle[ARRAY_SIZE(s_lpspiBases)];
0200 
0201 /*! @brief Pointer to master IRQ handler for each instance. */
0202 static lpspi_master_isr_t s_lpspiMasterIsr;
0203 /*! @brief Pointer to slave IRQ handler for each instance. */
0204 static lpspi_slave_isr_t s_lpspiSlaveIsr;
0205 /* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/
0206 volatile uint8_t g_lpspiDummyData[ARRAY_SIZE(s_lpspiBases)] = {0};
0207 
0208 /**********************************************************************************************************************
0209  * Code
0210  *********************************************************************************************************************/
0211 
0212 /*!
0213  * brief Get the LPSPI instance from peripheral base address.
0214  *
0215  * param base LPSPI peripheral base address.
0216  * return LPSPI instance.
0217  */
0218 uint32_t LPSPI_GetInstance(LPSPI_Type *base)
0219 {
0220     uint8_t instance = 0;
0221 
0222     /* Find the instance index from base address mappings. */
0223     for (instance = 0; instance < ARRAY_SIZE(s_lpspiBases); instance++)
0224     {
0225         if (s_lpspiBases[instance] == base)
0226         {
0227             break;
0228         }
0229     }
0230 
0231     assert(instance < ARRAY_SIZE(s_lpspiBases));
0232 
0233     return instance;
0234 }
0235 
0236 /*!
0237  * brief Set up the dummy data.
0238  *
0239  * param base LPSPI peripheral address.
0240  * param dummyData Data to be transferred when tx buffer is NULL.
0241  * Note:
0242  *      This API has no effect when LPSPI in slave interrupt mode, because driver
0243  *      will set the TXMSK bit to 1 if txData is NULL, no data is loaded from transmit
0244  *      FIFO and output pin is tristated.
0245  */
0246 void LPSPI_SetDummyData(LPSPI_Type *base, uint8_t dummyData)
0247 {
0248     uint32_t instance          = LPSPI_GetInstance(base);
0249     g_lpspiDummyData[instance] = dummyData;
0250 }
0251 
0252 /*!
0253  * brief Initializes the LPSPI master.
0254  *
0255  * param base LPSPI peripheral address.
0256  * param masterConfig Pointer to structure lpspi_master_config_t.
0257  * param srcClock_Hz Module source input clock in Hertz
0258  */
0259 void LPSPI_MasterInit(LPSPI_Type *base, const lpspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
0260 {
0261     assert(masterConfig != NULL);
0262 
0263     uint32_t tcrPrescaleValue = 0;
0264 
0265 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0266 
0267     uint32_t instance = LPSPI_GetInstance(base);
0268     /* Enable LPSPI clock */
0269     (void)CLOCK_EnableClock(s_lpspiClocks[instance]);
0270 
0271 #if defined(LPSPI_PERIPH_CLOCKS)
0272     (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
0273 #endif
0274 
0275 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0276 
0277     /* Set LPSPI to master */
0278     LPSPI_SetMasterSlaveMode(base, kLPSPI_Master);
0279 
0280     /* Set specific PCS to active high or low */
0281     LPSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow);
0282 
0283     /* Set Configuration Register 1 related setting.*/
0284     base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK | LPSPI_CFGR1_NOSTALL_MASK |
0285                                    LPSPI_CFGR1_SAMPLE_MASK)) |
0286                   LPSPI_CFGR1_OUTCFG(masterConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(masterConfig->pinCfg) |
0287                   LPSPI_CFGR1_NOSTALL(0) | LPSPI_CFGR1_SAMPLE((uint32_t)masterConfig->enableInputDelay);
0288 
0289     /* Set baudrate and delay times*/
0290     (void)LPSPI_MasterSetBaudRate(base, masterConfig->baudRate, srcClock_Hz, &tcrPrescaleValue);
0291 
0292     /* Set default watermarks */
0293     LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark);
0294 
0295     /* Set Transmit Command Register*/
0296     base->TCR = LPSPI_TCR_CPOL(masterConfig->cpol) | LPSPI_TCR_CPHA(masterConfig->cpha) |
0297                 LPSPI_TCR_LSBF(masterConfig->direction) | LPSPI_TCR_FRAMESZ(masterConfig->bitsPerFrame - 1U) |
0298                 LPSPI_TCR_PRESCALE(tcrPrescaleValue) | LPSPI_TCR_PCS(masterConfig->whichPcs);
0299 
0300     LPSPI_Enable(base, true);
0301 
0302     (void)LPSPI_MasterSetDelayTimes(base, masterConfig->pcsToSckDelayInNanoSec, kLPSPI_PcsToSck, srcClock_Hz);
0303     (void)LPSPI_MasterSetDelayTimes(base, masterConfig->lastSckToPcsDelayInNanoSec, kLPSPI_LastSckToPcs, srcClock_Hz);
0304     (void)LPSPI_MasterSetDelayTimes(base, masterConfig->betweenTransferDelayInNanoSec, kLPSPI_BetweenTransfer,
0305                                     srcClock_Hz);
0306 
0307     LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
0308 }
0309 
0310 /*!
0311  * brief Sets the lpspi_master_config_t structure to default values.
0312  *
0313  * This API initializes the configuration structure  for LPSPI_MasterInit().
0314  * The initialized structure can remain unchanged in LPSPI_MasterInit(), or can be modified
0315  * before calling the LPSPI_MasterInit().
0316  * Example:
0317  * code
0318  *  lpspi_master_config_t  masterConfig;
0319  *  LPSPI_MasterGetDefaultConfig(&masterConfig);
0320  * endcode
0321  * param masterConfig pointer to lpspi_master_config_t structure
0322  */
0323 void LPSPI_MasterGetDefaultConfig(lpspi_master_config_t *masterConfig)
0324 {
0325     assert(masterConfig != NULL);
0326 
0327     /* Initializes the configure structure to zero. */
0328     (void)memset(masterConfig, 0, sizeof(*masterConfig));
0329 
0330     masterConfig->baudRate     = 500000;
0331     masterConfig->bitsPerFrame = 8;
0332     masterConfig->cpol         = kLPSPI_ClockPolarityActiveHigh;
0333     masterConfig->cpha         = kLPSPI_ClockPhaseFirstEdge;
0334     masterConfig->direction    = kLPSPI_MsbFirst;
0335 
0336     masterConfig->pcsToSckDelayInNanoSec        = 1000000000U / masterConfig->baudRate * 2U;
0337     masterConfig->lastSckToPcsDelayInNanoSec    = 1000000000U / masterConfig->baudRate * 2U;
0338     masterConfig->betweenTransferDelayInNanoSec = 1000000000U / masterConfig->baudRate * 2U;
0339 
0340     masterConfig->whichPcs           = kLPSPI_Pcs0;
0341     masterConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
0342 
0343     masterConfig->pinCfg        = kLPSPI_SdiInSdoOut;
0344     masterConfig->dataOutConfig = kLpspiDataOutRetained;
0345 
0346     masterConfig->enableInputDelay = false;
0347 }
0348 
0349 /*!
0350  * brief LPSPI slave configuration.
0351  *
0352  * param base LPSPI peripheral address.
0353  * param slaveConfig Pointer to a structure lpspi_slave_config_t.
0354  */
0355 void LPSPI_SlaveInit(LPSPI_Type *base, const lpspi_slave_config_t *slaveConfig)
0356 {
0357     assert(slaveConfig != NULL);
0358 
0359 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0360 
0361     uint32_t instance = LPSPI_GetInstance(base);
0362     /* Enable LPSPI clock */
0363     (void)CLOCK_EnableClock(s_lpspiClocks[instance]);
0364 
0365 #if defined(LPSPI_PERIPH_CLOCKS)
0366     (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
0367 #endif
0368 
0369 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0370 
0371     LPSPI_SetMasterSlaveMode(base, kLPSPI_Slave);
0372 
0373     LPSPI_SetOnePcsPolarity(base, slaveConfig->whichPcs, slaveConfig->pcsActiveHighOrLow);
0374 
0375     base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK)) |
0376                   LPSPI_CFGR1_OUTCFG(slaveConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(slaveConfig->pinCfg);
0377 
0378     LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark);
0379 
0380     base->TCR = LPSPI_TCR_CPOL(slaveConfig->cpol) | LPSPI_TCR_CPHA(slaveConfig->cpha) |
0381                 LPSPI_TCR_LSBF(slaveConfig->direction) | LPSPI_TCR_FRAMESZ(slaveConfig->bitsPerFrame - 1U);
0382 
0383     /* This operation will set the dummy data for edma transfer, no effect in interrupt way. */
0384     LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
0385 
0386     LPSPI_Enable(base, true);
0387 }
0388 
0389 /*!
0390  * brief Sets the lpspi_slave_config_t structure to default values.
0391  *
0392  * This API initializes the configuration structure for LPSPI_SlaveInit().
0393  * The initialized structure can remain unchanged in LPSPI_SlaveInit() or can be modified
0394  * before calling the LPSPI_SlaveInit().
0395  * Example:
0396  * code
0397  *  lpspi_slave_config_t  slaveConfig;
0398  *  LPSPI_SlaveGetDefaultConfig(&slaveConfig);
0399  * endcode
0400  * param slaveConfig pointer to lpspi_slave_config_t structure.
0401  */
0402 void LPSPI_SlaveGetDefaultConfig(lpspi_slave_config_t *slaveConfig)
0403 {
0404     assert(slaveConfig != NULL);
0405 
0406     /* Initializes the configure structure to zero. */
0407     (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
0408 
0409     slaveConfig->bitsPerFrame = 8;                              /*!< Bits per frame, minimum 8, maximum 4096.*/
0410     slaveConfig->cpol         = kLPSPI_ClockPolarityActiveHigh; /*!< Clock polarity. */
0411     slaveConfig->cpha         = kLPSPI_ClockPhaseFirstEdge;     /*!< Clock phase. */
0412     slaveConfig->direction    = kLPSPI_MsbFirst;                /*!< MSB or LSB data shift direction. */
0413 
0414     slaveConfig->whichPcs           = kLPSPI_Pcs0;         /*!< Desired Peripheral Chip Select (pcs) */
0415     slaveConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow; /*!< Desired PCS active high or low */
0416 
0417     slaveConfig->pinCfg        = kLPSPI_SdiInSdoOut;
0418     slaveConfig->dataOutConfig = kLpspiDataOutRetained;
0419 }
0420 
0421 /*!
0422  * brief Restores the LPSPI peripheral to reset state. Note that this function
0423  * sets all registers to reset state. As a result, the LPSPI module can't work after calling
0424  * this API.
0425  * param base LPSPI peripheral address.
0426  */
0427 void LPSPI_Reset(LPSPI_Type *base)
0428 {
0429     /* Reset all internal logic and registers, except the Control Register. Remains set until cleared by software.*/
0430     base->CR |= LPSPI_CR_RST_MASK;
0431 
0432     /* Software reset doesn't reset the CR, so manual reset the FIFOs */
0433     base->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
0434 
0435     /* Master logic is not reset and module is disabled.*/
0436     base->CR = 0x00U;
0437 }
0438 
0439 /*!
0440  * brief De-initializes the LPSPI peripheral. Call this API to disable the LPSPI clock.
0441  * param base LPSPI peripheral address.
0442  */
0443 void LPSPI_Deinit(LPSPI_Type *base)
0444 {
0445     /* Reset to default value */
0446     LPSPI_Reset(base);
0447 
0448 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0449 
0450     uint32_t instance = LPSPI_GetInstance(base);
0451     /* Enable LPSPI clock */
0452     (void)CLOCK_DisableClock(s_lpspiClocks[instance]);
0453 
0454 #if defined(LPSPI_PERIPH_CLOCKS)
0455     (void)CLOCK_DisableClock(s_LpspiPeriphClocks[instance]);
0456 #endif
0457 
0458 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0459 }
0460 
0461 static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
0462                                     lpspi_which_pcs_t pcs,
0463                                     lpspi_pcs_polarity_config_t activeLowOrHigh)
0464 {
0465     uint32_t cfgr1Value = 0;
0466     /* Clear the PCS polarity bit */
0467     cfgr1Value = base->CFGR1 & ~(1UL << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs));
0468 
0469     /* Configure the PCS polarity bit according to the activeLowOrHigh setting */
0470     base->CFGR1 = cfgr1Value | ((uint32_t)activeLowOrHigh << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs));
0471 }
0472 
0473 /*!
0474  * brief Sets the LPSPI baud rate in bits per second.
0475  *
0476  * This function takes in the desired bitsPerSec (baud rate) and calculates the nearest
0477  * possible baud rate without exceeding the desired baud rate and returns the
0478  * calculated baud rate in bits-per-second. It requires the caller to provide
0479  * the frequency of the module source clock (in Hertz). Note that the baud rate
0480  * does not go into effect until the Transmit Control Register (TCR) is programmed
0481  * with the prescale value. Hence, this function returns the prescale tcrPrescaleValue
0482  * parameter for later programming in the TCR.  The higher level
0483  * peripheral driver should alert the user of an out of range baud rate input.
0484  *
0485  * Note that the LPSPI module must first be disabled before configuring this.
0486  * Note that the LPSPI module must be configured for master mode before configuring this.
0487  *
0488  * param base LPSPI peripheral address.
0489  * param baudRate_Bps The desired baud rate in bits per second.
0490  * param srcClock_Hz Module source input clock in Hertz.
0491  * param tcrPrescaleValue The TCR prescale value needed to program the TCR.
0492  * return  The actual calculated baud rate. This function may also return a "0" if the
0493  *          LPSPI is not configured for master mode or if the LPSPI module is not disabled.
0494  */
0495 
0496 uint32_t LPSPI_MasterSetBaudRate(LPSPI_Type *base,
0497                                  uint32_t baudRate_Bps,
0498                                  uint32_t srcClock_Hz,
0499                                  uint32_t *tcrPrescaleValue)
0500 {
0501     assert(tcrPrescaleValue != NULL);
0502 
0503     /* For master mode configuration only, if slave mode detected, return 0.
0504      * Also, the LPSPI module needs to be disabled first, if enabled, return 0
0505      */
0506     if ((!LPSPI_IsMaster(base)) || ((base->CR & LPSPI_CR_MEN_MASK) != 0U))
0507     {
0508         return 0U;
0509     }
0510 
0511     uint32_t prescaler, bestPrescaler;
0512     uint32_t scaler, bestScaler;
0513     uint32_t realBaudrate, bestBaudrate;
0514     uint32_t diff, min_diff;
0515     uint32_t desiredBaudrate = baudRate_Bps;
0516 
0517     /* find combination of prescaler and scaler resulting in baudrate closest to the
0518      * requested value
0519      */
0520     min_diff = 0xFFFFFFFFU;
0521 
0522     /* Set to maximum divisor value bit settings so that if baud rate passed in is less
0523      * than the minimum possible baud rate, then the SPI will be configured to the lowest
0524      * possible baud rate
0525      */
0526     bestPrescaler = 7;
0527     bestScaler    = 255;
0528 
0529     bestBaudrate = 0; /* required to avoid compilation warning */
0530 
0531     /* In all for loops, if min_diff = 0, the exit for loop*/
0532     for (prescaler = 0U; prescaler < 8U; prescaler++)
0533     {
0534         if (min_diff == 0U)
0535         {
0536             break;
0537         }
0538         for (scaler = 0U; scaler < 256U; scaler++)
0539         {
0540             if (min_diff == 0U)
0541             {
0542                 break;
0543             }
0544             realBaudrate = (srcClock_Hz / (s_baudratePrescaler[prescaler] * (scaler + 2U)));
0545 
0546             /* calculate the baud rate difference based on the conditional statement
0547              * that states that the calculated baud rate must not exceed the desired baud rate
0548              */
0549             if (desiredBaudrate >= realBaudrate)
0550             {
0551                 diff = desiredBaudrate - realBaudrate;
0552                 if (min_diff > diff)
0553                 {
0554                     /* a better match found */
0555                     min_diff      = diff;
0556                     bestPrescaler = prescaler;
0557                     bestScaler    = scaler;
0558                     bestBaudrate  = realBaudrate;
0559                 }
0560             }
0561         }
0562     }
0563 
0564     /* Write the best baud rate scalar to the CCR.
0565      * Note, no need to check for error since we've already checked to make sure the module is
0566      * disabled and in master mode. Also, there is a limit on the maximum divider so we will not
0567      * exceed this.
0568      */
0569 #if defined(FSL_FEATURE_LPSPI_HAS_CCR1) && FSL_FEATURE_LPSPI_HAS_CCR1
0570     /* When CCR1 is present, the CCR[DBT] and CCR[SCKDIV] is write only, all read will return 0
0571        The real DBT and SCKDIV can be obtained in CCR1, CCR[DBT]=CCR1[SCKSCK] and CCR[SCKDIV]=CCR1[SCKHLD]+CCR1[SCKSET]
0572        So when changing either CCR[DBT] or CCR[SCKDIV] make sure the other value is not overwritten by 0 */
0573     base->CCR = base->CCR | LPSPI_CCR_DBT((base->CCR1 & LPSPI_CCR1_SCKSCK_MASK) >> LPSPI_CCR1_SCKSCK_SHIFT) |
0574                 LPSPI_CCR_SCKDIV(bestScaler);
0575 #else
0576     base->CCR = (base->CCR & ~LPSPI_CCR_SCKDIV_MASK) | LPSPI_CCR_SCKDIV(bestScaler);
0577 #endif /* FSL_FEATURE_LPSPI_HAS_CCR1 */
0578 
0579     /* return the best prescaler value for user to use later */
0580     *tcrPrescaleValue = bestPrescaler;
0581 
0582     /* return the actual calculated baud rate */
0583     return bestBaudrate;
0584 }
0585 
0586 /*!
0587  * brief Manually configures a specific LPSPI delay parameter (module must be disabled to
0588  *        change the delay values).
0589  *
0590  * This function configures the following:
0591  * SCK to PCS delay, or
0592  * PCS to SCK delay, or
0593  * The configurations must occur between the transfer delay.
0594  *
0595  * The delay names are available in type lpspi_delay_type_t.
0596  *
0597  * The user passes the desired delay along with the delay value.
0598  * This allows the user to directly set the delay values if they have
0599  * pre-calculated them or if they simply wish to manually increment the value.
0600  *
0601  * Note that the LPSPI module must first be disabled before configuring this.
0602  * Note that the LPSPI module must be configured for master mode before configuring this.
0603  *
0604  * param base LPSPI peripheral address.
0605  * param scaler The 8-bit delay value 0x00 to 0xFF (255).
0606  * param whichDelay The desired delay to configure, must be of type lpspi_delay_type_t.
0607  */
0608 void LPSPI_MasterSetDelayScaler(LPSPI_Type *base, uint32_t scaler, lpspi_delay_type_t whichDelay)
0609 {
0610     /*These settings are only relevant in master mode */
0611 #if defined(FSL_FEATURE_LPSPI_HAS_CCR1) && FSL_FEATURE_LPSPI_HAS_CCR1
0612     /* When CCR1 is present, the CCR[DBT] and CCR[SCKDIV] is write only, all read will return 0
0613        The real DBT and SCKDIV can be obtained in CCR1, CCR[DBT]=CCR1[SCKSCK] and CCR[SCKDIV]=CCR1[SCKHLD]+CCR1[SCKSET]
0614        So when changing either CCR[DBT] or CCR[SCKDIV] make sure the other value is not overwritten by 0 */
0615     uint32_t dbt    = (base->CCR1 & LPSPI_CCR1_SCKSCK_MASK) >> LPSPI_CCR1_SCKSCK_SHIFT;
0616     uint32_t sckdiv = (base->CCR1 & LPSPI_CCR1_SCKHLD_MASK) >> LPSPI_CCR1_SCKHLD_SHIFT;
0617     sckdiv += (base->CCR1 & LPSPI_CCR1_SCKSET_MASK) >> LPSPI_CCR1_SCKSET_SHIFT;
0618     switch (whichDelay)
0619     {
0620         case kLPSPI_PcsToSck:
0621             base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler) | LPSPI_CCR_DBT(dbt) |
0622                         LPSPI_CCR_SCKDIV(sckdiv);
0623 
0624             break;
0625         case kLPSPI_LastSckToPcs:
0626             base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler) | LPSPI_CCR_DBT(dbt) |
0627                         LPSPI_CCR_SCKDIV(sckdiv);
0628 
0629             break;
0630         case kLPSPI_BetweenTransfer:
0631             base->CCR = base->CCR | LPSPI_CCR_DBT(scaler) | LPSPI_CCR_SCKDIV(sckdiv);
0632 #else
0633     switch (whichDelay)
0634     {
0635         case kLPSPI_PcsToSck:
0636             base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler);
0637 
0638             break;
0639         case kLPSPI_LastSckToPcs:
0640             base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler);
0641 
0642             break;
0643         case kLPSPI_BetweenTransfer:
0644             base->CCR = (base->CCR & (~LPSPI_CCR_DBT_MASK)) | LPSPI_CCR_DBT(scaler);
0645 #endif /* FSL_FEATURE_LPSPI_HAS_CCR1 */
0646             break;
0647         default:
0648             assert(false);
0649             break;
0650     }
0651 }
0652 
0653 /*!
0654  * brief Calculates the delay based on the desired delay input in nanoseconds (module must be
0655  *        disabled to change the delay values).
0656  *
0657  * This function calculates the values for the following:
0658  * SCK to PCS delay, or
0659  * PCS to SCK delay, or
0660  * The configurations must occur between the transfer delay.
0661  *
0662  * The delay names are available in type lpspi_delay_type_t.
0663  *
0664  * The user passes the desired delay and the desired delay value in
0665  * nano-seconds.  The function calculates the value needed for the desired delay parameter
0666  * and returns the actual calculated delay because an exact delay match may not be possible. In this
0667  * case, the closest match is calculated without going below the desired delay value input.
0668  * It is possible to input a very large delay value that exceeds the capability of the part, in
0669  * which case the maximum supported delay is returned. It is up to the higher level
0670  * peripheral driver to alert the user of an out of range delay input.
0671  *
0672  * Note that the LPSPI module must be configured for master mode before configuring this. And note that
0673  * the delayTime = LPSPI_clockSource / (PRESCALE * Delay_scaler).
0674  *
0675  * param base LPSPI peripheral address.
0676  * param delayTimeInNanoSec The desired delay value in nano-seconds.
0677  * param whichDelay The desired delay to configuration, which must be of type lpspi_delay_type_t.
0678  * param srcClock_Hz  Module source input clock in Hertz.
0679  * return actual Calculated delay value in nano-seconds.
0680  */
0681 uint32_t LPSPI_MasterSetDelayTimes(LPSPI_Type *base,
0682                                    uint32_t delayTimeInNanoSec,
0683                                    lpspi_delay_type_t whichDelay,
0684                                    uint32_t srcClock_Hz)
0685 {
0686     uint64_t realDelay, bestDelay;
0687     uint32_t scaler, bestScaler;
0688     uint32_t diff, min_diff;
0689     uint64_t initialDelayNanoSec;
0690     uint32_t clockDividedPrescaler;
0691 
0692     /* For delay between transfer, an additional scaler value is needed */
0693     uint32_t additionalScaler = 0;
0694 
0695     /*As the RM note, the LPSPI baud rate clock is itself divided by the PRESCALE setting, which can vary between
0696      * transfers.*/
0697     clockDividedPrescaler =
0698         srcClock_Hz / s_baudratePrescaler[(base->TCR & LPSPI_TCR_PRESCALE_MASK) >> LPSPI_TCR_PRESCALE_SHIFT];
0699 
0700     /* Find combination of prescaler and scaler resulting in the delay closest to the requested value.*/
0701     min_diff = 0xFFFFFFFFU;
0702 
0703     /* Initialize scaler to max value to generate the max delay */
0704     bestScaler = 0xFFU;
0705 
0706     /* Calculate the initial (min) delay and maximum possible delay based on the specific delay as
0707      * the delay divisors are slightly different based on which delay we are configuring.
0708      */
0709     if (whichDelay == kLPSPI_BetweenTransfer)
0710     {
0711         /* First calculate the initial, default delay, note min delay is 2 clock cycles. Due to large size of
0712          calculated values (uint64_t), we need to break up the calculation into several steps to ensure
0713          accurate calculated results
0714          */
0715         initialDelayNanoSec = 1000000000U;
0716         initialDelayNanoSec *= 2U;
0717         initialDelayNanoSec /= clockDividedPrescaler;
0718 
0719         /* Calculate the maximum delay */
0720         bestDelay = 1000000000U;
0721         bestDelay *= 257U; /* based on DBT+2, or 255 + 2 */
0722         bestDelay /= clockDividedPrescaler;
0723 
0724         additionalScaler = 1U;
0725     }
0726     else
0727     {
0728         /* First calculate the initial, default delay, min delay is 1 clock cycle. Due to large size of calculated
0729         values (uint64_t), we need to break up the calculation into several steps to ensure accurate calculated
0730         results.
0731         */
0732         initialDelayNanoSec = 1000000000U;
0733         initialDelayNanoSec /= clockDividedPrescaler;
0734 
0735         /* Calculate the maximum delay */
0736         bestDelay = 1000000000U;
0737         bestDelay *= 256U; /* based on SCKPCS+1 or PCSSCK+1, or 255 + 1 */
0738         bestDelay /= clockDividedPrescaler;
0739 
0740         additionalScaler = 0U;
0741     }
0742 
0743     /* If the initial, default delay is already greater than the desired delay, then
0744      * set the delay to their initial value (0) and return the delay. In other words,
0745      * there is no way to decrease the delay value further.
0746      */
0747     if (initialDelayNanoSec >= delayTimeInNanoSec)
0748     {
0749         LPSPI_MasterSetDelayScaler(base, 0, whichDelay);
0750         return (uint32_t)initialDelayNanoSec;
0751     }
0752 
0753     /* If min_diff = 0, the exit for loop */
0754     for (scaler = 0U; scaler < 256U; scaler++)
0755     {
0756         if (min_diff == 0U)
0757         {
0758             break;
0759         }
0760         /* Calculate the real delay value as we cycle through the scaler values.
0761         Due to large size of calculated values (uint64_t), we need to break up the
0762         calculation into several steps to ensure accurate calculated results
0763         */
0764         realDelay = 1000000000U;
0765         realDelay *= ((uint64_t)scaler + 1UL + (uint64_t)additionalScaler);
0766         realDelay /= clockDividedPrescaler;
0767 
0768         /* calculate the delay difference based on the conditional statement
0769          * that states that the calculated delay must not be less then the desired delay
0770          */
0771         if (realDelay >= delayTimeInNanoSec)
0772         {
0773             diff = (uint32_t)(realDelay - (uint64_t)delayTimeInNanoSec);
0774             if (min_diff > diff)
0775             {
0776                 /* a better match found */
0777                 min_diff   = diff;
0778                 bestScaler = scaler;
0779                 bestDelay  = realDelay;
0780             }
0781         }
0782     }
0783 
0784     /* write the best scaler value for the delay */
0785     LPSPI_MasterSetDelayScaler(base, bestScaler, whichDelay);
0786 
0787     /* return the actual calculated delay value (in ns) */
0788     return (uint32_t)bestDelay;
0789 }
0790 
0791 /*Transactional APIs -- Master*/
0792 
0793 /*!
0794  * brief Initializes the LPSPI master handle.
0795  *
0796  * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs.  Usually, for a
0797  * specified LPSPI instance, call this API once to get the initialized handle.
0798 
0799  * param base LPSPI peripheral address.
0800  * param handle LPSPI handle pointer to lpspi_master_handle_t.
0801  * param callback DSPI callback.
0802  * param userData callback function parameter.
0803  */
0804 void LPSPI_MasterTransferCreateHandle(LPSPI_Type *base,
0805                                       lpspi_master_handle_t *handle,
0806                                       lpspi_master_transfer_callback_t callback,
0807                                       void *userData)
0808 {
0809     assert(handle != NULL);
0810 
0811     /* Zero the handle. */
0812     (void)memset(handle, 0, sizeof(*handle));
0813 
0814     s_lpspiHandle[LPSPI_GetInstance(base)] = handle;
0815 
0816     /* Set irq handler. */
0817     s_lpspiMasterIsr = LPSPI_MasterTransferHandleIRQ;
0818 
0819     handle->callback = callback;
0820     handle->userData = userData;
0821 }
0822 
0823 /*!
0824  * brief Check the argument for transfer .
0825  *
0826  * param base LPSPI peripheral address.
0827  * param transfer the transfer struct to be used.
0828  * param isEdma True to check for EDMA transfer, false to check interrupt non-blocking transfer
0829  * return Return true for right and false for wrong.
0830  */
0831 bool LPSPI_CheckTransferArgument(LPSPI_Type *base, lpspi_transfer_t *transfer, bool isEdma)
0832 {
0833     assert(transfer != NULL);
0834     uint32_t bitsPerFrame  = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U;
0835     uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U;
0836     uint32_t temp          = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
0837     /* If the transfer count is zero, then return immediately.*/
0838     if (transfer->dataSize == 0U)
0839     {
0840         return false;
0841     }
0842 
0843     /* If both send buffer and receive buffer is null */
0844     if ((NULL == (transfer->txData)) && (NULL == (transfer->rxData)))
0845     {
0846         return false;
0847     }
0848 
0849     /*The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4 .
0850      *For bytesPerFrame greater than 4 situation:
0851      *the transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4 ,
0852      *otherwise , the transfer data size can be integer multiples of bytesPerFrame.
0853      */
0854     if (bytesPerFrame <= 4U)
0855     {
0856         if ((transfer->dataSize % bytesPerFrame) != 0U)
0857         {
0858             return false;
0859         }
0860     }
0861     else
0862     {
0863         if ((bytesPerFrame % 4U) != 0U)
0864         {
0865             if (transfer->dataSize != bytesPerFrame)
0866             {
0867                 return false;
0868             }
0869         }
0870         else
0871         {
0872             if ((transfer->dataSize % bytesPerFrame) != 0U)
0873             {
0874                 return false;
0875             }
0876         }
0877     }
0878 
0879     /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */
0880     if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut)))
0881     {
0882         /* The 3-wire mode can't send and receive data at the same time. */
0883         if ((transfer->txData != NULL) && (transfer->rxData != NULL))
0884         {
0885             return false;
0886         }
0887         if (NULL == transfer->txData)
0888         {
0889             base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK;
0890         }
0891     }
0892 
0893     if (isEdma && ((bytesPerFrame % 4U) == 3U))
0894     {
0895         return false;
0896     }
0897 
0898     return true;
0899 }
0900 
0901 static bool LPSPI_MasterTransferWriteAllTxData(LPSPI_Type *base,
0902                                                lpspi_transfer_t *transfer,
0903                                                lpspi_transfer_blocking_param_t *stateParams)
0904 {
0905     uint8_t dummyData             = g_lpspiDummyData[LPSPI_GetInstance(base)];
0906     uint32_t bytesPerFrame        = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
0907     uint32_t txRemainingByteCount = transfer->dataSize;
0908     bool isByteSwap               = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
0909     uint32_t wordToSend =
0910         ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
0911     uint32_t rxFifoMaxBytes = MIN(bytesPerFrame, 4U) * LPSPI_GetRxFifoSize(base);
0912     uint32_t readData;
0913     /*Write the TX data until txRemainingByteCount is equal to 0 */
0914     while (txRemainingByteCount > 0U)
0915     {
0916         if (txRemainingByteCount < (stateParams->bytesEachWrite))
0917         {
0918             (stateParams->bytesEachWrite) = (uint8_t)txRemainingByteCount;
0919         }
0920 
0921         /*Wait until TX FIFO is not full*/
0922 #if SPI_RETRY_TIMES
0923         uint32_t waitTimes = SPI_RETRY_TIMES;
0924         while ((LPSPI_GetTxFifoCount(base) == LPSPI_GetRxFifoSize(base)) && (--waitTimes) != 0U))
0925 #else
0926         while (LPSPI_GetTxFifoCount(base) == LPSPI_GetRxFifoSize(base))
0927 #endif
0928             {
0929             }
0930 #if SPI_RETRY_TIMES
0931         if (waitTimes == 0U)
0932         {
0933             return false;
0934         }
0935 #endif
0936 
0937         /* To prevent rxfifo overflow, ensure transmitting and receiving are executed in parallel */
0938         if (((NULL == (transfer->rxData)) ||
0939              ((stateParams->rxRemainingByteCount) - txRemainingByteCount) < rxFifoMaxBytes))
0940         {
0941             if (stateParams->isTxMask)
0942             {
0943                 /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared
0944                    by hardware every time when TCR[FRAMESZ] bit of data is transfered.
0945                    In this case TCR[TXMSK] should be set to initiate each transfer. */
0946                 base->TCR |= LPSPI_TCR_TXMSK_MASK;
0947                 if (stateParams->isPcsContinuous && (txRemainingByteCount == bytesPerFrame))
0948                 {
0949                     /* For the last piece of frame size of data, if is PCS continous mode(TCR[CONT]), TCR[CONTC] should
0950                      * be cleared to de-assert the PCS. Be sure to clear the TXMSK as well otherwise another FRAMESZ
0951                      * of data will be received. */
0952                     base->TCR &= ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK | LPSPI_TCR_TXMSK_MASK);
0953                 }
0954                 txRemainingByteCount -= bytesPerFrame;
0955             }
0956             else
0957             {
0958                 if ((transfer->txData) != NULL)
0959                 {
0960                     wordToSend = LPSPI_CombineWriteData((transfer->txData), (stateParams->bytesEachWrite), isByteSwap);
0961                     (transfer->txData) += (stateParams->bytesEachWrite);
0962                 }
0963                 /* Otherwise push data to tx FIFO to initiate transfer */
0964                 LPSPI_WriteData(base, wordToSend);
0965                 txRemainingByteCount -= (stateParams->bytesEachWrite);
0966             }
0967         }
0968 
0969         /* Check whether there is RX data in RX FIFO . Read out the RX data so that the RX FIFO would not overrun. */
0970         if (((transfer->rxData) != NULL) && ((stateParams->rxRemainingByteCount) != 0U))
0971         {
0972             /* To ensure parallel execution in 3-wire mode, after writting 1 to TXMSK to generate clock of
0973                bytesPerFrame's data wait until bytesPerFrame's data is received. */
0974             while ((stateParams->isTxMask) && (LPSPI_GetRxFifoCount(base) == 0U))
0975             {
0976             }
0977 #if SPI_RETRY_TIMES
0978             uint32_t waitTimes = SPI_RETRY_TIMES;
0979             while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U))
0980 #else
0981             while (LPSPI_GetRxFifoCount(base) != 0U)
0982 #endif
0983             {
0984                 readData = LPSPI_ReadData(base);
0985                 if ((stateParams->rxRemainingByteCount) < (stateParams->bytesEachRead))
0986                 {
0987                     (stateParams->bytesEachRead) = (uint8_t)(stateParams->rxRemainingByteCount);
0988                 }
0989 
0990                 LPSPI_SeparateReadData((transfer->rxData), readData, (stateParams->bytesEachRead), isByteSwap);
0991                 (transfer->rxData) += (stateParams->bytesEachRead);
0992 
0993                 (stateParams->rxRemainingByteCount) -= (stateParams->bytesEachRead);
0994             }
0995 #if SPI_RETRY_TIMES
0996             if (waitTimes == 0U)
0997             {
0998                 return false;
0999             }
1000 #endif
1001         }
1002     }
1003     return true;
1004 }
1005 
1006 static bool LPSPI_MasterTransferClearTCR(LPSPI_Type *base, lpspi_transfer_blocking_param_t *stateParams)
1007 {
1008 #if SPI_RETRY_TIMES
1009     uint32_t waitTimes = SPI_RETRY_TIMES;
1010     while ((LPSPI_GetTxFifoCount(base) == LPSPI_GetRxFifoSize(base)) && (--waitTimes != 0U))
1011 #else
1012     while (LPSPI_GetTxFifoCount(base) == LPSPI_GetRxFifoSize(base))
1013 #endif
1014     {
1015     }
1016 #if SPI_RETRY_TIMES
1017     if (waitTimes == 0U)
1018     {
1019         return false;
1020     }
1021 #endif
1022     base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK));
1023     return true;
1024 }
1025 
1026 static bool LPSPI_MasterTransferReadDataInFifo(LPSPI_Type *base,
1027                                                lpspi_transfer_t *transfer,
1028                                                lpspi_transfer_blocking_param_t *stateParams)
1029 {
1030     uint32_t readData;
1031     bool isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
1032     while ((stateParams->rxRemainingByteCount) > 0U)
1033     {
1034 #if SPI_RETRY_TIMES
1035         uint32_t waitTimes = SPI_RETRY_TIMES;
1036         while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U))
1037 #else
1038         while (LPSPI_GetRxFifoCount(base) != 0U)
1039 #endif
1040         {
1041             readData = LPSPI_ReadData(base);
1042 
1043             if ((stateParams->rxRemainingByteCount) < (stateParams->bytesEachRead))
1044             {
1045                 (stateParams->bytesEachRead) = (uint8_t)(stateParams->rxRemainingByteCount);
1046             }
1047 
1048             LPSPI_SeparateReadData((transfer->rxData), readData, (stateParams->bytesEachRead), isByteSwap);
1049             (transfer->rxData) += (stateParams->bytesEachRead);
1050 
1051             (stateParams->rxRemainingByteCount) -= (stateParams->bytesEachRead);
1052         }
1053 #if SPI_RETRY_TIMES
1054         if (waitTimes == 0U)
1055         {
1056             return false;
1057         }
1058 #endif
1059     }
1060     return true;
1061 }
1062 
1063 static bool LPSPI_MasterTransferReadDataInFifoNoBuf(LPSPI_Type *base, lpspi_transfer_blocking_param_t *stateParams)
1064 {
1065 #if SPI_RETRY_TIMES
1066     uint32_t waitTimes = SPI_RETRY_TIMES;
1067     while (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U) && (--waitTimes != 0U))
1068 #else
1069     while ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U)
1070 #endif
1071     {
1072     }
1073 #if SPI_RETRY_TIMES
1074     if (waitTimes == 0U)
1075     {
1076         return false;
1077     }
1078 #endif
1079     return true;
1080 }
1081 
1082 /*!
1083  * brief LPSPI master transfer data using a polling method.
1084  *
1085  * This function transfers data using a  polling method. This is a blocking function, which does not return until all
1086  * transfers have been completed.
1087  *
1088  * Note:
1089  * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
1090  * For bytesPerFrame greater than 4:
1091  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4.
1092  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
1093  *
1094  * param base LPSPI peripheral address.
1095  * param transfer pointer to lpspi_transfer_t structure.
1096  * return status of status_t.
1097  */
1098 status_t LPSPI_MasterTransferBlocking(LPSPI_Type *base, lpspi_transfer_t *transfer)
1099 {
1100     assert(transfer != NULL);
1101 
1102     /* Check that LPSPI is not busy.*/
1103     if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ModuleBusyFlag) != 0U)
1104     {
1105         return kStatus_LPSPI_Busy;
1106     }
1107     LPSPI_Enable(base, false);
1108     /* Check arguements */
1109     if (!LPSPI_CheckTransferArgument(base, transfer, false))
1110     {
1111         return kStatus_InvalidArgument;
1112     }
1113 
1114     LPSPI_FlushFifo(base, true, true);
1115     LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
1116 
1117     /* Variables */
1118     uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
1119     uint32_t temp     = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
1120     lpspi_transfer_blocking_param_t stateParams;
1121     (void)memset(&stateParams, 0, sizeof(stateParams));
1122 
1123     stateParams.isTxMask             = false;
1124     stateParams.rxRemainingByteCount = transfer->dataSize;
1125     /*The TX and RX FIFO sizes are always the same*/
1126     uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
1127     /* No need to configure PCS continous if the transfer byte count is smaller than frame size */
1128     stateParams.isPcsContinuous = (((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U) &&
1129                                    (bytesPerFrame < transfer->dataSize));
1130 
1131     /* Mask tx data in half duplex mode */
1132     if (((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) &&
1133         (transfer->txData == NULL))
1134     {
1135         stateParams.isTxMask = true;
1136     }
1137 
1138     base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
1139     LPSPI_Enable(base, true);
1140 
1141     /* Configure transfer control register. */
1142     base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
1143                                LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
1144                 LPSPI_TCR_PCS(whichPcs);
1145 
1146     /*TCR is also shared the FIFO, so wait for TCR written.*/
1147     if (!LPSPI_TxFifoReady(base))
1148     {
1149         return kStatus_LPSPI_Timeout;
1150     }
1151 
1152     /* PCS should be configured separately from the other bits, otherwise it will not take effect. */
1153     base->TCR |= LPSPI_TCR_CONT(stateParams.isPcsContinuous) | LPSPI_TCR_CONTC(stateParams.isPcsContinuous) |
1154                  LPSPI_TCR_RXMSK(NULL == transfer->rxData);
1155 
1156     /*TCR is also shared the FIFO, so wait for TCR written.*/
1157     if (!LPSPI_TxFifoReady(base))
1158     {
1159         return kStatus_LPSPI_Timeout;
1160     }
1161 
1162     if (bytesPerFrame <= 4U)
1163     {
1164         stateParams.bytesEachWrite = (uint8_t)bytesPerFrame;
1165         stateParams.bytesEachRead  = (uint8_t)bytesPerFrame;
1166     }
1167     else
1168     {
1169         stateParams.bytesEachWrite = 4U;
1170         stateParams.bytesEachRead  = 4U;
1171     }
1172 
1173     if (false == LPSPI_MasterTransferWriteAllTxData(base, transfer, &stateParams))
1174     {
1175         return kStatus_LPSPI_Timeout;
1176     }
1177 
1178     if (stateParams.isPcsContinuous && !stateParams.isTxMask)
1179     {
1180         /* In PCS continous mode(TCR[CONT]), after write all the data in TX FIFO, TCR[CONTC] and TCR[CONT] should be
1181            cleared to de-assert the PCS. Note that TCR register also use the TX FIFO. Also CONTC should be cleared when
1182            tx is not masked, otherwise written to TCR register with TXMSK bit wet will initiate a new transfer. */
1183         if (false == LPSPI_MasterTransferClearTCR(base, &stateParams))
1184         {
1185             return kStatus_LPSPI_Timeout;
1186         }
1187     }
1188 
1189     /*Read out the RX data in FIFO*/
1190     if (transfer->rxData != NULL)
1191     {
1192         if (false == LPSPI_MasterTransferReadDataInFifo(base, transfer, &stateParams))
1193         {
1194             return kStatus_LPSPI_Timeout;
1195         }
1196     }
1197     else
1198     {
1199         /* If no RX buffer, then transfer is not complete until transfer complete flag sets */
1200         if (false == LPSPI_MasterTransferReadDataInFifoNoBuf(base, &stateParams))
1201         {
1202             return kStatus_LPSPI_Timeout;
1203         }
1204     }
1205 
1206     return kStatus_Success;
1207 }
1208 
1209 /*!
1210  * brief LPSPI master transfer data using an interrupt method.
1211  *
1212  * This function transfers data using an interrupt method. This is a non-blocking function, which returns right away.
1213  * When all data is transferred, the callback function is called.
1214  *
1215  * Note:
1216  * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
1217  * For bytesPerFrame greater than 4:
1218  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4.
1219  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
1220  *
1221  * param base LPSPI peripheral address.
1222  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1223  * param transfer pointer to lpspi_transfer_t structure.
1224  * return status of status_t.
1225  */
1226 status_t LPSPI_MasterTransferNonBlocking(LPSPI_Type *base, lpspi_master_handle_t *handle, lpspi_transfer_t *transfer)
1227 {
1228     assert(handle != NULL);
1229     assert(transfer != NULL);
1230 
1231     /* Check that we're not busy.*/
1232     if (handle->state == (uint8_t)kLPSPI_Busy)
1233     {
1234         return kStatus_LPSPI_Busy;
1235     }
1236 
1237     LPSPI_Enable(base, false);
1238     /* Check arguements */
1239     if (!LPSPI_CheckTransferArgument(base, transfer, false))
1240     {
1241         return kStatus_InvalidArgument;
1242     }
1243 
1244     /* Flush FIFO, clear status, disable all the interrupts. */
1245     LPSPI_FlushFifo(base, true, true);
1246     LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
1247     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1248 
1249     /* Variables */
1250     bool isRxMask = false;
1251     uint8_t txWatermark;
1252     uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)];
1253     uint32_t tmpTimes;
1254     uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
1255     uint32_t temp     = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
1256 
1257     /* Assign the original value for members of transfer handle. */
1258     handle->state                = (uint8_t)kLPSPI_Busy;
1259     handle->txData               = transfer->txData;
1260     handle->rxData               = transfer->rxData;
1261     handle->txRemainingByteCount = transfer->dataSize;
1262     handle->rxRemainingByteCount = transfer->dataSize;
1263     handle->totalByteCount       = transfer->dataSize;
1264     handle->writeTcrInIsr        = false;
1265     handle->bytesPerFrame = (uint16_t)((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
1266     /* No need to configure PCS continous if the transfer byte count is smaller than frame size */
1267     bool isPcsContinuous = (((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U) &&
1268                             (transfer->dataSize > handle->bytesPerFrame));
1269     handle->writeRegRemainingTimes =
1270         (transfer->dataSize / (uint32_t)handle->bytesPerFrame) * (((uint32_t)handle->bytesPerFrame + 3U) / 4U);
1271     handle->readRegRemainingTimes = handle->writeRegRemainingTimes;
1272     handle->txBuffIfNull =
1273         ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
1274     /*The TX and RX FIFO sizes are always the same*/
1275     handle->fifoSize        = LPSPI_GetRxFifoSize(base);
1276     handle->isPcsContinuous = isPcsContinuous;
1277     handle->isByteSwap      = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
1278     /*Calculate the bytes for write/read the TX/RX register each time*/
1279     if (handle->bytesPerFrame <= 4U)
1280     {
1281         handle->bytesEachWrite = (uint8_t)handle->bytesPerFrame;
1282         handle->bytesEachRead  = (uint8_t)handle->bytesPerFrame;
1283     }
1284     else
1285     {
1286         handle->bytesEachWrite = 4U;
1287         handle->bytesEachRead  = 4U;
1288     }
1289 
1290     /*Set the RX and TX watermarks to reduce the ISR times.*/
1291     if (handle->fifoSize > 1U)
1292     {
1293         txWatermark         = 1U;
1294         handle->rxWatermark = handle->fifoSize - 2U;
1295     }
1296     else
1297     {
1298         txWatermark         = 0U;
1299         handle->rxWatermark = 0U;
1300     }
1301     LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
1302 
1303     /* If there is no rxData, mask the receive data so that receive data is not stored in receive FIFO. */
1304     if (handle->rxData == NULL)
1305     {
1306         isRxMask                     = true;
1307         handle->rxRemainingByteCount = 0;
1308     }
1309 
1310     /* Mask tx data in half duplex mode since the tx/rx share the same pin, so that the data received from slave is not
1311      * interfered. */
1312     if (((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) &&
1313         (handle->txData == NULL))
1314     {
1315         handle->isTxMask = true;
1316     }
1317 
1318     /*Transfers will stall when transmit FIFO is empty or receive FIFO is full. */
1319     base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
1320 
1321     /* Enable module for following configuration of TCR to take effect. */
1322     LPSPI_Enable(base, true);
1323 
1324     /* Configure transfer control register. */
1325     base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
1326                                LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
1327                 LPSPI_TCR_PCS(whichPcs);
1328 
1329     /*TCR is also shared the FIFO , so wait for TCR written.*/
1330     if (!LPSPI_TxFifoReady(base))
1331     {
1332         return kStatus_LPSPI_Timeout;
1333     }
1334 
1335     /* PCS should be configured separately from the other bits, otherwise it will not take effect. */
1336     base->TCR |= LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(isPcsContinuous) | LPSPI_TCR_RXMSK(isRxMask);
1337 
1338     /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
1339      * and you should also enable the INTMUX interupt in your application.
1340      */
1341     (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
1342 
1343     /*TCR is also shared the FIFO , so wait for TCR written.*/
1344     if (!LPSPI_TxFifoReady(base))
1345     {
1346         return kStatus_LPSPI_Timeout;
1347     }
1348 
1349     if (handle->isTxMask)
1350     {
1351         /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared by
1352            hardware every time when TCR[FRAMESZ] bit of data is transfered. In this case TCR[TXMSK] should be set to
1353            initiate each transfer. */
1354 
1355         base->TCR |= LPSPI_TCR_TXMSK_MASK;
1356         handle->txRemainingByteCount -= (uint32_t)handle->bytesPerFrame;
1357     }
1358     else
1359     {
1360         /* Fill up the TX data in FIFO to initiate transfer */
1361         LPSPI_MasterTransferFillUpTxFifo(base, handle);
1362     }
1363 
1364     /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
1365      * The IRQ handler will get the status of RX and TX interrupt flags.
1366      */
1367     if (handle->rxData != NULL)
1368     {
1369         if (handle->isTxMask)
1370         {
1371             /* if tx data is masked, transfer is initiated by writing 1 to TCR[TXMSK] and TCR[FRMESZ] bits of data is
1372                read. If rx water mark is set larger than TCR[FRMESZ], rx interrupt will not be generated. Lower the rx
1373                water mark setting */
1374             if ((handle->bytesPerFrame / 4U) < (uint16_t)handle->rxWatermark)
1375             {
1376                 handle->rxWatermark =
1377                     (uint8_t)(handle->bytesPerFrame / 4U) > 0U ? (uint8_t)(handle->bytesPerFrame / 4U - 1U) : 0U;
1378                 base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(handle->rxWatermark);
1379             }
1380         }
1381         else
1382         {
1383             /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise
1384              *there is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
1385              */
1386             tmpTimes = handle->readRegRemainingTimes;
1387             if (tmpTimes <= handle->rxWatermark)
1388             {
1389                 base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(tmpTimes - 1U);
1390             }
1391         }
1392 
1393         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
1394     }
1395     else
1396     {
1397         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable);
1398     }
1399 
1400     return kStatus_Success;
1401 }
1402 
1403 static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle)
1404 {
1405     assert(handle != NULL);
1406 
1407     uint32_t wordToSend             = 0;
1408     uint8_t fifoSize                = handle->fifoSize;
1409     uint32_t writeRegRemainingTimes = handle->writeRegRemainingTimes;
1410     uint32_t readRegRemainingTimes  = handle->readRegRemainingTimes;
1411     size_t txRemainingByteCount     = handle->txRemainingByteCount;
1412     uint8_t bytesEachWrite          = handle->bytesEachWrite;
1413     bool isByteSwap                 = handle->isByteSwap;
1414 
1415     /* Make sure the difference in remaining TX and RX byte counts does not exceed FIFO depth
1416      * and that the number of TX FIFO entries does not exceed the FIFO depth.
1417      * But no need to make the protection if there is no rxData.
1418      */
1419     while ((LPSPI_GetTxFifoCount(base) < fifoSize) &&
1420            (((readRegRemainingTimes - writeRegRemainingTimes) < (uint32_t)fifoSize) || (handle->rxData == NULL)))
1421     {
1422         if (txRemainingByteCount < (size_t)bytesEachWrite)
1423         {
1424             handle->bytesEachWrite = (uint8_t)txRemainingByteCount;
1425             bytesEachWrite         = handle->bytesEachWrite;
1426         }
1427 
1428         if (handle->txData != NULL)
1429         {
1430             wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap);
1431             handle->txData += bytesEachWrite;
1432         }
1433         else
1434         {
1435             wordToSend = handle->txBuffIfNull;
1436         }
1437 
1438         /*Write the word to TX register*/
1439         LPSPI_WriteData(base, wordToSend);
1440 
1441         /*Decrease the write TX register times.*/
1442         --handle->writeRegRemainingTimes;
1443         writeRegRemainingTimes = handle->writeRegRemainingTimes;
1444 
1445         /*Decrease the remaining TX byte count.*/
1446         handle->txRemainingByteCount -= (size_t)bytesEachWrite;
1447         txRemainingByteCount = handle->txRemainingByteCount;
1448 
1449         if (handle->txRemainingByteCount == 0U)
1450         {
1451             /* If PCS is continuous, update TCR to de-assert PCS */
1452             if (handle->isPcsContinuous)
1453             {
1454                 /* Only write to the TCR if the FIFO has room */
1455                 if (LPSPI_GetTxFifoCount(base) < fifoSize)
1456                 {
1457                     base->TCR             = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
1458                     handle->writeTcrInIsr = false;
1459                 }
1460                 /* Else, set a global flag to tell the ISR to do write to the TCR */
1461                 else
1462                 {
1463                     handle->writeTcrInIsr = true;
1464                 }
1465             }
1466             break;
1467         }
1468     }
1469 }
1470 
1471 static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle)
1472 {
1473     assert(handle != NULL);
1474 
1475     /* Disable interrupt requests*/
1476     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1477 
1478     handle->state = (uint8_t)kLPSPI_Idle;
1479 
1480     if (handle->callback != NULL)
1481     {
1482         handle->callback(base, handle, kStatus_Success, handle->userData);
1483     }
1484 }
1485 
1486 /*!
1487  * brief Gets the master transfer remaining bytes.
1488  *
1489  * This function gets the master transfer remaining bytes.
1490  *
1491  * param base LPSPI peripheral address.
1492  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1493  * param count Number of bytes transferred so far by the non-blocking transaction.
1494  * return status of status_t.
1495  */
1496 status_t LPSPI_MasterTransferGetCount(LPSPI_Type *base, lpspi_master_handle_t *handle, size_t *count)
1497 {
1498     assert(handle != NULL);
1499 
1500     if (NULL == count)
1501     {
1502         return kStatus_InvalidArgument;
1503     }
1504 
1505     /* Catch when there is not an active transfer. */
1506     if (handle->state != (uint8_t)kLPSPI_Busy)
1507     {
1508         *count = 0;
1509         return kStatus_NoTransferInProgress;
1510     }
1511 
1512     size_t remainingByte;
1513 
1514     if (handle->rxData != NULL)
1515     {
1516         remainingByte = handle->rxRemainingByteCount;
1517     }
1518     else
1519     {
1520         remainingByte = handle->txRemainingByteCount;
1521     }
1522 
1523     *count = handle->totalByteCount - remainingByte;
1524 
1525     return kStatus_Success;
1526 }
1527 
1528 /*!
1529  * brief LPSPI master abort transfer which uses an interrupt method.
1530  *
1531  * This function aborts a transfer which uses an interrupt method.
1532  *
1533  * param base LPSPI peripheral address.
1534  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1535  */
1536 void LPSPI_MasterTransferAbort(LPSPI_Type *base, lpspi_master_handle_t *handle)
1537 {
1538     assert(handle != NULL);
1539 
1540     /* Disable interrupt requests*/
1541     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1542 
1543     LPSPI_Reset(base);
1544 
1545     handle->state                = (uint8_t)kLPSPI_Idle;
1546     handle->txRemainingByteCount = 0;
1547     handle->rxRemainingByteCount = 0;
1548 }
1549 
1550 /*!
1551  * brief LPSPI Master IRQ handler function.
1552  *
1553  * This function processes the LPSPI transmit and receive IRQ.
1554  *
1555  * param base LPSPI peripheral address.
1556  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1557  */
1558 void LPSPI_MasterTransferHandleIRQ(LPSPI_Type *base, lpspi_master_handle_t *handle)
1559 {
1560     assert(handle != NULL);
1561 
1562     uint32_t readData;
1563     uint8_t bytesEachRead          = handle->bytesEachRead;
1564     bool isByteSwap                = handle->isByteSwap;
1565     uint32_t readRegRemainingTimes = handle->readRegRemainingTimes;
1566 
1567     if (handle->rxData != NULL)
1568     {
1569         if (handle->rxRemainingByteCount != 0U)
1570         {
1571             /* First, disable the interrupts to avoid potentially triggering another interrupt
1572              * while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
1573              * re-enable the interrupts based on the LPSPI state after reading out the FIFO.
1574              */
1575             LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
1576 
1577             while ((LPSPI_GetRxFifoCount(base) != 0U) && (handle->rxRemainingByteCount != 0U))
1578             {
1579                 /*Read out the data*/
1580                 readData = LPSPI_ReadData(base);
1581 
1582                 /*Decrease the read RX register times.*/
1583                 --handle->readRegRemainingTimes;
1584                 readRegRemainingTimes = handle->readRegRemainingTimes;
1585 
1586                 if (handle->rxRemainingByteCount < (size_t)bytesEachRead)
1587                 {
1588                     handle->bytesEachRead = (uint8_t)(handle->rxRemainingByteCount);
1589                     bytesEachRead         = handle->bytesEachRead;
1590                 }
1591 
1592                 LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap);
1593                 handle->rxData += bytesEachRead;
1594 
1595                 /*Decrease the remaining RX byte count.*/
1596                 handle->rxRemainingByteCount -= (size_t)bytesEachRead;
1597             }
1598 
1599             /* Re-enable the interrupts only if rxCount indicates there is more data to receive,
1600              * else we may get a spurious interrupt.
1601              * */
1602             if (handle->rxRemainingByteCount != 0U)
1603             {
1604                 /* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
1605                 LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
1606             }
1607         }
1608 
1609         /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
1610          *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
1611          */
1612         if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
1613         {
1614             base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
1615                         LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U));
1616         }
1617     }
1618 
1619     if (handle->txRemainingByteCount != 0U)
1620     {
1621         if (handle->isTxMask)
1622         {
1623             /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared by
1624                hardware every time when TCR[FRAMESZ] bit of data is transfered.
1625                In this case TCR[TXMSK] should be set to initiate each transfer. */
1626             base->TCR |= LPSPI_TCR_TXMSK_MASK;
1627             if ((handle->txRemainingByteCount == (uint32_t)handle->bytesPerFrame) && (handle->isPcsContinuous))
1628             {
1629                 /* For the last piece of frame size of data, if is PCS continous mode(TCR[CONT]), TCR[CONTC] should
1630                  * be cleared to de-assert the PCS. Be sure to clear the TXMSK as well otherwise another FRAMESZ
1631                  * of data will be received. */
1632                 base->TCR &= ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK | LPSPI_TCR_TXMSK_MASK);
1633             }
1634             handle->txRemainingByteCount -= (uint32_t)handle->bytesPerFrame;
1635         }
1636         else
1637         {
1638             LPSPI_MasterTransferFillUpTxFifo(base, handle);
1639         }
1640     }
1641     else
1642     {
1643         if ((LPSPI_GetTxFifoCount(base) < (handle->fifoSize)))
1644         {
1645             if ((handle->isPcsContinuous) && (handle->writeTcrInIsr) && (!handle->isTxMask))
1646             {
1647                 base->TCR             = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
1648                 handle->writeTcrInIsr = false;
1649             }
1650         }
1651     }
1652 
1653     if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U) && (!handle->writeTcrInIsr))
1654     {
1655         /* If no RX buffer, then transfer is not complete until transfer complete flag sets */
1656         if (handle->rxData == NULL)
1657         {
1658             if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) != 0U)
1659             {
1660                 LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransferCompleteFlag);
1661                 /* Complete the transfer and disable the interrupts */
1662                 LPSPI_MasterTransferComplete(base, handle);
1663             }
1664             else
1665             {
1666                 LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransferCompleteInterruptEnable);
1667                 LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
1668             }
1669         }
1670         else
1671         {
1672             /* Complete the transfer and disable the interrupts */
1673             LPSPI_MasterTransferComplete(base, handle);
1674         }
1675     }
1676 }
1677 
1678 /*Transactional APIs -- Slave*/
1679 /*!
1680  * brief Initializes the LPSPI slave handle.
1681  *
1682  * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs.  Usually, for a
1683  * specified LPSPI instance, call this API once to get the initialized handle.
1684  *
1685  * param base LPSPI peripheral address.
1686  * param handle LPSPI handle pointer to lpspi_slave_handle_t.
1687  * param callback DSPI callback.
1688  * param userData callback function parameter.
1689  */
1690 void LPSPI_SlaveTransferCreateHandle(LPSPI_Type *base,
1691                                      lpspi_slave_handle_t *handle,
1692                                      lpspi_slave_transfer_callback_t callback,
1693                                      void *userData)
1694 {
1695     assert(handle != NULL);
1696 
1697     /* Zero the handle. */
1698     (void)memset(handle, 0, sizeof(*handle));
1699 
1700     s_lpspiHandle[LPSPI_GetInstance(base)] = handle;
1701 
1702     /* Set irq handler. */
1703     s_lpspiSlaveIsr = LPSPI_SlaveTransferHandleIRQ;
1704 
1705     handle->callback = callback;
1706     handle->userData = userData;
1707 }
1708 
1709 /*!
1710  * brief LPSPI slave transfer data using an interrupt method.
1711  *
1712  * This function transfer data using an interrupt method. This is a non-blocking function, which returns right away.
1713  * When all data is transferred, the callback function is called.
1714  *
1715  * Note:
1716  * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
1717  * For bytesPerFrame greater than 4:
1718  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
1719  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
1720  *
1721  * param base LPSPI peripheral address.
1722  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1723  * param transfer pointer to lpspi_transfer_t structure.
1724  * return status of status_t.
1725  */
1726 status_t LPSPI_SlaveTransferNonBlocking(LPSPI_Type *base, lpspi_slave_handle_t *handle, lpspi_transfer_t *transfer)
1727 {
1728     assert(handle != NULL);
1729     assert(transfer != NULL);
1730 
1731     /* Check that we're not busy.*/
1732     if (handle->state == (uint8_t)kLPSPI_Busy)
1733     {
1734         return kStatus_LPSPI_Busy;
1735     }
1736     LPSPI_Enable(base, false);
1737     /* Check arguements */
1738     if (!LPSPI_CheckTransferArgument(base, transfer, false))
1739     {
1740         return kStatus_InvalidArgument;
1741     }
1742 
1743     /* Flush FIFO, clear status, disable all the inerrupts. */
1744     LPSPI_FlushFifo(base, true, true);
1745     LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
1746     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1747 
1748     /* Variables */
1749     bool isRxMask = false;
1750     bool isTxMask = false;
1751     uint8_t txWatermark;
1752     uint32_t readRegRemainingTimes;
1753     uint32_t whichPcs      = (transfer->configFlags & LPSPI_SLAVE_PCS_MASK) >> LPSPI_SLAVE_PCS_SHIFT;
1754     uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
1755 
1756     /* Assign the original value for members of transfer handle. */
1757     handle->state                  = (uint8_t)kLPSPI_Busy;
1758     handle->txData                 = transfer->txData;
1759     handle->rxData                 = transfer->rxData;
1760     handle->txRemainingByteCount   = transfer->dataSize;
1761     handle->rxRemainingByteCount   = transfer->dataSize;
1762     handle->totalByteCount         = transfer->dataSize;
1763     handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U);
1764     handle->readRegRemainingTimes  = handle->writeRegRemainingTimes;
1765     /*The TX and RX FIFO sizes are always the same*/
1766     handle->fifoSize   = LPSPI_GetRxFifoSize(base);
1767     handle->isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_SlaveByteSwap) != 0U);
1768     /*Calculate the bytes for write/read the TX/RX register each time*/
1769     if (bytesPerFrame <= 4U)
1770     {
1771         handle->bytesEachWrite = (uint8_t)bytesPerFrame;
1772         handle->bytesEachRead  = (uint8_t)bytesPerFrame;
1773     }
1774     else
1775     {
1776         handle->bytesEachWrite = 4U;
1777         handle->bytesEachRead  = 4U;
1778     }
1779     /* Set proper RX and TX watermarks to reduce the ISR response times. */
1780     if (handle->fifoSize > 1U)
1781     {
1782         txWatermark         = 1U;
1783         handle->rxWatermark = handle->fifoSize - 2U;
1784     }
1785     else
1786     {
1787         txWatermark         = 0U;
1788         handle->rxWatermark = 0U;
1789     }
1790     LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
1791 
1792     /* If there is no rxData, mask the receive data so that receive data is not stored in receive FIFO. */
1793     if (handle->rxData == NULL)
1794     {
1795         isRxMask                     = true;
1796         handle->rxRemainingByteCount = 0U;
1797     }
1798     /* If there is no txData, mask the transmit data so that no data is loaded from transmit FIFO and output pin
1799      * is tristated. */
1800     if (handle->txData == NULL)
1801     {
1802         isTxMask                     = true;
1803         handle->txRemainingByteCount = 0U;
1804     }
1805 
1806     /* Enable module for following configuration of TCR to take effect. */
1807     LPSPI_Enable(base, true);
1808 
1809     base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
1810                                LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
1811                 LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_TXMSK(isTxMask) | LPSPI_TCR_PCS(whichPcs);
1812 
1813     /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
1814      * and you should also enable the INTMUX interupt in your application.
1815      */
1816     (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
1817 
1818     /*TCR is also shared the FIFO, so wait for TCR written.*/
1819     if (!LPSPI_TxFifoReady(base))
1820     {
1821         return kStatus_LPSPI_Timeout;
1822     }
1823 
1824     /* Fill up the TX data in FIFO */
1825     if (handle->txData != NULL)
1826     {
1827         LPSPI_SlaveTransferFillUpTxFifo(base, handle);
1828     }
1829 
1830     /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
1831      * The IRQ handler will get the status of RX and TX interrupt flags.
1832      */
1833     if (handle->rxData != NULL)
1834     {
1835         /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
1836          *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
1837          */
1838         readRegRemainingTimes = handle->readRegRemainingTimes;
1839         if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
1840         {
1841             base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(readRegRemainingTimes - 1U);
1842         }
1843 
1844         /* RX request and FIFO overflow request enable */
1845         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable | (uint32_t)kLPSPI_ReceiveErrorInterruptEnable);
1846     }
1847     else
1848     {
1849         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable);
1850     }
1851 
1852     if (handle->txData != NULL)
1853     {
1854         /* TX FIFO underflow request enable */
1855         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransmitErrorInterruptEnable);
1856     }
1857 
1858     return kStatus_Success;
1859 }
1860 
1861 static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle)
1862 {
1863     assert(handle != NULL);
1864 
1865     uint32_t wordToSend    = 0U;
1866     uint8_t bytesEachWrite = handle->bytesEachWrite;
1867     bool isByteSwap        = handle->isByteSwap;
1868 
1869     while (LPSPI_GetTxFifoCount(base) < (handle->fifoSize))
1870     {
1871         if (handle->txRemainingByteCount < (size_t)bytesEachWrite)
1872         {
1873             handle->bytesEachWrite = (uint8_t)handle->txRemainingByteCount;
1874             bytesEachWrite         = handle->bytesEachWrite;
1875         }
1876 
1877         wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap);
1878         handle->txData += bytesEachWrite;
1879 
1880         /*Decrease the remaining TX byte count.*/
1881         handle->txRemainingByteCount -= (size_t)bytesEachWrite;
1882 
1883         /*Write the word to TX register*/
1884         LPSPI_WriteData(base, wordToSend);
1885 
1886         if (handle->txRemainingByteCount == 0U)
1887         {
1888             break;
1889         }
1890     }
1891 }
1892 
1893 static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle)
1894 {
1895     assert(handle != NULL);
1896 
1897     status_t status = kStatus_Success;
1898 
1899     /* Disable interrupt requests*/
1900     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1901 
1902     if (handle->state == (uint8_t)kLPSPI_Error)
1903     {
1904         status = kStatus_LPSPI_Error;
1905     }
1906     else
1907     {
1908         status = kStatus_Success;
1909     }
1910 
1911     handle->state = (uint8_t)kLPSPI_Idle;
1912 
1913     if (handle->callback != NULL)
1914     {
1915         handle->callback(base, handle, status, handle->userData);
1916     }
1917 }
1918 
1919 /*!
1920  * brief Gets the slave transfer remaining bytes.
1921  *
1922  * This function gets the slave transfer remaining bytes.
1923  *
1924  * param base LPSPI peripheral address.
1925  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1926  * param count Number of bytes transferred so far by the non-blocking transaction.
1927  * return status of status_t.
1928  */
1929 status_t LPSPI_SlaveTransferGetCount(LPSPI_Type *base, lpspi_slave_handle_t *handle, size_t *count)
1930 {
1931     assert(handle != NULL);
1932 
1933     if (NULL == count)
1934     {
1935         return kStatus_InvalidArgument;
1936     }
1937 
1938     /* Catch when there is not an active transfer. */
1939     if (handle->state != (uint8_t)kLPSPI_Busy)
1940     {
1941         *count = 0;
1942         return kStatus_NoTransferInProgress;
1943     }
1944 
1945     size_t remainingByte;
1946 
1947     if (handle->rxData != NULL)
1948     {
1949         remainingByte = handle->rxRemainingByteCount;
1950     }
1951     else
1952     {
1953         remainingByte = handle->txRemainingByteCount;
1954     }
1955 
1956     *count = handle->totalByteCount - remainingByte;
1957 
1958     return kStatus_Success;
1959 }
1960 
1961 /*!
1962  * brief LPSPI slave aborts a transfer which uses an interrupt method.
1963  *
1964  * This function aborts a transfer which uses an interrupt method.
1965  *
1966  * param base LPSPI peripheral address.
1967  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1968  */
1969 void LPSPI_SlaveTransferAbort(LPSPI_Type *base, lpspi_slave_handle_t *handle)
1970 {
1971     assert(handle != NULL);
1972 
1973     /* Disable interrupt requests*/
1974     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
1975 
1976     LPSPI_Reset(base);
1977 
1978     handle->state                = (uint8_t)kLPSPI_Idle;
1979     handle->txRemainingByteCount = 0U;
1980     handle->rxRemainingByteCount = 0U;
1981 }
1982 
1983 /*!
1984  * brief LPSPI Slave IRQ handler function.
1985  *
1986  * This function processes the LPSPI transmit and receives an IRQ.
1987  *
1988  * param base LPSPI peripheral address.
1989  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1990  */
1991 void LPSPI_SlaveTransferHandleIRQ(LPSPI_Type *base, lpspi_slave_handle_t *handle)
1992 {
1993     assert(handle != NULL);
1994 
1995     uint32_t readData; /* variable to store word read from RX FIFO */
1996     uint8_t bytesEachRead = handle->bytesEachRead;
1997     bool isByteSwap       = handle->isByteSwap;
1998     uint32_t readRegRemainingTimes;
1999 
2000     if (handle->rxData != NULL)
2001     {
2002         if (handle->rxRemainingByteCount > 0U)
2003         {
2004             while (LPSPI_GetRxFifoCount(base) != 0U)
2005             {
2006                 /*Read out the data*/
2007                 readData = LPSPI_ReadData(base);
2008 
2009                 /*Decrease the read RX register times.*/
2010                 --handle->readRegRemainingTimes;
2011 
2012                 if (handle->rxRemainingByteCount < (size_t)bytesEachRead)
2013                 {
2014                     handle->bytesEachRead = (uint8_t)handle->rxRemainingByteCount;
2015                     bytesEachRead         = handle->bytesEachRead;
2016                 }
2017 
2018                 LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap);
2019                 handle->rxData += bytesEachRead;
2020 
2021                 /*Decrease the remaining RX byte count.*/
2022                 handle->rxRemainingByteCount -= (size_t)bytesEachRead;
2023 
2024                 if ((handle->txRemainingByteCount > 0U) && (handle->txData != NULL))
2025                 {
2026                     LPSPI_SlaveTransferFillUpTxFifo(base, handle);
2027                 }
2028 
2029                 if (handle->rxRemainingByteCount == 0U)
2030                 {
2031                     break;
2032                 }
2033             }
2034         }
2035 
2036         /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
2037          *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
2038          */
2039         readRegRemainingTimes = handle->readRegRemainingTimes;
2040         if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
2041         {
2042             base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
2043                         LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U));
2044         }
2045     }
2046     if ((handle->rxData == NULL) && (handle->txRemainingByteCount != 0U) && (handle->txData != NULL))
2047     {
2048         LPSPI_SlaveTransferFillUpTxFifo(base, handle);
2049     }
2050 
2051     if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U))
2052     {
2053         /* If no RX buffer, then transfer is not complete until transfer complete flag sets and the TX FIFO empty*/
2054         if (handle->rxData == NULL)
2055         {
2056             if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_FrameCompleteFlag) != 0U) &&
2057                 (LPSPI_GetTxFifoCount(base) == 0U))
2058             {
2059                 LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag);
2060                 /* Complete the transfer and disable the interrupts */
2061                 LPSPI_SlaveTransferComplete(base, handle);
2062             }
2063             else
2064             {
2065                 LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag);
2066                 LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_FrameCompleteInterruptEnable);
2067                 LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
2068             }
2069         }
2070         else
2071         {
2072             /* Complete the transfer and disable the interrupts */
2073             LPSPI_SlaveTransferComplete(base, handle);
2074         }
2075     }
2076 
2077     /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */
2078     if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransmitErrorFlag) != 0U) &&
2079         ((base->IER & LPSPI_IER_TEIE_MASK) != 0U))
2080     {
2081         LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransmitErrorFlag);
2082         /* Change state to error and clear flag */
2083         if (handle->txData != NULL)
2084         {
2085             handle->state = (uint8_t)kLPSPI_Error;
2086         }
2087         handle->errorCount++;
2088     }
2089     /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */
2090     if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ReceiveErrorFlag) != 0U) &&
2091         ((base->IER & LPSPI_IER_REIE_MASK) != 0U))
2092     {
2093         LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_ReceiveErrorFlag);
2094         /* Change state to error and clear flag */
2095         if (handle->txData != NULL)
2096         {
2097             handle->state = (uint8_t)kLPSPI_Error;
2098         }
2099         handle->errorCount++;
2100     }
2101 }
2102 
2103 static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap)
2104 {
2105     assert(txData != NULL);
2106 
2107     uint32_t wordToSend = 0U;
2108 
2109     switch (bytesEachWrite)
2110     {
2111         case 1:
2112             wordToSend = *txData;
2113             ++txData;
2114             break;
2115 
2116         case 2:
2117             if (!isByteSwap)
2118             {
2119                 wordToSend = *txData;
2120                 ++txData;
2121                 wordToSend |= (unsigned)(*txData) << 8U;
2122                 ++txData;
2123             }
2124             else
2125             {
2126                 wordToSend = (unsigned)(*txData) << 8U;
2127                 ++txData;
2128                 wordToSend |= *txData;
2129                 ++txData;
2130             }
2131 
2132             break;
2133 
2134         case 3:
2135             if (!isByteSwap)
2136             {
2137                 wordToSend = *txData;
2138                 ++txData;
2139                 wordToSend |= (unsigned)(*txData) << 8U;
2140                 ++txData;
2141                 wordToSend |= (unsigned)(*txData) << 16U;
2142                 ++txData;
2143             }
2144             else
2145             {
2146                 wordToSend = (unsigned)(*txData) << 16U;
2147                 ++txData;
2148                 wordToSend |= (unsigned)(*txData) << 8U;
2149                 ++txData;
2150                 wordToSend |= *txData;
2151                 ++txData;
2152             }
2153             break;
2154 
2155         case 4:
2156             if (!isByteSwap)
2157             {
2158                 wordToSend = *txData;
2159                 ++txData;
2160                 wordToSend |= (unsigned)(*txData) << 8U;
2161                 ++txData;
2162                 wordToSend |= (unsigned)(*txData) << 16U;
2163                 ++txData;
2164                 wordToSend |= (unsigned)(*txData) << 24U;
2165                 ++txData;
2166             }
2167             else
2168             {
2169                 wordToSend = (unsigned)(*txData) << 24U;
2170                 ++txData;
2171                 wordToSend |= (unsigned)(*txData) << 16U;
2172                 ++txData;
2173                 wordToSend |= (unsigned)(*txData) << 8U;
2174                 ++txData;
2175                 wordToSend |= *txData;
2176                 ++txData;
2177             }
2178             break;
2179 
2180         default:
2181             assert(false);
2182             break;
2183     }
2184     return wordToSend;
2185 }
2186 
2187 static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap)
2188 {
2189     assert(rxData != NULL);
2190 
2191     switch (bytesEachRead)
2192     {
2193         case 1:
2194             *rxData = (uint8_t)readData;
2195             ++rxData;
2196             break;
2197 
2198         case 2:
2199             if (!isByteSwap)
2200             {
2201                 *rxData = (uint8_t)readData;
2202                 ++rxData;
2203                 *rxData = (uint8_t)(readData >> 8);
2204                 ++rxData;
2205             }
2206             else
2207             {
2208                 *rxData = (uint8_t)(readData >> 8);
2209                 ++rxData;
2210                 *rxData = (uint8_t)readData;
2211                 ++rxData;
2212             }
2213             break;
2214 
2215         case 3:
2216             if (!isByteSwap)
2217             {
2218                 *rxData = (uint8_t)readData;
2219                 ++rxData;
2220                 *rxData = (uint8_t)(readData >> 8);
2221                 ++rxData;
2222                 *rxData = (uint8_t)(readData >> 16);
2223                 ++rxData;
2224             }
2225             else
2226             {
2227                 *rxData = (uint8_t)(readData >> 16);
2228                 ++rxData;
2229                 *rxData = (uint8_t)(readData >> 8);
2230                 ++rxData;
2231                 *rxData = (uint8_t)readData;
2232                 ++rxData;
2233             }
2234             break;
2235 
2236         case 4:
2237             if (!isByteSwap)
2238             {
2239                 *rxData = (uint8_t)readData;
2240                 ++rxData;
2241                 *rxData = (uint8_t)(readData >> 8);
2242                 ++rxData;
2243                 *rxData = (uint8_t)(readData >> 16);
2244                 ++rxData;
2245                 *rxData = (uint8_t)(readData >> 24);
2246                 ++rxData;
2247             }
2248             else
2249             {
2250                 *rxData = (uint8_t)(readData >> 24);
2251                 ++rxData;
2252                 *rxData = (uint8_t)(readData >> 16);
2253                 ++rxData;
2254                 *rxData = (uint8_t)(readData >> 8);
2255                 ++rxData;
2256                 *rxData = (uint8_t)readData;
2257                 ++rxData;
2258             }
2259             break;
2260 
2261         default:
2262             assert(false);
2263             break;
2264     }
2265 }
2266 
2267 static bool LPSPI_TxFifoReady(LPSPI_Type *base)
2268 {
2269 #if SPI_RETRY_TIMES
2270     uint32_t waitTimes = SPI_RETRY_TIMES;
2271     while (((uint8_t)LPSPI_GetTxFifoCount(base) != 0U) && (--waitTimes != 0U))
2272 #else
2273     while ((uint8_t)LPSPI_GetTxFifoCount(base) != 0U)
2274 #endif
2275     {
2276     }
2277 #if SPI_RETRY_TIMES
2278     if (waitTimes == 0U)
2279     {
2280         return false;
2281     }
2282 #endif
2283     return true;
2284 }
2285 
2286 static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param)
2287 {
2288     if (LPSPI_IsMaster(base))
2289     {
2290         s_lpspiMasterIsr(base, (lpspi_master_handle_t *)param);
2291     }
2292     else
2293     {
2294         s_lpspiSlaveIsr(base, (lpspi_slave_handle_t *)param);
2295     }
2296     SDK_ISR_EXIT_BARRIER;
2297 }
2298 
2299 #if defined(LPSPI0)
2300 void LPSPI0_DriverIRQHandler(void);
2301 void LPSPI0_DriverIRQHandler(void)
2302 {
2303     assert(s_lpspiHandle[0] != NULL);
2304     LPSPI_CommonIRQHandler(LPSPI0, s_lpspiHandle[0]);
2305 }
2306 #endif
2307 
2308 #if defined(LPSPI1)
2309 void LPSPI1_DriverIRQHandler(void);
2310 void LPSPI1_DriverIRQHandler(void)
2311 {
2312     assert(s_lpspiHandle[1] != NULL);
2313     LPSPI_CommonIRQHandler(LPSPI1, s_lpspiHandle[1]);
2314 }
2315 #endif
2316 
2317 #if defined(LPSPI2)
2318 void LPSPI2_DriverIRQHandler(void);
2319 void LPSPI2_DriverIRQHandler(void)
2320 {
2321     assert(s_lpspiHandle[2] != NULL);
2322     LPSPI_CommonIRQHandler(LPSPI2, s_lpspiHandle[2]);
2323 }
2324 #endif
2325 
2326 #if defined(LPSPI3)
2327 void LPSPI3_DriverIRQHandler(void);
2328 void LPSPI3_DriverIRQHandler(void)
2329 {
2330     assert(s_lpspiHandle[3] != NULL);
2331     LPSPI_CommonIRQHandler(LPSPI3, s_lpspiHandle[3]);
2332 }
2333 #endif
2334 
2335 #if defined(LPSPI4)
2336 void LPSPI4_DriverIRQHandler(void);
2337 void LPSPI4_DriverIRQHandler(void)
2338 {
2339     assert(s_lpspiHandle[4] != NULL);
2340     LPSPI_CommonIRQHandler(LPSPI4, s_lpspiHandle[4]);
2341 }
2342 #endif
2343 
2344 #if defined(LPSPI5)
2345 void LPSPI5_DriverIRQHandler(void);
2346 void LPSPI5_DriverIRQHandler(void)
2347 {
2348     assert(s_lpspiHandle[5] != NULL);
2349     LPSPI_CommonIRQHandler(LPSPI5, s_lpspiHandle[5]);
2350 }
2351 #endif
2352 
2353 #if defined(DMA__LPSPI0)
2354 void DMA_SPI0_INT_DriverIRQHandler(void);
2355 void DMA_SPI0_INT_DriverIRQHandler(void)
2356 {
2357     assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)] != NULL);
2358     LPSPI_CommonIRQHandler(DMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)]);
2359 }
2360 #endif
2361 
2362 #if defined(DMA__LPSPI1)
2363 void DMA_SPI1_INT_DriverIRQHandler(void);
2364 void DMA_SPI1_INT_DriverIRQHandler(void)
2365 {
2366     assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)] != NULL);
2367     LPSPI_CommonIRQHandler(DMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)]);
2368 }
2369 #endif
2370 #if defined(DMA__LPSPI2)
2371 void DMA_SPI2_INT_DriverIRQHandler(void);
2372 void DMA_SPI2_INT_DriverIRQHandler(void)
2373 {
2374     assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)] != NULL);
2375     LPSPI_CommonIRQHandler(DMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)]);
2376 }
2377 #endif
2378 
2379 #if defined(DMA__LPSPI3)
2380 void DMA_SPI3_INT_DriverIRQHandler(void);
2381 void DMA_SPI3_INT_DriverIRQHandler(void)
2382 {
2383     assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)] != NULL);
2384     LPSPI_CommonIRQHandler(DMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)]);
2385 }
2386 #endif
2387 
2388 #if defined(ADMA__LPSPI0)
2389 void ADMA_SPI0_INT_DriverIRQHandler(void);
2390 void ADMA_SPI0_INT_DriverIRQHandler(void)
2391 {
2392     assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)] != NULL);
2393     LPSPI_CommonIRQHandler(ADMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)]);
2394 }
2395 #endif
2396 
2397 #if defined(ADMA__LPSPI1)
2398 void ADMA_SPI1_INT_DriverIRQHandler(void);
2399 void ADMA_SPI1_INT_DriverIRQHandler(void)
2400 {
2401     assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)] != NULL);
2402     LPSPI_CommonIRQHandler(ADMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)]);
2403 }
2404 #endif
2405 #if defined(ADMA__LPSPI2)
2406 void ADMA_SPI2_INT_DriverIRQHandler(void);
2407 void ADMA_SPI2_INT_DriverIRQHandler(void)
2408 {
2409     assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)] != NULL);
2410     LPSPI_CommonIRQHandler(ADMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)]);
2411 }
2412 #endif
2413 
2414 #if defined(ADMA__LPSPI3)
2415 void ADMA_SPI3_INT_DriverIRQHandler(void);
2416 void ADMA_SPI3_INT_DriverIRQHandler(void)
2417 {
2418     assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)] != NULL);
2419     LPSPI_CommonIRQHandler(ADMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)]);
2420 }
2421 #endif