当前位置:编程学习 > C/C++ >>

S3C2416 LCD裸机配制

最近在调S3C2416的裸机驱动,下面将LCD部分贴出来,供大家参考
文件名:lcd.c
背光控制:TOUT0,这里是直接用IO控制了。
这里使用的是7寸屏800*480
显存地址:0x33b00000
图片文件是用Image2Lcd工具生成的,色彩16位.
 
#include "include.h"  
  
#define CFG_HIGH    1  
#define CFG_LOW     0  
  
#define     HCLK    66000000  
  
#define PIXELBITS   16  
  
#define IVCLK       CFG_LOW  
#define IHSYNC      CFG_HIGH  
#define IVSYNC      CFG_HIGH  
#define IVDEN       CFG_LOW  
  
static uint8 HFP    =0;  
static uint8 HSW    =0;  
static uint8 HBP    =0;  
static uint8 VFP    =0;  
static uint8 VSW    =0;  
static uint8 VBP    =0;  
static uint16 HRES  =0;  
static uint16 VRES  =0;  
static uint8 CLKVAL =20;  
  
extern unsigned char gImage_one[];  
extern unsigned char gImage_two[];  
extern unsigned char gImage_three[];  
  
#define HRES_VIRTUAL    HRES  
#define VRES_VIRTUAL    VRES*2  
  
#define LCD_FRAMEBUFFER 0xc3b00000  
  
  
ulong virt_to_phy_gzsd2416(ulong addr)  
{  
    if((0xC0000000 <= addr) && (addr < 0xC4000000))  
        return (addr - 0xC0000000 + 0x30000000);  
    else  
        return addr;  
}  
  
  
#define CONFIG_ENABLE_MMU  
#ifdef CONFIG_ENABLE_MMU  
#define virt_to_phys(x) virt_to_phy_gzsd2416(x)  
#else  
#define virt_to_phys(x) x  
#endif  
  
  
static int gzsd_lcd_ctrl_init(void *lcdbase)  
{  
    ulong freq_lcdclk;  
    ulong freq_Hclk;  
    ulong fb_size;  
    uint8 nn;  
    uint16 *pp;  
    int i;  
      
    rGPCCON = 0xaaaa02aa;  
    rGPCUDP = 0xaaaa02aa;  
    rGPDCON = 0xaaaaaaaa;  
    rGPDUDP = 0xaaaaaaaa;  
      
    lcd_enable(0);  
      
    rWINCON0 &= ~WINCONx_ENWIN_F_ENABLE;  
    rWINCON1 &= ~WINCONx_ENWIN_F_ENABLE;  
  
    rVIDCON0 = (VIDCON0_S_RGB_IF)|(VIDCON0_S_RGB_PAR)|(VIDCON0_S_VCLK_GATING_OFF)  
            |(VIDCON0_S_CLKDIR_DIVIDED)|(VIDCON0_S_CLKSEL_HCLK)|VIDCON0_CLKVAL_F(CLKVAL);  
              
    rVIDCON1 = (VIDCON1_S_HSYNC_INVERTED)|(VIDCON1_S_VSYNC_INVERTED);  
      
    rVIDTCON0 = VIDTCON0_VBPD(VBP-1)|VIDTCON0_VFPD(VFP-1)|VIDTCON0_VSPW(VSW-1);  
      
    rVIDTCON1 = VIDTCON1_HBPD(HBP-1)|VIDTCON1_HFPD(HFP-1)|VIDTCON1_HSPW(HSW-1);  
      
    rVIDTCON2 = VIDTCON2_LINEVAL(VRES-1)|VIDTCON2_HOZVAL(HRES-1);  
      
    rWINCON0 = WINCONx_BPPMODE_F_16BPP_565;  
    rWINCON1 = WINCONx_BPPMODE_F_16BPP_565;  
      
    rVIDOSD0A = VIDOSDxA_OSD_LTX_F(0)|VIDOSDxA_OSD_LTY_F(0);  
      
    rVIDOSD0B = VIDOSDxB_OSD_RBX_F(HRES-1)|VIDOSDxB_OSD_RBY_F(VRES-1);  
      
    rVIDOSD1A = VIDOSDxA_OSD_LTX_F(0)|VIDOSDxA_OSD_LTY_F(0);  
      
    rVIDOSD1B = VIDOSDxB_OSD_RBX_F(HRES-1)|VIDOSDxB_OSD_RBY_F(VRES-1);  
      
    rVIDOSD1C = 0x0;  
      
    fb_size = HRES*VRES*2;  
      
    rVIDW00ADD0B0 = virt_to_phys((ulong)lcdbase);  
      
    rVIDW00ADD1B0 = virt_to_phys((ulong)(lcdbase) + fb_size);  
      
    rVIDW00ADD2B0 = VIDWxADD2_OFFSIZE_F(0)|VIDWxADD2_PAGEWIDTH_F(HRES*2);  
      
    lcd_enable(1);  
    rWINCON0 |= WINCONx_ENWIN_F_ENABLE;  
    rWINCON1 |= WINCONx_ENWIN_F_ENABLE;  
      
    return 0;  
      
}  
  
void lcd_enable(int enable)  
{  
    if(enable)  
        rVIDCON0 |= (VIDCON0_ENVID_ENABLE | VIDCON0_ENVID_F_ENABLE);  
    else  
        rVIDCON0 &= ~(VIDCON0_ENVID_ENABLE | VIDCON0_ENVID_F_ENABLE);  
}  
  
void gzsd_drv_lcd_init(void)  
{  
    void *lcd_base;  
    lcd_base = (void*)LCD_FRAMEBUFFER;  
    gzsd_lcd_ctrl_init(lcd_base);  
}  
  
void lcd_backlight(int onoff)  
{  
    rGPBCON &= ~(0x3 << 0);  
    rGPBCON |= (0x1 << 0);  
  
    if(onoff)  
        rGPBDAT |= (0x1 << 0);  
    else  
        rGPBDAT &= ~(0x1 << 0);  
}  
  
void lcd_init(void)  
{  
    VBP = 15;  
    VSW = 5;  
    VFP = 5;  
      
    HBP = 25;  
    HSW = 20;  
    HFP = 88;  
      
    CLKVAL = 0;  
      
    HRES = 800;  
    VRES = 480;  
      
    gzsd_drv_lcd_init();  
    lcd_backlight(1);  
}  
  
void lcd_test()  
{  
    uint16 *pFB;  
    int i;  
      
    pFB = (unsigned short *)LCD_FRAMEBUFFER;  
    for (i=0; i<HRES*VRES; i++)  
    {  
        *pFB++ = 0x001f;        // Blue  
    }  
}  
  
  
void lcd_bmp(void)  
{  
    uint16 *pFB;  
      
    pFB = (unsigned short *)LCD_FRAMEBUFFER;  
    while(1)  
    {  
        memcpy(pFB,gImage_one,800*480*2);  
        delay(1000);  
        memcpy(pFB,gImage_two,800*480*2);  
        delay(1000);  
        memcpy(pFB,gImage_three,800*480*2);  
        delay(1000);  
    }  
}  

 

主函数调用lcd_init进行初始化,调用lcd_bmp显示图片.
处理器:ARMCLK=400M,HCLK=66M,PCLK=33M.这里改成其它频率后就跑不起来了,正在郁闷中。
理论上应该是ARMCLK=400M,HCLK=133M,PCLK=33M.如果哪位高手有调试好的,请指点下我
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,