在汽车电子和导航系统的图形显示控制器(GDC)应用中,DMA(直接内存访问)技术是实现高速数据传输的关键。传统32位接口通过专用信号线(DREQ/DRACK)实现DMA控制,而Lime系列GDC引入的16位SRAM和地址复用模式采用了创新的连续地址访问机制。这种设计既保持了32位数据带宽,又兼容了16位接口的灵活性,特别适合VRAM写入等图形处理场景。
Lime的16位接口模式包含三种配置:16位专用SRAM接口、16位地址/数据复用接口以及32位地址/数据复用接口。与传统32位非复用接口不同,这些模式取消了专用的DMA控制信号(DREQ/DACK/DTACK),转而采用地址范围识别机制来区分CPU和DMA访问。
关键创新点在于:
注意:在未正确设置DMA地址窗口的情况下,CPU和DMA的16位数据会被错误地打包到同一32位数据块中,导致VRAM写入异常。
实现正确DMA传输需要配置以下核心寄存器(假设HostBase为0x80000000):
| 寄存器地址 | 名称 | 功能描述 | 配置示例值 |
|---|---|---|---|
| 0x80000500 | DMA_ST_ADR | DMA传输起始地址 | 0xA0000000 |
| 0x80000504 | DMA_ED_ADR | DMA传输结束地址 | 0xA00FFFFF |
| 0x80000508 | DMA_CTRL | 传输控制(突发长度等) | 0x00000010 |
地址范围设置需要遵循以下原则:
在16位接口模式下,DMA传输时序与普通CPU访问完全一致,但内部处理流程存在本质差异。以下是典型的VRAM写入时序:
初始化阶段:
数据传输阶段:
c复制// 伪代码示例:主机端DMA配置
void setup_dma_transfer(void* src, uint32_t dest, uint32_t length) {
DMA->SRC_ADDR = (uint32_t)src;
DMA->DST_ADDR = dest; // 必须在DMA_ST_ADR~DMA_ED_ADR范围内
DMA->LENGTH = length;
DMA->CTRL = DMA_CTRL_16BIT | DMA_CTRL_BURST_8;
}
数据打包流程:
当系统需要交替进行CPU寄存器访问和DMA传输时,Lime通过以下机制确保数据正确路由:
地址解码优先级:
数据缓冲设计:
典型混合访问序列示例:
code复制1. CPU写寄存器A(16位低半字)
2. DMA写VRAM地址X(16位低半字)
3. CPU写寄存器A(16位高半字)
4. DMA写VRAM地址X(16位高半字)
关键点:必须确保配对的16位访问顺序正确,否则会导致数据错位。
以常见的1920x720 TFT启动画面为例,其数据传输优化方案如下:
传统32位模式:
16位地址复用模式:
传输时间:~9.1ms(增加约10%)
节省12根信号线(DREQ/DACK等)
实际测试数据:
| 模式 | 传输时间 | 布线复杂度 | 功耗 |
|---|---|---|---|
| 32位非复用 | 8.3ms | 高 | 120mW |
| 16位地址复用 | 9.1ms | 中 | 95mW |
| 16位SRAM | 8.8ms | 低 | 88mW |
问题1:VRAM中出现数据错位
问题2:DMA传输性能低于预期
问题3:CPU访问期间DMA数据丢失
对于需要分块更新VRAM的场景,可采用动态重配DMA地址窗口的方法:
c复制void update_vram_block(uint32_t block_num) {
// 禁用DMA传输
GDC->DMA_CTRL &= ~DMA_ENABLE;
// 更新地址窗口
uint32_t start = VRAM_BASE + block_num * BLOCK_SIZE;
GDC->DMA_ST_ADR = start;
GDC->DMA_ED_ADR = start + BLOCK_SIZE - 1;
// 重新使能DMA
GDC->DMA_CTRL |= DMA_ENABLE;
}
当主机CPU采用32位总线而外设使用16位接口时,推荐以下配置:
实测数据显示,这种配置相比纯16位传输可获得15~20%的性能提升。