?? stm32l1xx_dma.c
字號:
/**
******************************************************************************
* @file stm32l1xx_dma.c
* @author MCD Application Team
* @version V1.1.0
* @date 24-January-2012
* @brief This file provides firmware functions to manage the following
* functionalities of the Direct Memory Access controller (DMA):
* + Initialization and Configuration
* + Data Counter
* + Interrupts and flags management
*
* @verbatim
==============================================================================
##### How to use this driver #####
==============================================================================
[..]
(#) Enable The DMA controller clock using
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE) function for DMA1 or
using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE) function for DMA2.
(#) Enable and configure the peripheral to be connected to the DMA channel
(except for internal SRAM / FLASH memories: no initialization is
necessary).
(#) For a given Channel, program the Source and Destination addresses,
the transfer Direction, the Buffer Size, the Peripheral and Memory
Incrementation mode and Data Size, the Circular or Normal mode,
the channel transfer Priority and the Memory-to-Memory transfer
mode (if needed) using the DMA_Init() function.
(#) Enable the NVIC and the corresponding interrupt(s) using the function
DMA_ITConfig() if you need to use DMA interrupts.
(#) Enable the DMA channel using the DMA_Cmd() function.
(#) Activate the needed channel Request using PPP_DMACmd() function for
any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...)
The function allowing this operation is provided in each PPP peripheral
driver (ie. SPI_DMACmd for SPI peripheral).
(#) Optionally, you can configure the number of data to be transferred
when the channel is disabled (ie. after each Transfer Complete event
or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter().
And you can get the number of remaining data to be transferred using
the function DMA_GetCurrDataCounter() at run time (when the DMA channel is
enabled and running).
(#) To control DMA events you can use one of the following two methods:
(##) Check on DMA channel flags using the function DMA_GetFlagStatus().
(##) Use DMA interrupts through the function DMA_ITConfig() at initialization
phase and DMA_GetITStatus() function into interrupt routines in
communication phase.
After checking on a flag you should clear it using DMA_ClearFlag()
function. And after checking on an interrupt event you should
clear it using DMA_ClearITPendingBit() function.
@endverbatim
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* FOR MORE INFORMATION PLEASE READ CAREFULLY THE LICENSE AGREEMENT FILE
* LOCATED IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*
* <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l1xx_dma.h"
#include "stm32l1xx_rcc.h"
/** @addtogroup STM32L1xx_StdPeriph_Driver
* @{
*/
/** @defgroup DMA
* @brief DMA driver modules
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* DMA1 Channelx interrupt pending bit masks */
#define DMA1_CHANNEL1_IT_MASK ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1))
#define DMA1_CHANNEL2_IT_MASK ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2))
#define DMA1_CHANNEL3_IT_MASK ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3))
#define DMA1_CHANNEL4_IT_MASK ((uint32_t)(DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4))
#define DMA1_CHANNEL5_IT_MASK ((uint32_t)(DMA_ISR_GIF5 | DMA_ISR_TCIF5 | DMA_ISR_HTIF5 | DMA_ISR_TEIF5))
#define DMA1_CHANNEL6_IT_MASK ((uint32_t)(DMA_ISR_GIF6 | DMA_ISR_TCIF6 | DMA_ISR_HTIF6 | DMA_ISR_TEIF6))
#define DMA1_CHANNEL7_IT_MASK ((uint32_t)(DMA_ISR_GIF7 | DMA_ISR_TCIF7 | DMA_ISR_HTIF7 | DMA_ISR_TEIF7))
/* DMA2 Channelx interrupt pending bit masks */
#define DMA2_CHANNEL1_IT_MASK ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1))
#define DMA2_CHANNEL2_IT_MASK ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2))
#define DMA2_CHANNEL3_IT_MASK ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3))
#define DMA2_CHANNEL4_IT_MASK ((uint32_t)(DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4))
#define DMA2_CHANNEL5_IT_MASK ((uint32_t)(DMA_ISR_GIF5 | DMA_ISR_TCIF5 | DMA_ISR_HTIF5 | DMA_ISR_TEIF5))
/* DMA FLAG mask */
#define FLAG_MASK ((uint32_t)0x10000000)
/* DMA registers Masks */
#define CCR_CLEAR_MASK ((uint32_t)0xFFFF800F)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup DMA_Private_Functions
* @{
*/
/** @defgroup DMA_Group1 Initialization and Configuration functions
* @brief Initialization and Configuration functions
*
@verbatim
===============================================================================
##### Initialization and Configuration functions #####
===============================================================================
[..] This subsection provides functions allowing to initialize the DMA channel
source and destination addresses, incrementation and data sizes, transfer
direction, buffer size, circular/normal mode selection, memory-to-memory
mode selection and channel priority value.
[..] The DMA_Init() function follows the DMA configuration procedures as described
in reference manual (RM0038).
@endverbatim
* @{
*/
/**
* @brief Deinitializes the DMAy Channelx registers to their default reset
* values.
* @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
* @retval None
*/
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx)
{
/* Check the parameters */
assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
/* Disable the selected DMAy Channelx */
DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR1_EN);
/* Reset DMAy Channelx control register */
DMAy_Channelx->CCR = 0;
/* Reset DMAy Channelx remaining bytes register */
DMAy_Channelx->CNDTR = 0;
/* Reset DMAy Channelx peripheral address register */
DMAy_Channelx->CPAR = 0;
/* Reset DMAy Channelx memory address register */
DMAy_Channelx->CMAR = 0;
if (DMAy_Channelx == DMA1_Channel1)
{
/* Reset interrupt pending bits for DMA1 Channel1 */
DMA1->IFCR |= DMA1_CHANNEL1_IT_MASK;
}
else if (DMAy_Channelx == DMA1_Channel2)
{
/* Reset interrupt pending bits for DMA1 Channel2 */
DMA1->IFCR |= DMA1_CHANNEL2_IT_MASK;
}
else if (DMAy_Channelx == DMA1_Channel3)
{
/* Reset interrupt pending bits for DMA1 Channel3 */
DMA1->IFCR |= DMA1_CHANNEL3_IT_MASK;
}
else if (DMAy_Channelx == DMA1_Channel4)
{
/* Reset interrupt pending bits for DMA1 Channel4 */
DMA1->IFCR |= DMA1_CHANNEL4_IT_MASK;
}
else if (DMAy_Channelx == DMA1_Channel5)
{
/* Reset interrupt pending bits for DMA1 Channel5 */
DMA1->IFCR |= DMA1_CHANNEL5_IT_MASK;
}
else if (DMAy_Channelx == DMA1_Channel6)
{
/* Reset interrupt pending bits for DMA1 Channel6 */
DMA1->IFCR |= DMA1_CHANNEL6_IT_MASK;
}
else if (DMAy_Channelx == DMA1_Channel7)
{
/* Reset interrupt pending bits for DMA1 Channel7 */
DMA1->IFCR |= DMA1_CHANNEL7_IT_MASK;
}
else if (DMAy_Channelx == DMA2_Channel1)
{
/* Reset interrupt pending bits for DMA2 Channel1 */
DMA2->IFCR |= DMA2_CHANNEL1_IT_MASK;
}
else if (DMAy_Channelx == DMA2_Channel2)
{
/* Reset interrupt pending bits for DMA2 Channel2 */
DMA2->IFCR |= DMA2_CHANNEL2_IT_MASK;
}
else if (DMAy_Channelx == DMA2_Channel3)
{
/* Reset interrupt pending bits for DMA2 Channel3 */
DMA2->IFCR |= DMA2_CHANNEL3_IT_MASK;
}
else if (DMAy_Channelx == DMA2_Channel4)
{
/* Reset interrupt pending bits for DMA2 Channel4 */
DMA2->IFCR |= DMA2_CHANNEL4_IT_MASK;
}
else
{
if (DMAy_Channelx == DMA2_Channel5)
{
/* Reset interrupt pending bits for DMA2 Channel5 */
DMA2->IFCR |= DMA2_CHANNEL5_IT_MASK;
}
}
}
/**
* @brief Initializes the DMAy Channelx according to the specified
* parameters in the DMA_InitStruct.
* @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
* @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that
* contains the configuration information for the specified DMA Channel.
* @retval None
*/
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR));
assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize));
assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc));
assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc));
assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize));
assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize));
assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode));
assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));
assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M));
/*--------------------------- DMAy Channelx CCR Configuration -----------------*/
/* Get the DMAy_Channelx CCR value */
tmpreg = DMAy_Channelx->CCR;
/* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
tmpreg &= CCR_CLEAR_MASK;
/* Configure DMAy Channelx: data transfer, data size, priority level and mode */
/* Set DIR bit according to DMA_DIR value */
/* Set CIRC bit according to DMA_Mode value */
/* Set PINC bit according to DMA_PeripheralInc value */
/* Set MINC bit according to DMA_MemoryInc value */
/* Set PSIZE bits according to DMA_PeripheralDataSize value */
/* Set MSIZE bits according to DMA_MemoryDataSize value */
/* Set PL bits according to DMA_Priority value */
/* Set the MEM2MEM bit according to DMA_M2M value */
tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |
DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;
/* Write to DMAy Channelx CCR */
DMAy_Channelx->CCR = tmpreg;
/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/
/* Write to DMAy Channelx CNDTR */
DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;
/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/
/* Write to DMAy Channelx CPAR */
DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;
/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/
/* Write to DMAy Channelx CMAR */
DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;
}
/**
* @brief Fills each DMA_InitStruct member with its default value.
* @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure which will
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -