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

📄 lcd_drv.c

📁 一个模拟可种嵌入开发环境的模拟软件.能模拟ARM系列等.
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	// 计算两点的垂直距离	tmp = y2 - y1;	// 用点组成垂直的直线	for (i = 0; i <= tmp; i++ )	{ 		lcd_kernel_pixel(x, y1 + i,color);	}	return;}// 绘制一条水平直线static void lcd_kernel_hline(int x1, int x2, int y, COLOR color){       	int tmp;	int i = 0;	// 如果起始点的x坐标大于终止点的x坐标, 则交换起始点和终止点	if (x1 > x2)	{		tmp = x1;		x1 = x2;		x2 = tmp;	}	// 计算两点的水平距离	tmp = x2 - x1;	// 用点组成水平的直线	for (i = 0; i <= tmp; i++ )	{		lcd_kernel_pixel(x1 + i, y, color);	}	return;}// 绘制一个矩形边框// 边框左上角坐标为(start_x, start_y)// 边框右下角坐标为(end_x, end_y))static void lcd_kernel_rectangle(int start_x,int start_y,int end_x,int end_y,COLOR color){	lcd_kernel_vline(start_x, start_y, end_y, color);	/* 绘制左边框 */	lcd_kernel_vline(end_x, start_y, end_y, color);		/* 绘制右边框 */	lcd_kernel_hline(start_x, end_x, start_y, color);	/* 绘制上边框 */	lcd_kernel_hline(start_x, end_x, end_y, color);		/* 绘制下边框 */	return;}// 显示一个ASCII字符// codes为指定ASCII字符的8 x 16点阵数组static void lcd_kernel_text_en(int x, int y, unsigned char* codes, COLOR color){	int i, j;	// 显示8 x 16的点阵	for (i = 0;i < 16; i++)	{		// 移动x坐标至要显示的字符的右侧的边界上		x += 8;				// 从左向右显示一行点		for (j = 0; j < 8; j++)		{			// x坐标向左移一个像素			x--;			// 根据点阵信息显示一个指定颜色的点			if ((codes[i] >> j) & 0x1)			{				lcd_kernel_pixel(x, y, color);			}		}		// 开始显示新的一行, y坐标向下移一个像素		y++;	}	return;}// 显示一个中文字符// codes为指定中文字符的16 * 16点阵数组static void lcd_kernel_text_chs(int x, int y, unsigned char* codes, COLOR color){	int i, j, k;	// 显示16 * 16的点阵	for(i = 0;i < 16; i++)	{		// 循环两次, 		// 先显示字符的左半部分的一行, 		// 然后显示字符的右半部分的一行		for (j = 0; j < 2; j++)		{			// 计算x坐标的位置			// 左半部分的起始点为x + 8			// 右半部分的起始点为x + 16			x += 8 * ( j + 1);			// 从左向右显示左(右)半部分的一行			for (k = 0; k < 8; k++)			{				// x坐标向左移一个像素				x--;				// 根据点阵信息显示一个指定颜色的点				// codes[2 * i + j]计算行点阵在数组中的位置:				// 2 * i + 0 为左半部分的行点阵信息				// 2 * i + 1 为右半部分的行点阵信息				if ((codes[2 * i + j] >> k) & 0x1)				{					lcd_kernel_pixel(x,y,color);				}			}		}		// 开始显示新的一行, 		// x坐标回到原先位置, 		// y坐标向下移一个像素		x -= 8;		++y;	}	return;}// 用指定颜色清屏static void lcd_kernel_clear(COLOR color){	unsigned char buffer[3];	long i;        COLOR  pure_color;       printk("\nclear the screen to color '%d' !!!\n",color);       pure_color=color&0x0000f;       pure_color|=(color&0x000f)<<4;	// 根据像素点的位置, 设置相应的更新字节	// 以两个像素点为一组, 共三个字节//	buffer[0] = color & 0xff;  //green(M)+red(L)//	buffer[1] = ((color & 0xf00) >> 8) + ((color & 0x0f) << 4);//red(M)+blue(L)//	buffer[2] = color >> 4;//blue(M)+green(L)		// *(__lcd_base + i) = 0x11;//		*(__lcd_base + i) = buffer[i % 3];	// 更新显示缓冲区	//	for (i = 0; i < SCR_X * SCR_Y * 3 * BPP / 8; i++)	for (i = 0; i < SCR_X * SCR_Y * 1 * BPP / 8; i++){	     *(__lcd_base + i) = pure_color;         /*	if (i & 0x1)	        {	           pure_color = (color & 0x000f) << 4;            // add by ywc		   *(__lcd_base + i) &= 0x0f;			   *(__lcd_base + i) |= pure_color;                 }else{	           pure_color = (color & 0x000f);            // add by ywc		   *(__lcd_base + i) &= 0xf0;			   *(__lcd_base + i) |= pure_color;                 } */	}}// 打开LCD设备文件static int lcd_kernel_open(struct inode *node, struct file *file){	return 0;}// 对LCD设备文件进行读操作static int lcd_kernel_read(struct file *file, char *buff, size_t count, loff_t *offp){	return 0;}// 对LCD设备文件进行写操作static int lcd_kernel_write(struct file *file, const char *buff, size_t count, loff_t *offp){	return 0;}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// by ywc 2004-04-17  对LCD设备文件按字节进行写操作(应用程序无法通过write//调用到该函数???暂时没有找出原因,所以先通过ioctl复制位图缓冲到显存//static int lcd_kernel_writeb(struct file *file, const char *buff, size_t count, loff_t *offp)static int lcd_kernel_writeb(const char *buff, size_t count, int rownum){	  int i;          unsigned char * fb_ptr;         fb_ptr=(unsigned char *)__lcd_base;                // printk("\n!!!enter the lcd_kernel_writeb()");          for(i=0;i<count;i++){            //*(fb_ptr+20*rownum+i)=*(buff+i);	    *(fb_ptr+i)=*(buff+i);         }        return 0;}static int lcd_kernel_writew(const char *buff, size_t count, int rownum){	  int i;         // unsigned char * fb_ptr;	  unsigned long * fb_ptr_word;         fb_ptr_word=(unsigned long *)__lcd_base;                // printk("\n!!!enter the lcd_kernel_writeb()");          for(i=0;i<count/4;i++){            *(fb_ptr_word+i)=*((unsigned long *)buff+i);         }        return 0;}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 对LCD设备文件进行读写之外的其它操作static int lcd_kernel_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	// 根据指令ID, 调用相应的操作	switch (cmd) 	{		// 清屏		case LCD_Clear:		{			struct lcd_display clear_display;			// 复制显示结构			if (copy_from_user(&clear_display, (struct lcd_display*)arg, sizeof(struct lcd_display))) 			{				printk("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Clear!\n");				return -1;			}			// 调用清屏函数			lcd_kernel_clear(clear_display.color);			break;		}		// 绘制像素点		case LCD_Draw_Pixel:		{			struct lcd_display pixel_display;			// 复制显示结构			if ( copy_from_user(&pixel_display, (struct lcd_display*)arg, sizeof(struct lcd_display)))			{				printk("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Draw_Pixel!\n");				return -1;			}			// 调用画点函数			lcd_kernel_pixel(pixel_display.x1, pixel_display.y1, 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("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Draw_VLine!\n");				return -1;			}			// 调用画线函数			lcd_kernel_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("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Draw_HLine!\n");				return -1;			}				// 调用画线函数			lcd_kernel_hline(hline_display.x1, hline_display.x2, hline_display.y1, hline_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("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Draw_Rectangle!\n");                							return -1;			}			// 调用画矩形边框函数			lcd_kernel_rectangle(rect_display.x1, rect_display.y1, rect_display.x2, rect_display.y2, rect_display.color);			break;		}                                  //将位图缓冲区写入显存 add by ywc 2004-04-18		case LCD_Draw_Buf:		{			struct lcd_display buf_display;			// 复制显示结构			if ( copy_from_user(&buf_display, (struct lcd_display*)arg, sizeof(struct lcd_display)))			{				printk("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Draw_Buf!\n");				return -1;			}			//调用复制位图缓冲到显存的函数			//lcd_kernel_writeb(buf_display.lcd_buf, buf_display.lcd_buf_size,buf_display.lcd_row);			lcd_kernel_writew(buf_display.lcd_buf, buf_display.lcd_buf_size,buf_display.lcd_row);			break;		}              		// 显示一个ASCII字符		case LCD_Write_EN:		{			struct lcd_display en_display;			// 复制显示结构			if ( copy_from_user(&en_display, (struct lcd_display*)arg, sizeof(struct lcd_display)))			{				printk("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Write_EN!\n");                							return -1;			}			// 调用显示字符函数			lcd_kernel_text_en(en_display.x1, en_display.y1, en_display.codes, 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("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Write_EN!\n");                							return -1;			}			// 调用显示字符函数			lcd_kernel_text_chs(cn_display.x1, cn_display.y1, cn_display.codes, cn_display.color);						break;        		}		// 保存屏幕指定部分内容		case LCD_Save_SCR:		{			// 调用保存屏幕函数			lcd_kernel_save_screen((*(struct lcd_screen*)arg).x1, (*(struct lcd_screen*)arg).y1, 									(*(struct lcd_screen*)arg).x2, (*(struct lcd_screen*)arg).y2, 									(*(struct lcd_screen*)arg).buffer);						break;        		}		// 加载保存的屏幕内容到指定位置		case LCD_Load_SCR:		{			struct lcd_screen load_screen;			// 复制屏幕结构			if ( copy_from_user(&load_screen,(struct lcd_screen*)arg,sizeof(struct lcd_screen)))			{				printk("System: copy_from_user error!\n");				printk("Caller: lcd_kernel_ioctl -> LCD_Load_SCR!\n");                							return -1;			}			// 调用加载屏幕函数			lcd_kernel_load_screen(load_screen.x1, load_screen.y1, *load_screen.buffer);						break;        		}		// 释放保存的屏幕内容		case LCD_Release_SCR:		{			lcd_kernel_release_screen((*(struct lcd_screen*)arg).buffer);						break;        		}		default:			printk("Unknown LCD command ID.\n");	}	return 0;}// 释放LCD设备文件static int lcdexp_release(struct inode *node, struct file *file){	// 缓存基址复位 	__lcd_base = (unsigned char *)0xc0000000;	return 0;}// LCD设备文件操作结构static struct file_operations lcd_fops = {	open:           lcd_kernel_open,		/* 打开设备文件 */	read:           lcd_kernel_read,		/* 设备文件的读操作 */	ioctl:			lcd_kernel_ioctl,		/* 设备文件的其它操作 */	//write:          lcd_kernel_write,		/* 设备文件的写操作 */	write:          lcd_kernel_writeb,		/* 设备文件的写操作 */	release:        lcdexp_release,			/* 释放设备文件 */};// 初始化LCD设备static int __init lcd_kernel_init(void){	int result;			/* 注册设备结果 */	long i;	// 设置显示缓存基地址	__lcd_base = (unsigned char*)0xc0000000;	// 注册LCD系统设备	printk("\nRegistering LCD Device\t--->\t");	result = register_chrdev(DEV_MAJOR, "lcd_ep7312", &lcd_fops);	if (result < 0)	{		printk(KERN_INFO "[FAILED: Cannot register lcd_ep7312!]\n");		return -EBUSY;	}	else		printk("[OK]\n");	printk("Initializing LCD Device\t--->\t\n");	// 设置LCD 	setup_lcd();  //  printk(" \nsetup_lcd runing end !//y ywc");	    // 初始化显示缓冲区内容//	for (i=0; i < SCR_X * SCR_Y * 3 * BPP / 8; i++)/*	for (i=0; i < SCR_X * SCR_Y * 1* BPP / 8; i++)	{            *__lcd_base++ = 0x00;                     // *__lcd_base= 0x11;		  __lcd_base++;                      //   *(__lcd_base)&= 0xf0;//		 *(__lcd_base)|= 0x04;//		 *(__lcd_base)&= 0x0f;//		 *(__lcd_base)|= 0x40; //		 __lcd_base++;     		}*/	//printk("\n__lcd_base=%p,*__lcd_base=%x\n",--__lcd_base,*__lcd_base);		// 复位显存基地址	__lcd_base =(unsigned char*)0xc0000000;	//printk("\n__lcd_base=%x\n",__lcd_base);	printk("[OK]\n");	// 显示成功加载信息	printk("\nEP7312 LCD Driver installed.\n");//	printk("Written by BIT200009123.\n");	return 0;}// 释放LCD设备static void __exit lcd_kernel_exit(void){	// 注销LCD设备, 并释放保存屏幕缓冲区	printk("Unregistering LCD Device\t--->\t");	unregister_chrdev(DEV_MAJOR, "lcd_ep7312");	printk("[OK]\n");	return;}// 初始化模块module_init(lcd_kernel_init);// 卸载模块module_exit(lcd_kernel_exit);

⌨️ 快捷键说明

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