LCD编程框架组织
阅读原文时间:2023年07月11日阅读:1

看下面的代码,你会发现韦老师这种组织与内核框架的组织是一脉相承的。

led.c

#define LCD_NUM 10

static p_lcd_params p_array_lcd[LCD_NUM];
static p_lcd_params g_p_lcd_selected;

int register_lcd(p_lcd_params plcd)
{
int i;
for (i = ; i < LCD_NUM; i++)
{
if (!p_array_lcd[i])
{
p_array_lcd[i] = plcd;
return i;
}
}
return -;
}

int select_lcd(char *name)
{
int i;
for (i = ; i < LCD_NUM; i++) { if (p_array_lcd[i] && !strcmp(p_array_lcd[i]->name, name))
{
g_p_lcd_selected = p_array_lcd[i];
return i;
}
}
return -;
}

int lcd_init(void)
{
/* 注册LCD */
lcd_4_3_add();

 /\* 注册LCD控制器 \*/  
 lcd\_contoller\_add();  
 /\* 选择某款LCD \*/  
 select\_lcd("lcd\_4.3");

 /\* 选择某款LCD控制器 \*/  
 select\_lcd\_controller("s3c2440");

 /\* 使用LCD的参数, 初始化LCD控制器 \*/  
 lcd\_controller\_init(g\_p\_lcd\_selected);  

}

led_4.3.c

#define LCD_FB_BASE 0x33c00000

lcd_params lcd_4_3_params = {
.name = "lcd_4.3"
.pins_polarity = {
.de = NORMAL, /* normal: 高电平时可以传输数据 */
.pwren = NORMAL, /* normal: 高电平有效 */
.vclk = NORMAL, /* normal: 在下降沿获取数据 */
.rgb = NORMAL, /* normal: 高电平表示1 */
.hsync = INVERT, /* normal: 高脉冲 */
.vsync = INVERT, /* normal: 高脉冲 */
},
.time_sequence = {
/* 垂直方向 */
.tvp= , /* vysnc脉冲宽度 */
.tvb= , /* 上边黑框, Vertical Back porch */
.tvf= , /* 下边黑框, Vertical Front porch */

     /\* 水平方向 \*/  
     .thp=    , /\* hsync脉冲宽度 \*/  
     .thb=    ,  /\* 左边黑框, Horizontal Back porch \*/  
     .thf=    ,  /\* 右边黑框, Horizontal Front porch \*/

     .vclk=    ,  /\* MHz \*/  
 },  
 .xres = ,  
 .yres = ,  
 .bpp  = ,  
 .fb\_base = LCD\_FB\_BASE,  

};

void lcd_4_3_add(void)
{
register_lcd(&lcd_4_3_params);
}

led_controller.c

#define LCD_CONTROLLER_NUM 10

static p_lcd_controller p_array_lcd_controller[LCD_CONTROLLER_NUM];
static p_lcd_controller g_p_lcd_controller_selected;

int register_lcd_controller(p_lcd_controller plcdcon)
{
int i;
for (i = ; i < LCD_CONTROLLER_NUM; i++)
{
if (!p_array_lcd_controller[i])
{
p_array_lcd_controller[i] = plcdcon;
return i;
}
}
return -;
}

int select_lcd_controller(char *name)
{
int i;
for (i = ; i < LCD_CONTROLLER_NUM; i++) { if (p_array_lcd_controller[i] && !strcmp(p_array_lcd_controller[i]->name, name))
{
g_p_lcd_controller_selected = p_array_lcd_controller[i];
return i;
}
}
return -;
}

/* 向上: 接收不同LCD的参数
* 向下: 使用这些参数设置对应的LCD控制器
*/

int lcd_controller_init(p_lcd_params plcdparams)
{
/* 调用所选择的LCD控制器的初始化函数 */
if (g_p_lcd_controller_selected)
{
g_p_lcd_controller_selected->init(plcdparams);
return ;
}
return -;
}

void lcd_contoller_add(void)
{
s3c2440_lcd_contoller_add();
}

s3c2440_lcd_controller.c

#define HCLK 100

void jz2440_lcd_pin_init(void)
{
/* 初始化引脚 : 背光引脚 */
GPBCON &= ~0x3;
GPBCON |= 0x01;

 /\* LCD专用引脚 \*/  
 GPCCON = 0xaaaaaaaa;  
 GPDCON = 0xaaaaaaaa;

 /\* PWREN \*/  
 GPGCON |= (<<);  

}

