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

📄 lcd.c

📁 linux 基于frambuffer 的lcd 驱动
💻 C
字号:
/*
 * $Id: fv.c
 * $Desp: draw jpeg to framebuffer
 * $Author: rockins
 * $Date: Wed Jan  3 20:15:49 CST 2007
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <jpeglib.h>
#include <jerror.h>

#define	FB_DEV	"/dev/fb0"
//TFT 240320
#define SCR_XSIZE_TFT_240320 	(640)
#define SCR_YSIZE_TFT_240320 	(480)
#define C_UP		( LCD_XSIZE_TFT_240320 - LCD_BLANK*2 )
#define C_RIGHT		( LCD_XSIZE_TFT_240320 - LCD_BLANK*2 )
#define V_BLACK		( ( LCD_YSIZE_TFT_240320 - LCD_BLANK*4 ) / 6 )
//TFT 240320
#define LCD_XSIZE_TFT_240320 	(240)	
#define LCD_YSIZE_TFT_240320 	(320)
#define LCD_BLANK		16
#define C_UP		( LCD_XSIZE_TFT_240320 - LCD_BLANK*2 )
#define C_RIGHT		( LCD_XSIZE_TFT_240320 - LCD_BLANK*2 )
#define V_BLACK		( ( LCD_YSIZE_TFT_240320 - LCD_BLANK*4 ) / 6 )
/***************** function declaration ******************/
void            usage(char *msg);
unsigned short  RGB888toRGB565(unsigned char red,
							   unsigned char green, unsigned char blue);
int             fb_open(char *fb_device);
int             fb_close(int fd);
int             fb_stat(int fd, int *width, int *height, int *depth);
void           *fb_mmap(int fd, unsigned int screensize);
int             fb_munmap(void *start, size_t length);
int             fb_pixel(void *fbmem, int width, int height,
						 int x, int y, unsigned short color);
volatile static unsigned short LCD_BUFER[SCR_YSIZE_TFT_240320][SCR_XSIZE_TFT_240320];
/************ function implementation ********************/
int
main(int argc, char *argv[])
{
	
	unsigned char  *buffer;

	/*
	 * declaration for framebuffer device
	 */
	int             fbdev;
	char           *fb_device;
	unsigned char  *fbmem;
	unsigned int    screensize;
	unsigned int    fb_width;
	unsigned int    fb_height;
	unsigned int    fb_depth;
	unsigned int    x;
	unsigned int    y;

	
	/*
	 * open framebuffer device
	 */
	if ((fb_device = getenv("FRAMEBUFFER")) == NULL)
		fb_device = FB_DEV;
	fbdev = fb_open(fb_device);

	/*
	 * get status of framebuffer device
	 */
	fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);

	/*
	 * map framebuffer device to shared memory
	 */
	screensize = fb_width * fb_height * fb_depth / 8;
	fbmem = fb_mmap(fbdev, screensize);
    *fbmem=&LCD_BUFER[0][0];
	
Glib_FilledRectangle( LCD_BLANK, LCD_BLANK, ( LCD_XSIZE_TFT_240320 - LCD_BLANK ), ( LCD_YSIZE_TFT_240320 - LCD_BLANK ),0x0000);		//fill a Rectangle with some color
Glib_FilledRectangle( (LCD_BLANK*2), (LCD_BLANK*2 + V_BLACK*0), (C_RIGHT), (LCD_BLANK*2 + V_BLACK*1),0x001f);		//fill a Rectangle with some color
Glib_FilledRectangle( (LCD_BLANK*2), (LCD_BLANK*2 + V_BLACK*1), (C_RIGHT), (LCD_BLANK*2 + V_BLACK*2),0x07e0);		//fill a Rectangle with some color
Glib_FilledRectangle( (LCD_BLANK*2), (LCD_BLANK*2 + V_BLACK*2), (C_RIGHT), (LCD_BLANK*2 + V_BLACK*3),0xf800);		//fill a Rectangle with some color
Glib_FilledRectangle( (LCD_BLANK*2), (LCD_BLANK*2 + V_BLACK*3), (C_RIGHT), (LCD_BLANK*2 + V_BLACK*4),0xffe0);		//fill a Rectangle with some color
Glib_FilledRectangle( (LCD_BLANK*2), (LCD_BLANK*2 + V_BLACK*4), (C_RIGHT), (LCD_BLANK*2 + V_BLACK*5),0xf81f);		//fill a Rectangle with some color
Glib_FilledRectangle( (LCD_BLANK*2), (LCD_BLANK*2 + V_BLACK*5), (C_RIGHT), (LCD_BLANK*2 + V_BLACK*6),0x07ff);		//fill a Rectangle with some color
 
	
   /*
	buffer = (unsigned char *) malloc(cinfo.output_width *
									  cinfo.output_components);
	y = 0;
	while (cinfo.output_scanline < cinfo.output_height) {
		jpeg_read_scanlines(&cinfo, &buffer, 1);
		if (fb_depth == 16) {
			unsigned short  color;
			for (x = 0; x < cinfo.output_width; x++) {
				color = RGB888toRGB565(buffer[x * 3], 
						buffer[x * 3 + 1], buffer[x * 3 + 2]);
				fb_pixel(fbmem, fb_width, fb_height, x, y, color);
			}
		} else if (fb_depth == 24) {
			memcpy((unsigned char *) fbmem + y * fb_width * 3,
				   buffer, cinfo.output_width * cinfo.output_components);
		}
		y++;					// next scanline
	}

	
	/*
	 * release memory buffer
	 */
	free(buffer);
	/*
	 * unmap framebuffer's shared memory
	 */
	fb_munmap(fbmem, screensize);

	/*
	 * close framebuffer device
	 */
	fb_close(fbdev);

	return (0);
}

