123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- /**
- * @file fbdev.c
- *
- */
- /*********************
- * INCLUDES
- *********************/
- #include "fbdev.h"
- #if USE_FBDEV
- #include <stdlib.h>
- #include <unistd.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <linux/fb.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include "lvgl/lv_core/lv_vdb.h"
- /*********************
- * DEFINES
- *********************/
- #ifndef FBDEV_PATH
- #define FBDEV_PATH "/dev/fb0"
- #endif
- /**********************
- * TYPEDEFS
- **********************/
- /**********************
- * STATIC PROTOTYPES
- **********************/
- /**********************
- * STATIC VARIABLES
- **********************/
- static struct fb_var_screeninfo vinfo;
- static struct fb_fix_screeninfo finfo;
- static char *fbp = 0;
- static long int screensize = 0;
- static int fbfd = 0;
- /**********************
- * MACROS
- **********************/
- /**********************
- * GLOBAL FUNCTIONS
- **********************/
- void fbdev_init(void)
- {
- // Open the file for reading and writing
- fbfd = open(FBDEV_PATH, O_RDWR);
- if (fbfd == -1) {
- perror("Error: cannot open framebuffer device");
- return;
- }
- printf("The framebuffer device was opened successfully.\n");
- // Get fixed screen information
- if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
- perror("Error reading fixed information");
- return;
- }
- // Get variable screen information
- if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
- perror("Error reading variable information");
- return;
- }
- printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
- // Figure out the size of the screen in bytes
- screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
- // Map the device to memory
- fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
- if ((int)fbp == -1) {
- perror("Error: failed to map framebuffer device to memory");
- return;
- }
- printf("The framebuffer device was mapped to memory successfully.\n");
- }
- /**
- * Flush a buffer to the marked area
- * @param x1 left coordinate
- * @param y1 top coordinate
- * @param x2 right coordinate
- * @param y2 bottom coordinate
- * @param color_p an array of colors
- */
- void fbdev_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
- {
- if(fbp == NULL) return;
- /*Return if the area is out the screen*/
- if(x2 < 0) return;
- if(y2 < 0) return;
- if(x1 > vinfo.xres - 1) return;
- if(y1 > vinfo.yres - 1) return;
- /*Truncate the area to the screen*/
- int32_t act_x1 = x1 < 0 ? 0 : x1;
- int32_t act_y1 = y1 < 0 ? 0 : y1;
- int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
- int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;
- long int location = 0;
- /*32 or 24 bit per pixel*/
- if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
- uint32_t *fbp32 = (uint32_t*)fbp;
- uint32_t x;
- uint32_t y;
- for(y = act_y1; y <= act_y2; y++) {
- for(x = act_x1; x <= act_x2; x++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp32[location] = color_p->full;
- color_p++;
- }
- color_p += x2 - act_x2;
- }
- }
- /*16 bit per pixel*/
- else if(vinfo.bits_per_pixel == 16) {
- uint16_t *fbp16 = (uint16_t*)fbp;
- uint32_t x;
- uint32_t y;
- for(y = act_y1; y <= act_y2; y++) {
- for(x = act_x1; x <= act_x2; x++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp16[location] = color_p->full;
- color_p++;
- }
- color_p += x2 - act_x2;
- }
- }
- /*8 bit per pixel*/
- else if(vinfo.bits_per_pixel == 8) {
- uint8_t *fbp8 = (uint8_t*)fbp;
- uint32_t x;
- uint32_t y;
- for(y = act_y1; y <= act_y2; y++) {
- for(x = act_x1; x <= act_x2; x++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp8[location] = color_p->full;
- color_p++;
- }
- color_p += x2 - act_x2;
- }
- } else {
- /*Not supported bit per pixel*/
- }
- //May be some direct update command is required
- //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
- lv_flush_ready();
- }
- /**
- * Fill out the marked area with a color
- * @param x1 left coordinate
- * @param y1 top coordinate
- * @param x2 right coordinate
- * @param y2 bottom coordinate
- * @param color fill color
- */
- void fbdev_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
- {
- if(fbp == NULL) return;
- /*Return if the area is out the screen*/
- if(x2 < 0) return;
- if(y2 < 0) return;
- if(x1 > vinfo.xres - 1) return;
- if(y1 > vinfo.yres - 1) return;
- /*Truncate the area to the screen*/
- int32_t act_x1 = x1 < 0 ? 0 : x1;
- int32_t act_y1 = y1 < 0 ? 0 : y1;
- int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
- int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;
- uint32_t x;
- uint32_t y;
- long int location = 0;
- /*32 or 24 bit per pixel*/
- if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
- uint32_t *fbp32 = (uint32_t*)fbp;
- for(x = act_x1; x <= act_x2; x++) {
- for(y = act_y1; y <= act_y2; y++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp32[location] = color.full;
- }
- }
- }
- else if(vinfo.bits_per_pixel == 16) {
- uint16_t *fbp16 = (uint16_t*)fbp;
- for(x = act_x1; x <= act_x2; x++) {
- for(y = act_y1; y <= act_y2; y++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp16[location] = color.full;
- }
- }
- }
- else if(vinfo.bits_per_pixel == 8) {
- uint8_t *fbp8 = (uint8_t*)fbp;
- for(x = act_x1; x <= act_x2; x++) {
- for(y = act_y1; y <= act_y2; y++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp8[location] = color.full;
- }
- }
- } else {
- /*Not supported bit per pixel*/
- }
- //May be some direct update command is required
- //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
- }
- /**
- * Put a color map to the marked area
- * @param x1 left coordinate
- * @param y1 top coordinate
- * @param x2 right coordinate
- * @param y2 bottom coordinate
- * @param color_p an array of colors
- */
- void fbdev_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
- {
- if(fbp == NULL) return;
- /*Return if the area is out the screen*/
- if(x2 < 0) return;
- if(y2 < 0) return;
- if(x1 > vinfo.xres - 1) return;
- if(y1 > vinfo.yres - 1) return;
- /*Truncate the area to the screen*/
- int32_t act_x1 = x1 < 0 ? 0 : x1;
- int32_t act_y1 = y1 < 0 ? 0 : y1;
- int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
- int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;
- long int location = 0;
- /*32 or 24 bit per pixel*/
- if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
- uint32_t *fbp32 = (uint32_t*)fbp;
- uint32_t x;
- uint32_t y;
- for(y = act_y1; y <= act_y2; y++) {
- for(x = act_x1; x <= act_x2; x++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp32[location] = color_p->full;
- color_p++;
- }
- color_p += x2 - act_x2;
- }
- }
- /*16 bit per pixel*/
- else if(vinfo.bits_per_pixel == 16) {
- uint16_t *fbp16 = (uint16_t*)fbp;
- uint32_t x;
- uint32_t y;
- for(y = act_y1; y <= act_y2; y++) {
- for(x = act_x1; x <= act_x2; x++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp16[location] = color_p->full;
- color_p++;
- }
- color_p += x2 - act_x2;
- }
- }
- /*8 bit per pixel*/
- else if(vinfo.bits_per_pixel == 8) {
- uint8_t *fbp8 = (uint8_t*)fbp;
- uint32_t x;
- uint32_t y;
- for(y = act_y1; y <= act_y2; y++) {
- for(x = act_x1; x <= act_x2; x++) {
- location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
- fbp8[location] = color_p->full;
- color_p++;
- }
- color_p += x2 - act_x2;
- }
- } else {
- /*Not supported bit per pixel*/
- }
- //May be some direct update command is required
- //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
- }
- /**********************
- * STATIC FUNCTIONS
- **********************/
- #endif
|