123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- /*
- ******************************************************************************
- * @file HAL_DMA.c
- * @version V1.0.0
- * @date 2020
- * @brief DMA HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Direct Memory Access (DMA) peripheral:
- * @ Initialization and de-initialization functions
- * @ IO operation functions
- ******************************************************************************
- */
- #include "ACM32Fxx_HAL.h"
- /**************** Used in cycle mode ****************/
- static DMA_LLI_InitTypeDef Cycle_Channel[DMA_CHANNEL_NUM];
- /*********************************************************************************
- * Function : HAL_DMA_IRQHandler
- * Description : This function handles DMA interrupt request.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- __weak void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
- {
- uint32_t lu32_Channel_Index;
-
- /* Get DMA Channel number */
- lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
- /* Channel has been interrupted */
- if (DMA->INT_STATUS & (1 << lu32_Channel_Index))
- {
- /* Transfer complete interrupt */
- if (DMA->INT_TC_STATUS & (1 << lu32_Channel_Index))
- {
- DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
- if (NULL != hdma->DMA_ITC_Callback)
- {
- hdma->DMA_ITC_Callback();
- }
- }
-
- /* Transfer error interrupt */
- if (DMA->INT_ERR_STATUS & (1 << lu32_Channel_Index))
- {
- DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
- if (NULL != hdma->DMA_IE_Callback)
- {
- hdma->DMA_IE_Callback();
- }
- }
- }
- }
- /*********************************************************************************
- * Function : HAL_DMA_Init
- * Description : DMA initial with parameters.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
- {
- #if (USE_FULL_ASSERT == 1)
- /* Check DMA Parameter */
- if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
- if (!IS_DMA_DATA_FLOW(hdma->Init.Data_Flow)) return HAL_ERROR;
- if (!IS_DMA_REQUEST_ID(hdma->Init.Request_ID)) return HAL_ERROR;
- if (!IS_DMA_SRC_WIDTH(hdma->Init.Source_Width)) return HAL_ERROR;
- if (!IS_DMA_DST_WIDTH(hdma->Init.Desination_Width)) return HAL_ERROR;
- #endif
- /* Enable DMA Module */
- System_Module_Enable(EN_DMA);
-
- /* Enable External Interrupt */
- NVIC_ClearPendingIRQ(DMA_IRQn);
- NVIC_EnableIRQ(DMA_IRQn);
- /* Default Little-Endian、Enable DMA */
- DMA->CONFIG = DMA_CONFIG_EN;
- /* Clear Channel Config */
- hdma->Instance->CONFIG = 0x00000000;
-
- if (hdma->Init.Data_Flow == DMA_DATA_FLOW_M2P)
- {
- hdma->Init.Request_ID <<= DMA_CHANNEL_CONFIG_DEST_PERIPH_POS;
- }
- else if (hdma->Init.Data_Flow == DMA_DATA_FLOW_P2M)
- {
- hdma->Init.Request_ID <<= DMA_CHANNEL_CONFIG_SRC_PERIPH_POS;
- }
- hdma->Instance->CONFIG = hdma->Init.Data_Flow | hdma->Init.Request_ID;
-
- /* Config Channel Control */
- hdma->Instance->CTRL = DMA_CHANNEL_CTRL_ITC;
- /* Source or Desination address increase */
- hdma->Instance->CTRL |= (hdma->Init.Desination_Inc | hdma->Init.Source_Inc);
- /* Source or Desination date width */
- hdma->Instance->CTRL |= (hdma->Init.Desination_Width | hdma->Init.Source_Width);
- return HAL_OK;
- }
- /*********************************************************************************
- * Function : HAL_DMA_DeInit
- * Description : DMA De-initial with parameters.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
- {
- #if (USE_FULL_ASSERT == 1)
- /* Check DMA Parameter */
- if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
- if (!IS_DMA_DATA_FLOW(hdma->Init.Data_Flow)) return HAL_ERROR;
- if (!IS_DMA_REQUEST_ID(hdma->Init.Request_ID)) return HAL_ERROR;
- if (!IS_DMA_SRC_WIDTH(hdma->Init.Source_Width)) return HAL_ERROR;
- if (!IS_DMA_DST_WIDTH(hdma->Init.Desination_Width)) return HAL_ERROR;
- #endif
- /* Reset DMA Module */
- System_Module_Reset(RST_DMA);
-
- /* Disable DMA Module */
- System_Module_Disable(EN_DMA);
-
- /* Disable Interrupt */
- NVIC_ClearPendingIRQ(DMA_IRQn);
- NVIC_DisableIRQ(DMA_IRQn);
-
- hdma->DMA_IE_Callback = NULL;
- hdma->DMA_ITC_Callback = NULL;
- memset(&hdma->Init, 0, sizeof(hdma->Init));
-
- return HAL_OK;
- }
- /*********************************************************************************
- * Function : HAL_DMA_NormalMode_Start
- * Description : DMA transfer start.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Input : fu32_SrcAddr: source address
- * Input : fu32_DstAddr: desination address
- * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_NormalMode_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
- {
- #if (USE_FULL_ASSERT == 1)
- /* Check DMA Parameter */
- if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
- #endif
-
- if (fu32_Size > 0xFFF)
- {
- return HAL_ERROR;
- }
- /* Set source address and desination address */
- hdma->Instance->SRC_ADDR = fu32_SrcAddr;
- hdma->Instance->DEST_ADDR = fu32_DstAddr;
- /* Set Transfer Size */
- hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
- /* DMA Channel Enable */
- hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_EN;
- return HAL_OK;
- }
- /*********************************************************************************
- * Function : HAL_DMA_NormalMode_Start_IT
- * Description : DMA transfer start with interrupt.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Input : fu32_SrcAddr: source address
- * Input : fu32_DstAddr: desination address
- * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_NormalMode_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
- {
- #if (USE_FULL_ASSERT == 1)
- /* Check DMA Parameter */
- if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
- #endif
- /* Set source address and desination address */
- hdma->Instance->SRC_ADDR = fu32_SrcAddr;
- hdma->Instance->DEST_ADDR = fu32_DstAddr;
- /* Set Transfer Size and enable LLI interrupt */
- hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
- /* DMA Channel Enable and enable transfer error interrupt and transfer complete interrupt*/
- hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_ITC | DMA_CHANNEL_CONFIG_IE | DMA_CHANNEL_CONFIG_EN;
- return HAL_OK;
- }
- /*********************************************************************************
- * Function : HAL_DMA_CycleMode_Start
- * Description : DMA Cycle transfer start.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Input : fu32_SrcAddr: source address
- * Input : fu32_DstAddr: desination address
- * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_CycleMode_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
- {
- uint32_t lu32_Channel_Index;
- #if (USE_FULL_ASSERT == 1)
- /* Check DMA Parameter */
- if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
- #endif
- /* Get DMA Channel number */
- lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
-
- /* Set source address and desination address */
- hdma->Instance->SRC_ADDR = fu32_SrcAddr;
- hdma->Instance->DEST_ADDR = fu32_DstAddr;
- /* Set Next Link */
- hdma->Instance->LLI = (uint32_t)&Cycle_Channel[lu32_Channel_Index];
- /* Set Transfer Size */
- hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
- /* The list point to oneself */
- Cycle_Channel[lu32_Channel_Index].SrcAddr = fu32_SrcAddr;
- Cycle_Channel[lu32_Channel_Index].DstAddr = fu32_DstAddr;
- Cycle_Channel[lu32_Channel_Index].Next = &Cycle_Channel[lu32_Channel_Index];
- Cycle_Channel[lu32_Channel_Index].Control = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
- /* DMA Channel Enable */
- hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_EN;
- return HAL_OK;
- }
- /*********************************************************************************
- * Function : HAL_DMA_CycleMode_Start_IT
- * Description : DMA Cycle transfer start with interrupt.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Input : fu32_SrcAddr: source address
- * Input : fu32_DstAddr: desination address
- * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_CycleMode_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
- {
- uint32_t lu32_Channel_Index;
- #if (USE_FULL_ASSERT == 1)
- /* Check DMA Parameter */
- if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
- #endif
- /* Get DMA Channel number */
- lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
-
- /* Set source address and desination address */
- hdma->Instance->SRC_ADDR = fu32_SrcAddr;
- hdma->Instance->DEST_ADDR = fu32_DstAddr;
- /* Set Next Link */
- hdma->Instance->LLI = (uint32_t)&Cycle_Channel[lu32_Channel_Index];
- /* Set Transfer Size */
- hdma->Instance->CTRL = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
- /* The list point to oneself */
- Cycle_Channel[lu32_Channel_Index].SrcAddr = fu32_SrcAddr;
- Cycle_Channel[lu32_Channel_Index].DstAddr = fu32_DstAddr;
- Cycle_Channel[lu32_Channel_Index].Next = &Cycle_Channel[lu32_Channel_Index];
- Cycle_Channel[lu32_Channel_Index].Control = (hdma->Instance->CTRL & (~0xFFF)) | fu32_Size;
- /* DMA Channel Enable and enable transfer error interrupt and transfer complete interrupt*/
- hdma->Instance->CONFIG |= DMA_CHANNEL_CONFIG_ITC | DMA_CHANNEL_CONFIG_IE | DMA_CHANNEL_CONFIG_EN;
- return HAL_OK;
- }
- /*********************************************************************************
- * Function : HAL_DMA_Start
- * Description : DMA transfer start.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Input : fu32_SrcAddr: source address
- * Input : fu32_DstAddr: desination address
- * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
- {
- /* Check DMA Parameter */
- if (!IS_DMA_MODE(hdma->Init.Mode)) return HAL_ERROR;
-
- if (hdma->Init.Mode == DMA_NORMAL)
- {
- return HAL_DMA_NormalMode_Start(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
- }
- else
- {
- return HAL_DMA_CycleMode_Start(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
- }
- }
- /*********************************************************************************
- * Function : HAL_DMA_Start_IT
- * Description : DMA transfer start with interrupt.
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Input : fu32_SrcAddr: source address
- * Input : fu32_DstAddr: desination address
- * Input : fu32_Size: transfer size (This parameter can be a 12-bit Size)
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t fu32_SrcAddr, uint32_t fu32_DstAddr, uint32_t fu32_Size)
- {
- /* Check DMA Parameter */
- if (!IS_DMA_MODE(hdma->Init.Mode)) return HAL_ERROR;
- if (hdma->Init.Mode == DMA_NORMAL)
- {
- return HAL_DMA_NormalMode_Start_IT(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
- }
- else
- {
- return HAL_DMA_CycleMode_Start_IT(hdma, fu32_SrcAddr, fu32_DstAddr, fu32_Size);
- }
- }
- /*********************************************************************************
- * Function : HAL_DMA_Abort
- * Description : Abort the DMA Transfer
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Output :
- * Author : Chris_Kyle Data : 2020
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
- {
- uint32_t lu32_Channel_Index;
- #if (USE_FULL_ASSERT == 1)
- /* Check DMA Parameter */
- if (!IS_DMA_ALL_INSTANCE(hdma->Instance)) return HAL_ERROR;
- #endif
- /* Get DMA Channel number */
- lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
- /* DMA Channel Disable */
- hdma->Instance->CONFIG &= ~(1 << 0);
- /* Clear TC ERR Falg */
- DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
- DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
- return HAL_OK;
- }
- /*********************************************************************************
- * Function : HAL_DMA_GetState
- * Description : Returns the DMA state..
- * Input : hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for DMA module
- * Output :
- * Author : Data : 2021
- **********************************************************************************/
- HAL_StatusTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
- {
- uint32_t lu32_Channel_Index;
- HAL_StatusTypeDef States = HAL_ERROR;
-
- /* Get DMA Channel number */
- lu32_Channel_Index = ((uint32_t)(hdma->Instance) - (uint32_t)(DMA_Channel0)) / 0x20;
- /* Transfer complete interrupt */
- if (DMA->RAW_INT_TC_STATUS & (1 << lu32_Channel_Index))
- {
- DMA->INT_TC_CLR |= (1 << lu32_Channel_Index);
- States = HAL_OK;
- }
-
- /* Transfer error interrupt */
- if (DMA->RAW_INT_ERR_STATUS & (1 << lu32_Channel_Index))
- {
- DMA->INT_ERR_CLR |= (1 << lu32_Channel_Index);
- States = HAL_ERROR;
- }
-
- return States;
- }
|