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

Update lily58.conf #1

Open
wants to merge 4 commits into
base: stephen/split-encoder
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/boards/shields/lily58/lily58.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y

# Uncomment the following line to enable the Lily58 OLED Display
# CONFIG_ZMK_DISPLAY=y
CONFIG_ZMK_DISPLAY=y
CONFIG_ZMK_WIDGET_WPM_STATUS=y
CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED=y
12 changes: 6 additions & 6 deletions app/include/drivers/behavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#pragma once

#include <drivers/sensor.h>
#include <zephyr/types.h>
#include <stddef.h>
#include <device.h>
Expand All @@ -23,7 +24,7 @@
typedef int (*behavior_keymap_binding_callback_t)(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event);
typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_binding *binding,
const struct device *sensor,
const struct sensor_value value,
int64_t timestamp);

__subsystem struct behavior_driver_api {
Expand Down Expand Up @@ -118,20 +119,19 @@ static inline int z_impl_behavior_keymap_binding_released(struct zmk_behavior_bi
* @retval Negative errno code if failure.
*/
__syscall int behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding,
const struct device *sensor,
const struct sensor_value value,
int64_t timestamp);

static inline int
z_impl_behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding,
const struct device *sensor, int64_t timestamp) {
static inline int z_impl_behavior_sensor_keymap_binding_triggered(
struct zmk_behavior_binding *binding, const struct sensor_value value, int64_t timestamp) {
const struct device *dev = device_get_binding(binding->behavior_dev);
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;

if (api->sensor_binding_triggered == NULL) {
return -ENOTSUP;
}

return api->sensor_binding_triggered(binding, sensor, timestamp);
return api->sensor_binding_triggered(binding, value, timestamp);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion app/include/zmk/events/sensor_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

#pragma once

#include <drivers/sensor.h>
#include <zephyr.h>
#include <zmk/event_manager.h>
#include <device.h>
struct zmk_sensor_event {
uint8_t sensor_number;
const struct device *sensor;
struct sensor_value value;
int64_t timestamp;
};

Expand Down
5 changes: 4 additions & 1 deletion app/include/zmk/split/bluetooth/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@

#pragma once

#include <drivers/sensor.h>

int zmk_split_bt_position_pressed(uint8_t position);
int zmk_split_bt_position_released(uint8_t position);
int zmk_split_bt_position_released(uint8_t position);
int zmk_split_bt_sensor_triggered(uint8_t sensor_number, struct sensor_value value);
1 change: 1 addition & 0 deletions app/include/zmk/split/bluetooth/uuid.h
Original file line number Diff line number Diff line change
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_SENSOR_STATE_UUID ZMK_BT_SPLIT_UUID(0x00000002)
11 changes: 1 addition & 10 deletions app/src/behaviors/behavior_sensor_rotate_key_press.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,10 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
static int behavior_sensor_rotate_key_press_init(const struct device *dev) { return 0; };

static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding,
const struct device *sensor, int64_t timestamp) {
struct sensor_value value;
int err;
const struct sensor_value value, int64_t timestamp) {
uint32_t keycode;
LOG_DBG("inc keycode 0x%02X dec keycode 0x%02X", binding->param1, binding->param2);

err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value);

if (err) {
LOG_WRN("Failed to ge sensor rotation value: %d", err);
return err;
}

switch (value.val1) {
case 1:
keycode = binding->param1;
Expand Down
6 changes: 3 additions & 3 deletions app/src/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ int zmk_keymap_position_state_changed(uint32_t position, bool pressed, int64_t t
}

#if ZMK_KEYMAP_HAS_SENSORS
int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sensor,
int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct sensor_value value,
int64_t timestamp) {
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= _zmk_keymap_layer_default; layer--) {
if (zmk_keymap_layer_active(layer) && zmk_sensor_keymap[layer] != NULL) {
Expand All @@ -227,7 +227,7 @@ int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sens
continue;
}

ret = behavior_sensor_keymap_binding_triggered(binding, sensor, timestamp);
ret = behavior_sensor_keymap_binding_triggered(binding, value, timestamp);

if (ret > 0) {
LOG_DBG("behavior processing to continue to next layer");
Expand Down Expand Up @@ -256,7 +256,7 @@ int keymap_listener(const zmk_event_t *eh) {
#if ZMK_KEYMAP_HAS_SENSORS
const struct zmk_sensor_event *sensor_ev;
if ((sensor_ev = as_zmk_sensor_event(eh)) != NULL) {
return zmk_keymap_sensor_triggered(sensor_ev->sensor_number, sensor_ev->sensor,
return zmk_keymap_sensor_triggered(sensor_ev->sensor_number, sensor_ev->value,
sensor_ev->timestamp);
}
#endif /* ZMK_KEYMAP_HAS_SENSORS */
Expand Down
9 changes: 8 additions & 1 deletion app/src/sensors.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,15 @@ static void zmk_sensors_trigger_handler(const struct device *dev, struct sensor_
return;
}

struct sensor_value value;
err = sensor_channel_get(dev, SENSOR_CHAN_ROTATION, &value);
if (err) {
LOG_WRN("Failed to get sensor rotation value: %d", err);
return;
}

ZMK_EVENT_RAISE(new_zmk_sensor_event((struct zmk_sensor_event){
.sensor_number = item->sensor_number, .sensor = dev, .timestamp = k_uptime_get()}));
.sensor_number = item->sensor_number, .value = value, .timestamp = k_uptime_get()}));
}

static void zmk_sensors_init_item(const char *node, uint8_t i, uint8_t abs_i) {
Expand Down
100 changes: 97 additions & 3 deletions app/src/split/bluetooth/central.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#include <zmk/ble.h>
#include <zmk/sensors.h>
#include <zmk/split/bluetooth/uuid.h>
#include <zmk/event_manager.h>
#include <zmk/events/position_state_changed.h>
#include <zmk/events/sensor_event.h>
#include <init.h>

static int start_scan(void);
Expand All @@ -46,6 +48,50 @@ void peripheral_event_work_callback(struct k_work *work) {

K_WORK_DEFINE(peripheral_event_work, peripheral_event_work_callback);

#if ZMK_KEYMAP_HAS_SENSORS
K_MSGQ_DEFINE(peripheral_sensor_event_msgq, sizeof(struct zmk_sensor_event),
CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4);

void peripheral_sensor_event_work_callback(struct k_work *work) {
struct zmk_sensor_event ev;
while (k_msgq_get(&peripheral_sensor_event_msgq, &ev, K_NO_WAIT) == 0) {
LOG_DBG("Trigger sensor change for %d", ev.sensor_number);
ZMK_EVENT_RAISE(new_zmk_sensor_event(ev));
}
}

K_WORK_DEFINE(peripheral_sensor_event_work, peripheral_sensor_event_work_callback);

struct sensor_event {
uint8_t sensor_number;
struct sensor_value value;
};

static uint8_t split_central_sensor_notify_func(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length) {

const struct sensor_event *sensor_event = data;

if (!data) {
LOG_DBG("[UNSUBSCRIBED]");
params->value_handle = 0U;
return BT_GATT_ITER_STOP;
}
LOG_DBG("[SENSOR NOTIFICATION] data %p length %u", data, length);

struct zmk_sensor_event ev = {
.sensor_number = sensor_event->sensor_number,
.value = {.val1 = (sensor_event->value).val1, .val2 = (sensor_event->value).val2},
.timestamp = k_uptime_get()};

k_msgq_put(&peripheral_sensor_event_msgq, &ev, K_NO_WAIT);
k_work_submit(&peripheral_sensor_event_work);

return BT_GATT_ITER_CONTINUE;
}
#endif /* ZMK_KEYMAP_HAS_SENSORS */

static uint8_t split_central_notify_func(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params, const void *data,
uint16_t length) {
Expand Down Expand Up @@ -83,8 +129,8 @@ static uint8_t split_central_notify_func(struct bt_conn *conn,
return BT_GATT_ITER_CONTINUE;
}

static int split_central_subscribe(struct bt_conn *conn) {
int err = bt_gatt_subscribe(conn, &subscribe_params);
static int split_central_subscribe(struct bt_conn *conn, struct bt_gatt_subscribe_params *params) {
int err = bt_gatt_subscribe(conn, params);
switch (err) {
case -EALREADY:
LOG_DBG("[ALREADY SUBSCRIBED]");
Expand All @@ -103,6 +149,39 @@ static int split_central_subscribe(struct bt_conn *conn) {
return 0;
}

#if ZMK_KEYMAP_HAS_SENSORS
static struct bt_uuid_128 sensor_uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID);
static struct bt_gatt_discover_params sensor_discover_params;
static struct bt_gatt_subscribe_params sensor_subscribe_params;
static uint8_t split_central_sensor_desc_discovery_func(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params) {
int err;

if (!bt_uuid_cmp(sensor_discover_params.uuid,
BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_SENSOR_STATE_UUID))) {
memcpy(&sensor_uuid, BT_UUID_GATT_CCC, sizeof(uuid));
sensor_discover_params.uuid = &sensor_uuid.uuid;
sensor_discover_params.start_handle = attr->handle;
sensor_discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;

sensor_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

err = bt_gatt_discover(conn, &sensor_discover_params);
if (err) {
LOG_ERR("Discover failed (err %d)", err);
}
} else {
sensor_subscribe_params.notify = split_central_sensor_notify_func;
sensor_subscribe_params.value = BT_GATT_CCC_NOTIFY;
sensor_subscribe_params.ccc_handle = attr->handle;
split_central_subscribe(conn, &sensor_subscribe_params);
}

return BT_GATT_ITER_STOP;
}
#endif /* ZMK_KEYMAP_HAS_SENSORS */

static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params) {
int err;
Expand Down Expand Up @@ -137,12 +216,27 @@ static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct b
if (err) {
LOG_ERR("Discover failed (err %d)", err);
}

#if ZMK_KEYMAP_HAS_SENSORS
memcpy(&sensor_uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_SENSOR_STATE_UUID),
sizeof(sensor_uuid));
sensor_discover_params.uuid = &sensor_uuid.uuid;
sensor_discover_params.start_handle = attr->handle;
sensor_discover_params.end_handle = 0xffff;
sensor_discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
sensor_discover_params.func = split_central_sensor_desc_discovery_func;

err = bt_gatt_discover(conn, &sensor_discover_params);
if (err) {
LOG_ERR("Discover failed (err %d)", err);
}
#endif /* ZMK_KEYMAP_HAS_SENSORS */
} else {
subscribe_params.notify = split_central_notify_func;
subscribe_params.value = BT_GATT_CCC_NOTIFY;
subscribe_params.ccc_handle = attr->handle;

split_central_subscribe(conn);
split_central_subscribe(conn, &subscribe_params);

return BT_GATT_ITER_STOP;
}
Expand Down
72 changes: 71 additions & 1 deletion app/src/split/bluetooth/service.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* SPDX-License-Identifier: MIT
*/

#include <drivers/sensor.h>
#include <zephyr/types.h>
#include <sys/util.h>
#include <init.h>
Expand All @@ -18,6 +19,23 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/matrix.h>
#include <zmk/split/bluetooth/uuid.h>
#include <zmk/split/bluetooth/service.h>
#include <zmk/sensors.h>

#if ZMK_KEYMAP_HAS_SENSORS
struct sensor_event {
uint8_t sensor_number;
struct sensor_value value;
} sensor_event;

static ssize_t split_svc_sensor_state(struct bt_conn *conn, const struct bt_gatt_attr *attrs,
void *buf, uint16_t len, uint16_t offset) {
return bt_gatt_attr_read(conn, attrs, buf, len, offset, &sensor_event, sizeof(sensor_event));
}

static void split_svc_sensor_state_ccc(const struct bt_gatt_attr *attr, uint16_t value) {
LOG_DBG("value %d", value);
}
#endif /* ZMK_KEYMAP_HAS_SENSORS */

#define POS_STATE_LEN 16

Expand Down Expand Up @@ -46,7 +64,14 @@ BT_GATT_SERVICE_DEFINE(
split_svc_pos_state, NULL, &position_state),
BT_GATT_CCC(split_svc_pos_state_ccc, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
BT_GATT_DESCRIPTOR(BT_UUID_NUM_OF_DIGITALS, BT_GATT_PERM_READ, split_svc_num_of_positions, NULL,
&num_of_positions), );
&num_of_positions),
#if ZMK_KEYMAP_HAS_SENSORS
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_SENSOR_STATE_UUID),
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ_ENCRYPT,
split_svc_sensor_state, NULL, &sensor_event),
BT_GATT_CCC(split_svc_sensor_state_ccc, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
#endif /* ZMK_KEYMAP_HAS_SENSORS */
);

K_THREAD_STACK_DEFINE(service_q_stack, CONFIG_ZMK_SPLIT_BLE_PERIPHERAL_STACK_SIZE);

Expand Down Expand Up @@ -99,6 +124,51 @@ int zmk_split_bt_position_released(uint8_t position) {
return send_position_state();
}

#if ZMK_KEYMAP_HAS_SENSORS
K_MSGQ_DEFINE(sensor_state_msgq, sizeof(sensor_event),
CONFIG_ZMK_SPLIT_BLE_PERIPHERAL_POSITION_QUEUE_SIZE, 4);

void send_sensor_state_callback(struct k_work *work) {
struct sensor_event ev;

while (k_msgq_get(&sensor_state_msgq, &ev, K_NO_WAIT) == 0) {
int err = bt_gatt_notify(NULL, &split_svc.attrs[5], &ev, sizeof(ev));
if (err) {
LOG_DBG("Error notifying %d", err);
}
}
};

K_WORK_DEFINE(service_sensor_notify_work, send_sensor_state_callback);

int send_sensor_state() {
int err = k_msgq_put(&sensor_state_msgq, &sensor_event, K_MSEC(100));
if (err) {
// retry...
switch (err) {
case -EAGAIN: {
LOG_WRN("Sensor state message queue full, popping first message and queueing again");
struct sensor_event discarded_state;
k_msgq_get(&sensor_state_msgq, &discarded_state, K_NO_WAIT);
return send_sensor_state();
}
default:
LOG_WRN("Failed to queue sensor state to send (%d)", err);
return err;
}
}

k_work_submit_to_queue(&service_work_q, &service_sensor_notify_work);
return 0;
}

int zmk_split_bt_sensor_triggered(uint8_t sensor_number, struct sensor_value value) {
sensor_event.sensor_number = sensor_number;
sensor_event.value = value;
return send_sensor_state();
}
#endif /* ZMK_KEYMAP_HAS_SENSORS */

int service_init(const struct device *_arg) {
k_work_q_start(&service_work_q, service_q_stack, K_THREAD_STACK_SIZEOF(service_q_stack),
CONFIG_ZMK_SPLIT_BLE_PERIPHERAL_PRIORITY);
Expand Down
Loading