ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

U-Boot 移植(3)

U-Boot 移植(3) 3.3 LCD 屏幕驱动修改在U-Boot 移植2中我们通过严密的 Kconfig 全局注册流与板级文件重构成功打通了自定义单板 mx6ull_kd 的编译闭环并实现了控制台UART的专属字符串输出。然而此时的 U-Boot 依然套着原厂驱动的“外壳”——屏幕相关的物理输出信息依然固化在官方默认的 TFT43AB (480x272) 规格导致物理屏幕目前仍处于黑屏、闪烁或无法承载画面的瘫痪状态。uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的xxx 为板子名称也就是\include\configs\mx6ull_kd.h\board\freescale\mx6ull_kd\mx6ull_kd.c3.3.1 LCD 引脚确认在 mx6ull_kd.c 中寻找 lcd 相关配置MX6_PAD_LCD_CLK__LCDIF_CLK命名规则介绍MX6_PAD_LCD_CLK前半段代表 i.MX6ULL 芯片物理封装上一个真实的、肉眼可见的物理引脚管脚名称叫 LCD_CLK。LCDIF_CLK后半段代表将这个物理引脚切换到芯片内部的 eLCDIF增强型液晶显示接口 控制器上作为它的像素时钟输出线CLK。总结把芯片上名字叫 LCD_CLK 的这根物理引脚复用切换为 LCDIF_CLK也就是显卡控制器的像素时钟输出线功能。LCD_CLK像素时钟信号线。LCD_ENABLE数据使能信号线DE 模式。LCD_HSYNC行同步信号线。LCD_VSYNC场同步信号线我们可以到以下文件中查找其对应的 IO 引脚\arch\arm\include\asm\arch-mx6\mx6ul_pins.hMX6_PAD_LCD_CLK__LCDIF_CLK IOMUX_PAD(0x0390, 0x0104, 0, 0x0000, 0, 0),参数 10x0390 ── 复用控制寄存器偏移量 (Mux Register Offset)物理含义指 IOMUXC_SW_MUX_CTL_PAD_LCD_CLK 寄存器相对于 IOMUXC 基地址的偏移量。手册对齐去查阅 i.MX6ULL 芯片手册的第 32 章IOMUXC 章节时搜索地址 0x0390会发现它精确指向的就是 LCD_CLK 这个物理管脚的功能选择寄存器。参数 20x0104 ── 电气属性寄存器偏移量 (Pad Config Register Offset)物理含义指 IOMUXC_SW_PAD_CTL_PAD_LCD_CLK 寄存器的物理偏移量。手册对齐这个寄存器负责控制该引脚的阻抗、上下拉电阻、驱动电流、虚焊检测等物理电气特性。代码里后面紧跟的 | MUX_PAD_CTRL(LCD_PAD_CTRL)其配置值最终就是写入到由 0x0104 指定的这个硬件寄存器里。参数 30 ── 复用模式选择值 (Mux Mode)物理含义直接写入到 MUX_MODE 寄存器位通常是 Bit[3:0]的数值。底层机制i.MX6ULL 的一个物理引脚可以复用成多达 8 种不同的功能ALT0 ~ ALT7。填 0 代表选择 ALT0 模式。手册中 LCD_CLK 管脚的 ALT0 功能刚好就是 LCDIF_CLK显卡时钟输出。补充如果这里填 5ALT5这个引脚就会变成一个普通的输入输出 IO 口GPIO3_IO00。参数 40x0000 ── 输入选择寄存器偏移量 (Select Input Register Offset)物理含义当引脚被复用为某种输入功能例如接收外部传感器信号、作为接收串口等时需要用这个寄存器来多路选择硬件内部的数据通路。底层机制因为 LCD_CLK 在这里是作为显卡的时钟输出引脚将时钟信号送给屏幕不涉及数据输入所以不需要配置输入选择寄存器直接硬编码填 0x0000 占位。参数 50 ── 输入选择寄存器写入值 (Select Input Value)物理含义配合参数 4 使用。既然参数 4 的寄存器地址是 0x0000不存在那么这里写入的选项值自然也直接填 0。参数 60 ── 纯软件保留标志位 (Reserved Flag)物理含义U-Boot 框架为了兼容不同系列如 i.MX6 和 i.MX7的芯片结构而留下的垫片参数在 i.MX6ULL 中不映射任何硬件寄存器物理上无意义恒填 0。 1. 相同的地方在数据总线和核心时序总线上百问网完全沿用了 NXP 官方的经典设计。24根RGB数据线LCD_DATA00 ~ LCD_DATA23 对应的物理管脚和复用关系完全一致。4根核心时序线时钟线LCD_CLK数据使能线LCD_ENABLE/DE行同步线LCD_HSYNC场同步线LCD_VSYNC这意味着代码里数组中前 28 行关于 MX6_PAD_LCD_xxx__LCDIF_xxx 的配置和韦东山的板子完全适配不用改。 2. 不同的地方原厂官方 EVK 评估板为了追求功能全面把 LCD 的外围控制引脚复位接在了一些非常偏僻、特殊的管脚甚至板外扩展芯片上。在设计底板时为了让电路更适合消费级、工业级开发对复位引脚进行了重新布线⚠️ 致命差异LCD 复位引脚RESETNXP 官方 EVK 默认使用的是 SNVS 域的引脚 MX6_PAD_SNVS_TAMPER9__GPIO5_IO09。以下是韦东山开发板的原理图芯片厂商NXP在设计这颗 i.MX6ULL 芯片时将芯片上的物理引脚编号114号管脚与软件代码中的寄存器逻辑名称GPIO3_IO04绑定在一起所以114引脚对应GPIO3_IO04。修改如下1. 修改 lcd_pads 数组 lcd_pads[ ]/* 删除或注释掉原厂默认的复位引脚MX6_PAD_SNVS_TAMPER9__GPIO5_IO09 */// MX6_PAD_SNVS_TAMPER9__GPIO5_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),/* 替换为百问网标准的 LCD 复位引脚Pin 114 复用为 GPIO3_IO04 */MX6_PAD_LCD_RESET__GPIO3_IO04|MUX_PAD_CTRL(NO_PAD_CTRL),2. 修改 do_enable_parallel_lcd这个函数负责在上电时给屏幕物理复位时序。需要把控制的 GPIO 编号从 5, 9 改为 3, 4/* Reset the LCD */gpio_request(IMX_GPIO_NR(5,9),lcd reset);gpio_direction_output(IMX_GPIO_NR(5,9),0);udelay(500);gpio_direction_output(IMX_GPIO_NR(5,9),1);修改如下/* Reset the LCD */gpio_request(IMX_GPIO_NR(3,4),lcd reset);gpio_direction_output(IMX_GPIO_NR(3,4),0);udelay(500);gpio_direction_output(IMX_GPIO_NR(3,4),1);3.3.2 LCD 配置参数structdisplay_info_tconstdisplays[]{{.busMX6UL_LCDIF1_BASE_ADDR,.addr0,.pixfmt24,.detectNULL,.enabledo_enable_parallel_lcd,.mode{.nameTFT43AB,.xres480,.yres272,.pixclock108695,.left_margin8,.right_margin4,.upper_margin2,.lower_margin4,.hsync_len41,.vsync_len10,.sync0,.vmodeFB_VMODE_NONINTERLACED}}};先看寄存器基地址#defineMX6UL_LCDIF1_BASE_ADDR(AIPS2_OFF_BASE_ADDR0x48000)MX6UL_LCDIF1_BASE_ADDR 是 i.MX6ULL 芯片内部的 eLCDIFEnhanced LCD Interface增强型液晶显示接口控制器的寄存器基地址。接下来我们逐步深入分析#defineMX6UL_LCDIF1_BASE_ADDR(AIPS2_OFF_BASE_ADDR0x48000)↓#defineAIPS2_OFF_BASE_ADDR(ATZ2_BASE_ADDR0x80000)↓#defineATZ2_BASE_ADDRAIPS2_ARB_BASE_ADDR↓#defineAIPS2_ARB_BASE_ADDR0x02100000把地址相加0x02100000 0x80000 0x48000 0x021C8000查阅 IMX6ULL 参考手册的 eLCDIF 的寄存器部分发现其寄存器基地址和计算出来的地址完全一致。LCD 的参数配置查阅屏幕参考手册第一步锁定结构体对应的时序参数翻到手册的 第 11 页 “9. Timing Characteristics”时序特性 。这里有两个模式DE MODE 和 SYNC MODE 。i.MX6ULL 通常使用 SYNC MODE同步模式我们需要将这里的硬件参数直接填进 U-Boot 的 displays[] 结构体中物理分辨率.xres水平有效像素直接看表格中的 Horizontal Effective Time (THA) 它的典型值Typ.固定为 1024 。.yres垂直有效像素看表格中的 Vertical Valid (Tvd) 典型值固定为 600 。**结论 **这是一块标准的1024 × 600 1024 \times 6001024×600的 7 寸高清屏 。水平消隐时序单位tCLK 像素时钟周期.left_margin行消隐后肩对应表格中的 Horizontal Back Porch (Thb) 它的典型值Typ.是 140 。.right_margin行消隐前肩对应表格中的 Horizontal Front Porch (Thfp) 它的典型值是 160 。.hsync_len行同步脉宽对应表格中的 Horizontal Pulse Width (Thpw) 它的典型值是 20 。 3. 垂直消隐时序单位th 行扫描周期.upper_margin场消隐后肩对应表格中的 Vertical Back Porch (Tvb) 它的典型值是 20 。.lower_margin场消隐前肩对应表格中的 Vertical Front Porch (Tvfp) 它的典型值是 12 。 .vsync_len场同步脉宽对应表格中的 Vertical Pulse Width (Tvw) 它的典型值是 3 。第二步计算 U-Boot 所需的 .pixclock在表格的第一行有一个关键参数Dot Clock (MCLK) 其典型值Typ.是 51.2 MHz 。因为 U-Boot 结构体需要的是皮秒ps单位使用标准公式换算 pixclock 10 12 时钟频率 (Hz) 1 , 000 , 000 , 000 , 000 51 , 200 , 000 ≈ 19531 \text{pixclock} \frac{10^{12}}{\text{时钟频率 (Hz)}} \frac{1,000,000,000,000}{51,200,000} \approx \mathbf{19531}pixclock时钟频率(Hz)1012​51,200,0001,000,000,000,000​≈19531由上可对函数进行修改structdisplay_info_tconstdisplays[]{{.busMX6UL_LCDIF1_BASE_ADDR,// eLCDIF控制器基地址.addr0,.pixfmt24,// 对应手册 RGB24BIT interface [cite: 10].detectNULL,.enabledo_enable_parallel_lcd,// 里面包含了对 RESET(3,4) 和背光(1,8) 的操作.mode{.nameSTD70_1024x600,// 屏幕起名.xres1024,// 手册Horizontal Effective.yres600,// 手册Vertical Valid.pixclock19531,// 由手册 51.2MHz 计算所得.left_margin140,// 手册Horizontal Back Porch.right_margin160,// 手册Horizontal Front Porch.upper_margin20,// 手册Vertical Back Porch.lower_margin12,// 手册Vertical Front Porch.hsync_len20,// 手册Horizontal Pulse Width.vsync_len3,// 手册Vertical Pulse Width.sync0,.vmodeFB_VMODE_NONINTERLACED}}};mx6ull_kd.c 修改完后还要修改 mx6ull_kd.h把两处panelTFT43AB\0\改成panelSTD70_1024x600\0\3.3.3 烧录报错及处理直接编译烧写会发现它还是会显示 TFT43AB报错根本原因代码里mx6ull_kd.c把原厂默认的数组改成了只支持新名称 “STD70_1024x600”。环境里EMMC 缓存系统在跑旧固件时残留在 EMMC 里的环境变量仍然是旧的 “TFT43AB”。运行结果video.c 拿着旧名字 “TFT43AB” 去数组里匹配结果一个都没对上于是执行到第 59 行打印出 unsupported panel TFT43AB。解决它甚至不需要重新编译代码只需要在串口终端强制清空旧的 EMMC 缓存。请在串口终端倒计时结束前按下任意键进入 U-Boot 命令行模式提示符为 输入envdefault-a # 强制清除 EMMC 中的旧缓存 saveenv # 将其持久化写入 EMMC 存储区 reset # 重启单板重启后即可看到 LCD 屏幕点亮驱动修改成功
返回列表