|
STM32G474xx HAL用户手册
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32g4xx_hal_dma.c 00004 * @author MCD Application Team 00005 * @brief DMA HAL模块驱动程序。 00006 * 本文件提供固件功能以管理直接内存访问(DMA)外设的以下功能: 00007 * + 初始化和反初始化函数 00008 * + IO操作函数 00009 * + 外设状态和错误函数 00010 * 00011 ****************************************************************************** 00012 * @attention 00013 * 00014 * Copyright (c) 2019 STMicroelectronics. 00015 * All rights reserved. 00016 * 00017 * This software is licensed under terms that can be found in the LICENSE file 00018 * in the root directory of this software component. 00019 * If no LICENSE file comes with this software, it is provided AS-IS. 00020 * 00021 ****************************************************************************** 00022 @verbatim 00023 ============================================================================== 00024 ##### 如何使用此驱动程序 ##### 00025 ============================================================================== 00026 [..] 00027 (#) 启用并配置要连接到DMA通道的外设 00028 (内部SRAM/FLASH存储器除外:无需初始化)。 00029 请参阅参考手册中外设与DMA请求之间的连接。 00030 00031 (#) 对于给定通道,通过以下参数编程所需配置: 00032 通道请求、传输方向、源和目标数据格式、 00033 循环或正常模式、通道优先级、源和目标递增模式 00034 使用HAL_DMA_Init()函数。 00035 00036 在HAL_DMA_Init之前,应为DMA和DMAMUX启用外设时钟: 00037 (##) DMA1或DMA2: __HAL_RCC_DMA1_CLK_ENABLE()或 __HAL_RCC_DMA2_CLK_ENABLE(); 00038 (##) DMAMUX1: __HAL_RCC_DMAMUX1_CLK_ENABLE(); 00039 00040 (#) 使用HAL_DMA_GetState()函数返回DMA状态,并在发生错误时使用HAL_DMA_GetError()进行错误检测。 00041 00042 (#) 使用HAL_DMA_Abort()函数中止当前传输 00043 00044 -@- 在内存到内存传输模式下,不允许使用循环模式。 00045 00046 *** 轮询模式IO操作 *** 00047 ================================= 00048 [..] 00049 (+) 使用HAL_DMA_Start()在配置源地址、目标地址和要传输的数据长度后启动DMA传输 00050 (+) 使用HAL_DMA_PollForTransfer()轮询当前传输的结束,在这种情况下 00051 用户可以根据其应用配置固定的超时时间。 00052 00053 *** 中断模式IO操作 *** 00054 =================================== 00055 [..] 00056 (+) 使用HAL_NVIC_SetPriority()配置DMA中断优先级 00057 (+) 使用HAL_NVIC_EnableIRQ()启用DMA IRQ处理程序 00058 (+) 使用HAL_DMA_Start_IT()在配置源地址、目标地址和要传输的数据长度后启动DMA传输。 00059 在这种情况下,DMA中断已被配置 00060 (+) 在DMA_IRQHandler()中断子程序中调用HAL_DMA_IRQHandler() 00061 (+) 在数据传输结束时执行HAL_DMA_IRQHandler()函数,用户可以通过HAL_DMA_RegisterCallback()注册自己的回调函数。 00062 00063 *** DMA HAL驱动程序宏列表 *** 00064 ============================================= 00065 [..] 00066 以下是DMA HAL驱动程序中的宏列表。 00067 00068 (+) __HAL_DMA_ENABLE:启用指定的DMA通道。 00069 (+) __HAL_DMA_DISABLE:禁用指定的DMA通道。 00070 (+) __HAL_DMA_GET_FLAG:获取DMA通道待处理标志。 00071 (+) __HAL_DMA_CLEAR_FLAG:清除DMA通道待处理标志。 00072 (+) __HAL_DMA_ENABLE_IT:启用指定的DMA通道中断。 00073 (+) __HAL_DMA_DISABLE_IT:禁用指定的DMA通道中断。 00074 (+) __HAL_DMA_GET_IT_SOURCE:检查指定的DMA通道中断是否已发生。 00075 00076 [..] 00077 (@) 您可以参阅DMA HAL驱动程序头文件以获取更多有用的宏 00078 00079 @endverbatim 00080 */ 00081 00082 /* Includes ------------------------------------------------------------------*/ 00083 #include "stm32g4xx_hal.h" 00084 00085 /** @addtogroup STM32G4xx_HAL_Driver 00086 * @{ 00087 */ 00088 00089 /** @defgroup DMA DMA 00090 * @brief DMA HAL模块驱动程序 00091 * @{ 00092 */ 00093 00094 #ifdef HAL_DMA_MODULE_ENABLED 00095 00096 /* Private typedef -----------------------------------------------------------*/ 00097 /* Private define ------------------------------------------------------------*/ 00098 /* Private macro -------------------------------------------------------------*/ 00099 /* Private variables ---------------------------------------------------------*/ 00100 /* Private function prototypes -----------------------------------------------*/ 00101 /** @defgroup DMA_Private_Functions DMA私有函数 00102 * @{ 00103 */ 00104 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); 00105 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma); 00106 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma); 00107 00108 /** 00109 * @} 00110 */ 00111 00112 /* Exported functions ---------------------------------------------------------*/ 00113 00114 /** @defgroup DMA_Exported_Functions DMA导出函数 00115 * @{ 00116 */ 00117 00118 /** @defgroup DMA_Exported_Functions_Group1 初始化和反初始化函数 00119 * @brief 初始化和反初始化函数 00120 * 00121 @verbatim 00122 =============================================================================== 00123 ##### 初始化和反初始化函数 ##### 00124 =============================================================================== 00125 [..] 00126 本节提供允许初始化DMA通道源和目标地址、递增和数据大小、传输方向、 00127 循环/正常模式选择、内存到内存模式选择以及通道优先级值的函数。 00128 [..] 00129 HAL_DMA_Init()函数遵循参考手册中描述的DMA配置过程。 00130 00131 @endverbatim 00132 * @{ 00133 */ 00134 00135 /** 00136 * @brief 根据DMA_InitTypeDef中的指定参数初始化DMA,并初始化相关的句柄。 00137 * @param hdma 指向DMA_HandleTypeDef结构的指针,该结构包含 00138 * 指定DMA通道的配置信息。 00139 * @retval HAL状态 00140 */ 00141 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) 00142 { 00143 uint32_t tmp; 00144 00145 /* 检查DMA句柄分配 */ 00146 if (hdma == NULL) 00147 { 00148 return HAL_ERROR; 00149 } 00150 00151 /* 检查参数 */ 00152 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 00153 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); 00154 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); 00155 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); 00156 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment)); 00157 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment)); 00158 assert_param(IS_DMA_MODE(hdma->Init.Mode)); 00159 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); 00160 00161 assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request)); 00162 00163 /* 计算通道索引 */ 00164 if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) 00165 { 00166 /* DMA1 */ 00167 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2; 00168 hdma->DmaBaseAddress = DMA1; 00169 } 00170 else 00171 { 00172 /* DMA2 */ 00173 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2; 00174 hdma->DmaBaseAddress = DMA2; 00175 }