最近使用 S3C2450 的 CPU 做机器,但是没有 2451 的 BSP 包,只有用 S3C2416 的BSP 移植了。
2416 接的是 RGB 的屏, 2451 用 CPU 屏, 所以改起来是个麻烦事呢。
从 EBOOT 开始吧。
1、把原来的 InitDisplay 删除。
2、把 IO 设置成 LCD 功能
s2450IOP->MISCCR |= (1<<28); // select LCD controller for TFT lcd controller
s2450IOP->GPCUDP = 0xFFFFFFFF;
s2450IOP->GPCCON = 0xAAAAAAAA;
s2450IOP->GPDUDP = 0xFFFFFFFF;
s2450IOP->GPDCON = 0xAAAAAAAA;
3、初始化 LCD 控制寄存器。
s2450LCD->VIDCON0 = s2450LCD->VIDCON0 & ~(0x3<<22) | (0x2<<22);
s2450LCD->SYSIFCON0 |= (1<<2);
s2450LCD->SIFCCON0 &= ~(1<<1); // RS low
s2450LCD->SIFCCON0 |= (1<<0); // command mode enable
s2450LCD->SIFCCON0 |= (1<<8); // nCS0(Main) enable// LCD module reset
s2450IOP->GPDCON = (s2450IOP->GPDCON & ~(3<<28)) | (1<<28); //GPD14 AS OUTPUT
s2450IOP->GPDDAT &=~(0x1<<14);
delayLoop(1000);s2450IOP->GPDCON = (s2450IOP->GPDCON & ~(3<<30)) | (1<<30); //
s2450IOP->GPDDAT |=(0x1<<15);
//delayLoop(36000);
i=1000;
while (i--)
{
delayLoop(1000);
}
s2450IOP->GPDDAT &=~(0x1<<15);
//delayLoop(36000);
i=1000;
while (i--)
{
delayLoop(1000);
}
s2450IOP->GPDDAT |=(0x1<<15);
// delay about 10ms
//delayLoop(36000);
i=1000;
while (i--)
{
delayLoop(1000);
}
4、初始化 LCD模块的寄存器
LCD_WriteReg(0x46,0x95);
。。。。。 更具自己的 LCD 设置
void wr_cmd(UINT16 cmd)
{
volatile S3C2416_LCD_REG *s2450LCD = (S3C2416_LCD_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_LCD, FALSE);
s2450LCD->SIFCCON0 &= ~(1<<1); // RS low
s2450LCD->SIFCCON0 |= (1<<6); // nWE enable
s2450LCD->SIFCCON1 = cmd;
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
}void wr_data(UINT16 dat)
{
volatile S3C2416_LCD_REG *s2450LCD = (S3C2416_LCD_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_LCD, FALSE);
s2450LCD->SIFCCON0 |= (1<<1); // RS high
s2450LCD->SIFCCON0 |= (1<<6); // nWE enable
s2450LCD->SIFCCON1 = dat;
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
}void LCD_WriteReg(UINT16 Reg,UINT16 Dat)
{
wr_cmd(Reg);
wr_data(Dat);
}
5、设置 LCD 模块工作在窗口模式
wr_cmd(0x0020);
wr_data(0);
wr_cmd(0x0021);
wr_data(0);
wr_cmd(0x0022);
delayLoop(100);
#if 0
delayLoop(50);
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
s2450LCD->SIFCCON0 |= (1<<8); // nCS0(Main) disable
s2450LCD->SIFCCON0 |= (1<<1); // RS high
s2450LCD->SIFCCON0 &= ~(1<<0); // command mode disable
#endif
//TFTFill(0xf800);
s2450LCD->SIFCCON0 |= (1<<1); // RS high
for(y=0;y<320*240;y++)
{
//*pFB++ =kay16bpp[y];
s2450LCD->SIFCCON0 |= (1<<6); // nWE enable
s2450LCD->SIFCCON1 = 0xf800;
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
}
delayLoop(50);
6、到这里 LCD 应该点亮了。
下面是我自己工程里面涉及到的几个函数
void Init_LDI(void)
{
volatile S3C2416_IOPORT_REG *s2450IOP = (S3C2416_IOPORT_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_IOPORT, FALSE);
volatile S3C2416_CLKPWR_REG *s2450CLK = (S3C2416_CLKPWR_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_CLOCK_POWER, FALSE);
unsigned int nPLLVALUE ;
unsigned int nCLKDIV;
unsigned int nM_DIV;
unsigned int nP_DIV;
unsigned int nS_DIV;
unsigned int nARMDIVN;
unsigned int nARMDIV;
unsigned int nPREDIV;
unsigned int nHCLKDIV;
unsigned int nPCLKDIV;
unsigned int nHALFHCLK;
unsigned int nS3C2450_FOUT;
unsigned int nS3C2450_FCLK;
unsigned int nS3C2450_HCLK ;
unsigned int nS3C2450_PCLK;
nPLLVALUE = s2450CLK->MPLLCON ;
nCLKDIV = s2450CLK->CLKDIV0 ;
nM_DIV = ((nPLLVALUE >> 14) & 0x3ff);
nP_DIV =((nPLLVALUE >> 5) & 0x3F);
nS_DIV =((nPLLVALUE >> 0) & 0x7);
nARMDIVN=((nCLKDIV >> 9) & 0xf);
nARMDIV = (nARMDIVN == 0 ? 1 : (nARMDIVN == 1 ? 2 : (nARMDIVN == 2 ? 3 : (nARMDIVN == 3 ? 4 :(nARMDIVN == 5 ? 6 :(nARMDIVN == 7 ? 8 : (nARMDIVN == 11 ? 12 : (nARMDIVN == 15 ? 16 : 1) ) ) ) ))));
nPREDIV = ((nCLKDIV >> 4) & 0x3);
nHCLKDIV = ((nCLKDIV>>0) & 0x3);
nPCLKDIV = ((nCLKDIV>>2) & 0x1);
nHALFHCLK = ((nCLKDIV>>3) & 0x1);
nS3C2450_FOUT = ((nM_DIV) * (12000000L / (nP_DIV) / (1<<nS_DIV )));
nS3C2450_FCLK = (nS3C2450_FOUT / nARMDIV );
nS3C2450_HCLK = (nS3C2450_FOUT / (nPREDIV+1) / (nHCLKDIV+1)); // divisor 4
nS3C2450_PCLK = (nS3C2450_HCLK / (nPCLKDIV+1)); // divisor 2
RETAILMSG(1, (TEXT("FOUT:%d, FCLK:%d, HCLK:%d, PCLK:%d\r\n"),nS3C2450_FOUT,nS3C2450_FCLK,nS3C2450_HCLK,nS3C2450_PCLK));
s2450IOP->MISCCR |= (1<<28); // select LCD controller for TFT lcd controller
s2450IOP->GPCUDP = 0xFFFFFFFF;
s2450IOP->GPCCON = 0xAAAAAAAA;
s2450IOP->GPDUDP = 0xFFFFFFFF;
s2450IOP->GPDCON = 0xAAAAAAAA;
s2450IOP->GPLCON = s2450IOP->GPLCON & ~(0x3ff<<20) | (0x1<< 28) | (0x1<< 26) | (0x1<< 24) | (0x1<< 22) | (0x1<< 20);
s2450IOP->GPLDAT |= (0x1f<<10);
s2450IOP->GPBDAT &= ~(1<<1);
s2450IOP->GPFCON = (s2450IOP->GPFCON & ~(0x3<<14)) | (0x1<<14); // GPF7: OUTPUT
s2450IOP->GPFUDP=(s2450IOP->GPFUDP&~(0x3<<14))|(2<<14);
s2450IOP->GPFDAT=(s2450IOP->GPFDAT&~(0x1<<7))|(1<<7);
///SYS POWER ON
s2450IOP->GPFCON = s2450IOP->GPFCON & ~(0x3<<8)|(0x1<<8);
s2450IOP->GPFUDP=(s2450IOP->GPFUDP&~(0x3<<8))|(2<<8);
s2450IOP->GPFDAT |= (0x1<<4);
///usb POWER ON
s2450IOP->GPBCON = s2450IOP->GPBCON & ~(0x3<<8)|(0x1<<8);
s2450IOP->GPBDAT = s2450IOP->GPBDAT & ~(0x1<<4);
EdbgOutputDebugString("Init_LDI \r\n");
InitLDI_LTS222_CPUIF();
//LCDC_Common_Init();
//Basic_Display_Setting();
}
void wr_cmd(UINT16 cmd)
{
volatile S3C2416_LCD_REG *s2450LCD = (S3C2416_LCD_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_LCD, FALSE);
s2450LCD->SIFCCON0 &= ~(1<<1); // RS low
s2450LCD->SIFCCON0 |= (1<<6); // nWE enable
s2450LCD->SIFCCON1 = cmd;
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
}
void wr_data(UINT16 dat)
{
volatile S3C2416_LCD_REG *s2450LCD = (S3C2416_LCD_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_LCD, FALSE);
s2450LCD->SIFCCON0 |= (1<<1); // RS high
s2450LCD->SIFCCON0 |= (1<<6); // nWE enable
s2450LCD->SIFCCON1 = dat;
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
}
void LCD_WriteReg(UINT16 Reg,UINT16 Dat)
{
wr_cmd(Reg);
wr_data(Dat);
}
void InitLDI_LTS222_CPUIF(void)
{
volatile S3C2416_LCD_REG *s2450LCD = (S3C2416_LCD_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_LCD, FALSE);
volatile S3C2416_IOPORT_REG *s2450IOP = (S3C2416_IOPORT_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_IOPORT, FALSE);
volatile S3C2416_PWM_REG *v_pPWMregs = (S3C2416_IOPORT_REG *)OALPAtoVA(S3C2416_BASE_REG_PA_PWM, FALSE);
int i,x,y;
s2450LCD->VIDCON0 = s2450LCD->VIDCON0 & ~(0x3<<22) | (0x2<<22);
s2450LCD->SYSIFCON0 |= (1<<2);
s2450LCD->SIFCCON0 &= ~(1<<1); // RS low
s2450LCD->SIFCCON0 |= (1<<0); // command mode enable
s2450LCD->SIFCCON0 |= (1<<8); // nCS0(Main) enable
// LCD module reset
s2450IOP->GPDCON = (s2450IOP->GPDCON & ~(3<<28)) | (1<<28); //GPD14 AS OUTPUT
s2450IOP->GPDDAT &=~(0x1<<14);
delayLoop(1000);
s2450IOP->GPDCON = (s2450IOP->GPDCON & ~(3<<30)) | (1<<30); //
s2450IOP->GPDDAT |=(0x1<<15);
//delayLoop(36000);
i=1000;
while (i--)
{
delayLoop(1000);
}
s2450IOP->GPDDAT &=~(0x1<<15);
//delayLoop(36000);
i=1000;
while (i--)
{
delayLoop(1000);
}
s2450IOP->GPDDAT |=(0x1<<15);
// delay about 10ms
//delayLoop(36000);
i=1000;
while (i--)
{
delayLoop(1000);
}
#if 1
LCD_WriteReg(0x46,0x95);
LCD_WriteReg(0x47,0x51);
LCD_WriteReg(0x48,0x00);
LCD_WriteReg(0x49,0x36);
LCD_WriteReg(0x4A,0x11);
LCD_WriteReg(0x4B,0x66);
LCD_WriteReg(0x4C,0x14);
LCD_WriteReg(0x4D,0x77);
LCD_WriteReg(0x4E,0x13);
LCD_WriteReg(0x4F,0x4C);
LCD_WriteReg(0x50,0x46);
LCD_WriteReg(0x51,0x46);
//240x320 window setting
LCD_WriteReg(0x02,0x00); // Column address start2
LCD_WriteReg(0x03,0x00); // Column address start1
LCD_WriteReg(0x04,0x00); // Column address end2
LCD_WriteReg(0x05,0xEF); // Column address end1
LCD_WriteReg(0x06,0x00); // Row address start2
LCD_WriteReg(0x07,0x00); // Row address start1
LCD_WriteReg(0x08,0x01); // Row address end2
LCD_WriteReg(0x09,0x3F); // Row address end1
// Display Setting
LCD_WriteReg(0x01,0x06); // IDMON=0, INVON=1, NORON=1, PTLON=0
LCD_WriteReg(0x16,0xc8); // MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0 0x48
// LCD_WriteReg(0x16,0x48); // MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0 0x48
LCD_WriteReg(0x38,0x00); // RGB_EN=0, use MPU Interface
LCD_WriteReg(0x23,0x95); // N_DC=1001 0101
LCD_WriteReg(0x24,0x95); // P_DC=1001 0101
LCD_WriteReg(0x25,0xFF); // I_DC=1111 1111
LCD_WriteReg(0x27,0x06); // N_BP=0000 0110
LCD_WriteReg(0x28,0x06); // N_FP=0000 0110
LCD_WriteReg(0x29,0x06); // P_BP=0000 0110
LCD_WriteReg(0x2A,0x06); // P_FP=0000 0110
LCD_WriteReg(0x2C,0x06); // I_BP=0000 0110
LCD_WriteReg(0x2D,0x06); // I_FP=0000 0110
LCD_WriteReg(0x3A,0x01); // N_RTN=0000, N_NW=001
LCD_WriteReg(0x3B,0x00); // P_RTN=0000, P_NW=000
LCD_WriteReg(0x3C,0xF0); // I_RTN=1111, I_NW=000
LCD_WriteReg(0x3D,0x00); // DIV=00
delayLoop(20); //DelayX1ms(20);
LCD_WriteReg(0x35,0x38); // EQS=38h
LCD_WriteReg(0x36,0x78); // EQP=78h
LCD_WriteReg(0x3E,0x38); // SON=38h
LCD_WriteReg(0x40,0x0F); // GDON=0Fh
LCD_WriteReg(0x41,0xF0); // GDOFF
// Power Supply Setting
LCD_WriteReg(0x19,0x49); // OSCADJ=10 0000, OSD_EN=1 //60Hz
LCD_WriteReg(0x93,0x0C); // RADJ=1100
delayLoop(20); //DelayX1ms(10);
LCD_WriteReg(0x20,0x40); // BT=0100
LCD_WriteReg(0x1D,0x07); // VC1=111
LCD_WriteReg(0x1E,0x00); // VC3=000
LCD_WriteReg(0x1F,0x04); // VRH=0100
// VCOM Setting for CMO 2.8 Panel
LCD_WriteReg(0x44,0x44); // VCM=101 0000 0x4D set vcomh voltage
LCD_WriteReg(0x45,0x11); // VDV=1 0001
delayLoop(20); //DelayX1ms(10);
LCD_WriteReg(0x1C,0x04); // AP=100
delayLoop(20); //DelayX1ms(20);
LCD_WriteReg(0x1B,0x18); // GASENB=0, PON=1, DK=1, XDK=0, DDVDH_TRI=0, STB=0
delayLoop(20); //DelayX1ms(10);
LCD_WriteReg(0x1B,0x10); // GASENB=0, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0
delayLoop(20); //DelayX1ms(10);
LCD_WriteReg(0x43,0x80); //Set VCOMG=1
delayLoop(20); //DelayX1ms(10);
// Display ON Setting
LCD_WriteReg(0x90,0x7F); // SAP=0111 1111
LCD_WriteReg(0x26,0x04); //GON=0, DTE=0, D=01
delayLoop(20); //DelayX1ms(10);
LCD_WriteReg(0x26,0x24); //GON=1, DTE=0, D=01
LCD_WriteReg(0x26,0x2C); //GON=1, DTE=0, D=11
delayLoop(20); //DelayX1ms(10);
LCD_WriteReg(0x26,0x3C); //GON=1, DTE=1, D=11
// Internal register setting
LCD_WriteReg(0x0057,0x0002); //Test_Mode Enable
LCD_WriteReg(0x0095,0x0001); // Set Display clock and Pumping clock to synchronize
LCD_WriteReg(0x0057,0x0000); // Test_Mode Disable
#endif
// GPRS Rst H
s2450IOP->GPGDAT &= (~(1<<1)) ;
wr_cmd(0x0020);
wr_data(0);
wr_cmd(0x0021);
wr_data(0);
wr_cmd(0x0022);
delayLoop(100);
#if 0
delayLoop(50);
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
s2450LCD->SIFCCON0 |= (1<<8); // nCS0(Main) disable
s2450LCD->SIFCCON0 |= (1<<1); // RS high
s2450LCD->SIFCCON0 &= ~(1<<0); // command mode disable
#endif
//TFTFill(0xf800);
s2450LCD->SIFCCON0 |= (1<<1); // RS high
for(y=0;y<320*240;y++)
{
//*pFB++ =kay16bpp[y];
s2450LCD->SIFCCON0 |= (1<<6); // nWE enable
s2450LCD->SIFCCON1 = 0xf800;
s2450LCD->SIFCCON0 &= ~(1<<6); // nWE disable
}
delayLoop(50);
v_pPWMregs->TCFG0 |= 0x5; // 24 ----> 5
v_pPWMregs->TCFG1 |= 0x2<<0; // 1/8
v_pPWMregs->TCMPB0 = 150;
v_pPWMregs->TCNTB0 = 1200; // PWM需要大于1KHZ ,5KHZ ,TCMPB0= 3,2,1,0 ------->lightest
v_pPWMregs->TCON |= 0x2<<0; //manual update TCNTB0 &TCMPB0
v_pPWMregs->TCON &= ~(2<<0);
v_pPWMregs->TCON |= 0x9<<0; //ATUO reload & start Inver off
s2450IOP->GPBUDP &= ~0x3;
s2450IOP->GPBCON = (s2450IOP->GPBCON & ~(3<<0)) | (2<<0); // Backlight Pwm control
s2450IOP->GPBDAT |=(1<<0);
//TERM_ON L
s2450IOP->GPFDAT |= (1<<5) ;
}