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

📄 lcd_drv.c

📁 一个模拟可种嵌入开发环境的模拟软件.能模拟ARM系列等.
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/delay.h>#include <linux/slab.h>#include <asm/fcntl.h>#include <asm/unistd.h>#include <asm/io.h>#include <asm/uaccess.h>#include "ep7312_sys.h"#include "lcd_struct.h"// ioctl 命令ID#define LCD_Clear		0#define LCD_Draw_Pixel		1#define LCD_Draw_VLine		2#define LCD_Draw_HLine		3#define LCD_Draw_Rectangle	4#define LCD_Draw_Buf		5#define LCD_Write_EN		10#define LCD_Write_CN		11#define LCD_Save_SCR		12#define LCD_Load_SCR		13#define LCD_Release_SCR		14// 定义LCD的主设备号#define DEV_MAJOR			60// 定义LCD显示模式参数//#define SCR_X				160		/* LCD屏幕宽度 *///#define SCR_Y				160		/* LCD屏幕高度 */#define SCR_X				320		/* LCD屏幕宽度 */#define SCR_Y				240		/* LCD屏幕高度 *///#define BPP					32		/* LCD显示模式 *///#define BPP					16		/* LCD显示模式 *///#define BPP					24		/* LCD显示模式 *///#define BPP					8		/* LCD显示模式 */#define BPP					4		/* LCD显示模式 *///#define BPP					2		/* LCD显示模式 *///#define BPP					1		/* LCD显示模式 */// 半字节复制标志#define LowS				0		/* 取字节低四位标志 */#define HighS				1		/* 取字节高四位标志 */// LCD显示缓存的基址static unsigned char * __lcd_base;/* 设置LCD寄存器 */static void setup_lcd(void){	// 禁用LCD设备	SYSCON1 &= ~0x00001000;      	// 设置LCD控制寄存器	// 显示缓存容量[0:12]	: 320 * 240 * 12 / (8*16) = 0x1c1f	// 线长度[13:18]		: 320 / 16 - 1 = 0x13	// 像素预定标[19:24]	: 0x01	// AC预定标[25:29]		: 0x13	// 灰度使能[30]			: = 1, 使用灰度级显示	// 灰度级模式[31]		: = 1, 4 bpp模式(16灰度级)	//LCDCON = 0xe60f7c1f;//	 LCDCON = 0xe60a7c1f;  //320*720        	 //LCDCON =0xe60a6257; //320x240x1//        	 LCDCON =0xe60920c8; //160x160x1//        	 LCDCON =0xe60a64af; //320x240x2                  LCDCON =0xe60a695f; //320x240x4         //LCDCON =0xe60a72bf;  //320x240x8//        LCDCON =0xe60a72bf;  //320x240x16/(8*32) //        LCDCON =0xe60a7c1f;  //320x240x24/(8*32)//         LCDCON =0xe60a72bf;  //320x240x32/(8*64)                  	// 设置调色板颜色寄存器的低位和高位有效字	PALLSW = 0x76543210;	/* 低位有效字 */	PALMSW = 0xfedcba98;	/* 高位有效字 */	// 设置LCD显示缓冲区在系统存储区域的起始位置	FBADDR = 0xc;	// 启用LCD设备	SYSCON1 |= 0x00001000;	return;}// 限制横坐标范围// 使横坐标在0至SCR_X之间static int xFormat(int x){	int fx;	fx = x;	fx = (fx < 0) ? 0 : fx;	fx = (fx >= SCR_X) ? (SCR_X - 1) : fx;	return fx;}// 限制纵坐标范围// 使纵坐标在0至SCR_Y之间static int yFormat(int y){	int fy;	fy = y;	fy = (fy < 0) ? 0 : fy;	fy = (fy >= SCR_Y) ? (SCR_Y - 1) : fy;	return fy;}// 释放保存屏幕缓冲区static void lcd_kernel_release_screen(struct save_struct * buffer){	if ((*buffer).save_buf != NULL)	{		// 释放缓冲区		kfree((*buffer).save_buf);		// 恢复缓冲区初始化设置		(*buffer).save_buf = NULL;		(*buffer).save_w = (*buffer).save_h = 0;	}}// 保存屏幕部分区域的内容static void lcd_kernel_save_screen(int x1, int y1, int x2, int y2, struct save_struct * buffer){	unsigned char * fb_lptr;		/* 每行第一个点的显存地址 */	unsigned char bufferByte;		/* 临时缓存字节 */	long buffer_size;				/* 保存屏幕缓冲区的字节数 */	int factorCount;				/* 每行需要存取的半字节的个数 */	int sb_sign, fb_sign;			/* 半字节复制标志, = LowS: 复制低四位, = HighS: 复制高四位*/	int p_sb;						/* 保存屏幕缓冲区指针偏移量 */	int p_fb;						/* 显示缓冲区指针偏移量 */	int currLine;					/* 当前行的纵坐标 */	int tmp, i;	// 修正保存范围坐标, 使其在屏幕的显示范围之内	x1 = xFormat(x1);	x2 = xFormat(x2);	y1 = yFormat(y1);	y2 = yFormat(y2);	// 修正保存范围的横坐标, 使x2值永远大于x1的值	if (x1 > x2)	{		tmp = x1;		x1 = x2;		x2 = tmp;	}	// 修正保存范围的纵坐标, 使y2值永远大于y1的值	if (y1 > y2)	{		tmp = y1;		y1 = y2;		y2 = tmp;	}	// 计算新保存的屏幕的宽度和高度	(*buffer).save_w = x2 - x1 + 1;	(*buffer).save_h = y2 - y1 + 1;	// 计算新缓冲区大小	buffer_size = (*buffer).save_w * (*buffer).save_h * 3 * BPP / 8 + 1;	// 申请新的屏幕缓冲区	(*buffer).save_buf = kmalloc(buffer_size, GFP_KERNEL);	// 初始化保存屏幕半字节复制标志	sb_sign = LowS;	// 计算每行中半字节的个数	factorCount = (*buffer).save_w * 3;	// 初始化屏幕缓冲区指针偏移量	p_sb = 0;	// 复制显存的内容到保存屏幕缓冲区中	for (currLine = y1; currLine <= y2; currLine++)	{		// 计算当前行第一个点的显存地址		fb_lptr = __lcd_base + (x1 + currLine * SCR_X) * 3 * BPP / 8;		// 初始化显存半字节复制标志		fb_sign = (x1 & 0x1);		// 初始化显示缓冲区指针偏移量		p_fb = 0;		// 复制显存当前行的内容		for (i = 0; i < factorCount; i++)		{			// 临时缓冲字节清零			bufferByte &= 0x00;			// 根据显存半字节复制标志, 将显存中当前字节的内容的低四位(或高四位)			// 复制到临时缓冲字节的低四位中			if (fb_sign == LowS)				bufferByte = (fb_lptr[p_fb] & 0x0f);			else				bufferByte = (fb_lptr[p_fb] & 0xf0) >> 4;			// 根据保存屏幕缓冲区半字节复制标志, 			// 对保存屏幕缓冲区当前字节中相应的四位清零;			// 如果是要复制高四位的内容, 			// 还要将临时缓冲字节的低四位内容移到高四位中			if (sb_sign == HighS)			{				(*buffer).save_buf[p_sb] &= 0x0f;				bufferByte = bufferByte << 4;			}			else				(*buffer).save_buf[p_sb] &= 0xf0;			// 用临时缓冲字节更新保存屏幕缓冲区的当前字节			(*buffer).save_buf[p_sb] |= bufferByte;			// 根据半字节复制标志, 设置相应的指针偏移量			if (fb_sign == HighS)				p_fb++;			if (sb_sign == HighS)				p_sb++;			// 更新半字节复制标志			sb_sign ^= 0x1;						fb_sign ^= 0x1;					}	}}// 加载屏幕部分区域的内容static void lcd_kernel_load_screen(int x1, int y1, struct save_struct buffer){	unsigned char * fb_lptr;		/* 每行第一个点的显存地址 */	unsigned char bufferByte;		/* 临时缓存字节 */	int factorCount;				/* 每行需要存取的半字节的个数 */	int sb_sign, fb_sign;			/* 半字节复制标志, = LowS: 复制低四位, = HighS: 复制高四位*/	int p_sb;						/* 保存屏幕缓冲区指针偏移量 */	int p_fb;						/* 显示缓冲区指针偏移量 */	int x2, y2;						/* 加载区域右下角的坐标 */	int currLine;					/* 当前行的纵坐标 */	int i;	// 修正加载范围坐标, 使其在屏幕的显示范围之内	x1 = xFormat(x1);	y1 = xFormat(y1);	// 计算加载范围右下角的坐标	x2 = x1 + buffer.save_w - 1;	y2 = y1 + buffer.save_h - 1;	// 如果加载范围超出屏幕的显示范围	// 则不作任何操作返回	if (x2 >= SCR_X || y2 >= SCR_Y)	{		printk(KERN_INFO "Load position out of screen boundary!\n");		return;	}	// 如果尚未执行保存屏幕的操作,	// 则不作任何操作返回	if (buffer.save_buf == NULL)	{		printk(KERN_INFO "No Saved Screen!\n");		return;	}	// 初始化保存屏幕半字节复制标志	sb_sign = LowS;	// 计算每行中半字节的个数	factorCount = buffer.save_w * 3;	// 初始化屏幕缓冲区指针偏移量	p_sb = 0;	// 加载保存屏幕缓冲区的内容到显存中	for (currLine = y1; currLine <= y2; currLine++)	{		// 计算当前行第一个点的显存地址		fb_lptr = __lcd_base + (x1 + currLine * SCR_X) * 3 * BPP / 8;		// 初始化显存半字节复制标志		fb_sign = (x1 & 0x1);		// 初始化显示缓冲区指针偏移量		p_fb = 0;		// 加载当行的内容到显存中		for (i = 0; i < factorCount; i++)		{			// 临时缓冲字节清零			bufferByte &= 0x00;			// 根据保存屏幕半字节复制标志, 将保存屏幕缓冲区中			// 当前字节的内容的低四位(或高四位)			// 复制到临时缓冲字节的低四位中			if (sb_sign == LowS)				bufferByte = (buffer.save_buf[p_sb] & 0x0f);			else				bufferByte = (buffer.save_buf[p_sb] & 0xf0) >> 4;			// 根据显存半字节复制标志, 			// 对显存当前字节中相应的四位清零;			// 如果是要复制高四位的内容, 			// 还要将临时缓冲字节的低四位内容移到高四位中			if (fb_sign == HighS)			{				fb_lptr[p_fb] &= 0x0f;				bufferByte = bufferByte << 4;			}			else				fb_lptr[p_fb] &= 0xf0;			// 用临时缓冲字节更新显存内容			fb_lptr[p_fb] |= bufferByte;			// 根据半字节复制标志, 设置相应的指针偏移量			if (fb_sign == HighS)				p_fb++;			if (sb_sign == HighS)				p_sb++;			// 更新半字节复制标志			sb_sign ^= 0x1;						fb_sign ^= 0x1;			}	}}// 绘制一个像素点static void lcd_kernel_pixel(int x, int y, COLOR color){	unsigned char*	fb_ptr;			/* 更新像素点对应的显存地址 */	unsigned short* fb_ptr_halfword;	unsigned int* fb_ptr_word;	unsigned int pointeraddr;			//COLOR pure_color=0x0000;	unsigned char pure_color_byte =       0x00;		/* 更新颜色信息 */	unsigned short  pure_color_halfword = 0x0000;	unsigned int  pure_color_word = 0x00000000;		// 如果坐标越界则不做任何操作, 直接返回	if ( x < 0 || x >= SCR_X|| y < 0 || y >= SCR_Y)	{		printk("out of bounds\n");		return;	}	// 计算当前点对应的显存地址	//fb_ptr = __lcd_base + (x + y * SCR_X) * 3 * BPP / 8;	fb_ptr = __lcd_base + (x + y * SCR_X) * 1 * BPP / 8;  //by ywc 4bpp,8bpp		fb_ptr_halfword = (unsigned short *)(__lcd_base + (x + y * SCR_X) * 1 * BPP / 8);//by ywc		pointeraddr = (((unsigned int )(__lcd_base + (x + y * SCR_X) * 1 * BPP / 8)));//by ywc	 fb_ptr_word =(unsigned int *)(pointeraddr&~0x3);		//fb_ptr_word   =__lcd_base + (x + y * SCR_X) * 1 * BPP / (8);					switch (BPP) {		case 1:		       switch(x & 0x07){	                        case 0:	                               pure_color_byte = (color & 0x01 ) <<0;            // add by ywc	                               *(fb_ptr) &= 0xfe;			                       *(fb_ptr) |= pure_color_byte;		                       break;		                case 1:	                               pure_color_byte = (color & 0x01 ) <<1;        // add by ywc	                               *(fb_ptr) &= 0xfd;		                       *(fb_ptr) |= pure_color_byte;                                       break;		                case 2:	                               pure_color_byte = (color & 0x01 ) <<2;            // add by ywc	                               *(fb_ptr) &= 0xfb;			                       *(fb_ptr) |= pure_color_byte;		                       break;		                case 3:	                               pure_color_byte = (color & 0x01 ) <<3;        // add by ywc	                               *(fb_ptr) &= 0xf7;		                       *(fb_ptr) |= pure_color_byte;                                       break;		                case 4:	                               pure_color_byte = (color & 0x01 ) <<4;            // add by ywc	                               *(fb_ptr) &= 0xef;			                       *(fb_ptr) |= pure_color_byte;		                       break;		                case 5:	                               pure_color_byte = (color & 0x01 ) <<5;        // add by ywc	                               *(fb_ptr) &= 0xdf;		                       *(fb_ptr) |= pure_color_byte;                                       break;		                case 6:	                               pure_color_byte = (color & 0x01 ) <<6;            // add by ywc	                               *(fb_ptr) &= 0xbf;			                       *(fb_ptr) |= pure_color_byte;		                       break;		                case 7:	                               pure_color_byte = (color & 0x01 ) <<7;        // add by ywc	                               *(fb_ptr) &= 0x7f;		                       *(fb_ptr) |= pure_color_byte;                                                            break;                               }                        break;                        case 2:                      switch(x & 0x03){	                        case 0:	                               pure_color_byte = (color & 0x03 ) <<0;            // add by ywc	                               *(fb_ptr) &= 0xfc;			                       *(fb_ptr) |= pure_color_byte;		                       break;		                case 1:	                               pure_color_byte = (color & 0x03 ) <<2;        // add by ywc	                               *(fb_ptr) &= 0xf3;		                       *(fb_ptr) |= pure_color_byte;                                       break;		                case 2:	                               pure_color_byte = (color & 0x03 ) <<4;            // add by ywc	                               *(fb_ptr) &= 0xcf;			                       *(fb_ptr) |= pure_color_byte;		                       break;		                case 3:	                               pure_color_byte = (color & 0x03 ) <<6;        // add by ywc	                               *(fb_ptr) &= 0x3f;		                       *(fb_ptr) |= pure_color_byte;		                       break;                               }                        break;		                case 4:                        if (x & 0x1)	                {	                 pure_color_byte = (color & 0x0f) << 4;            // add by ywc	                 *fb_ptr &= 0x0f;			         *fb_ptr |= pure_color_byte;		        }		        else 	                {	                 pure_color_byte = ( color & 0x0f );        // add by ywc	                 *(fb_ptr) &= 0xf0;		         *(fb_ptr) |= pure_color_byte;		        }                                                break;                case 8:                       pure_color_byte = ( color & 0xff);          // why not ? by ywc	               *(fb_ptr) = pure_color_byte;                       break;                case 15:                                                break;                case 16:                        pure_color_halfword = ( color & 0xffff);          // why not ? by ywc                        if(y==212)printk("color=%8x,fb_ptr_halfword=%p\n",color,fb_ptr_halfword);	               *(fb_ptr_halfword) = pure_color_halfword;                                                break;     /*           case 24:                       printk("color=%8x,fb_ptr_word=%p\n",color,fb_ptr);                       	               *(fb_ptr) = ( color & 0x0000ff);          // 24 bit=3 byte;	               *(fb_ptr+1) = ( color & 0x00ff00)>>4;	               *(fb_ptr+2) = ( color & 0xff0000)>>8;	               printk("pure_color_word=%8x\n",pure_color_word);                       break;      */                case 32:                       pure_color_word = ( color & 0x00ffffff);          // why not ? by ywc                      //  if(y==212)                      printk("color=%8x,fb_ptr_word=%p\n",color,fb_ptr_word);	               *(fb_ptr_word) = pure_color_word;                                                break;                                default:                                                break;                }		//pure_color = ( color & 0x00ff);   // why not ? by ywc	//*(fb_ptr) = pure_color;	// 更新像素点的颜色信息	// 处理x坐标为奇数的情况		/*	if (x & 0x1)	{	         pure_color = (color & 0x000f) << 4;            // add by ywc	         *fb_ptr &= 0x0f;			*fb_ptr |= pure_color;		}	// 处理x坐标为偶数的情况	else 	{	       pure_color = ( color & 0x000f );        // add by ywc	       *(fb_ptr) &= 0xf0;		*(fb_ptr) |= pure_color;		}*/	return;}// 绘制一条垂直直线static void lcd_kernel_vline(int x, int y1, int y2, COLOR color){	int tmp; 	int i = 0;			  	// 如果起始点的y坐标大于终止点的y坐标, 则交换起始点和终止点	if (y1 > y2)	{		tmp = y1;		y1 = y2;		y2 = tmp;

⌨️ 快捷键说明

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