DMA控制器
1 概述
DMA
控制器可以无需
CPU
介入而在内部存储器、外部存储器及片上外设之间传
送数据,
HPI
接口也使用
DMA
辅助端口传送数据。
DMA
具有如下的特点:
DMA
可以独立于
CPU
工作;
有
4
个标准端口(
port
)与
DARAM
、
SARAM
、外部存储器和外设相连;
一个辅助端口用于
HPI
和存储器之间的数据传送;
具有
6
个通道;
可以设置每个通道的优先级;
每个通道的传输可以由选定事件触发;
当操作完成之后,
DMA
控制器可向
CPU
发出中断。
HPI和存储器接口之间的数据传输不使用DMA通道,如果将数据从HPI传给外设接口,必须将存储器当作暂时缓存器使用。在C5509中,HPI和USB模块共用该辅助接口。
2 通道和端口
如前所述,
DMA
控制器有
6
个通道,用于
4
个标准端口之间的数据传送,每个通道可以从某个端口读取数据,也可以将数据写入某个端口。每个通道有一个
FIFO
缓冲区。如图所示,使数据的传输包括两个阶段:端口读取和端口写入。
DMA
先从源端口读取数据,并将其放到通道的
FIFO
缓冲区里,然后再从
FIFO
缓冲区取出写入目的端口。
DMA
控制器的寄存器有两套:一套是配置寄存器,供
CPU
写入所需的配置值;另一套是工作寄存器,供
DMA
工作时使用。所以,
DMA
通道正在进行数据传输时,
CPU
可以写入下次传输的配置参数,而不影响正在进行的传输。但是,寄存器DMACSDP,DMACCR,DMACICR,DMACSR,DMAGCR,DMAGSCR,和DMAGTCR不能使用这种方式配置。
传输数据时,配置寄存器的内容复制到工作寄存器,DMA控制器则使用工作寄存器的值来控制通道的工作。只要使能DMACCR的en = 1,就进行上述复制。如果使用自动初始化模式DMACCR里的AUTOINIT = 1,则该复制在块传输之间发生。
3 HPI的配置
如下图所示,
HPI
和
DMA
通道的关系由
DMAGCR
寄存器中的
EHPIEXCL
位确定。
(
1
)当
EHPIEXCL=0
,
HPI
和
DMA
通道共享
DARAM
、
SARAM
和
EMIF
。
(
2
)当
EHPIEXCL=1
,
HPI
独占
DARAM
和
SARAM
,
DMA
通道
只能访问
EMIF
和外设。
应当注意
HPI
不能访问外设端口。
4 服务链
每个标准口都可以对6个DMA通道以及HPI同时发来的请求进行仲裁,每个都标准口都有独立的功能服务链,即有软件和硬件来控制的,为访问请求提供服务的方案。虽然4个服务链功能上是独立的,但他们共享一个通用的配置。
1 DMA
通道和HPI具有可编程的优先级。通过寄存器DMACCR中的PRIO位可以设置每个通道的优先级,通过寄存器DMAGCR中的EHPIPRIO位可以设置HPI的优先级。
2 不管优先级如何设定,端口对通道和HPI的检测按照固定的顺序循环:0,1,2,3,4,5,HPI,0,1,2,3,4,5,HPI……
3 通道可以通过软件,单个地和服务链连接和断开。
4 DMAGCR库的EHPIEXCL位为1,可以使HPI单独访问DARAM和SARAM口。
5 一个通道与一个同步事件相联系,就不会产生DMA请求。
4 DMA传输配置
1
.数据传输单位
DMA
通道传输的数据单位有
4
种:
(1)字节(Byte):一个字节是DMA通道最小的数据传输单位;
(2)单元(Element):若干个字节构成的数据传输单位称为一个单元,一个单元可以是8位、16位或32位的。一个单元的传输是不能被中断的。
(3)帧(Frame):若干个单元构成的数据传输单位称为一帧。在一帧的传输过程中不能被中断。
(4)块(Block):若干个帧构成的数据传输单位称为一个块,每个通道一次或多次传输一个块。在块的传输过程中可以被中断。 对于DMA的每个通道,可以定义一块中包括帧的个数,一帧中单元的个数,一个单元中字节的个数。
2
.数据打包
DMA
控制器具有数据打包功能,比如选择
8
比特的数据传输而目
的端口是
32
位的数据总线,可以将
4
个
8
比特的数据片打包成一个
32
比特的数据包进行传输,这样会提高
DMA
的传输速率。
DMA
控
制器的数据打包功能通过参数寄存器
DMACSDP
中的
DST(SRC)PACK
字段设定。
2
.
DMA
通道控制寄存器
DMA_start
(
myhDma
)
; /*
开始传送
*/
DMA_close
(
myhDma
)
; /*
关闭通道
*/
当
DST(SRC)PACK=0
时,不打包;
当
DST(SRC)PACK=1
时,对数据打包后再传输。
3
.端口
DMA
通道传输的目的端口和源端口由参数寄存器
DMACSDP
中的
DST(SRC)
字段来确定。
当
DST(SRC)= xx00
时,目的(源)端口为
SARAM
;
当
DST(SRC)= xx01
时,目的(源)端口为
DARAM
;
当
DST(SRC)= xx10
时,目的(源)端口为
EMIF
;
当
DST(SRC)= xx11
时,目的(源)端口为
Peripheral
。
4
.
数据源和目的地址
DMA控制器采用字节地址,一个DMA通道的数据源起始地址由源起始地址寄存器DMACSSAL和DMACSSAU指定,其中DMACSSAL存放低16位地址,DMACSSAU存放高位地址;目的起始地址由目的起始地址寄存器DMACDSAL和DMACDSAU指定,其中DMACDSAL存放低16位地址,DMACDSAU存放高位地址。
DMA通道在数据传输过程中的地址修改方式由DMACCR寄存器中的DST(SRC) AMODE字段确定。
当DST(SRC)AMODE=00时,目的(源)地址为固定地址,用于单元的传输;
当DST(SRC)AMODE=01时,目的(源)地址在每个单元传输完后自动增加。根据数据的位数是8位、16位还是32位,地址分别增加1、2或4。
当
DST(SRC)AMODE=10
时,目的(源)地址在每个单元传输完
后自动增加一个索引值,索引值由单元索引寄存器
DMACEI/DMACSEI
确定。
当
DST(SRC)AMODE=11
时,目的(源)地址在每个单元传
输完后按单元索引和帧索引自动增加,索引值由单元索引寄存器
DMACEI/DMACSEI
和帧索引寄存器
DMACFI/DMACSFI
确定,
又称为双索引。
5 DMA控制器的寄存器
表中列出了
DMA
控制器的寄存器,其中有三个全局控制寄存器
DMAGCR
、
DMAGSCR
和
DMAGTCR
对所有的通道进行控制,此外还有通道配置寄存器用于对每个通道进行控制。
寄
存
器
名
|
说
明
|
数
量
|
DMAGCR
|
全局控制寄存器,用于配置
HPI
|
1
|
DMAGSCR*
|
全局软件兼容寄存器,用于控制
DMA
获得目的单元、目的
帧索引的方式
|
1
|
DMAGTCR*
|
全局超时控制寄存器,用于使能或禁止
SARAM
和
DARAM
端口的超时计数器
|
1
|
DMACCR
|
通道控制寄存器,
用于配置优先级等
|
每个通道一个
|
DMACICR
|
通道中断寄存器,用于中断使能
|
每个通道一个
|
DMACSR
|
状态寄存器
|
每个通道一个
|
DMACSDP
|
源和目的参数寄存器,用于配置数据块参数
|
每个通道一个
|
DMACSSAL
|
源起始地址寄存器(低地址)
|
每个通道一个
|
DMACSSAU
|
源起始地址寄存器(高地址)
|
每个通道一个
|
DMACDSAL
|
目的起始地址寄存器(低地址)
|
每个通道一个
|
DMACDSAU
|
目的起始地址寄存器(高地址)
|
每个通道一个
|
DMACEN
|
单元数量寄存器
|
每个通道一个
|
DMACFN
|
帧数量寄存器
|
每个通道一个
|
DMACEI/DMACSEI
|
单元索引寄存器
|
每个通道一个
|
DMACFI/DMACSFI
|
帧索引寄存器
|
每个通道一个
|
DMACDEI*
|
目的单元索引寄存器
|
每个通道一个
|
DMACDFI*
|
目的帧索引寄存器
|
每个通道一个
|
DMACSAC*
|
源地址计数寄存器
|
每个通道一个
|
DMACDAC*
|
目的地址计数寄存器
|
每个通道一个
|
*
标注的寄存器只在
TMS320VC5509a
和
TMS320VC5510
中应用。
1
.
DMA
全局控制寄存器
位
|
字
段
|
数
值
|
说
明
|
15
~
4
|
Reserved
|
|
保留位
|
3
|
Reserved
|
1
|
保留位(通常写入
1
)
|
2
|
FREE
|
0
1
|
遇到断点时的处理
停止
DMA
传输
继续
DMA
传输
|
1
|
EHPIEXCL
|
0
1
|
HPI
的配置
与通道共享
独占内部
RAM
|
0
|
EHPIPRIO
|
0
1
|
HPI
优先级
低优先级
高优先级
|
位
|
字
段
|
数
值
|
说
明
|
15
~
14
|
DSTAMODE
|
00
~
11
|
目的地址修改模式
|
13
~
12
|
SRCAMODE
|
00
~
11
|
源地址修改模式
|
11
|
ENDPROG
|
0
1
|
编程结束
|
10
|
Reserved
|
0
|
保留位
|
9
|
REPEAT
|
0
1
|
多次传输配置时的重复条件
在本次传输结束后,只有当
ENDPROG=1
,才装入新的配置值,开始
下次传输
在本次传输结束后,立即装入新的配置
值,开始下次传输
|
8
|
AUTOINIT
|
0
1
|
多次传输配置时的自动初始
自动初始禁止
自动初始使能
|
7
|
EN
|
0
1
|
通道使能
禁止
使能
|
6
|
PRIO
|
0
1
|
通道优先级
低优先级
高优先级
|
5
|
FS
|
0
1
|
帧
/
单元同步
单元同步
帧同步
|
4-0
|
SYNC
|
|
同步事件
|
3
.源和目的参数寄存器
位
|
字
段
|
数
值
|
说
明
|
15
~
14
|
DSTBEN
|
00
、
01
10
11
|
目的端口突发使能
目的端口突发禁止
目的端口突发使能
保留
|
13
|
DSTPACK
|
0
1
|
目的端口打包使能
禁止
使能
|
12
~
9
|
DST
|
xx00
xx01
xx10
xx11
|
目的端口类型
目的端口为
SARAM
目的端口为
SARAM
目的端口为
EMIF
目的端口为
Peripherals
|
8
~
7
|
SRCBEN
|
00
、
01
10
11
|
源端口突发使能
禁止
使能
保留
|
6
|
SRCPACK
|
0
1
|
源端口打包使能
禁止
使能
|
5
~
2
|
SRC
|
|
源端口类型(同
DST
)
|
1
~
0
|
DATATYPE
|
00
01
10
11
|
数据传输单位
8
位
16
位
32
位
保留
|
4
.起始地址寄存器
寄存器名
|
位
|
字
段
|
说
明
|
DMACSSAL
|
15
~
0
|
SSAL
|
源起始地址低
16
位
|
DMACSSAU
|
SSAU
|
源起始地址高位
| |
DMACDSAL
|
DSAL
|
目的起始地址低
16
位
| |
DMACDSAU
|
DSAU
|
目的起始地址高位
|
5
.单元数量和帧数量寄存器
寄存器名
|
位
|
字
段
|
说
明
|
DMACEN
|
15
~
0
|
ELEMENTNUM
|
每帧包含的单元数量
|
DMACFN
|
FRAMENUM
|
每块包含的帧数量
|
5
.单元索引寄存器和帧索引寄存器
寄存器名
|
位
|
字
段
|
说
明
|
DMACEI/DMACSEI
|
15
~
0
|
ELEMENTNDX
|
单元索引值
|
DMACFI/DMACSFI
|
FRAMENDX
|
帧索引值
| |
DMACDEI
|
ELEMENTNDX
|
目的单元索引值
| |
DMACDFI
|
FRAMENTDX
|
目的帧索引值
|
6 使用方法及实例
调用
DMA
库函数首先要在头文件中包含
csl_dma.h
文件,接下来介
绍
DMA
配置结构。
DMA
配置结构名为
DMA_Config
,
DMA_Config
包含如下成员:
Uint16 dmacsdp ;DMA
通道控制寄存器
Uint16 dmaccr ;DMA
通道中断寄存器
Uint16 dmacicr ;DMA
通道状态寄存器
(
DMA_AdrPtr
)
dmacssal ;DMA
通道源起始地址(低字段)
Uint16 dmacssau ;DMA
通道源起始地址(高字段)
(
DMA_AdrPtr
)
dmacdsal ;DMA
通道目的地址(低字段)
Uint16 dmacdsau ;
通道目的地址(高字段)
Uint16 dmacen ;DMA
通道数据单元数量寄存器
Uint16 dmacfn ;DMA
通道帧数寄存器
对于
CHIP_5509, CHIP_5510PG1_x
(
x=0, 2
)
Int16 dmacfi ;DMA
通道帧索引寄存器
Int16 dmacei ;DMA
通道单元索引寄存器
对于
CHIP_5510PG2_x
(
x=0, 1, 2
)
, 5509A, 5502
Int16 dmacsfi ;DMA
通道源帧索引寄存器
Int16 dmacsei ;DMA
通道源单元索引寄存器
Int16 dmacdfi ;DMA
通道目的帧索引寄存器
Int16 dmacdei DMA
通道目的单元索引寄存器
DMA_Config myconfig = {
……
}
声明配置结构之后,需要调用
DMA_open
函数,初始化
DMA
句柄
:
DMA_Handle myhDma;
myhDma = DMA_open
(
DMA_CHA0, 0
)
;/*
打开
DMA
通道
0 */
接下来调用
DMA_config
函数对
DMA
进行配置:
myconfig.dmacssal =
(
DMA_AdrPtr
)(((
Uint16
)(
myconfig.dmacssal
)
<<1
)
&0xFFFF
)
;
myconfig.dmacdsal =
(
DMA_AdrPtr
)(((
Uint16
)(
myconfig.dmacdsal
)
<<1
)
&0xFFFF
)
;
myconfig.dmacssau -
(((
Uint32
)
&src
)
>> 15
)
& 0xFFFF;
myconfig.dmacdsau -
(((
Uint32
)
&dst
)
>> 15
)
& 0xFFFF;
DMA_config
(
myhDma, &myConfig
)
; /*
配置通道
*/
配置完成之后,调用
DMA_start
()函数开始
DMA
传送:
等待
DMA
状态寄存器的帧状态位指示传输结束:
while
(
!DMA_FGETH
(
myhDma, DMACSR, FRAME
))
{
}
之后关闭句柄: