Zen display & battery tweaks
This commit is contained in:
parent
d10c48b027
commit
db45b69672
12 changed files with 157 additions and 25 deletions
|
@ -77,6 +77,9 @@ menuconfig CUSTOM_WIDGET_LAYER_STATUS
|
|||
menuconfig CUSTOM_WIDGET_PERIPHERAL_STATUS
|
||||
bool "custom peripheral status widget"
|
||||
|
||||
config CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING
|
||||
bool "Hide heading strip for layer widget and center widgets on 1/3rds"
|
||||
|
||||
endif # BOARD_CORNEISH_ZEN_LEFT || BOARD_CORNEISH_ZEN_RIGHT
|
||||
|
||||
if BOARD_CORNEISH_ZEN_V1_LEFT || BOARD_CORNEISH_ZEN_V1_RIGHT
|
||||
|
|
|
@ -40,37 +40,60 @@ lv_obj_t *zmk_display_status_screen() {
|
|||
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_BATTERY_STATUS)
|
||||
zmk_widget_battery_status_init(&battery_status_widget, screen);
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING)
|
||||
lv_obj_align(zmk_widget_battery_status_obj(&battery_status_widget), LV_ALIGN_CENTER, 0, -43);
|
||||
#else
|
||||
lv_obj_align(zmk_widget_battery_status_obj(&battery_status_widget), LV_ALIGN_TOP_MID, 0, 2);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_OUTPUT_STATUS)
|
||||
zmk_widget_output_status_init(&output_status_widget, screen);
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING)
|
||||
lv_obj_align(zmk_widget_output_status_obj(&output_status_widget), LV_ALIGN_CENTER, 0, 0);
|
||||
#else
|
||||
lv_obj_align(zmk_widget_output_status_obj(&output_status_widget), LV_ALIGN_TOP_MID, 0, 41);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_PERIPHERAL_STATUS)
|
||||
zmk_widget_peripheral_status_init(&peripheral_status_widget, screen);
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING)
|
||||
lv_obj_align(zmk_widget_peripheral_status_obj(&peripheral_status_widget), LV_ALIGN_CENTER, 0,
|
||||
0);
|
||||
#else
|
||||
lv_obj_align(zmk_widget_peripheral_status_obj(&peripheral_status_widget), LV_ALIGN_TOP_MID, 0,
|
||||
41);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS)
|
||||
#if !IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING)
|
||||
lv_obj_t *LayersHeading;
|
||||
LayersHeading = lv_img_create(screen);
|
||||
lv_obj_align(LayersHeading, LV_ALIGN_BOTTOM_MID, 0, -30);
|
||||
lv_img_set_src(LayersHeading, &layers2);
|
||||
#endif
|
||||
|
||||
zmk_widget_layer_status_init(&layer_status_widget, screen);
|
||||
lv_obj_set_style_text_font(zmk_widget_layer_status_obj(&layer_status_widget),
|
||||
&lv_font_montserrat_16, LV_PART_MAIN);
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING)
|
||||
lv_obj_align(zmk_widget_layer_status_obj(&layer_status_widget), LV_ALIGN_CENTER, 0, 43);
|
||||
#else
|
||||
lv_obj_align(zmk_widget_layer_status_obj(&layer_status_widget), LV_ALIGN_BOTTOM_MID, 0, -5);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
|
||||
lv_obj_t *zenlogo_icon;
|
||||
zenlogo_icon = lv_img_create(screen);
|
||||
lv_img_set_src(zenlogo_icon, &zenlogo);
|
||||
#if IS_ENABLED(CONFIG_CUSTOM_WIDGET_LAYER_STATUS_HIDE_HEADING)
|
||||
lv_obj_align(zenlogo_icon, LV_ALIGN_CENTER, 0, 43);
|
||||
#else
|
||||
lv_obj_align(zenlogo_icon, LV_ALIGN_BOTTOM_MID, 0, -5);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return screen;
|
||||
|
|
|
@ -41,21 +41,52 @@ LV_IMG_DECLARE(batt_0);
|
|||
LV_IMG_DECLARE(batt_0_chg);
|
||||
|
||||
static void set_battery_symbol(lv_obj_t *icon, struct battery_status_state state) {
|
||||
uint8_t level = state.level;
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
|
||||
if (level > 95) {
|
||||
lv_img_set_src(icon, state.usb_present ? &batt_100_chg : &batt_100);
|
||||
} else if (level > 74) {
|
||||
lv_img_set_src(icon, state.usb_present ? &batt_75_chg : &batt_75);
|
||||
} else if (level > 49) {
|
||||
lv_img_set_src(icon, state.usb_present ? &batt_50_chg : &batt_50);
|
||||
} else if (level > 24) {
|
||||
lv_img_set_src(icon, state.usb_present ? &batt_25_chg : &batt_25);
|
||||
static uint8_t stage_prev = 255;
|
||||
static bool usb_prev = false;
|
||||
|
||||
uint8_t level = state.level;
|
||||
bool usb_present = state.usb_present;
|
||||
uint8_t stage;
|
||||
|
||||
if (level > 87) {
|
||||
stage = 5;
|
||||
} else if (level > 62) {
|
||||
stage = 4;
|
||||
} else if (level > 37) {
|
||||
stage = 3;
|
||||
} else if (level > 12) {
|
||||
stage = 2;
|
||||
} else if (level > 5) {
|
||||
lv_img_set_src(icon, state.usb_present ? &batt_5_chg : &batt_5);
|
||||
stage = 1;
|
||||
} else {
|
||||
lv_img_set_src(icon, state.usb_present ? &batt_0_chg : &batt_0);
|
||||
stage = 0;
|
||||
}
|
||||
|
||||
// check if there is a change requiring an update
|
||||
if (usb_present != usb_prev || stage != stage_prev) {
|
||||
switch (stage) {
|
||||
case 5:
|
||||
lv_img_set_src(icon, usb_present ? &batt_100_chg : &batt_100);
|
||||
break;
|
||||
case 4:
|
||||
lv_img_set_src(icon, usb_present ? &batt_75_chg : &batt_75);
|
||||
break;
|
||||
case 3:
|
||||
lv_img_set_src(icon, usb_present ? &batt_50_chg : &batt_50);
|
||||
break;
|
||||
case 2:
|
||||
lv_img_set_src(icon, usb_present ? &batt_25_chg : &batt_25);
|
||||
break;
|
||||
case 1:
|
||||
lv_img_set_src(icon, usb_present ? &batt_5_chg : &batt_5);
|
||||
break;
|
||||
default:
|
||||
lv_img_set_src(icon, usb_present ? &batt_0_chg : &batt_0);
|
||||
break;
|
||||
}
|
||||
usb_prev = usb_present;
|
||||
stage_prev = stage;
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */
|
||||
}
|
||||
|
|
|
@ -27,6 +27,16 @@ static void set_layer_symbol(lv_obj_t *label, struct layer_status_state state) {
|
|||
const char *layer_label = state.label;
|
||||
uint8_t active_layer_index = state.index;
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_DISPLAY_HIDE_MOMENTARY_LAYERS)
|
||||
static uint8_t last_perm_index = 255;
|
||||
if (!zmk_keymap_layer_momentary(active_layer_index) && last_perm_index != active_layer_index) {
|
||||
last_perm_index = active_layer_index;
|
||||
LOG_DBG("Last perm layer index updated to %i", active_layer_index);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (layer_label == NULL) {
|
||||
char text[6] = {};
|
||||
|
||||
|
|
|
@ -17,8 +17,10 @@ typedef uint32_t zmk_keymap_layers_state_t;
|
|||
uint8_t zmk_keymap_layer_default();
|
||||
zmk_keymap_layers_state_t zmk_keymap_layer_state();
|
||||
bool zmk_keymap_layer_active(uint8_t layer);
|
||||
bool zmk_keymap_layer_momentary(uint8_t layer);
|
||||
bool zmk_keymap_layers_any_momentary(zmk_keymap_layers_state_t layers_mask);
|
||||
uint8_t zmk_keymap_highest_layer_active();
|
||||
int zmk_keymap_layer_activate(uint8_t layer);
|
||||
int zmk_keymap_layer_activate(uint8_t layer, bool momentary);
|
||||
int zmk_keymap_layer_deactivate(uint8_t layer);
|
||||
int zmk_keymap_layer_toggle(uint8_t layer);
|
||||
int zmk_keymap_layer_to(uint8_t layer);
|
||||
|
|
|
@ -9,3 +9,11 @@ config IL0323
|
|||
depends on HEAP_MEM_POOL_SIZE != 0
|
||||
help
|
||||
Enable driver for IL0323 compatible controller.
|
||||
|
||||
config IL0323_INVERT
|
||||
bool "Invert display"
|
||||
default n
|
||||
|
||||
config IL0323_ALTERNATIVE_REFRESH
|
||||
bool "Use an alternative approach for partial refreshes"
|
||||
default n
|
||||
|
|
|
@ -124,7 +124,11 @@ static int il0323_write(const struct device *dev, const uint16_t x, const uint16
|
|||
ptl[IL0323_PTL_HRED_IDX] = x_end_idx;
|
||||
ptl[IL0323_PTL_VRST_IDX] = y;
|
||||
ptl[IL0323_PTL_VRED_IDX] = y_end_idx;
|
||||
#if IS_ENABLED(CONFIG_IL0323_ALTERNATIVE_REFRESH)
|
||||
ptl[sizeof(ptl) - 1] = 0; // limits fading outside of refresh window
|
||||
#else
|
||||
ptl[sizeof(ptl) - 1] = IL0323_PTL_PT_SCAN;
|
||||
#endif
|
||||
LOG_HEXDUMP_DBG(ptl, sizeof(ptl), "ptl");
|
||||
|
||||
il0323_busy_wait(cfg);
|
||||
|
@ -242,8 +246,12 @@ static void il0323_get_capabilities(const struct device *dev, struct display_cap
|
|||
memset(caps, 0, sizeof(struct display_capabilities));
|
||||
caps->x_resolution = EPD_PANEL_WIDTH;
|
||||
caps->y_resolution = EPD_PANEL_HEIGHT;
|
||||
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10;
|
||||
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10 | PIXEL_FORMAT_MONO01;
|
||||
#if IS_ENABLED(CONFIG_IL0323_INVERT)
|
||||
caps->current_pixel_format = PIXEL_FORMAT_MONO01;
|
||||
#else
|
||||
caps->current_pixel_format = PIXEL_FORMAT_MONO10;
|
||||
#endif
|
||||
caps->screen_info = SCREEN_INFO_MONO_MSB_FIRST | SCREEN_INFO_EPD;
|
||||
}
|
||||
|
||||
|
@ -254,7 +262,7 @@ static int il0323_set_orientation(const struct device *dev,
|
|||
}
|
||||
|
||||
static int il0323_set_pixel_format(const struct device *dev, const enum display_pixel_format pf) {
|
||||
if (pf == PIXEL_FORMAT_MONO10) {
|
||||
if ((pf == PIXEL_FORMAT_MONO10) || (pf == PIXEL_FORMAT_MONO10)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ static int behavior_mo_init(const struct device *dev) { return 0; };
|
|||
static int mo_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
LOG_DBG("position %d layer %d", event.position, binding->param1);
|
||||
return zmk_keymap_layer_activate(binding->param1);
|
||||
return zmk_keymap_layer_activate(binding->param1, true);
|
||||
}
|
||||
|
||||
static int mo_keymap_binding_released(struct zmk_behavior_binding *binding,
|
||||
|
|
|
@ -49,12 +49,12 @@ static const struct conditional_layer_cfg CONDITIONAL_LAYER_CFGS[] = {
|
|||
static const int32_t NUM_CONDITIONAL_LAYER_CFGS =
|
||||
sizeof(CONDITIONAL_LAYER_CFGS) / sizeof(*CONDITIONAL_LAYER_CFGS);
|
||||
|
||||
static void conditional_layer_activate(int8_t layer) {
|
||||
static void conditional_layer_activate(int8_t layer, bool momentary) {
|
||||
// This may trigger another event that could, in turn, activate additional then-layers. However,
|
||||
// the process will eventually terminate (at worst, when every layer is active).
|
||||
if (!zmk_keymap_layer_active(layer)) {
|
||||
LOG_DBG("layer %d", layer);
|
||||
zmk_keymap_layer_activate(layer);
|
||||
zmk_keymap_layer_activate(layer, momentary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,7 @@ static int layer_state_changed_listener(const zmk_event_t *ev) {
|
|||
int8_t max_then_layer = -1;
|
||||
uint32_t then_layers = 0;
|
||||
uint32_t then_layer_state = 0;
|
||||
uint32_t momentariness_state = 0;
|
||||
|
||||
conditional_layer_updates_needed = false;
|
||||
|
||||
|
@ -100,13 +101,17 @@ static int layer_state_changed_listener(const zmk_event_t *ev) {
|
|||
// also trigger activation of another.
|
||||
if ((zmk_keymap_layer_state() & mask) == mask) {
|
||||
then_layer_state |= BIT(cfg->then_layer);
|
||||
if (zmk_keymap_layers_any_momentary(mask)) {
|
||||
momentariness_state |= BIT(cfg->then_layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t layer = 0; layer <= max_then_layer; layer++) {
|
||||
if ((BIT(layer) & then_layers) != 0U) {
|
||||
if ((BIT(layer) & then_layer_state) != 0U) {
|
||||
conditional_layer_activate(layer);
|
||||
bool momentary = BIT(layer) & momentariness_state;
|
||||
conditional_layer_activate(layer, momentary);
|
||||
} else {
|
||||
conditional_layer_deactivate(layer);
|
||||
}
|
||||
|
|
|
@ -176,6 +176,17 @@ choice ZMK_LV_FONT_DEFAULT_SMALL
|
|||
select LV_FONT_UNSCII_16
|
||||
endchoice
|
||||
|
||||
config ZMK_DISPLAY_FULL_REFRESH_PERIOD
|
||||
int "(Optional) Period to issue a full refresh to the display (in seconds)"
|
||||
default 0
|
||||
help
|
||||
Period in seconds for how often to completely refresh/redraw the whole screen.
|
||||
Most useful for e-ink/EPD displays that require occasional full redraws.
|
||||
|
||||
config ZMK_DISPLAY_HIDE_MOMENTARY_LAYERS
|
||||
bool "Do not update layer widget for momentary layer changes"
|
||||
default n
|
||||
|
||||
rsource "widgets/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
@ -50,6 +50,17 @@ struct k_work_q *zmk_display_work_q() {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD > 0
|
||||
void full_refresh_work_cb(struct k_work *work) { lv_obj_invalidate(lv_scr_act()); }
|
||||
|
||||
K_WORK_DEFINE(full_refresh_work, full_refresh_work_cb);
|
||||
|
||||
void full_refresh_timer_cb() { k_work_submit_to_queue(zmk_display_work_q(), &full_refresh_work); }
|
||||
|
||||
K_TIMER_DEFINE(full_refresh_timer, full_refresh_timer_cb, NULL);
|
||||
|
||||
#endif
|
||||
|
||||
void display_timer_cb() { k_work_submit_to_queue(zmk_display_work_q(), &display_tick_work); }
|
||||
|
||||
K_TIMER_DEFINE(display_timer, display_timer_cb, NULL);
|
||||
|
@ -57,6 +68,10 @@ K_TIMER_DEFINE(display_timer, display_timer_cb, NULL);
|
|||
void unblank_display_cb(struct k_work *work) {
|
||||
display_blanking_off(display);
|
||||
k_timer_start(&display_timer, K_MSEC(TICK_MS), K_MSEC(TICK_MS));
|
||||
#if CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD > 0
|
||||
k_timer_start(&full_refresh_timer, K_SECONDS(CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD),
|
||||
K_SECONDS(CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_DISPLAY_BLANK_ON_IDLE)
|
||||
|
@ -64,6 +79,9 @@ void unblank_display_cb(struct k_work *work) {
|
|||
void blank_display_cb(struct k_work *work) {
|
||||
k_timer_stop(&display_timer);
|
||||
display_blanking_on(display);
|
||||
#if CONFIG_ZMK_DISPLAY_FULL_REFRESH_PERIOD > 0
|
||||
k_timer_stop(&full_refresh_timer);
|
||||
#endif
|
||||
}
|
||||
K_WORK_DEFINE(blank_display_work, blank_display_cb);
|
||||
K_WORK_DEFINE(unblank_display_work, unblank_display_cb);
|
||||
|
|
|
@ -27,6 +27,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
#include <zmk/events/sensor_event.h>
|
||||
|
||||
static zmk_keymap_layers_state_t _zmk_keymap_layer_state = 0;
|
||||
static zmk_keymap_layers_state_t _zmk_keymap_layer_momentary = 0;
|
||||
static uint8_t _zmk_keymap_layer_default = 0;
|
||||
|
||||
#define DT_DRV_COMPAT zmk_keymap
|
||||
|
@ -78,7 +79,7 @@ static struct zmk_behavior_binding zmk_sensor_keymap[ZMK_KEYMAP_LAYERS_LEN]
|
|||
|
||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||
|
||||
static inline int set_layer_state(uint8_t layer, bool state) {
|
||||
static inline int set_layer_state(uint8_t layer, bool state, bool momentary) {
|
||||
if (layer >= ZMK_KEYMAP_LAYERS_LEN) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -93,6 +94,7 @@ static inline int set_layer_state(uint8_t layer, bool state) {
|
|||
// Don't send state changes unless there was an actual change
|
||||
if (old_state != _zmk_keymap_layer_state) {
|
||||
LOG_DBG("layer_changed: layer %d state %d", layer, state);
|
||||
WRITE_BIT(_zmk_keymap_layer_momentary, layer, momentary);
|
||||
ZMK_EVENT_RAISE(create_layer_state_changed(layer, state));
|
||||
}
|
||||
|
||||
|
@ -113,6 +115,15 @@ bool zmk_keymap_layer_active(uint8_t layer) {
|
|||
return zmk_keymap_layer_active_with_state(layer, _zmk_keymap_layer_state);
|
||||
};
|
||||
|
||||
bool zmk_keymap_layer_momentary(uint8_t layer) {
|
||||
return layer != _zmk_keymap_layer_default &&
|
||||
(_zmk_keymap_layer_momentary & (BIT(layer))) == (BIT(layer));
|
||||
};
|
||||
|
||||
bool zmk_keymap_layers_any_momentary(zmk_keymap_layers_state_t layers_mask) {
|
||||
return (_zmk_keymap_layer_momentary & layers_mask) > 0;
|
||||
};
|
||||
|
||||
uint8_t zmk_keymap_highest_layer_active() {
|
||||
for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) {
|
||||
if (zmk_keymap_layer_active(layer)) {
|
||||
|
@ -122,16 +133,18 @@ uint8_t zmk_keymap_highest_layer_active() {
|
|||
return zmk_keymap_layer_default();
|
||||
}
|
||||
|
||||
int zmk_keymap_layer_activate(uint8_t layer) { return set_layer_state(layer, true); };
|
||||
int zmk_keymap_layer_activate(uint8_t layer, bool momentary) {
|
||||
return set_layer_state(layer, true, momentary);
|
||||
};
|
||||
|
||||
int zmk_keymap_layer_deactivate(uint8_t layer) { return set_layer_state(layer, false); };
|
||||
int zmk_keymap_layer_deactivate(uint8_t layer) { return set_layer_state(layer, false, false); };
|
||||
|
||||
int zmk_keymap_layer_toggle(uint8_t layer) {
|
||||
if (zmk_keymap_layer_active(layer)) {
|
||||
return zmk_keymap_layer_deactivate(layer);
|
||||
}
|
||||
|
||||
return zmk_keymap_layer_activate(layer);
|
||||
return zmk_keymap_layer_activate(layer, false);
|
||||
};
|
||||
|
||||
int zmk_keymap_layer_to(uint8_t layer) {
|
||||
|
@ -139,7 +152,7 @@ int zmk_keymap_layer_to(uint8_t layer) {
|
|||
zmk_keymap_layer_deactivate(i);
|
||||
}
|
||||
|
||||
zmk_keymap_layer_activate(layer);
|
||||
zmk_keymap_layer_activate(layer, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue