HAL_DMA.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  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. /* DMA Channel Enable and enable transfer error interrupt and transfer complete interrupt*/
  179. hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_ITC | DMA_CHANNEL_CONFIG_IE | DMA_CHANNEL_CONFIG_EN;
  180. return HAL_OK;
  181. }
  182. /*********************************************************************************
  183. * Function : HAL_DMA_CycleMode_Start
  184. * Description : DMA Cycle transfer start.
  185. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  186. * the configuration information for DMA module
  187. * Input : fu32_SrcAddr: source address
  188. * Input : fu32_DstAddr: desination address
  189. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  190. * Output :
  191. * Author : Chris_Kyle Data : 2020
  192. **********************************************************************************/
  193. HAL_StatusTypeDef HAL_DMA_CycleMode_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  194. {
  195. uint32_t lu32_Channel_Index;
  196. #if (USE_FULL_ASSERT == 1)
  197. /* Check DMA Parameter */
  198. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  199. #endif
  200. /* Get DMA Channel number */
  201. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  202. /* Set source address and desination address */
  203. hdma->Instance->SRC_ADDR = fu32_SrcAddr;
  204. hdma->Instance->DEST_ADDR = fu32_DstAddr;
  205. /* Set Next Link */
  206. hdma->Instance->LLI = (uint32_t)&Cycle_Channel[lu32_Channel_Index];
  207. /* Set Transfer Size */
  208. hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  209. /* The list point to oneself */
  210. Cycle_Channel[lu32_Channel_Index].SrcAddr = fu32_SrcAddr;
  211. Cycle_Channel[lu32_Channel_Index].DstAddr = fu32_DstAddr;
  212. Cycle_Channel[lu32_Channel_Index].Next = &Cycle_Channel[lu32_Channel_Index];
  213. Cycle_Channel[lu32_Channel_Index].Control = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  214. /* DMA Channel Enable */
  215. hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_EN;
  216. return HAL_OK;
  217. }
  218. /*********************************************************************************
  219. * Function : HAL_DMA_CycleMode_Start_IT
  220. * Description : DMA Cycle transfer start with interrupt.
  221. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  222. * the configuration information for DMA module
  223. * Input : fu32_SrcAddr: source address
  224. * Input : fu32_DstAddr: desination address
  225. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  226. * Output :
  227. * Author : Chris_Kyle Data : 2020
  228. **********************************************************************************/
  229. HAL_StatusTypeDef HAL_DMA_CycleMode_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  230. {
  231. uint32_t lu32_Channel_Index;
  232. #if (USE_FULL_ASSERT == 1)
  233. /* Check DMA Parameter */
  234. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  235. #endif
  236. /* Get DMA Channel number */
  237. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  238. /* Set source address and desination address */
  239. hdma->Instance->SRC_ADDR = fu32_SrcAddr;
  240. hdma->Instance->DEST_ADDR = fu32_DstAddr;
  241. /* Set Next Link */
  242. hdma->Instance->LLI = (uint32_t)&Cycle_Channel[lu32_Channel_Index];
  243. /* Set Transfer Size */
  244. hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  245. /* The list point to oneself */
  246. Cycle_Channel[lu32_Channel_Index].SrcAddr = fu32_SrcAddr;
  247. Cycle_Channel[lu32_Channel_Index].DstAddr = fu32_DstAddr;
  248. Cycle_Channel[lu32_Channel_Index].Next = &Cycle_Channel[lu32_Channel_Index];
  249. Cycle_Channel[lu32_Channel_Index].Control = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
  250. /* DMA Channel Enable and enable transfer error interrupt and transfer complete interrupt*/
  251. hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_ITC | DMA_CHANNEL_CONFIG_IE | DMA_CHANNEL_CONFIG_EN;
  252. return HAL_OK;
  253. }
  254. /*********************************************************************************
  255. * Function : HAL_DMA_Start
  256. * Description : DMA transfer start.
  257. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  258. * the configuration information for DMA module
  259. * Input : fu32_SrcAddr: source address
  260. * Input : fu32_DstAddr: desination address
  261. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  262. * Output :
  263. * Author : Chris_Kyle Data : 2020
  264. **********************************************************************************/
  265. HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  266. {
  267. /* Check DMA Parameter */
  268. if (!IS_DMA_MODE(hdma->Init.Mode)) return HAL_ERROR;
  269. if (hdma->Init.Mode == DMA_NORMAL)
  270. {
  271. return HAL_DMA_NormalMode_Start(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  272. }
  273. else
  274. {
  275. return HAL_DMA_CycleMode_Start(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  276. }
  277. }
  278. /*********************************************************************************
  279. * Function : HAL_DMA_Start_IT
  280. * Description : DMA transfer start with interrupt.
  281. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  282. * the configuration information for DMA module
  283. * Input : fu32_SrcAddr: source address
  284. * Input : fu32_DstAddr: desination address
  285. * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
  286. * Output :
  287. * Author : Chris_Kyle Data : 2020
  288. **********************************************************************************/
  289. HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
  290. {
  291. /* Check DMA Parameter */
  292. if (!IS_DMA_MODE(hdma->Init.Mode)) return HAL_ERROR;
  293. if (hdma->Init.Mode == DMA_NORMAL)
  294. {
  295. return HAL_DMA_NormalMode_Start_IT(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  296. }
  297. else
  298. {
  299. return HAL_DMA_CycleMode_Start_IT(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
  300. }
  301. }
  302. /*********************************************************************************
  303. * Function : HAL_DMA_Abort
  304. * Description : Abort the DMA Transfer
  305. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  306. * the configuration information for DMA module
  307. * Output :
  308. * Author : Chris_Kyle Data : 2020
  309. **********************************************************************************/
  310. HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
  311. {
  312. uint32_t lu32_Channel_Index;
  313. #if (USE_FULL_ASSERT == 1)
  314. /* Check DMA Parameter */
  315. if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
  316. #endif
  317. /* Get DMA Channel number */
  318. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  319. /* DMA Channel Disable */
  320. hdma->Instance->CONFIG &= ~(1 << 0);
  321. /* Clear TC ERR Falg */
  322. DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
  323. DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
  324. return HAL_OK;
  325. }
  326. /*********************************************************************************
  327. * Function : HAL_DMA_GetState
  328. * Description : Returns the DMA state..
  329. * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
  330. * the configuration information for DMA module
  331. * Output :
  332. * Author : Data : 2021
  333. **********************************************************************************/
  334. HAL_StatusTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
  335. {
  336. uint32_t lu32_Channel_Index;
  337. HAL_StatusTypeDef States = HAL_ERROR;
  338. /* Get DMA Channel number */
  339. lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
  340. /* Transfer complete interrupt */
  341. if (DMA->RAW_INT_TC_STATUS & (1 << lu32_Channel_Index))
  342. {
  343. DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
  344. States = HAL_OK;
  345. }
  346. /* Transfer error interrupt */
  347. if (DMA->RAW_INT_ERR_STATUS & (1 << lu32_Channel_Index))
  348. {
  349. DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
  350. States = HAL_ERROR;
  351. }
  352. return States;
  353. }