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

Feature: Full-Duplex Wired Split #2766

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
5 changes: 5 additions & 0 deletions app/boards/shields/zmk_uno/zmk_uno_split.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ left_encoder: &encoder {
status = "disabled";
};

&arduino_serial {
status = "okay";
};

/ {
chosen {
zmk,split-uart = &arduino_serial;
zmk,physical-layout = &split_matrix_physical_layout;
};

Expand Down
9 changes: 9 additions & 0 deletions app/include/linker/zmk-split-transport-central.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <zephyr/linker/linker-defs.h>

ITERABLE_SECTION_ROM(zmk_split_transport_central, 4)
9 changes: 9 additions & 0 deletions app/include/linker/zmk-split-transport-peripheral.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <zephyr/linker/linker-defs.h>

ITERABLE_SECTION_ROM(zmk_split_transport_peripheral, 4)
3 changes: 1 addition & 2 deletions app/include/zmk/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
#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_ROLE_CENTRAL))
(IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) && IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL))

#if ZMK_BLE_IS_CENTRAL
#define ZMK_BLE_PROFILE_COUNT (CONFIG_BT_MAX_PAIRED - CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS)
Expand Down
21 changes: 5 additions & 16 deletions app/include/zmk/split/bluetooth/central.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

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

#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
#include <zmk/hid_indicators_types.h>
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)

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);
Expand Down
8 changes: 0 additions & 8 deletions app/include/zmk/split/bluetooth/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,3 @@ struct zmk_split_input_event_payload {
uint32_t value;
uint8_t sync;
} __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,
const struct zmk_sensor_channel_data channel_data[],
size_t channel_data_size);

int zmk_split_bt_report_input(uint8_t reg, uint8_t type, uint16_t code, int32_t value, bool sync);
42 changes: 42 additions & 0 deletions app/include/zmk/split/central.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

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

#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE)

#include <zmk/ble.h>
#define BLE_PERIPHERAL_COUNT ZMK_SPLIT_BLE_PERIPHERAL_COUNT

#else

#define BLE_PERIPHERAL_COUNT 0

#endif

#if IS_ENABLED(CONFIG_ZMK_SPLIT_WIRED)
#define WIRED_PERIPHERAL_COUNT 1
#else
#define WIRED_PERIPHERAL_COUNT 0
#endif

#define ZMK_SPLIT_CENTRAL_PERIPHERAL_COUNT MAX(BLE_PERIPHERAL_COUNT, WIRED_PERIPHERAL_COUNT)

#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
#include <zmk/hid_indicators_types.h>
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)

int zmk_split_cental_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_central_update_hid_indicator(zmk_hid_indicators_t indicators);

#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
11 changes: 11 additions & 0 deletions app/include/zmk/split/peripheral.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <zmk/split/transport/types.h>

int zmk_split_peripheral_report_event(const struct zmk_split_transport_peripheral_event *event);
33 changes: 33 additions & 0 deletions app/include/zmk/split/transport/central.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <zephyr/types.h>

#include <zmk/split/transport/types.h>

typedef int (*zmk_split_transport_central_send_command_t)(
uint8_t source, struct zmk_split_transport_central_command cmd);
typedef int (*zmk_split_transport_central_get_available_source_ids_t)(uint8_t *sources);

struct zmk_split_transport_central_api {
zmk_split_transport_central_send_command_t send_command;
zmk_split_transport_central_get_available_source_ids_t get_available_source_ids;
};

struct zmk_split_transport_central {
const struct zmk_split_transport_central_api *api;
};

int zmk_split_transport_central_peripheral_event_handler(
const struct zmk_split_transport_central *transport, uint8_t source,
struct zmk_split_transport_peripheral_event ev);

#define ZMK_SPLIT_TRANSPORT_CENTRAL_REGISTER(name, _api) \
STRUCT_SECTION_ITERABLE(zmk_split_transport_central, name) = { \
.api = _api, \
};
31 changes: 31 additions & 0 deletions app/include/zmk/split/transport/peripheral.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <zephyr/types.h>

#include <zmk/split/transport/types.h>

typedef int (*zmk_split_central_report_event_callback_t)(
const struct zmk_split_transport_peripheral_event *event);

struct zmk_split_transport_peripheral_api {
zmk_split_central_report_event_callback_t report_event;
};

struct zmk_split_transport_peripheral {
const struct zmk_split_transport_peripheral_api *api;
};

int zmk_split_transport_peripheral_command_handler(
const struct zmk_split_transport_peripheral *transport,
struct zmk_split_transport_central_command cmd);

#define ZMK_SPLIT_TRANSPORT_PERIPHERAL_REGISTER(name, _api) \
STRUCT_SECTION_ITERABLE(zmk_split_transport_peripheral, name) = { \
.api = _api, \
};
73 changes: 73 additions & 0 deletions app/include/zmk/split/transport/types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <zmk/hid_indicators_types.h>
#include <zmk/sensors.h>
#include <zephyr/sys/util.h>

enum zmk_split_transport_peripheral_event_type {
ZMK_SPLIT_TRANSPORT_PERIPHERAL_EVENT_TYPE_KEY_POSITION,
ZMK_SPLIT_TRANSPORT_PERIPHERAL_EVENT_TYPE_SENSOR_EVENT,
ZMK_SPLIT_TRANSPORT_PERIPHERAL_EVENT_TYPE_INPUT_EVENT,
};

struct zmk_split_transport_peripheral_event {
union {
struct {
uint8_t position;
uint8_t pressed;
} key_position;

struct {
struct zmk_sensor_channel_data channel_data;

int64_t timestamp;

uint8_t sensor_index;
} sensor_event;

struct {
uint8_t reg;
uint8_t sync;
uint8_t type;
uint16_t code;
int32_t value;
} input_event;
} data;

enum zmk_split_transport_peripheral_event_type type;
} __packed;

enum zmk_split_transport_central_command_type {
ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_POLL_EVENTS,
ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_TRIGGER_BEHAVIOR,
ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_SET_PHYSICAL_LAYOUT,
ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_SET_HID_INDICATORS,
} __packed;

struct zmk_split_transport_central_command {
union {
struct {
char behavior_dev[16];
uint32_t param1, param2;
uint32_t position;
uint8_t event_source;
uint8_t state;
} trigger_behavior;

struct {
uint8_t layout_idx;
} set_physical_layout;

struct {
zmk_hid_indicators_t indicators;
} set_hid_indicators;
} data;

enum zmk_split_transport_central_command_type type;
} __packed;
15 changes: 7 additions & 8 deletions app/src/behavior.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@

#endif

#include <zmk/ble.h>
#if ZMK_BLE_IS_CENTRAL
#include <zmk/split/bluetooth/central.h>
#if IS_ENABLED(CONFIG_ZMK_SPLIT) && IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
#include <zmk/split/central.h>
#endif

#include <drivers/behavior.h>
Expand Down Expand Up @@ -95,19 +94,19 @@ int zmk_behavior_invoke_binding(const struct zmk_behavior_binding *src_binding,
case BEHAVIOR_LOCALITY_CENTRAL:
return invoke_locally(&binding, event, pressed);
case BEHAVIOR_LOCALITY_EVENT_SOURCE:
#if ZMK_BLE_IS_CENTRAL // source is a member of event because CONFIG_ZMK_SPLIT is enabled
#if IS_ENABLED(CONFIG_ZMK_SPLIT) && IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
if (event.source == ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL) {
return invoke_locally(&binding, event, pressed);
} else {
return zmk_split_bt_invoke_behavior(event.source, &binding, event, pressed);
return zmk_split_cental_invoke_behavior(event.source, &binding, event, pressed);
}
#else
return invoke_locally(&binding, event, pressed);
#endif
case BEHAVIOR_LOCALITY_GLOBAL:
#if ZMK_BLE_IS_CENTRAL
for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) {
zmk_split_bt_invoke_behavior(i, &binding, event, pressed);
#if IS_ENABLED(CONFIG_ZMK_SPLIT) && IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
for (int i = 0; i < ZMK_SPLIT_CENTRAL_PERIPHERAL_COUNT; i++) {
zmk_split_cental_invoke_behavior(i, &binding, event, pressed);
}
#endif
return invoke_locally(&binding, event, pressed);
Expand Down
6 changes: 3 additions & 3 deletions app/src/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static struct bt_data zmk_ble_ad[] = {
),
};

#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) && IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)

static bt_addr_le_t peripheral_addrs[ZMK_SPLIT_BLE_PERIPHERAL_COUNT];

Expand Down Expand Up @@ -355,7 +355,7 @@ int zmk_ble_set_device_name(char *name) {
return update_advertising();
}

#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) && IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)

int zmk_ble_put_peripheral_addr(const bt_addr_le_t *addr) {
for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) {
Expand Down Expand Up @@ -444,7 +444,7 @@ static int ble_profiles_handle_set(const char *name, size_t len, settings_read_c
return err;
}
}
#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) && IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
else if (settings_name_steq(name, "peripheral_addresses", &next) && next) {
if (len != sizeof(bt_addr_le_t)) {
return -EINVAL;
Expand Down
6 changes: 3 additions & 3 deletions app/src/hid_indicators.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <zmk/hid_indicators.h>
#include <zmk/events/hid_indicators_changed.h>
#include <zmk/events/endpoint_changed.h>
#include <zmk/split/bluetooth/central.h>
#include <zmk/split/central.h>

LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

Expand All @@ -32,8 +32,8 @@ static void raise_led_changed_event(struct k_work *_work) {

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);
#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) && IS_ENABLED(CONFIG_ZMK_SPLIT)
zmk_split_central_update_hid_indicator(indicators);
#endif
}

Expand Down
14 changes: 11 additions & 3 deletions app/src/pointing/input_split.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int zmk_input_split_report_peripheral_event(uint8_t reg, uint8_t type, uint16_t

#else

#include <zmk/split/bluetooth/service.h>
#include <zmk/split/peripheral.h>

#define ZIS_INST(n) \
static const struct zmk_input_processor_entry processors_##n[] = \
Expand All @@ -59,8 +59,16 @@ int zmk_input_split_report_peripheral_event(uint8_t reg, uint8_t type, uint16_t
zmk_input_processor_handle_event(processors_##n[i].dev, evt, processors_##n[i].param1, \
processors_##n[i].param2, NULL); \
} \
zmk_split_bt_report_input(DT_INST_REG_ADDR(n), evt->type, evt->code, evt->value, \
evt->sync); \
struct zmk_split_transport_peripheral_event ev = { \
.type = ZMK_SPLIT_TRANSPORT_PERIPHERAL_EVENT_TYPE_INPUT_EVENT, \
.data = {.input_event = { \
.reg = DT_INST_REG_ADDR(n), \
.type = evt->type, \
.code = evt->code, \
.value = evt->value, \
.sync = evt->sync, \
}}}; \
zmk_split_peripheral_report_event(&ev); \
} \
INPUT_CALLBACK_DEFINE(DEVICE_DT_GET(DT_INST_PHANDLE(n, device)), split_input_handler_##n);

Expand Down
Loading
Loading