S3C6410中DMA操作步骤:
1、决定使用安全DMAC(SDMAC)还是通用DMAC(DMAC);
2、开始相应DMAC的系统时钟,并关闭另外一组的时钟(系统默认开启SDMA时钟);
3、开启DMAC控制,设置DMAC_Configuration寄存器;
4、清除传输结束中断寄存器和错误中断寄存器;
5、选择合适的优先级通道;
6、设置通道的源数据地址和目的数据地址(设置DMACC_SrcAddr和DMACC_DestAddr);
7、设置通道控制寄存器0(设置DMACC_Control0);
8、设置通道控制寄存器1,(传输大小,设置DMACC_Control1);
9、设置通道配置寄存器;(设置DMACC_Configuration)
10、使能相应通道(设置DMACC_Configuratoin);
注意:在DMA工作过程中,通道寄存器Control0,Control1,Configuration的值近尽量不要读取,否则会产生副作用,导致传输失败!!
文件:dma.H
- <span style="font-size:18px;">/*******************************************************************************************
- * 文件名: dma.h
- * 功能: S3C6410 DMA底层驱动函数
- * 作者: 肖仕刚
- * 创建时间: 2013年5月7日21:33
- * 最后修改时间: 2013年5月7日
- * 详细:
- *******************************************************************************************/
- /***功能:DMA控制****/
- #include "s3c6410_types.h"
- #include "s3c6410_map.h"
- #include "s3c6410_system.h"
- //模块功能: DMA通道定义
- typedef enum
- {
- DMA_CH1 = 0,
- DMA_CH2 = 1,
- DMA_CH3 = 2,
- DMA_CH4 = 3,
- DMA_CH5 = 4,
- DMA_CH6 = 5,
- DMA_CH7 = 6,
- DMA_CH8 = 7
- }DMA_CHx_Type;
- //模块功能: DMA数据源定义
- typedef enum
- {
- //DMA0,SDMA0
- 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_I2SV40_TX= 14,
- DMA_HSI_I2SV40_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_EXTERNAL = 27,
- DMA_SECU_RX = 30,
- DMA_SECU_TX = 31
- }DMA_Source_Type;
- //模块功能: DMA AHB主机选择
- typedef enum
- {
- AHB_M1 = 0, //主机1
- AHB_M2 = 1 //主机2
- }AHB_Manager_Type;
- //模块功能: DMA突发传输大小定义
- typedef enum
- {
- Burst_1 = 0x000,
- Burst_4 = 0x001,
- Burst_8 = 0x010,
- Burst_16= 0x011
- }DMA_BurstSize_Type;
- //模块功能: DMA传输宽度定义
- typedef enum
- {
- BitWidth_8 = 0x000,
- BitWidth_16= 0x001,
- BitWidth_32= 0x010
- }DMA_BitWidth_Type;
- //模块功能: DMA数据流模式定义
- typedef enum
- {
- MTM = 0x000,
- MTP = 0x001,
- PTM = 0x010,
- PTP = 0x011
- }DMA_Flow_Type;
- //模块功能: 外设DMA:MTM请求
- typedef enum
- {
- TX0 = 0x00,
- TX1 = 0x01,
- RX0 = 0x10,
- RX1 = 0x11
- }DMA_EXPREQ_Type;
- /***********************************************************************************************************
- *
- *模块功能: 对象、函数定义
- *
- ************************************************************************************************************/
- void DMA_EnableCLK(void);
- void DMA_SwitchEnable(DMA_TypeDef *DMA,u8 flag);
- void DMA_ClearTCStatus(DMA_TypeDef *DMA);
- void DMA_ClearErrorStatus(DMA_TypeDef *DMA);
- void DMA_CHBurstREQ_EN(DMA_TypeDef *DMA,u8 ChNo,u8 Flag);
- void DMA_CHSingleREQ_EN(DMA_TypeDef *DMA,u8 ChNo,u8 Flag);
- void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHx_Type ChNo);
- void CH_SwitchEnable(DMA_CH_Config *ch,u8 flag);
- void CH_SetSDAddr(DMA_CH_Config *CH,u32 SAddr,u32 DAddr);
- void CH_SetLII(DMA_CH_Config *ch,u32 LIIAddr,u8 LM);
- void CH_SetControl0(DMA_CH_Config *ch);
- void CH_SetControl1(DMA_CH_Config *ch);
- void CH_SetConfiguration(DMA_CH_Config *ch);
- </span>
文件:dma.C
- <span style="font-size:18px;">/*************************************************************************************************************
- * 文件名: dma.c
- * 功能: S3C6410 DMA底层驱动函数
- * 作者: 肖仕刚
- * 创建时间: 2013年5月7日21:33
- * 最后修改时间: 2013年5月7日
- * 详细:
- *************************************************************************************************************/
- /***功能:DMA控制****/
- #include "dma.h"
- #include "uart.h"
- #define DMA_Enable 0x1
- #define DMA_Disable 0x0
- //控制器0参数定义
- #define TERMCOUNT_INTEN 0x0<<31 //终点计数中断使能
- #define SRC_INCREMENT 0x1<<27 //源地址自增长
- #define DEST_INCREMENT 0x1<<26 //目的地址自增长
- #define DEST_MASTERSEL AHB_M1<<25 //目的AHB主机选择
- #define SRC_MASTERSEL AHB_M1<<24 //源AHB主机选择
- #define DEST_TRANWIDTH (0x7&BitWidth_8)<<21 //目的传输宽度
- #define SRC_TRANWIDTH (0x7&BitWidth_8)<<18 //源传输宽度
- #define DEST_BURSTWIDTH (0x7&Burst_1)<<15 //目的突发宽度
- #define SRC_BURSTWIDTH (0x7&Burst_1)<<12 //源突发宽度
- //控制器1参数配置
- #define TRANSFER_SIZE 0x64 //数据传输大小
- //Configuration寄存器参数
- #define HALT 0x0<<18 //通道终止控制(保留数据)
- #define LOCK_ENABLE 0x0<<16 //传输锁定使能
- #define TERMCOUNT_INTMASK 0x0<<15 //通道终点计数中断屏蔽位
- #define ERROR_INTMASK 0x0<<14 //通道错误中断屏蔽位
- #define FLOW_TYPE MTM //数据流控制和传输类型
- #define ONENAND_MODEDEST 0x0<<10 //oneNand模式目的选择
- #define DEST_PERIPHERAL 0x0<<6 //oneNand模式目的外设选择
- #define ONENAND_MODESRC 0x0<<5 //oneNand模式源选择
- #define SRC_PERIPHERAL 0x0<<1 //oneNand模式源外设选择
- //ConfigurationExp寄存器参数设置
- #define EXPREQ_SEL TX0 //外设DMA:MTM请求选择
- #define EXPREQ_ENA DMA_Enable //外设DMA请求使能
- void DMA_EnableCLK(void)
- {
- Set_CLK_GATE(HCLK_DMA0, 0x1);
- Set_CLK_GATE(HCLK_DMA1, 0x1);
- Set_CLK_GATE(HCLK_SDMA0,0x0);
- Set_CLK_GATE(HCLK_SDMA1,0x0);
- }
- /*************************************************************************************************************************
- *函数 : void DMA_SwitchEnable(DMA_TypeDef *DMA,u8 flag)
- *功能 : DMA使能、禁能转换
- *参数 : DMA
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void DMA_SwitchEnable(DMA_TypeDef *DMA,u8 flag)
- {
- if(flag&DMA_Enable)
- DMA->Configuration = DMA_Enable;
- else
- DMA->Configuration = DMA_Disable;
- }
- /*************************************************************************************************************************
- *函数 : void DMA_ClearTCStatus(DMA_TypeDef *DMA)
- *功能 : DMA终点计数中断清除
- *参数 : DMA
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void DMA_ClearTCStatus(DMA_TypeDef *DMA)
- {
- DMA->IntTCClear |= 0xFF; //寄存器写1清除
- }
- /*************************************************************************************************************************
- *函数 : void DMA_ClearErrorStatus(DMA_TypeDef *DMA)
- *功能 : DMA错误中断清除
- *参数 : DMA
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void DMA_ClearErrorStatus(DMA_TypeDef *DMA)
- {
- DMA->IntErrClr |= 0xFF; //寄存器写1清除
- }
- /*************************************************************************************************************************
- *函数 : void DMA_CHBurstREQ_EN(DMA_TypeDef *DMA,u8 ChNo,u8 Flag)
- *功能 : DMA通道软件突发请求使能
- *参数 : DMA,ChNo:通道号,Flag:使能/禁能位
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void DMA_CHBurstREQ_EN(DMA_TypeDef *DMA,u8 ChNo,u8 Flag)
- {
- DMA->SoftBReq &= ~(1<<ChNo); //复位相关位
- DMA->SoftBReq |= (Flag<<ChNo);
- }
- /*************************************************************************************************************************
- *函数 : void DMA_CHSingleREQ_EN(DMA_TypeDef *DMA,u8 ChNo,u8 Flag)
- *功能 : DMA通道软件单一请求使能
- *参数 : DMA,ChNo:通道号,Flag:使能/禁能位
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void DMA_CHSingleREQ_EN(DMA_TypeDef *DMA,u8 ChNo,u8 Flag)
- {
- DMA->SoftSReq &= ~(1<<ChNo); //复位相关位
- DMA->SoftSReq |= (Flag<<ChNo);
- }
- /*************************************************************************************************************************
- *函数 : void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHx_Type ChNo)
- *功能 : DMA通道传输完成
- *参数 : DMA,ChNo:通道号
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHx_Type ChNo)
- {
- while(!(DMA->RawIntTCStatus & (1 << ChNo)));
- }
- /*************************************************************************************************************************
- *函数 : void CH_SwitchEnable(DMA_CH_TypeDef *ch,u8 flag)
- *功能 : DMA通道使能、禁能转换
- *参数 : DMA
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void CH_SwitchEnable(DMA_CH_Config *ch,u8 flag)
- {
- if(flag&DMA_Enable)
- ch->Configuration = DMA_Enable<<0;
- else
- ch->Configuration = DMA_Disable<<0;
- }
- /*************************************************************************************************************************
- *函数 : void CH_SetSDAddr(DMA_CH_Config *CH,u32 SAddr,u32 DAddr)
- *功能 : 设置通道源地址,目的地址
- *参数 : ch:通道,SAddr:源地址,DAddr:目的地址
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void CH_SetSDAddr(DMA_CH_Config *CH,u32 SAddr,u32 DAddr)
- {
- CH->SrcAddr = SAddr;
- CH->DestAddr = DAddr;
- }
- /*************************************************************************************************************************
- *函数 : void CH_SetLII(DMA_CH_Config *ch,u32 LIIAddr,u8 LM)
- *功能 : 设置通道LII
- *参数 : ch:通道,LM:加载模式(0,1)
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void CH_SetLII(DMA_CH_Config *ch,u32 LIIAddr,u8 LM)
- {
- ch->LII |= (LIIAddr<<2); //设置下一个LII地址
- ch->LII |= (LM<<0); //设置加载模式
- }
- /*************************************************************************************************************************
- *函数 : void CH_SetControl0(DMA_CH_Config *ch)
- *功能 : 通道控制器0配置
- *参数 : ch:通道
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void CH_SetControl0(DMA_CH_Config *ch)
- {
- ch ->Control0 = SRC_BURSTWIDTH
- | DEST_BURSTWIDTH
- | SRC_TRANWIDTH
- | DEST_TRANWIDTH
- | SRC_MASTERSEL
- | DEST_MASTERSEL
- | DEST_INCREMENT
- | SRC_INCREMENT
- | TERMCOUNT_INTEN ; //功能设置
- }
- /*************************************************************************************************************************
- *函数 : void CH_SetControl1(DMA_CH_Config *ch)
- *功能 : 通道控制器1配置
- *参数 : ch:通道
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void CH_SetControl1(DMA_CH_Config *ch)
- {
- ch ->Control1 |= (0x1FFFFFF & TRANSFER_SIZE); //设置传输大小
- //ch ->Control1 = TRANSFER_SIZE;
- }
- /*************************************************************************************************************************
- *函数 : void CH_SetConfiguration(DMA_CH_Config *ch)
- *功能 : 通道配置寄存器
- *参数 : ch:通道
- *返回 : 无
- *依赖 : 底层宏定义
- *作者 : 肖仕刚
- *时间 : 2013年05月16
- *最后修改时间: 2013年05月16
- *说明 : -
- *************************************************************************************************************************/
- void CH_SetConfiguration(DMA_CH_Config *ch)
- {
- ch->Configuration |= ONENAND_MODESRC
- | DEST_PERIPHERAL
- | ONENAND_MODEDEST
- | FLOW_TYPE
- | ERROR_INTMASK
- | TERMCOUNT_INTMASK
- | LOCK_ENABLE
- | HALT; //配置寄存器功能设置
- }
- </span>
文件:mian.C
- <span style="font-size:18px;">/*************************************************************************************************************
- * 文件名: main.c
- * 功能: S3C6410 DMA测试函数
- * 作者: 肖仕刚
- * 创建时间: 2013年5月16日21:33
- * 最后修改时间 2013年5月16日
- * 详细: 基于DMA的串口初始化,发送,接收,配置等
- * 警告: DMA测试过程中不要输出寄存器的值以免产生副作用
- *************************************************************************************************************/
- #include "dma.h"
- #include "uart.h"
- #include <stdio.h>
- //主函数
- void main(void)
- {
- u8 src[100] = "1234567898765432123456987\n";
- u8 dest[100]= "000000\n";
- u8 str[40];
- UART_Init();
- //使能DMA系统时钟
- DMA_EnableCLK();
- //开启DMA
- DMA_SwitchEnable(DMAC0,0x01);
- //清除先前传输结束中断标志位
- DMA_ClearTCStatus(DMAC0);
- //清除先前错误中断标志位
- DMA_ClearErrorStatus(DMAC0);
- //设置通道源地址和目的地址
- CH_SetSDAddr(&DMAC0->Channel[DMA_CH1],(u32)src,(u32)dest);
- //设置通道控制信息
- CH_SetControl0(&DMAC0->Channel[DMA_CH1]);
- //设置通道传输大小
- CH_SetControl1(&DMAC0->Channel[DMA_CH1]);
- //设置通道配置信息
- CH_SetConfiguration(&DMAC0->Channel[DMA_CH1]);
- //使能通道开始工作
- CH_SwitchEnable(&DMAC0->Channel[DMA_CH1],0x1);
- //延时
- Delay(5000);
- sprintf((char *)str,"DMACCH_ EnbldChns:0x%X---\n",DMAC0->EnbldChns);
- UART_SendStr((char *)str);
- UART_SendStr((char *)src);
- UART_SendStr((char *)dest);
- UART_SendStr((char *)"Test Complete!!\n");
- }
- </span>