简介:
S3C2440A支持位于系统总线和外设总线的四通道DMA控制器。每一个DMA控制器的通道都可以在系统设备之间或者系统与外设之间,以及外设与外设之间进行数据传输操作而没有任何限制。换句话说,每个通道可以处理一下四种情况:
1. 源和目的都在系统总线
2. 源在系统总线,而目的在外部总线
3. 源在外部总线,而目的在系统总线
4. 源和目的都在外部总线
DMA主要的优势是:他可以在CPU不打扰的情况下传输数据。DMA操作可以被软件初始化,也可以使用片上外设的请求,或者外部的请求引脚。
DMA请求源
如果通过DCON寄存器选中H/W DMA请求模式,DMA控制器的每一个通道可以从四个DMA源中选择一个DMA请求源。(注意:如果S/W请求模式被选中,则这个DMA请求源将没有任何意义)。下表显示了每个通道的四个DMA
这里nXDREQ0 和nXDREQ1表示两个外部的源(外部的设备),而I2SSDO 和I2SSDI分别表示i2s的传输和接收。
DMA操作
DMA使用三态有限状态机(FSM)来做他的操作。这可以描述为下面的三个步骤:
Stat-1. 作为一个初始态,DMA等待DMA请求,一旦获得DMA请求,他将调到stat-2。而在该态中,DMA ACK和INT REQ都是0 。
Stat-2. 在这个态时,DMA ACK变为1 同时计数器(CURR_TC)从DCON寄存器[19:0]中加载。注意,此时DMA ACK还保持为1,直到他后面被清零。
Stat-3. 在这个态,处理DMA原子操作的子有限状态机(sub-FSM)被初始化。子有限状态机(sub-FSM)从源地址读取数据并将它们写到目的地址。在这个操作中,数据大小和传输大小(单字或者burst)是要考虑的。在全服务模式(Whole service mode)时,这个操作将一直重复进行直到计数器(CURR_TC)的数据变为0 。而在单服务模式(Single service mode)时,这个操作只要执行一次。当子有限状态机(sub-FSM)完成一次原子操作时,主有限状态机(main FSM)的计数器值将减一。此外,当计数器CURR_TC变为0,同时DCON寄存器[29]的中断设置为1时,主有限状态机(main FSM)保持INT REQ信号。而当下面情况中的一种满足时,将清DMA ACK:
1)在全服务模式(Whole service mode)时,计数器(CURR_TC)的数据变为0
2)在单服务模式(Single service mode)时,原子操作完成。
注意:在单服务模式(Single service mode)时,主有限状态机(main FSM)的这三种态将被执行,然后停止,来等待下一个DMAREQ。同时,如果DMA REQ到来,这三个态将再重复一遍。因此,DMA ACK将被保持,然后在完成每个原子操作后失效。相反,在在全服务模式(Whole service mode)时,主有限状态机(main FSM)将等在stat-3直到计数器(CURR_TC)变为0 。因此,DMAACK将在整个传输过程中保持,然后在计数器为0时失效。
然而,当计数器为0时将置位INT REQ,而不管服务模式(全服务模式或者单服务模式)。
外部DMA请求/应答协议
这里有三种外部DMA请求/应答协议(单服务请求,单服务握手以及全服务握手)。每种协议定义了DMA请求和应答与协议的关系。
基本DMA时间
DMA服务就是在DMA操作时编辑成对的读写周期,这可以组成一个DMA操作。下图显示了S3C2440A中基础操作所要的时间。
——在所有的模式中,XnXDREQ 和XnXDACK的设置时间和延迟时间是一样的。
——如果XnXDREQ的完成遇到了他的设置时间,将同步两次同时置位XnXDACK。
——置位XnXDACK之后,如果DMA请求总线获得总线,他将执行他的操作。当DMA操作完成,XnXDACK失效。
请求和握手模式的比较
请求和握手模式是与XnXDREQ 和XnXDACK相关的协议。下图显示了他们的不同。
在一次传输(Single/Burst传输)的结尾,DMA检查双同步XnXDREQ.的态
请求Mode
——如果XnXDREQ依然保持,而下一个传输立即开始。否则他将等待XnXDREQ置位。
握手Mode
——如果XnXDREQ失效,DMA失效XnXDACK在之后的两个周期,否则他将等待直到XnXDREQ失效
警告:当XnXDACK.(为高电平)失效时,XnXDREQ(为低电平)必须置位。
传输大小
——这里有两种不同的传输大小:单元大小和爆发4 。
——当传输大块数据时DMA将控制总线。因此其他的总线主机不能获得总线
爆发4传输大小
在爆发4传输时,将有4个连续的读写操作。
注意:单元传输大小为一个读写操作。
例子
在请求模式下单服务单元传输
XnXDREQ置位将需要每一个单元的传输(单服务模式)。当XnXDREQ置位时,操作将继续进行(请求模式),同时一对读写被执行(单元传输)。
在握手模式下单服务单元传输
在握手模式下全服务单元传输
DMA特有寄存器
每个DMA通道有九个控制寄存器(有四通道DMA控制器所以一共有36个)。其中有六个控制寄存器控制DMA传输,而另外的三个监督DMA控制器的状态。寄存器的详细信息在下面。
DMA初始化源寄存器(DISRC)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DISRC0 |
0x4B000000 |
R/W |
DMA0初始化源寄存器 |
0x00000000 |
DISRC1 |
0x4B000040 |
R/W |
DMA1初始化源寄存器 |
0x00000000 |
DISRC2 |
0x4B000080 |
R/W |
DMA2初始化源寄存器 |
0x00000000 |
DISRC3 |
0x4B0000C0 |
R/W |
DMA3初始化源寄存器 |
0x00000000 |
DISRCn |
位 |
描述 |
初始值 |
S_ADDR |
[30:0] |
用于传输的源的基地址(开始地址)。只有当CURR_SRC是0并且DMA ACK为1时,这个数据才会加载到CURR_SRC。 |
0x00000000 |
DMA初始化源控制寄存器(DISRCC)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DISRCC0 |
0x4B000004 |
R/W |
DMA0初始化源控制寄存器 |
0x00000000 |
DISRCC1 |
0x4B000044 |
R/W |
DMA1初始化源控制寄存器 |
0x00000000 |
DISRCC2 |
0x4B000084 |
R/W |
DMA2初始化源控制寄存器 |
0x00000000 |
DISRCC3 |
0x4B0000C4 |
R/W |
DMA3初始化源控制寄存器 |
0x00000000 |
DISRCCn |
位 |
描述 |
初始值 |
LOC |
[1] |
位1用于选择源的位置 0:源在系统总线(AHB) 1:源在外部总线(APB) |
0 |
INC |
[0] |
位0用于选择地址增加方式 0 = 增加 1= 固定不变 如果他是0,在burst或单传输模式时,地址按其每次传输的数据大小传输。 如果他是1,地址在传输时不会变化。(在burst模式时,地址会在burst传输时增加,但是地址也会在传输完后回到他的初始值) |
0 |
DMA初始化目的寄存器(DIDST)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DIDST0 |
0x4B000008 |
R/W |
DMA0初始化目的寄存器 |
0x00000000 |
DIDST1 |
0x4B000048 |
R/W |
DMA1初始化目的寄存器 |
0x00000000 |
DIDST2 |
0x4B000088 |
R/W |
DMA2初始化目的寄存器 |
0x00000000 |
DIDST3 |
0x4B0000C8 |
R/W |
DMA3初始化目的寄存器 |
0x00000000 |
DIDSTn |
位 |
描述 |
初始值 |
D_ADDR |
[30:0] |
用于传输的目的基地址(开始地址)。只有当CURR_DST是0并且DMA ACK为1时,这个数据才会加载到CURR_SRC。 |
0x00000000 |
DMA初始化目的控制寄存器(DIDSTC)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DIDSTC0 |
0x4B00000C |
R/W |
DMA0初始化目的控制寄存器 |
0x00000000 |
DIDSTC1 |
0x4B00004C |
R/W |
DMA1初始化目的控制寄存器 |
0x00000000 |
DIDSTC2 |
0x4B00008C |
R/W |
DMA2初始化目的控制寄存器 |
0x00000000 |
DIDSTC3 |
0x4B0000CC |
R/W |
DMA3初始化目的控制寄存器 |
0x00000000 |
DIDSTCn |
位 |
描述 |
初始值 |
CHK_INT |
[2] |
当自动加载设置后,选择中断发生时间 0:当计数器TC到达0时,中断发生 1:自动加载执行后中断发生 |
0 |
LOC |
[1] |
位1用于选择目的的位置 0:目的在系统总线(AHB) 1:目的在外部总线(APB) |
0 |
INC |
[0] |
位0用于选择地址增加方式 0 = 增加 1= 固定不变 如果他是0,在burst或单传输模式时,地址按其每次传输的数据大小传输。 如果他是1,地址在传输时不会变化。(在burst模式时,地址会在burst传输时增加,但是地址也会在传输完后回到他的初始值) |
0 |
DMA控制寄存器(DCON)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DCON0 |
0x4B000010 |
R/W |
DMA0控制寄存器 |
0x00000000 |
DCON1 |
0x4B000050 |
R/W |
DMA1控制寄存器 |
0x00000000 |
DCON2 |
0x4B000090 |
R/W |
DMA2控制寄存器 |
0x00000000 |
DCON3 |
0x4B0000D0 |
R/W |
DMA3控制寄存器 |
0x00000000 |
DCONn |
位 |
描述 |
初始值 |
DMD_HS |
[31] |
请求模式与握手模式选择 0:请求模式 1:握手模式 当获得置位DREQ,DMA控制器在这两种模式下都要开始他的传输并置位DACK。而这两种模式不同的是他们是否等待DACK失效。 在握手模式,DMA控制器在开始一个新的传输之前等待DREQ失效。如果如果他发现DREQ失效,他失效DACK然后等待另一个DREQ置位。 相反,在请求模式时,DMA控制器在DREQ失效前不会等待,他只会失效DACK然后开始另一个传输如果DREQ被置位。 我们为外部DMA请求源推荐使用握手模式来防止无意识的开始新的传输。 |
0 |
SYNC |
[30] |
选择请求/应答同步 0:请求/应答与PCLK同步(APB时钟) 1:请求/应答与HCLK同步(AHB时钟) 因此,对于连接到AHB系统总线的设备,这位将设为1,而对于连接到APB系统总线的设备,这位将设为0。而对于连接到外部系统的设备,用户应该选择该位来看这个设备是同步到AHB系统还是APB系统。 |
0 |
INT |
[29] |
CURR_TC(终端计数器)使能/失能中断设置 0:CURR_TC中断失能。用户用户不得不使用状态寄存器来观察传输计数(例如 polling) 1:当所有的传输完成时,产生中断请求(例如 当CURR_TC为0)。 |
0 |
TSZ |
[28] |
原子传输模式传输数据大小选择(例如 每次DMA传输拥有总线) 0:单元传输 1:burst传输(传输4个单元) |
0 |
SERVMODE |
[27] |
服务模式选择:单服务模式或全服务模式 0:单服务模式,在该模式下,每一次原子传输完成(单元或者四单元的burst)DMA停止,并等待下一个DMA请求。 1:全服务模式,在该模式下,一次请求将重复执行多次原子操作直到传输计数器为0。在该模式下额外的请求是不必要的。 注意:即使在全服务模式下,DMA在每次完成原子操作后释放原子总线,然后尽力去重新获得总线来防止其他主机占用总线。 |
0 |
HWSRCSEL |
[26:24] |
为每个DMA选择DMA请求源 DCON0: 000:nXDREQ0 001:UART0 010:SDI 011:Timer 100:USB device EP1 DCON1: 000:nXDREQ1 001:UART1 010:I2SSDI 011:SPI 100:USB device EP2 DCON2: 000:I2SSDO 001:I2SSDI 010:SDI 011:Timer 100:USB device EP3 DCON3: 000:UART2 001:SDI 010:SPI 011:Timer 100:USB device EP4 DCON0: 101:I2SSDO 110:PCMIN DCON1: 101:PCMOUT 110:SDI DCON2: 101:PCMIN 110:MICIN DCON3: 101:MICIN 110:PCMOUT 这些位控制4-1 MUX来为每个DMA选择DMA请求源。只有DCON的位[23]de H/W请求模式被选择时这些位才有效。 |
000 |
SWHW_SEL |
[23] |
通过软件(S/W请求模式)或者硬件(H/W请求模式)选择DMA源 0:软件请求模式,DMA通过设置DMASKTRIG寄存器的SW_TRIG位触发。 1:通过选择位[26:24]中设备触发DMA请求 |
0 |
RELOAD |
[22] |
设置重新加载开/关 0:当传输计数器现有值为0时,自动加载(例如 所有的需要的传输被执行) 1:当传输计数器现有值为0时,DMA通道(DMA REQ)关闭。通道开/关位(DMASKTRIGn[1])设置为0时(DREQ关)来阻止无意识开始的新DMA请求。 |
0 |
DSZ |
[21:20] |
用于传输的数据大小 00 = 字节 01 = 半字 10 = 字 11 = 保留 |
00 |
TC |
[19:0] |
初始传输计数(或传输节拍) 注意:真实用于传输的字节数通过下面的公式计数:DSZ x TSZ x TC。这里DSZ,TSZ(1或者4),TC分别表示数据大小DCONn[21:20],传输尺寸DCONn[28]以及初始传输计数。只有当CURR_TC为0并且DMA ACK为1时,这个值才会被加载到CURR_TC中。 |
|
DMA状态寄存器(DSTAT)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DSTAT0 |
0x4B000014 |
R |
DMA0状态寄存器 |
000000h |
DSTAT1 |
0x4B000054 |
R |
DMA1状态寄存器 |
000000h |
DSTAT2 |
0x4B000094 |
R |
DMA2状态寄存器 |
000000h |
DSTAT3 |
0x4B0000D4 |
R |
DMA3状态寄存器 |
000000h |
DSTATn |
位 |
描述 |
初始值 |
STAT |
[21:20] |
DMA控制器状态 00:DMA控制器为其他DMA请求准备就绪 01:DMA控制器正忙于传输 |
00 |
CURR_TC |
[19:0] |
传输计数器当前值 注:传输计数器初始值为DCONn[19:0]中的值,并随着每次原子操作而减一。 |
00000h |
DMA当前源寄存器(DCSRC)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DCSRC0 |
0x4B000018 |
R |
DMA0当前源寄存器 |
0x00000000 |
DCSRC1 |
0x4B000058 |
R |
DMA1当前源寄存器 |
0x00000000 |
DCSRC2 |
0x4B000098 |
R |
DMA2当前源寄存器 |
0x00000000 |
DCSRC3 |
0x4B0000D8 |
R |
DMA3当前源寄存器 |
0x00000000 |
DCSRCn |
位 |
描述 |
初始值 |
CURR_SRC |
[30:0] |
DMAn的当前源地址 |
0x00000000 |
DMA当前目的寄存器(DCDST)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DCDST0 |
0x4B00001C |
R |
DMA0当前目的寄存器 |
0x00000000 |
DCDST1 |
0x4B00005C |
R |
DMA1当前目的寄存器 |
0x00000000 |
DCDST2 |
0x4B00009C |
R |
DMA2当前目的寄存器 |
0x00000000 |
DCDST3 |
0x4B0000DC |
R |
DMA3当前目的寄存器 |
0x00000000 |
DCSRCn |
位 |
描述 |
初始值 |
CURR_DST |
[30:0] |
DMAn的当前目的寄存器 |
0x00000000 |
DMA禁止触发寄存器(DMASKTRIG)
寄存器 |
地址 |
R/W |
描述 |
重启值 |
DMASKTRIG0 |
0x4B000020 |
R/W |
DMA0禁止触发寄存器 |
000 |
DMASKTRIG1 |
0x4B000060 |
R/W |
DMA1禁止触发寄存器 |
000 |
DMASKTRIG2 |
0x4B0000A0 |
R/W |
DMA2禁止触发寄存器 |
000 |
DMASKTRIG3 |
0x4B0000E0 |
R/W |
DMA3禁止触发寄存器 |
000 |
DMASKTRIGn |
位 |
描述 |
初始值 |
STOP |
[2] |
停止DMA操作 1:当现在的原子传输完成时停止DMA,如果没有当前运行的原子传输,立即停止DMA CURR_TC, CURR_SRC, 以及CURR_DST将清零 注意:由于可能有当前的原子传输,停止操作要执行一个周期。完成停止的操作可以被检测到当检测通道开/关位(DMASKTRIGn[1])设为关闭。这个停止操作就是真实的停止了。 |
0 |
ON_OFF |
[1] |
DMA通道开/关位 0:DMA通道关闭(这个通道的DMA请求被忽略) 1:DMA通道打开,DMA请求被处理。如果我们设置DCONn[22]为无自动加载同时/或者DMASKTRIGn的STOP位设置为停止,这位将自动设为关闭。 注意:当DCONn[22]为无自动加载,当CURR_TC计数器变为0时,这位变为0 。如果DMASKTRIGn的STOP位设为1,这位将在当前原子传输完成后立即变为0 。 注:这位在DMA操作时不应该手动的改变(例如 他只能使用DCON[22]和STOP位来改变) |
0 |
SW_TRIG |
[0] |
在软件模式下触发DMA通道 1:对于这个控制器需要一个DMA操作 注意:只有当S/W请求模式已经被选中(DCONn[23])同时通道ON_OFF位被设置为1(通道打开),这个触发才有效。当DMA操作开始,这位将自动清零。 |
0 |
注意:
寄存器DISRC,DIDST以及DCON中的TC部分的值是允许你修改的。而这些修改只有当当前传输结束后才能有效(例如 当CURR_TC变为0)。同时,对其他寄存器或者域的任意模式的改变都将立即起作用。因此,当修改这些寄存器或者域时要小心。