83 lines
2.6 KiB
C
83 lines
2.6 KiB
C
/*
|
|
* Copyright (c) 2022 The ZMK Contributors
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <kernel.h>
|
|
#include <logging/log.h>
|
|
|
|
#include <zmk/ble.h>
|
|
#include <zmk/endpoints.h>
|
|
#include <zmk/led_indicators.h>
|
|
#include <zmk/events/led_indicator_changed.h>
|
|
#include <zmk/events/endpoint_selection_changed.h>
|
|
|
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|
|
|
#define NUM_USB_PROFILES (COND_CODE_1(IS_ENABLED(CONFIG_ZMK_USB), (1), (0)))
|
|
#define NUM_BLE_PROFILES (COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (CONFIG_BT_MAX_CONN), (0)))
|
|
#define NUM_PROFILES (NUM_USB_PROFILES + NUM_BLE_PROFILES)
|
|
|
|
static zmk_led_indicators_flags_t led_flags[NUM_PROFILES];
|
|
|
|
static size_t profile_index(enum zmk_endpoint endpoint, uint8_t profile) {
|
|
switch (endpoint) {
|
|
case ZMK_ENDPOINT_USB:
|
|
return 0;
|
|
case ZMK_ENDPOINT_BLE:
|
|
return NUM_USB_PROFILES + profile;
|
|
}
|
|
|
|
CODE_UNREACHABLE;
|
|
}
|
|
|
|
zmk_led_indicators_flags_t zmk_led_indicators_get_current_flags() {
|
|
enum zmk_endpoint endpoint = zmk_endpoints_selected();
|
|
uint8_t profile = 0;
|
|
|
|
#if IS_ENABLED(CONFIG_ZMK_BLE)
|
|
if (endpoint == ZMK_ENDPOINT_USB) {
|
|
profile = zmk_ble_active_profile_index();
|
|
}
|
|
#endif
|
|
|
|
return zmk_led_indicators_get_flags(endpoint, profile);
|
|
}
|
|
|
|
zmk_led_indicators_flags_t zmk_led_indicators_get_flags(enum zmk_endpoint endpoint,
|
|
uint8_t profile) {
|
|
size_t index = profile_index(endpoint, profile);
|
|
return led_flags[index];
|
|
}
|
|
|
|
static void raise_led_indicators_changed_event(struct k_work *_work) {
|
|
ZMK_EVENT_RAISE(new_zmk_led_indicators_changed(
|
|
(struct zmk_led_indicators_changed){.leds = zmk_led_indicators_get_current_flags()}));
|
|
}
|
|
|
|
static K_WORK_DEFINE(led_changed_work, raise_led_indicators_changed_event);
|
|
|
|
void zmk_led_indicators_update_flags(zmk_led_indicators_flags_t leds, enum zmk_endpoint endpoint,
|
|
uint8_t profile) {
|
|
size_t index = profile_index(endpoint, profile);
|
|
led_flags[index] = leds;
|
|
|
|
k_work_submit(&led_changed_work);
|
|
}
|
|
|
|
void zmk_led_indicators_process_report(struct zmk_hid_led_report_body *report,
|
|
enum zmk_endpoint endpoint, uint8_t profile) {
|
|
zmk_led_indicators_flags_t leds = report->leds;
|
|
zmk_led_indicators_update_flags(leds, endpoint, profile);
|
|
|
|
LOG_DBG("Update LED indicators: endpoint=%d, profile=%d, flags=%x", endpoint, profile, leds);
|
|
}
|
|
|
|
static int endpoint_listener(const zmk_event_t *eh) {
|
|
raise_led_indicators_changed_event(NULL);
|
|
return 0;
|
|
}
|
|
|
|
static ZMK_LISTENER(endpoint_listener, endpoint_listener);
|
|
static ZMK_SUBSCRIPTION(endpoint_listener, zmk_endpoint_selection_changed);
|