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