ILI9341: 增加 DMA/纯阻塞 两种传输 + 每次 flush 日志,便于定位错位/残留
- ILI9341_USE_DMA 开关:1=DMA+同步等待,0=纯阻塞SPI(不用DMA),同一入口 - ILI9341_LOG_EN/LOG_EVERY:每次(或每N次)flush 打印 方式/区域/字节/耗时/ 错误码/累计错误/超时/缓冲地址(判断是否落在AXI SRAM) - DWT 微秒计时;纯阻塞路径无 D-Cache/DMA 一致性问题,用于对照 - README 增加两种模式对照判读表
This commit is contained in:
@@ -69,6 +69,51 @@ STM32H7 的坑:**DMA1/DMA2 无法访问 DTCM(0x20000000)**,能访问 AXI SRA
|
||||
|
||||
---
|
||||
|
||||
## 4.5 诊断:DMA vs 纯阻塞 + 日志(排查错位/残留)
|
||||
|
||||
在 `ILI9341.h` 顶部有三个开关:
|
||||
|
||||
```c
|
||||
#define ILI9341_USE_DMA 1 // 1=DMA搬运(+任务内同步等待) 0=纯阻塞SPI(不用DMA)
|
||||
#define ILI9341_LOG_EN 1 // 1=每次flush打印一行日志(UART4)
|
||||
#define ILI9341_LOG_EVERY 1U // 每N次flush打印一次(串口太卡就调大,如 8/16)
|
||||
```
|
||||
|
||||
两种传输走**同一个入口** `ILI9341_FlushArea_DMA()`,只是内部实现不同,
|
||||
所以切换 `ILI9341_USE_DMA` 后其它代码无需改动,直接对比现象与日志即可判断
|
||||
“错位/残留”到底和 DMA / D-Cache 有没有关系。
|
||||
|
||||
日志格式(UART4,115200 或工程设定波特率):
|
||||
|
||||
```
|
||||
[LCD] DMA #1234 (20,115 46x40) len=3680 t=210us fail=0 err=0x0 eC=0 toC=0 buf=0x24000000
|
||||
│ │ │ │ │ │ │ │ │ │ └ 数据缓冲地址:必须是 0x24xxxxxx(AXI SRAM);
|
||||
│ │ │ │ │ │ │ │ │ └ 累计超时次数 若是 0x2000xxxx(DTCM) 说明 scatter 没生效
|
||||
│ │ │ │ │ │ │ │ └ 累计错误次数
|
||||
│ │ │ │ │ │ │ └ 本次 SPI 错误码(HAL ErrorCode)
|
||||
│ │ │ │ │ │ └ 本次是否失败(1=超时/出错)
|
||||
│ │ │ │ │ └ 本次传输耗时(微秒, DWT 计时)
|
||||
│ │ │ │ └ 本次字节数
|
||||
│ │ │ └ 区域宽x高
|
||||
│ │ └ 区域左上角(x,y)
|
||||
│ └ flush 序号
|
||||
└ 传输方式: DMA / POLL
|
||||
```
|
||||
|
||||
**怎么判断:**
|
||||
|
||||
| 现象 | 结论 |
|
||||
|---|---|
|
||||
| `POLL` 模式画面**干净**、`DMA` 模式**错位** | 问题在 DMA / D-Cache 一致性(缓冲没 clean 干净、或缓冲不在 AXI) |
|
||||
| 两种模式**都错位** | 与 DMA 无关,是**面板刷新撕裂**(需 TE 同步)或上层逻辑 |
|
||||
| 日志里 `buf=0x2000xxxx` | scatter 没生效,缓冲落在 DTCM,DMA 读到错/旧数据 → 先修内存放置 |
|
||||
| `err=` 非 0 或 `eC` 持续增长 | SPI 总线错误(接线/速率/干扰),先降 `BaudRatePrescaler` 验证 |
|
||||
| `toC` 增长 | 传输超时,DMA/中断未触发,查 NVIC/时钟 |
|
||||
| `t=` 远大于预期(如 >20ms) | SPI 太慢/被阻塞,撕裂概率大增 |
|
||||
|
||||
> 串口日志是**阻塞发送**,会显著拖慢刷新、改变时序。判断完请把 `ILI9341_LOG_EN`
|
||||
> 关回 0(或把 `ILI9341_LOG_EVERY` 调大),否则时序失真、也会掩盖真实表现。
|
||||
|
||||
## 5. 参数与调优
|
||||
|
||||
- `DISP_BUF_LINES`(lv_port_disp.c,默认 20):单块缓冲行数。越大单次 DMA 越长、
|
||||
|
||||
Reference in New Issue
Block a user