feat(rgb): Use data transfer framework
This commit is contained in:
parent
5fc212faeb
commit
8d953abdf7
2 changed files with 87 additions and 8 deletions
|
@ -146,7 +146,7 @@ static const struct behavior_driver_api behavior_rgb_underglow_driver_api = {
|
||||||
on_keymap_binding_convert_central_state_dependent_params,
|
on_keymap_binding_convert_central_state_dependent_params,
|
||||||
.binding_pressed = on_keymap_binding_pressed,
|
.binding_pressed = on_keymap_binding_pressed,
|
||||||
.binding_released = on_keymap_binding_released,
|
.binding_released = on_keymap_binding_released,
|
||||||
.locality = BEHAVIOR_LOCALITY_GLOBAL,
|
.locality = BEHAVIOR_LOCALITY_CENTRAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_rgb_underglow_init, NULL, NULL, NULL, POST_KERNEL,
|
BEHAVIOR_DT_INST_DEFINE(0, behavior_rgb_underglow_init, NULL, NULL, NULL, POST_KERNEL,
|
||||||
|
|
|
@ -21,11 +21,20 @@
|
||||||
|
|
||||||
#include <zmk/activity.h>
|
#include <zmk/activity.h>
|
||||||
#include <zmk/usb.h>
|
#include <zmk/usb.h>
|
||||||
|
#include <zmk/ble.h>
|
||||||
#include <zmk/event_manager.h>
|
#include <zmk/event_manager.h>
|
||||||
#include <zmk/events/activity_state_changed.h>
|
#include <zmk/events/activity_state_changed.h>
|
||||||
#include <zmk/events/usb_conn_state_changed.h>
|
#include <zmk/events/usb_conn_state_changed.h>
|
||||||
|
#include <zmk/events/split_peripheral_status_changed.h>
|
||||||
#include <zmk/workqueue.h>
|
#include <zmk/workqueue.h>
|
||||||
|
|
||||||
|
// Pull data sending framework if central, data receiving event if peripheral(s)
|
||||||
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
|
#include <zmk/split/bluetooth/central.h>
|
||||||
|
#elif IS_ENABLED(CONFIG_ZMK_SPLIT)
|
||||||
|
#include <zmk/events/split_data_xfer_event.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#if !DT_HAS_CHOSEN(zmk_underglow)
|
#if !DT_HAS_CHOSEN(zmk_underglow)
|
||||||
|
@ -130,6 +139,21 @@ static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) {
|
||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
|
|
||||||
|
static void zmk_rgb_send_state(struct k_work *work) {
|
||||||
|
LOG_HEXDUMP_DBG(&state, sizeof(struct rgb_underglow_state), "RGB state");
|
||||||
|
int err = zmk_split_central_send_data(DATA_TAG_RGB_STATE, sizeof(struct rgb_underglow_state),
|
||||||
|
(uint8_t *)&state);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("send failed (err %d)", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
K_WORK_DEFINE(rgb_send_state_work, zmk_rgb_send_state);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void zmk_rgb_underglow_effect_solid(void) {
|
static void zmk_rgb_underglow_effect_solid(void) {
|
||||||
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
pixels[i] = hsb_to_rgb(hsb_scale_min_max(state.color));
|
pixels[i] = hsb_to_rgb(hsb_scale_min_max(state.color));
|
||||||
|
@ -191,6 +215,14 @@ static void zmk_rgb_underglow_tick(struct k_work *work) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
|
// Every time the counter rolls to 1 synchronise the animations (If it was 0 then it constantly
|
||||||
|
// syncs when effect is a solid color)
|
||||||
|
if (state.animation_step == 1) {
|
||||||
|
k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int err = led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS);
|
int err = led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
LOG_ERR("Failed to update the RGB strip (%d)", err);
|
LOG_ERR("Failed to update the RGB strip (%d)", err);
|
||||||
|
@ -278,7 +310,9 @@ static int zmk_rgb_underglow_init(void) {
|
||||||
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
||||||
state.on = zmk_usb_is_powered();
|
state.on = zmk_usb_is_powered();
|
||||||
#endif
|
#endif
|
||||||
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
|
k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work);
|
||||||
|
#endif
|
||||||
if (state.on) {
|
if (state.on) {
|
||||||
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
||||||
}
|
}
|
||||||
|
@ -287,6 +321,10 @@ static int zmk_rgb_underglow_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_save_state(void) {
|
int zmk_rgb_underglow_save_state(void) {
|
||||||
|
// Send new state to peripheral when anything changes
|
||||||
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
|
k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work);
|
||||||
|
#endif
|
||||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||||
int ret = k_work_reschedule(&underglow_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
|
int ret = k_work_reschedule(&underglow_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
|
||||||
return MIN(ret, 0);
|
return MIN(ret, 0);
|
||||||
|
@ -319,7 +357,6 @@ int zmk_rgb_underglow_on(void) {
|
||||||
state.on = true;
|
state.on = true;
|
||||||
state.animation_step = 0;
|
state.animation_step = 0;
|
||||||
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
||||||
|
|
||||||
return zmk_rgb_underglow_save_state();
|
return zmk_rgb_underglow_save_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,8 +533,12 @@ static int rgb_underglow_auto_state(bool target_wake_state) {
|
||||||
return zmk_rgb_underglow_off();
|
return zmk_rgb_underglow_off();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int rgb_underglow_event_listener(const zmk_event_t *eh) {
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) || \
|
||||||
|
IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB) || ZMK_BLE_IS_CENTRAL
|
||||||
|
|
||||||
|
static int rgb_underglow_activity_event_listener(const zmk_event_t *eh) {
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE)
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE)
|
||||||
if (as_zmk_activity_state_changed(eh)) {
|
if (as_zmk_activity_state_changed(eh)) {
|
||||||
|
@ -511,19 +552,57 @@ static int rgb_underglow_event_listener(const zmk_event_t *eh) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
|
if (as_zmk_split_peripheral_status_changed(eh)) {
|
||||||
|
// TODO: Have this only update when connected
|
||||||
|
k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZMK_LISTENER(rgb_underglow, rgb_underglow_event_listener);
|
ZMK_LISTENER(rgb_underglow_activity, rgb_underglow_activity_event_listener);
|
||||||
#endif // IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) ||
|
#endif // IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) ||
|
||||||
// IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
// IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB) || ZMK_BLE_IS_CENTRAL
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE)
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE)
|
||||||
ZMK_SUBSCRIPTION(rgb_underglow, zmk_activity_state_changed);
|
ZMK_SUBSCRIPTION(rgb_underglow_activity, zmk_activity_state_changed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
||||||
ZMK_SUBSCRIPTION(rgb_underglow, zmk_usb_conn_state_changed);
|
ZMK_SUBSCRIPTION(rgb_underglow_activity, zmk_usb_conn_state_changed);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
|
ZMK_SUBSCRIPTION(rgb_underglow_activity, zmk_split_peripheral_status_changed);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
|
||||||
|
|
||||||
|
static int rgb_underglow_data_event_listener(const zmk_event_t *eh) {
|
||||||
|
const struct zmk_split_data_xfer_event *ev = as_zmk_split_data_xfer_event(eh);
|
||||||
|
if (ev->data_xfer.data_tag == DATA_TAG_RGB_STATE) {
|
||||||
|
LOG_DBG("RGB Data received of size: %d", ev->data_xfer.data_size);
|
||||||
|
// Should the RGB timer be stopped and started during this operation to keep state safe?
|
||||||
|
LOG_HEXDUMP_DBG(ev->data_xfer.data, sizeof(struct zmk_split_data_xfer_event),
|
||||||
|
"received event:");
|
||||||
|
static bool prev_state = false;
|
||||||
|
memcpy(&state, ev->data_xfer.data, sizeof(struct rgb_underglow_state));
|
||||||
|
LOG_HEXDUMP_DBG(&state, sizeof(struct rgb_underglow_state), "RGB state");
|
||||||
|
LOG_DBG("new on_state %d", state.on);
|
||||||
|
if (prev_state && !state.on) {
|
||||||
|
zmk_rgb_underglow_off();
|
||||||
|
} else if (!prev_state && state.on) {
|
||||||
|
zmk_rgb_underglow_on();
|
||||||
|
}
|
||||||
|
prev_state = state.on;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZMK_LISTENER(rgb_underglow_data, rgb_underglow_data_event_listener);
|
||||||
|
ZMK_SUBSCRIPTION(rgb_underglow_data, zmk_split_data_xfer_event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SYS_INIT(zmk_rgb_underglow_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
SYS_INIT(zmk_rgb_underglow_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||||
|
|
Loading…
Add table
Reference in a new issue