HAL_DMA.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /*
  2. ******************************************************************************
  3. * @file HAL_DMA.c
  4. * @version V1.0.0
  5. * @date 2020
  6. * @brief DMA HAL module driver.
  7. * This file provides firmware functions to manage the following
  8. * functionalities of the Direct Memory Access (DMA) peripheral:
  9. * @ Initialization and de-initialization functions
  10. * @ IO operation functions
  11. ******************************************************************************
  12. */
  13. #include "ACM32Fxx_HAL.h"
  14. /**************** Used in cycle mode ****************/
  15. static DMA_LLI_InitTypeDef Cycle_Channel[DMA_CHANNEL_NUM];
  16. /*********************************************************************************
  17. * Function : HAL_DMA_IRQHandler
  18. * Description : This function handles DMA interrupt request.
  19. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  20. * the configuration information for DMA module
  21. * Output :
  22. * Author : Chris_Kyle Data : 2020
  23. **********************************************************************************/
  24. __weak void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
  25. {
  26. uint32_t lu32_Channel_Index;
  27. /* Get DMA Channel number */
  28. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  29. /* Channel has been interrupted */
  30. if (DMA->INT_STATUS & (1 << lu32_Channel_Index))
  31. {
  32. /* Transfer complete interrupt */
  33. if (DMA->INT_TC_STATUS & (1 << lu32_Channel_Index))
  34. {
  35. DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
  36. if (NULL != hdma->DMA_ITC_Callback)
  37. {
  38. hdma->DMA_ITC_Callback();
  39. }
  40. }
  41. /* Transfer error interrupt */
  42. if (DMA->INT_ERR_STATUS & (1 << lu32_Channel_Index))
  43. {
  44. DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
  45. if (NULL != hdma->DMA_IE_Callback)
  46. {
  47. hdma->DMA_IE_Callback();
  48. }
  49. }
  50. }
  51. }
  52. /*********************************************************************************
  53. * Function : HAL_DMA_Init
  54. * Description : DMA initial with parameters.
  55. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  56. * the configuration information for DMA module
  57. * Output :
  58. * Author : Chris_Kyle Data : 2020
  59. **********************************************************************************/
  60. HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
  61. {
  62. #if (USE_FULL_ASSERT == 1)
  63. /* Check DMA Parameter */
  64. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  65. if (!IS_DMA_DATA_FLOW(hdma->Init.Data_Flow)) return HAL_ERROR;
  66. if (!IS_DMA_REQUEST_ID(hdma->Init.Request_ID)) return HAL_ERROR;
  67. if (!IS_DMA_SRC_WIDTH(hdma->Init.Source_Width)) return HAL_ERROR;
  68. if (!IS_DMA_DST_WIDTH(hdma->Init.Desination_Width)) return HAL_ERROR;
  69. #endif
  70. /* Enable DMA Module */
  71. System_Module_Enable(EN_DMA);
  72. /* Enable External Interrupt */
  73. NVIC_ClearPendingIRQ(DMA_IRQn);
  74. NVIC_EnableIRQ(DMA_IRQn);
  75. /* Default Little-Endian、Enable DMA */
  76. DMA->CONFIG = DMA_CONFIG_EN;
  77. /* Clear Channel Config */
  78. hdma->Instance->CONFIG = 0x00000000;
  79. if (hdma->Init.Data_Flow == DMA_DATA_FLOW_M2P)
  80. {
  81. hdma->Init.Request_ID <<= DMA_CHANNEL_CONFIG_DEST_PERIPH_POS;
  82. }
  83. else if (hdma->Init.Data_Flow == DMA_DATA_FLOW_P2M)
  84. {
  85. hdma->Init.Request_ID <<= DMA_CHANNEL_CONFIG_SRC_PERIPH_POS;
  86. }
  87. hdma->Instance->CONFIG = hdma->Init.Data_Flow | hdma->Init.Request_ID;
  88. /* Config Channel Control */
  89. hdma->Instance->CTRL = DMA_CHANNEL_CTRL_ITC;
  90. /* Source or Desination address increase */
  91. hdma->Instance->CTRL |= (hdma->Init.Desination_Inc | hdma->Init.Source_Inc);
  92. /* Source or Desination date width */
  93. hdma->Instance->CTRL |= (hdma->Init.Desination_Width | hdma->Init.Source_Width);
  94. return HAL_OK;
  95. }
  96. /*********************************************************************************
  97. * Function : HAL_DMA_DeInit
  98. * Description : DMA De-initial with parameters.
  99. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  100. * the configuration information for DMA module
  101. * Output :
  102. * Author : Chris_Kyle Data : 2020
  103. **********************************************************************************/
  104. HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
  105. {
  106. #if (USE_FULL_ASSERT == 1)
  107. /* Check DMA Parameter */
  108. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  109. if (!IS_DMA_DATA_FLOW(hdma->Init.Data_Flow)) return HAL_ERROR;
  110. if (!IS_DMA_REQUEST_ID(hdma->Init.Request_ID)) return HAL_ERROR;
  111. if (!IS_DMA_SRC_WIDTH(hdma->Init.Source_Width)) return HAL_ERROR;
  112. if (!IS_DMA_DST_WIDTH(hdma->Init.Desination_Width)) return HAL_ERROR;
  113. #endif
  114. /* Reset DMA Module */
  115. System_Module_Reset(RST_DMA);
  116. /* Disable DMA Module */
  117. System_Module_Disable(EN_DMA);
  118. /* Disable Interrupt */
  119. NVIC_ClearPendingIRQ(DMA_IRQn);
  120. NVIC_DisableIRQ(DMA_IRQn);
  121. hdma->DMA_IE_Callback = NULL;
  122. hdma->DMA_ITC_Callback = NULL;
  123. memset(&hdma->Init, 0, sizeof(hdma->Init));
  124. return HAL_OK;
  125. }
  126. /*********************************************************************************
  127. * Function : HAL_DMA_NormalMode_Start
  128. * Description : DMA transfer start.
  129. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  130. * the configuration information for DMA module
  131. * Input : fu32_SrcAddr: source address
  132. * Input : fu32_DstAddr: desination address
  133. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  134. * Output :
  135. * Author : Chris_Kyle Data : 2020
  136. **********************************************************************************/
  137. HAL_StatusTypeDef HAL_DMA_NormalMode_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  138. {
  139. #if (USE_FULL_ASSERT == 1)
  140. /* Check DMA Parameter */
  141. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  142. #endif
  143. if (fu32_Size > 0xFFF)
  144. {
  145. return HAL_ERROR;
  146. }
  147. /* Set source address and desination address */
  148. hdma->Instance->SRC_ADDR = fu32_SrcAddr;
  149. hdma->Instance->DEST_ADDR = fu32_DstAddr;
  150. /* Set Transfer Size */
  151. hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  152. /* DMA Channel Enable */
  153. hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_EN;
  154. return HAL_OK;
  155. }
  156. /*********************************************************************************
  157. * Function : HAL_DMA_NormalMode_Start_IT
  158. * Description : DMA transfer start with interrupt.
  159. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  160. * the configuration information for DMA module
  161. * Input : fu32_SrcAddr: source address
  162. * Input : fu32_DstAddr: desination address
  163. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  164. * Output :
  165. * Author : Chris_Kyle Data : 2020
  166. **********************************************************************************/
  167. HAL_StatusTypeDef HAL_DMA_NormalMode_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  168. {
  169. #if (USE_FULL_ASSERT == 1)
  170. /* Check DMA Parameter */
  171. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  172. #endif
  173. /* Set source address and desination address */
  174. hdma->Instance->SRC_ADDR = fu32_SrcAddr;
  175. hdma->Instance->DEST_ADDR = fu32_DstAddr;
  176. /* Set Transfer Size and enable LLI interrupt */
  177. hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  178. // hdma->Instance->CTRL &=~(1<<31);
  179. /* DMA Channel Enable and enable transfer error interrupt and transfer complete interrupt*/
  180. hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_ITC | DMA_CHANNEL_CONFIG_IE | DMA_CHANNEL_CONFIG_EN;
  181. return HAL_OK;
  182. }
  183. /*********************************************************************************
  184. * Function : HAL_DMA_CycleMode_Start
  185. * Description : DMA Cycle transfer start.
  186. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  187. * the configuration information for DMA module
  188. * Input : fu32_SrcAddr: source address
  189. * Input : fu32_DstAddr: desination address
  190. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  191. * Output :
  192. * Author : Chris_Kyle Data : 2020
  193. **********************************************************************************/
  194. HAL_StatusTypeDef HAL_DMA_CycleMode_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  195. {
  196. uint32_t lu32_Channel_Index;
  197. #if (USE_FULL_ASSERT == 1)
  198. /* Check DMA Parameter */
  199. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  200. #endif
  201. /* Get DMA Channel number */
  202. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  203. /* Set source address and desination address */
  204. hdma->Instance->SRC_ADDR = fu32_SrcAddr;
  205. hdma->Instance->DEST_ADDR = fu32_DstAddr;
  206. /* Set Next Link */
  207. hdma->Instance->LLI = (uint32_t)&Cycle_Channel[lu32_Channel_Index];
  208. /* Set Transfer Size */
  209. hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  210. /* The list point to oneself */
  211. Cycle_Channel[lu32_Channel_Index].SrcAddr = fu32_SrcAddr;
  212. Cycle_Channel[lu32_Channel_Index].DstAddr = fu32_DstAddr;
  213. Cycle_Channel[lu32_Channel_Index].Next = &Cycle_Channel[lu32_Channel_Index];
  214. Cycle_Channel[lu32_Channel_Index].Control = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  215. /* DMA Channel Enable */
  216. hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_EN;
  217. return HAL_OK;
  218. }
  219. /*********************************************************************************
  220. * Function : HAL_DMA_CycleMode_Start_IT
  221. * Description : DMA Cycle transfer start with interrupt.
  222. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  223. * the configuration information for DMA module
  224. * Input : fu32_SrcAddr: source address
  225. * Input : fu32_DstAddr: desination address
  226. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  227. * Output :
  228. * Author : Chris_Kyle Data : 2020
  229. **********************************************************************************/
  230. HAL_StatusTypeDef HAL_DMA_CycleMode_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  231. {
  232. uint32_t lu32_Channel_Index;
  233. #if (USE_FULL_ASSERT == 1)
  234. /* Check DMA Parameter */
  235. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  236. #endif
  237. /* Get DMA Channel number */
  238. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  239. /* Set source address and desination address */
  240. hdma->Instance->SRC_ADDR = fu32_SrcAddr;
  241. hdma->Instance->DEST_ADDR = fu32_DstAddr;
  242. /* Set Next Link */
  243. hdma->Instance->LLI = (uint32_t)&Cycle_Channel[lu32_Channel_Index];
  244. /* Set Transfer Size */
  245. hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  246. /* The list point to oneself */
  247. Cycle_Channel[lu32_Channel_Index].SrcAddr = fu32_SrcAddr;
  248. Cycle_Channel[lu32_Channel_Index].DstAddr = fu32_DstAddr;
  249. Cycle_Channel[lu32_Channel_Index].Next = &Cycle_Channel[lu32_Channel_Index];
  250. Cycle_Channel[lu32_Channel_Index].Control = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  251. /* DMA Channel Enable and enable transfer error interrupt and transfer complete interrupt*/
  252. hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_ITC | DMA_CHANNEL_CONFIG_IE | DMA_CHANNEL_CONFIG_EN;
  253. return HAL_OK;
  254. }
  255. /*********************************************************************************
  256. * Function : HAL_DMA_Start
  257. * Description : DMA transfer start.
  258. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  259. * the configuration information for DMA module
  260. * Input : fu32_SrcAddr: source address
  261. * Input : fu32_DstAddr: desination address
  262. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  263. * Output :
  264. * Author : Chris_Kyle Data : 2020
  265. **********************************************************************************/
  266. HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  267. {
  268. /* Check DMA Parameter */
  269. if (!IS_DMA_MODE(hdma->Init.Mode)) return HAL_ERROR;
  270. if (hdma->Init.Mode == DMA_NORMAL)
  271. {
  272. return HAL_DMA_NormalMode_Start(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  273. }
  274. else
  275. {
  276. return HAL_DMA_CycleMode_Start(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  277. }
  278. }
  279. /*********************************************************************************
  280. * Function : HAL_DMA_Start_IT
  281. * Description : DMA transfer start with interrupt.
  282. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  283. * the configuration information for DMA module
  284. * Input : fu32_SrcAddr: source address
  285. * Input : fu32_DstAddr: desination address
  286. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  287. * Output :
  288. * Author : Chris_Kyle Data : 2020
  289. **********************************************************************************/
  290. HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  291. {
  292. /* Check DMA Parameter */
  293. if (!IS_DMA_MODE(hdma->Init.Mode)) return HAL_ERROR;
  294. if (hdma->Init.Mode == DMA_NORMAL)
  295. {
  296. return HAL_DMA_NormalMode_Start_IT(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  297. }
  298. else
  299. {
  300. return HAL_DMA_CycleMode_Start_IT(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  301. }
  302. }
  303. /*********************************************************************************
  304. * Function : HAL_DMA_Abort
  305. * Description : Abort the DMA Transfer
  306. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  307. * the configuration information for DMA module
  308. * Output :
  309. * Author : Chris_Kyle Data : 2020
  310. **********************************************************************************/
  311. HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
  312. {
  313. uint32_t lu32_Channel_Index;
  314. #if (USE_FULL_ASSERT == 1)
  315. /* Check DMA Parameter */
  316. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  317. #endif
  318. /* Get DMA Channel number */
  319. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  320. /* DMA Channel Disable */
  321. hdma->Instance->CONFIG &= ~(1 << 0);
  322. /* Clear TC ERR Falg */
  323. DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
  324. DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
  325. return HAL_OK;
  326. }
  327. /*********************************************************************************
  328. * Function : HAL_DMA_GetState
  329. * Description : Returns the DMA state..
  330. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  331. * the configuration information for DMA module
  332. * Output :
  333. * Author : Data : 2021
  334. **********************************************************************************/
  335. HAL_StatusTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
  336. {
  337. uint32_t lu32_Channel_Index;
  338. HAL_StatusTypeDef States = HAL_ERROR;
  339. /* Get DMA Channel number */
  340. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  341. /* Transfer complete interrupt */
  342. if (DMA->RAW_INT_TC_STATUS & (1 << lu32_Channel_Index))
  343. {
  344. DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
  345. States = HAL_OK;
  346. }
  347. /* Transfer error interrupt */
  348. if (DMA->RAW_INT_ERR_STATUS & (1 << lu32_Channel_Index))
  349. {
  350. DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
  351. States = HAL_ERROR;
  352. }
  353. return States;
  354. }