/**************************************************************
??LCD????????????????????????
**************************************************************/
static void Glib_FilledRectangle(int x1,int y1,int x2,int y2,int color)
{
    int i;

    for(i=y1;i<=y2;i++)
	Glib_Line(x1,i,x2,i,color);
}
/**************************************************************
LCD???????????±·?×?
// LCD display is flipped vertically
// But, think the algorithm by mathematics point.
//   3I2
//   4 I 1
//  --+--   <-8 octants  mathematical cordinate
//   5 I 8
//   6I7
**************************************************************/
static void Glib_Line(int x1,int y1,int x2,int y2,int color)
{
	int dx,dy,e;
	dx=x2-x1; 
	dy=y2-y1;
    
	if(dx>=0)
	{
		if(dy >= 0) // dy>=0
		{
			if(dx>=dy) // 1/8 octant
			{
				e=dy-dx/2;
				while(x1<=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1+=1;e-=dx;}	
					x1+=1;
					e+=dy;
				}
			}
			else		// 2/8 octant
			{
				e=dx-dy/2;
				while(y1<=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1+=1;e-=dy;}	
					y1+=1;
					e+=dx;
				}
			}
		}
		else		   // dy<0
		{
			dy=-dy;   // dy=abs(dy)

			if(dx>=dy) // 8/8 octant
			{
				e=dy-dx/2;
				while(x1<=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1-=1;e-=dx;}	
					x1+=1;
					e+=dy;
				}
			}
			else		// 7/8 octant
			{
				e=dx-dy/2;
				while(y1>=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1+=1;e-=dy;}	
					y1-=1;
					e+=dx;
				}
			}
		}	
	}
	else //dx<0
	{
		dx=-dx;		//dx=abs(dx)
		if(dy >= 0) // dy>=0
		{
			if(dx>=dy) // 4/8 octant
			{
				e=dy-dx/2;
				while(x1>=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1+=1;e-=dx;}	
					x1-=1;
					e+=dy;
				}
			}
			else		// 3/8 octant
			{
				e=dx-dy/2;
				while(y1<=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1-=1;e-=dy;}	
					y1+=1;
					e+=dx;
				}
			}
		}
		else		   // dy<0
		{
			dy=-dy;   // dy=abs(dy)

			if(dx>=dy) // 5/8 octant
			{
				e=dy-dx/2;
				while(x1>=x2)
				{
					PutPixel(x1,y1,color);
					if(e>0){y1-=1;e-=dx;}	
					x1-=1;
					e+=dy;
				}
			}
			else		// 6/8 octant
			{
				e=dx-dy/2;
				while(y1>=y2)
				{
					PutPixel(x1,y1,color);
					if(e>0){x1-=1;e-=dy;}	
					y1-=1;
					e+=dx;
				}
			}
		}	
	}
}

/**************************************************************
320??240 16Bpp TFT LCD?????ó????????????????
**************************************************************/
static void PutPixel(U32 x,U32 y,U32 c)
{
	if ( (x < SCR_XSIZE_TFT_240320) && (y < SCR_YSIZE_TFT_240320) )
	LCD_BUFER[(y)][(x)] = c;
}






/*
 * open framebuffer device.
 * return positive file descriptor if success,
 * else return -1.
 */
int
fb_open(char *fb_device)
{
	int             fd;

	if ((fd = open(fb_device, O_RDWR)) < 0) {
		perror(__func__);
		return (-1);
	}
	return (fd);
}

/*
 * get framebuffer's width,height,and depth.
 * return 0 if success, else return -1.
 */
int
fb_stat(int fd, int *width, int *height, int *depth)
{
	struct fb_fix_screeninfo fb_finfo;
	struct fb_var_screeninfo fb_vinfo;

	if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
		perror(__func__);
		return (-1);
	}

	if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
		perror(__func__);
		return (-1);
	}

	*width = fb_vinfo.xres;
	*height = fb_vinfo.yres;
	*depth = fb_vinfo.bits_per_pixel;

	return (0);
}

/*
 * map shared memory to framebuffer device.
 * return maped memory if success,
 * else return -1, as mmap dose.
 */
void           *
fb_mmap(int fd, unsigned int screensize)
{
	caddr_t         fbmem;

	if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,
					  MAP_SHARED, fd, 0)) == MAP_FAILED) {
		perror(__func__);
		return (void *) (-1);
	}

	return (fbmem);
}

/*
 * unmap map memory for framebuffer device.
 */
int
fb_munmap(void *start, size_t length)
{
	return (munmap(start, length));
}

/*
 * close framebuffer device
 */
int
fb_close(int fd)
{
	return (close(fd));
}

/*
 * display a pixel on the framebuffer device.
 * fbmem is the starting memory of framebuffer,
 * width and height are dimension of framebuffer,
 * x and y are the coordinates to display,
 * color is the pixel's color value.
 * return 0 if success, otherwise return -1.
 */
int
fb_pixel(void *fbmem, int width, int height,
		 int x, int y, unsigned short color)
{
	if ((x > width) || (y > height))
		return (-1);

	unsigned short *dst = ((unsigned short *) fbmem + y * width + x);

	*dst = color;
	return (0);
}

⌨️ 快捷键说明

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