(1)背光控制
刚开始误认为drivers/video/mini6410_backlight.c是背光的驱动程序,但实际它不是。TINY6410的LCD屏的驱动不同于其它LCD的驱动写法,它使用所谓的“一线触屏”驱动,驱动文件是drivers/input/touchscreen/mini6410_1wire_host.c。
驱动初始化:
static int __init dev_init(void)
{
int ret;
ret = misc_register(&ts_misc) | misc_register(&bl_misc) ;
//set PWM as output, set output is 1.
set_pin_up();
set_pin_value(1);
set_pin_as_output();
if (ret == 0) {
setup_irq(IRQ_TIMER3, &timer_for_1wire_irq);
ret = init_timer_for_1wire();
init_timer(&one_wire_timer);
one_wire_timer_proc(0); //设置背光为127 (默认)
create_proc_read_entry("driver/one-wire-info", 0, NULL, read_proc, NULL);
}
if (ret == 0) {
printk (TOUCH_DEVICE_NAME"\tinitialized\n");
printk (BACKLIGHT_DEVICE_NAME"\tinitialized\n");
}
return ret;
}
static void __exit dev_exit(void)
{
exitting = 1;
remove_proc_entry("driver/one-wire-info", NULL);
del_timer_sync(&one_wire_timer);
free_irq(IRQ_TIMER3, &timer_for_1wire_irq);
misc_deregister(&ts_misc);
misc_deregister(&bl_misc);
}
一线触屏状态机:
enum {
IDLE,
START,
REQUEST,
WAITING,
RESPONSE,
STOPING,
} one_wire_status = IDLE;
static volatile unsigned int io_bit_count;
static volatile unsigned int io_data;
static volatile unsigned char one_wire_request;
static irqreturn_t timer_for_1wire_interrupt(int irq, void *dev_id)
{
io_bit_count--;
switch(one_wire_status) {
case START:
if (io_bit_count == 0) {
io_bit_count = 16;
one_wire_status = REQUEST;
}
break;
case REQUEST:
// Send a bit
set_pin_value(io_data & (1U << 31));
io_data <<= 1;
if (io_bit_count == 0) {
io_bit_count = 2;
one_wire_status = WAITING;
}
break;
case WAITING:
if (io_bit_count == 0) {
io_bit_count = 32;
one_wire_status = RESPONSE;
}
if (io_bit_count == 1) {
set_pin_as_input();
set_pin_value(1);
}
break;
case RESPONSE:
// Get a bit
io_data = (io_data << 1) | get_pin_value();
if (io_bit_count == 0) {
io_bit_count = 2;
one_wire_status = STOPING;
set_pin_value(1);
set_pin_as_output();
one_wire_session_complete(one_wire_request, io_data);
}
break;
case STOPING: // 2
if (io_bit_count == 0) {
one_wire_status = IDLE;
stop_timer_for_1wire();
}
break;
default:
stop_timer_for_1wire();
}
return IRQ_HANDLED;
}
(2)LCD的初始化
void LCDTest()
{
int i, j;
trace("Enter LCDTest().\r\n");
(*(volatile unsigned int *)0x7410800c)=0; //Must be '0' for Normal-path instead of By-pass
///set GPE0
//*(volatile unsigned int*)0x7F008080 = 0x00011111;
//*(volatile unsigned int*)0x7F008084 = 0x00000001;
//*(volatile unsigned int*)0x7F008088 = 0x00000000;
GPIO_SetLCDType(eRGBIF); //set LCD mode to RGB mode
//Set LCD GPIO Port
GPIO_SetFunctionAll(eGPIO_I, 0xaaaaaaaa, 2); //GPI[15..0]-> RGB VD[15..0]
GPIO_SetFunctionAll(eGPIO_J, 0xaaaaaaaa, 2); //GPJ[7..0]-> RGB VD[23..16], GPJ[11..8]-> VCLK, VDEN, VSYNC, HSYNC
GPIO_SetFunctionEach(eGPIO_E, eGPIO_0, 1); //GPF[15] -> Output
GPIO_SetDataEach(eGPIO_E, eGPIO_0 , 1); //GPF[15] -> High
trace("LCD GPIO init ok.\r\n");
//other pin gpio not set yet.
//LCD reset has not done
//LCD cmd init has not done
//begin base display test.
eBgWin = WIN0;
eFgWin = WIN1;
/* RGB 5-6-5 format for SMDK EVAL BOARD */
eBgBpp = RGB16;
eFgBpp = RGB16;
*(volatile unsigned long *)0x7E00F030 |= 1 << 3; //set lcd clk enable in hclk_gate register
LCD_InitDISPC(eBgBpp, uLcdFbAddr, eBgWin, false);
LCD_SetWinOnOff(1, eBgWin);
trace("Invoke LCD_Start().\r\n");
LCD_Start();
trace("Invoke set_bklight.\r\n");
set_bklight();
}
void LCD_InitBase(void)
{
u32 uLcdCon;
u32 uILcdIntCon;
u32 uClkVal, uClkDir;
CLK_SRC_m eVClkSrc;
u32 uVidconReg;
u32 i;
LCD_WINDOW eWin;
oLcdc.m_bIsAutoBuf = false;
oLcdc.m_uScanMode = 0; // progressive mode
oLcdc.m_bIsLocalCalled[0] = false;
oLcdc.m_bIsLocalCalled[1] = false;
oLcdc.m_bIsLocalCalled[2] = false;
/*set lcd clock source:
CLKSEL_F_HCLK (0<<2)
CLKSEL_F_SYSCON (1<<2)
CLKSEL_F_EXTCLK (3<<2)
*/
oLcdc.m_uVideoClockSource = CLKSEL_F_HCLK;
eVClkSrc = SRC_HCLK;
oLcdc.m_uLcdHSz = 800;
oLcdc.m_uLcdVSz = 480;
oLcdc.m_uVidOutFormat = VIDOUT_RGBIF;
oLcdc.m_uDitherMode = RDITHPOS_5BIT|GDITHPOS_6BIT|BDITHPOS_5BIT;
oLcdc.m_uDitherMode &= ~DITHERING_ENABLE;
LcdcOutp32(rVIDCON1, IHSYNC_INVERT | IVSYNC_INVERT); //Check
LcdcOutp32(rVIDTCON0, VBPDE(S3CFB_VBP) | VBPD(S3CFB_VBP) | VFPD(S3CFB_VFP) | VSPW(S3CFB_VSW));
LcdcOutp32(rVIDTCON1, VFPDE(S3CFB_VFP) | HBPD(S3CFB_HBP) | HFPD(S3CFB_HFP) | HSPW(S3CFB_HSW));
LcdcOutp32(rVIDTCON2, LINEVAL(oLcdc.m_uLcdVSz-1) | HOZVAL(oLcdc.m_uLcdHSz-1));
LcdcOutp32(rDITHMODE, oLcdc.m_uDitherMode); // Fixed Dithering Matrix
LCD_Stop();
//Check up LCD to turn off
while (1)
{
uLcdCon=Inp32(LCD_BASE+rVIDCON0);
if( (uLcdCon&0x03) == 0 ) // checking whether disable the video output and the Display control signal or not.
break;
}
LCD_SetClkSrc(eVClkSrc);
/**
* WARNING: CLKVAL is defined upon 133 MHz HCLK, please update it
* when HCLK freq changed.
* VCLK = 133 MHz / (CLKVAL + 1)
* = ~33.25 MHz
*/
uClkVal = 3;
uClkDir = 1;
uVidconReg =
PROGRESSIVE | oLcdc.m_uVidOutFormat | SUB_16_MODE | MAIN_16_MODE | PNRMODE_RGB_P | CLKVALUP_ALWAYS |
CLKVAL_F(uClkVal) | /*VCLKEN_DISABLE |*/ CLKDIR_F(uClkDir) | oLcdc.m_uVideoClockSource|
ENVID_DISABLE | ENVID_F_DISABLE;
LcdcOutp32(rVIDCON0, uVidconReg);
uILcdIntCon =Inp32(LCD_BASE+rVIDINTCON0);
LcdcOutp32(rVIDINTCON0, 0);
//LcdcOutp32(rVIDINTCON0, uILcdIntCon | FRAMESEL0_BACK | FRAMESEL1_NONE | INTFRMEN_DISABLE |
// FIFOSEL_WIN0 | FIFOLEVEL_25 | INTFIFOEN_DISABLE | INTEN_DISABLE);
LCD_SetAllWinOnOff(0); // Turn all windows off
LCD_SetAllWinColorMapOnOff(0); // Turn all windows color map off
LCD_SetAllWinColorKeyOnOff(0); // Turn all windows Color Key off
for (i=1; i<5; i++)
{
eWin =
(i == 1) ? WIN1 :
(i == 2) ? WIN2 :
(i == 3) ? WIN3 : WIN4;
LCD_SetAlpha(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, eWin);
}
}
void LCD_InitWinRegs(LCD_WINDOW eWin)
{
u32 uWinConXReg;
u32 uAlphaValReg;
u32 uFrmBufStAddrReg;
u32 uFrmBufEndAddrReg;
u32 uOffsetPageWidthReg;
u32 uOsdLeftPosReg;
u32 uOsdRightPosReg;
u32 uWinConXRegVal;
u32 uLcdEndX, uLcdEndY;
uWinConXReg =
(eWin == WIN0) ? rWINCON0 :
(eWin == WIN1) ? rWINCON1 :
(eWin == WIN2) ? rWINCON2 :
(eWin == WIN3) ? rWINCON3 : rWINCON4;
uAlphaValReg =
(eWin == WIN1) ? rVIDOSD1C :
(eWin == WIN2) ? rVIDOSD2C :
(eWin == WIN3) ? rVIDOSD3C :
(eWin == WIN4) ? rVIDOSD4C : rVIDOSD1C;
uFrmBufStAddrReg =
(eWin == WIN0) ? rVIDW00ADD0B0 :
(eWin == WIN1) ? rVIDW01ADD0B0:
(eWin == WIN2) ? rVIDW02ADD0 :
(eWin == WIN3) ? rVIDW03ADD0 : rVIDW04ADD0;
uFrmBufEndAddrReg =
(eWin == WIN0) ? rVIDW00ADD1B0 :
(eWin == WIN1) ? rVIDW01ADD1B0 :
(eWin == WIN2) ? rVIDW02ADD1 :
(eWin == WIN3) ? rVIDW03ADD1 : rVIDW04ADD1;
uOffsetPageWidthReg =
(eWin == WIN0) ? rVIDW00ADD2 :
(eWin == WIN1) ? rVIDW01ADD2 :
(eWin == WIN2) ? rVIDW02ADD2 :
(eWin == WIN3) ? rVIDW03ADD2 : rVIDW04ADD2;
uOsdLeftPosReg =
(eWin == WIN0) ? rVIDOSD0A :
(eWin == WIN1) ? rVIDOSD1A :
(eWin == WIN2) ? rVIDOSD2A :
(eWin == WIN3) ? rVIDOSD3A : rVIDOSD4A;
uOsdRightPosReg =
(eWin == WIN0) ? rVIDOSD0B :
(eWin == WIN1) ? rVIDOSD1B :
(eWin == WIN2) ? rVIDOSD2B :
(eWin == WIN3) ? rVIDOSD3B : rVIDOSD4B;
uWinConXRegVal = 0;
if (eWin == WIN0)
{
if (!oLcdc.m_bIsLocalCalled[0]) // Input path is DMA
{
uWinConXRegVal =
W0DMA | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode|
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | oLcdc.m_uBppMode |
ENWIN_F_DISABLE;
}
else // Input path is Local
{
//Assert(oLcdc.m_eLocalIn[0] == IN_POST);
if(oLcdc.m_uLocalInColorSpace[0] == LOCALIN_YCbCr)
{
uWinConXRegVal =
W0LOCAL_POST | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_YUV |
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | oLcdc.m_uBppMode |
ENWIN_F_DISABLE;
}
else
{
uWinConXRegVal =
W0LOCAL_POST | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_RGB |
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | oLcdc.m_uBppMode |
ENWIN_F_DISABLE;
}
}
LcdcOutp32(rVIDW00ADD0B1, oLcdc.m_uDoubleBufStAddr[0]);
LcdcOutp32(rVIDW00ADD1B1, oLcdc.m_uDoubleBufEndAddr[0]);
LcdcOutp32(rVIDOSD0C, OSDSIZE(oLcdc.m_uViewHSz[0]*oLcdc.m_uViewVSz[0]));
}
else
{
if (eWin == WIN1)
{
if (!oLcdc.m_bIsLocalCalled[1]) // Input path is DMA
{
uWinConXRegVal =
W0DMA | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode|
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
}
else // Input path is Local
{
//Assert(oLcdc.m_eLocalIn[1] == IN_POST || oLcdc.m_eLocalIn[1] == IN_CIM);
if(oLcdc.m_uLocalInColorSpace[1] == LOCALIN_YCbCr)
{
uWinConXRegVal =
((oLcdc.m_eLocalIn[1] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) |
W1LOCAL| W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_YUV |
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
}
else
{
uWinConXRegVal =
((oLcdc.m_eLocalIn[1] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) |
W1LOCAL| W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_RGB |
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
}
}
// set double buf. addr. and offset size
LcdcOutp32(rVIDW01ADD0B1, oLcdc.m_uDoubleBufStAddr[1]);
LcdcOutp32(rVIDW01ADD1B1, oLcdc.m_uDoubleBufEndAddr[1]);
LcdcOutp32(rVIDOSD1D, OSDSIZE(oLcdc.m_uViewHSz[1]*oLcdc.m_uViewVSz[1]));
}
else // eWin == WIN2 OR WIN3 OR WIN4
{
if (eWin == WIN2)
{
if (!oLcdc.m_bIsLocalCalled[2]) // Input path is DMA
{
uWinConXRegVal =
W0DMA | BITSWP_DISABLE |
oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode|
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
}
else // Input path is Local
{
//Assert(oLcdc.m_eLocalIn[2] == IN_POST || oLcdc.m_eLocalIn[2] == IN_CIM);
if(oLcdc.m_uLocalInColorSpace[2] == LOCALIN_YCbCr)
{
uWinConXRegVal =
((oLcdc.m_eLocalIn[2] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) |
W1LOCAL | BITSWP_DISABLE |oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_YUV |
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
}
else
{
uWinConXRegVal =
((oLcdc.m_eLocalIn[2] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) |
W1LOCAL | BITSWP_DISABLE |oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_RGB |
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
}
}
LcdcOutp32(rVIDOSD2D, OSDSIZE(oLcdc.m_uViewHSz[2]*oLcdc.m_uViewVSz[2]));
}
else // eWin == WIN3 || eWin == WIN4
{
uWinConXRegVal =
BITSWP_DISABLE | oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode |
oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen |
BLD_PIX_PLANE | oLcdc.m_uBppMode | BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
}
}
LcdcOutp32(uAlphaValReg,
ALPHA0_R(0xF) | ALPHA0_G(0xF) | ALPHA0_B(0xF) |
ALPHA1_R(0xF) | ALPHA1_G(0xF)| ALPHA1_B(0xF));
}
LcdcOutp32(uWinConXReg, uWinConXRegVal);
LcdcOutp32(uFrmBufStAddrReg, oLcdc.m_uFbStAddr[eWin]);
LcdcOutp32(uFrmBufEndAddrReg, oLcdc.m_uFbEndAddr[eWin]);
LcdcOutp32(uOffsetPageWidthReg, (oLcdc.m_uOffsetSz[eWin]<<13) | oLcdc.m_uPageWidth[eWin]);
uLcdEndX = oLcdc.m_uLcdStX + oLcdc.m_uViewHSz[eWin] - 1;
uLcdEndY = oLcdc.m_uLcdStY + oLcdc.m_uViewVSz[eWin] - 1;
if (oLcdc.m_uScanMode == 1) // Interlace mode
{
//Assert(!(oLcdc.m_uLcdStX%2)); // Left top -> Y coordinate must be even number in interlace mode
//Assert(uLcdEndY%2); // Rigth bottom -> Y coordinate must be odd number in interlace mode
// In interlace mode, Left Top Y(oLcdc.m_uLcdStY) and Right Bottom Y(uLcdEndY) must be divided by 2.
// And, Right Bottom Y must be rounded down
LcdcOutp32(uOsdLeftPosReg, OSD_LTX_F(oLcdc.m_uLcdStX) | (OSD_LTY_F(oLcdc.m_uLcdStY)>>1));
LcdcOutp32(uOsdRightPosReg, OSD_RBX_F(uLcdEndX) | (OSD_RBY_F(uLcdEndY)>>1));
}
else // Progressive mode
{
LcdcOutp32(uOsdLeftPosReg, OSD_LTX_F(oLcdc.m_uLcdStX) | OSD_LTY_F(oLcdc.m_uLcdStY));
LcdcOutp32(uOsdRightPosReg, OSD_RBX_F(uLcdEndX) | OSD_RBY_F(uLcdEndY));
}
}
void LCD_SetWinOnOff(u32 uOnOff, LCD_WINDOW eWin)
{
u32 uWinTemp;
u32 uWinConReg;
uWinConReg =
(eWin == WIN0) ? rWINCON0 :
(eWin == WIN1) ? rWINCON1 :
(eWin == WIN2) ? rWINCON2 :
(eWin == WIN3) ? rWINCON3 : rWINCON4;
uWinTemp=Inp32(LCD_BASE+uWinConReg);
if (uOnOff) // Turn OSD on
uWinTemp |= ENWIN_F_ENABLE;
else // Turn OSD off
uWinTemp &= ~ENWIN_F_ENABLE;
LcdcOutp32(uWinConReg, uWinTemp);
}
void LCD_InitWin(CSPACE eBpp,
u32 uFrameH, //800
u32 uFrameV, //480
u32 uX_Frame, //0
u32 uY_Frame, //0
u32 uViewH, //800
u32 uViewV, //480
u32 uX_Lcd, //0
u32 uY_Lcd, //0
u32 uFbAddr, //
LCD_WINDOW eWin,
u8 bIsDoubleBuf)
{
u32 uOffset;
//u32 uLineVal;
u32 uBurstSize;
//if ( (eWin != WIN0 && eWin != WIN1) && bIsDoubleBuf == true )
// Assert(0); // In WIN2, WIN3 or WIN4, Double buffering can't be supported
// Viewport size must be less than LCD size
//Assert(uViewH <= oLcdc.m_uLcdHSz);
//Assert(uViewV <= oLcdc.m_uLcdVSz);
// Check (X,Y) coordinate is valid in LCD and Frame?
//Assert( ((uX_Frame + uViewH) <= uFrameH) && ((uY_Frame + uViewV) <= uFrameV) );
//Assert( (uX_Lcd + uViewH <= oLcdc.m_uLcdHSz) && (uY_Lcd + uViewV <= oLcdc.m_uLcdVSz) );
// Double buffering is supported by only window 0 and window 1
//if ( ((eWin != WIN0) && (eWin != WIN1)) && (bIsDoubleBuf == true) )
// Assert(0);
oLcdc.m_uFrmHSz[eWin] = uFrameH; //800
oLcdc.m_uFrmVSz[eWin] = uFrameV; //480
oLcdc.m_uViewHSz[eWin] = uViewH; //800
oLcdc.m_uViewVSz[eWin] = uViewV; //480
oLcdc.m_uLcdStX = uX_Lcd; //0
oLcdc.m_uLcdStY = uY_Lcd; //0
uOffset = oLcdc.m_uFrmHSz[eWin] - oLcdc.m_uViewHSz[eWin]; //=0
oLcdc.m_uBytSwpMode = BYTSWP_DISABLE; // BYTE swap disable
oLcdc.m_uHawSwpMode = HAWSWP_DISABLE; // Half-Word swap disable
oLcdc.m_uMaxBurstLen = MAX_BURSTLEN_16WORD; // DMA'burst max 16word burst
oLcdc.m_uMinBurstLen = MIN_BURSTLEN_16WORD; // DMA'burst min 16 word burst
//m_uBytes濂藉儚鏄鍗犲灏戜釜瀛楄妭锛屽鏋滃皬浜庝竴涓瓧鑺傦紝閭d箞m_uBytes=1锛屽苟涓攎_uBits琛ㄧず鍗犲灏戜綅銆?
//else if (eBpp == RGB16)
//{
oLcdc.m_uBytes = 2;
oLcdc.m_uBits = 1;
//Assert( !(uOffset%2) ); // Must keep to word-alignment
oLcdc.m_uBppMode = BPPMODE_F_16BPP_565; //5<<2
oLcdc.m_uHawSwpMode = HAWSWP_ENABLE; // 1<<16
//}
// Get offsetsize, pagewidth and lineVal
if (oLcdc.m_uFrmHSz[eWin] >= oLcdc.m_uViewHSz[eWin])
{
oLcdc.m_uOffsetSz[eWin] = uOffset*oLcdc.m_uBytes/oLcdc.m_uBits; //0
oLcdc.m_uPageWidth[eWin] = oLcdc.m_uViewHSz[eWin]*oLcdc.m_uBytes/oLcdc.m_uBits; //=1600
// Offset size must be more than the burst size
uBurstSize =
(oLcdc.m_uMaxBurstLen == MAX_BURSTLEN_16WORD) ? 16*4 : //16
(oLcdc.m_uMaxBurstLen == MAX_BURSTLEN_8WORD) ? 8*4 : 4*4;
// Offset size must be more than the burst size
//Assert( oLcdc.m_uOffsetSz[eWin] == 0 || !(oLcdc.m_uOffsetSz[eWin]%4) );
//Assert(oLcdc.m_uPageWidth[eWin] > uBurstSize); // Page width must be more than burst size and be word-aligned
//uLineVal = oLcdc.m_uViewVSz[eWin] - 1;
}
else
{
//Assert(0);
}
oLcdc.m_uImgStAddr[eWin] = uFbAddr;
oLcdc.m_uFbStAddr[eWin] = uFbAddr + (oLcdc.m_uFrmHSz[eWin]*uY_Frame + uX_Frame)*oLcdc.m_uBytes/oLcdc.m_uBits; //= uFbAddr
oLcdc.m_uFbEndAddr[eWin] = oLcdc.m_uFbStAddr[eWin] + (oLcdc.m_uOffsetSz[eWin]+oLcdc.m_uPageWidth[eWin])*(uFrameV); //uFbAddr + 1600*480
if ( (bIsDoubleBuf == true) && ((eWin == WIN0) || (eWin == WIN1)) )
{
oLcdc.m_uDoubleBufImgStAddr[eWin] = oLcdc.m_uImgStAddr[eWin] + oLcdc.m_uFrmHSz[eWin]*oLcdc.m_uFrmVSz[eWin]*oLcdc.m_uBytes/oLcdc.m_uBits;
oLcdc.m_uDoubleBufStAddr[eWin] = oLcdc.m_uFbStAddr[eWin] + oLcdc.m_uFrmHSz[eWin]*oLcdc.m_uFrmVSz[eWin]*oLcdc.m_uBytes/oLcdc.m_uBits;
oLcdc.m_uDoubleBufEndAddr[eWin] = oLcdc.m_uDoubleBufStAddr[eWin] + (oLcdc.m_uOffsetSz[eWin]+oLcdc.m_uPageWidth[eWin])*(uFrameV);
}
else if ( (bIsDoubleBuf == false) && ((eWin == WIN0) || (eWin == WIN1)) )
{
oLcdc.m_uDoubleBufStAddr[eWin] = oLcdc.m_uFbStAddr[eWin];
oLcdc.m_uDoubleBufEndAddr[eWin] = oLcdc.m_uFbEndAddr[eWin];
}
LCD_InitWinRegs(eWin);
// For back-ward compatibility LCDC V2.0
if(eWin == WIN0)
LCD_SetWinOnOff(1, WIN0); // first arguement == 1 -> turn on window
}
(3)显示图像
我儿子的照片,晚上用手机拍的图片,不是很清晰: