fbdev.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /**
  2. * @file fbdev.c
  3. *
  4. */
  5. /*********************
  6. * INCLUDES
  7. *********************/
  8. #include "fbdev.h"
  9. #if USE_FBDEV
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include <stddef.h>
  13. #include <stdio.h>
  14. #include <fcntl.h>
  15. #include <linux/fb.h>
  16. #include <sys/mman.h>
  17. #include <sys/ioctl.h>
  18. #include "lvgl/lv_core/lv_vdb.h"
  19. /*********************
  20. * DEFINES
  21. *********************/
  22. #ifndef FBDEV_PATH
  23. #define FBDEV_PATH "/dev/fb0"
  24. #endif
  25. /**********************
  26. * TYPEDEFS
  27. **********************/
  28. /**********************
  29. * STATIC PROTOTYPES
  30. **********************/
  31. /**********************
  32. * STATIC VARIABLES
  33. **********************/
  34. static struct fb_var_screeninfo vinfo;
  35. static struct fb_fix_screeninfo finfo;
  36. static char *fbp = 0;
  37. static long int screensize = 0;
  38. static int fbfd = 0;
  39. /**********************
  40. * MACROS
  41. **********************/
  42. /**********************
  43. * GLOBAL FUNCTIONS
  44. **********************/
  45. void fbdev_init(void)
  46. {
  47. // Open the file for reading and writing
  48. fbfd = open(FBDEV_PATH, O_RDWR);
  49. if (fbfd == -1) {
  50. perror("Error: cannot open framebuffer device");
  51. return;
  52. }
  53. printf("The framebuffer device was opened successfully.\n");
  54. // Get fixed screen information
  55. if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
  56. perror("Error reading fixed information");
  57. return;
  58. }
  59. // Get variable screen information
  60. if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
  61. perror("Error reading variable information");
  62. return;
  63. }
  64. printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
  65. // Figure out the size of the screen in bytes
  66. screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
  67. // Map the device to memory
  68. fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
  69. if ((int)fbp == -1) {
  70. perror("Error: failed to map framebuffer device to memory");
  71. return;
  72. }
  73. printf("The framebuffer device was mapped to memory successfully.\n");
  74. }
  75. /**
  76. * Flush a buffer to the marked area
  77. * @param x1 left coordinate
  78. * @param y1 top coordinate
  79. * @param x2 right coordinate
  80. * @param y2 bottom coordinate
  81. * @param color_p an array of colors
  82. */
  83. void fbdev_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
  84. {
  85. if(fbp == NULL) return;
  86. /*Return if the area is out the screen*/
  87. if(x2 < 0) return;
  88. if(y2 < 0) return;
  89. if(x1 > vinfo.xres - 1) return;
  90. if(y1 > vinfo.yres - 1) return;
  91. /*Truncate the area to the screen*/
  92. int32_t act_x1 = x1 < 0 ? 0 : x1;
  93. int32_t act_y1 = y1 < 0 ? 0 : y1;
  94. int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
  95. int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;
  96. long int location = 0;
  97. /*32 or 24 bit per pixel*/
  98. if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
  99. uint32_t *fbp32 = (uint32_t*)fbp;
  100. uint32_t x;
  101. uint32_t y;
  102. for(y = act_y1; y <= act_y2; y++) {
  103. for(x = act_x1; x <= act_x2; x++) {
  104. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  105. fbp32[location] = color_p->full;
  106. color_p++;
  107. }
  108. color_p += x2 - act_x2;
  109. }
  110. }
  111. /*16 bit per pixel*/
  112. else if(vinfo.bits_per_pixel == 16) {
  113. uint16_t *fbp16 = (uint16_t*)fbp;
  114. uint32_t x;
  115. uint32_t y;
  116. for(y = act_y1; y <= act_y2; y++) {
  117. for(x = act_x1; x <= act_x2; x++) {
  118. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  119. fbp16[location] = color_p->full;
  120. color_p++;
  121. }
  122. color_p += x2 - act_x2;
  123. }
  124. }
  125. /*8 bit per pixel*/
  126. else if(vinfo.bits_per_pixel == 8) {
  127. uint8_t *fbp8 = (uint8_t*)fbp;
  128. uint32_t x;
  129. uint32_t y;
  130. for(y = act_y1; y <= act_y2; y++) {
  131. for(x = act_x1; x <= act_x2; x++) {
  132. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  133. fbp8[location] = color_p->full;
  134. color_p++;
  135. }
  136. color_p += x2 - act_x2;
  137. }
  138. } else {
  139. /*Not supported bit per pixel*/
  140. }
  141. //May be some direct update command is required
  142. //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
  143. lv_flush_ready();
  144. }
  145. /**
  146. * Fill out the marked area with a color
  147. * @param x1 left coordinate
  148. * @param y1 top coordinate
  149. * @param x2 right coordinate
  150. * @param y2 bottom coordinate
  151. * @param color fill color
  152. */
  153. void fbdev_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
  154. {
  155. if(fbp == NULL) return;
  156. /*Return if the area is out the screen*/
  157. if(x2 < 0) return;
  158. if(y2 < 0) return;
  159. if(x1 > vinfo.xres - 1) return;
  160. if(y1 > vinfo.yres - 1) return;
  161. /*Truncate the area to the screen*/
  162. int32_t act_x1 = x1 < 0 ? 0 : x1;
  163. int32_t act_y1 = y1 < 0 ? 0 : y1;
  164. int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
  165. int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;
  166. uint32_t x;
  167. uint32_t y;
  168. long int location = 0;
  169. /*32 or 24 bit per pixel*/
  170. if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
  171. uint32_t *fbp32 = (uint32_t*)fbp;
  172. for(x = act_x1; x <= act_x2; x++) {
  173. for(y = act_y1; y <= act_y2; y++) {
  174. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  175. fbp32[location] = color.full;
  176. }
  177. }
  178. }
  179. else if(vinfo.bits_per_pixel == 16) {
  180. uint16_t *fbp16 = (uint16_t*)fbp;
  181. for(x = act_x1; x <= act_x2; x++) {
  182. for(y = act_y1; y <= act_y2; y++) {
  183. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  184. fbp16[location] = color.full;
  185. }
  186. }
  187. }
  188. else if(vinfo.bits_per_pixel == 8) {
  189. uint8_t *fbp8 = (uint8_t*)fbp;
  190. for(x = act_x1; x <= act_x2; x++) {
  191. for(y = act_y1; y <= act_y2; y++) {
  192. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  193. fbp8[location] = color.full;
  194. }
  195. }
  196. } else {
  197. /*Not supported bit per pixel*/
  198. }
  199. //May be some direct update command is required
  200. //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
  201. }
  202. /**
  203. * Put a color map to the marked area
  204. * @param x1 left coordinate
  205. * @param y1 top coordinate
  206. * @param x2 right coordinate
  207. * @param y2 bottom coordinate
  208. * @param color_p an array of colors
  209. */
  210. void fbdev_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
  211. {
  212. if(fbp == NULL) return;
  213. /*Return if the area is out the screen*/
  214. if(x2 < 0) return;
  215. if(y2 < 0) return;
  216. if(x1 > vinfo.xres - 1) return;
  217. if(y1 > vinfo.yres - 1) return;
  218. /*Truncate the area to the screen*/
  219. int32_t act_x1 = x1 < 0 ? 0 : x1;
  220. int32_t act_y1 = y1 < 0 ? 0 : y1;
  221. int32_t act_x2 = x2 > vinfo.xres - 1 ? vinfo.xres - 1 : x2;
  222. int32_t act_y2 = y2 > vinfo.yres - 1 ? vinfo.yres - 1 : y2;
  223. long int location = 0;
  224. /*32 or 24 bit per pixel*/
  225. if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
  226. uint32_t *fbp32 = (uint32_t*)fbp;
  227. uint32_t x;
  228. uint32_t y;
  229. for(y = act_y1; y <= act_y2; y++) {
  230. for(x = act_x1; x <= act_x2; x++) {
  231. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  232. fbp32[location] = color_p->full;
  233. color_p++;
  234. }
  235. color_p += x2 - act_x2;
  236. }
  237. }
  238. /*16 bit per pixel*/
  239. else if(vinfo.bits_per_pixel == 16) {
  240. uint16_t *fbp16 = (uint16_t*)fbp;
  241. uint32_t x;
  242. uint32_t y;
  243. for(y = act_y1; y <= act_y2; y++) {
  244. for(x = act_x1; x <= act_x2; x++) {
  245. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  246. fbp16[location] = color_p->full;
  247. color_p++;
  248. }
  249. color_p += x2 - act_x2;
  250. }
  251. }
  252. /*8 bit per pixel*/
  253. else if(vinfo.bits_per_pixel == 8) {
  254. uint8_t *fbp8 = (uint8_t*)fbp;
  255. uint32_t x;
  256. uint32_t y;
  257. for(y = act_y1; y <= act_y2; y++) {
  258. for(x = act_x1; x <= act_x2; x++) {
  259. location = (x+vinfo.xoffset) + (y+vinfo.yoffset) * vinfo.xres;
  260. fbp8[location] = color_p->full;
  261. color_p++;
  262. }
  263. color_p += x2 - act_x2;
  264. }
  265. } else {
  266. /*Not supported bit per pixel*/
  267. }
  268. //May be some direct update command is required
  269. //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
  270. }
  271. /**********************
  272. * STATIC FUNCTIONS
  273. **********************/
  274. #endif