1 /*
2  * Copyright 2022-2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_lpspi.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.lpflexcomm_lpspi"
17 #endif
18 
19 /*!
20  * @brief Default watermark values.
21  *
22  * The default watermarks are set to zero.
23  */
24 enum _lpspi_default_watermarks
25 {
26     kLpspiDefaultTxWatermark = 0,
27     kLpspiDefaultRxWatermark = 0,
28 };
29 
30 /*! @brief Typedef for master interrupt handler. */
31 typedef void (*lpspi_master_isr_t)(uint32_t instance, lpspi_master_handle_t *handle);
32 
33 /*! @brief Typedef for slave interrupt handler. */
34 typedef void (*lpspi_slave_isr_t)(uint32_t instance, lpspi_slave_handle_t *handle);
35 
36 /*!
37  * @brief Used for conversion from `lpflexcomm_irq_handler_t` to `lpuart_irq_handler_t`
38  */
39 typedef union lpspi_to_lpflexcomm
40 {
41     lpspi_master_isr_t lpspi_master_handler;
42     lpspi_slave_isr_t lpspi_slave_handler;
43     lpflexcomm_irq_handler_t lpflexcomm_handler;
44 } lpspi_to_lpflexcomm_t;
45 
46 /*******************************************************************************
47  * Prototypes
48  ******************************************************************************/
49 
50 /*!
51  * @brief Configures the LPSPI peripheral chip select polarity.
52  *
53  * This function  takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and
54  * configures the Pcs signal to operate with the desired characteristic.
55  *
56  * @param base LPSPI peripheral address.
57  * @param pcs The particular peripheral chip select (parameter value is of type lpspi_which_pcs_t) for which we wish to
58  *            apply the active high or active low characteristic.
59  * @param activeLowOrHigh The setting for either "active high, inactive low (0)"  or "active low, inactive high(1)" of
60  *                        type lpspi_pcs_polarity_config_t.
61  */
62 static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
63                                     lpspi_which_pcs_t pcs,
64                                     lpspi_pcs_polarity_config_t activeLowOrHigh);
65 
66 /*!
67  * @brief Combine the write data for 1 byte to 4 bytes.
68  * This is not a public API.
69  */
70 static uint32_t LPSPI_CombineWriteData(const uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap);
71 
72 /*!
73  * @brief Separate the read data for 1 byte to 4 bytes.
74  * This is not a public API.
75  */
76 static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap);
77 
78 /*!
79  * @brief Wait for tx FIFO to be empty.
80  * This is not a public API.
81  * @param base LPSPI peripheral address.
82  * @return true for the tx FIFO is ready, false is not.
83  */
84 static bool LPSPI_TxFifoReady(LPSPI_Type *base);
85 
86 /*!
87  * @brief Master fill up the TX FIFO with data.
88  * This is not a public API.
89  */
90 static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle);
91 
92 /*!
93  * @brief Master finish up a transfer.
94  * It would call back if there is callback function and set the state to idle.
95  * This is not a public API.
96  */
97 static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle);
98 
99 /*!
100  * @brief Slave fill up the TX FIFO with data.
101  * This is not a public API.
102  */
103 static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle);
104 
105 /*!
106  * @brief Slave finish up a transfer.
107  * It would call back if there is callback function and set the state to idle.
108  * This is not a public API.
109  */
110 static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle);
111 
112 /*******************************************************************************
113  * Variables
114  ******************************************************************************/
115 
116 /* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
117 static const uint8_t s_baudratePrescaler[] = {1, 2, 4, 8, 16, 32, 64, 128};
118 
119 /*! @brief Pointers to lpspi bases for each instance. */
120 static LPSPI_Type *const s_lpspiBases[] = LPSPI_BASE_PTRS;
121 
122 /*! @brief Pointers to lpspi IRQ number for each instance. */
123 static const IRQn_Type s_lpspiIRQ[] = LPSPI_IRQS;
124 
125 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
126 /*! @brief Pointers to lpspi clocks for each instance. */
127 static const clock_ip_name_t s_lpspiClocks[] = LPSPI_CLOCKS;
128 
129 #if defined(LPSPI_PERIPH_CLOCKS)
130 static const clock_ip_name_t s_LpspiPeriphClocks[] = LPSPI_PERIPH_CLOCKS;
131 #endif
132 
133 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
134 
135 /*! @brief Pointers to lpspi handles for each instance. */
136 static void *s_lpspiHandle[ARRAY_SIZE(s_lpspiBases)];
137 
138 /* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/
139 volatile uint8_t g_lpspiDummyData[ARRAY_SIZE(s_lpspiBases)] = {0};
140 
141 /*! @brief Pointer to master IRQ handler for each instance. */
142 static lpspi_master_isr_t s_lpspiMasterIsr;
143 /*! @brief Pointer to slave IRQ handler for each instance. */
144 static lpspi_slave_isr_t s_lpspiSlaveIsr;
145 
146 /**********************************************************************************************************************
147  * Code
148  *********************************************************************************************************************/
149 
150 /*!
151  * brief Get the LPSPI instance from peripheral base address.
152  *
153  * param base LPSPI peripheral base address.
154  * return LPSPI instance.
155  */
LPSPI_GetInstance(LPSPI_Type * base)156 uint32_t LPSPI_GetInstance(LPSPI_Type *base)
157 {
158     uint8_t instance = 0;
159 
160     /* Find the instance index from base address mappings. */
161     for (instance = 0; instance < ARRAY_SIZE(s_lpspiBases); instance++)
162     {
163         if (MSDK_REG_SECURE_ADDR(s_lpspiBases[instance]) == MSDK_REG_SECURE_ADDR(base))
164         {
165             break;
166         }
167     }
168 
169     assert(instance < ARRAY_SIZE(s_lpspiBases));
170 
171     return instance;
172 }
173 
174 /*!
175  * brief Set up the dummy data.
176  *
177  * param base LPSPI peripheral address.
178  * param dummyData Data to be transferred when tx buffer is NULL.
179  * Note:
180  *      This API has no effect when LPSPI in slave interrupt mode, because driver
181  *      will set the TXMSK bit to 1 if txData is NULL, no data is loaded from transmit
182  *      FIFO and output pin is tristated.
183  */
LPSPI_SetDummyData(LPSPI_Type * base,uint8_t dummyData)184 void LPSPI_SetDummyData(LPSPI_Type *base, uint8_t dummyData)
185 {
186     uint32_t instance          = LPSPI_GetInstance(base);
187     g_lpspiDummyData[instance] = dummyData;
188 }
189 
190 /*!
191  * brief Initializes the LPSPI master.
192  *
193  * param base LPSPI peripheral address.
194  * param masterConfig Pointer to structure lpspi_master_config_t.
195  * param srcClock_Hz Module source input clock in Hertz
196  */
LPSPI_MasterInit(LPSPI_Type * base,const lpspi_master_config_t * masterConfig,uint32_t srcClock_Hz)197 void LPSPI_MasterInit(LPSPI_Type *base, const lpspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
198 {
199     assert(masterConfig != NULL);
200 
201     uint32_t tcrPrescaleValue = 0;
202     uint32_t instance = LPSPI_GetInstance(base);
203 
204     if(LP_FLEXCOMM_GetBaseAddress(instance) != 0U)
205     {
206 #if !(defined(LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER) && LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER)
207     /* initialize flexcomm to LPSPI mode */
208         status_t status = LP_FLEXCOMM_Init(LPSPI_GetInstance(base), LP_FLEXCOMM_PERIPH_LPSPI);
209         if (kStatus_Success != status)
210         {
211             assert(false);
212         }
213 #endif /* LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER */
214     }
215     else
216     {
217 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
218 
219         /* Enable LPSPI clock */
220         (void)CLOCK_EnableClock(s_lpspiClocks[instance]);
221 
222 #if defined(LPSPI_PERIPH_CLOCKS)
223         (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
224 #endif
225 
226 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
227     }
228 
229     /* Disable LPSPI first */
230     LPSPI_Enable(base, false);
231 
232     /* Set LPSPI to master */
233     LPSPI_SetMasterSlaveMode(base, kLPSPI_Master);
234 
235     /* Set specific PCS to active high or low */
236     LPSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow);
237 
238     /* Set Configuration Register 1 related setting.*/
239     base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK | LPSPI_CFGR1_NOSTALL_MASK |
240                                    LPSPI_CFGR1_SAMPLE_MASK | LPSPI_CFGR1_PCSCFG_MASK )) |
241                   LPSPI_CFGR1_OUTCFG(masterConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(masterConfig->pinCfg) |
242                   LPSPI_CFGR1_NOSTALL(0) | LPSPI_CFGR1_SAMPLE((uint32_t)masterConfig->enableInputDelay )|
243                   LPSPI_CFGR1_PCSCFG(masterConfig->pcsFunc);
244 
245     /* Set baudrate and delay times*/
246     (void)LPSPI_MasterSetBaudRate(base, masterConfig->baudRate, srcClock_Hz, &tcrPrescaleValue);
247 
248     /* Set default watermarks */
249     LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark);
250 
251     /* Set Transmit Command Register*/
252     base->TCR = LPSPI_TCR_CPOL(masterConfig->cpol) | LPSPI_TCR_CPHA(masterConfig->cpha) |
253                 LPSPI_TCR_LSBF(masterConfig->direction) | LPSPI_TCR_FRAMESZ(masterConfig->bitsPerFrame - 1U) |
254                 LPSPI_TCR_PRESCALE(tcrPrescaleValue) | LPSPI_TCR_PCS(masterConfig->whichPcs);
255 
256     LPSPI_Enable(base, true);
257 
258     (void)LPSPI_MasterSetDelayTimes(base, masterConfig->pcsToSckDelayInNanoSec, kLPSPI_PcsToSck, srcClock_Hz);
259     (void)LPSPI_MasterSetDelayTimes(base, masterConfig->lastSckToPcsDelayInNanoSec, kLPSPI_LastSckToPcs, srcClock_Hz);
260     (void)LPSPI_MasterSetDelayTimes(base, masterConfig->betweenTransferDelayInNanoSec, kLPSPI_BetweenTransfer,
261                                     srcClock_Hz);
262 
263     LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
264 }
265 
266 /*!
267  * brief Sets the lpspi_master_config_t structure to default values.
268  *
269  * This API initializes the configuration structure  for LPSPI_MasterInit().
270  * The initialized structure can remain unchanged in LPSPI_MasterInit(), or can be modified
271  * before calling the LPSPI_MasterInit().
272  * Example:
273  * code
274  *  lpspi_master_config_t  masterConfig;
275  *  LPSPI_MasterGetDefaultConfig(&masterConfig);
276  * endcode
277  * param masterConfig pointer to lpspi_master_config_t structure
278  */
LPSPI_MasterGetDefaultConfig(lpspi_master_config_t * masterConfig)279 void LPSPI_MasterGetDefaultConfig(lpspi_master_config_t *masterConfig)
280 {
281     assert(masterConfig != NULL);
282 
283     /* Initializes the configure structure to zero. */
284     (void)memset(masterConfig, 0, sizeof(*masterConfig));
285 
286     masterConfig->baudRate     = 500000;
287     masterConfig->bitsPerFrame = 8;
288     masterConfig->cpol         = kLPSPI_ClockPolarityActiveHigh;
289     masterConfig->cpha         = kLPSPI_ClockPhaseFirstEdge;
290     masterConfig->direction    = kLPSPI_MsbFirst;
291 
292     masterConfig->pcsToSckDelayInNanoSec        = (1000000000U / masterConfig->baudRate) / 2U;
293     masterConfig->lastSckToPcsDelayInNanoSec    = (1000000000U / masterConfig->baudRate) / 2U;
294     masterConfig->betweenTransferDelayInNanoSec = (1000000000U / masterConfig->baudRate) / 2U;
295 
296     masterConfig->whichPcs           = kLPSPI_Pcs0;
297     masterConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
298     masterConfig->pcsFunc            = kLPSPI_PcsAsCs;
299 
300     masterConfig->pinCfg        = kLPSPI_SdiInSdoOut;
301     masterConfig->dataOutConfig = kLpspiDataOutRetained;
302 
303     masterConfig->enableInputDelay = false;
304 }
305 
306 /*!
307  * brief LPSPI slave configuration.
308  *
309  * param base LPSPI peripheral address.
310  * param slaveConfig Pointer to a structure lpspi_slave_config_t.
311  */
LPSPI_SlaveInit(LPSPI_Type * base,const lpspi_slave_config_t * slaveConfig)312 void LPSPI_SlaveInit(LPSPI_Type *base, const lpspi_slave_config_t *slaveConfig)
313 {
314     assert(slaveConfig != NULL);
315 
316     uint32_t instance = LPSPI_GetInstance(base);
317 
318     if(LP_FLEXCOMM_GetBaseAddress(instance) != 0U)
319     {
320 #if !(defined(LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER) && LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER)
321     /* initialize flexcomm to LPSPI mode */
322         status_t status = LP_FLEXCOMM_Init(LPSPI_GetInstance(base), LP_FLEXCOMM_PERIPH_LPSPI);
323         if (kStatus_Success != status)
324         {
325             assert(false);
326         }
327 #endif /* LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER */
328     }
329     else
330     {
331 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
332 
333         /* Enable LPSPI clock */
334         (void)CLOCK_EnableClock(s_lpspiClocks[instance]);
335 
336 #if defined(LPSPI_PERIPH_CLOCKS)
337         (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
338 #endif
339 
340 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
341     }
342 
343     LPSPI_SetMasterSlaveMode(base, kLPSPI_Slave);
344 
345     LPSPI_SetOnePcsPolarity(base, slaveConfig->whichPcs, slaveConfig->pcsActiveHighOrLow);
346 
347     base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK)) |
348                   LPSPI_CFGR1_OUTCFG(slaveConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(slaveConfig->pinCfg);
349 
350     LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark);
351 
352     base->TCR = LPSPI_TCR_CPOL(slaveConfig->cpol) | LPSPI_TCR_CPHA(slaveConfig->cpha) |
353                 LPSPI_TCR_LSBF(slaveConfig->direction) | LPSPI_TCR_FRAMESZ(slaveConfig->bitsPerFrame - 1U);
354 
355     /* This operation will set the dummy data for edma transfer, no effect in interrupt way. */
356     LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
357 
358     LPSPI_Enable(base, true);
359 }
360 
361 /*!
362  * brief Sets the lpspi_slave_config_t structure to default values.
363  *
364  * This API initializes the configuration structure for LPSPI_SlaveInit().
365  * The initialized structure can remain unchanged in LPSPI_SlaveInit() or can be modified
366  * before calling the LPSPI_SlaveInit().
367  * Example:
368  * code
369  *  lpspi_slave_config_t  slaveConfig;
370  *  LPSPI_SlaveGetDefaultConfig(&slaveConfig);
371  * endcode
372  * param slaveConfig pointer to lpspi_slave_config_t structure.
373  */
LPSPI_SlaveGetDefaultConfig(lpspi_slave_config_t * slaveConfig)374 void LPSPI_SlaveGetDefaultConfig(lpspi_slave_config_t *slaveConfig)
375 {
376     assert(slaveConfig != NULL);
377 
378     /* Initializes the configure structure to zero. */
379     (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
380 
381     slaveConfig->bitsPerFrame = 8;                              /*!< Bits per frame, minimum 8, maximum 4096.*/
382     slaveConfig->cpol         = kLPSPI_ClockPolarityActiveHigh; /*!< Clock polarity. */
383     slaveConfig->cpha         = kLPSPI_ClockPhaseFirstEdge;     /*!< Clock phase. */
384     slaveConfig->direction    = kLPSPI_MsbFirst;                /*!< MSB or LSB data shift direction. */
385 
386     slaveConfig->whichPcs           = kLPSPI_Pcs0;         /*!< Desired Peripheral Chip Select (pcs) */
387     slaveConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow; /*!< Desired PCS active high or low */
388 
389     slaveConfig->pinCfg        = kLPSPI_SdiInSdoOut;
390     slaveConfig->dataOutConfig = kLpspiDataOutRetained;
391 }
392 
393 /*!
394  * brief Restores the LPSPI peripheral to reset state. Note that this function
395  * sets all registers to reset state. As a result, the LPSPI module can't work after calling
396  * this API.
397  * param base LPSPI peripheral address.
398  */
LPSPI_Reset(LPSPI_Type * base)399 void LPSPI_Reset(LPSPI_Type *base)
400 {
401     /* Reset all internal logic and registers, except the Control Register. Remains set until cleared by software.*/
402     base->CR |= LPSPI_CR_RST_MASK;
403 
404     /* Software reset doesn't reset the CR, so manual reset the FIFOs */
405     base->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
406 
407     /* Master logic is not reset and module is disabled.*/
408     base->CR = 0x00U;
409 }
410 
411 /*!
412  * brief De-initializes the LPSPI peripheral. Call this API to disable the LPSPI clock.
413  * param base LPSPI peripheral address.
414  */
LPSPI_Deinit(LPSPI_Type * base)415 void LPSPI_Deinit(LPSPI_Type *base)
416 {
417     uint32_t instance = LPSPI_GetInstance(base);
418 
419     /* Reset to default value */
420     LPSPI_Reset(base);
421     if(LP_FLEXCOMM_GetBaseAddress(instance) != 0U)
422     {
423 #if !(defined(LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER) && LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER)
424         LP_FLEXCOMM_Deinit(instance);
425 #endif
426     }
427     else
428     {
429 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
430         /* Disable LPSPI clock */
431         (void)CLOCK_DisableClock(s_lpspiClocks[instance]);
432 
433 #if defined(LPSPI_PERIPH_CLOCKS)
434         (void)CLOCK_DisableClock(s_LpspiPeriphClocks[instance]);
435 #endif
436 
437 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
438     }
439 }
440 
LPSPI_SetOnePcsPolarity(LPSPI_Type * base,lpspi_which_pcs_t pcs,lpspi_pcs_polarity_config_t activeLowOrHigh)441 static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
442                                     lpspi_which_pcs_t pcs,
443                                     lpspi_pcs_polarity_config_t activeLowOrHigh)
444 {
445     uint32_t cfgr1Value = 0;
446     /* Clear the PCS polarity bit */
447     cfgr1Value = base->CFGR1 & ~(1UL << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs));
448 
449     /* Configure the PCS polarity bit according to the activeLowOrHigh setting */
450     base->CFGR1 = cfgr1Value | ((uint32_t)activeLowOrHigh << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs));
451 }
452 
453 /*!
454  * brief Sets the LPSPI baud rate in bits per second.
455  *
456  * This function takes in the desired bitsPerSec (baud rate) and calculates the nearest
457  * possible baud rate without exceeding the desired baud rate and returns the
458  * calculated baud rate in bits-per-second. It requires the caller to provide
459  * the frequency of the module source clock (in Hertz). Note that the baud rate
460  * does not go into effect until the Transmit Control Register (TCR) is programmed
461  * with the prescale value. Hence, this function returns the prescale tcrPrescaleValue
462  * parameter for later programming in the TCR.  The higher level
463  * peripheral driver should alert the user of an out of range baud rate input.
464  *
465  * Note that the LPSPI module must first be disabled before configuring this.
466  * Note that the LPSPI module must be configured for master mode before configuring this.
467  *
468  * param base LPSPI peripheral address.
469  * param baudRate_Bps The desired baud rate in bits per second.
470  * param srcClock_Hz Module source input clock in Hertz.
471  * param tcrPrescaleValue The TCR prescale value needed to program the TCR.
472  * return  The actual calculated baud rate. This function may also return a "0" if the
473  *          LPSPI is not configured for master mode or if the LPSPI module is not disabled.
474  */
475 
LPSPI_MasterSetBaudRate(LPSPI_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz,uint32_t * tcrPrescaleValue)476 uint32_t LPSPI_MasterSetBaudRate(LPSPI_Type *base,
477                                  uint32_t baudRate_Bps,
478                                  uint32_t srcClock_Hz,
479                                  uint32_t *tcrPrescaleValue)
480 {
481     assert(tcrPrescaleValue != NULL);
482 
483     /* For master mode configuration only, if slave mode detected, return 0.
484      * Also, the LPSPI module needs to be disabled first, if enabled, return 0
485      */
486     if ((!LPSPI_IsMaster(base)) || ((base->CR & LPSPI_CR_MEN_MASK) != 0U))
487     {
488         return 0U;
489     }
490 
491     uint32_t prescaler, bestPrescaler;
492     uint32_t scaler, bestScaler;
493     uint32_t realBaudrate, bestBaudrate;
494     uint32_t diff, min_diff;
495     uint32_t desiredBaudrate = baudRate_Bps;
496 
497     /* find combination of prescaler and scaler resulting in baudrate closest to the
498      * requested value
499      */
500     min_diff = 0xFFFFFFFFU;
501 
502     /* Set to maximum divisor value bit settings so that if baud rate passed in is less
503      * than the minimum possible baud rate, then the SPI will be configured to the lowest
504      * possible baud rate
505      */
506     bestPrescaler = 7;
507     bestScaler    = 255;
508 
509     bestBaudrate = 0; /* required to avoid compilation warning */
510 
511     /* In all for loops, if min_diff = 0, the exit for loop*/
512     for (prescaler = 0U; prescaler < 8U; prescaler++)
513     {
514         if (min_diff == 0U)
515         {
516             break;
517         }
518         for (scaler = 0U; scaler < 256U; scaler++)
519         {
520             if (min_diff == 0U)
521             {
522                 break;
523             }
524             realBaudrate = (srcClock_Hz / (s_baudratePrescaler[prescaler] * (scaler + 2U)));
525 
526             /* calculate the baud rate difference based on the conditional statement
527              * that states that the calculated baud rate must not exceed the desired baud rate
528              */
529             if (desiredBaudrate >= realBaudrate)
530             {
531                 diff = desiredBaudrate - realBaudrate;
532                 if (min_diff > diff)
533                 {
534                     /* a better match found */
535                     min_diff      = diff;
536                     bestPrescaler = prescaler;
537                     bestScaler    = scaler;
538                     bestBaudrate  = realBaudrate;
539                 }
540             }
541         }
542     }
543 
544     /* Write the best baud rate scalar to the CCR.
545      * Note, no need to check for error since we've already checked to make sure the module is
546      * disabled and in master mode. Also, there is a limit on the maximum divider so we will not
547      * exceed this.
548      */
549 #if defined(FSL_FEATURE_LPSPI_HAS_CCR1) && FSL_FEATURE_LPSPI_HAS_CCR1
550     /* When CCR1 is present, the CCR[DBT] and CCR[SCKDIV] is write only, all read will return 0
551        The real DBT and SCKDIV can be obtained in CCR1, CCR[DBT]=CCR1[SCKSCK] and CCR[SCKDIV]=CCR1[SCKHLD]+CCR1[SCKSET]
552        So when changing either CCR[DBT] or CCR[SCKDIV] make sure the other value is not overwritten by 0 */
553     base->CCR = base->CCR | LPSPI_CCR_DBT((base->CCR1 & LPSPI_CCR1_SCKSCK_MASK) >> LPSPI_CCR1_SCKSCK_SHIFT) |
554                 LPSPI_CCR_SCKDIV(bestScaler);
555 #else
556     base->CCR = (base->CCR & ~LPSPI_CCR_SCKDIV_MASK) | LPSPI_CCR_SCKDIV(bestScaler);
557 #endif /* FSL_FEATURE_LPSPI_HAS_CCR1 */
558 
559     /* return the best prescaler value for user to use later */
560     *tcrPrescaleValue = bestPrescaler;
561 
562     /* return the actual calculated baud rate */
563     return bestBaudrate;
564 }
565 
566 /*!
567  * brief Manually configures a specific LPSPI delay parameter (module must be disabled to
568  *        change the delay values).
569  *
570  * This function configures the following:
571  * SCK to PCS delay, or
572  * PCS to SCK delay, or
573  * The configurations must occur between the transfer delay.
574  *
575  * The delay names are available in type lpspi_delay_type_t.
576  *
577  * The user passes the desired delay along with the delay value.
578  * This allows the user to directly set the delay values if they have
579  * pre-calculated them or if they simply wish to manually increment the value.
580  *
581  * Note that the LPSPI module must first be disabled before configuring this.
582  * Note that the LPSPI module must be configured for master mode before configuring this.
583  *
584  * param base LPSPI peripheral address.
585  * param scaler The 8-bit delay value 0x00 to 0xFF (255).
586  * param whichDelay The desired delay to configure, must be of type lpspi_delay_type_t.
587  */
LPSPI_MasterSetDelayScaler(LPSPI_Type * base,uint32_t scaler,lpspi_delay_type_t whichDelay)588 void LPSPI_MasterSetDelayScaler(LPSPI_Type *base, uint32_t scaler, lpspi_delay_type_t whichDelay)
589 {
590     /*These settings are only relevant in master mode */
591 #if defined(FSL_FEATURE_LPSPI_HAS_CCR1) && FSL_FEATURE_LPSPI_HAS_CCR1
592     /* When CCR1 is present, the CCR[DBT] and CCR[SCKDIV] is write only, all read will return 0
593        The real DBT and SCKDIV can be obtained in CCR1, CCR[DBT]=CCR1[SCKSCK] and CCR[SCKDIV]=CCR1[SCKHLD]+CCR1[SCKSET]
594        So when changing either CCR[DBT] or CCR[SCKDIV] make sure the other value is not overwritten by 0 */
595     uint32_t dbt    = (base->CCR1 & LPSPI_CCR1_SCKSCK_MASK) >> LPSPI_CCR1_SCKSCK_SHIFT;
596     uint32_t sckdiv = (base->CCR1 & LPSPI_CCR1_SCKHLD_MASK) >> LPSPI_CCR1_SCKHLD_SHIFT;
597     sckdiv += (base->CCR1 & LPSPI_CCR1_SCKSET_MASK) >> LPSPI_CCR1_SCKSET_SHIFT;
598     switch (whichDelay)
599     {
600         case kLPSPI_PcsToSck:
601             base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler) | LPSPI_CCR_DBT(dbt) |
602                         LPSPI_CCR_SCKDIV(sckdiv);
603 
604             break;
605         case kLPSPI_LastSckToPcs:
606             base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler) | LPSPI_CCR_DBT(dbt) |
607                         LPSPI_CCR_SCKDIV(sckdiv);
608 
609             break;
610         case kLPSPI_BetweenTransfer:
611             base->CCR = base->CCR | LPSPI_CCR_DBT(scaler) | LPSPI_CCR_SCKDIV(sckdiv);
612 #else
613     switch (whichDelay)
614     {
615         case kLPSPI_PcsToSck:
616             base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler);
617 
618             break;
619         case kLPSPI_LastSckToPcs:
620             base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler);
621 
622             break;
623         case kLPSPI_BetweenTransfer:
624             base->CCR = (base->CCR & (~LPSPI_CCR_DBT_MASK)) | LPSPI_CCR_DBT(scaler);
625 #endif /* FSL_FEATURE_LPSPI_HAS_CCR1 */
626             break;
627         default:
628             assert(false);
629             break;
630     }
631 }
632 
633 /*!
634  * brief Calculates the delay based on the desired delay input in nanoseconds (module must be
635  *        disabled to change the delay values).
636  *
637  * This function calculates the values for the following:
638  * SCK to PCS delay, or
639  * PCS to SCK delay, or
640  * The configurations must occur between the transfer delay.
641  *
642  * The delay names are available in type lpspi_delay_type_t.
643  *
644  * The user passes the desired delay and the desired delay value in
645  * nano-seconds.  The function calculates the value needed for the desired delay parameter
646  * and returns the actual calculated delay because an exact delay match may not be possible. In this
647  * case, the closest match is calculated without going below the desired delay value input.
648  * It is possible to input a very large delay value that exceeds the capability of the part, in
649  * which case the maximum supported delay is returned. It is up to the higher level
650  * peripheral driver to alert the user of an out of range delay input.
651  *
652  * Note that the LPSPI module must be configured for master mode before configuring this. And note that
653  * the delayTime = LPSPI_clockSource / (PRESCALE * Delay_scaler).
654  *
655  * param base LPSPI peripheral address.
656  * param delayTimeInNanoSec The desired delay value in nano-seconds.
657  * param whichDelay The desired delay to configuration, which must be of type lpspi_delay_type_t.
658  * param srcClock_Hz  Module source input clock in Hertz.
659  * return actual Calculated delay value in nano-seconds.
660  */
661 uint32_t LPSPI_MasterSetDelayTimes(LPSPI_Type *base,
662                                    uint32_t delayTimeInNanoSec,
663                                    lpspi_delay_type_t whichDelay,
664                                    uint32_t srcClock_Hz)
665 {
666     uint64_t realDelay, bestDelay;
667     uint32_t scaler, bestScaler;
668     uint32_t diff, min_diff;
669     uint64_t initialDelayNanoSec;
670     uint32_t clockDividedPrescaler;
671 
672     /* For delay between transfer, an additional scaler value is needed */
673     uint32_t additionalScaler = 0;
674 
675     /*As the RM note, the LPSPI baud rate clock is itself divided by the PRESCALE setting, which can vary between
676      * transfers.*/
677     clockDividedPrescaler =
678         srcClock_Hz / s_baudratePrescaler[(base->TCR & LPSPI_TCR_PRESCALE_MASK) >> LPSPI_TCR_PRESCALE_SHIFT];
679 
680     /* Find combination of prescaler and scaler resulting in the delay closest to the requested value.*/
681     min_diff = 0xFFFFFFFFU;
682 
683     /* Initialize scaler to max value to generate the max delay */
684     bestScaler = 0xFFU;
685 
686     /* Calculate the initial (min) delay and maximum possible delay based on the specific delay as
687      * the delay divisors are slightly different based on which delay we are configuring.
688      */
689     if (whichDelay == kLPSPI_BetweenTransfer)
690     {
691         /* First calculate the initial, default delay, note min delay is 2 clock cycles. Due to large size of
692          calculated values (uint64_t), we need to break up the calculation into several steps to ensure
693          accurate calculated results
694          */
695         initialDelayNanoSec = 1000000000U;
696         initialDelayNanoSec *= 2U;
697         initialDelayNanoSec /= clockDividedPrescaler;
698 
699         /* Calculate the maximum delay */
700         bestDelay = 1000000000U;
701         bestDelay *= 257U; /* based on DBT+2, or 255 + 2 */
702         bestDelay /= clockDividedPrescaler;
703 
704         additionalScaler = 1U;
705     }
706     else
707     {
708         /* First calculate the initial, default delay, min delay is 1 clock cycle. Due to large size of calculated
709         values (uint64_t), we need to break up the calculation into several steps to ensure accurate calculated
710         results.
711         */
712         initialDelayNanoSec = 1000000000U;
713         initialDelayNanoSec /= clockDividedPrescaler;
714 
715         /* Calculate the maximum delay */
716         bestDelay = 1000000000U;
717         bestDelay *= 256U; /* based on SCKPCS+1 or PCSSCK+1, or 255 + 1 */
718         bestDelay /= clockDividedPrescaler;
719 
720         additionalScaler = 0U;
721     }
722 
723     /* If the initial, default delay is already greater than the desired delay, then
724      * set the delay to their initial value (0) and return the delay. In other words,
725      * there is no way to decrease the delay value further.
726      */
727     if (initialDelayNanoSec >= delayTimeInNanoSec)
728     {
729         LPSPI_MasterSetDelayScaler(base, 0, whichDelay);
730         return (uint32_t)initialDelayNanoSec;
731     }
732 
733     /* If min_diff = 0, the exit for loop */
734     for (scaler = 0U; scaler < 256U; scaler++)
735     {
736         if (min_diff == 0U)
737         {
738             break;
739         }
740         /* Calculate the real delay value as we cycle through the scaler values.
741         Due to large size of calculated values (uint64_t), we need to break up the
742         calculation into several steps to ensure accurate calculated results
743         */
744         realDelay = 1000000000U;
745         realDelay *= ((uint64_t)scaler + 1UL + (uint64_t)additionalScaler);
746         realDelay /= clockDividedPrescaler;
747 
748         /* calculate the delay difference based on the conditional statement
749          * that states that the calculated delay must not be less then the desired delay
750          */
751         if (realDelay >= delayTimeInNanoSec)
752         {
753             diff = (uint32_t)(realDelay - (uint64_t)delayTimeInNanoSec);
754             if (min_diff > diff)
755             {
756                 /* a better match found */
757                 min_diff   = diff;
758                 bestScaler = scaler;
759                 bestDelay  = realDelay;
760             }
761         }
762     }
763 
764     /* write the best scaler value for the delay */
765     LPSPI_MasterSetDelayScaler(base, bestScaler, whichDelay);
766 
767     /* return the actual calculated delay value (in ns) */
768     return (uint32_t)bestDelay;
769 }
770 
771 /*Transactional APIs -- Master*/
772 
773 /*!
774  * brief Initializes the LPSPI master handle.
775  *
776  * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs.  Usually, for a
777  * specified LPSPI instance, call this API once to get the initialized handle.
778 
779  * param base LPSPI peripheral address.
780  * param handle LPSPI handle pointer to lpspi_master_handle_t.
781  * param callback DSPI callback.
782  * param userData callback function parameter.
783  */
784 void LPSPI_MasterTransferCreateHandle(LPSPI_Type *base,
785                                       lpspi_master_handle_t *handle,
786                                       lpspi_master_transfer_callback_t callback,
787                                       void *userData)
788 {
789     assert(handle != NULL);
790 
791     uint32_t instance = LPSPI_GetInstance(base);
792 
793     /* Zero the handle. */
794     (void)memset(handle, 0, sizeof(*handle));
795 
796     handle->callback = callback;
797     handle->userData = userData;
798 
799     if(LP_FLEXCOMM_GetBaseAddress(instance) != 0U)
800     {
801         lpspi_to_lpflexcomm_t handler;
802         handler.lpspi_master_handler = LPSPI_MasterTransferHandleIRQ;
803 
804         /* Save the handle in global variables to support the double weak mechanism. */
805         LP_FLEXCOMM_SetIRQHandler(instance, handler.lpflexcomm_handler, handle, LP_FLEXCOMM_PERIPH_LPSPI);
806     }
807     else
808     {
809         s_lpspiHandle[instance] = handle;
810 
811         /* Set irq handler. */
812         s_lpspiMasterIsr = LPSPI_MasterTransferHandleIRQ;
813     }
814 }
815 
816 /*!
817  * brief Check the argument for transfer .
818  *
819  * param base LPSPI peripheral address.
820  * param transfer the transfer struct to be used.
821  * param isEdma True to check for EDMA transfer, false to check interrupt non-blocking transfer
822  * return Return true for right and false for wrong.
823  */
824 bool LPSPI_CheckTransferArgument(LPSPI_Type *base, lpspi_transfer_t *transfer, bool isEdma)
825 {
826     assert(transfer != NULL);
827     uint32_t bitsPerFrame  = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U;
828     uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U;
829     uint32_t temp          = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
830     /* If the transfer count is zero, then return immediately.*/
831     if (transfer->dataSize == 0U)
832     {
833         return false;
834     }
835 
836     /* If both send buffer and receive buffer is null */
837     if ((NULL == (transfer->txData)) && (NULL == (transfer->rxData)))
838     {
839         return false;
840     }
841 
842     /*The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4 .
843      *For bytesPerFrame greater than 4 situation:
844      *the transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4 ,
845      *otherwise , the transfer data size can be integer multiples of bytesPerFrame.
846      */
847     if (bytesPerFrame <= 4U)
848     {
849         if ((transfer->dataSize % bytesPerFrame) != 0U)
850         {
851             return false;
852         }
853     }
854     else
855     {
856         if ((bytesPerFrame % 4U) != 0U)
857         {
858             if (transfer->dataSize != bytesPerFrame)
859             {
860                 return false;
861             }
862         }
863         else
864         {
865             if ((transfer->dataSize % bytesPerFrame) != 0U)
866             {
867                 return false;
868             }
869         }
870     }
871 
872     /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */
873     if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut)))
874     {
875         /* The 3-wire mode can't send and receive data at the same time. */
876         if ((transfer->txData != NULL) && (transfer->rxData != NULL))
877         {
878             return false;
879         }
880         if (NULL == transfer->txData)
881         {
882             base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK;
883         }
884     }
885 
886     if (isEdma && ((bytesPerFrame % 4U) == 3U))
887     {
888         return false;
889     }
890 
891     return true;
892 }
893 
894 /*!
895  * brief LPSPI master transfer data using a polling method.
896  *
897  * This function transfers data using a  polling method. This is a blocking function, which does not return until all
898  * transfers have been completed.
899  *
900  * Note:
901  * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
902  * For bytesPerFrame greater than 4:
903  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4.
904  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
905  *
906  * param base LPSPI peripheral address.
907  * param transfer pointer to lpspi_transfer_t structure.
908  * return status of status_t.
909  */
910 status_t LPSPI_MasterTransferBlocking(LPSPI_Type *base, lpspi_transfer_t *transfer)
911 {
912     assert(transfer != NULL);
913 
914     /* Check that LPSPI is not busy.*/
915     if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ModuleBusyFlag) != 0U)
916     {
917         return kStatus_LPSPI_Busy;
918     }
919     LPSPI_Enable(base, false);
920     /* Check arguements */
921     if (!LPSPI_CheckTransferArgument(base, transfer, false))
922     {
923         return kStatus_InvalidArgument;
924     }
925 
926     LPSPI_FlushFifo(base, true, true);
927     LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
928 
929     /* Variables */
930     bool isTxMask   = false;
931     bool isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
932     uint8_t bytesEachWrite;
933     uint8_t bytesEachRead;
934     const uint8_t *txData         = transfer->txData;
935     uint8_t *rxData               = transfer->rxData;
936     uint8_t dummyData             = g_lpspiDummyData[LPSPI_GetInstance(base)];
937     uint32_t readData             = 0U;
938     uint32_t txRemainingByteCount = transfer->dataSize;
939     uint32_t rxRemainingByteCount = transfer->dataSize;
940     uint32_t wordToSend =
941         ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
942     /*The TX and RX FIFO sizes are always the same*/
943     uint32_t fifoSize      = LPSPI_GetRxFifoSize(base);
944     uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
945     /* No need to configure PCS continous if the transfer byte count is smaller than frame size */
946     bool isPcsContinuous    = (((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U) &&
947                             (bytesPerFrame < transfer->dataSize));
948     uint32_t rxFifoMaxBytes = MIN(bytesPerFrame, 4U) * fifoSize;
949     uint32_t whichPcs       = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
950     uint32_t width          = (transfer->configFlags & LPSPI_MASTER_WIDTH_MASK) >> LPSPI_MASTER_WIDTH_SHIFT;
951     uint32_t temp           = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
952 
953 #if SPI_RETRY_TIMES
954     uint32_t waitTimes;
955 #endif
956 
957     /* Mask tx data in half duplex mode */
958     if (((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) &&
959         (txData == NULL))
960     {
961         isTxMask = true;
962     }
963 
964     base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
965     LPSPI_Enable(base, true);
966 
967     /* Configure transfer control register. */
968     base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
969                                LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
970                 LPSPI_TCR_PCS(whichPcs) | LPSPI_TCR_WIDTH(width);
971 
972     /*TCR is also shared the FIFO, so wait for TCR written.*/
973     if (!LPSPI_TxFifoReady(base))
974     {
975         return kStatus_LPSPI_Timeout;
976     }
977 
978     /* PCS should be configured separately from the other bits, otherwise it will not take effect. */
979     base->TCR |= LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(isPcsContinuous) | LPSPI_TCR_RXMSK(NULL == rxData);
980 
981     /*TCR is also shared the FIFO, so wait for TCR written.*/
982     if (!LPSPI_TxFifoReady(base))
983     {
984         return kStatus_LPSPI_Timeout;
985     }
986 
987     if (bytesPerFrame <= 4U)
988     {
989         bytesEachWrite = (uint8_t)bytesPerFrame;
990         bytesEachRead  = (uint8_t)bytesPerFrame;
991     }
992     else
993     {
994         bytesEachWrite = 4U;
995         bytesEachRead  = 4U;
996     }
997 
998     /*Write the TX data until txRemainingByteCount is equal to 0 */
999     while (txRemainingByteCount > 0U)
1000     {
1001         if (txRemainingByteCount < bytesEachWrite)
1002         {
1003             bytesEachWrite = (uint8_t)txRemainingByteCount;
1004         }
1005 
1006         /*Wait until TX FIFO is not full*/
1007 #if SPI_RETRY_TIMES
1008         waitTimes = SPI_RETRY_TIMES;
1009         while ((LPSPI_GetTxFifoCount(base) == fifoSize) && (--waitTimes != 0U))
1010 #else
1011         while (LPSPI_GetTxFifoCount(base) == fifoSize)
1012 #endif
1013         {
1014         }
1015 #if SPI_RETRY_TIMES
1016         if (waitTimes == 0U)
1017         {
1018             return kStatus_LPSPI_Timeout;
1019         }
1020 #endif
1021 
1022         /* To prevent rxfifo overflow, ensure transmitting and receiving are executed in parallel */
1023         if (((NULL == rxData) || (rxRemainingByteCount - txRemainingByteCount) < rxFifoMaxBytes))
1024         {
1025             if (isTxMask)
1026             {
1027                 /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared
1028                    by hardware every time when TCR[FRAMESZ] bit of data is transfered.
1029                    In this case TCR[TXMSK] should be set to initiate each transfer. */
1030                 base->TCR |= LPSPI_TCR_TXMSK_MASK;
1031                 if (isPcsContinuous && (txRemainingByteCount == bytesPerFrame))
1032                 {
1033                     /* For the last piece of frame size of data, if is PCS continous mode(TCR[CONT]), TCR[CONTC] should
1034                      * be cleared to de-assert the PCS. Be sure to clear the TXMSK as well otherwise another FRAMESZ
1035                      * of data will be received. */
1036                     base->TCR &= ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK | LPSPI_TCR_TXMSK_MASK);
1037                 }
1038                 txRemainingByteCount -= bytesPerFrame;
1039             }
1040             else
1041             {
1042                 if (txData != NULL)
1043                 {
1044                     wordToSend = LPSPI_CombineWriteData(txData, bytesEachWrite, isByteSwap);
1045                     txData += bytesEachWrite;
1046                 }
1047                 /* Otherwise push data to tx FIFO to initiate transfer */
1048                 LPSPI_WriteData(base, wordToSend);
1049                 txRemainingByteCount -= bytesEachWrite;
1050             }
1051         }
1052 
1053         /* Check whether there is RX data in RX FIFO . Read out the RX data so that the RX FIFO would not overrun. */
1054         if ((rxData != NULL) && (rxRemainingByteCount != 0U))
1055         {
1056             /* To ensure parallel execution in 3-wire mode, after writting 1 to TXMSK to generate clock of
1057                bytesPerFrame's data wait until bytesPerFrame's data is received. */
1058             while (isTxMask && (LPSPI_GetRxFifoCount(base) == 0U))
1059             {
1060             }
1061 #if SPI_RETRY_TIMES
1062             waitTimes = SPI_RETRY_TIMES;
1063             while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U))
1064 #else
1065             while (LPSPI_GetRxFifoCount(base) != 0U)
1066 #endif
1067             {
1068                 readData = LPSPI_ReadData(base);
1069                 if (rxRemainingByteCount < bytesEachRead)
1070                 {
1071                     bytesEachRead = (uint8_t)rxRemainingByteCount;
1072                 }
1073 
1074                 LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap);
1075                 rxData += bytesEachRead;
1076 
1077                 rxRemainingByteCount -= bytesEachRead;
1078             }
1079 #if SPI_RETRY_TIMES
1080             if (waitTimes == 0U)
1081             {
1082                 return kStatus_LPSPI_Timeout;
1083             }
1084 #endif
1085         }
1086     }
1087 
1088     if (isPcsContinuous && !isTxMask)
1089     {
1090         /* In PCS continous mode(TCR[CONT]), after write all the data in TX FIFO, TCR[CONTC] and TCR[CONT] should be
1091            cleared to de-assert the PCS. Note that TCR register also use the TX FIFO. Also CONTC should be cleared when
1092            tx is not masked, otherwise written to TCR register with TXMSK bit wet will initiate a new transfer. */
1093 #if SPI_RETRY_TIMES
1094         waitTimes = SPI_RETRY_TIMES;
1095         while ((LPSPI_GetTxFifoCount(base) == fifoSize) && (--waitTimes != 0U))
1096 #else
1097         while (LPSPI_GetTxFifoCount(base) == fifoSize)
1098 #endif
1099         {
1100         }
1101 #if SPI_RETRY_TIMES
1102         if (waitTimes == 0U)
1103         {
1104             return kStatus_LPSPI_Timeout;
1105         }
1106 #endif
1107         base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK));
1108     }
1109 
1110     /*Read out the RX data in FIFO*/
1111     if (rxData != NULL)
1112     {
1113         while (rxRemainingByteCount > 0U)
1114         {
1115 #if SPI_RETRY_TIMES
1116             waitTimes = SPI_RETRY_TIMES;
1117             while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U))
1118 #else
1119             while (LPSPI_GetRxFifoCount(base) != 0U)
1120 #endif
1121             {
1122                 readData = LPSPI_ReadData(base);
1123 
1124                 if (rxRemainingByteCount < bytesEachRead)
1125                 {
1126                     bytesEachRead = (uint8_t)rxRemainingByteCount;
1127                 }
1128 
1129                 LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap);
1130                 rxData += bytesEachRead;
1131 
1132                 rxRemainingByteCount -= bytesEachRead;
1133             }
1134 #if SPI_RETRY_TIMES
1135             if (waitTimes == 0U)
1136             {
1137                 return kStatus_LPSPI_Timeout;
1138             }
1139 #endif
1140         }
1141     }
1142 
1143     /* Wait for transfer complete flag, that is the PCS is re-asserted. */
1144 #if SPI_RETRY_TIMES
1145     waitTimes = SPI_RETRY_TIMES;
1146     while (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U) && (--waitTimes != 0U))
1147 #else
1148     while ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U)
1149 #endif
1150     {
1151     }
1152 #if SPI_RETRY_TIMES
1153     if (waitTimes == 0U)
1154     {
1155         return kStatus_LPSPI_Timeout;
1156     }
1157 #endif
1158 
1159     return kStatus_Success;
1160 }
1161 
1162 /*!
1163  * brief LPSPI master transfer data using an interrupt method.
1164  *
1165  * This function transfers data using an interrupt method. This is a non-blocking function, which returns right away.
1166  * When all data is transferred, the callback function is called.
1167  *
1168  * Note:
1169  * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
1170  * For bytesPerFrame greater than 4:
1171  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4.
1172  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
1173  *
1174  * param base LPSPI peripheral address.
1175  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1176  * param transfer pointer to lpspi_transfer_t structure.
1177  * return status of status_t.
1178  */
1179 status_t LPSPI_MasterTransferNonBlocking(LPSPI_Type *base, lpspi_master_handle_t *handle, lpspi_transfer_t *transfer)
1180 {
1181     assert(handle != NULL);
1182     assert(transfer != NULL);
1183 
1184     /* Check that we're not busy.*/
1185     if (handle->state == (uint8_t)kLPSPI_Busy)
1186     {
1187         return kStatus_LPSPI_Busy;
1188     }
1189 
1190     LPSPI_Enable(base, false);
1191     /* Check arguements */
1192     if (!LPSPI_CheckTransferArgument(base, transfer, false))
1193     {
1194         return kStatus_InvalidArgument;
1195     }
1196 
1197     /* Flush FIFO, clear status, disable all the interrupts. */
1198     LPSPI_FlushFifo(base, true, true);
1199     LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
1200     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1201 
1202     /* Variables */
1203     bool isRxMask = false;
1204     handle->isTxMask = false;
1205     uint8_t txWatermark;
1206     uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)];
1207     uint32_t tmpTimes;
1208     uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
1209     uint32_t temp     = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
1210 
1211     /* Assign the original value for members of transfer handle. */
1212     handle->state                = (uint8_t)kLPSPI_Busy;
1213     handle->txData               = transfer->txData;
1214     handle->rxData               = transfer->rxData;
1215     handle->txRemainingByteCount = transfer->dataSize;
1216     handle->rxRemainingByteCount = transfer->dataSize;
1217     handle->totalByteCount       = transfer->dataSize;
1218     handle->writeTcrInIsr        = false;
1219     handle->bytesPerFrame = (uint16_t)((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
1220     /* No need to configure PCS continous if the transfer byte count is smaller than frame size */
1221     bool isPcsContinuous = (((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U) &&
1222                             (transfer->dataSize > handle->bytesPerFrame));
1223     handle->writeRegRemainingTimes =
1224         (transfer->dataSize / (uint32_t)handle->bytesPerFrame) * (((uint32_t)handle->bytesPerFrame + 3U) / 4U);
1225     handle->readRegRemainingTimes = handle->writeRegRemainingTimes;
1226     handle->txBuffIfNull =
1227         ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
1228     /*The TX and RX FIFO sizes are always the same*/
1229     handle->fifoSize        = LPSPI_GetRxFifoSize(base);
1230     handle->isPcsContinuous = isPcsContinuous;
1231     handle->isByteSwap      = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
1232     /*Calculate the bytes for write/read the TX/RX register each time*/
1233     if (handle->bytesPerFrame <= 4U)
1234     {
1235         handle->bytesEachWrite = (uint8_t)handle->bytesPerFrame;
1236         handle->bytesEachRead  = (uint8_t)handle->bytesPerFrame;
1237     }
1238     else
1239     {
1240         handle->bytesEachWrite = 4U;
1241         handle->bytesEachRead  = 4U;
1242     }
1243 
1244     /*Set the RX and TX watermarks to reduce the ISR times.*/
1245     if (handle->fifoSize > 1U)
1246     {
1247         txWatermark         = 1U;
1248         handle->rxWatermark = handle->fifoSize - 2U;
1249     }
1250     else
1251     {
1252         txWatermark         = 0U;
1253         handle->rxWatermark = 0U;
1254     }
1255     LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
1256 
1257     /* If there is no rxData, mask the receive data so that receive data is not stored in receive FIFO. */
1258     if (handle->rxData == NULL)
1259     {
1260         isRxMask                     = true;
1261         handle->rxRemainingByteCount = 0;
1262     }
1263 
1264     /* Mask tx data in half duplex mode since the tx/rx share the same pin, so that the data received from slave is not
1265      * interfered. */
1266     if (((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) &&
1267         (handle->txData == NULL))
1268     {
1269         handle->isTxMask = true;
1270     }
1271 
1272     /*Transfers will stall when transmit FIFO is empty or receive FIFO is full. */
1273     base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
1274 
1275     /* Enable module for following configuration of TCR to take effect. */
1276     LPSPI_Enable(base, true);
1277 
1278     /* Configure transfer control register. */
1279     base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
1280                                LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
1281                 LPSPI_TCR_PCS(whichPcs);
1282 
1283     /*TCR is also shared the FIFO , so wait for TCR written.*/
1284     if (!LPSPI_TxFifoReady(base))
1285     {
1286         return kStatus_LPSPI_Timeout;
1287     }
1288 
1289     /* PCS should be configured separately from the other bits, otherwise it will not take effect. */
1290     base->TCR |= LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(isPcsContinuous) | LPSPI_TCR_RXMSK(isRxMask);
1291 
1292     /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
1293      * and you should also enable the INTMUX interupt in your application.
1294      */
1295     (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
1296 
1297     /*TCR is also shared the FIFO , so wait for TCR written.*/
1298     if (!LPSPI_TxFifoReady(base))
1299     {
1300         return kStatus_LPSPI_Timeout;
1301     }
1302 
1303     if (handle->isTxMask)
1304     {
1305         /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared by
1306            hardware every time when TCR[FRAMESZ] bit of data is transfered. In this case TCR[TXMSK] should be set to
1307            initiate each transfer. */
1308 
1309         base->TCR |= LPSPI_TCR_TXMSK_MASK;
1310         handle->txRemainingByteCount -= (uint32_t)handle->bytesPerFrame;
1311     }
1312     else
1313     {
1314         /* Fill up the TX data in FIFO to initiate transfer */
1315         LPSPI_MasterTransferFillUpTxFifo(base, handle);
1316     }
1317 
1318     /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
1319      * The IRQ handler will get the status of RX and TX interrupt flags.
1320      */
1321     if (handle->rxData != NULL)
1322     {
1323         if (handle->isTxMask)
1324         {
1325             /* if tx data is masked, transfer is initiated by writing 1 to TCR[TXMSK] and TCR[FRMESZ] bits of data is
1326                read. If rx water mark is set larger than TCR[FRMESZ], rx interrupt will not be generated. Lower the rx
1327                water mark setting */
1328             if ((handle->bytesPerFrame / 4U) < (uint16_t)handle->rxWatermark)
1329             {
1330                 handle->rxWatermark =
1331                     (uint8_t)(handle->bytesPerFrame / 4U) > 0U ? (uint8_t)(handle->bytesPerFrame / 4U - 1U) : 0U;
1332                 base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(handle->rxWatermark);
1333             }
1334         }
1335         else
1336         {
1337             /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise
1338              *there is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
1339              */
1340             tmpTimes = handle->readRegRemainingTimes;
1341             if (tmpTimes <= handle->rxWatermark)
1342             {
1343                 base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(tmpTimes - 1U);
1344             }
1345         }
1346 
1347         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
1348     }
1349     else
1350     {
1351         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable);
1352     }
1353 
1354     return kStatus_Success;
1355 }
1356 
1357 static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle)
1358 {
1359     assert(handle != NULL);
1360 
1361     uint32_t wordToSend             = 0;
1362     uint8_t fifoSize                = handle->fifoSize;
1363     uint32_t writeRegRemainingTimes = handle->writeRegRemainingTimes;
1364     uint32_t readRegRemainingTimes  = handle->readRegRemainingTimes;
1365     size_t txRemainingByteCount     = handle->txRemainingByteCount;
1366     uint8_t bytesEachWrite          = handle->bytesEachWrite;
1367     bool isByteSwap                 = handle->isByteSwap;
1368 
1369     /* Make sure the difference in remaining TX and RX byte counts does not exceed FIFO depth
1370      * and that the number of TX FIFO entries does not exceed the FIFO depth.
1371      * But no need to make the protection if there is no rxData.
1372      */
1373     while ((LPSPI_GetTxFifoCount(base) < fifoSize) &&
1374            (((readRegRemainingTimes - writeRegRemainingTimes) < (uint32_t)fifoSize) || (handle->rxData == NULL)))
1375     {
1376         if (txRemainingByteCount < (size_t)bytesEachWrite)
1377         {
1378             handle->bytesEachWrite = (uint8_t)txRemainingByteCount;
1379             bytesEachWrite         = handle->bytesEachWrite;
1380         }
1381 
1382         if (handle->txData != NULL)
1383         {
1384             wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap);
1385             handle->txData += bytesEachWrite;
1386         }
1387         else
1388         {
1389             wordToSend = handle->txBuffIfNull;
1390         }
1391 
1392         /*Write the word to TX register*/
1393         LPSPI_WriteData(base, wordToSend);
1394 
1395         /*Decrease the write TX register times.*/
1396         --handle->writeRegRemainingTimes;
1397         writeRegRemainingTimes = handle->writeRegRemainingTimes;
1398 
1399         /*Decrease the remaining TX byte count.*/
1400         handle->txRemainingByteCount -= (size_t)bytesEachWrite;
1401         txRemainingByteCount = handle->txRemainingByteCount;
1402 
1403         if (handle->txRemainingByteCount == 0U)
1404         {
1405             /* If PCS is continuous, update TCR to de-assert PCS */
1406             if (handle->isPcsContinuous)
1407             {
1408                 /* Only write to the TCR if the FIFO has room */
1409                 if (LPSPI_GetTxFifoCount(base) < fifoSize)
1410                 {
1411                     base->TCR             = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
1412                     handle->writeTcrInIsr = false;
1413                 }
1414                 /* Else, set a global flag to tell the ISR to do write to the TCR */
1415                 else
1416                 {
1417                     handle->writeTcrInIsr = true;
1418                 }
1419             }
1420             break;
1421         }
1422     }
1423 }
1424 
1425 static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle)
1426 {
1427     assert(handle != NULL);
1428 
1429     /* Disable interrupt requests*/
1430     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1431 
1432     handle->state = (uint8_t)kLPSPI_Idle;
1433 
1434     if (handle->callback != NULL)
1435     {
1436         handle->callback(base, handle, kStatus_Success, handle->userData);
1437     }
1438 }
1439 
1440 /*!
1441  * brief Gets the master transfer remaining bytes.
1442  *
1443  * This function gets the master transfer remaining bytes.
1444  *
1445  * param base LPSPI peripheral address.
1446  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1447  * param count Number of bytes transferred so far by the non-blocking transaction.
1448  * return status of status_t.
1449  */
1450 status_t LPSPI_MasterTransferGetCount(LPSPI_Type *base, lpspi_master_handle_t *handle, size_t *count)
1451 {
1452     assert(handle != NULL);
1453 
1454     if (NULL == count)
1455     {
1456         return kStatus_InvalidArgument;
1457     }
1458 
1459     /* Catch when there is not an active transfer. */
1460     if (handle->state != (uint8_t)kLPSPI_Busy)
1461     {
1462         *count = 0;
1463         return kStatus_NoTransferInProgress;
1464     }
1465 
1466     size_t remainingByte;
1467 
1468     if (handle->rxData != NULL)
1469     {
1470         remainingByte = handle->rxRemainingByteCount;
1471     }
1472     else
1473     {
1474         remainingByte = handle->txRemainingByteCount;
1475     }
1476 
1477     *count = handle->totalByteCount - remainingByte;
1478 
1479     return kStatus_Success;
1480 }
1481 
1482 /*!
1483  * brief LPSPI master abort transfer which uses an interrupt method.
1484  *
1485  * This function aborts a transfer which uses an interrupt method.
1486  *
1487  * param base LPSPI peripheral address.
1488  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1489  */
1490 void LPSPI_MasterTransferAbort(LPSPI_Type *base, lpspi_master_handle_t *handle)
1491 {
1492     assert(handle != NULL);
1493 
1494     /* Disable interrupt requests*/
1495     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1496 
1497     LPSPI_Reset(base);
1498 
1499     handle->state                = (uint8_t)kLPSPI_Idle;
1500     handle->txRemainingByteCount = 0;
1501     handle->rxRemainingByteCount = 0;
1502 }
1503 
1504 /*!
1505  * brief LPSPI Master IRQ handler function.
1506  *
1507  * This function processes the LPSPI transmit and receive IRQ.
1508  *
1509  * param instance LPSPI instance.
1510  * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
1511  */
1512 void LPSPI_MasterTransferHandleIRQ(uint32_t instance, lpspi_master_handle_t *handle)
1513 {
1514     assert(handle != NULL);
1515     assert(instance < ARRAY_SIZE(s_lpspiBases));
1516     LPSPI_Type *base = s_lpspiBases[instance];
1517     uint32_t readData;
1518     uint8_t bytesEachRead          = handle->bytesEachRead;
1519     bool isByteSwap                = handle->isByteSwap;
1520     uint32_t readRegRemainingTimes = handle->readRegRemainingTimes;
1521 
1522     if (handle->rxData != NULL)
1523     {
1524         if (handle->rxRemainingByteCount != 0U)
1525         {
1526             /* First, disable the interrupts to avoid potentially triggering another interrupt
1527              * while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
1528              * re-enable the interrupts based on the LPSPI state after reading out the FIFO.
1529              */
1530             LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
1531 
1532             while ((LPSPI_GetRxFifoCount(base) != 0U) && (handle->rxRemainingByteCount != 0U))
1533             {
1534                 /*Read out the data*/
1535                 readData = LPSPI_ReadData(base);
1536 
1537                 /*Decrease the read RX register times.*/
1538                 --handle->readRegRemainingTimes;
1539                 readRegRemainingTimes = handle->readRegRemainingTimes;
1540 
1541                 if (handle->rxRemainingByteCount < (size_t)bytesEachRead)
1542                 {
1543                     handle->bytesEachRead = (uint8_t)(handle->rxRemainingByteCount);
1544                     bytesEachRead         = handle->bytesEachRead;
1545                 }
1546 
1547                 LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap);
1548                 handle->rxData += bytesEachRead;
1549 
1550                 /*Decrease the remaining RX byte count.*/
1551                 handle->rxRemainingByteCount -= (size_t)bytesEachRead;
1552             }
1553 
1554             /* Re-enable the interrupts only if rxCount indicates there is more data to receive,
1555              * else we may get a spurious interrupt.
1556              * */
1557             if (handle->rxRemainingByteCount != 0U)
1558             {
1559                 /* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
1560                 LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
1561             }
1562         }
1563 
1564         /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
1565          *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
1566          */
1567         if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
1568         {
1569             base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
1570                         LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U));
1571         }
1572     }
1573 
1574     if (handle->txRemainingByteCount != 0U)
1575     {
1576         if (handle->isTxMask)
1577         {
1578             /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared by
1579                hardware every time when TCR[FRAMESZ] bit of data is transfered.
1580                In this case TCR[TXMSK] should be set to initiate each transfer. */
1581             base->TCR |= LPSPI_TCR_TXMSK_MASK;
1582             if ((handle->txRemainingByteCount == (uint32_t)handle->bytesPerFrame) && (handle->isPcsContinuous))
1583             {
1584                 /* For the last piece of frame size of data, if is PCS continous mode(TCR[CONT]), TCR[CONTC] should
1585                  * be cleared to de-assert the PCS. Be sure to clear the TXMSK as well otherwise another FRAMESZ
1586                  * of data will be received. */
1587                 base->TCR &= ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK | LPSPI_TCR_TXMSK_MASK);
1588             }
1589             handle->txRemainingByteCount -= (uint32_t)handle->bytesPerFrame;
1590         }
1591         else
1592         {
1593             LPSPI_MasterTransferFillUpTxFifo(base, handle);
1594         }
1595     }
1596     else
1597     {
1598         if ((LPSPI_GetTxFifoCount(base) < (handle->fifoSize)))
1599         {
1600             if ((handle->isPcsContinuous) && (handle->writeTcrInIsr) && (!handle->isTxMask))
1601             {
1602                 base->TCR             = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
1603                 handle->writeTcrInIsr = false;
1604             }
1605         }
1606     }
1607 
1608     if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U) && (!handle->writeTcrInIsr))
1609     {
1610         /* If no RX buffer, then transfer is not complete until transfer complete flag sets */
1611         if (handle->rxData == NULL)
1612         {
1613             if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) != 0U)
1614             {
1615                 LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransferCompleteFlag);
1616                 /* Complete the transfer and disable the interrupts */
1617                 LPSPI_MasterTransferComplete(base, handle);
1618             }
1619             else
1620             {
1621                 LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransferCompleteInterruptEnable);
1622                 LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
1623             }
1624         }
1625         else
1626         {
1627             /* Complete the transfer and disable the interrupts */
1628             LPSPI_MasterTransferComplete(base, handle);
1629         }
1630     }
1631 }
1632 
1633 /*Transactional APIs -- Slave*/
1634 /*!
1635  * brief Initializes the LPSPI slave handle.
1636  *
1637  * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs.  Usually, for a
1638  * specified LPSPI instance, call this API once to get the initialized handle.
1639  *
1640  * param base LPSPI peripheral address.
1641  * param handle LPSPI handle pointer to lpspi_slave_handle_t.
1642  * param callback DSPI callback.
1643  * param userData callback function parameter.
1644  */
1645 void LPSPI_SlaveTransferCreateHandle(LPSPI_Type *base,
1646                                      lpspi_slave_handle_t *handle,
1647                                      lpspi_slave_transfer_callback_t callback,
1648                                      void *userData)
1649 {
1650     assert(handle != NULL);
1651 
1652     /* Get instance from peripheral base address. */
1653     uint32_t instance = LPSPI_GetInstance(base);
1654 
1655     /* Zero the handle. */
1656     (void)memset(handle, 0, sizeof(*handle));
1657 
1658     handle->callback = callback;
1659     handle->userData = userData;
1660 
1661     if(LP_FLEXCOMM_GetBaseAddress(instance) != 0U)
1662     {
1663         lpspi_to_lpflexcomm_t handler;
1664         handler.lpspi_slave_handler = LPSPI_SlaveTransferHandleIRQ;
1665 
1666         /* Save the handle in global variables to support the double weak mechanism. */
1667         LP_FLEXCOMM_SetIRQHandler(instance, handler.lpflexcomm_handler, handle, LP_FLEXCOMM_PERIPH_LPSPI);
1668     }
1669     else
1670     {
1671         s_lpspiHandle[instance] = handle;
1672 
1673         /* Set irq handler. */
1674         s_lpspiSlaveIsr = LPSPI_SlaveTransferHandleIRQ;
1675     }
1676 }
1677 
1678 /*!
1679  * brief LPSPI slave transfer data using an interrupt method.
1680  *
1681  * This function transfer data using an interrupt method. This is a non-blocking function, which returns right away.
1682  * When all data is transferred, the callback function is called.
1683  *
1684  * Note:
1685  * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
1686  * For bytesPerFrame greater than 4:
1687  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
1688  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
1689  *
1690  * param base LPSPI peripheral address.
1691  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1692  * param transfer pointer to lpspi_transfer_t structure.
1693  * return status of status_t.
1694  */
1695 status_t LPSPI_SlaveTransferNonBlocking(LPSPI_Type *base, lpspi_slave_handle_t *handle, lpspi_transfer_t *transfer)
1696 {
1697     assert(handle != NULL);
1698     assert(transfer != NULL);
1699 
1700     /* Check that we're not busy.*/
1701     if (handle->state == (uint8_t)kLPSPI_Busy)
1702     {
1703         return kStatus_LPSPI_Busy;
1704     }
1705     LPSPI_Enable(base, false);
1706     /* Check arguements */
1707     if (!LPSPI_CheckTransferArgument(base, transfer, false))
1708     {
1709         return kStatus_InvalidArgument;
1710     }
1711 
1712     /* Flush FIFO, clear status, disable all the inerrupts. */
1713     LPSPI_FlushFifo(base, true, true);
1714     LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
1715     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1716 
1717     /* Variables */
1718     bool isRxMask = false;
1719     bool isTxMask = false;
1720     uint8_t txWatermark;
1721     uint32_t readRegRemainingTimes;
1722     uint32_t whichPcs      = (transfer->configFlags & LPSPI_SLAVE_PCS_MASK) >> LPSPI_SLAVE_PCS_SHIFT;
1723     uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
1724 
1725     /* Assign the original value for members of transfer handle. */
1726     handle->state                  = (uint8_t)kLPSPI_Busy;
1727     handle->txData                 = transfer->txData;
1728     handle->rxData                 = transfer->rxData;
1729     handle->txRemainingByteCount   = transfer->dataSize;
1730     handle->rxRemainingByteCount   = transfer->dataSize;
1731     handle->totalByteCount         = transfer->dataSize;
1732     handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U);
1733     handle->readRegRemainingTimes  = handle->writeRegRemainingTimes;
1734     /*The TX and RX FIFO sizes are always the same*/
1735     handle->fifoSize   = LPSPI_GetRxFifoSize(base);
1736     handle->isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_SlaveByteSwap) != 0U);
1737     /*Calculate the bytes for write/read the TX/RX register each time*/
1738     if (bytesPerFrame <= 4U)
1739     {
1740         handle->bytesEachWrite = (uint8_t)bytesPerFrame;
1741         handle->bytesEachRead  = (uint8_t)bytesPerFrame;
1742     }
1743     else
1744     {
1745         handle->bytesEachWrite = 4U;
1746         handle->bytesEachRead  = 4U;
1747     }
1748     /* Set proper RX and TX watermarks to reduce the ISR response times. */
1749     if (handle->fifoSize > 1U)
1750     {
1751         txWatermark         = 1U;
1752         handle->rxWatermark = handle->fifoSize - 2U;
1753     }
1754     else
1755     {
1756         txWatermark         = 0U;
1757         handle->rxWatermark = 0U;
1758     }
1759     LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
1760 
1761     /* If there is no rxData, mask the receive data so that receive data is not stored in receive FIFO. */
1762     if (handle->rxData == NULL)
1763     {
1764         isRxMask                     = true;
1765         handle->rxRemainingByteCount = 0U;
1766     }
1767     /* If there is no txData, mask the transmit data so that no data is loaded from transmit FIFO and output pin
1768      * is tristated. */
1769     if (handle->txData == NULL)
1770     {
1771         isTxMask                     = true;
1772         handle->txRemainingByteCount = 0U;
1773     }
1774 
1775     /* Enable module for following configuration of TCR to take effect. */
1776     LPSPI_Enable(base, true);
1777 
1778     base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
1779                                LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
1780                 LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_TXMSK(isTxMask) | LPSPI_TCR_PCS(whichPcs);
1781 
1782     /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
1783      * and you should also enable the INTMUX interupt in your application.
1784      */
1785     (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
1786 
1787     /*TCR is also shared the FIFO, so wait for TCR written.*/
1788     if (!LPSPI_TxFifoReady(base))
1789     {
1790         return kStatus_LPSPI_Timeout;
1791     }
1792 
1793     /* Fill up the TX data in FIFO */
1794     if (handle->txData != NULL)
1795     {
1796         LPSPI_SlaveTransferFillUpTxFifo(base, handle);
1797     }
1798 
1799     /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
1800      * The IRQ handler will get the status of RX and TX interrupt flags.
1801      */
1802     if (handle->rxData != NULL)
1803     {
1804         /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
1805          *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
1806          */
1807         readRegRemainingTimes = handle->readRegRemainingTimes;
1808         if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
1809         {
1810             base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(readRegRemainingTimes - 1U);
1811         }
1812 
1813         /* RX request and FIFO overflow request enable */
1814         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable | (uint32_t)kLPSPI_ReceiveErrorInterruptEnable);
1815     }
1816     else
1817     {
1818         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable);
1819     }
1820 
1821     if (handle->txData != NULL)
1822     {
1823         /* TX FIFO underflow request enable */
1824         LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransmitErrorInterruptEnable);
1825     }
1826 
1827     return kStatus_Success;
1828 }
1829 
1830 static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle)
1831 {
1832     assert(handle != NULL);
1833 
1834     uint32_t wordToSend    = 0U;
1835     uint8_t bytesEachWrite = handle->bytesEachWrite;
1836     bool isByteSwap        = handle->isByteSwap;
1837 
1838     while (LPSPI_GetTxFifoCount(base) < (handle->fifoSize))
1839     {
1840         if (handle->txRemainingByteCount < (size_t)bytesEachWrite)
1841         {
1842             handle->bytesEachWrite = (uint8_t)handle->txRemainingByteCount;
1843             bytesEachWrite         = handle->bytesEachWrite;
1844         }
1845 
1846         wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap);
1847         handle->txData += bytesEachWrite;
1848 
1849         /*Decrease the remaining TX byte count.*/
1850         handle->txRemainingByteCount -= (size_t)bytesEachWrite;
1851 
1852         /*Write the word to TX register*/
1853         LPSPI_WriteData(base, wordToSend);
1854 
1855         if (handle->txRemainingByteCount == 0U)
1856         {
1857             break;
1858         }
1859     }
1860 }
1861 
1862 static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle)
1863 {
1864     assert(handle != NULL);
1865 
1866     status_t status = kStatus_Success;
1867 
1868     /* Disable interrupt requests*/
1869     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
1870 
1871     if (handle->state == (uint8_t)kLPSPI_Error)
1872     {
1873         status = kStatus_LPSPI_Error;
1874     }
1875     else
1876     {
1877         status = kStatus_Success;
1878     }
1879 
1880     handle->state = (uint8_t)kLPSPI_Idle;
1881 
1882     if (handle->callback != NULL)
1883     {
1884         handle->callback(base, handle, status, handle->userData);
1885     }
1886 }
1887 
1888 /*!
1889  * brief Gets the slave transfer remaining bytes.
1890  *
1891  * This function gets the slave transfer remaining bytes.
1892  *
1893  * param base LPSPI peripheral address.
1894  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1895  * param count Number of bytes transferred so far by the non-blocking transaction.
1896  * return status of status_t.
1897  */
1898 status_t LPSPI_SlaveTransferGetCount(LPSPI_Type *base, lpspi_slave_handle_t *handle, size_t *count)
1899 {
1900     assert(handle != NULL);
1901 
1902     if (NULL == count)
1903     {
1904         return kStatus_InvalidArgument;
1905     }
1906 
1907     /* Catch when there is not an active transfer. */
1908     if (handle->state != (uint8_t)kLPSPI_Busy)
1909     {
1910         *count = 0;
1911         return kStatus_NoTransferInProgress;
1912     }
1913 
1914     size_t remainingByte;
1915 
1916     if (handle->rxData != NULL)
1917     {
1918         remainingByte = handle->rxRemainingByteCount;
1919     }
1920     else
1921     {
1922         remainingByte = handle->txRemainingByteCount;
1923     }
1924 
1925     *count = handle->totalByteCount - remainingByte;
1926 
1927     return kStatus_Success;
1928 }
1929 
1930 /*!
1931  * brief LPSPI slave aborts a transfer which uses an interrupt method.
1932  *
1933  * This function aborts a transfer which uses an interrupt method.
1934  *
1935  * param base LPSPI peripheral address.
1936  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1937  */
1938 void LPSPI_SlaveTransferAbort(LPSPI_Type *base, lpspi_slave_handle_t *handle)
1939 {
1940     assert(handle != NULL);
1941 
1942     /* Disable interrupt requests*/
1943     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
1944 
1945     LPSPI_Reset(base);
1946 
1947     handle->state                = (uint8_t)kLPSPI_Idle;
1948     handle->txRemainingByteCount = 0U;
1949     handle->rxRemainingByteCount = 0U;
1950 }
1951 
1952 /*!
1953  * brief LPSPI Slave IRQ handler function.
1954  *
1955  * This function processes the LPSPI transmit and receives an IRQ.
1956  *
1957  * param instance LPSPI instance index.
1958  * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
1959  */
1960 void LPSPI_SlaveTransferHandleIRQ(uint32_t instance, lpspi_slave_handle_t *handle)
1961 {
1962     assert(handle != NULL);
1963     assert(instance < ARRAY_SIZE(s_lpspiBases));
1964     LPSPI_Type *base = s_lpspiBases[instance];
1965     uint32_t readData; /* variable to store word read from RX FIFO */
1966     uint8_t bytesEachRead = handle->bytesEachRead;
1967     bool isByteSwap       = handle->isByteSwap;
1968     uint32_t readRegRemainingTimes;
1969 
1970     if (handle->rxData != NULL)
1971     {
1972         if (handle->rxRemainingByteCount > 0U)
1973         {
1974             while (LPSPI_GetRxFifoCount(base) != 0U)
1975             {
1976                 /*Read out the data*/
1977                 readData = LPSPI_ReadData(base);
1978 
1979                 /*Decrease the read RX register times.*/
1980                 --handle->readRegRemainingTimes;
1981 
1982                 if (handle->rxRemainingByteCount < (size_t)bytesEachRead)
1983                 {
1984                     handle->bytesEachRead = (uint8_t)handle->rxRemainingByteCount;
1985                     bytesEachRead         = handle->bytesEachRead;
1986                 }
1987 
1988                 LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap);
1989                 handle->rxData += bytesEachRead;
1990 
1991                 /*Decrease the remaining RX byte count.*/
1992                 handle->rxRemainingByteCount -= (size_t)bytesEachRead;
1993 
1994                 if ((handle->txRemainingByteCount > 0U) && (handle->txData != NULL))
1995                 {
1996                     LPSPI_SlaveTransferFillUpTxFifo(base, handle);
1997                 }
1998 
1999                 if (handle->rxRemainingByteCount == 0U)
2000                 {
2001                     break;
2002                 }
2003             }
2004         }
2005 
2006         /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
2007          *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
2008          */
2009         readRegRemainingTimes = handle->readRegRemainingTimes;
2010         if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
2011         {
2012             base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
2013                         LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U));
2014         }
2015     }
2016     if ((handle->rxData == NULL) && (handle->txRemainingByteCount != 0U) && (handle->txData != NULL))
2017     {
2018         LPSPI_SlaveTransferFillUpTxFifo(base, handle);
2019     }
2020 
2021     if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U))
2022     {
2023         /* If no RX buffer, then transfer is not complete until transfer complete flag sets and the TX FIFO empty*/
2024         if (handle->rxData == NULL)
2025         {
2026             if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_FrameCompleteFlag) != 0U) &&
2027                 (LPSPI_GetTxFifoCount(base) == 0U))
2028             {
2029                 LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag);
2030                 /* Complete the transfer and disable the interrupts */
2031                 LPSPI_SlaveTransferComplete(base, handle);
2032             }
2033             else
2034             {
2035                 LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag);
2036                 LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_FrameCompleteInterruptEnable);
2037                 LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
2038             }
2039         }
2040         else
2041         {
2042             /* Complete the transfer and disable the interrupts */
2043             LPSPI_SlaveTransferComplete(base, handle);
2044         }
2045     }
2046 
2047     /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */
2048     if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransmitErrorFlag) != 0U) &&
2049         ((base->IER & LPSPI_IER_TEIE_MASK) != 0U))
2050     {
2051         LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransmitErrorFlag);
2052         /* Change state to error and clear flag */
2053         if (handle->txData != NULL)
2054         {
2055             handle->state = (uint8_t)kLPSPI_Error;
2056         }
2057         handle->errorCount++;
2058         /* ERR051588: Clear FIFO after underrun occurs */
2059         LPSPI_FlushFifo(base, true, false);
2060     }
2061     /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */
2062     if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ReceiveErrorFlag) != 0U) &&
2063         ((base->IER & LPSPI_IER_REIE_MASK) != 0U))
2064     {
2065         LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_ReceiveErrorFlag);
2066         /* Change state to error and clear flag */
2067         if (handle->txData != NULL)
2068         {
2069             handle->state = (uint8_t)kLPSPI_Error;
2070         }
2071         handle->errorCount++;
2072     }
2073 }
2074 
2075 static uint32_t LPSPI_CombineWriteData(const uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap)
2076 {
2077     assert(txData != NULL);
2078 
2079     uint32_t wordToSend = 0U;
2080 
2081     switch (bytesEachWrite)
2082     {
2083         case 1:
2084             wordToSend = *txData;
2085             ++txData;
2086             break;
2087 
2088         case 2:
2089             if (!isByteSwap)
2090             {
2091                 wordToSend = *txData;
2092                 ++txData;
2093                 wordToSend |= (unsigned)(*txData) << 8U;
2094                 ++txData;
2095             }
2096             else
2097             {
2098                 wordToSend = (unsigned)(*txData) << 8U;
2099                 ++txData;
2100                 wordToSend |= *txData;
2101                 ++txData;
2102             }
2103 
2104             break;
2105 
2106         case 3:
2107             if (!isByteSwap)
2108             {
2109                 wordToSend = *txData;
2110                 ++txData;
2111                 wordToSend |= (unsigned)(*txData) << 8U;
2112                 ++txData;
2113                 wordToSend |= (unsigned)(*txData) << 16U;
2114                 ++txData;
2115             }
2116             else
2117             {
2118                 wordToSend = (unsigned)(*txData) << 16U;
2119                 ++txData;
2120                 wordToSend |= (unsigned)(*txData) << 8U;
2121                 ++txData;
2122                 wordToSend |= *txData;
2123                 ++txData;
2124             }
2125             break;
2126 
2127         case 4:
2128             if (!isByteSwap)
2129             {
2130                 wordToSend = *txData;
2131                 ++txData;
2132                 wordToSend |= (unsigned)(*txData) << 8U;
2133                 ++txData;
2134                 wordToSend |= (unsigned)(*txData) << 16U;
2135                 ++txData;
2136                 wordToSend |= (unsigned)(*txData) << 24U;
2137                 ++txData;
2138             }
2139             else
2140             {
2141                 wordToSend = (unsigned)(*txData) << 24U;
2142                 ++txData;
2143                 wordToSend |= (unsigned)(*txData) << 16U;
2144                 ++txData;
2145                 wordToSend |= (unsigned)(*txData) << 8U;
2146                 ++txData;
2147                 wordToSend |= *txData;
2148                 ++txData;
2149             }
2150             break;
2151 
2152         default:
2153             assert(false);
2154             break;
2155     }
2156     return wordToSend;
2157 }
2158 
2159 static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap)
2160 {
2161     assert(rxData != NULL);
2162 
2163     switch (bytesEachRead)
2164     {
2165         case 1:
2166             *rxData = (uint8_t)readData;
2167             ++rxData;
2168             break;
2169 
2170         case 2:
2171             if (!isByteSwap)
2172             {
2173                 *rxData = (uint8_t)readData;
2174                 ++rxData;
2175                 *rxData = (uint8_t)(readData >> 8);
2176                 ++rxData;
2177             }
2178             else
2179             {
2180                 *rxData = (uint8_t)(readData >> 8);
2181                 ++rxData;
2182                 *rxData = (uint8_t)readData;
2183                 ++rxData;
2184             }
2185             break;
2186 
2187         case 3:
2188             if (!isByteSwap)
2189             {
2190                 *rxData = (uint8_t)readData;
2191                 ++rxData;
2192                 *rxData = (uint8_t)(readData >> 8);
2193                 ++rxData;
2194                 *rxData = (uint8_t)(readData >> 16);
2195                 ++rxData;
2196             }
2197             else
2198             {
2199                 *rxData = (uint8_t)(readData >> 16);
2200                 ++rxData;
2201                 *rxData = (uint8_t)(readData >> 8);
2202                 ++rxData;
2203                 *rxData = (uint8_t)readData;
2204                 ++rxData;
2205             }
2206             break;
2207 
2208         case 4:
2209             if (!isByteSwap)
2210             {
2211                 *rxData = (uint8_t)readData;
2212                 ++rxData;
2213                 *rxData = (uint8_t)(readData >> 8);
2214                 ++rxData;
2215                 *rxData = (uint8_t)(readData >> 16);
2216                 ++rxData;
2217                 *rxData = (uint8_t)(readData >> 24);
2218                 ++rxData;
2219             }
2220             else
2221             {
2222                 *rxData = (uint8_t)(readData >> 24);
2223                 ++rxData;
2224                 *rxData = (uint8_t)(readData >> 16);
2225                 ++rxData;
2226                 *rxData = (uint8_t)(readData >> 8);
2227                 ++rxData;
2228                 *rxData = (uint8_t)readData;
2229                 ++rxData;
2230             }
2231             break;
2232 
2233         default:
2234             assert(false);
2235             break;
2236     }
2237 }
2238 
2239 static bool LPSPI_TxFifoReady(LPSPI_Type *base)
2240 {
2241 #if SPI_RETRY_TIMES
2242     uint32_t waitTimes = SPI_RETRY_TIMES;
2243     while (((uint8_t)LPSPI_GetTxFifoCount(base) != 0U) && (--waitTimes != 0U))
2244 #else
2245     while ((uint8_t)LPSPI_GetTxFifoCount(base) != 0U)
2246 #endif
2247     {
2248     }
2249 #if SPI_RETRY_TIMES
2250     if (waitTimes == 0U)
2251     {
2252         return false;
2253     }
2254 #endif
2255     return true;
2256 }
2257 
2258 void LPSPI_CommonIRQHandler(LPSPI_Type *base, uint32_t instance);
2259 void LPSPI_CommonIRQHandler(LPSPI_Type *base, uint32_t instance)
2260 {
2261     assert(s_lpspiHandle[instance] != NULL);
2262     if (LPSPI_IsMaster(base))
2263     {
2264         s_lpspiMasterIsr(instance, (lpspi_master_handle_t *)s_lpspiHandle[instance]);
2265     }
2266     else
2267     {
2268         s_lpspiSlaveIsr(instance, (lpspi_slave_handle_t *)s_lpspiHandle[instance]);
2269     }
2270     SDK_ISR_EXIT_BARRIER;
2271 }
2272 
2273 #if defined(LPSPI14)
2274 void LPSPI14_DriverIRQHandler(void);
2275 void LPSPI14_DriverIRQHandler(void)
2276 {
2277     LPSPI_CommonIRQHandler(LPSPI14, 14);
2278 }
2279 #endif
2280 
2281 #if defined(LPSPI16)
2282 void LPSPI16_DriverIRQHandler(void);
2283 void LPSPI16_DriverIRQHandler(void)
2284 {
2285     LPSPI_CommonIRQHandler(LPSPI16, 16);
2286 }
2287 #endif
2288