Files
zmk/app/src/hid_indicators.c
Pete Johanson 147c340c6e 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>
2025-03-18 02:48:32 -04:00

69 lines
2.4 KiB
C

/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zmk/ble.h>
#include <zmk/endpoints.h>
#include <zmk/hid_indicators.h>
#include <zmk/events/hid_indicators_changed.h>
#include <zmk/events/endpoint_changed.h>
#include <zmk/split/central.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
static zmk_hid_indicators_t hid_indicators[ZMK_ENDPOINT_COUNT];
zmk_hid_indicators_t zmk_hid_indicators_get_current_profile(void) {
return zmk_hid_indicators_get_profile(zmk_endpoints_selected());
}
zmk_hid_indicators_t zmk_hid_indicators_get_profile(struct zmk_endpoint_instance endpoint) {
const int profile = zmk_endpoint_instance_to_index(endpoint);
return hid_indicators[profile];
}
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)
zmk_split_central_update_hid_indicator(indicators);
#endif
}
static K_WORK_DEFINE(led_changed_work, raise_led_changed_event);
void zmk_hid_indicators_set_profile(zmk_hid_indicators_t indicators,
struct zmk_endpoint_instance endpoint) {
int profile = zmk_endpoint_instance_to_index(endpoint);
// This write is not happening on the main thread. To prevent potential data races, every
// operation involving hid_indicators must be atomic. Currently, each function either reads
// or writes only one entry at a time, so it is safe to do these operations without a lock.
hid_indicators[profile] = indicators;
k_work_submit(&led_changed_work);
}
void zmk_hid_indicators_process_report(struct zmk_hid_led_report_body *report,
struct zmk_endpoint_instance endpoint) {
const zmk_hid_indicators_t indicators = (zmk_hid_indicators_t)report->leds;
zmk_hid_indicators_set_profile(indicators, endpoint);
LOG_DBG("Update HID indicators: endpoint=%d, indicators=%x", endpoint.transport, indicators);
}
static int profile_listener(const zmk_event_t *eh) {
raise_led_changed_event(NULL);
return 0;
}
ZMK_LISTENER(profile_listener, profile_listener);
ZMK_SUBSCRIPTION(profile_listener, zmk_endpoint_changed);