fsl_edma.h 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2021 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #ifndef _FSL_EDMA_H_
  9. #define _FSL_EDMA_H_
  10. #include "fsl_common.h"
  11. /*!
  12. * @addtogroup edma
  13. * @{
  14. */
  15. /*******************************************************************************
  16. * Definitions
  17. ******************************************************************************/
  18. /*! @name Driver version */
  19. /*@{*/
  20. /*! @brief eDMA driver version */
  21. #define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 4, 3)) /*!< Version 2.4.3. */
  22. /*@}*/
  23. /*! @brief Compute the offset unit from DCHPRI3 */
  24. #define DMA_DCHPRI_INDEX(channel) (((channel) & ~0x03U) | (3U - ((channel)&0x03U)))
  25. /*! @brief eDMA transfer configuration */
  26. typedef enum _edma_transfer_size
  27. {
  28. kEDMA_TransferSize1Bytes = 0x0U, /*!< Source/Destination data transfer size is 1 byte every time */
  29. kEDMA_TransferSize2Bytes = 0x1U, /*!< Source/Destination data transfer size is 2 bytes every time */
  30. kEDMA_TransferSize4Bytes = 0x2U, /*!< Source/Destination data transfer size is 4 bytes every time */
  31. kEDMA_TransferSize8Bytes = 0x3U, /*!< Source/Destination data transfer size is 8 bytes every time */
  32. kEDMA_TransferSize16Bytes = 0x4U, /*!< Source/Destination data transfer size is 16 bytes every time */
  33. kEDMA_TransferSize32Bytes = 0x5U, /*!< Source/Destination data transfer size is 32 bytes every time */
  34. } edma_transfer_size_t;
  35. /*! @brief eDMA modulo configuration */
  36. typedef enum _edma_modulo
  37. {
  38. kEDMA_ModuloDisable = 0x0U, /*!< Disable modulo */
  39. kEDMA_Modulo2bytes, /*!< Circular buffer size is 2 bytes. */
  40. kEDMA_Modulo4bytes, /*!< Circular buffer size is 4 bytes. */
  41. kEDMA_Modulo8bytes, /*!< Circular buffer size is 8 bytes. */
  42. kEDMA_Modulo16bytes, /*!< Circular buffer size is 16 bytes. */
  43. kEDMA_Modulo32bytes, /*!< Circular buffer size is 32 bytes. */
  44. kEDMA_Modulo64bytes, /*!< Circular buffer size is 64 bytes. */
  45. kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */
  46. kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */
  47. kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */
  48. kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */
  49. kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */
  50. kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */
  51. kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */
  52. kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */
  53. kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */
  54. kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */
  55. kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */
  56. kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */
  57. kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */
  58. kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */
  59. kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */
  60. kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */
  61. kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */
  62. kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */
  63. kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */
  64. kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */
  65. kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */
  66. kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */
  67. kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */
  68. kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */
  69. kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */
  70. } edma_modulo_t;
  71. /*! @brief Bandwidth control */
  72. typedef enum _edma_bandwidth
  73. {
  74. kEDMA_BandwidthStallNone = 0x0U, /*!< No eDMA engine stalls. */
  75. kEDMA_BandwidthStall4Cycle = 0x2U, /*!< eDMA engine stalls for 4 cycles after each read/write. */
  76. kEDMA_BandwidthStall8Cycle = 0x3U, /*!< eDMA engine stalls for 8 cycles after each read/write. */
  77. } edma_bandwidth_t;
  78. /*! @brief Channel link type */
  79. typedef enum _edma_channel_link_type
  80. {
  81. kEDMA_LinkNone = 0x0U, /*!< No channel link */
  82. kEDMA_MinorLink, /*!< Channel link after each minor loop */
  83. kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */
  84. } edma_channel_link_type_t;
  85. /*!@brief _edma_channel_status_flags eDMA channel status flags. */
  86. enum
  87. {
  88. kEDMA_DoneFlag = 0x1U, /*!< DONE flag, set while transfer finished, CITER value exhausted*/
  89. kEDMA_ErrorFlag = 0x2U, /*!< eDMA error flag, an error occurred in a transfer */
  90. kEDMA_InterruptFlag = 0x4U, /*!< eDMA interrupt flag, set while an interrupt occurred of this channel */
  91. };
  92. /*! @brief _edma_error_status_flags eDMA channel error status flags. */
  93. enum
  94. {
  95. kEDMA_DestinationBusErrorFlag = DMA_ES_DBE_MASK, /*!< Bus error on destination address */
  96. kEDMA_SourceBusErrorFlag = DMA_ES_SBE_MASK, /*!< Bus error on the source address */
  97. kEDMA_ScatterGatherErrorFlag = DMA_ES_SGE_MASK, /*!< Error on the Scatter/Gather address, not 32byte aligned. */
  98. kEDMA_NbytesErrorFlag = DMA_ES_NCE_MASK, /*!< NBYTES/CITER configuration error */
  99. kEDMA_DestinationOffsetErrorFlag = DMA_ES_DOE_MASK, /*!< Destination offset not aligned with destination size */
  100. kEDMA_DestinationAddressErrorFlag = DMA_ES_DAE_MASK, /*!< Destination address not aligned with destination size */
  101. kEDMA_SourceOffsetErrorFlag = DMA_ES_SOE_MASK, /*!< Source offset not aligned with source size */
  102. kEDMA_SourceAddressErrorFlag = DMA_ES_SAE_MASK, /*!< Source address not aligned with source size*/
  103. kEDMA_ErrorChannelFlag = DMA_ES_ERRCHN_MASK, /*!< Error channel number of the cancelled channel number */
  104. kEDMA_ChannelPriorityErrorFlag = DMA_ES_CPE_MASK, /*!< Channel priority is not unique. */
  105. kEDMA_TransferCanceledFlag = DMA_ES_ECX_MASK, /*!< Transfer cancelled */
  106. #if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && (FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1)
  107. kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */
  108. #endif
  109. kEDMA_ValidFlag = (int)DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */
  110. };
  111. /*! @brief eDMA interrupt source */
  112. typedef enum _edma_interrupt_enable
  113. {
  114. kEDMA_ErrorInterruptEnable = 0x1U, /*!< Enable interrupt while channel error occurs. */
  115. kEDMA_MajorInterruptEnable = DMA_CSR_INTMAJOR_MASK, /*!< Enable interrupt while major count exhausted. */
  116. kEDMA_HalfInterruptEnable = DMA_CSR_INTHALF_MASK, /*!< Enable interrupt while major count to half value. */
  117. } edma_interrupt_enable_t;
  118. /*! @brief eDMA transfer type */
  119. typedef enum _edma_transfer_type
  120. {
  121. kEDMA_MemoryToMemory = 0x0U, /*!< Transfer from memory to memory */
  122. kEDMA_PeripheralToMemory, /*!< Transfer from peripheral to memory */
  123. kEDMA_MemoryToPeripheral, /*!< Transfer from memory to peripheral */
  124. kEDMA_PeripheralToPeripheral, /*!< Transfer from Peripheral to peripheral */
  125. } edma_transfer_type_t;
  126. /*! @brief _edma_transfer_status eDMA transfer status */
  127. enum
  128. {
  129. kStatus_EDMA_QueueFull = MAKE_STATUS(kStatusGroup_EDMA, 0), /*!< TCD queue is full. */
  130. kStatus_EDMA_Busy = MAKE_STATUS(kStatusGroup_EDMA, 1), /*!< Channel is busy and can't handle the
  131. transfer request. */
  132. };
  133. /*! @brief eDMA global configuration structure.*/
  134. typedef struct _edma_config
  135. {
  136. bool enableContinuousLinkMode; /*!< Enable (true) continuous link mode. Upon minor loop completion, the channel
  137. activates again if that channel has a minor loop channel link enabled and
  138. the link channel is itself. */
  139. bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set.
  140. Subsequently, all service requests are ignored until the HALT bit is cleared.*/
  141. bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority
  142. arbitration is used for channel selection */
  143. bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of
  144. a new channel. Executing channels are allowed to complete. */
  145. } edma_config_t;
  146. /*!
  147. * @brief eDMA transfer configuration
  148. *
  149. * This structure configures the source/destination transfer attribute.
  150. */
  151. typedef struct _edma_transfer_config
  152. {
  153. uint32_t srcAddr; /*!< Source data address. */
  154. uint32_t destAddr; /*!< Destination data address. */
  155. edma_transfer_size_t srcTransferSize; /*!< Source data transfer size. */
  156. edma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */
  157. int16_t srcOffset; /*!< Sign-extended offset applied to the current source address to
  158. form the next-state value as each source read is completed. */
  159. int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
  160. form the next-state value as each destination write is completed. */
  161. uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/
  162. uint32_t majorLoopCounts; /*!< Major loop iteration count. */
  163. } edma_transfer_config_t;
  164. /*! @brief eDMA channel priority configuration */
  165. typedef struct _edma_channel_Preemption_config
  166. {
  167. bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */
  168. bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */
  169. uint8_t channelPriority; /*!< Channel priority */
  170. } edma_channel_Preemption_config_t;
  171. /*! @brief eDMA minor offset configuration */
  172. typedef struct _edma_minor_offset_config
  173. {
  174. bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
  175. bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */
  176. uint32_t minorOffset; /*!< Offset for a minor loop mapping. */
  177. } edma_minor_offset_config_t;
  178. /*!
  179. * @brief eDMA TCD.
  180. *
  181. * This structure is same as TCD register which is described in reference manual,
  182. * and is used to configure the scatter/gather feature as a next hardware TCD.
  183. */
  184. typedef struct _edma_tcd
  185. {
  186. __IO uint32_t SADDR; /*!< SADDR register, used to save source address */
  187. __IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */
  188. __IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */
  189. __IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */
  190. __IO uint32_t SLAST; /*!< SLAST register */
  191. __IO uint32_t DADDR; /*!< DADDR register, used for destination address */
  192. __IO uint16_t DOFF; /*!< DOFF register, used for destination offset */
  193. __IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/
  194. __IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next tcd address used in scatter-gather mode */
  195. __IO uint16_t CSR; /*!< CSR register, for TCD control status */
  196. __IO uint16_t BITER; /*!< BITER register, begin minor loop count. */
  197. } edma_tcd_t;
  198. /*! @brief Callback for eDMA */
  199. struct _edma_handle;
  200. /*! @brief Define callback function for eDMA.
  201. *
  202. * This callback function is called in the EDMA interrupt handle.
  203. * In normal mode, run into callback function means the transfer users need is done.
  204. * In scatter gather mode, run into callback function means a transfer control block (tcd) is finished. Not
  205. * all transfer finished, users can get the finished tcd numbers using interface EDMA_GetUnusedTCDNumber.
  206. *
  207. * @param handle EDMA handle pointer, users shall not touch the values inside.
  208. * @param userData The callback user parameter pointer. Users can use this parameter to involve things users need to
  209. * change in EDMA callback function.
  210. * @param transferDone If the current loaded transfer done. In normal mode it means if all transfer done. In scatter
  211. * gather mode, this parameter shows is the current transfer block in EDMA register is done. As the
  212. * load of core is different, it will be different if the new tcd loaded into EDMA registers while
  213. * this callback called. If true, it always means new tcd still not loaded into registers, while
  214. * false means new tcd already loaded into registers.
  215. * @param tcds How many tcds are done from the last callback. This parameter only used in scatter gather mode. It
  216. * tells user how many tcds are finished between the last callback and this.
  217. */
  218. typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
  219. /*! @brief eDMA transfer handle structure */
  220. typedef struct _edma_handle
  221. {
  222. edma_callback callback; /*!< Callback function for major count exhausted. */
  223. void *userData; /*!< Callback function parameter. */
  224. DMA_Type *base; /*!< eDMA peripheral base address. */
  225. edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
  226. uint8_t channel; /*!< eDMA channel number. */
  227. volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */
  228. volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */
  229. volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in
  230. the memory. */
  231. volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
  232. uint8_t flags; /*!< The status of the current channel. */
  233. } edma_handle_t;
  234. /*******************************************************************************
  235. * APIs
  236. ******************************************************************************/
  237. #if defined(__cplusplus)
  238. extern "C" {
  239. #endif /* __cplusplus */
  240. /*!
  241. * @name eDMA initialization and de-initialization
  242. * @{
  243. */
  244. /*!
  245. * @brief Initializes the eDMA peripheral.
  246. *
  247. * This function ungates the eDMA clock and configures the eDMA peripheral according
  248. * to the configuration structure.
  249. *
  250. * @param base eDMA peripheral base address.
  251. * @param config A pointer to the configuration structure, see "edma_config_t".
  252. * @note This function enables the minor loop map feature.
  253. */
  254. void EDMA_Init(DMA_Type *base, const edma_config_t *config);
  255. /*!
  256. * @brief Deinitializes the eDMA peripheral.
  257. *
  258. * This function gates the eDMA clock.
  259. *
  260. * @param base eDMA peripheral base address.
  261. */
  262. void EDMA_Deinit(DMA_Type *base);
  263. /*!
  264. * @brief Push content of TCD structure into hardware TCD register.
  265. *
  266. * @param base EDMA peripheral base address.
  267. * @param channel EDMA channel number.
  268. * @param tcd Point to TCD structure.
  269. */
  270. void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd);
  271. /*!
  272. * @brief Gets the eDMA default configuration structure.
  273. *
  274. * This function sets the configuration structure to default values.
  275. * The default configuration is set to the following values.
  276. * @code
  277. * config.enableContinuousLinkMode = false;
  278. * config.enableHaltOnError = true;
  279. * config.enableRoundRobinArbitration = false;
  280. * config.enableDebugMode = false;
  281. * @endcode
  282. *
  283. * @param config A pointer to the eDMA configuration structure.
  284. */
  285. void EDMA_GetDefaultConfig(edma_config_t *config);
  286. /*!
  287. * @brief Enable/Disable continuous channel link mode.
  288. *
  289. * @note Do not use continuous link mode with a channel linking to itself if there is only one minor loop
  290. * iteration per service request, for example, if the channel's NBYTES value is the same as either
  291. * the source or destination size. The same data transfer profile can be achieved by simply
  292. * increasing the NBYTES value, which provides more efficient, faster processing.
  293. *
  294. * @param base EDMA peripheral base address.
  295. * @param enable true is enable, false is disable.
  296. */
  297. static inline void EDMA_EnableContinuousChannelLinkMode(DMA_Type *base, bool enable)
  298. {
  299. if (enable)
  300. {
  301. base->CR |= DMA_CR_CLM_MASK;
  302. }
  303. else
  304. {
  305. base->CR &= ~DMA_CR_CLM_MASK;
  306. }
  307. }
  308. /*!
  309. * @brief Enable/Disable minor loop mapping.
  310. *
  311. * The TCDn.word2 is redefined to include individual enable fields, an offset field, and the
  312. * NBYTES field.
  313. *
  314. * @param base EDMA peripheral base address.
  315. * @param enable true is enable, false is disable.
  316. */
  317. static inline void EDMA_EnableMinorLoopMapping(DMA_Type *base, bool enable)
  318. {
  319. if (enable)
  320. {
  321. base->CR |= DMA_CR_EMLM_MASK;
  322. }
  323. else
  324. {
  325. base->CR &= ~DMA_CR_EMLM_MASK;
  326. }
  327. }
  328. /* @} */
  329. /*!
  330. * @name eDMA Channel Operation
  331. * @{
  332. */
  333. /*!
  334. * @brief Sets all TCD registers to default values.
  335. *
  336. * This function sets TCD registers for this channel to default values.
  337. *
  338. * @param base eDMA peripheral base address.
  339. * @param channel eDMA channel number.
  340. * @note This function must not be called while the channel transfer is ongoing
  341. * or it causes unpredictable results.
  342. * @note This function enables the auto stop request feature.
  343. */
  344. void EDMA_ResetChannel(DMA_Type *base, uint32_t channel);
  345. /*!
  346. * @brief Configures the eDMA transfer attribute.
  347. *
  348. * This function configures the transfer attribute, including source address, destination address,
  349. * transfer size, address offset, and so on. It also configures the scatter gather feature if the
  350. * user supplies the TCD address.
  351. * Example:
  352. * @code
  353. * edma_transfer_t config;
  354. * edma_tcd_t tcd;
  355. * config.srcAddr = ..;
  356. * config.destAddr = ..;
  357. * ...
  358. * EDMA_SetTransferConfig(DMA0, channel, &config, &stcd);
  359. * @endcode
  360. *
  361. * @param base eDMA peripheral base address.
  362. * @param channel eDMA channel number.
  363. * @param config Pointer to eDMA transfer configuration structure.
  364. * @param nextTcd Point to TCD structure. It can be NULL if users
  365. * do not want to enable scatter/gather feature.
  366. * @note If nextTcd is not NULL, it means scatter gather feature is enabled
  367. * and DREQ bit is cleared in the previous transfer configuration, which
  368. * is set in the eDMA_ResetChannel.
  369. */
  370. void EDMA_SetTransferConfig(DMA_Type *base,
  371. uint32_t channel,
  372. const edma_transfer_config_t *config,
  373. edma_tcd_t *nextTcd);
  374. /*!
  375. * @brief Configures the eDMA minor offset feature.
  376. *
  377. * The minor offset means that the signed-extended value is added to the source address or destination
  378. * address after each minor loop.
  379. *
  380. * @param base eDMA peripheral base address.
  381. * @param channel eDMA channel number.
  382. * @param config A pointer to the minor offset configuration structure.
  383. */
  384. void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config);
  385. /*!
  386. * @brief Configures the eDMA channel preemption feature.
  387. *
  388. * This function configures the channel preemption attribute and the priority of the channel.
  389. *
  390. * @param base eDMA peripheral base address.
  391. * @param channel eDMA channel number
  392. * @param config A pointer to the channel preemption configuration structure.
  393. */
  394. void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, const edma_channel_Preemption_config_t *config);
  395. /*!
  396. * @brief Sets the channel link for the eDMA transfer.
  397. *
  398. * This function configures either the minor link or the major link mode. The minor link means that the channel link is
  399. * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
  400. * exhausted.
  401. *
  402. * @param base eDMA peripheral base address.
  403. * @param channel eDMA channel number.
  404. * @param type A channel link type, which can be one of the following:
  405. * @arg kEDMA_LinkNone
  406. * @arg kEDMA_MinorLink
  407. * @arg kEDMA_MajorLink
  408. * @param linkedChannel The linked channel number.
  409. * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
  410. */
  411. void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel);
  412. /*!
  413. * @brief Sets the bandwidth for the eDMA transfer.
  414. *
  415. * Because the eDMA processes the minor loop, it continuously generates read/write sequences
  416. * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of
  417. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
  418. *
  419. * @param base eDMA peripheral base address.
  420. * @param channel eDMA channel number.
  421. * @param bandWidth A bandwidth setting, which can be one of the following:
  422. * @arg kEDMABandwidthStallNone
  423. * @arg kEDMABandwidthStall4Cycle
  424. * @arg kEDMABandwidthStall8Cycle
  425. */
  426. void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth);
  427. /*!
  428. * @brief Sets the source modulo and the destination modulo for the eDMA transfer.
  429. *
  430. * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
  431. * calculation is performed or the original register value. It provides the ability to implement a circular data
  432. * queue easily.
  433. *
  434. * @param base eDMA peripheral base address.
  435. * @param channel eDMA channel number.
  436. * @param srcModulo A source modulo value.
  437. * @param destModulo A destination modulo value.
  438. */
  439. void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo);
  440. #if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT
  441. /*!
  442. * @brief Enables an async request for the eDMA transfer.
  443. *
  444. * @param base eDMA peripheral base address.
  445. * @param channel eDMA channel number.
  446. * @param enable The command to enable (true) or disable (false).
  447. */
  448. static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable)
  449. {
  450. assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
  451. base->EARS &= ~((uint32_t)1U << channel);
  452. base->EARS |= ((uint32_t)(true == enable ? 1U : 0U) << channel);
  453. }
  454. #endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */
  455. /*!
  456. * @brief Enables an auto stop request for the eDMA transfer.
  457. *
  458. * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
  459. *
  460. * @param base eDMA peripheral base address.
  461. * @param channel eDMA channel number.
  462. * @param enable The command to enable (true) or disable (false).
  463. */
  464. static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable)
  465. {
  466. assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
  467. base->TCD[channel].CSR =
  468. (uint16_t)((base->TCD[channel].CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ((true == enable ? 1U : 0U)));
  469. }
  470. /*!
  471. * @brief Enables the interrupt source for the eDMA transfer.
  472. *
  473. * @param base eDMA peripheral base address.
  474. * @param channel eDMA channel number.
  475. * @param mask The mask of interrupt source to be set. Users need to use
  476. * the defined edma_interrupt_enable_t type.
  477. */
  478. void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
  479. /*!
  480. * @brief Disables the interrupt source for the eDMA transfer.
  481. *
  482. * @param base eDMA peripheral base address.
  483. * @param channel eDMA channel number.
  484. * @param mask The mask of the interrupt source to be set. Use
  485. * the defined edma_interrupt_enable_t type.
  486. */
  487. void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
  488. /*!
  489. * @brief Configures the eDMA channel TCD major offset feature.
  490. *
  491. * Adjustment value added to the source address at the completion of the major iteration count
  492. *
  493. * @param base eDMA peripheral base address.
  494. * @param channel edma channel number.
  495. * @param sourceOffset source address offset will be applied to source address after major loop done.
  496. * @param destOffset destination address offset will be applied to source address after major loop done.
  497. */
  498. void EDMA_SetMajorOffsetConfig(DMA_Type *base, uint32_t channel, int32_t sourceOffset, int32_t destOffset);
  499. /* @} */
  500. /*!
  501. * @name eDMA TCD Operation
  502. * @{
  503. */
  504. /*!
  505. * @brief Sets all fields to default values for the TCD structure.
  506. *
  507. * This function sets all fields for this TCD structure to default value.
  508. *
  509. * @param tcd Pointer to the TCD structure.
  510. * @note This function enables the auto stop request feature.
  511. */
  512. void EDMA_TcdReset(edma_tcd_t *tcd);
  513. /*!
  514. * @brief Configures the eDMA TCD transfer attribute.
  515. *
  516. * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
  517. * The STCD is used in the scatter-gather mode.
  518. * This function configures the TCD transfer attribute, including source address, destination address,
  519. * transfer size, address offset, and so on. It also configures the scatter gather feature if the
  520. * user supplies the next TCD address.
  521. * Example:
  522. * @code
  523. * edma_transfer_t config = {
  524. * ...
  525. * }
  526. * edma_tcd_t tcd __aligned(32);
  527. * edma_tcd_t nextTcd __aligned(32);
  528. * EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd);
  529. * @endcode
  530. *
  531. * @param tcd Pointer to the TCD structure.
  532. * @param config Pointer to eDMA transfer configuration structure.
  533. * @param nextTcd Pointer to the next TCD structure. It can be NULL if users
  534. * do not want to enable scatter/gather feature.
  535. * @note TCD address should be 32 bytes aligned or it causes an eDMA error.
  536. * @note If the nextTcd is not NULL, the scatter gather feature is enabled
  537. * and DREQ bit is cleared in the previous transfer configuration, which
  538. * is set in the EDMA_TcdReset.
  539. */
  540. void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd);
  541. /*!
  542. * @brief Configures the eDMA TCD minor offset feature.
  543. *
  544. * A minor offset is a signed-extended value added to the source address or a destination
  545. * address after each minor loop.
  546. *
  547. * @param tcd A point to the TCD structure.
  548. * @param config A pointer to the minor offset configuration structure.
  549. */
  550. void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config);
  551. /*!
  552. * @brief Sets the channel link for the eDMA TCD.
  553. *
  554. * This function configures either a minor link or a major link. The minor link means the channel link is
  555. * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
  556. * exhausted.
  557. *
  558. * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
  559. * @param tcd Point to the TCD structure.
  560. * @param type Channel link type, it can be one of:
  561. * @arg kEDMA_LinkNone
  562. * @arg kEDMA_MinorLink
  563. * @arg kEDMA_MajorLink
  564. * @param linkedChannel The linked channel number.
  565. */
  566. void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel);
  567. /*!
  568. * @brief Sets the bandwidth for the eDMA TCD.
  569. *
  570. * Because the eDMA processes the minor loop, it continuously generates read/write sequences
  571. * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of
  572. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
  573. * @param tcd A pointer to the TCD structure.
  574. * @param bandWidth A bandwidth setting, which can be one of the following:
  575. * @arg kEDMABandwidthStallNone
  576. * @arg kEDMABandwidthStall4Cycle
  577. * @arg kEDMABandwidthStall8Cycle
  578. */
  579. static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWidth)
  580. {
  581. assert(tcd != NULL);
  582. assert(((uint32_t)tcd & 0x1FU) == 0U);
  583. tcd->CSR = (uint16_t)((tcd->CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth));
  584. }
  585. /*!
  586. * @brief Sets the source modulo and the destination modulo for the eDMA TCD.
  587. *
  588. * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
  589. * calculation is performed or the original register value. It provides the ability to implement a circular data
  590. * queue easily.
  591. *
  592. * @param tcd A pointer to the TCD structure.
  593. * @param srcModulo A source modulo value.
  594. * @param destModulo A destination modulo value.
  595. */
  596. void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo);
  597. /*!
  598. * @brief Sets the auto stop request for the eDMA TCD.
  599. *
  600. * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
  601. *
  602. * @param tcd A pointer to the TCD structure.
  603. * @param enable The command to enable (true) or disable (false).
  604. */
  605. static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable)
  606. {
  607. assert(tcd != NULL);
  608. assert(((uint32_t)tcd & 0x1FU) == 0U);
  609. tcd->CSR = (uint16_t)((tcd->CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ((true == enable ? 1U : 0U)));
  610. }
  611. /*!
  612. * @brief Enables the interrupt source for the eDMA TCD.
  613. *
  614. * @param tcd Point to the TCD structure.
  615. * @param mask The mask of interrupt source to be set. Users need to use
  616. * the defined edma_interrupt_enable_t type.
  617. */
  618. void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask);
  619. /*!
  620. * @brief Disables the interrupt source for the eDMA TCD.
  621. *
  622. * @param tcd Point to the TCD structure.
  623. * @param mask The mask of interrupt source to be set. Users need to use
  624. * the defined edma_interrupt_enable_t type.
  625. */
  626. void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask);
  627. /*!
  628. * @brief Configures the eDMA TCD major offset feature.
  629. *
  630. * Adjustment value added to the source address at the completion of the major iteration count
  631. *
  632. * @param tcd A point to the TCD structure.
  633. * @param sourceOffset source address offset wiil be applied to source address after major loop done.
  634. * @param destOffset destination address offset will be applied to source address after major loop done.
  635. */
  636. void EDMA_TcdSetMajorOffsetConfig(edma_tcd_t *tcd, int32_t sourceOffset, int32_t destOffset);
  637. /*! @} */
  638. /*!
  639. * @name eDMA Channel Transfer Operation
  640. * @{
  641. */
  642. /*!
  643. * @brief Enables the eDMA hardware channel request.
  644. *
  645. * This function enables the hardware channel request.
  646. *
  647. * @param base eDMA peripheral base address.
  648. * @param channel eDMA channel number.
  649. */
  650. static inline void EDMA_EnableChannelRequest(DMA_Type *base, uint32_t channel)
  651. {
  652. assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
  653. base->SERQ = DMA_SERQ_SERQ(channel);
  654. }
  655. /*!
  656. * @brief Disables the eDMA hardware channel request.
  657. *
  658. * This function disables the hardware channel request.
  659. *
  660. * @param base eDMA peripheral base address.
  661. * @param channel eDMA channel number.
  662. */
  663. static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel)
  664. {
  665. assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
  666. base->CERQ = DMA_CERQ_CERQ(channel);
  667. }
  668. /*!
  669. * @brief Starts the eDMA transfer by using the software trigger.
  670. *
  671. * This function starts a minor loop transfer.
  672. *
  673. * @param base eDMA peripheral base address.
  674. * @param channel eDMA channel number.
  675. */
  676. static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel)
  677. {
  678. assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
  679. base->SSRT = DMA_SSRT_SSRT(channel);
  680. }
  681. /*! @} */
  682. /*!
  683. * @name eDMA Channel Status Operation
  684. * @{
  685. */
  686. /*!
  687. * @brief Gets the remaining major loop count from the eDMA current channel TCD.
  688. *
  689. * This function checks the TCD (Task Control Descriptor) status for a specified
  690. * eDMA channel and returns the number of major loop count that has not finished.
  691. *
  692. * @param base eDMA peripheral base address.
  693. * @param channel eDMA channel number.
  694. * @return Major loop count which has not been transferred yet for the current TCD.
  695. * @note 1. This function can only be used to get unfinished major loop count of transfer without
  696. * the next TCD, or it might be inaccuracy.
  697. * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while
  698. * the channel is running.
  699. * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO
  700. * register is needed while the eDMA IP does not support getting it while a channel is active.
  701. * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine
  702. * is working with while a channel is running.
  703. * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example
  704. * copied before enabling the channel) is needed. The formula to calculate it is shown below:
  705. * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured)
  706. */
  707. uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel);
  708. /*!
  709. * @brief Gets the eDMA channel error status flags.
  710. *
  711. * @param base eDMA peripheral base address.
  712. * @return The mask of error status flags. Users need to use the
  713. * _edma_error_status_flags type to decode the return variables.
  714. */
  715. static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base)
  716. {
  717. return base->ES;
  718. }
  719. /*!
  720. * @brief Gets the eDMA channel status flags.
  721. *
  722. * @param base eDMA peripheral base address.
  723. * @param channel eDMA channel number.
  724. * @return The mask of channel status flags. Users need to use the
  725. * _edma_channel_status_flags type to decode the return variables.
  726. */
  727. uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel);
  728. /*!
  729. * @brief Clears the eDMA channel status flags.
  730. *
  731. * @param base eDMA peripheral base address.
  732. * @param channel eDMA channel number.
  733. * @param mask The mask of channel status to be cleared. Users need to use
  734. * the defined _edma_channel_status_flags type.
  735. */
  736. void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask);
  737. /*! @} */
  738. /*!
  739. * @name eDMA Transactional Operation
  740. */
  741. /*!
  742. * @brief Creates the eDMA handle.
  743. *
  744. * This function is called if using the transactional API for eDMA. This function
  745. * initializes the internal state of the eDMA handle.
  746. *
  747. * @param handle eDMA handle pointer. The eDMA handle stores callback function and
  748. * parameters.
  749. * @param base eDMA peripheral base address.
  750. * @param channel eDMA channel number.
  751. */
  752. void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel);
  753. /*!
  754. * @brief Installs the TCDs memory pool into the eDMA handle.
  755. *
  756. * This function is called after the EDMA_CreateHandle to use scatter/gather feature. This function shall only be used
  757. * while users need to use scatter gather mode. Scatter gather mode enables EDMA to load a new transfer control block
  758. * (tcd) in hardware, and automatically reconfigure that DMA channel for a new transfer.
  759. * Users need to prepare tcd memory and also configure tcds using interface EDMA_SubmitTransfer.
  760. *
  761. * @param handle eDMA handle pointer.
  762. * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned.
  763. * @param tcdSize The number of TCD slots.
  764. */
  765. void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize);
  766. /*!
  767. * @brief Installs a callback function for the eDMA transfer.
  768. *
  769. * This callback is called in the eDMA IRQ handler. Use the callback to do something after
  770. * the current major loop transfer completes. This function will be called every time one tcd finished transfer.
  771. *
  772. * @param handle eDMA handle pointer.
  773. * @param callback eDMA callback function pointer.
  774. * @param userData A parameter for the callback function.
  775. */
  776. void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
  777. /*!
  778. * @brief Prepares the eDMA transfer structure configurations.
  779. *
  780. * This function prepares the transfer configuration structure according to the user input.
  781. *
  782. * @param config The user configuration structure of type edma_transfer_t.
  783. * @param srcAddr eDMA transfer source address.
  784. * @param srcWidth eDMA transfer source address width(bytes).
  785. * @param srcOffset source address offset.
  786. * @param destAddr eDMA transfer destination address.
  787. * @param destWidth eDMA transfer destination address width(bytes).
  788. * @param destOffset destination address offset.
  789. * @param bytesEachRequest eDMA transfer bytes per channel request.
  790. * @param transferBytes eDMA transfer bytes to be transferred.
  791. * @note The data address and the data width must be consistent. For example, if the SRC
  792. * is 4 bytes, the source address must be 4 bytes aligned, or it results in
  793. * source address error (SAE).
  794. */
  795. void EDMA_PrepareTransferConfig(edma_transfer_config_t *config,
  796. void *srcAddr,
  797. uint32_t srcWidth,
  798. int16_t srcOffset,
  799. void *destAddr,
  800. uint32_t destWidth,
  801. int16_t destOffset,
  802. uint32_t bytesEachRequest,
  803. uint32_t transferBytes);
  804. /*!
  805. * @brief Prepares the eDMA transfer structure.
  806. *
  807. * This function prepares the transfer configuration structure according to the user input.
  808. *
  809. * @param config The user configuration structure of type edma_transfer_t.
  810. * @param srcAddr eDMA transfer source address.
  811. * @param srcWidth eDMA transfer source address width(bytes).
  812. * @param destAddr eDMA transfer destination address.
  813. * @param destWidth eDMA transfer destination address width(bytes).
  814. * @param bytesEachRequest eDMA transfer bytes per channel request.
  815. * @param transferBytes eDMA transfer bytes to be transferred.
  816. * @param type eDMA transfer type.
  817. * @note The data address and the data width must be consistent. For example, if the SRC
  818. * is 4 bytes, the source address must be 4 bytes aligned, or it results in
  819. * source address error (SAE).
  820. */
  821. void EDMA_PrepareTransfer(edma_transfer_config_t *config,
  822. void *srcAddr,
  823. uint32_t srcWidth,
  824. void *destAddr,
  825. uint32_t destWidth,
  826. uint32_t bytesEachRequest,
  827. uint32_t transferBytes,
  828. edma_transfer_type_t type);
  829. /*!
  830. * @brief Submits the eDMA transfer request.
  831. *
  832. * This function submits the eDMA transfer request according to the transfer configuration structure.
  833. * In scatter gather mode, call this function will add a configured tcd to the circular list of tcd pool.
  834. * The tcd pools is setup by call function EDMA_InstallTCDMemory before.
  835. *
  836. * @param handle eDMA handle pointer.
  837. * @param config Pointer to eDMA transfer configuration structure.
  838. * @retval kStatus_EDMA_Success It means submit transfer request succeed.
  839. * @retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed.
  840. * @retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later.
  841. */
  842. status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config);
  843. /*!
  844. * @brief eDMA starts transfer.
  845. *
  846. * This function enables the channel request. Users can call this function after submitting the transfer request
  847. * or before submitting the transfer request.
  848. *
  849. * @param handle eDMA handle pointer.
  850. */
  851. void EDMA_StartTransfer(edma_handle_t *handle);
  852. /*!
  853. * @brief eDMA stops transfer.
  854. *
  855. * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer()
  856. * again to resume the transfer.
  857. *
  858. * @param handle eDMA handle pointer.
  859. */
  860. void EDMA_StopTransfer(edma_handle_t *handle);
  861. /*!
  862. * @brief eDMA aborts transfer.
  863. *
  864. * This function disables the channel request and clear transfer status bits.
  865. * Users can submit another transfer after calling this API.
  866. *
  867. * @param handle DMA handle pointer.
  868. */
  869. void EDMA_AbortTransfer(edma_handle_t *handle);
  870. /*!
  871. * @brief Get unused TCD slot number.
  872. *
  873. * This function gets current tcd index which is run. If the TCD pool pointer is NULL, it will return 0.
  874. *
  875. * @param handle DMA handle pointer.
  876. * @return The unused tcd slot number.
  877. */
  878. static inline uint32_t EDMA_GetUnusedTCDNumber(edma_handle_t *handle)
  879. {
  880. int8_t tmpTcdSize = handle->tcdSize;
  881. int8_t tmpTcdUsed = handle->tcdUsed;
  882. return ((uint32_t)tmpTcdSize - (uint32_t)tmpTcdUsed);
  883. }
  884. /*!
  885. * @brief Get the next tcd address.
  886. *
  887. * This function gets the next tcd address. If this is last TCD, return 0.
  888. *
  889. * @param handle DMA handle pointer.
  890. * @return The next TCD address.
  891. */
  892. static inline uint32_t EDMA_GetNextTCDAddress(edma_handle_t *handle)
  893. {
  894. return (uint32_t)(handle->base->TCD[handle->channel].DLAST_SGA);
  895. }
  896. /*!
  897. * @brief eDMA IRQ handler for the current major loop transfer completion.
  898. *
  899. * This function clears the channel major interrupt flag and calls
  900. * the callback function if it is not NULL.
  901. *
  902. * Note:
  903. * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed.
  904. * These include the final address adjustments and reloading of the BITER field into the CITER.
  905. * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from
  906. * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled).
  907. *
  908. * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine.
  909. * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index
  910. * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be
  911. * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have
  912. * been loaded into the eDMA engine at this point already.).
  913. *
  914. * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not
  915. * load a new TCD) from the memory pool to the eDMA engine when major loop completes.
  916. * Therefore, ensure that the header and tcdUsed updated are identical for them.
  917. * tcdUsed are both 0 in this case as no TCD to be loaded.
  918. *
  919. * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for
  920. * further details.
  921. *
  922. * @param handle eDMA handle pointer.
  923. */
  924. void EDMA_HandleIRQ(edma_handle_t *handle);
  925. /* @} */
  926. #if defined(__cplusplus)
  927. }
  928. #endif /* __cplusplus */
  929. /* @} */
  930. #endif /*_FSL_EDMA_H_*/