|
1 | 1 | /*
|
2 | 2 | * Copyright (c) 2019 Jan Van Winkel <[email protected]>
|
| 3 | + * Copyright 2023 NXP |
3 | 4 | *
|
4 | 5 | * SPDX-License-Identifier: Apache-2.0
|
5 | 6 | */
|
6 | 7 |
|
| 8 | +#include <zephyr/kernel.h> |
7 | 9 | #include <errno.h>
|
8 | 10 |
|
9 | 11 | #include "lvgl_display.h"
|
10 | 12 |
|
| 13 | +#ifdef CONFIG_LV_Z_FLUSH_THREAD |
| 14 | + |
| 15 | +K_SEM_DEFINE(flush_complete, 0, 1); |
| 16 | +/* Message queue will only ever need to queue one message */ |
| 17 | +K_MSGQ_DEFINE(flush_queue, sizeof(struct lvgl_display_flush), 1, 1); |
| 18 | + |
| 19 | +void lvgl_flush_thread_entry(void *arg1, void *arg2, void *arg3) |
| 20 | +{ |
| 21 | + struct lvgl_display_flush flush; |
| 22 | + struct lvgl_disp_data *data; |
| 23 | + |
| 24 | + while (1) { |
| 25 | + k_msgq_get(&flush_queue, &flush, K_FOREVER); |
| 26 | + data = (struct lvgl_disp_data *)flush.disp_drv->user_data; |
| 27 | + |
| 28 | + display_write(data->display_dev, flush.x, flush.y, &flush.desc, |
| 29 | + flush.buf); |
| 30 | + |
| 31 | + lv_disp_flush_ready(flush.disp_drv); |
| 32 | + k_sem_give(&flush_complete); |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +K_THREAD_DEFINE(lvgl_flush_thread, CONFIG_LV_Z_FLUSH_THREAD_STACK_SIZE, |
| 37 | + lvgl_flush_thread_entry, NULL, NULL, NULL, |
| 38 | + K_PRIO_COOP(CONFIG_LV_Z_FLUSH_THREAD_PRIO), 0, 0); |
| 39 | + |
| 40 | + |
| 41 | +void lvgl_wait_cb(lv_disp_drv_t *disp_drv) |
| 42 | +{ |
| 43 | + k_sem_take(&flush_complete, K_FOREVER); |
| 44 | +} |
| 45 | + |
| 46 | +#endif /* CONFIG_LV_Z_FLUSH_THREAD */ |
| 47 | + |
11 | 48 | int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv)
|
12 | 49 | {
|
13 | 50 | int err = 0;
|
14 | 51 | struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
15 | 52 |
|
| 53 | +#ifdef CONFIG_LV_Z_FLUSH_THREAD |
| 54 | + disp_drv->wait_cb = lvgl_wait_cb; |
| 55 | +#endif |
| 56 | + |
16 | 57 | switch (data->cap.current_pixel_format) {
|
17 | 58 | case PIXEL_FORMAT_ARGB_8888:
|
18 | 59 | disp_drv->flush_cb = lvgl_flush_cb_32bit;
|
@@ -54,3 +95,25 @@ int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv)
|
54 | 95 |
|
55 | 96 | return err;
|
56 | 97 | }
|
| 98 | + |
| 99 | +void lvgl_flush_display(struct lvgl_display_flush *request) |
| 100 | +{ |
| 101 | +#ifdef CONFIG_LV_Z_FLUSH_THREAD |
| 102 | + /* |
| 103 | + * LVGL will only start a flush once the previous one is complete, |
| 104 | + * so we can reset the flush state semaphore here. |
| 105 | + */ |
| 106 | + k_sem_reset(&flush_complete); |
| 107 | + k_msgq_put(&flush_queue, request, K_FOREVER); |
| 108 | + /* Explicitly yield, in case the calling thread is a cooperative one */ |
| 109 | + k_yield(); |
| 110 | +#else |
| 111 | + /* Write directly to the display */ |
| 112 | + struct lvgl_disp_data *data = |
| 113 | + (struct lvgl_disp_data *)request->disp_drv->user_data; |
| 114 | + |
| 115 | + display_write(data->display_dev, request->x, request->y, |
| 116 | + &request->desc, request->buf); |
| 117 | + lv_disp_flush_ready(request->disp_drv); |
| 118 | +#endif |
| 119 | +} |
0 commit comments