Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invoke behaviors with different "locality" #547

Merged
5 changes: 3 additions & 2 deletions app/CMakeLists.txt
Expand Up @@ -23,6 +23,7 @@ zephyr_linker_sources(RODATA include/linker/zmk-events.ld)
# find_package(Zephyr) which defines the target.
target_include_directories(app PRIVATE include)
target_sources_ifdef(CONFIG_ZMK_SLEEP app PRIVATE src/power.c)
target_sources(app PRIVATE src/stdlib.c)
target_sources(app PRIVATE src/activity.c)
target_sources(app PRIVATE src/kscan.c)
target_sources(app PRIVATE src/matrix_transform.c)
Expand All @@ -42,9 +43,10 @@ target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/events/wpm_state_changed.c)
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/ble_active_profile_changed.c)
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/battery_state_changed.c)
target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c)
target_sources(app PRIVATE src/behaviors/behavior_reset.c)
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c)
if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
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_hold_tap.c)
target_sources(app PRIVATE src/behaviors/behavior_sticky_key.c)
target_sources(app PRIVATE src/behaviors/behavior_caps_word.c)
Expand All @@ -57,7 +59,6 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
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_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c)
target_sources(app PRIVATE src/combo.c)
target_sources(app PRIVATE src/conditional_layer.c)
target_sources(app PRIVATE src/keymap.c)
Expand Down
8 changes: 8 additions & 0 deletions app/Kconfig
Expand Up @@ -175,6 +175,14 @@ config ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE
int "Max number of key position state events to queue when received from peripherals"
default 5

config ZMK_BLE_SPLIT_CENTRAL_SPLIT_RUN_STACK_SIZE
int "BLE split central write thread stack size"
default 512

config ZMK_BLE_SPLIT_CENTRAL_SPLIT_RUN_QUEUE_SIZE
int "Max number of behavior run events to queue to send to the peripheral(s)"
default 5

endif

if !ZMK_SPLIT_BLE_ROLE_CENTRAL
Expand Down
4 changes: 2 additions & 2 deletions app/dts/behaviors/ext_power.dtsi
Expand Up @@ -6,9 +6,9 @@

/ {
behaviors {
/omit-if-no-ref/ ext_power: behavior_ext_power {
ext_power: behavior_ext_power {
compatible = "zmk,behavior-ext-power";
label = "EXT_POWER_BEHAVIOR";
label = "EXTPOWER";
#binding-cells = <1>;
};
};
Expand Down
6 changes: 3 additions & 3 deletions app/dts/behaviors/reset.dtsi
Expand Up @@ -8,15 +8,15 @@

/ {
behaviors {
/omit-if-no-ref/ reset: behavior_reset {
reset: behavior_reset {
compatible = "zmk,behavior-reset";
label = "RESET";
#binding-cells = <0>;
};

/omit-if-no-ref/ bootloader: behavior_reset_dfu {
bootloader: behavior_reset_dfu {
compatible = "zmk,behavior-reset";
label = "BOOTLOADER_RESET";
label = "BOOTLOAD";
innovaker marked this conversation as resolved.
Show resolved Hide resolved
type = <RST_UF2>;
#binding-cells = <0>;
};
Expand Down
4 changes: 2 additions & 2 deletions app/dts/behaviors/rgb_underglow.dtsi
Expand Up @@ -6,9 +6,9 @@

/ {
behaviors {
/omit-if-no-ref/ rgb_ug: behavior_rgb_underglow {
rgb_ug: behavior_rgb_underglow {
compatible = "zmk,behavior-rgb-underglow";
label = "RGB_UNDERGLOW";
label = "RGB_UG";
#binding-cells = <2>;
};
};
Expand Down
46 changes: 46 additions & 0 deletions app/include/drivers/behavior.h
Expand Up @@ -8,6 +8,8 @@

#include <zephyr/types.h>
#include <stddef.h>
#include <sys/util.h>
#include <string.h>
#include <device.h>
#include <zmk/keys.h>
#include <zmk/behavior.h>
Expand All @@ -26,7 +28,14 @@ typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_bin
const struct device *sensor,
int64_t timestamp);

enum behavior_locality {
BEHAVIOR_LOCALITY_CENTRAL,
BEHAVIOR_LOCALITY_EVENT_SOURCE,
BEHAVIOR_LOCALITY_GLOBAL
};

__subsystem struct behavior_driver_api {
enum behavior_locality locality;
behavior_keymap_binding_callback_t binding_convert_central_state_dependent_params;
behavior_keymap_binding_callback_t binding_pressed;
behavior_keymap_binding_callback_t binding_released;
Expand Down Expand Up @@ -60,6 +69,28 @@ static inline int z_impl_behavior_keymap_binding_convert_central_state_dependent
return api->binding_convert_central_state_dependent_params(binding, event);
}

/**
* @brief Determine where the behavior should be run
* @param behavior Pointer to the device structure for the driver instance.
*
* @retval Zero if successful.
* @retval Negative errno code if failure.
*/
__syscall int behavior_get_locality(const struct device *behavior,
enum behavior_locality *locality);

static inline int z_impl_behavior_get_locality(const struct device *behavior,
enum behavior_locality *locality) {
if (behavior == NULL) {
return -EINVAL;
}

const struct behavior_driver_api *api = (const struct behavior_driver_api *)behavior->api;
*locality = api->locality;

return 0;
}

/**
* @brief Handle the keymap binding being pressed
* @param dev Pointer to the device structure for the driver instance.
Expand All @@ -75,6 +106,11 @@ __syscall int behavior_keymap_binding_pressed(struct zmk_behavior_binding *bindi
static inline int z_impl_behavior_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
const struct device *dev = device_get_binding(binding->behavior_dev);

if (dev == NULL) {
return -EINVAL;
}

const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;

if (api->binding_pressed == NULL) {
Expand All @@ -98,6 +134,11 @@ __syscall int behavior_keymap_binding_released(struct zmk_behavior_binding *bind
static inline int z_impl_behavior_keymap_binding_released(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
const struct device *dev = device_get_binding(binding->behavior_dev);

if (dev == NULL) {
return -EINVAL;
}

const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;

if (api->binding_released == NULL) {
Expand Down Expand Up @@ -125,6 +166,11 @@ static inline int
z_impl_behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding,
const struct device *sensor, int64_t timestamp) {
const struct device *dev = device_get_binding(binding->behavior_dev);

if (dev == NULL) {
return -EINVAL;
}

const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;

if (api->sensor_binding_triggered == NULL) {
Expand Down
3 changes: 2 additions & 1 deletion app/include/dt-bindings/zmk/rgb.h
Expand Up @@ -17,7 +17,8 @@
#define RGB_SPD_CMD 10
#define RGB_EFF_CMD 11
#define RGB_EFR_CMD 12
#define RGB_COLOR_HSB_CMD 13
#define RGB_EFS_CMD 13
petejohanson marked this conversation as resolved.
Show resolved Hide resolved
#define RGB_COLOR_HSB_CMD 14

#define RGB_TOG RGB_TOG_CMD 0
#define RGB_ON RGB_ON_CMD 0
Expand Down
11 changes: 11 additions & 0 deletions app/include/zmk/ble.h
Expand Up @@ -9,6 +9,17 @@
#include <zmk/keys.h>
#include <zmk/ble/profile.h>

#define ZMK_BLE_IS_CENTRAL \
(IS_ENABLED(CONFIG_ZMK_SPLIT) && IS_ENABLED(CONFIG_ZMK_BLE) && \
IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL))

#if ZMK_BLE_IS_CENTRAL
#define ZMK_BLE_PROFILE_COUNT (CONFIG_BT_MAX_PAIRED - 1)
#define ZMK_BLE_SPLIT_PERIPHERAL_COUNT 1
#else
#define ZMK_BLE_PROFILE_COUNT CONFIG_BT_MAX_PAIRED
#endif

int zmk_ble_clear_bonds();
int zmk_ble_prof_next();
int zmk_ble_prof_prev();
Expand Down
6 changes: 5 additions & 1 deletion app/include/zmk/events/position_state_changed.h
Expand Up @@ -8,10 +8,14 @@

#include <zephyr.h>
#include <zmk/event_manager.h>

#define ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL UINT8_MAX

struct zmk_position_state_changed {
uint8_t source;
uint32_t position;
bool state;
int64_t timestamp;
};

ZMK_EVENT_DECLARE(zmk_position_state_changed);
ZMK_EVENT_DECLARE(zmk_position_state_changed);
5 changes: 4 additions & 1 deletion app/include/zmk/keymap.h
Expand Up @@ -6,6 +6,8 @@

#pragma once

#include <zmk/events/position_state_changed.h>

typedef uint32_t zmk_keymap_layers_state_t;

uint8_t zmk_keymap_layer_default();
Expand All @@ -18,7 +20,8 @@ int zmk_keymap_layer_toggle(uint8_t layer);
int zmk_keymap_layer_to(uint8_t layer);
const char *zmk_keymap_layer_label(uint8_t layer);

int zmk_keymap_position_state_changed(uint32_t position, bool pressed, int64_t timestamp);
int zmk_keymap_position_state_changed(uint8_t source, uint32_t position, bool pressed,
int64_t timestamp);

#define ZMK_KEYMAP_EXTRACT_BINDING(idx, drv_inst) \
{ \
Expand Down
2 changes: 2 additions & 0 deletions app/include/zmk/rgb_underglow.h
Expand Up @@ -17,6 +17,8 @@ int zmk_rgb_underglow_get_state(bool *state);
int zmk_rgb_underglow_on();
int zmk_rgb_underglow_off();
int zmk_rgb_underglow_cycle_effect(int direction);
int zmk_rgb_underglow_calc_effect(int direction);
int zmk_rgb_underglow_select_effect(int effect);
struct zmk_led_hsb zmk_rgb_underglow_calc_hue(int direction);
struct zmk_led_hsb zmk_rgb_underglow_calc_sat(int direction);
struct zmk_led_hsb zmk_rgb_underglow_calc_brt(int direction);
Expand Down
8 changes: 8 additions & 0 deletions app/include/zmk/split/bluetooth/central.h
@@ -0,0 +1,8 @@

#pragma once

#include <bluetooth/addr.h>
#include <zmk/behavior.h>

int zmk_split_bt_invoke_behavior(uint8_t source, struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event, bool state);
14 changes: 14 additions & 0 deletions app/include/zmk/split/bluetooth/service.h
Expand Up @@ -6,5 +6,19 @@

#pragma once

#define ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN 9

struct zmk_split_run_behavior_data {
uint8_t position;
uint8_t state;
uint32_t param1;
uint32_t param2;
} __packed;

struct zmk_split_run_behavior_payload {
struct zmk_split_run_behavior_data data;
char behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN];
} __packed;

int zmk_split_bt_position_pressed(uint8_t position);
int zmk_split_bt_position_released(uint8_t position);
1 change: 1 addition & 0 deletions app/include/zmk/split/bluetooth/uuid.h
Expand Up @@ -15,3 +15,4 @@
#define ZMK_BT_SPLIT_UUID(num) BT_UUID_128_ENCODE(num, 0x0096, 0x7107, 0xc967, 0xc5cfb1c2482a)
#define ZMK_SPLIT_BT_SERVICE_UUID ZMK_BT_SPLIT_UUID(0x00000000)
#define ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID ZMK_BT_SPLIT_UUID(0x00000001)
#define ZMK_SPLIT_BT_CHAR_RUN_BEHAVIOR_UUID ZMK_BT_SPLIT_UUID(0x00000002)
19 changes: 19 additions & 0 deletions app/include/zmk/stdlib.h
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <stdlib.h> /* for size_t */

/*
* ANSI C version of strlcpy
* Based on the NetBSD strlcpy man page.
*
* Nathan Myers <ncm-nospam@cantrip.org>, 2003/06/03
* Placed in the public domain.
*/

size_t strlcpy(char *dst, const char *src, size_t size);
1 change: 1 addition & 0 deletions app/src/behaviors/behavior_ext_power.c
Expand Up @@ -71,6 +71,7 @@ static const struct behavior_driver_api behavior_ext_power_driver_api = {
on_keymap_binding_convert_central_state_dependent_params,
.binding_pressed = on_keymap_binding_pressed,
.binding_released = on_keymap_binding_released,
.locality = BEHAVIOR_LOCALITY_GLOBAL,
};

DEVICE_DT_INST_DEFINE(0, behavior_ext_power_init, device_pm_control_nop, NULL, NULL, APPLICATION,
Expand Down
1 change: 1 addition & 0 deletions app/src/behaviors/behavior_reset.c
Expand Up @@ -36,6 +36,7 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,

static const struct behavior_driver_api behavior_reset_driver_api = {
.binding_pressed = on_keymap_binding_pressed,
.locality = BEHAVIOR_LOCALITY_EVENT_SOURCE,
};

#define RST_INST(n) \
Expand Down
13 changes: 13 additions & 0 deletions app/src/behaviors/behavior_rgb_underglow.c
Expand Up @@ -77,6 +77,16 @@ on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_bin
binding->param2 = RGB_COLOR_HSB_VAL(color.h, color.s, color.b);
break;
}
case RGB_EFR_CMD: {
binding->param1 = RGB_EFS_CMD;
binding->param2 = zmk_rgb_underglow_calc_effect(-1);
break;
}
case RGB_EFF_CMD: {
binding->param1 = RGB_EFS_CMD;
binding->param2 = zmk_rgb_underglow_calc_effect(1);
break;
}
default:
return 0;
}
Expand Down Expand Up @@ -111,6 +121,8 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
return zmk_rgb_underglow_change_spd(1);
case RGB_SPD_CMD:
return zmk_rgb_underglow_change_spd(-1);
case RGB_EFS_CMD:
return zmk_rgb_underglow_select_effect(binding->param2);
case RGB_EFF_CMD:
return zmk_rgb_underglow_cycle_effect(1);
case RGB_EFR_CMD:
Expand All @@ -134,6 +146,7 @@ static const struct behavior_driver_api behavior_rgb_underglow_driver_api = {
on_keymap_binding_convert_central_state_dependent_params,
.binding_pressed = on_keymap_binding_pressed,
.binding_released = on_keymap_binding_released,
.locality = BEHAVIOR_LOCALITY_GLOBAL,
};

DEVICE_DT_INST_DEFINE(0, behavior_rgb_underglow_init, device_pm_control_nop, NULL, NULL,
Expand Down