| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- #include "lcd_drv.h"
- #include "io.h"
- #include "elog.h"
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <linux/fb.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #define BACKLIGHT_GPIO_NUM 98
- static int fd_fb = 0 ;
- static struct fb_var_screeninfo var;
- static unsigned char *fb_base;
- static unsigned int line_width;
- static unsigned int pixel_width;
- static int screen_size;
- /// @brief 初始化LCD
- /// @param
- /// @return
- int lcd_init(void)
- {
- //打开背光
- //初始化IO
- io_init(BACKLIGHT_GPIO_NUM);
- //设置输出
- io_set_dir(BACKLIGHT_GPIO_NUM,1);
- //拉高
- io_set_value(BACKLIGHT_GPIO_NUM,1);
- fd_fb = open("/dev/fb0", O_RDWR);
- if (fd_fb < 0) {
- log_e("Can't open /dev/fb0\n");
- return -1;
- }
- if(ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)) {
- log_e("Can't get var\n");
- return -1;
- }
- line_width = var.xres * var.bits_per_pixel / 8; // 一行多少byte
- pixel_width = var.bits_per_pixel / 8; // 一个像素多少byte
- screen_size = var.xres * var.yres * var.bits_per_pixel / 8; // 一屏多少byte
- fb_base = (unsigned char*)mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
- if (fb_base == (unsigned char*)MAP_FAILED) {
- log_e("Can't mmap\n");
- return -1;
- }
- //清屏为黑色 0x00 黑色 0xFF 白色
- memset(fb_base, 0x00, screen_size);
- return 0;
- }
- /// @brief 释放LCD接口
- /// @param
- /// @return
- int lcd_deinit(void)
- {
- munmap(fb_base , screen_size);
- close(fd_fb);
- io_set_dir(BACKLIGHT_GPIO_NUM,0);
- io_set_value(BACKLIGHT_GPIO_NUM,0);
- io_deinit(BACKLIGHT_GPIO_NUM);
- return 0;
- }
- /// @brief 画点
- /// @param x
- /// @param y
- /// @param color
- void lcd_put_pixel(int x, int y, unsigned int color)
- {
- unsigned char *pen_8 = fb_base + y * line_width + x * pixel_width;
- unsigned short *pen_16;
- unsigned int *pen_32;
- unsigned int red, green, blue;
-
- pen_16 = (unsigned short *)pen_8;
- pen_32 = (unsigned int *)pen_8;
- switch(var.bits_per_pixel) { /* bpp 像素深度 */
- case 8:
- {
- *pen_8 = color;
- break;
- }
- case 16:
- {
- /* RGB565 */
- red = (color >> 16) & 0xFF;
- green = (color >> 8) & 0xFF;
- blue = (color >> 0) & 0xFF;
- color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
- *pen_16 = color;
- break;
- }
- case 32:
- {
- /* RGB888 */
- *pen_32 = color;
- break;
- }
- default:
- {
- log_e("Can't support %d bpp\n", var.bits_per_pixel);
- break;
- }
- }
- }
- #if 0
- /// @brief 绘制字符 在LCD指定位置上显示一个8*16的字符
- /// @param x
- /// @param y
- /// @param c
- /// @param color
- void lcd_put_ascii(int x, int y, unsigned char c, int color)
- {
- unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
- int i, b;
- unsigned char byte;
- for (i = 0; i < 16; i++)
- {
- byte = dots[i];
- for (b = 7; b >= 0; b--)
- {
- if (byte & (1<<b))
- {
- /* show */
- lcd_put_pixel(x+7-b, y+i, color); /* 白 */
- }
- else
- {
- /* hide */
- lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */
- }
- }
- }
- }
- /// @brief 在指定位置显示字符串
- /// @param x
- /// @param y
- /// @param string
- /// @param color
- void lcd_show_string(int x, int y, unsigned char *string, int color)
- {
- int string_len = strlen(string);
- int string_x = x;
- int string_y = y;
- for(int i = 0; i < string_len; i++)
- {
- if(string[i] == '\n')
- {
- string_y += 18;
- string_x = 0;
- if(string_y > var.yres)
- {
- return ;
- }
- }
- else
- {
- lcd_put_ascii(string_x, string_y, string[i], color);
- string_x += 8;
- if(string_x > var.xres)
- {
- string_x = 0;
- string_y += 18;
- if(string_y > var.yres)
- {
- return ;
- }
- }
- }
-
- }
- }
- /// @brief 显示中文
- /// @param x
- /// @param y
- /// @param str
- /// @param color
- void lcd_put_chinese(int x, int y, unsigned char *str, unsigned int color)
- {
- unsigned int area = str[0] - 0xA1;
- unsigned int where = str[1] - 0xA1;
- unsigned char *dots = hzkmem + (area * 94 + where)*32;
- unsigned char byte;
- int i, j, b;
- for (i = 0; i < 16; i++)
- for (j = 0; j < 2; j++)
- {
- byte = dots[i*2 + j];
- for (b = 7; b >=0; b--)
- {
- if (byte & (1<<b))
- {
- /* show */
- lcd_put_pixel(x+j*8+7-b, y+i, color); /* 白 */
- }
- else
- {
- /* hide */
- lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */
- }
- }
- }
- }
- #endif
|