⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stm32f2xx_dma.c

📁 STM32+Grlib
💻 C
📖 第 1 页 / 共 4 页
字号:
/**
  ******************************************************************************
  * @file    stm32f2xx_dma.c
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    18-April-2011
  * @brief   This file provides firmware functions to manage the following 
  *          functionalities of the Direct Memory Access controller (DMA):           
  *           - Initialization and Configuration
  *           - Data Counter
  *           - Double Buffer mode configuration and command  
  *           - Interrupts and flags management
  *           
  *  @verbatim
  *      
  *          ===================================================================      
  *                                 How to use this driver
  *          =================================================================== 
  *          1. Enable The DMA controller clock using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE)
  *             function for DMA1 or using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA2, ENABLE)
  *             function for DMA2.
  *
  *          2. Enable and configure the peripheral to be connected to the DMA Stream
  *             (except for internal SRAM / FLASH memories: no initialization is 
  *             necessary). 
  *        
  *          3. For a given Stream, program the required configuration through following parameters:   
  *             Source and Destination addresses, Transfer Direction, Transfer size, Source and Destination 
  *             data formats, Circular or Normal mode, Stream Priority level, Source and Destination 
  *             Incrementation mode, FIFO mode and its Threshold (if needed), Burst mode for Source and/or 
  *             Destination (if needed) using the DMA_Init() function.
  *             To avoid filling un-nesecessary fields, you can call DMA_StructInit() function
  *             to initialize a given structure with default values (reset values), the modify
  *             only necessary fields (ie. Source and Destination addresses, Transfer size and Data Formats).
  *
  *          4. Enable the NVIC and the corresponding interrupt(s) using the function 
  *             DMA_ITConfig() if you need to use DMA interrupts. 
  *
  *          5. Optionally, if the Circular mode is enabled, you can use the Double buffer mode by configuring 
  *             the second Memory address and the first Memory to be used through the function 
  *             DMA_DoubleBufferModeConfig(). Then enable the Double buffer mode through the function
  *             DMA_DoubleBufferModeCmd(). These operations must be done before step 6.
  *    
  *          6. Enable the DMA stream using the DMA_Cmd() function. 
  *                
  *          7. Activate the needed Stream 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).
  *             Once the Stream is enabled, it is not possible to modify its configuration
  *             unless the stream is stopped and disabled.
  *             After enabling the Stream, it is advised to monitor the EN bit status using
  *             the function DMA_GetCmdStatus(). In case of configuration errors or bus errors
  *             this bit will remain reset and all transfers on this Stream will remain on hold.      
  *
  *          8. Optionally, you can configure the number of data to be transferred
  *             when the Stream 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 Stream is
  *             enabled and running).  
  *                   
  *          9. To control DMA events you can use one of the following 
  *              two methods:
  *               a- Check on DMA Stream flags using the function DMA_GetFlagStatus().  
  *               b- 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.    
  *              
  *          10. Optionally, if Circular mode and Double Buffer mode are enabled, you can modify
  *              the Memory Addresses using the function DMA_MemoryTargetConfig(). Make sure that
  *              the Memory Address to be modified is not the one currently in use by DMA Stream.
  *              This condition can be monitored using the function DMA_GetCurrentMemoryTarget().
  *              
  *          11. Optionally, Pause-Resume operations may be performed:
  *              The DMA_Cmd() function may be used to perform Pause-Resume operation. When a 
  *              transfer is ongoing, calling this function to disable the Stream will cause the 
  *              transfer to be paused. All configuration registers and the number of remaining 
  *              data will be preserved. When calling again this function to re-enable the Stream, 
  *              the transfer will be resumed from the point where it was paused.          
  *                 
  * @note   Memory-to-Memory transfer is possible by setting the address of the memory into
  *         the Peripheral registers. In this mode, Circular mode and Double Buffer mode
  *         are not allowed.
  *  
  * @note   The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
  *         possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
  *         Half-Word data size for the peripheral to access its data register and set Word data size
  *         for the Memory to gain in access time. Each two Half-words will be packed and written in
  *         a single access to a Word in the Memory).
  *    
  * @note  When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
  *        and Destination. In this case the Peripheral Data Size will be applied to both Source
  *        and Destination.               
  *
  *  @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.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************  
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm32f2xx_dma.h"
#include "stm32f2xx_rcc.h"

/** @addtogroup STM32F2xx_StdPeriph_Driver
  * @{
  */

/** @defgroup DMA 
  * @brief DMA driver modules
  * @{
  */ 

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Masks Definition */
#define TRANSFER_IT_ENABLE_MASK (uint32_t)(DMA_SxCR_TCIE | DMA_SxCR_HTIE | \
                                           DMA_SxCR_TEIE | DMA_SxCR_DMEIE)

#define DMA_Stream0_IT_MASK     (uint32_t)(DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 | \
                                           DMA_LISR_TEIF0 | DMA_LISR_HTIF0 | \
                                           DMA_LISR_TCIF0)

#define DMA_Stream1_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK << 6)
#define DMA_Stream2_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK << 16)
#define DMA_Stream3_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK << 22)
#define DMA_Stream4_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK | (uint32_t)0x20000000)
#define DMA_Stream5_IT_MASK     (uint32_t)(DMA_Stream1_IT_MASK | (uint32_t)0x20000000)
#define DMA_Stream6_IT_MASK     (uint32_t)(DMA_Stream2_IT_MASK | (uint32_t)0x20000000)
#define DMA_Stream7_IT_MASK     (uint32_t)(DMA_Stream3_IT_MASK | (uint32_t)0x20000000)
#define TRANSFER_IT_MASK        (uint32_t)0x0F3C0F3C
#define HIGH_ISR_MASK           (uint32_t)0x20000000
#define RESERVED_MASK           (uint32_t)0x0F7D0F7D  

