📄 lcd_drv.c
字号:
/******************************************************************************
Lenovo Mobile LTD. R&D Centre Shanghai Branch
Software Dept. I
Copyright(C) 2005.12
File Name : LCD_driver.c
autoor :
Date : 2005/12/26
Description:
********************************************************************************/
#include "LCD_drv.h"
#include "lcd\lcd_transport.h"
#include"dar\dar_api.h"
#include "spi_drv.h"
#include "pin_config.h"
#include <stdlib.h>
#include <stdarg.h>
#include "lls\lls_api.h"
#define DSR_TX_EMPTY 0x02
#define LCD_DEBUG
#define LCD_START_TRANS_DATA AI_SetBit(24) // Set C/D to data
#define LCD_START_TRANS_CMD AI_ResetBit(24)
#define LCD_TRS_WIAT 2
#define LCD_DEF_CONTRAST 0x4A
#define LCD_MAX_CONTRAST 0xff
#define LCD_WAIT(n) (0x8000|n)
#define LCD_END 0xffff
#define LCD_MAX_LEVEL 0xff
typedef enum lcd_state_e{
LCD_ST_UNKNOW,
LCD_ST_INITED
}lcd_state_e;
typedef enum lcd_trans_type_e{
LCD_TRS_NONE,
LCD_TRS_CMD,
LCD_TRS_DATA
}lcd_trans_type_e;
static lcd_ret_e _LCD_Init(void);
static void _LCD_Sleep(void);
static void _LCD_Wakeup(void);
static void _LCD_SetBacklight( U16 level);
static void _LCD_Reset(void);
static void _LCD_CfgSPIPin(void);
static void _LCD_CfgSPI(void);
static void _LCD_RstSPI(void);
static void _LCD_SPIWriteData(unsigned long data);
static void _LCD_SPIWriteCMD(unsigned long data);
static void _LCD_UpdateContrast(void);
void lcd_write_pixel( int x, int y, unsigned char data);
unsigned char g_lcd_buf[LCD_BUF_SIZE+LCD_BUF_CY];
static lcd_trans_type_e lcd_trans_type = LCD_TRS_NONE;
static lcd_state_e g_lcd_state = LCD_ST_UNKNOW;
static U16 g_lcd_backlight_level = 0x00;
UINT32 lcd_sleep_flag = 0;
static U8 _g_contrast = LCD_DEF_CONTRAST;
//#define LCD_IC_UC1612
#ifdef LCD_IC_UC1612
unsigned short lcd_init_seq[] =
{
0xE2, //system reset
LCD_WAIT(100), // delay 100ms
//LCD_WAIT(25), // delay 100ms
0x27, //set temperature compensation
LCD_WAIT(10),
0xA2, //set line rate 0xa0-0xa3 // CMD-14
0xC2, //set LCD mapping control 0xc0-0xc3 // CMD-18
0xD2, //set LCD Gray Shade 0xD0-0xD7 // CMD-19 gray shade is 3
0x2F, //set pump control
LCD_WAIT(10),
0x28, //set panel loading 0x28,0x29 // CMD-6
0xEB, //set LCD bias ratio
LCD_WAIT(10),
0x81, //REFERENCE VOLTAGE PARAMETER
LCD_DEF_CONTRAST,// SubLCD_WCom(SubCtrl); //SET REFERENCE VOLTAGE 0x00-0xFF
LCD_WAIT(10),
0x84, //set partial display control 0x84--disable 0x85--enable
0xA4, //set all-piexl-on 0xa4 0xa5
0xA6, //set inverse display 0xA6 0xA7
LCD_WAIT(1),
0x40, //set scroll line LSB // CMD-9(2-1)
0x50, //set scroll line MSB // CMD-9(2-2)
0xF1, //set com end
63,//63,//OK 63,//79,//63, //=0x3f OK
0xAF, //set display enable 4-gray mode
LCD_WAIT(20),
LCD_END
};
#else /*LCD_IC_UC1612*/
//UC1602S
unsigned short lcd_init_seq[] =
{
0xE2, //system reset
LCD_WAIT(100),
0x26, //set temperature compensation
LCD_WAIT(10),
0xA1, //set line rate 0xa0-0xa3
//0xc0,//0xC8, //set LCD mapping control 0xc0-0xc3//////c4
//0xc4,//0xC8, //set LCD mapping control 0xc0-0xc3//////c4
// 0xc8,//0xC8, //set LCD mapping control 0xc0-0xc3//////c4
//0xcc,//0xC8, //set LCD mapping control 0xc0-0xc3//////c4
0xc8,//0xC8, //set LCD mapping control 0xc0-0xc3//////c4
0x2E, //set power control
LCD_WAIT(10),
0xEB, //set LCD bias ratio BIAS=1/9
LCD_WAIT(10),
0x81, //REFERENCE VOLTAGE PARAMETER
LCD_DEF_CONTRAST,//SubLCD_WCom(Ctrl); //SET REFERENCE VOLTAGE 0x00-0xFF
LCD_WAIT(1),
0x84, //set partial display control 0x84--disable 0x85--enable
0xA4, //set all-piexl-on 0xa4 0xa5
0xA6, //set inverse display 0xA6 0xA7
0x00, //00
0x10, //
0xb0,//0xb0,//00
0x89,//89
0xF1, //set com end
0x3f,
LCD_WAIT(1),
0x40, //set scroll
0xAF, //set display enable 4-gray mode
LCD_WAIT(20),
LCD_END
};
#endif /*LCD_IC_UC1612*/
#ifdef LCD_DEBUG
static int g_er_line = 0;
static char *g_er_str = NULL;
#define LCD_TRACE LCD_Trace
#define LCD_SET_ER(ret,er) \
{\
ret = er;\
g_er_line = __LINE__;\
g_er_str = #er;\
}
#define LCD_CHK_ER(ret) \
{\
if(ret)\
{\
if(g_er_str)\
LCD_TRACE("LCD ER-STR:%s LN:%d", g_er_str, g_er_line);\
else\
LCD_TRACE("LCD ER-CODE:%d LN:%d", ret, g_er_line);\
}\
}
#else /*LCD_DEBUG*/
#define LCD_TRACE _LCD_Trace
#define LCD_SET_ER(ret,er)
#define LCD_CHK_ER(ret)
#endif /*LCD_DEBUG*/
void LCD_Init2(void)
{
LCD_Trace("LCD_Init");
_LCD_Init();
LCD_Trace("LCD End");
rvf_delay(10);
}
U16 LCD_GetMaxBackLightLevel(void)
{
return LCD_MAX_LEVEL;
}
lcd_ret_e LCD_SetBackLightLevel(U16 level)
{
lcd_ret_e ret = LCD_ER_OK;
//return ret;//maggie 2007-07-17 //' for test
LCD_TRACE("LCD Set BackLight Level:%d",level);
//LCD_TRACE("LCD Set g_lcd_backlight_level:%d",g_lcd_backlight_level);//'maggie
do
{
//_LCD_Init(); //' maggie
if(g_lcd_backlight_level == level)
break;
if(level >= LCD_MAX_LEVEL)
{
level = LCD_MAX_LEVEL-1;
}
if(g_lcd_backlight_level == 0 )
{
_LCD_Wakeup();
_LCD_SetBacklight(level);
break;
}
if(level == 0)
{
_LCD_SetBacklight(level);
_LCD_Sleep();
break;
}
_LCD_SetBacklight(level);
}while(FALSE);
g_lcd_backlight_level = level;
lcd_sleep_flag = level? 1: 0;
//LCD_TRACE("LCD Set lcd_sleep_flag:%d",lcd_sleep_flag); //' maggie
return ret;
}
U16 LCD_GetBackLightLevel(void)
{
return g_lcd_backlight_level;
}
/*
reconfig the lcd power supply when refresh lcd,
to make ESD stronger, fujl20070411
*/
void Lcd_Power_Reconfig(void)
{
_LCD_SPIWriteCMD(0x26); //set temperature compensation
_LCD_SPIWriteCMD(0xA1); //set line rate 0xa0-0xa3
_LCD_SPIWriteCMD(0xC8); //set LCD mapping control 0xc0-0xc3//////c4
_LCD_SPIWriteCMD(0x2E); //set power control
_LCD_SPIWriteCMD(0xEB); //set LCD bias ratio BIAS=1/9
_LCD_SPIWriteCMD(0x81); //REFERENCE VOLTAGE PARAMETER
//_LCD_SPIWriteCMD(0x8C); //SET REFERENCE VOLTAGE 0x00-0xFF
_LCD_SPIWriteCMD(_g_contrast);
_LCD_SPIWriteCMD(0x84); //set partial display control 0x84--disable 0x85--enable
_LCD_SPIWriteCMD(0xA4); //set all-piexl-on 0xa4 0xa5
_LCD_SPIWriteCMD(0xA6); //set inverse display 0xA6 0xA7
_LCD_SPIWriteCMD(0xF1); //set com end
_LCD_SPIWriteCMD(0x3f);
_LCD_SPIWriteCMD(0x40); //set scroll
_LCD_SPIWriteCMD(0xAF); //set display enable 4-gray mode
}
#define TEMP_FOR_101_LCD 1//maggie add 2007-08-07
void LCD_Update(void)
{
int idx;
int p,i;//maggie add 2007-08-07
//_LCD_Debug();
Lcd_Power_Reconfig();
#ifdef LCD_IC_UC1612
_LCD_SPIWriteCMD(0x00);
_LCD_SPIWriteCMD(0x00);
_LCD_SPIWriteCMD(0x6a);
_LCD_SPIWriteCMD(0x70);
_LCD_SPIWriteCMD(0xf1);
_LCD_SPIWriteCMD(63);
_LCD_SPIWriteCMD(0x89);
#else /*LCD_IC_UC1612*/
_LCD_SPIWriteCMD(0x40); // Set Scroll Line
_LCD_SPIWriteCMD(0x00);
_LCD_SPIWriteCMD(0x10);
_LCD_SPIWriteCMD(0xB0);
_LCD_SPIWriteCMD(0xc8);
_LCD_SPIWriteCMD(0xA6); //reconfig inverse display mode to prevent anti_pixel, fujl20070510
#endif /*LCD_IC_UC1612*/
//'maggie add 2007-08-07
#ifdef TEMP_FOR_101_LCD
for (p = 0;p<LCD_BUF_CY ;p++)//MAIN_LCD_HEIGHT
{
for(i = 0;i < 102;i ++)
{
_LCD_SPIWriteData(g_lcd_buf[p*128+i]);
}
}
#else
//'
for(idx = 0; idx < LCD_BUF_SIZE; idx++)
{
_LCD_SPIWriteData(g_lcd_buf[idx]);//maggie 2007-08-07
}
#endif//maggie add 2007-08-07
}
static lcd_ret_e _LCD_Init(void)
{
//LCD_TRACE("LCD _LCD_Init !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); //' maggie
if(g_lcd_state == LCD_ST_UNKNOW)
{
int idx;
//LCD_TRACE("g_lcd_state == LCD_ST_UNKNOW");//' maggie
_LCD_Reset();
_LCD_CfgSPIPin();
_LCD_RstSPI();
_LCD_CfgSPI();
memset(g_lcd_buf,0x00,LCD_BUF_SIZE);
//_LCD_Debug();
LCD_Update();
for( idx = 0; lcd_init_seq[idx] != LCD_END; idx++)
{
if((lcd_init_seq[idx] &0xff00)!= 0)
{
lcd_ms_delay((lcd_init_seq[idx] &0xff)>>1);
idx++;
continue;
}
_LCD_SPIWriteCMD(lcd_init_seq[idx]);
}
if(_g_contrast != LCD_DEF_CONTRAST)
_LCD_UpdateContrast();
g_lcd_state = LCD_ST_INITED;
}
return LCD_ER_OK;
}
static void _LCD_CfgSPIPin(void)
{
// SPI Enable 0
CONF_GPIO_26 |= (1<<0);
// Config SPI_CLK
CONF_GPIO_23 |= (1<<0);
// Config SPI_MOSI
CONF_GPIO_25 |= (1<<0);
// Config SPI_MISO C/D/
//CONF_GPIO_24 |= (1<<0);
CONF_GPIO_24 = 0x18; // GPIO, Pull-H.
AI_ConfigBitAsOutput(24);
}
static void _LCD_RstSPI(void)
{
SPI_REG_SCR = 0x02;
//checking if reset complete
while(!(SPI_REG_SSR & 0x1));
}
static void _LCD_CfgSPI(void)
{
spi_dev_t spi_dev;
spi_dev_t * pDev;
spi_dev.eCHID= SPI_CH_ID_0; // The ID of devices.
spi_dev.eMode= SPI_MODE_MASTER;
spi_dev.ePTV = SPI_PTV_2;//SPI_PTV_128;
spi_dev.eCP = SPI_CP_BEG;
spi_dev.eCE = SPI_CE_LO;
spi_dev.eCI = SPI_CI_HI;
spi_dev.NB =SPI_BITNUM_TO_NB(8);
pDev = &spi_dev;
SPI_REG_ISR = 0x00000001;
SPI_REG_SET1 = ((pDev->ePTV)<<1)|0x01; //Enable CLK. FIX ME
SPI_DRV_TRACE_PARA("SPI SET1",SPI_REG_SET1);
SPI_REG_SET2= (pDev->eMode<<15)|\
(((pDev->eCP<<10)|(pDev->eCE<<5)|(pDev->eCI<<0))<<pDev->eCHID);
SPI_DRV_TRACE_PARA("SPI SET2",SPI_REG_SET2);
SPI_REG_CTRL= (pDev->eCHID<<7)|(pDev->NB<<2);
SPI_DRV_TRACE_PARA("SPI CTRL",SPI_REG_CTRL);
}
static BOOL lcd_spi_TxIsEmpty(void)
{
return (SPI_REG_DSR&DSR_TX_EMPTY);
}
static void _LCD_SPIWriteData(unsigned long data)
{
#if 0
if(lcd_trans_type !=LCD_TRS_NONE)
{
//while(!lcd_spi_TxIsEmpty()){};
}
#endif
if(lcd_trans_type != LCD_TRS_DATA)
{
LCD_START_TRANS_DATA;
lcd_trans_type = LCD_TRS_DATA;
}
// check busy.
SPI_REG_TX = data;
SPI_START_WRITE;
wait_ARM_cycles(convert_nanosec_to_cycles(2*1000*LCD_TRS_WIAT));
}
static void _LCD_SPIWriteCMD(unsigned long data)
{
if(lcd_trans_type != LCD_TRS_CMD)
{
LCD_START_TRANS_CMD;
lcd_trans_type = LCD_TRS_CMD;
}
SPI_REG_TX = data;
SPI_START_WRITE;
wait_ARM_cycles(convert_nanosec_to_cycles(2*1000*LCD_TRS_WIAT));
}
static void _LCD_Reset(void)
{
AI_ModeConfig(35,1); //gpio35 set gpio mode
AI_ConfigBitAsOutput(35);
AI_ResetBit(35);
lcd_ms_delay(10);
AI_SetBit(35);
}
static void _LCD_Sleep(void)
{
//Revised by ZhangTing for AirTel Mar 06, 2007
//_LCD_SPIWriteCMD(0xAE);
}
static void _LCD_Wakeup(void)
{
//Revised by ZhangTing for AirTel Mar 06, 2007
//_LCD_SPIWriteCMD(0xAF);
}
/*update to prevent can not enter deepsleep, because the backlight not shut off, fujl20070330*/
static void _LCD_SetBacklight( U16 level)
{
if(0==level)
{
lls_switch_off(LLS_BACKLIGHT);
//LCD_TRACE("LCD lls_switch_off:%d",level);//'maggie
}
else
{
lls_switch_level(LLS_BACKLIGHT,level);
//LCD_TRACE("LCD lls_switch_level:%d",level);//'maggie
}
}
U16 LCD_GetMaxContrast(void)
{
return LCD_MAX_CONTRAST;
}
U16 LCD_SetContrast(U16 contrast)
{
U16 old_contrast = (U16)_g_contrast;
LCD_Trace("LCD_SetContrast = %d",contrast);
do
{
if(contrast > LCD_MAX_CONTRAST)
contrast = LCD_MAX_CONTRAST;
if(_g_contrast == contrast)
break;
_g_contrast = (U8)contrast;
_LCD_UpdateContrast();
}while(FALSE);
return old_contrast;
}
U16 LCD_GetContrast(void)
{
return _g_contrast;
}
static void _LCD_UpdateContrast(void)
{
_LCD_SPIWriteCMD(0x81);
_LCD_SPIWriteCMD(_g_contrast);
}
void LCD_Trace(const char * szfmt, ...)
{
#ifdef LCD_DEBUG
static char buf[255+1];
va_list args;
va_start(args, szfmt);
vsprintf(buf, szfmt, args);
va_end(args);
//rvf_send_trace(buf, strlen(buf), NULL_PARAM,RV_TRACE_LEVEL_DEBUG_MEDIUM, SPI_USE_ID);
rvf_send_trace(buf, strlen(buf), NULL_PARAM,RV_TRACE_LEVEL_ERROR, SPI_USE_ID);
while(strlen(buf)>= 255 )
{
rvf_delay(1);
}
#else /*LCD_DEBUG*/
szfmt;
#endif /*LCD_DEBUG*/
}
void lcd_write_pixel( int x, int y, unsigned char data)
{
#ifdef LCD_IC_UC1612
int bit_idx = y&0x07; //mod 8
int row_byte_idx = y>>3;
int byte_idx = x*LCD_BUF_CY+(bit_idx>>3);
unsigned char mask;
mask = 1<<(bit_idx);
if(data)
{
g_lcd_buf[byte_idx] |= mask;
}
else
{
g_lcd_buf[byte_idx] &= ~mask;
}
#else /*LCD_IC_UC1612*/
int row_byte ;
int byte_idx;
int bit_idx ;
unsigned char mask;
x>128? 128:x;
y+=2;
y &= 0x3f;
row_byte = y>>3;
byte_idx = 128*row_byte+x;
bit_idx = y&0x07;
mask = 1<<(bit_idx);
if(data)
{
g_lcd_buf[byte_idx] |= mask;
}
else
{
g_lcd_buf[byte_idx] &= ~mask;
}
#endif /*LCD_IC_UC1612*/
}
//add some function to support etm cmd to operate lcd panel>>>
void ETM_Cmd_Operate_Lcd(U8 lcd_state)
{
//U16 lcd_id;
//lcd_id = LCD_DrvGetDeviceID();
//get_lcd_init_setting(lcd_id);
LCD_TRACE("Wanted state:%d", lcd_state);
switch(lcd_state)
{
case 0: //power on
//LCD_DrvWriteRegTable(g_pLCDSeq->PowerOn);
//LCD_MainSetLackLightState(LCD_BKL_ON);
_LCD_Init();
break;
case 1: //wake up
//LCD_DrvWriteRegTable(g_pLCDSeq->Wakeup);
//LCD_MainSetLackLightState(LCD_BKL_ON);
_LCD_Wakeup();
break;
case 2: //stand by
//LCD_DrvWriteRegTable(g_pLCDSeq->Standby);
//LCD_MainSetLackLightState(LCD_BKL_OFF);
break;
case 3: //power off
//LCD_DrvWriteRegTable(g_pLCDSeq->PowerOff);
//LCD_MainSetLackLightState(LCD_BKL_OFF);
break;
case 4: //reset lcd
//lcd_controller_reset();
//LCD_MainSetLackLightState(LCD_BKL_ON);
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -