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

📄 lcd_drv_org.c

📁 一个模拟可种嵌入开发环境的模拟软件.能模拟ARM系列等.
💻 C
📖 第 1 页 / 共 2 页
字号:
	         *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;
	}

	// 计算两点的垂直距离
	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;
}

// 对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;
		}         
        
		// 显示一个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,		/* 设备文件的写操作 */
	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 + -