LCD编程框架组织

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

led.c

 1 #define LCD_NUM 10
 2 
 3 static p_lcd_params p_array_lcd[LCD_NUM];
 4 static p_lcd_params g_p_lcd_selected;
 5 
 6 int register_lcd(p_lcd_params plcd)
 7 {
 8     int i;
 9     for (i = 0; i < LCD_NUM; i++)
10     {
11         if (!p_array_lcd[i])
12         {
13             p_array_lcd[i] = plcd;
14             return i;
15         }
16     }
17     return -1;        
18 }
19 
20 int select_lcd(char *name)
21 {
22     int i;
23     for (i = 0; i < LCD_NUM; i++)
24     {
25         if (p_array_lcd[i] && !strcmp(p_array_lcd[i]->name, name))
26         {
27             g_p_lcd_selected = p_array_lcd[i];
28             return i;
29         }
30     }
31     return -1;        
32 }
33 
34 int lcd_init(void)
35 {
36     /* 注册LCD */
37     lcd_4_3_add();
38 
39     /* 注册LCD控制器 */
40     lcd_contoller_add();
4142     /* 选择某款LCD */
43     select_lcd("lcd_4.3");
44 
45     /* 选择某款LCD控制器 */
46     select_lcd_controller("s3c2440");
47 
48     /* 使用LCD的参数, 初始化LCD控制器 */
49     lcd_controller_init(g_p_lcd_selected);
50 }

led_4.3.c

 1 #define LCD_FB_BASE 0x33c00000
 2 
 3 lcd_params lcd_4_3_params = {
 4     .name = "lcd_4.3"
 5     .pins_polarity = {
 6         .de    = NORMAL,    /* normal: 高电平时可以传输数据 */
 7         .pwren = NORMAL,    /* normal: 高电平有效 */
 8         .vclk  = NORMAL,    /* normal: 在下降沿获取数据 */
 9         .rgb   = NORMAL,    /* normal: 高电平表示1 */
10         .hsync = INVERT,    /* normal: 高脉冲 */
11         .vsync = INVERT,     /* normal: 高脉冲 */
12     },
13     .time_sequence = {
14         /* 垂直方向 */
15         .tvp=    10, /* vysnc脉冲宽度 */
16         .tvb=    2,  /* 上边黑框, Vertical Back porch */
17         .tvf=    2,  /* 下边黑框, Vertical Front porch */
18 
19         /* 水平方向 */
20         .thp=    41, /* hsync脉冲宽度 */
21         .thb=    2,  /* 左边黑框, Horizontal Back porch */
22         .thf=    2,  /* 右边黑框, Horizontal Front porch */
23 
24         .vclk=    9,  /* MHz */
25     },
26     .xres = 480,
27     .yres = 272,
28     .bpp  = 16,
29     .fb_base = LCD_FB_BASE,
30 };
31 
32 
33 void lcd_4_3_add(void)
34 {
35     register_lcd(&lcd_4_3_params);
36 }

led_controller.c

 1 #define LCD_CONTROLLER_NUM 10
 2 
 3 static p_lcd_controller p_array_lcd_controller[LCD_CONTROLLER_NUM];
 4 static p_lcd_controller g_p_lcd_controller_selected;
 5 
 6 int register_lcd_controller(p_lcd_controller plcdcon)
 7 {
 8     int i;
 9     for (i = 0; i < LCD_CONTROLLER_NUM; i++)
10     {
11         if (!p_array_lcd_controller[i])
12         {
13             p_array_lcd_controller[i] = plcdcon;
14             return i;
15         }
16     }
17     return -1;        
18 }
19 
20 int select_lcd_controller(char *name)
21 {
22     int i;
23     for (i = 0; i < LCD_CONTROLLER_NUM; i++)
24     {
25         if (p_array_lcd_controller[i] && !strcmp(p_array_lcd_controller[i]->name, name))
26         {
27             g_p_lcd_controller_selected = p_array_lcd_controller[i];
28             return i;
29         }
30     }
31     return -1;        
32 }
33 
34 
35 /* 向上: 接收不同LCD的参数
36  * 向下: 使用这些参数设置对应的LCD控制器
37  */
38 
39 int lcd_controller_init(p_lcd_params plcdparams)
40 {
41     /* 调用所选择的LCD控制器的初始化函数 */
42     if (g_p_lcd_controller_selected)
43     {
44         g_p_lcd_controller_selected->init(plcdparams);
45         return 0;
46     }
47     return -1;
48 }
49 
50 void lcd_contoller_add(void)
51 {
52     s3c2440_lcd_contoller_add();
53 }

