1 /*
2 * Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <lvgl.h>
9 #include "lvgl_display.h"
10
lvgl_flush_cb_mono(lv_disp_drv_t * disp_drv,const lv_area_t * area,lv_color_t * color_p)11 void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv,
12 const lv_area_t *area, lv_color_t *color_p)
13 {
14 uint16_t w = area->x2 - area->x1 + 1;
15 uint16_t h = area->y2 - area->y1 + 1;
16 struct lvgl_disp_data *data =
17 (struct lvgl_disp_data *)disp_drv->user_data;
18 const struct device *display_dev = data->display_dev;
19 struct display_buffer_descriptor desc;
20 const bool is_epd = data->cap.screen_info & SCREEN_INFO_EPD;
21 const bool is_last = lv_disp_flush_is_last(disp_drv);
22
23 if (is_epd && !data->blanking_on && !is_last) {
24 /*
25 * Turn on display blanking when using an EPD
26 * display. This prevents updates and the associated
27 * flicker if the screen is rendered in multiple
28 * steps.
29 */
30 display_blanking_on(display_dev);
31 data->blanking_on = true;
32 }
33
34 desc.buf_size = (w * h)/8U;
35 desc.width = w;
36 desc.pitch = w;
37 desc.height = h;
38 display_write(display_dev, area->x1, area->y1, &desc, (void *) color_p);
39 if (data->cap.screen_info & SCREEN_INFO_DOUBLE_BUFFER) {
40 display_write(display_dev, area->x1, area->y1, &desc,
41 (void *) color_p);
42 }
43
44 if (is_epd && is_last && data->blanking_on) {
45 /*
46 * The entire screen has now been rendered. Update the
47 * display by disabling blanking.
48 */
49 display_blanking_off(display_dev);
50 data->blanking_on = false;
51 }
52
53 lv_disp_flush_ready(disp_drv);
54 }
55
56
lvgl_set_px_cb_mono(lv_disp_drv_t * disp_drv,uint8_t * buf,lv_coord_t buf_w,lv_coord_t x,lv_coord_t y,lv_color_t color,lv_opa_t opa)57 void lvgl_set_px_cb_mono(lv_disp_drv_t *disp_drv,
58 uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
59 lv_color_t color, lv_opa_t opa)
60 {
61 struct lvgl_disp_data *data =
62 (struct lvgl_disp_data *)disp_drv->user_data;
63 uint8_t *buf_xy;
64 uint8_t bit;
65
66 if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) {
67 buf_xy = buf + x + y/8 * buf_w;
68
69 if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
70 bit = 7 - y%8;
71 } else {
72 bit = y%8;
73 }
74 } else {
75 buf_xy = buf + x/8 + y * buf_w/8;
76
77 if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
78 bit = 7 - x%8;
79 } else {
80 bit = x%8;
81 }
82 }
83
84 if (data->cap.current_pixel_format == PIXEL_FORMAT_MONO10) {
85 if (color.full == 0) {
86 *buf_xy &= ~BIT(bit);
87 } else {
88 *buf_xy |= BIT(bit);
89 }
90 } else {
91 if (color.full == 0) {
92 *buf_xy |= BIT(bit);
93 } else {
94 *buf_xy &= ~BIT(bit);
95 }
96 }
97 }
98
lvgl_rounder_cb_mono(lv_disp_drv_t * disp_drv,lv_area_t * area)99 void lvgl_rounder_cb_mono(lv_disp_drv_t *disp_drv,
100 lv_area_t *area)
101 {
102 struct lvgl_disp_data *data =
103 (struct lvgl_disp_data *)disp_drv->user_data;
104
105 if (data->cap.screen_info & SCREEN_INFO_X_ALIGNMENT_WIDTH) {
106 area->x1 = 0;
107 area->x2 = data->cap.x_resolution - 1;
108 } else {
109 if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) {
110 area->y1 &= ~0x7;
111 area->y2 |= 0x7;
112 } else {
113 area->x1 &= ~0x7;
114 area->x2 |= 0x7;
115 }
116 }
117 }
118