fsl_flexio_mculcd_edma.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2019 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_flexio_mculcd_edma.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.flexio_mculcd_edma"
  15. #endif
  16. #define EDMA_MAX_MAJOR_COUNT (DMA_CITER_ELINKNO_CITER_MASK >> DMA_CITER_ELINKNO_CITER_SHIFT)
  17. enum
  18. {
  19. kFLEXIO_MCULCD_StateIdle, /*!< No transfer in progress. */
  20. kFLEXIO_MCULCD_StateReadArray, /*!< Reading array in progress. */
  21. kFLEXIO_MCULCD_StateWriteArray, /*!< Writing array in progress. */
  22. kFLEXIO_MCULCD_StateWriteSameValue, /*!< Writing the same value in progress.
  23. */
  24. };
  25. /*******************************************************************************
  26. * Prototypes
  27. ******************************************************************************/
  28. /*!
  29. * @brief EDMA callback function for FLEXIO MCULCD TX.
  30. *
  31. * For details, see @ref edma_callback.
  32. */
  33. static void FLEXIO_MCULCD_TxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds);
  34. /*!
  35. * @brief EDMA callback function for FLEXIO MCULCD RX.
  36. *
  37. * For details, see @ref edma_callback.
  38. */
  39. static void FLEXIO_MCULCD_RxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds);
  40. /*!
  41. * @brief Set EDMA config for FLEXIO MCULCD transfer.
  42. *
  43. * @param base pointer to FLEXIO_MCULCD_Type structure.
  44. * @param handle pointer to flexio_mculcd_edma_handle_t structure to store the
  45. * transfer state.
  46. */
  47. static void FLEXIO_MCULCD_EDMAConfig(FLEXIO_MCULCD_Type *base, flexio_mculcd_edma_handle_t *handle);
  48. /*!
  49. * @brief Convert the FlexIO shifter number to eDMA modulo.
  50. *
  51. * @param shifterNum The FlexIO shifter number.
  52. * @param modulo The modulo number.
  53. * @retval Get the modulo successfully.
  54. * @retval Could not get the modulo for the shifter number.
  55. */
  56. static bool FLEXIO_MCULCD_GetEDMAModulo(uint8_t shifterNum, edma_modulo_t *modulo);
  57. /*******************************************************************************
  58. * Variables
  59. ******************************************************************************/
  60. /*******************************************************************************
  61. * Code
  62. ******************************************************************************/
  63. static void FLEXIO_MCULCD_TxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds)
  64. {
  65. tcds = tcds;
  66. flexio_mculcd_edma_handle_t *flexioLcdMcuHandle = (flexio_mculcd_edma_handle_t *)param;
  67. FLEXIO_MCULCD_Type *flexioLcdMcuBase = flexioLcdMcuHandle->base;
  68. if (transferDone)
  69. {
  70. if (flexioLcdMcuHandle->remainingCount >= flexioLcdMcuHandle->minorLoopBytes)
  71. {
  72. FLEXIO_MCULCD_EDMAConfig(flexioLcdMcuBase, flexioLcdMcuHandle);
  73. EDMA_StartTransfer(flexioLcdMcuHandle->txDmaHandle);
  74. }
  75. else
  76. {
  77. FLEXIO_MCULCD_EnableTxDMA(flexioLcdMcuBase, false);
  78. /* Now the data are in shifter, wait for the data send out from the shifter. */
  79. FLEXIO_MCULCD_WaitTransmitComplete();
  80. /* Disable the TX shifter and the timer. */
  81. FLEXIO_MCULCD_ClearMultiBeatsWriteConfig(flexioLcdMcuBase);
  82. /* Send the remaining data. */
  83. if (0U != flexioLcdMcuHandle->remainingCount)
  84. {
  85. if ((uint32_t)kFLEXIO_MCULCD_StateWriteSameValue == flexioLcdMcuHandle->state)
  86. {
  87. FLEXIO_MCULCD_WriteSameValueBlocking(flexioLcdMcuBase, flexioLcdMcuHandle->dataAddrOrSameValue,
  88. flexioLcdMcuHandle->remainingCount);
  89. }
  90. else
  91. {
  92. FLEXIO_MCULCD_WriteDataArrayBlocking(flexioLcdMcuBase,
  93. (uint8_t *)flexioLcdMcuHandle->dataAddrOrSameValue,
  94. flexioLcdMcuHandle->remainingCount);
  95. }
  96. }
  97. /* De-assert nCS. */
  98. FLEXIO_MCULCD_StopTransfer(flexioLcdMcuBase);
  99. /* Change the state. */
  100. flexioLcdMcuHandle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle;
  101. flexioLcdMcuHandle->dataCount = 0;
  102. flexioLcdMcuHandle->remainingCount = 0;
  103. /* Callback to inform upper layer. */
  104. if (NULL != flexioLcdMcuHandle->completionCallback)
  105. {
  106. flexioLcdMcuHandle->completionCallback(flexioLcdMcuBase, flexioLcdMcuHandle, kStatus_FLEXIO_MCULCD_Idle,
  107. flexioLcdMcuHandle->userData);
  108. }
  109. }
  110. }
  111. }
  112. static void FLEXIO_MCULCD_RxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds)
  113. {
  114. tcds = tcds;
  115. uint32_t i;
  116. uint32_t rxBufAddr;
  117. flexio_mculcd_edma_handle_t *flexioLcdMcuHandle = (flexio_mculcd_edma_handle_t *)param;
  118. FLEXIO_MCULCD_Type *flexioLcdMcuBase = flexioLcdMcuHandle->base;
  119. FLEXIO_Type *flexioBase = flexioLcdMcuBase->flexioBase;
  120. if (transferDone)
  121. {
  122. if (flexioLcdMcuHandle->remainingCount >= (2U * flexioLcdMcuHandle->minorLoopBytes))
  123. {
  124. FLEXIO_MCULCD_EDMAConfig(flexioLcdMcuBase, flexioLcdMcuHandle);
  125. EDMA_StartTransfer(flexioLcdMcuHandle->rxDmaHandle);
  126. }
  127. else
  128. {
  129. FLEXIO_MCULCD_EnableRxDMA(flexioLcdMcuBase, false);
  130. /* Wait the data saved to the shifter buffer. */
  131. while (0U == ((1UL << flexioLcdMcuBase->rxShifterEndIndex) & FLEXIO_GetShifterStatusFlags(flexioBase)))
  132. {
  133. }
  134. /* Disable the RX shifter and the timer. */
  135. FLEXIO_MCULCD_ClearMultiBeatsReadConfig(flexioLcdMcuBase);
  136. rxBufAddr = FLEXIO_MCULCD_GetRxDataRegisterAddress(flexioLcdMcuBase);
  137. /* Read out the data. */
  138. #if (defined(__CORTEX_M) && (__CORTEX_M == 0))
  139. /* Cortex M0 and M0+ only support aligned access. */
  140. for (i = 0; i < flexioLcdMcuHandle->rxShifterNum * 4; i++)
  141. {
  142. ((uint8_t *)(flexioLcdMcuHandle->dataAddrOrSameValue))[i] = ((volatile uint8_t *)rxBufAddr)[i];
  143. }
  144. #else
  145. for (i = 0; i < flexioLcdMcuHandle->rxShifterNum; i++)
  146. {
  147. ((uint32_t *)(flexioLcdMcuHandle->dataAddrOrSameValue))[i] = ((volatile uint32_t *)rxBufAddr)[i];
  148. }
  149. #endif
  150. flexioLcdMcuHandle->remainingCount -= flexioLcdMcuHandle->minorLoopBytes;
  151. if (0U != flexioLcdMcuHandle->remainingCount)
  152. {
  153. FLEXIO_MCULCD_ReadDataArrayBlocking(
  154. flexioLcdMcuBase,
  155. (uint8_t *)(flexioLcdMcuHandle->dataAddrOrSameValue + flexioLcdMcuHandle->minorLoopBytes),
  156. flexioLcdMcuHandle->remainingCount);
  157. }
  158. /* De-assert nCS. */
  159. FLEXIO_MCULCD_StopTransfer(flexioLcdMcuBase);
  160. /* Change the state. */
  161. flexioLcdMcuHandle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle;
  162. flexioLcdMcuHandle->dataCount = 0;
  163. flexioLcdMcuHandle->remainingCount = 0;
  164. /* Callback to inform upper layer. */
  165. if (NULL != flexioLcdMcuHandle->completionCallback)
  166. {
  167. flexioLcdMcuHandle->completionCallback(flexioLcdMcuBase, flexioLcdMcuHandle, kStatus_FLEXIO_MCULCD_Idle,
  168. flexioLcdMcuHandle->userData);
  169. }
  170. }
  171. }
  172. }
  173. static void FLEXIO_MCULCD_EDMAConfig(FLEXIO_MCULCD_Type *base, flexio_mculcd_edma_handle_t *handle)
  174. {
  175. edma_transfer_config_t xferConfig = {0};
  176. edma_transfer_size_t transferSize = kEDMA_TransferSize1Bytes;
  177. int16_t offset;
  178. uint32_t majorLoopCounts;
  179. uint32_t transferCount;
  180. #if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH)
  181. transferSize = kEDMA_TransferSize1Bytes;
  182. offset = 1;
  183. #else
  184. transferSize = kEDMA_TransferSize2Bytes;
  185. offset = 2;
  186. #endif
  187. majorLoopCounts = handle->remainingCount / handle->minorLoopBytes;
  188. /* For reading, the last minor loop data is not tranfered by DMA. */
  189. if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == handle->state)
  190. {
  191. majorLoopCounts--;
  192. }
  193. if (majorLoopCounts > EDMA_MAX_MAJOR_COUNT)
  194. {
  195. majorLoopCounts = EDMA_MAX_MAJOR_COUNT;
  196. }
  197. transferCount = majorLoopCounts * handle->minorLoopBytes;
  198. if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == handle->state)
  199. {
  200. xferConfig.srcAddr = FLEXIO_MCULCD_GetRxDataRegisterAddress(base);
  201. xferConfig.destAddr = handle->dataAddrOrSameValue;
  202. xferConfig.srcTransferSize = kEDMA_TransferSize4Bytes;
  203. xferConfig.destTransferSize = transferSize;
  204. xferConfig.srcOffset = 4;
  205. xferConfig.destOffset = offset;
  206. xferConfig.minorLoopBytes = handle->minorLoopBytes;
  207. xferConfig.majorLoopCounts = majorLoopCounts;
  208. handle->remainingCount -= transferCount;
  209. handle->dataAddrOrSameValue += transferCount;
  210. (void)EDMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig);
  211. EDMA_SetModulo(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, handle->rxEdmaModulo,
  212. kEDMA_ModuloDisable);
  213. }
  214. else
  215. {
  216. if ((uint32_t)kFLEXIO_MCULCD_StateWriteArray == handle->state)
  217. {
  218. xferConfig.srcAddr = handle->dataAddrOrSameValue;
  219. xferConfig.srcOffset = offset;
  220. handle->dataAddrOrSameValue += transferCount;
  221. }
  222. else
  223. {
  224. xferConfig.srcAddr = (uint32_t)(&(handle->dataAddrOrSameValue));
  225. xferConfig.srcOffset = 0;
  226. }
  227. xferConfig.destAddr = FLEXIO_MCULCD_GetTxDataRegisterAddress(base);
  228. xferConfig.srcTransferSize = transferSize;
  229. xferConfig.destTransferSize = kEDMA_TransferSize4Bytes;
  230. xferConfig.destOffset = 4;
  231. xferConfig.minorLoopBytes = handle->minorLoopBytes;
  232. xferConfig.majorLoopCounts = majorLoopCounts;
  233. handle->remainingCount -= transferCount;
  234. (void)EDMA_SubmitTransfer(handle->txDmaHandle, &xferConfig);
  235. EDMA_SetModulo(handle->txDmaHandle->base, handle->txDmaHandle->channel, kEDMA_ModuloDisable,
  236. handle->txEdmaModulo);
  237. }
  238. }
  239. static bool FLEXIO_MCULCD_GetEDMAModulo(uint8_t shifterNum, edma_modulo_t *modulo)
  240. {
  241. bool ret = true;
  242. switch (shifterNum)
  243. {
  244. case 1U:
  245. *modulo = kEDMA_Modulo4bytes;
  246. break;
  247. case 2U:
  248. *modulo = kEDMA_Modulo8bytes;
  249. break;
  250. case 4U:
  251. *modulo = kEDMA_Modulo16bytes;
  252. break;
  253. case 8U:
  254. *modulo = kEDMA_Modulo32bytes;
  255. break;
  256. default:
  257. ret = false;
  258. break;
  259. }
  260. return ret;
  261. }
  262. /*!
  263. * brief Initializes the FLEXO MCULCD master eDMA handle.
  264. *
  265. * This function initializes the FLEXO MCULCD master eDMA handle which can be
  266. * used for other FLEXO MCULCD transactional APIs. For a specified FLEXO MCULCD
  267. * instance, call this API once to get the initialized handle.
  268. *
  269. * param base Pointer to FLEXIO_MCULCD_Type structure.
  270. * param handle Pointer to flexio_mculcd_edma_handle_t structure to store the
  271. * transfer state.
  272. * param callback MCULCD transfer complete callback, NULL means no callback.
  273. * param userData callback function parameter.
  274. * param txDmaHandle User requested eDMA handle for FlexIO MCULCD eDMA TX,
  275. * the DMA request source of this handle should be the first of TX shifters.
  276. * param rxDmaHandle User requested eDMA handle for FlexIO MCULCD eDMA RX,
  277. * the DMA request source of this handle should be the last of RX shifters.
  278. * retval kStatus_Success Successfully create the handle.
  279. */
  280. status_t FLEXIO_MCULCD_TransferCreateHandleEDMA(FLEXIO_MCULCD_Type *base,
  281. flexio_mculcd_edma_handle_t *handle,
  282. flexio_mculcd_edma_transfer_callback_t callback,
  283. void *userData,
  284. edma_handle_t *txDmaHandle,
  285. edma_handle_t *rxDmaHandle)
  286. {
  287. assert(NULL != handle);
  288. /* Zero the handle. */
  289. (void)memset(handle, 0, sizeof(*handle));
  290. /* Initialize the state. */
  291. handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle;
  292. /* Register callback and userData. */
  293. handle->completionCallback = callback;
  294. handle->userData = userData;
  295. handle->base = base;
  296. handle->txShifterNum = base->txShifterEndIndex - base->txShifterStartIndex + 1U;
  297. handle->rxShifterNum = base->rxShifterEndIndex - base->rxShifterStartIndex + 1U;
  298. if (NULL != rxDmaHandle)
  299. {
  300. if (!FLEXIO_MCULCD_GetEDMAModulo(handle->rxShifterNum, &handle->rxEdmaModulo))
  301. {
  302. return kStatus_InvalidArgument;
  303. }
  304. handle->rxDmaHandle = rxDmaHandle;
  305. EDMA_SetCallback(rxDmaHandle, FLEXIO_MCULCD_RxEDMACallback, handle);
  306. }
  307. if (NULL != txDmaHandle)
  308. {
  309. if (!FLEXIO_MCULCD_GetEDMAModulo(handle->txShifterNum, &handle->txEdmaModulo))
  310. {
  311. return kStatus_InvalidArgument;
  312. }
  313. handle->txDmaHandle = txDmaHandle;
  314. EDMA_SetCallback(txDmaHandle, FLEXIO_MCULCD_TxEDMACallback, handle);
  315. }
  316. return kStatus_Success;
  317. }
  318. /*!
  319. * brief Performs a non-blocking FlexIO MCULCD transfer using eDMA.
  320. *
  321. * This function returns immediately after transfer initiates. To check whether
  322. * the transfer is completed, user could:
  323. * 1. Use the transfer completed callback;
  324. * 2. Polling function ref FLEXIO_MCULCD_GetTransferCountEDMA
  325. *
  326. * param base pointer to FLEXIO_MCULCD_Type structure.
  327. * param handle pointer to flexio_mculcd_edma_handle_t structure to store the
  328. * transfer state.
  329. * param xfer Pointer to FlexIO MCULCD transfer structure.
  330. * retval kStatus_Success Successfully start a transfer.
  331. * retval kStatus_InvalidArgument Input argument is invalid.
  332. * retval kStatus_FLEXIO_MCULCD_Busy FlexIO MCULCD is not idle, it is running another
  333. * transfer.
  334. */
  335. status_t FLEXIO_MCULCD_TransferEDMA(FLEXIO_MCULCD_Type *base,
  336. flexio_mculcd_edma_handle_t *handle,
  337. flexio_mculcd_transfer_t *xfer)
  338. {
  339. assert(NULL != handle);
  340. assert(NULL != xfer);
  341. /*
  342. * The data transfer mechanism:
  343. *
  344. * Read:
  345. * Assume the data length is Lr = (n1 * minorLoopBytes + n2), where
  346. * n2 < minorLoopBytes.
  347. * If (n1 <= 1), then all data are sent using blocking method.
  348. * If (n1 > 1), then the beginning ((n1-1) * minorLoopBytes) are read
  349. * using DMA, the left (minorLoopBytes + n2) are read using blocking method.
  350. *
  351. * Write:
  352. * Assume the data length is Lw = (n1 * minorLoopBytes + n2), where
  353. * n2 < minorLoopBytes.
  354. * If (n1 = 0), then all data are sent using blocking method.
  355. * If (n1 >= 1), then the beginning (n1 * minorLoopBytes) are sent
  356. * using DMA, the left n2 are sent using blocking method.
  357. */
  358. /* Check if the device is busy. */
  359. if ((uint32_t)kFLEXIO_MCULCD_StateIdle != handle->state)
  360. {
  361. return kStatus_FLEXIO_MCULCD_Busy;
  362. }
  363. /* Set the state in handle. */
  364. if (kFLEXIO_MCULCD_ReadArray == xfer->mode)
  365. {
  366. handle->state = (uint32_t)kFLEXIO_MCULCD_StateReadArray;
  367. handle->minorLoopBytes = handle->rxShifterNum * 4UL;
  368. }
  369. else
  370. {
  371. handle->minorLoopBytes = handle->txShifterNum * 4UL;
  372. if (kFLEXIO_MCULCD_WriteArray == xfer->mode)
  373. {
  374. handle->state = (uint32_t)kFLEXIO_MCULCD_StateWriteArray;
  375. }
  376. else
  377. {
  378. handle->state = (uint32_t)kFLEXIO_MCULCD_StateWriteSameValue;
  379. }
  380. }
  381. /*
  382. * For TX, if data is less than one minor loop, then use polling method.
  383. * For RX, if data is less than two minor loop, then use polling method.
  384. */
  385. if ((xfer->dataSize < handle->minorLoopBytes) ||
  386. ((kFLEXIO_MCULCD_ReadArray == xfer->mode) && (xfer->dataSize < 2U * (handle->minorLoopBytes))))
  387. {
  388. FLEXIO_MCULCD_TransferBlocking(base, xfer);
  389. handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle;
  390. /* Callback to inform upper layer. */
  391. if (NULL != handle->completionCallback)
  392. {
  393. handle->completionCallback(base, handle, kStatus_FLEXIO_MCULCD_Idle, handle->userData);
  394. }
  395. }
  396. else
  397. {
  398. handle->dataCount = xfer->dataSize;
  399. handle->remainingCount = xfer->dataSize;
  400. handle->dataAddrOrSameValue = xfer->dataAddrOrSameValue;
  401. /* Setup DMA to transfer data. */
  402. /* Assert the nCS. */
  403. FLEXIO_MCULCD_StartTransfer(base);
  404. /* Send the command. */
  405. FLEXIO_MCULCD_WriteCommandBlocking(base, xfer->command);
  406. /* Setup the DMA configuration. */
  407. FLEXIO_MCULCD_EDMAConfig(base, handle);
  408. /* Start the transfer. */
  409. if (kFLEXIO_MCULCD_ReadArray == xfer->mode)
  410. {
  411. /* For 6800, assert the RDWR pin. */
  412. if (kFLEXIO_MCULCD_6800 == base->busType)
  413. {
  414. base->setRDWRPin(true);
  415. }
  416. FLEXIO_MCULCD_SetMultiBeatsReadConfig(base);
  417. FLEXIO_MCULCD_EnableRxDMA(base, true);
  418. EDMA_StartTransfer(handle->rxDmaHandle);
  419. }
  420. else
  421. {
  422. /* For 6800, de-assert the RDWR pin. */
  423. if (kFLEXIO_MCULCD_6800 == base->busType)
  424. {
  425. base->setRDWRPin(false);
  426. }
  427. FLEXIO_MCULCD_SetMultiBeatsWriteConfig(base);
  428. FLEXIO_MCULCD_EnableTxDMA(base, true);
  429. EDMA_StartTransfer(handle->txDmaHandle);
  430. }
  431. }
  432. return kStatus_Success;
  433. }
  434. /*!
  435. * brief Aborts a FlexIO MCULCD transfer using eDMA.
  436. *
  437. * param base pointer to FLEXIO_MCULCD_Type structure.
  438. * param handle FlexIO MCULCD eDMA handle pointer.
  439. */
  440. void FLEXIO_MCULCD_TransferAbortEDMA(FLEXIO_MCULCD_Type *base, flexio_mculcd_edma_handle_t *handle)
  441. {
  442. assert(NULL != handle);
  443. /* Disable dma. */
  444. if (NULL != handle->txDmaHandle)
  445. {
  446. EDMA_AbortTransfer(handle->txDmaHandle);
  447. }
  448. if (NULL != handle->rxDmaHandle)
  449. {
  450. EDMA_AbortTransfer(handle->rxDmaHandle);
  451. }
  452. /* Disable DMA enable bit. */
  453. FLEXIO_MCULCD_EnableTxDMA(handle->base, false);
  454. FLEXIO_MCULCD_EnableRxDMA(handle->base, false);
  455. /* Set the handle state. */
  456. handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle;
  457. handle->dataCount = 0;
  458. }
  459. /*!
  460. * brief Gets the remaining bytes for FlexIO MCULCD eDMA transfer.
  461. *
  462. * param base pointer to FLEXIO_MCULCD_Type structure.
  463. * param handle FlexIO MCULCD eDMA handle pointer.
  464. * param count Number of count transferred so far by the eDMA transaction.
  465. * retval kStatus_Success Get the transferred count Successfully.
  466. * retval kStatus_NoTransferInProgress No transfer in process.
  467. */
  468. status_t FLEXIO_MCULCD_TransferGetCountEDMA(FLEXIO_MCULCD_Type *base,
  469. flexio_mculcd_edma_handle_t *handle,
  470. size_t *count)
  471. {
  472. assert(NULL != handle);
  473. assert(NULL != count);
  474. uint32_t state = handle->state;
  475. if ((uint32_t)kFLEXIO_MCULCD_StateIdle == state)
  476. {
  477. return kStatus_NoTransferInProgress;
  478. }
  479. else
  480. {
  481. *count = handle->dataCount - handle->remainingCount;
  482. if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == state)
  483. {
  484. *count -= handle->minorLoopBytes *
  485. EDMA_GetRemainingMajorLoopCount(handle->rxDmaHandle->base, handle->rxDmaHandle->channel);
  486. }
  487. else
  488. {
  489. *count -= handle->minorLoopBytes *
  490. EDMA_GetRemainingMajorLoopCount(handle->txDmaHandle->base, handle->txDmaHandle->channel);
  491. }
  492. }
  493. return kStatus_Success;
  494. }