📄 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 + -