/************************************************************************************************************* * 文件名: dma.c * 功能: S3C6410 DMA底层驱动函数 * 作者: [email protected] * 创建时间: 2013年01月23日21:06 * 最后修改时间:2013年01月23日 * 详细: DMA控制器底层驱动 *************************************************************************************************************/ #include "system.h" #include "DMA.h" /************************************************************************************************************************* *函数 : void DMA_Init(void) *功能 : DMA初始化 *参数 : 无 *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 无 *************************************************************************************************************************/ void DMA_Init(void) { Set_GateClk(HCLK_DMA0, ENABLE); Set_GateClk(HCLK_DMA1, ENABLE); } /************************************************************************************************************************* *函数 : void DMA_SetConfig(DMA_TypeDef *DMA, DMA_CHX ch, DMA_Config *config) *功能 : DMA配置 *参数 : DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX;config:配置,见DMA_Config *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 用于设置DMA *************************************************************************************************************************/ void DMA_SetConfig(DMA_TypeDef *DMA, DMA_CHX ch, DMA_Config *config) { DMA_Enable(DMA); //使能DMA模块 (DMA->CH[ch]).SrcAddr = config->SrcAddr; //设置源地址 (DMA->CH[ch]).DestAddr = config->DestAddr; //设置目标地址 (DMA->CH[ch]).Control0 = 0x80000000 //1<<31 //是否在当前的传输完成后产生中断 | ((config->DestIncrement == ENABLE) ? (1 << 27) : 0) //目标地址自增 | ((config->SrcIncrement == ENABLE) ? (1 << 26) : 0) //源地址自增 | ((config->DestPeripheral == DMA_MEM) ? AHB_M1 : AHB_M2) << 25 //目标AHB主机选择 | ((config->SrcPeripheral == DMA_MEM) ? AHB_M1 : AHB_M2) << 24 //源AHB主机选择 | (config->FlowWidth & 0x7) << 21 //目标传输宽度 | (config->FlowWidth & 0x7) << 18 //源传输宽度 | (config->BurstSize & 0x7) << 15 //目标传输脉冲大小,单次传输的数量 | (config->BurstSize & 0x7) << 12; //源传输脉冲大小,单次传输的数量 (DMA->CH[ch]).Control1 = config->DataSize & 0x1ffffff; //传输数据数量 (DMA->CH[ch]).Config = (0<<18)// enable DMA requests | (0<<16) // disables locked transfers | (1<<15) // Teminal count interrupt enable | (0<<14) // Interrupt error mask //允许DMA请求 | (((config->SrcPeripheral == DMA_MEM) ? 0 : 1) << 12) | (((config->DestPeripheral == DMA_MEM) ? 0 : 1) << 11) //传输模式,如内存到内存等 | (config->DestPeripheral & 0x0f) << 6 //目标外设 | (config->SrcPeripheral & 0x0f) << 1; //源外设 (DMA->CH[ch]).LLI = config->LLIArrd; //下一个传输LLI配置位置 //(DMA->CH[ch]).ConfigExp = 7; } /************************************************************************************************************************* *函数 : void DMA_Enable(DMA_TypeDef *DMA) *功能 : DMA使能 *参数 : DMA:DMA模块选择,见DMA_TypeDef; *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 无 *************************************************************************************************************************/ void DMA_Enable(DMA_TypeDef *DMA) { DMA->Config = 0x01; //AHB小端模式,启动DMA控制器 } /************************************************************************************************************************* *函数 : void DMA_Disable(DMA_TypeDef *DMA) *功能 : DMA关闭 *参数 : DMA:DMA模块选择,见DMA_TypeDef; *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 无 *************************************************************************************************************************/ void DMA_Disable(DMA_TypeDef *DMA) { DMA->Config = 0x00; //AHB小端模式,关闭DMA控制器 } /************************************************************************************************************************* *函数 : void DMA_StartChannels(DMA_TypeDef *DMA, DMA_CHX ch) *功能 : DMA通道传输开始 *参数 : DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX; *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 无 *************************************************************************************************************************/ void DMA_StartChannels(DMA_TypeDef *DMA, DMA_CHX ch) { DMA_ClearIntTCStatus(DMA0, ch); DMA_ClearIntErrorStatus(DMA0, ch); (DMA->CH[ch]).Config |= 1 << 0; //通道使能 } /************************************************************************************************************************* *函数 : void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHX ch) *功能 : 等待传输完成 *参数 : DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX; *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 无 *************************************************************************************************************************/ void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHX ch) { while(!(DMA->RawIntTCStatus & (1 << ch))); } /************************************************************************************************************************* *函数 : void DMA_ClearIntTCStatus(DMA_TypeDef *DMA, DMA_CHX ch) *功能 : DMA清除DMA传输完成中断状态 *参数 : DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX; *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 无 *************************************************************************************************************************/ void DMA_ClearIntTCStatus(DMA_TypeDef *DMA, DMA_CHX ch) { DMA->IntTcClear |= 1 << ch; } /************************************************************************************************************************* *函数 : void DMA_ClearIntErrorStatus(DMA_TypeDef *DMA, DMA_CHX ch) *功能 : 清除DMA传输错误中断状态 *参数 : DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX; *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 20130131 *最后修改时间 : 20130131 *说明 : 无 *************************************************************************************************************************/ void DMA_ClearIntErrorStatus(DMA_TypeDef *DMA, DMA_CHX ch) { DMA->IntErrClear |= 1 << ch; }
#ifndef DMA_H_ #define DMA_H_ //DMA通道定义 typedef enum { DMA_CH0 = 0, DMA_CH1 = 1, DMA_CH2 = 2, DMA_CH3 = 3, DMA_CH4 = 4, DMA_CH5 = 5, DMA_CH6 = 6, DMA_CH7 = 7, }DMA_CHX; //DMA单独通道结构 typedef volatile struct { vu32 SrcAddr; vu32 DestAddr; vu32 LLI; vu32 Control0; vu32 Control1; vu32 Config; vu32 ConfigExp; vu32 Reserved; }DMA_CH_Config; //DMA寄存器结构 typedef volatile struct { vu32 IntStatus; //中断状态 vu32 IntTcStatus; //处理过程中中断状态 vu32 IntTcClear; //中断清除 vu32 IntErrorStatus; vu32 IntErrClear; vu32 RawIntTCStatus; vu32 RawIntErrorStatus; vu32 EnbldChns; vu32 SoftBReq; vu32 SoftSReq; vu32 SoftLBReq; vu32 SoftLSReq; vu32 Config; vu32 Sync; vu32 Reserved[50];//保留 DMA_CH_Config CH[8]; //8个独立通道 } DMA_TypeDef; //4个DMA控制器的基址 #define DMA0_BASE 0x75000000 #define DMA1_BASE 0x75100000 #define SDMA0_BASE 0x7DB00000 #define SDMA1_BASE 0x7DC00000 //DMA寄存器指针 #define DMA0 ((DMA_TypeDef *)DMA0_BASE) #define DMA1 ((DMA_TypeDef *)DMA1_BASE) #define SDMA0 ((DMA_TypeDef *)SDMA0_BASE) #define SDMA1 ((DMA_TypeDef *)SDMA1_BASE) //DMA源定义 typedef enum { //DMA0,SDMA0 DMA_MEM = 0, DMA_UART0_0 = 0, DMA_UART0_1 = 1, DMA_UART1_0 = 2, DMA_UART1_1 = 3, DMA_UART2_0 = 4, DMA_UART2_1 = 5, DMA_UART3_0 = 6, DMA_UART3_1 = 7, DMA_PCM0_TX = 8, DMA_PCM0_RX = 9, DMA_I2S0_TX = 10, DMA_I2S0_RX = 11, DMA_SPI0_TX = 12, DMA_SPI0_RX = 13, DMA_HSI_TX = 14, DMA_HSI_RX = 15, //DMA1,SDMA1 DMA_PCM1_TX = 16, DMA_PCM1_RX = 17, DMA_I2S1_TX = 18, DMA_I2S1_RX = 19, DMA_SPI1_TX = 20, DMA_SPI1_RX = 21, DMA_AC_PCMout = 22, DMA_AC_PCMin = 23, DMA_AC_MICin = 24, DMA_PWM = 25, DMA_IrDA = 26, DMA_SECU_RX = 30, DMA_SECU_TX = 31 }DMA_Sources_Type; //DMA传输类型定义 /* typedef enum { MemToMem = 0, //内存到内存 MemToPer = 1, //内存到外设 PerToMem = 2, //外设到内存 PerToPer = 3 //外设到外设 }DMA_Transfer_Type; */ typedef enum { NO_INT_PEND = 0x0, TC_INT_PEND = 0x1, ERR_INT_PEND = 0x2, TC_AND_ERR_INT_PEND = 0x3 } DMA_INT_STATUS; //DMA AHB主机选择定义 typedef enum { AHB_M1 = 0, //AHB主机1 AHB_M2 = 1, //AHB主机2 }DMA_AHB_Type; //DAM传输宽度 typedef enum { WIDTH_8BIT = 0, //8bit WIDTH_16BIT = 1, //16bit WIDTH_32BIT = 2 //32bit }DAM_Width_Type; //源或目标突发传输大小 typedef enum { BURST1 = 0, BURST4 = 1, BURST8 = 2, BURST16 = 4, BURST32 = 5, BURST64 = 6, BURST128 = 7, BURST256 = 8 }DMA_BurstSize_Type; /* *DMAC内部每个通道的4字FIFO。因此,脉冲串的大小和传输宽度是有限的由FIFO 大小。例如,如果数据宽度为字,可用的突发脉冲尺寸是4下。如果数据宽度为字节,可突发尺寸 在16岁以下。 */ //DMA传输配置 typedef struct { u32 SrcAddr; //DMA源地址 u32 DestAddr; //DAM目标地址 DMA_Sources_Type SrcPeripheral; //源外设 DMA_Sources_Type DestPeripheral; //目标外设 FunctionalState SrcIncrement; //源地址增量模式 FunctionalState DestIncrement; //目标地址增量模式 DAM_Width_Type FlowWidth; //传输宽度 DMA_BurstSize_Type BurstSize; //突发传输大小 u32 DataSize; //传输数据个数,32bit u32 LLIArrd; //下一个传输配置地址 }DMA_Config; //LLI地址设置 typedef struct { u32 SrcAddr; //下一个传输的源地址 u32 DestAddr; //下一个传输的目标地址 u32 LLIAddr; //下一个传输的LLI地址 u32 DMAControl0;//下一个传输的DMAControl0数据 u32 DMAControl1;//下一个传输的DMAControl1数据 }DMA_LLI_Addr; //函数声明 void DMA_Init(void); void DMA_SetConfig(DMA_TypeDef *DMA, DMA_CHX ch, DMA_Config *config); void DMA_Enable(DMA_TypeDef *DMA); void DMA_Disable(DMA_TypeDef *DMA); void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHX ch); void DMA_ClearIntTCStatus(DMA_TypeDef *DMA, DMA_CHX ch); void DMA_ClearIntErrorStatus(DMA_TypeDef *DMA, DMA_CHX ch); void DMA_StartChannels(DMA_TypeDef *DMA, DMA_CHX ch); #endif /*DMA_H_*/