Skip to content
Open
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
791 changes: 400 additions & 391 deletions patches/c2usb/0001-Add-diagnostics-logs.patch

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion right/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,18 @@
"runToEntryPoint": "main",
"armToolchainPath": "${env:ARM_GCC_DIR}/bin",
"svdFile": "${workspaceFolder}/../svd/MK22F51212.xml",
"preLaunchTask": "Build + Merge UHK 60 right (v2-release)"
"preLaunchTask": "Build + Merge UHK 60 right (v2-release)",
"rttConfig": {
"enabled": true,
"address": "auto",
"decoders": [
{
"label": "RTT",
"port": 0,
"type": "console"
}
]
}
}
],
"inputs": [
Expand Down
3 changes: 3 additions & 0 deletions right/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ CONFIG_MCUX_COMPONENT_driver.pit=y
CONFIG_MCUX_COMPONENT_driver.rtc=y
CONFIG_MCUX_COMPONENT_driver.uart=n
CONFIG_MCUX_COMPONENT_driver.lpuart=n

# Segger J-Link RTT debug console, enable for PRINTF debugging
#CONFIG_MCUX_COMPONENT_utility.debug_console_rtt=y
372 changes: 337 additions & 35 deletions right/src/hid/keyboard_app.cpp

Large diffs are not rendered by default.

135 changes: 134 additions & 1 deletion right/src/hid/keyboard_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,144 @@ extern "C" {
}
#include "double_buffer.hpp"
#include <hid/app/keyboard.hpp>
#include <hid/app/lamparray.hpp>
#include <hid/application.hpp>
#include <hid/page/consumer.hpp>
#include <usb/df/class/hid.hpp>

using scancode = hid::page::keyboard_keypad;

template <std::uint8_t REPORT_ID = 0>
struct keyboard_attributes_report
: public hid::report::base<hid::report::type::FEATURE, REPORT_ID> {
hid::app::keyboard::form_factor form_factor{};
hid::app::keyboard::key_type key_type{};
hid::app::keyboard::layout layout{};
usb::istring ietf_lang_tag_index{};

[[nodiscard]] static constexpr auto descriptor()
{
using namespace hid::page;
using namespace hid::rdf;

// clang-format off
return hid::rdf::descriptor(
usage_page<consumer>(),
collection::logical(
conditional_report_id<REPORT_ID>(),
report_size(8),
report_count(4),
usage(consumer::KEYBOARD_FORM_FACTOR),
usage(consumer::KEYBOARD_KEY_TYPE),
usage(consumer::KEYBOARD_PHYSICAL_LAYOUT),
usage(consumer::KEYBOARD_IETF_LANGUAGE_TAG_INDEX),
logical_limits<1, 2>(0, std::numeric_limits<std::uint8_t>::max()),
feature::absolute_constant()
)
);
// clang-format on
}
};

class keyboard_base_session : public hid::session {
public:
using hid::session::session;
using leds_boot_report = hid::app::keyboard::output_report<0>;
using leds_report = hid::app::keyboard::output_report<report_ids::OUT_KEYBOARD_LEDS>;
using attributes_report = keyboard_attributes_report<report_ids::FEATURE_KEYBOARD_ATTRIBUTES>;

virtual leds_boot_report get_leds_report() const = 0;

#if DEVICE_IS_UHK60
static constexpr uint8_t MULTI_UPDATE_LIMIT = 10;

static constexpr uint8_t LEFT_MAX_LAMP_ID = 33;
static constexpr uint8_t LEFT_LAMP_COUNT = LEFT_MAX_LAMP_ID + 1;

static constexpr uint8_t LEFT_HALF_LAMP_COUNT = LEFT_LAMP_COUNT - 3;

static constexpr uint8_t RIGHT_MAX_LAMP_ID = 32;
static constexpr uint8_t RIGHT_LAMP_COUNT = RIGHT_MAX_LAMP_ID + 1;

using left_lamp_array_attrs_report = hid::app::lamparray::lamp_array_attributes_report<
report_ids::FEATURE_LEFT_LAMP_ARRAY_ATTRS>;
using left_lamp_attrs_req_report = hid::app::lamparray::lamp_attributes_request_report<
report_ids::FEATURE_LEFT_LAMP_ATTRS_REQ>;
using left_lamp_attrs_rsp_report = hid::app::lamparray::lamp_attributes_response_report<
report_ids::FEATURE_LEFT_LAMP_ATTRS_RSP>;
using left_lamp_multi_update_report =
hid::app::lamparray::lamp_multi_update_report<report_ids::FEATURE_LEFT_LAMP_MULTI_UPDATE,
MULTI_UPDATE_LIMIT>;
using left_lamp_range_update_report =
hid::app::lamparray::lamp_range_update_report<report_ids::FEATURE_LEFT_LAMP_RANGE_UPDATE>;
using left_lamp_control_report =
hid::app::lamparray::control_report<report_ids::FEATURE_LEFT_LAMP_CONTROL>;

static constexpr auto left_lamp_descriptor()
{
using namespace hid::rdf;
return descriptor(
// clang-format off
usage_page<hid::page::lighting_and_illumination>(),
usage(hid::page::lighting_and_illumination::LAMP_ARRAY),
collection::application(
left_lamp_array_attrs_report::descriptor(),
left_lamp_attrs_req_report::descriptor(),
left_lamp_attrs_rsp_report::descriptor(),
left_lamp_multi_update_report::descriptor(),
left_lamp_range_update_report::descriptor(),
left_lamp_control_report::descriptor()
)
// clang-format on
);
}
using right_lamp_array_attrs_report = hid::app::lamparray::lamp_array_attributes_report<
report_ids::FEATURE_RIGHT_LAMP_ARRAY_ATTRS>;
using right_lamp_attrs_req_report = hid::app::lamparray::lamp_attributes_request_report<
report_ids::FEATURE_RIGHT_LAMP_ATTRS_REQ>;
using right_lamp_attrs_rsp_report = hid::app::lamparray::lamp_attributes_response_report<
report_ids::FEATURE_RIGHT_LAMP_ATTRS_RSP>;
using right_lamp_multi_update_report =
hid::app::lamparray::lamp_multi_update_report<report_ids::FEATURE_RIGHT_LAMP_MULTI_UPDATE,
MULTI_UPDATE_LIMIT>;
using right_lamp_range_update_report =
hid::app::lamparray::lamp_range_update_report<report_ids::FEATURE_RIGHT_LAMP_RANGE_UPDATE>;
using right_lamp_control_report =
hid::app::lamparray::control_report<report_ids::FEATURE_RIGHT_LAMP_CONTROL>;

static constexpr auto right_lamp_descriptor()
{
using namespace hid::rdf;
return descriptor(
// clang-format off
usage_page<hid::page::lighting_and_illumination>(),
usage(hid::page::lighting_and_illumination::LAMP_ARRAY),
collection::application(
right_lamp_array_attrs_report::descriptor(),
right_lamp_attrs_req_report::descriptor(),
right_lamp_attrs_rsp_report::descriptor(),
right_lamp_multi_update_report::descriptor(),
right_lamp_range_update_report::descriptor(),
right_lamp_control_report::descriptor()
)
// clang-format on
);
}
#endif
};

class keyboard_session : public keyboard_base_session {
C2USB_USB_TRANSFER_ALIGN(leds_report, leds_buffer_) {};

#if DEVICE_IS_UHK60
uint8_t req_led_left_{};
uint8_t req_led_right_{};
static constexpr uint8_t left_led_remote_mode_flag = 0x1;
static constexpr uint8_t right_led_remote_mode_flag = 0x2;
static constexpr uint8_t led_remote_mode = 0x3;
uint8_t led_remote_mode_flags_{};
#endif

protected:
void report_sent(const std::span<const uint8_t> &data) override;
std::span<const uint8_t> get_report(
Expand Down Expand Up @@ -54,6 +178,7 @@ class keyboard_app : public hid::application {
using keys_boot_report = hid::app::keyboard::keys_input_report<0>;
using keys_6kro_report = hid::app::keyboard::keys_input_report<KEYS_6KRO_REPORT_ID>;

// this includes both 6KRO and NKRO reports, used on BLE
static constexpr auto report_desc()
{
using namespace hid::page;
Expand Down Expand Up @@ -124,6 +249,11 @@ class keyboard_app : public hid::application {
input::absolute_variable(),
input::byte_padding<NKRO_USAGE_COUNT>()
)
#if DEVICE_IS_UHK60
,
keyboard_session::left_lamp_descriptor(),
keyboard_session::right_lamp_descriptor()
#endif
);
// clang-format on
}
Expand Down Expand Up @@ -180,10 +310,13 @@ class keyboard_app : public hid::application {

keyboard_session *session() { return session_.has_value() ? &*session_ : nullptr; }

static usb::df::hid::string_function &usb_function() { return usb_handle().usb_function_; }

private:
std::optional<keyboard_session> session_{};
usb::df::hid::string_function usb_function_;

keyboard_app(const hid::report_protocol &rp) : hid::application(rp) {}
keyboard_app(const hid::report_protocol &rp);
hid::session &start(const hid::session::params &params) override;
void stop(hid::session &sess) override;
};
Expand Down
27 changes: 22 additions & 5 deletions right/src/hid/report_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

enum report_ids {
#if DEVICE_IS_UHK60
IN_KEYBOARD_6KRO = 0,
IN_KEYBOARD_NKRO = 0,
OUT_KEYBOARD_LEDS = 0,
IN_KEYBOARD_6KRO = 1,
IN_KEYBOARD_NKRO = 2,
OUT_KEYBOARD_LEDS = 1,
FEATURE_KEYBOARD_ATTRIBUTES = 1,

IN_MOUSE = 1,
IN_MOUSE = 3,
FEATURE_MOUSE =
1, // mouse needs nonzero report ID as workaround for Linux high-res scrolling bug
3, // mouse needs nonzero report ID as workaround for Linux high-res scrolling bug
// https://bugzilla.kernel.org/show_bug.cgi?id=220144

IN_CONTROLS = 0,
Expand All @@ -19,6 +20,21 @@ enum report_ids {
OUT_COMMAND = 0,

IN_GAMEPAD = 0,

FEATURE_LEFT_LAMP_ARRAY_ATTRS = 8,
FEATURE_LEFT_LAMP_ATTRS_REQ = 9,
FEATURE_LEFT_LAMP_ATTRS_RSP = 10,
FEATURE_LEFT_LAMP_MULTI_UPDATE = 11,
FEATURE_LEFT_LAMP_RANGE_UPDATE = 12,
FEATURE_LEFT_LAMP_CONTROL = 13,

FEATURE_RIGHT_LAMP_ARRAY_ATTRS = 14,
FEATURE_RIGHT_LAMP_ATTRS_REQ = 15,
FEATURE_RIGHT_LAMP_ATTRS_RSP = 16,
FEATURE_RIGHT_LAMP_MULTI_UPDATE = 17,
FEATURE_RIGHT_LAMP_RANGE_UPDATE = 18,
FEATURE_RIGHT_LAMP_CONTROL = 19,

#else
// due to Android HOGP limitation, only one HOGP instance can exist,
// so the applications are merged into one instance with multiple TLCs
Expand All @@ -28,6 +44,7 @@ enum report_ids {
IN_KEYBOARD_6KRO = 1,
IN_KEYBOARD_NKRO = 2,
OUT_KEYBOARD_LEDS = 1,
FEATURE_KEYBOARD_ATTRIBUTES = 1,

IN_MOUSE = 3,
FEATURE_MOUSE = 3,
Expand Down
10 changes: 5 additions & 5 deletions right/src/hid/transport_usb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ extern "C" {
#endif
}
#ifdef __ZEPHYR__
#include "port/zephyr/udc_mac.hpp"
#include "usb/df/vendor/zephyr/udc_mac.hpp"
#else
#include "port/nxp/mcux_mac.hpp"
#include "usb/df/vendor/nxp/mcux_mac.hpp"
#endif
#include "command_app.hpp"
#include "controls_app.hpp"
#include "keyboard_app.hpp"
#include "mouse_app.hpp"
#include "usb/df/class/hid.hpp"
#include "usb/df/config_factory.hpp"
#include "usb/df/device.hpp"
#include "usb/df/vendor/microsoft/os_extension.hpp"
#include "usb/df/vendor/microsoft/xinput.hpp"
Expand Down Expand Up @@ -71,8 +72,7 @@ struct usb_manager {
using namespace usb::df;

static constexpr auto speed = usb::speed::FULL;
static usb::df::hid::function usb_kb{
keyboard_app::usb_handle(), usb::hid::boot_protocol_mode::KEYBOARD};
auto &usb_kb = keyboard_app::usb_function();
static usb::df::hid::function usb_mouse{mouse_app::usb_handle()};
static usb::df::hid::function usb_command{command_app::usb_handle()};
static usb::df::hid::function usb_controls{controls_app::usb_handle()};
Expand Down Expand Up @@ -134,7 +134,7 @@ struct usb_manager {
}

#ifdef __ZEPHYR__
usb::zephyr::udc_mac mac_{DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), 256,
usb::df::zephyr::udc_mac mac_{DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), 256,
(nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_CONNECTED)
? usb::power::state::L2_SUSPEND
: usb::power::state::L3_OFF};
Expand Down
14 changes: 13 additions & 1 deletion right/src/ledmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,9 @@ static void setKeyColor(const rgb_t* color, uint8_t slotId, uint8_t keyId) {
setPerKeyColor(color, determineMode(slotId), slotId, keyId);
}

void Ledmap_SetKeyColor(const rgb_t* color, uint8_t slotId, uint8_t keyId) {
setKeyColor(color, slotId, keyId);
}

void Ledmap_SetBlackValues(void) {
setEntireMatrix(0);
Expand All @@ -653,6 +656,11 @@ void handleModeChange(backlighting_mode_t from, backlighting_mode_t to) {
}
}

void Ledmap_TriggerFullUpdate(void) {
EventVector_Set(EventVector_LedManagerFullUpdateNeeded);
EventVector_WakeMain();
}

void Ledmap_ActivateTestLedMode(bool active) {
if (active) {
backlightingLedTestStart = Timer_GetCurrentTime();
Expand Down Expand Up @@ -700,6 +708,7 @@ void Ledmap_UpdateBacklightLeds(void) {
updateLedsByLightNoneStrategy();
break;
case BacklightingMode_Unspecified:
case BacklightingMode_HidLampArray:
break;
}
#if DEVICE_IS_UHK80_RIGHT || DEVICE_IS_UHK80_LEFT
Expand Down Expand Up @@ -756,7 +765,10 @@ void Ledmap_InitLedLayout(void) {

static void updateAlwaysOn() {
backlighting_mode_t mode = Ledmap_GetEffectiveBacklightMode();
Ledmap_AlwaysOn = mode == BacklightingMode_LightAll || mode == BacklightingMode_LedTest;
Ledmap_AlwaysOn = (mode == BacklightingMode_LightAll)
|| (mode == BacklightingMode_LedTest)
|| (mode == BacklightingMode_HidLampArray)
;
}

void Ledmap_SetTemporaryLedBacklightingMode(backlighting_mode_t newMode) {
Expand Down
5 changes: 5 additions & 0 deletions right/src/ledmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
BacklightingMode_LightAll,
BacklightingMode_LightNone,
BacklightingMode_Unspecified,
// https://www.usb.org/sites/default/files/hutrr84_-_lighting_and_illumination_page.pdf
// https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/dynamic-lighting-devices
BacklightingMode_HidLampArray,
} backlighting_mode_t;

typedef enum {
Expand Down Expand Up @@ -59,5 +62,7 @@
void Ledmap_SetTemporaryLedBacklightingMode(backlighting_mode_t newMode);
void Ledmap_ResetTemporaryLedBacklightingMode();
backlighting_mode_t Ledmap_GetEffectiveBacklightMode();
void Ledmap_SetKeyColor(const rgb_t* color, uint8_t slotId, uint8_t keyId);
void Ledmap_TriggerFullUpdate(void);

#endif
6 changes: 6 additions & 0 deletions right/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@
#include "trace_reasons.h"
#include "config_manager.h"
#include "hid/transport.h"
#if __has_include("fsl_debug_console.h")
#include "fsl_debug_console.h"
#endif

static volatile bool IsEepromInitialized = false;
static volatile bool IsConfigInitialized = false;
static volatile bool IsHardwareConfigInitialized = false;

ATTR_WEAK void DbgConsole_Init(void) {}

static void userConfigurationReadFinished(void)
{
IsEepromInitialized = true;
Expand Down Expand Up @@ -196,6 +201,7 @@ static void checkSleepMode() {

int main(void)
{
DbgConsole_Init();
Debug_InitStackCanary();
Trace_Init();
if (StateWormhole_IsOpen()) {
Expand Down
2 changes: 1 addition & 1 deletion submanifests/c2usb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ manifest:
projects:
- name: c2usb
remote: IntergatedCircuits
revision: 0e11e25e72ecad59847a3de55507ab985a785ee6
revision: aab54956fbddc0b9ae70deb180aef479d131345d
import: true