目标平台:CPKCOR-RA8D1B + CPKEXP-EKRA8X1,Zephyr 4.4.0。 成果:222x480 RGB565 通过 GLCDC → MIPI-DSI(1 lane,video mode)→ ST7796U 稳定显示。

显示链路
应用(LVGL/display_write) → GLCDC 显示控制器(lcdif,renesas,ra-glcdc) 显存在 SDRAM 0x68000000 → MIPI-DSI host(mipi_dsi,renesas,ra-mipi-dsi) 1 lane video mode → ST7796U panel(H0233S001 模组)
关键参数
GLCDC(lcdif)
| width / height | 222 / 480 |
| input/output pixel format | RGB565 / RGB565 |
| 像素时钟 | LCDCLK(PLL 480MHz / 2 = 240MHz)/ 24 = 10MHz,刷新率 ≈57.6Hz |
| 时序 | hsync=40 hbp=40 hfp=48(htotal=350);vsync=4 vbp=8 vfp=4(vtotal=496),sync 低有效 |
| 显存 | ext-ram = <&sdram1>,驱动内行步长按 64 字节对齐为 224px(448 字节/行) |
MIPI-DSI host
| lane 数 | 1(2 lane 会导致无显示,panel 按 1 lane 工作) |
| PHY PLL | 24MHz xtal × 20 = 480MHz(pll-div=1 pll-mul-int=20 pll-mul-frac="0.00" pll-out-div=1) |
| lp-divisor | 5 |
| blanking | LP blanking(no_lp=0),见下文补丁 2 |
| phys-timing | t-init=71999, t-clk-prep=8, t-hs-prep=6, t-lp-exit=6, dphytim4=<27 4 33 7>, dphytim5=<15 9 12>(单位:PCLKA=120MHz 周期) |
| video-mode-delay / timing | 186 / <1183 11 26 40>(沿用 EK-RA8D1 shield 值) |
| panel 侧时序 | HBP/VBP 需减去 sync 宽度(见下文坑 3):hsync=40 hbp=0 hfp=48;vsync=4 vbp=4 vfp=4 |
ST7796U 初始化
复位:P000(低有效),高 100ms → 低 1ms → 高 120ms
24 条 DCS 初始化序列(全部 LP 模式下发)见 drivers/display/display_st7796u_dsi.c,来自瑞萨 FSP 官方例程 mipi_cpkexp_ra8d1_ep
MADCTL=0x48(MV=1 行列交换,BGR=1);CASET 49~270(222 列窗口),RASET 0~479
文件清单
应用目录(app/ra8d1_blink/)
| boards/cpkcor_ra8d1b.overlay | 启用 lcdclk/mipi_dsi/lcdif,ST7796U 子节点,SDRAM 9-bit 修正(见坑 4) |
| drivers/display/display_st7796u_dsi.c | out-of-tree DSI panel 驱动 |
| drivers/display/Kconfig.st7796u_dsi | CONFIG_ST7796U_DSI(节点 okay 时 default y),init priority 86 |
| dts/bindings/display/sitronix,st7796u.yaml | panel binding |
| CMakeLists.txt | DTS_ROOT 追加 + panel 驱动直接编入 app 目标(见坑 1) |
| Kconfig | rsource drivers/Kconfig |
| prj.conf | CONFIG_DISPLAY=y CONFIG_MIPI_DSI=y CONFIG_MEMC=y,日志调试项 |
| src/main.c | 四色横条测试 + LED 心跳 + DSI VMSR 状态诊断打印 |
Zephyr 源码树补丁(2 处,升级 Zephyr 需重新合入)
补丁 1 — GLCDC 驱动 stride 对齐修复:zephyr/drivers/display/display_renesas_ra.h/.c
背景:屏宽 222px(RGB565,444 字节/行)不满足 GLCDC 64 字节行对齐;原驱动 framebuffer 大小和读写路径按 222 算,hstride 却按 224 算,会错位越界
修复:framebuffer 大小、input.hsize/hstride、write/read 行步长统一用对齐行宽(224px);display_cyc 仍用 222(GLCDC 支持裁剪,FSP 例程同样写法);零拷贝路径增加 pitch == 对齐行宽 条件,不满足自动走内部 memcpy
对 ek_ra8d1 等已对齐宽度(480px)的板子行为不变
补丁 2 — DSI host 允许 LP blanking:zephyr/drivers/mipi_dsi/dsi_renesas_ra.c
原驱动硬编码 hsa/hbp/hfp_no_lp=1(blanking 期间强制 HS),带宽需求大增,本板 1-lane 配置下视频 FIFO 持续上溢(VBUFOVF),表现为画面闪烁、竖线错位
改为 0(与 FSP 例程一致);EK-RA8D1(1000MHz PLL、2 lane)带宽充裕,不受影响
调试过程中踩过的坑
out-of-tree 驱动的 zephyr_library() 失效:在应用 add_subdirectory(drivers) 上下文中,zephyr_library 产物不会挂进 zephyr.elf 链接——编译不报错、devicetree 正常,但设备初始化函数根本不执行(无任何日志)。改用 target_sources_ifdef(CONFIG_... app PRIVATE ...) 直接编入 app 目标解决。验证方法:nm zephyr.elf | grep <驱动init函数>。
LOG 不开等于瞎调:LOG_ERR 依赖 CONFIG_LOG=y 及模块 log level;blink 原始配置下驱动报错全部被静默。调试期开 CONFIG_LOG=y + CONFIG_DISPLAY_LOG_LEVEL_DBG=y + CONFIG_MIPI_DSI_LOG_LEVEL_DBG=y,并在关键路径加 printk。
DSI host 的 HBP/VBP 语义与 GLCDC 不同:需减去 sync 宽度(参照树内 display_ili9806e_dsi.h 的换算宏)。两者不一致时画面出现竖线错位(因 MADCTL MV=1 旋转,流内的帧/行边界错位在玻璃上表现为竖缝)、闪烁。
SDRAM 行地址偏移:板级 dts multiplex-addr-shift 误写 8-bit(照搬 ek_ra8d1),本板 W9825G6KB-6I 应为 9-bit(FSP 例程 readme 明确),已在 overlay 修正。
DSI 状态诊断:VMSR 寄存器(0x40346410)bit20=TIMERR、bit22=VBUFUDF、bit23=VBUFOVF;LINKSR(0x40346010)bit8=VRUN。main.c 里有每秒打印 + 写回清除的示例代码。
真机现象对照表
| 背光亮、无任何图像、无 panel 日志 | 驱动未链接进固件(坑 1) |
| 有图像但闪烁、中间竖线、两半相位错开,VBUFOVF 反复置位 | 1 lane + HS blanking 带宽不足(补丁 2) |
| 2 lane 完全无显示 | panel 按 1 lane 工作,勿用 2 |
| 竖线错位/闪烁(带宽正常后仍存在) | DSI HBP/VBP 未减 sync(坑 3) |
下一步:接入 LVGL
显存链路已就绪,LVGL 接入要点(参考 zephyr/boards/shields/rtkmipilcdb00000be/boards/ek_ra8d1.defconfig 和 zephyr/samples/subsys/display/lvgl/):
CONFIG_LVGL=y CONFIG_LV_Z_MEM_POOL_SIZE=65536 # 按需,可放 SDRAM CONFIG_LV_Z_VDB_ZEPHYR_REGION=y # LVGL 显存 buffer 放 SDRAM 区域 CONFIG_LV_Z_VDB_ZEPHYR_REGION_NAME="SDRAM" CONFIG_LV_Z_VDB_ALIGN=64 # 与 GLCDC 64 字节行对齐匹配 CONFIG_LV_COLOR_DEPTH_16=y # RGB565
LVGL 通过 chosen { zephyr,display = &lcdif; }; 找到显示设备(overlay 已配好)
LVGL flush 的 buffer pitch=222 ≠ 对齐行宽 224,会自动走 GLCDC 驱动的内部 framebuffer memcpy 路径(补丁 1 保证正确);后续如需性能优化,可让 LVGL 按 224 对齐分配 buffer 走零拷贝路径
我要赚赏金
