看下面的代码,你会发现韦老师这种组织与内核框架的组织是一脉相承的。
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);
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章