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/.github/workflows/ci.yml b/.github/workflows/ci.yml index 271868745..7c2757e45 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 @@ -83,7 +83,9 @@ jobs: uses: actions/upload-artifact@v4 with: name: firmware - path: firmware/scripts/uhk-firmware-*.tar.gz + path: | + firmware/scripts/uhk-firmware-*.tar.gz + firmware/right/build/v2-release/uhk-60-right.elf compression-level: 0 retention-days: 90 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..d80f88356 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, @@ -217,12 +217,10 @@ On a first try, this error might manifest: > Could not start GDB. Check that the file exists, and it can be manually started. Error: Error: spawn $env{ARM_GCC_DIR}/bin/arm-none-eabi-gdb ENOENT -There are two problems to solve: -1. The arm-none-eabi package doesn't ship with gdb by default. +This is due to the arm-none-eabi apt package not shipping with gdb by default. You can follow [this guide](https://interrupt.memfault.com/blog/installing-gdb#binaries-from-arm) to get a full toolchain installed. -2. The extension doesn't expand the environment variable, so you'll need to modify the `.vscode/mcuxpresso-tools.json` file, -to have a hardcoded `toolchainPath` variable. (Don't push this change into the repository, obviously.) + ### Releasing 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/build.sh b/build.sh index a8ab2cf1a..a4cfc30b7 100755 --- a/build.sh +++ b/build.sh @@ -158,17 +158,23 @@ function dealiasDeviceZephyr() { } function dealiasDeviceMcux() { + if [ "$DEBUG" == "1" ]; then + BUILD_TYPE="debug" + else + BUILD_TYPE="release" + fi + case $DEVICE in uhk-60v1-right|rightv1|right) DEVICE="uhk-60v1-right" - VARIANT="v1-release" + VARIANT="v1-$BUILD_TYPE" BUILD_DIR="right/build/$VARIANT" DEVICE_DIR="right" USBDEVICEARG="--vid=0x37a8 --pid=1" ;; uhk-60v2-right|rightv2|right) DEVICE="uhk-60v2-right" - VARIANT="v2-release" + VARIANT="v2-$BUILD_TYPE" BUILD_DIR="right/build/$VARIANT" DEVICE_DIR="right" USBDEVICEARG="--vid=0x37a8 --pid=3" @@ -315,33 +321,22 @@ function performZephyrAction() { case $ACTION in build) # reference version of the build process is to be found in scripts/make-release.mjs - nrfutil toolchain-manager launch --shell --ncs-version $NCS_VERSION << END - unset PYTHONPATH - unset PYTHONHOME - ZEPHYR_TOOLCHAIN_VARIANT=zephyr west build \ - --build-dir "$ROOT/device/build/$DEVICE" "$ROOT/device" \ - --pristine \ - -- \ - --preset $DEVICE - exit $? -END + ZEPHYR_TOOLCHAIN_VARIANT=zephyr west build \ + --build-dir "$ROOT/device/build/$DEVICE" "$ROOT/device" \ + --pristine \ + -- \ + --preset $DEVICE exitOnFail $? createCentralCompileCommands ;; make) - nrfutil toolchain-manager launch --shell --ncs-version $NCS_VERSION << END - west build --build-dir $ROOT/device/build/$DEVICE device - exit $? -END + west build --build-dir $ROOT/device/build/$DEVICE device exitOnFail $? ;; flash) export BUILD_DIR="$ROOT/device/build/$DEVICE" export DEVICE="$DEVICE" - nrfutil toolchain-manager launch --shell --ncs-version $NCS_VERSION << END - west flash --softreset --build-dir $BUILD_DIR $DEVICEARG $OTHER_ARGS - exit $? -END + west flash --softreset --build-dir $BUILD_DIR $DEVICEARG $OTHER_ARGS exitOnFail $? ;; flashUsb) diff --git a/device/CMakePresets.json b/device/CMakePresets.json index 859b0966b..93c5703ba 100644 --- a/device/CMakePresets.json +++ b/device/CMakePresets.json @@ -1,93 +1,75 @@ { - "version": 2, + "version": 4, "cmakeMinimumRequired": { "major": 3, "minor": 20 }, "configurePresets": [ { - "name": "uhk-80-right", - "displayName": "Build for UHK 80 right", + "name": "defaults", + "hidden": true, "generator": "Ninja", - "binaryDir": "${sourceDir}/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": "${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" + "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", + "inherits": "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.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" + "CONF_FILE": "${fileDir}/prj.conf" } }, { "name": "uhk-80-left", "displayName": "Build for UHK 80 left", - "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-80-left", + "inherits": "defaults", "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" + "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", + "inherits": "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.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" + "CONF_FILE": "${fileDir}/prj.conf" } }, { "name": "uhk-dongle", "displayName": "Build for UHK dongle", - "generator": "Ninja", - "binaryDir": "${sourceDir}/build/uhk-dongle", + "inherits": "defaults", "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" + "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", + "inherits": "uhk-dongle", "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" + "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/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 ebdcc67ef..172a88a6d 100644 --- a/device/src/bt_conn.c +++ b/device/src/bt_conn.c @@ -22,11 +22,11 @@ #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" #include "bt_manager.h" +#include "hid/transport.h" #include #include "config_manager.h" #include "zephyr/kernel.h" @@ -551,6 +551,8 @@ static void connectHid(struct bt_conn *conn, connection_id_t connectionId, conne LOG_INF("Established HID connection with %s", GetPeerStringByConn(conn)); Connections_SetState(connectionId, ConnectionState_Ready); BtManager_StartScanningAndAdvertisingAsync(false, "connectHid"); + + EventScheduler_Reschedule(Timer_GetCurrentTime() + 10000, EventSchedulerEvent_KickHid, "HID health kick"); } #define BT_UUID_NUS_VAL BT_UUID_128_ENCODE(0x6e400001, 0xb5a3, 0xf393, 0xe0a9, 0xe50e24dcca9e) @@ -619,7 +621,9 @@ static void connected(struct bt_conn *conn, uint8_t err) { // Without this, linux pairing fails, because tiny 27 byte packets // exhaust acl buffers easily enableDataLengthExtension(conn); - requestMtuExchange(conn); + if (!DEBUG_STRESS_GATT) { + requestMtuExchange(conn); + } if (err) { LOG_WRN("Failed to connect (in connected cb) to %s, err %u", GetPeerStringByConn(conn), err); @@ -942,6 +946,18 @@ void BtConn_DisconnectOne(connection_id_t connectionId) { safeDisconnect(conn, BT_REASON_NOT_SELECTED); } +void BtConn_KickHid(void) { +#if DEVICE_IS_UHK80_RIGHT + LOG_INF("Kicking HID connections to check if HOGP is healthy."); + if (HOGP_HealthCheck()) { + LOG_ERR("BtConn_KickHid: HOGP health check failed, disconnecting hids.\n"); + disconnectAllHids(); + } else { + LOG_INF("BtConn_KickHid: the connection looks fine.\n"); + } +#endif +} + static void bt_foreach_conn_cb_disconnect_unidentified(struct bt_conn *conn, void *user_data) { peer_t* peer = getPeerByConn(conn); if (!peer) { diff --git a/device/src/bt_conn.h b/device/src/bt_conn.h index 90ef605c0..bada16b3d 100644 --- a/device/src/bt_conn.h +++ b/device/src/bt_conn.h @@ -80,6 +80,7 @@ typedef enum { void BtConn_MakeSpaceForHid(); uint8_t BtConn_ConnectedHidCount(const bt_addr_le_t* excludeAddr); + void BtConn_KickHid(void); static inline bool BtAddrEq(const bt_addr_le_t *a, const bt_addr_le_t *b) { return 0 == memcmp(a->a.val, b->a.val, sizeof(a->a.val)); diff --git a/device/src/bt_health.c b/device/src/bt_health.c index 175a332ac..01bda1aa2 100644 --- a/device/src/bt_health.c +++ b/device/src/bt_health.c @@ -9,6 +9,7 @@ #include #include "bt_advertise.h" #include "connections.h" +#include "hid/transport.h" LOG_MODULE_DECLARE(Bt); @@ -36,6 +37,11 @@ void Bt_HealthCheck(log_target_t targetOnError, bool isError) { } } + // 2. HOGP health check + if (DEVICE_IS_UHK80_RIGHT) { + HOGP_HealthCheck(); + } + // 3. Check bond count int bond_count = 0; bt_foreach_bond(BT_ID_DEFAULT, bond_count_cb, &bond_count); diff --git a/device/src/bt_manager.c b/device/src/bt_manager.c index bd8b386fb..3fd160d4b 100644 --- a/device/src/bt_manager.c +++ b/device/src/bt_manager.c @@ -4,7 +4,7 @@ #include "device.h" #include "device_state.h" #include "event_scheduler.h" -#include "usb/usb.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 a6cdc8f57..7cf7251df 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/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 f3af375e6..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 "usb/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 4a77ac7c1..ba55566cc 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/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 fa3a67723..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 "usb/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 18b4e0884..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" @@ -16,7 +15,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 f4651d645..ae5c5a6f5 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,17 +17,18 @@ #include "host_connection.h" #include "thread_stats.h" #include "trace.h" -#include "usb_compatibility.h" #include "mouse_keys.h" #include "config_manager.h" #include #include #include +#include "bt_health.h" #include "connections.h" #include "logger_priority.h" #include "pin_wiring.h" #include "device.h" #include "logger.h" +#include "hid/transport.h" #include "shell_backend_usb.h" #include "stubs.h" #include "test_suite/test_suite.h" @@ -162,19 +162,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; } @@ -336,6 +326,12 @@ static int cmd_uhk_irqs(const struct shell *shell, size_t argc, char *argv[]) { return 0; } +static int cmd_uhk_healthcheck(const struct shell *shell, size_t argc, char *argv[]) +{ + Bt_HealthCheck(LogTarget_Uart, false); + return 0; +} + static int cmd_uhk_mouseMultipliers(const struct shell *shell, size_t argc, char *argv[]) { int16_t horizontalScrollMultiplier = HorizontalScrollMultiplier(); int16_t verticalScrollMultiplier = VerticalScrollMultiplier(); @@ -515,10 +511,10 @@ 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), + SHELL_CMD_ARG(healthcheck, NULL, "run BT and HOGP health check", cmd_uhk_healthcheck, 1, 0), SHELL_CMD_ARG(threads, NULL, "list thread statistics", cmd_uhk_threads, 1, 0), SHELL_CMD_ARG(trace, NULL, "lists minimalistic event trace", cmd_uhk_trace, 1, 0), SHELL_CMD_ARG(mouseMultipliers, NULL, "print mouse multipliers", cmd_uhk_mouseMultipliers, 1, 0), diff --git a/device/src/state_sync.c b/device/src/state_sync.c index 234019623..3dda2b685 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/transport.h" #include #include #include "peripherals/merge_sensor.h" diff --git a/device/src/usb/app_base.cpp b/device/src/usb/app_base.cpp deleted file mode 100644 index 325278740..000000000 --- a/device/src/usb/app_base.cpp +++ /dev/null @@ -1,53 +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(); - const char* err = "unknown"; - if (result == hid::result::INVALID) { - err = "invalid"; - } else if (result == hid::result::NO_TRANSPORT) { - err = "no transport"; - } else if (result == hid::result::BUSY) { - err = "busy"; - } else if (result == hid::result::NO_CONNECTION) { - err = "no connection"; - } else if (result == hid::result::NO_MEMORY) { - err = "no memory"; - } - printk("Send fail: %s\n", err); - } -} - -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/device/src/usb/app_base.hpp b/device/src/usb/app_base.hpp deleted file mode 100644 index 8577842d5..000000000 --- a/device/src/usb/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/device/src/usb/controls_app.cpp b/device/src/usb/controls_app.cpp deleted file mode 100644 index e49f9748d..000000000 --- a/device/src/usb/controls_app.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "controls_app.hpp" - -controls_app &controls_app::usb_handle() -{ - static controls_app app{}; - return app; -} - -#if DEVICE_IS_UHK80_RIGHT -controls_app &controls_app::ble_handle() -{ - static controls_app ble_app{}; - return ble_app; -} -#endif - -void controls_app::start(hid::protocol prot) -{ - // TODO start handling controls events - report_buffer_ = {}; -} - -void controls_app::set_report_state(const controls_report_base<0> &data) -{ - send({data.data(), sizeof(data)}); -} diff --git a/device/src/usb/gamepad_app.cpp b/device/src/usb/gamepad_app.cpp deleted file mode 100644 index f91c956db..000000000 --- a/device/src/usb/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/device/src/usb/gamepad_app.hpp b/device/src/usb/gamepad_app.hpp deleted file mode 100644 index 16e4f4107..000000000 --- a/device/src/usb/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