WINCE6.0+ILI9806E休眠唤醒显示异常问题


分类: WINCE驱动开发   265人阅读  评论(0)  收藏  举报

我们的系统WINCE6.0,它支持睡眠和唤醒,目的是想在不使用的时候让设备进入睡眠状态,降低功耗,我们遇到的问题就是设备正常启动后正常显示,但睡眠然后唤醒后要么显示白屏要么是条纹状白屏,如下图:

WINCE6.0+ILI9806E休眠唤醒显示异常问题_第1张图片

图1

WINCE6.0+ILI9806E休眠唤醒显示异常问题_第2张图片

图2

同样的驱动调用流程、睡眠和唤醒流程,我们另一一种RGB显示屏(与你们的屏控制方式比较接近,也是采用串行总结初始化驱动IC)就正常。

 

问题排查及解决过程如下:做过下面的尝试,睡眠唤醒也还是上图的现象

(1)确认显示屏下面的控制引脚休眠前后是否正确

GPC0--------LCD_CS低电平选中---29----输出高----OK

GPC1--------LCD_VCLK---23----正弦波----OK

GPC2--------LCD_HSYNC---22---高脉冲宽的矩形波----OK

GPC3--------LCD_VSYNC---21---高脉冲宽的矩形波----OK

GPC4--------LCD_EN---24----高脉冲宽的矩形波(睡眠唤醒)----OK

GPC[15:10]---VD[5:0]---[7:2]---OK

 

GPD0--------LCD_RESET低电平初始化驱动IC-------25---输出高---OK

GPD[7:2]---------VD[11:6]-----------[13:8]---OK

GPD[15:10]---------VD[17:12]---------[19:14]---OK

 

GPK0---LCD_SDA---27----输出高---OK

GPK1---LCD_SCL---28---输出高---OK

 

VCC---30---OVCC---31---OK

—睡眠前、睡眠中和唤醒后都是3.263V,和睡眠唤醒后正常显示的一样。

 

(2)休眠时拉低显示屏的LCD_RESET引脚+唤醒时重新初始化显示屏驱动IC

在睡眠前会拉低显示屏驱动IC的复位引脚,唤醒之后先拉低复位引脚,然后调用初始化代码重新初始化驱动IC。睡眠的时候VCC和IOVCC都保持为正常显示时的3.3V,但问题依旧,经过排查发现S3C2451三星原厂的BSP包中S3C2450Disp::DevPowerOn函数,如下:

WINCE6.0+ILI9806E休眠唤醒显示异常问题_第3张图片

图3

图3中DeviceIoControl(m_hVideoDrv,IOCTL_SVE_PM_SET_POWER_ON, NULL, 0, NULL, 0, &dwBytes, NULL)对应调用的是s3c2450_Video.dll下的VDE_IOControl函数,IOCTL_SVE_PM_SET_POWER_ON控制码的处理代码很简单:

bRet = SVE_video_engine_power_on();

我们BSP包的S3C2450Disp::DevPowerOn函数,如下:

WINCE6.0+ILI9806E休眠唤醒显示异常问题_第4张图片

图4

VDE_IOControl函数,IOCTL_SVE_PM_SET_POWER_ON控制码的处理代码很简单:

[cpp]  view plain copy
  1. <span style="font-size:14px;">bRet = SVE_video_engine_power_on();  
  2. LDI_deinitialize_LCD_module();</span>  

可见我们BSP对这两者的调用和三星原厂对它们的的调用先后顺序发过来了,但为什么对于之前的显示屏就没有问题呢?很奇怪,这可能和显示屏采用不同驱动IC的初始化这块有关。

 

(3)休眠时不拉低显示屏的LCD_RESET引脚+休眠唤醒显示屏驱动IC

[cpp]  view plain copy
  1. <span style="font-size:14px;">        void InitLDI_RGB_ILI9806E_sleep_in(void)  
  2. {  
  3.         RETAILMSG(1, (TEXT("InitLDI_RGB_ILI9806E_sleep_in()\r\n")));  
  4.           SPI_WriteComm(0x28);//display off  
  5.         DelayLoop_1ms(10);  
  6.         SPI_WriteComm(0x10); // Sleep in  
  7.         DelayLoop_1ms(10);  
  8. }  
  9.    
  10. void InitLDI_RGB_ILI9806E_sleep_out(void)  
  11. {  
  12.         RETAILMSG(1, (TEXT("InitLDI_RGB_ILI9806E_sleep_out()\r\n")));  
  13.         //This command turns off sleep mode  
  14.         SPI_WriteComm(0x11);//sleep out  
  15.         DelayLoop_1ms(220);  
  16.           
  17.         //This command is used to recover from Display Off mode. Output data isenabled.  
  18.         SPI_WriteComm(0x29);//display on  
  19.         DelayLoop_1ms(20);  
  20. }</span>  


在休眠之前调用InitLDI_RGB_ILI9806E_sleep_in函数,唤醒时调用InitLDI_RGB_ILI9806E_sleep_out问题依旧。显示屏技术支持给出下面的建议:

1)  在Sleep InèSleep Out 的过程中,Reset信号被拉低过,导致IC内部记录的Initial 值被清洗掉;

2) 在Sleep InèSleepOut 的过程中,VCI、IOVCC有出现掉电的情况;

查找整个BSP代码,没有发现有代码拉低复位引脚,后来用示波器来监测,发现在唤醒的时候的确有一瞬间被拉低了,问题在哪里呢?原来是在休眠之前的OEMPowerOff函数中并没有保存LCD_RESET所对应的GPD引脚状态,下图是CPU数据手册的相关描述部分

//GPDCON=0x40000,GPDDAT=0x200

WINCE6.0+ILI9806E休眠唤醒显示异常问题_第5张图片

图5

在OEMPowerOff函数中休眠前增加下面的代码:

[cpp]  view plain copy
  1. <span style="font-size:14px;">saveArea[87]  =INPORT32(&pIOPort->GPDCON);  
  2.    saveArea[88]  =INPORT32(&pIOPort->GPDDAT);  
  3. saveArea[89] =INPORT32(&pIOPort->GPDUDP);</span>  

唤醒时增加下面的代码就OK了。

[cpp]  view plain copy
  1. <span style="font-size:14px;">OUTPORT32(&pIOPort->GPDCON,   saveArea[87]);  
  2.    OUTPORT32(&pIOPort->GPDDAT,  saveArea[88]);  
  3. OUTPORT32(&pIOPort->GPDUDP,    saveArea[89]);</span>  

你可能感兴趣的:(WINCE驱动开发)