s3c2440_lcd_controller.c

  1 #define HCLK 100
  2 
  3 void jz2440_lcd_pin_init(void)
  4 {
  5     /* 初始化引脚 : 背光引脚 */
  6     GPBCON &= ~0x3;
  7     GPBCON |= 0x01;
  8 
  9     /* LCD专用引脚 */
 10     GPCCON = 0xaaaaaaaa;
 11     GPDCON = 0xaaaaaaaa;
 12 
 13     /* PWREN */
 14     GPGCON |= (3<<8);
 15 }
 16 
 17 
 18 /* 根据传入的LCD参数设置LCD控制器 */
 19 void s3c2440_lcd_controller_init(p_lcd_params plcdparams)
 20 {
 21     int pixelplace;
 22     unsigned int addr;
 23 
 24     jz2440_lcd_pin_init();
 25     
 26     /* [17:8]: clkval, vclk = HCLK / [(CLKVAL+1) x 2]
 27      *                   9   = 100M /[(CLKVAL+1) x 2], clkval = 4.5 = 5
 28      *                 CLKVAL = 100/vclk/2-1
 29      * [6:5]: 0b11, tft lcd
 30      * [4:1]: bpp mode
 31      * [0]  : LCD video output and the logic enable/disable
 32      */
 33     int clkval = (double)HCLK/plcdparams->time_seq.vclk/2-1+0.5;
 34     int bppmode = plcdparams->bpp == 8  ? 0xb :
 35                   plcdparams->bpp == 16 ? 0xc :
 36                   0xd;  /* 0xd: 24bpp */
 37     LCDCON1 = (clkval<<8) | (3<<5) | (bppmode<<1) ;
 38 
 39     /* [31:24] : VBPD    = tvb - 1
 40      * [23:14] : LINEVAL = line - 1
 41      * [13:6]  : VFPD    = tvf - 1
 42      * [5:0]   : VSPW    = tvp - 1
 43      */
 44     LCDCON2 =     ((plcdparams->time_seq.tvb - 1)<<24) | 
 45                 ((plcdparams->yres - 1)<<14)         | 
 46                 ((plcdparams->time_seq.tvf - 1)<<6)  | 
 47                 ((plcdparams->time_seq.tvp - 1)<<0);
 48 
 49     /* [25:19] : HBPD     = thb - 1
 50      * [18:8]  : HOZVAL  = 列 - 1
 51      * [7:0]   : HFPD     = thf - 1
 52      */
 53     LCDCON3 =    ((plcdparams->time_seq.thb - 1)<<19) | 
 54                 ((plcdparams->xres - 1)<<8)              | 
 55                 ((plcdparams->time_seq.thf - 1)<<0);
 56 
 57     /* 
 58      * [7:0]   : HSPW     = thp - 1
 59      */
 60     LCDCON4 =    ((plcdparams->time_seq.thp - 1)<<0);
 61 
 62     /* 用来设置引脚极性, 设置16bpp, 设置内存中象素存放的格式
 63      * [12] : BPP24BL
 64      * [11] : FRM565, 1-565
 65      * [10] : INVVCLK, 0 = The video data is fetched at VCLK falling edge
 66      * [9]  : HSYNC是否反转
 67      * [8]  : VSYNC是否反转
 68      * [7]  : INVVD, rgb是否反转
 69      * [6]  : INVVDEN
 70      * [5]  : INVPWREN
 71      * [4]  : INVLEND
 72      * [3]  : PWREN, LCD_PWREN output signal enable/disable
 73      * [2]  : ENLEND
 74      * [1]  : BSWP
 75      * [0]  : HWSWP
 76      */
 77 
 78     pixelplace = plcdparams->bpp == 24 ? (0) : |
 79                  plcdparams->bpp == 16 ? (1) : |
 80                  (1<<1);  /* 8bpp */
 81     LCDCON5 = (plcdparams->pins_pol.vclk<<10) |
 82               (plcdparams->pins_pol.rgb<<7)   |
 83               (plcdparams->pins_pol.hsync<<9) |
 84               (plcdparams->pins_pol.vsync<<8) |
 85                (plcdparams->pins_pol.de<<6)    |
 86               (plcdparams->pins_pol.pwren<<5) |
 87               (1<<11) | pixelplace;
 88 
 89     /* framebuffer地址 */
 90     /*
 91      * [29:21] : LCDBANK, A[30:22] of fb
 92      * [20:0]  : LCDBASEU, A[21:1] of fb
 93      */
 94     addr = plcdparams->fb_base & ~(1<<31);
 95     LCDSADDR1 = (addr >> 1);
 96 
 97     /* 
 98      * [20:0] : LCDBASEL, A[21:1] of end addr
 99      */
100     addr = plcdparams->fb_base + plcdparams->xres*plcdparams->yres*plcdparams->bpp/8;
101     addr >>=1;
102     addr &= 0x1fffff;
103     LCDSADDR2 = addr;//    
104 }
105 
106 void s3c2440_lcd_controller_enalbe(void)
107 {
108     /* 背光引脚 : GPB0 */
109     GPBDAT |= (1<<0);
110     
111     /* pwren    : 给LCD提供AVDD  */
112     LCDCON5 |= (1<<3);
113     
114     /* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
115     LCDCON1 |= (1<<0);
116 }
117 
118 void s3c2440_lcd_controller_disable(void)
119 {
120     /* 背光引脚 : GPB0 */
121     GPBDAT &= ~(1<<0);
122 
123     /* pwren    : 给LCD提供AVDD  */
124     LCDCON5 &= ~(1<<3);
125 
126     /* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
127     LCDCON1 &= ~(1<<0);
128 }
129 
130 struct lcd_controller s3c2440_lcd_controller = {
131     .name    = "s3c2440",
132     .init    = s3c2440_lcd_controller_init,
133     .enalbe  = s3c2440_lcd_controller_enalbe,
134     .disable = s3c2440_lcd_controller_disable,
135 };
136 
137 
138 void s3c2440_lcd_contoller_add(void)
139 {
140     register_lcd_controller(&s3c2440_lcd_controller);
141 }
原文地址:https://www.cnblogs.com/-glb/p/11342459.html