1 LCD调试常见问题

1.1 Green stripes on the right side of the LCD screen;

如下图:

alt text
Please confirm the modification according to the following picture;:

alt text

1.2 LCD shows screen distortion;

debug方法,如下图:
alt text

1, After jlink connection, press h to stop the cpu;,
2, In the cmd window, go to this directory and execute \release\tools\crash_dump_analyser\script\save_ram_a0.bat to save memory information;
3, Dump out memory information;如下:

alt text
4, Run the release\tools\crash_dump_analyser\simarm\t32marm.exe tool to restore the scene of hcpu;,选择load_memory_butterfli_hcpu.cmm进行Restore operation;,

alt text
然后再跳出,When selecting the bin at address 0x20000000, select hcpu_ram.bin;

alt text
When it pops up and needs to select the bin at address 0x60000000, select psram.bin;,如下图:

alt text
When it pops up and you need to select a *.axf file, select the *.axf file of hcpu that you compiled;,
Wachdemo工程对应的路径为: example\watch_demo\project\ec-lb551\build\bf0_ap.axf
如下图:

alt text
After restoring the scene, open the Var->watch window, enter the drv_lcd variable to be searched, and then add it to the watch window for viewing;,

alt text
Expand the drv_lcd variable in the watch window, and find that the window size set by the LCD does not match the LCD driver;,

alt text
Modify the configuration in the rtconfig.h file, and the screen distortion problem is solved;.

#define LCD_HOR_RES_MAX 454
#define LCD_VER_RES_MAX 454

Change several macros of the corresponding littleVGL screen setting register to be consistent with the LCD size;

#define LV_HOR_RES_MAX 454
#define LV_VER_RES_MAX 454
#define LV_DPI 315
#define LV_FB_LINE_NUM 454

1.3 The first frame of the TFT screen is distorted when booting or waking up;

The screen distortion occurs when the display is turned on, and the data in the GRAM of the screen is incorrect;,从开机显示逻辑来看,
应该是先送好数, 再display_on芯片,再开背光,如果顺序错了,就会导致第一帧花屏, 也可以采用After the initialization is completed, send a black screen over;,如果屏驱IC支持写寄存器让输出黑屏,优先采用写屏寄存器方式,
或者采用如下方法:
Refer to the practice of SPD2012 driver in the reference code, before turning on the screen, send the data of the black screen through the background of LCDC first to clear the GRAM inside the screen;.

alt text

1.4 The problem that the initialization read and write are normal but the screen does not light up;

Each screen IC will have different delays between power-on and register initialization;,If the delay from screen power-on to LCD register initialization init in the BSP_Power_Up function is not enough, it will cause the register unable to be configured during initialization, resulting in the LCD driver not being able to start;;
解决方法:
Add a certain delay according to the requirements of the screen drive IC at the beginning of the LCD register initialization init;。

alt text

The following lists the three delay lengths that need to be paid attention to during screen initialization. Too long delay will cause the screen to light up slowly. When reducing the delay, it must be based on the screen IC specification;

static void SPD2010_Init_SPI_Mode(LCDC_HandleTypeDef *hlcdc)
{
    uint8_t   parameter[14];
    int i, j;

    memcpy(&hlcdc->Init, &lcdc_int_cfg, sizeof(LCDC_InitTypeDef));
    HAL_LCDC_Init(hlcdc);

    BSP_LCD_Reset(0);//Reset LCD
  	rt_thread_delay(1);  //依据屏驱IC规格书配置此延时
    BSP_LCD_Reset(1);

    /* Wait for 50ms */
    rt_thread_delay(50); //依据屏驱IC规格书配置此延时

    for (i = 0; i < sizeof(lcd_init_cmds) / MAX_CMD_LEN; i++)
    {
        SPD2010_WriteReg_I(hlcdc, lcd_init_cmds[i][0], (uint8_t *)&lcd_init_cmds[i][2], lcd_init_cmds[i][1]);
		HAL_Delay_us(10);
    }
	rt_thread_delay(50); //依据屏驱IC规格书配置此延时
	
  SPD2010_WriteReg(hlcdc, 0x29,(uint8_t *)NULL, 0);

}

1.5 How to export from Framebuffer to check if the image is normal;?

a,Find the address of the global variable buf1_1 from the *.map file in the build directory;,如下图:
或者Ozone下也能找到buf1_1全局变量的地址,

alt text
b, jlink saves memory values as bin files;,
savebin

;
例如: savebin D:\sifli\customer\weizhang\lcd\1.bin 0x20036940 0x52e20
The screen is in rgb565 format, occupying 2 bytes, with a resolution of 412x412, and the length is 412x412x2=339488=0x52E20;
c, Use the python tool tools\bin2bmp\bin2bmp.py to convert bin to bmp image format;
The command is as follows;:
Old command;:
python bin2bmp.py <文件路径> <屏长> <屏宽> <每个像素占用bit> <bin的偏移地址>
例如: 屏412x412, 1.bin是从基址开始save,不需要偏移

python bin2bmp.py 1.bin 412 412 16 0

New command;:
python bin2bmp.py <文件路径> <颜色格式> <屏长> <屏宽> <bin的偏移地址>

python bin2bmp.py 1.bin rgb565 412 412 0

