这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【瑞萨启明RA6M5|Zephyr】2、LCD-PAR-S035(ST7796S

共1条 1/1 1 跳转至页

【瑞萨启明RA6M5|Zephyr】2、LCD-PAR-S035(ST7796S+GT911)Zephyr移植调试笔记

高工
2026-10-03 11:21:35     打赏
LCD-PAR-S035(ST7796S + GT911)Zephyr 移植调试笔记

适用环境:野火启明6M5(R7FA6M5BH3CFC)+ Zephyr(D:\zephyrproject,v4.4)+ 板卡 ebf_qm6m5(BOARD_ROOT=D:/RA/RA6M5)+ 应用 app/lcd_demo。屏通过 PMOD1(J25)直插,SW1 拨到四线 SPI 模式。

8cf2a3fa5e71dd8ab210e062c2c71d5d.jpg

1. 最终可用配置(结论速查)

引脚(PMOD1)

屏信号PMOD1 脚MCU 引脚配置
CS1P301GPIO CS(spi_config.cs,注意 cs_is_gpio,见 §3)
MOSI2P203SPI0 MOSIA
D/CX3P202GPIO 输出(MISO 位,四线模式无回读)
SCK4P204SPI0 RSPCKA
INT7P905触摸中断(未用,查询方式)
RESET8P111GPIO 输出,低 100ms 复位
触摸 SCL9P303bit-bang I2C(自研方向切换,见 §5)
触摸 SDA10P302同上

关键参数

  • SPI0,模式 0,8bit,15MHz(实测 1MHz~15MHz 显示均正常,非信号完整性敏感)

  • MADCTL = 0x28(MV=1 横屏 + BGR 位,S035 屏为 BGR 序)

  • COLMOD = 0x55(RGB565),INVON(1-dot 反相,B4=0x01)

  • 初始化序列与 NXP fsl_st7796s.c(GUI Guider 生成)/ Zephyr lcd_par_s035 shield 完全一致;SLPOUT(0x11) 后必须延时 ≥120ms 再 DISPON(0x29)

  • 像素数据高字节先发(DBI 大端;用 Zephyr 原生栈时开 CONFIG_LV_COLOR_16_SWAP=y,见 §4,本次最大的坑)

  • GT911:I2C 地址 0x14(INT 未受控复位时锁 0x14 而非 0x5D);坐标映射 px=ry, py=319-rx;读出的 7 字节里 data[1] 是触摸 ID,坐标从 data[2] 开始

2. 症状与根因总表

症状根因章节
背光亮、全白/黑屏,软件日志全正常CS 恒高:spi_cs_control 缺 cs_is_gpio=true,CS 从不翻转,屏忽略所有命令§3
红→蓝、绿→红、蓝→绿(通道轮换)像素低字节先发上线;S035 四线 SPI 要求高字节先发(BE),原生栈开 CONFIG_LV_COLOR_16_SWAP§4
文字"发花"、有彩色杂点,色块正常同上——抗锯齿中间色被字节交换映射成彩色镶边,黑白大色块无感§4
LVGL 界面只剩计数器,其余消失Zephyr LVGL 胶合层按 chosen 自建了一个空白 display,lv_timer_handler 把它刷到屏上覆盖了 UI§6
GT911 I2C 完全扫不到Zephyr gpio-i2c 在 RA6M5 上不可用(输出模式 PIDR 读回恒 0)§5
gt911 驱动 bus faultZephyr goodix,gt911 驱动在无 reset-gpios 时解引用空指针§5

3. 黑屏:CS 恒高(cs_is_gpio)

这版 Zephyr(v4.4)的 struct spi_cs_control 新增了 bool cs_is_gpio 字段;spi_context_cs_control() 只有在 config->cs.cs_is_gpio == true 时才翻转 CS GPIO(drivers/spi/spi_context.h、include/zephyr/drivers/spi.h)。设备树路径(SPI_CS_CONTROL_INIT)会自动置位,但手动填充 spi_config 时必须显式写上:

static struct spi_config spi_cfg = {
    .frequency = 15000000,
    .operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8),
    .cs = {
        .gpio = { .port = port3, .pin = 1, .dt_flags = GPIO_ACTIVE_LOW },
        .delay = 0,
        .cs_is_gpio = true,   /* 缺了它 CS 永远不动,且无报错 */
    },
};

排查手法(值得复用)

  1. 软件正常 ≠ 波形正常。RA SPI 轮询驱动(spi_renesas_ra.c,无 CONFIG_SPI_INTERRUPT 时)只等 SPTEF/SPRF 标志,即使引脚复用没生效,外设内部移位照常,传输照样"成功"返回。必须上逻辑分析仪。

  2. 降到 100kHz 再量。15MHz 的 SCK 需要 ≥30MSa/s 采样率;普通 USB 分析仪测 I2C 用的低速率档根本采不到,会误判"SCK 没起振"。

  3. 持续 0xAA 测试模式:固件里写个永不返回的循环发 0xAA,CS/SCK/MOSI 波形稳定可重复,不挑抓取时机,一次就能定位是固件问题还是探头问题。

  4. J-Link 读不到 RA6M5 的 0x4004xxxx/0x4008xxxx 外设寄存器(全返回 0),不要用它判寄存器,只能用固件日志。

4. 颜色通道轮换 / 文字发花:像素字节序

现象:直接写已知值色带,0xF800(红)→显示蓝、0x07E0(绿)→显示红、0x001F(蓝)→显示绿,正好是 16bit 高低字节互换的结果(0xF800↔0x00F8、0x07E0↔0xE007、0x001F↔0x1F00)。

