LCD编程框架组织
看下面的代码,你会发现韦老师这种组织与内核框架的组织是一脉相承的。
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);
}
LCD编程框架组织的更多相关文章
- React Native是一套使用 React 构建 Native app 的编程框架
React Native是一套使用 React 构建 Native app 的编程框架 React Native at first sight what is React Native? 跟据官方的描 ...
- Java网络编程和NIO详解9:基于NIO的网络编程框架Netty
Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...
- Ligg.EasyWinApp-000: 一款Windows应用编程框架介绍
本框架(解决方案)是一个Windows应用编程框架和UI库,通过该框架,不需任何代码,通过XML配置文件,搭建任意复杂的Windows应用界面,以类似Execel公式的方式实现基本的过程控制( ...
- (46)LINUX应用编程和网络编程之一Linux应用编程框架
3.1.1.应用编程框架介绍 3.1.1.1.什么是应用编程 (1)整个嵌入式linux核心课程包括5个点,按照学习顺序依次是:裸机.C高级.uboot和系统移植.linux应用编程和网络编程.驱动. ...
- acl 是一个跨平台的网络通信库及服务器编程框架
acl 工程是一个跨平台(支持LINUX,WIN32,Solaris,MacOS,FreeBSD)的网络通信库及服务器编程框架,同时提供更多的实用功能库.通过该库,用户可以非常容易地编写支持多种模式( ...
- 开源软件实践之linux高性能服务器编程框架和选型
很多人学习编程技术一般都通过一本编程语言的入门书籍,然后尝试做一些例子和小项目.但是这些都不能让我们深入的学习很多的编程技巧和高深技术,当然这个时候很多有经验的学习人员就会告诉大家,找一个好的开源软件 ...
- 跨平台网络通信与server编程框架库(acl库)介绍
一.描写叙述 acl project是一个跨平台(支持LINUX,WIN32,Solaris,MacOS,FreeBSD)的网络通信库及server编程框架,同一时候提供很多其它的有用功能库.通过该库 ...
- lcd驱动框架
目录 lcd驱动框架 框图 程序分析 入口 打开open 读read 初始化registered_fb 注册 小结 程序设计 测试 方式一操作fb0 方式二操作tty 方式三操作终端 完整程序 tit ...
- Javascript:自己写异步流程编程框架
背景 自从NodeJs出来以后,异步编程便更加系统化和框架话了,为了应对异步编程框架带来的深层嵌套问题,社区也出现了异步流程编程框架,本文主要对异步流程框架做一个简单的解析. 现配代码了 var As ...
随机推荐
- Linux性能优化实战学习笔记:第五十六讲
一.上节回顾 上一节,我带你一起梳理了,性能问题分析的一般步骤.先带你简单回顾一下. 我们可以从系统资源瓶颈和应用程序瓶颈,这两个角度来分析性能问题的根源. 从系统资源瓶颈的角度来说,USE 法是最为 ...
- MySQL实战45讲学习笔记:第九讲
一.今日内容概要 今天的正文开始前,我要特意感谢一下评论区几位留下高质量留言的同学.用户名是 @某.人 的同学,对文章的知识点做了梳理,然后提了关于事务可见性的问题,就是先启动但是后提交的事务,对数据 ...
- Java-volatile底层实现原理
一.volatile 代码 package jvm; public class VolatileVisibilityTest { private static boolean initFlag = f ...
- 万亿数据下Hadoop的核心竞争力
1.前言 在大数据时代,Hadoop有着得天独厚的优势.然而,每个企业的技术储备和需求特点不同,他们希望从海量的客户数据中挖掘真正的商业价值,像Google.Facebook.Twitter等这样的企 ...
- 【转】PyQt弹出式对话框的常用方法及标准按钮类型
pyQt之弹出式对话框(QMessageBox)的常用方法及标准按钮类型 一.控件说明 QMessageBox是一种通用的弹出式对话框,用于显示消息,允许用户通过单击不同的标准按钮对消息进行反馈,且每 ...
- Loj #3045. 「ZJOI2019」开关
Loj #3045. 「ZJOI2019」开关 题目描述 九条可怜是一个贪玩的女孩子. 这天,她和她的好朋友法海哥哥去玩密室逃脱.在他们面前的是 \(n\) 个开关,开始每个开关都是关闭的状态.要通过 ...
- 联合CRF和字典学习的自顶向下的视觉显著性-全文解读
top-down visual saliency via joint CRF anddictionary learning 自顶向下的视觉显著性是使用目标对象的可判别表示和一个降低搜索空间的概率图来进 ...
- 2018年Java面试题整理
面试是我们每个人都要经历的事情,大部分人且不止一次,这里给大家总结最新的2018年面试题,让大家在找工作时候能够事半功倍. 1. Switch能否用string做参数? a. 在 Java 7 之前 ...
- $scope里的$watch方法
一.$watch的作用 监听model,如果model发生变化,则触发某些事情. 二.$watch的格式 $scope. $watch(watchFn,watchAction,deepWatch); ...
- ROS消息vs服务
1.ROS包消息/服务模式与要点 从功能上看,ROS包是信息交互和处理的基本单元.根据信息的交互和处理方式,ROS包有以下两大类: 消息发布者与订阅者 服务器与客户端 对于消息模式的包,信息的提供者主 ...