/* 根据传入的LCD参数设置LCD控制器 */
void s3c2440_lcd_controller_init(p_lcd_params plcdparams)
{
int pixelplace;
unsigned int addr;

 jz2440\_lcd\_pin\_init();

 /\* \[17:8\]: clkval, vclk = HCLK / \[(CLKVAL+1) x 2\]  
  \*                   9   = 100M /\[(CLKVAL+1) x 2\], clkval = 4.5 = 5  
  \*                 CLKVAL = 100/vclk/2-1  
  \* \[6:5\]: 0b11, tft lcd  
  \* \[4:1\]: bpp mode  
  \* \[0\]  : LCD video output and the logic enable/disable  
  \*/  
 int clkval = (double)HCLK/plcdparams->time\_seq.vclk/-+0.5;  
 int bppmode = plcdparams->bpp ==   ? 0xb :\\  
               plcdparams->bpp ==  ? 0xc :\\  
               0xd;  /\* 0xd: 24bpp \*/  
 LCDCON1 = (clkval<<) | (<<) | (bppmode<<) ;

 /\* \[31:24\] : VBPD    = tvb - 1  
  \* \[23:14\] : LINEVAL = line - 1  
  \* \[13:6\]  : VFPD    = tvf - 1  
  \* \[5:0\]   : VSPW    = tvp - 1  
  \*/  
 LCDCON2 =     ((plcdparams->time\_seq.tvb - )<<) | \\  
             ((plcdparams->yres - )<<)         | \\  
             ((plcdparams->time\_seq.tvf - )<<)  | \\  
             ((plcdparams->time\_seq.tvp - )<<);

 /\* \[25:19\] : HBPD     = thb - 1  
  \* \[18:8\]  : HOZVAL  = 列 - 1  
  \* \[7:0\]   : HFPD     = thf - 1  
  \*/  
 LCDCON3 =    ((plcdparams->time\_seq.thb - )<<) | \\  
             ((plcdparams->xres - )<<)              | \\  
             ((plcdparams->time\_seq.thf - )<<);

 /\*  
  \* \[7:0\]   : HSPW     = thp - 1  
  \*/  
 LCDCON4 =    ((plcdparams->time\_seq.thp - )<<);

 /\* 用来设置引脚极性, 设置16bpp, 设置内存中象素存放的格式  
  \* \[12\] : BPP24BL  
  \* \[11\] : FRM565, 1-565  
  \* \[10\] : INVVCLK, 0 = The video data is fetched at VCLK falling edge  
  \* \[9\]  : HSYNC是否反转  
  \* \[8\]  : VSYNC是否反转  
  \* \[7\]  : INVVD, rgb是否反转  
  \* \[6\]  : INVVDEN  
  \* \[5\]  : INVPWREN  
  \* \[4\]  : INVLEND  
  \* \[3\]  : PWREN, LCD\_PWREN output signal enable/disable  
  \* \[2\]  : ENLEND  
  \* \[1\]  : BSWP  
  \* \[0\]  : HWSWP  
  \*/

 pixelplace = plcdparams->bpp ==  ? () : |\\  
              plcdparams->bpp ==  ? () : |\\  
              (<<);  /\* 8bpp \*/  
 LCDCON5 = (plcdparams->pins\_pol.vclk<<) |\\  
           (plcdparams->pins\_pol.rgb<<)   |\\  
           (plcdparams->pins\_pol.hsync<<) |\\  
           (plcdparams->pins\_pol.vsync<<) |\\  
            (plcdparams->pins\_pol.de<<)    |\\  
           (plcdparams->pins\_pol.pwren<<) |\\  
           (<<) | pixelplace;

 /\* framebuffer地址 \*/  
 /\*  
  \* \[29:21\] : LCDBANK, A\[30:22\] of fb  
  \* \[20:0\]  : LCDBASEU, A\[21:1\] of fb  
  \*/  
 addr = plcdparams->fb\_base & ~(<<);  
 LCDSADDR1 = (addr >> );

 /\*  
  \* \[20:0\] : LCDBASEL, A\[21:1\] of end addr  
  \*/  
 addr = plcdparams->fb\_base + plcdparams->xres\*plcdparams->yres\*plcdparams->bpp/;  
 addr >>=;  
 addr &= 0x1fffff;  
 LCDSADDR2 = addr;//  

}

void s3c2440_lcd_controller_enalbe(void)
{
/* 背光引脚 : GPB0 */
GPBDAT |= (<<);

 /\* pwren    : 给LCD提供AVDD  \*/  
 LCDCON5 |= (<<);

 /\* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 \*/  
 LCDCON1 |= (<<);  

}

void s3c2440_lcd_controller_disable(void)
{
/* 背光引脚 : GPB0 */
GPBDAT &= ~(<<);

 /\* pwren    : 给LCD提供AVDD  \*/  
 LCDCON5 &= ~(<<);

 /\* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 \*/  
 LCDCON1 &= ~(<<);  

}

struct lcd_controller s3c2440_lcd_controller = {
.name = "s3c2440",
.init = s3c2440_lcd_controller_init,
.enalbe = s3c2440_lcd_controller_enalbe,
.disable = s3c2440_lcd_controller_disable,
};

void s3c2440_lcd_contoller_add(void)
{
register_lcd_controller(&s3c2440_lcd_controller);
}