根因:S035 屏四线 SPI 要求像素高字节先发(DBI 标准大端序)。Cortex-M 内存里 RGB565 是小端存储,若把缓冲原样发上线(低字节先发),屏端组装出的像素即高低字节互换,颜色通道轮换。NXP 各工程正常的原因:RW612 走 LCDIC 硬件字节交换(nxp,swap-bytes),MCUXpresso SPI 路径按 16bit 处理,上线都是高字节先发。

修复(按使用的栈二选一):

  • 自研驱动:RAMWR 数据阶段按 16bit 做字节交换后再发(命令为单字节不受影响)。

  • Zephyr 原生 display 栈:CONFIG_LV_COLOR_16_SWAP=y。LVGL 在 call_flush_cb 里会对 px_map 做 lv_draw_sw_rgb565_swap(),flush 上线即为高字节先发。注意此设置只影响 LVGL 渲染路径,绕过 LVGL 直接调 display_write() 时仍需自己保证大端。

为什么表现为"文字发花"而非明显色错:黑白大色块(0xFFFF/0x0000)字节对称,交换无感;纯色块肉眼也难察觉 R/B 互换(红位不变、绿近似对称)。文字抗锯齿的中间灰阶被交换后变成彩色镶边,肉眼看上去就是"杂点/不清楚"。同一现象此前在 RA6E1+ST7789 上也出现过,应属同类问题。

教训:

  • 1px 棋盘格(0xFFFF/0x0000 交替)对 bit 误码和字节序都不敏感,不是好的传输验证图案。

  • 好的诊断图案:8 条已知值色带(红/绿/蓝/白/黑/0xAAAA/0x8410/黄)——0xAAAA 的 R=68%/G=33%/B=32% 对任何通道交换/旋转都敏感,一次成像即可钉死颜色映射。

  • "屏在别的平台是好的"只证明屏没坏,字节序/MADCTL 这类软件配置差异照样能让同一块屏表现完全不同。

5. GT911 触摸

  • Zephyr gpio-i2c 在 RA6M5 上不可用:RA 的 GPIO 在输出模式下读 PIDR 恒为 0(固件实测),导致 bit-bang 读不到 SDA。解决:自研方向切换 bit-bang(touch_bb.c)——释放=配置为输入+上拉,拉低=配置为输出低。

  • GT911 地址是 0x14 不是 0x5D:复位时序中 INT 脚未被正确控制时 GT911 锁定 0x14。i2c scan 时两个地址都可以试试。

  • Zephyr goodix,gt911 驱动在无 reset-gpios 属性时会解引用空指针 bus fault;要么给全 reset/irq gpios,要么绕过自研。

  • 读坐标注意:0x814E 起始的 7 字节中 data[0]=状态、data[1]=触摸 ID,X=data[2]|data[3]<<8、Y=data[4]|data[5]<<8(ID 字节曾导致坐标错位)。

  • 本板映射:px=ry, py=319-rx(竖屏 320x480 原始坐标 → 横屏显示)。

6. Zephyr LVGL 胶合层的坑

  • CONFIG_LVGL=y 时 modules/lvgl/lvgl.c 强制要求 zephyr,display chosen(或 zephyr,displays 节点),否则编译报错。绕过 display 子系统自建驱动时,设备树里的显示节点仍要保留 enabled 给它用。

  • 胶合层会自动创建一个 lv_display 并注册空白屏幕。应用再 lv_display_create() 自建 display 后,必须删掉胶合层那个,否则每次 lv_timer_handler() 都会把它的空白屏刷到屏上覆盖 UI——现象是"界面只剩每秒更新的计数器":

lv_display_t *glue_disp = lv_display_get_default(); /* 在 set_default 之前取 */
lv_display_set_default(disp);
if (glue_disp != NULL && glue_disp != disp) {
    lv_display_delete(glue_disp);
}
  • 本版未启用 CONFIG_LV_Z_RUN_LVGL_ON_WORKQUEUE/CONFIG_LV_Z_FLUSH_THREAD,胶合层不会自己跑 timer handler,应用主循环每 10ms 调一次 lv_timer_handler() 即可。

7. 其他备忘

  • 串口日志中文在 PowerShell 读取时显示为 ?,是读取端编码问题,非固件问题。

  • 烧录:west flash -d build/lcd_demo -r jlink;脱手复位用 build/jlink_reset.jlink(reset/go/exit)。

  • 构建命令(Git Bash):

cd /d/RA/RA6M5 && export ZEPHYR_BASE=/d/zephyrproject/zephyr \
  ZEPHYR_SDK_INSTALL_DIR=/d/luglZephyrproject/zephyr-sdk-1.0.1/zephyr-sdk-1.0.1 \
  PATH="/c/ncs/toolchains/936afb6332/opt/bin:/c/Program Files/SEGGER/JLink:$PATH"
west build -b ebf_qm6m5 -d build/lcd_demo app/lcd_demo -- -DBOARD_ROOT=D:/RA/RA6M5

8. 源码位置

  • 应用/LVGL:app/lcd_demo/src/main.c(Zephyr display 原生驱动 + LVGL 胶合层 + 触摸接入)

  • 触摸:app/lcd_demo/src/touch_bb.c(方向切换 bit-bang GT911)

  • 配置:app/lcd_demo/prj.conf(含 CONFIG_LV_COLOR_16_SWAP=y)

  • 板卡:boards/ebf/ebf_qm6m5/(spi0/cs-gpios/pinctrl 定义)

  • overlay:app/lcd_demo/boards/ebf_qm6m5.overlay(mipi_dbi/st7796s 节点,madctl=0x28)





关键词: RA6M5     Zephyr     LCD-PAR-S035    

共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]