# lv_walle **Repository Path**: YJHmath/lv_walle ## Basic Information - **Project Name**: lv_walle - **Description**: 适配瓦力机器人双眼屏幕 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: spi_dual - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-01 - **Last Updated**: 2026-04-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 快速编译lv_examples mmo lv_examples -B ## 关于lv_conf.h /opt/aw/v821/tina-v821-release/platform/thirdparty/gui/lvgl-8/lv_examples/src/lv_conf.h 在DBI模式下, 应LV_COLOR_16_SWAP赋0; 在SPI模式下, LV_COLOR_16_SWAP赋1 2025-10-1 22:59:45 我正编译lv_example_spi_fb0 lv_examples_v2: 尝试打开FBIOGET_FSCREENINFO, 其实跟v1无区别;fbp_line_length依旧等于:480; lv_examples_v4(508fc913f54e006fc5843f1d0dd09edd): 尝试 int32_t act_x1 = 0; int32_t act_y1 = 0; int32_t act_x2 = 256; int32_t act_y2 = 256; fbp_line_length = 256 * 16 / 8; 段错误; lv_examples_v5: 尝试width = 256, height = 256; 段错误; lv_examples_v6: 撤回修改关于sunxifb.c的非法修改; 一个120x120矩形从屏幕左侧平移到右侧的程序(屏幕长宽240x240) lv_examples_v8: 取消w=256, h=256 v11: 30x30方块会被吃掉; v13: sunxifb.c下刀, printf出fbp16[location + i]; v14: 更狠了, 把color_t全给篡改成0xFFFF; 证明篡改的蓝色方块就是我们关注的目标; v15: 进一步完善了; 0x07E0u:纯红色 v16: g_x1 += 0; g_x2 += 0; 期间调整了st7789v的address() v17: 关闭double; 直接没显示了 2025-10-5 09:40:49 v18: 开启lvgl-8.3.2 use sunxifb direct mode v19: 纯fb操作 v23: 魔改sunxifb直至不再显示; 有显示, 但依旧漂移; v24: 自制colorbar; v27之前: 开启lvgl-8.3.2 use sunxifb direct mode 没关! v28: 成功实现三色条带; v29: 间隔1像素的三色带, 根本看不清楚; ## 方向变更: 探寻刷新的原理, 追查到驱动 ```c "./bsp/drivers/video/sunxi/disp2/disp/fb_core.c" int sunxi_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { case FBIOPAN_DISPLAY_SUNXI: if (copy_from_user(&var, argp, sizeof(var))) return -EFAULT; ret = sunxi_fb_pan_display(&var, info); break; } ./bsp/drivers/video/sunxi/disp2/disp/fb_core.c:46 int sunxi_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { fb_debug_inf("fb %d pan display start update\n", info->node); platform_update_fb_output(info->par, var); if (var->reserved[0] == FB_ACTIVATE_FORCE) return 0; platform_fb_pan_display_post_proc(info->par); fb_debug_inf("fb %d pan display ok\n", info->node); return 0; } int platform_update_fb_output(struct fb_hw_info *hw_info, void *info) { cfg.dev = drm; cfg.de_id = de; cfg.channel_id = channel; cfg.force = var->reserved[0] == FB_ACTIVATE_FORCE; cfg.fake_state = &hw_info->state; cfg.out_plane = &hw_info->state.base.plane; cfg.out_crtc = &hw_info->state.base.crtc; hw_info->state.base.src_y = ((long long)var->yoffset) << 16; /* TODO: if dual output, use two thread to call sunxi_fbdev_plane_update, * and block until two thread finish */ sunxi_fbdev_plane_update(&cfg); } ./bsp/drivers/drm/sunxi_drm_crtc.c:420 int sunxi_fbdev_plane_update(struct fbdev_config *config) { } ``` # 2025-10-5 23:44:31 更换彻底没有disp2的kernel v30: 增加注释 # 2025-10-9 10:31:21 v2.img 改动disp_lcd.c验证是否经disp_lcd.c发出SPI信号的? 能确认display会调用到: sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_qspi_lcd_panel_dma_transfer,line:2009 - [YE]addr_buf:C3A479A4, buf:E3CC0000 v3.img 增加发送0x2c, 看看还能不能正常初始化; 更完善一下disp_lcd输出; 结果: 没显示 v4.img 恢复st7789v.c 结果: 疯狂调用: sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_lcd_para_write,line:2255 - para:80 屏幕有显; 最后卡死在此: sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_lcd_para_write,line:2255 - para:FF ## 比较神奇的一点: 通过SPI的方式进行初始化, 屏幕能够正常显示; QSPI后续能控制屏幕以正常颜色输出; ## 考虑新驱动 基于77916进行修改; 写单个cmd用:sunxi_lcd_fb_disp_qspi_lcd_cmd_write sunxi_lcd_panel_qspi_cmd_write 写单个cmd+para,则用:sunxi_lcd_fb_disp_qspi_lcd_para_write sunxi_lcd_panel_qspi_para_write 写多个para:sunxi_lcd_fb_disp_qspi_lcd_multi_para_write sunxi_lcd_panel_qspi_multi_para_write # 2025-10-9 15:09:43 # 再走一下纯SPI控制; 双屏SPI_v2.img 估计大概率还是会失败; # 整理一下思路: ## 思路I 既然单SPI能做到正常的显示输出(验证:) 我们看看单SPI究竟对屏幕发送了什么? 再对比下QSPI对屏幕发送了什么 ## 思路II 既然QSPI能正常显示LVGL, 只是画面出现左飘; 何不研究一下它的发送实现(是否跟手册匹配); [ 42.035996] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_qspi_lcd_panel_dma_transfer,line:2011 - [YE]addr_buf:02, 00, 2C, 00; buf:E0, len:115200 [ 67.429703] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_qspi_lcd_set_layer,line:2124 - len:480 [ 67.429714] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_qspi_lcd_set_layer,line:2125 - lcdp->panel_info.lines_per_transfer:240 # v5.img 但求能正常启动并显示lvgl画面; 能显示, 但左飘; # spi_single.img 使用正常显示SPI单屏的设备树, 但修改了disp_lcd以显示更多日志 没有左飘, 没有调用: 结论:发现没有踩中(FBIO_DISPLAY)任何一个日志输出的点; # spi_single_v2.img ```c ./lv_examples_v15 1 1 wh=240x240, vwh=240x480, bpp=16, rotated=0 Turn on double buffering. w x h:240, 240 unable to open evdev interface:: No such file or directory vinfo.bits_per_pixel: 16 2 480,act_x1: 0 act_y1: 0 act_x2: 239 act_y2: 239 [ 45.904282] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_bsp_disp_lcd_set_layer,line:58 - lcd:C35D2200 vinfo.bits_per_pixel: 16 2 480,act_x1: 0 act_y1: 100 act_x2: 34 act_y2: 139 fbp16[24000]: ... vinfo.bits_per_pixel: 16 2 480,act_x1: 100 act_y1: 0 act_x2: 139 act_y2: 35 [ 45.904330] [LCD_FB] sunxi_lcd_fb_disp_spi_lcd_set_layer,line:2078 [ 49.836285] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_bsp_disp_lcd_set_layer,line:58 - lcd:C35D2200 [ 49.836319] [LCD_FB] sunxi_lcd_fb_disp_spi_lcd_set_layer,line:2078 ``` [ 55.423099]先sunxi_lcd_fb_disp_spi_lcd_set_layer(); [ 55.456752]再sunxi_lcd_fb_bsp_disp_lcd_set_layer(); # spi_single_v3.img 增加了disp_lcd.c中的日志输出: ```c [ 36.291676] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_lcd_panel_dma_transfer,line:1934 - [YE]tmp:31, len:115200 [ 38.524154] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_bsp_disp_lcd_set_layer,line:58 - lcd:C35D2200 [ 38.524166] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_spi_lcd_set_layer,line:2093 - len:480 [ 38.524175] sunxi:lcd_fb:[DBG ] sunxi_lcd_fb_disp_spi_lcd_set_layer,line:2094 - lcdp->panel_info.lines_per_transfer:240 ``` # 2025-10-10 09:55:15 spi_sync()和spi_sync_transfer()的差异? ./kernel/linux-5.4-ansc/drivers/spi/spi.c:3571:int spi_sync(struct spi_device *spi, struct spi_message *message) ./kernel/linux-5.4-ansc/include/linux/spi/spi.h:1120:extern int spi_sync(struct spi_device *spi, struct spi_message *message); B: ```c "./kernel/linux-5.4-ansc/include/linux/spi/spi.h" /** * spi_sync_transfer - synchronous SPI data transfer * @spi: device with which data will be exchanged * @xfers: An array of spi_transfers * @num_xfers: Number of items in the xfer array * Context: can sleep * Does a synchronous SPI data transfer of the given spi_transfer array. * For more specific semantics see spi_sync(). * Return: Return: zero on success, else a negative error code. */ static inline int spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers, unsigned int num_xfers) { struct spi_message msg; spi_message_init_with_transfers(&msg, xfers, num_xfers); return spi_sync(spi, &msg); } /** * spi_message_init_with_transfers - Initialize spi_message and append transfers * @m: spi_message to be initialized * @xfers: An array of spi transfers * @num_xfers: Number of items in the xfer array * * This function initializes the given spi_message and adds each spi_transfer in * the given array to the message. */ static inline void spi_message_init_with_transfers(struct spi_message *m, struct spi_transfer *xfers, unsigned int num_xfers) { unsigned int i; spi_message_init(m); for (i = 0; i < num_xfers; ++i) spi_message_add_tail(&xfers[i], m); } ``` 总结: - SPI通信使用spi_sync_transfer()相对高级, 内部还调用了spi_sync();(兼有:spi_transfer==>spi_message) - QSPI通信使用spi_sync()更底层; # v6.img - 采用QSPI单线模式; - 修改sunxi_lcd_fb_disp_qspi_lcd_panel_dma_transfer()的发送细节(删除发送addr_buf) 总结: ✿✿ヽ(°▽°)ノ✿, 貌似解决了; 根本原因系:qspi模式下会强制发送addr_buf[4], 导致误解析成屏幕有512列? # spi_dual_v1.img 为何双屏SPI无法正常初始化成两个/dev/fb? 重新编译貌似又可以! 对比v6.txt和spi_dual_v1.txt可以实锤确实用了两种不同的通信方式; # lv_examples_v31 ## 2025-12-10 22:34:00 # qspi_dual_v2001.img - 不听劝, 驱动不画色条; 后续和平无法显示(st7789v.c); - 取消了驱动和fb相关的printf # qspi_dual_v2002.img - 完美双屏异显;