📄 displaylib.c
字号:
/*********************************************************************
;* Project Name : S3C2450X
;*
;* Copyright 2008 by Samsung Electronics, Inc.
;* All rights reserved.
;*
;* Project Description :
;* This software is only for verifying functions of the S3C2450X
;* Anybody can use this code without our permission.
;**********************************************************************/
#include "System.h"
#include "Display.h"
#include "DisplaySample.h" // 8bpp pallet
#include "DisplaySample_240_320.h" // snail16bpp
#include "DisplaySample_320_240.h" // prayer16bpp
#include "sjy_320_240.h"
#include "WVGA_SmileAgain.h"
#include "FONT.h"
uint32 debug_print=0;
uint8 debug_continue=TRUE;
void (*PutPixel)(uint32 x,uint32 y,uint32 c);
void SetLcdPort(void)
{
// set gpio for lcd
rGPCCON = 0xaaaa02aa; // CTRL, VD[7:0]
rGPDCON = 0xaaaaaaaa; // VD[23:8]
rGPCUDP = 0;
rGPDUDP = 0;
/* // for test
rGPCCON &= ~(3);
rGPCCON |= 1;
rGPCDAT = 1;
*/
// set gpio for lcd initialize, spi emulate(LTS222...)
rGPLDAT |= (0x1f<<10);
rGPLCON = (rGPLCON & ~((3<<28)|(3<<22)|(3<<20))) | ((1<<28)|(1<<22)|(3<<20));// GPIO SPI emul.
//rGPLCON = (rGPLCON & ~((3<<28)|(3<<22)|(3<<20))) | ((2<<28)|(2<<22)|(2<<20));// SPI function
//pull-up pull-down disable
rGPLUDP = 0;
// set gpio for lcd backlight(GPB0) & nRESET(GPB1)
rGPBCON = (rGPBCON & ~((3<<2)|(3<<0))) | ((1<<2)|(1<<0));
rGPBDAT &= ~(1<<1); // nRESET: Low
// set gpio for lcd backlight dimming control(GPB3)
rGPBCON = (rGPBCON & ~(3<<6)) | (2<<6);
// PWM timer3 on for Backlight dimming
rTCFG0 = (rTCFG0 & ~(0xf<<8)) | 0x1<<8; //Dead zone=0, Prescaler1=1
rTCFG1 = 0x1<<12; //All Interrupt, MUX3: 1/4
rTCNTB3 = 200;
rTCMPB3 = 200-50; // default 75%
rTCON = (rTCON & ~(0xf<<16)) | (1<<17); // Manual update
rTCON = (rTCON & ~(1<<17)) | ((1<<19)|(1<<16)); // Start & auto
LcdBacklightCon(1);
}
void LcdBacklightCon(int onoff)// Backlight control(0:off, 1:on)
{
if(onoff)
rGPBDAT |= (1<<0);
else
rGPBDAT &= ~(1<<0);
}
void LcdBacklightDimCon(int level)
{
// Add....to do
}
uint32 tmp=0;
void delayLoop(uint32 count)
{
uint32 j, tmp;
for(j = 0; j < count; j++)
tmp=rGSTATUS1; // to avoid compiler optimization
j=tmp;
}
//===================================================
// functions related to LCDC general settings
//
void LCDC_Common_Init(void)
{
uint8 clkval=0;
uint16 h_cnt,v_cnt;
uint32 vclk;
if(lcd_if==SERIAL_IF)
rVIDCON0 = VIDCON0_S_RGB_IF|VIDCON0_S_RGB_SER|VIDCON0_S_VCLK_GATING_OFF|\
VIDCON0_S_CLKDIR_DIVIDED|VIDCON0_S_CLKSEL_HCLK;
else if(lcd_if==I80_IF) // Selctable main or sub
{
printf("Select Main or Sub LCD..\n0: Main 1: Sub\n");
if(!GetIntNum())
rVIDCON0 = VIDCON0_S_CPU_IF_MAIN|VIDCON0_S_RGB_PAR|VIDCON0_S_VCLK_GATING_OFF|\
VIDCON0_S_CLKDIR_DIVIDED|VIDCON0_S_CLKSEL_HCLK;
else
rVIDCON0 = VIDCON0_S_CPU_IF_SUB|VIDCON0_S_RGB_PAR|VIDCON0_S_VCLK_GATING_OFF|\
VIDCON0_S_CLKDIR_DIVIDED|VIDCON0_S_CLKSEL_HCLK;
}
else // parallel
rVIDCON0 = VIDCON0_S_RGB_IF|VIDCON0_S_RGB_PAR|VIDCON0_S_VCLK_GATING_OFF|\
VIDCON0_S_CLKDIR_DIVIDED|VIDCON0_S_CLKSEL_HCLK;
v_cnt = (lcd_vbpd+lcd_vfpd+lcd_vspw+lcd_line_value);
h_cnt = (lcd_hbpd+lcd_hfpd+lcd_hspw+lcd_horizon_value);
if(rVIDCON0 & (1<<2)) //EPLL
{
rCLKDIV1 &= ~(0xf<<8);
rCLKDIV1 |= (0x2<<8); // 400/3(133MHz)
SetEPLL( 400, 3, 2); // EPLL 400MHz
rEPLLCON&=~(1<<24); // EPLL ON
rCLKSRC|=(1<<6); // EPLL Output
clkval = (uint8)(((float)HCLK/(float)(h_cnt*v_cnt*lcd_frame_rate))+0.5)-1;
}
else //HCLK
clkval = (uint8)( ((float)HCLK/(float)(v_cnt*h_cnt*lcd_frame_rate) )+0.5)-1;
vclk = (HCLK/(clkval+1))/1000;
printf("VCLK: %dKHz\n",vclk);
if(clkval > 0x3f)
printf("!!! Check frame rate: over flow !!!\n");
rVIDCON0 |= (clkval <<VIDCON0_CLKVAL_F_SHIFT);
if(lcd_if==I80_IF)
{
rSYSIFCON0 = (lcd_cs_setup<<16)|(lcd_wr_setup<<12)|(lcd_wr_act<<8)|\
(lcd_wr_hold<<4)|(1<<2)|(1<<1)|(1);
rSYSIFCON1 = (lcd_cs_setup<<16)|(lcd_wr_setup<<12)|(lcd_wr_act<<8)|\
(lcd_wr_hold<<4)|(1<<2)|(1<<1)|(1);
// CS_SETUP=0xf, WR_SETUP=0xf, WR_ACT=0xf, WR_HOLD=0xf, RSPOL=HIGH, SUCCEUP=One time, SYSIFEN=Enable
}
else
{
//check point
rVIDCON1 = VIDCON1_S_HSYNC_INVERTED|VIDCON1_S_VSYNC_INVERTED;
rVIDTCON0=((lcd_vbpd-1)<<VIDTCON0_BPD_S)|((lcd_vfpd-1)<<VIDTCON0_FPD_S)|(lcd_vspw-1);
rVIDTCON1=((lcd_hbpd-1)<<VIDTCON0_BPD_S)|((lcd_hfpd-1)<<VIDTCON0_FPD_S)|(lcd_hspw-1);
rVIDTCON2 = ((lcd_line_value-1)<<VIDTCON2_LINEVAL_S)|(lcd_horizon_value-1);
}
rVIDTCON2 = ((lcd_line_value-1)<<VIDTCON2_LINEVAL_S)|(lcd_horizon_value-1);
}
// 2006.06.02
// Frame buffer address setting : Windows0 have the two buffer like as buffer0, buffer1.
// Each buffer have the register for setting the start and end address. But Window1 have one buffer
// base lcd_framebuffer = Noncache address(0x31000000)
void Basic_Display_Setting( int32 win_num,int32 buf_num, int32 bpp, uint32 width, uint32 height)
{
uint32 screenwidth_in_byte=0,offsize_in_byte=0;
int32 pagewidth,offsize,pageheight;
// uint32 one_line_word;
lcd_bpp = bpp;
switch(bpp)
{
case WINCONx_1BPP_PALLET:
PutPixel=_PutPixel1Bit;
break;
case WINCONx_2BPP_PALLET:
PutPixel=_PutPixel2Bit;
break;
case WINCONx_4BPP_PALLET:
PutPixel=_PutPixel4Bit;
break;
case WINCONx_8BPP_PALLET:
case WINCONx_8BPP_NO_PALLET:
PutPixel=_PutPixel8Bit;
break;
case WINCONx_16BPP_565:
case WINCONx_16BPP_A555:
case WINCONx_16BPP_1555:
PutPixel=_PutPixel16Bit;
break;
case WINCONx_18BPP_666:
case WINCONx_18BPP_A665:
case WINCONx_19BPP_A666:
case WINCONx_24BPP_888:
case WINCONx_24BPP_A887:
case WINCONx_25BPP_A888:
PutPixel=_PutPixel32Bit;
break;
}
screen_width=width; // Frame Buffer hoz. size
screen_height=height; // Frame Buffer ver. size
pagewidth=lcd_horizon_value;// Real LCD hoz. size
pageheight=lcd_line_value; // Real LCD ver. size
offsize = screen_width - pagewidth;
if(offsize<0)// LCD size > frame buffer
{
offsize=0;
pagewidth=screen_width;
pageheight=screen_height;
}
screenwidth_in_byte = screen_width*lcd_bit_order[bpp]/8;
if((screenwidth_in_byte%lcd_burst_in_byte[lcd_burst_mode])!=0)
{
screenwidth_in_byte += lcd_burst_in_byte[lcd_burst_mode] - (screenwidth_in_byte%lcd_burst_in_byte[lcd_burst_mode]);
}
offsize_in_byte = offsize*lcd_bit_order[bpp]/8;
/*
one_line_word = pagewidth/lcd_bit_convert[bpp];
if((one_line_word%lcd_burst_size[lcd_burst_mode])!=0)
{
printf("[ Be careful!!! ] Burst length does not align to the LCD width and bpp\n");
}
*/
// WINCON0/1
*WINCONx_Reg_Addr[win_num] = \
(buf_num<<WINCON_BUFSEL)|(0<<WINCON_BUFAUTOEN)|(0<<WINCON_SWAP_S)|(lcd_burst_mode<<WINCON_BURSTLEN_S)|(bpp<<WINCON_BPP_S);
// WIN0/1 OSD(top)
*VIDOSDxA_Reg_Addr[win_num] = (0<<VIDOSDxAB_HORIZON_X_S)|(0);
// WIN0/1 OSD(bottom)
*VIDOSDxB_Reg_Addr[win_num] = ((pagewidth-1)<<VIDOSDxAB_HORIZON_X_S)|(pageheight-1);
lcd_framebuffer = (uint32 *)lcd_frame_buffer[win_num][buf_num];
// printf("pagewidth=%d\n",pagewidth);
// printf("bpp=%d, pagewidth_in_byte=%d, offsize_in_byte=%d, pageheight=%d\n",bpp,screenwidth_in_byte,offsize_in_byte,pageheight);
// WIN0/1 buffer start address
*VIDWxADD0_Reg_Addr[win_num][buf_num] = (uint32)lcd_framebuffer;
// WIN0/1 buffer end address
*VIDWxADD1_Reg_Addr[win_num][buf_num] = (uint32)lcd_framebuffer + (screenwidth_in_byte+offsize_in_byte)*(pageheight);
// WIN0/1 buffer size
*VIDWxADD2_Reg_Addr[win_num][buf_num] = (offsize_in_byte<<VIDWxADD2_OFFSET_SIZE_S)|screenwidth_in_byte;
*WINxMAP_Reg_Addr[win_num] = 0;
if (win_num>0)
{
*VIDOSDxC_Reg_Addr[win_num] = 0;
*WxKEYCON0_Reg_Addr[win_num] = 0;
*WxKEYCON1_Reg_Addr[win_num] = 0;
}
}
void Display_Start(int8 win_num) // 0: LCD_WIN_0, 1: LCD_WIN_1, 2: LCD_WIN_ALL
{
LcdWindowOnOff(win_num,LCD_ON);
LcdEnvidOnOff(LCD_ON);
Delay(1);
if(lcd_if == I80_IF)
rCPUTRIGCON2 = 1;
if(lcd_module==LCD_MODULE_LTE480WV)
{
delayLoop(3000);
rGPBDAT |= 1<<1;
}
LcdBacklightCon(LCD_ON);
return;
}
void Display_End(int8 win_num)
{
printf("\nIf you want to end this test, press any key\n");
while(!(Uart_getc()));
LcdBacklightCon(LCD_OFF);
LcdWindowOnOff(win_num,LCD_OFF);
LcdEnvidOnOff(LCD_OFF);
return;
}
int8* Select_Win_Buf(void)
{
int8 winbuf[2];
printf("\nSelect the window # which you want to test\n");
printf(" 0: Window 0 1: Window 1\n");
winbuf[0] = (int8)GetIntNum();
if( (winbuf[0]<0) || (winbuf[0]>1) )
return &winbuf[0];
if (winbuf[0]==0)
{
printf("\nSelect the buffer # which you want to test\n");
printf(" 0: Buffer 0 1: Buffer 1\n");
winbuf[1] = (int8)GetIntNum();
if( (winbuf[1]<0) || (winbuf[1]>1) )
return &winbuf[0];
}
else
winbuf[1]=0;
return &winbuf[0];
}
void Make_Image(int8 window, int8 buffer, int8 image) // 0: 24bpp Color bar 1: Picturs for each size and type
{
uint32 i,j,k=0;
if(image)
{
if(lcd_type==LANDSCAPE && lcd_size==WVGA)//Smile Again(LTE480)
{
Basic_Display_Setting(window,buffer,WINCONx_24BPP_888,lcd_horizon_value,lcd_line_value);
for(j=0;j<screen_height;j++)
for(i=0;i<screen_width;i++)
PutPixel(i,j,pSmileAgain[k++]);
}
else if(lcd_type==LANDSCAPE && lcd_size==QVGA)// Praying girl(LTV350)
{
Basic_Display_Setting(window,buffer,WINCONx_16BPP_565,lcd_horizon_value,lcd_line_value);
for(j=0;j<screen_height;j++)
for(i=0;i<screen_width;i++)
PutPixel(i,j,pSjy_320_240[k++]);
}
else if(lcd_type==PORTRAIT && lcd_size==QVGA)// Snail(LTS222-parallel,serial,i80)
{
Basic_Display_Setting(window,buffer,WINCONx_16BPP_565,lcd_horizon_value,lcd_line_value);
for(j=0;j<screen_height;j++)
for(i=0;i<screen_width;i++)
PutPixel(i,j,snail16bpp[k++]);
}
}
else //RGB bar(24bpp)
{
Basic_Display_Setting(window,buffer,WINCONx_24BPP_888,lcd_horizon_value,lcd_line_value);
LCD_FilledRectangle(0, 0, screen_width-1, screen_height/4*1-1, 0xff0000);
LCD_FilledRectangle(0, screen_height/4*1, screen_width-1, screen_height/4*2-1, 0x00ff00);
LCD_FilledRectangle(0, screen_height/4*2, screen_width-1, screen_height/4*3-1, 0x0000ff);
LCD_FilledRectangle(0, screen_height/4*3, screen_width-1, screen_height-1, 0xffffff);
lprintf(screen_width/2,screen_height/2,0xffffff,"Hello~");
}
}
void Prepare_Image(int8 win_num, int8 bpp)
{
uint32 i, j;
uint32 *framebuffer,data;
framebuffer = lcd_framebuffer;
if(bpp<=WINCONx_8BPP_PALLET)
Prepare_Pallet(win_num,bpp);
switch(bpp)
{
case WINCONx_1BPP_PALLET:
for(i=0;i<2;i++)
{
LCD_FilledRectangle(0, screen_height/2*i, screen_width-1, screen_height/2*(i+1)-1, i);
lprintf(50,screen_height/2*i,i^0x1,"Color %d",i);
}
break;
case WINCONx_2BPP_PALLET:
for(i=0;i<4;i++)
{
LCD_FilledRectangle(0, screen_height/4*i, screen_width-1, screen_height/4*(i+1)-1, i);
lprintf(50,screen_height/4*i,i^0x3,"Color %d",i);
}
break;
case WINCONx_4BPP_PALLET:
for(i=0;i<16;i++)
{
LCD_FilledRectangle(0, screen_height/16*i, screen_width-1, screen_height/16*(i+1)-1, i);
lprintf(50,screen_height/16*i,i^0xf,"Color %d",i);
}
break;
case WINCONx_8BPP_PALLET:
if(lcd_type == LCD_MODULE_LTS222) // Portrait
{
for(i=0; i<(screen_width*screen_height*lcd_bit_order[bpp]/32); i++)
{
data =(DEMO256[i*4]<<24);
data |= (DEMO256[i*4+1] <<16);
data |= (DEMO256[i*4+2] <<8);
data |= DEMO256[i*4+3];
*framebuffer++ = data;
}
lprintf(0,0,0xff,"8BPP paletteized mode.");
}
else if(lcd_type == LCD_MODULE_LTV350 || lcd_type == LCD_MODULE_LTE480WV) // Landscape
#if 1 // Pattern view
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0xff);
lprintf(0,0,0xff,"8BPP paletteized mode.");
break;
#endif
#if 0 // Square view
for(j=0; j<16; j++)
{
for(i=0; i<16; i++)
{
LCD_FilledRectangle( i*(screen_width/16), j*(screen_height/16), (1+i)*(screen_width/16)-1, (1+j)*(screen_height/16)-1,k );
k++;
}
}
lprintf(0,0,0xff,"8BPP paletteized mode.");
}
else
printf("This test for the LCD type is not prepared\n");
break;
#endif
case WINCONx_8BPP_NO_PALLET:
if (win_num==0)
{
printf("This mode is not supported in window 0.\n");
return;
}
else
{
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0xff);
lprintf(0,0,0xff,"8BPP(A232) Non-paletteized mode.");
}
break;
case WINCONx_16BPP_565:
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0xffff);
lprintf(0,0,0xffff,"16BPP(565) Non-paletteized mode.");
break;
case WINCONx_16BPP_A555:
if (win_num==0)
{
printf("This mode is not supported in window 0!!!\n");
return;
}
else
{
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0xffff);
lprintf(0,0,0xffff,"16BPP(A555) Non-paletteized mode.");
}
break;
case WINCONx_16BPP_1555:
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0xffff);
lprintf(0,0,0xffff,"16BPP(1555) Non-paletteized mode.");
break;
case WINCONx_18BPP_666:
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0x3ffff);
lprintf(0,0,0x3ffff,"18BPP(666) Non-paletteized mode.");
break;
case WINCONx_18BPP_A665:
if (win_num==0)
{
printf("This mode is not supported in window 0!!!\n");
return;
}
else
{
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0x3ffff);
lprintf(0,0,0x3ffff,"18BPP(A665) Non-paletteized mode.");
}
break;
case WINCONx_19BPP_A666:
if (win_num==0)
{
printf("This mode is not supported in window 0!!!\n");
return;
}
else
{
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
PutPixel(i,j,(i*j)&0x7ffff);
lprintf(0,0,0x7ffff,"19BPP(A666) Non-paletteized mode.");
}
break;
case WINCONx_24BPP_888:
for(i=0;i<screen_width;i++)
for(j=0;j<screen_height;j++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -