1 LCD调试常见问题¶
1.1 LCD屏幕右侧有一个绿条纹,怎么解决?¶
如下图:
请按下图确认修改:
1.2 LCD显示花屏,debug方法,如下图:¶
1, jlink连接后,敲h,让cpu停下来,
2, cmd窗口到该目录执行\release\tools\crash_dump_analyser\script\save_ram_a0.bat保存内存信息
3, dump出内存信息如下:
4, 运行release\tools\crash_dump_analyser\simarm\t32marm.exe工具, 恢复hcpu的现场,选择load_memory_butterfli_hcpu.cmm进行恢复操作,
然后再跳出,选择0x20000000地址bin时,选择hcpu_ram.bin
在跳出需要选择0x60000000地址的bin时, 选择psram.bin,如下图:
在跳出来需要选择*.axf文件时,选择你编译出来的hcpu的*.axf文件,
Wachdemo工程对应的路径为: example\watch_demo\project\ec-lb551\build\bf0_ap.axf
如下图:
恢复现场后, 打开Var->watch窗口,输入要查找的drv_lcd变量,再添加到watch窗口查看,
在watch窗口展开drv_lcd的变量,发现LCD设置的窗口尺寸大小与LCD驱动不符合,
修改rtconfig.h文件中的,配置后,花屏问题解决.
#define LCD_HOR_RES_MAX 454
#define LCD_VER_RES_MAX 454
把对应littleVGL的屏设置寄存器几个宏也要改为和LCD尺寸一致
#define LV_HOR_RES_MAX 454
#define LV_VER_RES_MAX 454
#define LV_DPI 315
#define LV_FB_LINE_NUM 454
1.3 TFT的LCD屏,开机或者从睡眠唤醒第一帧花屏¶
花屏是开显示时,屏GRAM内数据不对,从开机显示逻辑来看,
应该是先送好数, 再display_on芯片,再开背光,如果顺序错了,就会导致第一帧花屏, 也可以采用初始化完成后,送黑屏过去,如果屏驱IC支持写寄存器让输出黑屏,优先采用写屏寄存器方式,
或者采用如下方法:
参考代码中SPD2012驱动的做法,在打开屏幕之前,先通过LCDC的背景送黑屏的数据过去,清除屏幕内部的GRAM.
1.4 更换晟和+基合(SH8601Z)的屏后,reset之后不亮屏¶
BSP_Power_Up中会有屏上电的动作,由于屏的特殊性,到lcd init显示时lcd充电时间不够,导致lcd驱动不起来,需要再lcd init开始的时候,做个延时。
1.5 如何从Framebuffer 导出来看图像是否正常?¶
a,从build目录*.map文件找到buf1_1全局变量的地址,如下图:
或者Ozone下也能找到buf1_1全局变量的地址,
b, jlink保存内存值为bin文件,
savebin <路径> <地址> <长度>
例如: savebin D:\sifli\customer\weizhang\lcd\1.bin 0x20036940 0x52e20
该屏是rgb565格式,占2个byte, 412x412分辨率, 长度为412x412x2=339488=0x52E20
c, 用tools\bin2bmp\bin2bmp.py 的python工具,把bin转换为bmp图片格式
命令如下:
旧命令:
python bin2bmp.py <文件路径> <屏长> <屏宽> <每个像素占用bit> <bin的偏移地址>
例如: 屏412x412, 1.bin是从基址开始save,不需要偏移
python bin2bmp.py 1.bin 412 412 16 0
新命令:
python bin2bmp.py <文件路径> <颜色格式> <屏长> <屏宽> <bin的偏移地址>
python bin2bmp.py 1.bin rgb565 412 412 0
支持的颜色格式: a8/rgb565/rgb888/argb8888/rgba8888
d,新增了jlinkbin2bmp.py脚本,在jlink连接的情况下,从savebin到转换,一次性导出bmp图片,如下命令:
python jlinkbin2bmp.py SF32LB55X rgb565 412 412 2004E3E0
e,最新使用说明,请参考:tools\bin2bmp\readme.txt文件。
1.6 LCD驱动中常见的Assert死机¶
出现Assert:
Assertion failed at function:async_send_timeout_handler, line number:876 ,(0)
根本原因:
开了宏 LCD_GC9B71_VSYNC_ENABLE 开启了TE功能,LCD送数后会等待TE信号再进行刷屏,一直没有等到LCD的TE信号到来,超时Assert。
常见情形1:
OTA过程出现该assert,因为马达的默认IO是PA44, 这个项目PA44是lcd的reset信号,进入dfu会启动马达,导致LCD被误reset,LCD不再有TE信号输出,然后dfu刷屏时死机。
常见情形2:
灭屏按键唤醒死机
表现,就是灭屏后,按按键唤醒后,出现assert,死在刷屏等待TE的assert中。
根本原因:
初始化LCD屏后,在TP内初始化延时过长,存在100ms的延时。而客户采用的rt_thread_mdelay(100);延时函数,此时Hcpu进入IDLE进程,进入睡眠,
定时器到了后,又从standby醒来,此时LCD掉过电,LCD没有初始化过,不会有TE信号,此时继续刷之前的刷屏,死机。
解决方案:
驱动中,不要用rt_thread_mdelay(10);延时函数,
要改用:HAL_Delay(100); 或者 HAL_Delay_us(10); 函数,
rt_thread_mdelay函数,会进行线程切换,切换到Idle进程后,就会睡眠,
HAL_Delay函数,是死循环,不会切走到Idle进程。
1.7 打静电ESD,LCD花屏或者无TE信号输出,重初始化LCD¶
a,如果LCD花屏或者死机时,无TE信号输出,
解决方案:
drv_lcd.c文件中,在等待TE超时函数async_send_timeout_handler中:
采用下面红框这块代码,就能重初始化LCD:
b,如果是LCD花屏时,有TE信号输出,需要读取LCD寄存器值,才得知花屏状态。
解决方案:
1,按照上面的方案a,先打开刷屏timeout重初始化LCD代码。
2,在LCD驱动的XXXX_WriteMultiplePixels送屏函数中,
添加读取LCD寄存器值,如果发现寄存器不对,return出去,不进行刷屏,
这时因为没有执行送屏操作,就会导致刷屏timeout进入async_send_timeout_handler中,重初始化LCD,如下图:
做了3次对LCD寄存器的判别,如果3次寄存器值都不对,认为LCD异常,return出去,触发刷屏timeout,重初始化LCD。
void SH8601Z_WriteMultiplePixels(LCDC_HandleTypeDef *hlcdc, const uint8_t *RGBCode, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
uint32_t size;
static uint32_t err_num=0;
//DEBUG_PRINTF("SH8601Z: WriteMultiplePixels %d,%d,%d,%d \n",Xpos0, Ypos0, Xpos1, Ypos1);
SH8601Z_ALIGN2(Xpos0);
SH8601Z_ALIGN2(Ypos0);
SH8601Z_ALIGN1(Xpos1);
SH8601Z_ALIGN1(Ypos1);
uint32_t data;
data = SH8601Z_ReadData(hlcdc, 0x0A, 1) & 0xff;
if(0x9c != data)
{
if(err_num<3)
{
err_num++;
rt_kprintf("\nSH8601Z_Read0A:0x%x,err_num:%d \n", data,err_num);
}
else
{
rt_kprintf("reinit SH8601Z \n");
err_num=0;
return; //return To trigger drv_lcd timeout and reinit lcd
}
}
else
{
err_num=0;
}
HAL_LCDC_LayerSetData(hlcdc, HAL_LCDC_LAYER_DEFAULT, (uint8_t *)RGBCode, Xpos0, Ypos0, Xpos1, Ypos1);
HAL_LCDC_SendLayerData2Reg_IT(hlcdc, SH8601Z_WRITE_RAM, 1);
}
1.8 开关机动画或者充电图像显示扭曲问题¶
显示异常如下图:
根本原因:
像素对齐问题,需要送4的倍数的像素给屏,如下图一屏驱IC的datasheet,指明给屏送数,需要送像素为4的倍数:
解决方案:
1,修图:要保证开机动画,充电这种一幅图送往整屏的图像,要是偶数分辨率,如下图尺寸为161x80,修正为160x80后,图片扭曲问题解决。
2,代码中,进行4倍像素对齐,比如如上图片为161x80,修改成164x80,另外3个像素填充背景色,
或者丢掉一个像素为160x80。
1.9 屏QSPI读不到屏ID的问题¶
目前55x,56x系列芯片,屏驱的QSPI只支持IO0读取QSPI/SPI数据,不支持读取IO1输出的SPI数据,屏ID从IO1输出,不支持(52x系列芯片可以支持配置IO0-IO3任一IO读取),如下图:
Interface-II方式输出,不支持,如下图:
屏ID从IO0输出,支持,如下图:
解决方案:
GPIO模拟SPI读chipid
备注:
目前52x系列芯片,已经支持屏驱的QSPI中IO0-IO3任一数据线,读写读取QSPI/SPI数据
配置方法如下:
.readback_from_Dx= 0, /* 0对应IO0, 1对应IO1, 2对应IO2, 3对应IO3,*/
1.10 屏QSPI读写寄存器时动态调整clk的速率¶
有些屏驱IC,在初始化的时候,对读写寄存器的CLK频率有上限要求,比如不能高于20Mhz, 送屏则可以到50Mhz,可以通过如下方式修改:
默认送屏频率为.freq = 48000000, //48Mhz
在读寄存器的时候,改成2Mhz,如下:
void GC9B71_ReadMode(LCDC_HandleTypeDef *hlcdc, bool enable)
{
if (HAL_LCDC_IS_SPI_IF(lcdc_int_cfg.lcd_itf)){
if (enable){
HAL_LCDC_SetFreq(hlcdc, 2000000); //read mode min cycle 300ns
}
else {
HAL_LCDC_SetFreq(hlcdc, lcdc_int_cfg.freq); //Restore normal frequency
}
}
}
写寄存器GC9B71_WriteReg的时候,也可以采用如上的方法来调整clk速率。