⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcdexp.c

📁 Linux 嵌入式设备 液晶屏驱动代码
💻 C
字号:
/* * lcdexp.c : LCD driver * * Copyright (C) 2003 ynding ( haoanian@263.net ) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#define EXPORT_SYMTAB#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/delay.h>#include <asm/fcntl.h>#include <asm/unistd.h>#include <asm/io.h>#include <asm/uaccess.h>#include "lcdexp.h"static unsigned char* __lcd_base;/* Configuration of LCD */int setup_lcd(void){	/* LCDEN[12] = 0 : Disable LCD before setting the registers of LCD */	SYSCON1 &= ~0x00001000;	/*	 * set LCD Control Register	 * Video Buffer Size[0:12] : 320*240*12 / 128 = 0x1c1f	 * Line Length[13:18] : 320 / 16 -1 = 0x13	 * Pixel Prescale[19:24] : 0x01	 * AC Prescale[25:29] : 0x13	 * GSEN[30] : =1,Enables gray scale output to LCD	 * GSMD[31] : =1,4 bpp ( 16-gray scale )	 */	LCDCON = 0xe60f7c1f;	/* Set Least/Most Significant Word - Set LCD Palette Register */	PALLSW = 0x76543210;	PALMSW = 0xfedcba98;	/*	 * Sets the start location in system memory for LCD frame buffer	 * thus, the frame buffer starts from the location 0xc0000000	 * in system memory	 */	FBADDR = 0xc;	/* LCDEN[12] = 1 : Enable LCD after the LCD configuration */	SYSCON1 |= 0x00001000;        	return 0;}void clear_lcd(void){	unsigned char *base = __lcd_base;	int i;	/* clear from the beginning of the frame buffer until the end of it */	for ( i=0;i<320*240*12/8;i++ ) {		*base++ = 0x77;	}	return;}void init_lcd(void){	setup_lcd();	clear_lcd();	return;}/*  * draw a dot in the LCD * x,y : coordinate of the pixel to be lightened * color : the color of the dot */void lcd_pixel_set(int x,int y,struct COLOR color){	unsigned char*	fb_ptr;	/* if the dot is out of the LCD, return */	if ( x<0 || x>=320|| y<0 || y>=240) {		return;	}	/* calculate the address according the dot */	fb_ptr = __lcd_base + (x+y*320)*12/8;	/* setup the image from the pixel to the frame buffer */	if ( x & 0x1 ) {		*fb_ptr &= 0x0f;		*fb_ptr |= color.red << 4;		*(fb_ptr+1) = 0xff & ( (color.blue << 4) | color.green );	} else {		*fb_ptr = 0xff & ( (color.green << 4) | color.red );		*(fb_ptr+1) &= 0xf0;		*(fb_ptr+1) |= color.blue;	}	return;}/* draw a big dot 2*2 */void lcd_big_pixel_set(int x, int y, struct COLOR color){	lcd_pixel_set( x, y, color);	lcd_pixel_set( x, y+1, color);	lcd_pixel_set( x+1, y, color);	lcd_pixel_set( x+1, y+1, color);	return;}/* draw a vertical line */void draw_vline(int x, int y1, int y2, struct COLOR color){	int tmp; 	int i = 0;			        	if ( y1>y2 ) {		tmp = y1;		y1 = y2;		y2 = tmp;	}	tmp = y2 - y1;	for ( i=0;i<=tmp;++i ) { 		lcd_pixel_set(x,y1+i,color);	}	return;}/* draw a horizontal line */void draw_hline(int x1, int x2, int y, struct COLOR color){       	int tmp;	int i = 0;	if ( x1>x2 ) {		tmp = x1;		x1 = x2;		x2 = tmp;	}	tmp = x2 - x1;	for ( i=0;i<=tmp;++i ) {		lcd_pixel_set(x1+i,y,color);	}	return;}/* draw a vertical dashed */ void draw_vdashed(int x, int y1, int y2, struct COLOR color){       	int tmp;	int i = 0;			        	if ( y1>y2 ) {		tmp = y1;		y1 = y2;		y2 = tmp;	}				        	tmp = y2 - y1;	for ( i=0;i<=tmp;i+=5 ) {		lcd_pixel_set(x, y1+i, color);	}	return;}/* draw a horizontal dashed */void draw_hdashed(int x1, int x2, int y, struct COLOR color){	int tmp;	int i = 0;	if ( x1>x2 ) {		tmp = x1;		x1 = x2;		x2 = tmp;	}	tmp = x2 - x1;	for ( i=0;i<=tmp;i+=5 ) {		lcd_pixel_set(x1+i, y, color);	}	return;}/* draw vertical scales */void draw_vscale(int x, int y1, int y2, struct COLOR color){	int tmp;	int i = 0;	if ( y1>y2 ) {		tmp = y1;		y1 = y2;		y2 = tmp;	}	tmp = y2 - y1;	draw_vdashed(x, y1, y2, color);	draw_vdashed(x-1, y1, y2, color);	draw_vdashed(x+1, y1, y2, color);	return;}/* draw horizontal scales */void draw_hscale(int x1, int x2, int y, struct COLOR color){	int tmp;	int i = 0;	if ( x1>x2 ) {		tmp = x1;		x1 = x2;		x2 = tmp;	}	tmp = x2 - x1;	draw_hdashed(x1, x2, y, color);	draw_hdashed(x1, x2, y-1, color);	draw_hdashed(x1, x2, y+1, color);	return;}/* * (start_x,start_y) : coordinate of the top-left-corner of the rectangle  * (end_x,end_y) : coordinate of the bottom-right-corner of the rectangle */void draw_rectangle(int start_x,int start_y,int end_x,int end_y,struct COLOR color){	draw_vline(start_x, start_y, end_y, color);	draw_vline(end_x, start_y, end_y, color);	draw_hline(start_x, end_x, start_y, color);	draw_hline(start_x, end_x, end_y, color);	return;}/* * (start_x,start_y) : coordinate of the top-left-corner of the rectangle  * (end_x,end_y) : coordinate of the bottom-right-corner of the rectangle * this rectangle is filled with pixels which color is the same as the frame */void draw_full_rectangle(int start_x, int start_y, int end_x, int end_y, struct COLOR color){	int i = 0;	int tmp = 0;	tmp = end_x - start_x;	for ( i=0;i<tmp;++i ) {		draw_vline(start_x+i, start_y,end_y, color);	}	return;}/* * display an ascii character * x,y   : coordinates of the start pixel * codes : the the bytes serial to be displayed  * the size of the ascii characters is 8*16 * color : the color of the character */void write_en(int x, int y, unsigned char* codes, struct COLOR color){	int i = 0;	/* total 16 bytes codes*/	for ( i=0;i<16;++i ) {		int j = 0;		x += 8;		for ( j=0;j<8;++j ) {			--x;			if ( (codes[i]>>j) & 0x1 ) {				lcd_pixel_set(x, y, color);			}		}		/* move to the next line : x axis unchanged, y axis increase 1 */		++y;	}	return;}/* * display a Chinese character * x,y   : coordinates of the start pixel * codes : the bytes serial to be displayed * the size of the Chinese characters is 16*16 * color : the color of the character */void write_cn(int x, int y, unsigned char* codes, struct COLOR color){	int i;	/* total 2*16 bytes codes */	for(i=0;i<16;i++) {		int j = 0;		for (j=0;j<2;++j) {			int k = 0;			x += 8*(j+1);			for ( k=0;k<8;++k ){				--x;				if ( ( codes[2*i+j] >> k) & 0x1 ) {					lcd_pixel_set(x,y,color);				}			}		}		/* move to the next line : x axis unchanged, y axis increase 1 */		x -= 8;		++y;	}	return;}static int lcdexp_open(struct inode *node, struct file *file){	return 0;}static int lcdexp_read(struct file *file, char *buff, size_t count, loff_t *offp){	return 0;}static int lcdexp_write(struct file *file, const char *buff, size_t count, loff_t *offp){	return 0;}static int lcdexp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	switch ( cmd ) {	case LCD_Clear:	{		clear_lcd();		break;	}	case LCD_Pixel_Set:	{		struct lcd_display	pixel_display;		if ( copy_from_user(&pixel_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		lcd_pixel_set(pixel_display.x1, pixel_display.y1, pixel_display.color);		break;	}	case LCD_Big_Pixel_Set:	{		struct lcd_display	b_pixel_display;		if ( copy_from_user(&b_pixel_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		lcd_big_pixel_set(b_pixel_display.x1, b_pixel_display.y1, b_pixel_display.color);		break;	}	case LCD_Draw_VLine:	{		struct lcd_display	vline_display;		if ( copy_from_user(&vline_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		draw_vline(vline_display.x1, vline_display.y1, vline_display.y2, vline_display.color);		break;	}	case LCD_Draw_HLine:	{		struct lcd_display      hline_display;		if ( copy_from_user(&hline_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		draw_hline(hline_display.x1, hline_display.x2, hline_display.y1, hline_display.color);	}	case LCD_Draw_VDashed:	{		struct lcd_display      vdashed_display;		if ( copy_from_user(&vdashed_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");      			return -1;                                                      		}                                                                                       		draw_vdashed(vdashed_display.x1, vdashed_display.y1, vdashed_display.y2,			       	vdashed_display.color);		break;	}	case LCD_Draw_HDashed:	{       		struct lcd_display      hdashed_display;		if ( copy_from_user(&hdashed_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		} 		draw_hdashed(hdashed_display.x1, hdashed_display.x2, hdashed_display.y1,			       	hdashed_display.color);		break;                                                                  	}       	case LCD_Draw_VScale:	{       		struct lcd_display      vscale_display;		if ( copy_from_user(&vscale_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		} 		draw_vscale(vscale_display.x1, vscale_display.y1, vscale_display.y2, vscale_display.color);								                              		break;                                                                  	}       	case LCD_Draw_HScale:	{		struct lcd_display      hscale_display;		if ( copy_from_user(&hscale_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		draw_hscale(hscale_display.x1, hscale_display.x2, hscale_display.y1, hscale_display.color);		break;	}         	case LCD_Draw_Rectangle:	{		struct lcd_display      rect_display;		if ( copy_from_user(&rect_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		draw_rectangle(rect_display.x1, rect_display.y1,			       	rect_display.x2, rect_display.y2, rect_display.color);		break;	}         	case LCD_Draw_Full_Rectangle:	{		struct lcd_display      frect_display;		if ( copy_from_user(&frect_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		draw_full_rectangle(frect_display.x1, frect_display.y1,			       	frect_display.x2, frect_display.y2, frect_display.color);		break;                                                          	}                        	case LCD_Write_EN:	{		struct lcd_display      en_display;		if ( copy_from_user(&en_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		write_en(en_display.x1, en_display.y1, en_display.buf, en_display.color);		break;                                                          	}                        	case LCD_Write_CN:	{		struct lcd_display      cn_display;		if ( copy_from_user(&cn_display,(struct lcd_display*)arg,sizeof(struct lcd_display))) {			printk("copy_from_user error!\n");			return -1;		}		write_cn(cn_display.x1, cn_display.y1, cn_display.buf, cn_display.color);		break;        	}	default:		printk("unknown cmd\n");		break;	}	return 0;}static int lcdexp_release(struct inode *node, struct file *file){	return 0;}static struct file_operations lcdexp_fops = {	owner:          THIS_MODULE,	open:           lcdexp_open,	read:           lcdexp_read,	ioctl:		lcdexp_ioctl,	write:          lcdexp_write,	release:        lcdexp_release,};int lcdexp_init(void){	int result;	__lcd_base = (unsigned char *)__ioremap(0xc0000000, 0x20000, 0);	result = register_chrdev(DEV_MAJOR,"lcdexp",&lcdexp_fops);	if ( result < 0 ) {		printk( KERN_INFO "lcdexp:register lcdexp failed !\n");		return result;	}	init_lcd();	printk("LCD init\n");	return 0;}static void __exit lcdexp_exit(void){	/* clear LCD */	unregister_chrdev(DEV_MAJOR,"lcdexp");	return;}module_init(lcdexp_init);module_exit(lcdexp_exit);// EXPORT_SYMBOL(lcd_big_pixel_set);MODULE_LICENSE("GPL");MODULE_AUTHOR("ynding");MODULE_DESCRIPTION("ARM EP7312 LCD driver");MODULE_SUPPORTED_DEVICE("ARM");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -