diff options
-rw-r--r-- | app/CMakeLists.txt | 2 | ||||
-rw-r--r-- | app/boards/arm/nice_nano/nice_nano.dts | 7 | ||||
-rw-r--r-- | app/dts/behaviors.dtsi | 2 | ||||
-rw-r--r-- | app/dts/behaviors/none.dtsi | 15 | ||||
-rw-r--r-- | app/dts/behaviors/toggle_layer.dtsi | 15 | ||||
-rw-r--r-- | app/dts/bindings/behaviors/zmk,behavior-none.yaml | 8 | ||||
-rw-r--r-- | app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml | 8 | ||||
-rw-r--r-- | app/include/zmk/keymap.h | 2 | ||||
-rw-r--r-- | app/src/behaviors/behavior_none.c | 48 | ||||
-rw-r--r-- | app/src/behaviors/behavior_toggle_layer.c | 49 | ||||
-rw-r--r-- | app/src/ble.c | 12 | ||||
-rw-r--r-- | app/src/keymap.c | 15 | ||||
-rw-r--r-- | app/src/usb_hid.c | 36 | ||||
-rw-r--r-- | docs/docs/behavior/key-press.md | 2 | ||||
-rw-r--r-- | docs/docs/behavior/layers.md | 51 | ||||
-rw-r--r-- | docs/docs/behavior/misc.md | 41 | ||||
-rw-r--r-- | docs/docs/behavior/mod-tap.md | 29 | ||||
-rw-r--r-- | docs/sidebars.js | 2 |
18 files changed, 329 insertions, 15 deletions
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 1f6de5d..054f84a 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -38,7 +38,9 @@ target_sources(app PRIVATE src/behaviors/behavior_key_press.c) target_sources(app PRIVATE src/behaviors/behavior_reset.c) target_sources(app PRIVATE src/behaviors/behavior_mod_tap.c) target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c) +target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c) target_sources(app PRIVATE src/behaviors/behavior_transparent.c) +target_sources(app PRIVATE src/behaviors/behavior_none.c) target_sources(app PRIVATE src/behaviors/behavior_sensor_rotate_key_press.c) target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/behaviors/behavior_rgb_underglow.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c) diff --git a/app/boards/arm/nice_nano/nice_nano.dts b/app/boards/arm/nice_nano/nice_nano.dts index 7c676e3..c1b9cc0 100644 --- a/app/boards/arm/nice_nano/nice_nano.dts +++ b/app/boards/arm/nice_nano/nice_nano.dts @@ -39,13 +39,6 @@ status = "okay"; }; -&uart0 { - compatible = "nordic,nrf-uart"; - current-speed = <115200>; - tx-pin = <6>; - rx-pin = <8>; -}; - &i2c0 { compatible = "nordic,nrf-twi"; sda-pin = <17>; diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index 04e42b6..4cfb7a0 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -1,7 +1,9 @@ #include <behaviors/key_press.dtsi> #include <behaviors/transparent.dtsi> +#include <behaviors/none.dtsi> #include <behaviors/mod_tap.dtsi> #include <behaviors/momentary_layer.dtsi> +#include <behaviors/toggle_layer.dtsi> #include <behaviors/reset.dtsi> #include <behaviors/sensor_rotate_key_press.dtsi> #include <behaviors/rgb_underglow.dtsi>
\ No newline at end of file diff --git a/app/dts/behaviors/none.dtsi b/app/dts/behaviors/none.dtsi new file mode 100644 index 0000000..e84ed49 --- /dev/null +++ b/app/dts/behaviors/none.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020 Pete Johanson + * + * SPDX-License-Identifier: MIT + */ + +/ { + behaviors { + none: behavior_none { + compatible = "zmk,behavior-none"; + label = "NONE"; + #binding-cells = <0>; + }; + }; +}; diff --git a/app/dts/behaviors/toggle_layer.dtsi b/app/dts/behaviors/toggle_layer.dtsi new file mode 100644 index 0000000..86a050d --- /dev/null +++ b/app/dts/behaviors/toggle_layer.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020 Cody McGinnis <brainwart@gmail.com> + * + * SPDX-License-Identifier: MIT + */ + + / { + behaviors { + tog: behavior_toggle_layer { + compatible = "zmk,behavior-toggle-layer"; + label = "TOGGLE_LAYER"; + #binding-cells = <1>; + }; + }; +}; diff --git a/app/dts/bindings/behaviors/zmk,behavior-none.yaml b/app/dts/bindings/behaviors/zmk,behavior-none.yaml new file mode 100644 index 0000000..9c66c94 --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-none.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2020, Pete Johanson +# SPDX-License-Identifier: MIT + +description: None Binding Behavior + +compatible: "zmk,behavior-none" + +include: zero_param.yaml diff --git a/app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml b/app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml new file mode 100644 index 0000000..065949f --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2020, Cody McGinnis <brainwart@gmail.com> +# SPDX-License-Identifier: MIT + +description: Toggle Layer + +compatible: "zmk,behavior-toggle-layer" + +include: one_param.yaml diff --git a/app/include/zmk/keymap.h b/app/include/zmk/keymap.h index 4a6bb37..c1f6393 100644 --- a/app/include/zmk/keymap.h +++ b/app/include/zmk/keymap.h @@ -1,6 +1,8 @@ #pragma once +bool zmk_keymap_layer_active(u8_t layer); int zmk_keymap_layer_activate(u8_t layer); int zmk_keymap_layer_deactivate(u8_t layer); +int zmk_keymap_layer_toggle(u8_t layer); int zmk_keymap_position_state_changed(u32_t position, bool pressed); diff --git a/app/src/behaviors/behavior_none.c b/app/src/behaviors/behavior_none.c new file mode 100644 index 0000000..7e77e54 --- /dev/null +++ b/app/src/behaviors/behavior_none.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 Peter Johanson <peter@peterjohanson.com> + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_none + +#include <device.h> +#include <power/reboot.h> +#include <drivers/behavior.h> +#include <logging/log.h> + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct behavior_none_config { }; +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) +{ + return 1; +} + +static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1, u32_t _param2) +{ + return 1; +} + +static const struct behavior_driver_api behavior_none_driver_api = { + .binding_pressed = on_keymap_binding_pressed, + .binding_released = on_keymap_binding_released, +}; + + +static const struct behavior_none_config behavior_none_config = {}; + +static struct behavior_none_data behavior_none_data; + +DEVICE_AND_API_INIT(behavior_none, DT_INST_LABEL(0), behavior_none_init, + &behavior_none_data, + &behavior_none_config, + APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &behavior_none_driver_api);
\ No newline at end of file diff --git a/app/src/behaviors/behavior_toggle_layer.c b/app/src/behaviors/behavior_toggle_layer.c new file mode 100644 index 0000000..13f4a29 --- /dev/null +++ b/app/src/behaviors/behavior_toggle_layer.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 Cody McGinnis <brainwart@gmail.com> + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_toggle_layer + +#include <device.h> +#include <drivers/behavior.h> +#include <logging/log.h> + +#include <zmk/keymap.h> + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct behavior_tog_config { }; +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 _) +{ + return zmk_keymap_layer_toggle(layer); +} + +static int tog_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _) +{ + return 0; +} + +static const struct behavior_driver_api behavior_tog_driver_api = { + .binding_pressed = tog_keymap_binding_pressed, + .binding_released = tog_keymap_binding_released, +}; + +static const struct behavior_tog_config behavior_tog_config = {}; + +static struct behavior_tog_data behavior_tog_data; + +DEVICE_AND_API_INIT(behavior_tog, DT_INST_LABEL(0), behavior_tog_init, + &behavior_tog_data, + &behavior_tog_config, + APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &behavior_tog_driver_api); diff --git a/app/src/ble.c b/app/src/ble.c index 686a536..0e96d16 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -28,6 +28,16 @@ static struct bt_conn *auth_passkey_entry_conn; static u8_t passkey_entries[6] = {0, 0, 0, 0, 0, 0}; static u8_t passkey_digit = 0; +#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) +#define ZMK_ADV_PARAMS BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \ + BT_LE_ADV_OPT_USE_NAME | \ + BT_LE_ADV_OPT_ONE_TIME, \ + BT_GAP_ADV_FAST_INT_MIN_2, \ + BT_GAP_ADV_FAST_INT_MAX_2, NULL) +#else +#define ZMK_ADV_PARAMS BT_LE_ADV_CONN_NAME +#endif + static void connected(struct bt_conn *conn, u8_t err) { char addr[BT_ADDR_LE_STR_LEN]; @@ -159,7 +169,7 @@ static void zmk_ble_ready(int err) return; } - err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); + err = bt_le_adv_start(ZMK_ADV_PARAMS, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); if (err) { LOG_ERR("Advertising failed to start (err %d)", err); diff --git a/app/src/keymap.c b/app/src/keymap.c index ff494f7..ee6e370 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -76,6 +76,11 @@ static struct zmk_behavior_binding zmk_sensor_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_ WRITE_BIT(zmk_keymap_layer_state, layer, state); \ return 0; +bool zmk_keymap_layer_active(u8_t layer) +{ + return (zmk_keymap_layer_state & (BIT(layer))) == (BIT(layer)); +}; + int zmk_keymap_layer_activate(u8_t layer) { SET_LAYER_STATE(layer, true); @@ -86,6 +91,16 @@ int zmk_keymap_layer_deactivate(u8_t layer) SET_LAYER_STATE(layer, false); }; +int zmk_keymap_layer_toggle(u8_t layer) +{ + if (zmk_keymap_layer_active(layer)) + { + return zmk_keymap_layer_deactivate(layer); + } + + return zmk_keymap_layer_activate(layer); +}; + bool is_active_position(u32_t position, u8_t layer) { return (zmk_keymap_layer_state & BIT(layer)) == BIT(layer) diff --git a/app/src/usb_hid.c b/app/src/usb_hid.c index 4c6dd4b..784fc25 100644 --- a/app/src/usb_hid.c +++ b/app/src/usb_hid.c @@ -11,18 +11,42 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -static enum usb_dc_status_code usb_status; +static enum usb_dc_status_code usb_status = USB_DC_UNKNOWN; static struct device *hid_dev; +static K_SEM_DEFINE(hid_sem, 1, 1); + +static void in_ready_cb(void) +{ + k_sem_give(&hid_sem); +} + +static const struct hid_ops ops = +{ + .int_in_ready = in_ready_cb, +}; + int zmk_usb_hid_send_report(const u8_t *report, size_t len) { - if (usb_status == USB_DC_SUSPEND) - { + switch(usb_status) { + case USB_DC_SUSPEND: return usb_wakeup_request(); + case USB_DC_ERROR: + case USB_DC_RESET: + case USB_DC_DISCONNECTED: + case USB_DC_UNKNOWN: + return -ENODEV; + default: + k_sem_take(&hid_sem, K_MSEC(30)); + int err = hid_int_ep_write(hid_dev, report, len, NULL); + + if (err) { + k_sem_give(&hid_sem); + } + + return err; } - - return hid_int_ep_write(hid_dev, report, len, NULL); } void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params) @@ -43,7 +67,7 @@ static int zmk_usb_hid_init(struct device *_arg) usb_hid_register_device(hid_dev, zmk_hid_report_desc, sizeof(zmk_hid_report_desc), - NULL); + &ops); usb_hid_init(hid_dev); diff --git a/docs/docs/behavior/key-press.md b/docs/docs/behavior/key-press.md index 08296bb..1ae7e31 100644 --- a/docs/docs/behavior/key-press.md +++ b/docs/docs/behavior/key-press.md @@ -4,7 +4,7 @@ title: Key Presses ## Summary -The most basic of behaiors, is the ability to send certain keycode presses and releases in response to activating +The most basic of behaviors, is the ability to send certain keycode presses and releases in response to activating a certain key. For reference on keycode values, see the [USB HID Usage Tables](https://www.usb.org/document-library/hid-usage-tables-12). diff --git a/docs/docs/behavior/layers.md b/docs/docs/behavior/layers.md index 2388caf..3e520ca 100644 --- a/docs/docs/behavior/layers.md +++ b/docs/docs/behavior/layers.md @@ -39,3 +39,54 @@ Example: ``` &mo LOWER ``` + +## Toggle Layer + +The "toggle layer" behavior allows you to enable a layer until the layer is manually disabled. + +### Behavior Binding + +- Reference: `&tog` +- Parameter: The layer number to enable/disable, e.g. `1` + +Example: + +``` +&tog LOWER +``` + +"Toggle layer" for a : +``` +#define DEFAULT 0 +#define NAVI 1 + +#define NONE 0 + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { + bindings = < + &tog NAVI &kp KDIV &kp KMLT &kp KMIN + &kp NUM_7 &kp NUM_8 &kp NUM_9 &kp KPLS + &kp NUM_4 &kp NUM_5 &kp NUM_6 &kp KPLS + &kp NUM_1 &kp NUM_2 &kp NUM_3 &kp RET + &kp NUM_0 &kp NUM_0 &kp DOT &kp RET + >; + }; + + nav_layer { + bindings = < + &tog NAVI &kp KDIV &kp KMLT &kp KMIN + &kp HOME &kp UARW &kp PGUP &kp KPLS + &kp LARW &none &kp RARW &kp KPLS + &kp END &kp DARW &kp PGDN &kp RET + &kp INS &kp INS &kp DEL &kp RET + >; + }; + }; +}; +``` + +It is possible to use "toggle layer" to have keys that raise and lower the layers as well.
\ No newline at end of file diff --git a/docs/docs/behavior/misc.md b/docs/docs/behavior/misc.md new file mode 100644 index 0000000..799c91c --- /dev/null +++ b/docs/docs/behavior/misc.md @@ -0,0 +1,41 @@ +--- +title: Miscellaneous +--- + +## Summary + +There are a few miscellaneous behaviors that are helpful when working with layers in keymaps, +in particular, with handling what happens in higher layers, and if events are passed to +the next layer or not + +## Transparent + +The transparent behavior simply ignores key position presses/releases, so they will be +passed down to the next active layer in the stack. + +### Behavior Binding + +- Reference: `&trans` +- Parameters: None + +Example: + +``` +&trans +``` + +## None + +The none behavior simply swallows and stops key position presses/releases, so they will **not** +be passed down to the next active layer in the stack. + +### Behavior Binding + +- Reference: `&none` +- Parameters: None + +Example: + +``` +&none +``` diff --git a/docs/docs/behavior/mod-tap.md b/docs/docs/behavior/mod-tap.md new file mode 100644 index 0000000..cae667e --- /dev/null +++ b/docs/docs/behavior/mod-tap.md @@ -0,0 +1,29 @@ +--- +title: Mod-Tap +--- + +## Summary + +The Mod-Tap behavior allows varying the effect of pressing and releasing a key position depending +on whether it is used with other simultaneous key presses at the same time. + +If pressed and released independently, the Mod-Tap behavior will send the press and release events +for the configure keycode. If pressed and held while another key is pressed and released, then +the configured modifiers will be applied to that _other_ key press, and no press will be generated +on the release of the Mod-Tap key. + +## Mod-Tap + +The Mod-Tap behavior either acts as a held modifier, or as a tapped keycode. + +### Behavior Binding + +- Reference: `&mt` +- Parameter #1: The modifiers to be used when activating as a modifier, e.g. `MOD_LSFT` +- Parameter #2: The keycode to sent when used as a tap, e.g. `A`, `B`. + +Example: + +``` +&mt MOD_LSFT A +``` diff --git a/docs/sidebars.js b/docs/sidebars.js index 1bd0358..be02a65 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -10,6 +10,8 @@ module.exports = { Behaviors: [ "behavior/key-press", "behavior/layers", + "behavior/misc", + "behavior/mod-tap", "behavior/lighting", ], Development: [ |