This commit is contained in:
Nick Conway 2023-06-06 14:13:45 -04:00 committed by GitHub
commit ab05967964
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 197 additions and 0 deletions

View file

@ -18,6 +18,8 @@ on:
default: "bin" default: "bin"
required: false required: false
type: string type: string
artifact_name:
description: "Artifact output file name"
archive_name: archive_name:
description: "Archive output file name" description: "Archive output file name"
default: "firmware" default: "firmware"

View file

@ -47,6 +47,8 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c) target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_mod_morph.c) target_sources(app PRIVATE src/behaviors/behavior_mod_morph.c)
target_sources(app PRIVATE src/behaviors/behavior_outputs.c) target_sources(app PRIVATE src/behaviors/behavior_outputs.c)
target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_LAST_DEVICE app PRIVATE src/behaviors/behavior_last_device.c)
target_sources(app PRIVATE src/behaviors/behavior_tap_dance.c)
target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c) target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_to_layer.c) target_sources(app PRIVATE src/behaviors/behavior_to_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_transparent.c) target_sources(app PRIVATE src/behaviors/behavior_transparent.c)

View file

@ -524,6 +524,12 @@ choice CBPRINTF_IMPLEMENTATION
endchoice endchoice
DT_COMPAT_ZMK_BEHAVIOR_LAST_DEVICE := zmk,behavior-last-device
config ZMK_BEHAVIOR_LAST_DEVICE
bool
default $(dt_compat_enabled,$(DT_COMPAT_ZMK_BEHAVIOR_LAST_DEVICE))
module = ZMK module = ZMK
module-str = zmk module-str = zmk
source "subsys/logging/Kconfig.template.log_config" source "subsys/logging/Kconfig.template.log_config"

View file

@ -0,0 +1,29 @@
#
# Copyright (c) 2020 Geanix ApS
#
# SPDX-License-Identifier: Apache-2.0
#
description: >
This is a representation of the Microchip MCP23017 I2C Gpio Expander.
compatible: "microchip,mcp23017"
include: [gpio-controller.yaml, i2c-device.yaml]
properties:
label:
required: true
"#gpio-cells":
const: 2
ngpios:
type: int
required: true
const: 16
description: Number of gpios supported
gpio-cells:
- pin
- flags

View file

@ -15,6 +15,7 @@
#include <behaviors/bluetooth.dtsi> #include <behaviors/bluetooth.dtsi>
#include <behaviors/ext_power.dtsi> #include <behaviors/ext_power.dtsi>
#include <behaviors/outputs.dtsi> #include <behaviors/outputs.dtsi>
#include <behaviors/last_device.dtsi>
#include <behaviors/caps_word.dtsi> #include <behaviors/caps_word.dtsi>
#include <behaviors/key_repeat.dtsi> #include <behaviors/key_repeat.dtsi>
#include <behaviors/backlight.dtsi> #include <behaviors/backlight.dtsi>

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <dt-bindings/zmk/keys.h>
/ {
behaviors {
/omit-if-no-ref/ last_dev: last_device {
compatible = "zmk,behavior-last-device";
label = "LAST_DEVICE";
#binding-cells = <0>;
};
};
};

View file

@ -0,0 +1,8 @@
# Copyright (c) 2022 The ZMK Contributors
# SPDX-License-Identifier: MIT
description: Last Device Behavior
compatible: "zmk,behavior-last-device"
include: zero_param.yaml

View file

@ -16,4 +16,5 @@ properties:
description: The default time to wait (in milliseconds) before triggering the next behavior in the macro bindings list. description: The default time to wait (in milliseconds) before triggering the next behavior in the macro bindings list.
tap-ms: tap-ms:
type: int type: int
default: 100
description: The default time to wait (in milliseconds) between the press and release events on a tapped macro behavior binding description: The default time to wait (in milliseconds) between the press and release events on a tapped macro behavior binding

View file

@ -25,8 +25,10 @@ int zmk_ble_prof_next();
int zmk_ble_prof_prev(); int zmk_ble_prof_prev();
int zmk_ble_prof_select(uint8_t index); int zmk_ble_prof_select(uint8_t index);
int zmk_ble_last_profile_index();
int zmk_ble_active_profile_index(); int zmk_ble_active_profile_index();
bt_addr_le_t *zmk_ble_active_profile_addr(); bt_addr_le_t *zmk_ble_active_profile_addr();
bool zmk_ble_profile_is_open(uint8_t profile);
bool zmk_ble_active_profile_is_open(); bool zmk_ble_active_profile_is_open();
bool zmk_ble_active_profile_is_connected(); bool zmk_ble_active_profile_is_connected();
char *zmk_ble_active_profile_name(); char *zmk_ble_active_profile_name();

View file

@ -10,6 +10,8 @@
int zmk_endpoints_select(enum zmk_endpoint endpoint); int zmk_endpoints_select(enum zmk_endpoint endpoint);
int zmk_endpoints_toggle(); int zmk_endpoints_toggle();
enum zmk_endpoint zmk_preferred_endpoint();
enum zmk_endpoint zmk_last_endpoint();
enum zmk_endpoint zmk_endpoints_selected(); enum zmk_endpoint zmk_endpoints_selected();
int zmk_endpoints_send_report(uint16_t usage_page); int zmk_endpoints_send_report(uint16_t usage_page);

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <zephyr/device.h>
#include <drivers/behavior.h>
#include <zephyr/logging/log.h>
#include <zmk/behavior.h>
#include <zmk/ble.h>
#include <zmk/endpoints.h>
#include <zmk/hid.h>
#include <dt-bindings/zmk/hid_usage_pages.h>
#include <zmk/usb_hid.h>
#include <zmk/hog.h>
#include <zmk/event_manager.h>
#include <zmk/events/ble_active_profile_changed.h>
#include <zmk/events/usb_conn_state_changed.h>
#include <zmk/events/endpoint_selection_changed.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#define DT_DRV_COMPAT zmk_behavior_last_device
int8_t last_device;
bool skip_next_endpoint_change = false;
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
if (last_device == -1) {
LOG_DBG("Toggling output");
zmk_endpoints_toggle();
} else {
LOG_DBG("Switching to last ble device: %d", last_device);
zmk_ble_prof_select(last_device);
if (zmk_endpoints_selected() == ZMK_ENDPOINT_USB) {
LOG_DBG("Toggling output");
zmk_endpoints_toggle();
}
}
return ZMK_BEHAVIOR_OPAQUE;
}
static int behavior_last_device_init(const struct device *dev) { return 0; }
static const struct behavior_driver_api behavior_last_device_driver_api = {
.binding_pressed = on_keymap_binding_pressed,
};
static void update_last_device_ble_index(uint8_t profile) {
if (!zmk_ble_profile_is_open(profile)) {
last_device = profile;
LOG_DBG("Last device set to %d", last_device);
}
};
static int last_device_listener(const zmk_event_t *eh) {
if (as_zmk_endpoint_selection_changed(eh) != NULL) {
if (zmk_preferred_endpoint() == zmk_endpoints_selected()) {
if (!skip_next_endpoint_change) {
if (zmk_endpoints_selected() == ZMK_ENDPOINT_USB) {
update_last_device_ble_index(zmk_ble_active_profile_index());
} else {
last_device = -1;
LOG_DBG("Last device set to %d", last_device);
}
} else {
skip_next_endpoint_change = false;
}
} else if (zmk_endpoints_selected() == ZMK_ENDPOINT_BLE &&
zmk_preferred_endpoint() == ZMK_ENDPOINT_USB) {
LOG_DBG("USB disconnected");
update_last_device_ble_index(zmk_ble_last_profile_index());
} else {
LOG_DBG("Skipping next endpoint change");
skip_next_endpoint_change = true;
}
}
if (as_zmk_ble_active_profile_changed(eh) != NULL &&
zmk_endpoints_selected() == ZMK_ENDPOINT_BLE) {
update_last_device_ble_index(zmk_ble_last_profile_index());
}
return 0;
}
ZMK_LISTENER(last_device_listener, last_device_listener);
ZMK_SUBSCRIPTION(last_device_listener, zmk_endpoint_selection_changed);
ZMK_SUBSCRIPTION(last_device_listener, zmk_ble_active_profile_changed);
#define LAST_DEVICE_INST(n) \
DEVICE_DT_INST_DEFINE(n, behavior_last_device_init, NULL, NULL, NULL, APPLICATION, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_last_device_driver_api);
DT_INST_FOREACH_STATUS_OKAY(LAST_DEVICE_INST)

View file

