Skip to content

Commit 7554a4e

Browse files
authored
Change Toucan display to show "Sleep" while in deep sleep (#8)
* Change Toucan display to show "Sleep" while in deep sleep * add a beekeeb icon while in sleep * No need to force_redraw when IDLE/SLEEP state ends
1 parent 72e817d commit 7554a4e

File tree

4 files changed

+213
-0
lines changed

4 files changed

+213
-0
lines changed

boards/shields/nice_view_gem/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ if(CONFIG_ZMK_DISPLAY AND CONFIG_NICE_VIEW_WIDGET_STATUS)
1111
zephyr_library_sources(widgets/layer.c)
1212
zephyr_library_sources(widgets/profile.c)
1313
zephyr_library_sources(widgets/screen.c)
14+
zephyr_library_sources(widgets/sleep.c)
1415
endif()
1516
endif()

boards/shields/nice_view_gem/widgets/screen.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
55

66
#include <zmk/event_manager.h>
7+
#include <zmk/events/activity_state_changed.h>
78
#include <zmk/events/battery_state_changed.h>
89
#include <zmk/events/split_peripheral_status_changed.h>
910
#include <zmk/events/ble_active_profile_changed.h>
@@ -26,6 +27,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
2627
#include "output.h"
2728
#include "profile.h"
2829
#include "screen.h"
30+
#include "sleep.h"
2931

3032
struct connection_status_state {
3133
bool connected;
@@ -41,6 +43,11 @@ static void draw_top(lv_obj_t *widget, lv_color_t cbuf[], const struct status_st
4143
lv_obj_t *canvas = lv_obj_get_child(widget, 0);
4244
fill_background(canvas);
4345

46+
if (is_sleep_screen_active()) {
47+
draw_sleep_screen(canvas);
48+
return;
49+
}
50+
4451
// Draw widgets
4552
draw_output_status(canvas, state);
4653
draw_layer_status(canvas, state);
@@ -189,6 +196,46 @@ ZMK_SUBSCRIPTION(widget_output_status, zmk_usb_conn_state_changed);
189196
ZMK_SUBSCRIPTION(widget_output_status, zmk_ble_active_profile_changed);
190197
#endif
191198

199+
/**
200+
* Activity state handling for sleep screen
201+
**/
202+
203+
static void force_redraw_all_widgets(void) {
204+
struct zmk_widget_screen *widget;
205+
SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) {
206+
draw_top(widget->obj, widget->cbuf, &widget->state);
207+
}
208+
}
209+
210+
static int display_activity_event_handler(const zmk_event_t *eh) {
211+
struct zmk_activity_state_changed *ev = as_zmk_activity_state_changed(eh);
212+
if (ev == NULL) {
213+
return -ENOTSUP;
214+
}
215+
216+
switch (ev->state) {
217+
case ZMK_ACTIVITY_ACTIVE:
218+
set_sleep_screen_active(false);
219+
// No need to force a redraw, it will happen automatically if really coming back from sleep (ACTIVE also comes after IDLE)
220+
//force_redraw_all_widgets();
221+
break;
222+
case ZMK_ACTIVITY_SLEEP:
223+
set_sleep_screen_active(true);
224+
force_redraw_all_widgets();
225+
// Force LVGL to process pending updates and flush to display hardware
226+
// before the CPU enters deep sleep
227+
lv_task_handler();
228+
lv_refr_now(NULL);
229+
break;
230+
default:
231+
break; // ignore other states (like IDLE)
232+
}
233+
return 0;
234+
}
235+
236+
ZMK_LISTENER(nice_view_gem_display, display_activity_event_handler);
237+
ZMK_SUBSCRIPTION(nice_view_gem_display, zmk_activity_state_changed);
238+
192239
/**
193240
* Initialization
194241
**/
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#include <zephyr/kernel.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
5+
#include "sleep.h"
6+
#include "../assets/custom_fonts.h"
7+
8+
static bool show_sleep_screen = false;
9+
10+
// Beekeeb icon 96x96 - LVGL indexed 1-bit format
11+
static const uint8_t sleep_icon_map[] = {
12+
0x00, 0x00, 0x00, 0xff, /*Color of index 0 - black*/
13+
0xff, 0xff, 0xff, 0xff, /*Color of index 1 - white*/
14+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
15+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
16+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
19+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
23+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00,
24+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00,
25+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00,
26+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00,
27+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00,
28+
0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x01, 0xfd, 0xfc, 0x00, 0x00,
29+
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0xf8, 0xfe, 0x00, 0x00,
30+
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x7f, 0x00, 0x00,
31+
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x3f, 0x80, 0x00,
32+
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x3f, 0xc0, 0x00,
33+
0x00, 0x00, 0x00, 0x7c, 0x03, 0xe0, 0x00, 0x3f, 0xf0, 0x7f, 0xe0, 0x00,
34+
0x00, 0x00, 0x00, 0x7c, 0x3f, 0xfe, 0x00, 0x7f, 0xf8, 0xff, 0xf0, 0x00,
35+
0x00, 0x00, 0x00, 0x7d, 0xff, 0xff, 0xc0, 0xff, 0xfd, 0xff, 0xf8, 0x00,
36+
0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf1, 0xfc, 0xff, 0xf9, 0xfc, 0x00,
37+
0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfb, 0xf8, 0x7f, 0xf0, 0xfe, 0x00,
38+
0x00, 0x00, 0x00, 0x7f, 0xfe, 0x3f, 0xff, 0xf0, 0x3f, 0xe0, 0x7f, 0x00,
39+
0x00, 0x03, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xe0, 0x1f, 0xc0, 0x3f, 0x00,
40+
0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0xff, 0xf0, 0x3f, 0xe0, 0x7f, 0x00,
41+
0x00, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xf8, 0x7f, 0xf0, 0xfe, 0x00,
42+
0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xfc, 0xff, 0xf9, 0xfc, 0x00,
43+
0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0xfe, 0xff, 0xfd, 0xff, 0xf8, 0x00,
44+
0x00, 0x00, 0x03, 0xf0, 0x00, 0x01, 0xfc, 0x7f, 0xf8, 0xff, 0xf0, 0x00,
45+
0x00, 0x00, 0x07, 0xe0, 0x00, 0x03, 0xf8, 0x3f, 0xf0, 0x7f, 0xe0, 0x00,
46+
0x00, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xf0, 0x1f, 0xe0, 0x3f, 0xc0, 0x00,
47+
0x00, 0x00, 0x07, 0xc0, 0x00, 0x0f, 0xf0, 0x1f, 0xe0, 0x3f, 0xc0, 0x00,
48+
0x00, 0x00, 0x0f, 0xc0, 0x00, 0x1f, 0xf8, 0x3f, 0xf0, 0x7f, 0xe0, 0x00,
49+
0x00, 0x00, 0x0f, 0x80, 0x00, 0x3f, 0xfc, 0x7f, 0xf8, 0xff, 0xf0, 0x00,
50+
0x00, 0x00, 0x0f, 0x80, 0x00, 0x7f, 0xfe, 0xff, 0xfd, 0xff, 0xf8, 0x00,
51+
0x00, 0x00, 0x0f, 0x80, 0x00, 0xfe, 0x7f, 0xfc, 0xff, 0xf9, 0xfc, 0x00,
52+
0x00, 0x00, 0x1f, 0x00, 0x01, 0xfc, 0x3f, 0xf8, 0x7f, 0xf0, 0xfe, 0x00,
53+
0x00, 0x00, 0x1f, 0x00, 0x03, 0xf8, 0x1f, 0xf0, 0x3f, 0xe0, 0x7f, 0x00,
54+
0x00, 0x00, 0x1f, 0x00, 0x07, 0xf0, 0x0f, 0xe0, 0x1f, 0xc0, 0x3f, 0x00,
55+
0x00, 0x00, 0x1f, 0x00, 0x0f, 0xf8, 0x1f, 0xf0, 0x3f, 0xe0, 0x7f, 0x00,
56+
0x00, 0x00, 0x1f, 0x00, 0x1f, 0xfc, 0x3f, 0xf8, 0x7f, 0xf0, 0xfe, 0x00,
57+
0x00, 0x00, 0x0f, 0x80, 0x3f, 0xfe, 0x7f, 0xfc, 0xff, 0xf9, 0xfc, 0x00,
58+
0x00, 0x00, 0x0f, 0x80, 0x7f, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xf8, 0x00,
59+
0x00, 0x00, 0x0f, 0x80, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xf0, 0x00,
60+
0x00, 0x00, 0x0f, 0xc1, 0xfc, 0x1f, 0xf8, 0x3f, 0xf7, 0xff, 0xe0, 0x00,
61+
0x00, 0x00, 0x07, 0xc3, 0xf8, 0x0f, 0xf0, 0x1f, 0xe3, 0xff, 0xc0, 0x00,
62+
0x00, 0x00, 0x07, 0xe7, 0xf8, 0x0f, 0xe0, 0x1f, 0xc1, 0xff, 0x80, 0x00,
63+
0x00, 0x00, 0x07, 0xff, 0xfc, 0x1f, 0xc0, 0x3f, 0x80, 0xff, 0x00, 0x00,
64+
0x00, 0x00, 0x03, 0xff, 0xfe, 0x3f, 0x80, 0x7f, 0x00, 0xfe, 0x00, 0x00,
65+
0x00, 0x00, 0x03, 0xff, 0xff, 0x7f, 0x00, 0xfe, 0x01, 0xfe, 0x00, 0x00,
66+
0x00, 0x00, 0x01, 0xff, 0x3f, 0xfe, 0x01, 0xfc, 0x03, 0xfe, 0x00, 0x00,
67+
0x00, 0x00, 0x00, 0xfe, 0x1f, 0xfc, 0x03, 0xf8, 0x07, 0xff, 0x00, 0x00,
68+
0x00, 0x00, 0x01, 0xfc, 0x0f, 0xf8, 0x07, 0xf0, 0x0f, 0xff, 0x00, 0x00,
69+
0x00, 0x00, 0x03, 0xf8, 0x07, 0xf0, 0x0f, 0xe0, 0x1f, 0xdf, 0x00, 0x00,
70+
0x00, 0x00, 0x07, 0xfc, 0x0f, 0xf8, 0x1f, 0xc0, 0x3f, 0x9f, 0x00, 0x00,
71+
0x00, 0x00, 0x0f, 0xfe, 0x1f, 0xfc, 0x3f, 0x80, 0x7f, 0x1f, 0x00, 0x00,
72+
0x00, 0x00, 0x1f, 0xff, 0x3f, 0xfe, 0x7f, 0x00, 0xfe, 0x1f, 0x00, 0x00,
73+
0x00, 0x00, 0x3f, 0xbf, 0xff, 0x7f, 0xfe, 0x01, 0xfc, 0x1f, 0x00, 0x00,
74+
0x00, 0x00, 0x7f, 0x1f, 0xfe, 0x3f, 0xfc, 0x03, 0xf8, 0x1f, 0x00, 0x00,
75+
0x00, 0x00, 0xfe, 0x0f, 0xfc, 0x1f, 0xf8, 0x07, 0xf0, 0x1f, 0x00, 0x00,
76+
0x00, 0x01, 0xfc, 0x07, 0xf8, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0x00, 0x00,
77+
0x00, 0x03, 0xfc, 0x07, 0xf8, 0x0f, 0xe0, 0x1f, 0xc0, 0x1f, 0x00, 0x00,
78+
0x00, 0x07, 0xfe, 0x0f, 0xfc, 0x1f, 0xc0, 0x3f, 0x80, 0x1f, 0x00, 0x00,
79+
0x00, 0x0f, 0xff, 0x1f, 0xfe, 0x3f, 0x80, 0x7f, 0x00, 0x3f, 0x00, 0x00,
80+
0x00, 0x1f, 0xff, 0xbf, 0xff, 0x7f, 0x00, 0xfe, 0x00, 0x3e, 0x00, 0x00,
81+
0x00, 0x3f, 0x9f, 0xff, 0x3f, 0xfe, 0x01, 0xfc, 0x00, 0x7e, 0x00, 0x00,
82+
0x00, 0x7f, 0x0f, 0xfe, 0x1f, 0xfc, 0x03, 0xf8, 0x00, 0xfc, 0x00, 0x00,
83+
0x00, 0xfe, 0x07, 0xfc, 0x0f, 0xfe, 0x07, 0xf0, 0x00, 0xfc, 0x00, 0x00,
84+
0x00, 0xfc, 0x03, 0xf8, 0x07, 0xff, 0x0f, 0xe0, 0x01, 0xf8, 0x00, 0x00,
85+
0x00, 0xfe, 0x07, 0xfc, 0x0f, 0xff, 0x9f, 0xc0, 0x03, 0xf8, 0x00, 0x00,
86+
0x00, 0x7f, 0x0f, 0xfe, 0x1f, 0xff, 0xff, 0x80, 0x07, 0xf0, 0x00, 0x00,
87+
0x00, 0x3f, 0x9f, 0xff, 0x3f, 0x9f, 0xff, 0x00, 0x1f, 0xf8, 0x00, 0x00,
88+
0x00, 0x1f, 0xff, 0xff, 0xff, 0x0f, 0xff, 0x00, 0x7f, 0xfc, 0x00, 0x00,
89+
0x00, 0x0f, 0xff, 0x1f, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
90+
0x00, 0x07, 0xfe, 0x0f, 0xfc, 0x01, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
91+
0x00, 0x03, 0xfc, 0x07, 0xf8, 0x00, 0x7f, 0xff, 0xfc, 0x3f, 0x00, 0x00,
92+
0x00, 0x01, 0xfc, 0x07, 0xf0, 0x00, 0x3f, 0xff, 0xf0, 0x1f, 0x80, 0x00,
93+
0x00, 0x00, 0xfe, 0x0f, 0xe0, 0x00, 0x07, 0xff, 0xc0, 0x0f, 0x00, 0x00,
94+
0x00, 0x00, 0x7f, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95+
0x00, 0x00, 0x3f, 0xbf, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96+
0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97+
0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98+
0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99+
0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100+
0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101+
0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110+
};
111+
112+
static const lv_img_dsc_t sleep_icon = {
113+
.header.cf = LV_IMG_CF_INDEXED_1BIT,
114+
.header.always_zero = 0,
115+
.header.reserved = 0,
116+
.header.w = 96,
117+
.header.h = 96,
118+
.data_size = 1160,
119+
.data = sleep_icon_map,
120+
};
121+
122+
bool is_sleep_screen_active(void) {
123+
return show_sleep_screen;
124+
}
125+
126+
void set_sleep_screen_active(bool active) {
127+
show_sleep_screen = active;
128+
}
129+
130+
void draw_sleep_screen(lv_obj_t *canvas) {
131+
// Draw the sleep icon centered horizontally, near top of screen
132+
lv_draw_img_dsc_t img_dsc;
133+
lv_draw_img_dsc_init(&img_dsc);
134+
// Center the 96px icon on the 144px wide screen: (144-96)/2 = 24
135+
// Draw it a bit down from the top: y=32
136+
lv_canvas_draw_img(canvas, 24, 32, &sleep_icon, &img_dsc);
137+
138+
// Show "SLEEP" in small text below the icon
139+
lv_draw_label_dsc_t label_dsc;
140+
init_label_dsc(&label_dsc, LVGL_FOREGROUND, &quinquefive_8, LV_TEXT_ALIGN_LEFT);
141+
lv_canvas_draw_text(canvas, 12, 140, SCREEN_WIDTH-8, &label_dsc, "SLEEP");
142+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <lvgl.h>
4+
#include "util.h"
5+
6+
/**
7+
* Draw a sleep screen showing the keyboard is in sleep mode.
8+
* This is displayed when the device enters deep sleep to give the user visual
9+
* feedback before the display is powered off.
10+
*/
11+
void draw_sleep_screen(lv_obj_t *canvas);
12+
13+
/**
14+
* Check if the sleep screen should be shown.
15+
* Returns true when the device is entering sleep mode.
16+
*/
17+
bool is_sleep_screen_active(void);
18+
19+
/**
20+
* Set the sleep screen active state.
21+
* Called by the activity state change handler.
22+
*/
23+
void set_sleep_screen_active(bool active);

0 commit comments

Comments
 (0)