lv_port_disp.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-10-18 Meco Man The first version
  9. */
  10. #include <lvgl.h>
  11. #include <drv_clcd.h>
  12. /*A static or global variable to store the buffers*/
  13. static lv_disp_draw_buf_t disp_buf;
  14. rt_device_t lcd_device = 0;
  15. static struct rt_device_graphic_info info;
  16. static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
  17. typedef struct
  18. {
  19. uint8_t blue;
  20. uint8_t green;
  21. uint8_t red;
  22. } lv_color24_t;
  23. static void color_to16_maybe(lv_color16_t *dst, lv_color_t *src)
  24. {
  25. #if (LV_COLOR_DEPTH == 16)
  26. dst->full = src->full;
  27. #else
  28. dst->ch.blue = src->ch.blue;
  29. dst->ch.green = src->ch.green;
  30. dst->ch.red = src->ch.red;
  31. #endif
  32. }
  33. static void color_to24(lv_color24_t *dst, lv_color_t *src)
  34. {
  35. dst->blue = src->ch.blue;
  36. dst->green = src->ch.green;
  37. dst->red = src->ch.red;
  38. }
  39. /*Flush the content of the internal buffer the specific area on the display
  40. *You can use DMA or any hardware acceleration to do this operation in the background but
  41. *'lv_disp_flush_ready()' has to be called when finished.*/
  42. static void lcd_fb_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
  43. {
  44. int x1, x2, y1, y2;
  45. x1 = area->x1;
  46. x2 = area->x2;
  47. y1 = area->y1;
  48. y2 = area->y2;
  49. /*Return if the area is out the screen*/
  50. if (x2 < 0)
  51. return;
  52. if (y2 < 0)
  53. return;
  54. if (x1 > info.width - 1)
  55. return;
  56. if (y1 > info.height - 1)
  57. return;
  58. /*Truncate the area to the screen*/
  59. int32_t act_x1 = x1 < 0 ? 0 : x1;
  60. int32_t act_y1 = y1 < 0 ? 0 : y1;
  61. int32_t act_x2 = x2 > info.width - 1 ? info.width - 1 : x2;
  62. int32_t act_y2 = y2 > info.height - 1 ? info.height - 1 : y2;
  63. uint32_t x;
  64. uint32_t y;
  65. long int location = 0;
  66. /* 8 bit per pixel */
  67. if (info.bits_per_pixel == 8)
  68. {
  69. uint8_t *fbp8 = (uint8_t *)info.framebuffer;
  70. //TODO color convert maybe
  71. for (y = act_y1; y <= act_y2; y++)
  72. {
  73. for (x = act_x1; x <= act_x2; x++)
  74. {
  75. location = (x) + (y)*info.width;
  76. fbp8[location] = color_p->full;
  77. color_p++;
  78. }
  79. color_p += x2 - act_x2;
  80. }
  81. }
  82. /* 16 bit per pixel */
  83. else if (info.bits_per_pixel == 16)
  84. {
  85. lv_color16_t *fbp16 = (lv_color16_t *)info.framebuffer;
  86. for (y = act_y1; y <= act_y2; y++)
  87. {
  88. for (x = act_x1; x <= act_x2; x++)
  89. {
  90. location = (x) + (y)*info.width;
  91. color_to16_maybe(&fbp16[location], color_p);
  92. color_p++;
  93. }
  94. color_p += x2 - act_x2;
  95. }
  96. }
  97. /* 24 bit per pixel */
  98. else if (info.bits_per_pixel == 24)
  99. {
  100. lv_color24_t *fbp24 = (lv_color24_t *)info.framebuffer;
  101. for (y = act_y1; y <= act_y2; y++)
  102. {
  103. for (x = act_x1; x <= act_x2; x++)
  104. {
  105. location = (x) + (y)*info.width;
  106. color_to24(&fbp24[location], color_p);
  107. color_p++;
  108. }
  109. color_p += x2 - act_x2;
  110. }
  111. }
  112. /* 32 bit per pixel */
  113. else if (info.bits_per_pixel == 32)
  114. {
  115. uint32_t *fbp32 = (uint32_t *)info.framebuffer;
  116. //TODO
  117. for (y = act_y1; y <= act_y2; y++)
  118. {
  119. for (x = act_x1; x <= act_x2; x++)
  120. {
  121. location = (x) + (y)*info.width;
  122. fbp32[location] = color_p->full;
  123. color_p++;
  124. }
  125. color_p += x2 - act_x2;
  126. }
  127. }
  128. struct rt_device_rect_info rect_info;
  129. rect_info.x = x1;
  130. rect_info.y = y1;
  131. rect_info.width = x2 - x1 + 1;
  132. rect_info.height = y2 - y1 + 1;
  133. rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
  134. lv_disp_flush_ready(disp_drv);
  135. }
  136. void lv_port_disp_init(void)
  137. {
  138. rt_err_t result;
  139. lv_color_t *fbuf;
  140. lcd_device = rt_device_find("lcd");
  141. if (lcd_device == 0)
  142. {
  143. rt_kprintf("error!\n");
  144. return;
  145. }
  146. result = rt_device_open(lcd_device, 0);
  147. if (result != RT_EOK)
  148. {
  149. rt_kprintf("error!\n");
  150. return;
  151. }
  152. /* get framebuffer address */
  153. result = rt_device_control(lcd_device, RTGRAPHIC_CTRL_GET_INFO, &info);
  154. if (result != RT_EOK)
  155. {
  156. rt_kprintf("error!\n");
  157. /* get device information failed */
  158. return;
  159. }
  160. RT_ASSERT(info.bits_per_pixel == 8 || info.bits_per_pixel == 16 ||
  161. info.bits_per_pixel == 24 || info.bits_per_pixel == 32);
  162. fbuf = rt_malloc(info.width * info.height / 10);
  163. if (!fbuf)
  164. {
  165. rt_kprintf("Error: alloc disp buf fail\n");
  166. return;
  167. }
  168. /*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
  169. lv_disp_draw_buf_init(&disp_buf, fbuf, RT_NULL, info.width * 10);
  170. lv_disp_drv_init(&disp_drv); /*Basic initialization*/
  171. /*Set the resolution of the display*/
  172. disp_drv.hor_res = info.width;
  173. disp_drv.ver_res = info.height;
  174. /*Set a display buffer*/
  175. disp_drv.draw_buf = &disp_buf;
  176. /*Used to copy the buffer's content to the display*/
  177. disp_drv.flush_cb = lcd_fb_flush;
  178. /*Finally register the driver*/
  179. lv_disp_drv_register(&disp_drv);
  180. }