From 6ed14e9634a0d468d0b7dda3b73ef800521008f6 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:03:56 +0000 Subject: [PATCH 1/9] feat(split): raise status changed events on central --- app/src/split/bluetooth/central.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index ee21a12f..61ec4e8d 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -29,6 +29,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include #include +#include static int start_scanning(void); @@ -712,6 +713,8 @@ static void split_central_connected(struct bt_conn *conn, uint8_t conn_err) { confirm_peripheral_slot_conn(conn); split_central_process_connection(conn); + raise_zmk_split_peripheral_status_changed( + (struct zmk_split_peripheral_status_changed){.connected = true}); } static void split_central_disconnected(struct bt_conn *conn, uint8_t reason) { @@ -728,6 +731,8 @@ static void split_central_disconnected(struct bt_conn *conn, uint8_t reason) { k_msgq_put(&peripheral_batt_lvl_msgq, &ev, K_NO_WAIT); k_work_submit(&peripheral_batt_lvl_work); #endif // IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) + raise_zmk_split_peripheral_status_changed( + (struct zmk_split_peripheral_status_changed){.connected = false}); err = release_peripheral_slot_for_conn(conn); From ff7e0b7e481facf068be9d7f50b20445f042d11e Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Tue, 21 Nov 2023 09:40:56 +0000 Subject: [PATCH 2/9] feat(split): central to peripheral communication --- app/include/zmk/split/bluetooth/central.h | 14 +-- app/include/zmk/split/bluetooth/service.h | 20 ++++ app/include/zmk/split/bluetooth/uuid.h | 2 +- app/src/split/bluetooth/Kconfig | 8 ++ app/src/split/bluetooth/central.c | 135 +++++++++++++++------- app/src/split/bluetooth/service.c | 26 +++++ 6 files changed, 151 insertions(+), 54 deletions(-) diff --git a/app/include/zmk/split/bluetooth/central.h b/app/include/zmk/split/bluetooth/central.h index 5e9e09ff..c609aa3b 100644 --- a/app/include/zmk/split/bluetooth/central.h +++ b/app/include/zmk/split/bluetooth/central.h @@ -3,22 +3,14 @@ #include #include - -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) -#include -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) +#include int zmk_split_bt_invoke_behavior(uint8_t source, struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event, bool state); -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - -int zmk_split_bt_update_hid_indicator(zmk_hid_indicators_t indicators); - -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) int zmk_split_get_peripheral_battery_level(uint8_t source, uint8_t *level); -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) \ No newline at end of file +#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) +int zmk_split_central_send_data(enum data_tag, uint8_t data_size, uint8_t *data); diff --git a/app/include/zmk/split/bluetooth/service.h b/app/include/zmk/split/bluetooth/service.h index 112cd552..c7b9008f 100644 --- a/app/include/zmk/split/bluetooth/service.h +++ b/app/include/zmk/split/bluetooth/service.h @@ -10,6 +10,20 @@ #include #define ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN 9 +#define ZMK_SPLIT_DATA_XFER_MAX_LEN 16 + +enum data_tag { + // RGB state + DATA_TAG_RGB_STATE, + // Backlight state + DATA_TAG_BACKLIGHT_STATE, + // HID indicators state + DATA_TAG_HID_INDICATORS_STATE, + // Keymap state + DATA_TAG_KEYMAP_STATE, + // Start of custom tags + DATA_TAG_CUSTOM_START, +}; struct sensor_event { uint8_t sensor_index; @@ -30,6 +44,12 @@ struct zmk_split_run_behavior_payload { char behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN]; } __packed; +struct zmk_split_data_xfer_data { + enum data_tag data_tag; + uint8_t data_size; + uint8_t data[ZMK_SPLIT_DATA_XFER_MAX_LEN]; +} __packed; + int zmk_split_bt_position_pressed(uint8_t position); int zmk_split_bt_position_released(uint8_t position); int zmk_split_bt_sensor_triggered(uint8_t sensor_index, diff --git a/app/include/zmk/split/bluetooth/uuid.h b/app/include/zmk/split/bluetooth/uuid.h index dccdfc80..737a043f 100644 --- a/app/include/zmk/split/bluetooth/uuid.h +++ b/app/include/zmk/split/bluetooth/uuid.h @@ -17,4 +17,4 @@ #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) #define ZMK_SPLIT_BT_CHAR_SENSOR_STATE_UUID ZMK_BT_SPLIT_UUID(0x00000003) -#define ZMK_SPLIT_BT_UPDATE_HID_INDICATORS_UUID ZMK_BT_SPLIT_UUID(0x00000004) +#define ZMK_SPLIT_BT_CHAR_DATA_XFER_UUID ZMK_BT_SPLIT_UUID(0x00000004) diff --git a/app/src/split/bluetooth/Kconfig b/app/src/split/bluetooth/Kconfig index 4da50528..e6f34f27 100644 --- a/app/src/split/bluetooth/Kconfig +++ b/app/src/split/bluetooth/Kconfig @@ -58,6 +58,14 @@ config ZMK_SPLIT_BLE_CENTRAL_SPLIT_RUN_QUEUE_SIZE int "Max number of behavior run events to queue to send to the peripheral(s)" default 5 +config ZMK_SPLIT_BLE_CENTRAL_DATA_XFER_STACK_SIZE + int "BLE split central to peripheral thread stack size" + default 512 + +config ZMK_SPLIT_BLE_CENTRAL_DATA_XFER_QUEUE_SIZE + int "Max number of data transfer requests to queue to send to the peripheral(s)" + default 5 + config ZMK_SPLIT_BLE_PREF_INT int "Connection interval to use for split central/peripheral connection" default 6 diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index 61ec4e8d..5acaf6b2 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -28,7 +28,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include #include -#include #include static int start_scanning(void); @@ -53,9 +52,7 @@ struct peripheral_slot { struct bt_gatt_subscribe_params batt_lvl_subscribe_params; struct bt_gatt_read_params batt_lvl_read_params; #endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) */ -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - uint16_t update_hid_indicators; -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) + uint16_t data_xfer_handle; uint8_t position_state[POSITION_STATE_DATA_LEN]; uint8_t changed_positions[POSITION_STATE_DATA_LEN]; }; @@ -141,9 +138,7 @@ int release_peripheral_slot(int index) { // Clean up previously discovered handles; slot->subscribe_params.value_handle = 0; slot->run_behavior_handle = 0; -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - slot->update_hid_indicators = 0; -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) + slot->data_xfer_handle = 0; return 0; } @@ -442,12 +437,7 @@ static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn, slot->discover_params.uuid = NULL; slot->discover_params.start_handle = attr->handle + 2; slot->run_behavior_handle = bt_gatt_attr_value_handle(attr); -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - } else if (!bt_uuid_cmp(((struct bt_gatt_chrc *)attr->user_data)->uuid, - BT_UUID_DECLARE_128(ZMK_SPLIT_BT_UPDATE_HID_INDICATORS_UUID))) { - LOG_DBG("Found update HID indicators handle"); - slot->update_hid_indicators = bt_gatt_attr_value_handle(attr); -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) + #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) } else if (!bt_uuid_cmp(((struct bt_gatt_chrc *)attr->user_data)->uuid, BT_UUID_BAS_BATTERY_LEVEL)) { @@ -469,13 +459,36 @@ static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn, bool subscribed = slot->run_behavior_handle && slot->subscribe_params.value_handle; + } else if (bt_uuid_cmp(chrc_uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_DATA_XFER_UUID)) == 0) { + LOG_DBG("Found data transfer handle"); + slot->discover_params.uuid = NULL; + slot->discover_params.start_handle = attr->handle + 2; + slot->data_xfer_handle = bt_gatt_attr_value_handle(attr); +#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) + } else if (!bt_uuid_cmp(((struct bt_gatt_chrc *)attr->user_data)->uuid, + BT_UUID_BAS_BATTERY_LEVEL)) { + LOG_DBG("Found battery level characteristics"); + slot->batt_lvl_subscribe_params.disc_params = &slot->sub_discover_params; + slot->batt_lvl_subscribe_params.end_handle = slot->discover_params.end_handle; + slot->batt_lvl_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr); + slot->batt_lvl_subscribe_params.notify = split_central_battery_level_notify_func; + slot->batt_lvl_subscribe_params.value = BT_GATT_CCC_NOTIFY; + split_central_subscribe(conn, &slot->batt_lvl_subscribe_params); + + slot->batt_lvl_read_params.func = split_central_battery_level_read_func; + slot->batt_lvl_read_params.handle_count = 1; + slot->batt_lvl_read_params.single.handle = bt_gatt_attr_value_handle(attr); + slot->batt_lvl_read_params.single.offset = 0; + bt_gatt_read(conn, &slot->batt_lvl_read_params); +#endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) */ + } + + bool subscribed = + slot->run_behavior_handle && slot->data_xfer_handle && slot->subscribe_params.value_handle; #if ZMK_KEYMAP_HAS_SENSORS subscribed = subscribed && slot->sensor_subscribe_params.value_handle; #endif /* ZMK_KEYMAP_HAS_SENSORS */ -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - subscribed = subscribed && slot->update_hid_indicators; -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) subscribed = subscribed && slot->batt_lvl_subscribe_params.value_handle; #endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) */ @@ -833,47 +846,85 @@ int zmk_split_bt_invoke_behavior(uint8_t source, struct zmk_behavior_binding *bi return split_bt_invoke_behavior_payload(wrapper); } -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) +K_THREAD_STACK_DEFINE(split_central_data_xfer_q_stack, + CONFIG_ZMK_SPLIT_BLE_CENTRAL_DATA_XFER_STACK_SIZE); -static zmk_hid_indicators_t hid_indicators = 0; +struct k_work_q split_central_data_xfer_q; -static void split_central_update_indicators_callback(struct k_work *work) { - zmk_hid_indicators_t indicators = hid_indicators; - for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) { - if (peripherals[i].state != PERIPHERAL_SLOT_STATE_CONNECTED) { - continue; - } +K_MSGQ_DEFINE(zmk_split_central_data_xfer_msgq, sizeof(struct zmk_split_data_xfer_data), + CONFIG_ZMK_SPLIT_BLE_CENTRAL_DATA_XFER_QUEUE_SIZE, 2); - if (peripherals[i].update_hid_indicators == 0) { - // It appears that sometimes the peripheral is considered connected - // before the GATT characteristics have been discovered. If this is - // the case, the update_hid_indicators handle will not yet be set. - continue; - } +void split_central_data_xfer_callback(struct k_work *work) { + struct zmk_split_data_xfer_data payload; - int err = bt_gatt_write_without_response(peripherals[i].conn, - peripherals[i].update_hid_indicators, &indicators, - sizeof(indicators), true); + while (k_msgq_get(&zmk_split_central_data_xfer_msgq, &payload, K_NO_WAIT) == 0) { + for (uint8_t i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) { + if (peripherals[i].state != PERIPHERAL_SLOT_STATE_CONNECTED) { + LOG_ERR("Source not connected"); + continue; + } - if (err) { - LOG_ERR("Failed to write HID indicator characteristic (err %d)", err); + if (!peripherals[i].data_xfer_handle) { + LOG_ERR("Handle not discovered"); + continue; + } + + int err = bt_gatt_write_without_response(peripherals[i].conn, + peripherals[i].data_xfer_handle, &payload, + sizeof(struct zmk_split_data_xfer_data), true); + + if (err) { + LOG_ERR("Failed to write the data transfer characteristic (err %d)", err); + } } } } -static K_WORK_DEFINE(split_central_update_indicators, split_central_update_indicators_callback); +K_WORK_DEFINE(split_central_data_xfer_work, split_central_data_xfer_callback); -int zmk_split_bt_update_hid_indicator(zmk_hid_indicators_t indicators) { - hid_indicators = indicators; - return k_work_submit_to_queue(&split_central_split_run_q, &split_central_update_indicators); +static int split_bt_data_xfer_payload(struct zmk_split_data_xfer_data payload) { + LOG_DBG(""); + + int err = k_msgq_put(&zmk_split_central_data_xfer_msgq, &payload, K_MSEC(100)); + if (err) { + switch (err) { + case -EAGAIN: { + LOG_WRN("Consumer message queue full, popping first message and queueing again"); + struct zmk_split_data_xfer_data discarded_report; + k_msgq_get(&zmk_split_central_data_xfer_msgq, &discarded_report, K_NO_WAIT); + return split_bt_data_xfer_payload(payload); + } + default: + LOG_WRN("Failed to queue data to send (%d)", err); + return err; + } + } + + k_work_submit_to_queue(&split_central_data_xfer_q, &split_central_data_xfer_work); + + return 0; +}; + +int zmk_split_central_send_data(enum data_tag tag, uint8_t size, uint8_t *data) { + if (size > ZMK_SPLIT_DATA_XFER_MAX_LEN) { + LOG_ERR("Payload too large. Size: %d", size); + return -EFBIG; + } + struct zmk_split_data_xfer_data payload; + payload.data_tag = tag; + payload.data_size = size; + memcpy(payload.data, data, size); + LOG_HEXDUMP_DBG(&payload, sizeof(struct zmk_split_data_xfer_data), "sending :"); + return split_bt_data_xfer_payload(payload); } -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - -static int zmk_split_bt_central_init(void) { +int zmk_split_bt_central_init(const struct device *_arg) { k_work_queue_start(&split_central_split_run_q, split_central_split_run_q_stack, K_THREAD_STACK_SIZEOF(split_central_split_run_q_stack), CONFIG_ZMK_BLE_THREAD_PRIORITY, NULL); + k_work_queue_start(&split_central_data_xfer_q, split_central_data_xfer_q_stack, + K_THREAD_STACK_SIZEOF(split_central_data_xfer_q_stack), + CONFIG_ZMK_BLE_THREAD_PRIORITY, NULL); bt_conn_cb_register(&conn_callbacks); return IS_ENABLED(CONFIG_ZMK_BLE_CLEAR_BONDS_ON_START) ? 0 : start_scanning(); diff --git a/app/src/split/bluetooth/service.c b/app/src/split/bluetooth/service.c index 505eb363..9a508c92 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -49,6 +49,7 @@ static uint8_t num_of_positions = ZMK_KEYMAP_LEN; static uint8_t position_state[POS_STATE_LEN]; static struct zmk_split_run_behavior_payload behavior_run_payload; +static struct zmk_split_data_xfer_data data_xfer_payload; static ssize_t split_svc_pos_state(struct bt_conn *conn, const struct bt_gatt_attr *attrs, void *buf, uint16_t len, uint16_t offset) { @@ -101,6 +102,28 @@ static ssize_t split_svc_run_behavior(struct bt_conn *conn, const struct bt_gatt return len; } +static ssize_t split_svc_data_xfer(struct bt_conn *conn, const struct bt_gatt_attr *attrs, + const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { + struct zmk_split_data_xfer_data *payload = attrs->user_data; + uint16_t end_addr = offset + len; + + LOG_DBG("offset %d len %d", offset, len); + + memcpy(payload + offset, buf, len); + + // If whole packet transferred correctly + if ((end_addr == sizeof(struct zmk_split_data_xfer_data))) { + // Raise new data transfer event with received data + LOG_HEXDUMP_DBG(&payload, sizeof(struct zmk_split_data_xfer_data), "receiving :"); + LOG_DBG("Size correct, raising evt, %d", end_addr); + struct zmk_split_data_xfer_event event; + memcpy(&event.data_xfer, payload, sizeof(struct zmk_split_data_xfer_data)); + ZMK_EVENT_RAISE(new_zmk_split_data_xfer_event(event)); + } + + return len; +} + static ssize_t split_svc_num_of_positions(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, attrs->user_data, sizeof(uint8_t)); @@ -147,6 +170,9 @@ BT_GATT_SERVICE_DEFINE( BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_RUN_BEHAVIOR_UUID), BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE_ENCRYPT, NULL, split_svc_run_behavior, &behavior_run_payload), + BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_DATA_XFER_UUID), + BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE_ENCRYPT, NULL, + split_svc_data_xfer, &data_xfer_payload), BT_GATT_DESCRIPTOR(BT_UUID_NUM_OF_DIGITALS, BT_GATT_PERM_READ, split_svc_num_of_positions, NULL, &num_of_positions), #if ZMK_KEYMAP_HAS_SENSORS From ef8ab95d7c13e92ca0d88a1cd37f4b0a17a28b5d Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:55:45 +0000 Subject: [PATCH 3/9] feat(split): Add data transfer event --- app/CMakeLists.txt | 1 + app/include/zmk/events/split_data_xfer_event.h | 17 +++++++++++++++++ app/src/events/split_data_xfer_event.c | 10 ++++++++++ app/src/split/bluetooth/service.c | 1 + 4 files changed, 29 insertions(+) create mode 100644 app/include/zmk/events/split_data_xfer_event.h create mode 100644 app/src/events/split_data_xfer_event.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 0b681ea9..314796c0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -89,6 +89,7 @@ target_sources_ifdef(CONFIG_ZMK_BATTERY_REPORTING app PRIVATE src/battery.c) target_sources_ifdef(CONFIG_ZMK_HID_INDICATORS app PRIVATE src/events/hid_indicators_changed.c) target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_peripheral_status_changed.c) +target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_data_xfer_event.c) add_subdirectory(src/split) target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/usb.c) diff --git a/app/include/zmk/events/split_data_xfer_event.h b/app/include/zmk/events/split_data_xfer_event.h new file mode 100644 index 00000000..b8d65c73 --- /dev/null +++ b/app/include/zmk/events/split_data_xfer_event.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include +#include + +struct zmk_split_data_xfer_event { + struct zmk_split_data_xfer_data data_xfer; +}; + +ZMK_EVENT_DECLARE(zmk_split_data_xfer_event); diff --git a/app/src/events/split_data_xfer_event.c b/app/src/events/split_data_xfer_event.c new file mode 100644 index 00000000..ee1b0a57 --- /dev/null +++ b/app/src/events/split_data_xfer_event.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +ZMK_EVENT_IMPL(zmk_split_data_xfer_event); \ No newline at end of file diff --git a/app/src/split/bluetooth/service.c b/app/src/split/bluetooth/service.c index 9a508c92..cd774914 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -28,6 +28,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include +#include #if ZMK_KEYMAP_HAS_SENSORS static struct sensor_event last_sensor_event; From 5fc212faebbdd6b7c7f6062b820a9d6a0f0cbf08 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Thu, 23 Nov 2023 23:13:35 +0000 Subject: [PATCH 4/9] fix(split): change peripheral to use work --- app/src/split/bluetooth/service.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/app/src/split/bluetooth/service.c b/app/src/split/bluetooth/service.c index cd774914..5798dc7a 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -103,23 +103,27 @@ static ssize_t split_svc_run_behavior(struct bt_conn *conn, const struct bt_gatt return len; } +static void split_svc_data_xfer_callback(struct k_work *work) { + LOG_DBG("Size correct, raising event"); + struct zmk_split_data_xfer_event event; + memcpy(&event.data_xfer, &data_xfer_payload, sizeof(struct zmk_split_data_xfer_data)); + ZMK_EVENT_RAISE(new_zmk_split_data_xfer_event(event)); +} + +static K_WORK_DEFINE(split_svc_data_xfer_work, split_svc_data_xfer_callback); + static ssize_t split_svc_data_xfer(struct bt_conn *conn, const struct bt_gatt_attr *attrs, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { - struct zmk_split_data_xfer_data *payload = attrs->user_data; uint16_t end_addr = offset + len; LOG_DBG("offset %d len %d", offset, len); - - memcpy(payload + offset, buf, len); + LOG_HEXDUMP_DBG(buf, len, "Receiving :"); // If whole packet transferred correctly if ((end_addr == sizeof(struct zmk_split_data_xfer_data))) { // Raise new data transfer event with received data - LOG_HEXDUMP_DBG(&payload, sizeof(struct zmk_split_data_xfer_data), "receiving :"); - LOG_DBG("Size correct, raising evt, %d", end_addr); - struct zmk_split_data_xfer_event event; - memcpy(&event.data_xfer, payload, sizeof(struct zmk_split_data_xfer_data)); - ZMK_EVENT_RAISE(new_zmk_split_data_xfer_event(event)); + memcpy(&data_xfer_payload + offset, buf, len); + k_work_submit(&split_svc_data_xfer_work); } return len; @@ -173,7 +177,7 @@ BT_GATT_SERVICE_DEFINE( split_svc_run_behavior, &behavior_run_payload), BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_DATA_XFER_UUID), BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE_ENCRYPT, NULL, - split_svc_data_xfer, &data_xfer_payload), + split_svc_data_xfer, NULL), BT_GATT_DESCRIPTOR(BT_UUID_NUM_OF_DIGITALS, BT_GATT_PERM_READ, split_svc_num_of_positions, NULL, &num_of_positions), #if ZMK_KEYMAP_HAS_SENSORS From 8d953abdf7e414a0062abdf00ae8691f2a019a23 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Thu, 23 Nov 2023 23:17:26 +0000 Subject: [PATCH 5/9] feat(rgb): Use data transfer framework --- app/src/behaviors/behavior_rgb_underglow.c | 2 +- app/src/rgb_underglow.c | 93 ++++++++++++++++++++-- 2 files changed, 87 insertions(+), 8 deletions(-) diff --git a/app/src/behaviors/behavior_rgb_underglow.c b/app/src/behaviors/behavior_rgb_underglow.c index a16ee591..14b185ac 100644 --- a/app/src/behaviors/behavior_rgb_underglow.c +++ b/app/src/behaviors/behavior_rgb_underglow.c @@ -146,7 +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, + .locality = BEHAVIOR_LOCALITY_CENTRAL, }; BEHAVIOR_DT_INST_DEFINE(0, behavior_rgb_underglow_init, NULL, NULL, NULL, POST_KERNEL, diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index 5bf1ef25..32a331e9 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -21,11 +21,20 @@ #include #include +#include #include #include #include +#include #include +// Pull data sending framework if central, data receiving event if peripheral(s) +#if ZMK_BLE_IS_CENTRAL +#include +#elif IS_ENABLED(CONFIG_ZMK_SPLIT) +#include +#endif + LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #if !DT_HAS_CHOSEN(zmk_underglow) @@ -130,6 +139,21 @@ static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { return rgb; } +#if ZMK_BLE_IS_CENTRAL + +static void zmk_rgb_send_state(struct k_work *work) { + LOG_HEXDUMP_DBG(&state, sizeof(struct rgb_underglow_state), "RGB state"); + int err = zmk_split_central_send_data(DATA_TAG_RGB_STATE, sizeof(struct rgb_underglow_state), + (uint8_t *)&state); + if (err) { + LOG_ERR("send failed (err %d)", err); + } +} + +K_WORK_DEFINE(rgb_send_state_work, zmk_rgb_send_state); + +#endif + static void zmk_rgb_underglow_effect_solid(void) { for (int i = 0; i < STRIP_NUM_PIXELS; i++) { pixels[i] = hsb_to_rgb(hsb_scale_min_max(state.color)); @@ -191,6 +215,14 @@ static void zmk_rgb_underglow_tick(struct k_work *work) { break; } +#if ZMK_BLE_IS_CENTRAL + // Every time the counter rolls to 1 synchronise the animations (If it was 0 then it constantly + // syncs when effect is a solid color) + if (state.animation_step == 1) { + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work); + } +#endif + int err = led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS); if (err < 0) { LOG_ERR("Failed to update the RGB strip (%d)", err); @@ -278,7 +310,9 @@ static int zmk_rgb_underglow_init(void) { #if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB) state.on = zmk_usb_is_powered(); #endif - +#if ZMK_BLE_IS_CENTRAL + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work); +#endif if (state.on) { k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); } @@ -287,6 +321,10 @@ static int zmk_rgb_underglow_init(void) { } int zmk_rgb_underglow_save_state(void) { + // Send new state to peripheral when anything changes +#if ZMK_BLE_IS_CENTRAL + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work); +#endif #if IS_ENABLED(CONFIG_SETTINGS) int ret = k_work_reschedule(&underglow_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE)); return MIN(ret, 0); @@ -319,7 +357,6 @@ int zmk_rgb_underglow_on(void) { state.on = true; state.animation_step = 0; k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); - return zmk_rgb_underglow_save_state(); } @@ -496,8 +533,12 @@ static int rgb_underglow_auto_state(bool target_wake_state) { return zmk_rgb_underglow_off(); } } +#endif -static int rgb_underglow_event_listener(const zmk_event_t *eh) { +#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) || \ + IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB) || ZMK_BLE_IS_CENTRAL + +static int rgb_underglow_activity_event_listener(const zmk_event_t *eh) { #if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) if (as_zmk_activity_state_changed(eh)) { @@ -511,19 +552,57 @@ static int rgb_underglow_event_listener(const zmk_event_t *eh) { } #endif +#if ZMK_BLE_IS_CENTRAL + if (as_zmk_split_peripheral_status_changed(eh)) { + // TODO: Have this only update when connected + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &rgb_send_state_work); + } +#endif + return -ENOTSUP; } -ZMK_LISTENER(rgb_underglow, rgb_underglow_event_listener); +ZMK_LISTENER(rgb_underglow_activity, rgb_underglow_activity_event_listener); #endif // IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) || - // IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB) + // IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB) || ZMK_BLE_IS_CENTRAL #if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE) -ZMK_SUBSCRIPTION(rgb_underglow, zmk_activity_state_changed); +ZMK_SUBSCRIPTION(rgb_underglow_activity, zmk_activity_state_changed); #endif #if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB) -ZMK_SUBSCRIPTION(rgb_underglow, zmk_usb_conn_state_changed); +ZMK_SUBSCRIPTION(rgb_underglow_activity, zmk_usb_conn_state_changed); +#endif + +#if ZMK_BLE_IS_CENTRAL +ZMK_SUBSCRIPTION(rgb_underglow_activity, zmk_split_peripheral_status_changed); +#endif + +#if IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) + +static int rgb_underglow_data_event_listener(const zmk_event_t *eh) { + const struct zmk_split_data_xfer_event *ev = as_zmk_split_data_xfer_event(eh); + if (ev->data_xfer.data_tag == DATA_TAG_RGB_STATE) { + LOG_DBG("RGB Data received of size: %d", ev->data_xfer.data_size); + // Should the RGB timer be stopped and started during this operation to keep state safe? + LOG_HEXDUMP_DBG(ev->data_xfer.data, sizeof(struct zmk_split_data_xfer_event), + "received event:"); + static bool prev_state = false; + memcpy(&state, ev->data_xfer.data, sizeof(struct rgb_underglow_state)); + LOG_HEXDUMP_DBG(&state, sizeof(struct rgb_underglow_state), "RGB state"); + LOG_DBG("new on_state %d", state.on); + if (prev_state && !state.on) { + zmk_rgb_underglow_off(); + } else if (!prev_state && state.on) { + zmk_rgb_underglow_on(); + } + prev_state = state.on; + } + return 0; +} + +ZMK_LISTENER(rgb_underglow_data, rgb_underglow_data_event_listener); +ZMK_SUBSCRIPTION(rgb_underglow_data, zmk_split_data_xfer_event); #endif SYS_INIT(zmk_rgb_underglow_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); From a7fb050104b06b3ab3e509dde927c4e100811cdf Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Fri, 24 Nov 2023 18:32:47 +0000 Subject: [PATCH 6/9] feat(backlight): Use data transfer framework --- app/src/backlight.c | 63 +++++++++++++++++++++++++- app/src/behaviors/behavior_backlight.c | 2 +- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/app/src/backlight.c b/app/src/backlight.c index f050978f..d83109aa 100644 --- a/app/src/backlight.c +++ b/app/src/backlight.c @@ -16,9 +16,19 @@ #include #include #include +#include #include #include #include +#include +#include + +// Pull data sending framework if central, data receiving eventt if peripheral(s) +#if ZMK_BLE_IS_CENTRAL +#include +#elif IS_ENABLED(CONFIG_ZMK_SPLIT) +#include +#endif LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -42,7 +52,25 @@ struct backlight_state { static struct backlight_state state = {.brightness = CONFIG_ZMK_BACKLIGHT_BRT_START, .on = IS_ENABLED(CONFIG_ZMK_BACKLIGHT_ON_START)}; +#if ZMK_BLE_IS_CENTRAL + +static void zmk_backlight_send_state(struct k_work *work) { + LOG_HEXDUMP_DBG(&state, sizeof(struct backlight_state), "backlight state"); + int err = zmk_split_central_send_data(DATA_TAG_BACKLIGHT_STATE, sizeof(struct backlight_state), + (uint8_t *)&state); + if (err) { + LOG_ERR("send failed (err %d)", err); + } +} + +K_WORK_DEFINE(backlight_send_state_work, zmk_backlight_send_state); + +#endif + static int zmk_backlight_update(void) { +#if ZMK_BLE_IS_CENTRAL + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &backlight_send_state_work); +#endif uint8_t brt = zmk_backlight_get_brt(); LOG_DBG("Update backlight brightness: %d%%", brt); @@ -157,7 +185,10 @@ static int backlight_auto_state(bool *prev_state, bool new_state) { *prev_state = !new_state; return zmk_backlight_update(); } +#endif +#if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) || \ + IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB) || ZMK_BLE_IS_CENTRAL static int backlight_event_listener(const zmk_event_t *eh) { #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) @@ -174,12 +205,19 @@ static int backlight_event_listener(const zmk_event_t *eh) { } #endif +#if ZMK_BLE_IS_CENTRAL + if (as_zmk_split_peripheral_status_changed(eh)) { + // TODO: Have this only update when connected + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &backlight_send_state_work); + } +#endif + return -ENOTSUP; } ZMK_LISTENER(backlight, backlight_event_listener); #endif // IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) || - // IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB) + // IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB) || ZMK_BLE_IS_CENTRAL #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) ZMK_SUBSCRIPTION(backlight, zmk_activity_state_changed); @@ -189,4 +227,27 @@ ZMK_SUBSCRIPTION(backlight, zmk_activity_state_changed); ZMK_SUBSCRIPTION(backlight, zmk_usb_conn_state_changed); #endif +#if ZMK_BLE_IS_CENTRAL +ZMK_SUBSCRIPTION(backlight, zmk_split_peripheral_status_changed); +#endif + +#if IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) + +static int backlight_data_event_listener(const zmk_event_t *eh) { + const struct zmk_split_data_xfer_event *ev = as_zmk_split_data_xfer_event(eh); + if (ev->data_xfer.data_tag == DATA_TAG_BACKLIGHT_STATE) { + LOG_DBG("Backlight Data received of size: %d", ev->data_xfer.data_size); + LOG_HEXDUMP_DBG(ev->data_xfer.data, sizeof(struct zmk_split_data_xfer_event), + "received event:"); + memcpy(&state, ev->data_xfer.data, sizeof(struct backlight_state)); + LOG_HEXDUMP_DBG(&state, sizeof(struct backlight_state), "backlight state"); + zmk_backlight_update_and_save(); + } + return 0; +} + +ZMK_LISTENER(backlight_data, backlight_data_event_listener); +ZMK_SUBSCRIPTION(backlight_data, zmk_split_data_xfer_event); +#endif + SYS_INIT(zmk_backlight_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/src/behaviors/behavior_backlight.c b/app/src/behaviors/behavior_backlight.c index 3f836b73..12b50160 100644 --- a/app/src/behaviors/behavior_backlight.c +++ b/app/src/behaviors/behavior_backlight.c @@ -88,7 +88,7 @@ static const struct behavior_driver_api behavior_backlight_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, + .locality = BEHAVIOR_LOCALITY_CENTRAL, }; BEHAVIOR_DT_INST_DEFINE(0, behavior_backlight_init, NULL, NULL, NULL, POST_KERNEL, From 574ee4ee5f96da37ab4e6d083c15bedb1f04e799 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:23:06 +0000 Subject: [PATCH 7/9] feat(split): Use split data transfer for hid indicators --- app/src/hid_indicators.c | 24 ++++++++++++++++---- app/src/split/bluetooth/service.c | 37 ------------------------------- 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/app/src/hid_indicators.c b/app/src/hid_indicators.c index 1b489068..817b238e 100644 --- a/app/src/hid_indicators.c +++ b/app/src/hid_indicators.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -27,14 +29,23 @@ zmk_hid_indicators_t zmk_hid_indicators_get_profile(struct zmk_endpoint_instance return hid_indicators[profile]; } +static void zmk_hid_indicators_send_state(struct k_work *work) { + zmk_hid_indicators_t indicators = zmk_hid_indicators_get_current_profile(); + int err = zmk_split_central_send_data(DATA_TAG_HID_INDICATORS_STATE, + sizeof(zmk_hid_indicators_t), (uint8_t *)&indicators); + if (err) { + LOG_ERR("HID indicators send failed (err %d)", err); + } +} + +K_WORK_DEFINE(hid_indicators_send_state_work, zmk_hid_indicators_send_state); + static void raise_led_changed_event(struct k_work *_work) { const zmk_hid_indicators_t indicators = zmk_hid_indicators_get_current_profile(); raise_zmk_hid_indicators_changed((struct zmk_hid_indicators_changed){.indicators = indicators}); -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) && IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) - zmk_split_bt_update_hid_indicator(indicators); -#endif + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &hid_indicators_send_state_work); } static K_WORK_DEFINE(led_changed_work, raise_led_changed_event); @@ -60,9 +71,14 @@ void zmk_hid_indicators_process_report(struct zmk_hid_led_report_body *report, } static int profile_listener(const zmk_event_t *eh) { - raise_led_changed_event(NULL); + if (as_zmk_endpoint_changed(eh)) { + raise_led_changed_event(NULL); + } else if (as_zmk_split_peripheral_status_changed(eh)) { + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &hid_indicators_send_state_work); + } return 0; } static ZMK_LISTENER(profile_listener, profile_listener); static ZMK_SUBSCRIPTION(profile_listener, zmk_endpoint_changed); +static ZMK_SUBSCRIPTION(profile_listener, zmk_split_peripheral_status_changed); diff --git a/app/src/split/bluetooth/service.c b/app/src/split/bluetooth/service.c index 5798dc7a..461ee185 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -22,10 +22,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) -#include -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - #include #include #include @@ -138,34 +134,6 @@ static void split_svc_pos_state_ccc(const struct bt_gatt_attr *attr, uint16_t va LOG_DBG("value %d", value); } -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - -static zmk_hid_indicators_t hid_indicators = 0; - -static void split_svc_update_indicators_callback(struct k_work *work) { - LOG_DBG("Raising HID indicators changed event: %x", hid_indicators); - raise_zmk_hid_indicators_changed( - (struct zmk_hid_indicators_changed){.indicators = hid_indicators}); -} - -static K_WORK_DEFINE(split_svc_update_indicators_work, split_svc_update_indicators_callback); - -static ssize_t split_svc_update_indicators(struct bt_conn *conn, const struct bt_gatt_attr *attr, - const void *buf, uint16_t len, uint16_t offset, - uint8_t flags) { - if (offset + len > sizeof(zmk_hid_indicators_t)) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); - } - - memcpy((uint8_t *)&hid_indicators + offset, buf, len); - - k_work_submit(&split_svc_update_indicators_work); - - return len; -} - -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - BT_GATT_SERVICE_DEFINE( split_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID)), BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID), @@ -186,11 +154,6 @@ BT_GATT_SERVICE_DEFINE( split_svc_sensor_state, NULL, &last_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 */ -#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) - BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_UPDATE_HID_INDICATORS_UUID), - BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE_ENCRYPT, NULL, - split_svc_update_indicators, NULL), -#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) ); K_THREAD_STACK_DEFINE(service_q_stack, CONFIG_ZMK_SPLIT_BLE_PERIPHERAL_STACK_SIZE); From f4176656ab7ce66bf7b2c00c4f20a9b1517c7143 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:39:18 +0000 Subject: [PATCH 8/9] feat(split): Add keymap state sending --- app/src/keymap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/keymap.c b/app/src/keymap.c index 94bd1204..c0657e41 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -97,10 +97,14 @@ static inline int set_layer_state(uint8_t layer, bool state) { // Don't send state changes unless there was an actual change if (old_state != _zmk_keymap_layer_state) { LOG_DBG("layer_changed: layer %d state %d", layer, state); - ret = raise_layer_state_changed(layer, state); - if (ret < 0) { - LOG_WRN("Failed to raise layer state changed (%d)", ret); + ZMK_EVENT_RAISE(create_layer_state_changed(layer, state)); +#if ZMK_BLE_IS_CENTRAL + int err = zmk_split_central_send_data(DATA_TAG_KEYMAP_STATE, sizeof(uint32_t), + (uint8_t *)&_zmk_keymap_layer_state); + if (err) { + LOG_ERR("Keymap send failed (err %d)", err); } +#endif } return ret; From c0a3d490b0e845d5b52c55ee9687bb7f639f62f6 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:44:56 +0000 Subject: [PATCH 9/9] fix(split): Update events and init function --- app/src/keymap.c | 2 +- app/src/split/bluetooth/central.c | 6 +----- app/src/split/bluetooth/service.c | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/src/keymap.c b/app/src/keymap.c index c0657e41..a5880f98 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -97,7 +97,7 @@ static inline int set_layer_state(uint8_t layer, bool state) { // Don't send state changes unless there was an actual change if (old_state != _zmk_keymap_layer_state) { LOG_DBG("layer_changed: layer %d state %d", layer, state); - ZMK_EVENT_RAISE(create_layer_state_changed(layer, state)); + raise_layer_state_changed(layer, state); #if ZMK_BLE_IS_CENTRAL int err = zmk_split_central_send_data(DATA_TAG_KEYMAP_STATE, sizeof(uint32_t), (uint8_t *)&_zmk_keymap_layer_state); diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index 5acaf6b2..41ca66a3 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -455,10 +455,6 @@ static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn, slot->batt_lvl_read_params.single.offset = 0; bt_gatt_read(conn, &slot->batt_lvl_read_params); #endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) */ - } - - bool subscribed = slot->run_behavior_handle && slot->subscribe_params.value_handle; - } else if (bt_uuid_cmp(chrc_uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_DATA_XFER_UUID)) == 0) { LOG_DBG("Found data transfer handle"); slot->discover_params.uuid = NULL; @@ -918,7 +914,7 @@ int zmk_split_central_send_data(enum data_tag tag, uint8_t size, uint8_t *data) return split_bt_data_xfer_payload(payload); } -int zmk_split_bt_central_init(const struct device *_arg) { +int zmk_split_bt_central_init(void) { k_work_queue_start(&split_central_split_run_q, split_central_split_run_q_stack, K_THREAD_STACK_SIZEOF(split_central_split_run_q_stack), CONFIG_ZMK_BLE_THREAD_PRIORITY, NULL); diff --git a/app/src/split/bluetooth/service.c b/app/src/split/bluetooth/service.c index 461ee185..b162348c 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -103,7 +103,7 @@ static void split_svc_data_xfer_callback(struct k_work *work) { LOG_DBG("Size correct, raising event"); struct zmk_split_data_xfer_event event; memcpy(&event.data_xfer, &data_xfer_payload, sizeof(struct zmk_split_data_xfer_data)); - ZMK_EVENT_RAISE(new_zmk_split_data_xfer_event(event)); + raise_zmk_split_data_xfer_event(event); } static K_WORK_DEFINE(split_svc_data_xfer_work, split_svc_data_xfer_callback);