Supported color formats: a8/rgb565/rgb888/argb8888/rgba8888;
d,A new script jlinkbin2bmp.py has been added, which can export bmp images at one time from savebin to conversion when jlink is connected;,如下命令:

 python jlinkbin2bmp.py SF32LB55X rgb565 412 412 2004E3E0

e,For the latest instructions, please refer to: tools\bin2bmp\readme.txt file;。

1.6 Common Assert crashes in LCD drivers;

出现Assert:

Assertion failed at function:async_send_timeout_handler, line number:876 ,(0); 


alt text
根本原因:
Turned on the macro LCD_GC9B71_VSYNC_ENABLE to enable the TE function, the LCD will wait for the TE signal to refresh the screen after sending the data, but the TE signal of the LCD never arrived, causing a timeout Assert;。
常见情形1:
This assert occurs during the OTA process because the default IO of the motor is PA44, and in this project, PA44 is the reset signal of the lcd. Entering dfu will start the motor, causing the LCD to be mistakenly reset, and the LCD no longer outputs TE signals, then the dfu crashes when refreshing the screen;。
常见情形2:
Crash when waking up by pressing the screen-off button;
表现,就是灭屏后,按按键唤醒后,出现assert,死在刷屏等待TE的assert中。
根本原因:
After initializing the LCD screen, the initialization delay inside the TP is too long, with a delay of 100ms;。The customer uses the rt_thread_mdelay(100); delay function, at this time, Hcpu enters the IDLE process and goes to sleep;,
When the timer is up, it wakes up from standby. At this point, the LCD has lost power and has not been initialized, so there will be no TE signal. Continuing to refresh the previous screen will cause a crash;。
解决方案:
In the driver, do not use the rt_thread_mdelay(10); delay function;,
Instead, use: HAL_Delay(100); or HAL_Delay_us(10); functions;,
The rt_thread_mdelay function will perform a thread switch, and after switching to the Idle process, it will go to sleep;,
The HAL_Delay function is a dead loop and will not switch to the Idle process;。

1.7 打静电ESD时LCD花屏和定屏问题

解决思路:Determine whether the screen display is normal through the TE output signal or register value of the screen drive IC, and reinitialize the LCD if it is abnormal;

  1. If the LCD screen is garbled or frozen, there will be no TE signal output;,
    解决方案:
    In the drv_lcd.c file, in the async_send_timeout_handler function waiting for TE timeout;:
    Use the code in the red box below to reinitialize the LCD;:

    drv_lcd.assert_timeout = 3; //配置刷屏超时情况下是assert、不做操作还是重初始化LCD


alt text
2. 如果是LCD花屏时,有TE信号输出,需要读取LCD寄存器值,才得知花屏状态。
解决方案:

  • According to the above solution 1, first open the screen timeout reinitialization LCD code;。

  • In the XXXX_WriteMultiplePixels send screen function of the LCD driver;,
    Add reading of the LCD register value, if the register is found to be incorrect, return and do not refresh the screen;,
    At this time, because the screen operation is not performed, it will cause the screen refresh to enter RT_ETIMEOUT, and reinitialize the LCD according to the configuration drv_lcd.assert_timeout;,如下图:
    Made three judgments on the LCD register, if the register values are wrong for three times, it is considered that the LCD is abnormal, return, trigger the screen refresh timeout, and reinitialize the LCD;。

    alt text

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 开关机动画或者充电图像显示扭曲问题

显示异常如下图:

alt text


alt text

根本原因:
Pixel alignment issue, need to send a multiple of 4 pixels to the screen;,如下图一屏驱IC的datasheet,指明给屏送数,需要送像素为4的倍数:

alt text

解决方案:
1,Image editing: Ensure that the image sent to the entire screen for boot animation and charging is of even resolution;,如下图尺寸为161x80,修正为160x80后,图片扭曲问题解决。
alt text

2,In the code, perform 4x pixel alignment, for example, change the above image from 161x80 to 164x80, and fill the other 3 pixels with background color;,
Or drop one pixel to 160x80;。

1.9 屏QSPI读不到屏ID的问题

The current 55x, 56x series chips, the QSPI of the screen drive only supports reading QSPI/SPI data from IO0, does not support reading SPI data output from IO1, and the screen ID output from IO1 is not supported;(52x系列芯片可以支持配置IO0-IO3任一IO读取),如下图:
alt text

Interface-II mode output is not supported;,如下图:

alt text

Screen ID output from IO0 is supported;,如下图:

alt text

解决方案:
GPIO simulates SPI to read chipid;

备注: The current 52x series chips already support any data line among IO0-IO3 in the QSPI of the screen drive to read and write QSPI/SPI data;
配置方法如下:

.readback_from_Dx= 0,  /* 0对应IO0,  1对应IO1,  2对应IO2,  3对应IO3,*/


alt text

1.10 屏QSPI动态调整读写寄存器CLK速率

Some screen drive ICs have an upper limit requirement for the CLK frequency of reading and writing registers during initialization, for example, it cannot be higher than 20Mhz, but sending to the screen can reach 50Mhz, which can be modified as follows;:
The default screen sending frequency is .freq = 48000000, //48Mhz;

alt text
Change to 2Mhz when reading the register;,如下:

alt text

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
        }
    }
}

When writing to the GC9B71_WriteReg register, you can also use the above method to adjust the clk rate;。