DMA 簡介
DMA (Direct Memory Access ,直接內(nèi)存存取)是比一種效率比較高的系統(tǒng)內(nèi)部的一種數(shù)據(jù)傳輸方式,在系統(tǒng)運(yùn)行時(shí)經(jīng)常需要從一個(gè)地址空間拷貝大量數(shù)據(jù)到另一個(gè)地址空間,每次拷貝都需要占用cpu大量的時(shí)間,不能夠去執(zhí)行其他的工作,而DMA控制器就是為了解決這個(gè)問題,當(dāng)需要拷貝數(shù)據(jù)時(shí),cpu只要告訴DMA控制器源地址,目標(biāo)地址,拷貝大小這些參數(shù)后就可以去做其他事情了,DMA會(huì)接管相關(guān)總線,去完成數(shù)據(jù)拷貝的工作。當(dāng)DMA完成傳輸工作后,會(huì)通知CPU來進(jìn)行處理。這樣就大大提高了CPU的工作效率。
S3C6410的DMAC
S3C6410 包括4個(gè)DMA控制器,每個(gè)DMA控制器有8個(gè)傳輸通道,DMA控制器的每個(gè)通道都能夠無限制的在AXI SYSTEM 總線和AXI PERIPHERAL 總線之間通過AHBtoAXI 橋路傳輸數(shù)據(jù)。換句話說,每個(gè)通道能夠應(yīng)用在下面的場合:
- 1 源和目標(biāo)都在SYSTEM總線上
- 2 源在SYSTEM總線但目標(biāo)在PERIPHREAL 總線
- 3 源在PERIPHREAL總線但是目標(biāo)在SYSTEM總線
- 4 源和目標(biāo)都在PERIPHREAL總線上
DMA的主要優(yōu)勢就是在沒有CPU的干涉下也能進(jìn)行數(shù)據(jù)傳輸,DMA傳輸操作可以被軟件或硬件驅(qū)動(dòng),或者是內(nèi)部外設(shè)的請求,或者是外部引腳的請求。
一些特性:
- 4個(gè) DMA 控制器,每個(gè)含8個(gè)通道,每個(gè)通道支持一個(gè)單向傳輸
- 每個(gè)DMA控制器提供16個(gè)外圍DMA請求
- 每個(gè)外設(shè)能夠請求一個(gè)突發(fā)模式或單次模式的DMA請求,突發(fā)模式大小在DMAC寄存器設(shè)置
- 支持內(nèi)存到內(nèi)存,內(nèi)存到外設(shè),外設(shè)到內(nèi)存,外設(shè)到外設(shè)四種請求
- 使用鏈表支持分散或者聚集的DMA請求
- 硬件DMA優(yōu)先級區(qū)分,每個(gè)通道都有固定的優(yōu)先級,從Chanal 0到Chanal 7 優(yōu)先級依次降低
- 源或目標(biāo)源地址自動(dòng)遞增或非遞增
- 可編程的突發(fā)模式的數(shù)據(jù)大小,通常為FIFO的一般
- 每個(gè)通道4個(gè)字的FIFO
- 支持8,16,32bit 寬度傳輸
- 分離的DMA 錯(cuò)誤和DMA 總數(shù)中斷請求,一個(gè)中斷能夠通過DMA 錯(cuò)誤或者DMA count達(dá)到0 產(chǎn)生(通常意味著傳輸完成)
- 中斷屏蔽
- 原始中斷狀態(tài)

S3C6410 支持64個(gè)DMA 源,四個(gè)DMA控制器分為安全DMA控制器和通用DMA控制器兩種,通過系統(tǒng)控制模塊中的SDMA_SEL寄存器進(jìn)行選擇,64個(gè)DMA源如下表:

使能一個(gè)DMA通道的步驟
- 1、決定使用安全DMA控制器還是通用DMA控制器,若要使用通用的DMA控制器,關(guān)閉系統(tǒng)控制器的安全DMA控制寄存器(SDMA_SEL),復(fù)位值是SDMAC
- 2、選擇一個(gè)符合優(yōu)先級要求的空閑的DMA通道 Chanal 0 到Chanal 7 優(yōu)先級從高到低
- 3、清空通道中斷掛起寄存器和錯(cuò)誤寄存器 DMACIntTCClr 和 DMACIntErrClr
- 4、寫源地址到源地址寄存器 DMACCxSrcAddr
- 5、寫目的地址到目標(biāo)地址寄存器 DMACCxDestAddr
- 6、寫下次鏈接地址到DMACCxLLI寄存器,如果傳輸包含一個(gè)單數(shù)據(jù)包,則必須寫入這個(gè)寄存器
- 7、編程DMACCxControl 寄存器填寫控制信息
- 8、編程通道配置信息到DMACCxConfiguration 寄存器,如果使能位被設(shè)置,則DMA通道會(huì)自動(dòng)使能
寄存器描述
四個(gè)DMA控制器被命名為DMAC0,DMAC1,SDMAC0,SDMAC1,寄存器基地址分別為0x7500_0000,0x7510_0000,0x7DB0_0000和0x7DC0_0000。



