From 8f0cd0f158d9a2d54f360cb50b284c17506d696f Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Fri, 26 Sep 2025 22:38:39 +0200 Subject: [PATCH 01/16] nrf: update sysbuild presets workaround with upstream https://github.com/zephyrproject-rtos/zephyr/pull/96609 --- device/CMakePresets.json | 60 +++++------ ...-application-CMakePresets.json-files.patch | 101 ++++++++++++++++++ ...lows-using-application-cmake-presets.patch | 59 ---------- 3 files changed, 131 insertions(+), 89 deletions(-) create mode 100644 patches/zephyr/0003-sysbuild-support-application-CMakePresets.json-files.patch delete mode 100644 patches/zephyr/0003-west-sysbuild-allows-using-application-cmake-presets.patch diff --git a/device/CMakePresets.json b/device/CMakePresets.json index 859b0966b..d446610cf 100644 --- a/device/CMakePresets.json +++ b/device/CMakePresets.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 4, "cmakeMinimumRequired": { "major": 3, "minor": 20 @@ -9,84 +9,84 @@ "name": "uhk-80-right", "displayName": "Build for UHK 80 right", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-80-right", + "binaryDir": "${fileDir}/build/uhk-80-right", "cacheVariables": { "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-80-right", "BOARD_ROOT": "${sourceParentDir}/", - "mcuboot_OVERLAY_CONFIG": "${sourceDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${sourceDir}/prj_release.conf", - "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/uhk-80.conf;${sourceDir}/prj.conf.overlays/ble_nus.conf;${sourceDir}/prj.conf.overlays/ble_nus_client.conf;${sourceDir}/prj.conf.overlays/ble_hid.conf;prj.conf.overlays/uhk-80-right.conf" + "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", + "CONF_FILE": "${fileDir}/prj_release.conf", + "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf;${fileDir}/prj.conf.overlays/ble_hid.conf;${fileDir}/prj.conf.overlays/uhk-80-right.conf" } }, { "name": "uhk-80-right-debug", "displayName": "Debug build for UHK 80 right", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-80-right-debug", + "binaryDir": "${fileDir}/build/uhk-80-right-debug", "cacheVariables": { "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-80-right", - "BOARD_ROOT": "${sourceParentDir}/", - "mcuboot_OVERLAY_CONFIG": "${sourceDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${sourceDir}/prj.conf", - "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/uhk-80.conf;${sourceDir}/prj.conf.overlays/ble_nus.conf;${sourceDir}/prj.conf.overlays/ble_nus_client.conf;${sourceDir}/prj.conf.overlays/ble_hid.conf,prj.conf.overlays/uhk-80-right.conf" + "BOARD_ROOT": "${fileDir}/../", + "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", + "CONF_FILE": "${fileDir}/prj.conf", + "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf;${fileDir}/prj.conf.overlays/ble_hid.conf;${fileDir}/prj.conf.overlays/uhk-80-right.conf" } }, { "name": "uhk-80-left", "displayName": "Build for UHK 80 left", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-80-left", + "binaryDir": "${fileDir}/build/uhk-80-left", "cacheVariables": { "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-80-left", - "BOARD_ROOT": "${sourceParentDir}/", - "mcuboot_OVERLAY_CONFIG": "${sourceDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${sourceDir}/prj_release.conf", - "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/uhk-80.conf;${sourceDir}/prj.conf.overlays/ble_nus.conf" + "BOARD_ROOT": "${fileDir}/../", + "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", + "CONF_FILE": "${fileDir}/prj_release.conf", + "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf" } }, { "name": "uhk-80-left-debug", "displayName": "Debug build for UHK 80 left", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-80-left-debug", + "binaryDir": "${fileDir}/build/uhk-80-left-debug", "cacheVariables": { "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-80-left", - "BOARD_ROOT": "${sourceParentDir}/", - "mcuboot_OVERLAY_CONFIG": "${sourceDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${sourceDir}/prj.conf", - "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/uhk-80.conf;${sourceDir}/prj.conf.overlays/ble_nus.conf" + "BOARD_ROOT": "${fileDir}/../", + "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", + "CONF_FILE": "${fileDir}/prj.conf", + "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf" } }, { "name": "uhk-dongle", "displayName": "Build for UHK dongle", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-dongle", + "binaryDir": "${fileDir}/build/uhk-dongle", "cacheVariables": { "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-dongle", - "BOARD_ROOT": "${sourceParentDir}/", - "mcuboot_OVERLAY_CONFIG": "${sourceDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${sourceDir}/prj_release.conf", - "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/ble_nus_client.conf" + "BOARD_ROOT": "${fileDir}/../", + "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", + "CONF_FILE": "${fileDir}/prj_release.conf", + "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf" } }, { "name": "uhk-dongle-debug", "displayName": "Debug build for UHK dongle", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-dongle-debug", + "binaryDir": "${fileDir}/build/uhk-dongle-debug", "cacheVariables": { "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-dongle", - "BOARD_ROOT": "${sourceParentDir}/", - "mcuboot_OVERLAY_CONFIG": "${sourceDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${sourceDir}/prj.conf", - "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/ble_nus_client.conf" + "BOARD_ROOT": "${fileDir}/../", + "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", + "CONF_FILE": "${fileDir}/prj.conf", + "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf" } } ] diff --git a/patches/zephyr/0003-sysbuild-support-application-CMakePresets.json-files.patch b/patches/zephyr/0003-sysbuild-support-application-CMakePresets.json-files.patch new file mode 100644 index 000000000..2d79a386f --- /dev/null +++ b/patches/zephyr/0003-sysbuild-support-application-CMakePresets.json-files.patch @@ -0,0 +1,101 @@ +From 2669cb1f5240bfa5a92bf47bed97e3ce00a26a2c Mon Sep 17 00:00:00 2001 +From: Torsten Rasmussen +Date: Fri, 26 Sep 2025 12:55:07 +0200 +Subject: [PATCH] sysbuild: support application CMakePresets.json files with + sysbuild + +This commit provides a CMakePresets.json which includes the sample's +CMakePresets.json file. + +`west build` is extended to set `APP_DIR` in environment when sysbuild +is used. This allows sysbuild's CMakePresets.json to include the +sample's presets file. + +Signed-off-by: Torsten Rasmussen +--- + scripts/west_commands/build.py | 5 ++++- + scripts/west_commands/zcmake.py | 5 +++-- + share/sysbuild/CMakePresets.json | 11 +++++++++++ + 3 files changed, 18 insertions(+), 3 deletions(-) + create mode 100644 share/sysbuild/CMakePresets.json + +diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py +index 260945483cf..5710da41c95 100644 +--- a/scripts/west_commands/build.py ++++ b/scripts/west_commands/build.py +@@ -578,6 +578,7 @@ class Build(Forceable): + if not self.run_cmake: + return + ++ cmake_env = None + _banner('generating a build system') + + if board is not None and origin != 'CMakeCache.txt': +@@ -604,6 +605,8 @@ class Build(Forceable): + if self.args.sysbuild or (config_sysbuild and not self.args.no_sysbuild): + cmake_opts.extend(['-S{}'.format(SYSBUILD_PROJ_DIR), + '-DAPP_DIR:PATH={}'.format(self.source_dir)]) ++ cmake_env = os.environ.copy() ++ cmake_env["APP_DIR"] = str(self.source_dir) + else: + # self.args.no_sysbuild == True or config sysbuild False + cmake_opts.extend(['-S{}'.format(self.source_dir)]) +@@ -620,7 +623,7 @@ class Build(Forceable): + DEFAULT_CMAKE_GENERATOR))] + if cmake_opts: + final_cmake_args.extend(cmake_opts) +- run_cmake(final_cmake_args, dry_run=self.args.dry_run) ++ run_cmake(final_cmake_args, dry_run=self.args.dry_run, env=cmake_env) + + def _run_pristine(self): + _banner('making build dir {} pristine'.format(self.build_dir)) +diff --git a/scripts/west_commands/zcmake.py b/scripts/west_commands/zcmake.py +index aad616aadd4..25e3d6407b5 100644 +--- a/scripts/west_commands/zcmake.py ++++ b/scripts/west_commands/zcmake.py +@@ -26,7 +26,7 @@ DEFAULT_CMAKE_GENERATOR = 'Ninja' + '''Name of the default CMake generator.''' + + +-def run_cmake(args, cwd=None, capture_output=False, dry_run=False): ++def run_cmake(args, cwd=None, capture_output=False, dry_run=False, env=None): + '''Run cmake to (re)generate a build system, a script, etc. + + :param args: arguments to pass to CMake +@@ -36,6 +36,7 @@ def run_cmake(args, cwd=None, capture_output=False, dry_run=False): + dry_run is also True) + :param dry_run: don't actually execute the command, just print what + would have been run ++ :param env: used adjusted environment when running CMake + + If capture_output is set to True, returns the output of the command instead + of displaying it on stdout/stderr..''' +@@ -60,7 +61,7 @@ def run_cmake(args, cwd=None, capture_output=False, dry_run=False): + return None + + log.dbg('Running CMake:', quote_sh_list(cmd), level=log.VERBOSE_NORMAL) +- p = subprocess.Popen(cmd, **kwargs) ++ p = subprocess.Popen(cmd, env=env, **kwargs) + out, _ = p.communicate() + if p.returncode == 0: + if out: +diff --git a/share/sysbuild/CMakePresets.json b/share/sysbuild/CMakePresets.json +new file mode 100644 +index 00000000000..437f3b68a94 +--- /dev/null ++++ b/share/sysbuild/CMakePresets.json +@@ -0,0 +1,11 @@ ++{ ++ "version": 7, ++ "cmakeMinimumRequired": { ++ "major": 3, ++ "minor": 27, ++ "patch": 0 ++ }, ++ "include": [ ++ "$penv{APP_DIR}/CMakePresets.json" ++ ] ++} +-- +2.43.0 + diff --git a/patches/zephyr/0003-west-sysbuild-allows-using-application-cmake-presets.patch b/patches/zephyr/0003-west-sysbuild-allows-using-application-cmake-presets.patch deleted file mode 100644 index 5f762212b..000000000 --- a/patches/zephyr/0003-west-sysbuild-allows-using-application-cmake-presets.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 67e38cff8129e51203dbb79011d254a211c41840 Mon Sep 17 00:00:00 2001 -From: Benedek Kupper -Date: Wed, 13 Aug 2025 00:48:37 +0200 -Subject: [PATCH] west sysbuild allows using application cmake presets - ---- - scripts/west_commands/build.py | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py -index 260945483cf..c34e23b30ad 100644 ---- a/scripts/west_commands/build.py -+++ b/scripts/west_commands/build.py -@@ -601,7 +601,26 @@ class Build(Forceable): - # If no option is set, then enable sysbuild globally - config_sysbuild = True - -+ # sysbuild has its own cmake project directory, so we need to -+ # copy the application's CMakePresets.json file and replace the paths -+ sysbuild_presets = SYSBUILD_PROJ_DIR / 'CMakePresets.json' -+ source_presets = pathlib.Path(self.source_dir) / 'CMakePresets.json' -+ - if self.args.sysbuild or (config_sysbuild and not self.args.no_sysbuild): -+ try: -+ if source_presets.exists(): -+ with open(source_presets, 'r') as f: -+ content = f.read() -+ content = (content -+ .replace("${sourceDir}", self.source_dir) -+ .replace("${sourceParentDir}", str(pathlib.Path(self.source_dir).parent)) -+ .replace("${sourceDirName}", str(pathlib.Path(self.source_dir).name)) -+ ) -+ with open(sysbuild_presets, 'w') as f: -+ f.write(content) -+ except Exception as e: -+ log.wrn(f'Failed to adopt CMakePresets.json to sysbuild: {e}') -+ - cmake_opts.extend(['-S{}'.format(SYSBUILD_PROJ_DIR), - '-DAPP_DIR:PATH={}'.format(self.source_dir)]) - else: -@@ -622,6 +641,15 @@ class Build(Forceable): - final_cmake_args.extend(cmake_opts) - run_cmake(final_cmake_args, dry_run=self.args.dry_run) - -+ # clean up the sysbuild CMakePresets.json file after each run -+ if sysbuild_presets.exists(): -+ try: -+ sysbuild_presets.unlink() -+ except FileNotFoundError: -+ pass -+ except Exception as e: -+ log.wrn(f'Failed to remove sysbuild CMakePresets.json: {e}') -+ - def _run_pristine(self): - _banner('making build dir {} pristine'.format(self.build_dir)) - if not is_zephyr_build(self.build_dir): --- -2.43.0 - From a4729c727220d9396c7b66ae2a43768aa8b8e995 Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Wed, 19 Nov 2025 21:35:01 +0100 Subject: [PATCH 02/16] move c2usb interfacing code under the right sources --- device/src/CMakeLists.txt | 11 ------ device/src/bt_conn.c | 1 - device/src/bt_manager.c | 2 +- device/src/connections.c | 2 +- .../src/keyboard/oled/widgets/widget_store.c | 2 +- device/src/main.c | 2 +- device/src/messenger.c | 2 +- device/src/nus_client.c | 1 - device/src/pin_wiring.c | 2 -- device/src/shell.c | 2 -- device/src/state_sync.c | 2 +- right/src/CMakeLists.txt | 2 ++ right/src/hid/CMakeLists.txt | 10 ++++++ .../src/usb => right/src/hid}/app_base.cpp | 0 .../src/usb => right/src/hid}/app_base.hpp | 0 .../src/usb => right/src/hid}/command_app.cpp | 0 .../src/usb => right/src/hid}/command_app.hpp | 0 .../src/usb/usb.h => right/src/hid/config.h | 6 ++-- .../usb => right/src/hid}/controls_app.cpp | 0 .../usb => right/src/hid}/controls_app.hpp | 0 .../usb => right/src/hid}/double_buffer.hpp | 0 .../src/usb => right/src/hid}/gamepad_app.cpp | 0 .../src/usb => right/src/hid}/gamepad_app.hpp | 0 .../usb => right/src/hid}/keyboard_app.cpp | 0 .../usb => right/src/hid}/keyboard_app.hpp | 0 .../src/usb => right/src/hid}/mouse_app.cpp | 0 .../src/usb => right/src/hid}/mouse_app.hpp | 0 .../src/usb => right/src/hid}/report_ids.h | 0 {device/src/usb => right/src/hid}/usb.cpp | 36 ++++++++++--------- .../src/hid}/usb_compatibility.cpp | 0 .../usb => right/src/hid}/usb_compatibility.h | 0 right/src/power_mode.c | 2 +- .../usb_interface_basic_keyboard.c | 2 +- .../src/usb_interfaces/usb_interface_mouse.c | 2 +- right/src/usb_report_updater.c | 2 +- 35 files changed, 45 insertions(+), 46 deletions(-) create mode 100644 right/src/hid/CMakeLists.txt rename {device/src/usb => right/src/hid}/app_base.cpp (100%) rename {device/src/usb => right/src/hid}/app_base.hpp (100%) rename {device/src/usb => right/src/hid}/command_app.cpp (100%) rename {device/src/usb => right/src/hid}/command_app.hpp (100%) rename device/src/usb/usb.h => right/src/hid/config.h (88%) rename {device/src/usb => right/src/hid}/controls_app.cpp (100%) rename {device/src/usb => right/src/hid}/controls_app.hpp (100%) rename {device/src/usb => right/src/hid}/double_buffer.hpp (100%) rename {device/src/usb => right/src/hid}/gamepad_app.cpp (100%) rename {device/src/usb => right/src/hid}/gamepad_app.hpp (100%) rename {device/src/usb => right/src/hid}/keyboard_app.cpp (100%) rename {device/src/usb => right/src/hid}/keyboard_app.hpp (100%) rename {device/src/usb => right/src/hid}/mouse_app.cpp (100%) rename {device/src/usb => right/src/hid}/mouse_app.hpp (100%) rename {device/src/usb => right/src/hid}/report_ids.h (100%) rename {device/src/usb => right/src/hid}/usb.cpp (92%) rename {device/src/usb => right/src/hid}/usb_compatibility.cpp (100%) rename {device/src/usb => right/src/hid}/usb_compatibility.h (100%) diff --git a/device/src/CMakeLists.txt b/device/src/CMakeLists.txt index 908727b59..00f21807d 100644 --- a/device/src/CMakeLists.txt +++ b/device/src/CMakeLists.txt @@ -3,16 +3,6 @@ target_include_directories(${PROJECT_NAME} PUBLIC usb ) -set(usb_cpp_sources - usb/app_base.cpp - usb/command_app.cpp - usb/controls_app.cpp - usb/gamepad_app.cpp - usb/keyboard_app.cpp - usb/mouse_app.cpp - usb/usb_compatibility.cpp - usb/usb.cpp -) file(GLOB_RECURSE keyboard_sources keyboard/*.c) file(GLOB lvgl_dummy lvgl/*.c) @@ -25,7 +15,6 @@ if(NOT CONFIG_BOARD_UHK_60_RIGHT) target_link_libraries(app PRIVATE zephyr_interface) target_sources(${PROJECT_NAME} PRIVATE - ${usb_cpp_sources} bt_conn.c bt_manager.c bt_pair.c diff --git a/device/src/bt_conn.c b/device/src/bt_conn.c index e6e185903..2baf40af1 100644 --- a/device/src/bt_conn.c +++ b/device/src/bt_conn.c @@ -22,7 +22,6 @@ #include "device.h" #include "keyboard/oled/screens/pairing_screen.h" #include "keyboard/oled/screens/screen_manager.h" -#include "usb/usb.h" #include "keyboard/oled/widgets/widgets.h" #include #include "bt_pair.h" diff --git a/device/src/bt_manager.c b/device/src/bt_manager.c index cff0ceb04..684ccab36 100644 --- a/device/src/bt_manager.c +++ b/device/src/bt_manager.c @@ -3,7 +3,7 @@ #include "connections.h" #include "device_state.h" #include "event_scheduler.h" -#include "usb/usb.h" +#include "hid/config.h" #include "bt_advertise.h" #include "nus_client.h" #include "nus_server.h" diff --git a/device/src/connections.c b/device/src/connections.c index a6cdc8f57..ba77fc185 100644 --- a/device/src/connections.c +++ b/device/src/connections.c @@ -10,7 +10,7 @@ #include #include "connections.h" #include "stubs.h" -#include "usb_compatibility.h" +#include "hid/usb_compatibility.h" #include "logger.h" #include #include "config_manager.h" diff --git a/device/src/keyboard/oled/widgets/widget_store.c b/device/src/keyboard/oled/widgets/widget_store.c index f3af375e6..d12662d3d 100644 --- a/device/src/keyboard/oled/widgets/widget_store.c +++ b/device/src/keyboard/oled/widgets/widget_store.c @@ -21,7 +21,7 @@ #include #include #include "device_state.h" -#include "usb/usb_compatibility.h" +#include "hid/usb_compatibility.h" #include "macros/status_buffer.h" #include "host_connection.h" #include "connections.h" diff --git a/device/src/main.c b/device/src/main.c index df1ea0ebb..d6cd269a5 100644 --- a/device/src/main.c +++ b/device/src/main.c @@ -22,7 +22,7 @@ #include "peripherals/merge_sensor.h" #include "shell.h" #include "device.h" -#include "usb/usb.h" +#include "hid/config.h" #include "bt_conn.h" #include "settings.h" #include "flash.h" diff --git a/device/src/messenger.c b/device/src/messenger.c index fa3a67723..046b830f6 100644 --- a/device/src/messenger.c +++ b/device/src/messenger.c @@ -11,7 +11,7 @@ #include "shared/slave_protocol.h" #include "state_sync.h" #include "thread_stats.h" -#include "usb/usb_compatibility.h" +#include "hid/usb_compatibility.h" #include "nus_server.h" #include "nus_client.h" #include "module.h" diff --git a/device/src/nus_client.c b/device/src/nus_client.c index 18b4e0884..081b960e1 100644 --- a/device/src/nus_client.c +++ b/device/src/nus_client.c @@ -16,7 +16,6 @@ #include "key_states.h" #include "keyboard/oled/widgets/console_widget.h" #include "state_sync.h" -#include "usb/usb_compatibility.h" #include "link_protocol.h" #include "messenger_queue.h" #include "debug.h" diff --git a/device/src/pin_wiring.c b/device/src/pin_wiring.c index 48e96033e..90d7ba4a9 100644 --- a/device/src/pin_wiring.c +++ b/device/src/pin_wiring.c @@ -6,7 +6,6 @@ #include "keyboard/leds.h" #include "keyboard/oled/oled.h" #include "logger.h" -#include "usb/usb.h" #include #include #include @@ -17,7 +16,6 @@ #include "host_connection.h" #include "thread_stats.h" #include "trace.h" -#include "usb_compatibility.h" #include "mouse_keys.h" #include "config_manager.h" #include diff --git a/device/src/shell.c b/device/src/shell.c index 729450b60..0a412ba4f 100644 --- a/device/src/shell.c +++ b/device/src/shell.c @@ -7,7 +7,6 @@ #include "logger.h" #include "proxy_log_backend.h" #include "usb_log_buffer.h" -#include "usb/usb.h" #include #include #include @@ -18,7 +17,6 @@ #include "host_connection.h" #include "thread_stats.h" #include "trace.h" -#include "usb_compatibility.h" #include "mouse_keys.h" #include "config_manager.h" #include diff --git a/device/src/state_sync.c b/device/src/state_sync.c index e838c3a75..f38016310 100644 --- a/device/src/state_sync.c +++ b/device/src/state_sync.c @@ -25,7 +25,7 @@ #include "utils.h" #include "messenger.h" #include "state_sync.h" -#include "usb/usb_compatibility.h" +#include "hid/usb_compatibility.h" #include #include #include "peripherals/merge_sensor.h" diff --git a/right/src/CMakeLists.txt b/right/src/CMakeLists.txt index 18b5b38ef..d6c77c42f 100644 --- a/right/src/CMakeLists.txt +++ b/right/src/CMakeLists.txt @@ -21,6 +21,8 @@ if(IS_MCUX_SDK) # need to add header explicitly to avoid pulling in wrong SDK header # https://github.com/nxp-mcuxpresso/mcuxsdk-middleware-usb/issues/12 mcux_add_source(SOURCES usb_device_config.h) +else() + add_subdirectory(hid) endif() target_sources(${PROJECT_NAME} PRIVATE diff --git a/right/src/hid/CMakeLists.txt b/right/src/hid/CMakeLists.txt new file mode 100644 index 000000000..0fc8d246c --- /dev/null +++ b/right/src/hid/CMakeLists.txt @@ -0,0 +1,10 @@ +target_sources(${PROJECT_NAME} PRIVATE + app_base.cpp + command_app.cpp + controls_app.cpp + gamepad_app.cpp + keyboard_app.cpp + mouse_app.cpp + usb_compatibility.cpp + usb.cpp +) diff --git a/device/src/usb/app_base.cpp b/right/src/hid/app_base.cpp similarity index 100% rename from device/src/usb/app_base.cpp rename to right/src/hid/app_base.cpp diff --git a/device/src/usb/app_base.hpp b/right/src/hid/app_base.hpp similarity index 100% rename from device/src/usb/app_base.hpp rename to right/src/hid/app_base.hpp diff --git a/device/src/usb/command_app.cpp b/right/src/hid/command_app.cpp similarity index 100% rename from device/src/usb/command_app.cpp rename to right/src/hid/command_app.cpp diff --git a/device/src/usb/command_app.hpp b/right/src/hid/command_app.hpp similarity index 100% rename from device/src/usb/command_app.hpp rename to right/src/hid/command_app.hpp diff --git a/device/src/usb/usb.h b/right/src/hid/config.h similarity index 88% rename from device/src/usb/usb.h rename to right/src/hid/config.h index 90f70ede8..1063fe40a 100644 --- a/device/src/usb/usb.h +++ b/right/src/hid/config.h @@ -1,5 +1,5 @@ -#ifndef __USB_HEADER__ -#define __USB_HEADER__ +#ifndef __HID_CONFIG_HEADER__ +#define __HID_CONFIG_HEADER__ // Includes: @@ -37,4 +37,4 @@ void USB_SetSerialNumber(uint32_t serialNumber); void USB_RemoteWakeup(void); -#endif // __USB_HEADER__ +#endif // __HID_CONFIG_HEADER__ diff --git a/device/src/usb/controls_app.cpp b/right/src/hid/controls_app.cpp similarity index 100% rename from device/src/usb/controls_app.cpp rename to right/src/hid/controls_app.cpp diff --git a/device/src/usb/controls_app.hpp b/right/src/hid/controls_app.hpp similarity index 100% rename from device/src/usb/controls_app.hpp rename to right/src/hid/controls_app.hpp diff --git a/device/src/usb/double_buffer.hpp b/right/src/hid/double_buffer.hpp similarity index 100% rename from device/src/usb/double_buffer.hpp rename to right/src/hid/double_buffer.hpp diff --git a/device/src/usb/gamepad_app.cpp b/right/src/hid/gamepad_app.cpp similarity index 100% rename from device/src/usb/gamepad_app.cpp rename to right/src/hid/gamepad_app.cpp diff --git a/device/src/usb/gamepad_app.hpp b/right/src/hid/gamepad_app.hpp similarity index 100% rename from device/src/usb/gamepad_app.hpp rename to right/src/hid/gamepad_app.hpp diff --git a/device/src/usb/keyboard_app.cpp b/right/src/hid/keyboard_app.cpp similarity index 100% rename from device/src/usb/keyboard_app.cpp rename to right/src/hid/keyboard_app.cpp diff --git a/device/src/usb/keyboard_app.hpp b/right/src/hid/keyboard_app.hpp similarity index 100% rename from device/src/usb/keyboard_app.hpp rename to right/src/hid/keyboard_app.hpp diff --git a/device/src/usb/mouse_app.cpp b/right/src/hid/mouse_app.cpp similarity index 100% rename from device/src/usb/mouse_app.cpp rename to right/src/hid/mouse_app.cpp diff --git a/device/src/usb/mouse_app.hpp b/right/src/hid/mouse_app.hpp similarity index 100% rename from device/src/usb/mouse_app.hpp rename to right/src/hid/mouse_app.hpp diff --git a/device/src/usb/report_ids.h b/right/src/hid/report_ids.h similarity index 100% rename from device/src/usb/report_ids.h rename to right/src/hid/report_ids.h diff --git a/device/src/usb/usb.cpp b/right/src/hid/usb.cpp similarity index 92% rename from device/src/usb/usb.cpp rename to right/src/hid/usb.cpp index 4500c76d5..c67702b85 100644 --- a/device/src/usb/usb.cpp +++ b/right/src/hid/usb.cpp @@ -1,8 +1,8 @@ extern "C" { -#include "usb.h" #include "connections.h" #include "device.h" #include "device_state.h" +#include "hid/config.h" #include "key_states.h" #include "keyboard/charger.h" #include "keyboard/key_scanner.h" @@ -11,8 +11,8 @@ extern "C" { #include "timer.h" #include "usb_report_updater.h" #include "user_logic.h" -#include #include +#include } #include "command_app.hpp" #include "controls_app.hpp" @@ -55,7 +55,8 @@ class multi_hid : public hid::multi_application { } private: - std::array app_array_{(&Args::ble_handle())..., nullptr}; + std::array app_array_{ + (&Args::ble_handle())..., nullptr}; multi_hid() : multi_application({{}, 0, 0, 0}, app_array_) { static constexpr const auto desc = report_desc(); @@ -138,7 +139,9 @@ struct usb_manager { usb::df::microsoft::xconfig( usb_xpad, usb::endpoint::address(0x85), 1, usb::endpoint::address(0x05), 255)); - printk("USB config changing to %s\n", magic_enum::enum_name(conf).data() == NULL ? "NULL" : magic_enum::enum_name(conf).data()); + printk("USB config changing to %s\n", magic_enum::enum_name(conf).data() == NULL + ? "NULL" + : magic_enum::enum_name(conf).data()); if (conf == Hid_NoGamepad) { ms_enum_.set_config({}); device_.set_config(base_config); @@ -150,23 +153,24 @@ struct usb_manager { } usb_manager() - : mac_{DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), - (nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_CONNECTED) ? - usb::power::state::L2_SUSPEND : usb::power::state::L3_OFF} + : mac_{DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), + (nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_CONNECTED) + ? usb::power::state::L2_SUSPEND + : usb::power::state::L3_OFF} { device_.set_power_event_delegate([](usb::df::device &dev, usb::df::device::event ev) { using event = enum usb::df::device::event; if ((ev & event::POWER_STATE_CHANGE) != event::NONE) { switch (dev.power_state()) { - case usb::power::state::L2_SUSPEND: - PowerMode_SetUsbAwake(false); - break; - case usb::power::state::L0_ON: - PowerMode_SetUsbAwake(true); - break; - default: - break; - } + case usb::power::state::L2_SUSPEND: + PowerMode_SetUsbAwake(false); + break; + case usb::power::state::L0_ON: + PowerMode_SetUsbAwake(true); + break; + default: + break; + } } }); } diff --git a/device/src/usb/usb_compatibility.cpp b/right/src/hid/usb_compatibility.cpp similarity index 100% rename from device/src/usb/usb_compatibility.cpp rename to right/src/hid/usb_compatibility.cpp diff --git a/device/src/usb/usb_compatibility.h b/right/src/hid/usb_compatibility.h similarity index 100% rename from device/src/usb/usb_compatibility.h rename to right/src/hid/usb_compatibility.h diff --git a/right/src/power_mode.c b/right/src/power_mode.c index d41ce37cc..ef392376f 100644 --- a/right/src/power_mode.c +++ b/right/src/power_mode.c @@ -8,7 +8,7 @@ #ifdef __ZEPHYR__ #include "device_state.h" - #include "usb/usb.h" + #include "hid/config.h" #include "connections.h" #include "keyboard/key_scanner.h" #include "keyboard/charger.h" diff --git a/right/src/usb_interfaces/usb_interface_basic_keyboard.c b/right/src/usb_interfaces/usb_interface_basic_keyboard.c index 70f6d74d9..239a7a719 100644 --- a/right/src/usb_interfaces/usb_interface_basic_keyboard.c +++ b/right/src/usb_interfaces/usb_interface_basic_keyboard.c @@ -8,7 +8,7 @@ #include "usb_report_updater.h" #ifdef __ZEPHYR__ -#include "usb/usb_compatibility.h" +#include "hid/usb_compatibility.h" #endif #include "utils.h" diff --git a/right/src/usb_interfaces/usb_interface_mouse.c b/right/src/usb_interfaces/usb_interface_mouse.c index 699c5ccd5..de6783c17 100644 --- a/right/src/usb_interfaces/usb_interface_mouse.c +++ b/right/src/usb_interfaces/usb_interface_mouse.c @@ -7,7 +7,7 @@ #include "utils.h" #ifdef __ZEPHYR__ -#include "usb/usb_compatibility.h" +#include "hid/usb_compatibility.h" #endif static bool needsResending = false; diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index 24e94ba67..4f05ffc6e 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -49,7 +49,7 @@ #ifdef __ZEPHYR__ #include "debug_eventloop_timing.h" #include "shell.h" -#include "usb/usb_compatibility.h" +#include "hid/usb_compatibility.h" #include "keyboard/input_interceptor.h" #include "keyboard/charger.h" #include "logger.h" From 92200838257551e2b4c4a30e7b07a21cbbcc8bee Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Wed, 19 Nov 2025 22:07:03 +0100 Subject: [PATCH 03/16] split vscode to two workspaces, one for nrfsdk and one for mcuxsdk development --- .vscode/tasks.json | 28 ++++++- README.md | 2 +- mcuxsdk.code-workspace | 79 +++++++++++++++++++ ...re.code-workspace => nrfsdk.code-workspace | 53 ++++++------- 4 files changed, 129 insertions(+), 33 deletions(-) create mode 100644 mcuxsdk.code-workspace rename firmware.code-workspace => nrfsdk.code-workspace (58%) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9a55d6f3e..9f94f0e3e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -8,7 +8,7 @@ "isDefault": true }, "options": { - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder:firmware}" }, "type": "process", "command": "west", @@ -25,7 +25,7 @@ "isDefault": true }, "options": { - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder:firmware}" }, "type": "process", "command": "west", @@ -42,7 +42,7 @@ "isDefault": true }, "options": { - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder:firmware}" }, "type": "process", "command": "west", @@ -57,7 +57,7 @@ "isDefault": true }, "options": { - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder:firmware}" }, "type": "process", "command": "west", @@ -68,6 +68,26 @@ "dependsOn": [ "West update" ] + }, + { + "label": "Select SDK by vscode workspace", + "group": { + "kind": "none", + "isDefault": true + }, + "options": { + "cwd": "${workspaceFolder:firmware}" + }, + "runOptions": { + "runOn": "folderOpen" + }, + "type": "process", + "command": "west", + "args": [ + "config", + "manifest.file", + "west_${config:firmware.startupSdk}.yml" + ] } ] } \ No newline at end of file diff --git a/README.md b/README.md index e04c5f21a..44f39c64a 100644 --- a/README.md +++ b/README.md @@ -194,7 +194,7 @@ BUILD_DIR=device/build/uhk-80-right; west flash --build-dir $BUILD_DIR It is recommended to start development in the IDE once a successful build is available, as the build parameters aren't trivial to pass to the IDE, but it does pick up existing build configurations. -To get started, choose *Open Workspace from File...*, then select the `firmware.code-workspace` file. +To get started, choose *Open Workspace from File...*, then select either the `mcuxsdk.code-workspace` (for UHK60 and modules) or the `nrfsdk.code-workspace` (for UHK80 and dongle) file. Install the recommended extensions or pick the one for your single device depending on the SDK. > Note that using *MCUXpresso for VS Code* extension currently overwrites the `mcux_includes.json` file, diff --git a/mcuxsdk.code-workspace b/mcuxsdk.code-workspace new file mode 100644 index 000000000..46fb90aa2 --- /dev/null +++ b/mcuxsdk.code-workspace @@ -0,0 +1,79 @@ +{ + "folders": [ + { + "name": "right", + "path": "right" + }, + { + "name": "left", + "path": "left" + }, + { + "name": "keycluster", + "path": "keycluster" + }, + { + "name": "trackball", + "path": "trackball" + }, + { + "name": "trackpoint", + "path": "trackpoint" + }, + { + "path": "." + }, + { + "name": "mcuxsdk", + "path": "../mcuxsdk" + }, + { + "name": "c2usb", + "path": "../c2usb" + } + ], + "settings": { + "files.associations": { + "*.h": "c", + "*.c": "c", + "*.hpp": "cpp", + "*.cpp": "cpp" + }, + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "C_Cpp.workspaceParsingPriority": "high", + "C_Cpp.autoAddFileAssociations": false, + "cmake.useCMakePresets": "always", + "cmake.configureOnOpen": false, + "cmake.enableAutomaticKitScan": false, + "cmake.options.advanced": { + "build": { + "statusBarVisibility": "hidden" + }, + "launch": { + "statusBarVisibility": "hidden" + }, + "debug": { + "statusBarVisibility": "hidden" + } + }, + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features", + "editor.formatOnSave": true + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features", + "editor.formatOnSave": true + }, + "task.allowAutomaticTasks": "on", + "firmware.startupSdk": "mcuxsdk" + }, + "extensions": { + "recommendations": [ + "NXPSemiconductors.mcuxpresso", + "ms-vscode.cpptools-extension-pack", + "ms-vscode.vscode-embedded-tools", + "mcu-debug.peripheral-viewer", + "marus25.cortex-debug" + ] + } +} \ No newline at end of file diff --git a/firmware.code-workspace b/nrfsdk.code-workspace similarity index 58% rename from firmware.code-workspace rename to nrfsdk.code-workspace index ea8032edf..dfe8bc0a4 100644 --- a/firmware.code-workspace +++ b/nrfsdk.code-workspace @@ -7,26 +7,6 @@ "name": "uhk-80", "path": "device" }, - { - "name": "right", - "path": "right" - }, - { - "name": "left", - "path": "left" - }, - { - "name": "keycluster", - "path": "keycluster" - }, - { - "name": "trackball", - "path": "trackball" - }, - { - "name": "trackpoint", - "path": "trackpoint" - }, { "name": "workspace", "path": ".." @@ -52,22 +32,39 @@ "*.hpp": "cpp", "*.cpp": "cpp" }, - "cmake.useCMakePresets": "always", "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "C_Cpp.workspaceParsingPriority": "high", "C_Cpp.autoAddFileAssociations": false, - "clangd.arguments": [ - "--compile-commands-dir=${workspaceFolder}/build/v2-debug" - ] + "cmake.useCMakePresets": "always", + "cmake.configureOnOpen": false, + "cmake.enableAutomaticKitScan": false, + "cmake.options.advanced": { + "build": { + "statusBarVisibility": "hidden" + }, + "launch": { + "statusBarVisibility": "hidden" + }, + "debug": { + "statusBarVisibility": "hidden" + } + }, + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features", + "editor.formatOnSave": true + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features", + "editor.formatOnSave": true + }, + "task.allowAutomaticTasks": "on", + "firmware.startupSdk": "nrfsdk" }, "extensions": { "recommendations": [ "nordic-semiconductor.nrf-connect-extension-pack", - "NXPSemiconductors.mcuxpresso", "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-embedded-tools", - "mcu-debug.peripheral-viewer", - "marus25.cortex-debug" + "ms-vscode.vscode-embedded-tools" ] } } \ No newline at end of file From 08febc12408cbf319b9ef04e9c7e8360c6ec6de9 Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Wed, 19 Nov 2025 22:57:23 +0100 Subject: [PATCH 04/16] right: integrate c2usb into the build, without any effect --- ...llow-coexistence-with-mcux-usb-stack.patch | 82 +++++++++++++++++++ .../0001-allow-coexistence-with-c2usb.patch | 25 ++++++ right/CMakeLists.txt | 8 ++ right/prj.conf | 1 + submanifests/c2usb.yml | 2 +- 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 patches/c2usb/0001-allow-coexistence-with-mcux-usb-stack.patch create mode 100644 patches/usb/0001-allow-coexistence-with-c2usb.patch diff --git a/patches/c2usb/0001-allow-coexistence-with-mcux-usb-stack.patch b/patches/c2usb/0001-allow-coexistence-with-mcux-usb-stack.patch new file mode 100644 index 000000000..8724ad69a --- /dev/null +++ b/patches/c2usb/0001-allow-coexistence-with-mcux-usb-stack.patch @@ -0,0 +1,82 @@ +From 814d66eb88b04c1a4e3c85afaa0a559cd61576a1 Mon Sep 17 00:00:00 2001 +From: Benedek Kupper +Date: Wed, 19 Nov 2025 22:56:30 +0100 +Subject: [PATCH] allow coexistence with mcux usb stack + +--- + c2usb/port/nxp/CMakeLists.txt | 4 ---- + c2usb/port/nxp/mcux_mac.cpp | 9 ++++++++- + c2usb/port/nxp/mcux_mac.hpp | 2 ++ + 3 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/c2usb/port/nxp/CMakeLists.txt b/c2usb/port/nxp/CMakeLists.txt +index e14ad09..481e1dc 100644 +--- a/c2usb/port/nxp/CMakeLists.txt ++++ b/c2usb/port/nxp/CMakeLists.txt +@@ -15,10 +15,6 @@ if(CONFIG_C2USB_MCUX_MAC) + PRIVATE + ${PROJECT_NAME} + ) +- # since MCUX_COMPONENT_middleware.usb.device.controller.driver cannot be disabled +- mcux_project_remove_source(BASE_PATH ${SdkRootDirPath}/middleware/usb/device +- SOURCES usb_device_dci.c +- ) + else() + set_target_properties(${PROJECT_NAME} PROPERTIES EXCLUDE_FROM_ALL TRUE) + endif() +diff --git a/c2usb/port/nxp/mcux_mac.cpp b/c2usb/port/nxp/mcux_mac.cpp +index 665f189..03b9a50 100644 +--- a/c2usb/port/nxp/mcux_mac.cpp ++++ b/c2usb/port/nxp/mcux_mac.cpp +@@ -25,6 +25,7 @@ static IRQn_Type usb_irqn(int index) + + void mcux_mac::init(const speeds& speeds) + { ++ notification_routing = true; + [[maybe_unused]] auto status = driver_.deviceInit(index_, this, &handle_); + assert(status == kStatus_USB_Success); + +@@ -290,6 +291,8 @@ void mcux_mac::process_notification(const _usb_device_callback_message_struct& m + } + } + ++extern "C" usb_status_t _USB_DeviceNotificationTrigger(void* handle, void* msg); ++ + extern "C" usb_status_t USB_DeviceNotificationTrigger(void* handle, void* msg) + { + assert(msg != nullptr); +@@ -297,13 +300,17 @@ extern "C" usb_status_t USB_DeviceNotificationTrigger(void* handle, void* msg) + { + return kStatus_USB_InvalidHandle; + } +- else ++ else if (mcux_mac::notification_routing) + { + auto* mac = reinterpret_cast(handle); + mac->process_notification( + *reinterpret_cast(msg)); + return kStatus_USB_Success; + } ++ else ++ { ++ return _USB_DeviceNotificationTrigger(handle, msg); ++ } + } + + } // namespace usb::df::nxp +diff --git a/c2usb/port/nxp/mcux_mac.hpp b/c2usb/port/nxp/mcux_mac.hpp +index d2a6e3a..456c710 100644 +--- a/c2usb/port/nxp/mcux_mac.hpp ++++ b/c2usb/port/nxp/mcux_mac.hpp +@@ -30,6 +30,8 @@ struct controller_interface; + class mcux_mac : public df::address_handle_mac + { + public: ++ static inline bool notification_routing{}; ++ + void process_notification(const ::_usb_device_callback_message_struct& message); + + void handle_irq(); +-- +2.43.0 + diff --git a/patches/usb/0001-allow-coexistence-with-c2usb.patch b/patches/usb/0001-allow-coexistence-with-c2usb.patch new file mode 100644 index 000000000..f3187e93d --- /dev/null +++ b/patches/usb/0001-allow-coexistence-with-c2usb.patch @@ -0,0 +1,25 @@ +From a62a08a60d97535713912db08310d7bbb7d8bb90 Mon Sep 17 00:00:00 2001 +From: Benedek Kupper +Date: Wed, 19 Nov 2025 22:54:33 +0100 +Subject: [PATCH] allow coexistence with c2usb + +--- + device/usb_device_dci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/device/usb_device_dci.c b/device/usb_device_dci.c +index 84660bb..cf6262d 100644 +--- a/device/usb_device_dci.c ++++ b/device/usb_device_dci.c +@@ -679,7 +679,7 @@ static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_devi + * + * @return A USB error code or kStatus_USB_Success. + */ +-usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg) ++usb_status_t _USB_DeviceNotificationTrigger(void *handle, void *msg) + { + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg; +-- +2.43.0 + diff --git a/right/CMakeLists.txt b/right/CMakeLists.txt index dfc617a2f..dd279bd9b 100644 --- a/right/CMakeLists.txt +++ b/right/CMakeLists.txt @@ -5,6 +5,10 @@ add_subdirectory(sysbuild) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(EXTRA_MCUX_MODULES ${CMAKE_CURRENT_LIST_DIR}/../../c2usb) set(board frdmk22f) # TODO: how to remove the board selection? set(device MK22F51212) @@ -28,6 +32,10 @@ target_compile_definitions(${PROJECT_NAME} PUBLIC #USB_STACK_BM ) +target_link_libraries(${PROJECT_NAME} PUBLIC + c2usb +) + add_subdirectory(src) target_include_directories(${PROJECT_NAME} PRIVATE # as some headers are included via shared/ prefix diff --git a/right/prj.conf b/right/prj.conf index d10bbeb5f..843ac5afa 100644 --- a/right/prj.conf +++ b/right/prj.conf @@ -15,6 +15,7 @@ CONFIG_MCUX_MISC_USB_LITE=y #CONFIG_USB_DEVICE_CONFIG_ENDPOINTS=9 #CONFIG_USB_DEVICE_CONFIG_LOW_POWER_MODE=y #CONFIG_USB_DEVICE_CONFIG_REMOTE_WAKEUP=y +CONFIG_C2USB_MCUX_MAC=y # disable board (and device) specific source files, as the project has its own sources # examples/_common/project_segments/common/Kconfig.prjseg diff --git a/submanifests/c2usb.yml b/submanifests/c2usb.yml index 27dfe0e31..2215b67c8 100644 --- a/submanifests/c2usb.yml +++ b/submanifests/c2usb.yml @@ -5,5 +5,5 @@ manifest: projects: - name: c2usb remote: IntergatedCircuits - revision: 4ab4ca1df2f363770a653d68683fd28c8e12b42a + revision: cc4751b40b4fe1690f85be4f0be0eca3ccdb5cdf submodules: true From ab69735108a540e19e4b681c92c4c8a76ed7544b Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Tue, 25 Nov 2025 21:39:51 +0100 Subject: [PATCH 05/16] tooling configuration update --- .clang-format | 2 ++ right/.vscode/c_cpp_properties.json | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/.clang-format b/.clang-format index d6343bd61..4deb87041 100644 --- a/.clang-format +++ b/.clang-format @@ -40,3 +40,5 @@ AllowShortFunctionsOnASingleLine: Inline AllowShortLambdasOnASingleLine: Inline ShortNamespaceLines: 1 FixNamespaceComments: true +InsertNewlineAtEOF: true +KeepEmptyLinesAtEOF: true diff --git a/right/.vscode/c_cpp_properties.json b/right/.vscode/c_cpp_properties.json index 4747f65b8..2b80c1122 100644 --- a/right/.vscode/c_cpp_properties.json +++ b/right/.vscode/c_cpp_properties.json @@ -6,6 +6,21 @@ "compileCommands": [ "${workspaceFolder}/build/v2-release/compile_commands.json" ], + "includePath": [ + "${workspaceFolder:right}/**", + "${workspaceFolder:firmware}/shared/*", + "${workspaceFolder:mcuxsdk}/**", + "${workspaceFolder:c2usb}/**" + ], + "browse": { + "path": [ + "${workspaceFolder:right}", + "${workspaceFolder:firmware}/shared", + "${workspaceFolder:mcuxsdk}", + "${workspaceFolder:c2usb}" + ], + "limitSymbolsToIncludedHeaders": true + }, "intelliSenseMode": "gcc-arm" } ] From f2f5ac64c2dc8c1ae4f7c48dcb8ed2ca5564ad5a Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Thu, 5 Feb 2026 23:28:18 +0100 Subject: [PATCH 06/16] major refactoring of UHK60 right USB interface * start using Kconfig for device configuration values (see right/Kconfig.device) * use generated usb_device_config.h header * organize HID report manipulation into self-contained sources and headers * remove kusb interfacing code, except for buspal * update c2usb dependency handling * merge zephyr c2usb interface with UHK60 * use single report for system and media usages * remove unused gamepad interface --- .github/workflows/ci.yml | 2 +- boards/ugl/uhk-60-right/Kconfig.board | 10 +- boards/ugl/uhk-80/Kconfig.defconfig | 8 +- device/CMakePresets.json | 62 +-- device/Kconfig | 50 +-- device/src/bt_manager.c | 2 +- device/src/connections.c | 4 +- device/src/keyboard/input_interceptor.c | 25 -- device/src/keyboard/input_interceptor.h | 21 - .../src/keyboard/oled/widgets/widget_store.c | 2 +- device/src/main.c | 2 +- device/src/messenger.c | 8 +- device/src/nus_client.c | 3 +- device/src/shell.c | 16 +- device/src/state_sync.c | 2 +- mcux_include.json | 8 +- mcuxsdk.code-workspace | 4 + nrfsdk.code-workspace | 13 +- ...-set-_IS_TOP_LEVEL-project-variables.patch | 76 ++++ .../usb/0001-use-SDK-delay-for-wakeup.patch | 42 +- right/.vscode/launch.json | 17 +- right/.vscode/settings.json | 3 +- right/CMakeLists.txt | 11 +- right/CMakePresets.json | 84 ++-- right/Kconfig | 12 + right/Kconfig.device | 98 ++++ right/prj.conf | 11 +- right/src/CMakeLists.txt | 11 +- right/src/buspal/bm_usb/composite.h | 1 - right/src/buspal/bm_usb/hid_bootloader.c | 1 + right/src/buspal/bm_usb/usb_descriptor.c | 16 +- right/src/buspal/bm_usb/usb_descriptor.h | 11 +- right/src/buspal/bus_pal_hardware.c | 6 +- right/src/debug.c | 4 +- right/src/debug.h | 4 +- right/src/event_scheduler.c | 1 - right/src/event_scheduler.h | 2 +- right/src/hid/CMakeLists.txt | 15 +- right/src/hid/app_base.cpp | 40 -- right/src/hid/app_base.hpp | 45 -- right/src/hid/command_app.cpp | 12 +- right/src/hid/config.h | 40 -- right/src/hid/controls_app.cpp | 32 +- right/src/hid/controls_app.hpp | 62 +-- right/src/hid/controls_report.c | 111 +++++ right/src/hid/controls_report.h | 33 ++ right/src/hid/gamepad_app.cpp | 74 --- right/src/hid/gamepad_app.hpp | 202 --------- right/src/hid/keyboard_app.cpp | 222 ++++----- right/src/hid/keyboard_app.hpp | 87 +++- right/src/hid/keyboard_report.c | 131 ++++++ right/src/hid/keyboard_report.h | 77 ++++ right/src/hid/mouse_app.cpp | 48 +- right/src/hid/mouse_app.hpp | 51 +-- right/src/hid/mouse_report.c | 23 + right/src/hid/mouse_report.h | 25 ++ right/src/hid/report_ids.h | 35 +- right/src/hid/transport.cpp | 321 +++++++++++++ right/src/hid/transport.h | 52 +++ right/src/hid/transport_ble.cpp | 62 +++ right/src/hid/transport_usb.cpp | 185 ++++++++ right/src/hid/usb.cpp | 323 -------------- right/src/hid/usb_compatibility.cpp | 260 ----------- right/src/hid/usb_compatibility.h | 44 -- right/src/init_peripherals.c | 3 +- right/src/key_action.h | 3 - right/src/ksdk_usb/usb_device_ch9.c | 5 - right/src/ksdk_usb/usb_device_hid.c | 4 +- right/src/ksdk_usb/usb_microsoft_os.h | 304 ------------- right/src/led_manager.c | 1 - right/src/macro_events.h | 1 - right/src/macro_recorder.c | 10 +- right/src/macro_recorder.h | 6 +- right/src/macros/commands.c | 1 - right/src/macros/core.h | 1 - right/src/macros/key_timing.c | 4 +- right/src/macros/key_timing.h | 4 +- right/src/macros/scancode_commands.c | 61 +-- right/src/macros/set_command.h | 1 - right/src/macros/string_reader.h | 1 - right/src/macros/typedefs.h | 11 +- right/src/macros/vars.h | 1 - right/src/main.c | 24 +- right/src/mouse_controller.c | 4 +- right/src/mouse_controller.h | 4 +- right/src/mouse_keys.c | 3 +- right/src/mouse_keys.h | 4 +- right/src/power_mode.c | 8 +- right/src/slave_drivers/touchpad_driver.c | 1 - right/src/slave_drivers/touchpad_driver.h | 1 - right/src/test_suite/test_hooks.h | 4 +- right/src/test_suite/test_input_machine.c | 10 +- right/src/test_suite/test_output_machine.c | 1 - right/src/test_suite/test_output_machine.h | 4 +- right/src/test_suite/test_suite.c | 7 +- right/src/usb_api.h | 132 ------ .../src/usb_commands/usb_command_draw_oled.c | 1 - .../usb_command_exec_macro_command.c | 6 +- .../usb_command_exec_macro_command.h | 3 +- .../usb_command_exec_shell_command.c | 4 +- .../usb_command_get_debug_buffer.c | 15 +- .../usb_command_get_debug_buffer.h | 2 +- .../usb_command_get_device_property.c | 6 +- .../usb_command_get_module_property.c | 4 +- .../usb_command_get_new_pairings.c | 2 +- .../usb_commands/usb_command_get_variable.c | 5 +- .../usb_commands/usb_command_read_config.c | 2 +- .../src/usb_commands/usb_command_read_oled.c | 3 +- .../usb_commands/usb_command_write_config.c | 2 +- right/src/usb_composite_device.c | 344 -------------- right/src/usb_composite_device.h | 47 -- right/src/usb_descriptors/CMakeLists.txt | 10 - .../usb_descriptor_basic_keyboard_report.h | 100 ----- .../usb_descriptor_configuration.c | 350 --------------- .../usb_descriptor_configuration.h | 26 -- .../usb_descriptors/usb_descriptor_device.c | 32 -- .../usb_descriptors/usb_descriptor_device.h | 32 -- .../usb_descriptor_gamepad_report.h | 121 ----- .../usb_descriptor_generic_hid_report.h | 44 -- .../src/usb_descriptors/usb_descriptor_hid.c | 54 --- .../src/usb_descriptors/usb_descriptor_hid.h | 16 - .../usb_descriptor_media_keyboard_report.h | 33 -- .../usb_descriptor_mouse_report.h | 112 ----- .../usb_descriptors/usb_descriptor_strings.c | 140 ------ .../usb_descriptors/usb_descriptor_strings.h | 26 -- .../usb_descriptor_system_keyboard_report.h | 45 -- .../usb_descriptors_microsoft.c | 172 ------- .../usb_descriptors_microsoft.h | 15 - right/src/usb_device_config.h | 69 --- right/src/usb_interfaces/CMakeLists.txt | 8 - .../usb_interface_basic_keyboard.c | 421 ------------------ .../usb_interface_basic_keyboard.h | 92 ---- .../usb_interfaces/usb_interface_gamepad.c | 124 ------ .../usb_interfaces/usb_interface_gamepad.h | 108 ----- .../usb_interface_generic_hid.c | 80 ---- .../usb_interface_generic_hid.h | 40 -- .../usb_interface_media_keyboard.c | 157 ------- .../usb_interface_media_keyboard.h | 51 --- .../src/usb_interfaces/usb_interface_mouse.c | 230 ---------- .../src/usb_interfaces/usb_interface_mouse.h | 61 --- .../usb_interface_system_keyboard.c | 161 ------- .../usb_interface_system_keyboard.h | 59 --- right/src/usb_protocol_handler.c | 4 +- right/src/usb_protocol_handler.h | 2 +- right/src/usb_report_updater.c | 194 +++++--- right/src/usb_report_updater.h | 21 +- right/src/user_logic.c | 6 - right/src/utils.c | 36 +- right/src/utils.h | 31 +- shared/CMakeLists.txt | 6 +- shared/device.h | 29 +- shared/versioning.h | 6 +- submanifests/c2usb.yml | 4 +- 153 files changed, 1997 insertions(+), 5671 deletions(-) delete mode 100644 device/src/keyboard/input_interceptor.c delete mode 100644 device/src/keyboard/input_interceptor.h create mode 100644 patches/core/0005-cmake-set-_IS_TOP_LEVEL-project-variables.patch create mode 100644 right/Kconfig create mode 100644 right/Kconfig.device delete mode 100644 right/src/hid/app_base.cpp delete mode 100644 right/src/hid/app_base.hpp delete mode 100644 right/src/hid/config.h create mode 100644 right/src/hid/controls_report.c create mode 100644 right/src/hid/controls_report.h delete mode 100644 right/src/hid/gamepad_app.cpp delete mode 100644 right/src/hid/gamepad_app.hpp create mode 100644 right/src/hid/keyboard_report.c create mode 100644 right/src/hid/keyboard_report.h create mode 100644 right/src/hid/mouse_report.c create mode 100644 right/src/hid/mouse_report.h create mode 100644 right/src/hid/transport.cpp create mode 100644 right/src/hid/transport.h create mode 100644 right/src/hid/transport_ble.cpp create mode 100644 right/src/hid/transport_usb.cpp delete mode 100644 right/src/hid/usb.cpp delete mode 100644 right/src/hid/usb_compatibility.cpp delete mode 100644 right/src/hid/usb_compatibility.h delete mode 100644 right/src/ksdk_usb/usb_microsoft_os.h delete mode 100644 right/src/usb_api.h delete mode 100644 right/src/usb_composite_device.c delete mode 100644 right/src/usb_composite_device.h delete mode 100644 right/src/usb_descriptors/CMakeLists.txt delete mode 100644 right/src/usb_descriptors/usb_descriptor_basic_keyboard_report.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_configuration.c delete mode 100644 right/src/usb_descriptors/usb_descriptor_configuration.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_device.c delete mode 100644 right/src/usb_descriptors/usb_descriptor_device.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_gamepad_report.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_generic_hid_report.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_hid.c delete mode 100644 right/src/usb_descriptors/usb_descriptor_hid.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_media_keyboard_report.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_mouse_report.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_strings.c delete mode 100644 right/src/usb_descriptors/usb_descriptor_strings.h delete mode 100644 right/src/usb_descriptors/usb_descriptor_system_keyboard_report.h delete mode 100644 right/src/usb_descriptors/usb_descriptors_microsoft.c delete mode 100644 right/src/usb_descriptors/usb_descriptors_microsoft.h delete mode 100644 right/src/usb_device_config.h delete mode 100644 right/src/usb_interfaces/CMakeLists.txt delete mode 100644 right/src/usb_interfaces/usb_interface_basic_keyboard.c delete mode 100644 right/src/usb_interfaces/usb_interface_basic_keyboard.h delete mode 100644 right/src/usb_interfaces/usb_interface_gamepad.c delete mode 100644 right/src/usb_interfaces/usb_interface_gamepad.h delete mode 100644 right/src/usb_interfaces/usb_interface_generic_hid.c delete mode 100644 right/src/usb_interfaces/usb_interface_generic_hid.h delete mode 100644 right/src/usb_interfaces/usb_interface_media_keyboard.c delete mode 100644 right/src/usb_interfaces/usb_interface_media_keyboard.h delete mode 100644 right/src/usb_interfaces/usb_interface_mouse.c delete mode 100644 right/src/usb_interfaces/usb_interface_mouse.h delete mode 100644 right/src/usb_interfaces/usb_interface_system_keyboard.c delete mode 100644 right/src/usb_interfaces/usb_interface_system_keyboard.h diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 271868745..3e31d2c9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ on: jobs: release: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 25 env: ARM_GCC_DIR: /usr diff --git a/boards/ugl/uhk-60-right/Kconfig.board b/boards/ugl/uhk-60-right/Kconfig.board index 2cd56c676..dbeabd420 100644 --- a/boards/ugl/uhk-60-right/Kconfig.board +++ b/boards/ugl/uhk-60-right/Kconfig.board @@ -1,7 +1,9 @@ -# Copyright (c) 2018, Prevas A/S -# SPDX-License-Identifier: Apache-2.0 +config BOARD_UHK_60_RIGHT_V1 + bool "UHK 60 v1" + depends on SOC_SERIES_KINETIS_K2X + select SOC_PART_NUMBER_MK22FN512VLH12 -config BOARD_UHK_60_RIGHT - bool "UHK 60 right" +config BOARD_UHK_60_RIGHT_V2 + bool "UHK 60 v2" depends on SOC_SERIES_KINETIS_K2X select SOC_PART_NUMBER_MK22FN512VLH12 diff --git a/boards/ugl/uhk-80/Kconfig.defconfig b/boards/ugl/uhk-80/Kconfig.defconfig index 5312f1f53..e1aa2c962 100644 --- a/boards/ugl/uhk-80/Kconfig.defconfig +++ b/boards/ugl/uhk-80/Kconfig.defconfig @@ -25,28 +25,22 @@ endif # BT_DIS && BT_DIS_PNP if BOARD_UHK_80_LEFT config USB_DEVICE_PRODUCT default "UHK 80 left half bootloader" if MCUBOOT - default "UHK 80 Left USB" config USB_DEVICE_PID - default 0x0006 if !BT - default 0x0007 + default 0x0006 if MCUBOOT endif # BOARD_UHK_80_LEFT if BOARD_UHK_80_RIGHT config USB_DEVICE_PRODUCT default "UHK 80 right half bootloader" if MCUBOOT - default "UHK 80 Right USB" config USB_DEVICE_PID default 0x0008 if MCUBOOT - default 0x0009 endif # BOARD_UHK_80_RIGHT if BOARD_UHK_DONGLE config USB_DEVICE_PRODUCT default "UHK dongle bootloader" if MCUBOOT - default "UHK dongle" config USB_DEVICE_PID default 0x0004 if MCUBOOT - default 0x0005 endif # BOARD_UHK_DONGLE if BT diff --git a/device/CMakePresets.json b/device/CMakePresets.json index d446610cf..93c5703ba 100644 --- a/device/CMakePresets.json +++ b/device/CMakePresets.json @@ -6,15 +6,23 @@ }, "configurePresets": [ { - "name": "uhk-80-right", - "displayName": "Build for UHK 80 right", + "name": "defaults", + "hidden": true, "generator": "Ninja", - "binaryDir": "${fileDir}/build/uhk-80-right", + "binaryDir": "${fileDir}/build/${presetName}", "cacheVariables": { + "CPM_SOURCE_CACHE": "${fileDir}/../../cpm", "NCS_TOOLCHAIN_VERSION": "NONE", + "BOARD_ROOT": "${fileDir}/../", + "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf" + } + }, + { + "name": "uhk-80-right", + "displayName": "Build for UHK 80 right", + "inherits": "defaults", + "cacheVariables": { "BOARD": "uhk-80-right", - "BOARD_ROOT": "${sourceParentDir}/", - "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", "CONF_FILE": "${fileDir}/prj_release.conf", "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf;${fileDir}/prj.conf.overlays/ble_hid.conf;${fileDir}/prj.conf.overlays/uhk-80-right.conf" } @@ -22,27 +30,17 @@ { "name": "uhk-80-right-debug", "displayName": "Debug build for UHK 80 right", - "generator": "Ninja", - "binaryDir": "${fileDir}/build/uhk-80-right-debug", + "inherits": "uhk-80-right", "cacheVariables": { - "NCS_TOOLCHAIN_VERSION": "NONE", - "BOARD": "uhk-80-right", - "BOARD_ROOT": "${fileDir}/../", - "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${fileDir}/prj.conf", - "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf;${fileDir}/prj.conf.overlays/ble_hid.conf;${fileDir}/prj.conf.overlays/uhk-80-right.conf" + "CONF_FILE": "${fileDir}/prj.conf" } }, { "name": "uhk-80-left", "displayName": "Build for UHK 80 left", - "generator": "Ninja", - "binaryDir": "${fileDir}/build/uhk-80-left", + "inherits": "defaults", "cacheVariables": { - "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-80-left", - "BOARD_ROOT": "${fileDir}/../", - "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", "CONF_FILE": "${fileDir}/prj_release.conf", "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf" } @@ -50,27 +48,17 @@ { "name": "uhk-80-left-debug", "displayName": "Debug build for UHK 80 left", - "generator": "Ninja", - "binaryDir": "${fileDir}/build/uhk-80-left-debug", + "inherits": "uhk-80-left", "cacheVariables": { - "NCS_TOOLCHAIN_VERSION": "NONE", - "BOARD": "uhk-80-left", - "BOARD_ROOT": "${fileDir}/../", - "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${fileDir}/prj.conf", - "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/uhk-80.conf;${fileDir}/prj.conf.overlays/ble_nus.conf" + "CONF_FILE": "${fileDir}/prj.conf" } }, { "name": "uhk-dongle", "displayName": "Build for UHK dongle", - "generator": "Ninja", - "binaryDir": "${fileDir}/build/uhk-dongle", + "inherits": "defaults", "cacheVariables": { - "NCS_TOOLCHAIN_VERSION": "NONE", "BOARD": "uhk-dongle", - "BOARD_ROOT": "${fileDir}/../", - "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", "CONF_FILE": "${fileDir}/prj_release.conf", "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf" } @@ -78,16 +66,10 @@ { "name": "uhk-dongle-debug", "displayName": "Debug build for UHK dongle", - "generator": "Ninja", - "binaryDir": "${fileDir}/build/uhk-dongle-debug", + "inherits": "uhk-dongle", "cacheVariables": { - "NCS_TOOLCHAIN_VERSION": "NONE", - "BOARD": "uhk-dongle", - "BOARD_ROOT": "${fileDir}/../", - "mcuboot_OVERLAY_CONFIG": "${fileDir}/sysbuild/mcuboot.conf", - "CONF_FILE": "${fileDir}/prj.conf", - "EXTRA_CONF_FILE": "${fileDir}/prj.conf.overlays/nrf_shared.conf;${fileDir}/prj.conf.overlays/c2usb.conf;${fileDir}/prj.conf.overlays/ble_nus_client.conf" + "CONF_FILE": "${fileDir}/prj.conf" } } ] -} +} \ No newline at end of file diff --git a/device/Kconfig b/device/Kconfig index ca02dcde3..cbfe8fcff 100644 --- a/device/Kconfig +++ b/device/Kconfig @@ -1,12 +1,6 @@ # custom Kconfig defaults are set per board here, # as the board-specific Kconfig files are used for mcuboot build as well -config DEVICE_ID - int "UHK device id" - default 5 if BOARD_UHK_DONGLE - default 3 if BOARD_UHK_80_LEFT - default 4 if BOARD_UHK_80_RIGHT - help - The device id that identifies the specific UHK half or dongle. +rsource "../right/Kconfig.device" config UHK_BATTERY_DEVICE bool @@ -14,48 +8,6 @@ config UHK_BATTERY_DEVICE default n imply ADC -config KEYBOARD_MAX_SCANCODE - hex "highest keyboard scancode" - default 0xDD - range 0x66 0xDD - help - The highest keyboard scancode value influences the overall length of the HID record sent to the host. - The value 0x86 is the maximum for Android devices (which don't exchange the MTU from the default 23) - to still receive the "NKRO" report layout. If a higher scancode is used, the report size will exceed this size, - causing a fallback to 6KRO report layout on Android. - -# by using the same Kconfig symbol names as mcuboot, the board Kconfig files can contain the values -config USB_DEVICE_VID - hex "USB vendor ID" - range 0x0000 0xFFFF - default 0x37A8 - help - The USB vendor ID is used to identify the specific UHK device. - -config USB_DEVICE_MANUFACTURER - string "USB vendor name" - default "Ultimate Gadget Laboratories" - help - The USB vendor name is used to describe the specific UHK device to the host OS user. - -config USB_DEVICE_PID - hex "USB product ID" - range 0x0000 0xFFFF - help - The USB product ID is used to identify the specific UHK device. - -config USB_DEVICE_PRODUCT - string "USB product name" - help - The USB product name is used to describe the specific UHK device to the host OS user. - -config USB_DEVICE_PRODUCT_VERSION - hex "USB product version" - range 0x0000 0xFFFF - default 0x0001 - help - The USB product version is used to identify the UHK device operating mode. - # copy over the USB properties to BT configdefault BT_DIS_MANUF default USB_DEVICE_MANUFACTURER diff --git a/device/src/bt_manager.c b/device/src/bt_manager.c index 684ccab36..1d0f2eba3 100644 --- a/device/src/bt_manager.c +++ b/device/src/bt_manager.c @@ -3,7 +3,7 @@ #include "connections.h" #include "device_state.h" #include "event_scheduler.h" -#include "hid/config.h" +#include "hid/transport.h" #include "bt_advertise.h" #include "nus_client.h" #include "nus_server.h" diff --git a/device/src/connections.c b/device/src/connections.c index ba77fc185..7cf7251df 100644 --- a/device/src/connections.c +++ b/device/src/connections.c @@ -10,7 +10,7 @@ #include #include "connections.h" #include "stubs.h" -#include "hid/usb_compatibility.h" +#include "hid/transport.h" #include "logger.h" #include #include "config_manager.h" @@ -412,7 +412,7 @@ static void switchOver(connection_id_t connectionId) { HostConnection_SetSelectedConnection(ConnectionId_Invalid); } - UsbCompatibility_UpdateKeyboardLedsState(); + Hid_UpdateKeyboardLedsState(); } void Connections_HandleSwitchover(connection_id_t connectionId, bool forceSwitch) { diff --git a/device/src/keyboard/input_interceptor.c b/device/src/keyboard/input_interceptor.c deleted file mode 100644 index 57b5c55d5..000000000 --- a/device/src/keyboard/input_interceptor.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "input_interceptor.h" -#include "keyboard/oled/screens/screen_manager.h" -#include "keyboard/oled/screens/pairing_screen.h" - -static void(*recipient)(uint8_t) = NULL; - -static void registerScancode(uint8_t scancode) -{ - usb_basic_keyboard_report_t* inactiveReport = GetInactiveUsbBasicKeyboardReport(); - if (!UsbBasicKeyboard_ContainsScancode(inactiveReport, scancode) && recipient != NULL) - { - recipient(scancode); - } -} - -bool InputInterceptor_RegisterReport(usb_basic_keyboard_report_t* activeReport) -{ - if (InteractivePairingInProgress) { - recipient = &PairingScreen_RegisterScancode; - UsbBasicKeyboard_ForeachScancode(activeReport, ®isterScancode); - return true; - } else { - return false; - } -} diff --git a/device/src/keyboard/input_interceptor.h b/device/src/keyboard/input_interceptor.h deleted file mode 100644 index e7f59fa2d..000000000 --- a/device/src/keyboard/input_interceptor.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __INPUT_INTERCEPTOR_H__ -#define __INPUT_INTERCEPTOR_H__ - -// Includes: - - #include - #include - #include "usb_interfaces/usb_interface_basic_keyboard.h" - -// Macros: - -// Typedefs: - -// Variables: - - -// Functions: - - bool InputInterceptor_RegisterReport(usb_basic_keyboard_report_t* activeReport); - -#endif diff --git a/device/src/keyboard/oled/widgets/widget_store.c b/device/src/keyboard/oled/widgets/widget_store.c index d12662d3d..0f8e16d8c 100644 --- a/device/src/keyboard/oled/widgets/widget_store.c +++ b/device/src/keyboard/oled/widgets/widget_store.c @@ -21,7 +21,7 @@ #include #include #include "device_state.h" -#include "hid/usb_compatibility.h" +#include "hid/transport.h" #include "macros/status_buffer.h" #include "host_connection.h" #include "connections.h" diff --git a/device/src/main.c b/device/src/main.c index d6cd269a5..a196079ab 100644 --- a/device/src/main.c +++ b/device/src/main.c @@ -22,7 +22,7 @@ #include "peripherals/merge_sensor.h" #include "shell.h" #include "device.h" -#include "hid/config.h" +#include "hid/transport.h" #include "bt_conn.h" #include "settings.h" #include "flash.h" diff --git a/device/src/messenger.c b/device/src/messenger.c index 046b830f6..66f6ee5c1 100644 --- a/device/src/messenger.c +++ b/device/src/messenger.c @@ -11,7 +11,7 @@ #include "shared/slave_protocol.h" #include "state_sync.h" #include "thread_stats.h" -#include "hid/usb_compatibility.h" +#include "hid/transport.h" #include "nus_server.h" #include "nus_client.h" #include "module.h" @@ -206,13 +206,13 @@ static void processSyncablePropertyDongle(device_id_t src, const uint8_t* data, const uint8_t* message = data; switch (propertyId) { case SyncablePropertyId_KeyboardReport: - UsbCompatibility_SendKeyboardReport((usb_basic_keyboard_report_t*)message); + Hid_SendKeyboardReport((const hid_keyboard_report_t*)message); break; case SyncablePropertyId_MouseReport: - UsbCompatibility_SendMouseReport((usb_mouse_report_t*)message); + Hid_SendMouseReport((const hid_mouse_report_t*)message); break; case SyncablePropertyId_ControlsReport: - UsbCompatibility_SendConsumerReport2(message); + Hid_SendControlsReport((const hid_controls_report_t*)message); break; default: printk("Unrecognized or unexpected message [%i, %i, ...]\n", data[0], data[1]); diff --git a/device/src/nus_client.c b/device/src/nus_client.c index 081b960e1..b12d4a329 100644 --- a/device/src/nus_client.c +++ b/device/src/nus_client.c @@ -5,8 +5,7 @@ #include "bt_conn.h" #include "connections.h" #include "device.h" -#include "usb_interfaces/usb_interface_basic_keyboard.h" -#include "usb_interfaces/usb_interface_mouse.h" +#include "hid/transport.h" #include "messenger.h" #include "nus_client.h" #include "bool_array_converter.h" diff --git a/device/src/shell.c b/device/src/shell.c index 0a412ba4f..096ef0594 100644 --- a/device/src/shell.c +++ b/device/src/shell.c @@ -27,6 +27,7 @@ #include "pin_wiring.h" #include "device.h" #include "logger.h" +#include "hid/transport.h" #include "shell_backend_usb.h" #include "stubs.h" #include @@ -158,19 +159,9 @@ static int cmd_uhk_rollover(const struct shell *shell, size_t argc, char *argv[] { if (argc == 1) { shell_fprintf( - shell, SHELL_NORMAL, "%c\n", (HID_GetKeyboardRollover() == Rollover_NKey) ? 'n' : '6'); + shell, SHELL_NORMAL, "%c\n", (HID_GetKeyboardRollover() == ROLLOVER_N_KEY) ? 'n' : '6'); } else { - HID_SetKeyboardRollover((argv[1][0] == '6') ? Rollover_6Key : Rollover_NKey); - } - return 0; -} - -static int cmd_uhk_gamepad(const struct shell *shell, size_t argc, char *argv[]) -{ - if (argc == 1) { - shell_fprintf(shell, SHELL_NORMAL, "%c\n", HID_GetGamepadActive() ? 'y' : 'n'); - } else { - HID_SetGamepadActive(argv[1][0] != '0'); + HID_SetKeyboardRollover((argv[1][0] == '6') ? ROLLOVER_6_KEY : ROLLOVER_N_KEY); } return 0; } @@ -493,7 +484,6 @@ void InitShellCommands(void) #endif SHELL_CMD_ARG( rollover, NULL, "get/set keyboard rollover mode (n/6)", cmd_uhk_rollover, 1, 1), - SHELL_CMD_ARG(gamepad, NULL, "switch gamepad on/off", cmd_uhk_gamepad, 1, 1), SHELL_CMD_ARG(passkey, NULL, "send passkey for bluetooth pairing", cmd_uhk_passkey, 2, 0), SHELL_CMD_ARG(btunpair, NULL, "unpair bluetooth devices", cmd_uhk_btunpair, 1, 1), SHELL_CMD_ARG(connections, NULL, "list BLE connections", cmd_uhk_connections, 1, 0), diff --git a/device/src/state_sync.c b/device/src/state_sync.c index f38016310..aa125c325 100644 --- a/device/src/state_sync.c +++ b/device/src/state_sync.c @@ -25,7 +25,7 @@ #include "utils.h" #include "messenger.h" #include "state_sync.h" -#include "hid/usb_compatibility.h" +#include "hid/transport.h" #include #include #include "peripherals/merge_sensor.h" diff --git a/mcux_include.json b/mcux_include.json index 36c789ea0..6134918b6 100644 --- a/mcux_include.json +++ b/mcux_include.json @@ -16,7 +16,9 @@ "POSTPROCESS_UTILITY": "", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" }, - "cacheVariables": {} + "cacheVariables": { + "CPM_SOURCE_CACHE": "${fileDir}/../../cpm" + } }, { "name": "release-env", @@ -30,7 +32,9 @@ "POSTPROCESS_UTILITY": "", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" }, - "cacheVariables": {} + "cacheVariables": { + "CPM_SOURCE_CACHE": "${fileDir}/../../cpm" + } } ], "buildPresets": [] diff --git a/mcuxsdk.code-workspace b/mcuxsdk.code-workspace index 46fb90aa2..16eae8df9 100644 --- a/mcuxsdk.code-workspace +++ b/mcuxsdk.code-workspace @@ -30,6 +30,10 @@ { "name": "c2usb", "path": "../c2usb" + }, + { + "name": "lib", + "path": "../modules/lib" } ], "settings": { diff --git a/nrfsdk.code-workspace b/nrfsdk.code-workspace index dfe8bc0a4..0a6f247b9 100644 --- a/nrfsdk.code-workspace +++ b/nrfsdk.code-workspace @@ -1,11 +1,12 @@ { "folders": [ { - "path": "." + "name": "uhk-80", + "path": "./device" }, { - "name": "uhk-80", - "path": "device" + "name": "firmware", + "path": "." }, { "name": "workspace", @@ -14,17 +15,17 @@ ], "settings": { "nrf-connect.applications": [ - "${workspaceFolder}/device" + "${workspaceFolder:uhk-80}" ], "nrf-connect.applicationOptions": { - "${workspaceFolder}/device": { + "${workspaceFolder:uhk-80}": { "flash": { "softreset": true } } }, "nrf-connect.boardRoots": [ - "${workspaceFolder}/" + "${workspaceFolder:firmware}/" ], "files.associations": { "*.h": "c", diff --git a/patches/core/0005-cmake-set-_IS_TOP_LEVEL-project-variables.patch b/patches/core/0005-cmake-set-_IS_TOP_LEVEL-project-variables.patch new file mode 100644 index 000000000..fd6b35255 --- /dev/null +++ b/patches/core/0005-cmake-set-_IS_TOP_LEVEL-project-variables.patch @@ -0,0 +1,76 @@ +From c12b32684bbbd2bf33dbb0924b40769d02f97739 Mon Sep 17 00:00:00 2001 +From: Benedek Kupper +Date: Tue, 3 Feb 2026 23:57:45 +0100 +Subject: [PATCH] cmake: set _IS_TOP_LEVEL project variables + +--- + cmake/extension/mcux.cmake | 53 ++++++++++++++++++++++++++------------ + 1 file changed, 37 insertions(+), 16 deletions(-) + +diff --git a/cmake/extension/mcux.cmake b/cmake/extension/mcux.cmake +index 96732ef..db62e4e 100644 +--- a/cmake/extension/mcux.cmake ++++ b/cmake/extension/mcux.cmake +@@ -29,22 +29,43 @@ macro(project project_name) + + __project(${${project_ARGV}}) + +- set(PROJECT_NAME +- "${PROJECT_NAME}" +- PARENT_SCOPE) +- set(PROJECT_BINARY_DIR +- "${PROJECT_BINARY_DIR}" +- PARENT_SCOPE) +- set(PROJECT_SOURCE_DIR +- "${PROJECT_SOURCE_DIR}" +- PARENT_SCOPE) +- +- set(${PROJECT_NAME}_BINARY_DIR +- "${${PROJECT_NAME}_BINARY_DIR}" +- PARENT_SCOPE) +- set(${PROJECT_NAME}_SOURCE_DIR +- "${${PROJECT_NAME}_SOURCE_DIR}" +- PARENT_SCOPE) ++ # Set the variables that project() normally sets, documented in the ++ # command's docs. ++ # ++ # https://cmake.org/cmake/help/v3.16/command/project.html ++ # ++ # There is some nuance when it comes to setting version variables in terms of whether ++ # CMP0048 is set to OLD or NEW. However, the proper behavior should have bee already handled by the original ++ # project call, and we're just echoing the values those variables were set to. ++ set(PROJECT_NAME "${PROJECT_NAME}" PARENT_SCOPE) ++ set(PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}" PARENT_SCOPE) ++ set(PROJECT_SOURCE_DIR "${PROJECT_SOURCE_DIR}" PARENT_SCOPE) ++ set(PROJECT_VERSION "${PROJECT_VERSION}" PARENT_SCOPE) ++ set(PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}" PARENT_SCOPE) ++ set(PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}" PARENT_SCOPE) ++ set(PROJECT_VERSION_PATCH "${PROJECT_VERSION_PATCH}" PARENT_SCOPE) ++ set(PROJECT_VERSION_TWEAK "${PROJECT_VERSION_TWEAK}" PARENT_SCOPE) ++ set(PROJECT_DESCRIPTION "${PROJECT_DESCRIPTION}" PARENT_SCOPE) ++ set(PROJECT_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}" PARENT_SCOPE) ++ ++ set(${PROJECT_NAME}_BINARY_DIR "${${PROJECT_NAME}_BINARY_DIR}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_SOURCE_DIR "${${PROJECT_NAME}_SOURCE_DIR}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_VERSION_MAJOR "${${PROJECT_NAME}_VERSION_MAJOR}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_VERSION_MINOR "${${PROJECT_NAME}_VERSION_MINOR}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_VERSION_PATCH "${${PROJECT_NAME}_VERSION_PATCH}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_VERSION_TWEAK "${${PROJECT_NAME}_VERSION_TWEAK}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_DESCRIPTION "${${PROJECT_NAME}_DESCRIPTION}" PARENT_SCOPE) ++ set(${PROJECT_NAME}_HOMEPAGE_URL "${${PROJECT_NAME}_HOMEPAGE_URL}" PARENT_SCOPE) ++ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.21") ++ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) ++ set(PROJECT_IS_TOP_LEVEL ON PARENT_SCOPE) ++ set(${PROJECT_NAME}_IS_TOP_LEVEL ON PARENT_SCOPE) ++ else() ++ set(PROJECT_IS_TOP_LEVEL OFF PARENT_SCOPE) ++ set(${PROJECT_NAME}_IS_TOP_LEVEL OFF PARENT_SCOPE) ++ endif() ++ endif() + endfunction() + + # valiate compiler version +-- +2.43.0 + diff --git a/patches/usb/0001-use-SDK-delay-for-wakeup.patch b/patches/usb/0001-use-SDK-delay-for-wakeup.patch index 57600316b..5926576dc 100644 --- a/patches/usb/0001-use-SDK-delay-for-wakeup.patch +++ b/patches/usb/0001-use-SDK-delay-for-wakeup.patch @@ -1,18 +1,30 @@ -From 17f6f616c91abe1929df346866b1c3405f09594e Mon Sep 17 00:00:00 2001 +From 2f8bfdef70e9d099e5778c92081e2d217c330fba Mon Sep 17 00:00:00 2001 From: Benedek Kupper -Date: Tue, 22 Jul 2025 15:52:37 +0200 +Date: Thu, 5 Feb 2026 21:34:25 +0100 Subject: [PATCH] use SDK delay for wakeup --- - device/usb_device_ehci.c | 6 +----- - device/usb_device_khci.c | 6 +----- - 2 files changed, 2 insertions(+), 10 deletions(-) + device/usb_device_ehci.c | 11 +---------- + device/usb_device_khci.c | 11 +---------- + 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/device/usb_device_ehci.c b/device/usb_device_ehci.c -index 1780f87..e6462fe 100644 +index 1780f87..87f7a06 100644 --- a/device/usb_device_ehci.c +++ b/device/usb_device_ehci.c -@@ -2073,11 +2073,7 @@ usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_ +@@ -1944,11 +1944,6 @@ usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_ + + #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + usb_device_struct_t *deviceHandle; +-#endif +-#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +-#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) +- uint64_t startTick; +-#endif + #endif + + if (NULL == ehciHandle) +@@ -2073,11 +2068,7 @@ usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_ #endif ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; @@ -26,10 +38,22 @@ index 1780f87..e6462fe 100644 error = kStatus_USB_Success; break; diff --git a/device/usb_device_khci.c b/device/usb_device_khci.c -index c62addc..f0e1fce 100644 +index c62addc..0ee7f7e 100644 --- a/device/usb_device_khci.c +++ b/device/usb_device_khci.c -@@ -1627,11 +1627,7 @@ usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, usb_ +@@ -1507,11 +1507,6 @@ usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, usb_ + #endif + #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + usb_device_struct_t *deviceHandle; +-#endif +-#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +-#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) +- uint64_t startTick; +-#endif + #endif + usb_status_t status = kStatus_USB_Error; + +@@ -1627,11 +1622,7 @@ usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, usb_ #if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U) case kUSB_DeviceControlResume: khciState->registerBase->CTL |= USB_CTL_RESUME_MASK; diff --git a/right/.vscode/launch.json b/right/.vscode/launch.json index 13ad2b189..55a21068b 100644 --- a/right/.vscode/launch.json +++ b/right/.vscode/launch.json @@ -7,26 +7,27 @@ "cwd": "${workspaceFolder}", "svdPath": "${workspaceFolder}/../svd/MK22F51212.xml", - "executable": "", + "executable": { + "elf": "${workspaceFolder}/build/v2-debug/uhk-60-right.elf" + }, "stopAtSymbol": "main", "probeSerialNumber": "", "isAttach": false, - "probeType": "", "skipBuildBeforeDebug": false, - "skipPreFlashActions": true, - "gdbInitCommands": [ "set remotetimeout 600", "set debug-file-directory", "set non-stop off" ], - + "gdbClientPath": "${env:ARM_GCC_DIR}/bin/arm-none-eabi-gdb", "gdbServerConfigs": { "linkserver": {}, - "segger": {}, - "pemicro": {} + "segger": { + "interface": "SWD", + "device": "MK22FN512xxx12", + }, + "pemicro": {} }, - "showDevDebugOutput": "none" } ] diff --git a/right/.vscode/settings.json b/right/.vscode/settings.json index 15fa8fd21..c101b99a0 100644 --- a/right/.vscode/settings.json +++ b/right/.vscode/settings.json @@ -5,5 +5,6 @@ "cmake.useCMakePresets": "always", "cmake.buildTask": true, "cmake.skipConfigureIfCachePresent": true, - "cmake.sourceDirectory": "${workspaceFolder}" + "cmake.sourceDirectory": "${workspaceFolder}", + "mcuxpresso.toolchainCompatibilityRecommendations": false } \ No newline at end of file diff --git a/right/CMakeLists.txt b/right/CMakeLists.txt index dd279bd9b..dbe3a73fb 100644 --- a/right/CMakeLists.txt +++ b/right/CMakeLists.txt @@ -2,12 +2,20 @@ cmake_minimum_required(VERSION 3.22.0) add_subdirectory(sysbuild) +# Avoid linking test executables (prevents newlib _exit/_sbrk etc. linker errors) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE STRING "") + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(WORKSPACE_TOPDIR "${CMAKE_CURRENT_LIST_DIR}/../..") +set(CPM_bitfilled_SOURCE "${WORKSPACE_TOPDIR}/modules/lib/bitfilled") +set(CPM_hid-rp_SOURCE "${WORKSPACE_TOPDIR}/modules/lib/hid-rp") +set(CPM_etl_SOURCE "${WORKSPACE_TOPDIR}/modules/lib/etl") + set(EXTRA_MCUX_MODULES ${CMAKE_CURRENT_LIST_DIR}/../../c2usb) set(board frdmk22f) # TODO: how to remove the board selection? @@ -23,9 +31,6 @@ set(IS_MCUX_SDK ON) set(BL_APP_VECTOR_TABLE_ADDRESS 0xc000) target_compile_definitions(${PROJECT_NAME} PUBLIC - PROJECT_NAME=${DEVICE_PROJECT_NAME} - DEVICE_ID=${DEVICE_ID} - DEVICE_PID=${DEVICE_PID} BL_HAS_BOOTLOADER_CONFIG=1 BL_APP_VECTOR_TABLE_ADDRESS=${BL_APP_VECTOR_TABLE_ADDRESS} __STARTUP_CLEAR_BSS diff --git a/right/CMakePresets.json b/right/CMakePresets.json index 936d52f92..20dcd2193 100644 --- a/right/CMakePresets.json +++ b/right/CMakePresets.json @@ -5,14 +5,17 @@ }, "configurePresets": [ { - "name": "v1-debug", - "displayName": "v1-debug", + "name": "debug", + "hidden": true, "generator": "Ninja", "binaryDir": "${fileDir}/build/${presetName}", "toolchainFile": "$env{SdkRootDirPath}/mcuxsdk/cmake/toolchain/armgcc.cmake", "inherits": "debug-env", "cacheVariables": { - "APP_DIR": "${fileDir}", + "APP_DIR": { + "value": "${fileDir}", + "type": "PATH" + }, "SdkRootDirPath": "$env{SdkRootDirPath}/mcuxsdk", "CMAKE_BUILD_TYPE": "debug", "CONFIG_TOOLCHAIN": "armgcc", @@ -20,65 +23,37 @@ "CMAKE_RUNTIME_OUTPUT_DIRECTORY": "$env{binaryDir}", "CMAKE_LIBRARY_OUTPUT_DIRECTORY": "$env{binaryDir}", "CMAKE_ARCHIVE_OUTPUT_DIRECTORY": "$env{binaryDir}", - "PrjRootDirPath": "${fileDir}/", - "DEVICE_PROJECT_NAME": "uhk60v1", - "DEVICE_ID": "DEVICE_ID_UHK60V1", - "DEVICE_PID": "1" + "PrjRootDirPath": "${fileDir}/" } }, { - "name": "v1-release", - "displayName": "v1-release", - "generator": "Ninja", - "binaryDir": "${fileDir}/build/${presetName}", - "toolchainFile": "$env{SdkRootDirPath}/mcuxsdk/cmake/toolchain/armgcc.cmake", - "inherits": "release-env", + "name": "v1-debug", + "displayName": "v1-debug", + "inherits": "debug", "cacheVariables": { - "APP_DIR": "${fileDir}", - "SdkRootDirPath": "$env{SdkRootDirPath}/mcuxsdk", - "CMAKE_BUILD_TYPE": "release", - "CONFIG_TOOLCHAIN": "armgcc", - "board": "$env{BOARD}", - "CMAKE_RUNTIME_OUTPUT_DIRECTORY": "$env{binaryDir}", - "CMAKE_LIBRARY_OUTPUT_DIRECTORY": "$env{binaryDir}", - "CMAKE_ARCHIVE_OUTPUT_DIRECTORY": "$env{binaryDir}", - "PrjRootDirPath": "${fileDir}/", - "DEVICE_PROJECT_NAME": "uhk60v1", - "DEVICE_ID": "DEVICE_ID_UHK60V1", - "DEVICE_PID": "1" + "CONFIG_BOARD_UHK_60_RIGHT_V1": "y" } }, { "name": "v2-debug", "displayName": "v2-debug", - "generator": "Ninja", - "binaryDir": "${fileDir}/build/${presetName}", - "toolchainFile": "$env{SdkRootDirPath}/mcuxsdk/cmake/toolchain/armgcc.cmake", - "inherits": "debug-env", + "inherits": "debug", "cacheVariables": { - "APP_DIR": "${fileDir}", - "SdkRootDirPath": "$env{SdkRootDirPath}/mcuxsdk", - "CMAKE_BUILD_TYPE": "debug", - "CONFIG_TOOLCHAIN": "armgcc", - "board": "$env{BOARD}", - "CMAKE_RUNTIME_OUTPUT_DIRECTORY": "$env{binaryDir}", - "CMAKE_LIBRARY_OUTPUT_DIRECTORY": "$env{binaryDir}", - "CMAKE_ARCHIVE_OUTPUT_DIRECTORY": "$env{binaryDir}", - "PrjRootDirPath": "${fileDir}/", - "DEVICE_PROJECT_NAME": "uhk60v2", - "DEVICE_ID": "DEVICE_ID_UHK60V2", - "DEVICE_PID": "3" + "CONFIG_BOARD_UHK_60_RIGHT_V2": "y" } }, { - "name": "v2-release", - "displayName": "v2-release", + "name": "release", + "hidden": true, "generator": "Ninja", "binaryDir": "${fileDir}/build/${presetName}", "toolchainFile": "$env{SdkRootDirPath}/mcuxsdk/cmake/toolchain/armgcc.cmake", "inherits": "release-env", "cacheVariables": { - "APP_DIR": "${fileDir}", + "APP_DIR": { + "value": "${fileDir}", + "type": "PATH" + }, "SdkRootDirPath": "$env{SdkRootDirPath}/mcuxsdk", "CMAKE_BUILD_TYPE": "release", "CONFIG_TOOLCHAIN": "armgcc", @@ -86,10 +61,23 @@ "CMAKE_RUNTIME_OUTPUT_DIRECTORY": "$env{binaryDir}", "CMAKE_LIBRARY_OUTPUT_DIRECTORY": "$env{binaryDir}", "CMAKE_ARCHIVE_OUTPUT_DIRECTORY": "$env{binaryDir}", - "PrjRootDirPath": "${fileDir}/", - "DEVICE_PROJECT_NAME": "uhk60v2", - "DEVICE_ID": "DEVICE_ID_UHK60V2", - "DEVICE_PID": "3" + "PrjRootDirPath": "${fileDir}/" + } + }, + { + "name": "v1-release", + "displayName": "v1-release", + "inherits": "release", + "cacheVariables": { + "CONFIG_BOARD_UHK_60_RIGHT_V1": "y" + } + }, + { + "name": "v2-release", + "displayName": "v2-release", + "inherits": "release", + "cacheVariables": { + "CONFIG_BOARD_UHK_60_RIGHT_V2": "y" } } ], diff --git a/right/Kconfig b/right/Kconfig new file mode 100644 index 000000000..534aa359c --- /dev/null +++ b/right/Kconfig @@ -0,0 +1,12 @@ +# Need to refer the root Kconfig.mcuxpreso to get all Kconfig data +source "Kconfig.mcuxpresso" + +# Board example specific Kconfig can be linked in this way if needed +osource "${project_board_port_path}/Kconfig" + +config BOARD_UHK_60_RIGHT_V1 + bool "UHK 60 v1" +config BOARD_UHK_60_RIGHT_V2 + bool "UHK 60 v2" + +rsource "Kconfig.device" diff --git a/right/Kconfig.device b/right/Kconfig.device new file mode 100644 index 000000000..2df6e206d --- /dev/null +++ b/right/Kconfig.device @@ -0,0 +1,98 @@ +# custom Kconfig defaults are set per board here, +# as the board-specific Kconfig files are used for mcuboot build as well + +config DEVICE_ID + int "UHK device id" + default 1 if BOARD_UHK_60_RIGHT_V1 + default 2 if BOARD_UHK_60_RIGHT_V2 + default 3 if BOARD_UHK_80_LEFT + default 4 if BOARD_UHK_80_RIGHT + default 5 if BOARD_UHK_DONGLE + help + The device id that identifies the specific UHK. + +config KEYBOARD_MAX_SCANCODE + hex "highest keyboard scancode" + default 0xDD + range 0x66 0xDD + help + The highest keyboard scancode value influences the overall length of the HID record sent to the host. + The value 0x86 is the maximum for Android devices (which don't exchange the MTU from the default 23) + to still receive the "NKRO" report layout. If a higher scancode is used, the report size will exceed this size, + causing a fallback to 6KRO report layout on Android. + +# Device vid / pid / comment: +# +# old: +# 0x1D50 0x6120 UHK 60 v1 KBOOT Bootloader +# 0x1D50 0x6121 UHK Bootloader proxy +# 0x1D50 0x6122 UHK 60 v1 Keyboard firmware +# 0x1D50 0x6123 UHK 60 v2 KBOOT Bootloader +# 0x1D50 0x6124 UHK 60 v2 Keyboard firmware +# +# new: +# 0x37A8 0x0000 UHK 60 v1 BusPal proxy +# 0x37A8 0x0001 UHK 60 v1 keyboard firmware +# 0x37A8 0x0002 UHK 60 v2 BusPal proxy +# 0x37A8 0x0003 UHK 60 v2 keyboard firmware +# 0x37A8 0x0004 UHK Dongle MCUboot bootloader +# 0x37A8 0x0005 UHK Dongle firmware +# 0x37A8 0x0006 UHK 80 left MCUboot +# 0x37A8 0x0007 UHK 80 left keyboard firmware +# 0x37A8 0x0008 UHK 80 right MCUboot +# 0x37A8 0x0009 UHK 80 right keyboard firmware + +# by using the same Kconfig symbol names as mcuboot, the board Kconfig files can contain the values +config USB_DEVICE_VID + hex "USB vendor ID" + range 0x0000 0xFFFF + default 0x37A8 + help + The USB vendor ID is used to identify the specific UHK device. + +config USB_DEVICE_MANUFACTURER + string "USB vendor name" + default "Ultimate Gadget Laboratories" + help + The USB vendor name is used to describe the specific UHK device to the host OS user. + Macro value is in quotes + +config USB_BUSPAL_DEVICE_PID + hex "USB BusPal product ID" + range 0x0000 0xFFFF + default 0x0000 if BOARD_UHK_60_RIGHT_V1 + default 0x0002 if BOARD_UHK_60_RIGHT_V2 + default 0x0000 + help + The USB BusPal product ID is used to identify the specific UHK device. + +config USB_DEVICE_PID + hex "USB product ID" + range 0x0000 0xFFFF + default 0x0001 if BOARD_UHK_60_RIGHT_V1 + default 0x0003 if BOARD_UHK_60_RIGHT_V2 + default 0x0005 if BOARD_UHK_DONGLE + default 0x0007 if BOARD_UHK_80_LEFT + default 0x0009 if BOARD_UHK_80_RIGHT + help + The USB product ID is used to identify the specific UHK device. + +config USB_DEVICE_PRODUCT + string "USB product name" + default "UHK 60 v1" if BOARD_UHK_60_RIGHT_V1 + default "UHK 60 v2" if BOARD_UHK_60_RIGHT_V2 + default "UHK dongle" if BOARD_UHK_DONGLE + default "UHK 80 Left USB" if BOARD_UHK_80_LEFT + default "UHK 80 Right USB" if BOARD_UHK_80_RIGHT + help + The USB product name is used to describe the specific UHK device to the host OS user. + Macro value is in quotes + +config USB_DEVICE_PRODUCT_VERSION + hex "USB product version" + range 0x0000 0xFFFF + default 0x0001 if BOARD_UHK_60_RIGHT_V1 + default 0x0002 if BOARD_UHK_60_RIGHT_V2 + default 0x0001 + help + The USB product version is used to identify the UHK device operating mode. diff --git a/right/prj.conf b/right/prj.conf index 843ac5afa..92594546d 100644 --- a/right/prj.conf +++ b/right/prj.conf @@ -8,13 +8,14 @@ CONFIG_MCUX_COMPONENT_middleware.usb.device.common_header=y CONFIG_MCUX_COMPONENT_middleware.usb.device.khci=y #CONFIG_MCUX_COMPONENT_middleware.usb.device.khci_config_header=n #CONFIG_MCUX_COMPONENT_middleware.usb.device.controller.driver=y -CONFIG_MCUX_MISC_USB_DEVICE_GENERATE_CONFIG=n +CONFIG_MCUX_MISC_USB_DEVICE_GENERATE_CONFIG=y CONFIG_MCUX_MISC_USB_LITE=y -#CONFIG_USB_DEVICE_CONFIG_SELF_POWER=n -#CONFIG_USB_DEVICE_CONFIG_HID=5 +CONFIG_USB_DEVICE_CONFIG_SELF_POWER=n +# buspal USB HID device +CONFIG_USB_DEVICE_CONFIG_HID=1 #CONFIG_USB_DEVICE_CONFIG_ENDPOINTS=9 -#CONFIG_USB_DEVICE_CONFIG_LOW_POWER_MODE=y -#CONFIG_USB_DEVICE_CONFIG_REMOTE_WAKEUP=y +CONFIG_USB_DEVICE_CONFIG_LOW_POWER_MODE=y +CONFIG_USB_DEVICE_CONFIG_REMOTE_WAKEUP=y CONFIG_C2USB_MCUX_MAC=y # disable board (and device) specific source files, as the project has its own sources diff --git a/right/src/CMakeLists.txt b/right/src/CMakeLists.txt index d6c77c42f..1fa4565b0 100644 --- a/right/src/CMakeLists.txt +++ b/right/src/CMakeLists.txt @@ -4,25 +4,19 @@ target_include_directories(${PROJECT_NAME} PUBLIC ) add_subdirectory(config_parser) +add_subdirectory(hid) add_subdirectory(layouts) add_subdirectory(macros) add_subdirectory(peripherals) add_subdirectory(slave_drivers) -add_subdirectory(usb_commands) -add_subdirectory(usb_interfaces) add_subdirectory(test_suite) +add_subdirectory(usb_commands) if(IS_MCUX_SDK) add_subdirectory(buspal) add_subdirectory(ksdk_usb) - add_subdirectory(usb_descriptors) target_sources(${PROJECT_NAME} PRIVATE startup/startup_MK22F51212.S ) - # need to add header explicitly to avoid pulling in wrong SDK header - # https://github.com/nxp-mcuxpresso/mcuxsdk-middleware-usb/issues/12 - mcux_add_source(SOURCES usb_device_config.h) -else() - add_subdirectory(hid) endif() target_sources(${PROJECT_NAME} PRIVATE @@ -69,7 +63,6 @@ target_sources(${PROJECT_NAME} PRIVATE timer.c trace.c $<$:${CMAKE_CURRENT_SOURCE_DIR}/trace_reasons.c> - $<$:${CMAKE_CURRENT_SOURCE_DIR}/usb_composite_device.c> usb_log_buffer.c usb_protocol_handler.c usb_report_updater.c diff --git a/right/src/buspal/bm_usb/composite.h b/right/src/buspal/bm_usb/composite.h index a62fee3b9..838713939 100644 --- a/right/src/buspal/bm_usb/composite.h +++ b/right/src/buspal/bm_usb/composite.h @@ -2,7 +2,6 @@ #define __USB_DEVICE_COMPOSITE_H__ #include "hid_bootloader.h" -#include "usb_device_config.h" #include "bm_usb/usb_descriptor.h" #define CONTROLLER_ID kUSB_ControllerKhci0 diff --git a/right/src/buspal/bm_usb/hid_bootloader.c b/right/src/buspal/bm_usb/hid_bootloader.c index e16cdfebc..9235b3492 100644 --- a/right/src/buspal/bm_usb/hid_bootloader.c +++ b/right/src/buspal/bm_usb/hid_bootloader.c @@ -1,6 +1,7 @@ #include "usb_descriptor.h" #include "composite.h" #include "peripherals/test_led.h" +#include "usb_device_hid.h" extern usb_device_endpoint_struct_t g_hid_generic_endpoints[]; static usb_device_composite_struct_t *g_device_composite; diff --git a/right/src/buspal/bm_usb/usb_descriptor.c b/right/src/buspal/bm_usb/usb_descriptor.c index 819ef64e4..bc6db8981 100644 --- a/right/src/buspal/bm_usb/usb_descriptor.c +++ b/right/src/buspal/bm_usb/usb_descriptor.c @@ -106,20 +106,16 @@ uint8_t g_device_descriptor[USB_DEVICE_DESCRIPTOR_LENGTH] = { /* Max Packet size */ USB_CONTROL_MAX_PACKET_SIZE, /* Vendor ID */ - 0xa8, 0x37, /* UHK bootloader proxy VID */ + USB_SHORT_GET_LOW(CONFIG_USB_DEVICE_VID), USB_SHORT_GET_HIGH(CONFIG_USB_DEVICE_VID), /* Product ID */ - #if DEVICE_ID == DEVICE_ID_UHK60V1 - 0x00, 0x00, /* UHK bootloader proxy PID */ - #elif DEVICE_ID == DEVICE_ID_UHK60V2 - 0x02, 0x00, /* UHK bootloader proxy PID */ - #endif + USB_SHORT_GET_LOW(CONFIG_USB_BUSPAL_DEVICE_PID), USB_SHORT_GET_HIGH(CONFIG_USB_BUSPAL_DEVICE_PID), /* BCD Device version */ - 0x02, 0x00, + USB_SHORT_GET_LOW(CONFIG_USB_DEVICE_PRODUCT_VERSION), USB_SHORT_GET_HIGH(CONFIG_USB_DEVICE_PRODUCT_VERSION), /* Manufacturer string index */ 0x01, /* Product string index */ 0x02, -/* Serial number string index */ + /* Serial number string index */ 0x00, /* Number of configurations */ USB_CONFIGURE_COUNT, @@ -140,9 +136,7 @@ uint8_t g_config_descriptor[USB_CONFIGURE_DESCRIPTOR_LENGTH] = { /* Configuration Description String Index */ 0, /* Attributes.support RemoteWakeup and self power */ - (USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) | - (USB_DEVICE_CONFIG_SELF_POWER << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT) | - (USB_DEVICE_CONFIG_REMOTE_WAKEUP << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT), + (USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK), /* Current draw from bus */ USB_CONFIGURE_DRAWN, diff --git a/right/src/buspal/bm_usb/usb_descriptor.h b/right/src/buspal/bm_usb/usb_descriptor.h index 4d6847036..7490a826d 100644 --- a/right/src/buspal/bm_usb/usb_descriptor.h +++ b/right/src/buspal/bm_usb/usb_descriptor.h @@ -3,9 +3,18 @@ #include "bootloader_common.h" #include "usb_device_config.h" -#include "usb_api.h" +#include "usb.h" #include "usb_device.h" #include "usb_device_class.h" +#include "usb_device_config.h" + +#define USB_DEVICE_CLASS 0x00 +#define USB_DEVICE_SUBCLASS 0x00 +#define USB_DEVICE_PROTOCOL 0x00 + +#ifndef USB_DEVICE_CONFIG_SELF_POWER + #define USB_DEVICE_CONFIG_SELF_POWER 0 +#endif #define USB_BCD_VERSION (0x0200) diff --git a/right/src/buspal/bus_pal_hardware.c b/right/src/buspal/bus_pal_hardware.c index bd85b08fe..3660b8bda 100644 --- a/right/src/buspal/bus_pal_hardware.c +++ b/right/src/buspal/bus_pal_hardware.c @@ -1,11 +1,13 @@ #include "bus_pal_hardware.h" #include "usb_descriptor.h" -#include "usb_device_config.h" #include "composite.h" #include "microseconds/microseconds.h" #include "i2c.h" #include "peripherals/test_led.h" -#include "usb_composite_device.h" +#include "usb_device_hid.h" + +#define CONTROLLER_ID kUSB_ControllerKhci0 +#define USB_DEVICE_INTERRUPT_PRIORITY 3 bool is_usb_active(); static status_t usb_device_full_init(const peripheral_descriptor_t *self, serial_byte_receive_func_t function); diff --git a/right/src/debug.c b/right/src/debug.c index 21b009cf6..1f37661b8 100644 --- a/right/src/debug.c +++ b/right/src/debug.c @@ -1,5 +1,6 @@ #include #include "debug.h" +#include "hid/keyboard_report.h" #ifdef __ZEPHYR__ #include "logger.h" @@ -14,7 +15,6 @@ #include "timer.h" #include "key_states.h" #include -#include "usb_interfaces/usb_interface_basic_keyboard.h" #include "macros/status_buffer.h" #include "segment_display.h" @@ -53,7 +53,7 @@ static void writeScancode(uint8_t b) Macros_SetStatusNum(b); } -void AddReportToStatusBuffer(char* dbgTag, usb_basic_keyboard_report_t *report) +void AddReportToStatusBuffer(char* dbgTag, hid_keyboard_report_t *report) { if (dbgTag != NULL && *dbgTag != '\0') { Macros_SetStatusString(dbgTag, NULL); diff --git a/right/src/debug.h b/right/src/debug.h index 290539299..04c94b401 100644 --- a/right/src/debug.h +++ b/right/src/debug.h @@ -31,7 +31,6 @@ #include #include "key_states.h" -#include "usb_interfaces/usb_interface_basic_keyboard.h" #if WATCHES @@ -111,7 +110,8 @@ bool WatchCondition(uint8_t n); void ShowValue(int v, uint8_t n); void ShowString(char const * v, uint8_t n); - void AddReportToStatusBuffer(char* dbgTag, usb_basic_keyboard_report_t *report); + struct hid_keyboard_report_t; + void AddReportToStatusBuffer(char* dbgTag, hid_keyboard_report_t *report); #ifdef __ZEPHYR__ void WatchSemaforeTake(struct k_sem* sem, char const * label, uint8_t n); diff --git a/right/src/event_scheduler.c b/right/src/event_scheduler.c index 8b03ef3fd..e5624b37f 100644 --- a/right/src/event_scheduler.c +++ b/right/src/event_scheduler.c @@ -340,7 +340,6 @@ void EventVector_ReportMask(const char* prefix, uint32_t mask) { REPORT_MASK(KeyboardLedState); REPORT_MASK(UsbMacroCommandWaitingForExecution); - REPORT_MASK(ProtocolChanged); REPORT_MASK(LedManagerFullUpdateNeeded); REPORT_MASK(KeymapReloadNeeded); REPORT_MASK(SegmentDisplayNeedsUpdate); diff --git a/right/src/event_scheduler.h b/right/src/event_scheduler.h index 1e6812092..6c73e8712 100644 --- a/right/src/event_scheduler.h +++ b/right/src/event_scheduler.h @@ -71,7 +71,7 @@ // some other minor triggers EventVector_KeyboardLedState = 1 << 10, EventVector_UsbMacroCommandWaitingForExecution = 1 << 11, - EventVector_ProtocolChanged = 1 << 12, + // EventVector_ProtocolChanged = 1 << 12, // unused EventVector_LedManagerFullUpdateNeeded = 1 << 13, EventVector_KeymapReloadNeeded = 1 << 14, EventVector_SegmentDisplayNeedsUpdate = 1 << 15, diff --git a/right/src/hid/CMakeLists.txt b/right/src/hid/CMakeLists.txt index 0fc8d246c..a6ba9a42f 100644 --- a/right/src/hid/CMakeLists.txt +++ b/right/src/hid/CMakeLists.txt @@ -1,10 +1,17 @@ target_sources(${PROJECT_NAME} PRIVATE - app_base.cpp + controls_report.c + keyboard_report.c + mouse_report.c command_app.cpp controls_app.cpp - gamepad_app.cpp keyboard_app.cpp mouse_app.cpp - usb_compatibility.cpp - usb.cpp + transport.cpp + transport_usb.cpp ) + +if(CONFIG_C2USB_BLUETOOTH) + target_sources(${PROJECT_NAME} PRIVATE + transport_ble.cpp + ) +endif() diff --git a/right/src/hid/app_base.cpp b/right/src/hid/app_base.cpp deleted file mode 100644 index dc115d0ad..000000000 --- a/right/src/hid/app_base.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "app_base.hpp" - -void app_base::stop() -{ - sending_sem_.release(); -} - -void app_base::send(const std::span &buffer) -{ - if (!active()) { - return; - } - if (!sending_sem_.try_acquire_for(SEMAPHORE_RESET_TIMEOUT)) { - //return; - } - std::copy(buffer.begin(), buffer.end(), in_buffer_.data() + sizeof(in_id_)); - auto result = send_report(in_buffer_); - if (result != hid::result::ok) { - sending_sem_.release(); - } -} - -void app_base::in_report_sent(const std::span &data) -{ - if (data.front() != in_id_) { - return; - } - sending_sem_.release(); -} - -void app_base::get_report(hid::report::selector select, const std::span &buffer) -{ - if (select != hid::report::selector(hid::report::type::INPUT, in_id_)) { - return; - } - assert(buffer.size() >= in_buffer_.size()); - - memcpy(buffer.data(), in_buffer_.data(), in_buffer_.size()); - send_report(buffer.subspan(0, in_buffer_.size())); -} diff --git a/right/src/hid/app_base.hpp b/right/src/hid/app_base.hpp deleted file mode 100644 index 8577842d5..000000000 --- a/right/src/hid/app_base.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __APP_BASE_HEADER__ -#define __APP_BASE_HEADER__ - -extern "C" { -#include "device.h" -} -#include "hid/application.hpp" -#include "hid/rdf/descriptor.hpp" -#include "hid/report_protocol.hpp" -#include "port/zephyr/semaphore.hpp" -#include - -class app_base : public hid::application { - public: - bool active() const; - - protected: - static constexpr std::chrono::milliseconds SEMAPHORE_RESET_TIMEOUT{100}; - - template - static hid::report_protocol rp() - { - static constexpr const auto rd{T::report_desc()}; - constexpr hid::report_protocol rp{rd}; - return rp; - } - template - constexpr app_base([[maybe_unused]] T *t, TReport &in_report_buffer) - : application(rp()), - in_id_(in_report_buffer.ID), - in_buffer_(in_report_buffer.data(), sizeof(TReport)) - {} - - void stop() override; - void set_report(hid::report::type type, const std::span &data) override {} - void get_report(hid::report::selector select, const std::span &buffer) override; - void in_report_sent(const std::span &data) override; - void send(const std::span &buffer); - - const hid::report::id in_id_; - const std::span in_buffer_; - os::zephyr::binary_semaphore sending_sem_{1}; -}; - -#endif // __APP_BASE_HEADER__ diff --git a/right/src/hid/command_app.cpp b/right/src/hid/command_app.cpp index d7c57ede6..7f0d1a0eb 100644 --- a/right/src/hid/command_app.cpp +++ b/right/src/hid/command_app.cpp @@ -1,7 +1,9 @@ #include "command_app.hpp" -#include "hid/rdf/descriptor.hpp" -#include "hid/report_protocol.hpp" -#include "zephyr/sys/printk.h" +#include +#include +#if __has_include() + #include +#endif extern "C" void UsbProtocolHandler(const uint8_t *GenericHidOutBuffer, uint8_t *GenericHidInBuffer); @@ -40,9 +42,11 @@ void command_app::set_report(hid::report::type type, const std::span) printk("Command app failed to send report with: %d\n", std::bit_cast(err)); +#endif } } diff --git a/right/src/hid/config.h b/right/src/hid/config.h deleted file mode 100644 index 1063fe40a..000000000 --- a/right/src/hid/config.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __HID_CONFIG_HEADER__ -#define __HID_CONFIG_HEADER__ - - -// Includes: - - #include - #include - #include - -// Typedefs: - - typedef enum - { - Rollover_NKey = 0, - Rollover_6Key = 1, - } rollover_t; - - typedef enum - { - Hid_Empty = 0, - Hid_NoGamepad, - Hid_Full, - } hid_config_t; - -// Variables: - -// Functions: - - rollover_t HID_GetKeyboardRollover(void); - void HID_SetKeyboardRollover(rollover_t mode); - void HID_SetGamepadActive(bool active); - bool HID_GetGamepadActive(void); - void HOGP_Enable(void); - void HOGP_Disable(void); - void USB_Enable(void); - void USB_SetSerialNumber(uint32_t serialNumber); - void USB_RemoteWakeup(void); - -#endif // __HID_CONFIG_HEADER__ diff --git a/right/src/hid/controls_app.cpp b/right/src/hid/controls_app.cpp index e49f9748d..ba9e18efb 100644 --- a/right/src/hid/controls_app.cpp +++ b/right/src/hid/controls_app.cpp @@ -16,11 +16,35 @@ controls_app &controls_app::ble_handle() void controls_app::start(hid::protocol prot) { - // TODO start handling controls events - report_buffer_ = {}; + report_buffer_.reset(); } -void controls_app::set_report_state(const controls_report_base<0> &data) +int controls_app::send_report(const hid_controls_report_t &report) { - send({data.data(), sizeof(data)}); + auto &buf = report_buffer_[report_buffer_.active_side()]; + buf.data = report; + auto result = application::send_report( + std::span(reinterpret_cast(&buf), sizeof(buf))); + if (result == hid::result::ok) { + report_buffer_.swap_sides(); + } + return result.to_int(); +} + +void controls_app::in_report_sent(const std::span &data) +{ + Hid_ControlsReportSentCallback((this == &usb_handle()) ? HID_TRANSPORT_USB : HID_TRANSPORT_BLE); +} + +void controls_app::get_report(hid::report::selector select, const std::span &buffer) +{ + if (select != controls_report::selector()) { + return; + } + + // copy to buffer to avoid overwriting data in transit + auto &report = report_buffer_[report_buffer_.inactive_side()]; + assert(buffer.size() >= sizeof(report)); + memcpy(buffer.data(), &report, sizeof(report)); + application::send_report(buffer.subspan(0, sizeof(report))); } diff --git a/right/src/hid/controls_app.hpp b/right/src/hid/controls_app.hpp index 542890fb4..2fc4a2ac7 100644 --- a/right/src/hid/controls_app.hpp +++ b/right/src/hid/controls_app.hpp @@ -1,45 +1,47 @@ #ifndef __CONTROLS_APP_HEADER__ #define __CONTROLS_APP_HEADER__ -#include "app_base.hpp" -#include "hid/page/consumer.hpp" -#include "hid/page/generic_desktop.hpp" -#include "hid/page/telephony.hpp" -#include "hid/report_array.hpp" -#include "report_ids.h" +extern "C" { +#include "hid/controls_report.h" +#include "hid/report_ids.h" +#include "hid/transport.h" +} +#include "double_buffer.hpp" +#include +#include +#include +#include +#include using system_code = hid::page::generic_desktop; using consumer_code = hid::page::consumer; -using telephony_code = hid::page::telephony; -class controls_app : public app_base { - static constexpr size_t CONSUMER_CODE_COUNT = 2; - static constexpr size_t SYSTEM_CODE_COUNT = 2; - static constexpr size_t TELEPHONY_CODE_COUNT = 2; +class controls_app : public hid::application { + static constexpr size_t CONSUMER_CODE_COUNT = HID_CONTROLS_MAX_CONSUMER_KEYS; + static constexpr size_t SYSTEM_CODE_COUNT = HID_CONTROLS_MAX_SYSTEM_KEYS; public: template struct controls_report_base : public hid::report::base { - hid::report_array consumer_codes{}; - hid::report_array system_codes{}; - hid::report_array telephony_codes{}; - - constexpr controls_report_base() = default; bool operator==(const controls_report_base &other) const = default; bool operator!=(const controls_report_base &other) const = default; +#if 1 + hid_controls_report_t data{}; +#else + hid::report_array consumer_codes{}; + hid::report_array system_codes{}; + bool set_code(system_code c, bool value = true) { return system_codes.set(c, value); } bool test(system_code c) const { return system_codes.test(c); } bool set_code(consumer_code c, bool value = true) { return consumer_codes.set(c, value); } bool test(consumer_code c) const { return consumer_codes.test(c); } - bool set_code(telephony_code c, bool value = true) { return telephony_codes.set(c, value); } - bool test(telephony_code c) const { return telephony_codes.test(c); } +#endif }; static constexpr auto report_desc() { - using namespace hid; using namespace hid::page; using namespace hid::rdf; @@ -56,16 +58,10 @@ class controls_app : public app_base { usage_extended_limits(nullusage, static_cast(get_info().max_usage_id)), input::array(), - report_size(sizeof(hid::le_uint16_t) * 8), + report_size(sizeof(uint8_t) * 8), report_count(SYSTEM_CODE_COUNT), - logical_limits<1, 2>(0, get_info().max_usage_id), + logical_limits<1, 1>(0, get_info().max_usage_id), usage_extended_limits(nullusage, static_cast(get_info().max_usage_id)), - input::array(), - - report_size(sizeof(hid::le_uint16_t) * 8), - report_count(TELEPHONY_CODE_COUNT), - logical_limits<1, 2>(0, get_info().max_usage_id), - usage_extended_limits(nullusage, static_cast(get_info().max_usage_id)), input::array() ) ); @@ -77,15 +73,21 @@ class controls_app : public app_base { static controls_app &ble_handle(); #endif - void set_report_state(const controls_report_base<0> &data); + int send_report(const hid_controls_report_t &report); private: - controls_app() : app_base(this, report_buffer_) {} + controls_app() : hid::application(hid::report_protocol::from_descriptor()) {} void start(hid::protocol prot) override; + void get_report(hid::report::selector select, const std::span &buffer) override; + void set_report(hid::report::type type, const std::span &data) override + { + // No OUTPUT or FEATURE reports are used + } + void in_report_sent(const std::span &data) override; using controls_report = controls_report_base; - C2USB_USB_TRANSFER_ALIGN(controls_report, report_buffer_) {}; + double_buffer report_buffer_{}; }; using controls_buffer = controls_app::controls_report_base<0>; diff --git a/right/src/hid/controls_report.c b/right/src/hid/controls_report.c new file mode 100644 index 000000000..3d3f129cf --- /dev/null +++ b/right/src/hid/controls_report.c @@ -0,0 +1,111 @@ +#include "hid/controls_report.h" +#include +#include "utils.h" + +void ControlsReport_MergeReports( + const hid_controls_report_t *sourceReport, hid_controls_report_t *targetReport) +{ + uint8_t idx, i = 0; + /* find empty position */ + for (idx = 0; idx < UTILS_ARRAY_SIZE(targetReport->consumer); idx++) { + if (targetReport->consumer[idx] == 0) { + break; + } + } + /* copy into empty positions */ + while ((i < UTILS_ARRAY_SIZE(sourceReport->consumer)) && (sourceReport->consumer[i] != 0) && + (idx < UTILS_ARRAY_SIZE(targetReport->consumer))) { + targetReport->consumer[idx++] = sourceReport->consumer[i++]; + } + + for (idx = 0; idx < UTILS_ARRAY_SIZE(targetReport->system); idx++) { + if (targetReport->system[idx] == 0) { + break; + } + } + while ((i < UTILS_ARRAY_SIZE(sourceReport->system)) && (sourceReport->system[i] != 0) && + (idx < UTILS_ARRAY_SIZE(targetReport->system))) { + targetReport->system[idx++] = sourceReport->system[i++]; + } +} + +bool ControlsReport_AddConsumerUsage(hid_controls_report_t *report, uint16_t scancode) +{ + if (scancode == 0) { + return true; + } + for (uint8_t i = 0; i < UTILS_ARRAY_SIZE(report->consumer); i++) { + if (report->consumer[i] == 0) { + report->consumer[i] = scancode; + return true; + } + } + return false; +} + +bool ControlsReport_RemoveConsumerUsage(hid_controls_report_t *report, uint16_t scancode) +{ + if (scancode == 0) { + return false; + } + for (uint8_t i = 0; i < UTILS_ARRAY_SIZE(report->consumer); i++) { + if (report->consumer[i] == scancode) { + report->consumer[i] = 0; + return true; + } + } + return false; +} + +bool ControlsReport_AddSystemUsage(hid_controls_report_t *report, uint8_t scancode) +{ + if (scancode == 0) { + return true; + } + for (uint8_t i = 0; i < UTILS_ARRAY_SIZE(report->system); i++) { + if (report->system[i] == 0) { + report->system[i] = scancode; + return true; + } + } + return false; +} + +bool ControlsReport_RemoveSystemUsage(hid_controls_report_t *report, uint8_t scancode) +{ + if (scancode == 0) { + return true; + } + for (uint8_t i = 0; i < UTILS_ARRAY_SIZE(report->system); i++) { + if (report->system[i] == scancode) { + report->system[i] = 0; + return true; + } + } + return false; +} + +bool ControlsReport_ContainsConsumerUsage(const hid_controls_report_t *report, uint16_t scancode) +{ + for (uint8_t i = 0; i < UTILS_ARRAY_SIZE(report->consumer); i++) { + if (report->consumer[i] == scancode) { + return true; + } + } + return false; +} + +bool ControlsReport_ContainsSystemUsage(const hid_controls_report_t *report, uint8_t scancode) +{ + for (uint8_t i = 0; i < UTILS_ARRAY_SIZE(report->system); i++) { + if (report->system[i] == scancode) { + return true; + } + } + return false; +} + +bool ControlsReport_HasChanges(const hid_controls_report_t buffer[2]) +{ + return memcmp(&buffer[0], &buffer[1], sizeof(hid_controls_report_t)) != 0; +} diff --git a/right/src/hid/controls_report.h b/right/src/hid/controls_report.h new file mode 100644 index 000000000..c43ae3579 --- /dev/null +++ b/right/src/hid/controls_report.h @@ -0,0 +1,33 @@ +#ifndef __HID_CONTROLS_REPORT_H__ +#define __HID_CONTROLS_REPORT_H__ + +#include "arduino_hid/SystemAPI.h" +#include "attributes.h" +#include +#include +#include + +#define HID_CONTROLS_MAX_CONSUMER_KEYS 4 +#define HID_CONTROLS_MAX_SYSTEM_KEYS 2 + +#define HID_CONTROLS_MIN_SYSTEM_USAGE SYSTEM_POWER_DOWN +#define HID_CONTROLS_MAX_SYSTEM_USAGE SYSTEM_WAKE_UP + +typedef struct { + uint16_t consumer[HID_CONTROLS_MAX_CONSUMER_KEYS]; + uint8_t system[HID_CONTROLS_MAX_SYSTEM_KEYS]; +} ATTR_PACKED hid_controls_report_t; + +void ControlsReport_MergeReports( + const hid_controls_report_t *sourceReport, hid_controls_report_t *targetReport); +bool ControlsReport_AddConsumerUsage(hid_controls_report_t *report, uint16_t scancode); +bool ControlsReport_RemoveConsumerUsage(hid_controls_report_t *report, uint16_t scancode); +bool ControlsReport_AddSystemUsage(hid_controls_report_t *report, uint8_t scancode); +bool ControlsReport_RemoveSystemUsage(hid_controls_report_t *report, uint8_t scancode); +bool ControlsReport_ContainsConsumerUsage( + const hid_controls_report_t *report, uint16_t scancode); +bool ControlsReport_ContainsSystemUsage( + const hid_controls_report_t *report, uint8_t scancode); +bool ControlsReport_HasChanges(const hid_controls_report_t buffer[2]); + +#endif // __HID_CONTROLS_REPORT_H__ diff --git a/right/src/hid/gamepad_app.cpp b/right/src/hid/gamepad_app.cpp deleted file mode 100644 index f91c956db..000000000 --- a/right/src/hid/gamepad_app.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "gamepad_app.hpp" - -gamepad_app &gamepad_app::usb_handle() -{ - static gamepad_app app{}; - return app; -} -#if DEVICE_IS_UHK80_RIGHT -gamepad_app &gamepad_app::ble_handle() -{ - static gamepad_app ble_app{}; - return ble_app; -} -#endif - -void gamepad_app::start(hid::protocol prot) -{ - // TODO start handling gamepad events - report_buffer_.reset(); - if (prot != hid::protocol::REPORT) { - report_buffer_[0].id = 0; - report_buffer_[1].id = 0; - } -} - -void gamepad_app::stop() -{ - // TODO stop handling gamepad events -} - -void gamepad_app::set_report_state(const gamepad_report &data) -{ - auto buf_idx = report_buffer_.active_side(); - auto &report = report_buffer_[buf_idx]; - report.buttons = data.buttons; - report.left = data.left; - report.right = data.right; - report.left_trigger = data.left_trigger; - report.right_trigger = data.right_trigger; - send_buffer(buf_idx); -} - -void gamepad_app::send_buffer(uint8_t buf_idx) -{ - if (!report_buffer_.differs()) { - return; - } - if (send_report(&report_buffer_[buf_idx]) == hid::result::ok) { - report_buffer_.compare_swap_copy(buf_idx); - } -} - -void gamepad_app::in_report_sent(const std::span &data) -{ - if (data.front() != report_ids::IN_GAMEPAD) { - return; - } - auto buf_idx = report_buffer_.indexof(data.data()); - if (!report_buffer_.compare_swap_copy(buf_idx)) { - send_buffer(1 - buf_idx); - } -} - -void gamepad_app::get_report(hid::report::selector select, const std::span &buffer) -{ - if (select != gamepad_report::selector()) { - return; - } - // copy to buffer to avoid overwriting data in transit - auto &report = report_buffer_[report_buffer_.inactive_side()]; - assert(buffer.size() >= sizeof(report)); - memcpy(buffer.data(), report.data(), sizeof(report)); - send_report(buffer.subspan(0, sizeof(report))); -} diff --git a/right/src/hid/gamepad_app.hpp b/right/src/hid/gamepad_app.hpp deleted file mode 100644 index 16e4f4107..000000000 --- a/right/src/hid/gamepad_app.hpp +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef __GAMEPAD_APP_HEADER__ -#define __GAMEPAD_APP_HEADER__ - -#include "double_buffer.hpp" -#include "hid/application.hpp" -#include "hid/page/button.hpp" -#include "hid/page/generic_desktop.hpp" -#include "hid/rdf/descriptor.hpp" -#include "hid/report_protocol.hpp" -#include "report_ids.h" - -enum class gamepad_button { - UP = 0, - DOWN = 1, - LEFT = 2, - RIGHT = 3, - START = 4, - BACK = 5, - LS = 6, - RS = 7, - LB = 8, - RB = 9, - HOME = 10, - A = 12, - B = 13, - X = 14, - Y = 15 -}; - -class gamepad_app : public hid::application { - gamepad_app() : application(report_protocol()) {} - - public: - static constexpr auto report_desc() - { - using namespace hid::page; - using namespace hid::rdf; - - // clang-format off - // translate XBOX360 report mapping to HID as much as possible - return descriptor( - usage_page(), - usage(generic_desktop::GAMEPAD), - collection::application( - // Report ID (0, which isn't valid, mark it as reserved) - report_id(report_ids::IN_GAMEPAD), - // Report size - input::padding(8), - - // Buttons p1 - usage_page