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位宽、小端模式。驱动开发中必须重点关注的寄存器组如下:

偏移地址寄存器名称功能描述驱动关注点
0x00USRUART状态寄存器TX/RX FIFO空/满状态、线路空闲标志
0x04UCRUART控制寄存器使能DMA模式(TX/RX)、FIFO使能、波特率分频
0x08ULCR线路控制寄存器数据位、停止位、校验模式、DLAB位
0x0CUMCR调制解调控制寄存器流控使能(RTS/CTS)
0x10ULSR线路状态寄存器接收错误标志(溢出、帧错误、奇偶错误)
0x14UMSR调制解调状态寄存器CTS/DCD/DSR状态变化
0x1CUSR2UART状态寄存器2TX/RX DMA请求状态
0x20UTCRUART发送控制寄存器TX DMA触发阈值(1~64字节)
0x24URCRUART接收控制寄存器RX DMA触发阈值(1~64字节)
0x80URB接收缓冲寄存器DMA读取数据端口(FIFO顶部)
0x84UTB发送缓冲寄存器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字节)以平衡延迟与吞吐量。
UART控制器内部寄存器与DMA接口结构 UART 控制器 USR (0x00) UCR (0x04) ULCR (0x08) UTCR (0x20) URCR (0x24) USR2 (0x1C) ... TX FIFO (64B) RX FIFO (64B) URB (0x80) UTB (0x84) DMA 接口 TX_DMA_REQ (UCR[2]) RX_DMA_REQ (UCR[3]) DMA_ACK 中断控制器 UARTx_IRQn DMA_TC_IRQn DMA_ERR_IRQn AHB 系统总线 说明:UART通过内部DMA接口向DMA控制器发送请求,DMA完成后通过中断控制器上报完成中断

3.2 DMA控制器寄存器描述

T113的DMA控制器支持8个独立通道,每个通道可配置为内存到内存、内存到外设、外设到内存三种传输模式。UART的DMA传输属于外设到内存(RX)和内存到外设(TX)模式。关键寄存器分组如下:

偏移地址寄存器名称功能描述驱动关注点
0x00DMA_ENDMA控制器使能寄存器全局使能位
0x04DMA_IRQ_EN中断使能寄存器各通道传输完成/错误中断使能
0x08DMA_IRQ_STA中断状态寄存器读取中断源,写1清除
0x10 + ch*0x20DMA_CHx_CFG通道x配置寄存器传输方向、数据宽度、突发长度、优先级
0x14 + ch*0x20DMA_CHx_SRC通道x源地址寄存器外设地址(UART数据端口)或内存地址
0x18 + ch*0x20DMA_CHx_DST通道x目的地址寄存器内存地址或外设地址
0x1C + ch*0x20DMA_CHx_CNT通道x传输计数寄存器传输字节数(最大64KB)
0x20 + ch*0x20DMA_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]:循环模式使能,用于连续数据流场景
DMA通道与外设连接架构 DMA 控制器 通道0 (UART0 TX) 通道1 (UART0 RX) 通道2 (UART1 TX) 通道3 (UART1 RX) 通道4~7 (其他外设) UART 外设 UART0 (调试) UART1 (用户) UART2~UART7 DMA请求线 系统内存 TX DMA Buffer RX DMA Buffer 描述符链表 中断控制器 DMA_TC_IRQ DMA_ERR_IRQ 说明:每个DMA通道独立配置源/目的地址,通过外设请求线触发传输,完成后上报中断

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描述
UART0SPI32UART0全局中断(线路状态、调制解调状态)
UART1SPI33UART1全局中断
UART2SPI34UART2全局中断
UART3SPI35UART3全局中断
UART4SPI36UART4全局中断
UART5SPI37UART5全局中断
UART6SPI38UART6全局中断
UART7SPI39UART7全局中断
DMA通道0SPI48DMA通道0传输完成/错误
DMA通道1SPI49DMA通道1传输完成/错误
DMA通道2SPI50DMA通道2传输完成/错误
DMA通道3SPI51DMA通道3传输完成/错误
DMA通道4SPI52DMA通道4传输完成/错误
DMA通道5SPI53DMA通道5传输完成/错误
DMA通道6SPI54DMA通道6传输完成/错误
DMA通道7SPI55DMA通道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中断仍使能),避免数据丢失。
中断请求与DMA请求的完整路径 UART 外设 DMA请求线 中断线 (SPI 32~39) DMA 控制器 通道完成/错误 中断线 (SPI 48~55) 中断控制器 中断分发 到CPU核心 CPU 核心 DMA模式下此路径禁用 说明:DMA模式下,数据流经UART→DMA控制器→内存,中断路径为DMA控制器→中断控制器→CPU

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发送请求。