3. T113芯片手册导读:UART控制器寄存器描述、DMA控制器寄存器描述、中断控制器与DMA请求映射关系
本章是全志T113 UART DMA驱动开发的基石。只有精确理解UART控制器、DMA控制器以及中断控制器之间的寄存器级交互与请求映射关系,才能正确配置硬件并编写出稳定高效的驱动程序。我们将从三份核心手册(User Manual、Technical Reference Manual、Datasheet)中提取关键寄存器描述与映射逻辑,并以结构化方式呈现。
3.1 UART控制器寄存器描述
T113集成了最多8路UART(UART0~UART7),其中UART0固定用于调试终端。每路UART的寄存器基地址偏移0x1000,内部寄存器采用32位宽、小端模式。驱动开发中必须重点关注的寄存器组如下:
| 偏移地址 | 寄存器名称 | 功能描述 | 驱动关注点 |
|---|---|---|---|
| 0x00 | USR | UART状态寄存器 | TX/RX FIFO空/满状态、线路空闲标志 |
| 0x04 | UCR | UART控制寄存器 | 使能DMA模式(TX/RX)、FIFO使能、波特率分频 |
| 0x08 | ULCR | 线路控制寄存器 | 数据位、停止位、校验模式、DLAB位 |
| 0x0C | UMCR | 调制解调控制寄存器 | 流控使能(RTS/CTS) |
| 0x10 | ULSR | 线路状态寄存器 | 接收错误标志(溢出、帧错误、奇偶错误) |
| 0x14 | UMSR | 调制解调状态寄存器 | CTS/DCD/DSR状态变化 |
| 0x1C | USR2 | UART状态寄存器2 | TX/RX DMA请求状态 |
| 0x20 | UTCR | UART发送控制寄存器 | TX DMA触发阈值(1~64字节) |
| 0x24 | URCR | UART接收控制寄存器 | RX DMA触发阈值(1~64字节) |
| 0x80 | URB | 接收缓冲寄存器 | DMA读取数据端口(FIFO顶部) |
| 0x84 | UTB | 发送缓冲寄存器 | DMA写入数据端口(FIFO尾部) |
关键提示:UART的DMA模式使能位位于UCR[2](TX_DMA_EN)和UCR[3](RX_DMA_EN)。同时必须将UCR[0](FIFO_EN)置1,否则DMA请求不会产生。触发阈值寄存器(UTCR/URCR)决定了DMA请求的触发时机,通常设置为FIFO深度的一半(32字节)以平衡延迟与吞吐量。
3.2 DMA控制器寄存器描述
T113的DMA控制器支持8个独立通道,每个通道可配置为内存到内存、内存到外设、外设到内存三种传输模式。UART的DMA传输属于外设到内存(RX)和内存到外设(TX)模式。关键寄存器分组如下:
| 偏移地址 | 寄存器名称 | 功能描述 | 驱动关注点 |
|---|---|---|---|
| 0x00 | DMA_EN | DMA控制器使能寄存器 | 全局使能位 |
| 0x04 | DMA_IRQ_EN | 中断使能寄存器 | 各通道传输完成/错误中断使能 |
| 0x08 | DMA_IRQ_STA | 中断状态寄存器 | 读取中断源,写1清除 |
| 0x10 + ch*0x20 | DMA_CHx_CFG | 通道x配置寄存器 | 传输方向、数据宽度、突发长度、优先级 |
| 0x14 + ch*0x20 | DMA_CHx_SRC | 通道x源地址寄存器 | 外设地址(UART数据端口)或内存地址 |
| 0x18 + ch*0x20 | DMA_CHx_DST | 通道x目的地址寄存器 | 内存地址或外设地址 |
| 0x1C + ch*0x20 | DMA_CHx_CNT | 通道x传输计数寄存器 | 传输字节数(最大64KB) |
| 0x20 + ch*0x20 | DMA_CHx_CTL | 通道x控制寄存器 | 启动传输、停止传输、循环模式 |
寄存器配置要点:
- DMA_CHx_CFG[3:0]:选择外设类型(UART0~UART7对应值0x0~0x7)
- DMA_CHx_CFG[7:4]:数据宽度(0:8位、1:16位、2:32位),UART固定为8位
- DMA_CHx_CFG[11:8]:突发长度(0:1、1:4、2:8、3:16),建议设置为4或8
- DMA_CHx_CTL[0]:写1启动传输,硬件自动清零
- DMA_CHx_CTL[1]:循环模式使能,用于连续数据流场景
3.3 中断控制器与DMA请求映射关系
T113使用GIC(Generic Interrupt Controller)v2架构,支持SPI(Shared Peripheral Interrupt)和PPI(Private Peripheral Interrupt)。UART和DMA的中断号在芯片手册的“Interrupt Mapping Table”中定义。以下是UART与DMA相关的中断映射关系:
| 中断源 | 中断类型 | SPI ID | 描述 |
|---|---|---|---|
| UART0 | SPI | 32 | UART0全局中断(线路状态、调制解调状态) |
| UART1 | SPI | 33 | UART1全局中断 |
| UART2 | SPI | 34 | UART2全局中断 |
| UART3 | SPI | 35 | UART3全局中断 |
| UART4 | SPI | 36 | UART4全局中断 |
| UART5 | SPI | 37 | UART5全局中断 |
| UART6 | SPI | 38 | UART6全局中断 |
| UART7 | SPI | 39 | UART7全局中断 |
| DMA通道0 | SPI | 48 | DMA通道0传输完成/错误 |
| DMA通道1 | SPI | 49 | DMA通道1传输完成/错误 |
| DMA通道2 | SPI | 50 | DMA通道2传输完成/错误 |
| DMA通道3 | SPI | 51 | DMA通道3传输完成/错误 |
| DMA通道4 | SPI | 52 | DMA通道4传输完成/错误 |
| DMA通道5 | SPI | 53 | DMA通道5传输完成/错误 |
| DMA通道6 | SPI | 54 | DMA通道6传输完成/错误 |
| DMA通道7 | SPI | 55 | DMA通道7传输完成/错误 |
重要注意事项:
- UART的中断(SPI 32~39)在DMA模式下不应使能,否则会导致CPU被频繁打断,失去DMA的卸载优势。
- DMA传输完成后,由DMA通道中断(SPI 48~55)通知CPU。驱动中只需注册对应的DMA通道中断处理函数。
- UART的DMA请求线是硬件直连的,不需要软件配置中断控制器来路由DMA请求。DMA请求直接由UART的DMA接口产生,经DMA控制器处理后上报完成中断。
- 中断优先级配置:建议将DMA中断优先级设为高于UART中断(如果UART中断仍使能),避免数据丢失。
3.4 驱动开发中的寄存器操作示例
以下代码展示了如何在驱动初始化阶段配置UART的DMA模式以及对应的DMA通道。代码基于Linux内核驱动框架,使用readl/writel访问寄存器。
/* UART DMA模式初始化示例 */
static void uart_dma_init(struct uart_port *port)
{
void __iomem *base = port->membase;
u32 val;
/* 1. 使能UART FIFO */
val = readl(base + UCR);
val |= UCR_FIFO_EN;
writel(val, base + UCR);
/* 2. 设置TX/RX DMA触发阈值(32字节) */
writel(32, base + UTCR); /* TX触发阈值 */
writel(32, base + URCR); /* RX触发阈值 */
/* 3. 使能TX/RX DMA模式 */
val = readl(base + UCR);
val |= UCR_TX_DMA_EN | UCR_RX_DMA_EN;
writel(val, base + UCR);
/* 4. 配置DMA通道(以UART0 RX为例) */
struct dma_slave_config config;
config.direction = DMA_DEV_TO_MEM;
config.src_addr = base + URB; /* 外设数据端口地址 */
config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
config.src_maxburst = 4; /* 突发长度4 */
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
config.dst_maxburst = 4;
dmaengine_slave_config(port->rx_dma_chan, &config);
}
调试建议:在首次配置DMA时,建议先使用单次传输模式(非循环模式)验证基本功能。通过读取
DMA_CHx_CNT寄存器可以确认实际传输的字节数,与预期值对比即可判断配置是否正确。同时,观察USR2寄存器中的DMA请求状态位,可以确认UART是否正在向DMA发送请求。