{"code":1,"msg":"成功","time":"1791589181","data":{"title":"【2026嵌入式大赛】edgi-talk lvgl横屏显示配置指南","content":"# 横屏（800×480）显示配置指南\r\n\r\n> 适用工程：`Edgi_Talk_M55_XiaoZhi`（PSoC Edge 84 \/ Cortex-M55 \/ RT-Thread 5.0.2）\r\n> 面板：TL043WVV02（4.3 寸，EK79007AD3 驱动 IC，MIPI DSI 2-lane）\r\n> 最后更新：2026-07-22（已在目标板上验证）\r\n\r\n![screenshot_4e3b646ac673af927cf52123e3266741.jpg](https:\/\/oss-club.rt-thread.org\/uploads\/20261006\/3b777e24f2b1d9ae33d903c5f605df7d.jpg.webp)\r\n---\r\n\r\n## 1. 背景\r\n\r\n面板**物理分辨率是 480×800（竖屏原生）**，但产品整机横装，UI 需要 **800×480 横屏逻辑分辨率**。\r\n\r\n关键约束：显示控制器（GFXSS DC，VeriSilicon DCnano8000）**不支持取数旋转**（`vivENABLE_LAYER_ROT` 未启用，寄存器无旋转字段），所以旋转只能在软件里做。\r\n\r\n最终架构（已验证）：\r\n\r\n```\r\nLVGL 逻辑 800×480 横屏渲染（局部刷新，VGLite GPU 加速）\r\n        │\r\n        │  disp_flush() 里 lv_draw_sw_rotate() 逐脏区旋转 90°\r\n        ▼\r\n面板帧缓冲 480×800（行距 512px \/ 1024B，乒乓双缓冲，gfx_mem）\r\n        │\r\n        │  GFXSS DC → MIPI DSI（视频模式，RGB565）\r\n        ▼\r\nTL043WVV02 面板（物理竖屏，横装显示）\r\n```\r\n\r\n触摸无需改驱动：LVGL 内核按 `disp->rotation` 自动旋转触摸坐标（`lv_indev.c`）。\r\n\r\n---\r\n\r\n## 2. 配置清单（全部改动点）\r\n\r\n### 2.1 显示时序 \/ DC \/ DSI —— `libs\/TARGET_APP_KIT_PSE84_EVAL_EPC2\/config\/GeneratedSource\/cycfg_peripherals.c`\r\n\r\n| 字段 | 值 | 说明 |\r\n|------|-----|------|\r\n| `GFXSS_graphics_layer.width` \/ `height` | 480 \/ 800 | 图层尺寸（面板物理值） |\r\n| `GFXSS_dc_config.display_width` \/ `display_height` | 480 \/ 800 | DC 输出尺寸 |\r\n| `GFXSS_mipidsi_display_params.hdisplay` \/ `vdisplay` | 480 \/ 800 | DSI 视频行像素数 |\r\n| `GFXSS_mipidsi_display_params.hbp` | **120** | ⚠️ 关键！480 宽时必须 120（见 3.2） |\r\n| 其余时序 | hsync=2, hfp=36, vsync=2, vfp=180, vbp=10, pclk=33448kHz | 保持不变 |\r\n\r\n> ⚠️ 该文件是 device-configurator 生成物。请同时在 `design.modus` 里改好（GFXSS 显示宽 480、hbp 120），否则重新生成代码会被覆盖回 512\/40。\r\n\r\n### 2.2 LCD 驱动 —— `libraries\/HAL_Drivers\/drv_lcd.c`\r\n\r\n```c\r\n#define LCD_WIDTH           480   \/\/ 可视宽度\r\n#define LCD_HEIGHT          800\r\n#define LCD_STRIDE          512   \/\/ 行距 512px = 1024B（128B 对齐，见 3.1）\r\n```\r\n\r\n`psoc_lcd_init()` 末尾（面板初始化之后）覆写 DC 取数行距寄存器：\r\n\r\n```c\r\n\/* 厂商 viv 层初始化只会写 宽×2=960B，必须覆写为 1024B *\/\r\ngfxbase->GFXSS_DC.DCNANO.GCREGFRAMEBUFFERSTRIDE = LCD_STRIDE * 2U;\r\n```\r\n\r\n### 2.3 LVGL 移植层 —— `libraries\/Common\/board\/ports\/lvgl\/lv_port_disp.h`\r\n\r\n```c\r\n#define MY_DISP_HOR_RES     (480U)  \/\/ 面板物理宽\r\n#define MY_DISP_VER_RES     (800U)  \/\/ 面板物理高\r\n#define MY_DISP_STRIDE      (512U)  \/\/ 面板帧缓冲行距（像素）\r\n#define MY_DISP_ROTATION    LV_DISPLAY_ROTATION_90   \/\/ 方向反了改 270\r\n#define MY_DISP_DRAW_BUF_LINES  (80U) \/\/ 局部渲染缓冲 800×80\r\n```\r\n\r\n### 2.4 LVGL 初始化与旋转 flush —— `lv_port_disp.c`\r\n\r\n- 面板帧缓冲 `disp_buf1\/2`：`MY_DISP_STRIDE × 800 × 2B`，乒乓双缓冲；\r\n- LVGL 渲染缓冲 `draw_buf1\/2`：800×80×2B，`CY_SECTION(\".cy_gpu_buf\")`（VGLite 需要 GPU 可访问内存）；\r\n- 初始化：\r\n\r\n```c\r\nlv_display_t *disp = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES); \/\/ 物理值\r\nlv_display_set_rotation(disp, MY_DISP_ROTATION);   \/\/ 逻辑分辨率自动变 800×480\r\nlv_display_set_buffers(disp, draw_buf1, draw_buf2, sizeof(draw_buf1),\r\n                       LV_DISPLAY_RENDER_MODE_PARTIAL);\r\n```\r\n\r\n- `disp_flush()`：用 `lv_display_rotate_area()` 把逻辑坐标脏区换算到面板坐标系，再用 `lv_draw_sw_rotate()` 旋转写入**两块**面板帧缓冲（乒乓对永不发散），帧末 `Cy_GFXSS_Set_FrameBuffer()` 翻转地址。\r\n\r\n### 2.5 触摸\r\n\r\n无需改动。LVGL 内核按 `disp->rotation` 自动旋转 indev 坐标（实测按钮\/滑条\/四角均准确）。\r\n\r\n### 2.6 其它\r\n\r\n- `usbh_uvc_display.c` 的 `LCD_STRIDE` 保持 512（UVC 路径仍按竖屏直写面板帧缓冲）。\r\n- gfx_mem 只有 3 MB（`board\/linker_scripts\/link.ld`），无法容纳双份全屏渲染缓冲，**必须用局部刷新模式**。\r\n\r\n---\r\n\r\n## 3. 三个硬件坑（调试实录）\r\n\r\n### 3.1 DC 取数行距必须 128B 对齐\r\n\r\n480 宽 × 2B = 960B 的紧凑行距会让画面**整体平移约 80 列**。原因是 DC 取数引擎按 128B（AXI burst）对齐工作（厂商 DBI 路径代码 `Cy_GFXSS_Transfer_Frame` 里有显式的 128B 向上取整逻辑，视频模式虽不走那段代码，但硬件约束相同）。\r\n\r\n**对策**：面板帧缓冲行距用 512px（1024B），480 有效列 + 32px padding；并在 GFXSS 初始化后覆写 `GCREGFRAMEBUFFERSTRIDE = 1024`。\r\n\r\n> 注意：512 时代行距本来就是 1024B，所以没有暴露这个问题。\r\n\r\n### 3.2 DSI 行时序 hbp 要 120\r\n\r\n480 宽、hbp=40 时面板数据窗口对齐错位，画面平移 80 列；hbp 改为 120 后像素级对齐。512 宽时 hbp=40 无此问题。\r\n\r\n> 若换屏\/改分辨率后画面平移，优先调 hbp 验证。\r\n\r\n### 3.3 测试模式下旧 UI 控件悬空导致的 hard fault\r\n\r\n绕过 GUI Guider 界面初始化时，小智应用仍会往 UI 线程发气泡消息，`ui_process_message()` 操作未创建的控件导致 `rt_memheap_free` 野指针崩溃。测试模式下该路径已整体屏蔽（`XZ_UI_TEST_480_UI`）。\r\n\r\n---\r\n\r\n## 4. 验证与诊断工具\r\n\r\n### 4.1 面板级诊断（绕过 LVGL）\r\n\r\n`lv_port_disp_test_ruler()`（`lv_port_disp.c`）+ `xiaozhi_ui.c` 里 `XZ_UI_BRINGUP_RULER 1`：\r\n直接写面板帧缓冲——红绿坐标渐变 + 四角色块（左上白\/右上红\/左下蓝\/右下黄）。用于区分\"LVGL 内容错\"还是\"DC\/DSI\/面板链路错\"。\r\n\r\n另有 `XZ_UI_BRINGUP_SOLID_FILL`（纯色点亮）。\r\n\r\n### 4.2 LVGL 横屏测试界面\r\n\r\n`applications\/xiaozhi\/ui\/test_ui_480.c` + `XZ_UI_TEST_480_UI 1`：\r\n800×480 横屏测试页——绿框 + 四角色块 + 中文标题（tiny_ttf）+ 圆弧动画 + 渐变进度条 + 计数按钮 + 滑条。一次验证：几何完整性、GPU 渲染、动画刷新、触摸映射。\r\n\r\n### 4.3 OpenOCD 寄存器 dump\r\n\r\nGFXSS 非安全基址 `0x44800000`：\r\n\r\n| 寄存器 | 地址 | 正常值 |\r\n|--------|------|--------|\r\n| DC 帧缓冲地址 | `0x44801828` | disp_buf1\/2 之一 |\r\n| DC 取数行距 | `0x4480182C` | **0x400 (1024B)** |\r\n| DC 帧缓冲尺寸 | `0x4480186C` | 0x032001E0 (480×800) |\r\n| DC HDISPLAY | `0x44801900` | 0x028601E0（active 480 \/ total 638，hbp=120 后） |\r\n| DSI VID_PKT_SIZE | `0x4480303C` | 0x1E0 (480) |\r\n| DSI VID_HLINE_TIME | `0x44803050` | lbcc(htotal) |\r\n\r\n示例命令（板子运行中直接读，无需复位）：\r\n\r\n```bash\r\nopenocd -s ..\/scripts -f interface\/kitprog3.cfg -f target\/infineon\/pse84xgxs2.cfg \\\r\n  -c \"transport select swd\" -c \"init\" -c \"targets cat1d.cm55\" \\\r\n  -c \"mdw 0x44801828 1\" -c \"mdw 0x4480182C 1\" -c \"shutdown\"\r\n```\r\n\r\n也可以 `dump_image` 把帧缓冲整个拖下来离线分析像素落位（本次偏移就是这么定位的）。\r\n\r\n### 4.4 判读速查\r\n\r\n| 现象 | 怀疑对象 |\r\n|------|----------|\r\n| 画面整体平移 ~80 列\/行 | hbp 不对（3.2）或帧缓冲行距未 128B 对齐（3.1） |\r\n| 细竖条\/斜纹花屏 | 帧缓冲行距与 DC stride 寄存器不一致 |\r\n| 图像上下颠倒\/镜像 | `MY_DISP_ROTATION` 90↔270 翻转 |\r\n| 触摸位置偏差 | 检查 `lv_display_set_rotation` 是否调用（触摸旋转由内核完成） |\r\n| xz_ui hard fault（memheap） | 是否有代码触碰未创建的旧界面控件（3.3） |\r\n\r\n---\r\n\r\n## 5. GUI Guider 对接要点\r\n\r\n- 工程分辨率：**800×480**，颜色格式 RGB565。\r\n- 图片素材导出 RGB565A8 后用 `applications\/xiaozhi\/ui\/guider\/convert_rgb565a8.py` 拍平，宽度保持 16 的倍数走 GPU。\r\n- 自定义逻辑只写 custom code 区，防止重新导出被覆盖。\r\n- 对接完成后把 `xiaozhi_ui.c` 的 `XZ_UI_TEST_480_UI` 置 0 恢复正式 UI 路径。\r\n\r\n---\r\n\r\n## 6. 相关提交\r\n\r\n- `401ea22` 显示链路 512×800 → 480×800（物理分辨率）\r\n- `0cca0dc` 横屏 800×480 支持（软件旋转 flush）+ hbp=120 对齐修复","updatetime":"2026-10-08 08:40:48","author":"Lu_盼盼"}}