diff options
Diffstat (limited to 'app/src')
23 files changed, 528 insertions, 144 deletions
diff --git a/app/src/behaviors/behavior_bt.c b/app/src/behaviors/behavior_bt.c index 09fadba..066c437 100644 --- a/app/src/behaviors/behavior_bt.c +++ b/app/src/behaviors/behavior_bt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Peter Johanson <peter@peterjohanson.com> + * Copyright (c) 2020 The ZMK Contributors * * SPDX-License-Identifier: MIT */ @@ -8,18 +8,18 @@ #include <device.h> #include <drivers/behavior.h> - #include <dt-bindings/zmk/bt.h> - #include <bluetooth/conn.h> - #include <logging/log.h> +#include <zmk/behavior.h> + LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include <zmk/ble.h> -static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t command, u32_t arg) { - switch (command) { +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + switch (binding->param1) { case BT_CLR_CMD: return zmk_ble_clear_bonds(); case BT_NXT_CMD: @@ -27,9 +27,9 @@ static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t c case BT_PRV_CMD: return zmk_ble_prof_prev(); case BT_SEL_CMD: - return zmk_ble_prof_select(arg); + return zmk_ble_prof_select(binding->param2); default: - LOG_ERR("Unknown BT command: %d", command); + LOG_ERR("Unknown BT command: %d", binding->param1); } return -ENOTSUP; @@ -37,8 +37,8 @@ static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t c static int behavior_bt_init(struct device *dev) { return 0; }; -static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t command, - u32_t arg) { +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { return 0; } diff --git a/app/src/behaviors/behavior_ext_power.c b/app/src/behaviors/behavior_ext_power.c new file mode 100644 index 0000000..825f983 --- /dev/null +++ b/app/src/behaviors/behavior_ext_power.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_ext_power + +#include <device.h> +#include <devicetree.h> +#include <drivers/behavior.h> +#include <drivers/ext_power.h> + +#include <dt-bindings/zmk/ext_power.h> + +#include <logging/log.h> +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + struct device *ext_power = device_get_binding("EXT_POWER"); + if (ext_power == NULL) { + LOG_ERR("Unable to retrieve ext_power device: %d", binding->param1); + return -EIO; + } + + switch (binding->param1) { + case EXT_POWER_OFF_CMD: + return ext_power_disable(ext_power); + case EXT_POWER_ON_CMD: + return ext_power_enable(ext_power); + case EXT_POWER_TOGGLE_CMD: + if (ext_power_get(ext_power) > 0) + return ext_power_disable(ext_power); + else + return ext_power_enable(ext_power); + default: + LOG_ERR("Unknown ext_power command: %d", binding->param1); + } + + return -ENOTSUP; +} + +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + return 0; +} + +static int behavior_ext_power_init(struct device *dev) { return 0; }; + +static const struct behavior_driver_api behavior_ext_power_driver_api = { + .binding_pressed = on_keymap_binding_pressed, + .binding_released = on_keymap_binding_released, +}; + +DEVICE_AND_API_INIT(behavior_ext_power, DT_INST_LABEL(0), behavior_ext_power_init, NULL, NULL, + APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY, &behavior_ext_power_driver_api); diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 8f307a6..8b3620e 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -10,7 +10,6 @@ #include <drivers/behavior.h> #include <logging/log.h> #include <zmk/behavior.h> - #include <zmk/matrix.h> #include <zmk/endpoints.h> #include <zmk/event-manager.h> @@ -18,6 +17,7 @@ #include <zmk/events/keycode-state-changed.h> #include <zmk/events/modifiers-state-changed.h> #include <zmk/hid.h> +#include <zmk/behavior.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -40,10 +40,8 @@ struct behavior_hold_tap_behaviors { struct zmk_behavior_binding hold; }; -typedef k_timeout_t (*timer_func)(); - struct behavior_hold_tap_config { - timer_func tapping_term_ms; + int tapping_term_ms; struct behavior_hold_tap_behaviors *behaviors; enum flavor flavor; }; @@ -51,8 +49,10 @@ struct behavior_hold_tap_config { // this data is specific for each hold-tap struct active_hold_tap { s32_t position; + // todo: move these params into the config->behaviors->tap and u32_t param_hold; u32_t param_tap; + s64_t timestamp; bool is_decided; bool is_hold; const struct behavior_hold_tap_config *config; @@ -164,6 +164,7 @@ static struct active_hold_tap *find_hold_tap(u32_t position) { } static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold, u32_t param_tap, + s64_t timestamp, const struct behavior_hold_tap_config *config) { for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) { if (active_hold_taps[i].position != ZMK_BHV_HOLD_TAP_POSITION_NOT_USED) { @@ -175,6 +176,7 @@ static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold, active_hold_taps[i].config = config; active_hold_taps[i].param_hold = param_hold; active_hold_taps[i].param_tap = param_tap; + active_hold_taps[i].timestamp = timestamp; return &active_hold_taps[i]; } return NULL; @@ -253,7 +255,7 @@ static inline char *flavor_str(enum flavor flavor) { return "UNKNOWN FLAVOR"; } -static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment event) { +static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment event_type) { if (hold_tap->is_decided) { return; } @@ -265,11 +267,11 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome switch (hold_tap->config->flavor) { case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED: - decide_hold_preferred(hold_tap, event); + decide_hold_preferred(hold_tap, event_type); case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED: - decide_balanced(hold_tap, event); + decide_balanced(hold_tap, event_type); case ZMK_BHV_HOLD_TAP_FLAVOR_TAP_PREFERRED: - decide_tap_preferred(hold_tap, event); + decide_tap_preferred(hold_tap, event_type); } if (!hold_tap->is_decided) { @@ -277,26 +279,31 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome } LOG_DBG("%d decided %s (%s event %d)", hold_tap->position, hold_tap->is_hold ? "hold" : "tap", - flavor_str(hold_tap->config->flavor), event); + flavor_str(hold_tap->config->flavor), event_type); undecided_hold_tap = NULL; - struct zmk_behavior_binding *behavior; + struct zmk_behavior_binding_event event = { + .position = hold_tap->position, + .timestamp = hold_tap->timestamp, + }; + + struct zmk_behavior_binding binding; if (hold_tap->is_hold) { - behavior = &hold_tap->config->behaviors->hold; - struct device *behavior_device = device_get_binding(behavior->behavior_dev); - behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_hold, - 0); + binding.behavior_dev = hold_tap->config->behaviors->hold.behavior_dev; + binding.param1 = hold_tap->param_hold; + binding.param2 = 0; } else { - behavior = &hold_tap->config->behaviors->tap; - struct device *behavior_device = device_get_binding(behavior->behavior_dev); - behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_tap, - 0); + binding.behavior_dev = hold_tap->config->behaviors->tap.behavior_dev; + binding.param1 = hold_tap->param_tap; + binding.param2 = 0; } + behavior_keymap_binding_pressed(&binding, event); release_captured_events(); } -static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t param_hold, - u32_t param_tap) { +static int on_hold_tap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + struct device *dev = device_get_binding(binding->behavior_dev); const struct behavior_hold_tap_config *cfg = dev->config_info; if (undecided_hold_tap != NULL) { @@ -305,54 +312,69 @@ static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t return 0; } - struct active_hold_tap *hold_tap = store_hold_tap(position, param_hold, param_tap, cfg); + struct active_hold_tap *hold_tap = + store_hold_tap(event.position, binding->param1, binding->param2, event.timestamp, cfg); if (hold_tap == NULL) { LOG_ERR("unable to store hold-tap info, did you press more than %d hold-taps?", ZMK_BHV_HOLD_TAP_MAX_HELD); return 0; } - LOG_DBG("%d new undecided hold_tap", position); + LOG_DBG("%d new undecided hold_tap", event.position); undecided_hold_tap = hold_tap; - k_delayed_work_submit(&hold_tap->work, cfg->tapping_term_ms()); - // todo: once we get timing info for keypresses, start the timer relative to the original - // keypress don't forget to simulate a timer-event before the event after that time was handled. + // if this behavior was queued we have to adjust the timer to only + // wait for the remaining time. + s32_t tapping_term_ms_left = (hold_tap->timestamp + cfg->tapping_term_ms) - k_uptime_get(); + if (tapping_term_ms_left > 0) { + k_delayed_work_submit(&hold_tap->work, K_MSEC(tapping_term_ms_left)); + } return 0; } -static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_t _, u32_t __) { - struct active_hold_tap *hold_tap = find_hold_tap(position); - +static int on_hold_tap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + struct active_hold_tap *hold_tap = find_hold_tap(event.position); if (hold_tap == NULL) { LOG_ERR("ACTIVE_HOLD_TAP_CLEANED_UP_TOO_EARLY"); return 0; } + // If these events were queued, the timer event may be queued too late or not at all. + // We insert a timer event before the TH_KEY_UP event to verify. int work_cancel_result = k_delayed_work_cancel(&hold_tap->work); + if (event.timestamp > (hold_tap->timestamp + hold_tap->config->tapping_term_ms)) { + decide_hold_tap(hold_tap, HT_TIMER_EVENT); + } + decide_hold_tap(hold_tap, HT_KEY_UP); - struct zmk_behavior_binding *behavior; + // todo: set up the binding and data items inside of the active_hold_tap struct + struct zmk_behavior_binding_event sub_behavior_data = { + .position = hold_tap->position, + .timestamp = hold_tap->timestamp, + }; + + struct zmk_behavior_binding sub_behavior_binding; if (hold_tap->is_hold) { - behavior = &hold_tap->config->behaviors->hold; - struct device *behavior_device = device_get_binding(behavior->behavior_dev); - behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_hold, - 0); + sub_behavior_binding.behavior_dev = hold_tap->config->behaviors->hold.behavior_dev; + sub_behavior_binding.param1 = hold_tap->param_hold; + sub_behavior_binding.param2 = 0; } else { - behavior = &hold_tap->config->behaviors->tap; - struct device *behavior_device = device_get_binding(behavior->behavior_dev); - behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_tap, - 0); + sub_behavior_binding.behavior_dev = hold_tap->config->behaviors->tap.behavior_dev; + sub_behavior_binding.param1 = hold_tap->param_tap; + sub_behavior_binding.param2 = 0; } + behavior_keymap_binding_released(&sub_behavior_binding, sub_behavior_data); if (work_cancel_result == -EINPROGRESS) { // let the timer handler clean up // if we'd clear now, the timer may call back for an uninitialized active_hold_tap. - LOG_DBG("%d hold-tap timer work in event queue", position); + LOG_DBG("%d hold-tap timer work in event queue", event.position); hold_tap->work_is_cancelled = true; } else { - LOG_DBG("%d cleaning up hold-tap", position); + LOG_DBG("%d cleaning up hold-tap", event.position); clear_hold_tap(hold_tap); } @@ -382,6 +404,14 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) { } } + // If these events were queued, the timer event may be queued too late or not at all. + // We make a timer decision before the other key events are handled if the timer would + // have run out. + if (ev->timestamp > + (undecided_hold_tap->timestamp + undecided_hold_tap->config->tapping_term_ms)) { + decide_hold_tap(undecided_hold_tap, HT_TIMER_EVENT); + } + if (!ev->state && find_captured_keydown_event(ev->position) == NULL) { // no keydown event has been captured, let it bubble. // we'll catch modifiers later in modifier_state_changed_listener @@ -463,6 +493,7 @@ static int behavior_hold_tap_init(struct device *dev) { struct behavior_hold_tap_data {}; static struct behavior_hold_tap_data behavior_hold_tap_data; +/* todo: get rid of unused param1 and param2. */ #define _TRANSFORM_ENTRY(idx, node) \ { \ .behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \ @@ -473,14 +504,11 @@ static struct behavior_hold_tap_data behavior_hold_tap_data; }, #define KP_INST(n) \ - static k_timeout_t behavior_hold_tap_config_##n##_gettime() { \ - return K_MSEC(DT_INST_PROP(n, tapping_term_ms)); \ - } \ static struct behavior_hold_tap_behaviors behavior_hold_tap_behaviors_##n = { \ .hold = _TRANSFORM_ENTRY(0, n).tap = _TRANSFORM_ENTRY(1, n)}; \ static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \ .behaviors = &behavior_hold_tap_behaviors_##n, \ - .tapping_term_ms = &behavior_hold_tap_config_##n##_gettime, \ + .tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \ .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ }; \ DEVICE_AND_API_INIT(behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \ diff --git a/app/src/behaviors/behavior_key_press.c b/app/src/behaviors/behavior_key_press.c index bbfbe36..923b098 100644 --- a/app/src/behaviors/behavior_key_press.c +++ b/app/src/behaviors/behavior_key_press.c @@ -12,6 +12,7 @@ #include <zmk/event-manager.h> #include <zmk/events/keycode-state-changed.h> +#include <zmk/behavior.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -22,18 +23,24 @@ struct behavior_key_press_data {}; static int behavior_key_press_init(struct device *dev) { return 0; }; -static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t keycode, u32_t _) { +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + struct device *dev = device_get_binding(binding->behavior_dev); const struct behavior_key_press_config *cfg = dev->config_info; - LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode); + LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", event.position, cfg->usage_page, + binding->param1); - return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, keycode, true)); + return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, binding->param1, true)); } -static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t keycode, u32_t _) { +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + struct device *dev = device_get_binding(binding->behavior_dev); const struct behavior_key_press_config *cfg = dev->config_info; - LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode); + LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", event.position, cfg->usage_page, + binding->param1); - return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, keycode, false)); + return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, binding->param1, false)); } static const struct behavior_driver_api behavior_key_press_driver_api = { @@ -47,4 +54,4 @@ static const struct behavior_driver_api behavior_key_press_driver_api = { &behavior_key_press_data_##n, &behavior_key_press_config_##n, APPLICATION, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_key_press_driver_api); -DT_INST_FOREACH_STATUS_OKAY(KP_INST)
\ No newline at end of file +DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_momentary_layer.c b/app/src/behaviors/behavior_momentary_layer.c index 80b7165..b1fb14b 100644 --- a/app/src/behaviors/behavior_momentary_layer.c +++ b/app/src/behaviors/behavior_momentary_layer.c @@ -11,6 +11,7 @@ #include <logging/log.h> #include <zmk/keymap.h> +#include <zmk/behavior.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -19,16 +20,16 @@ struct behavior_mo_data {}; static int behavior_mo_init(struct device *dev) { return 0; }; -static int mo_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _) { - LOG_DBG("position %d layer %d", position, layer); - - return zmk_keymap_layer_activate(layer); +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); } -static int mo_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _) { - LOG_DBG("position %d layer %d", position, layer); - - return zmk_keymap_layer_deactivate(layer); +static int mo_keymap_binding_released(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_deactivate(binding->param1); } static const struct behavior_driver_api behavior_mo_driver_api = { diff --git a/app/src/behaviors/behavior_none.c b/app/src/behaviors/behavior_none.c index b548e6f..96ea9d5 100644 --- a/app/src/behaviors/behavior_none.c +++ b/app/src/behaviors/behavior_none.c @@ -11,6 +11,8 @@ #include <drivers/behavior.h> #include <logging/log.h> +#include <zmk/behavior.h> + LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct behavior_none_config {}; @@ -18,13 +20,13 @@ struct behavior_none_data {}; static int behavior_none_init(struct device *dev) { return 0; }; -static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1, - u32_t _param2) { +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { return 0; } -static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1, - u32_t _param2) { +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { return 0; } diff --git a/app/src/behaviors/behavior_reset.c b/app/src/behaviors/behavior_reset.c index 90de20b..d1233a5 100644 --- a/app/src/behaviors/behavior_reset.c +++ b/app/src/behaviors/behavior_reset.c @@ -11,6 +11,8 @@ #include <drivers/behavior.h> #include <logging/log.h> +#include <zmk/behavior.h> + LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct behavior_reset_config { @@ -19,8 +21,9 @@ struct behavior_reset_config { static int behavior_reset_init(struct device *dev) { return 0; }; -static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1, - u32_t _param2) { +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + struct device *dev = device_get_binding(binding->behavior_dev); const struct behavior_reset_config *cfg = dev->config_info; // TODO: Correct magic code for going into DFU? diff --git a/app/src/behaviors/behavior_rgb_underglow.c b/app/src/behaviors/behavior_rgb_underglow.c index 621eab5..2ee6716 100644 --- a/app/src/behaviors/behavior_rgb_underglow.c +++ b/app/src/behaviors/behavior_rgb_underglow.c @@ -12,13 +12,15 @@ #include <dt-bindings/zmk/rgb.h> #include <zmk/rgb_underglow.h> +#include <zmk/keymap.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); static int behavior_rgb_underglow_init(struct device *dev) { return 0; } -static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t action, u32_t _) { - switch (action) { +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + switch (binding->param1) { case RGB_TOG: return zmk_rgb_underglow_toggle(); case RGB_HUI: diff --git a/app/src/behaviors/behavior_sensor_rotate_key_press.c b/app/src/behaviors/behavior_sensor_rotate_key_press.c index 1a0bf03..71c4376 100644 --- a/app/src/behaviors/behavior_sensor_rotate_key_press.c +++ b/app/src/behaviors/behavior_sensor_rotate_key_press.c @@ -23,15 +23,16 @@ struct behavior_sensor_rotate_key_press_data {}; static int behavior_sensor_rotate_key_press_init(struct device *dev) { return 0; }; -static int on_sensor_binding_triggered(struct device *dev, struct device *sensor, - u32_t increment_keycode, u32_t decrement_keycode) { +static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding, + struct device *sensor) { + struct device *dev = device_get_binding(binding->behavior_dev); const struct behavior_sensor_rotate_key_press_config *cfg = dev->config_info; struct sensor_value value; int err; u32_t keycode; struct keycode_state_changed *ev; LOG_DBG("usage_page 0x%02X inc keycode 0x%02X dec keycode 0x%02X", cfg->usage_page, - increment_keycode, decrement_keycode); + binding->param1, binding->param2); err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value); @@ -42,10 +43,10 @@ static int on_sensor_binding_triggered(struct device *dev, struct device *sensor switch (value.val1) { case 1: - keycode = increment_keycode; + keycode = binding->param1; break; case -1: - keycode = decrement_keycode; + keycode = binding->param2; break; default: return -ENOTSUP; diff --git a/app/src/behaviors/behavior_toggle_layer.c b/app/src/behaviors/behavior_toggle_layer.c index 2819451..b3c6961 100644 --- a/app/src/behaviors/behavior_toggle_layer.c +++ b/app/src/behaviors/behavior_toggle_layer.c @@ -11,6 +11,7 @@ #include <logging/log.h> #include <zmk/keymap.h> +#include <zmk/behavior.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -19,15 +20,15 @@ struct behavior_tog_data {}; static int behavior_tog_init(struct device *dev) { return 0; }; -static int tog_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _) { - LOG_DBG("position %d layer %d", position, layer); - - return zmk_keymap_layer_toggle(layer); +static int tog_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_toggle(binding->param1); } -static int tog_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _) { - LOG_DBG("position %d layer %d", position, layer); - +static int tog_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + LOG_DBG("position %d layer %d", event.position, binding->param1); return 0; } diff --git a/app/src/behaviors/behavior_transparent.c b/app/src/behaviors/behavior_transparent.c index f7852f3..cede369 100644 --- a/app/src/behaviors/behavior_transparent.c +++ b/app/src/behaviors/behavior_transparent.c @@ -11,6 +11,8 @@ #include <drivers/behavior.h> #include <logging/log.h> +#include <zmk/behavior.h> + LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct behavior_transparent_config {}; @@ -18,13 +20,13 @@ struct behavior_transparent_data {}; static int behavior_transparent_init(struct device *dev) { return 0; }; -static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1, - u32_t _param2) { +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { return 1; } -static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1, - u32_t _param2) { +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { return 1; } diff --git a/app/src/ble.c b/app/src/ble.c index 49e2b3b..9090582 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -45,10 +45,29 @@ static u8_t passkey_digit = 0; #define PROFILE_COUNT CONFIG_BT_MAX_PAIRED #endif +enum advertising_type { + ZMK_ADV_NONE, + ZMK_ADV_DIR, + ZMK_ADV_CONN, +} advertising_status; + +#define CURR_ADV(adv) (adv << 4) + +#define ZMK_ADV_CONN_NAME \ + BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME, BT_GAP_ADV_FAST_INT_MIN_2, \ + BT_GAP_ADV_FAST_INT_MAX_2, NULL) + static struct zmk_ble_profile profiles[PROFILE_COUNT]; static u8_t active_profile; +#define DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) + static const struct bt_data zmk_ble_ad[] = { +#if !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) + BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), + BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, 0xC1, 0x03), +#endif BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA_BYTES(BT_DATA_UUID16_SOME, #if !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) @@ -92,29 +111,101 @@ void set_profile_address(u8_t index, const bt_addr_le_t *addr) { raise_profile_changed_event(); } -int zmk_ble_adv_pause() { - int err = bt_le_adv_stop(); - if (err) { - LOG_ERR("Failed to stop advertising (err %d)", err); - return err; +bool active_profile_is_connected() { + struct bt_conn *conn; + bt_addr_le_t *addr = zmk_ble_active_profile_addr(); + if (!bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) { + return false; + } else if ((conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, addr)) == NULL) { + return false; } - return 0; -}; + bt_conn_unref(conn); -int zmk_ble_adv_resume() { - LOG_DBG("active_profile %d, directed? %s", active_profile, - active_profile_is_open() ? "no" : "yes"); + return true; +} - int err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); - if (err) { - LOG_ERR("Advertising failed to start (err %d)", err); - return err; +#define CHECKED_ADV_STOP() \ + err = bt_le_adv_stop(); \ + advertising_status = ZMK_ADV_NONE; \ + if (err) { \ + LOG_ERR("Failed to stop advertising (err %d)", err); \ + return err; \ + } + +#define CHECKED_DIR_ADV() \ + addr = zmk_ble_active_profile_addr(); \ + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, addr); \ + if (conn != NULL) { /* TODO: Check status of connection */ \ + LOG_DBG("Skipping advertising, profile host is already connected"); \ + bt_conn_unref(conn); \ + return 0; \ + } \ + err = bt_le_adv_start(BT_LE_ADV_CONN_DIR_LOW_DUTY(addr), zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), \ + NULL, 0); \ + if (err) { \ + LOG_ERR("Advertising failed to start (err %d)", err); \ + return err; \ + } \ + advertising_status = ZMK_ADV_DIR; + +#define CHECKED_OPEN_ADV() \ + err = bt_le_adv_start(ZMK_ADV_CONN_NAME, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); \ + if (err) { \ + LOG_ERR("Advertising failed to start (err %d)", err); \ + return err; \ + } \ + advertising_status = ZMK_ADV_CONN; + +int update_advertising() { + int err = 0; + bt_addr_le_t *addr; + struct bt_conn *conn; + enum advertising_type desired_adv = ZMK_ADV_NONE; + + if (active_profile_is_open() || !active_profile_is_connected()) { + desired_adv = ZMK_ADV_CONN; + } else if (!active_profile_is_connected()) { + desired_adv = ZMK_ADV_CONN; + // Need to fix directed advertising for privacy centrals. See + // https://github.com/zephyrproject-rtos/zephyr/pull/14984 char + // addr_str[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(zmk_ble_active_profile_addr(), addr_str, + // sizeof(addr_str)); + + // LOG_DBG("Directed advertising to %s", log_strdup(addr_str)); + // desired_adv = ZMK_ADV_DIR; + } + LOG_DBG("advertising from %d to %d", advertising_status, desired_adv); + + switch (desired_adv + CURR_ADV(advertising_status)) { + case ZMK_ADV_NONE + CURR_ADV(ZMK_ADV_DIR): + case ZMK_ADV_NONE + CURR_ADV(ZMK_ADV_CONN): + CHECKED_ADV_STOP(); + break; + case ZMK_ADV_DIR + CURR_ADV(ZMK_ADV_DIR): + case ZMK_ADV_DIR + CURR_ADV(ZMK_ADV_CONN): + CHECKED_ADV_STOP(); + CHECKED_DIR_ADV(); + break; + case ZMK_ADV_DIR + CURR_ADV(ZMK_ADV_NONE): + CHECKED_DIR_ADV(); + break; + case ZMK_ADV_CONN + CURR_ADV(ZMK_ADV_DIR): + CHECKED_ADV_STOP(); + CHECKED_OPEN_ADV(); + break; + case ZMK_ADV_CONN + CURR_ADV(ZMK_ADV_NONE): + CHECKED_OPEN_ADV(); + break; } return 0; }; +static void update_advertising_callback(struct k_work *work) { update_advertising(); } + +K_WORK_DEFINE(update_advertising_work, update_advertising_callback); + int zmk_ble_clear_bonds() { LOG_DBG(""); @@ -124,6 +215,8 @@ int zmk_ble_clear_bonds() { set_profile_address(active_profile, BT_ADDR_LE_ANY); } + update_advertising(); + return 0; }; @@ -134,9 +227,13 @@ int zmk_ble_prof_select(u8_t index) { } active_profile = index; - return settings_save_one("ble/active_profile", &active_profile, sizeof(active_profile)); + settings_save_one("ble/active_profile", &active_profile, sizeof(active_profile)); + + update_advertising(); raise_profile_changed_event(); + + return 0; }; int zmk_ble_prof_next() { @@ -234,8 +331,11 @@ static void connected(struct bt_conn *conn, u8_t err) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + advertising_status = ZMK_ADV_NONE; + if (err) { LOG_WRN("Failed to connect to %s (%u)", log_strdup(addr), err); + update_advertising(); return; } @@ -250,6 +350,8 @@ static void connected(struct bt_conn *conn, u8_t err) { if (bt_conn_set_security(conn, BT_SECURITY_L2)) { LOG_ERR("Failed to set security"); } + + update_advertising(); } static void disconnected(struct bt_conn *conn, u8_t reason) { @@ -259,14 +361,9 @@ static void disconnected(struct bt_conn *conn, u8_t reason) { LOG_DBG("Disconnected from %s (reason 0x%02x)", log_strdup(addr), reason); -#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) - // if (bt_addr_le_cmp(&peripheral_addr, BT_ADDR_LE_ANY) && bt_addr_le_cmp(&peripheral_addr, - // bt_conn_get_dst(conn))) { - // zmk_ble_adv_resume(); - // } -#else - // zmk_ble_adv_resume(); -#endif + // We need to do this in a work callback, otherwise the advertising update will still see the + // connection for a profile as active, and not start advertising yet. + k_work_submit(&update_advertising_work); } static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { @@ -361,6 +458,7 @@ static void auth_pairing_complete(struct bt_conn *conn, bool bonded) { #endif /* !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) */ set_profile_address(active_profile, dst); + update_advertising(); }; static struct bt_conn_auth_cb zmk_ble_auth_cb_display = { @@ -383,7 +481,7 @@ static void zmk_ble_ready(int err) { return; } - zmk_ble_adv_resume(); + update_advertising(); } static int zmk_ble_init(struct device *_arg) { diff --git a/app/src/endpoints.c b/app/src/endpoints.c index ae78587..79d294e 100644 --- a/app/src/endpoints.c +++ b/app/src/endpoints.c @@ -6,7 +6,7 @@ #include <zmk/endpoints.h> #include <zmk/hid.h> -#include <zmk/usb_hid.h> +#include <zmk/usb.h> #include <zmk/hog.h> #include <logging/log.h> diff --git a/app/src/events/ble_active_profile_changed.c b/app/src/events/ble_active_profile_changed.c index a270a14..06988e2 100644 --- a/app/src/events/ble_active_profile_changed.c +++ b/app/src/events/ble_active_profile_changed.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Peter Johanson <peter@peterjohanson.com> + * Copyright (c) 2020 The ZMK Contributors * * SPDX-License-Identifier: MIT */ diff --git a/app/src/ext_power_generic.c b/app/src/ext_power_generic.c new file mode 100644 index 0000000..4817030 --- /dev/null +++ b/app/src/ext_power_generic.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_ext_power_generic + +#include <device.h> +#include <init.h> +#include <drivers/gpio.h> +#include <drivers/ext_power.h> + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +#include <logging/log.h> +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct ext_power_generic_config { + const char *label; + const u8_t pin; + const u8_t flags; +}; + +struct ext_power_generic_data { + struct device *gpio; + bool status; +}; + +static int ext_power_generic_enable(struct device *dev) { + struct ext_power_generic_data *data = dev->driver_data; + const struct ext_power_generic_config *config = dev->config_info; + + if (gpio_pin_set(data->gpio, config->pin, 1)) { + LOG_WRN("Failed to set ext-power control pin"); + return -EIO; + } + data->status = true; + return 0; +} + +static int ext_power_generic_disable(struct device *dev) { + struct ext_power_generic_data *data = dev->driver_data; + const struct ext_power_generic_config *config = dev->config_info; + + if (gpio_pin_set(data->gpio, config->pin, 0)) { + LOG_WRN("Failed to clear ext-power control pin"); + return -EIO; + } + data->status = false; + return 0; +} + +static int ext_power_generic_get(struct device *dev) { + struct ext_power_generic_data *data = dev->driver_data; + return data->status; +} + +static int ext_power_generic_init(struct device *dev) { + struct ext_power_generic_data *data = dev->driver_data; + const struct ext_power_generic_config *config = dev->config_info; + + data->gpio = device_get_binding(config->label); + if (data->gpio == NULL) { + LOG_ERR("Failed to get ext-power control device"); + return -EINVAL; + } + + if (gpio_pin_configure(data->gpio, config->pin, config->flags | GPIO_OUTPUT)) { + LOG_ERR("Failed to configure ext-power control pin"); + return -EIO; + } + + return 0; +} + +static const struct ext_power_generic_config config = { + .label = DT_INST_GPIO_LABEL(0, control_gpios), + .pin = DT_INST_GPIO_PIN(0, control_gpios), + .flags = DT_INST_GPIO_FLAGS(0, control_gpios)}; + +static struct ext_power_generic_data data = {.status = false}; + +static const struct ext_power_api api = {.enable = ext_power_generic_enable, + .disable = ext_power_generic_disable, + .get = ext_power_generic_get}; + +DEVICE_AND_API_INIT(ext_power_generic, DT_INST_LABEL(0), ext_power_generic_init, &data, &config, + APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &api); + +#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/hog.c b/app/src/hog.c index 11349ac..bcd652d 100644 --- a/app/src/hog.c +++ b/app/src/hog.c @@ -164,8 +164,10 @@ int zmk_hog_send_keypad_report(struct zmk_hid_keypad_report_body *report) { LOG_DBG("Sending to NULL? %s", conn == NULL ? "yes" : "no"); - return bt_gatt_notify(conn, &hog_svc.attrs[5], report, - sizeof(struct zmk_hid_keypad_report_body)); + int err = + bt_gatt_notify(conn, &hog_svc.attrs[5], report, sizeof(struct zmk_hid_keypad_report_body)); + bt_conn_unref(conn); + return err; }; int zmk_hog_send_consumer_report(struct zmk_hid_consumer_report_body *report) { @@ -174,6 +176,8 @@ int zmk_hog_send_consumer_report(struct zmk_hid_consumer_report_body *report) { return -ENOTCONN; } - return bt_gatt_notify(conn, &hog_svc.attrs[10], report, - sizeof(struct zmk_hid_consumer_report_body)); + int err = bt_gatt_notify(conn, &hog_svc.attrs[10], report, + sizeof(struct zmk_hid_consumer_report_body)); + bt_conn_unref(conn); + return err; }; diff --git a/app/src/keymap.c b/app/src/keymap.c index a87ce04..74fe60d 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -104,9 +104,14 @@ bool is_active_layer(u8_t layer, u32_t layer_state) { return (layer_state & BIT(layer)) == BIT(layer) || layer == zmk_keymap_layer_default; } -int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed) { +int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed, s64_t timestamp) { struct zmk_behavior_binding *binding = &zmk_keymap[layer][position]; struct device *behavior; + struct zmk_behavior_binding_event event = { + .layer = layer, + .position = position, + .timestamp = timestamp, + }; LOG_DBG("layer: %d position: %d, binding name: %s", layer, position, log_strdup(binding->behavior_dev)); @@ -119,20 +124,18 @@ int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed) { } if (pressed) { - return behavior_keymap_binding_pressed(behavior, position, binding->param1, - binding->param2); + return behavior_keymap_binding_pressed(binding, event); } else { - return behavior_keymap_binding_released(behavior, position, binding->param1, - binding->param2); + return behavior_keymap_binding_released(binding, event); } } -int zmk_keymap_position_state_changed(u32_t position, bool pressed) { +int zmk_keymap_position_state_changed(u32_t position, bool pressed, s64_t timestamp) { for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--) { u32_t layer_state = pressed ? zmk_keymap_layer_state : zmk_keymap_active_behavior_layer[position]; if (is_active_layer(layer, layer_state)) { - int ret = zmk_keymap_apply_position_state(layer, position, pressed); + int ret = zmk_keymap_apply_position_state(layer, position, pressed, timestamp); zmk_keymap_active_behavior_layer[position] = zmk_keymap_layer_state; @@ -171,8 +174,7 @@ int zmk_keymap_sensor_triggered(u8_t sensor_number, struct device *sensor) { continue; } - ret = behavior_sensor_keymap_binding_triggered(behavior, sensor, binding->param1, - binding->param2); + ret = behavior_sensor_keymap_binding_triggered(binding, sensor); if (ret > 0) { LOG_DBG("behavior processing to continue to next layer"); @@ -194,7 +196,7 @@ int zmk_keymap_sensor_triggered(u8_t sensor_number, struct device *sensor) { int keymap_listener(const struct zmk_event_header *eh) { if (is_position_state_changed(eh)) { const struct position_state_changed *ev = cast_position_state_changed(eh); - return zmk_keymap_position_state_changed(ev->position, ev->state); + return zmk_keymap_position_state_changed(ev->position, ev->state, ev->timestamp); #if ZMK_KEYMAP_HAS_SENSORS } else if (is_sensor_event(eh)) { const struct sensor_event *ev = cast_sensor_event(eh); diff --git a/app/src/kscan.c b/app/src/kscan.c index 0046f5c..8575e70 100644 --- a/app/src/kscan.c +++ b/app/src/kscan.c @@ -52,6 +52,7 @@ void zmk_kscan_process_msgq(struct k_work *item) { pos_ev = new_position_state_changed(); pos_ev->state = pressed; pos_ev->position = position; + pos_ev->timestamp = k_uptime_get(); ZMK_EVENT_RAISE(pos_ev); } } diff --git a/app/src/kscan_composite.c b/app/src/kscan_composite.c index 0249140..f8e8d60 100644 --- a/app/src/kscan_composite.c +++ b/app/src/kscan_composite.c @@ -38,8 +38,7 @@ struct kscan_composite_data { }; static int kscan_composite_enable_callback(struct device *dev) { - for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); - i++) { + for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; kscan_enable_callback(device_get_binding(cfg->label)); @@ -48,8 +47,7 @@ static int kscan_composite_enable_callback(struct device *dev) { } static int kscan_composite_disable_callback(struct device *dev) { - for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); - i++) { + for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; kscan_disable_callback(device_get_binding(cfg->label)); @@ -63,8 +61,7 @@ static void kscan_composite_child_callback(struct device *child_dev, u32_t row, struct device *dev = device_get_binding(DT_INST_LABEL(0)); struct kscan_composite_data *data = dev->driver_data; - for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); - i++) { + for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; if (device_get_binding(cfg->label) != child_dev) { @@ -82,8 +79,7 @@ static int kscan_composite_configure(struct device *dev, kscan_callback_t callba return -EINVAL; } - for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); - i++) { + for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) { const struct kscan_composite_child_config *cfg = &kscan_composite_children[i]; kscan_config(device_get_binding(cfg->label), &kscan_composite_child_callback); diff --git a/app/src/main.c b/app/src/main.c index dca923e..0551356 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -15,16 +15,25 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL); #include <zmk/matrix.h> #include <zmk/kscan.h> #include <zmk/display.h> +#include <drivers/ext_power.h> #define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID) void main(void) { + struct device *ext_power; LOG_INF("Welcome to ZMK!\n"); if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) { return; } + // Enable the external VCC output + ext_power = device_get_binding("EXT_POWER"); + if (ext_power != NULL) { + const struct ext_power_api *ext_power_api = ext_power->driver_api; + ext_power_api->enable(ext_power); + } + #ifdef CONFIG_ZMK_DISPLAY zmk_display_init(); diff --git a/app/src/power.c b/app/src/power.c new file mode 100644 index 0000000..73b3f12 --- /dev/null +++ b/app/src/power.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include <zephyr.h> +#include <kernel.h> +#include <power/power.h> + +#include <logging/log.h> + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include <zmk/usb.h> +#include <zmk/event-manager.h> +#include <zmk/events/position-state-changed.h> +#include <zmk/events/sensor-event.h> + +static u32_t power_last_uptime; + +#define MAX_IDLE_MS CONFIG_ZMK_IDLE_SLEEP_TIMEOUT + +bool is_usb_power_present() { +#ifdef CONFIG_USB + enum usb_dc_status_code usb_status = zmk_usb_get_status(); + switch (usb_status) { + case USB_DC_DISCONNECTED: + case USB_DC_UNKNOWN: + return false; + default: + return true; + } +#else + return false; +#endif /* CONFIG_USB */ +} + +enum power_states sys_pm_policy_next_state(s32_t ticks) { +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP_STATES +#ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_1 + s32_t current = k_uptime_get(); + if (power_last_uptime > 0 && !is_usb_power_present() && + current - power_last_uptime > MAX_IDLE_MS) { + return SYS_POWER_STATE_DEEP_SLEEP_1; + } +#endif /* CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_1 */ +#endif /* CONFIG_SYS_POWER_DEEP_SLEEP_STATES */ + + return SYS_POWER_STATE_ACTIVE; +} + +int power_event_listener(const struct zmk_event_header *eh) { + power_last_uptime = k_uptime_get(); + + return 0; +} + +int power_init() { + power_last_uptime = k_uptime_get(); + + return 0; +} + +ZMK_LISTENER(power, power_event_listener); +ZMK_SUBSCRIPTION(power, position_state_changed); +ZMK_SUBSCRIPTION(power, sensor_event); + +SYS_INIT(power_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
\ No newline at end of file diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index cb1b68b..ed52ba0 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -60,6 +60,7 @@ static u8_t split_central_notify_func(struct bt_conn *conn, struct bt_gatt_subsc struct position_state_changed *pos_ev = new_position_state_changed(); pos_ev->position = position; pos_ev->state = pressed; + pos_ev->timestamp = k_uptime_get(); LOG_DBG("Trigger key position state change for %d", position); ZMK_EVENT_RAISE(pos_ev); diff --git a/app/src/usb_hid.c b/app/src/usb.c index 530ffea..434b3d4 100644 --- a/app/src/usb_hid.c +++ b/app/src/usb.c @@ -18,6 +18,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); static enum usb_dc_status_code usb_status = USB_DC_UNKNOWN; +#ifdef CONFIG_ZMK_USB + static struct device *hid_dev; static K_SEM_DEFINE(hid_sem, 1, 1); @@ -49,11 +51,16 @@ int zmk_usb_hid_send_report(const u8_t *report, size_t len) { } } -void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params) { usb_status = status; }; +#endif /* CONFIG_ZMK_USB */ + +enum usb_dc_status_code zmk_usb_get_status() { return usb_status; } -static int zmk_usb_hid_init(struct device *_arg) { +void usb_status_cb(enum usb_dc_status_code status, const u8_t *params) { usb_status = status; }; + +static int zmk_usb_init(struct device *_arg) { int usb_enable_ret; +#ifdef CONFIG_ZMK_USB hid_dev = device_get_binding("HID_0"); if (hid_dev == NULL) { LOG_ERR("Unable to locate HID device"); @@ -64,7 +71,9 @@ static int zmk_usb_hid_init(struct device *_arg) { usb_hid_init(hid_dev); - usb_enable_ret = usb_enable(usb_hid_status_cb); +#endif /* CONFIG_ZMK_USB */ + + usb_enable_ret = usb_enable(usb_status_cb); if (usb_enable_ret != 0) { LOG_ERR("Unable to enable USB"); @@ -74,4 +83,4 @@ static int zmk_usb_hid_init(struct device *_arg) { return 0; } -SYS_INIT(zmk_usb_hid_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY); +SYS_INIT(zmk_usb_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY); |