/************************************************************************************************************* * 檔案名稱:dma.c * 功能:S3C6410 DMA底層驅動函數 * 作者:cp1300@139.com * 建立時間:2013年01月23日21:06 * 最後修改時間:2013年01月23日 * 詳細:DMA控制器底層驅動*************************************************************************************************************/#include "system.h"#include "DMA.h"/**************************************************************************************************************************函數 :void DMA_Init(void)*功能 :DMA初始化*參數 :無*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :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*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :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;*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :20130131*最後修改時間:20130131*說明 :無*************************************************************************************************************************/void DMA_Enable(DMA_TypeDef *DMA){DMA->Config = 0x01;//AHB小端模式,啟動DMA控制器}/**************************************************************************************************************************函數 :void DMA_Disable(DMA_TypeDef *DMA)*功能 :DMA關閉*參數 :DMA:DMA模組選擇,見DMA_TypeDef;*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :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;*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :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;*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :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;*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :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;*返回 :無*依賴: 底層*作者 :cp1300@139.com*時間 :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{vu32SrcAddr;vu32DestAddr;vu32LLI;vu32Control0;vu32Control1;vu32Config;vu32ConfigExp;vu32Reserved;}DMA_CH_Config;//DMA寄存器結構typedef volatile struct{vu32IntStatus;//中斷狀態vu32IntTcStatus;//處理過程中中斷狀態vu32IntTcClear;//中斷清除vu32 IntErrorStatus;vu32IntErrClear;vu32RawIntTCStatus;vu32RawIntErrorStatus;vu32EnbldChns;vu32SoftBReq;vu32SoftSReq;vu32SoftLBReq;vu32SoftLSReq;vu32Config;vu32Sync;vu32Reserved[50];//保留DMA_CH_Config CH[8];//8個獨立通道} DMA_TypeDef;//4個DMA控制器的基址#define DMA0_BASE0x75000000#define DMA1_BASE0x75100000#define SDMA0_BASE0x7DB00000#define SDMA1_BASE0x7DC00000//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,SDMA0DMA_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,SDMA1DMA_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主機1AHB_M2=1,//AHB主機2}DMA_AHB_Type;//DAM傳輸寬度typedef enum{WIDTH_8BIT=0,//8bitWIDTH_16BIT=1,//16bitWIDTH_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{u32SrcAddr;//DMA源地址u32DestAddr;//DAM目標地址DMA_Sources_TypeSrcPeripheral;//源外設DMA_Sources_TypeDestPeripheral;//目標外設FunctionalStateSrcIncrement;//源地址增量模式FunctionalStateDestIncrement;//目標地址增量模式DAM_Width_TypeFlowWidth;//傳輸寬度DMA_BurstSize_TypeBurstSize;//突發傳輸大小u32DataSize;//傳輸資料個數,32bitu32LLIArrd;//下一個傳輸配置地址}DMA_Config;//LLI地址設定typedef struct {u32SrcAddr;//下一個傳輸的源地址u32DestAddr;//下一個傳輸的目標地址u32LLIAddr;//下一個傳輸的LLI地址u32DMAControl0;//下一個傳輸的DMAControl0資料u32DMAControl1;//下一個傳輸的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_*/