-
中斷狀態(tài)寄存器
中斷狀態(tài)寄存器 DMACIntStatus 是一個(gè)只讀的用來指示屏蔽后的中斷狀態(tài)的寄存器,某位為高表示一個(gè)特定的DMA通道中斷請求是激活的,請求能夠被錯(cuò)誤或終端計(jì)數(shù)中斷請求產(chǎn)生。
-
終端計(jì)數(shù)中斷狀態(tài)寄存器
-
終端計(jì)數(shù)請求清零寄存器
-
錯(cuò)誤中斷狀態(tài)寄存器
-
錯(cuò)誤中斷狀態(tài)清零
-
原始終端計(jì)數(shù)中斷寄存器
-
原始錯(cuò)誤中斷狀態(tài)寄存器
-
通道使能狀態(tài)寄存器
-
Burst請求寄存器
-
Single請求寄存器
-
DMACConfiguration 使能寄存器
-
同步寄存器
-
源地址寄存器
-
目標(biāo)地址寄存器
-
鏈接表寄存器
-
通道控制寄存器0
-
通道控制寄存器1
-
通道配置寄存器
-
通道配置寄存器-額外
簡單代碼分析
/*
S3C6410中DMA操作步驟:
1、決定使用安全DMAC(SDMAC)還是通用DMAC(DMAC);
2、開啟DMAC控制,設(shè)置DMAC_Configuration寄存器;
3、清除傳輸結(jié)束中斷寄存器和錯(cuò)誤中斷寄存器;
4、選擇合適的優(yōu)先級通道;
5、設(shè)置通道的源數(shù)據(jù)地址和目的數(shù)據(jù)地址(設(shè)置DMACC_SrcAddr和DMACC_DestAddr);
6、設(shè)置通道控制寄存器0(設(shè)置DMACC_Control0);
7、設(shè)置通道控制寄存器1,(傳輸大小,設(shè)置DMACC_Control1);
8、設(shè)置通道配置寄存器;(設(shè)置DMACC_Configuration)
9、使能相應(yīng)通道(設(shè)置DMACC_Configuratoin);
*/
#define SDMA_SEL (*((volatile unsigned long *)0x7E00F110))
#define DMACIntTCClear (*((volatile unsigned long *)0x7DB00008))
#define DMACIntErrClr (*((volatile unsigned long *)0x7DB00010))
#define DMACConfiguration (*((volatile unsigned long *)0x7DB00030))
#define DMACSync (*((volatile unsigned long *)0x7DB00034))
#define DMACC0SrcAddr (*((volatile unsigned long *)0x7DB00100))
#define DMACC0DestAddr (*((volatile unsigned long *)0x7DB00104))
#define DMACC0Control0 (*((volatile unsigned long *)0x7DB0010c))
#define DMACC0Control1 (*((volatile unsigned long *)0x7DB00110))
#define DMACC0Configuration (*((volatile unsigned long *)0x7DB00114))
#define UTXH0 (volatile unsigned long *)0x7F005020
char src[100] = "\n\rHello World-> This is a test!\n\r";
void dma_init()
{
//DMA控制器的選擇(SDMAC0)
SDMA_SEL = 0;
/* 如果外設(shè)的工作時(shí)鐘與DMA控制器的時(shí)鐘不相同, 要使能"同步邏輯" */
DMACSync = 0;
//DMA控制器使能
DMACConfiguration = 1;
//初始化源地址
DMACC0SrcAddr = (unsigned int)src;
//初始化目的地址
DMACC0DestAddr = (unsigned int)UTXH0;
//對控制寄存器進(jìn)行配置
/*
源地址自增
目的地址固定、
目標(biāo)主機(jī)選擇AHB主機(jī)2
源主機(jī)選擇AHB主機(jī)1
*/
DMACC0Control0 =(1<<25) | (1 << 26)| (1<<31);
DMACC0Control1 = 0x64; //傳輸?shù)拇笮? /*
流控制和傳輸類型:MTP 為 001
目標(biāo)外設(shè):DMA_UART0_1,源外設(shè):DMA_MEM
通道有效: 1
*/
DMACC0Configuration = (1<<6) | (1<<11) | (1<<14) | (1<<15);
}
void dma_start()
{
//開啟channel0 DMA
DMACC0Configuration = 1;
}