@ -60,6 +60,7 @@ enum advertising_type {
BT_GAP_ADV_FAST_INT_MAX_2, NULL) BT_GAP_ADV_FAST_INT_MAX_2, NULL)
static struct zmk_ble_profile profiles[ZMK_BLE_PROFILE_COUNT]; static struct zmk_ble_profile profiles[ZMK_BLE_PROFILE_COUNT];
static uint8_t last_profile;
static uint8_t active_profile; static uint8_t active_profile;
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
@ -93,6 +94,10 @@ static void raise_profile_changed_event_callback(struct k_work *work) {
K_WORK_DEFINE(raise_profile_changed_event_work, raise_profile_changed_event_callback); K_WORK_DEFINE(raise_profile_changed_event_work, raise_profile_changed_event_callback);
bool zmk_ble_profile_is_open(uint8_t profile) {
return !bt_addr_le_cmp(&profiles[profile].peer, BT_ADDR_LE_ANY);
}
bool zmk_ble_active_profile_is_open() { bool zmk_ble_active_profile_is_open() {
return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY); return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY);
} }
@ -222,6 +227,7 @@ int zmk_ble_clear_bonds() {
return 0; return 0;
}; };
int zmk_ble_last_profile_index() { return last_profile; }
int zmk_ble_active_profile_index() { return active_profile; } int zmk_ble_active_profile_index() { return active_profile; }
#if IS_ENABLED(CONFIG_SETTINGS) #if IS_ENABLED(CONFIG_SETTINGS)
@ -250,6 +256,7 @@ int zmk_ble_prof_select(uint8_t index) {
return 0; return 0;
} }
last_profile = active_profile;
active_profile = index; active_profile = index;
ble_save_profile(); ble_save_profile();

View file

@ -24,6 +24,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#define DEFAULT_ENDPOINT \ #define DEFAULT_ENDPOINT \
COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ZMK_ENDPOINT_BLE), (ZMK_ENDPOINT_USB)) COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ZMK_ENDPOINT_BLE), (ZMK_ENDPOINT_USB))
static enum zmk_endpoint last_endpoint = DEFAULT_ENDPOINT;
static enum zmk_endpoint current_endpoint = DEFAULT_ENDPOINT; static enum zmk_endpoint current_endpoint = DEFAULT_ENDPOINT;
static enum zmk_endpoint preferred_endpoint = static enum zmk_endpoint preferred_endpoint =
ZMK_ENDPOINT_USB; /* Used if multiple endpoints are ready */ ZMK_ENDPOINT_USB; /* Used if multiple endpoints are ready */
@ -62,6 +63,8 @@ int zmk_endpoints_select(enum zmk_endpoint endpoint) {
return 0; return 0;
} }
enum zmk_endpoint zmk_last_endpoint() { return last_endpoint; }
enum zmk_endpoint zmk_preferred_endpoint() { return preferred_endpoint; }
enum zmk_endpoint zmk_endpoints_selected() { return current_endpoint; } enum zmk_endpoint zmk_endpoints_selected() { return current_endpoint; }
int zmk_endpoints_toggle() { int zmk_endpoints_toggle() {
@ -240,6 +243,7 @@ static void update_current_endpoint() {
/* Cancel all current keypresses so keys don't stay held on the old endpoint. */ /* Cancel all current keypresses so keys don't stay held on the old endpoint. */
disconnect_current_endpoint(); disconnect_current_endpoint();
last_endpoint = current_endpoint;
current_endpoint = new_endpoint; current_endpoint = new_endpoint;
LOG_INF("Endpoint changed: %d", current_endpoint); LOG_INF("Endpoint changed: %d", current_endpoint);

View file

@ -0,0 +1,19 @@
---
title: Last Device Behavior
sidebar_label: Reset
---
## Summary
The last device behavior switches to the last connected device, whether it be bluetooth or USB.
### Behavior Binding
- Reference: `&last_dev`
- Parameters: None
Example:
```
&last_dev
```

View file

@ -39,6 +39,7 @@ module.exports = {
"behaviors/reset", "behaviors/reset",
"behaviors/bluetooth", "behaviors/bluetooth",
"behaviors/outputs", "behaviors/outputs",
"behaviors/last-device",
"behaviors/underglow", "behaviors/underglow",
"behaviors/backlight", "behaviors/backlight",
"behaviors/power", "behaviors/power",