之前已经写过了,这次做的灵活一些,例子看我后面发的SAI驱动,使用的是DMA双缓冲模式。
//DMA外设结构
static const DMA_TypeDef * const DMA_TYPE_BUFF[2] = {DMA1, DMA2};
static const DMA_Stream_TypeDef *DMA1_Stream[8] = {DMA1_Stream0, DMA1_Stream1, DMA1_Stream2, DMA1_Stream3, DMA1_Stream4, DMA1_Stream5, DMA1_Stream6, DMA1_Stream7};
static const DMA_Stream_TypeDef *DMA2_Stream[8] = {DMA2_Stream0, DMA2_Stream1, DMA2_Stream2, DMA2_Stream3, DMA2_Stream4, DMA2_Stream5, DMA2_Stream6, DMA2_Stream7};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//2020-02-20 新标准接口
/*************************************************************************************************************************
* 函数 : void DMA_Config(DMAxSx_CH_TYPE DMAxSx_Ch, DAM_CONFIG *pConfig)
* 功能 : DMA配置
* 参数 : DMAxSx_Ch:DMA通道选择;pConfig:配置,见DAM_CONFIG
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2020-02-20
* 最后修改时间 : 2020-02-20
* 说明 :
*************************************************************************************************************************/
void DMA_Config(DMAxSx_CH_TYPE DMAxSx_Ch, DAM_CONFIG *pConfig)
{
u8 Stream,ch;
DMA_Stream_TypeDef *DMA_Stream;
DMA_TypeDef *DMAx;
DMAx = (DMA_TypeDef *)DMA_TYPE_BUFF[(DMAxSx_Ch >> 16)&0x01]; //获取DMA
Stream = (DMAxSx_Ch >> 8)&0xff; //获取流通道
ch = DMAxSx_Ch&0xff;
if((ch > 7) || (Stream > 7)) //通道或流超出了范围
{
return;
}
if((DMAxSx_Ch >> 16)&0x01) //DMA2
{
SYS_DeviceClockEnable(DEV_DMA2, TRUE); //使能DMA2时钟
DMA_Stream = (DMA_Stream_TypeDef *)DMA2_Stream[Stream]; //获取数据流 x 配置寄存器
}
else //DMA1
{
SYS_DeviceClockEnable(DEV_DMA1, TRUE); //使能DMA1时钟
DMA_Stream = (DMA_Stream_TypeDef *)DMA1_Stream[Stream]; //获取数据流 x 配置寄存器
}
//开始配置
DMA_Stream->CR = 0; //禁止数据流,才能进行后面的设置
DMA_Stream->CR |= ch<<25; //设置通道
DMA_Stream->CR |= (pConfig->Mem_BurstSize & 0x03)<<23; //存储器突发传输配置
DMA_Stream->CR |= (pConfig->Per_BurstSize & 0x03)<<21; //外设突发传输配置
if(pConfig->isDoubleBuffer) //使能双缓冲模式
{
DMA_Stream->CR |= 1<<18;
}
DMA_Stream->CR |= (pConfig->PrioLevel & 0x03)<<16; //优先级设置
if(!pConfig->isPerIncPsizeAuto) //外设地址的偏移量与 PSIZE 相关
{
DMA_Stream->CR |= 1<<15; //用于计算外设地址的偏移量固定为 4(32 位对齐)。
}
DMA_Stream->CR |= (pConfig->Mem_Size & 0x03)<<13; //存储器数据大小设置
DMA_Stream->CR |= (pConfig->Pre_Size & 0x03)<<11; //外设数据大小设置
if(pConfig->isMemInc)
{
DMA_Stream->CR |= 1<<10; //存储器地址递增模式
}
if(pConfig->isPerInc)
{
DMA_Stream->CR |= 1<<9; //外设地址递增模式
}
if(pConfig->isCircMode)
{
DMA_Stream->CR |= 1<<8; //循环模式
}
DMA_Stream->CR |= (pConfig->DataTranDir & 0x03)<<6; //数据传输方向
if(pConfig->isPreFlowCtrl)
{
DMA_Stream->CR |= 1<<5; //外设是流控设备
}
if(pConfig->isEnableTranComplInt)
{
DMA_Stream->CR |= 1<<4; //使能完成中断
}
DMA_Stream->NDTR = pConfig->TranDataCount; //传输的数据项数-外设到存储器是流控无需设置长度
DMA_Stream->PAR = pConfig->PerAddr; //外设地址
DMA_Stream->M0AR = pConfig->Mem0Addr; //存储器0地址
DMA_Stream->M1AR = pConfig->Mem0Addr; //存储器1地址
DMA_Stream->FCR = 0;
if(!pConfig->isDirectMode)
{
DMA_Stream->FCR |= 1 << 2; //禁止直接模式
}
DMA_Stream->FCR |= (pConfig->FIFO_Thres & 0x03)<<0; //FIFO阈值选择
//必须清除中断标记,否则DMA可能会停止工作
DMA_ClearIntStatus(DMAxSx_Ch, DMA_INT_ALL);
if(pConfig->isEnableStream)
{
DMA_Stream->CR |= 1<<0; //使能流,开始传输
}
//uart_printf("DMA_Stream->NDTR:%X\r\n",DMA_Stream->NDTR);
//uart_printf("DMA_Stream->NDTR:%X\r\n",DMA_Stream->NDTR);
//uart_printf("DMA_Stream->NDTR:%X\r\n",DMA_Stream->NDTR);
}
/*************************************************************************************************************************
* 函数 : void DMA_StartTrans(DMAxSx_CH_TYPE DMAxSx_Ch, u32 Mem0Addr, u32 Mem1Addr, u16 TranDataCount)
* 功能 : 启动DMA 传输
* 参数 : DMAxSx_Ch:DMA通道选择;Mem0Addr:内存地址0,Mem1Addr:内存地址1(双缓冲模式下有效);TranDataCount:传输数据数量
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2020-02-20
* 最后修改时间 : 2020-02-02
* 说明 : 启动传输,请先调用DMA_Config对当前通道进行配置
*************************************************************************************************************************/
void DMA_StartTrans(DMAxSx_CH_TYPE DMAxSx_Ch, u32 Mem0Addr, u32 Mem1Addr, u16 TranDataCount)
{
u8 Stream,ch;
DMA_Stream_TypeDef *DMA_Stream;
DMA_TypeDef *DMAx;
DMAx = (DMA_TypeDef *)DMA_TYPE_BUFF[(DMAxSx_Ch >> 16)&0x01]; //获取DMA
Stream = (DMAxSx_Ch >> 8)&0xff; //获取流通道
ch = DMAxSx_Ch&0xff;
if((ch > 7) || (Stream > 7)) //通道或流超出了范围
{
return;
}
if((DMAxSx_Ch >> 16)&0x01) //DMA2
{
DMA_Stream = (DMA_Stream_TypeDef *)DMA2_Stream[Stream]; //获取数据流 x 配置寄存器
}
else //DMA1
{
DMA_Stream = (DMA_Stream_TypeDef *)DMA1_Stream[Stream]; //获取数据流 x 配置寄存器
}
DMA_Stream->CR &= ~BIT0; //关闭数据流
DMA_Stream->NDTR = TranDataCount; //传输的数据项数
DMA_Stream->M0AR = Mem0Addr; //存储器0地址
DMA_Stream->M1AR = Mem1Addr; //存储器1地址
//必须清除中断标记,否则DMA可能会停止工作
DMA_ClearIntStatus(DMAxSx_Ch, DMA_INT_ALL);
DMA_Stream->CR |= 1<<0; //使能流,开始传输
}
/*************************************************************************************************************************
* 函数 : void DMA_StopTrans(DMAxSx_CH_TYPE DMAxSx_Ch)
* 功能 : 关闭 DMA 传输
* 参数 : DMAxSx_Ch:DMA通道选择
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2020-02-20
* 最后修改时间 : 2020-02-02
* 说明 :
*************************************************************************************************************************/
void DMA_StopTrans(DMAxSx_CH_TYPE DMAxSx_Ch)
{
u8 Stream,ch;
DMA_Stream_TypeDef *DMA_Stream;
DMA_TypeDef *DMAx;
u8 retry = 10;
DMAx = (DMA_TypeDef *)DMA_TYPE_BUFF[(DMAxSx_Ch >> 16)&0x01]; //获取DMA
Stream = (DMAxSx_Ch >> 8)&0xff; //获取流通道
ch = DMAxSx_Ch&0xff;
if((ch > 7) || (Stream > 7)) //通道或流超出了范围
{
return;
}
if((DMAxSx_Ch >> 16)&0x01) //DMA2
{
DMA_Stream = (DMA_Stream_TypeDef *)DMA2_Stream[Stream]; //获取数据流 x 配置寄存器
}
else //DMA1
{
DMA_Stream = (DMA_Stream_TypeDef *)DMA1_Stream[Stream]; //获取数据流 x 配置寄存器
}
DMA_Stream->CR &= ~BIT0; //关闭数据流
while((DMA_Stream->CR & BIT0) && retry) //等待数据流关闭成功
{
retry --;
SYS_DelayMS(1);
}
//必须清除中断标记,否则DMA可能会停止工作
DMA_ClearIntStatus(DMAxSx_Ch, DMA_INT_ALL);
}
/*************************************************************************************************************************
* 函数 : u32 DMA_GetIntStatus(DMAxSx_CH_TYPE DMAxSx_Ch)
* 功能 : 获取DMA中断状态
* 参数 : DMAxSx_Ch:DMA通道选择
* 返回 : 中断状态,见DMA中断定义
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2020-02-20
* 最后修改时间 : 2020-02-02
* 说明 :
*************************************************************************************************************************/
u32 DMA_GetIntStatus(DMAxSx_CH_TYPE DMAxSx_Ch)
{
u8 Stream;
DMA_TypeDef *DMAx;
u32 temp = 0;
DMAx = (DMA_TypeDef *)DMA_TYPE_BUFF[(DMAxSx_Ch >> 16)&0x01]; //获取DMA
Stream = (DMAxSx_Ch >> 8)&0xff; //获取流通道
switch(Stream)
{
case 0: //Stream 0
{
temp = (DMAx->LISR >> 0)&0x3F;
}break;
case 1: //Stream 1
{
temp = (DMAx->LISR >> 6)&0x3F;
}break;
case 2: //Stream 2
{
temp = (DMAx->LISR >> (16+0))&0x3F;
}break;
case 3: //Stream 3
{
temp = (DMAx->LISR >> (16+6))&0x3F;
}break;
case 4: //Stream 4
{
temp = (DMAx->HISR >> 0)&0x3F;
}break;
case 5: //Stream 5
{
temp = (DMAx->HISR >> 6)&0x3F;
}break;
case 6: //Stream 6
{
temp = (DMAx->HISR >> (16+0))&0x3F;
}break;
case 7: //Stream 7
{
temp = (DMAx->HISR >> (16+6))&0x3F;
}break;
default:
{
temp = 0;
}break;
}
return temp;
}
/*************************************************************************************************************************
* 函数 : void DMA_ClearIntStatus(DMAxSx_CH_TYPE DMAxSx_Ch, u32 IntStatus)
* 功能 : 清除DMA中断状态
* 参数 : DMAxSx_Ch:DMA通道选择;IntStatus:要清除的中断,见DMA中断定义
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2020-02-20
* 最后修改时间 : 2020-02-02
* 说明 :
*************************************************************************************************************************/
void DMA_ClearIntStatus(DMAxSx_CH_TYPE DMAxSx_Ch, u32 IntStatus)
{
u8 Stream;
DMA_TypeDef *DMAx;
u32 temp;
DMAx = (DMA_TypeDef *)DMA_TYPE_BUFF[(DMAxSx_Ch >> 16)&0x01]; //获取DMA
Stream = (DMAxSx_Ch >> 8)&0xff; //获取流通道
switch(Stream)
{
case 0: //Stream 0
{
temp = IntStatus & 0x3F;
DMAx->LIFCR |= temp << 0;
}break;
case 1: //Stream 1
{
temp = IntStatus & 0x3F;
DMAx->LIFCR |= temp << 6;
}break;
case 2: //Stream 2
{
temp = IntStatus & 0x3F;
DMAx->LIFCR |= temp << (16 + 0);
}break;
case 3: //Stream 3
{
temp = IntStatus & 0x3F;
DMAx->LIFCR |= temp << (16 + 6);
}break;
case 4: //Stream 4
{
temp = IntStatus & 0x3F;
DMAx->HIFCR |= temp << 0;
}break;
case 5: //Stream 5
{
temp = IntStatus & 0x3F;
DMAx->HIFCR |= temp << 6;
}break;
case 6: //Stream 6
{
temp = IntStatus & 0x3F;
DMAx->HIFCR |= temp << (16 + 0);
}break;
case 7: //Stream 7
{
temp = IntStatus & 0x3F;
DMAx->HIFCR |= temp << (16 + 6);
}break;
default : break;
}
}
/*************************************************************************************************************************
* 函数 : u8 DMA_GetCurrentTargetBuffIndex(DMAxSx_CH_TYPE DMAxSx_Ch)
* 功能 : 获取双缓冲模式下当前使用的存储器缓冲区索引(0,1)
* 参数 : DMAxSx_Ch:DMA通道选择;
* 返回 : 0:存储器0正在被使用;1:存储器1正在被使用
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2020-02-20
* 最后修改时间 : 2020-02-02
* 说明 : 仅在双缓冲模式下有效
*************************************************************************************************************************/
u8 DMA_GetCurrentTargetBuffIndex(DMAxSx_CH_TYPE DMAxSx_Ch)
{
u8 Stream;
DMA_Stream_TypeDef *DMA_Stream;
DMA_TypeDef *DMAx;
u32 temp;
DMAx = (DMA_TypeDef *)DMA_TYPE_BUFF[(DMAxSx_Ch >> 16)&0x01]; //获取DMA
Stream = (DMAxSx_Ch >> 8)&0xff; //获取流通道
if(Stream > 7) return 0;
if((DMAxSx_Ch >> 16)&0x01) //DMA2
{
DMA_Stream = (DMA_Stream_TypeDef *)DMA2_Stream[Stream]; //获取数据流 x 配置寄存器
}
else //DMA1
{
DMA_Stream = (DMA_Stream_TypeDef *)DMA1_Stream[Stream]; //获取数据流 x 配置寄存器
}
if(DMA_Stream->CR & BIT19) return 1;
else return 0;
}
/*************************************************************************************************************
* 文件名 : dma.c
* 功能 : STM32F7 DMA驱动
* 作者 : [email protected]
* 创建时间 : 2016-03-13
* 最后修改时间 : 2016-03-13
* 详细: 几乎与STM32F4完全兼容
*************************************************************************************************************/
#ifndef __DMA_H_
#define __DMA_H_
#include "system.h"
//传输数据位宽定义
typedef enum
{
DMA_SIZE_8BIT = 0,
DMA_SIZE_16BIT = 1,
DMA_SIZE_32BIT = 2,
}DMA_SIZE_TYPE;
//DMA1请求映射,,高16位代表DMA1还是DMA2,高8位代表数据流,低8位位通道
typedef enum
{
//数据流 0
DMA1S0_SPI3_RX = 0x000000,
DMA1S0_I2C1_RX = 0x000001,
DMA1S0_TIM4_CH1 = 0x000002,
DMA1S0_UART5_RX = 0x000004,
DMA1S0_UART8_TX = 0x000005,
DMA1S0_TIM5_CH3_TIM5_UP = 0x000006,
//数据流 1
DMA1S1_SPDIF_RX_DT = 0x000100,
DMA1S1_I2C3_RX = 0x000101,
DMA1S1_TIM2_UP_TIM2_CH3 = 0x000103,
DMA1S1_USART3_RX = 0x000104,
DMA1S1_UART7_TX = 0x000105,
DMA1S1_TIM5_CH4_TIM5_TRIG = 0x000106,
DMA1S1_TIM6_UP = 0x000107,
//数据流 2
DMA1S2_SPI3_RX = 0x000200,
DMA1S2_TIM7_UP0 = 0x000201,
DMA1S2_I2C4_RX = 0x000202,
DMA1S2_I2C3_RX = 0x000203,
DMA1S2_UART4_RX = 0x000204,
DMA1S2_TIM3_CH4_TIM3_UP = 0x000205,
DMA1S2_TIM5_CH1 = 0x000206,
DMA1S2_I2C2_RX0 = 0x000207,
//数据流 3
DMA1S3_SPI2_RX = 0x000300,
DMA1S3_TIM4_CH2 = 0x000302,
DMA1S3_USART3_TX = 0x000304,
DMA1S3_UART7_RX = 0x000305,
DMA1S3_TIM5_CH4_TIM5_TRIG = 0x000306,
DMA1S3_I2C2_RX = 0x000307,
//数据流 4
DMA1S4_SPI2_TX = 0x000400,
DMA1S4_TIM7_UP = 0x000401,
DMA1S4_I2C3_TX = 0x000403,
DMA1S4_UART4_TX = 0x000404,
DMA1S4_TIM3_CH1_TIM3_TRIG = 0x000405,
DMA1S4_TIM5_CH2 = 0x000406,
DMA1S4_USART3_TX = 0x000407,
//数据流 5
DMA1S5_SPI3_TX = 0x000500,
DMA1S5_I2C1_RX = 0x000501,
DMA1S5_I2C4_TX = 0x000502,
DMA1S5_TIM2_CH1 = 0x000503,
DMA1S5_USART2_RX = 0x000504,
DMA1S5_TIM3_CH2 = 0x000505,
DMA1S5_DAC1 = 0x000507,
//数据流 6
DMA1S6_SPDIF_RX_CS = 0x000600,
DMA1S6_I2C1_TX = 0x000601,
DMA1S6_TIM4_UP = 0x000602,
DMA1S6_TIM2_CH2_TIM2_CH4 = 0x000603,
DMA1S6_USART2_TX = 0x000604,
DMA1S6_UART8_RX = 0x000605,
DMA1S6_TIM5_UP = 0x000606,
DMA1S6_DAC2 = 0x000607,
//数据流 7
DMA1S7_SPI3_TX = 0x000700,
DMA1S7_I2C1_TX = 0x000701,
DMA1S7_TIM4_CH3 = 0x000702,
DMA1S7_TIM2_UP_TIM2_CH4 = 0x000703,
DMA1S7_UART5_TX = 0x000704,
DMA1S7_TIM3_CH3 = 0x000705,
DMA1S7_I2C2_TX = 0x000707,
//DMA2请求映射,高16位代表DMA1还是DMA2,高8位代表数据流,低8位位通道
//数据流 0
DMA2S0_ADC1 = 0x010000,
DMA2S0_ADC3 = 0x010002,
DMA2S0_SPI1_RX = 0x010003,
DMA2S0_SPI4_RX = 0x010004,
DMA2S0_TIM1_TRIG = 0x010006,
//数据流 1
DMA2S1_SAI1_A = 0x010100,
DMA2S1_DCMI = 0x010101,
DMA2S1_ADC3 = 0x010102,
DMA2S1_SPI4_TX = 0x010104,
DMA2S1_USART6_RX = 0x010105,
DMA2S1_TIM1_CH1 = 0x010106,
DMA2S1_TIM8_UP = 0x010107,
//数据流 2
DMA2S2_TIM8_CH1_CH2_CH3 = 0x010200,
DMA2S2_ADC2 = 0x010201,
DMA2S2_SPI1_RX = 0x010203,
DMA2S2_USART1_RX = 0x010204,
DMA2S2_USART6_RX = 0x010205,
DMA2S2_TIM1_CH2 = 0x010206,
DMA2S2_TIM8_CH1 = 0x010205,
//数据流 3
DMA2S3_SAI1_A = 0x010300,
DMA2S3_ADC2 = 0x010301,
DMA2S3_SPI5_RX = 0x010302,
DMA2S3_SPI1_TX = 0x010303,
DMA2S3_SDIO = 0x010304,
DMA2S3_SPI4_RX = 0x010305,
DMA2S3_TIM1_CH1 = 0x010306,
DMA2S3_TIM8_CH2 = 0x010307,
//数据流 4
DMA2S4_ADC1 = 0x010400,
DMA2S4_SAI1_B = 0x010401,
DMA2S4_SPI5_TX = 0x010402,
DMA2S4_SAI2_A = 0x010403,
DMA2S4_SPI4_TX = 0x010405,
DMA2S4_TIM1_CH4_TRIG_COM = 0x010406,
DMA2S4_TIM8_CH3 = 0x010407,
//数据流 5
DMA2S5_SAI1_B = 0x010500,
DMA2S5_SPI6_TX = 0x010501,
DMA2S5_CRYP_OUT = 0x010502,
DMA2S5_SPI1_TX = 0x010503,
DMA2S5_USART1_RX = 0x010504,
DMA2S5_TIM1_UP = 0x010506,
DMA2S5_SPI5_RX = 0x010507,
//数据流 6
DMA2S6_TIM1_CH1_CH2_CH3 = 0x010600,
DMA2S6_SPI6_RX = 0x010601,
DMA2S6_CRYP_IN = 0x010602,
DMA2S6_SAI2_B = 0x010603,
DMA2S6_SDIO = 0x010604,
DMA2S6_USART6_TX = 0x010605,
DMA2S6_TIM1_CH3 = 0x010606,
DMA2S6_SPI5_TX = 0x010607,
//数据流 7
DMA2S7_SAI2_B = 0x010700,
DMA2S7_DCMI = 0x010701,
DMA2S7_HASH_IN = 0x010702,
DMA2S7_QUADSPI = 0x010703,
DMA2S7_USART1_TX = 0x010704,
DMA2S7_USART6_TX = 0x010705,
DMA2S7_TIM8_CH4_TRIG_COM = 0x010707,
}DMAxSx_CH_TYPE;
//存储器到存储器通道定义
typedef enum
{
//内存到内存通道,使用一些不常用的通道用内存到内存的通道
DAM2S0_MEM = 0x010603,
DAM2S1_MEM = 0x010103,
DAM2S2_MEM = 0x010202,
DAM2S3_MEM = 0x010300,
DAM2S4_MEM = 0x010401,
DAM2S5_MEM = 0x010503,
DAM2S6_MEM = 0x010600,
}DMA_MEM_CH;
//2020-02-20 新标准接口
//突发传输长度配置(在直接模式中,当位EN =1时这些位由硬件强制置为 0x0。)
typedef enum
{
DMA_BURST_INCR1 = 0, //单次传输
DMA_BURST_INCR4 = 1, //4个节拍传输
DMA_BURST_INCR8 = 2, //8个节拍传输
DMA_BURST_INCR16 = 3, //16个节拍传输
}DMA_BURST_TRAN_SIZE;
//优先级
typedef enum
{
DAM_PRIO_LEVEL_0 = 0, //优先级低
DAM_PRIO_LEVEL_1 = 1, //优先级中
DAM_PRIO_LEVEL_2 = 3, //优先级高
DAM_PRIO_LEVEL_3 = 4, //优先级最高
}DAM_PRIO_LEVEL;
//数据传输方向定义
typedef enum
{
DMA_PRE_TO_MEM = 0, //外设到存储器
DMA_MEM_TO_PRE = 1, //存储器到外设
DMA_MEM_TO_MEM = 2, //存储器到存储器
}DMA_TRAN_DIR;
//FIFO阈值选择
typedef enum
{
DMA_FIFO_THRES_1_4 = 0, //FIFO阈值为1/4
DMA_FIFO_THRES_1_2 = 1, //FIFO阈值为1/2
DMA_FIFO_THRES_3_4 = 2, //FIFO阈值为3/4
DMA_FIFO_THRES_FULL = 3, //FIFO阈值为完整容量
}DMA_FIFO_THRES;
//DMA配置
typedef struct
{
DMA_BURST_TRAN_SIZE Mem_BurstSize; //存储器的突发传输长度配置
DMA_BURST_TRAN_SIZE Per_BurstSize; //外设的突发传输长度配置
DAM_PRIO_LEVEL PrioLevel; //传输优先级
DMA_SIZE_TYPE Mem_Size; //存储器数据大小
DMA_SIZE_TYPE Pre_Size; //外设数据大小
DMA_TRAN_DIR DataTranDir; //数据传输方向
u32 PerAddr; //外设地址
u32 Mem0Addr; //存储器0地址
u32 Mem1Addr; //存储器1地址
DMA_FIFO_THRES FIFO_Thres; //非直接模式下,FIFO阈值容量选择
u16 TranDataCount; //传输数据长度-外设到存储器是流控无需设置长度
bool isDoubleBuffer; //使能双缓冲模式
bool isPerIncPsizeAuto; //外设偏移量自动根据PSIZE设置(TRUE:偏移量与 PSIZE 相关;否则4字节对齐,如果位 PINC =“0”,则此位没有意义)
bool isMemInc; //存储器地址自增
bool isPerInc; //外设地址自增
bool isCircMode; //循环模式
bool isPreFlowCtrl; //外设是流控制设备
bool isEnableTranComplInt; //传输完成中断使能
bool isDirectMode; //直接模式
bool isEnableStream; //是否使能数据流-开始传输
}DAM_CONFIG;
//DMA中断定义
#define DAM_INT_FIFO_ERROR BIT0 //数据流FIFO错误中断
#define DMA_INT_DIRECT_ERROR BIT2 //直接模式错误中断
#define DMA_INT_TRANS_ERROR BIT3 //传输错误
#define DMA_INT_TRANS_HALF BIT4 //传输过半
#define DMA_INT_TRANS_COMPL BIT5 //传输完成中断
#define DMA_INT_ALL (0x3D) //所有中断
void DMA_Config(DMAxSx_CH_TYPE DMAxSx_Ch, DAM_CONFIG *pConfig); //DMA配置
void DMA_StartTrans(DMAxSx_CH_TYPE DMAxSx_Ch, u32 Mem0Addr, u32 Mem1Addr, u16 TranDataCount); //启动DMA 传输
void DMA_StopTrans(DMAxSx_CH_TYPE DMAxSx_Ch); //关闭 DMA 传输
u32 DMA_GetIntStatus(DMAxSx_CH_TYPE DMAxSx_Ch); //获取DMA中断状态
void DMA_ClearIntStatus(DMAxSx_CH_TYPE DMAxSx_Ch, u32 IntStatus); //清除DMA中断状态
u8 DMA_GetCurrentTargetBuffIndex(DMAxSx_CH_TYPE DMAxSx_Ch); //获取双缓冲模式下当前使用的存储器缓冲区索引(0,1)
#endif //__DMA_H_