22. 直接内存存取控制器 (DMA)
22.1. 概述
DMA模块支持特定外设(UART,USART,SPI,QSPI,SARADC,MPU)和存储器(SRAM)之间或总线地址和存储器(SRAM)之间的高速数据传输,无需CPU干涉,数据可以快速的通过DMA传输,从而节省了CPU的资源来做其他操作。
22.2. 特性
2个独立的可配置的通道
每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置
多个请求间的优先权可以通过软件编程设置,优先权设置相等时由硬件决定(请求0优先于请求1,依此类推)
支持传输宽度(字节、半字、全字)可配置。源和目标地址必须按数据传输宽度对齐
支持循环的缓冲器管理
支持步进 (TIMER触发) 传输
每个通道都有3个事件标志(DMA自定义数目传输完成、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。
支持存储器和存储器间的传输
支持外设和存储器、存储器和外设之间的传输
可编程的数据传输数目:最大为65535
22.3. 功能描述
DMA 控制器通过与 Cortex®-M0 内核共享系统总线来执行直接内存传输。
22.3.1. DMA 事务
在发生一个事件后,外设向DMA控制器发送一个请求信号。DMA控制器根据通道的优先权处理请求。当DMA控制器开始访问发出请求的外设时,DMA控制器立即发送给它一个应答信号。当从DMA控制器得到应答信号时,外设立即释放它的请求。一旦外设释放了这个请求,DMA控制器同时撤销应答信号。如果有更多的请求时,外设可以启动下一个周期。
总之,每次DMA传送由3个操作组成:
从外设数据寄存器或者从当前外设/存储器地址寄存器指示的存储器地址取数据,第一次传输时的开始地址是DMA_PARx或DMA_MARx寄存器指定的外设基地址或存储器单元。
存数据到外设数据寄存器或者当前外设/存储器地址寄存器指示的存储器地址,第一次传输时的开始地址是DMA_PARx或DMA_MARx寄存器指定的外设基地址或存储器单元。
执行一次DMA_NDTx寄存器的递减操作,该寄存器包含未完成的操作数目。
22.3.2. 仲裁器
仲裁器根据通道请求的优先级来启动外设/存储器的访问。
优先权管理分2个阶段:
软件:每个通道的优先级可以在DMA_CRx寄存器中设置,可设置为0~0xF,数值越小,优先级越高
硬件:如果2个请求有相同的软件优先级,则较低编号的通道比较高编号的通道有较高的优先权。举个例子,通道2优先于通道4。
22.3.3. DMA 通道
每个通道都可以在有固定地址的外设寄存器和存储器地址之间执行DMA传输。DMA传输数据量是可编程的,最大达到65535。包含要传输的数据项数量的寄存器,在每次传输后递减。
传输单位大小
外设和存储器的传输数据单位可以通过DMA_CRx寄存器中的PSIZ和MSIZ位编程。
指针递增
通过设置DMA_CRx寄存器中的PINC和MINC标志位,外设和存储器的指针在每次传输后可以有选择地完成自动增量。 当设置为增量模式时,下一个要传输的地址将是前一个地址加上增量值,增量值取决与所选的数据宽度为1、2或4。 第一个传输的地址是存放在DMA_PARx/DMA_MARx寄存器中地址。 在传输过程中,这些寄存器保持它们初始的数值,软件不能改变和读出当前正在传输的地址(它在内部的当前外设/存储器地址寄存器中)。
当通道配置为非循环模式时,传输结束后(即传输计数变为0)将不再产生DMA操作。 要开始新的DMA传输,需要在关闭DMA通道的情况下,在DMA_NDTx寄存器中重新写入传输数目。
在循环模式下,最后一次传输结束时,DMA_NDTx寄存器的内容会自动地被重新加载为其初始数值, 内部的当前外设/存储器地址寄存器也被重新加载为DMA_PARx/DMA_MARx寄存器设定的初始基地址。
通道配置过程
下面是配置DMA通道x的过程(x代表通道号):
在DMA_PARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将是数据传输的源或目标。
在DMA_MARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数据将从这个地址读出或写入这个地址。
在DMA_NDTx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
在DMA_CRx寄存器的PL[3:0]位中设置通道的优先级。
在DMA_CRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
设置DMA_CRx寄存器的EN位,启动该通道。
一旦启动了DMA通道,它既可响应连到该通道上的外设的DMA请求。
当传输一半的数据后,半传输标志(HALF)被置1,当设置了允许半传输中断位(HALFIE)时,将产生一个中断请求。在数据传输结束后,传输完成标志(DONE)被置1,当设置了允许传输完成中断位(DONEIE)时,将产生一个中断请求。
循环模式
循环模式用于处理循环缓冲区和连续的数据传输(如ADC的扫描模式)。在DMA_CRx寄存器中的CIRC位用于开启这一功能。当启动了循环模式,数据传输的数目变为0时,将会自动地被恢复成配置通道时设置的初值,DMA操作将会继续进行。
存储器到存储器模式
DMA通道的操作可以在没有外设请求的情况下进行,这种操作就是存储器到存储器模式。
当设置了DMA_CRx寄存器中的MEM2MEM位之后,在软件设置了DMA_CRx寄存器中的EN位启动DMA通道时,DMA传输将马上开始。 当DMA_NDTx寄存器变为0时,DMA传输结束。存储器到存储器模式不能与循环模式同时使用。
22.3.4. 错误管理
读写一个保留的地址区域,将会产生DMA传输错误。当在DMA读写操作时发生DMA传输错误时, 硬件会自动地清除发生错误的通道所对应的通道配置寄存器 (DMA_CRx)的EN位,该通道操作被停止。 此时,在DMA_IF寄存器中对应该通道的传输错误中断标志位(ERR)将被置位,如果在DMA_CRx寄存器中设置了传输错误中断允许位,则将产生中断。
22.3.5. 通道请求信号
通道 |
请求选择 |
读内存请求信号 |
写内存请求信号 |
---|---|---|---|
CH0 |
0 |
UART0TX |
USART0RX |
1 |
SPI0TX |
UART1RX |
|
2 |
QSPI0TX |
MPURX |
|
3 |
/ |
ADC0SEQ1 |
|
CH1 |
0 |
USART0TX |
UART0RX |
1 |
UART1TX |
SPI0RX |
|
2 |
MPUTX |
QSPI0RX |
|
3 |
/ |
ADC1SEQ1 |
每个通道有8个请求信号,通道配置时选择其中一个用作DMA搬运请求信号。
8个信号分为两组:4个读内存请求信号、4个写内存请求信号。 读内存请求信号是指此信号请求从内存指定位置读取数据,写入指定外设数据寄存器中。 写内存请求信号是指此信号请求从指定外设数据寄存器读取数据,写入指定内存地址。
22.4. 寄存器映射
名称 |
偏移 |
复位值 |
---|---|---|
DMA BASE:0x40000800 |
||
IF |
0x00 |
0x00000000 |
IFC |
0x04 |
0x00000000 |
MUX |
0x10 + 0x20 * CH |
0x00000000 |
CR |
0x14 + 0x20 * CH |
0x00000000 |
NDT |
0x18 + 0x20 * CH |
0x00000000 |
PAR |
0x1C + 0x20 * CH |
0x00000000 |
MAR |
0x20 + 0x20 * CH |
0x00000000 |
22.5. 寄存器描述
22.5.1. IF
偏移: 0x00 |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ERR1 |
HALF1 |
DONE1 |
GLB1 |
ERR0 |
HALF0 |
DONE0 |
GLB0 |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
7 |
ERR1 |
RO |
通道1传输出错中断标志 |
6 |
HALF1 |
RO |
通道1传输完成一半中断标志 |
5 |
DONE1 |
RO |
通道1传输完成中断标志 |
4 |
GLB1 |
RO |
通道1全局中断标志 |
3 |
ERR0 |
RO |
通道0传输出错中断标志 |
2 |
HALF0 |
RO |
通道0传输完成一半中断标志 |
1 |
DONE0 |
RO |
通道0传输完成中断标志 |
0 |
GLB0 |
RO |
通道0全局中断标志 |
22.5.2. IFC
偏移: 0x04 |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ERR1 |
HALF1 |
DONE1 |
GLB1 |
ERR0 |
HALF0 |
DONE0 |
GLB0 |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
7 |
ERR1 |
WO |
通道1传输出错中断标志清除 |
6 |
HALF1 |
WO |
通道1传输完成一半中断标志清除 |
5 |
DONE1 |
WO |
通道1传输完成中断标志清除 |
4 |
GLB1 |
WO |
通道1全局中断标志清除 |
3 |
ERR0 |
WO |
通道0传输出错中断标志清除 |
2 |
HALF0 |
WO |
通道0传输完成一半中断标志清除 |
1 |
DONE0 |
WO |
通道0传输完成中断标志清除 |
0 |
GLB0 |
WO |
通道0全局中断标志清除 |
22.5.3. MUX
偏移: 0x10 + 0x20 * CH |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
EXTHSEN |
EXTHSSIG |
||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
MWRHSEN |
MWRHSSIG |
MRDHSEN |
MRDHSSIG |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
11 |
EXTHSEN |
R/W |
外部握手使能 |
10:8 |
EXTHSSIG |
R/W |
外部握手信号 0 TIMR0 1 TIMR1 2 TIMR2 3 TIMR3 5 DMA_TRIG0 6 DMA_TRIG1 |
7 |
MWRHSEN |
R/W |
内存写握手使能 |
5:4 |
MWRHSSIG |
R/W |
内存写握手信号 |
3 |
MRDHSEN |
R/W |
内存读握手使能 |
1:0 |
MRDHSSIG |
R/W |
内存读握手信号 |
22.5.4. CR
偏移: 0x14 + 0x20 * CH |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
MEM2MEM |
|||||||
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
PL |
MSIZ |
PSIZ |
|||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
MINC |
PINC |
CIRC |
DIR |
ERRIE |
HALFIE |
DONEIE |
EN |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
16 |
MEM2MEM |
R/W |
内存到内存搬运使能 |
15:12 |
PL |
R/W |
通道传输优先级 |
11:10 |
MSIZ |
R/W |
内存访问单元大小,0 字节,1 半字,2 字 |
9:8 |
PSIZ |
R/W |
外设访问单元大小,0 字节,1 半字,2 字 |
7 |
MINC |
R/W |
内存地址递增 |
6 |
PINC |
R/W |
外设地址递增 |
5 |
CIRC |
R/W |
循环模式使能 |
4 |
DIR |
R/W |
传输方向,0 从外设传搬运到内存,1 从内存搬运到外设 |
3 |
ERRIE |
R/W |
传输错误中断使能 |
2 |
HALFIE |
R/W |
传输完成一半中断使能 |
1 |
DONEIE |
R/W |
传输完成中断使能 |
0 |
EN |
R/W |
通道使能 |
22.5.5. NDT
偏移: 0x18 + 0x20 * CH |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
HALF |
|||||||
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
HALF |
|||||||
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
LEN |
|||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
LEN |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:16 |
HALF |
R/W |
传输 HALF 指定个数数据后,置位 DMA->IF.HALF 中断标志位 |
15:0 |
LEN |
R/W |
通道关闭时,写入要传输的数据个数;通道使能后,指示剩余的待传输数据数目 |
22.5.6. PAR
偏移: 0x1C + 0x20 * CH |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
ADDRESS |
|||||||
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
ADDRESS |
|||||||
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
ADDRESS |
|||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ADDRESS |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:0 |
ADDRESS |
R/W |
通道外设地址 |
22.5.7. MAR
偏移: 0x20 + 0x20 * CH |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
ADDRESS |
|||||||
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
ADDRESS |
|||||||
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
ADDRESS |
|||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ADDRESS |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:0 |
ADDRESS |
R/W |
通道内存地址 |