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_edma.h"
10 
11 /*
12  * $Coverage Justification Reference$
13  *
14  * $Justification fsl_lpspi_edma_c_ref_1$
15  * The default branch cannot be executed in any circumstances, it is only added to avoid MISRA violation.
16  *
17  */
18 /***********************************************************************************************************************
19  * Definitions
20  ***********************************************************************************************************************/
21 
22 /* Component ID definition, used by tools. */
23 #ifndef FSL_COMPONENT_ID
24 #define FSL_COMPONENT_ID "platform.drivers.lpspi_edma"
25 #endif
26 
27 /*!
28  * @brief Structure definition for dspi_master_edma_private_handle_t. The structure is private.
29  */
30 typedef struct _lpspi_master_edma_private_handle
31 {
32     LPSPI_Type *base;                   /*!< LPSPI peripheral base address. */
33     lpspi_master_edma_handle_t *handle; /*!< lpspi_master_edma_handle_t handle */
34 } lpspi_master_edma_private_handle_t;
35 
36 /*!
37  * @brief Structure definition for dspi_slave_edma_private_handle_t. The structure is private.
38  */
39 typedef struct _lpspi_slave_edma_private_handle
40 {
41     LPSPI_Type *base;                  /*!< LPSPI peripheral base address. */
42     lpspi_slave_edma_handle_t *handle; /*!< lpspi_slave_edma_handle_t handle */
43 } lpspi_slave_edma_private_handle_t;
44 
45 /***********************************************************************************************************************
46  * Prototypes
47  ***********************************************************************************************************************/
48 
49 /*!
50  * @brief EDMA_LpspiMasterCallback after the LPSPI master transfer completed by using EDMA.
51  * This is not a public API.
52  */
53 static void EDMA_LpspiMasterCallback(edma_handle_t *edmaHandle,
54                                      void *g_lpspiEdmaPrivateHandle,
55                                      bool transferDone,
56                                      uint32_t tcds);
57 
58 /*!
59  * @brief EDMA_LpspiSlaveCallback after the LPSPI slave transfer completed by using EDMA.
60  * This is not a public API.
61  */
62 static void EDMA_LpspiSlaveCallback(edma_handle_t *edmaHandle,
63                                     void *g_lpspiEdmaPrivateHandle,
64                                     bool transferDone,
65                                     uint32_t tcds);
66 
67 static void LPSPI_SeparateEdmaReadData(uint8_t *rxData, uint32_t readData, uint32_t bytesEachRead, bool isByteSwap);
68 
69 /***********************************************************************************************************************
70  * Variables
71  ***********************************************************************************************************************/
72 /*! @brief Pointers to lpspi bases for each instance. */
73 static LPSPI_Type *const s_lpspiBases[] = LPSPI_BASE_PTRS;
74 
75 /*! @brief Pointers to lpspi edma handles for each instance. */
76 static lpspi_master_edma_private_handle_t s_lpspiMasterEdmaPrivateHandle[ARRAY_SIZE(s_lpspiBases)];
77 static lpspi_slave_edma_private_handle_t s_lpspiSlaveEdmaPrivateHandle[ARRAY_SIZE(s_lpspiBases)];
78 
79 /***********************************************************************************************************************
80  * Code
81  ***********************************************************************************************************************/
LPSPI_SeparateEdmaReadData(uint8_t * rxData,uint32_t readData,uint32_t bytesEachRead,bool isByteSwap)82 static void LPSPI_SeparateEdmaReadData(uint8_t *rxData, uint32_t readData, uint32_t bytesEachRead, bool isByteSwap)
83 {
84     assert(rxData != NULL);
85 
86     /*
87      * $Branch Coverage Justification$
88      * $ref fsl_lpspi_edma_c_ref_1$
89      */
90     switch (bytesEachRead)
91     {
92         case 1:
93             if (!isByteSwap)
94             {
95                 *rxData = (uint8_t)readData;
96                 ++rxData;
97             }
98             else
99             {
100                 *rxData = (uint8_t)(readData >> 24);
101                 ++rxData;
102             }
103             break;
104 
105         case 2:
106             if (!isByteSwap)
107             {
108                 *rxData = (uint8_t)readData;
109                 ++rxData;
110                 *rxData = (uint8_t)(readData >> 8);
111                 ++rxData;
112             }
113             else
114             {
115                 *rxData = (uint8_t)(readData >> 16);
116                 ++rxData;
117                 *rxData = (uint8_t)(readData >> 24);
118                 ++rxData;
119             }
120             break;
121 
122         case 4:
123 
124             *rxData = (uint8_t)readData;
125             ++rxData;
126             *rxData = (uint8_t)(readData >> 8);
127             ++rxData;
128             *rxData = (uint8_t)(readData >> 16);
129             ++rxData;
130             *rxData = (uint8_t)(readData >> 24);
131             ++rxData;
132 
133             break;
134 
135         default:
136             assert(false);
137             break;
138     }
139 }
140 
141 /*!
142  * brief Initializes the LPSPI master eDMA handle.
143  *
144  * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs.  Usually, for a
145  * specified LPSPI instance, call this API once to get the initialized handle.
146  *
147  * Note that the LPSPI eDMA has a separated (Rx and Rx as two sources) or shared (Rx  and Tx are the same source) DMA
148  * request source.
149  * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
150  * Tx DMAMUX source for edmaIntermediaryToTxRegHandle.
151  * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle.
152  *
153  * param base LPSPI peripheral base address.
154  * param handle LPSPI handle pointer to lpspi_master_edma_handle_t.
155  * param callback LPSPI callback.
156  * param userData callback function parameter.
157  * param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
158  * param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
159  */
LPSPI_MasterTransferCreateHandleEDMA(LPSPI_Type * base,lpspi_master_edma_handle_t * handle,lpspi_master_edma_transfer_callback_t callback,void * userData,edma_handle_t * edmaRxRegToRxDataHandle,edma_handle_t * edmaTxDataToTxRegHandle)160 void LPSPI_MasterTransferCreateHandleEDMA(LPSPI_Type *base,
161                                           lpspi_master_edma_handle_t *handle,
162                                           lpspi_master_edma_transfer_callback_t callback,
163                                           void *userData,
164                                           edma_handle_t *edmaRxRegToRxDataHandle,
165                                           edma_handle_t *edmaTxDataToTxRegHandle)
166 {
167     assert(handle != NULL);
168     assert(edmaRxRegToRxDataHandle != NULL);
169     assert(edmaTxDataToTxRegHandle != NULL);
170 
171     /* Zero the handle. */
172     (void)memset(handle, 0, sizeof(*handle));
173 
174     uint32_t instance = LPSPI_GetInstance(base);
175 
176     s_lpspiMasterEdmaPrivateHandle[instance].base   = base;
177     s_lpspiMasterEdmaPrivateHandle[instance].handle = handle;
178 
179     handle->callback = callback;
180     handle->userData = userData;
181 
182     handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle;
183     handle->edmaTxDataToTxRegHandle = edmaTxDataToTxRegHandle;
184 }
185 
LPSPI_PrepareTransferEDMA(LPSPI_Type * base)186 static void LPSPI_PrepareTransferEDMA(LPSPI_Type *base)
187 {
188     /* Flush FIFO, clear status, disable all the inerrupts and DMA requests. */
189     LPSPI_FlushFifo(base, true, true);
190     LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
191     LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
192     LPSPI_DisableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable);
193 }
194 
195 /*!
196  * brief LPSPI master config transfer parameter using eDMA.
197  *
198  * This function is preparing to transfers data using eDMA.
199  *
200  * param base LPSPI peripheral base address.
201  * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
202  * param configFlags transfer configuration flags. ref _lpspi_transfer_config_flag_for_master.
203  * return Indicates whether LPSPI master transfer was successful or not.
204  * retval kStatus_Success          Execution successfully.
205  * retval kStatus_LPSPI_Busy       The LPSPI device is busy.
206  */
LPSPI_MasterTransferPrepareEDMALite(LPSPI_Type * base,lpspi_master_edma_handle_t * handle,uint32_t configFlags)207 status_t LPSPI_MasterTransferPrepareEDMALite(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, uint32_t configFlags)
208 {
209     assert(handle != NULL);
210 
211     /* Check that we're not busy.*/
212     if (handle->state == (uint8_t)kLPSPI_Busy)
213     {
214         return kStatus_LPSPI_Busy;
215     }
216 
217     /* Disable module before configuration */
218     LPSPI_Enable(base, false);
219 
220     LPSPI_PrepareTransferEDMA(base);
221 
222     bool isByteSwap      = ((configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
223     bool isPcsContinuous = ((configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U);
224     uint32_t instance    = LPSPI_GetInstance(base);
225     uint8_t dummyData    = g_lpspiDummyData[instance];
226     /*Used for byte swap*/
227     uint32_t whichPcs      = (configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
228     uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
229 
230     handle->txBuffIfNull =
231         ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
232     /*The TX and RX FIFO sizes are always the same*/
233     handle->fifoSize            = LPSPI_GetRxFifoSize(base);
234     handle->isPcsContinuous     = isPcsContinuous;
235     handle->isByteSwap          = isByteSwap;
236     handle->isThereExtraRxBytes = false;
237 
238     /*Because DMA is fast enough , so set the RX and TX watermarks to 0 .*/
239     LPSPI_SetFifoWatermarks(base, 0U, 0U);
240 
241     /* Transfers will stall when transmit FIFO is empty or receive FIFO is full. */
242     base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
243 
244     /* Enable module for following configuration of TCR to take effect. */
245     LPSPI_Enable(base, true);
246 
247     /* For DMA transfer , we'd better not masked the transmit data and receive data in TCR since the transfer flow is
248      * hard to controlled by software. */
249     base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_BYSW_MASK | LPSPI_TCR_PCS_MASK)) |
250                 LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_BYSW(isByteSwap) | LPSPI_TCR_PCS(whichPcs);
251 
252     /*Calculate the bytes for write/read the TX/RX register each time*/
253     if (bytesPerFrame <= 4U)
254     {
255         handle->bytesEachWrite = (uint8_t)bytesPerFrame;
256         handle->bytesEachRead  = (uint8_t)bytesPerFrame;
257         handle->bytesLastRead  = (uint8_t)bytesPerFrame;
258     }
259     else
260     {
261         handle->bytesEachWrite = 4U;
262         handle->bytesEachRead  = 4U;
263 
264         handle->bytesLastRead = 4U;
265     }
266     return kStatus_Success;
267 }
268 
269 /*!
270  * brief LPSPI master transfer data using eDMA without configs.
271  *
272  * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
273  * is transferred, the callback function is called.
274  *
275  * Note:
276  * This API is only for transfer through DMA without configuration.
277  * Before calling this API, you must call LPSPI_MasterTransferPrepareEDMALite to configure it once.
278  * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
279  * For bytesPerFrame greater than 4:
280  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
281  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
282  *
283  * param base LPSPI peripheral base address.
284  * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
285  * param transfer pointer to lpspi_transfer_t structure, config field is not working.
286  * return Indicates whether LPSPI master transfer was successful or not.
287  * retval kStatus_Success          Execution successfully.
288  * retval kStatus_LPSPI_Busy       The LPSPI device is busy.
289  * retval kStatus_InvalidArgument  The transfer structure is invalid.
290  */
LPSPI_MasterTransferEDMALite(LPSPI_Type * base,lpspi_master_edma_handle_t * handle,lpspi_transfer_t * transfer)291 status_t LPSPI_MasterTransferEDMALite(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer)
292 {
293     assert(handle != NULL);
294     assert(transfer != NULL);
295 
296     /* Check that we're not busy.*/
297     if (handle->state == (uint8_t)kLPSPI_Busy)
298     {
299         return kStatus_LPSPI_Busy;
300     }
301 
302     /* Check arguements */
303     if (!LPSPI_CheckTransferArgument(base, transfer, true))
304     {
305         return kStatus_InvalidArgument;
306     }
307 
308     /* Variables */
309     bool isThereExtraTxBytes = false;
310     uint8_t bytesLastWrite   = 0;
311     uint32_t instance        = LPSPI_GetInstance(base);
312     /*Used for byte swap*/
313     uint32_t addrOffset    = 0;
314     uint32_t rxAddr        = LPSPI_GetRxRegisterAddress(base);
315     uint32_t txAddr        = LPSPI_GetTxRegisterAddress(base);
316     uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
317     edma_transfer_config_t transferConfigRx = {0};
318     edma_transfer_config_t transferConfigTx = {0};
319     edma_tcd_t *softwareTCD_pcsContinuous   = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[2]) & (~0x1FU));
320     edma_tcd_t *softwareTCD_extraBytes      = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[1]) & (~0x1FU));
321 
322     handle->state                  = (uint8_t)kLPSPI_Busy;
323     handle->txData                 = transfer->txData;
324     handle->rxData                 = transfer->rxData;
325     handle->txRemainingByteCount   = transfer->dataSize;
326     handle->rxRemainingByteCount   = transfer->dataSize;
327     handle->totalByteCount         = transfer->dataSize;
328     handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U);
329     handle->readRegRemainingTimes  = handle->writeRegRemainingTimes;
330 
331     handle->isThereExtraRxBytes = false;
332 
333     /*Calculate the bytes for write/read the TX/RX register each time*/
334     if (bytesPerFrame > 4U)
335     {
336         if ((transfer->dataSize % 4U) != 0U)
337         {
338             bytesLastWrite        = (uint8_t)(transfer->dataSize % 4U);
339             handle->bytesLastRead = bytesLastWrite;
340 
341             isThereExtraTxBytes = true;
342 
343             --handle->writeRegRemainingTimes;
344 
345             --handle->readRegRemainingTimes;
346             handle->isThereExtraRxBytes = true;
347         }
348     }
349 
350     EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_LpspiMasterCallback,
351                      &s_lpspiMasterEdmaPrivateHandle[instance]);
352 
353     /* Configure rx EDMA transfer */
354     EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel);
355 
356     if (handle->rxData != NULL)
357     {
358         transferConfigRx.destAddr   = (uint32_t) & (handle->rxData[0]);
359         transferConfigRx.destOffset = 1;
360     }
361     else
362     {
363         transferConfigRx.destAddr   = (uint32_t) & (handle->rxBuffIfNull);
364         transferConfigRx.destOffset = 0;
365     }
366     transferConfigRx.destTransferSize = kEDMA_TransferSize1Bytes;
367 
368     addrOffset = 0;
369     /*
370      * $Branch Coverage Justification$
371      * $ref fsl_lpspi_edma_c_ref_1$
372      */
373     switch (handle->bytesEachRead)
374     {
375         case (1U):
376             transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes;
377             transferConfigRx.minorLoopBytes  = 1;
378             if (handle->isByteSwap)
379             {
380                 addrOffset = 3;
381             }
382             break;
383 
384         case (2U):
385             transferConfigRx.srcTransferSize = kEDMA_TransferSize2Bytes;
386             transferConfigRx.minorLoopBytes  = 2;
387             if (handle->isByteSwap)
388             {
389                 addrOffset = 2;
390             }
391             break;
392 
393         case (4U):
394             transferConfigRx.srcTransferSize = kEDMA_TransferSize4Bytes;
395             transferConfigRx.minorLoopBytes  = 4;
396             break;
397 
398         default:
399             transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes;
400             transferConfigRx.minorLoopBytes  = 1;
401             assert(false);
402             break;
403     }
404 
405     transferConfigRx.srcAddr   = (uint32_t)rxAddr + addrOffset;
406     transferConfigRx.srcOffset = 0;
407 
408     transferConfigRx.majorLoopCounts = handle->readRegRemainingTimes;
409 
410     /* Store the initially configured eDMA minor byte transfer count into the LPSPI handle */
411     handle->nbytes = (uint8_t)transferConfigRx.minorLoopBytes;
412 
413     EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
414                            &transferConfigRx, NULL);
415     EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
416                                  (uint32_t)kEDMA_MajorInterruptEnable);
417 
418     /* Configure tx EDMA transfer */
419     EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel);
420 
421     if (isThereExtraTxBytes)
422     {
423         if (handle->txData != NULL)
424         {
425             transferConfigTx.srcAddr   = (uint32_t) & (transfer->txData[transfer->dataSize - bytesLastWrite]);
426             transferConfigTx.srcOffset = 1;
427         }
428         else
429         {
430             transferConfigTx.srcAddr   = (uint32_t)(&handle->txBuffIfNull);
431             transferConfigTx.srcOffset = 0;
432         }
433 
434         transferConfigTx.destOffset = 0;
435 
436         transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes;
437 
438         addrOffset = 0;
439         /*
440          * $Branch Coverage Justification$
441          * $ref fsl_lpspi_edma_c_ref_1$
442          */
443         switch (bytesLastWrite)
444         {
445             case (1U):
446                 transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
447                 transferConfigTx.minorLoopBytes   = 1;
448                 if (handle->isByteSwap)
449                 {
450                     addrOffset = 3;
451                 }
452                 break;
453 
454             case (2U):
455                 transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes;
456                 transferConfigTx.minorLoopBytes   = 2;
457                 if (handle->isByteSwap)
458                 {
459                     addrOffset = 2;
460                 }
461                 break;
462 
463             default:
464                 transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
465                 transferConfigTx.minorLoopBytes   = 1;
466                 assert(false);
467                 break;
468         }
469 
470         transferConfigTx.destAddr        = (uint32_t)txAddr + addrOffset;
471         transferConfigTx.majorLoopCounts = 1;
472 
473         EDMA_TcdReset(softwareTCD_extraBytes);
474 
475         if (handle->isPcsContinuous)
476         {
477             EDMA_TcdSetTransferConfig(softwareTCD_extraBytes, &transferConfigTx, softwareTCD_pcsContinuous);
478         }
479         else
480         {
481             EDMA_TcdSetTransferConfig(softwareTCD_extraBytes, &transferConfigTx, NULL);
482         }
483     }
484 
485     if (handle->isPcsContinuous)
486     {
487         handle->transmitCommand = base->TCR & ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK);
488 
489         transferConfigTx.srcAddr   = (uint32_t) & (handle->transmitCommand);
490         transferConfigTx.srcOffset = 0;
491 
492         transferConfigTx.destAddr   = (uint32_t) & (base->TCR);
493         transferConfigTx.destOffset = 0;
494 
495         transferConfigTx.srcTransferSize  = kEDMA_TransferSize4Bytes;
496         transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes;
497         transferConfigTx.minorLoopBytes   = 4;
498         transferConfigTx.majorLoopCounts  = 1;
499 
500         EDMA_TcdReset(softwareTCD_pcsContinuous);
501         EDMA_TcdSetTransferConfig(softwareTCD_pcsContinuous, &transferConfigTx, NULL);
502     }
503 
504     if (handle->txData != NULL)
505     {
506         transferConfigTx.srcAddr   = (uint32_t)(handle->txData);
507         transferConfigTx.srcOffset = 1;
508     }
509     else
510     {
511         transferConfigTx.srcAddr   = (uint32_t)(&handle->txBuffIfNull);
512         transferConfigTx.srcOffset = 0;
513     }
514 
515     transferConfigTx.destOffset = 0;
516 
517     transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes;
518 
519     addrOffset = 0U;
520     /*
521      * $Branch Coverage Justification$
522      * $ref fsl_lpspi_edma_c_ref_1$
523      */
524     switch (handle->bytesEachRead)
525     {
526         case (1U):
527             transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
528             transferConfigTx.minorLoopBytes   = 1;
529             if (handle->isByteSwap)
530             {
531                 addrOffset = 3;
532             }
533             break;
534 
535         case (2U):
536             transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes;
537             transferConfigTx.minorLoopBytes   = 2;
538 
539             if (handle->isByteSwap)
540             {
541                 addrOffset = 2;
542             }
543             break;
544 
545         case (4U):
546             transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes;
547             transferConfigTx.minorLoopBytes   = 4;
548             break;
549 
550         default:
551             transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
552             transferConfigTx.minorLoopBytes   = 1;
553             assert(false);
554             break;
555     }
556 
557     transferConfigTx.destAddr = (uint32_t)txAddr + addrOffset;
558 
559     transferConfigTx.majorLoopCounts = handle->writeRegRemainingTimes;
560 
561     if (isThereExtraTxBytes)
562     {
563         EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
564                                &transferConfigTx, softwareTCD_extraBytes);
565     }
566     else if (handle->isPcsContinuous)
567     {
568         EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
569                                &transferConfigTx, softwareTCD_pcsContinuous);
570     }
571     else
572     {
573         EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
574                                &transferConfigTx, NULL);
575     }
576 
577     EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle);
578     EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle);
579     LPSPI_EnableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable);
580 
581     return kStatus_Success;
582 }
583 
584 /*!
585  * brief LPSPI master transfer data using eDMA.
586  *
587  * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
588  * is transferred, the callback function is called.
589  *
590  * Note:
591  * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
592  * For bytesPerFrame greater than 4:
593  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
594  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
595  *
596  * param base LPSPI peripheral base address.
597  * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
598  * param transfer pointer to lpspi_transfer_t structure.
599  * return status of status_t.
600  */
LPSPI_MasterTransferEDMA(LPSPI_Type * base,lpspi_master_edma_handle_t * handle,lpspi_transfer_t * transfer)601 status_t LPSPI_MasterTransferEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer)
602 {
603     status_t status = kStatus_Fail;
604     status = LPSPI_MasterTransferPrepareEDMALite(base, handle, transfer->configFlags);
605     if(kStatus_Success != status)
606     {
607        return status;
608     }
609     return LPSPI_MasterTransferEDMALite(base,handle,transfer);
610 }
611 
EDMA_LpspiMasterCallback(edma_handle_t * edmaHandle,void * g_lpspiEdmaPrivateHandle,bool transferDone,uint32_t tcds)612 static void EDMA_LpspiMasterCallback(edma_handle_t *edmaHandle,
613                                      void *g_lpspiEdmaPrivateHandle,
614                                      bool transferDone,
615                                      uint32_t tcds)
616 {
617     assert(edmaHandle != NULL);
618     assert(g_lpspiEdmaPrivateHandle != NULL);
619 
620     uint32_t readData;
621 
622     lpspi_master_edma_private_handle_t *lpspiEdmaPrivateHandle;
623 
624     lpspiEdmaPrivateHandle = (lpspi_master_edma_private_handle_t *)g_lpspiEdmaPrivateHandle;
625 
626     size_t rxRemainingByteCount = lpspiEdmaPrivateHandle->handle->rxRemainingByteCount;
627     uint8_t bytesLastRead       = lpspiEdmaPrivateHandle->handle->bytesLastRead;
628     bool isByteSwap             = lpspiEdmaPrivateHandle->handle->isByteSwap;
629 
630     LPSPI_DisableDMA(lpspiEdmaPrivateHandle->base, (uint32_t)kLPSPI_TxDmaEnable | (uint32_t)kLPSPI_RxDmaEnable);
631 
632     if (lpspiEdmaPrivateHandle->handle->isThereExtraRxBytes)
633     {
634         while (LPSPI_GetRxFifoCount(lpspiEdmaPrivateHandle->base) == 0U)
635         {
636         }
637         readData = LPSPI_ReadData(lpspiEdmaPrivateHandle->base);
638 
639         if (lpspiEdmaPrivateHandle->handle->rxData != NULL)
640         {
641             LPSPI_SeparateEdmaReadData(&(lpspiEdmaPrivateHandle->handle->rxData[rxRemainingByteCount - bytesLastRead]),
642                                        readData, bytesLastRead, isByteSwap);
643         }
644     }
645 
646     lpspiEdmaPrivateHandle->handle->state = (uint8_t)kLPSPI_Idle;
647 
648     if (lpspiEdmaPrivateHandle->handle->callback != NULL)
649     {
650         lpspiEdmaPrivateHandle->handle->callback(lpspiEdmaPrivateHandle->base, lpspiEdmaPrivateHandle->handle,
651                                                  kStatus_Success, lpspiEdmaPrivateHandle->handle->userData);
652     }
653 }
654 
655 /*!
656  * brief LPSPI master aborts a transfer which is using eDMA.
657  *
658  * This function aborts a transfer which is using eDMA.
659  *
660  * param base LPSPI peripheral base address.
661  * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
662  */
LPSPI_MasterTransferAbortEDMA(LPSPI_Type * base,lpspi_master_edma_handle_t * handle)663 void LPSPI_MasterTransferAbortEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle)
664 {
665     assert(handle != NULL);
666 
667     LPSPI_DisableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable);
668 
669     EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle);
670     EDMA_AbortTransfer(handle->edmaTxDataToTxRegHandle);
671 
672     handle->state = (uint8_t)kLPSPI_Idle;
673 }
674 
675 /*!
676  * brief Gets the master eDMA transfer remaining bytes.
677  *
678  * This function gets the master eDMA transfer remaining bytes.
679  *
680  * param base LPSPI peripheral base address.
681  * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
682  * param count Number of bytes transferred so far by the EDMA transaction.
683  * return status of status_t.
684  */
LPSPI_MasterTransferGetCountEDMA(LPSPI_Type * base,lpspi_master_edma_handle_t * handle,size_t * count)685 status_t LPSPI_MasterTransferGetCountEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, size_t *count)
686 {
687     assert(handle != NULL);
688 
689     if (NULL == count)
690     {
691         return kStatus_InvalidArgument;
692     }
693 
694     /* Catch when there is not an active transfer. */
695     if (handle->state != (uint8_t)kLPSPI_Busy)
696     {
697         *count = 0;
698         return kStatus_NoTransferInProgress;
699     }
700 
701     size_t remainingByte;
702 
703     remainingByte =
704         (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base,
705                                                                    handle->edmaRxRegToRxDataHandle->channel);
706 
707     *count = handle->totalByteCount - remainingByte;
708 
709     return kStatus_Success;
710 }
711 
712 /*!
713  * brief Initializes the LPSPI slave eDMA handle.
714  *
715  * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs.  Usually, for a
716  * specified LPSPI instance, call this API once to get the initialized handle.
717  *
718  * Note that LPSPI eDMA has a separated (Rx and Tx as two sources) or shared (Rx  and Tx as the same source) DMA request
719  * source.
720  *
721  * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
722  * Tx DMAMUX source for edmaTxDataToTxRegHandle.
723  * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle .
724  *
725  * param base LPSPI peripheral base address.
726  * param handle LPSPI handle pointer to lpspi_slave_edma_handle_t.
727  * param callback LPSPI callback.
728  * param userData callback function parameter.
729  * param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
730  * param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
731  */
LPSPI_SlaveTransferCreateHandleEDMA(LPSPI_Type * base,lpspi_slave_edma_handle_t * handle,lpspi_slave_edma_transfer_callback_t callback,void * userData,edma_handle_t * edmaRxRegToRxDataHandle,edma_handle_t * edmaTxDataToTxRegHandle)732 void LPSPI_SlaveTransferCreateHandleEDMA(LPSPI_Type *base,
733                                          lpspi_slave_edma_handle_t *handle,
734                                          lpspi_slave_edma_transfer_callback_t callback,
735                                          void *userData,
736                                          edma_handle_t *edmaRxRegToRxDataHandle,
737                                          edma_handle_t *edmaTxDataToTxRegHandle)
738 {
739     assert(handle != NULL);
740     assert(edmaRxRegToRxDataHandle != NULL);
741     assert(edmaTxDataToTxRegHandle != NULL);
742 
743     /* Zero the handle. */
744     (void)memset(handle, 0, sizeof(*handle));
745 
746     uint32_t instance = LPSPI_GetInstance(base);
747 
748     s_lpspiSlaveEdmaPrivateHandle[instance].base   = base;
749     s_lpspiSlaveEdmaPrivateHandle[instance].handle = handle;
750 
751     handle->callback = callback;
752     handle->userData = userData;
753 
754     handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle;
755     handle->edmaTxDataToTxRegHandle = edmaTxDataToTxRegHandle;
756 }
757 
758 /*!
759  * brief LPSPI slave transfers data using eDMA.
760  *
761  * This function transfers data using eDMA. This is a non-blocking function, which return right away. When all data
762  * is transferred, the callback function is called.
763  *
764  * Note:
765  * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
766  * For bytesPerFrame greater than 4:
767  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
768  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
769  *
770  * param base LPSPI peripheral base address.
771  * param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
772  * param transfer pointer to lpspi_transfer_t structure.
773  * return status of status_t.
774  */
LPSPI_SlaveTransferEDMA(LPSPI_Type * base,lpspi_slave_edma_handle_t * handle,lpspi_transfer_t * transfer)775 status_t LPSPI_SlaveTransferEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, lpspi_transfer_t *transfer)
776 {
777     assert(handle != NULL);
778     assert(transfer != NULL);
779 
780     /* Check that we're not busy.*/
781     if (handle->state == (uint8_t)kLPSPI_Busy)
782     {
783         return kStatus_LPSPI_Busy;
784     }
785     /* Disable module before configuration. */
786     LPSPI_Enable(base, false);
787     /* Check arguements, also dma transfer can not support 3 bytes */
788     if (!LPSPI_CheckTransferArgument(base, transfer, true))
789     {
790         return kStatus_InvalidArgument;
791     }
792 
793     LPSPI_PrepareTransferEDMA(base);
794 
795     /* Variables */
796     bool isThereExtraTxBytes = false;
797     bool isByteSwap          = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
798     uint8_t bytesLastWrite   = 0;
799     uint8_t dummyData        = g_lpspiDummyData[LPSPI_GetInstance(base)];
800     uint32_t mask            = (uint32_t)kLPSPI_RxDmaEnable;
801 
802     /* Used for byte swap */
803     uint32_t addrOffset    = 0;
804     uint32_t instance      = LPSPI_GetInstance(base);
805     uint32_t rxAddr        = LPSPI_GetRxRegisterAddress(base);
806     uint32_t txAddr        = LPSPI_GetTxRegisterAddress(base);
807     uint32_t whichPcs      = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
808     uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
809     edma_transfer_config_t transferConfigRx = {0};
810     edma_transfer_config_t transferConfigTx = {0};
811     edma_tcd_t *softwareTCD_extraBytes      = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[1]) & (~0x1FU));
812 
813     /* Assign the original value for members of transfer handle. */
814     handle->state                  = (uint8_t)kLPSPI_Busy;
815     handle->txData                 = transfer->txData;
816     handle->rxData                 = transfer->rxData;
817     handle->txRemainingByteCount   = transfer->dataSize;
818     handle->rxRemainingByteCount   = transfer->dataSize;
819     handle->totalByteCount         = transfer->dataSize;
820     handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U);
821     handle->readRegRemainingTimes  = handle->writeRegRemainingTimes;
822     handle->txBuffIfNull =
823         ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
824     /*The TX and RX FIFO sizes are always the same*/
825     handle->fifoSize            = LPSPI_GetRxFifoSize(base);
826     handle->isByteSwap          = isByteSwap;
827     handle->isThereExtraRxBytes = false;
828 
829     /* Because DMA is fast enough, set the RX and TX watermarks to 0. */
830     LPSPI_SetFifoWatermarks(base, 0U, 0U);
831 
832     /* Transfers will stall when transmit FIFO is empty or receive FIFO is full. */
833     base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
834 
835     /* Enable module for following configuration of TCR to take effect. */
836     LPSPI_Enable(base, true);
837 
838     /* For DMA transfer, mask the transmit data if the tx data is null, for rx the receive data should not be masked at
839        any time since we use rx dma transfer finish cllback to indicate transfer finish. */
840     base->TCR =
841         (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_BYSW_MASK | LPSPI_TCR_TXMSK_MASK)) |
842         LPSPI_TCR_TXMSK(transfer->txData == NULL) | LPSPI_TCR_BYSW(isByteSwap) | LPSPI_TCR_PCS(whichPcs);
843 
844     /*Calculate the bytes for write/read the TX/RX register each time*/
845     if (bytesPerFrame <= 4U)
846     {
847         handle->bytesEachWrite = (uint8_t)bytesPerFrame;
848         handle->bytesEachRead  = (uint8_t)bytesPerFrame;
849 
850         handle->bytesLastRead = (uint8_t)bytesPerFrame;
851     }
852     else
853     {
854         handle->bytesEachWrite = 4U;
855         handle->bytesEachRead  = 4U;
856 
857         handle->bytesLastRead = 4U;
858 
859         if ((transfer->dataSize % 4U) != 0U)
860         {
861             bytesLastWrite        = (uint8_t)(transfer->dataSize % 4U);
862             handle->bytesLastRead = bytesLastWrite;
863 
864             isThereExtraTxBytes = true;
865             --handle->writeRegRemainingTimes;
866 
867             handle->isThereExtraRxBytes = true;
868             --handle->readRegRemainingTimes;
869         }
870     }
871 
872     EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_LpspiSlaveCallback,
873                      &s_lpspiSlaveEdmaPrivateHandle[instance]);
874 
875     /*Rx*/
876     /*
877      * $Branch Coverage Justification$
878      * LPSPI_CheckTransferArgument will check parameters, here readRegRemainingTimes cannot be 0.
879      */
880     if (handle->readRegRemainingTimes > 0U)
881     {
882         EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel);
883 
884         if (handle->rxData != NULL)
885         {
886             transferConfigRx.destAddr   = (uint32_t) & (handle->rxData[0]);
887             transferConfigRx.destOffset = 1;
888         }
889         else
890         {
891             transferConfigRx.destAddr   = (uint32_t) & (handle->rxBuffIfNull);
892             transferConfigRx.destOffset = 0;
893         }
894         transferConfigRx.destTransferSize = kEDMA_TransferSize1Bytes;
895 
896         addrOffset = 0;
897         /*
898          * $Branch Coverage Justification$
899          * $ref fsl_lpspi_edma_c_ref_1$
900          */
901         switch (handle->bytesEachRead)
902         {
903             case (1U):
904                 transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes;
905                 transferConfigRx.minorLoopBytes  = 1;
906                 if (handle->isByteSwap)
907                 {
908                     addrOffset = 3;
909                 }
910                 break;
911 
912             case (2U):
913                 transferConfigRx.srcTransferSize = kEDMA_TransferSize2Bytes;
914                 transferConfigRx.minorLoopBytes  = 2;
915                 if (handle->isByteSwap)
916                 {
917                     addrOffset = 2;
918                 }
919                 break;
920 
921             case (4U):
922                 transferConfigRx.srcTransferSize = kEDMA_TransferSize4Bytes;
923                 transferConfigRx.minorLoopBytes  = 4;
924                 break;
925 
926             default:
927                 transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes;
928                 transferConfigRx.minorLoopBytes  = 1;
929                 assert(false);
930                 break;
931         }
932 
933         transferConfigRx.srcAddr   = (uint32_t)rxAddr + addrOffset;
934         transferConfigRx.srcOffset = 0;
935 
936         transferConfigRx.majorLoopCounts = handle->readRegRemainingTimes;
937 
938         /* Store the initially configured eDMA minor byte transfer count into the DSPI handle */
939         handle->nbytes = (uint8_t)transferConfigRx.minorLoopBytes;
940 
941         EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
942                                &transferConfigRx, NULL);
943         EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
944                                      (uint32_t)kEDMA_MajorInterruptEnable);
945         EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle);
946     }
947 
948     /*Tx*/
949     if (handle->txData != NULL)
950     {
951         EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel);
952         if (isThereExtraTxBytes)
953         {
954             transferConfigTx.srcAddr         = (uint32_t) & (transfer->txData[transfer->dataSize - bytesLastWrite]);
955             transferConfigTx.srcOffset       = 1;
956             transferConfigTx.destOffset      = 0;
957             transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes;
958             addrOffset                       = 0;
959             /*
960              * $Branch Coverage Justification$
961              * $ref fsl_lpspi_edma_c_ref_1$
962              */
963             switch (bytesLastWrite)
964             {
965                 case (1U):
966                     transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
967                     transferConfigTx.minorLoopBytes   = 1;
968                     if (handle->isByteSwap)
969                     {
970                         addrOffset = 3;
971                     }
972                     break;
973 
974                 case (2U):
975                     transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes;
976                     transferConfigTx.minorLoopBytes   = 2;
977                     if (handle->isByteSwap)
978                     {
979                         addrOffset = 2;
980                     }
981                     break;
982 
983                 default:
984                     transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
985                     transferConfigTx.minorLoopBytes   = 1;
986                     assert(false);
987                     break;
988             }
989 
990             transferConfigTx.destAddr        = (uint32_t)txAddr + addrOffset;
991             transferConfigTx.majorLoopCounts = 1;
992 
993             EDMA_TcdReset(softwareTCD_extraBytes);
994             EDMA_TcdSetTransferConfig(softwareTCD_extraBytes, &transferConfigTx, NULL);
995         }
996 
997         transferConfigTx.srcAddr         = (uint32_t)(handle->txData);
998         transferConfigTx.srcOffset       = 1;
999         transferConfigTx.destOffset      = 0;
1000         transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes;
1001         addrOffset                       = 0;
1002         /*
1003          * $Branch Coverage Justification$
1004          * $ref fsl_lpspi_edma_c_ref_1$
1005          */
1006         switch (handle->bytesEachRead)
1007         {
1008             case (1U):
1009                 transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
1010                 transferConfigTx.minorLoopBytes   = 1;
1011                 if (handle->isByteSwap)
1012                 {
1013                     addrOffset = 3;
1014                 }
1015                 break;
1016 
1017             case (2U):
1018                 transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes;
1019                 transferConfigTx.minorLoopBytes   = 2;
1020 
1021                 if (handle->isByteSwap)
1022                 {
1023                     addrOffset = 2;
1024                 }
1025                 break;
1026 
1027             case (4U):
1028                 transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes;
1029                 transferConfigTx.minorLoopBytes   = 4;
1030                 break;
1031 
1032             default:
1033                 transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
1034                 transferConfigTx.minorLoopBytes   = 1;
1035                 assert(false);
1036                 break;
1037         }
1038 
1039         transferConfigTx.destAddr        = (uint32_t)txAddr + addrOffset;
1040         transferConfigTx.majorLoopCounts = handle->writeRegRemainingTimes;
1041 
1042         if (isThereExtraTxBytes)
1043         {
1044             EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
1045                                    &transferConfigTx, softwareTCD_extraBytes);
1046         }
1047         else
1048         {
1049             EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
1050                                    &transferConfigTx, NULL);
1051         }
1052         EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle);
1053         mask |= (uint32_t)kLPSPI_TxDmaEnable;
1054     }
1055 
1056     LPSPI_EnableDMA(base, mask);
1057 
1058     return kStatus_Success;
1059 }
1060 
EDMA_LpspiSlaveCallback(edma_handle_t * edmaHandle,void * g_lpspiEdmaPrivateHandle,bool transferDone,uint32_t tcds)1061 static void EDMA_LpspiSlaveCallback(edma_handle_t *edmaHandle,
1062                                     void *g_lpspiEdmaPrivateHandle,
1063                                     bool transferDone,
1064                                     uint32_t tcds)
1065 {
1066     assert(edmaHandle != NULL);
1067     assert(g_lpspiEdmaPrivateHandle != NULL);
1068 
1069     uint32_t readData;
1070 
1071     lpspi_slave_edma_private_handle_t *lpspiEdmaPrivateHandle;
1072 
1073     lpspiEdmaPrivateHandle = (lpspi_slave_edma_private_handle_t *)g_lpspiEdmaPrivateHandle;
1074 
1075     size_t rxRemainingByteCount = lpspiEdmaPrivateHandle->handle->rxRemainingByteCount;
1076     uint8_t bytesLastRead       = lpspiEdmaPrivateHandle->handle->bytesLastRead;
1077     bool isByteSwap             = lpspiEdmaPrivateHandle->handle->isByteSwap;
1078 
1079     LPSPI_DisableDMA(lpspiEdmaPrivateHandle->base, (uint32_t)kLPSPI_TxDmaEnable | (uint32_t)kLPSPI_RxDmaEnable);
1080 
1081     /*
1082      * $Branch Coverage Justification$
1083      * When there are extra bytes, the slave will not receive the extra bytes,The while here will not stop.(will
1084      * improve)
1085      */
1086     if (lpspiEdmaPrivateHandle->handle->isThereExtraRxBytes)
1087     {
1088         while (LPSPI_GetRxFifoCount(lpspiEdmaPrivateHandle->base) == 0U)
1089         {
1090         }
1091         readData = LPSPI_ReadData(lpspiEdmaPrivateHandle->base);
1092 
1093         if (lpspiEdmaPrivateHandle->handle->rxData != NULL)
1094         {
1095             LPSPI_SeparateEdmaReadData(&(lpspiEdmaPrivateHandle->handle->rxData[rxRemainingByteCount - bytesLastRead]),
1096                                        readData, bytesLastRead, isByteSwap);
1097         }
1098     }
1099 
1100     lpspiEdmaPrivateHandle->handle->state = (uint8_t)kLPSPI_Idle;
1101 
1102     if (lpspiEdmaPrivateHandle->handle->callback != NULL)
1103     {
1104         lpspiEdmaPrivateHandle->handle->callback(lpspiEdmaPrivateHandle->base, lpspiEdmaPrivateHandle->handle,
1105                                                  kStatus_Success, lpspiEdmaPrivateHandle->handle->userData);
1106     }
1107 }
1108 
1109 /*!
1110  * brief LPSPI slave aborts a transfer which is using eDMA.
1111  *
1112  * This function aborts a transfer which is using eDMA.
1113  *
1114  * param base LPSPI peripheral base address.
1115  * param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
1116  */
LPSPI_SlaveTransferAbortEDMA(LPSPI_Type * base,lpspi_slave_edma_handle_t * handle)1117 void LPSPI_SlaveTransferAbortEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle)
1118 {
1119     assert(handle != NULL);
1120 
1121     LPSPI_DisableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable);
1122 
1123     EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle);
1124     EDMA_AbortTransfer(handle->edmaTxDataToTxRegHandle);
1125 
1126     handle->state = (uint8_t)kLPSPI_Idle;
1127 }
1128 
1129 /*!
1130  * brief Gets the slave eDMA transfer remaining bytes.
1131  *
1132  * This function gets the slave eDMA transfer remaining bytes.
1133  *
1134  * param base LPSPI peripheral base address.
1135  * param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
1136  * param count Number of bytes transferred so far by the eDMA transaction.
1137  * return status of status_t.
1138  */
LPSPI_SlaveTransferGetCountEDMA(LPSPI_Type * base,lpspi_slave_edma_handle_t * handle,size_t * count)1139 status_t LPSPI_SlaveTransferGetCountEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, size_t *count)
1140 {
1141     assert(handle != NULL);
1142 
1143     if (NULL == count)
1144     {
1145         return kStatus_InvalidArgument;
1146     }
1147 
1148     /* Catch when there is not an active transfer. */
1149     if (handle->state != (uint8_t)kLPSPI_Busy)
1150     {
1151         *count = 0;
1152         return kStatus_NoTransferInProgress;
1153     }
1154 
1155     size_t remainingByte;
1156 
1157     remainingByte =
1158         (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base,
1159                                                                    handle->edmaRxRegToRxDataHandle->channel);
1160 
1161     *count = handle->totalByteCount - remainingByte;
1162 
1163     return kStatus_Success;
1164 }
1165