/* 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 Stream source
  and destination addresses, incrementation and data sizes, transfer direction, 
  buffer size, circular/normal mode selection, memory-to-memory mode selection 
  and Stream priority value.
  
  The DMA_Init() function follows the DMA configuration procedures as described in
  reference manual (RM0033) except the first point: waiting on EN bit to be reset.
  This condition should be checked by user application using the function DMA_GetCmdStatus()
  before calling the DMA_Init() function.

@endverbatim
  * @{
  */

/**
  * @brief  Deinitialize the DMAy Streamx registers to their default reset values.
  * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
  *         to 7 to select the DMA Stream.
  * @retval None
  */
void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx)
{
  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));

  /* Disable the selected DMAy Streamx */
  DMAy_Streamx->CR &= ~((uint32_t)DMA_SxCR_EN);

  /* Reset DMAy Streamx control register */
  DMAy_Streamx->CR  = 0;
  
  /* Reset DMAy Streamx Number of Data to Transfer register */
  DMAy_Streamx->NDTR = 0;
  
  /* Reset DMAy Streamx peripheral address register */
  DMAy_Streamx->PAR  = 0;
  
  /* Reset DMAy Streamx memory 0 address register */
  DMAy_Streamx->M0AR = 0;

  /* Reset DMAy Streamx memory 1 address register */
  DMAy_Streamx->M1AR = 0;

  /* Reset DMAy Streamx FIFO control register */
  DMAy_Streamx->FCR = (uint32_t)0x00000021; 

  /* Reset interrupt pending bits for the selected stream */
  if (DMAy_Streamx == DMA1_Stream0)
  {
    /* Reset interrupt pending bits for DMA1 Stream0 */
    DMA1->LIFCR = DMA_Stream0_IT_MASK;
  }
  else if (DMAy_Streamx == DMA1_Stream1)
  {
    /* Reset interrupt pending bits for DMA1 Stream1 */
    DMA1->LIFCR = DMA_Stream1_IT_MASK;
  }
  else if (DMAy_Streamx == DMA1_Stream2)
  {
    /* Reset interrupt pending bits for DMA1 Stream2 */
    DMA1->LIFCR = DMA_Stream2_IT_MASK;
  }
  else if (DMAy_Streamx == DMA1_Stream3)
  {
    /* Reset interrupt pending bits for DMA1 Stream3 */
    DMA1->LIFCR = DMA_Stream3_IT_MASK;
  }
  else if (DMAy_Streamx == DMA1_Stream4)
  {
    /* Reset interrupt pending bits for DMA1 Stream4 */
    DMA1->HIFCR = DMA_Stream4_IT_MASK;
  }
  else if (DMAy_Streamx == DMA1_Stream5)
  {
    /* Reset interrupt pending bits for DMA1 Stream5 */
    DMA1->HIFCR = DMA_Stream5_IT_MASK;
  }
  else if (DMAy_Streamx == DMA1_Stream6)
  {
    /* Reset interrupt pending bits for DMA1 Stream6 */
    DMA1->HIFCR = (uint32_t)DMA_Stream6_IT_MASK;
  }
  else if (DMAy_Streamx == DMA1_Stream7)
  {
    /* Reset interrupt pending bits for DMA1 Stream7 */
    DMA1->HIFCR = DMA_Stream7_IT_MASK;
  }
  else if (DMAy_Streamx == DMA2_Stream0)
  {
    /* Reset interrupt pending bits for DMA2 Stream0 */
    DMA2->LIFCR = DMA_Stream0_IT_MASK;
  }
  else if (DMAy_Streamx == DMA2_Stream1)
  {
    /* Reset interrupt pending bits for DMA2 Stream1 */
    DMA2->LIFCR = DMA_Stream1_IT_MASK;
  }
  else if (DMAy_Streamx == DMA2_Stream2)
  {
    /* Reset interrupt pending bits for DMA2 Stream2 */
    DMA2->LIFCR = DMA_Stream2_IT_MASK;
  }
  else if (DMAy_Streamx == DMA2_Stream3)
  {
    /* Reset interrupt pending bits for DMA2 Stream3 */
    DMA2->LIFCR = DMA_Stream3_IT_MASK;
  }
  else if (DMAy_Streamx == DMA2_Stream4)
  {
    /* Reset interrupt pending bits for DMA2 Stream4 */
    DMA2->HIFCR = DMA_Stream4_IT_MASK;
  }
  else if (DMAy_Streamx == DMA2_Stream5)
  {
    /* Reset interrupt pending bits for DMA2 Stream5 */
    DMA2->HIFCR = DMA_Stream5_IT_MASK;
  }
  else if (DMAy_Streamx == DMA2_Stream6)
  {
    /* Reset interrupt pending bits for DMA2 Stream6 */
    DMA2->HIFCR = DMA_Stream6_IT_MASK;
  }
  else 
  {
    if (DMAy_Streamx == DMA2_Stream7)
    {
      /* Reset interrupt pending bits for DMA2 Stream7 */
      DMA2->HIFCR = DMA_Stream7_IT_MASK;
    }
  }
}

/**
  * @brief  Initializes the DMAy Streamx according to the specified parameters in 
  *         the DMA_InitStruct structure.
  * @note   Before calling this function, it is recommended to check that the Stream 
  *         is actually disabled using the function DMA_GetCmdStatus().  
  * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
  *         to 7 to select the DMA Stream.
  * @param  DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains
  *         the configuration information for the specified DMA Stream.  
  * @retval None
  */
void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct)
{
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
  assert_param(IS_DMA_CHANNEL(DMA_InitStruct->DMA_Channel));
  assert_param(IS_DMA_DIRECTION(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));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -