mirror of
https://github.com/zmkfirmware/zmk.git
synced 2026-03-19 20:45:18 -05:00
Feature: Full-Duplex Wired Split (#2766)
refactor(split): Refactor split code for extension Extract central/peripheral code to allow for plugging in alternate transports, instead of tying all split logic to BT. feat(split): Add full-duplex wired split support * Depends on full-duplex hardware UART for communication. * Supports all existing central commands/peripheral events, including sensors/inputs from peripherals. * Only one wired split peripheral supported (for now) * Relies on chosen `zmk,split-uart` referencing the UART device. docs: Add wired split config docs. Migrate split to its own dedicated config file, and add details on wired split config. Co-authored-by: Nicolas Munnich <98408764+Nick-Munnich@users.noreply.github.com> fix: Properly override stack size on RP2040 Move the system work queue stack size override on RP2040 ouf of a `ZMK_BLE` conditional so it is properly applied generally for that SoC. --------- Co-authored-by: Nicolas Munnich <98408764+Nick-Munnich@users.noreply.github.com>
This commit is contained in:
9
app/include/linker/zmk-split-transport-central.ld
Normal file
9
app/include/linker/zmk-split-transport-central.ld
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2025 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <zephyr/linker/linker-defs.h>
|
||||
|
||||
ITERABLE_SECTION_ROM(zmk_split_transport_central, 4)
|
||||
9
app/include/linker/zmk-split-transport-peripheral.ld
Normal file
9
app/include/linker/zmk-split-transport-peripheral.ld
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2025 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <zephyr/linker/linker-defs.h>
|
||||
|
||||
ITERABLE_SECTION_ROM(zmk_split_transport_peripheral, 4)
|
||||
@@ -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)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
#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);
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING)
|
||||
@@ -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);
|
||||
|
||||
48
app/include/zmk/split/central.h
Normal file
48
app/include/zmk/split/central.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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_central_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)
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING)
|
||||
|
||||
int zmk_split_central_get_peripheral_battery_level(uint8_t source, uint8_t *level);
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING)
|
||||
11
app/include/zmk/split/peripheral.h
Normal file
11
app/include/zmk/split/peripheral.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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
app/include/zmk/split/transport/central.h
Normal file
33
app/include/zmk/split/transport/central.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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
app/include/zmk/split/transport/peripheral.h
Normal file
31
app/include/zmk/split/transport/peripheral.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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, \
|
||||
};
|
||||
76
app/include/zmk/split/transport/types.h
Normal file
76
app/include/zmk/split/transport/types.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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_EVENT,
|
||||
ZMK_SPLIT_TRANSPORT_PERIPHERAL_EVENT_TYPE_SENSOR_EVENT,
|
||||
ZMK_SPLIT_TRANSPORT_PERIPHERAL_EVENT_TYPE_INPUT_EVENT,
|
||||
ZMK_SPLIT_TRANSPORT_PERIPHERAL_EVENT_TYPE_BATTERY_EVENT,
|
||||
};
|
||||
|
||||
struct zmk_split_transport_peripheral_event {
|
||||
enum zmk_split_transport_peripheral_event_type type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint8_t position;
|
||||
uint8_t pressed;
|
||||
} key_position_event;
|
||||
|
||||
struct {
|
||||
struct zmk_sensor_channel_data channel_data;
|
||||
|
||||
uint8_t sensor_index;
|
||||
} sensor_event;
|
||||
|
||||
struct {
|
||||
uint8_t reg;
|
||||
uint8_t sync;
|
||||
uint8_t type;
|
||||
uint16_t code;
|
||||
int32_t value;
|
||||
} input_event;
|
||||
|
||||
struct {
|
||||
uint8_t level;
|
||||
} battery_event;
|
||||
} data;
|
||||
} __packed;
|
||||
|
||||
enum zmk_split_transport_central_command_type {
|
||||
ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_POLL_EVENTS,
|
||||
ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_INVOKE_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 {
|
||||
enum zmk_split_transport_central_command_type type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
char behavior_dev[16];
|
||||
uint32_t param1, param2;
|
||||
uint32_t position;
|
||||
uint8_t event_source;
|
||||
uint8_t state;
|
||||
} invoke_behavior;
|
||||
|
||||
struct {
|
||||
uint8_t layout_idx;
|
||||
} set_physical_layout;
|
||||
|
||||
struct {
|
||||
zmk_hid_indicators_t indicators;
|
||||
} set_hid_indicators;
|
||||
} data;
|
||||
} __packed;
|
||||
Reference in New Issue
Block a user