From 6d9be98b9124cb8f9c38966be1a8b13508adbf7e Mon Sep 17 00:00:00 2001 From: Gary Likovic <81448614+garylikovic@users.noreply.github.com> Date: Wed, 30 Jul 2025 14:55:00 -0400 Subject: [PATCH 01/42] Add files via upload Added IDs for Wii U Pro Controller, 8BitDo Ultimate Bluetooth Controller, Switch 1 Joy cons (Left and Right) and Ouya Gen 1 Controller. --- Firmware/RP2040/src/USBHost/HardwareIDs.h | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Firmware/RP2040/src/USBHost/HardwareIDs.h b/Firmware/RP2040/src/USBHost/HardwareIDs.h index b02b7941..ccb924b9 100644 --- a/Firmware/RP2040/src/USBHost/HardwareIDs.h +++ b/Firmware/RP2040/src/USBHost/HardwareIDs.h @@ -67,6 +67,34 @@ static const HardwareID N64_IDS[] = {0x0079, 0x0006} // Retrolink N64 USB gamepad }; +static const HardwareID WIIU_PRO_IDS[] = +{ + {0x057E, 0x0330} // Wii U Pro Wireless Controller +}; + +static const HardwareID OUYA_IDS[] = +{ + {0x2836, 0x0001} // OUYA Controller +}; + +static const HardwareID Bit_Ult_IDS[] = +{ + {0x057E, 0x2009} // 8Bit Ultimate Bluetooth Controller +}; + +static const HardwareID Wii_IDS[] = +{ + {0x057e, 0x0306} // Wii Motion Plus Controller + +}; + +static const HardwareID Switch_Joycon_IDS[] = +{ + {0x057e, 0x2007} // Switch Joycon (R) + {0x057e, 0x2006} // Switch Joycon (L) + +}; + struct HostTypeMap { const HardwareID* ids; @@ -84,6 +112,10 @@ static const HostTypeMap HOST_TYPE_MAP[] = { SWITCH_PRO_IDS, sizeof(SWITCH_PRO_IDS) / sizeof(HardwareID), HostDriverType::SWITCH_PRO }, { PSCLASSIC_IDS, sizeof(PSCLASSIC_IDS) / sizeof(HardwareID), HostDriverType::PSCLASSIC }, { N64_IDS, sizeof(N64_IDS) / sizeof(HardwareID), HostDriverType::N64 }, + { WIIU_PRO_IDS, sizeof(WIIU_PRO_IDS) / sizeof(HardwareID), HostDriverType::WIIUPRO }, + { Bit_Ult_IDS, sizeof(Bit_Ult_IDS) / sizeof(HardwareID), HostDriverType::Bit_Ult }, + { Wii_IDS, sizeof(Wii_IDS) / sizeof(HardwareID), HostDriverType::Wii }, + { OUYA_IDS, sizeof(OUYA_IDS) / sizeof(HardwareID), HostDriverType::OUYA }, }; #endif // _HW_ID_H_ \ No newline at end of file From 93dd1bd769e4d2a891486657fcce386342996bac Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Fri, 6 Feb 2026 09:56:31 -0500 Subject: [PATCH 02/42] Add files via upload Fixed Wii and Wii U controller support, RB LB and RT LT work now for both controllers --- Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 132 +++++++++++++++++--- 1 file changed, 117 insertions(+), 15 deletions(-) diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index 836811e5..83df3b64 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -46,6 +47,27 @@ bool any_connected() return false; } +bool is_wii_controller_connected(uint8_t idx) +{ + if (idx >= MAX_GAMEPADS) { + return false; + } + uni_hid_device_t* bp_device = uni_hid_device_get_instance_for_idx(idx); + return (bp_device != nullptr && bp_device->controller_type == CONTROLLER_TYPE_WiiController); +} + +bool any_wii_controller_connected() +{ + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) + { + if (bt_devices_[i].connected && is_wii_controller_connected(i)) + { + return true; + } + } + return false; +} + //This solves a function pointer/crash issue with bluepad32 void set_rumble(uni_hid_device_t* bp_device, uint16_t length, uint8_t rumble_l, uint8_t rumble_r) { @@ -132,9 +154,14 @@ static void init_complete_cb(void) { } static uni_error_t device_discovered_cb(bd_addr_t addr, const char* name, uint16_t cod, uint8_t rssi) { - if (!((cod & UNI_BT_COD_MINOR_MASK) & UNI_BT_COD_MINOR_GAMEPAD)) { + uint8_t minor = cod & UNI_BT_COD_MINOR_MASK; + + if (!(minor & (UNI_BT_COD_MINOR_GAMEPAD | + UNI_BT_COD_MINOR_JOYSTICK | + UNI_BT_COD_MINOR_REMOTE_CONTROL))) { return UNI_ERROR_IGNORE_DEVICE; } + return UNI_ERROR_SUCCESS; } @@ -190,6 +217,11 @@ static void oob_event_cb(uni_platform_oob_event_t event, void* data) { return; } +// Set to 1 to print all Bluepad32 controller inputs to UART (only when state changes) +#ifndef BLUEPAD32_UART_LOG_INPUT +#define BLUEPAD32_UART_LOG_INPUT 1 +#endif + static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* controller) { static uni_gamepad_t prev_uni_gp[MAX_GAMEPADS] = {}; @@ -199,6 +231,19 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr uni_gamepad_t *uni_gp = &controller->gamepad; int idx = uni_hid_device_get_idx_for_instance(device); + +#if BLUEPAD32_UART_LOG_INPUT + { + bool changed = std::memcmp(uni_gp, &prev_uni_gp[idx], sizeof(uni_gamepad_t)) != 0; + if (changed) { + printf("[BP32 idx=%d] dpad=0x%02x btns=0x%04x misc=0x%02x brake=%u throttle=%u " + "Lx=%d Ly=%d Rx=%d Ry=%d\n", + idx, (unsigned)uni_gp->dpad, (unsigned)uni_gp->buttons, (unsigned)uni_gp->misc_buttons, + (unsigned)uni_gp->brake, (unsigned)uni_gp->throttle, + (int)uni_gp->axis_x, (int)uni_gp->axis_y, (int)uni_gp->axis_rx, (int)uni_gp->axis_ry); + } + } +#endif Gamepad* gamepad = bt_devices_[idx].gamepad; Gamepad::PadIn gp_in; @@ -233,25 +278,82 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr break; } - if (uni_gp->buttons & BUTTON_A) gp_in.buttons |= gamepad->MAP_BUTTON_A; - if (uni_gp->buttons & BUTTON_B) gp_in.buttons |= gamepad->MAP_BUTTON_B; - if (uni_gp->buttons & BUTTON_X) gp_in.buttons |= gamepad->MAP_BUTTON_X; - if (uni_gp->buttons & BUTTON_Y) gp_in.buttons |= gamepad->MAP_BUTTON_Y; - if (uni_gp->buttons & BUTTON_SHOULDER_L) gp_in.buttons |= gamepad->MAP_BUTTON_LB; - if (uni_gp->buttons & BUTTON_SHOULDER_R) gp_in.buttons |= gamepad->MAP_BUTTON_RB; - if (uni_gp->buttons & BUTTON_THUMB_L) gp_in.buttons |= gamepad->MAP_BUTTON_L3; - if (uni_gp->buttons & BUTTON_THUMB_R) gp_in.buttons |= gamepad->MAP_BUTTON_R3; - if (uni_gp->misc_buttons & MISC_BUTTON_BACK) gp_in.buttons |= gamepad->MAP_BUTTON_BACK; - if (uni_gp->misc_buttons & MISC_BUTTON_START) gp_in.buttons |= gamepad->MAP_BUTTON_START; - if (uni_gp->misc_buttons & MISC_BUTTON_SYSTEM) gp_in.buttons |= gamepad->MAP_BUTTON_SYS; - - gp_in.trigger_l = gamepad->scale_trigger_l<10>(static_cast(uni_gp->brake)); - gp_in.trigger_r = gamepad->scale_trigger_r<10>(static_cast(uni_gp->throttle)); + if (is_wii_controller_connected(idx)) { + if (uni_gp->buttons & BUTTON_A) gp_in.buttons |= gamepad->MAP_BUTTON_A; + if (uni_gp->buttons & BUTTON_B) gp_in.buttons |= gamepad->MAP_BUTTON_B; + if (uni_gp->buttons & BUTTON_X) gp_in.buttons |= gamepad->MAP_BUTTON_X; + if (uni_gp->buttons & BUTTON_Y) gp_in.buttons |= gamepad->MAP_BUTTON_Y; + if (uni_gp->buttons & BUTTON_SHOULDER_L) gp_in.buttons |= gamepad->MAP_BUTTON_LB; + if (uni_gp->buttons & BUTTON_SHOULDER_R) gp_in.buttons |= gamepad->MAP_BUTTON_RB; + //if (uni_gp->buttons & BUTTON_THUMB_L) gp_in.buttons |= gamepad->MAP_BUTTON_L3; + //if (uni_gp->buttons & BUTTON_THUMB_R) gp_in.buttons |= gamepad->MAP_BUTTON_R3; + if (uni_gp->misc_buttons & MISC_BUTTON_BACK) gp_in.buttons |= gamepad->MAP_BUTTON_BACK; + if (uni_gp->misc_buttons & MISC_BUTTON_START) gp_in.buttons |= gamepad->MAP_BUTTON_START; + if (uni_gp->misc_buttons & MISC_BUTTON_SYSTEM) gp_in.buttons |= gamepad->MAP_BUTTON_SYS; + } + else { + if (uni_gp->buttons & BUTTON_A) gp_in.buttons |= gamepad->MAP_BUTTON_A; + if (uni_gp->buttons & BUTTON_B) gp_in.buttons |= gamepad->MAP_BUTTON_B; + if (uni_gp->buttons & BUTTON_X) gp_in.buttons |= gamepad->MAP_BUTTON_X; + if (uni_gp->buttons & BUTTON_Y) gp_in.buttons |= gamepad->MAP_BUTTON_Y; + if (uni_gp->buttons & BUTTON_SHOULDER_L) gp_in.buttons |= gamepad->MAP_BUTTON_LB; + if (uni_gp->buttons & BUTTON_SHOULDER_R) gp_in.buttons |= gamepad->MAP_BUTTON_RB; + if (uni_gp->buttons & BUTTON_THUMB_L) gp_in.buttons |= gamepad->MAP_BUTTON_L3; + if (uni_gp->buttons & BUTTON_THUMB_R) gp_in.buttons |= gamepad->MAP_BUTTON_R3; + if (uni_gp->misc_buttons & MISC_BUTTON_BACK) gp_in.buttons |= gamepad->MAP_BUTTON_BACK; + if (uni_gp->misc_buttons & MISC_BUTTON_START) gp_in.buttons |= gamepad->MAP_BUTTON_START; + if (uni_gp->misc_buttons & MISC_BUTTON_SYSTEM) gp_in.buttons |= gamepad->MAP_BUTTON_SYS; + } + + // Check for disconnect combo: Start+Select for most controllers, L3+R3 for OUYA (no Start/Select) + static uint32_t disconnect_combo_hold_time[MAX_GAMEPADS] = {0}; + bool is_ouya = (device->controller_type == CONTROLLER_TYPE_OUYAController); + bool combo_pressed = is_ouya + ? ((uni_gp->buttons & BUTTON_THUMB_L) && (uni_gp->buttons & BUTTON_THUMB_R)) + : ((uni_gp->misc_buttons & MISC_BUTTON_START) && (uni_gp->misc_buttons & MISC_BUTTON_BACK)); + + if (combo_pressed) { + disconnect_combo_hold_time[idx]++; + // Require combo to be held for ~500ms (assuming ~60Hz callback rate, ~30 frames) + if (disconnect_combo_hold_time[idx] >= 30) { + printf("[BP32] Disconnect combo detected, disconnecting controller %d\n", idx); + uni_hid_device_disconnect(device); + disconnect_combo_hold_time[idx] = 0; + return; // Don't process further input after disconnect + } + } else { + disconnect_combo_hold_time[idx] = 0; + } + + // Prefer analog triggers (brake / throttle) when present, but fall back to + // digital trigger buttons (e.g. Wii U LT / RT) when analog value is zero. + // For Wii controllers: Z button (shoulder) reports brake/throttle, but we only want it to map to LB/RB, not triggers + // So skip trigger mapping when shoulder buttons are pressed on Wii controllers + bool wii_shoulder_pressed = is_wii_controller_connected(idx) && + ((uni_gp->buttons & BUTTON_SHOULDER_L) || (uni_gp->buttons & BUTTON_SHOULDER_R)); + + if (!wii_shoulder_pressed) { + gp_in.trigger_l = gamepad->scale_trigger_l<10>(static_cast(uni_gp->brake)); + gp_in.trigger_r = gamepad->scale_trigger_r<10>(static_cast(uni_gp->throttle)); + + if (gp_in.trigger_l == 0 && (uni_gp->buttons & BUTTON_TRIGGER_L)) { + gp_in.trigger_l = 0xFF; + } + if (gp_in.trigger_r == 0 && (uni_gp->buttons & BUTTON_TRIGGER_R)) { + gp_in.trigger_r = 0xFF; + } + } std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad->scale_joystick_l<10>(uni_gp->axis_x, uni_gp->axis_y); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad->scale_joystick_r<10>(uni_gp->axis_rx, uni_gp->axis_ry); gamepad->set_pad_in(gp_in); + +#if BLUEPAD32_UART_LOG_INPUT + if (idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { + std::memcpy(&prev_uni_gp[idx], uni_gp, sizeof(uni_gamepad_t)); + } +#endif } const uni_property_t* get_property_cb(uni_property_idx_t idx) From 0317bf93b043be422785137bfef7362cf3e7e0fa Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Fri, 6 Feb 2026 10:11:29 -0500 Subject: [PATCH 03/42] Update README for OGX-Mini Fork and new features Updated README to reflect the fork status and added new features for Wii U Pro and Wii Remotes. Changed purchase link to the original creator's store. --- README.md | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3aa52f23..56a9f50f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# OGX-Mini +# OGX-Mini Fork ![OGX-Mini Boards](images/OGX-Mini-github.jpg "OGX-Mini Boards") Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. @@ -37,6 +37,10 @@ Start = Plus (Switch) = Options (Dualsense/DS4) After a new mode is stored, the RP2040 will reset itself so you don't need to unplug it. +## Disconnecting Controllers +For most controllers pressing and holding Start+Select (+/-, etc) for the controller will disconnect it and restart pairing mode. +For the OUYA controller there is no Start+Select, the disconnection combo has been set to L3+R3. + ## Supported devices ### Wired controllers - Original Xbox Duke and S @@ -67,10 +71,22 @@ Note: There are some third party controllers that can change their VID/PID, thes - Switch Pro - Steam - Stadia -- And more +- Wii U Pro +- Wii Remote + - Supported Extensions: + - Gamepad + - Nunchuck + - GameCube Controller +- 8BitDo Ultimate Wireless (Switch layout) Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supported_gamepads/) for a more comprehensive list of supported controllers and Bluetooth pairing instructions. +# Features new to this fork: +Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. +- Wii U Pro controllers are supported fully with working LT and RT +- Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. +- Disconnection Combo has been added: Start+Select for most controllers, L3+R3 for OUYA controllers. + ## Features new to v1.0.0 - Bluetooth functionality for the Pico W, Pico 2 W, and Pico+ESP32. - Web application (connectable via USB or Bluetooth) for configuring deadzones and buttons mappings, supports up to 8 saved profiles. @@ -85,7 +101,7 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte - Analog button support on OG Xbox and PS3. - RGB LED support for RP2040-Zero and Adafruit Feather boards. -## Planned additions +## Planned additions from the original creator - More accurate report parser for unknown HID controllers - Hardware design for internal OG Xbox install - Hardware design for 4 channel RP2040-Zero adapter @@ -97,6 +113,17 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte - Button macros - Rumble settings (intensity, enabled/disable, etc.) +## Planned additions for this fork +- Output to the following consoles: + - GameCube + - Wii U (GameCube controller adapter) + - PS2 + - DreamCast + - NES + - SNES + - Genesis + - Master System + ## Hardware For Pi Pico, RP2040-Zero, 4 channel, and ESP32 configurations, please see the hardware folder for diagrams. @@ -104,7 +131,7 @@ I've designed a PCB for the RP2040-Zero so you can make a small form-factor adap OGX-Mini Boards -If you would like a prebuilt unit, you can purchase one, with cable and Xbox adapter included, from my [**Etsy store**](https://www.etsy.com/listing/1426992904/ogx-mini-controller-adapter-for-original). +If you would like a prebuilt unit, you can purchase one, with cable and Xbox adapter included, from the original creators store: [**Etsy store**](https://www.etsy.com/listing/1426992904/ogx-mini-controller-adapter-for-original). ## Adding supported controllers If your third party controller isn't working, but the original version is listed above, send me the device's VID and PID and I'll add it so it's recognized properly. @@ -140,4 +167,8 @@ Please see the Hardware directory for a diagram showing how to hookup the ESP32 You will need ESP-IDF v5.1, esptool, python3, and git installed. If you use VSCode, you can install the ESP-IDF extension and configure the project for ESP-IDF v5.1, it'll download everything for you and then you just click the build button at the bottom of the window. -When you build with ESP-IDF, Cmake will run a python script that copies the necessary BTStack files into the components directory, this is needed since BTStack isn't configured as an ESP-IDF component when you download it with git. +When you build with ESP-IDF, Cmake will run a python script that copies the necessary BTStack files into the components directory, this is needed since BTStack isn't configured as an ESP-IDF + +# Credit to the original creator [https://wiredopposite.github.io/](https://github.com/wiredopposite/OGX-Mini/tree/master) for the original base of the project! + +component when you download it with git. From 78b191ab4338c0a357f7fdfe60c4d6dc693aee5d Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Fri, 6 Feb 2026 10:13:09 -0500 Subject: [PATCH 04/42] Update repository URL in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 56a9f50f..bf1c4758 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ You can also set ```MAX_GAMEPADS``` which, if greater than one, will only suppor You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. Here's an example on Windows: ``` -git clone --recursive https://github.com/wiredopposite/OGX-Mini.git +git clone --recursive https://github.com/MegaCadeDev/OGX-Mini.git cd OGX-Mini/Firmware/RP2040 cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DOGXM_BOARD=PI_PICOW -DMAX_GAMEPADS=1 cmake --build build From bf05140dd587cc0644b6977c25fef502a9641cc4 Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Fri, 6 Feb 2026 10:15:19 -0500 Subject: [PATCH 05/42] Update README with clearer ESP-IDF build instructions Clarified the installation instructions for ESP-IDF and BTStack. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bf1c4758..a55e0819 100644 --- a/README.md +++ b/README.md @@ -167,8 +167,8 @@ Please see the Hardware directory for a diagram showing how to hookup the ESP32 You will need ESP-IDF v5.1, esptool, python3, and git installed. If you use VSCode, you can install the ESP-IDF extension and configure the project for ESP-IDF v5.1, it'll download everything for you and then you just click the build button at the bottom of the window. -When you build with ESP-IDF, Cmake will run a python script that copies the necessary BTStack files into the components directory, this is needed since BTStack isn't configured as an ESP-IDF +When you build with ESP-IDF, Cmake will run a python script that copies the necessary BTStack files into the components directory, this is needed since BTStack isn't configured as an ESP-IDF component when you download it with git. + # Credit to the original creator [https://wiredopposite.github.io/](https://github.com/wiredopposite/OGX-Mini/tree/master) for the original base of the project! -component when you download it with git. From 02e5911dc28d33a24929719d2253df13be396647 Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:01:01 -0500 Subject: [PATCH 06/42] Update supported controllers list in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a55e0819..a0ae44d1 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. -- Wii U Pro controllers are supported fully with working LT and RT +- Wii U & Switch Pro controllers are supported fully with working LT and RT - Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. - Disconnection Combo has been added: Start+Select for most controllers, L3+R3 for OUYA controllers. From 25d545fb05ed9e775fae72708b62ad3522d017aa Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Sun, 8 Feb 2026 04:34:59 -0500 Subject: [PATCH 07/42] Change repository URL in README Updated repository URL in the cloning instructions. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a0ae44d1..317891bd 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ You can also set ```MAX_GAMEPADS``` which, if greater than one, will only suppor You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. Here's an example on Windows: ``` -git clone --recursive https://github.com/MegaCadeDev/OGX-Mini.git +git clone --recursive https://github.com/MegaCadeDev/OGX-Mini-2026.git cd OGX-Mini/Firmware/RP2040 cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DOGXM_BOARD=PI_PICOW -DMAX_GAMEPADS=1 cmake --build build From 1fc6a784ecc421cb098d2533510cdb6799ab25b4 Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Sun, 8 Feb 2026 04:37:53 -0500 Subject: [PATCH 08/42] Fix directory path in README for cloning repo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 317891bd..a36b0db7 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ You can also set ```MAX_GAMEPADS``` which, if greater than one, will only suppor You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. Here's an example on Windows: ``` git clone --recursive https://github.com/MegaCadeDev/OGX-Mini-2026.git -cd OGX-Mini/Firmware/RP2040 +cd OGX-Mini-2026/Firmware/RP2040 cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DOGXM_BOARD=PI_PICOW -DMAX_GAMEPADS=1 cmake --build build ``` From 13dc57f9a151776faba5312666df30e0bb208d1d Mon Sep 17 00:00:00 2001 From: Gary Date: Sun, 8 Feb 2026 04:48:49 -0500 Subject: [PATCH 09/42] Added Wii U GameCube emulation support for Wii U and Switch --- Firmware/RP2040/CMakeLists.txt | 2 + Firmware/RP2040/src/Board/ogxm_log.cpp | 1 + Firmware/RP2040/src/Descriptors/WiiU.h | 168 ++++++++++++++++++ Firmware/RP2040/src/Gamepad/Gamepad.h | 2 +- .../DeviceDriver/DeviceDriverTypes.h | 1 + .../USBDevice/DeviceDriver/Switch/Switch.cpp | 4 +- .../src/USBDevice/DeviceDriver/WiiU/WiiU.cpp | 165 +++++++++++++++++ .../src/USBDevice/DeviceDriver/WiiU/WiiU.h | 28 +++ .../RP2040/src/USBDevice/DeviceManager.cpp | 17 ++ .../RP2040/src/USBDevice/tud_callbacks.cpp | 3 +- Firmware/RP2040/src/USBHost/HardwareIDs.h | 35 +--- .../HostDriver/SwitchWired/SwitchWired.cpp | 7 +- Firmware/RP2040/src/USBHost/HostManager.h | 15 ++ .../RP2040/src/UserSettings/UserSettings.cpp | 7 +- Firmware/RP2040/src/main.cpp | 11 ++ 15 files changed, 425 insertions(+), 41 deletions(-) create mode 100644 Firmware/RP2040/src/Descriptors/WiiU.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.h diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 291dbf50..36d45e1a 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -63,6 +63,7 @@ set(SOURCES_BOARD ${SRC}/USBDevice/DeviceDriver/PSClassic/PSClassic.cpp ${SRC}/USBDevice/DeviceDriver/PS3/PS3.cpp ${SRC}/USBDevice/DeviceDriver/Switch/Switch.cpp + ${SRC}/USBDevice/DeviceDriver/WiiU/WiiU.cpp ${SRC}/USBDevice/DeviceDriver/XInput/XInput.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/XboxOG_SB.cpp @@ -325,6 +326,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS "UART port: ${UART_PORT}, TX: ${TX_PIN}, RX: ${RX_PIN}") + pico_enable_stdio_usb(${FW_NAME} 0) pico_enable_stdio_uart(${FW_NAME} 1) target_compile_definitions(${FW_NAME} PRIVATE PICO_DEFAULT_UART=${UART_PORT} diff --git a/Firmware/RP2040/src/Board/ogxm_log.cpp b/Firmware/RP2040/src/Board/ogxm_log.cpp index 6bb55c5f..bd2d6b18 100644 --- a/Firmware/RP2040/src/Board/ogxm_log.cpp +++ b/Firmware/RP2040/src/Board/ogxm_log.cpp @@ -24,6 +24,7 @@ std::ostream& operator<<(std::ostream& os, DeviceDriverType type) { case DeviceDriverType::DINPUT: os << "DINPUT"; break; case DeviceDriverType::PSCLASSIC: os << "PSCLASSIC"; break; case DeviceDriverType::SWITCH: os << "SWITCH"; break; + case DeviceDriverType::WIIU: os << "WIIU"; break; case DeviceDriverType::WEBAPP: os << "WEBAPP"; break; case DeviceDriverType::UART_BRIDGE: os << "UART_BRIDGE"; break; default: os << "UNKNOWN"; break; diff --git a/Firmware/RP2040/src/Descriptors/WiiU.h b/Firmware/RP2040/src/Descriptors/WiiU.h new file mode 100644 index 00000000..5c97fd18 --- /dev/null +++ b/Firmware/RP2040/src/Descriptors/WiiU.h @@ -0,0 +1,168 @@ +#ifndef _WIIU_DESCRIPTORS_H_ +#define _WIIU_DESCRIPTORS_H_ + +#include + +#include "tusb.h" + +namespace WiiU +{ + // Wii U GameCube Adapter protocol (same as Dolphin / gc_adapter_read.py) + static constexpr uint8_t HID_REPORT_ID = 0x21; + static constexpr uint8_t INIT_PAYLOAD = 0x13; + static constexpr uint8_t CONTROLLER_PAYLOAD_SIZE = 37; // report_id + 4 * 9 bytes per port + + // Controller type in first byte of each 9-byte port block + static constexpr uint8_t PORT_WIRED = (1 << 4); + static constexpr uint8_t PORT_WIRELESS = (1 << 5); + + // GameCube button bits (bytes 1 and 2 of each port block) + namespace GCButtons + { + // Byte 1 + static constexpr uint8_t A = (1 << 0); + static constexpr uint8_t B = (1 << 1); + static constexpr uint8_t X = (1 << 2); + static constexpr uint8_t Y = (1 << 3); + static constexpr uint8_t LEFT = (1 << 4); + static constexpr uint8_t RIGHT = (1 << 5); + static constexpr uint8_t DOWN = (1 << 6); + static constexpr uint8_t UP = (1 << 7); + // Byte 2 + static constexpr uint8_t START = (1 << 0); + static constexpr uint8_t Z = (1 << 1); + static constexpr uint8_t R = (1 << 2); + static constexpr uint8_t L = (1 << 3); + } + + static constexpr uint8_t STICK_CENTER = 128; + + #pragma pack(push, 1) + // Full adapter input report: report ID 0x21 + 4 ports × 9 bytes + struct InReport + { + uint8_t report_id{ HID_REPORT_ID }; + uint8_t port_data[4][9]; // [port][type, b1, b2, stickX, stickY, substickX, substickY, triggerL, triggerR] + }; + static_assert(sizeof(InReport) == CONTROLLER_PAYLOAD_SIZE, "WiiU::InReport must be 37 bytes"); + #pragma pack(pop) + + static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 }; + static const uint8_t STRING_MANUFACTURER[] = "Nintendo"; + static const uint8_t STRING_PRODUCT[] = "GameCube For Switch"; + static const uint8_t STRING_SERIAL[] = "GH-GC-001 T8"; + static const uint8_t STRING_VERSION[] = "1.0"; + + static const uint8_t *STRING_DESCRIPTORS[] __attribute__((unused)) = + { + STRING_LANGUAGE, + STRING_MANUFACTURER, + STRING_PRODUCT, + STRING_SERIAL, + STRING_VERSION + }; + + // Nintendo Wii U GameCube Adapter + static const uint8_t DEVICE_DESCRIPTORS[] = + { + 0x12, // bLength + 0x01, // bDescriptorType (Device) + 0x00, 0x02, // bcdUSB 2.00 + 0x00, // bDeviceClass (Use class information in the Interface Descriptors) + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + 0x40, // bMaxPacketSize0 64 + 0x7E, 0x05, // idVendor 0x057E (Nintendo) + 0x37, 0x03, // idProduct 0x0337 (Wii U GameCube Adapter) + 0x00, 0x01, // bcdDevice 1.00 + 0x01, // iManufacturer (String Index) + 0x02, // iProduct (String Index) + 0x03, // iSerialNumber (String Index) + 0x01, // bNumConfigurations 1 + }; + + // HID report descriptor (exact dump from real Nintendo Wii U GameCube Adapter 057e:0337) + static const uint8_t REPORT_DESCRIPTORS[] = + { + 0x05, 0x05, 0x09, 0x00, 0xA1, 0x01, 0x85, 0x11, 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x15, 0x00, 0x26, + 0xFF, 0x00, 0x75, 0x08, 0x95, 0x05, 0x91, 0x00, 0xC0, 0xA1, 0x01, 0x85, 0x21, 0x19, 0x00, 0x2A, + 0xFF, 0x00, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x25, 0x81, 0x00, 0xC0, 0xA1, 0x01, + 0x85, 0x12, 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, + 0x91, 0x00, 0xC0, 0xA1, 0x01, 0x85, 0x22, 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x15, 0x00, 0x26, 0xFF, + 0x00, 0x75, 0x08, 0x95, 0x19, 0x81, 0x00, 0xC0, 0xA1, 0x01, 0x85, 0x13, 0x19, 0x00, 0x2A, 0xFF, + 0x00, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x00, 0xC0, 0xA1, 0x01, 0x85, + 0x23, 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x02, 0x81, + 0x00, 0xC0, 0xA1, 0x01, 0x85, 0x14, 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x15, 0x00, 0x26, 0xFF, 0x00, + 0x75, 0x08, 0x95, 0x01, 0x91, 0x00, 0xC0, 0xA1, 0x01, 0x85, 0x24, 0x19, 0x00, 0x2A, 0xFF, 0x00, + 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x02, 0x81, 0x00, 0xC0, 0xA1, 0x01, 0x85, 0x15, + 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x00, + 0xC0, 0xA1, 0x01, 0x85, 0x25, 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, + 0x08, 0x95, 0x02, 0x81, 0x00, 0xC0, + }; + static_assert(sizeof(REPORT_DESCRIPTORS) == 214, "WiiU report descriptor must be 214 bytes"); + + // HID class descriptor (matches real adapter: bcdHID 1.10, report len 214) + static const uint8_t HID_DESCRIPTORS[] = + { + 0x09, // bLength + 0x21, // bDescriptorType (HID) + 0x10, 0x01, // bcdHID 1.10 + 0x00, // bCountryCode + 0x01, // bNumDescriptors + 0x22, // bDescriptorType[0] (Report) + 0xD6, 0x00, // wDescriptorLength 214 + }; + + // Raw configuration descriptor (matches real adapter: IN 37 bytes, OUT 5 bytes, bInterval 8, bmAttributes 0xe0) + static const uint8_t CONFIGURATION_DESCRIPTORS[] = + { + // Configuration descriptor + 0x09, // bLength + 0x02, // bDescriptorType (Configuration) + 0x29, 0x00, // wTotalLength 41 + 0x01, // bNumInterfaces 1 + 0x01, // bConfigurationValue 1 + 0x00, // iConfiguration (String Index) + 0xE0, // bmAttributes (Self Powered | Remote Wakeup) + 0xFA, // bMaxPower 500mA (0xFA * 2mA) + + // Interface descriptor (HID) + 0x09, // bLength + 0x04, // bDescriptorType (Interface) + 0x00, // bInterfaceNumber 0 + 0x00, // bAlternateSetting 0 + 0x02, // bNumEndpoints 2 + 0x03, // bInterfaceClass (HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0x00, // iInterface (String Index) + + // HID descriptor + 0x09, // bLength + 0x21, // bDescriptorType (HID) + 0x10, 0x01, // bcdHID 1.10 + 0x00, // bCountryCode + 0x01, // bNumDescriptors + 0x22, // bDescriptorType[0] (Report) + 0xD6, 0x00, // wDescriptorLength 214 + + // Endpoint descriptor (OUT 0x02, 5 bytes, interval 8) + 0x07, // bLength + 0x05, // bDescriptorType (Endpoint) + 0x02, // bEndpointAddress (OUT) + 0x03, // bmAttributes (Interrupt) + 0x05, 0x00, // wMaxPacketSize 5 + 0x08, // bInterval 8 + + // Endpoint descriptor (IN 0x81, 37 bytes, interval 8) + 0x07, // bLength + 0x05, // bDescriptorType (Endpoint) + 0x81, // bEndpointAddress (IN) + 0x03, // bmAttributes (Interrupt) + 0x25, 0x00, // wMaxPacketSize 37 + 0x08, // bInterval 8 + }; + +}; // namespace WiiU + +#endif // _WIIU_DESCRIPTORS_H_ diff --git a/Firmware/RP2040/src/Gamepad/Gamepad.h b/Firmware/RP2040/src/Gamepad/Gamepad.h index 9f8cca5e..e6348cb5 100644 --- a/Firmware/RP2040/src/Gamepad/Gamepad.h +++ b/Firmware/RP2040/src/Gamepad/Gamepad.h @@ -21,8 +21,8 @@ class Gamepad { public: + //Defaults used by device to get buttons - static constexpr uint8_t DPAD_UP = 0x01; static constexpr uint8_t DPAD_DOWN = 0x02; static constexpr uint8_t DPAD_LEFT = 0x04; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h index 1fae44ec..5cfd7443 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h @@ -14,6 +14,7 @@ enum class DeviceDriverType : uint8_t DINPUT, PSCLASSIC, SWITCH, + WIIU, WEBAPP = 100, UART_BRIDGE }; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp index df1dddde..2604e347 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp @@ -72,10 +72,10 @@ void SwitchDevice::process(const uint8_t idx, Gamepad& gamepad) if (gp_in.buttons & Gamepad::BUTTON_R3) in_report.buttons |= SwitchWired::Buttons::R3; if (gp_in.buttons & Gamepad::BUTTON_SYS) in_report.buttons |= SwitchWired::Buttons::HOME; if (gp_in.buttons & Gamepad::BUTTON_MISC) in_report.buttons |= SwitchWired::Buttons::CAPTURE; - + if (gp_in.trigger_l) in_report.buttons |= SwitchWired::Buttons::ZL; if (gp_in.trigger_r) in_report.buttons |= SwitchWired::Buttons::ZR; - + in_report.joystick_lx = Scale::int16_to_uint8(gp_in.joystick_lx); in_report.joystick_ly = Scale::int16_to_uint8(gp_in.joystick_ly); in_report.joystick_rx = Scale::int16_to_uint8(gp_in.joystick_rx); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp new file mode 100644 index 00000000..6f5a8c20 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp @@ -0,0 +1,165 @@ +#include + +#include "Board/ogxm_log.h" +#include "USBDevice/DeviceDriver/WiiU/WiiU.h" + +// Set to 1 to bypass init gate: always send reports for testing (Dolphin/Linux may not send 0x13). +#ifndef WIIU_SKIP_INIT_GATE +#define WIIU_SKIP_INIT_GATE 1 +#endif + +void WiiUDevice::initialize() +{ + class_driver_ = + { + .name = TUD_DRV_NAME("WIIU"), + .init = hidd_init, + .deinit = hidd_deinit, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL + }; + + in_report_.report_id = WiiU::HID_REPORT_ID; + std::memset(in_report_.port_data, 0, sizeof(in_report_.port_data)); + init_received_ = false; +} + +// GC stick deadzone: values near center map to 128 to avoid spurious LEFT/RIGHT/UP/DOWN +static constexpr int16_t STICK_DEADZONE = 4096; // ~12.5% of -32768..32767 + +static uint8_t stick_to_gc(int16_t value) +{ + if (value > -STICK_DEADZONE && value < STICK_DEADZONE) + return WiiU::STICK_CENTER; + return Scale::int16_to_uint8(value); +} + +static void fill_port_block(uint8_t port[9], const Gamepad::PadIn& gp_in) +{ + // Byte 0 (type): Bit 4 = Wired. Dolphin: (type & 0x10) != 0 → connected. + port[0] = WiiU::PORT_WIRED; + + // Byte 1 (b1): A, B, X, Y, D-pad Left, Right, Down, Up — direct mapping (A→A, B→B, etc.) + uint8_t b1 = 0; + if (gp_in.buttons & Gamepad::BUTTON_B) b1 |= WiiU::GCButtons::A; + if (gp_in.buttons & Gamepad::BUTTON_A) b1 |= WiiU::GCButtons::B; + if (gp_in.buttons & Gamepad::BUTTON_Y) b1 |= WiiU::GCButtons::X; + if (gp_in.buttons & Gamepad::BUTTON_X) b1 |= WiiU::GCButtons::Y; + if (gp_in.dpad & Gamepad::DPAD_LEFT) b1 |= WiiU::GCButtons::LEFT; + if (gp_in.dpad & Gamepad::DPAD_RIGHT) b1 |= WiiU::GCButtons::RIGHT; + if (gp_in.dpad & Gamepad::DPAD_DOWN) b1 |= WiiU::GCButtons::DOWN; + if (gp_in.dpad & Gamepad::DPAD_UP) b1 |= WiiU::GCButtons::UP; + port[1] = b1; + + // Byte 2 (b2): Start, Z, R (digital), L (digital) + // L/R come from triggers at 255; Z from RB; LB maps to nothing + uint8_t b2 = 0; + if (gp_in.buttons & Gamepad::BUTTON_START) b2 |= WiiU::GCButtons::START; + if (gp_in.buttons & Gamepad::BUTTON_RB) b2 |= WiiU::GCButtons::Z; + if (gp_in.trigger_l >= 255) b2 |= WiiU::GCButtons::L; + if (gp_in.trigger_r >= 255) b2 |= WiiU::GCButtons::R; + port[2] = b2; + + // Bytes 3–4: main stick X, Y (0–255, 128 = center) — Y axis inverted + port[3] = stick_to_gc(gp_in.joystick_lx); + port[4] = stick_to_gc(-gp_in.joystick_ly); + // Bytes 5–6: C-stick (substick) X, Y — Y axis inverted + port[5] = stick_to_gc(gp_in.joystick_rx); + port[6] = stick_to_gc(-gp_in.joystick_ry); + // Bytes 7–8: L/R trigger analog (0–255) + port[7] = gp_in.trigger_l; + port[8] = gp_in.trigger_r; +} + +void WiiUDevice::process(const uint8_t idx, Gamepad& gamepad) +{ + if (idx >= 4) + return; + + // Always update from current gamepad state so late controller connections are reflected immediately. + // Dolphin may stop re-checking after seeing initial zeros; filling every frame avoids that. + // Combo check (check_for_driver_change) also uses get_pad_in(); both see the same current state. + Gamepad::PadIn gp_in = gamepad.get_pad_in(); + fill_port_block(in_report_.port_data[idx], gp_in); + + if (tud_suspended()) + tud_remote_wakeup(); + + // Send once per frame after the last port, only when init received (or WIIU_SKIP_INIT_GATE) and endpoint ready. + // Real adapter does not send reports until host sends Start Polling (0x13). + constexpr uint8_t last_port = (MAX_GAMEPADS >= 4) ? 3 : (MAX_GAMEPADS - 1); + if (idx == last_port && (WIIU_SKIP_INIT_GATE || init_received_) && tud_hid_n_ready(0)) + { + // TinyUSB prepends report_id; pass only port_data (36 bytes) to avoid double report ID + tud_hid_n_report(0, WiiU::HID_REPORT_ID, in_report_.port_data, sizeof(in_report_.port_data)); +#if defined(CONFIG_OGXM_DEBUG) + static uint32_t send_count = 0; + if (++send_count % 500 == 0) + OGXM_LOG("WiiU: IN report sent (count " + std::to_string(send_count) + ")\n"); +#endif + } +} + +uint16_t WiiUDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) +{ + if (report_type != HID_REPORT_TYPE_INPUT || report_id != WiiU::HID_REPORT_ID || itf != 0) + return 0; + if (reqlen < sizeof(WiiU::InReport)) + return 0; + std::memcpy(buffer, &in_report_, sizeof(WiiU::InReport)); + return sizeof(WiiU::InReport); +} + +void WiiUDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) +{ + // Host sends Start Polling (0x13) via Output report. May be [0x13] or [0x21, 0x13] if report ID prepended. + bool is_init = (bufsize >= 1 && buffer[0] == WiiU::INIT_PAYLOAD) || + (bufsize >= 2 && buffer[1] == WiiU::INIT_PAYLOAD); + if (is_init) + { + init_received_ = true; +#if defined(CONFIG_OGXM_DEBUG) + OGXM_LOG("WiiU: init 0x13 received from host\n"); +#endif + } + (void)itf; + (void)report_id; + (void)report_type; +} + +bool WiiUDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +{ + (void)rhport; + (void)stage; + (void)request; + return false; +} + +const uint16_t* WiiUDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + const char *value = reinterpret_cast(WiiU::STRING_DESCRIPTORS[index]); + return get_string_descriptor(value, index); +} + +const uint8_t* WiiUDevice::get_descriptor_device_cb() +{ + return WiiU::DEVICE_DESCRIPTORS; +} + +const uint8_t* WiiUDevice::get_hid_descriptor_report_cb(uint8_t itf) +{ + return WiiU::REPORT_DESCRIPTORS; +} + +const uint8_t* WiiUDevice::get_descriptor_configuration_cb(uint8_t index) +{ + return WiiU::CONFIGURATION_DESCRIPTORS; +} + +const uint8_t* WiiUDevice::get_descriptor_device_qualifier_cb() +{ + return nullptr; +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.h new file mode 100644 index 00000000..537a12e3 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.h @@ -0,0 +1,28 @@ +#ifndef _WIIU_DEVICE_H_ +#define _WIIU_DEVICE_H_ + +#include + +#include "USBDevice/DeviceDriver/DeviceDriver.h" +#include "Descriptors/WiiU.h" + +class WiiUDevice : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; + +private: + WiiU::InReport in_report_{}; + bool init_received_{ false }; // true after host sends Start Polling (0x13) +}; + +#endif // _WIIU_DEVICE_H_ diff --git a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp index ef660535..76e8e6c4 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp @@ -4,6 +4,7 @@ #include "USBDevice/DeviceDriver/PSClassic/PSClassic.h" #include "USBDevice/DeviceDriver/XInput/XInput.h" #include "USBDevice/DeviceDriver/Switch/Switch.h" +#include "USBDevice/DeviceDriver/WiiU/WiiU.h" #include "USBDevice/DeviceDriver/DInput/DInput.h" #include "USBDevice/DeviceDriver/PS3/PS3.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h" @@ -20,40 +21,56 @@ void DeviceManager::initialize_driver( DeviceDriverType driver_type, Gamepad(&gamepads)[MAX_GAMEPADS]) { //TODO: Put gamepad setup in the drivers themselves bool has_analog = false; + + printf("Attempting to allocate driver\n"); switch (driver_type) { case DeviceDriverType::DINPUT: + printf("DINPUT Loaded\n"); has_analog = true; device_driver_ = std::make_unique(); break; case DeviceDriverType::PS3: + printf("PS3 Loaded\n"); has_analog = true; device_driver_ = std::make_unique(); break; case DeviceDriverType::PSCLASSIC: + printf("PSCLASSIC Loaded\n"); device_driver_ = std::make_unique(); break; case DeviceDriverType::SWITCH: + printf("SWITCH Loaded\n"); device_driver_ = std::make_unique(); break; + case DeviceDriverType::WIIU: + printf("WIIU Loaded\n"); + device_driver_ = std::make_unique(); + break; case DeviceDriverType::XINPUT: + printf("XINPUT Loaded\n"); device_driver_ = std::make_unique(); break; case DeviceDriverType::XBOXOG: + printf("XBOXOG Loaded\n"); has_analog = true; device_driver_ = std::make_unique(); break; case DeviceDriverType::XBOXOG_SB: + printf("XBOXOG SB Loaded\n"); device_driver_ = std::make_unique(); break; case DeviceDriverType::XBOXOG_XR: + printf("XBOXOG XR Loaded\n"); device_driver_ = std::make_unique(); break; case DeviceDriverType::WEBAPP: + printf("WEBAPP Loaded\n"); device_driver_ = std::make_unique(); break; #if defined(CONFIG_EN_UART_BRIDGE) case DeviceDriverType::UART_BRIDGE: + printf("UART Loaded\n"); device_driver_ = std::make_unique(); break; #endif //defined(CONFIG_EN_UART_BRIDGE) diff --git a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp index c463ff98..b6ee0d4d 100644 --- a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp +++ b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp @@ -20,7 +20,8 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { DeviceManager::get_instance().get_driver()->set_report_cb(itf, report_id, report_type, buffer, bufsize); - tud_hid_report(report_id, buffer, bufsize); + // Do not echo received output back as input report (e.g. Wii U GC adapter init 0x13 must only be received; + // TinyUSB re-arms the OUT endpoint after this returns so the host can keep sending 0x13). } bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) diff --git a/Firmware/RP2040/src/USBHost/HardwareIDs.h b/Firmware/RP2040/src/USBHost/HardwareIDs.h index ccb924b9..faff4776 100644 --- a/Firmware/RP2040/src/USBHost/HardwareIDs.h +++ b/Firmware/RP2040/src/USBHost/HardwareIDs.h @@ -18,7 +18,7 @@ static const HardwareID DINPUT_IDS[] = {0x0810, 0x0003}, // Personal Communication Systems, Inc. Generic {0x146B, 0x0902}, // BigBen Interactive Wired Mini PS3 Game Controller {0x2563, 0x0575}, // SHANWAN 2In1 USB Joystick - {0x046D, 0xC218} // Logitech RumblePad 2 + {0x046D, 0xC218}, // Logitech RumblePad 2 }; static const HardwareID PS3_IDS[] = @@ -51,6 +51,7 @@ static const HardwareID PSCLASSIC_IDS[] = static const HardwareID SWITCH_PRO_IDS[] = { {0x057E, 0x2009}, // Switch Pro + {0x057E, 0x0330} // Wii U Pro // {0x20D6, 0xA711}, // OpenSteamController, emulated pro controller }; @@ -67,34 +68,6 @@ static const HardwareID N64_IDS[] = {0x0079, 0x0006} // Retrolink N64 USB gamepad }; -static const HardwareID WIIU_PRO_IDS[] = -{ - {0x057E, 0x0330} // Wii U Pro Wireless Controller -}; - -static const HardwareID OUYA_IDS[] = -{ - {0x2836, 0x0001} // OUYA Controller -}; - -static const HardwareID Bit_Ult_IDS[] = -{ - {0x057E, 0x2009} // 8Bit Ultimate Bluetooth Controller -}; - -static const HardwareID Wii_IDS[] = -{ - {0x057e, 0x0306} // Wii Motion Plus Controller - -}; - -static const HardwareID Switch_Joycon_IDS[] = -{ - {0x057e, 0x2007} // Switch Joycon (R) - {0x057e, 0x2006} // Switch Joycon (L) - -}; - struct HostTypeMap { const HardwareID* ids; @@ -112,10 +85,6 @@ static const HostTypeMap HOST_TYPE_MAP[] = { SWITCH_PRO_IDS, sizeof(SWITCH_PRO_IDS) / sizeof(HardwareID), HostDriverType::SWITCH_PRO }, { PSCLASSIC_IDS, sizeof(PSCLASSIC_IDS) / sizeof(HardwareID), HostDriverType::PSCLASSIC }, { N64_IDS, sizeof(N64_IDS) / sizeof(HardwareID), HostDriverType::N64 }, - { WIIU_PRO_IDS, sizeof(WIIU_PRO_IDS) / sizeof(HardwareID), HostDriverType::WIIUPRO }, - { Bit_Ult_IDS, sizeof(Bit_Ult_IDS) / sizeof(HardwareID), HostDriverType::Bit_Ult }, - { Wii_IDS, sizeof(Wii_IDS) / sizeof(HardwareID), HostDriverType::Wii }, - { OUYA_IDS, sizeof(OUYA_IDS) / sizeof(HardwareID), HostDriverType::OUYA }, }; #endif // _HW_ID_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchWired/SwitchWired.cpp b/Firmware/RP2040/src/USBHost/HostDriver/SwitchWired/SwitchWired.cpp index b5c6210a..5f821c92 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchWired/SwitchWired.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchWired/SwitchWired.cpp @@ -7,6 +7,7 @@ void SwitchWiredHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { + tuh_hid_receive_report(address, instance); } @@ -64,9 +65,9 @@ void SwitchWiredHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t if (in_report->buttons & SwitchWired::Buttons::L3) gp_in.buttons |= gamepad.MAP_BUTTON_L3; if (in_report->buttons & SwitchWired::Buttons::R3) gp_in.buttons |= gamepad.MAP_BUTTON_R3; - gp_in.trigger_l = (in_report->buttons & SwitchWired::Buttons::ZL) ? Range::MAX : Range::MIN; - gp_in.trigger_r = (in_report->buttons & SwitchWired::Buttons::ZR) ? Range::MAX : Range::MIN; - + if (in_report->buttons & SwitchWired::Buttons::ZR) gp_in.trigger_r = Range::MAX; + if (in_report->buttons & SwitchWired::Buttons::ZL) gp_in.trigger_l = Range::MAX; + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report->joystick_lx, in_report->joystick_ly); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report->joystick_rx, in_report->joystick_ry); diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index e8638fb2..eaf05c39 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -70,48 +70,63 @@ class HostManager Device& device_slot = device_slots_[dev_idx]; Interface& interface = device_slot.interfaces[instance]; + debug_printf("Attempting to allocate driver for index %d\n", gp_idx); + switch (driver_type) { case HostDriverType::PS5: + debug_printf("PS5 Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::PS4: + debug_printf("PS4 Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::PS3: + debug_printf("PS3 Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::DINPUT: + debug_printf("DINPUT Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::SWITCH: + debug_printf("SWITCH Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::SWITCH_PRO: + debug_printf("SWITCH PRO Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::N64: + debug_printf("N64 Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::PSCLASSIC: + debug_printf("PSCLASSIC Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::XBOXOG: + debug_printf("XBOXOG Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::XBOXONE: + debug_printf("XBOXONE Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::XBOX360: + debug_printf("XBOX360 Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; case HostDriverType::XBOX360W: //Composite device, takes up all 4 gamepads when mounted + debug_printf("XBOX360W Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; default: if (is_hid_gamepad(report_desc, desc_len)) { interface.driver = std::make_unique(gp_idx); + debug_printf("HIDHOST Loaded\n"); fflush(stdout); } else { diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.cpp b/Firmware/RP2040/src/UserSettings/UserSettings.cpp index b0cd1805..ec75d608 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/UserSettings.cpp @@ -18,6 +18,7 @@ namespace ButtonCombo { static constexpr uint32_t DINPUT = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_RB, Gamepad::DPAD_LEFT); static constexpr uint32_t XINPUT = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_UP); static constexpr uint32_t SWITCH = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_DOWN); + static constexpr uint32_t WIIU = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB, Gamepad::DPAD_DOWN); static constexpr uint32_t XBOXOG = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_RIGHT); static constexpr uint32_t XBOXOG_SB = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_RB, Gamepad::DPAD_RIGHT); static constexpr uint32_t XBOXOG_XR = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB, Gamepad::DPAD_RIGHT); @@ -32,6 +33,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::XINPUT, DeviceDriverType::PS3, DeviceDriverType::PSCLASSIC, + DeviceDriverType::WIIU, DeviceDriverType::WEBAPP, #if defined(XREMOTE_ROM_AVAILABLE) DeviceDriverType::XBOXOG_XR, @@ -40,6 +42,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { #elif MAX_GAMEPADS > 1 DeviceDriverType::DINPUT, DeviceDriverType::SWITCH, + DeviceDriverType::WIIU, DeviceDriverType::WEBAPP, #else // MAX_GAMEPADS == 1 @@ -47,6 +50,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::XBOXOG_SB, DeviceDriverType::DINPUT, DeviceDriverType::SWITCH, + DeviceDriverType::WIIU, DeviceDriverType::WEBAPP, DeviceDriverType::PS3, DeviceDriverType::PSCLASSIC, @@ -63,13 +67,14 @@ struct ComboMap { DeviceDriverType driver; }; -static constexpr std::array BUTTON_COMBO_MAP = {{ +static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::XBOXOG, DeviceDriverType::XBOXOG }, { ButtonCombo::XBOXOG_SB, DeviceDriverType::XBOXOG_SB }, { ButtonCombo::XBOXOG_XR, DeviceDriverType::XBOXOG_XR }, { ButtonCombo::WEBAPP, DeviceDriverType::WEBAPP }, { ButtonCombo::DINPUT, DeviceDriverType::DINPUT }, { ButtonCombo::SWITCH, DeviceDriverType::SWITCH }, + { ButtonCombo::WIIU, DeviceDriverType::WIIU }, { ButtonCombo::XINPUT, DeviceDriverType::XINPUT }, { ButtonCombo::PS3, DeviceDriverType::PS3 }, { ButtonCombo::PSCLASSIC, DeviceDriverType::PSCLASSIC } diff --git a/Firmware/RP2040/src/main.cpp b/Firmware/RP2040/src/main.cpp index afdb49d4..51f2254e 100644 --- a/Firmware/RP2040/src/main.cpp +++ b/Firmware/RP2040/src/main.cpp @@ -1,8 +1,19 @@ #include #include "OGXMini/OGXMini.h" +#include "pico/stdlib.h" +#include "pico/flash.h" +#include int main() { + stdio_init_all(); + uart_init(uart0, 115200); // Initialize UART0 at 115200 baud + gpio_set_function(0, GPIO_FUNC_UART); // TX + gpio_set_function(1, GPIO_FUNC_UART); // RX + printf("Debug ready\n"); + + flash_safe_execute_core_init(); + OGXMini::initialize(); OGXMini::run(); return 0; From 8a3d938fd35498432789436668013af64d04f19c Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Sun, 8 Feb 2026 05:24:42 -0500 Subject: [PATCH 10/42] Revise README with platform support and features Updated supported platforms and added new features for Wii U and Switch. --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a36b0db7..ca738846 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,11 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles ## Supported platforms - Original Xbox - Playstation 3 -- Nintendo Switch (docked) +- Nintendo Switch 1 & 2 (docked) - XInput (use [**UsbdSecPatch**](https://github.com/InvoxiPlayGames/UsbdSecPatch) for Xbox 360, or select the patch in J-Runner while flashing your NAND) - Playstation Classic - DInput +- Wii U (GameCube Adapter) ## Changing platforms By default the OGX-Mini will emulate an OG Xbox controller, you must hold a button combo for 3 seconds to change which platform you want to play on. Your chosen mode will persist after powering off the device. @@ -32,9 +33,12 @@ Start = Plus (Switch) = Options (Dualsense/DS4) - Start + Dpad Left - PlayStation Classic - Start + A (Cross for PlayStation and B for Switch gamepads) +- Wii U (GameCube Adapter) + - Start + Left Bumper + D-Pad Down - Web Application Mode - Start + Left Bumper + Right Bumper + After a new mode is stored, the RP2040 will reset itself so you don't need to unplug it. ## Disconnecting Controllers @@ -83,6 +87,7 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. +- Ability to emulate the GameCube controller adapter for Wii U. (Also tested on Switch 1/ 2) - Wii U & Switch Pro controllers are supported fully with working LT and RT - Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. - Disconnection Combo has been added: Start+Select for most controllers, L3+R3 for OUYA controllers. @@ -116,7 +121,6 @@ Note: These features have been added to the Pico W/ Pico 2 W firmware support, I ## Planned additions for this fork - Output to the following consoles: - GameCube - - Wii U (GameCube controller adapter) - PS2 - DreamCast - NES From e222300c9c4cfb5d5dc70bbb95bd084acfd48c09 Mon Sep 17 00:00:00 2001 From: Gary Date: Thu, 12 Feb 2026 07:10:09 -0500 Subject: [PATCH 11/42] Fixed a bug with Wii U mode that caused pushing Left stick up to input as down --- .../docs/XINPUT_JOYPAD_OS_COMPARISON.md | 160 ++++++++++ Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 6 +- Firmware/RP2040/src/Bluepad32/Bluepad32.h | 1 + Firmware/RP2040/src/Descriptors/XInput.h | 78 ++--- Firmware/RP2040/src/Descriptors/XboxOne.h | 300 +++++++++++++++++- Firmware/RP2040/src/Gamepad/Gamepad.h | 6 + .../src/USBDevice/DeviceDriver/WiiU/WiiU.cpp | 33 +- .../USBDevice/DeviceDriver/XInput/XInput.cpp | 7 +- .../XInput/tud_xinput/tud_xinput.cpp | 115 ++++--- .../XInput/tud_xinput/tud_xinput.h | 5 +- .../src/USBHost/HostDriver/XInput/XboxOne.cpp | 35 +- Firmware/RP2040/src/USBHost/HostManager.h | 11 + 12 files changed, 602 insertions(+), 155 deletions(-) create mode 100644 Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md diff --git a/Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md b/Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md new file mode 100644 index 00000000..dadbbac2 --- /dev/null +++ b/Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md @@ -0,0 +1,160 @@ +# XInput (Xbox 360) Report & Descriptor Comparison: OGX-Mini vs joypad-os + +This document compares the XInput device implementation in this project (OGX-Mini) with [joypad-os](https://github.com/joypad-ai/joypad-os) so we can align behavior and add **real Xbox 360 console** support. + +--- + +## 1. Input report (20 bytes) — byte-by-byte + +Both projects use the **same 20-byte input report layout**. Field names differ; byte positions and semantics match. + +| Byte | OGX-Mini (`XInput::InReport`) | joypad-os (`xinput_in_report_t`) | Notes | +|------|------------------------------|-----------------------------------|--------| +| 0 | `report_id` | `report_id` | Always `0x00` | +| 1 | `report_size` | `report_size` | Always `0x14` (20) | +| 2 | `buttons[0]` | `buttons0` | D-pad (0–3), Start (4), Back (5), L3 (6), R3 (7) | +| 3 | `buttons[1]` | `buttons1` | LB (0), RB (1), Guide (2), — (3), A (4), B (5), X (6), Y (7) | +| 4 | `trigger_l` | `trigger_l` | 0–255 | +| 5 | `trigger_r` | `trigger_r` | 0–255 | +| 6–7 | `joystick_lx` | `stick_lx` | int16 LE (-32768..32767) | +| 8–9 | `joystick_ly` | `stick_ly` | int16 LE (Y inverted: positive = up) | +| 10–11 | `joystick_rx` | `stick_rx` | int16 LE | +| 12–13 | `joystick_ry` | `stick_ry` | int16 LE (Y inverted) | +| 14–19 | `reserved[6]` | `reserved[6]` | Zero padding | + +**Conclusion:** No change needed for the **input report format**. OGX-Mini’s mapping in `XInput.cpp` already matches joypad-os’s `xinput_mode.c` (same button bits and axis handling, including Y inversion). + +--- + +## 2. Button bit definitions — identical + +| Button | Byte | Bit | OGX-Mini | joypad-os | +|--------|------|-----|----------|-----------| +| D-pad U/D/L/R | 2 | 0–3 | `Buttons0::DPAD_*` | `XINPUT_BTN_DPAD_*` | +| Start | 2 | 4 | `Buttons0::START` | `XINPUT_BTN_START` | +| Back | 2 | 5 | `Buttons0::BACK` | `XINPUT_BTN_BACK` | +| L3 / R3 | 2 | 6–7 | `Buttons0::L3/R3` | `XINPUT_BTN_L3/R3` | +| LB / RB | 3 | 0–1 | `Buttons1::LB/RB` | `XINPUT_BTN_LB/RB` | +| Guide | 3 | 2 | `Buttons1::HOME` | `XINPUT_BTN_GUIDE` | +| A / B / X / Y | 3 | 4–7 | `Buttons1::A/B/X/Y` | `XINPUT_BTN_A/B/X/Y` | + +No code changes required for button mapping. + +--- + +## 3. Output report (8 bytes) — identical + +| Byte | Content | OGX-Mini | joypad-os | +|------|---------|----------|-----------| +| 0 | report_id | RUMBLE=0x00, LED=0x01 | Same | +| 1 | report_size | 0x08 | 0x08 | +| 2 | led | LED pattern | led | +| 3 | rumble_l | rumble_l | rumble_l | +| 4 | rumble_r | rumble_r | rumble_r | +| 5–7 | reserved | 0 | reserved[3] | + +No change needed for output report layout. + +--- + +## 4. Device descriptor — same VID/PID, minor bmAttributes + +| Field | OGX-Mini | joypad-os | +|-------|----------|-----------| +| idVendor | 0x045E | XINPUT_VID 0x045E | +| idProduct | 0x028E | XINPUT_PID 0x028E | +| bcdDevice | 0x0114 (2.14) | XINPUT_BCD_DEVICE 0x0114 | +| bmAttributes | 0x80 (no remote wakeup) | 0xA0 (remote wakeup) | + +Optional: set bmAttributes to `0xA0` in `DESC_DEVICE[]` if you want remote wakeup to match joypad-os and some 360 behavior. + +--- + +## 5. Configuration descriptor — main difference (PC vs 360 console) + +### OGX-Mini (current): PC-only, 1 interface + +- **wTotalLength:** 48 (0x30) +- **bNumInterfaces:** 1 +- **Interface 0:** Gamepad (0xFF / 0x5D / 0x01), 2 endpoints + - EP 0x81 IN (interrupt, 32 bytes, **bInterval 1**) + - EP 0x01 OUT (interrupt, 32 bytes, bInterval 8) +- Followed by a 16-byte vendor/HID-style descriptor (0x21 with bNumDescriptors, etc.). + +This is enough for **PC (XInput)** and many games. It is **not** enough for a **real Xbox 360 console**, which expects a multi-interface device and XSM3 security. + +### joypad-os: PC + Xbox 360 console, 4 interfaces + +- **wTotalLength:** 153 +- **bNumInterfaces:** 4 + +| Iface | Class / SubClass / Protocol | Purpose | Endpoints | +|-------|-----------------------------|---------|-----------| +| 0 | 0xFF / 0x5D / 0x01 | Gamepad | EP 0x81 IN (4 ms), EP 0x02 OUT (8 ms) | +| 1 | 0xFF / 0x5D / 0x03 | Audio (stub) | 4 EPs (not opened by driver) | +| 2 | 0xFF / 0x5D / 0x02 | Plugin (stub) | 1 EP (not opened) | +| 3 | 0xFF / **0xFD** / **0x13** | **Security (XSM3)** | 0 EPs (control only) | + +- Gamepad uses a **17-byte vendor descriptor** (0x21) after the interface, not the longer HID-style block. +- **Interface 3** is the security interface; the console uses **vendor control requests** on the device to run the XSM3 challenge/response. Without this interface and the XSM3 handler, the 360 console will not accept the device. + +--- + +## 6. What to add for real Xbox 360 console support + +To have OGX-Mini work on a **real Xbox 360** (like joypad-os), you need the following. + +### 6.1 Four-interface configuration descriptor + +- Replace the single-interface configuration in `Descriptors/XInput.h` with a **153-byte** configuration that includes: + - Interface 0: Gamepad (0xFF/0x5D/0x01) + 17-byte vendor descriptor + EP 0x81 IN (bInterval **4**), EP 0x02 OUT (8). + - Interface 1: Audio (0xFF/0x5D/0x03), stub only (descriptors present, no need to open EPs). + - Interface 2: Plugin (0xFF/0x5D/0x02), stub only. + - Interface 3: Security (0xFF/0xFD/0x13), no endpoints, security descriptor (0x41) only. + +You can copy the exact bytes from joypad-os’s `xinput_descriptors.h` (`xinput_config_descriptor[]`) and adapt to OGX-Mini’s naming (e.g. `DESC_CONFIGURATION[]` / `XINPUT_CONFIG_TOTAL_LEN`). + +### 6.2 XSM3 authentication + +- The 360 console sends **vendor control** requests (bRequest): + - **0x81** GET_SERIAL — device returns 29-byte ID (from libxsm3). + - **0x82** INIT_AUTH — console sends 34-byte challenge; device must respond with 46-byte response. + - **0x83** RESPOND — device returns challenge response (46 or 22 bytes). + - **0x84** KEEPALIVE — device responds with 0 bytes. + - **0x86** STATE — device returns 2-byte state (e.g. 2 = response ready). + - **0x87** VERIFY — console sends 22-byte verify; device responds with 22-byte response. + +- joypad-os uses **[libxsm3](https://github.com/InvoxiPlayGames/libxsm3)** (LGPL-2.1) to compute the challenge/response. You would need to: + - Add libxsm3 (or a port) to the OGX-Mini firmware. + - In the USB device stack, route **vendor control** transfers to an XInput/XSM3 handler (joypad-os does this in `tud_xinput_vendor_control_xfer_cb`). + - Implement the same state machine: on 0x82 store the challenge and call libxsm3 init; on 0x83 return the response; on 0x87 run verify and return the verify response; etc. + +### 6.3 Class driver `open()` for multiple interfaces + +- joypad-os’s `tud_xinput.c` `xinput_open()` is called for **each** interface. It: + - **Opens** only Interface 0 (gamepad): claims the interface and opens EP IN and EP OUT. + - **Skips** Interfaces 1 and 2 (audio, plugin): advances the descriptor pointer without opening endpoints. + - **Records** Interface 3 (security) index (e.g. `_sec_itf_num`) for XSM3; no endpoints. + +OGX-Mini’s `tud_xinput` currently assumes a single interface. It needs to be extended so that when the device presents the 4-interface configuration, the driver parses and skips the stub interfaces and only opens the gamepad endpoints, and recognizes the security interface (for routing vendor requests in usbd, not necessarily by interface number in the driver). + +### 6.4 Optional: IN endpoint interval + +- joypad-os uses **bInterval 4** (4 ms) for the gamepad IN endpoint; OGX-Mini uses **1** (1 ms). For 360 compatibility, changing the gamepad IN endpoint to **4** in the new configuration descriptor is a good idea. + +--- + +## 7. Summary table + +| Item | OGX-Mini | joypad-os | Action for 360 | +|------|----------|-----------|----------------| +| Input report (20 bytes) | Same layout | Same | None | +| Button bits | Same | Same | None | +| Output report (8 bytes) | Same | Same | None | +| VID/PID | 045E:028E | 045E:028E | None | +| Config: num interfaces | 1 | 4 | Add 4-interface, 153-byte config | +| Config: gamepad EP IN interval | 1 | 4 | Use 4 in new config | +| Vendor control (XSM3) | Not implemented | 0x81/82/83/84/86/87 | Add libxsm3 + vendor handler | +| Class driver multi-interface | Single iface | Opens if 0, skips 1–2, records 3 | Extend open() for 4-iface config | + +Implementing the 4-interface descriptor and XSM3 (with libxsm3) will align OGX-Mini with joypad-os’s XInput mode for **real Xbox 360 console** output while keeping the existing report code unchanged. diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index 83df3b64..02cdc520 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -381,7 +381,7 @@ uni_platform* get_driver() //Public API -void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]) +void init(Gamepad(&gamepads)[MAX_GAMEPADS]) { for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { @@ -396,7 +396,11 @@ void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]) led_timer_.context = nullptr; btstack_run_loop_set_timer(&led_timer_, LED_CHECK_TIME_MS); btstack_run_loop_add_timer(&led_timer_); +} +void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]) +{ + init(gamepads); btstack_run_loop_execute(); } diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.h b/Firmware/RP2040/src/Bluepad32/Bluepad32.h index 19b13a21..c823ed92 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.h +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.h @@ -11,4 +11,5 @@ namespace bluepad32 { void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]); + void init(Gamepad(&gamepads)[MAX_GAMEPADS]); } \ No newline at end of file diff --git a/Firmware/RP2040/src/Descriptors/XInput.h b/Firmware/RP2040/src/Descriptors/XInput.h index 4f72b306..c625d889 100644 --- a/Firmware/RP2040/src/Descriptors/XInput.h +++ b/Firmware/RP2040/src/Descriptors/XInput.h @@ -172,7 +172,7 @@ namespace XInput static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 }; static const uint8_t STRING_MANUFACTURER[] = "Microsoft"; - static const uint8_t STRING_PRODUCT[] = "XInput STANDARD GAMEPAD"; + static const uint8_t STRING_PRODUCT[] = "Xbox 360 Controller"; static const uint8_t STRING_VERSION[] = "1.0"; static const uint8_t *DESC_STRING[] __attribute__((unused)) = @@ -180,7 +180,7 @@ namespace XInput STRING_LANGUAGE, STRING_MANUFACTURER, STRING_PRODUCT, - STRING_VERSION + STRING_VERSION, }; static const uint8_t DESC_DEVICE[] = @@ -188,68 +188,44 @@ namespace XInput 0x12, // bLength 0x01, // bDescriptorType (Device) 0x00, 0x02, // bcdUSB 2.00 - 0xFF, // bDeviceClass - 0xFF, // bDeviceSubClass - 0xFF, // bDeviceProtocol - 0x40, // bMaxPacketSize0 64 - 0x5E, 0x04, // idVendor 0x045E - 0x8E, 0x02, // idProduct 0x028E - 0x14, 0x01, // bcdDevice 2.14 + 0xFF, // bDeviceClass + 0xFF, // bDeviceSubClass + 0xFF, // bDeviceProtocol + 0x40, // bMaxPacketSize0 64 + 0x5E, 0x04, // idVendor 0x045E (Microsoft) + 0x8E, 0x02, // idProduct 0x028E (Xbox 360 Controller) + 0x14, 0x01, // bcdDevice 1.14 0x01, // iManufacturer (String Index) 0x02, // iProduct (String Index) 0x03, // iSerialNumber (String Index) 0x01, // bNumConfigurations 1 }; + // Single-interface XInput config (48 bytes) for PC + static constexpr uint16_t CONFIG_TOTAL_LENGTH = 48; + static const uint8_t DESC_CONFIGURATION[] = { - 0x09, // bLength - 0x02, // bDescriptorType (Configuration) - 0x30, 0x00, // wTotalLength 48 + // Configuration descriptor (9 bytes) + 0x09, 0x02, + 0x30, 0x00, // wTotalLength 48 (LE) 0x01, // bNumInterfaces 1 0x01, // bConfigurationValue - 0x00, // iConfiguration (String Index) - 0x80, // bmAttributes + 0x00, // iConfiguration + 0x80, // bmAttributes (bus powered) 0xFA, // bMaxPower 500mA - 0x09, // bLength - 0x04, // bDescriptorType (Interface) - 0x00, // bInterfaceNumber 0 - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints 2 - 0xFF, // bInterfaceClass - 0x5D, // bInterfaceSubClass - 0x01, // bInterfaceProtocol - 0x00, // iInterface (String Index) - - 0x10, // bLength - 0x21, // bDescriptorType (HID) - // 0x10, 0x01, // bcdHID 1.10 - 0x00, 0x01, // bcdHID 1.00 - 0x01, // bCountryCode - 0x24, // bNumDescriptors - 0x81, // bDescriptorType[0] (Unknown 0x81) - 0x14, 0x03, // wDescriptorLength[0] 788 - 0x00, // bDescriptorType[1] (Unknown 0x00) - 0x03, 0x13, // wDescriptorLength[1] 4867 - 0x01, // bDescriptorType[2] (Unknown 0x02) - 0x00, 0x03, // wDescriptorLength[2] 768 - 0x00, // bDescriptorType[3] (Unknown 0x00) - - 0x07, // bLength - 0x05, // bDescriptorType (Endpoint) - 0x81, // bEndpointAddress (IN/D2H) - 0x03, // bmAttributes (Interrupt) - 0x20, 0x00, // wMaxPacketSize 32 - 0x01, // bInterval 1 (unit depends on device speed) - - 0x07, // bLength - 0x05, // bDescriptorType (Endpoint) - 0x01, // bEndpointAddress (OUT/H2D) - 0x03, // bmAttributes (Interrupt) - 0x20, 0x00, // wMaxPacketSize 32 - 0x08, // bInterval 8 (unit depends on device speed) + // Interface 0: Gamepad (0xFF/0x5D/0x01) + 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x5D, 0x01, 0x00, + // Vendor descriptor (type 0x21, 16 bytes) + 0x10, 0x21, 0x00, 0x01, 0x01, 0x25, 0x81, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x08, 0x00, + // EP 0x81 IN - Interrupt, 32 bytes, 1ms + 0x07, 0x05, 0x81, 0x03, 0x20, 0x00, 0x01, + // EP 0x01 OUT - Interrupt, 32 bytes, 8ms + 0x07, 0x05, 0x01, 0x03, 0x20, 0x00, 0x08, }; + static_assert(sizeof(DESC_CONFIGURATION) == CONFIG_TOTAL_LENGTH, "XInput config descriptor size"); }; #endif // _XINPUT_DESCRIPTORS_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/Descriptors/XboxOne.h b/Firmware/RP2040/src/Descriptors/XboxOne.h index cda84eb7..2517b1ef 100644 --- a/Firmware/RP2040/src/Descriptors/XboxOne.h +++ b/Firmware/RP2040/src/Descriptors/XboxOne.h @@ -28,36 +28,302 @@ namespace XboxOne static constexpr uint8_t R3 = (1 << 7); }; + // GIP Command IDs + static constexpr uint8_t GIP_CMD_DEVICE_ARRIVAL = 0x02; + static constexpr uint8_t GIP_CMD_DEVICE_STATUS = 0x03; + static constexpr uint8_t GIP_CMD_DEVICE_DESCRIPTOR = 0x04; + static constexpr uint8_t GIP_CMD_VIRTUAL_KEY = 0x07; // Guide/Home; payload byte 4: 01=pressed, 00=released + static constexpr uint8_t GIP_CMD_SET_DEVICE_STATE = 0x09; + static constexpr uint8_t GIP_CMD_INPUT = 0x20; + static constexpr uint8_t GIP_CMD_SYSTEM_FOCUS_CHANGE = 0xE0; + + // GIP Header Flags + namespace GipFlags + { + static constexpr uint8_t NONE = 0x00; + static constexpr uint8_t INTERNAL = 0x20; // Core protocol message (request from host) + static constexpr uint8_t RESPONSE_FIRST = 0xF0; // First chunk of response (from device) + static constexpr uint8_t RESPONSE_CONTINUE = 0xA0; // Continuation chunk of response (from device) + } + + // GIP Battery Types + namespace BatteryType + { + static constexpr uint8_t WIRED = 0; + static constexpr uint8_t STANDARD = 1; + static constexpr uint8_t CHARGE_KIT = 2; + } + + // GIP Battery Levels + namespace BatteryLevel + { + static constexpr uint8_t LOW = 0; + static constexpr uint8_t MEDIUM = 1; + static constexpr uint8_t HIGH = 2; + static constexpr uint8_t FULL = 3; + } + + // GIP Interface GUIDs (for descriptor) + static constexpr uint8_t GUID_GAMEPAD[16] = { + 0x08, 0x2E, 0x40, 0x2C, 0x07, 0xDF, 0x45, 0xE1, + 0xA5, 0xAB, 0xA3, 0x12, 0x7A, 0xF1, 0x97, 0xB5 + }; + #pragma pack(push, 1) - struct InReport + + // GIP Message Header (8 bytes for USB GIP) + struct GipMessageHeader { - struct GipHeader - { - uint8_t command; - uint8_t client : 4; - uint8_t needsAck : 1; - uint8_t internal : 1; - uint8_t chunkStart : 1; - uint8_t chunked : 1; - uint8_t sequence; - uint8_t length; - } header; + uint8_t command; + uint8_t client : 4; + uint8_t needsAck : 1; + uint8_t internal : 1; + uint8_t chunkStart : 1; + uint8_t chunked : 1; + uint8_t sequence; + uint8_t length; + }; + static_assert(sizeof(GipMessageHeader) == 4, "GipMessageHeader must be 4 bytes"); - uint8_t buttons[2]; + // Device Arrival Message (GIP CMD 0x02) + struct DeviceArrivalMessage + { + GipMessageHeader header; + uint64_t deviceId; // Unique device identifier + uint16_t vendorId; // 0x045E + uint16_t productId; // 0x02D1 + struct { + uint16_t major; + uint16_t minor; + uint16_t build; + uint16_t revision; + } firmwareVersion; + uint8_t unknown[8]; // Padding to make total 32 bytes + }; + static_assert(sizeof(DeviceArrivalMessage) == 32, "DeviceArrivalMessage must be 32 bytes"); + + // Device Status Message (GIP CMD 0x03) + struct DeviceStatusMessage + { + GipMessageHeader header; + uint8_t batteryLevel : 2; + uint8_t batteryType : 2; + uint8_t unknown : 3; + uint8_t connected : 1; + uint8_t unknown2[3]; + }; + static_assert(sizeof(DeviceStatusMessage) == 8, "DeviceStatusMessage must be 8 bytes"); - uint16_t trigger_l; - uint16_t trigger_r; + // Device Descriptor Message (GIP CMD 0x04) + // Windows requests this to identify the device type (gamepad, chatpad, etc.) + // According to GIP spec, this is a variable-size message (typically 200-500 bytes) + // It contains a descriptor header with offsets to various metadata blocks + // NOTE: Vendor/product IDs are NOT in the descriptor header - they're only in Device Arrival message + struct DeviceDescriptorHeader + { + uint16_t unknown1; // 0x0293 (real controller value) + uint16_t unknown2; // 0x0010 (real controller value) + uint16_t unknown3; // 0x0001 (real controller value) + uint8_t padding[8]; // 8 bytes of zeros + uint16_t offset_externalCommands; + uint16_t offset_firmwareVersions; + uint16_t offset_audioFormats; + uint16_t offset_inputCommands; + uint16_t offset_outputCommands; + uint16_t offset_classNames; + uint16_t offset_interfaceGuids; + uint16_t offset_hidDescriptor; + uint16_t unknown4; // 0x004C (real controller value) + }; + // Note: Size may be 32 or 36 bytes depending on compiler alignment + // We'll use sizeof() in the code rather than hardcoding + + // Minimal Device Descriptor Message structure + // We'll build this dynamically to include at least the interface GUID + struct DeviceDescriptorMessage + { + GipMessageHeader header; // 4 bytes + DeviceDescriptorHeader descHeader; // 32 bytes + // Following buffer will contain metadata blocks + // For a minimal gamepad descriptor, we need at least: + // - Interface GUID block (16 bytes + 1 byte count = 17 bytes minimum) + uint8_t buffer[64]; // Buffer for metadata (can be expanded) + }; + + // 48-byte input report (4-byte header + 44-byte payload). Header: 0x20, 0x00, sequence, 0x2C. + // We put gamepad data at payload offset 0 (report bytes 4-17) for Linux xpad/GamepadTester. + // Real controller uses payload offset 6 for buttons; both formats are 48 bytes total. + static constexpr uint16_t GIP_INPUT_REPORT_SIZE = 48; + static constexpr uint8_t GIP_INPUT_PAYLOAD_SIZE = 44; // 0x2C + + // Input Report (GIP CMD 0x20) - logical gamepad state (we build 48-byte wire format from this) + struct InReport + { + GipMessageHeader header; + uint16_t buttons; // Bitfield: Sync, Menu, View, A, B, X, Y, Dpad, Shoulders, Thumbs + uint16_t trigger_l; // 0x000 to 0x3FF (0-1023) + uint16_t trigger_r; // 0x000 to 0x3FF (0-1023) int16_t joystick_lx; int16_t joystick_ly; int16_t joystick_rx; int16_t joystick_ry; + uint8_t guide_pressed; // Home/Guide: when set, report bytes 12-13 = 0xF5FE (real controller encoding) + }; + static_assert(sizeof(InReport) == 19, "XboxOne::InReport must be 19 bytes"); + + // Button bitfield for InReport.buttons (uint16_t) + // Order matches Linux evdev / GamepadTester / official Xbox One controller: + // B0=A, B1=B, B2=X, B3=Y, B4=LB, B5=RB, B6=LT, B7=RT, B8=Select, B9=Start, + // B10=L3, B11=R3, B12=DPAD_UP, B13=DPAD_DOWN, B14=DPAD_LEFT, B15=DPAD_RIGHT. (B16=Home separate.) + namespace GamepadButtons + { + static constexpr uint16_t A = 0x0001; // B0 + static constexpr uint16_t B = 0x0002; // B1 + static constexpr uint16_t X = 0x0004; // B2 + static constexpr uint16_t Y = 0x0008; // B3 + static constexpr uint16_t LEFT_SHOULDER = 0x0010; // B4 LB + static constexpr uint16_t RIGHT_SHOULDER = 0x0020; // B5 RB + static constexpr uint16_t LEFT_TRIGGER_BTN = 0x0040; // B6 LT (from trigger value) + static constexpr uint16_t RIGHT_TRIGGER_BTN = 0x0080; // B7 RT + static constexpr uint16_t VIEW = 0x0100; // B8 Select/Back + static constexpr uint16_t MENU = 0x0200; // B9 Start + static constexpr uint16_t LEFT_THUMB = 0x0400; // B10 L3 + static constexpr uint16_t RIGHT_THUMB = 0x0800; // B11 R3 + static constexpr uint16_t DPAD_UP = 0x1000; // B12 + static constexpr uint16_t DPAD_DOWN = 0x2000; // B13 + static constexpr uint16_t DPAD_LEFT = 0x4000; // B14 + static constexpr uint16_t DPAD_RIGHT = 0x8000; // B15 + // B16 = Home/Guide (evdev often as separate key; we can't fit in 16 bits here) + static constexpr uint16_t SYNC = 0x0000; // unused in 16-bit; map to KEY_PROG1 etc. if needed + } - uint8_t reserved[18]; // 18-byte padding at the end + // Set Device State / Force Feedback (GIP CMD 0x09) + struct OutReport + { + GipMessageHeader header; + uint8_t unknown1; + uint8_t flags; // Force feedback flags + uint8_t leftTrigger; // Left trigger vibration (0-255) + uint8_t rightTrigger; // Right trigger vibration (0-255) + uint8_t leftMotor; // Left motor (0-255) + uint8_t rightMotor; // Right motor (0-255) + uint8_t duration; // Duration in 10ms units + uint8_t delay; // Delay before starting + uint8_t repeat; // Repeat count }; - static_assert(sizeof(InReport) == 36, "XboxOne::InReport is not the correct size"); + static_assert(sizeof(OutReport) == 13, "XboxOne::OutReport must be 13 bytes"); + + // Force Feedback Flags + namespace ForceFeedbackFlags + { + static constexpr uint8_t RIGHT_MOTOR = 0x01; + static constexpr uint8_t LEFT_MOTOR = 0x02; + static constexpr uint8_t RIGHT_TRIGGER = 0x04; + static constexpr uint8_t LEFT_TRIGGER = 0x08; + } #pragma pack(pop) + // USB Descriptors + static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 }; + static const uint8_t STRING_MANUFACTURER[] = "Microsoft"; + static const uint8_t STRING_PRODUCT[] = "Xbox One Controller"; + static const uint8_t STRING_SERIAL[] = "000000000000"; + static const uint8_t STRING_VERSION[] = "1.0"; + + static const uint8_t *STRING_DESCRIPTORS[] __attribute__((unused)) = + { + STRING_LANGUAGE, + STRING_MANUFACTURER, + STRING_PRODUCT, + STRING_SERIAL, + STRING_VERSION + }; + + // Device descriptor - Windows loads xb1usb for VID_045E&PID_02D1 (Xbox One Controller) + static const uint8_t DEVICE_DESCRIPTORS[] = + { + 0x12, // bLength + 0x01, // bDescriptorType (Device) + 0x00, 0x02, // bcdUSB 2.00 + 0xFF, // bDeviceClass (Vendor Specific) + 0x47, // bDeviceSubClass (71) + 0xD0, // bDeviceProtocol (208) + 0x40, // bMaxPacketSize0 64 + 0x5E, 0x04, // idVendor 0x045E (Microsoft) + 0xD1, 0x02, // idProduct 0x02D1 (Xbox One Controller - Windows compatible) + 0x16, 0x05, // bcdDevice 5.16 (match capture) + 0x01, // iManufacturer (String Index) + 0x02, // iProduct (String Index) + 0x03, // iSerialNumber (String Index) + 0x01, // bNumConfigurations 1 + }; + + // Configuration descriptor - match real controller: Interface 0 has BOTH GIP endpoints (0x02 OUT, 0x82 IN) + static const uint8_t CONFIGURATION_DESCRIPTORS[] = + { + // Configuration descriptor + 0x09, // bLength + 0x02, // bDescriptorType (Configuration) + 0x32, 0x00, // wTotalLength 50 bytes + 0x03, // bNumInterfaces 3 + 0x01, // bConfigurationValue 1 + 0x00, // iConfiguration (String Index) + 0xA0, // bmAttributes (Bus Powered, Remote Wakeup supported) + 0xFA, // bMaxPower 500mA + + // Interface 0 - GIP data (both IN and OUT on this interface, like real controller) + 0x09, // bLength + 0x04, // bDescriptorType (Interface) + 0x00, // bInterfaceNumber 0 + 0x00, // bAlternateSetting 0 + 0x02, // bNumEndpoints 2 + 0xFF, // bInterfaceClass (Vendor Specific) + 0x47, // bInterfaceSubClass (71) + 0xD0, // bInterfaceProtocol (208) + 0x00, // iInterface (String Index) + + // Endpoint 0x02 OUT (first EP in descriptor = 0x02) + 0x07, // bLength + 0x05, // bDescriptorType (Endpoint) + 0x02, // bEndpointAddress (OUT) + 0x03, // bmAttributes (Interrupt) + 0x40, 0x00, // wMaxPacketSize 64 + 0x04, // bInterval 4 + + // Endpoint 0x82 IN (second EP = 0x82) + 0x07, // bLength + 0x05, // bDescriptorType (Endpoint) + 0x82, // bEndpointAddress (IN) + 0x03, // bmAttributes (Interrupt) + 0x40, 0x00, // wMaxPacketSize 64 + 0x04, // bInterval 4 + + // Interface 1 - no endpoints (placeholder for 3-interface layout) + 0x09, // bLength + 0x04, // bDescriptorType (Interface) + 0x01, // bInterfaceNumber 1 + 0x00, // bAlternateSetting 0 + 0x00, // bNumEndpoints 0 + 0xFF, // bInterfaceClass (Vendor Specific) + 0x47, // bInterfaceSubClass (71) + 0xD0, // bInterfaceProtocol (208) + 0x00, // iInterface (String Index) + + // Interface 2 - no endpoints (placeholder for 3-interface layout) + 0x09, // bLength + 0x04, // bDescriptorType (Interface) + 0x02, // bInterfaceNumber 2 + 0x00, // bAlternateSetting 0 + 0x00, // bNumEndpoints 0 + 0xFF, // bInterfaceClass (Vendor Specific) + 0x47, // bInterfaceSubClass (71) + 0xD0, // bInterfaceProtocol (208) + 0x00, // iInterface (String Index) + }; + + static constexpr uint16_t DRIVER_LEN = sizeof(CONFIGURATION_DESCRIPTORS); + }; // namespace XboxOne #endif // _XBOX_ONE_DESCRIPTORS_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/Gamepad/Gamepad.h b/Firmware/RP2040/src/Gamepad/Gamepad.h index e6348cb5..d223aad9 100644 --- a/Firmware/RP2040/src/Gamepad/Gamepad.h +++ b/Firmware/RP2040/src/Gamepad/Gamepad.h @@ -224,6 +224,10 @@ class Gamepad mutex_exit(&chatpad_in_mutex_); } + // Wii U GC adapter: set by host when controller uses positive Y for physical up (e.g. Xbox One/360) + void set_stick_y_positive_is_up(bool v) { stick_y_positive_is_up_ = v; } + bool stick_y_positive_is_up() const { return stick_y_positive_is_up_; } + inline void reset_pad_in() { mutex_enter_blocking(&pad_in_mutex_); @@ -359,6 +363,8 @@ class Gamepad bool profile_analog_enabled_{false}; + bool stick_y_positive_is_up_{false}; // true for Xbox (positive Y = up), false for Wii U/Nintendo + JoystickSettings joy_settings_l_; JoystickSettings joy_settings_r_; TriggerSettings trig_settings_l_; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp index 6f5a8c20..6ae32692 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/WiiU/WiiU.cpp @@ -30,6 +30,9 @@ void WiiUDevice::initialize() // GC stick deadzone: values near center map to 128 to avoid spurious LEFT/RIGHT/UP/DOWN static constexpr int16_t STICK_DEADZONE = 4096; // ~12.5% of -32768..32767 +// Dolphin GameCube test reported max stick range: Left ±111, C-stick ~±110..112 (center 0). +// Our bytes 0–255 map to that via host; Y uses 1..254 to avoid full-up→down misread. + static uint8_t stick_to_gc(int16_t value) { if (value > -STICK_DEADZONE && value < STICK_DEADZONE) @@ -37,7 +40,18 @@ static uint8_t stick_to_gc(int16_t value) return Scale::int16_to_uint8(value); } -static void fill_port_block(uint8_t port[9], const Gamepad::PadIn& gp_in) +// Y axis only: map to 1..254 so 0/255 are never sent (some hosts treat extremes as wrong direction). +static uint8_t stick_y_to_gc(int16_t value) +{ + if (value > -STICK_DEADZONE && value < STICK_DEADZONE) + return WiiU::STICK_CENTER; + uint8_t u = Scale::int16_to_uint8(value); + if (u <= 1) return 1u; + if (u >= 254) return 254u; + return u; +} + +static void fill_port_block(uint8_t port[9], const Gamepad::PadIn& gp_in, bool stick_y_positive_is_up) { // Byte 0 (type): Bit 4 = Wired. Dolphin: (type & 0x10) != 0 → connected. port[0] = WiiU::PORT_WIRED; @@ -63,12 +77,19 @@ static void fill_port_block(uint8_t port[9], const Gamepad::PadIn& gp_in) if (gp_in.trigger_r >= 255) b2 |= WiiU::GCButtons::R; port[2] = b2; - // Bytes 3–4: main stick X, Y (0–255, 128 = center) — Y axis inverted + // Bytes 3–4: main stick X, Y (0–255, 128 = center). + // Y: set by host — Xbox uses positive=up (send value), Wii U/Nintendo use negative=up (send 255-value). port[3] = stick_to_gc(gp_in.joystick_lx); - port[4] = stick_to_gc(-gp_in.joystick_ly); - // Bytes 5–6: C-stick (substick) X, Y — Y axis inverted + { + uint8_t ly = stick_y_to_gc(gp_in.joystick_ly); + port[4] = stick_y_positive_is_up ? ly : static_cast(255 - ly); + } + // Bytes 5–6: C-stick (substick) X, Y port[5] = stick_to_gc(gp_in.joystick_rx); - port[6] = stick_to_gc(-gp_in.joystick_ry); + { + uint8_t ry = stick_y_to_gc(gp_in.joystick_ry); + port[6] = stick_y_positive_is_up ? ry : static_cast(255 - ry); + } // Bytes 7–8: L/R trigger analog (0–255) port[7] = gp_in.trigger_l; port[8] = gp_in.trigger_r; @@ -83,7 +104,7 @@ void WiiUDevice::process(const uint8_t idx, Gamepad& gamepad) // Dolphin may stop re-checking after seeing initial zeros; filling every frame avoids that. // Combo check (check_for_driver_change) also uses get_pad_in(); both see the same current state. Gamepad::PadIn gp_in = gamepad.get_pad_in(); - fill_port_block(in_report_.port_data[idx], gp_in); + fill_port_block(in_report_.port_data[idx], gp_in, gamepad.stick_y_positive_is_up()); if (tud_suspended()) tud_remote_wakeup(); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp index 43d1465d..89e47d89 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp @@ -3,7 +3,7 @@ #include "USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h" #include "USBDevice/DeviceDriver/XInput/XInput.h" -void XInputDevice::initialize() +void XInputDevice::initialize() { class_driver_ = *tud_xinput::class_driver(); } @@ -94,8 +94,11 @@ uint16_t XInputDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_ void XInputDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) {} -bool XInputDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +bool XInputDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { + (void)rhport; + (void)stage; + (void)request; return false; } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp index 26f38f1d..0f6b07e6 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp @@ -13,14 +13,13 @@ namespace tud_xinput { static constexpr uint16_t ENDPOINT_SIZE = 32; +static constexpr uint8_t DESC_TYPE_VENDOR = 0x21; uint8_t endpoint_in_ = 0xFF; uint8_t endpoint_out_ = 0xFF; uint8_t ep_in_buffer_[ENDPOINT_SIZE]; uint8_t ep_out_buffer_[ENDPOINT_SIZE]; -//Class Driver - static void init(void) { endpoint_in_ = 0xFF; @@ -37,66 +36,75 @@ static bool deinit(void) static void reset(uint8_t rhport) { + (void)rhport; init(); } +static inline uint16_t tu_desc_len(uint8_t const* desc) { return desc[0]; } + static uint16_t open(uint8_t rhport, tusb_desc_interface_t const *itf_descriptor, uint16_t max_length) { - uint16_t driver_length = sizeof(tusb_desc_interface_t) + (itf_descriptor->bNumEndpoints * sizeof(tusb_desc_endpoint_t)) + 16; - - TU_VERIFY(max_length >= driver_length, 0); - - uint8_t const *current_descriptor = tu_desc_next(itf_descriptor); - uint8_t found_endpoints = 0; - while ((found_endpoints < itf_descriptor->bNumEndpoints) && (driver_length <= max_length)) - { - tusb_desc_endpoint_t const *endpoint_descriptor = (tusb_desc_endpoint_t const *)current_descriptor; - if (TUSB_DESC_ENDPOINT == tu_desc_type(endpoint_descriptor)) - { - TU_ASSERT(usbd_edpt_open(rhport, endpoint_descriptor)); - - if (tu_edpt_dir(endpoint_descriptor->bEndpointAddress) == TUSB_DIR_IN) - { - endpoint_in_ = endpoint_descriptor->bEndpointAddress; - } - else - { - endpoint_out_ = endpoint_descriptor->bEndpointAddress; - } - - ++found_endpoints; - } - - current_descriptor = tu_desc_next(current_descriptor); - } - return driver_length; + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const *p_desc = tu_desc_next((uint8_t const*)itf_descriptor); + + if (itf_descriptor->bInterfaceClass != 0xFF || + itf_descriptor->bInterfaceSubClass != 0x5D || + itf_descriptor->bInterfaceProtocol != 0x01) + { + return 0; + } + + if (p_desc[1] == DESC_TYPE_VENDOR) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + for (uint8_t i = 0; i < itf_descriptor->bNumEndpoints; i++) { + tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; + if (TUSB_DESC_ENDPOINT != tu_desc_type(ep_desc)) break; + TU_VERIFY(usbd_edpt_open(rhport, ep_desc), 0); + if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) + endpoint_in_ = ep_desc->bEndpointAddress; + else + endpoint_out_ = ep_desc->bEndpointAddress; + drv_len += sizeof(tusb_desc_endpoint_t); + p_desc = tu_desc_next(p_desc); + } + + if (endpoint_out_ != 0xFF) + usbd_edpt_xfer(rhport, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE); + + TU_VERIFY(max_length >= drv_len, 0); + return drv_len; } static bool control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { - return true; + (void)rhport; + (void)stage; + (void)request; + return true; } static bool xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - if (ep_addr == endpoint_out_) - { - usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE); + (void)result; + (void)xferred_bytes; + if (ep_addr == endpoint_out_) { + usbd_edpt_xfer(rhport, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE); } - return true; + return true; } -// Public API - const usbd_class_driver_t* class_driver() { static const usbd_class_driver_t tud_class_driver_ = { - #if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= 2 .name = "XINPUT", - #else +#else .name = NULL, - #endif +#endif .init = init, .deinit = deinit, .reset = reset, @@ -110,31 +118,23 @@ const usbd_class_driver_t* class_driver() bool send_report_ready() { - if (tud_ready() && - (endpoint_in_ != 0xFF) && - (!usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_in_))) - { - return true; - } - return false; + return tud_ready() && + (endpoint_in_ != 0xFF) && + (!usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_in_)); } bool receive_report_ready() { - if (tud_ready() && - (endpoint_out_ != 0xFF) && - (!usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_out_))) - { - return true; - } - return false; + return tud_ready() && + (endpoint_out_ != 0xFF) && + (!usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_out_)); } bool send_report(const uint8_t *report, uint16_t len) { if (send_report_ready()) { - std::memcpy(ep_in_buffer_, report, std::min(len, ENDPOINT_SIZE)); + std::memcpy(ep_in_buffer_, report, std::min(len, (uint16_t)ENDPOINT_SIZE)); usbd_edpt_claim(BOARD_TUD_RHPORT, endpoint_in_); usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_in_, ep_in_buffer_, sizeof(XInput::InReport)); usbd_edpt_release(BOARD_TUD_RHPORT, endpoint_in_); @@ -151,11 +151,10 @@ bool receive_report(uint8_t *report, uint16_t len) usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE); usbd_edpt_release(BOARD_TUD_RHPORT, endpoint_out_); } - - std::memcpy(report, ep_out_buffer_, std::min(len, ENDPOINT_SIZE)); + std::memcpy(report, ep_out_buffer_, std::min(len, (uint16_t)ENDPOINT_SIZE)); return true; } } // namespace tud_xinput -#endif // (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XINPUT) \ No newline at end of file +#endif // (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XINPUT) diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h index 74a87473..9da42428 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h @@ -6,13 +6,12 @@ #include "tusb.h" #include "device/usbd_pvt.h" -namespace tud_xinput +namespace tud_xinput { bool send_report_ready(); bool send_report(const uint8_t *report, uint16_t len); bool receive_report(uint8_t *report, uint16_t len); const usbd_class_driver_t* class_driver(); - -} // namespace tud_xinput +} #endif // _TUD_XINPUT_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp index 6dab8113..14ff9024 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp @@ -21,23 +21,24 @@ void XboxOneHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t inst Gamepad::PadIn gp_in; - if (in_report->buttons[1] & XboxOne::Buttons1::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; - if (in_report->buttons[1] & XboxOne::Buttons1::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; - if (in_report->buttons[1] & XboxOne::Buttons1::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; - if (in_report->buttons[1] & XboxOne::Buttons1::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; - - if (in_report->buttons[1] & XboxOne::Buttons1::L3) gp_in.buttons |= gamepad.MAP_BUTTON_L3; - if (in_report->buttons[1] & XboxOne::Buttons1::R3) gp_in.buttons |= gamepad.MAP_BUTTON_R3; - if (in_report->buttons[1] & XboxOne::Buttons1::LB) gp_in.buttons |= gamepad.MAP_BUTTON_LB; - if (in_report->buttons[1] & XboxOne::Buttons1::RB) gp_in.buttons |= gamepad.MAP_BUTTON_RB; - if (in_report->buttons[0] & XboxOne::Buttons0::BACK) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; - if (in_report->buttons[0] & XboxOne::Buttons0::START) gp_in.buttons |= gamepad.MAP_BUTTON_START; - if (in_report->buttons[0] & XboxOne::Buttons0::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; - if (in_report->buttons[0] & XboxOne::Buttons0::GUIDE) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (in_report->buttons[0] & XboxOne::Buttons0::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; - if (in_report->buttons[0] & XboxOne::Buttons0::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; - if (in_report->buttons[0] & XboxOne::Buttons0::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; - if (in_report->buttons[0] & XboxOne::Buttons0::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; + const uint16_t b = in_report->buttons; + if (b & XboxOne::GamepadButtons::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; + if (b & XboxOne::GamepadButtons::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (b & XboxOne::GamepadButtons::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + if (b & XboxOne::GamepadButtons::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + + if (b & XboxOne::GamepadButtons::LEFT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_L3; + if (b & XboxOne::GamepadButtons::RIGHT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_R3; + if (b & XboxOne::GamepadButtons::LEFT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_LB; + if (b & XboxOne::GamepadButtons::RIGHT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_RB; + if (b & XboxOne::GamepadButtons::VIEW) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + if (b & XboxOne::GamepadButtons::MENU) gp_in.buttons |= gamepad.MAP_BUTTON_START; + if (b & XboxOne::GamepadButtons::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + if (in_report->guide_pressed) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + if (b & XboxOne::GamepadButtons::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; + if (b & XboxOne::GamepadButtons::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; + if (b & XboxOne::GamepadButtons::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; + if (b & XboxOne::GamepadButtons::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; gp_in.trigger_l = gamepad.scale_trigger_l(static_cast(in_report->trigger_l >> 2)); gp_in.trigger_r = gamepad.scale_trigger_r(static_cast(in_report->trigger_r >> 2)); diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index eaf05c39..18b8ca99 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -9,7 +9,14 @@ #include #include "Board/Config.h" +#include "Board/ogxm_log.h" #include "USBHost/HardwareIDs.h" + +#if defined(CONFIG_OGXM_DEBUG) +#define debug_printf OGXM_LOG +#else +#define debug_printf(...) ((void)0) +#endif #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/HostDriver.h" #include "USBHost/HostDriver/PS5/PS5.h" @@ -138,6 +145,10 @@ class HostManager device_slot.address = address; interface.gamepad_idx = gp_idx; interface.gamepad = gamepads_[gp_idx]; + // Wii U GC adapter: Xbox controllers report positive Y for up; Nintendo use negative + const bool xbox_stick_y = (driver_type == HostDriverType::XBOXONE || driver_type == HostDriverType::XBOX360 + || driver_type == HostDriverType::XBOX360W || driver_type == HostDriverType::XBOXOG); + interface.gamepad->set_stick_y_positive_is_up(xbox_stick_y); interface.driver->initialize(*interface.gamepad, device_slot.address, instance, report_desc, desc_len); return true; From 8f18ecfc6313db08071b62448786260c7665b6f8 Mon Sep 17 00:00:00 2001 From: Gary Date: Thu, 12 Feb 2026 07:10:55 -0500 Subject: [PATCH 12/42] Fixed a bug with Wii U mode that caused pushing Left stick up to input as down --- .../docs/XINPUT_JOYPAD_OS_COMPARISON.md | 160 ------------------ 1 file changed, 160 deletions(-) delete mode 100644 Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md diff --git a/Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md b/Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md deleted file mode 100644 index dadbbac2..00000000 --- a/Firmware/RP2040/docs/XINPUT_JOYPAD_OS_COMPARISON.md +++ /dev/null @@ -1,160 +0,0 @@ -# XInput (Xbox 360) Report & Descriptor Comparison: OGX-Mini vs joypad-os - -This document compares the XInput device implementation in this project (OGX-Mini) with [joypad-os](https://github.com/joypad-ai/joypad-os) so we can align behavior and add **real Xbox 360 console** support. - ---- - -## 1. Input report (20 bytes) — byte-by-byte - -Both projects use the **same 20-byte input report layout**. Field names differ; byte positions and semantics match. - -| Byte | OGX-Mini (`XInput::InReport`) | joypad-os (`xinput_in_report_t`) | Notes | -|------|------------------------------|-----------------------------------|--------| -| 0 | `report_id` | `report_id` | Always `0x00` | -| 1 | `report_size` | `report_size` | Always `0x14` (20) | -| 2 | `buttons[0]` | `buttons0` | D-pad (0–3), Start (4), Back (5), L3 (6), R3 (7) | -| 3 | `buttons[1]` | `buttons1` | LB (0), RB (1), Guide (2), — (3), A (4), B (5), X (6), Y (7) | -| 4 | `trigger_l` | `trigger_l` | 0–255 | -| 5 | `trigger_r` | `trigger_r` | 0–255 | -| 6–7 | `joystick_lx` | `stick_lx` | int16 LE (-32768..32767) | -| 8–9 | `joystick_ly` | `stick_ly` | int16 LE (Y inverted: positive = up) | -| 10–11 | `joystick_rx` | `stick_rx` | int16 LE | -| 12–13 | `joystick_ry` | `stick_ry` | int16 LE (Y inverted) | -| 14–19 | `reserved[6]` | `reserved[6]` | Zero padding | - -**Conclusion:** No change needed for the **input report format**. OGX-Mini’s mapping in `XInput.cpp` already matches joypad-os’s `xinput_mode.c` (same button bits and axis handling, including Y inversion). - ---- - -## 2. Button bit definitions — identical - -| Button | Byte | Bit | OGX-Mini | joypad-os | -|--------|------|-----|----------|-----------| -| D-pad U/D/L/R | 2 | 0–3 | `Buttons0::DPAD_*` | `XINPUT_BTN_DPAD_*` | -| Start | 2 | 4 | `Buttons0::START` | `XINPUT_BTN_START` | -| Back | 2 | 5 | `Buttons0::BACK` | `XINPUT_BTN_BACK` | -| L3 / R3 | 2 | 6–7 | `Buttons0::L3/R3` | `XINPUT_BTN_L3/R3` | -| LB / RB | 3 | 0–1 | `Buttons1::LB/RB` | `XINPUT_BTN_LB/RB` | -| Guide | 3 | 2 | `Buttons1::HOME` | `XINPUT_BTN_GUIDE` | -| A / B / X / Y | 3 | 4–7 | `Buttons1::A/B/X/Y` | `XINPUT_BTN_A/B/X/Y` | - -No code changes required for button mapping. - ---- - -## 3. Output report (8 bytes) — identical - -| Byte | Content | OGX-Mini | joypad-os | -|------|---------|----------|-----------| -| 0 | report_id | RUMBLE=0x00, LED=0x01 | Same | -| 1 | report_size | 0x08 | 0x08 | -| 2 | led | LED pattern | led | -| 3 | rumble_l | rumble_l | rumble_l | -| 4 | rumble_r | rumble_r | rumble_r | -| 5–7 | reserved | 0 | reserved[3] | - -No change needed for output report layout. - ---- - -## 4. Device descriptor — same VID/PID, minor bmAttributes - -| Field | OGX-Mini | joypad-os | -|-------|----------|-----------| -| idVendor | 0x045E | XINPUT_VID 0x045E | -| idProduct | 0x028E | XINPUT_PID 0x028E | -| bcdDevice | 0x0114 (2.14) | XINPUT_BCD_DEVICE 0x0114 | -| bmAttributes | 0x80 (no remote wakeup) | 0xA0 (remote wakeup) | - -Optional: set bmAttributes to `0xA0` in `DESC_DEVICE[]` if you want remote wakeup to match joypad-os and some 360 behavior. - ---- - -## 5. Configuration descriptor — main difference (PC vs 360 console) - -### OGX-Mini (current): PC-only, 1 interface - -- **wTotalLength:** 48 (0x30) -- **bNumInterfaces:** 1 -- **Interface 0:** Gamepad (0xFF / 0x5D / 0x01), 2 endpoints - - EP 0x81 IN (interrupt, 32 bytes, **bInterval 1**) - - EP 0x01 OUT (interrupt, 32 bytes, bInterval 8) -- Followed by a 16-byte vendor/HID-style descriptor (0x21 with bNumDescriptors, etc.). - -This is enough for **PC (XInput)** and many games. It is **not** enough for a **real Xbox 360 console**, which expects a multi-interface device and XSM3 security. - -### joypad-os: PC + Xbox 360 console, 4 interfaces - -- **wTotalLength:** 153 -- **bNumInterfaces:** 4 - -| Iface | Class / SubClass / Protocol | Purpose | Endpoints | -|-------|-----------------------------|---------|-----------| -| 0 | 0xFF / 0x5D / 0x01 | Gamepad | EP 0x81 IN (4 ms), EP 0x02 OUT (8 ms) | -| 1 | 0xFF / 0x5D / 0x03 | Audio (stub) | 4 EPs (not opened by driver) | -| 2 | 0xFF / 0x5D / 0x02 | Plugin (stub) | 1 EP (not opened) | -| 3 | 0xFF / **0xFD** / **0x13** | **Security (XSM3)** | 0 EPs (control only) | - -- Gamepad uses a **17-byte vendor descriptor** (0x21) after the interface, not the longer HID-style block. -- **Interface 3** is the security interface; the console uses **vendor control requests** on the device to run the XSM3 challenge/response. Without this interface and the XSM3 handler, the 360 console will not accept the device. - ---- - -## 6. What to add for real Xbox 360 console support - -To have OGX-Mini work on a **real Xbox 360** (like joypad-os), you need the following. - -### 6.1 Four-interface configuration descriptor - -- Replace the single-interface configuration in `Descriptors/XInput.h` with a **153-byte** configuration that includes: - - Interface 0: Gamepad (0xFF/0x5D/0x01) + 17-byte vendor descriptor + EP 0x81 IN (bInterval **4**), EP 0x02 OUT (8). - - Interface 1: Audio (0xFF/0x5D/0x03), stub only (descriptors present, no need to open EPs). - - Interface 2: Plugin (0xFF/0x5D/0x02), stub only. - - Interface 3: Security (0xFF/0xFD/0x13), no endpoints, security descriptor (0x41) only. - -You can copy the exact bytes from joypad-os’s `xinput_descriptors.h` (`xinput_config_descriptor[]`) and adapt to OGX-Mini’s naming (e.g. `DESC_CONFIGURATION[]` / `XINPUT_CONFIG_TOTAL_LEN`). - -### 6.2 XSM3 authentication - -- The 360 console sends **vendor control** requests (bRequest): - - **0x81** GET_SERIAL — device returns 29-byte ID (from libxsm3). - - **0x82** INIT_AUTH — console sends 34-byte challenge; device must respond with 46-byte response. - - **0x83** RESPOND — device returns challenge response (46 or 22 bytes). - - **0x84** KEEPALIVE — device responds with 0 bytes. - - **0x86** STATE — device returns 2-byte state (e.g. 2 = response ready). - - **0x87** VERIFY — console sends 22-byte verify; device responds with 22-byte response. - -- joypad-os uses **[libxsm3](https://github.com/InvoxiPlayGames/libxsm3)** (LGPL-2.1) to compute the challenge/response. You would need to: - - Add libxsm3 (or a port) to the OGX-Mini firmware. - - In the USB device stack, route **vendor control** transfers to an XInput/XSM3 handler (joypad-os does this in `tud_xinput_vendor_control_xfer_cb`). - - Implement the same state machine: on 0x82 store the challenge and call libxsm3 init; on 0x83 return the response; on 0x87 run verify and return the verify response; etc. - -### 6.3 Class driver `open()` for multiple interfaces - -- joypad-os’s `tud_xinput.c` `xinput_open()` is called for **each** interface. It: - - **Opens** only Interface 0 (gamepad): claims the interface and opens EP IN and EP OUT. - - **Skips** Interfaces 1 and 2 (audio, plugin): advances the descriptor pointer without opening endpoints. - - **Records** Interface 3 (security) index (e.g. `_sec_itf_num`) for XSM3; no endpoints. - -OGX-Mini’s `tud_xinput` currently assumes a single interface. It needs to be extended so that when the device presents the 4-interface configuration, the driver parses and skips the stub interfaces and only opens the gamepad endpoints, and recognizes the security interface (for routing vendor requests in usbd, not necessarily by interface number in the driver). - -### 6.4 Optional: IN endpoint interval - -- joypad-os uses **bInterval 4** (4 ms) for the gamepad IN endpoint; OGX-Mini uses **1** (1 ms). For 360 compatibility, changing the gamepad IN endpoint to **4** in the new configuration descriptor is a good idea. - ---- - -## 7. Summary table - -| Item | OGX-Mini | joypad-os | Action for 360 | -|------|----------|-----------|----------------| -| Input report (20 bytes) | Same layout | Same | None | -| Button bits | Same | Same | None | -| Output report (8 bytes) | Same | Same | None | -| VID/PID | 045E:028E | 045E:028E | None | -| Config: num interfaces | 1 | 4 | Add 4-interface, 153-byte config | -| Config: gamepad EP IN interval | 1 | 4 | Use 4 in new config | -| Vendor control (XSM3) | Not implemented | 0x81/82/83/84/86/87 | Add libxsm3 + vendor handler | -| Class driver multi-interface | Single iface | Opens if 0, skips 1–2, records 3 | Extend open() for 4-iface config | - -Implementing the 4-interface descriptor and XSM3 (with libxsm3) will align OGX-Mini with joypad-os’s XInput mode for **real Xbox 360 console** output while keeping the existing report code unchanged. From 04836d0afc12a676e38971e252103f70356bda9c Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Thu, 12 Feb 2026 07:25:14 -0500 Subject: [PATCH 13/42] Change project name to OGX-Mini 2026 Updated project name and year in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca738846..74421805 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# OGX-Mini Fork +# OGX-Mini 2026 ![OGX-Mini Boards](images/OGX-Mini-github.jpg "OGX-Mini Boards") Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. From 97c6aca9a3584376460d1338a5b0698b84cfa168 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Thu, 26 Feb 2026 16:07:31 -0500 Subject: [PATCH 14/42] XInput: Xbox 360 (XSM3) support and joypad-os alignment --- Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/CMakeLists.txt | 77 ++++++++- Firmware/RP2040/cmake/Platform/PICO.cmake | 17 ++ Firmware/RP2040/docs/IMPROVEMENTS.md | 81 +++++++++ Firmware/RP2040/docs/README.md | 18 ++ .../docs/XInput_joypad-os_comparison.md | 40 +++++ Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md | 74 +++++++++ Firmware/RP2040/scripts/build-with-vs.cmd | 5 + Firmware/RP2040/scripts/build-with-vs.ps1 | 43 +++++ Firmware/RP2040/scripts/test_xsm3_windows.py | 124 ++++++++++++++ Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 48 +++++- Firmware/RP2040/src/Board/Config.h | 7 + Firmware/RP2040/src/Descriptors/XInput.h | 55 ++++-- Firmware/RP2040/src/Gamepad/Gamepad.h | 13 ++ .../src/OGXMini/Board/ESP32_Blueretro_I2C.cpp | 8 +- .../src/OGXMini/Board/Four_Channel_I2C.cpp | 15 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 29 +++- .../RP2040/src/OGXMini/Board/Standard.cpp | 13 +- Firmware/RP2040/src/TaskQueue/TaskQueue.h | 2 + .../src/USBDevice/DeviceDriver/PS3/PS3.cpp | 41 +++-- .../USBDevice/DeviceDriver/XInput/XInput.cpp | 157 +++++++++++++++++- .../XInput/tud_xinput/tud_xinput.cpp | 98 ++++++++--- .../RP2040/src/USBDevice/tud_callbacks.cpp | 3 + .../RP2040/src/USBHost/HostDriver/PS5/PS5.cpp | 6 +- Firmware/RP2040/src/USBHost/HostManager.h | 3 +- .../RP2040/src/UserSettings/UserSettings.cpp | 13 ++ 26 files changed, 908 insertions(+), 84 deletions(-) create mode 100644 Firmware/RP2040/cmake/Platform/PICO.cmake create mode 100644 Firmware/RP2040/docs/IMPROVEMENTS.md create mode 100644 Firmware/RP2040/docs/README.md create mode 100644 Firmware/RP2040/docs/XInput_joypad-os_comparison.md create mode 100644 Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md create mode 100644 Firmware/RP2040/scripts/build-with-vs.cmd create mode 100644 Firmware/RP2040/scripts/build-with-vs.ps1 create mode 100644 Firmware/RP2040/scripts/test_xsm3_windows.py diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index dfc6cda9..c425732b 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a3") \ No newline at end of file +set(FW_VERSION "v1.0.0a4") \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 36d45e1a..924cc423 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -13,6 +13,11 @@ set(SRC ${CMAKE_CURRENT_LIST_DIR}/src) set(EXTERNAL_DIR ${CMAKE_CURRENT_LIST_DIR}/../external) set(PICOSDK_VERSION_TAG "2.1.0") +# Default Pico SDK path when not set (e.g. by CMake Tools or command line) +if(NOT PICO_SDK_PATH) + set(PICO_SDK_PATH ${EXTERNAL_DIR}/pico-sdk CACHE PATH "Path to Pico SDK") +endif() + include(${CMAKE_CURRENT_LIST_DIR}/../cmake/init_submodules.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../cmake/patch_libs.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../cmake/generate_gatt_header.cmake) @@ -72,6 +77,12 @@ set(SOURCES_BOARD ${SRC}/USBDevice/DeviceDriver/WebApp/WebApp.cpp ${SRC}/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.cpp + # libxsm3 for Xbox 360 (XSM3) authentication in XInput mode + ${EXTERNAL_DIR}/libxsm3/xsm3.c + ${EXTERNAL_DIR}/libxsm3/usbdsec.c + ${EXTERNAL_DIR}/libxsm3/excrypt_des.c + ${EXTERNAL_DIR}/libxsm3/excrypt_parve.c + ${EXTERNAL_DIR}/libxsm3/excrypt_sha.c ) set(LIBS_BOARD # Base @@ -173,7 +184,49 @@ else() endif() -add_definitions(-DOGXM_BOARD=${OGXM_BOARD}) +# Optional: default or lock USB output mode. +# OGXM_FIXED_DRIVER = one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, PS3, PSCLASSIC, WEBAPP. +# Empty = use first valid driver as default, combos enabled. +# Set = use that mode as default (first boot / NVS init). If OGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF (default): +# combos disabled, mode locked. If OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON: default is this mode, combos still work. +set(OGXM_FIXED_DRIVER "" CACHE STRING "Default/lock output mode. One of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, PS3, PSCLASSIC, WEBAPP. Empty = combos enabled.") +set(OGXM_FIXED_DRIVER_ALLOW_COMBOS OFF CACHE BOOL "If OGXM_FIXED_DRIVER is set: ON = use it as default but allow combos to change mode; OFF = lock to that mode, combos disabled.") +if(OGXM_FIXED_DRIVER) + add_compile_definitions(CONFIG_OGXM_FIXED_DRIVER=1) + if(OGXM_FIXED_DRIVER_ALLOW_COMBOS) + add_compile_definitions(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS=1) + endif() + if(OGXM_FIXED_DRIVER STREQUAL "XBOXOG") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=1) + elseif(OGXM_FIXED_DRIVER STREQUAL "XBOXOG_SB") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=2) + elseif(OGXM_FIXED_DRIVER STREQUAL "XBOXOG_XR") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=3) + elseif(OGXM_FIXED_DRIVER STREQUAL "XINPUT") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=4) + elseif(OGXM_FIXED_DRIVER STREQUAL "PS3") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=5) + elseif(OGXM_FIXED_DRIVER STREQUAL "DINPUT") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=6) + elseif(OGXM_FIXED_DRIVER STREQUAL "PSCLASSIC") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=7) + elseif(OGXM_FIXED_DRIVER STREQUAL "SWITCH") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=8) + elseif(OGXM_FIXED_DRIVER STREQUAL "WIIU") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=9) + elseif(OGXM_FIXED_DRIVER STREQUAL "WEBAPP") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=100) + else() + message(FATAL_ERROR "OGXM_FIXED_DRIVER must be one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, PS3, PSCLASSIC, WEBAPP") + endif() + if(OGXM_FIXED_DRIVER_ALLOW_COMBOS) + message(STATUS "Default output mode: ${OGXM_FIXED_DRIVER} (combos enabled)") + else() + message(STATUS "Fixed output mode: ${OGXM_FIXED_DRIVER} (combos disabled)") + endif() +endif() + +# Do not add -DOGXM_BOARD here; Config.h defines OGXM_BOARD from CONFIG_OGXM_BOARD_* to avoid redefinition warnings if(EN_USB_HOST) message(STATUS "USB host enabled.") @@ -299,6 +352,15 @@ if(NOT EN_BLUETOOTH) add_compile_definitions(PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64) endif() +# Cross-compile: skip linker in compiler check (ARM linker does not accept Windows flags) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +set(CMAKE_SYSTEM_NAME PICO) +set(CMAKE_CXX_STANDARD_LIBRARIES "") +set(CMAKE_C_STANDARD_LIBRARIES "") + +# Use our Platform/PICO.cmake so CMake does not add Windows linker flags (--out-implib, etc.) +list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) + include(${PICO_SDK_PATH}/pico_sdk_init.cmake) project(${FW_NAME} C CXX ASM) @@ -336,6 +398,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_definitions(CFG_TUSB_DEBUG=1) add_compile_definitions(OGXM_DEBUG=1) + add_compile_definitions(CONFIG_OGXM_DEBUG=1) target_compile_options(${FW_NAME} PRIVATE -Wall # Enable most warnings @@ -370,7 +433,9 @@ pico_set_program_version(${FW_NAME} ${FW_VERSION}) target_include_directories(${FW_NAME} PRIVATE ${SRC} + ${EXTERNAL_DIR}/libxsm3 ) +target_compile_definitions(${FW_NAME} PRIVATE XSM3_NO_DEBUGGING=1 XSM3_EMBEDDED=1) if(EN_RGB) pico_generate_pio_header(${FW_NAME} ${SRC}/Board/Pico_WS2812/WS2812.pio) @@ -406,6 +471,16 @@ else() set(EXE_FILENAME "${FW_NAME}-${FW_VERSION}-${OGXM_BOARD}${BUILD_STR}") endif() +# Output filename always reflects the mode: fixed driver name (XINPUT, PS3, ...) or "Multi" for combo mode +if(OGXM_FIXED_DRIVER) + set(EXE_FILENAME "${EXE_FILENAME}-${OGXM_FIXED_DRIVER}") + if(OGXM_FIXED_DRIVER_ALLOW_COMBOS) + set(EXE_FILENAME "${EXE_FILENAME}-Combos") + endif() +else() + set(EXE_FILENAME "${EXE_FILENAME}-Multi") +endif() + set_target_properties(${FW_NAME} PROPERTIES OUTPUT_NAME ${EXE_FILENAME}) pico_add_extra_outputs(${FW_NAME}) \ No newline at end of file diff --git a/Firmware/RP2040/cmake/Platform/PICO.cmake b/Firmware/RP2040/cmake/Platform/PICO.cmake new file mode 100644 index 00000000..4ec1b156 --- /dev/null +++ b/Firmware/RP2040/cmake/Platform/PICO.cmake @@ -0,0 +1,17 @@ +# Platform file for PICO (bare-metal ARM). Overrides Windows-GNU link rules +# so the ARM linker is not given Windows-only flags (--out-implib, --major-image-version). + +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) +set(CMAKE_EXECUTABLE_SUFFIX .elf) + +if(CMAKE_HOST_WIN32) + include(Platform/WindowsPaths) +else() + include(Platform/UnixPaths) +endif() + +# Bare-metal executable link: no Windows implib or image version flags +# (C, CXX, and ASM - boot_stage2 is ASM-only) +set(CMAKE_C_LINK_EXECUTABLE " -o ") +set(CMAKE_CXX_LINK_EXECUTABLE " -o ") +set(CMAKE_ASM_LINK_EXECUTABLE " -o ") diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md new file mode 100644 index 00000000..3b90954c --- /dev/null +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -0,0 +1,81 @@ +# Firmware Improvements + +Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. + +**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, and latency improvements (see below). + +--- + +## PS3 mode — input delays and stuck inputs + +**Source:** Fixes from [OGX-Mini-Plus](https://github.com/guimaraf/OGX-Mini-Plus) (v1.1.1) — *“PS3 Driver Fixes - Fixed input delays and stuck inputs.”* + +**File:** `src/USBDevice/DeviceDriver/PS3/PS3.cpp` + +### Changes + +1. **L2/R2 axis values** + - `report_in_.l2_axis` and `report_in_.r2_axis` are now set from `gp_in.trigger_l` and `gp_in.trigger_r`. + - Previously left at zero, which could cause stuck or incorrect trigger behaviour on PS3. Filling these is required for many PS3 games. + +2. **Joystick centre and deadzone** + - Replaced generic `Scale::int16_to_uint8()` (centre 128) with PS3-specific mapping: + - Centre **0x7F (127)** and ~5% deadzone (~1640 on a ±32768 scale). + - In deadzone, sticks report exactly 0x7F so the console does not see drift. + - Outside deadzone, values are scaled into 0–254 so 127 remains the logical centre. + - Avoids stick drift and “stuck” stick behaviour caused by wrong centre or jitter. + +3. **D-pad in analog mode** + - When `gamepad.analog_enabled()` is true, D-pad axes (`up_axis`, `down_axis`, `left_axis`, `right_axis`) are now derived from the **digital** D-pad bits instead of `gp_in.analog[ANALOG_OFF_*]`. + - Prevents noisy analog D-pad values from causing stuck or wrong D-pad input on PS3. + +4. **Face button axes (digital / non-analog branch)** + - Corrected mapping so that: + - `circle_axis` = BUTTON_B (was BUTTON_X) + - `cross_axis` = BUTTON_A (was BUTTON_B) + - `square_axis` = BUTTON_X (was BUTTON_A) + - Circle / Cross / Square now match the intended face buttons. + +--- + +## Latency reduction + +**Goal:** Reduce input-to-output latency in the device (Core0) main loop. + +### Main loop delay + +- **Before:** The device loop used `sleep_ms(1)` every iteration, limiting the loop to ~1000 Hz and adding up to ~1 ms before the next read/send. +- **After:** Configurable delay in **microseconds** via `MAIN_LOOP_DELAY_US` in `src/Board/Config.h`: + - **Default: 250 µs** — loop runs at ~4000 Hz; average extra delay reduced (e.g. from ~0.5 ms to ~0.125 ms). + - **0** — no delay; loop runs as fast as possible for minimum latency (higher CPU use). + - **1000** — 1 ms (same as original behaviour). + +**Files changed:** + +- `src/Board/Config.h` — added `MAIN_LOOP_DELAY_US` and comment (override via CMake documented). +- `src/OGXMini/Board/Standard.cpp` — use `sleep_us(MAIN_LOOP_DELAY_US)` when `> 0`, and `#include `. +- `src/OGXMini/Board/PicoW.cpp` — same. +- `src/OGXMini/Board/Four_Channel_I2C.cpp` — same. + +### How to use + +| Goal | Setting | +|------|--------| +| Lower latency (default) | Leave `MAIN_LOOP_DELAY_US` at **250** (already set). | +| Minimum latency | Set `MAIN_LOOP_DELAY_US=0`, e.g. in CMake: `add_compile_definitions(MAIN_LOOP_DELAY_US=0)` or `-DCMAKE_CXX_FLAGS="-DMAIN_LOOP_DELAY_US=0"`. | +| Slightly lower CPU use | Use e.g. `MAIN_LOOP_DELAY_US=500`. | + +### Notes + +- Core1 (USB host / gamepad polling) already runs with no sleep in its loop. +- USB full-speed has a 1 ms frame; reports are still limited by that; the improvement is that each report uses the **latest** input. +- For lowest end-to-end latency, use a **wired** controller and a USB host board; Bluetooth (e.g. Pico W) adds more latency. + +--- + +## Summary + +| Area | Improvement | +|------|-------------| +| **PS3** | Stuck inputs and input delays addressed via L2/R2 axes, joystick centre/deadzone, D-pad handling, and face button mapping. | +| **Latency** | Main loop delay reduced from 1 ms to 250 µs by default, with option for 0 µs for minimum latency. | diff --git a/Firmware/RP2040/docs/README.md b/Firmware/RP2040/docs/README.md new file mode 100644 index 00000000..5ce0a040 --- /dev/null +++ b/Firmware/RP2040/docs/README.md @@ -0,0 +1,18 @@ +# OGX-Mini RP2040 Firmware — Documentation + +Documentation for the OGX-Mini 2026 RP2040 firmware (controller adapter for OG Xbox, XInput, PS3, Switch, Wii U, etc.). + +## Contents + +| Document | Description | +|----------|-------------| +| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Improvements and fixes applied to this firmware (PS3 driver, latency, etc.). | + +## Building + +See the project root and `scripts/build-with-vs.ps1` (or CMake directly) for build instructions. Board is selected via CMake `OGXM_BOARD` (e.g. `PI_PICO`, `PI_PICO2W`, `RP2040_ZERO`). + +## Configuration + +- **Board / driver:** Set at CMake configure time (`OGXM_BOARD`, fixed driver options). +- **Latency:** `MAIN_LOOP_DELAY_US` in `src/Board/Config.h` (or override via CMake). See [IMPROVEMENTS.md](IMPROVEMENTS.md#latency). diff --git a/Firmware/RP2040/docs/XInput_joypad-os_comparison.md b/Firmware/RP2040/docs/XInput_joypad-os_comparison.md new file mode 100644 index 00000000..93c73c24 --- /dev/null +++ b/Firmware/RP2040/docs/XInput_joypad-os_comparison.md @@ -0,0 +1,40 @@ +# XInput vs joypad-os comparison + +Comparison of OGX-Mini XInput (Xbox 360) with joypad-os for descriptor and runtime behavior, to align with what works on the 360. + +## Descriptors + +| Item | joypad-os | OGX-Mini (after alignment) | +|------|-----------|-----------------------------| +| **Device** | 0x045E / 0x028E, bcd 0x0114, bNumConfigurations = 1 | Same (byte-identical) | +| **Config** | 153 bytes, 4 interfaces, bConfigurationValue 1, bMaxPower 0xFA | Same (byte-identical) | +| **Config callback** | `tud_descriptor_configuration_cb(uint8_t index)` — ignores `index`, returns mode-specific config | Now return `nullptr` for `index != 0` (single config) | +| **String 4 (XSM3)** | 96-char buffer, **full** security string (no truncation) | Was truncated to 31 chars; now use full length in dedicated buffer | + +## Mode / enumeration + +| Item | joypad-os | OGX-Mini | +|------|-----------|----------| +| **When XInput is active** | `output_mode` loaded from flash before USB init; device presents XInput descriptors from first enumeration | Fixed XInput driver; always present XInput from first enumeration | +| **Driver registration** | `usbd_app_driver_get_cb()` returns `driver_count = 1`, `tud_xinput_class_driver()` when mode is XINPUT | Single driver from `DeviceManager::get_driver()->get_class_driver()` (XInput) | + +## Control transfer handling + +| Item | joypad-os | OGX-Mini | +|------|-----------|----------| +| **Vendor callback** | `tud_vendor_control_xfer_cb()` calls `tud_xinput_vendor_control_xfer_cb()` when `output_mode == XINPUT` | `tud_vendor_control_xfer_cb()` forwards to active driver `vendor_control_xfer_cb()` | +| **Class driver control** | `xinput_control_xfer_cb()` returns `true` and does **nothing**; XSM3 is handled only in vendor callback | We forward class `control_xfer_cb` to driver `vendor_control_xfer_cb()` so both paths reach XSM3 | + +## XSM3 runtime (already aligned) + +- XSM3 init at driver init (not in 0x81 callback). +- 0x82 / 0x87: only set state; crypto in `process()` loop. +- 0x83: 46 bytes init, 22 bytes verify. +- 0x86: state 1 = processing, 2 = ready. + +## Changes made from this comparison + +1. **Configuration descriptor** — `get_descriptor_configuration_cb(index)`: return `nullptr` when `index != 0` (we have one config). +2. **String descriptor index 4** — Use a 96-element buffer and the **full** XSM3 security string (no 31-character truncation from `get_string_descriptor()`). + +If the 360 still does not send XSM3 requests after these fixes, next steps: confirm joypad-os on the same 360 shows XSM3 traffic, and/or add logging of **all** control requests (e.g. in TinyUSB) to see if any vendor/class traffic arrives. diff --git a/Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md b/Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md new file mode 100644 index 00000000..8fc6d6b6 --- /dev/null +++ b/Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md @@ -0,0 +1,74 @@ +# Debug build and UART on Windows + +## Build Debug XInput firmware (Pico 2 W) + +From the `RP2040` folder: + +```powershell +.\scripts\build-with-vs.ps1 -Config Debug -FixedDriver XINPUT +``` + +Output: `build_pico2w\OGX-Mini-v1.0.0a4-PI_PICO2W-XINPUT-Debug.uf2` + +Flash this .uf2 to the Pico 2 W. Debug builds enable: + +- **UART** for log output (TX = GPIO 0, RX = GPIO 1) +- **OGXM_LOG** / **XSM3** messages (e.g. `XSM3: 0x81 GET_SERIAL`, `XSM3: 0x86 GET_STATE`) + +## Reading UART on Windows + +### 1. Connect the Pico 2 W UART to the PC + +- **Pico 2 W** (and most Pico boards): **GPIO 0 = UART TX** (from Pico), **GPIO 1 = UART RX** (into Pico). +- Use a **USB–serial adapter** (e.g. CP2102, FT232, CH340) or a second Pico in UART mode: + - Connect adapter **RX** to Pico **GPIO 0 (TX)**. + - Connect **GND** to **GND**. + - Do **not** connect adapter TX to Pico unless you need to send data; for log viewing, RX + GND is enough. + +### 2. Find the COM port + +- Open **Device Manager** → **Ports (COM & LPT)**. +- Note the COM number for your USB–serial device (e.g. **COM4**). + +### 3. Open a serial terminal + +**Option A – PuTTY (recommended)** + +1. Download [PuTTY](https://www.putty.org/). +2. Run PuTTY → **Session**: + - **Connection type**: Serial. + - **Serial line**: `COM4` (use your port). + - **Speed**: **115200** (Pico default). +3. Click **Open**. + +**Option B – Windows Terminal / PowerShell (if serial module available)** + +```powershell +# List serial ports (PowerShell) +[System.IO.Ports.SerialPort]::getportnames() +``` + +Then use a terminal that can open a serial port (e.g. PuTTY, or a VS Code serial extension). + +**Option C – VS Code** + +- Install an extension such as **Serial Monitor** or **Serial Port Utility**. +- Select the correct COM port and **115200** baud. + +### 4. Baud rate + +Use **115200** unless the firmware is built with a different `PICO_DEFAULT_UART_BAUD_RATE`. + +### 5. What you’ll see (XInput debug) + +When the controller is used (or the XSM3 test script runs), you should see lines like: + +``` +OGXM: XSM3: 0x81 GET_SERIAL +OGXM: XSM3: 0x86 GET_STATE +OGXM: XSM3: 0x82 challenge init received, processing +OGXM: XSM3: 0x83 sending init response (0x30 bytes) +... +``` + +On an **Xbox 360** you’ll see the full auth sequence (0x81 → 0x82 → 0x83 → 0x86 → 0x87 → 0x83). On **Windows**, only 0x81 and 0x86 may appear unless you run the test script. diff --git a/Firmware/RP2040/scripts/build-with-vs.cmd b/Firmware/RP2040/scripts/build-with-vs.cmd new file mode 100644 index 00000000..862018dd --- /dev/null +++ b/Firmware/RP2040/scripts/build-with-vs.cmd @@ -0,0 +1,5 @@ +@echo off +REM Build OGX-Mini for Pico 2 W (uses VS for pioasm/picotool). Run from RP2040 folder. +cd /d "%~dp0.." +powershell -ExecutionPolicy Bypass -File "%~dp0build-with-vs.ps1" %* +exit /b %ERRORLEVEL% diff --git a/Firmware/RP2040/scripts/build-with-vs.ps1 b/Firmware/RP2040/scripts/build-with-vs.ps1 new file mode 100644 index 00000000..d811caed --- /dev/null +++ b/Firmware/RP2040/scripts/build-with-vs.ps1 @@ -0,0 +1,43 @@ +# Build OGX-Mini firmware for Pico 2 W, using Visual Studio's host compiler for SDK tools (pioasm, picotool). +# Run from RP2040 folder: .\scripts\build-with-vs.ps1 + +param( + [string] $BuildDir = "build_pico2w", + [string] $Config = "Release", + [string] $FixedDriver = "", # e.g. PS3, XINPUT to lock output mode (no combos) + [switch] $FixedDriverAllowCombos # if -FixedDriver set: allow combos to change mode +) + +$ErrorActionPreference = "Stop" +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$RP2040Dir = Split-Path -Parent $ScriptDir +$VsPath = "${env:ProgramFiles}\Microsoft Visual Studio\2022\Community" +if (-not (Test-Path $VsPath)) { + $VsPath = "${env:ProgramFiles}\Microsoft Visual Studio\2022\Professional" +} +if (-not (Test-Path $VsPath)) { + $VsPath = "${env:ProgramFiles}\Microsoft Visual Studio\2022\Enterprise" +} +$Vcvars = "$VsPath\VC\Auxiliary\Build\vcvars64.bat" +if (-not (Test-Path $Vcvars)) { + Write-Error "Visual Studio 2022 not found (no vcvars64.bat). Install VS 2022 with 'Desktop development with C++' workload." +} + +$PicoSdkPath = Join-Path $RP2040Dir "..\external\pico-sdk" +$ConfigureArgs = @( + "-G", "Ninja", + "-DCMAKE_BUILD_TYPE=$Config", + "-DOGXM_BOARD=PI_PICO2W", + "-DPICO_SDK_PATH=$($PicoSdkPath -replace '\\','/')" +) +# Always pass OGXM_FIXED_DRIVER so the output filename matches the built mode (avoids reusing cached PS3/XINPUT name) +if ($FixedDriver) { + $ConfigureArgs += "-DOGXM_FIXED_DRIVER=$FixedDriver" + if ($FixedDriverAllowCombos) { $ConfigureArgs += "-DOGXM_FIXED_DRIVER_ALLOW_COMBOS=ON" } +} else { + $ConfigureArgs += "-DOGXM_FIXED_DRIVER=" +} +$ConfigureArgsStr = $ConfigureArgs -join " " + +& cmd /c "call `"$Vcvars`" && cd /d `"$RP2040Dir`" && cmake -B `"$BuildDir`" $ConfigureArgsStr && cmake --build `"$BuildDir`" --config $Config" +exit $LASTEXITCODE diff --git a/Firmware/RP2040/scripts/test_xsm3_windows.py b/Firmware/RP2040/scripts/test_xsm3_windows.py new file mode 100644 index 00000000..26868012 --- /dev/null +++ b/Firmware/RP2040/scripts/test_xsm3_windows.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +""" +Test XSM3 (Xbox 360 Security Method 3) vendor requests on Windows. + +Sends control transfers 0x81 (get serial/ID) and 0x86 (get auth state) to verify +the OGX-Mini XInput device responds correctly. Full auth (0x82/0x83/0x87) requires +an Xbox 360 console or a host that can generate valid challenge data. + +Requirements: + pip install pyusb + +On Windows you may need to replace the Xbox 360 driver with WinUSB so libusb can +claim the device: use Zadig (https://zadig.akeo.ie/) and select the "Xbox 360 Controller" +then "Replace Driver" with WinUSB. The controller will stop working as a gamepad +until you restore the original driver (Zadig can do that too). + +Usage: + python scripts/test_xsm3_windows.py + # or from RP2040 folder: + python test_xsm3_windows.py +""" + +import sys + +try: + import usb.core + import usb.util +except ImportError: + print("Install pyusb: pip install pyusb") + sys.exit(1) + +# Microsoft Xbox 360 Controller +VID, PID = 0x045E, 0x028E + +# Vendor control: bmRequestType, bRequest +# 0x81 = GET serial/ID (0x1D bytes), 0x86 = GET state (2 bytes) +REQ_GET_SERIAL = 0x81 +REQ_GET_STATE = 0x86 +SERIAL_LEN = 0x1D +STATE_LEN = 2 + + +def find_device(): + dev = usb.core.find(idVendor=VID, idProduct=PID) + if dev is None: + print("No Xbox 360 controller (045E:028E) found.") + return None + return dev + + +def main(): + dev = find_device() + if dev is None: + sys.exit(1) + + try: + if dev.is_kernel_driver_active(0): + try: + dev.detach_kernel_driver(0) + print("Detached kernel driver for interface 0.") + except usb.core.USBError as e: + print("Could not detach kernel driver:", e) + print("Try using Zadig to install WinUSB for this device.") + sys.exit(1) + dev.set_configuration() + except usb.core.USBError as e: + print("USB error:", e) + print("If the device is in use by the Xbox 360 driver, use Zadig to replace it with WinUSB.") + sys.exit(1) + + print("Device found. Testing XSM3 vendor requests...") + ok = True + + # 0x81: Get serial/identification (29 bytes) + try: + data = dev.ctrl_transfer( + 0xC0, # bmRequestType: Vendor, Device, IN + REQ_GET_SERIAL, + 0, 0, + SERIAL_LEN, + timeout=1000, + ) + if len(data) == SERIAL_LEN: + print(" 0x81 (GET_SERIAL): OK, 29 bytes") + print(" First 8 bytes (hex):", " ".join(f"{b:02X}" for b in data[:8])) + else: + print(" 0x81 (GET_SERIAL): unexpected length", len(data)) + ok = False + except usb.core.USBError as e: + print(" 0x81 (GET_SERIAL): FAIL -", e) + ok = False + + # 0x86: Get auth state (2 bytes; 2 = ready) + try: + data = dev.ctrl_transfer( + 0xC0, + REQ_GET_STATE, + 0, 0, + STATE_LEN, + timeout=1000, + ) + if len(data) >= 2: + state = data[0] | (data[1] << 8) + print(" 0x86 (GET_STATE): OK, state =", state, "(2 = ready)") + if state != 1 and state != 2: + print(" (unexpected value; 1=processing, 2=ready)") + else: + print(" 0x86 (GET_STATE): unexpected length", len(data)) + ok = False + except usb.core.USBError as e: + print(" 0x86 (GET_STATE): FAIL -", e) + ok = False + + if ok: + print("\nXSM3 vendor requests succeeded. Device is responding to auth commands.") + print("Full auth (0x82/0x83/0x87) is only run by an Xbox 360 console;") + print("to verify that, plug the controller into a 360.") + else: + print("\nOne or more requests failed.") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index 02cdc520..b9e7bc45 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -7,6 +7,7 @@ #include "btstack_run_loop.h" #include "uni.h" +#include "parser/uni_hid_parser_ds5.h" #include "sdkconfig.h" #include "Bluepad32/Bluepad32.h" @@ -35,6 +36,10 @@ btstack_timer_source_t led_timer_; bool led_timer_set_{false}; bool feedback_timer_set_{false}; +// PS5: touchpad click toggles adaptive triggers (per-controller state) +static bool adaptive_trigger_enabled_[MAX_GAMEPADS]{false}; +static bool prev_touchpad_clicked_[MAX_GAMEPADS]{false}; + bool any_connected() { for (auto& device : bt_devices_) @@ -148,6 +153,12 @@ static void init(int argc, const char** arg_V) { } static void init_complete_cb(void) { + // Faster pairing: more aggressive GAP inquiry/periodic (units: 1.28s). + // Defaults are inquiry=3, max=5, min=4; slightly tighter so we discover and reconnect sooner. + uni_bt_set_gap_inquiry_length(2); + uni_bt_set_gap_max_peridic_length(4); + uni_bt_set_gap_min_peridic_length(3); + uni_bt_enable_new_connections_unsafe(true); // uni_bt_del_keys_unsafe(); uni_property_dump_all(); @@ -175,6 +186,7 @@ static void device_disconnected_cb(uni_hid_device_t* device) { } bt_devices_[idx].connected = false; + prev_touchpad_clicked_[idx] = false; bt_devices_[idx].gamepad->reset_pad_in(); if (!led_timer_set_ && !any_connected()) { @@ -198,6 +210,20 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { bt_devices_[idx].connected = true; + // Set controller player LED to match slot (e.g. Wii U: LED 1 = player 1, LED 2 = player 2). + // Same as Bluepad32 NINA platform: set_player_leds(d, BIT(idx)). + if (device->report_parser.set_player_leds != nullptr) { + device->report_parser.set_player_leds(device, static_cast(1u << idx)); + } + + // PS5: start with adaptive triggers off; touchpad click toggles them. + if (device->controller_type == CONTROLLER_TYPE_PS5Controller) { + adaptive_trigger_enabled_[idx] = false; + ds5_adaptive_trigger_effect_t off = ds5_new_adaptive_trigger_effect_off(); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &off); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &off); + } + if (led_timer_set_) { led_timer_set_ = false; btstack_run_loop_remove_timer(&led_timer_); @@ -219,7 +245,7 @@ static void oob_event_cb(uni_platform_oob_event_t event, void* data) { // Set to 1 to print all Bluepad32 controller inputs to UART (only when state changes) #ifndef BLUEPAD32_UART_LOG_INPUT -#define BLUEPAD32_UART_LOG_INPUT 1 +#define BLUEPAD32_UART_LOG_INPUT 0 #endif static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* controller) { @@ -231,7 +257,25 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr uni_gamepad_t *uni_gp = &controller->gamepad; int idx = uni_hid_device_get_idx_for_instance(device); - + + // PS5: touchpad click toggles adaptive triggers on/off + if (device->controller_type == CONTROLLER_TYPE_PS5Controller && idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { + bool touchpad_clicked = (uni_gp->misc_buttons & MISC_BUTTON_TOUCHPAD) != 0; + if (touchpad_clicked && !prev_touchpad_clicked_[idx]) { + adaptive_trigger_enabled_[idx] = !adaptive_trigger_enabled_[idx]; + if (adaptive_trigger_enabled_[idx]) { + ds5_adaptive_trigger_effect_t on = ds5_new_adaptive_trigger_effect_feedback(5, 4); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &on); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &on); + } else { + ds5_adaptive_trigger_effect_t off = ds5_new_adaptive_trigger_effect_off(); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &off); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &off); + } + } + prev_touchpad_clicked_[idx] = touchpad_clicked; + } + #if BLUEPAD32_UART_LOG_INPUT { bool changed = std::memcmp(uni_gp, &prev_uni_gp[idx], sizeof(uni_gamepad_t)) != 0; diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index 658378e2..2ece95f8 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -17,6 +17,13 @@ #define MAX_GAMEPADS 1 #endif +/** Main loop delay (device/core0) in microseconds. Lower = less input latency, higher CPU. + * 0 = no delay (lowest latency, highest CPU). 250–500 = good balance. 1000 = 1 ms (original). + * Override in CMake: add_compile_definitions(MAIN_LOOP_DELAY_US=0) for minimum latency. */ +#ifndef MAIN_LOOP_DELAY_US + #define MAIN_LOOP_DELAY_US 250 +#endif + #if defined(CONFIG_OGXM_BOARD_PI_PICO) || defined(CONFIG_OGXM_BOARD_PI_PICO2) #define OGXM_BOARD PI_PICO #define PIO_USB_DP_PIN 0 // DM = 1 diff --git a/Firmware/RP2040/src/Descriptors/XInput.h b/Firmware/RP2040/src/Descriptors/XInput.h index c625d889..38334fd2 100644 --- a/Firmware/RP2040/src/Descriptors/XInput.h +++ b/Firmware/RP2040/src/Descriptors/XInput.h @@ -170,10 +170,13 @@ namespace XInput static_assert(sizeof(OutReport) == 8, "XInput::OutReport is misaligned"); #pragma pack(pop) + // String descriptors — from joypad-os xinput_descriptors.h static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 }; - static const uint8_t STRING_MANUFACTURER[] = "Microsoft"; + static const uint8_t STRING_MANUFACTURER[] = "\xa9Microsoft Corporation"; static const uint8_t STRING_PRODUCT[] = "Xbox 360 Controller"; static const uint8_t STRING_VERSION[] = "1.0"; + // XSM3 security string (iInterface=4), joypad-os: XINPUT_SECURITY_STRING + static const uint8_t STRING_XSM3[] = "Xbox Security Method 3, Version 1.00, \xa9 2005 Microsoft Corporation. All rights reserved."; static const uint8_t *DESC_STRING[] __attribute__((unused)) = { @@ -181,8 +184,10 @@ namespace XInput STRING_MANUFACTURER, STRING_PRODUCT, STRING_VERSION, + STRING_XSM3, }; + // Device descriptor — from joypad-os (XINPUT_VID 0x045E, XINPUT_PID 0x028E, XINPUT_BCD_DEVICE 0x0114) static const uint8_t DESC_DEVICE[] = { 0x12, // bLength @@ -194,36 +199,54 @@ namespace XInput 0x40, // bMaxPacketSize0 64 0x5E, 0x04, // idVendor 0x045E (Microsoft) 0x8E, 0x02, // idProduct 0x028E (Xbox 360 Controller) - 0x14, 0x01, // bcdDevice 1.14 + 0x14, 0x01, // bcdDevice 0x0114 (v1.14) 0x01, // iManufacturer (String Index) 0x02, // iProduct (String Index) 0x03, // iSerialNumber (String Index) 0x01, // bNumConfigurations 1 }; - // Single-interface XInput config (48 bytes) for PC - static constexpr uint16_t CONFIG_TOTAL_LENGTH = 48; + // Configuration descriptor (153 bytes) — from joypad-os xinput_config_descriptor[] + // https://github.com/joypad-ai/joypad-os src/usb/usbd/descriptors/xinput_descriptors.h + static constexpr uint16_t CONFIG_TOTAL_LENGTH = 153; static const uint8_t DESC_CONFIGURATION[] = { // Configuration descriptor (9 bytes) 0x09, 0x02, - 0x30, 0x00, // wTotalLength 48 (LE) - 0x01, // bNumInterfaces 1 + 0x99, 0x00, // wTotalLength 153 (LE) + 0x04, // bNumInterfaces 0x01, // bConfigurationValue 0x00, // iConfiguration - 0x80, // bmAttributes (bus powered) - 0xFA, // bMaxPower 500mA + 0xA0, // bmAttributes (bus powered, remote wakeup) + 0xFA, // bMaxPower (500mA) - // Interface 0: Gamepad (0xFF/0x5D/0x01) + // ---- Interface 0: Gamepad (SubClass 0x5D, Protocol 0x01) ---- 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x5D, 0x01, 0x00, - // Vendor descriptor (type 0x21, 16 bytes) - 0x10, 0x21, 0x00, 0x01, 0x01, 0x25, 0x81, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x08, 0x00, - // EP 0x81 IN - Interrupt, 32 bytes, 1ms - 0x07, 0x05, 0x81, 0x03, 0x20, 0x00, 0x01, - // EP 0x01 OUT - Interrupt, 32 bytes, 8ms - 0x07, 0x05, 0x01, 0x03, 0x20, 0x00, 0x08, + 0x11, 0x21, 0x00, 0x01, 0x01, 0x25, 0x81, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x08, 0x00, 0x00, + 0x07, 0x05, 0x81, 0x03, 0x20, 0x00, 0x04, + 0x07, 0x05, 0x02, 0x03, 0x20, 0x00, 0x08, + + // ---- Interface 1: Audio (SubClass 0x5D, Protocol 0x03) ---- + 0x09, 0x04, 0x01, 0x00, 0x04, 0xFF, 0x5D, 0x03, 0x00, + 0x1B, 0x21, 0x00, 0x01, 0x01, 0x01, 0x83, 0x40, + 0x01, 0x04, 0x20, 0x16, 0x85, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x16, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x07, 0x05, 0x83, 0x03, 0x20, 0x00, 0x02, + 0x07, 0x05, 0x04, 0x03, 0x20, 0x00, 0x04, + 0x07, 0x05, 0x85, 0x03, 0x20, 0x00, 0x40, + 0x07, 0x05, 0x06, 0x03, 0x20, 0x00, 0x10, + + // ---- Interface 2: Plugin Module (SubClass 0x5D, Protocol 0x02) ---- + 0x09, 0x04, 0x02, 0x00, 0x01, 0xFF, 0x5D, 0x02, 0x00, + 0x09, 0x21, 0x00, 0x01, 0x01, 0x22, 0x86, 0x03, 0x00, + 0x07, 0x05, 0x86, 0x03, 0x20, 0x00, 0x10, + + // ---- Interface 3: Security (SubClass 0xFD, Protocol 0x13), iInterface=4 ---- + 0x09, 0x04, 0x03, 0x00, 0x00, 0xFF, 0xFD, 0x13, 0x04, + 0x06, 0x41, 0x00, 0x01, 0x01, 0x03, }; static_assert(sizeof(DESC_CONFIGURATION) == CONFIG_TOTAL_LENGTH, "XInput config descriptor size"); }; diff --git a/Firmware/RP2040/src/Gamepad/Gamepad.h b/Firmware/RP2040/src/Gamepad/Gamepad.h index d223aad9..9e751c6d 100644 --- a/Firmware/RP2040/src/Gamepad/Gamepad.h +++ b/Firmware/RP2040/src/Gamepad/Gamepad.h @@ -143,6 +143,15 @@ class Gamepad inline bool new_pad_in() const { return new_pad_in_.load(); } inline bool new_pad_out() const { return new_pad_out_.load(); } + // True if current pad_out has non-zero rumble (read-only, does not clear new_pad_out). + inline bool has_rumble() + { + mutex_enter_blocking(&pad_out_mutex_); + bool r = (pad_out_.rumble_l > 0 || pad_out_.rumble_r > 0); + mutex_exit(&pad_out_mutex_); + return r; + } + //True if both host and device have enabled analog inline bool analog_enabled() const { return analog_enabled_.load(std::memory_order_relaxed); } @@ -378,7 +387,9 @@ class Gamepad void set_profile_settings(const UserProfile& profile) { profile_analog_enabled_ = profile.analog_enabled ? true : false; +#if 0 OGXM_LOG("profile_analog_enabled_: %d\n", profile_analog_enabled_); +#endif if ((joy_settings_l_en_ = !joy_settings_l_.is_same(profile.joystick_settings_l))) { @@ -405,11 +416,13 @@ class Gamepad trig_settings_r_.set_from_raw(profile.trigger_settings_r); } +#if 0 OGXM_LOG("GamepadMapper: JoyL: %s, JoyR: %s, TrigL: %s, TrigR: %s\n", joy_settings_l_en_ ? "Enabled" : "Disabled", joy_settings_r_en_ ? "Enabled" : "Disabled", trig_settings_l_en_ ? "Enabled" : "Disabled", trig_settings_r_en_ ? "Enabled" : "Disabled"); +#endif } void set_profile_mappings(const UserProfile& profile) diff --git a/Firmware/RP2040/src/OGXMini/Board/ESP32_Blueretro_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/ESP32_Blueretro_I2C.cpp index 1a0f3ff5..a713cf2c 100644 --- a/Firmware/RP2040/src/OGXMini/Board/ESP32_Blueretro_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/ESP32_Blueretro_I2C.cpp @@ -113,9 +113,10 @@ static void core1_task() { } void set_gp_check_timer(uint32_t task_id) { +#if !defined(CONFIG_OGXM_FIXED_DRIVER) || defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) UserSettings& user_settings = UserSettings::get_instance(); - - TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, + + TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, [&user_settings] { //Check gamepad inputs for button combo to change usb device driver if (user_settings.check_for_driver_change(_gamepads[0])) { @@ -124,6 +125,9 @@ void set_gp_check_timer(uint32_t task_id) { user_settings.store_driver_type(user_settings.get_current_driver()); } }); +#else + (void)task_id; // Fixed output, combos disabled +#endif } void run_uart_bridge() { diff --git a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp index 5b86f353..f70ee88a 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -366,8 +367,9 @@ void core1_task() { } void set_gp_check_timer(uint32_t task_id) { +#if !defined(CONFIG_OGXM_FIXED_DRIVER) || defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) UserSettings& user_settings = UserSettings::get_instance(); - TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, + TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, [&user_settings] { //Check gamepad inputs for button combo to change usb device driver if (user_settings.check_for_driver_change(_gamepads[0])) @@ -376,6 +378,9 @@ void set_gp_check_timer(uint32_t task_id) { user_settings.store_driver_type(user_settings.get_current_driver()); } }); +#else + (void)task_id; // Fixed output, combos disabled +#endif } void four_ch_i2c::wireless_connected(bool connected, uint8_t idx) { @@ -447,14 +452,18 @@ void four_ch_i2c::run() { I2C::Master::process(); device_driver->process(0, _gamepads[0]); tud_task(); - sleep_ms(1); +#if MAIN_LOOP_DELAY_US > 0 + sleep_us(MAIN_LOOP_DELAY_US); +#endif } } else { while (true) { TaskQueue::Core0::process_tasks(); device_driver->process(0, _gamepads[0]); tud_task(); - sleep_ms(1); +#if MAIN_LOOP_DELAY_US > 0 + sleep_us(MAIN_LOOP_DELAY_US); +#endif } } } diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index 929d2497..4f7a5867 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -2,8 +2,10 @@ #include "OGXMini/Board/PicoW.h" #if (OGXM_BOARD == PI_PICOW) +#include #include #include +#include #include "tusb.h" #include "bsp/board_api.h" @@ -26,8 +28,9 @@ void core1_task() { } void set_gp_check_timer(uint32_t task_id) { +#if !defined(CONFIG_OGXM_FIXED_DRIVER) || defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) UserSettings& user_settings = UserSettings::get_instance(); - TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, + TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, [&user_settings] { //Check gamepad inputs for button combo to change usb device driver if (user_settings.check_for_driver_change(_gamepads[0])) { @@ -35,6 +38,9 @@ void set_gp_check_timer(uint32_t task_id) { user_settings.store_driver_type(user_settings.get_current_driver()); } }); +#else + (void)task_id; // Fixed output, combos disabled +#endif } void pico_w::initialize() { @@ -53,15 +59,20 @@ void pico_w::initialize() { void pico_w::run() { multicore_reset_core1(); + + // Initialize USB before starting core1 (BT). If BT FW download hangs, the host can + // still enumerate and run XSM3 auth; core1 runs Bluetooth in parallel. + DeviceDriver* device_driver = DeviceManager::get_instance().get_driver(); + tud_init(BOARD_TUD_RHPORT); + printf("USB init done\n"); + multicore_launch_core1(core1_task); + printf("Core1 (BT) launched\n"); uint32_t tid_gp_check = TaskQueue::Core0::get_new_task_id(); set_gp_check_timer(tid_gp_check); - DeviceDriver* device_driver = DeviceManager::get_instance().get_driver(); - - tud_init(BOARD_TUD_RHPORT); - + static bool mounted_logged = false; while (true) { TaskQueue::Core0::process_tasks(); @@ -69,7 +80,13 @@ void pico_w::run() { device_driver->process(i, _gamepads[i]); tud_task(); } - sleep_ms(1); + if (tud_mounted() && !mounted_logged) { + mounted_logged = true; + printf("USB configured (host enumerated)\n"); + } +#if MAIN_LOOP_DELAY_US > 0 + sleep_us(MAIN_LOOP_DELAY_US); +#endif } } diff --git a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp index 1db4f58b..575b4e0c 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp @@ -3,6 +3,7 @@ #if ((OGXM_BOARD == PI_PICO) || (OGXM_BOARD == RP2040_ZERO) || (OGXM_BOARD == ADAFRUIT_FEATHER)) #include +#include #include "tusb.h" #include "bsp/board_api.h" @@ -47,9 +48,10 @@ void core1_task() { } void set_gp_check_timer(uint32_t task_id) { +#if !defined(CONFIG_OGXM_FIXED_DRIVER) || defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) UserSettings& user_settings = UserSettings::get_instance(); - - TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, + + TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, [&user_settings] { //Check gamepad inputs for button combo to change usb device driver if (user_settings.check_for_driver_change(_gamepads[0])) { @@ -58,6 +60,9 @@ void set_gp_check_timer(uint32_t task_id) { user_settings.store_driver_type(user_settings.get_current_driver()); } }); +#else + (void)task_id; // Fixed output, combos disabled +#endif } //Called by tusb host so we know to connect or disconnect usb @@ -121,7 +126,9 @@ void standard::run() { device_driver->process(i, _gamepads[i]); } tud_task(); - sleep_ms(1); +#if MAIN_LOOP_DELAY_US > 0 + sleep_us(MAIN_LOOP_DELAY_US); +#endif } } diff --git a/Firmware/RP2040/src/TaskQueue/TaskQueue.h b/Firmware/RP2040/src/TaskQueue/TaskQueue.h index 7ee2e0cb..2c32866e 100644 --- a/Firmware/RP2040/src/TaskQueue/TaskQueue.h +++ b/Firmware/RP2040/src/TaskQueue/TaskQueue.h @@ -1,6 +1,8 @@ #ifndef TASK_QUEUE_H #define TASK_QUEUE_H +#include +#include #include #include #include diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp index c070b5d1..dd12a038 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp @@ -71,25 +71,40 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) if (gp_in.trigger_l) report_in_.buttons[1] |= PS3::Buttons1::L2; if (gp_in.trigger_r) report_in_.buttons[1] |= PS3::Buttons1::R2; - report_in_.joystick_lx = Scale::int16_to_uint8(gp_in.joystick_lx); - report_in_.joystick_ly = Scale::int16_to_uint8(gp_in.joystick_ly); - report_in_.joystick_rx = Scale::int16_to_uint8(gp_in.joystick_rx); - report_in_.joystick_ry = Scale::int16_to_uint8(gp_in.joystick_ry); + // L2/R2 axis values (critical for PS3 games - avoids stuck triggers) + report_in_.l2_axis = gp_in.trigger_l; + report_in_.r2_axis = gp_in.trigger_r; + + // PS3 uses 0x7F (127) as joystick center; 5% deadzone avoids drift/stuck inputs + constexpr int16_t DEADZONE_LEFT = 1640; // ~5% of 32768 + constexpr int16_t DEADZONE_RIGHT = 1640; + constexpr uint8_t PS3_CENTER = 0x7F; + + auto joystick_to_ps3 = [](int16_t value, int16_t deadzone) -> uint8_t { + if (value > -deadzone && value < deadzone) + return PS3_CENTER; + int32_t scaled = ((static_cast(value) + 32768) * 254) / 65535; + return static_cast(scaled); + }; + + report_in_.joystick_lx = joystick_to_ps3(gp_in.joystick_lx, DEADZONE_LEFT); + report_in_.joystick_ly = joystick_to_ps3(gp_in.joystick_ly, DEADZONE_LEFT); + report_in_.joystick_rx = joystick_to_ps3(gp_in.joystick_rx, DEADZONE_RIGHT); + report_in_.joystick_ry = joystick_to_ps3(gp_in.joystick_ry, DEADZONE_RIGHT); if (gamepad.analog_enabled()) { - report_in_.up_axis = gp_in.analog[Gamepad::ANALOG_OFF_UP]; - report_in_.down_axis = gp_in.analog[Gamepad::ANALOG_OFF_DOWN]; - report_in_.right_axis = gp_in.analog[Gamepad::ANALOG_OFF_RIGHT]; - report_in_.left_axis = gp_in.analog[Gamepad::ANALOG_OFF_LEFT]; - report_in_.triangle_axis = gp_in.analog[Gamepad::ANALOG_OFF_Y]; report_in_.circle_axis = gp_in.analog[Gamepad::ANALOG_OFF_B]; report_in_.cross_axis = gp_in.analog[Gamepad::ANALOG_OFF_A]; report_in_.square_axis = gp_in.analog[Gamepad::ANALOG_OFF_X]; - report_in_.r1_axis = gp_in.analog[Gamepad::ANALOG_OFF_RB]; report_in_.l1_axis = gp_in.analog[Gamepad::ANALOG_OFF_LB]; + // D-pad: use digital conversion to avoid noisy analog causing stuck inputs + report_in_.up_axis = (gp_in.dpad & Gamepad::DPAD_UP) ? 0xFF : 0; + report_in_.down_axis = (gp_in.dpad & Gamepad::DPAD_DOWN) ? 0xFF : 0; + report_in_.right_axis = (gp_in.dpad & Gamepad::DPAD_RIGHT) ? 0xFF : 0; + report_in_.left_axis = (gp_in.dpad & Gamepad::DPAD_LEFT) ? 0xFF : 0; } else { @@ -99,9 +114,9 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) report_in_.left_axis = (gp_in.dpad & Gamepad::DPAD_LEFT) ? 0xFF : 0; report_in_.triangle_axis = (gp_in.buttons & Gamepad::BUTTON_Y) ? 0xFF : 0; - report_in_.circle_axis = (gp_in.buttons & Gamepad::BUTTON_X) ? 0xFF : 0; - report_in_.cross_axis = (gp_in.buttons & Gamepad::BUTTON_B) ? 0xFF : 0; - report_in_.square_axis = (gp_in.buttons & Gamepad::BUTTON_A) ? 0xFF : 0; + report_in_.circle_axis = (gp_in.buttons & Gamepad::BUTTON_B) ? 0xFF : 0; + report_in_.cross_axis = (gp_in.buttons & Gamepad::BUTTON_A) ? 0xFF : 0; + report_in_.square_axis = (gp_in.buttons & Gamepad::BUTTON_X) ? 0xFF : 0; report_in_.r1_axis = (gp_in.buttons & Gamepad::BUTTON_RB) ? 0xFF : 0; report_in_.l1_axis = (gp_in.buttons & Gamepad::BUTTON_LB) ? 0xFF : 0; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp index 89e47d89..9e7754c7 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp @@ -1,15 +1,58 @@ +#include #include +#include "tusb.h" #include "USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h" #include "USBDevice/DeviceDriver/XInput/XInput.h" +extern "C" { +#include "xsm3.h" +} + +// XSM3 state and buffers — match joypad-os: init at driver init, defer crypto to process() loop +namespace { + enum class Xsm3AuthState : uint8_t { + Idle = 0, + InitReceived = 1, // 0x82 data received, pending xsm3_do_challenge_init + Responded = 2, // init response ready for 0x83 + VerifyReceived = 3, // 0x87 data received, pending xsm3_do_challenge_verify + Authenticated = 4, + }; + static Xsm3AuthState xsm3_auth_state = Xsm3AuthState::Idle; + static uint8_t xsm3_buf_82[0x22]; + static uint8_t xsm3_buf_87[0x16]; + // joypad-os: state 1 = processing, state 2 = response ready + static constexpr uint8_t XSM3_STATE_PROCESSING = 1; + static constexpr uint8_t XSM3_STATE_READY = 2; + // joypad-os: init response is 46 bytes (0x2E), not full 0x30 + static constexpr uint16_t XSM3_RESPONSE_INIT_LEN = 46u; + static constexpr uint16_t XSM3_RESPONSE_VERIFY_LEN = 0x16u; + + static void xsm3_process_pending(void) { + if (xsm3_auth_state == Xsm3AuthState::InitReceived) { + xsm3_do_challenge_init(xsm3_buf_82); + xsm3_auth_state = Xsm3AuthState::Responded; + } else if (xsm3_auth_state == Xsm3AuthState::VerifyReceived) { + xsm3_do_challenge_verify(xsm3_buf_87); + xsm3_auth_state = Xsm3AuthState::Authenticated; + } + } +} + void XInputDevice::initialize() { - class_driver_ = *tud_xinput::class_driver(); + class_driver_ = *tud_xinput::class_driver(); + // joypad-os: init XSM3 at mode init so 0x81 can send ID without doing init in callback + xsm3_initialise_state(); + xsm3_set_identification_data(xsm3_id_data_ms_controller); + xsm3_auth_state = Xsm3AuthState::Idle; } void XInputDevice::process(const uint8_t idx, Gamepad& gamepad) { + // joypad-os: run XSM3 crypto in task loop, not in USB callback + xsm3_process_pending(); + if (gamepad.new_pad_in()) { in_report_.buttons[0] = 0; @@ -96,14 +139,109 @@ void XInputDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type bool XInputDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { - (void)rhport; - (void)stage; - (void)request; - return false; + printf("XSM3 cb bReq 0x%02x stage %u bmReqType 0x%02x wIdx 0x%04x\n", + (unsigned)request->bRequest, (unsigned)stage, (unsigned)request->bmRequestType, (unsigned)request->wIndex); + // 360 can send XSM3 as Vendor (0x40/0xC0) or Class (0x20/0xA0) to the security interface. + // Accept Vendor (bits 6-5 == 0x40) or Class (bits 6-5 == 0x20). + uint8_t type_bits = request->bmRequestType & 0x60; + if (type_bits != 0x40 && type_bits != 0x20) + return false; + + switch (request->bRequest) + { + // 0x81: Host GET — send controller identification (0x1D bytes). XSM3 already inited in initialize(). + case 0x81: + if (stage == CONTROL_STAGE_SETUP) printf("XSM3: 0x81 GET_SERIAL\n"); + if (stage == CONTROL_STAGE_SETUP && request->wLength >= 0x1D) + return tud_control_xfer(rhport, request, const_cast(xsm3_id_data_ms_controller), 0x1D); + return true; + + // 0x82: Host OUT — receive challenge init; defer xsm3_do_challenge_init to process() (joypad-os) + case 0x82: + if (stage == CONTROL_STAGE_SETUP && request->wLength >= 0x22) + return tud_control_xfer(rhport, request, xsm3_buf_82, 0x22); + if (stage == CONTROL_STAGE_DATA) + { + printf("XSM3: 0x82 challenge init received (defer process)\n"); + xsm3_auth_state = Xsm3AuthState::InitReceived; + } + return true; + + // 0x83: Host GET — send challenge response. Joypad: 46 bytes init, 22 bytes verify. + case 0x83: + if (stage == CONTROL_STAGE_SETUP) + { + if (xsm3_auth_state == Xsm3AuthState::Responded) + { + printf("XSM3: 0x83 sending init response (46 bytes)\n"); + uint16_t len = (request->wLength < XSM3_RESPONSE_INIT_LEN) ? request->wLength : XSM3_RESPONSE_INIT_LEN; + bool ok = tud_control_xfer(rhport, request, xsm3_challenge_response, len); + if (ok) + xsm3_auth_state = Xsm3AuthState::Idle; + return ok; + } + if (xsm3_auth_state == Xsm3AuthState::Authenticated) + { + printf("XSM3: 0x83 sending verify response (0x16 bytes)\n"); + uint16_t len = (request->wLength < XSM3_RESPONSE_VERIFY_LEN) ? request->wLength : XSM3_RESPONSE_VERIFY_LEN; + bool ok = tud_control_xfer(rhport, request, xsm3_challenge_response, len); + if (ok) + xsm3_auth_state = Xsm3AuthState::Idle; + return ok; + } + return false; + } + return true; + + // 0x84: Host GET — keepalive, zero-length response (joypad-os) + case 0x84: + if (stage == CONTROL_STAGE_SETUP) printf("XSM3: 0x84 KEEPALIVE\n"); + if (stage == CONTROL_STAGE_SETUP) + return tud_control_xfer(rhport, request, nullptr, 0); + return true; + + // 0x86: Host GET — state 1 = processing, 2 = response ready (joypad-os) + case 0x86: + if (stage == CONTROL_STAGE_SETUP && request->wLength >= 2) + { + uint8_t state_val = (xsm3_auth_state == Xsm3AuthState::Responded || xsm3_auth_state == Xsm3AuthState::Authenticated) + ? XSM3_STATE_READY : XSM3_STATE_PROCESSING; + printf("XSM3: 0x86 GET_STATE %u\n", (unsigned)state_val); + uint8_t state_data[] = { state_val, 0x00 }; + return tud_control_xfer(rhport, request, state_data, 2); + } + return true; + + // 0x87: Host OUT — receive verify; defer xsm3_do_challenge_verify to process() (joypad-os) + case 0x87: + if (stage == CONTROL_STAGE_SETUP && request->wLength >= 0x16) + return tud_control_xfer(rhport, request, xsm3_buf_87, 0x16); + if (stage == CONTROL_STAGE_DATA) + { + printf("XSM3: 0x87 verify received (defer process)\n"); + xsm3_auth_state = Xsm3AuthState::VerifyReceived; + } + return true; + + default: + return false; + } } -const uint16_t * XInputDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) +const uint16_t * XInputDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) { + // joypad-os: XInput string index 4 (XSM3 security) uses a 96-char buffer and full length + if (index == 4) + { + static uint16_t xsm3_str[96]; + const char *str = reinterpret_cast(XInput::STRING_XSM3); + size_t len = std::strlen(str); + if (len > 95) len = 95; + for (size_t i = 0; i < len; i++) + xsm3_str[1 + i] = static_cast(str[i]); + xsm3_str[0] = (0x03u << 8) | static_cast(2 * len + 2); + return xsm3_str; + } const char *value = reinterpret_cast(XInput::DESC_STRING[index]); return get_string_descriptor(value, index); } @@ -118,9 +256,12 @@ const uint8_t * XInputDevice::get_hid_descriptor_report_cb(uint8_t itf) return nullptr; } -const uint8_t * XInputDevice::get_descriptor_configuration_cb(uint8_t index) +const uint8_t * XInputDevice::get_descriptor_configuration_cb(uint8_t index) { - return XInput::DESC_CONFIGURATION; + // joypad-os: single config; return nullptr for index != 0 (bNumConfigurations == 1) + if (index != 0) + return nullptr; + return XInput::DESC_CONFIGURATION; } const uint8_t * XInputDevice::get_descriptor_device_qualifier_cb() diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp index 0f6b07e6..a5322401 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp @@ -1,6 +1,7 @@ #include "tusb_option.h" #if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XINPUT) +#include #include #include @@ -8,12 +9,14 @@ #include "device/usbd_pvt.h" #include "Descriptors/XInput.h" +#include "USBDevice/DeviceManager.h" #include "USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h" namespace tud_xinput { static constexpr uint16_t ENDPOINT_SIZE = 32; static constexpr uint8_t DESC_TYPE_VENDOR = 0x21; +static constexpr uint8_t DESC_TYPE_SEC = 0x41; uint8_t endpoint_in_ = 0xFF; uint8_t endpoint_out_ = 0xFF; @@ -42,57 +45,98 @@ static void reset(uint8_t rhport) static inline uint16_t tu_desc_len(uint8_t const* desc) { return desc[0]; } +// Match joypad-os: claim all 4 interfaces, but only OPEN endpoints for gamepad (0x01). +// Audio (0x03) and plugin (0x02) endpoints are skipped (stub). Security (0xFD/0x13) has no EPs. static uint16_t open(uint8_t rhport, tusb_desc_interface_t const *itf_descriptor, uint16_t max_length) { uint16_t drv_len = sizeof(tusb_desc_interface_t); uint8_t const *p_desc = tu_desc_next((uint8_t const*)itf_descriptor); - if (itf_descriptor->bInterfaceClass != 0xFF || - itf_descriptor->bInterfaceSubClass != 0x5D || - itf_descriptor->bInterfaceProtocol != 0x01) - { + if (itf_descriptor->bInterfaceClass != 0xFF) return 0; + + // --- Interface 0: Gamepad (0x5D/0x01) — open endpoints --- + if (itf_descriptor->bInterfaceSubClass == 0x5D && itf_descriptor->bInterfaceProtocol == 0x01) + { + if (p_desc[1] == DESC_TYPE_VENDOR) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + for (uint8_t i = 0; i < itf_descriptor->bNumEndpoints; i++) { + tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; + if (TUSB_DESC_ENDPOINT != tu_desc_type(ep_desc)) break; + TU_VERIFY(usbd_edpt_open(rhport, ep_desc), 0); + if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) + endpoint_in_ = ep_desc->bEndpointAddress; + else + endpoint_out_ = ep_desc->bEndpointAddress; + drv_len += sizeof(tusb_desc_endpoint_t); + p_desc = tu_desc_next(p_desc); + } + if (endpoint_out_ != 0xFF) + usbd_edpt_xfer(rhport, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE); + TU_VERIFY(max_length >= drv_len, 0); + return drv_len; } - if (p_desc[1] == DESC_TYPE_VENDOR) { - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + // --- Interface 1: Audio (0x5D/0x03) — skip endpoints (stub) --- + if (itf_descriptor->bInterfaceSubClass == 0x5D && itf_descriptor->bInterfaceProtocol == 0x03) + { + if (p_desc[1] == DESC_TYPE_VENDOR) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + for (uint8_t i = 0; i < itf_descriptor->bNumEndpoints; i++) { + drv_len += sizeof(tusb_desc_endpoint_t); + p_desc = tu_desc_next(p_desc); + } + TU_VERIFY(max_length >= drv_len, 0); + return drv_len; } - for (uint8_t i = 0; i < itf_descriptor->bNumEndpoints; i++) { - tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; - if (TUSB_DESC_ENDPOINT != tu_desc_type(ep_desc)) break; - TU_VERIFY(usbd_edpt_open(rhport, ep_desc), 0); - if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) - endpoint_in_ = ep_desc->bEndpointAddress; - else - endpoint_out_ = ep_desc->bEndpointAddress; - drv_len += sizeof(tusb_desc_endpoint_t); - p_desc = tu_desc_next(p_desc); + // --- Interface 2: Plugin (0x5D/0x02) — skip endpoint (stub) --- + if (itf_descriptor->bInterfaceSubClass == 0x5D && itf_descriptor->bInterfaceProtocol == 0x02) + { + if (p_desc[1] == DESC_TYPE_VENDOR) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + for (uint8_t i = 0; i < itf_descriptor->bNumEndpoints; i++) { + drv_len += sizeof(tusb_desc_endpoint_t); + p_desc = tu_desc_next(p_desc); + } + TU_VERIFY(max_length >= drv_len, 0); + return drv_len; } - if (endpoint_out_ != 0xFF) - usbd_edpt_xfer(rhport, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE); + // --- Interface 3: Security (0xFD/0x13) — skip 0x41 descriptor, no EPs --- + if (itf_descriptor->bInterfaceSubClass == 0xFD && itf_descriptor->bInterfaceProtocol == 0x13) + { + if (p_desc[1] == DESC_TYPE_SEC) { + drv_len += tu_desc_len(p_desc); + } + TU_VERIFY(max_length >= drv_len, 0); + return drv_len; + } - TU_VERIFY(max_length >= drv_len, 0); - return drv_len; + return 0; } +// Forward interface-directed control requests (e.g. XSM3 from 360) to the device driver. +// The 360 may send XSM3 as Class requests to the security interface; TinyUSB routes those here. static bool control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { - (void)rhport; - (void)stage; - (void)request; - return true; + printf("tud_xinput ctrl bReq 0x%02x stage %u type 0x%02x wIdx 0x%04x\n", + (unsigned)request->bRequest, (unsigned)stage, (unsigned)request->bmRequestType, (unsigned)request->wIndex); + return DeviceManager::get_instance().get_driver()->vendor_control_xfer_cb(rhport, stage, request); } static bool xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)result; (void)xferred_bytes; - if (ep_addr == endpoint_out_) { + if (ep_addr == endpoint_out_) usbd_edpt_xfer(rhport, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE); - } return true; } diff --git a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp index b6ee0d4d..bf14304a 100644 --- a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp +++ b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp @@ -1,4 +1,5 @@ #include +#include #include "tusb.h" #include "class/hid/hid_device.h" @@ -26,6 +27,8 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { + printf("tud_vendor_cb bReq 0x%02x stage %u type 0x%02x wIdx 0x%04x\n", + (unsigned)request->bRequest, (unsigned)stage, (unsigned)request->bmRequestType, (unsigned)request->wIndex); return DeviceManager::get_instance().get_driver()->vendor_control_xfer_cb(rhport, stage, request); } diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp index 0389b787..a6e821b7 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp @@ -84,7 +84,11 @@ void PS5Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance if (in_report->buttons[1] & PS5::Buttons1::SHARE) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; if (in_report->buttons[1] & PS5::Buttons1::OPTIONS) gp_in.buttons |= gamepad.MAP_BUTTON_START; if (in_report->buttons[2] & PS5::Buttons2::PS) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (in_report->buttons[2] & PS5::Buttons2::MUTE) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + if (in_report->buttons[2] & PS5::Buttons2::TP) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; // Touchpad press + if (in_report->buttons[2] & PS5::Buttons2::MUTE) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; // Mute button + // Touchpad finger touch (no click) – report has two points + if (in_report->points[0].touching || in_report->points[1].touching) + gp_in.buttons |= gamepad.MAP_BUTTON_MISC; gp_in.trigger_l = gamepad.scale_trigger_l(in_report->trigger_l); gp_in.trigger_r = gamepad.scale_trigger_r(in_report->trigger_r); diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index 18b8ca99..7a04fd62 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -204,7 +204,8 @@ class HostManager } for (uint8_t i = 0; i < MAX_INTERFACES; ++i) { - if (device_slot.interfaces[i].driver && device_slot.interfaces[i].gamepad->new_pad_out()) + if (device_slot.interfaces[i].driver && + (device_slot.interfaces[i].gamepad->new_pad_out() || device_slot.interfaces[i].gamepad->has_rumble())) { device_slot.interfaces[i].driver->send_feedback(*device_slot.interfaces[i].gamepad, device_slot.address, i); tuh_task(); diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.cpp b/Firmware/RP2040/src/UserSettings/UserSettings.cpp index ec75d608..44b87ead 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/UserSettings.cpp @@ -107,12 +107,20 @@ const std::string UserSettings::DATETIME_KEY() DeviceDriverType UserSettings::DEFAULT_DRIVER() { +#if defined(CONFIG_OGXM_FIXED_DRIVER) + return static_cast(OGXM_FIXED_DRIVER_TYPE); +#else return VALID_DRIVER_TYPES[0]; +#endif } //Checks if button combo has been held for 3 seconds, returns true if mode has been changed bool UserSettings::check_for_driver_change(Gamepad& gamepad) { +#if defined(CONFIG_OGXM_FIXED_DRIVER) && !defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) + (void)gamepad; + return false; // Fixed output build: combos disabled +#else Gamepad::PadIn gp_in = gamepad.get_pad_in(); static uint32_t last_button_combo = BUTTON_COMBO(gp_in.buttons, gp_in.dpad); static uint8_t call_count = 0; @@ -155,6 +163,7 @@ bool UserSettings::check_for_driver_change(Gamepad& gamepad) current_driver_ = new_driver; return true; +#endif // !(CONFIG_OGXM_FIXED_DRIVER && !CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) } //Disconnects usb and resets pico, call from core0 @@ -285,6 +294,9 @@ bool UserSettings::is_valid_driver(DeviceDriverType driver) DeviceDriverType UserSettings::get_current_driver() { +#if defined(CONFIG_OGXM_FIXED_DRIVER) && !defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) + return static_cast(OGXM_FIXED_DRIVER_TYPE); +#else if (current_driver_ != DeviceDriverType::NONE) { return current_driver_; @@ -305,6 +317,7 @@ DeviceDriverType UserSettings::get_current_driver() current_driver_ = DEFAULT_DRIVER(); return current_driver_; +#endif // !(CONFIG_OGXM_FIXED_DRIVER && !CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) } void UserSettings::write_datetime() From 0aca3234b10c62de1bd82b87b1cfc2871bf6ab70 Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Thu, 26 Feb 2026 16:10:03 -0500 Subject: [PATCH 15/42] Delete Firmware/RP2040/scripts directory --- Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md | 74 ----------- Firmware/RP2040/scripts/build-with-vs.cmd | 5 - Firmware/RP2040/scripts/build-with-vs.ps1 | 43 ------ Firmware/RP2040/scripts/test_xsm3_windows.py | 124 ------------------ 4 files changed, 246 deletions(-) delete mode 100644 Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md delete mode 100644 Firmware/RP2040/scripts/build-with-vs.cmd delete mode 100644 Firmware/RP2040/scripts/build-with-vs.ps1 delete mode 100644 Firmware/RP2040/scripts/test_xsm3_windows.py diff --git a/Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md b/Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md deleted file mode 100644 index 8fc6d6b6..00000000 --- a/Firmware/RP2040/scripts/DEBUG-UART-WINDOWS.md +++ /dev/null @@ -1,74 +0,0 @@ -# Debug build and UART on Windows - -## Build Debug XInput firmware (Pico 2 W) - -From the `RP2040` folder: - -```powershell -.\scripts\build-with-vs.ps1 -Config Debug -FixedDriver XINPUT -``` - -Output: `build_pico2w\OGX-Mini-v1.0.0a4-PI_PICO2W-XINPUT-Debug.uf2` - -Flash this .uf2 to the Pico 2 W. Debug builds enable: - -- **UART** for log output (TX = GPIO 0, RX = GPIO 1) -- **OGXM_LOG** / **XSM3** messages (e.g. `XSM3: 0x81 GET_SERIAL`, `XSM3: 0x86 GET_STATE`) - -## Reading UART on Windows - -### 1. Connect the Pico 2 W UART to the PC - -- **Pico 2 W** (and most Pico boards): **GPIO 0 = UART TX** (from Pico), **GPIO 1 = UART RX** (into Pico). -- Use a **USB–serial adapter** (e.g. CP2102, FT232, CH340) or a second Pico in UART mode: - - Connect adapter **RX** to Pico **GPIO 0 (TX)**. - - Connect **GND** to **GND**. - - Do **not** connect adapter TX to Pico unless you need to send data; for log viewing, RX + GND is enough. - -### 2. Find the COM port - -- Open **Device Manager** → **Ports (COM & LPT)**. -- Note the COM number for your USB–serial device (e.g. **COM4**). - -### 3. Open a serial terminal - -**Option A – PuTTY (recommended)** - -1. Download [PuTTY](https://www.putty.org/). -2. Run PuTTY → **Session**: - - **Connection type**: Serial. - - **Serial line**: `COM4` (use your port). - - **Speed**: **115200** (Pico default). -3. Click **Open**. - -**Option B – Windows Terminal / PowerShell (if serial module available)** - -```powershell -# List serial ports (PowerShell) -[System.IO.Ports.SerialPort]::getportnames() -``` - -Then use a terminal that can open a serial port (e.g. PuTTY, or a VS Code serial extension). - -**Option C – VS Code** - -- Install an extension such as **Serial Monitor** or **Serial Port Utility**. -- Select the correct COM port and **115200** baud. - -### 4. Baud rate - -Use **115200** unless the firmware is built with a different `PICO_DEFAULT_UART_BAUD_RATE`. - -### 5. What you’ll see (XInput debug) - -When the controller is used (or the XSM3 test script runs), you should see lines like: - -``` -OGXM: XSM3: 0x81 GET_SERIAL -OGXM: XSM3: 0x86 GET_STATE -OGXM: XSM3: 0x82 challenge init received, processing -OGXM: XSM3: 0x83 sending init response (0x30 bytes) -... -``` - -On an **Xbox 360** you’ll see the full auth sequence (0x81 → 0x82 → 0x83 → 0x86 → 0x87 → 0x83). On **Windows**, only 0x81 and 0x86 may appear unless you run the test script. diff --git a/Firmware/RP2040/scripts/build-with-vs.cmd b/Firmware/RP2040/scripts/build-with-vs.cmd deleted file mode 100644 index 862018dd..00000000 --- a/Firmware/RP2040/scripts/build-with-vs.cmd +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -REM Build OGX-Mini for Pico 2 W (uses VS for pioasm/picotool). Run from RP2040 folder. -cd /d "%~dp0.." -powershell -ExecutionPolicy Bypass -File "%~dp0build-with-vs.ps1" %* -exit /b %ERRORLEVEL% diff --git a/Firmware/RP2040/scripts/build-with-vs.ps1 b/Firmware/RP2040/scripts/build-with-vs.ps1 deleted file mode 100644 index d811caed..00000000 --- a/Firmware/RP2040/scripts/build-with-vs.ps1 +++ /dev/null @@ -1,43 +0,0 @@ -# Build OGX-Mini firmware for Pico 2 W, using Visual Studio's host compiler for SDK tools (pioasm, picotool). -# Run from RP2040 folder: .\scripts\build-with-vs.ps1 - -param( - [string] $BuildDir = "build_pico2w", - [string] $Config = "Release", - [string] $FixedDriver = "", # e.g. PS3, XINPUT to lock output mode (no combos) - [switch] $FixedDriverAllowCombos # if -FixedDriver set: allow combos to change mode -) - -$ErrorActionPreference = "Stop" -$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path -$RP2040Dir = Split-Path -Parent $ScriptDir -$VsPath = "${env:ProgramFiles}\Microsoft Visual Studio\2022\Community" -if (-not (Test-Path $VsPath)) { - $VsPath = "${env:ProgramFiles}\Microsoft Visual Studio\2022\Professional" -} -if (-not (Test-Path $VsPath)) { - $VsPath = "${env:ProgramFiles}\Microsoft Visual Studio\2022\Enterprise" -} -$Vcvars = "$VsPath\VC\Auxiliary\Build\vcvars64.bat" -if (-not (Test-Path $Vcvars)) { - Write-Error "Visual Studio 2022 not found (no vcvars64.bat). Install VS 2022 with 'Desktop development with C++' workload." -} - -$PicoSdkPath = Join-Path $RP2040Dir "..\external\pico-sdk" -$ConfigureArgs = @( - "-G", "Ninja", - "-DCMAKE_BUILD_TYPE=$Config", - "-DOGXM_BOARD=PI_PICO2W", - "-DPICO_SDK_PATH=$($PicoSdkPath -replace '\\','/')" -) -# Always pass OGXM_FIXED_DRIVER so the output filename matches the built mode (avoids reusing cached PS3/XINPUT name) -if ($FixedDriver) { - $ConfigureArgs += "-DOGXM_FIXED_DRIVER=$FixedDriver" - if ($FixedDriverAllowCombos) { $ConfigureArgs += "-DOGXM_FIXED_DRIVER_ALLOW_COMBOS=ON" } -} else { - $ConfigureArgs += "-DOGXM_FIXED_DRIVER=" -} -$ConfigureArgsStr = $ConfigureArgs -join " " - -& cmd /c "call `"$Vcvars`" && cd /d `"$RP2040Dir`" && cmake -B `"$BuildDir`" $ConfigureArgsStr && cmake --build `"$BuildDir`" --config $Config" -exit $LASTEXITCODE diff --git a/Firmware/RP2040/scripts/test_xsm3_windows.py b/Firmware/RP2040/scripts/test_xsm3_windows.py deleted file mode 100644 index 26868012..00000000 --- a/Firmware/RP2040/scripts/test_xsm3_windows.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python3 -""" -Test XSM3 (Xbox 360 Security Method 3) vendor requests on Windows. - -Sends control transfers 0x81 (get serial/ID) and 0x86 (get auth state) to verify -the OGX-Mini XInput device responds correctly. Full auth (0x82/0x83/0x87) requires -an Xbox 360 console or a host that can generate valid challenge data. - -Requirements: - pip install pyusb - -On Windows you may need to replace the Xbox 360 driver with WinUSB so libusb can -claim the device: use Zadig (https://zadig.akeo.ie/) and select the "Xbox 360 Controller" -then "Replace Driver" with WinUSB. The controller will stop working as a gamepad -until you restore the original driver (Zadig can do that too). - -Usage: - python scripts/test_xsm3_windows.py - # or from RP2040 folder: - python test_xsm3_windows.py -""" - -import sys - -try: - import usb.core - import usb.util -except ImportError: - print("Install pyusb: pip install pyusb") - sys.exit(1) - -# Microsoft Xbox 360 Controller -VID, PID = 0x045E, 0x028E - -# Vendor control: bmRequestType, bRequest -# 0x81 = GET serial/ID (0x1D bytes), 0x86 = GET state (2 bytes) -REQ_GET_SERIAL = 0x81 -REQ_GET_STATE = 0x86 -SERIAL_LEN = 0x1D -STATE_LEN = 2 - - -def find_device(): - dev = usb.core.find(idVendor=VID, idProduct=PID) - if dev is None: - print("No Xbox 360 controller (045E:028E) found.") - return None - return dev - - -def main(): - dev = find_device() - if dev is None: - sys.exit(1) - - try: - if dev.is_kernel_driver_active(0): - try: - dev.detach_kernel_driver(0) - print("Detached kernel driver for interface 0.") - except usb.core.USBError as e: - print("Could not detach kernel driver:", e) - print("Try using Zadig to install WinUSB for this device.") - sys.exit(1) - dev.set_configuration() - except usb.core.USBError as e: - print("USB error:", e) - print("If the device is in use by the Xbox 360 driver, use Zadig to replace it with WinUSB.") - sys.exit(1) - - print("Device found. Testing XSM3 vendor requests...") - ok = True - - # 0x81: Get serial/identification (29 bytes) - try: - data = dev.ctrl_transfer( - 0xC0, # bmRequestType: Vendor, Device, IN - REQ_GET_SERIAL, - 0, 0, - SERIAL_LEN, - timeout=1000, - ) - if len(data) == SERIAL_LEN: - print(" 0x81 (GET_SERIAL): OK, 29 bytes") - print(" First 8 bytes (hex):", " ".join(f"{b:02X}" for b in data[:8])) - else: - print(" 0x81 (GET_SERIAL): unexpected length", len(data)) - ok = False - except usb.core.USBError as e: - print(" 0x81 (GET_SERIAL): FAIL -", e) - ok = False - - # 0x86: Get auth state (2 bytes; 2 = ready) - try: - data = dev.ctrl_transfer( - 0xC0, - REQ_GET_STATE, - 0, 0, - STATE_LEN, - timeout=1000, - ) - if len(data) >= 2: - state = data[0] | (data[1] << 8) - print(" 0x86 (GET_STATE): OK, state =", state, "(2 = ready)") - if state != 1 and state != 2: - print(" (unexpected value; 1=processing, 2=ready)") - else: - print(" 0x86 (GET_STATE): unexpected length", len(data)) - ok = False - except usb.core.USBError as e: - print(" 0x86 (GET_STATE): FAIL -", e) - ok = False - - if ok: - print("\nXSM3 vendor requests succeeded. Device is responding to auth commands.") - print("Full auth (0x82/0x83/0x87) is only run by an Xbox 360 console;") - print("to verify that, plug the controller into a 360.") - else: - print("\nOne or more requests failed.") - sys.exit(1) - - -if __name__ == "__main__": - main() From 7231174adc7da217bd15e289891fb02ed888e21f Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Thu, 26 Feb 2026 16:11:12 -0500 Subject: [PATCH 16/42] Update XInput support information in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 74421805..e444dd4d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles - Original Xbox - Playstation 3 - Nintendo Switch 1 & 2 (docked) -- XInput (use [**UsbdSecPatch**](https://github.com/InvoxiPlayGames/UsbdSecPatch) for Xbox 360, or select the patch in J-Runner while flashing your NAND) +- XInput (UsbdSecPatch no longer required, works without it) - Playstation Classic - DInput - Wii U (GameCube Adapter) From 1c0a100102fb420f92e31918e7343e56d8922155 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Thu, 26 Feb 2026 20:31:57 -0500 Subject: [PATCH 17/42] Docs and latency: README/IMPROVEMENTS, low-latency default, XInput always-send; remove scripts from repo - docs/README.md: project overview, output modes, XInput/360, latency, building - docs/IMPROVEMENTS.md: XInput/360 section, latency default 0, always-send in XInput - MAIN_LOOP_DELAY_US default 0 (Config.h, CMakeLists.txt) - XInput process(): always send latest state when USB ready - .gitignore: add Firmware/RP2040/scripts; scripts removed from tracking (not shipped with build) Made-with: Cursor --- .gitignore | 1 + Firmware/RP2040/CMakeLists.txt | 4 + Firmware/RP2040/docs/IMPROVEMENTS.md | 69 ++++++++--- Firmware/RP2040/docs/README.md | 58 +++++++-- Firmware/RP2040/src/Board/Config.h | 6 +- .../USBDevice/DeviceDriver/XInput/XInput.cpp | 110 +++++++++--------- 6 files changed, 160 insertions(+), 88 deletions(-) diff --git a/.gitignore b/.gitignore index 5eb13e18..d769e228 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ Firmware/.vscode Firmware/RP2040/build +Firmware/RP2040/scripts Firmware/RP2040/.ignore Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid_xremote_rom.h Firmware/RP2040/src/BLEServer/att_delayed_response.h diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 924cc423..fabc00e8 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -228,6 +228,10 @@ endif() # Do not add -DOGXM_BOARD here; Config.h defines OGXM_BOARD from CONFIG_OGXM_BOARD_* to avoid redefinition warnings +# Main loop delay (microseconds). 0 = lowest latency (default). Set to 250+ for lower CPU. +set(MAIN_LOOP_DELAY_US 0 CACHE STRING "Main loop delay in microseconds; 0 = low latency (default)") +add_compile_definitions(MAIN_LOOP_DELAY_US=${MAIN_LOOP_DELAY_US}) + if(EN_USB_HOST) message(STATUS "USB host enabled.") add_compile_definitions(CONFIG_EN_USB_HOST=1) diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 3b90954c..cc3fa0c1 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -2,7 +2,36 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. -**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, and latency improvements (see below). +**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). + +--- + +## Xbox 360 (XInput) support + +**Goal:** Use the adapter in XInput mode on Xbox 360 with Bluetooth controllers (e.g. PS5, Xbox One). The 360 requires XSM3 authentication and specific USB descriptors. + +**References:** [joypad-os](https://github.com/joypad-ai/joypad-os) XInput implementation; [libxsm3](https://github.com/InvoxiPlayGames/libxsm3). + +### Changes + +1. **Descriptors** + - Device and configuration descriptors aligned with joypad-os (153-byte config, 4 interfaces, bConfigurationValue 1, bMaxPower 0xFA). + - Configuration callback returns `nullptr` for `index != 0` (single config). + - String descriptor index 4 (XSM3 security) uses a 96-character buffer and the full string (no 31-char truncation). + +2. **XSM3 authentication** + - XSM3 state is initialized at driver init (not in the 0x81 callback). + - Challenge init (0x82) and verify (0x87) data are stored when received; crypto (`xsm3_do_challenge_init` / `xsm3_do_challenge_verify`) runs in the main loop (`process()`), not in the USB callback. + - 0x83 responses: 46 bytes for init, 22 bytes for verify. + - 0x86 state: 1 = processing, 2 = response ready. + +3. **USB on Pico 2 W** + - USB is initialized before Core1 (Bluetooth) so the 360 can enumerate and run XSM3 even if BT firmware is still loading. + +4. **Control handling** + - Vendor and class control requests are forwarded to the active driver so XSM3 traffic reaches the XInput handler. + +See [XInput_joypad-os_comparison.md](XInput_joypad-os_comparison.md) for a detailed comparison. --- @@ -40,36 +69,39 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. ## Latency reduction -**Goal:** Reduce input-to-output latency in the device (Core0) main loop. +**Goal:** Reduce input-to-output latency in the device (Core0) main loop, especially for XInput with Bluetooth controllers (PS5, Xbox One). ### Main loop delay -- **Before:** The device loop used `sleep_ms(1)` every iteration, limiting the loop to ~1000 Hz and adding up to ~1 ms before the next read/send. -- **After:** Configurable delay in **microseconds** via `MAIN_LOOP_DELAY_US` in `src/Board/Config.h`: - - **Default: 250 µs** — loop runs at ~4000 Hz; average extra delay reduced (e.g. from ~0.5 ms to ~0.125 ms). - - **0** — no delay; loop runs as fast as possible for minimum latency (higher CPU use). - - **1000** — 1 ms (same as original behaviour). +- **Before:** The device loop used `sleep_ms(1)` every iteration, then a configurable `MAIN_LOOP_DELAY_US` (default 250 µs). +- **After:** + - **Default: 0 µs** — no added delay; loop runs as fast as possible for minimum latency (low-latency default). + - **250+ µs** — set via CMake (e.g. `-DMAIN_LOOP_DELAY_US=250`) to reduce CPU use if desired. **Files changed:** -- `src/Board/Config.h` — added `MAIN_LOOP_DELAY_US` and comment (override via CMake documented). -- `src/OGXMini/Board/Standard.cpp` — use `sleep_us(MAIN_LOOP_DELAY_US)` when `> 0`, and `#include `. -- `src/OGXMini/Board/PicoW.cpp` — same. -- `src/OGXMini/Board/Four_Channel_I2C.cpp` — same. +- `src/Board/Config.h` — `MAIN_LOOP_DELAY_US` default **0**; override via CMake. +- `src/OGXMini/Board/Standard.cpp`, `PicoW.cpp`, `Four_Channel_I2C.cpp` — use `sleep_us(MAIN_LOOP_DELAY_US)` when `> 0`. +- `CMakeLists.txt` — `MAIN_LOOP_DELAY_US` cache variable (default 0). + +### XInput: always send latest state + +In XInput mode, the adapter no longer sends a report only when `gamepad.new_pad_in()` is true. It **always** reads the current gamepad state and sends whenever the USB IN endpoint is free. That way the host (e.g. 360) gets updates at its poll interval (4 ms) with the freshest state, instead of being limited by how often the BT stack sets “new input.” Reduces perceived latency with PS5/Xbox One over Bluetooth. + +**File:** `src/USBDevice/DeviceDriver/XInput/XInput.cpp` — `process()` always builds and sends the report; no gate on `new_pad_in()`. ### How to use | Goal | Setting | |------|--------| -| Lower latency (default) | Leave `MAIN_LOOP_DELAY_US` at **250** (already set). | -| Minimum latency | Set `MAIN_LOOP_DELAY_US=0`, e.g. in CMake: `add_compile_definitions(MAIN_LOOP_DELAY_US=0)` or `-DCMAKE_CXX_FLAGS="-DMAIN_LOOP_DELAY_US=0"`. | -| Slightly lower CPU use | Use e.g. `MAIN_LOOP_DELAY_US=500`. | +| Low latency (default) | Use default `MAIN_LOOP_DELAY_US=0`. | +| Lower CPU use | Configure with e.g. `-DMAIN_LOOP_DELAY_US=250`. | ### Notes -- Core1 (USB host / gamepad polling) already runs with no sleep in its loop. -- USB full-speed has a 1 ms frame; reports are still limited by that; the improvement is that each report uses the **latest** input. -- For lowest end-to-end latency, use a **wired** controller and a USB host board; Bluetooth (e.g. Pico W) adds more latency. +- Core1 (Bluetooth / gamepad) runs with no sleep in its loop. +- USB full-speed poll interval (e.g. 4 ms for XInput) still applies; the improvement is that each report carries the **latest** input and the main loop adds no extra delay by default. +- Bluetooth adds latency; the changes above minimize the adapter’s contribution. --- @@ -77,5 +109,6 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. | Area | Improvement | |------|-------------| +| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). | | **PS3** | Stuck inputs and input delays addressed via L2/R2 axes, joystick centre/deadzone, D-pad handling, and face button mapping. | -| **Latency** | Main loop delay reduced from 1 ms to 250 µs by default, with option for 0 µs for minimum latency. | +| **Latency** | Main loop delay default **0 µs** (low latency); XInput always sends latest state when USB is ready for lower latency with PS5/Xbox One over BT. | diff --git a/Firmware/RP2040/docs/README.md b/Firmware/RP2040/docs/README.md index 5ce0a040..d72f0a8c 100644 --- a/Firmware/RP2040/docs/README.md +++ b/Firmware/RP2040/docs/README.md @@ -1,18 +1,58 @@ -# OGX-Mini RP2040 Firmware — Documentation +# OGX-Mini RP2040 Firmware -Documentation for the OGX-Mini 2026 RP2040 firmware (controller adapter for OG Xbox, XInput, PS3, Switch, Wii U, etc.). +Firmware for the OGX-Mini controller adapter on **RP2040** (e.g. Raspberry Pi Pico, Pico 2 W). The adapter accepts input from Bluetooth controllers (e.g. PS5, Xbox One, Switch Pro) and presents them to a console or PC as a single USB gamepad in the chosen output mode. -## Contents +## Supported output modes (USB device) -| Document | Description | -|----------|-------------| -| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Improvements and fixes applied to this firmware (PS3 driver, latency, etc.). | +| Mode | Target | +|------|--------| +| **XInput** | Xbox 360 (wired controller + XSM3 auth) | +| **DInput** | PC (DirectInput), legacy | +| **PS3** | PlayStation 3 | +| **Switch** | Nintendo Switch (wired) | +| **Wii U** | Wii U | +| **Xbox OG** | Original Xbox (XID: Gamepad, Steel Battalion, XRemote) | +| **PS Classic** | PlayStation Classic | +| **Web App** | Configuration / profiles over CDC | + +On **Pico 2 W**, Bluetooth (Bluepad32) runs on Core1; USB device runs on Core0. You can build with a **fixed** output mode (e.g. XINPUT only) or with **button combos** to switch modes at runtime (e.g. Start + D-pad held ~3 s). + +## Xbox 360 (XInput) support + +XInput mode works on **Xbox 360** with full **XSM3** authentication: + +- Descriptors and XSM3 flow aligned with [joypad-os](https://github.com/joypad-ai/joypad-os) for console compatibility. +- Single configuration; full XSM3 security string; init/verify handled in the main loop. +- USB is initialized before Core1 (BT) so the 360 can enumerate even while Bluetooth firmware loads. + +See [XInput_joypad-os_comparison.md](XInput_joypad-os_comparison.md) for technical details. + +## Input latency (PS5 / Xbox One over Bluetooth) + +- **Always send latest state** — In XInput (and similar) mode, the adapter sends the current gamepad state whenever the USB endpoint is free, instead of only when the BT stack flags “new” data. The host (e.g. 360) gets updates at its poll rate (e.g. 4 ms) with the freshest state. +- **Low-latency default** — The main loop uses **no** added delay by default (`MAIN_LOOP_DELAY_US=0`), so there is no extra delay between reading the controller and sending to USB. + +To trade a little latency for lower CPU use, configure with `MAIN_LOOP_DELAY_US=250` (or higher). See [IMPROVEMENTS.md](IMPROVEMENTS.md#latency-reduction). ## Building -See the project root and `scripts/build-with-vs.ps1` (or CMake directly) for build instructions. Board is selected via CMake `OGXM_BOARD` (e.g. `PI_PICO`, `PI_PICO2W`, `RP2040_ZERO`). +Build with **CMake** from the `Firmware/RP2040` directory. Required: + +- **Board:** `OGXM_BOARD` (e.g. `PI_PICO2W`, `PI_PICO`, `RP2040_ZERO`). +- **Pico SDK:** `PICO_SDK_PATH` pointing at the SDK (or use the project’s submodule). +- **Optional:** `OGXM_FIXED_DRIVER` to lock output mode (e.g. `XINPUT`, `PS3`); `OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON` to keep combos when a fixed driver is set. +- **Optional:** `MAIN_LOOP_DELAY_US` (default `0`) to set main-loop delay in microseconds. + +Outputs (`.elf`, `.uf2`, etc.) are produced in the chosen build directory; flash the `.uf2` to the board. ## Configuration -- **Board / driver:** Set at CMake configure time (`OGXM_BOARD`, fixed driver options). -- **Latency:** `MAIN_LOOP_DELAY_US` in `src/Board/Config.h` (or override via CMake). See [IMPROVEMENTS.md](IMPROVEMENTS.md#latency). +- **Board and driver:** Set at CMake configure time (`OGXM_BOARD`, `OGXM_FIXED_DRIVER`, `OGXM_FIXED_DRIVER_ALLOW_COMBOS`). +- **Latency:** `MAIN_LOOP_DELAY_US` — default `0` (low latency). Override via CMake (e.g. `-DMAIN_LOOP_DELAY_US=250`) if desired. See [IMPROVEMENTS.md](IMPROVEMENTS.md#latency-reduction). + +## Documentation + +| Document | Description | +|----------|-------------| +| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360. | +| [XInput_joypad-os_comparison.md](XInput_joypad-os_comparison.md) | XInput vs joypad-os (descriptors, XSM3, control handling). | diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index 2ece95f8..e11e245c 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -17,11 +17,9 @@ #define MAX_GAMEPADS 1 #endif -/** Main loop delay (device/core0) in microseconds. Lower = less input latency, higher CPU. - * 0 = no delay (lowest latency, highest CPU). 250–500 = good balance. 1000 = 1 ms (original). - * Override in CMake: add_compile_definitions(MAIN_LOOP_DELAY_US=0) for minimum latency. */ +/** Main loop delay (device/core0) in microseconds. 0 = low latency (default). 250+ = lower CPU. */ #ifndef MAIN_LOOP_DELAY_US - #define MAIN_LOOP_DELAY_US 250 + #define MAIN_LOOP_DELAY_US 0 #endif #if defined(CONFIG_OGXM_BOARD_PI_PICO) || defined(CONFIG_OGXM_BOARD_PI_PICO2) diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp index 9e7754c7..32f4706a 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp @@ -53,71 +53,67 @@ void XInputDevice::process(const uint8_t idx, Gamepad& gamepad) // joypad-os: run XSM3 crypto in task loop, not in USB callback xsm3_process_pending(); - if (gamepad.new_pad_in()) - { - in_report_.buttons[0] = 0; - in_report_.buttons[1] = 0; + // Always read latest state and send when USB is ready (reduces latency vs only sending on new_pad_in()) + in_report_.buttons[0] = 0; + in_report_.buttons[1] = 0; - Gamepad::PadIn gp_in = gamepad.get_pad_in(); + Gamepad::PadIn gp_in = gamepad.get_pad_in(); - switch (gp_in.dpad) - { - case Gamepad::DPAD_UP: - in_report_.buttons[0] = XInput::Buttons0::DPAD_UP; - break; - case Gamepad::DPAD_DOWN: - in_report_.buttons[0] = XInput::Buttons0::DPAD_DOWN; - break; - case Gamepad::DPAD_LEFT: - in_report_.buttons[0] = XInput::Buttons0::DPAD_LEFT; - break; - case Gamepad::DPAD_RIGHT: - in_report_.buttons[0] = XInput::Buttons0::DPAD_RIGHT; - break; - case Gamepad::DPAD_UP_LEFT: - in_report_.buttons[0] = XInput::Buttons0::DPAD_UP | XInput::Buttons0::DPAD_LEFT; - break; - case Gamepad::DPAD_UP_RIGHT: - in_report_.buttons[0] = XInput::Buttons0::DPAD_UP | XInput::Buttons0::DPAD_RIGHT; - break; - case Gamepad::DPAD_DOWN_LEFT: - in_report_.buttons[0] = XInput::Buttons0::DPAD_DOWN | XInput::Buttons0::DPAD_LEFT; - break; - case Gamepad::DPAD_DOWN_RIGHT: - in_report_.buttons[0] = XInput::Buttons0::DPAD_DOWN | XInput::Buttons0::DPAD_RIGHT; - break; - default: - break; - } + switch (gp_in.dpad) + { + case Gamepad::DPAD_UP: + in_report_.buttons[0] = XInput::Buttons0::DPAD_UP; + break; + case Gamepad::DPAD_DOWN: + in_report_.buttons[0] = XInput::Buttons0::DPAD_DOWN; + break; + case Gamepad::DPAD_LEFT: + in_report_.buttons[0] = XInput::Buttons0::DPAD_LEFT; + break; + case Gamepad::DPAD_RIGHT: + in_report_.buttons[0] = XInput::Buttons0::DPAD_RIGHT; + break; + case Gamepad::DPAD_UP_LEFT: + in_report_.buttons[0] = XInput::Buttons0::DPAD_UP | XInput::Buttons0::DPAD_LEFT; + break; + case Gamepad::DPAD_UP_RIGHT: + in_report_.buttons[0] = XInput::Buttons0::DPAD_UP | XInput::Buttons0::DPAD_RIGHT; + break; + case Gamepad::DPAD_DOWN_LEFT: + in_report_.buttons[0] = XInput::Buttons0::DPAD_DOWN | XInput::Buttons0::DPAD_LEFT; + break; + case Gamepad::DPAD_DOWN_RIGHT: + in_report_.buttons[0] = XInput::Buttons0::DPAD_DOWN | XInput::Buttons0::DPAD_RIGHT; + break; + default: + break; + } - if (gp_in.buttons & Gamepad::BUTTON_BACK) in_report_.buttons[0] |= XInput::Buttons0::BACK; - if (gp_in.buttons & Gamepad::BUTTON_START) in_report_.buttons[0] |= XInput::Buttons0::START; - if (gp_in.buttons & Gamepad::BUTTON_L3) in_report_.buttons[0] |= XInput::Buttons0::L3; - if (gp_in.buttons & Gamepad::BUTTON_R3) in_report_.buttons[0] |= XInput::Buttons0::R3; + if (gp_in.buttons & Gamepad::BUTTON_BACK) in_report_.buttons[0] |= XInput::Buttons0::BACK; + if (gp_in.buttons & Gamepad::BUTTON_START) in_report_.buttons[0] |= XInput::Buttons0::START; + if (gp_in.buttons & Gamepad::BUTTON_L3) in_report_.buttons[0] |= XInput::Buttons0::L3; + if (gp_in.buttons & Gamepad::BUTTON_R3) in_report_.buttons[0] |= XInput::Buttons0::R3; - if (gp_in.buttons & Gamepad::BUTTON_X) in_report_.buttons[1] |= XInput::Buttons1::X; - if (gp_in.buttons & Gamepad::BUTTON_A) in_report_.buttons[1] |= XInput::Buttons1::A; - if (gp_in.buttons & Gamepad::BUTTON_Y) in_report_.buttons[1] |= XInput::Buttons1::Y; - if (gp_in.buttons & Gamepad::BUTTON_B) in_report_.buttons[1] |= XInput::Buttons1::B; - if (gp_in.buttons & Gamepad::BUTTON_LB) in_report_.buttons[1] |= XInput::Buttons1::LB; - if (gp_in.buttons & Gamepad::BUTTON_RB) in_report_.buttons[1] |= XInput::Buttons1::RB; - if (gp_in.buttons & Gamepad::BUTTON_SYS) in_report_.buttons[1] |= XInput::Buttons1::HOME; + if (gp_in.buttons & Gamepad::BUTTON_X) in_report_.buttons[1] |= XInput::Buttons1::X; + if (gp_in.buttons & Gamepad::BUTTON_A) in_report_.buttons[1] |= XInput::Buttons1::A; + if (gp_in.buttons & Gamepad::BUTTON_Y) in_report_.buttons[1] |= XInput::Buttons1::Y; + if (gp_in.buttons & Gamepad::BUTTON_B) in_report_.buttons[1] |= XInput::Buttons1::B; + if (gp_in.buttons & Gamepad::BUTTON_LB) in_report_.buttons[1] |= XInput::Buttons1::LB; + if (gp_in.buttons & Gamepad::BUTTON_RB) in_report_.buttons[1] |= XInput::Buttons1::RB; + if (gp_in.buttons & Gamepad::BUTTON_SYS) in_report_.buttons[1] |= XInput::Buttons1::HOME; - in_report_.trigger_l = gp_in.trigger_l; - in_report_.trigger_r = gp_in.trigger_r; + in_report_.trigger_l = gp_in.trigger_l; + in_report_.trigger_r = gp_in.trigger_r; - in_report_.joystick_lx = gp_in.joystick_lx; - in_report_.joystick_ly = Range::invert(gp_in.joystick_ly); - in_report_.joystick_rx = gp_in.joystick_rx; - in_report_.joystick_ry = Range::invert(gp_in.joystick_ry); + in_report_.joystick_lx = gp_in.joystick_lx; + in_report_.joystick_ly = Range::invert(gp_in.joystick_ly); + in_report_.joystick_rx = gp_in.joystick_rx; + in_report_.joystick_ry = Range::invert(gp_in.joystick_ry); - if (tud_suspended()) - { - tud_remote_wakeup(); - } + if (tud_suspended()) + tud_remote_wakeup(); - tud_xinput::send_report((uint8_t*)&in_report_, sizeof(XInput::InReport)); - } + tud_xinput::send_report((uint8_t*)&in_report_, sizeof(XInput::InReport)); if (tud_xinput::receive_report(reinterpret_cast(&out_report_), sizeof(XInput::OutReport)) && out_report_.report_id == XInput::OutReportID::RUMBLE) From 4eff855961fe26f64d28bc0c965834cdb7677005 Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Fri, 27 Feb 2026 07:09:36 -0500 Subject: [PATCH 18/42] Revise README with version updates and features Updated README to include new features and changes for version 1.0.0.4a and 1.0.0.3a patched. --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e444dd4d..d7754594 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ By default the OGX-Mini will emulate an OG Xbox controller, you must hold a butt Start = Plus (Switch) = Options (Dualsense/DS4) -- XInput +- XInput (Xbox 360) - Start + Dpad Up - Original Xbox - Start + Dpad Right @@ -87,6 +87,14 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. + +==== Version 1.0.0.4a === +- Xbox 360 no longer requires the USB patch to authenticate, uses the same authentication as Joypad-OS to do official handshake with Retail consoles. Homebrew/ Jailbreaking is no longer required to use the XINPUT mode on 360 but it will no longer output to PC. +- Improved latency on Xbox 360 and PS3 controllers. +- Added build flags so you can make it only output in a specific mode and disable mode switching. +- Using a PS5 controller allows you to tap the touchpad to enable or disable the adaptive triggers. + + === Version 1.0.0.3a patched === - Ability to emulate the GameCube controller adapter for Wii U. (Also tested on Switch 1/ 2) - Wii U & Switch Pro controllers are supported fully with working LT and RT - Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. From 14f8de8a54d56becdcf0ebe52bce9596020c7401 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Fri, 27 Feb 2026 09:43:46 -0500 Subject: [PATCH 19/42] Sync README and LICENSE: credits, third-party licenses, Xbox 360 (libxsm3) Made-with: Cursor --- LICENSE | 7 +++++++ README.md | 23 +++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 9ee7aa25..e01d42e2 100644 --- a/LICENSE +++ b/LICENSE @@ -6,6 +6,13 @@ under Apache 2.0 (Bluepad32) and BTStack's proprietary (non-commercial) license. For full details, please refer to the repositories contained in the Firmware/external directory of this project. +Xbox 360 console authentication: Builds that emulate Xbox 360 controllers use +libxsm3 (Xbox Security Method 3) for authentication with retail Xbox 360 +consoles. libxsm3 is licensed under the GNU Lesser General Public License +v2.1 (or later). A copy of the LGPL v2.1 is included in +Firmware/external/libxsm3/LICENSE.txt. libxsm3 also uses ExCrypt (3-clause BSD); +see Firmware/external/libxsm3/README.md for credits. + Copyright (c) 2024 wiredOpposite (wiredopposite.com) Copyright (c) 2024 OpenStickCommunity (gp2040-ce.info) Copyright (c) 2021 Jason Skuby (mytechtoybox.com) diff --git a/README.md b/README.md index e444dd4d..b004a922 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles - Original Xbox - Playstation 3 - Nintendo Switch 1 & 2 (docked) -- XInput (UsbdSecPatch no longer required, works without it) +- XInput (Xbox 360, UsbdSecPatch no longer required) - Playstation Classic - DInput - Wii U (GameCube Adapter) @@ -19,7 +19,7 @@ By default the OGX-Mini will emulate an OG Xbox controller, you must hold a butt Start = Plus (Switch) = Options (Dualsense/DS4) -- XInput +- XInput (Xbox 360) - Start + Dpad Up - Original Xbox - Start + Dpad Right @@ -87,6 +87,14 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. + +==== Version 1.0.0.4a === +- Xbox 360 no longer requires the USB patch to authenticate, uses the same authentication as Joypad-OS to do official handshake with Retail consoles. Homebrew/ Jailbreaking is no longer required to use the XINPUT mode on 360 but it will no longer output to PC. +- Improved latency on Xbox 360 and PS3 controllers. +- Added build flags so you can make it only output in a specific mode and disable mode switching. +- Using a PS5 controller allows you to tap the touchpad to enable or disable the adaptive triggers. + +=== Version 1.0.0.3a patched === - Ability to emulate the GameCube controller adapter for Wii U. (Also tested on Switch 1/ 2) - Wii U & Switch Pro controllers are supported fully with working LT and RT - Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. @@ -176,3 +184,14 @@ When you build with ESP-IDF, Cmake will run a python script that copies the nece # Credit to the original creator [https://wiredopposite.github.io/](https://github.com/wiredopposite/OGX-Mini/tree/master) for the original base of the project! +## Other projects that have helped enhance this fork + +- **[Joypad OS](https://github.com/joypad-ai/joypad-os)** — Reference for Xbox 360 (XSM3) authentication with retail consoles; XInput mode on 360 follows the same approach. +- **[Bluepad32](https://github.com/ricardoquesada/bluepad32)** — Bluetooth controller support (Pico W / Pico 2 W). +- **[GP2040-CE](https://github.com/OpenStickCommunity/GP2040-CE)** — USB device output modes (credited in the root LICENSE). + +## Licenses and third-party code + +- **Xbox 360 console authentication:** XInput builds that work on retail Xbox 360 consoles use [libxsm3](https://github.com/InvoxiPlayGames/libxsm3) (Xbox Security Method 3). libxsm3 is licensed under the GNU Lesser General Public License v2.1 or later; see `Firmware/external/libxsm3/LICENSE.txt`. libxsm3 credits oct0xor, emoose (ExCrypt), and sanjay900; see `Firmware/external/libxsm3/README.md`. +- **Other dependencies:** See the root `LICENSE` file and the `Firmware/external` directory for Bluepad32, BTStack, TinyUSB, Pico SDK, and other third-party licenses. + From 363bb3fe2c5f664650010c6e2e540728c23a340f Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Fri, 27 Feb 2026 09:53:58 -0500 Subject: [PATCH 20/42] Add libxsm3 for Xbox 360 (XSM3) auth: source, LICENSE.txt, README.md Made-with: Cursor --- Firmware/external/libxsm3/.gitignore | 1 + Firmware/external/libxsm3/LICENSE.txt | 502 +++++++++++++++++++ Firmware/external/libxsm3/README.md | 59 +++ Firmware/external/libxsm3/excrypt.h | 39 ++ Firmware/external/libxsm3/excrypt_des.c | 198 ++++++++ Firmware/external/libxsm3/excrypt_des.h | 24 + Firmware/external/libxsm3/excrypt_des_data.h | 157 ++++++ Firmware/external/libxsm3/excrypt_parve.c | 78 +++ Firmware/external/libxsm3/excrypt_parve.h | 9 + Firmware/external/libxsm3/excrypt_sha.c | 155 ++++++ Firmware/external/libxsm3/excrypt_sha.h | 18 + Firmware/external/libxsm3/usbdsec.c | 153 ++++++ Firmware/external/libxsm3/usbdsec.h | 29 ++ Firmware/external/libxsm3/xsm3.c | 301 +++++++++++ Firmware/external/libxsm3/xsm3.h | 51 ++ 15 files changed, 1774 insertions(+) create mode 100644 Firmware/external/libxsm3/.gitignore create mode 100644 Firmware/external/libxsm3/LICENSE.txt create mode 100644 Firmware/external/libxsm3/README.md create mode 100644 Firmware/external/libxsm3/excrypt.h create mode 100644 Firmware/external/libxsm3/excrypt_des.c create mode 100644 Firmware/external/libxsm3/excrypt_des.h create mode 100644 Firmware/external/libxsm3/excrypt_des_data.h create mode 100644 Firmware/external/libxsm3/excrypt_parve.c create mode 100644 Firmware/external/libxsm3/excrypt_parve.h create mode 100644 Firmware/external/libxsm3/excrypt_sha.c create mode 100644 Firmware/external/libxsm3/excrypt_sha.h create mode 100644 Firmware/external/libxsm3/usbdsec.c create mode 100644 Firmware/external/libxsm3/usbdsec.h create mode 100644 Firmware/external/libxsm3/xsm3.c create mode 100644 Firmware/external/libxsm3/xsm3.h diff --git a/Firmware/external/libxsm3/.gitignore b/Firmware/external/libxsm3/.gitignore new file mode 100644 index 00000000..496ee2ca --- /dev/null +++ b/Firmware/external/libxsm3/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/Firmware/external/libxsm3/LICENSE.txt b/Firmware/external/libxsm3/LICENSE.txt new file mode 100644 index 00000000..f166cc57 --- /dev/null +++ b/Firmware/external/libxsm3/LICENSE.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! \ No newline at end of file diff --git a/Firmware/external/libxsm3/README.md b/Firmware/external/libxsm3/README.md new file mode 100644 index 00000000..c592cee1 --- /dev/null +++ b/Firmware/external/libxsm3/README.md @@ -0,0 +1,59 @@ +# libxsm3 + +A "library" for completing Xbox Security Method 3 challenges used by the Xbox 360 video game console to authenticate controllers. + +## What this does + +This library allows an Xbox 360 controller emulator to authenticate with retail consoles. + +## TODO + +- Make sure this is able to work on embedded platforms (e.g. Pi Pico). +- Document more of the values used in the identification packet. +- Unit tests and being able to verify packets from a controller to be valid. + +## Uses + +libxsm3 is used in the [Santroller](https://github.com/santroller/santroller) and [portal_of_flipper](https://github.com/sanjay900/portal_of_flipper) projects. + +## Credits + +- [oct0xor](https://github.com/oct0xor) for reversing, documenting and implementing much of the process. ([blog post](https://oct0xor.github.io/2017/05/03/xsm3/), [source code](https://github.com/oct0xor/xbox_security_method_3)) +- [emoose](https://github.com/emoose) for reimplementing many of the XeCrypt functions in [ExCrypt](https://github.com/emoose/ExCrypt). +- [sanjay900](https://github.com/sanjay900) and an anonymous contributor for helping discover the retail keys. + +## License + +libxsm3 is licensed under the GNU Lesser General Public License version 2.1, or (at your option) any later version. + +This project uses [ExCrypt](https://github.com/emoose/ExCrypt), licensed under the [3-clause BSD license](https://github.com/emoose/ExCrypt/blob/b2e037c3102de22d1107d1e362df4ce407d964ac/LICENSE) - all files included are prefixed with "excrypt". + +## Example + +Being used in a handler for setup requests for the XSM3 interface descriptor + +```c +#include "xsm3.h" +void xsm3_setup_request_handler(usb_setup_request* ctrl) { + switch (ctrl->bRequest) { + case 0x81: + xsm3_initialise_state(); + xsm3_set_identification_data(xsm3_id_data_ms_controller); + ctrl->send_data(xsm3_id_data_ms_controller); + break; + case 0x82: + xsm3_do_challenge_init(ctrl->in_data); + break; + case 0x87: + xsm3_do_challenge_verify(ctrl->in_data); + break; + case 0x83: + ctrl->send_data(xsm3_challenge_response); + break; + case 0x86: + short state = 2; // 1 = in-progress, 2 = complete + ctrl->send_data(&state); + break; + } +} +``` diff --git a/Firmware/external/libxsm3/excrypt.h b/Firmware/external/libxsm3/excrypt.h new file mode 100644 index 00000000..47049c72 --- /dev/null +++ b/Firmware/external/libxsm3/excrypt.h @@ -0,0 +1,39 @@ +#ifndef EXCRYPT_H_ +#define EXCRYPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#if(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define SWAP16(i) i +#define SWAP32(i) i +#define SWAP64(i) i +#else +#define SWAP16(i) ((((i) & 0xFF) << 8 | ((i) >> 8) & 0xFF) & 0xFFFF) +#define SWAP32(i) (((i) & 0xff) << 24 | ((i) & 0xff00) << 8 | ((i) & 0xff0000) >> 8 | ((i) >> 24) & 0xff) +#define SWAP64(i) (SWAP32((i) & 0xFFFFFFFF) << 32 | SWAP32(((i) >> 32) & 0xFFFFFFFF)) +#endif + +#define U8V(data) ((uint8_t)(data) & 0xFF) +#define ROTL8(data, bits) (U8V((data) << (bits)) | ((data) >> (8 - (bits)))) + +#define U16V(data) ((uint16_t)(data) & 0xFFFF) +#define ROTL16(data, bits) (U16V((data) << (bits)) | ((data) >> (16 - (bits)))) + +#define U32V(data) ((uint32_t)(data) & 0xFFFFFFFF) +#define ROTL32(data, bits) (U32V((data) << (bits)) | ((data) >> (32 - (bits)))) + +#define ROTL64(data, bits) (((data) << (bits)) | ((data) >> (64 - (bits)))) + +typedef int BOOL; + +#include "excrypt_des.h" +#include "excrypt_sha.h" +#include "excrypt_parve.h" +#ifdef __cplusplus +} +#endif + +#endif // EXCRYPT_H_ \ No newline at end of file diff --git a/Firmware/external/libxsm3/excrypt_des.c b/Firmware/external/libxsm3/excrypt_des.c new file mode 100644 index 00000000..a8c27599 --- /dev/null +++ b/Firmware/external/libxsm3/excrypt_des.c @@ -0,0 +1,198 @@ +#include "excrypt.h" +#include "excrypt_des_data.h" +#include + +#define LODWORD(_qw) ((uint32_t)(_qw)) +#define HIDWORD(_qw) ((uint32_t)(((_qw) >> 32) & 0xffffffff)) + +// DES code based on https://github.com/fffaraz/cppDES + +void ExCryptDesParity(const uint8_t* input, uint32_t input_size, uint8_t* output) +{ + for (uint32_t i = 0; i < input_size; i++) + { + uint8_t parity = input[i]; + + parity ^= parity >> 4; + parity ^= parity >> 2; + parity ^= parity >> 1; + + output[i] = (input[i] & 0xFE) | (~parity & 1); + } +} + +void ExCryptDesKey(EXCRYPT_DES_STATE* state, const uint8_t* key) +{ + uint64_t qkey = SWAP64(*(const uint64_t*)key); + + // initial key schedule calculation + uint64_t permuted_choice_1 = 0; // 56 bits + for (int i = 0; i < 56; i++) + { + permuted_choice_1 <<= 1; + permuted_choice_1 |= (qkey >> (64 - PC1[i])) & LB64_MASK; + } + + // 28 bits + uint32_t C = (uint32_t)((permuted_choice_1 >> 28) & 0x000000000fffffff); + uint32_t D = (uint32_t)(permuted_choice_1 & 0x000000000fffffff); + + // Calculation of the 16 keys + for (int i = 0; i < 16; i++) + { + // key schedule, shifting Ci and Di + for (int j = 0; j < ITERATION_SHIFT[i]; j++) + { + C = (0x0fffffff & (C << 1)) | (0x00000001 & (C >> 27)); + D = (0x0fffffff & (D << 1)) | (0x00000001 & (D >> 27)); + } + + uint64_t permuted_choice_2 = (((uint64_t)C) << 28) | (uint64_t)D; + + uint64_t sub_key = 0; // 48 bits (2*24) + for (int j = 0; j < 48; j++) + { + sub_key <<= 1; + sub_key |= (permuted_choice_2 >> (56 - PC2[j])) & LB64_MASK; + } + state->keytab[i] = sub_key; + } +} + +uint32_t f(uint32_t R, uint64_t k) +{ + // applying expansion permutation and returning 48-bit data + uint64_t s_input = 0; + for (int i = 0; i < 48; i++) + { + s_input <<= 1; + s_input |= (uint64_t)((R >> (32 - EXPANSION[i])) & LB32_MASK); + } + + // XORing expanded Ri with Ki, the round key + s_input = s_input ^ k; + + // applying S-Boxes function and returning 32-bit data + uint32_t s_output = 0; + for (int i = 0; i < 8; i++) + { + // Outer bits + char row = (char)((s_input & (0x0000840000000000 >> 6 * i)) >> (42 - 6 * i)); + row = (row >> 4) | (row & 0x01); + + // Middle 4 bits of input + char column = (char)((s_input & (0x0000780000000000 >> 6 * i)) >> (43 - 6 * i)); + + s_output <<= 4; + s_output |= (uint32_t)(SBOX[i][16 * row + column] & 0x0f); + } + + // applying the round permutation + uint32_t f_result = 0; + for (int i = 0; i < 32; i++) + { + f_result <<= 1; + f_result |= (s_output >> (32 - PBOX[i])) & LB32_MASK; + } + + return f_result; +} + +void feistel(uint32_t* L, uint32_t* R, uint32_t F) +{ + uint32_t temp = *R; + *R = *L ^ F; + *L = temp; +} + +void ExCryptDesEcb(const EXCRYPT_DES_STATE* state, const uint8_t* input, uint8_t* output, uint8_t encrypt) +{ + uint64_t block; + memcpy(&block, input, sizeof(uint64_t)); + block = SWAP64(block); + //uint64_t block = SWAP64(*(uint64_t*)input) + + + // initial permutation + uint64_t result = 0; + for (int i = 0; i < 64; i++) + { + result <<= 1; + result |= (block >> (64 - IP[i])) & LB64_MASK; + } + + // dividing T' into two 32-bit parts + uint32_t L = HIDWORD(result); + uint32_t R = LODWORD(result); + + // 16 rounds + for (int i = 0; i < 16; i++) + { + uint32_t F = !encrypt ? f(R, state->keytab[15 - i]) : f(R, state->keytab[i]); + feistel(&L, &R, F); + } + + // swapping the two parts + block = (((uint64_t)R) << 32) | (uint64_t)L; + + // inverse initial permutation + result = 0; + for (int i = 0; i < 64; i++) + { + result <<= 1; + result |= (block >> (64 - FP[i])) & LB64_MASK; + } + result = SWAP64(result); + memcpy(output, &result, sizeof(result)); +} + +void ExCryptDes3Key(EXCRYPT_DES3_STATE* state, const uint64_t* keys) +{ + ExCryptDesKey(&state->des_state[0], (const uint8_t*)& keys[0]); + ExCryptDesKey(&state->des_state[1], (const uint8_t*)& keys[1]); + ExCryptDesKey(&state->des_state[2], (const uint8_t*)& keys[2]); +} + +void ExCryptDes3Ecb(const EXCRYPT_DES3_STATE* state, const uint8_t* input, uint8_t* output, uint8_t encrypt) +{ + if (encrypt) + { + ExCryptDesEcb(&state->des_state[0], input, output, encrypt); + ExCryptDesEcb(&state->des_state[1], output, output, !encrypt); + ExCryptDesEcb(&state->des_state[2], output, output, encrypt); + } + else + { + ExCryptDesEcb(&state->des_state[2], input, output, encrypt); + ExCryptDesEcb(&state->des_state[1], output, output, !encrypt); + ExCryptDesEcb(&state->des_state[0], output, output, encrypt); + } +} + +void ExCryptDes3Cbc(const EXCRYPT_DES3_STATE* state, const uint8_t* input, uint32_t input_size, uint8_t* output, uint8_t* feed, uint8_t encrypt) +{ + uint64_t last_block = *(uint64_t*)feed; + for (uint32_t i = 0; i < input_size / 8; i++) + { + if (encrypt) { + uint64_t temp; + memcpy(&temp, input, sizeof(temp)); + temp = temp ^ last_block; + memcpy(output, &temp, sizeof(temp)); + ExCryptDes3Ecb(state, output, output, encrypt); + memcpy(&last_block, output, sizeof(last_block)); + } + else + { + ExCryptDes3Ecb(state, input, output, encrypt); + uint64_t temp; + memcpy(&temp, output, sizeof(temp)); + temp = temp ^ last_block; + memcpy(output, &temp, sizeof(temp)); + memcpy(&last_block, input, sizeof(last_block)); + } + input += 8; + output += 8; + } + *(uint64_t*)feed = last_block; +} diff --git a/Firmware/external/libxsm3/excrypt_des.h b/Firmware/external/libxsm3/excrypt_des.h new file mode 100644 index 00000000..f4b3ee17 --- /dev/null +++ b/Firmware/external/libxsm3/excrypt_des.h @@ -0,0 +1,24 @@ +#ifndef EXCRYPT_DES_H_ +#define EXCRYPT_DES_H_ +// DES & 3DES functions + +typedef struct _EXCRYPT_DES_STATE +{ + uint64_t keytab[16]; +} EXCRYPT_DES_STATE; + +void ExCryptDesParity(const uint8_t* input, uint32_t input_size, uint8_t* output); + +void ExCryptDesKey(EXCRYPT_DES_STATE* state, const uint8_t* key); +void ExCryptDesEcb(const EXCRYPT_DES_STATE* state, const uint8_t* input, uint8_t* output, uint8_t encrypt); + +typedef struct _EXCRYPT_DES3_STATE +{ + EXCRYPT_DES_STATE des_state[3]; +} EXCRYPT_DES3_STATE; + +void ExCryptDes3Key(EXCRYPT_DES3_STATE* state, const uint64_t* keys); +void ExCryptDes3Ecb(const EXCRYPT_DES3_STATE* state, const uint8_t* input, uint8_t* output, uint8_t encrypt); +void ExCryptDes3Cbc(const EXCRYPT_DES3_STATE* state, const uint8_t* input, uint32_t input_size, uint8_t* output, uint8_t* feed, uint8_t encrypt); + +#endif // EXCRYPT_DES_H_ \ No newline at end of file diff --git a/Firmware/external/libxsm3/excrypt_des_data.h b/Firmware/external/libxsm3/excrypt_des_data.h new file mode 100644 index 00000000..d585e875 --- /dev/null +++ b/Firmware/external/libxsm3/excrypt_des_data.h @@ -0,0 +1,157 @@ +#ifndef EXCRYPT_DES_DATA_H_ +#define EXCRYPT_DES_DATA_H_ +// Data needed by DES/3DES functions +// (only included by excrypt_des.c - no headers should include this!) + +#define LB32_MASK 0x00000001 +#define LB64_MASK 0x0000000000000001 +#define L64_MASK 0x00000000ffffffff + +// Initial Permutation Table [8*8] +static const char IP[] = +{ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +// Inverse Initial Permutation Table [8*8] +static const char FP[] = +{ + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; + +// Expansion table [6*8] +static const char EXPANSION[] = +{ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 +}; + +// The S-Box tables [8*16*4] +static const char SBOX[8][64] = +{ + { + // S1 + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 +}, +{ + // S2 + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 +}, +{ + // S3 + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 +}, +{ + // S4 + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 +}, +{ + // S5 + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 +}, +{ + // S6 + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 +}, +{ + // S7 + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 +}, +{ + // S8 + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 +} +}; + +// Post S-Box permutation [4*8] +static const char PBOX[] = +{ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 +}; + +// Permuted Choice 1 Table [7*8] +static const char PC1[] = +{ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 +}; + +// Permuted Choice 2 Table [6*8] +static const char PC2[] = +{ + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 +}; + +// Iteration Shift Array +static const char ITERATION_SHIFT[] = +{ + // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +#endif // EXCRYPT_DES_DATA_H_ \ No newline at end of file diff --git a/Firmware/external/libxsm3/excrypt_parve.c b/Firmware/external/libxsm3/excrypt_parve.c new file mode 100644 index 00000000..bebb023e --- /dev/null +++ b/Firmware/external/libxsm3/excrypt_parve.c @@ -0,0 +1,78 @@ +#include +#include + +#include "excrypt.h" + +void ExCryptParveEcb(const uint8_t* key, const uint8_t* sbox, const uint8_t* input, uint8_t* output) +{ + uint8_t block[9]; + + memcpy(block, input, 8); + block[8] = block[0]; + + for (int i = 8; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + uint8_t x = key[j] + block[j] + i; + uint8_t y = sbox[x] + block[j + 1]; + block[j + 1] = ROTL8(y, 1); + } + + block[0] = block[8]; + } + + memcpy(output, block, 8); +} + +void ExCryptParveCbcMac(const uint8_t* key, const uint8_t* sbox, const uint8_t* iv, const uint8_t* input, uint32_t input_size, uint8_t* output) +{ + uint64_t block; + uint64_t temp; + memcpy(&block, iv, 8); + + if (input_size >= 8) + { + for (uint32_t i = 0; i < input_size / 8; i++) + { + memcpy(&temp, input + (i * 8), sizeof(temp)); + block ^= temp; + ExCryptParveEcb(key, sbox, (uint8_t*)&block, (uint8_t*)&block); + } + } + + memcpy(output, &block, 8); +} + +void ExCryptChainAndSumMac(const uint32_t* cd, const uint32_t* ab, const uint32_t* input, uint32_t input_dwords, uint32_t* output) +{ + uint64_t out0 = 0; + uint64_t out1 = 0; + + uint32_t ab0 = SWAP32(ab[0]) % 0x7FFFFFFF; + uint32_t ab1 = SWAP32(ab[1]) % 0x7FFFFFFF; + uint32_t cd0 = SWAP32(cd[0]) % 0x7FFFFFFF; + uint32_t cd1 = SWAP32(cd[1]) % 0x7FFFFFFF; + + for (uint32_t i = 0; i < input_dwords / 2; i++) + { + out0 += (uint64_t)SWAP32(input[0]) * 0xE79A9C1; + out0 = (out0 % 0x7FFFFFFF) * ab0; + out0 += ab1; + out0 = out0 % 0x7FFFFFFF; + + out1 += out0; + + out0 = (uint64_t)(SWAP32(input[1]) + out0) * cd0; + out0 = (out0 % 0x7FFFFFFF) + cd1; + out0 = out0 % 0x7FFFFFFF; + + out1 += out0; + + input += 2; + } + out0 = SWAP32((out0 + ab1) % 0x7FFFFFFF); + out1 = SWAP32((out1 + cd1) % 0x7FFFFFFF); + memcpy(output, &out0, sizeof(uint32_t)); + memcpy(output+1, &out1, sizeof(uint32_t)); +} diff --git a/Firmware/external/libxsm3/excrypt_parve.h b/Firmware/external/libxsm3/excrypt_parve.h new file mode 100644 index 00000000..b7082dfa --- /dev/null +++ b/Firmware/external/libxsm3/excrypt_parve.h @@ -0,0 +1,9 @@ +#ifndef EXCRYPT_PARVE_H_ +#define EXCRYPT_PARVE_H_ +// "Parve" functions, seem to be used during controller auth + +void ExCryptParveEcb(const uint8_t* key, const uint8_t* sbox, const uint8_t* input, uint8_t* output); +void ExCryptParveCbcMac(const uint8_t* key, const uint8_t* sbox, const uint8_t* iv, const uint8_t* input, uint32_t input_size, uint8_t* output); +void ExCryptChainAndSumMac(const uint32_t* cd, const uint32_t* ab, const uint32_t* input, uint32_t input_dwords, uint32_t* output); + +#endif // EXCRYPT_PARVE_H_ \ No newline at end of file diff --git a/Firmware/external/libxsm3/excrypt_sha.c b/Firmware/external/libxsm3/excrypt_sha.c new file mode 100644 index 00000000..a68e3468 --- /dev/null +++ b/Firmware/external/libxsm3/excrypt_sha.c @@ -0,0 +1,155 @@ +#include +#include + +#include "excrypt.h" + +// SHA1 code based on https://github.com/mohaps/TinySHA1 + +void sha1_process_block(EXCRYPT_SHA_STATE* state) +{ + uint32_t w[80]; + for (size_t i = 0; i < 16; i++) { + w[i] = ((uint32_t)state->buffer[i * 4 + 0] << 24); + w[i] |= ((uint32_t)state->buffer[i * 4 + 1] << 16); + w[i] |= ((uint32_t)state->buffer[i * 4 + 2] << 8); + w[i] |= ((uint32_t)state->buffer[i * 4 + 3]); + } + for (size_t i = 16; i < 80; i++) { + w[i] = ROTL32((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); + } + + uint32_t a = state->state[0]; + uint32_t b = state->state[1]; + uint32_t c = state->state[2]; + uint32_t d = state->state[3]; + uint32_t e = state->state[4]; + + for (int i = 0; i < 80; ++i) { + uint32_t f = 0; + uint32_t k = 0; + + if (i < 20) { + f = (b & c) | (~b & d); + k = 0x5A827999; + } + else if (i < 40) { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } + else if (i < 60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } + else { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + uint32_t temp = ROTL32(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = ROTL32(b, 30); + b = a; + a = temp; + } + + state->state[0] += a; + state->state[1] += b; + state->state[2] += c; + state->state[3] += d; + state->state[4] += e; +} + +void sha1_process_byte(EXCRYPT_SHA_STATE* state, uint8_t octet) +{ + uint32_t offset = state->count++ & 0x3F; + state->buffer[offset] = octet; + if ((state->count & 0x3F) == 0) + { + sha1_process_block(state); + } +} + +void ExCryptShaInit(EXCRYPT_SHA_STATE* state) +{ + state->count = 0; + state->state[0] = 0x67452301; + state->state[1] = 0xEFCDAB89; + state->state[2] = 0x98BADCFE; + state->state[3] = 0x10325476; + state->state[4] = 0xC3D2E1F0; +} + +void ExCryptShaUpdate(EXCRYPT_SHA_STATE* state, const uint8_t* input, uint32_t input_size) +{ + for (uint32_t i = 0; i < input_size; i++) + { + sha1_process_byte(state, input[i]); + } +} + +void ExCryptShaFinal(EXCRYPT_SHA_STATE* state, uint8_t* output, uint32_t output_size) +{ + uint64_t bit_count = (uint64_t)state->count * 8; + + sha1_process_byte(state, 0x80); + + if ((state->count & 0x3F) > 56) + { + while ((state->count & 0x3F) != 0) + { + sha1_process_byte(state, 0); + } + while ((state->count & 0x3F) < 56) + { + sha1_process_byte(state, 0); + } + } + else + { + while ((state->count & 0x3F) < 56) + { + sha1_process_byte(state, 0); + } + } + + sha1_process_byte(state, 0); + sha1_process_byte(state, 0); + sha1_process_byte(state, 0); + sha1_process_byte(state, 0); + + sha1_process_byte(state, (uint8_t)((bit_count >> 24) & 0xFF)); + sha1_process_byte(state, (uint8_t)((bit_count >> 16) & 0xFF)); + sha1_process_byte(state, (uint8_t)((bit_count >> 8) & 0xFF)); + sha1_process_byte(state, (uint8_t)((bit_count) & 0xFF)); + + //sha1_process_block(state); + uint32_t result[5]; + result[0] = SWAP32(state->state[0]); + result[1] = SWAP32(state->state[1]); + result[2] = SWAP32(state->state[2]); + result[3] = SWAP32(state->state[3]); + result[4] = SWAP32(state->state[4]); + memcpy(output, result, 0x14); +} + +void ExCryptSha(const uint8_t* input1, uint32_t input1_size, const uint8_t* input2, uint32_t input2_size, + const uint8_t* input3, uint32_t input3_size, uint8_t* output, uint32_t output_size) +{ + EXCRYPT_SHA_STATE state[1]; + ExCryptShaInit(state); + + if (input1 && input1_size) + { + ExCryptShaUpdate(state, input1, input1_size); + } + if (input2 && input2_size) + { + ExCryptShaUpdate(state, input2, input2_size); + } + if (input3 && input3_size) + { + ExCryptShaUpdate(state, input3, input3_size); + } + + ExCryptShaFinal(state, output, output_size); +} \ No newline at end of file diff --git a/Firmware/external/libxsm3/excrypt_sha.h b/Firmware/external/libxsm3/excrypt_sha.h new file mode 100644 index 00000000..80024d85 --- /dev/null +++ b/Firmware/external/libxsm3/excrypt_sha.h @@ -0,0 +1,18 @@ +#ifndef EXCRYPT_SHA_H_ +#define EXCRYPT_SHA_H_ +// SHA1 hash & HMAC algorithm + +typedef struct _EXCRYPT_SHA_STATE +{ + uint32_t count; + uint32_t state[5]; + uint8_t buffer[64]; +} EXCRYPT_SHA_STATE; + +void ExCryptShaInit(EXCRYPT_SHA_STATE* state); +void ExCryptShaUpdate(EXCRYPT_SHA_STATE* state, const uint8_t* input, uint32_t input_size); +void ExCryptShaFinal(EXCRYPT_SHA_STATE* state, uint8_t* output, uint32_t output_size); +void ExCryptSha(const uint8_t* input1, uint32_t input1_size, const uint8_t* input2, uint32_t input2_size, + const uint8_t* input3, uint32_t input3_size, uint8_t* output, uint32_t output_size); + +#endif // EXCRYPT_SHA_H_ \ No newline at end of file diff --git a/Firmware/external/libxsm3/usbdsec.c b/Firmware/external/libxsm3/usbdsec.c new file mode 100644 index 00000000..d5ab64e1 --- /dev/null +++ b/Firmware/external/libxsm3/usbdsec.c @@ -0,0 +1,153 @@ +/* + usbdsec.c - part of libxsm3 + Copyright (C) 2013 oct0xor + Copyright (C) 2022 InvoxiPlayGames + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include "excrypt.h" + +static uint8_t UsbdSecSboxData[256] __attribute__ ((aligned(4))) = { + 0xB0, 0x3D, 0x9B, 0x70, 0xF3, 0xC7, 0x80, 0x60, + 0x73, 0x9F, 0x6C, 0xC0, 0xF1, 0x3D, 0xBB, 0x40, + 0xB3, 0xC8, 0x37, 0x14, 0xDF, 0x49, 0xDA, 0xD4, + 0x48, 0x22, 0x78, 0x80, 0x6E, 0xCD, 0xE7, 0x00, + 0x81, 0x86, 0x68, 0xE1, 0x5D, 0x7C, 0x54, 0x2C, + 0x55, 0x7B, 0xEF, 0x48, 0x42, 0x7B, 0x3B, 0x68, + 0xE3, 0xDB, 0xAA, 0xC0, 0x0F, 0xA9, 0x96, 0x20, + 0x95, 0x05, 0x93, 0x94, 0x9A, 0xF6, 0xA3, 0x64, + 0x5D, 0xCC, 0x76, 0x00, 0xE5, 0x08, 0x19, 0xE8, + 0x8D, 0x29, 0xD7, 0x4C, 0x21, 0x91, 0x17, 0xF4, + 0xBC, 0x6A, 0xB3, 0x80, 0x83, 0xC6, 0xD4, 0x90, + 0x9B, 0xAE, 0x0E, 0xFE, 0x2E, 0x4A, 0xF2, 0x00, + 0x73, 0x88, 0xD9, 0x40, 0x66, 0xC5, 0xD4, 0x08, + 0x57, 0xB1, 0x89, 0x48, 0xDC, 0x54, 0xFC, 0x43, + 0x6A, 0x26, 0x87, 0xB8, 0x09, 0x5F, 0xCE, 0x80, + 0xE4, 0x0B, 0x05, 0x9C, 0x24, 0xF3, 0xDE, 0xE2, + 0x3E, 0xEC, 0x38, 0x8A, 0xA2, 0x55, 0xA4, 0x50, + 0x4E, 0x4B, 0xE9, 0x58, 0x7F, 0x9F, 0x7D, 0x80, + 0x23, 0x0C, 0x4D, 0x80, 0x05, 0x44, 0x26, 0xB8, + 0xE9, 0xD8, 0xBC, 0xE6, 0x76, 0x3A, 0x6E, 0xA4, + 0x19, 0xDE, 0xC2, 0xD0, 0xC4, 0xBC, 0xC3, 0x5C, + 0x59, 0xDF, 0x16, 0x46, 0x39, 0x70, 0xF4, 0xEE, + 0x2D, 0x58, 0x5A, 0xA8, 0x17, 0x86, 0x6B, 0x60, + 0x29, 0x58, 0x4D, 0xD2, 0x5F, 0x28, 0x7A, 0xD8, + 0x8E, 0x79, 0xEA, 0x82, 0x94, 0x33, 0x31, 0x81, + 0xD9, 0x22, 0xD5, 0x10, 0xDA, 0x92, 0xA0, 0x7D, + 0x3D, 0xDA, 0xAC, 0x1C, 0xA2, 0x53, 0x31, 0xB8, + 0x3C, 0x96, 0x52, 0x00, 0x82, 0x6B, 0x56, 0xA0, + 0xD3, 0xC2, 0x40, 0xC7, 0x1B, 0x7F, 0xDC, 0x01, + 0x72, 0x70, 0xB1, 0x8C, 0x01, 0x09, 0x09, 0x36, + 0xFC, 0x97, 0xEA, 0xDE, 0xE3, 0x0D, 0xAE, 0x7E, + 0xE3, 0x0D, 0xAE, 0x7E, 0x33, 0x69, 0x80, 0x40 +}; + +static uint8_t UsbdSecPlainTextData[128] __attribute__ ((aligned(4))) = { + 0xD1, 0xD2, 0xF2, 0x80, 0x6E, 0xBA, 0x0C, 0xC0, + 0xB6, 0xC4, 0xC9, 0xD8, 0x61, 0x75, 0x1D, 0x1A, + 0x3F, 0x95, 0x58, 0xBE, 0xD8, 0x0D, 0xE2, 0xC0, + 0xD0, 0x21, 0x79, 0x20, 0x65, 0x2D, 0x99, 0x40, + 0x3C, 0x96, 0x52, 0x00, 0x1B, 0x7F, 0xDC, 0x01, + 0x82, 0x1C, 0x13, 0xD8, 0x33, 0x69, 0x80, 0x40, + 0xFC, 0x97, 0xEA, 0xDE, 0x08, 0xEA, 0x14, 0xDC, + 0xEB, 0x0F, 0x6A, 0x18, 0x6F, 0x78, 0x2C, 0xB0, + 0xD3, 0xC2, 0x40, 0xC7, 0x82, 0x6B, 0x56, 0xA0, + 0x19, 0x09, 0x36, 0xE0, 0x72, 0x70, 0xB1, 0x8C, + 0xE3, 0x0D, 0xAE, 0x7E, 0x50, 0xA5, 0x2B, 0xE2, + 0xC9, 0xAF, 0xC7, 0x70, 0x1C, 0x29, 0x80, 0x56, + 0x24, 0xF0, 0x66, 0xFA, 0x02, 0x2B, 0x58, 0x98, + 0x8F, 0xE4, 0xD1, 0x3C, 0x6E, 0x38, 0x2A, 0xFF, + 0xB8, 0xFA, 0x35, 0xB0, 0x52, 0x49, 0xC5, 0xB4, + 0x66, 0xFA, 0x47, 0x55, 0x6C, 0x8D, 0x40, 0x08 +}; + +void UsbdSecXSM3AuthenticationCrypt(const uint8_t *key, const uint8_t *input, size_t length, uint8_t *output, uint8_t encrypt) { + EXCRYPT_DES3_STATE des; + uint64_t sk[3]; + uint8_t iv[8]; + + // clear local variables + memset(iv, 0, sizeof(iv)); + // run parity on the key + ExCryptDesParity(key, 0x10, (uint8_t *)sk); + sk[2] = sk[0]; + // set the key in the state and run triple-des cbc en/decryption on it + ExCryptDes3Key(&des, sk); + ExCryptDes3Cbc(&des, input, length, output, iv, encrypt); +} + +void UsbdSecXSM3AuthenticationMac(const uint8_t *key, uint8_t *salt, uint8_t *input, size_t length, uint8_t *output) { + EXCRYPT_DES3_STATE des3; + EXCRYPT_DES_STATE des; + uint64_t sk[3]; + uint8_t iv[8]; + uint8_t temp[8]; + uint64_t input_temp; + int i; + + // clear iv + temp value of stack junk + memset(iv, 0, sizeof(iv)); + memset(temp, 0, sizeof(temp)); + // run parity on the key + ExCryptDesParity(key, 0x10, (uint8_t *)sk); + sk[2] = sk[0]; + // set the key in our initial des state + ExCryptDesKey(&des, (uint8_t *)&sk[0]); + // if we have a salt, encrypt it into the temp value + if (salt) { + memcpy(&input_temp, salt, sizeof(input_temp)); + input_temp = SWAP64(SWAP64(input_temp) + 1); + memcpy(salt, &input_temp, sizeof(input_temp)); // no idea what this does + ExCryptDesEcb(&des, salt, temp, 1); + } + // for every 8 byte input block, xor the temp value with it and encrypt over itself + for (i = 0; i < length; i += 8) { + memcpy(&input_temp, input+i, sizeof(input_temp)); + *(uint64_t *)temp ^= input_temp; + ExCryptDesEcb(&des, temp, temp, 1); + } + // xor the highest bit of the temp value + temp[0] ^= 0x80; + // set the key and perform the final triple-des encryption + ExCryptDes3Key(&des3, sk); + ExCryptDes3Cbc(&des3, temp, 8, output, iv, 1); + // real kernel does the following, but the above works: + // XeCryptDesEcb(des_state_1, temp, temp, 1); + // XeCryptDesEcb(des_state_2, temp, temp, 0); + // XeCryptDesEcb(des_state_1, temp, output, 1); +} + +void UsbdSecXSMAuthenticationAcr(const uint8_t *console_id, const uint8_t *input, const uint8_t *key, uint8_t *output) { + uint8_t block[8]; + uint8_t iv[8]; + uint8_t ab[8]; + uint8_t cd[8]; + + // fill in the input block with the first 4 bytes of input data and the first 4 bytes of the console ID + memcpy(block, input, 4); + memcpy(block+4, console_id, 4); + // run custom "parve" crypto algorithms. idk whar they do + ExCryptParveEcb(key, UsbdSecSboxData, input + 0x10, iv); + ExCryptParveEcb(key, UsbdSecSboxData, block, cd); + ExCryptParveCbcMac(key, UsbdSecSboxData, iv, UsbdSecPlainTextData, 0x80, ab); + ExCryptChainAndSumMac((uint32_t *)cd, (uint32_t *)ab, (uint32_t *)UsbdSecPlainTextData, 0x20, (uint32_t *)output); + uint64_t current; + memcpy(¤t, output, sizeof(current)); + current ^= *(uint64_t *)ab; + memcpy(output, ¤t, sizeof(current)); +} \ No newline at end of file diff --git a/Firmware/external/libxsm3/usbdsec.h b/Firmware/external/libxsm3/usbdsec.h new file mode 100644 index 00000000..3e647147 --- /dev/null +++ b/Firmware/external/libxsm3/usbdsec.h @@ -0,0 +1,29 @@ +/* + usbdsec.h - part of libxsm3 + Copyright (C) 2022 InvoxiPlayGames + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef USBDSEC_H_ +#define USBDSEC_H_ + +#include + +void UsbdSecXSM3AuthenticationCrypt(const uint8_t *key, const uint8_t *input, size_t length, uint8_t *output, uint8_t encrypt); +void UsbdSecXSM3AuthenticationMac(const uint8_t *key, const uint8_t *salt, uint8_t *input, size_t length, uint8_t *output); +void UsbdSecXSMAuthenticationAcr(const uint8_t *console_id, const uint8_t *input, const uint8_t *key, uint8_t *output); + +#endif // USBDSEC_H_ \ No newline at end of file diff --git a/Firmware/external/libxsm3/xsm3.c b/Firmware/external/libxsm3/xsm3.c new file mode 100644 index 00000000..f7e1a761 --- /dev/null +++ b/Firmware/external/libxsm3/xsm3.c @@ -0,0 +1,301 @@ +/* + xsm3.c - part of libxsm3 + Copyright (C) 2022-2023 InvoxiPlayGames + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include +#if !defined(XSM3_EMBEDDED) +#include +#endif +#include "xsm3.h" +#if defined(XSM3_EMBEDDED) +#include "pico/rand.h" +#endif +#include "excrypt.h" +#include "usbdsec.h" + +// disable debugging by specifying XSM3_NO_DEBUGGING at compile time +#ifndef XSM3_NO_DEBUGGING +#define XSM3_printf printf +#else +#define XSM3_printf +#endif // XSM3_NO_DEBUGGING + +// constant variables +const uint8_t xsm3_id_data_ms_controller[0x1D] = { + 0x49, 0x4B, 0x00, 0x00, 0x17, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x00, 0x00, 0x80, 0x02, 0x5E, 0x04, 0x8E, 0x02, + 0x03, 0x00, 0x01, 0x01, 0x16 +}; + +// static global keys from the keyvault (shared across every retail system) +static const uint8_t xsm3_key_0x1D[0x10] = { + 0xE3, 0x5B, 0xFB, 0x1C, 0xCD, 0xAD, 0x32, 0x5B, + 0xF7, 0x0E, 0x07, 0xFD, 0x62, 0x3D, 0xA7, 0xC4 +}; +static const uint8_t xsm3_key_0x1E[0x10] = { + 0x8F, 0x29, 0x08, 0x38, 0x0B, 0x5B, 0xFE, 0x68, + 0x7C, 0x26, 0x46, 0x2A, 0x51, 0xF2, 0xBC, 0x19 +}; + +// retail keys for generating 0x23/0x24 keys from console ID +static const uint8_t xsm3_root_key_0x23[0x10] = { + 0x82, 0x80, 0x78, 0x68, 0x3A, 0x52, 0x3A, 0x98, + 0x10, 0xF4, 0x0C, 0x12, 0x70, 0x66, 0xDC, 0xBA +}; +static const uint8_t xsm3_root_key_0x24[0x10] = { + 0x66, 0x62, 0x1A, 0x78, 0xF8, 0x60, 0x9C, 0x8A, + 0x26, 0x9A, 0x04, 0xAE, 0xD8, 0x5C, 0x1E, 0xC8 +}; + +/* +global device keys from devkit keyvaults +static const uint8_t xsm3_key_0x1D[0x10] = { + 0xC2, 0x15, 0xE5, 0x5E, 0xE5, 0x51, 0x94, 0x2A, + 0xEC, 0x3D, 0x45, 0xEC, 0xB6, 0xE6, 0xF2, 0x16 +}; +static const uint8_t xsm3_key_0x1E[0x10] = { + 0xC7, 0x45, 0xAD, 0x1F, 0x08, 0x0B, 0xD9, 0xE9, + 0x9B, 0x1C, 0x34, 0xE3, 0xA4, 0x6D, 0xC8, 0xC4 +}; +*/ + +// devkit recovery keys for generating 0x23/0x24 keys from console ID +// static const uint8_t xsm3_root_key_0x23[0x10] = { +// 0xB9, 0xE0, 0x9E, 0x68, 0x04, 0x83, 0x91, 0xB3, +// 0x32, 0x45, 0x7A, 0xDA, 0x43, 0x6B, 0x80, 0xAD +// }; +// static const uint8_t xsm3_root_key_0x24[0x10] = { +// 0x92, 0x5D, 0x29, 0x6E, 0xB0, 0x61, 0x0B, 0xF1, +// 0xD6, 0x29, 0x3B, 0xC8, 0xC7, 0xD9, 0x32, 0xBC +// }; + +// response to give to the given challenge command +uint8_t xsm3_challenge_response[0x30]; +// console id fetched from challenge init packet +uint8_t xsm3_console_id[0x8]; + +// buffer to store the first key fetched from the KV (0x23) +static uint8_t xsm3_kv_2des_key_1[0x10]; +// buffer to store the second key fetched from the KV (0x24) +static uint8_t xsm3_kv_2des_key_2[0x10]; +// have we been given a KV key yet? +static bool xsm3_has_kv_keys = false; + +// temporary buffer for decrypting packets +static uint8_t xsm3_decryption_buffer[0x30]; +// identification data for the current device +static uint8_t xsm3_identification_data[0x20]; +// random data sent from the console during the challenge init stage +static uint8_t xsm3_random_console_data[0x10]; +static uint8_t xsm3_random_console_data_enc[0x10]; +static uint8_t xsm3_random_console_data_swap[0x10]; +static uint8_t xsm3_random_console_data_swap_enc[0x10]; +// random data set by the controller during the challenge init stage +static uint8_t xsm3_random_controller_data[0x10]; +// hash of the decrypted data sent by the controller during challenge init +static uint8_t xsm3_challenge_init_hash[0x14]; + +void xsm3_initialise_state() { + // set all variables to all zeroes + memset(xsm3_challenge_response, 0, sizeof(xsm3_challenge_response)); + memset(xsm3_console_id, 0, sizeof(xsm3_console_id)); + memset(xsm3_kv_2des_key_1, 0, sizeof(xsm3_kv_2des_key_1)); + memset(xsm3_kv_2des_key_2, 0, sizeof(xsm3_kv_2des_key_2)); + memset(xsm3_decryption_buffer, 0, sizeof(xsm3_decryption_buffer)); + memset(xsm3_identification_data, 0, sizeof(xsm3_identification_data)); + memset(xsm3_random_console_data, 0, sizeof(xsm3_random_console_data)); + memset(xsm3_random_console_data_enc, 0, sizeof(xsm3_random_console_data_enc)); + memset(xsm3_random_console_data_swap, 0, sizeof(xsm3_random_console_data_swap)); + memset(xsm3_random_console_data_swap_enc, 0, sizeof(xsm3_random_console_data_swap_enc)); + memset(xsm3_random_controller_data, 0, sizeof(xsm3_random_controller_data)); + memset(xsm3_challenge_init_hash, 0, sizeof(xsm3_challenge_init_hash)); +} + +static uint8_t xsm3_calculate_checksum(const uint8_t * packet) { + // packet length in header doesn't include the header itself + uint8_t packet_length = packet[0x4] + 0x5; + uint8_t checksum = 0x00; + int i = 0; + // checksum is just a XOR over all packet bytes + for(i = 0x5; i < packet_length; i++) { + checksum ^= packet[i]; + } + // last byte of the packet is the checksum + return checksum; +} + +static bool xsm3_verify_checksum(const uint8_t * packet) { + // packet length in header doesn't include the header itself + uint8_t packet_length = packet[0x4] + 0x5; + // last byte of the packet is the checksum + return (xsm3_calculate_checksum(packet) == packet[packet_length]); +} + +void xsm3_set_identification_data(const uint8_t id_data[0x1D]) { + // validate the checksum + if (!xsm3_verify_checksum(id_data)) { + XSM3_printf("[ Checksum failed when setting identification data! ]\n"); + } + + // skip over the packet header + id_data += 0x5; + + // prepare the xsm3_identification_data buffer + + // contains serial number (len: 0xC), unknown (len: 0x2) and the "category node" to use (len: 0x1) + memcpy(xsm3_identification_data, id_data, 0xF); + // vendor ID + memcpy(xsm3_identification_data + 0x10, id_data + 0xF, sizeof(unsigned short)); + // product ID + memcpy(xsm3_identification_data + 0x12, id_data + 0x11, sizeof(unsigned short)); + // unknown + memcpy(xsm3_identification_data + 0x14, id_data + 0x13, sizeof(unsigned char)); + // unknown + memcpy(xsm3_identification_data + 0x15, id_data + 0x16, sizeof(unsigned char)); + // unknown + memcpy(xsm3_identification_data + 0x16, id_data + 0x14, sizeof(unsigned short)); +} + +void xsm3_import_kv_keys(const uint8_t key1[0x10], const uint8_t key2[0x10]) { + xsm3_has_kv_keys = true; + // copy the provided keys into our buffers + memcpy(xsm3_kv_2des_key_1, key1, sizeof(xsm3_kv_2des_key_1)); + memcpy(xsm3_kv_2des_key_2, key2, sizeof(xsm3_kv_2des_key_2)); +} + +void xsm3_generate_kv_keys(const uint8_t console_id[0x8]) { + xsm3_has_kv_keys = true; + // make a sha-1 hash of the console id + uint8_t console_id_hash[0x14]; + ExCryptSha(console_id, 0x8, NULL, 0, NULL, 0, console_id_hash, 0x14); + // encrypt it with the root keys for 1st party controllers + UsbdSecXSM3AuthenticationCrypt(xsm3_root_key_0x23, console_id_hash, 0x10, xsm3_kv_2des_key_1, 1); + UsbdSecXSM3AuthenticationCrypt(xsm3_root_key_0x24, console_id_hash + 0x4, 0x10, xsm3_kv_2des_key_2, 1); +} + +void xsm3_do_challenge_init(uint8_t challenge_packet[0x22]) { + uint8_t incoming_packet_mac[0x8]; + uint8_t response_packet_mac[0x8]; + int i = 0; + + // validate the checksum + if (!xsm3_verify_checksum(challenge_packet)) { + XSM3_printf("[ Checksum failed when validating challenge init! ]\n"); + } + + // decrypt the packet content using the static key from the keyvault + UsbdSecXSM3AuthenticationCrypt(xsm3_key_0x1D, challenge_packet + 0x5, 0x18, xsm3_decryption_buffer, 0); + // first 0x10 bytes are random data + memcpy(xsm3_random_console_data, xsm3_decryption_buffer, 0x10); + // next 0x8 bytes are from the console certificate + memcpy(xsm3_console_id, xsm3_decryption_buffer + 0x10, 0x8); + // last 4 bytes of the packet are the last 4 bytes of the MAC + UsbdSecXSM3AuthenticationMac(xsm3_key_0x1E, NULL, challenge_packet + 5, 0x18, incoming_packet_mac); + // validate the MAC + if (memcmp(incoming_packet_mac + 4, challenge_packet + 0x5 + 0x18, 0x4) != 0) { + XSM3_printf("[ MAC failed when validating challenge init! ]\n"); + } + + // if we haven't got our KV keys yet, generate it + if (!xsm3_has_kv_keys) xsm3_generate_kv_keys(xsm3_console_id); + + // the random value is swapped at an 8 byte boundary + memcpy(xsm3_random_console_data_swap, xsm3_random_console_data + 0x8, 0x8); + memcpy(xsm3_random_console_data_swap + 0x8, xsm3_random_console_data, 0x8); + // and then encrypted - the regular value encrypted with key 1, the swapped value encrypted with key 2 + UsbdSecXSM3AuthenticationCrypt(xsm3_kv_2des_key_1, xsm3_random_console_data, 0x10, xsm3_random_console_data_enc, 1); + UsbdSecXSM3AuthenticationCrypt(xsm3_kv_2des_key_2, xsm3_random_console_data_swap, 0x10, xsm3_random_console_data_swap_enc, 1); + + // generate random data +#if defined(XSM3_EMBEDDED) + for (i = 0; i < 0x10; i++) { + xsm3_random_controller_data[i] = (uint8_t)(get_rand_32() & 0xFF); + } +#else + srand(time(NULL)); + for (i = 0; i < 0x10; i++) { + xsm3_random_controller_data[i] = rand() & 0xFF; + } +#endif + + // clear response buffers + memset(xsm3_challenge_response, 0, sizeof(xsm3_challenge_response)); + memset(xsm3_decryption_buffer, 0, sizeof(xsm3_decryption_buffer)); + // set header and packet length of challenge response + xsm3_challenge_response[0] = 0x49; // packet magic + xsm3_challenge_response[1] = 0x4C; + xsm3_challenge_response[4] = 0x28; // packet length + // copy random controller, random console data to the encryption buffer + memcpy(xsm3_decryption_buffer, xsm3_random_controller_data, 0x10); + memcpy(xsm3_decryption_buffer + 0x10, xsm3_random_console_data, 0x10); + // save the sha1 hash of the decrypted contents for later + ExCryptSha(xsm3_decryption_buffer, 0x20, NULL, 0, NULL, 0, xsm3_challenge_init_hash, 0x14); + + // encrypt challenge response packet using the encrypted random key + UsbdSecXSM3AuthenticationCrypt(xsm3_random_console_data_enc, xsm3_decryption_buffer, 0x20, xsm3_challenge_response + 0x5, 1); + // calculate MAC using the encrypted swapped random key and use it to calculate ACR + UsbdSecXSM3AuthenticationMac(xsm3_random_console_data_swap_enc, NULL, xsm3_challenge_response + 0x5, 0x20, response_packet_mac); + // calculate ACR and append to the end of the xsm3_challenge_response + UsbdSecXSMAuthenticationAcr(xsm3_console_id, xsm3_identification_data, response_packet_mac, xsm3_challenge_response + 0x5 + 0x20); + // calculate the checksum for the response packet + xsm3_challenge_response[0x5 + 0x28] = xsm3_calculate_checksum(xsm3_challenge_response); + + // the console random value changes slightly after this point + memcpy(xsm3_random_console_data, xsm3_random_controller_data + 0xC, 0x4); + memcpy(xsm3_random_console_data + 0x4, xsm3_random_console_data + 0xC, 0x4); +} + +void xsm3_do_challenge_verify(uint8_t challenge_packet[0x16]) { + uint8_t incoming_packet_mac[0x8]; + + // validate the checksum + if (!xsm3_verify_checksum(challenge_packet)) { + XSM3_printf("[ Checksum failed when validating challenge verify! ]\n"); + } + + // decrypt the packet using the controller generated random value + UsbdSecXSM3AuthenticationCrypt(xsm3_random_controller_data, challenge_packet + 0x5, 0x8, xsm3_decryption_buffer, 0); + // replace part of our random encryption value with the decrypted buffer + memcpy(xsm3_random_console_data + 0x8, xsm3_decryption_buffer, 0x8); + + // calculate the MAC of the incoming packet + UsbdSecXSM3AuthenticationMac(xsm3_challenge_init_hash, xsm3_random_console_data, challenge_packet + 0x5, 0x8, incoming_packet_mac); + // validate the MAC + if (memcmp(incoming_packet_mac, challenge_packet + 0x5 + 0x8, 0x8) != 0) { + XSM3_printf("[ MAC failed when validating challenge verify! ]\n"); + } + // clear response buffers + memset(xsm3_challenge_response, 0, sizeof(xsm3_challenge_response)); + memset(xsm3_decryption_buffer, 0, sizeof(xsm3_decryption_buffer)); + // set header and packet length of challenge response + xsm3_challenge_response[0] = 0x49; // packet magic + xsm3_challenge_response[1] = 0x4C; + xsm3_challenge_response[4] = 0x10; // packet length + // calculate the ACR value and encrypt it into the outgoing packet using the encrypted random + UsbdSecXSMAuthenticationAcr(xsm3_console_id, xsm3_identification_data, xsm3_random_console_data + 0x8, xsm3_decryption_buffer); + UsbdSecXSM3AuthenticationCrypt(xsm3_random_console_data_enc, xsm3_decryption_buffer, 0x8, xsm3_challenge_response + 0x5, 1); + // calculate the MAC of the encrypted packet and append it to the end + UsbdSecXSM3AuthenticationMac(xsm3_random_console_data_swap_enc, xsm3_random_console_data, xsm3_challenge_response + 0x5, 0x8, xsm3_challenge_response + 0x5 + 0x8); + // calculate the checksum for the response packet + xsm3_challenge_response[0x5 + 0x10] = xsm3_calculate_checksum(xsm3_challenge_response); +} diff --git a/Firmware/external/libxsm3/xsm3.h b/Firmware/external/libxsm3/xsm3.h new file mode 100644 index 00000000..93e985b3 --- /dev/null +++ b/Firmware/external/libxsm3/xsm3.h @@ -0,0 +1,51 @@ +/* + xsm3.h - part of libxsm3 + Copyright (C) 2022 InvoxiPlayGames + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef XSM3_H_ +#define XSM3_H_ + +#include +#include +#include + +// Identification data taken from an official wired controller. (Serial number is static.) +extern const uint8_t xsm3_id_data_ms_controller[0x1D]; + +// The response data from the previously completed challenge. +extern uint8_t xsm3_challenge_response[0x30]; + +// The console ID fetched from the console after request 0x82. +extern uint8_t xsm3_console_id[0x8]; + +// Clears the state of the XSM3 internal variables. +void xsm3_initialise_state(); + +// Sets the identification data to use. +void xsm3_set_identification_data(const uint8_t id_data[0x1D]); + +// Imports the console-specific keys (GetKey index 0x23 and 0x24 for wired controllers) into the current state. +void xsm3_import_kv_keys(const uint8_t key1[0x10], const uint8_t key2[0x10]); + +// Initialises the XSM3 state using information from the challenge init packet (0x82) and places a response in xsm3_challenge_response. +void xsm3_do_challenge_init(uint8_t challenge_packet[0x22]); + +// Completes a verify challenge passed from request 0x87 and places the response data in xsm3_challenge_response. +void xsm3_do_challenge_verify(uint8_t challenge_packet[0x16]); + +#endif // XSM3_H_ \ No newline at end of file From f5416c7736d75814be7d645e1c30f6f3f077149a Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Sun, 1 Mar 2026 07:57:00 -0500 Subject: [PATCH 21/42] Delete Firmware/RP2040/docs/XInput_joypad-os_comparison.md --- .../docs/XInput_joypad-os_comparison.md | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 Firmware/RP2040/docs/XInput_joypad-os_comparison.md diff --git a/Firmware/RP2040/docs/XInput_joypad-os_comparison.md b/Firmware/RP2040/docs/XInput_joypad-os_comparison.md deleted file mode 100644 index 93c73c24..00000000 --- a/Firmware/RP2040/docs/XInput_joypad-os_comparison.md +++ /dev/null @@ -1,40 +0,0 @@ -# XInput vs joypad-os comparison - -Comparison of OGX-Mini XInput (Xbox 360) with joypad-os for descriptor and runtime behavior, to align with what works on the 360. - -## Descriptors - -| Item | joypad-os | OGX-Mini (after alignment) | -|------|-----------|-----------------------------| -| **Device** | 0x045E / 0x028E, bcd 0x0114, bNumConfigurations = 1 | Same (byte-identical) | -| **Config** | 153 bytes, 4 interfaces, bConfigurationValue 1, bMaxPower 0xFA | Same (byte-identical) | -| **Config callback** | `tud_descriptor_configuration_cb(uint8_t index)` — ignores `index`, returns mode-specific config | Now return `nullptr` for `index != 0` (single config) | -| **String 4 (XSM3)** | 96-char buffer, **full** security string (no truncation) | Was truncated to 31 chars; now use full length in dedicated buffer | - -## Mode / enumeration - -| Item | joypad-os | OGX-Mini | -|------|-----------|----------| -| **When XInput is active** | `output_mode` loaded from flash before USB init; device presents XInput descriptors from first enumeration | Fixed XInput driver; always present XInput from first enumeration | -| **Driver registration** | `usbd_app_driver_get_cb()` returns `driver_count = 1`, `tud_xinput_class_driver()` when mode is XINPUT | Single driver from `DeviceManager::get_driver()->get_class_driver()` (XInput) | - -## Control transfer handling - -| Item | joypad-os | OGX-Mini | -|------|-----------|----------| -| **Vendor callback** | `tud_vendor_control_xfer_cb()` calls `tud_xinput_vendor_control_xfer_cb()` when `output_mode == XINPUT` | `tud_vendor_control_xfer_cb()` forwards to active driver `vendor_control_xfer_cb()` | -| **Class driver control** | `xinput_control_xfer_cb()` returns `true` and does **nothing**; XSM3 is handled only in vendor callback | We forward class `control_xfer_cb` to driver `vendor_control_xfer_cb()` so both paths reach XSM3 | - -## XSM3 runtime (already aligned) - -- XSM3 init at driver init (not in 0x81 callback). -- 0x82 / 0x87: only set state; crypto in `process()` loop. -- 0x83: 46 bytes init, 22 bytes verify. -- 0x86: state 1 = processing, 2 = ready. - -## Changes made from this comparison - -1. **Configuration descriptor** — `get_descriptor_configuration_cb(index)`: return `nullptr` when `index != 0` (we have one config). -2. **String descriptor index 4** — Use a 96-element buffer and the **full** XSM3 security string (no 31-character truncation from `get_string_descriptor()`). - -If the 360 still does not send XSM3 requests after these fixes, next steps: confirm joypad-os on the same 360 shows XSM3 traffic, and/or add logging of **all** control requests (e.g. in TinyUSB) to see if any vendor/class traffic arrives. From 1c623c8532b613799d7c54d4843daecb7485b050 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Sun, 1 Mar 2026 09:31:45 -0500 Subject: [PATCH 22/42] v1.0.0.4a: Wii mode, 360 rumble fix, Pico 2 builds, docs and attribution Made-with: Cursor --- .gitignore | 5 +- Firmware/RP2040/CMakeLists.txt | 58 +- Firmware/RP2040/docs/IMPROVEMENTS.md | 2 +- Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md | 99 ++ Firmware/RP2040/docs/README.md | 57 +- Firmware/RP2040/docs/Wii_Mode_Guide.md | 139 +++ Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 4 +- Firmware/RP2040/src/Board/Config.h | 5 + Firmware/RP2040/src/Board/ogxm_log.cpp | 1 + Firmware/RP2040/src/Descriptors/XboxOne.h | 27 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 152 +++- Firmware/RP2040/src/TaskQueue/TaskQueue.cpp | 6 +- Firmware/RP2040/src/TaskQueue/TaskQueue.h | 4 +- .../DeviceDriver/DeviceDriverTypes.h | 1 + .../src/USBDevice/DeviceDriver/Wii/Wii.cpp | 32 + .../src/USBDevice/DeviceDriver/Wii/Wii.h | 24 + .../RP2040/src/USBDevice/DeviceManager.cpp | 5 + .../src/USBHost/HostDriver/XInput/XboxOne.cpp | 92 +- .../src/USBHost/HostDriver/XInput/XboxOne.h | 2 + .../XInput/tuh_xinput/tuh_xinput.cpp | 6 + .../RP2040/src/UserSettings/UserSettings.cpp | 64 +- .../RP2040/src/UserSettings/UserSettings.h | 4 + .../RP2040/src/Wii/WiiReportConverter.cpp | 225 +++++ Firmware/RP2040/src/Wii/WiiReportConverter.h | 19 + Firmware/RP2040/src/Wii/utils.c | 8 + Firmware/RP2040/src/Wii/utils.h | 19 + .../RP2040/src/Wii/wiimote-lib/CMakeLists.txt | 11 + .../src/Wii/wiimote-lib/btstack_config.h | 79 ++ .../RP2040/src/Wii/wiimote-lib/eeprom.bin.h | 20 + Firmware/RP2040/src/Wii/wiimote-lib/inet.c | 44 + Firmware/RP2040/src/Wii/wiimote-lib/inet.h | 6 + Firmware/RP2040/src/Wii/wiimote-lib/motion.c | 155 ++++ Firmware/RP2040/src/Wii/wiimote-lib/motion.h | 8 + .../RP2040/src/Wii/wiimote-lib/sdp_consts.h | 183 ++++ .../RP2040/src/Wii/wiimote-lib/vector_math.h | 263 ++++++ Firmware/RP2040/src/Wii/wiimote-lib/wiimote.c | 860 ++++++++++++++++++ Firmware/RP2040/src/Wii/wiimote-lib/wiimote.h | 229 +++++ .../src/Wii/wiimote-lib/wiimote_btstack.c | 559 ++++++++++++ .../src/Wii/wiimote-lib/wiimote_btstack.h | 8 + .../RP2040/src/Wii/wiimote-lib/wm_crypto.c | 239 +++++ .../RP2040/src/Wii/wiimote-lib/wm_crypto.h | 16 + .../RP2040/src/Wii/wiimote-lib/wm_reports.c | 440 +++++++++ .../RP2040/src/Wii/wiimote-lib/wm_reports.h | 381 ++++++++ Firmware/RP2040/src/main.cpp | 25 +- README.md | 28 +- 45 files changed, 4490 insertions(+), 124 deletions(-) create mode 100644 Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md create mode 100644 Firmware/RP2040/docs/Wii_Mode_Guide.md create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.h create mode 100644 Firmware/RP2040/src/Wii/WiiReportConverter.cpp create mode 100644 Firmware/RP2040/src/Wii/WiiReportConverter.h create mode 100644 Firmware/RP2040/src/Wii/utils.c create mode 100644 Firmware/RP2040/src/Wii/utils.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/CMakeLists.txt create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/btstack_config.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/eeprom.bin.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/inet.c create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/inet.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/motion.c create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/motion.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/sdp_consts.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/vector_math.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wiimote.c create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wiimote.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.c create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.c create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.h create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.c create mode 100644 Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.h diff --git a/.gitignore b/.gitignore index d769e228..af8cf84d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,7 @@ Firmware/ESP32/components/btstack Firmware/ESP32/sdkconfig.old Firmware/external/pico-sdk Firmware/external/picotool -Tools/dvd-dongle-rom.bin \ No newline at end of file +Tools/dvd-dongle-rom.bin + +# Local comparison doc (not for GitHub) +Firmware/RP2040/docs/XInput_joypad-os_comparison.md \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index fabc00e8..839577b3 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -69,6 +69,7 @@ set(SOURCES_BOARD ${SRC}/USBDevice/DeviceDriver/PS3/PS3.cpp ${SRC}/USBDevice/DeviceDriver/Switch/Switch.cpp ${SRC}/USBDevice/DeviceDriver/WiiU/WiiU.cpp + ${SRC}/USBDevice/DeviceDriver/Wii/Wii.cpp ${SRC}/USBDevice/DeviceDriver/XInput/XInput.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/XboxOG_SB.cpp @@ -122,17 +123,20 @@ if (OGXM_BOARD STREQUAL "PI_PICO") elseif (OGXM_BOARD STREQUAL "PI_PICO2") add_compile_definitions(CONFIG_OGXM_BOARD_PI_PICO2=1) set(EN_USB_HOST TRUE) + set(PICO_BOARD pico2) set(PICO_PLATFORM rp2350) set(FLASH_SIZE_MB 4) elseif(OGXM_BOARD STREQUAL "PI_PICOW") add_compile_definitions(CONFIG_OGXM_BOARD_PI_PICOW=1) set(EN_BLUETOOTH TRUE) + set(EN_USB_HOST TRUE) # PIO USB host for Wii mode (controller on external USB) set(PICO_BOARD pico_w) elseif(OGXM_BOARD STREQUAL "PI_PICO2W") add_compile_definitions(CONFIG_OGXM_BOARD_PI_PICO2W=1) set(EN_BLUETOOTH TRUE) + set(EN_USB_HOST TRUE) # PIO USB host for Wii mode (controller on external USB) set(PICO_BOARD pico2_w) set(PICO_PLATFORM rp2350) set(FLASH_SIZE_MB 4) @@ -185,15 +189,16 @@ else() endif() # Optional: default or lock USB output mode. -# OGXM_FIXED_DRIVER = one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, PS3, PSCLASSIC, WEBAPP. +# OGXM_FIXED_DRIVER = one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP. # Empty = use first valid driver as default, combos enabled. # Set = use that mode as default (first boot / NVS init). If OGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF (default): # combos disabled, mode locked. If OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON: default is this mode, combos still work. -set(OGXM_FIXED_DRIVER "" CACHE STRING "Default/lock output mode. One of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, PS3, PSCLASSIC, WEBAPP. Empty = combos enabled.") +set(OGXM_FIXED_DRIVER "" CACHE STRING "Default/lock output mode. One of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP. Empty = combos enabled.") set(OGXM_FIXED_DRIVER_ALLOW_COMBOS OFF CACHE BOOL "If OGXM_FIXED_DRIVER is set: ON = use it as default but allow combos to change mode; OFF = lock to that mode, combos disabled.") if(OGXM_FIXED_DRIVER) add_compile_definitions(CONFIG_OGXM_FIXED_DRIVER=1) - if(OGXM_FIXED_DRIVER_ALLOW_COMBOS) + # WII is build-only: no combos to switch into or out of Wii. + if(OGXM_FIXED_DRIVER_ALLOW_COMBOS AND NOT (OGXM_FIXED_DRIVER STREQUAL "WII")) add_compile_definitions(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS=1) endif() if(OGXM_FIXED_DRIVER STREQUAL "XBOXOG") @@ -214,12 +219,16 @@ if(OGXM_FIXED_DRIVER) add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=8) elseif(OGXM_FIXED_DRIVER STREQUAL "WIIU") add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=9) + elseif(OGXM_FIXED_DRIVER STREQUAL "WII") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=10) elseif(OGXM_FIXED_DRIVER STREQUAL "WEBAPP") add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=100) else() - message(FATAL_ERROR "OGXM_FIXED_DRIVER must be one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, PS3, PSCLASSIC, WEBAPP") + message(FATAL_ERROR "OGXM_FIXED_DRIVER must be one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP") endif() - if(OGXM_FIXED_DRIVER_ALLOW_COMBOS) + if(OGXM_FIXED_DRIVER STREQUAL "WII") + message(STATUS "Wii-only build: ${OGXM_FIXED_DRIVER} (combos disabled, build option only)") + elseif(OGXM_FIXED_DRIVER_ALLOW_COMBOS) message(STATUS "Default output mode: ${OGXM_FIXED_DRIVER} (combos enabled)") else() message(STATUS "Fixed output mode: ${OGXM_FIXED_DRIVER} (combos disabled)") @@ -288,6 +297,25 @@ if(EN_BLUETOOTH) pico_btstack_cyw43 bluepad32 ) + + # Wii mode: Wiimote BT emulator (Pico W/2W with USB host) + if(EN_USB_HOST AND (OGXM_BOARD STREQUAL "PI_PICOW" OR OGXM_BOARD STREQUAL "PI_PICO2W")) + message(STATUS "Wii Wiimote lib enabled.") + list(APPEND SOURCES_BOARD + ${SRC}/Wii/utils.c + ${SRC}/Wii/WiiReportConverter.cpp + ${SRC}/Wii/wiimote-lib/wiimote_btstack.c + ${SRC}/Wii/wiimote-lib/wiimote.c + ${SRC}/Wii/wiimote-lib/wm_reports.c + ${SRC}/Wii/wiimote-lib/motion.c + ${SRC}/Wii/wiimote-lib/wm_crypto.c + ${SRC}/Wii/wiimote-lib/inet.c + ) + list(APPEND INC_DIRS_BOARD + ${SRC}/Wii + ${SRC}/Wii/wiimote-lib + ) + endif() endif() if(EN_RGB) @@ -351,7 +379,8 @@ if(EXISTS ${SRC}/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid_xremote_rom.h) add_definitions(-DXREMOTE_ROM_AVAILABLE) endif() -if(NOT EN_BLUETOOTH) +# RP2040-only: force generic boot2 when no Bluetooth (pico2/pico2_w use board's boot2 choice) +if(NOT EN_BLUETOOTH AND NOT (OGXM_BOARD STREQUAL "PI_PICO2") AND NOT (OGXM_BOARD STREQUAL "PI_PICO2W")) add_compile_definitions(PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H=1) add_compile_definitions(PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64) endif() @@ -376,15 +405,18 @@ add_executable(${FW_NAME} ${SOURCES_BOARD}) set(BUILD_STR "") if(CMAKE_BUILD_TYPE STREQUAL "Debug") - if(OGXM_BOARD STREQUAL "PI_PICOW") - message(FATAL_ERROR "Debug build will not work with the Pico W currently") - endif() - - message(STATUS "Debug build enabled.") + message(STATUS "Debug build enabled (UART logging).") set(BUILD_STR "-Debug") - set(TX_PIN 0) - set(RX_PIN 1) + # Pico W/2W: use UART1 on GP4 (TX) / GP5 (RX) - valid UART pins, avoids PIO USB (GP0/1) in Wii mode + # Note: GP10/11 are not valid UART pins on RP2040/RP2350 + if(OGXM_BOARD STREQUAL "PI_PICOW" OR OGXM_BOARD STREQUAL "PI_PICO2W") + set(TX_PIN 4) + set(RX_PIN 5) + else() + set(TX_PIN 0) + set(RX_PIN 1) + endif() set(UART_PORT) include(${CMAKE_CURRENT_LIST_DIR}/cmake/get_pico_uart_port.cmake) diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index cc3fa0c1..c692c16e 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -31,7 +31,7 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. 4. **Control handling** - Vendor and class control requests are forwarded to the active driver so XSM3 traffic reaches the XInput handler. -See [XInput_joypad-os_comparison.md](XInput_joypad-os_comparison.md) for a detailed comparison. +Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad-ai/joypad-os); a local comparison doc may be kept out of the repo for reference. --- diff --git a/Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md b/Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md new file mode 100644 index 00000000..7757099a --- /dev/null +++ b/Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md @@ -0,0 +1,99 @@ +# Pico 2 W – Wii Mode with USB Controller + +This document describes how **Pico 2 W** (and Pico W) use a **USB gamepad** on an **external USB host port** when the adapter is in **Wii (Wiimote) mode**. The approach is the same as in [PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter): the single Bluetooth radio is used for the Wiimote connection to the Wii, so the controller must be USB and must be on **PIO USB** (external port), not the built-in USB. + +--- + +## 1. Hardware constraints + +- **Pico 2 W** (and Pico W) have a single **Bluetooth radio** (CYW43439). +- In **Wii mode** that radio is used for the **Wiimote connection** (Pico → Wii). +- You **cannot** use Bluetooth for both the Wii and a wireless controller at the same time. +- **Solution:** Use a **USB controller** on an external USB host port (PIO USB on GPIO). The controller must be plugged into the **external** USB connector (D+/D− on GPIO), not the Pico’s built-in USB port. + +--- + +## 2. USB host: use PIO USB (external port) in Wii mode + +### The bug (in projects that get it wrong) + +If the firmware uses the **wrong USB port** for the controller in Wii mode: + +- **`tuh_init(0)`** → **native USB (roothub 0)** = the Pico’s **built-in USB port** (the one used for programming). +- The controller is on the **external USB** on **GP0/GP1** (**PIO USB, roothub 1**), which is then **never used**. +- Result: controller gets power (e.g. vibrate) but is **never enumerated** → no LED, no input. + +### The fix in OGX-Mini + +When the output mode is **WII** (Wiimote) on Pico W / Pico 2 W, the firmware uses **PIO USB** (roothub port **1**) for the host: + +- Configure PIO USB with the chosen D+/D− pins (and optional swap). +- Call `tuh_configure(1, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg)` then `tuh_init(1)`. +- Run `tuh_task()` in the host loop. + +So the controller **must** be plugged into the **external** USB port (PIO USB). The built-in USB is not used for the host in Wii mode. + +--- + +## 3. PIO USB pin configuration (Pico W / Pico 2 W) + +For OGX-Mini, Pico W and Pico 2 W use the following when USB host is used (e.g. Wii mode). Defined in `Board/Config.h` for `CONFIG_OGXM_BOARD_PI_PICOW` / `PI_PICO2W`: + +- **`PIO_USB_DP_PIN`** – Base pin for D+ (e.g. `0` → D+ = GP0, D− = GP1 with default pinout). +- **`PIO_USB_SWAP_DP_DM`** – Optional. Set to `1` if the controller gets power but does not enumerate (D+/D− swapped on the cable). + +**Wiring:** + +| Config | D+ | D− | +|---------------------|------|------| +| Swap = 0, PIN = 0 | GP0 | GP1 | +| Swap = 1 | GP1 | GP0 | + +Also connect USB **GND** and **VBUS** (5 V) to the external connector. + +--- + +## 4. Building for Pico 2 W (Wii mode) + +Wii mode is **build-option only**: you must build with **`-DOGXM_FIXED_DRIVER=WII`**. Button combos cannot switch into or out of Wii; the firmware is Wii-only and combos are disabled. + +- Set **`OGXM_BOARD`** to **`PI_PICO2W`** (e.g. `-DOGXM_BOARD=PI_PICO2W`). +- Set **`OGXM_FIXED_DRIVER`** to **`WII`** (e.g. `-DOGXM_FIXED_DRIVER=WII`). +- On Windows, use the project’s **build script** (e.g. `scripts/build-with-vs.ps1 -Board PI_PICO2W -Debug`) or a **Visual Studio Developer Command Prompt** so host tools build correctly. + +Example (from `Firmware/RP2040`): +`.\scripts\build-with-vs.ps1 -Board PI_PICO2W -FixedDriver WII -Debug` + +--- + +## 5. Usage summary (Wii mode on Pico 2 W) + +1. **Wire** the external USB connector: D+ and D− to the chosen GPIOs (e.g. GP0/GP1), plus GND and 5 V (VBUS). +2. **Build** firmware with **`-DOGXM_FIXED_DRIVER=WII`** for **PI_PICO2W** and **flash** the `.uf2`. +3. **Plug** the USB controller into the **external** port; the controller LED should turn on when it enumerates. +4. **Sync** the Pico to the Wii (Wii Sync, then Pico as needed). The Pico appears as a Wiimote; input comes from the USB gamepad. + +--- + +## 6. Debug / UART logging (crash debugging) + +To see where the firmware gets to when switching to Wii mode (or if it crashes), build in **Debug** so that **UART logging** is enabled. Logs go to **UART1** on **GP4 (TX)** and **GP5 (RX)** so they do not conflict with PIO USB on GP0/GP1. (GP10/11 are not valid UART pins on RP2040/RP2350.) + +1. **Build Debug** for Pico 2 W: `cmake -G Ninja -DOGXM_BOARD=PI_PICO2W -DCMAKE_BUILD_TYPE=Debug ` then `ninja`. Or use the build script with a Debug build directory. +2. **Connect a USB–UART adapter** (3.3 V) to **GP4 (TX)** and **GP5 (RX)** and GND. Open a terminal at **115200** baud. +3. **Flash** the Debug `.uf2`, switch to Wii mode, and watch the log. You should see: `PicoW init: start` … `driver inited`; `PicoW run: wii_mode=1` … `Core1 launched`; `WII Core1: entry` … `HostManager init done` … `tuh_init done` … `entering loop`; `PicoW run: Wii main loop tick`. The **last line printed** before a crash or hang shows how far the code got. + +--- + +## 7. Troubleshooting + +| Symptom | Likely cause | What to do | +|--------|----------------|------------| +| Controller vibrates, no LED, doesn’t sync | Host using native USB instead of PIO USB | Ensure Wii mode uses PIO USB (roothub 1) as in §2. | +| Same | D+ and D− swapped on cable | Set `PIO_USB_SWAP_DP_DM 1` in config and rebuild, or swap D+ and D− wires. | +| No response at all | Wrong port or no VBUS | Use the **external** USB (PIO USB) and ensure VBUS has 5 V. | +| Crash when switching to Wii | Debug with UART (GP4/5) | Build Debug, connect UART to GP4/5 @ 115200; see §6. | + +--- + +This setup gives **Wii (Wiimote) output** with a **USB controller** on the Pico 2 W’s external USB host port, with the single Bluetooth radio reserved for the Wii connection. diff --git a/Firmware/RP2040/docs/README.md b/Firmware/RP2040/docs/README.md index d72f0a8c..19a3a987 100644 --- a/Firmware/RP2040/docs/README.md +++ b/Firmware/RP2040/docs/README.md @@ -1,58 +1,11 @@ -# OGX-Mini RP2040 Firmware +# RP2040 firmware docs -Firmware for the OGX-Mini controller adapter on **RP2040** (e.g. Raspberry Pi Pico, Pico 2 W). The adapter accepts input from Bluetooth controllers (e.g. PS5, Xbox One, Switch Pro) and presents them to a console or PC as a single USB gamepad in the chosen output mode. +See the [project README](../../README.md) for overview, supported platforms, build, and configuration. -## Supported output modes (USB device) - -| Mode | Target | -|------|--------| -| **XInput** | Xbox 360 (wired controller + XSM3 auth) | -| **DInput** | PC (DirectInput), legacy | -| **PS3** | PlayStation 3 | -| **Switch** | Nintendo Switch (wired) | -| **Wii U** | Wii U | -| **Xbox OG** | Original Xbox (XID: Gamepad, Steel Battalion, XRemote) | -| **PS Classic** | PlayStation Classic | -| **Web App** | Configuration / profiles over CDC | - -On **Pico 2 W**, Bluetooth (Bluepad32) runs on Core1; USB device runs on Core0. You can build with a **fixed** output mode (e.g. XINPUT only) or with **button combos** to switch modes at runtime (e.g. Start + D-pad held ~3 s). - -## Xbox 360 (XInput) support - -XInput mode works on **Xbox 360** with full **XSM3** authentication: - -- Descriptors and XSM3 flow aligned with [joypad-os](https://github.com/joypad-ai/joypad-os) for console compatibility. -- Single configuration; full XSM3 security string; init/verify handled in the main loop. -- USB is initialized before Core1 (BT) so the 360 can enumerate even while Bluetooth firmware loads. - -See [XInput_joypad-os_comparison.md](XInput_joypad-os_comparison.md) for technical details. - -## Input latency (PS5 / Xbox One over Bluetooth) - -- **Always send latest state** — In XInput (and similar) mode, the adapter sends the current gamepad state whenever the USB endpoint is free, instead of only when the BT stack flags “new” data. The host (e.g. 360) gets updates at its poll rate (e.g. 4 ms) with the freshest state. -- **Low-latency default** — The main loop uses **no** added delay by default (`MAIN_LOOP_DELAY_US=0`), so there is no extra delay between reading the controller and sending to USB. - -To trade a little latency for lower CPU use, configure with `MAIN_LOOP_DELAY_US=250` (or higher). See [IMPROVEMENTS.md](IMPROVEMENTS.md#latency-reduction). - -## Building - -Build with **CMake** from the `Firmware/RP2040` directory. Required: - -- **Board:** `OGXM_BOARD` (e.g. `PI_PICO2W`, `PI_PICO`, `RP2040_ZERO`). -- **Pico SDK:** `PICO_SDK_PATH` pointing at the SDK (or use the project’s submodule). -- **Optional:** `OGXM_FIXED_DRIVER` to lock output mode (e.g. `XINPUT`, `PS3`); `OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON` to keep combos when a fixed driver is set. -- **Optional:** `MAIN_LOOP_DELAY_US` (default `0`) to set main-loop delay in microseconds. - -Outputs (`.elf`, `.uf2`, etc.) are produced in the chosen build directory; flash the `.uf2` to the board. - -## Configuration - -- **Board and driver:** Set at CMake configure time (`OGXM_BOARD`, `OGXM_FIXED_DRIVER`, `OGXM_FIXED_DRIVER_ALLOW_COMBOS`). -- **Latency:** `MAIN_LOOP_DELAY_US` — default `0` (low latency). Override via CMake (e.g. `-DMAIN_LOOP_DELAY_US=250`) if desired. See [IMPROVEMENTS.md](IMPROVEMENTS.md#latency-reduction). - -## Documentation +## Firmware docs (this folder) | Document | Description | |----------|-------------| +| [Wii_Mode_Guide.md](Wii_Mode_Guide.md) | Wii mode (build-option only): No Extension / Nunchuk / Classic, USB host, sync and auto-connect, button mapping, supported controllers. | +| [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | | [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360. | -| [XInput_joypad-os_comparison.md](XInput_joypad-os_comparison.md) | XInput vs joypad-os (descriptors, XSM3, control handling). | diff --git a/Firmware/RP2040/docs/Wii_Mode_Guide.md b/Firmware/RP2040/docs/Wii_Mode_Guide.md new file mode 100644 index 00000000..87f0de09 --- /dev/null +++ b/Firmware/RP2040/docs/Wii_Mode_Guide.md @@ -0,0 +1,139 @@ +# Wii Mode Guide + +This guide covers **Wii mode** on OGX-Mini when using a **Pico W** or **Pico 2 W**. In this mode the adapter appears as a **Nintendo Wiimote** over Bluetooth to a Wii or Wii U, while your **input** comes from a **USB gamepad** plugged into the board’s **external USB host port**. + +**Wii mode is build-option only:** you cannot switch into or out of Wii with button combos. Build with `-DOGXM_FIXED_DRIVER=WII` to get a Wii-only firmware; combos are disabled in that build. + +For hardware wiring and USB port setup (PIO USB, pins, build), see [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md). + +--- + +## 1. How Wii mode works + +- The adapter’s **Bluetooth** is used only for the **Wiimote** link to the console (Wii or Wii U). +- A **USB controller** must be connected to the **external USB host port** (PIO USB on GPIO). The built-in USB port is for programming and is **not** used for the gamepad in Wii mode. +- The firmware converts USB gamepad input into Wiimote (and extension) reports and sends them over Bluetooth. The console sees a normal Wiimote; you control it with your USB pad. + +--- + +## 2. USB connection (controller input) + +- **Use the external USB port** (PIO USB). On Pico W / Pico 2 W this is the connector wired to **D+/D− on GP0/GP1** (or swapped per board config). See [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md) for pins and wiring. +- **Do not** plug the gamepad into the Pico’s **built-in** USB port (the one used for flashing). That port is not used as host in Wii mode. +- Power the board and plug the USB controller into the external port. When it enumerates, the controller’s LED (if any) should indicate it’s active. The firmware waits for a controller before starting the Wiimote connection flow. + +--- + +## 3. Connecting to the Wii / Wii U + +### First-time sync + +1. **Build** the firmware with Wii mode: `-DOGXM_FIXED_DRIVER=WII` (see [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md) for full build steps). +2. Power the adapter and plug in the USB controller on the **external** port. +3. On the **Wii or Wii U**: open **Wii Remote** (sync) from the system menu. +4. The adapter appears as **“Nintendo RVL-CNT-01”**. When the console asks to press **Sync**, trigger sync on the **adapter** (or follow on-screen instructions). The adapter may also **auto-connect** if it was previously paired (see below). +5. After pairing, the console treats the adapter as player 1’s Wiimote; input comes from the USB gamepad. + +### Auto-connect (after first sync) + +- The adapter **saves the last paired console’s Bluetooth address** in flash. +- On later power-ups it will **automatically try to connect** to that console (like a normal Wiimote). You do **not** need to press Sync again unless you want to pair a different console or re-pair after the console “forgot” the remote. +- If auto-connect fails (e.g. authentication error because the console removed the remote), the saved address is cleared and the adapter stays **discoverable** so you can sync again from the Wii/U menu. + +--- + +## 4. Wii report modes (No Extension, Nunchuk, Classic) + +The adapter can emulate three Wiimote “shapes” that many games support. You **cycle** between them with a button combo; the **LED flashes** to show the current mode after a change. + +| Mode | LED flashes | Description | +|-------------------|------------|-------------| +| **No Extension** | 1 | Wiimote only (can be used horizontal/sideways). | +| **Nunchuk** | 2 | Wiimote + Nunchuk (stick, C, Z). | +| **Classic** | 3 | Classic Controller (two sticks, triggers, full button set). | + +- **Default at boot:** **No Extension** (1 flash when you switch to it). +- **Cycle:** Hold **Home (Guide) + D-pad Down** for about **1 second** (10 frames). The mode advances in order: **No Extension → Nunchuk → Classic → No Extension** (repeat). Each time you change mode, the LED flashes 1, 2, or 3 times to indicate which mode you’re in. + +--- + +## 5. Button and stick mapping by mode + +Mappings assume an **Xbox-style** USB gamepad (A/B/X/Y, Start, Back, Guide, D-pad, bumpers, triggers, two sticks). Other USB pads are mapped to the same logical layout by the host driver. + +### No Extension (Wiimote only) + +| Wiimote | USB gamepad | +|------------|----------------| +| A, B | A, B | +| 1, 2 | X, Y | +| +, − | Start, Back | +| Home | Guide (SYS) | +| D-pad | D-pad | +| IR pointer | Left stick | +| Sideways | Home + LB (toggle horizontal mode) | + +### Nunchuk (Wiimote + Nunchuk) + +| Wiimote | USB gamepad | +|------------|----------------| +| A, B, 1, 2, +, −, Home, D-pad | Same as above | +| IR pointer | **Right stick** | +| Nunchuk stick | **Left stick** | +| C | Left trigger > half | +| Z | Right bumper (RB) | +| Shake | Left bumper (LB) held | + +### Classic Controller + +| Classic | USB gamepad | +|------------|----------------| +| A, B, X, Y | A, B, Y, X (X↔Y) | +| +, −, Home | Start, Back, Guide | +| D-pad | D-pad | +| L/R bumpers | LB, RB | +| L/R triggers | Left/right triggers | +| Left stick | Left stick | +| Right stick | Right stick (also used for IR pointer) | + +In all modes, **IR pointer** and sticks use a small **deadzone** so the cursor or character doesn’t drift when the stick is at rest. + +--- + +## 6. Supported controllers for input (USB host) + +In Wii mode the adapter uses the **USB host** on the external port and supports the same controllers as in other OGX-Mini host modes. Typically tested/supported USB gamepads include: + +- **Xbox One** (wired USB) +- **Xbox 360** (wired USB) +- **Xbox 360 Wireless** (with USB receiver) +- **Generic Xinput / DirectInput (DInput)** pads +- **PlayStation** (PS3, PS4, PS5) over USB, when supported by the host stack +- **Nintendo Switch Pro** (wired USB), when supported +- Other HID gamepads that enumerate as a single gamepad + +Only **one** controller is used (player 1). It must enumerate on the **external** PIO USB port. If your pad is not recognized, check wiring and [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md) (e.g. D+/D− swap). + +--- + +## 7. Wii is build-option only (no combos) + +Wii mode is **not** selectable by button combo. To use Wii you must **build** with: + +- **`-DOGXM_FIXED_DRIVER=WII`** + +Combos are **disabled** in Wii builds (you cannot switch to another mode at runtime). To use a different mode (Switch, XInput, etc.), reflash a firmware built without `OGXM_FIXED_DRIVER` or with a different fixed driver. + +--- + +## 8. Summary + +| Topic | Detail | +|-------|--------| +| **Input** | USB gamepad on **external** USB port (PIO USB). | +| **Output** | Wiimote over Bluetooth to Wii / Wii U. | +| **Modes** | No Extension (1 flash), Nunchuk (2), Classic (3). Cycle with **Home + D-pad Down** (~1 s). | +| **Sync** | First time: sync from console. After that, adapter auto-connects to last console. | +| **Wii build** | Build with `-DOGXM_FIXED_DRIVER=WII`; no combos to switch mode. | + +For wiring, pins, and build instructions, see [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md). diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index b9e7bc45..8a122925 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -258,9 +258,9 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr uni_gamepad_t *uni_gp = &controller->gamepad; int idx = uni_hid_device_get_idx_for_instance(device); - // PS5: touchpad click toggles adaptive triggers on/off + // PS5: capture/mute button toggles adaptive triggers (touchpad click not in Bluepad32 misc_buttons) if (device->controller_type == CONTROLLER_TYPE_PS5Controller && idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { - bool touchpad_clicked = (uni_gp->misc_buttons & MISC_BUTTON_TOUCHPAD) != 0; + bool touchpad_clicked = (uni_gp->misc_buttons & MISC_BUTTON_CAPTURE) != 0; if (touchpad_clicked && !prev_touchpad_clicked_[idx]) { adaptive_trigger_enabled_[idx] = !adaptive_trigger_enabled_[idx]; if (adaptive_trigger_enabled_[idx]) { diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index e11e245c..a40ecf60 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -29,6 +29,11 @@ #elif defined(CONFIG_OGXM_BOARD_PI_PICOW) || defined(CONFIG_OGXM_BOARD_PI_PICO2W) #define OGXM_BOARD PI_PICOW + // PIO USB host for external port (e.g. Wii mode: controller on USB, BT for Wiimote) + #define PIO_USB_DP_PIN 0 // D+ = GP0, D- = GP1 + #ifndef PIO_USB_SWAP_DP_DM + #define PIO_USB_SWAP_DP_DM 0 // set 1 if controller powers but does not enumerate + #endif #elif defined(CONFIG_OGXM_BOARD_RP2040_ZERO) #define OGXM_BOARD RP2040_ZERO diff --git a/Firmware/RP2040/src/Board/ogxm_log.cpp b/Firmware/RP2040/src/Board/ogxm_log.cpp index bd2d6b18..9fb6fc44 100644 --- a/Firmware/RP2040/src/Board/ogxm_log.cpp +++ b/Firmware/RP2040/src/Board/ogxm_log.cpp @@ -25,6 +25,7 @@ std::ostream& operator<<(std::ostream& os, DeviceDriverType type) { case DeviceDriverType::PSCLASSIC: os << "PSCLASSIC"; break; case DeviceDriverType::SWITCH: os << "SWITCH"; break; case DeviceDriverType::WIIU: os << "WIIU"; break; + case DeviceDriverType::WII: os << "WII"; break; case DeviceDriverType::WEBAPP: os << "WEBAPP"; break; case DeviceDriverType::UART_BRIDGE: os << "UART_BRIDGE"; break; default: os << "UNKNOWN"; break; diff --git a/Firmware/RP2040/src/Descriptors/XboxOne.h b/Firmware/RP2040/src/Descriptors/XboxOne.h index 2517b1ef..fe183d65 100644 --- a/Firmware/RP2040/src/Descriptors/XboxOne.h +++ b/Firmware/RP2040/src/Descriptors/XboxOne.h @@ -172,10 +172,29 @@ namespace XboxOne }; static_assert(sizeof(InReport) == 19, "XboxOne::InReport must be 19 bytes"); - // Button bitfield for InReport.buttons (uint16_t) - // Order matches Linux evdev / GamepadTester / official Xbox One controller: - // B0=A, B1=B, B2=X, B3=Y, B4=LB, B5=RB, B6=LT, B7=RT, B8=Select, B9=Start, - // B10=L3, B11=R3, B12=DPAD_UP, B13=DPAD_DOWN, B14=DPAD_LEFT, B15=DPAD_RIGHT. (B16=Home separate.) + // Wire format: GIP 0x20 payload bytes 0-1 (report bytes 4-5) use Microsoft layout: + // B0=Sync, B1=reserved, B2=Start, B3=Back, B4=A, B5=B, B6=X, B7=Y, + // B8=DPAD_UP, B9=DPAD_DOWN, B10=DPAD_LEFT, B11=DPAD_RIGHT, B12=LB, B13=RB, B14=L3, B15=R3. + namespace GipWireButtons + { + static constexpr uint16_t SYNC = (1U << 0); + static constexpr uint16_t START = (1U << 2); + static constexpr uint16_t BACK = (1U << 3); + static constexpr uint16_t A = (1U << 4); + static constexpr uint16_t B = (1U << 5); + static constexpr uint16_t X = (1U << 6); + static constexpr uint16_t Y = (1U << 7); + static constexpr uint16_t DPAD_UP = (1U << 8); + static constexpr uint16_t DPAD_DOWN = (1U << 9); + static constexpr uint16_t DPAD_LEFT = (1U << 10); + static constexpr uint16_t DPAD_RIGHT = (1U << 11); + static constexpr uint16_t LEFT_SHOULDER = (1U << 12); + static constexpr uint16_t RIGHT_SHOULDER = (1U << 13); + static constexpr uint16_t LEFT_THUMB = (1U << 14); + static constexpr uint16_t RIGHT_THUMB = (1U << 15); + } + + // Logical Gamepad bitfield (evdev-style); used after mapping from GipWireButtons. namespace GamepadButtons { static constexpr uint16_t A = 0x0001; // B0 diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index 4f7a5867..cbb8d8c3 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -3,6 +3,7 @@ #if (OGXM_BOARD == PI_PICOW) #include +#include #include #include #include @@ -11,15 +12,115 @@ #include "bsp/board_api.h" #include "USBDevice/DeviceManager.h" +#include "USBDevice/DeviceDriver/DeviceDriverTypes.h" #include "UserSettings/UserSettings.h" #include "Board/board_api.h" +#include "Board/ogxm_log.h" #include "Bluepad32/Bluepad32.h" #include "BLEServer/BLEServer.h" #include "Gamepad/Gamepad.h" #include "TaskQueue/TaskQueue.h" +#if defined(CONFIG_EN_USB_HOST) +#include "pio_usb.h" +#include "USBHost/HostManager.h" +#include +#include "Wii/WiiReportConverter.h" + +/** Called from flash_safe_execute on Core1; only write flash. Reboot is done by caller after return. */ +static void store_driver_type_callback(void* arg) { + auto d = *static_cast(arg); + UserSettings::get_instance().store_driver_type_only(d); +} + +extern "C" { +#include "Wii/wiimote-lib/wiimote.h" +#include "Wii/wiimote-lib/wiimote_btstack.h" +} + +static WiimoteReport s_wiimote_report = {}; // shared: Core0 reads, Core1 writes + +extern "C" void wii_led_on(void) { board_api::set_led(true); } +extern "C" void wii_led_off(void) { board_api::set_led(false); } +#endif + Gamepad _gamepads[MAX_GAMEPADS]; +#if defined(CONFIG_EN_USB_HOST) +constexpr uint32_t FEEDBACK_DELAY_MS = 200; + +void core1_task_wii_usb_host() { + OGXM_LOG("WII Core1: entry\n"); + flash_safe_execute_core_init(); // so Core0 can flash_safe_execute when saving Wii address (TLV) + HostManager& host_manager = HostManager::get_instance(); + host_manager.initialize(_gamepads); + OGXM_LOG("WII Core1: HostManager init done\n"); + + OGXM_LOG("WII Core1: waiting for host_connected() (plug USB controller into external port GP0/GP1)\n"); + uint32_t wait_count = 0; + while (!board_api::usb::host_connected()) { + sleep_ms(100); + if ((++wait_count % 20) == 0) { + OGXM_LOG("WII Core1: still waiting for host_connected()...\n"); + } + } + OGXM_LOG("WII Core1: host_connected\n"); + + // Use an unused hardware alarm for PIO USB host so TaskQueue Core1 can keep alarm 2 (avoids conflict; alarm 3 may be claimed on Pico 2 W) + static alarm_pool_t* s_wii_usb_alarm_pool = alarm_pool_create_with_unused_hardware_alarm(1); + pio_usb_configuration_t pio_cfg = PIO_USB_CONFIG; + pio_cfg.alarm_pool = s_wii_usb_alarm_pool; + // CYW43 (BT on Core0) claims DMA 0 and 1; use channel 2 for PIO USB TX to avoid "DMA channel 0 is already claimed" + pio_cfg.tx_ch = 2; + tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); + OGXM_LOG("WII Core1: tuh_configure done\n"); + tuh_init(BOARD_TUH_RHPORT); + OGXM_LOG("WII Core1: tuh_init done\n"); + + uint32_t tid_feedback = TaskQueue::Core1::get_new_task_id(); + TaskQueue::Core1::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, + [&host_manager]() { host_manager.send_feedback(); }); + OGXM_LOG("WII Core1: feedback task queued, entering loop\n"); + + s_wiimote_report.mode = (uint8_t)NO_EXTENSION; // Wiimote only; home+down cycles to Nunchuk, then Classic + +#if !defined(CONFIG_OGXM_FIXED_DRIVER) || defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) + uint32_t last_gp_check_ms = 0; // throttle: same 600 ms / 3 s hold as other modes + uint32_t gp_check_ticks = 0; +#endif + + while (true) { + TaskQueue::Core1::process_tasks(); + tuh_task(); + Wii::gamepad_to_wiimote_report(_gamepads[0], &s_wiimote_report); + +#if !defined(CONFIG_OGXM_FIXED_DRIVER) || defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) + uint32_t now = board_api::ms_since_boot(); + if (now - last_gp_check_ms >= static_cast(UserSettings::GP_CHECK_DELAY_MS)) { + last_gp_check_ms = now; + UserSettings& user_settings = UserSettings::get_instance(); + bool changed = user_settings.check_for_driver_change(_gamepads[0]); +#if defined(CONFIG_OGXM_DEBUG) + if ((++gp_check_ticks % 10) == 0) + OGXM_LOG("WII Core1: gp check tick " + std::to_string(gp_check_ticks) + "\n"); +#endif + if (changed) { + static DeviceDriverType new_driver; + new_driver = user_settings.get_current_driver(); + OGXM_LOG("WII Core1: driver change detected, new_driver=" + OGXM_TO_STRING(new_driver) + ", calling flash_safe_execute\n"); + int fs_ret = flash_safe_execute(store_driver_type_callback, &new_driver, 200); + OGXM_LOG("WII Core1: flash_safe_execute returned " + std::to_string(fs_ret) + " (0=ok)\n"); + if (fs_ret == 0) { + OGXM_LOG("WII Core1: calling reboot\n"); + board_api::reboot(); + } + } + } +#endif + } +} +#endif + void core1_task() { board_api::init_bluetooth(); board_api::set_led(true); @@ -44,10 +145,17 @@ void set_gp_check_timer(uint32_t task_id) { } void pico_w::initialize() { + OGXM_LOG("PicoW init: start\n"); board_api::init_board(); + OGXM_LOG("PicoW init: board inited\n"); UserSettings& user_settings = UserSettings::get_instance(); user_settings.initialize_flash(); +#if defined(CONFIG_OGXM_DEBUG) + OGXM_LOG("PicoW init: flash inited, driver=" + OGXM_TO_STRING(user_settings.get_current_driver()) + "\n"); +#else + OGXM_LOG("PicoW init: flash inited\n"); +#endif for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { _gamepads[i].set_profile(user_settings.get_profile_by_index(i)); @@ -55,35 +163,57 @@ void pico_w::initialize() { DeviceManager& device_manager = DeviceManager::get_instance(); device_manager.initialize_driver(user_settings.get_current_driver(), _gamepads); + OGXM_LOG("PicoW init: driver inited\n"); } void pico_w::run() { + OGXM_LOG("PicoW run: start\n"); multicore_reset_core1(); - // Initialize USB before starting core1 (BT). If BT FW download hangs, the host can - // still enumerate and run XSM3 auth; core1 runs Bluetooth in parallel. + UserSettings& user_settings = UserSettings::get_instance(); DeviceDriver* device_driver = DeviceManager::get_instance().get_driver(); - tud_init(BOARD_TUD_RHPORT); - printf("USB init done\n"); - - multicore_launch_core1(core1_task); - printf("Core1 (BT) launched\n"); + const bool wii_mode = (user_settings.get_current_driver() == DeviceDriverType::WII); + OGXM_LOG("PicoW run: wii_mode=" + std::string(wii_mode ? "1" : "0") + "\n"); + +#if defined(CONFIG_EN_USB_HOST) + if (wii_mode) { + OGXM_LOG("PicoW run: launching Core1 (Wii USB host)\n"); + multicore_launch_core1(core1_task_wii_usb_host); + OGXM_LOG("PicoW run: Core1 launched, starting Wiimote BT (discoverable as Nintendo RVL-CNT-01)\n"); + board_api::init_bluetooth(); + wiimote_emulator_set_led(wii_led_on, wii_led_off); + wiimote_emulator(&s_wiimote_report); // never returns: BT run loop, LED blinks until connected + } else +#endif + { + tud_init(BOARD_TUD_RHPORT); + OGXM_LOG("PicoW run: tud_init done, launching Core1 (BT)\n"); + multicore_launch_core1(core1_task); + OGXM_LOG("PicoW run: Core1 (BT) launched\n"); + } uint32_t tid_gp_check = TaskQueue::Core0::get_new_task_id(); set_gp_check_timer(tid_gp_check); + OGXM_LOG("PicoW run: gp check timer set, entering main loop\n"); static bool mounted_logged = false; + static uint32_t loop_count = 0; while (true) { TaskQueue::Core0::process_tasks(); for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { device_driver->process(i, _gamepads[i]); - tud_task(); } - if (tud_mounted() && !mounted_logged) { - mounted_logged = true; - printf("USB configured (host enumerated)\n"); + if (!wii_mode) { + tud_task(); + if (tud_mounted() && !mounted_logged) { + mounted_logged = true; + OGXM_LOG("PicoW run: USB configured\n"); + } + } else if (loop_count == 0 || loop_count == 5000) { + OGXM_LOG("PicoW run: Wii main loop tick\n"); } + loop_count++; #if MAIN_LOOP_DELAY_US > 0 sleep_us(MAIN_LOOP_DELAY_US); #endif diff --git a/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp b/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp index 2e8fbc18..33a596c2 100644 --- a/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp +++ b/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp @@ -1,9 +1,9 @@ #include "TaskQueue/TaskQueue.h" -TaskQueue::TaskQueue(CoreNum core_num) -{ +TaskQueue::TaskQueue(CoreNum core_num) +{ alarm_num_ = (core_num == CoreNum::Core0) ? 0 : 1; - alarm_num_ += (OGXM_BOARD == PI_PICOW) ? 1 : 0; //BTStack uses alarm 0 + alarm_num_ += (OGXM_BOARD == PI_PICOW) ? 1 : 0; // BTStack uses alarm 0; PicoW Wii mode gives PIO USB alarm 3 via config hw_set_bits(&timer_hw->inte, 1u << alarm_num_); diff --git a/Firmware/RP2040/src/TaskQueue/TaskQueue.h b/Firmware/RP2040/src/TaskQueue/TaskQueue.h index 2c32866e..90a3796f 100644 --- a/Firmware/RP2040/src/TaskQueue/TaskQueue.h +++ b/Firmware/RP2040/src/TaskQueue/TaskQueue.h @@ -48,7 +48,7 @@ class TaskQueue } }; -#if (OGXM_BOARD != PI_PICOW) //BTstack uses core1 +#if (OGXM_BOARD != PI_PICOW) || defined(CONFIG_EN_USB_HOST) // PI_PICOW: Core1 for Wii USB host struct Core1 { static inline uint32_t get_new_task_id() @@ -80,7 +80,7 @@ class TaskQueue get_core1().resume_delayed(); } }; // Core1 -#endif // OGXM_BOARD != PI_PICOW +#endif static void suspend_delayed_tasks(); static void resume_delayed_tasks(); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h index 5cfd7443..0ba091ca 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h @@ -15,6 +15,7 @@ enum class DeviceDriverType : uint8_t PSCLASSIC, SWITCH, WIIU, + WII, // Wiimote (Pico W/2W: controller on PIO USB, BT for Wii link) WEBAPP = 100, UART_BRIDGE }; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.cpp new file mode 100644 index 00000000..c80d9f96 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.cpp @@ -0,0 +1,32 @@ +#include "USBDevice/DeviceDriver/Wii/Wii.h" + +void WiiDevice::initialize() +{ + // No USB device (tud) in Wii mode on Pico W; BT is used for Wiimote. + (void)class_driver_; // unused +} + +void WiiDevice::process(const uint8_t idx, Gamepad& gamepad) +{ + (void)idx; + (void)gamepad; + // Gamepad is filled by USB host on Core1. Optional: send to Wiimote BT stack here. +} + +uint16_t WiiDevice::get_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t*, uint16_t) +{ + return 0; +} + +void WiiDevice::set_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t const*, uint16_t) {} + +bool WiiDevice::vendor_control_xfer_cb(uint8_t, uint8_t, tusb_control_request_t const*) +{ + return false; +} + +const uint16_t* WiiDevice::get_descriptor_string_cb(uint8_t, uint16_t) { return nullptr; } +const uint8_t* WiiDevice::get_descriptor_device_cb() { return nullptr; } +const uint8_t* WiiDevice::get_hid_descriptor_report_cb(uint8_t) { return nullptr; } +const uint8_t* WiiDevice::get_descriptor_configuration_cb(uint8_t) { return nullptr; } +const uint8_t* WiiDevice::get_descriptor_device_qualifier_cb() { return nullptr; } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.h new file mode 100644 index 00000000..1288fab6 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Wii/Wii.h @@ -0,0 +1,24 @@ +#ifndef _WII_DEVICE_H_ +#define _WII_DEVICE_H_ + +#include "USBDevice/DeviceDriver/DeviceDriver.h" + +/** Stub Wiimote driver for Pico W/2W Wii mode. + * Controller is on PIO USB host; BT is used for Wiimote link to the Wii. + * process() can be extended to send gamepad state to a Wiimote BT stack. */ +class WiiDevice : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; +}; + +#endif // _WII_DEVICE_H_ diff --git a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp index 76e8e6c4..2cdef188 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp @@ -5,6 +5,7 @@ #include "USBDevice/DeviceDriver/XInput/XInput.h" #include "USBDevice/DeviceDriver/Switch/Switch.h" #include "USBDevice/DeviceDriver/WiiU/WiiU.h" +#include "USBDevice/DeviceDriver/Wii/Wii.h" #include "USBDevice/DeviceDriver/DInput/DInput.h" #include "USBDevice/DeviceDriver/PS3/PS3.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h" @@ -47,6 +48,10 @@ void DeviceManager::initialize_driver( DeviceDriverType driver_type, printf("WIIU Loaded\n"); device_driver_ = std::make_unique(); break; + case DeviceDriverType::WII: + printf("WII Loaded\n"); + device_driver_ = std::make_unique(); + break; case DeviceDriverType::XINPUT: printf("XINPUT Loaded\n"); device_driver_ = std::make_unique(); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp index 14ff9024..914917bf 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp @@ -1,10 +1,13 @@ #include #include "host/usbh.h" +#include "Board/board_api.h" #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/XInput/XboxOne.h" +static constexpr uint32_t GUIDE_STALE_MS = 400u; // clear Guide if no 0x07 packet this long (stuck/noise) + void XboxOneHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { tuh_xinput::receive_report(address, instance); @@ -12,8 +15,60 @@ void XboxOneHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance void XboxOneHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) { + const uint8_t cmd = report[0]; + if (cmd == XboxOne::GIP_CMD_VIRTUAL_KEY) + { + last_guide_07_ms_ = board_api::ms_since_boot(); + // Guide (Home) in 0x07: payload byte 4 = pressed (bit 0) / released; or keycode 0x5B at 4, pressed at 5 + if (len >= 5) { + if (report[4] == 0x5B && len >= 6) + guide_pressed_ = (report[5] & 0x01) ? 1 : 0; // keycode then pressed + else + guide_pressed_ = (report[4] & 0x01) ? 1 : 0; // pressed bit in first payload byte + } + // Push state immediately so Guide registers (next 0x20 might be unchanged and skip set_pad_in) + const XboxOne::InReport* prev = &prev_in_report_; + Gamepad::PadIn gp_in; + const uint16_t b = prev->buttons; + if (b & XboxOne::GipWireButtons::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; + if (b & XboxOne::GipWireButtons::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (b & XboxOne::GipWireButtons::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + if (b & XboxOne::GipWireButtons::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + if (b & XboxOne::GipWireButtons::LEFT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_L3; + if (b & XboxOne::GipWireButtons::RIGHT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_R3; + if (b & XboxOne::GipWireButtons::LEFT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_LB; + if (b & XboxOne::GipWireButtons::RIGHT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_RB; + if (b & XboxOne::GipWireButtons::BACK) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + if (b & XboxOne::GipWireButtons::START) gp_in.buttons |= gamepad.MAP_BUTTON_START; + if (b & XboxOne::GipWireButtons::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + if (guide_pressed_) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + if (b & XboxOne::GipWireButtons::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; + if (b & XboxOne::GipWireButtons::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; + if (b & XboxOne::GipWireButtons::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; + if (b & XboxOne::GipWireButtons::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; + gp_in.trigger_l = gamepad.scale_trigger_l(static_cast(prev->trigger_l >> 2)); + gp_in.trigger_r = gamepad.scale_trigger_r(static_cast(prev->trigger_r >> 2)); + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(prev->joystick_lx, prev->joystick_ly, true); + std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(prev->joystick_rx, prev->joystick_ry, true); + gamepad.set_pad_in(gp_in); + tuh_xinput::receive_report(address, instance); + return; + } + + if (cmd != XboxOne::GIP_CMD_INPUT) + { + tuh_xinput::receive_report(address, instance); + return; + } + const XboxOne::InReport* in_report = reinterpret_cast(report); - if (std::memcmp(&prev_in_report_ + 4, in_report + 4, 14) == 0) + // Clear Guide if we haven't seen a 0x07 packet in a while (stuck / noise) + bool guide_cleared = false; + if (guide_pressed_ && (board_api::ms_since_boot() - last_guide_07_ms_) > GUIDE_STALE_MS) { + guide_pressed_ = 0; + guide_cleared = true; + } + if (std::memcmp(&prev_in_report_ + 4, in_report + 4, 14) == 0 && !guide_cleared) { tuh_xinput::receive_report(address, instance); return; @@ -21,24 +76,25 @@ void XboxOneHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t inst Gamepad::PadIn gp_in; + // Raw GIP 0x20 uses Microsoft bit layout; map to project Gamepad (then WiiReportConverter → Wii) const uint16_t b = in_report->buttons; - if (b & XboxOne::GamepadButtons::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; - if (b & XboxOne::GamepadButtons::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; - if (b & XboxOne::GamepadButtons::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; - if (b & XboxOne::GamepadButtons::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; - - if (b & XboxOne::GamepadButtons::LEFT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_L3; - if (b & XboxOne::GamepadButtons::RIGHT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_R3; - if (b & XboxOne::GamepadButtons::LEFT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_LB; - if (b & XboxOne::GamepadButtons::RIGHT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_RB; - if (b & XboxOne::GamepadButtons::VIEW) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; - if (b & XboxOne::GamepadButtons::MENU) gp_in.buttons |= gamepad.MAP_BUTTON_START; - if (b & XboxOne::GamepadButtons::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; - if (in_report->guide_pressed) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (b & XboxOne::GamepadButtons::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; - if (b & XboxOne::GamepadButtons::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; - if (b & XboxOne::GamepadButtons::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; - if (b & XboxOne::GamepadButtons::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; + if (b & XboxOne::GipWireButtons::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; + if (b & XboxOne::GipWireButtons::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (b & XboxOne::GipWireButtons::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + if (b & XboxOne::GipWireButtons::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + + if (b & XboxOne::GipWireButtons::LEFT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_L3; + if (b & XboxOne::GipWireButtons::RIGHT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_R3; + if (b & XboxOne::GipWireButtons::LEFT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_LB; + if (b & XboxOne::GipWireButtons::RIGHT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_RB; + if (b & XboxOne::GipWireButtons::BACK) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + if (b & XboxOne::GipWireButtons::START) gp_in.buttons |= gamepad.MAP_BUTTON_START; + if (b & XboxOne::GipWireButtons::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + if (guide_pressed_) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + if (b & XboxOne::GipWireButtons::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; + if (b & XboxOne::GipWireButtons::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; + if (b & XboxOne::GipWireButtons::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; + if (b & XboxOne::GipWireButtons::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; gp_in.trigger_l = gamepad.scale_trigger_l(static_cast(in_report->trigger_l >> 2)); gp_in.trigger_r = gamepad.scale_trigger_r(static_cast(in_report->trigger_r >> 2)); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h index 84836004..13dabe0a 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h @@ -18,6 +18,8 @@ class XboxOneHost : public HostDriver private: XboxOne::InReport prev_in_report_; + uint8_t guide_pressed_{0}; // Guide (Home) from GIP 0x07; not in 0x20 report + uint32_t last_guide_07_ms_{0}; // when we last saw 0x07; clear Guide if no 0x07 for a while }; #endif // _XBOX_ONE_HOST_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp index c07e0ccb..e88e9789 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp @@ -509,12 +509,18 @@ bool set_rumble(uint8_t dev_addr, uint8_t instance, uint8_t rumble_l, uint8_t ru switch (interface->dev_type) { case DevType::XBOX360W: + send_report(dev_addr, instance, Xbox360W::RUMBLE_ENABLE, sizeof(Xbox360W::RUMBLE_ENABLE)); + wait_for_tx_complete(dev_addr, interface->ep_out); + std::memcpy(buffer, Xbox360W::RUMBLE, sizeof(Xbox360W::RUMBLE)); buffer[5] = rumble_l; buffer[6] = rumble_r; len = sizeof(Xbox360W::RUMBLE); break; case DevType::XBOX360: + send_report(dev_addr, instance, Xbox360::RUMBLE, sizeof(Xbox360::RUMBLE)); + wait_for_tx_complete(dev_addr, interface->ep_out); + std::memcpy(buffer, Xbox360::RUMBLE, sizeof(Xbox360::RUMBLE)); buffer[3] = rumble_l; buffer[4] = rumble_r; diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.cpp b/Firmware/RP2040/src/UserSettings/UserSettings.cpp index 44b87ead..84f1fcb1 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/UserSettings.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -24,6 +25,7 @@ namespace ButtonCombo { static constexpr uint32_t XBOXOG_XR = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB, Gamepad::DPAD_RIGHT); static constexpr uint32_t PSCLASSIC = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_A); static constexpr uint32_t WEBAPP = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB | Gamepad::BUTTON_RB); + // WII is build-option only (OGXM_FIXED_DRIVER=WII), not in combo map }; static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { @@ -34,6 +36,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::PS3, DeviceDriverType::PSCLASSIC, DeviceDriverType::WIIU, + DeviceDriverType::WII, DeviceDriverType::WEBAPP, #if defined(XREMOTE_ROM_AVAILABLE) DeviceDriverType::XBOXOG_XR, @@ -43,6 +46,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::DINPUT, DeviceDriverType::SWITCH, DeviceDriverType::WIIU, + DeviceDriverType::WII, DeviceDriverType::WEBAPP, #else // MAX_GAMEPADS == 1 @@ -51,6 +55,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::DINPUT, DeviceDriverType::SWITCH, DeviceDriverType::WIIU, + DeviceDriverType::WII, DeviceDriverType::WEBAPP, DeviceDriverType::PS3, DeviceDriverType::PSCLASSIC, @@ -127,7 +132,7 @@ bool UserSettings::check_for_driver_change(Gamepad& gamepad) uint32_t current_button_combo = BUTTON_COMBO(gp_in.buttons, gp_in.dpad); - if (!(current_button_combo & (static_cast(Gamepad::BUTTON_START) << 16)) || + if (!(current_button_combo & (static_cast(Gamepad::BUTTON_START) << 16)) || last_button_combo != current_button_combo) { last_button_combo = current_button_combo; @@ -157,13 +162,19 @@ bool UserSettings::check_for_driver_change(Gamepad& gamepad) if (new_driver == DeviceDriverType::NONE || new_driver == current_driver_) { +#if defined(CONFIG_OGXM_DEBUG) + if (new_driver == DeviceDriverType::NONE) + OGXM_LOG("WII driver check: combo 0x" + std::to_string(current_button_combo) + " no match\n"); + else + OGXM_LOG("WII driver check: same driver " + OGXM_TO_STRING(current_driver_) + ", no change\n"); +#endif return false; } current_driver_ = new_driver; - + OGXM_LOG("WII driver check: returning true, new_driver=" + OGXM_TO_STRING(new_driver) + "\n"); return true; -#endif // !(CONFIG_OGXM_FIXED_DRIVER && !CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) +#endif } //Disconnects usb and resets pico, call from core0 @@ -226,7 +237,7 @@ bool UserSettings::store_profile_and_driver_type(DeviceDriverType new_driver_typ } //Disconnects usb and resets pico if it's a new & valid mode, call from core0 -void UserSettings::store_driver_type(DeviceDriverType new_driver) +void UserSettings::store_driver_type(DeviceDriverType new_driver) { if (!is_valid_driver(new_driver)) { @@ -243,6 +254,40 @@ void UserSettings::store_driver_type(DeviceDriverType new_driver) board_api::reboot(); } +// Store driver and reboot only; no disconnect_all(). Use from Core0. +void UserSettings::store_driver_type_and_reboot(DeviceDriverType new_driver) +{ + if (!is_valid_driver(new_driver)) + { + OGXM_LOG("Invalid driver type during store_and_reboot: " + OGXM_TO_STRING(new_driver) + "\n"); + return; + } + + OGXM_LOG("Storing new driver type and rebooting: " + OGXM_TO_STRING(new_driver) + "\n"); + + nvs_tool_.write(DRIVER_TYPE_KEY(), &new_driver, sizeof(uint8_t)); + + board_api::reboot(); +} + +// Store driver to flash only. Used from Core0 after watchdog reboot (Wii exit) or from flash_safe_execute callback. +// Updates in-memory current_driver_ so the rest of run() sees the new mode. +bool UserSettings::store_driver_type_only(DeviceDriverType new_driver) +{ + if (!is_valid_driver(new_driver)) + { + OGXM_LOG("Invalid driver type in store_driver_type_only: " + OGXM_TO_STRING(new_driver) + "\n"); + return false; + } + + OGXM_LOG("Storing new driver type (flash only): " + OGXM_TO_STRING(new_driver) + "\n"); + + nvs_tool_.write(DRIVER_TYPE_KEY(), &new_driver, sizeof(uint8_t)); + current_driver_ = new_driver; + + return true; +} + uint8_t UserSettings::get_active_profile_id(const uint8_t index) { if (index > MAX_GAMEPADS - 1) @@ -303,9 +348,9 @@ DeviceDriverType UserSettings::get_current_driver() } uint8_t stored_value = 0; - nvs_tool_.read(DRIVER_TYPE_KEY(), &stored_value, sizeof(uint8_t)); + bool read_ok = nvs_tool_.read(DRIVER_TYPE_KEY(), &stored_value, sizeof(uint8_t)); - if (is_valid_driver(static_cast(stored_value))) + if (read_ok && is_valid_driver(static_cast(stored_value))) { OGXM_LOG("Driver type read from flash: " + OGXM_TO_STRING(static_cast(stored_value)) + "\n"); @@ -313,7 +358,14 @@ DeviceDriverType UserSettings::get_current_driver() return current_driver_; } +#if defined(CONFIG_OGXM_DEBUG) + if (!read_ok) + OGXM_LOG("Driver type read failed or key missing, using default\n"); + else + OGXM_LOG("Driver type from flash raw=0x" + std::to_string(stored_value) + " invalid, using default " + OGXM_TO_STRING(DEFAULT_DRIVER()) + "\n"); +#else OGXM_LOG("Invalid driver type read from flash, setting default driver\n"); +#endif current_driver_ = DEFAULT_DRIVER(); return current_driver_; diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.h b/Firmware/RP2040/src/UserSettings/UserSettings.h index ae406942..0fc75386 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.h +++ b/Firmware/RP2040/src/UserSettings/UserSettings.h @@ -37,6 +37,10 @@ class UserSettings uint8_t get_active_profile_id(const uint8_t index); void store_driver_type(DeviceDriverType new_driver_type); + /** Store driver and reboot without disconnect_all(); use from Core0. */ + void store_driver_type_and_reboot(DeviceDriverType new_driver_type); + /** Store driver to flash only (no disconnect, no reboot). Use from flash_safe_execute callback (Wii exit); caller must reboot after. */ + bool store_driver_type_only(DeviceDriverType new_driver_type); bool store_profile(uint8_t index, const UserProfile& profile); bool store_profile_and_driver_type(DeviceDriverType new_driver_type, uint8_t index, const UserProfile& profile); diff --git a/Firmware/RP2040/src/Wii/WiiReportConverter.cpp b/Firmware/RP2040/src/Wii/WiiReportConverter.cpp new file mode 100644 index 00000000..08b9a0a7 --- /dev/null +++ b/Firmware/RP2040/src/Wii/WiiReportConverter.cpp @@ -0,0 +1,225 @@ +/** + * Converts OGX-Mini Gamepad state to WiimoteReport for Wii mode BT emulation. + * Mappings match PicoGamepadConverter convert_data.c WII case (XInput layout). + */ +#include "Wii/WiiReportConverter.h" +#include "Gamepad/Gamepad.h" +#include "Wii/wiimote-lib/wiimote.h" +#include +#include + +#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) +#include "Board/board_api.h" +#include "pico/time.h" + +namespace Wii { + +/** Flash LED n times to indicate mode: 1 = NO_EXTENSION, 2 = Nunchuk, 3 = Classic */ +static void flash_led_times(unsigned n) { + for (unsigned i = 0; i < n; ++i) { + board_api::set_led(false); + sleep_ms(80); + board_api::set_led(true); + if (i + 1 < n) + sleep_ms(100); + } +} + +// Require Home+Down held this many consecutive frames before switching mode (avoids stuck/noisy Home) +static constexpr unsigned MODE_SWITCH_HOLD_FRAMES = 10; +static unsigned s_home_down_hold_count = 0; + +// Same as PicoGamepadConverter: int16 stick -> int8 for IR (-128..127) +static inline int8_t stick_to_wiimote_ir(int16_t val) { + return (int8_t)(val >> 8); +} +// int16 stick -> uint8 for nunchuk stick (0-255, center 128). val>>8 is -128..127; +128 -> 0..255 +static inline uint8_t stick_to_nunchuk_xy(int16_t val) { + int v = (val >> 8) + 128; + return (uint8_t)std::clamp(v, 0, 255); +} +// int16 stick -> uint8 for classic stick (32..63 center 32). PicoGamepadConverter: (sThumbLX/32768.0)*31+32 +static inline uint8_t stick_to_classic_xy(int16_t val) { + int v = (int)((float)val / 32768.f * 31.f + 32.f); + return (uint8_t)std::clamp(v, 0, 63); +} + +// Classic right stick: center 15, range 0..30. Deadzone to avoid pointer drift at rest. +static constexpr int16_t CLASSIC_RS_DEADZONE = 2048; +static inline int16_t classic_rs_apply_deadzone(int16_t val) { + return (val > -CLASSIC_RS_DEADZONE && val < CLASSIC_RS_DEADZONE) ? 0 : val; +} + +void gamepad_to_wiimote_report(Gamepad& gamepad, void* out_wiimote_report) +{ + WiimoteReport* out = static_cast(out_wiimote_report); + if (!out) return; + + Gamepad::PadIn pad = gamepad.get_pad_in(); + + // Preserve console_info so the Wiimote stack keeps the saved Wii address across frames + // (we only leave it unchanged; first boot it's zero so we stay discoverable) + + // Default mode to NO_EXTENSION if invalid (first frame or corrupted) + if (out->mode != NO_EXTENSION && out->mode != WIIMOTE_AND_NUNCHUCK && out->mode != CLASSIC_CONTROLLER) + out->mode = NO_EXTENSION; + + // --- Wiimote buttons (match PicoGamepadConverter NO_EXTENSION / WIIMOTE_AND_NUNCHUCK) --- + // XInput: A=0x1000 B=0x2000 X=0x4000 Y=0x8000 BACK=0x0020 START=0x0010 GUIDE=0x0400 DPAD_*=0x0001/2/4/8 LB=0x0100 RB=0x0200 + // Our Gamepad: BUTTON_A=0x0001 B=0x0002 X=0x0004 Y=0x0008 BACK=0x0040 START=0x0080 SYS=0x0400 LB=0x0100 RB=0x0200 + out->wiimote.a = (pad.buttons & Gamepad::BUTTON_A) != 0; + out->wiimote.b = (pad.buttons & Gamepad::BUTTON_B) != 0; + out->wiimote.minus = (pad.buttons & Gamepad::BUTTON_BACK) != 0; + out->wiimote.plus = (pad.buttons & Gamepad::BUTTON_START) != 0; + out->wiimote.home = (pad.buttons & Gamepad::BUTTON_SYS) != 0; + out->wiimote.one = (pad.buttons & Gamepad::BUTTON_X) != 0; + out->wiimote.two = (pad.buttons & Gamepad::BUTTON_Y) != 0; + out->wiimote.up = (pad.dpad & Gamepad::DPAD_UP) != 0; + out->wiimote.down = (pad.dpad & Gamepad::DPAD_DOWN) != 0; + out->wiimote.left = (pad.dpad & Gamepad::DPAD_LEFT) != 0; + out->wiimote.right = (pad.dpad & Gamepad::DPAD_RIGHT) != 0; + out->wiimote.sync = false; + out->wiimote.power = false; + + // Accelerometer: neutral ~0x200 (10-bit). Wii expects this for pointer/motion + out->wiimote.accel_x = 0x200; + out->wiimote.accel_y = 0x200; + out->wiimote.accel_z = 0x200; + + // IR pointer: left stick for NO_EXTENSION (right→right, up→up; deadzone to prevent drift) + out->wiimote.ir_x = stick_to_wiimote_ir(classic_rs_apply_deadzone(pad.joystick_lx)); + out->wiimote.ir_y = stick_to_wiimote_ir(classic_rs_apply_deadzone(-pad.joystick_ly)); + + // Mode and extension data (match PicoGamepadConverter) + switch (out->mode) { + case NO_EXTENSION: + // Sideway: home+LB toggles (we don't change sideway here; leave as-is or 0) + if ((out->wiimote.home) && (pad.buttons & Gamepad::BUTTON_LB)) { + out->wiimote.home = false; + out->sideway = (0xF << 1) | (out->sideway & 1); + } else if ((out->sideway >> 1) == 0xF) { + out->sideway = (out->sideway & 1) ? 0 : 1; + } + // Mode switch: home+down held for MODE_SWITCH_HOLD_FRAMES -> next mode (NO_EXTENSION -> WIIMOTE_AND_NUNCHUCK) + if (out->wiimote.home && out->wiimote.down) { + if (++s_home_down_hold_count >= MODE_SWITCH_HOLD_FRAMES) { + s_home_down_hold_count = 0; + out->wiimote.home = false; + out->wiimote.down = false; + out->switch_mode = 1; + } + } else { + s_home_down_hold_count = 0; + } + if (out->switch_mode) { + out->mode = WIIMOTE_AND_NUNCHUCK; + out->switch_mode = 0; + out->reset_ir = 1; + flash_led_times(2); + } + break; + + case WIIMOTE_AND_NUNCHUCK: + // Wiimote IR from right stick (right→right, up→up; deadzone to prevent drift) + out->wiimote.ir_x = stick_to_wiimote_ir(classic_rs_apply_deadzone(pad.joystick_rx)); + out->wiimote.ir_y = stick_to_wiimote_ir(classic_rs_apply_deadzone(-pad.joystick_ry)); + // Nunchuk stick from left stick (right→right, up→forward); deadzone so center is true 128 (stops drift in aiming) + out->nunchuk.x = stick_to_nunchuk_xy(classic_rs_apply_deadzone(pad.joystick_lx)); + out->nunchuk.y = stick_to_nunchuk_xy(classic_rs_apply_deadzone(-pad.joystick_ly)); + out->nunchuk.c = (pad.trigger_l > 127); + out->nunchuk.z = (pad.buttons & Gamepad::BUTTON_RB) != 0; + out->nunchuk.accel_x = 0x200; + out->nunchuk.accel_y = 0x200; + out->nunchuk.accel_z = 0x200; + // Fake motion: LB held + if (pad.buttons & Gamepad::BUTTON_LB) { + out->fake_motion = 1; + } else if (out->fake_motion) { + out->wiimote.accel_x = 0x82 << 2; + out->nunchuk.accel_x = 0x82 << 2; + out->wiimote.accel_y = 0x82 << 2; + out->nunchuk.accel_y = 0x82 << 2; + out->wiimote.accel_z = 0x9f << 2; + out->nunchuk.accel_z = 0x9f << 2; + out->fake_motion = 0; + out->center_accel = 1; + } + // Mode switch: home+down held -> CLASSIC + if (out->wiimote.home && out->wiimote.down) { + if (++s_home_down_hold_count >= MODE_SWITCH_HOLD_FRAMES) { + s_home_down_hold_count = 0; + out->wiimote.home = false; + out->wiimote.down = false; + out->switch_mode = 1; + } + } else { + s_home_down_hold_count = 0; + } + if (out->switch_mode) { + out->mode = CLASSIC_CONTROLLER; + out->switch_mode = 0; + out->reset_ir = 1; + flash_led_times(3); + } + break; + + case CLASSIC_CONTROLLER: { + // IR pointer from right stick (correct direction: +rx = right, -ry = up; deadzone avoids drift) + out->wiimote.ir_x = stick_to_wiimote_ir(classic_rs_apply_deadzone(pad.joystick_rx)); + out->wiimote.ir_y = stick_to_wiimote_ir(classic_rs_apply_deadzone(-pad.joystick_ry)); + out->classic.a = (pad.buttons & Gamepad::BUTTON_A) != 0; + out->classic.b = (pad.buttons & Gamepad::BUTTON_B) != 0; + out->classic.x = (pad.buttons & Gamepad::BUTTON_Y) != 0; // PicoGamepadConverter: x=Y, y=X + out->classic.y = (pad.buttons & Gamepad::BUTTON_X) != 0; + out->classic.minus = (pad.buttons & Gamepad::BUTTON_BACK) != 0; + out->classic.plus = (pad.buttons & Gamepad::BUTTON_START) != 0; + out->classic.home = (pad.buttons & Gamepad::BUTTON_SYS) != 0; + out->classic.up = (pad.dpad & Gamepad::DPAD_UP) != 0; + out->classic.down = (pad.dpad & Gamepad::DPAD_DOWN) != 0; + out->classic.left = (pad.dpad & Gamepad::DPAD_LEFT) != 0; + out->classic.right = (pad.dpad & Gamepad::DPAD_RIGHT) != 0; + out->classic.lz = (pad.buttons & Gamepad::BUTTON_LB) != 0; + out->classic.rz = (pad.buttons & Gamepad::BUTTON_RB) != 0; + out->classic.lt = pad.trigger_l; + out->classic.rt = pad.trigger_r; + out->classic.ltrigger = (pad.trigger_l > 32); + out->classic.rtrigger = (pad.trigger_r > 32); + // Left stick: correct direction (right→right, up→forward) + out->classic.ls_x = stick_to_classic_xy(pad.joystick_lx); + out->classic.ls_y = stick_to_classic_xy(-pad.joystick_ly); + // Right stick → classic RS (used for pointer): fix X/Y direction, deadzone to prevent drift up + int16_t rs_x = classic_rs_apply_deadzone(pad.joystick_rx); + int16_t rs_y = classic_rs_apply_deadzone(-pad.joystick_ry); + out->classic.rs_x = (uint8_t)std::clamp((int)((float)rs_x / 32768.f * 15.f + 15.f), 0, 30); + out->classic.rs_y = (uint8_t)std::clamp((int)((float)rs_y / 32768.f * 15.f + 15.f), 0, 30); + // Mode switch: home+down held -> NO_EXTENSION + if (out->classic.home && out->classic.down) { + if (++s_home_down_hold_count >= MODE_SWITCH_HOLD_FRAMES) { + s_home_down_hold_count = 0; + out->classic.home = false; + out->classic.down = false; + out->switch_mode = 1; + } + } else { + s_home_down_hold_count = 0; + } + if (out->switch_mode) { + out->mode = NO_EXTENSION; + out->switch_mode = 0; + out->reset_ir = 1; + flash_led_times(1); + } + break; + } + + default: + out->mode = NO_EXTENSION; + out->switch_mode = 0; + out->reset_ir = 0; + break; + } +} + +} // namespace Wii + +#endif diff --git a/Firmware/RP2040/src/Wii/WiiReportConverter.h b/Firmware/RP2040/src/Wii/WiiReportConverter.h new file mode 100644 index 00000000..91d7f42b --- /dev/null +++ b/Firmware/RP2040/src/Wii/WiiReportConverter.h @@ -0,0 +1,19 @@ +#ifndef OGXM_WII_REPORT_CONVERTER_H +#define OGXM_WII_REPORT_CONVERTER_H + +#include "Board/Config.h" + +#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) + +class Gamepad; + +namespace Wii { + +/** Fill WiimoteReport (C struct from wiimote.h) from Gamepad (for Wii mode BT). */ +void gamepad_to_wiimote_report(Gamepad& gamepad, void* out_wiimote_report); + +} // namespace Wii + +#endif + +#endif diff --git a/Firmware/RP2040/src/Wii/utils.c b/Firmware/RP2040/src/Wii/utils.c new file mode 100644 index 00000000..79fcf7b0 --- /dev/null +++ b/Firmware/RP2040/src/Wii/utils.c @@ -0,0 +1,8 @@ +#include "utils.h" +#include + +void save_wii_addr(void *wii_addr) +{ + (void)wii_addr; + /* TODO: persist to flash (e.g. UserSettings sector) for reconnection */ +} diff --git a/Firmware/RP2040/src/Wii/utils.h b/Firmware/RP2040/src/Wii/utils.h new file mode 100644 index 00000000..05ed98fd --- /dev/null +++ b/Firmware/RP2040/src/Wii/utils.h @@ -0,0 +1,19 @@ +#ifndef OGXM_WII_UTILS_H +#define OGXM_WII_UTILS_H + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** Save Wii console BD address to flash (for reconnection). Stub: no-op until we add persistence. */ +void save_wii_addr(void *wii_addr); + +#ifdef __cplusplus +} +#endif + +#endif /* OGXM_WII_UTILS_H */ diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/CMakeLists.txt b/Firmware/RP2040/src/Wii/wiimote-lib/CMakeLists.txt new file mode 100644 index 00000000..9fac7517 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/CMakeLists.txt @@ -0,0 +1,11 @@ +add_library(wiimote-lib INTERFACE) +target_include_directories(wiimote-lib INTERFACE ${CMAKE_CURRENT_LIST_DIR}) +target_link_libraries(wiimote-lib INTERFACE pico_stdlib pico_btstack_classic pico_btstack_cyw43 + pico_cyw43_arch_none) +target_sources(wiimote-lib INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/wiimote_btstack.c + ${CMAKE_CURRENT_LIST_DIR}/wiimote.c + ${CMAKE_CURRENT_LIST_DIR}/wm_reports.c + ${CMAKE_CURRENT_LIST_DIR}/motion.c + ${CMAKE_CURRENT_LIST_DIR}/wm_crypto.c + ${CMAKE_CURRENT_LIST_DIR}/inet.c) diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/btstack_config.h b/Firmware/RP2040/src/Wii/wiimote-lib/btstack_config.h new file mode 100644 index 00000000..b3b19083 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/btstack_config.h @@ -0,0 +1,79 @@ +#ifndef _PICO_BTSTACK_BTSTACK_CONFIG_H +#define _PICO_BTSTACK_BTSTACK_CONFIG_H + +// BTstack features that can be enabled +#ifdef ENABLE_BLE +#define ENABLE_LE_PERIPHERAL +#define ENABLE_LE_CENTRAL +#define ENABLE_L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE +#endif +#define ENABLE_LOG_INFO +#define ENABLE_LOG_ERROR +#define ENABLE_PRINTF_HEXDUMP +#define ENABLE_SCO_OVER_HCI + +// BTstack configuration. buffers, sizes, ... +#define HCI_OUTGOING_PRE_BUFFER_SIZE 4 +#define HCI_ACL_PAYLOAD_SIZE (1691 + 4) +#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4 +#define MAX_NR_AVDTP_CONNECTIONS 1 +#define MAX_NR_AVDTP_STREAM_ENDPOINTS 1 +#define MAX_NR_AVRCP_CONNECTIONS 2 +#define MAX_NR_BNEP_CHANNELS 1 +#define MAX_NR_BNEP_SERVICES 1 +#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 2 +#define MAX_NR_GATT_CLIENTS 1 +#define MAX_NR_HCI_CONNECTIONS 2 +#define MAX_NR_HID_HOST_CONNECTIONS 1 +#define MAX_NR_HIDS_CLIENTS 1 +#define MAX_NR_HFP_CONNECTIONS 1 +#define MAX_NR_L2CAP_CHANNELS 4 +#define MAX_NR_L2CAP_SERVICES 3 +#define MAX_NR_RFCOMM_CHANNELS 1 +#define MAX_NR_RFCOMM_MULTIPLEXERS 1 +#define MAX_NR_RFCOMM_SERVICES 1 +#define MAX_NR_SERVICE_RECORD_ITEMS 4 +#define MAX_NR_SM_LOOKUP_ENTRIES 3 +#define MAX_NR_WHITELIST_ENTRIES 16 +#define MAX_NR_LE_DEVICE_DB_ENTRIES 16 + +// Limit number of ACL/SCO Buffer to use by stack to avoid cyw43 shared bus overrun +#define MAX_NR_CONTROLLER_ACL_BUFFERS 3 +#define MAX_NR_CONTROLLER_SCO_PACKETS 3 + +// Enable and configure HCI Controller to Host Flow Control to avoid cyw43 shared bus overrun +#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL +#define HCI_HOST_ACL_PACKET_LEN 1024 +#define HCI_HOST_ACL_PACKET_NUM 3 +#define HCI_HOST_SCO_PACKET_LEN 120 +#define HCI_HOST_SCO_PACKET_NUM 3 + +// Link Key DB and LE Device DB using TLV on top of Flash Sector interface +#define NVM_NUM_DEVICE_DB_ENTRIES 16 +#define NVM_NUM_LINK_KEYS 16 + +// We don't give btstack a malloc, so use a fixed-size ATT DB. +#define MAX_ATT_DB_SIZE 512 + +// BTstack HAL configuration +#define HAVE_EMBEDDED_TIME_MS + +// map btstack_assert onto Pico SDK assert() +#define HAVE_ASSERT + +// Some USB dongles take longer to respond to HCI reset (e.g. BCM20702A). +#define HCI_RESET_RESEND_TIMEOUT_MS 1000 + +#define ENABLE_SOFTWARE_AES128 +#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS + +#define HAVE_BTSTACK_STDIN + +// To get the audio demos working even with HCI dump at 115200, this truncates long ACL packets +//#define HCI_DUMP_STDOUT_MAX_SIZE_ACL 100 + +#ifdef ENABLE_CLASSIC +// #define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE +#endif + +#endif // _PICO_BTSTACK_BTSTACK_CONFIG_H diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/eeprom.bin.h b/Firmware/RP2040/src/Wii/wiimote-lib/eeprom.bin.h new file mode 100644 index 00000000..73a743e1 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/eeprom.bin.h @@ -0,0 +1,20 @@ +#ifndef EEPROM_BIN_H +#define EEPROM_BIN_H + +#define TOTAL_SIZE_EEPROM 5888 +#define LAST_DATA_BEGIN_POS 5843 + +const unsigned char eeprom_bin_1[] = { + 0x66, 0x4d, 0x08, 0x66, 0xb3, 0x9a, 0xb3, 0xb3, 0x9a, 0x4d, 0x97, 0x66, + 0x4d, 0x08, 0x66, 0xb3, 0x9a, 0xb3, 0xb3, 0x9a, 0x4d, 0x97, 0x85, 0x85, + 0x85, 0x00, 0xa0, 0xa0, 0xa0, 0x00, 0x40, 0x04, 0x85, 0x85, 0x85, 0x00, + 0xa0, 0xa0, 0xa0, 0x00, 0x40, 0x04 +}; + +const unsigned char eeprom_bin_2[] = { + 0xff, + 0x11, 0xee, 0x00, 0x00, 0x33, 0xcc, 0x44, 0xbb, 0x00, 0x00, 0x66, 0x99, + 0x77, 0x88, 0x00, 0x00, 0x2b, 0x01, 0x30, 0x13 +}; + +#endif /* EEPROM_BIN_H */ diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/inet.c b/Firmware/RP2040/src/Wii/wiimote-lib/inet.c new file mode 100644 index 00000000..8cf0629a --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/inet.c @@ -0,0 +1,44 @@ +#include +#include + +/* variables */ +const int _test = 0x1234; +const char * _ptest = (char *)&_test; + + +/* functions */ +/* htonl */ +uint32_t htonl(uint32_t host32) +{ + if(*_ptest == 0x12) + return host32; + return ((host32 & 0xff) << 24) | ((host32 & 0xff00) << 8) + | ((host32 & 0xff0000) >> 8) | ((host32 & 0xff000000) >> 24); +} + + +/* htons */ +uint16_t htons(uint16_t host16) +{ + if(*_ptest == 0x12) + return host16; + return ((host16 & 0xff) << 8) | ((host16 & 0xff00) >> 8); +} + + +/* ntohl */ +uint32_t ntohl(uint32_t net32) +{ + return htonl(net32); +} + + +/* ntohs */ +uint16_t ntohs(uint16_t net16) +{ + return htons(net16); +} + + +//https://codereview.stackexchange.com/questions/149717/implementation-of-c-standard-library-function-ntohl +//https://github.com/joeferner/stm32-network/blob/master/interface.h \ No newline at end of file diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/inet.h b/Firmware/RP2040/src/Wii/wiimote-lib/inet.h new file mode 100644 index 00000000..02424312 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/inet.h @@ -0,0 +1,6 @@ +#include + +uint16_t htons(uint16_t host16); +uint32_t ntohl(uint32_t net32); +uint16_t htons(uint16_t host16); +uint16_t ntohs(uint16_t net16); \ No newline at end of file diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/motion.c b/Firmware/RP2040/src/Wii/wiimote-lib/motion.c new file mode 100644 index 00000000..254297f6 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/motion.c @@ -0,0 +1,155 @@ +#include "motion.h" + +#include "vector_math.h" + +//units in meters +static const double screen_distance = 2; +static const double screen_width = 1.0; +static const double screen_aspect = 4.0 / 3.0; + +static const double sensor_bar_y = screen_width / screen_aspect * 0.5; +static const double sensor_bar_width = 0.20; + +static const double cam_aspect = 1024.0 / 768.0; +static const double cam_fov = 42.0; +static const double cam_far = 4.0; +static const double cam_near = 0.5; + +static const uint16_t accelerometer_zero = 0x85 << 2; +static const uint16_t accelerometer_unit = 0x6C; + +void look_at_pointer(mat4 * wiimote_mat, float pointer_x, float pointer_y) +{ + vec3 pointer_world = { + (pointer_x - 0.5) * screen_width, + (pointer_y - 0.5) * screen_width / screen_aspect, + -screen_distance + }; + + vec3 dir = { pointer_world.x, pointer_world.y, pointer_world.z }; + vec3_normalize(&dir); + + vec3 up = { 0.0, 1.0, 0.0 }; + vec3 z = { -dir.x, -dir.y, -dir.z }; + + vec3 x; + vec3_cross(&x, &up, &z); + vec3_normalize(&x); + + vec3 y; + vec3_cross(&y, &z, &x); + // vec3_normalize(&y); + + wiimote_mat->v0 = (vec4){ x.x, x.y, x.z, 0.0 }; + wiimote_mat->v1 = (vec4){ y.x, y.y, y.z, 0.0 }; + wiimote_mat->v2 = (vec4){ z.x, z.y, z.z, 0.0 }; + wiimote_mat->v3 = (vec4){ 0.0, 0.0, 0.0, 1.0 }; +} + +void make_cam_projection_mat(mat4 * proj_mat) +{ + double near = cam_near; + double far = cam_far; + + double top = near * tan(cam_fov / 180.0 * M_PI * 0.5); + double height = 2.0 * top; + double width = cam_aspect * height; + double left = -0.5 * width; + + double right = left + width; + double bottom = top - height; + + proj_mat->v0 = (vec4){ 2.0 * near / (right - left), 0.0, 0.0, 0.0 }; + proj_mat->v1 = (vec4){ 0.0, 2.0 * near / (top - bottom), 0.0, 0.0 }; + proj_mat->v2 = (vec4){ (right + left) / (right - left), (top + bottom) / (top - bottom), -(far + near) / (far - near), -1.0 }; + proj_mat->v3 = (vec4){ 0.0, 0.0, -2.0 * far * near / (far - near), 0.0 }; +} + +void set_accelerometer(struct wiimote_state * state, const mat4 * wiimote_mat) +{ + vec3 accel = { 0, -1.0, 0 }; + mat3 accel_m; + mat3_from_mat4(&accel_m, wiimote_mat); + mat3_invert(&accel_m); + mat3_transpose(&accel_m); + vec3_apply_mat3(&accel, &accel_m); + + accel.x = fmax(-3.4, fmin(3.4, accel.x)); + accel.y = fmax(-3.4, fmin(3.4, accel.y)); + accel.z = fmax(-3.4, fmin(3.4, accel.z)); + + //transform to wiimote's accelerometer coordinate system + state->usr.accel_x = accelerometer_zero + + (int)round((double)accelerometer_unit * -accel.x); + state->usr.accel_z = accelerometer_zero + + (int)round((double)accelerometer_unit * -accel.y); + state->usr.accel_y = accelerometer_zero + + (int)round((double)accelerometer_unit * accel.z); +} + +void set_motionplus(struct wiimote_state * state, const mat4 * wiimote_mat) +{ + +} + +void set_motion_state(struct wiimote_state * state, float pointer_x, float pointer_y) +{ + mat4 wiimote_mat; + look_at_pointer(&wiimote_mat, pointer_x, pointer_y); + + mat4 view_mat = wiimote_mat; + mat4_invert(&view_mat); + + mat4 model_mat; + vec3 model_pos = (vec3){ 0.0, sensor_bar_y, -screen_distance }; + mat4_make_translation(&model_mat, &model_pos); + + mat4 proj_mat; + make_cam_projection_mat(&proj_mat); + + mat4_mult(&view_mat, &model_mat); + mat4_mult(&proj_mat, &view_mat); + + vec4 sensor_pt0 = { -sensor_bar_width * 0.5, 0.0, 0.0, 1.0 }; + vec4 sensor_pt1 = { sensor_bar_width * 0.5, 0.0, 0.0, 1.0 }; + + vec4_apply_mat4(&sensor_pt0, &proj_mat); + vec4_apply_mat4(&sensor_pt1, &proj_mat); + + vec4_multiply_scalar(&sensor_pt0, 1 / sensor_pt0.w); + vec4_multiply_scalar(&sensor_pt1, 1 / sensor_pt1.w); + + vec4_add_scalar(&sensor_pt0, 1.0); + vec4_multiply_scalar(&sensor_pt0, 0.5); + + vec4_add_scalar(&sensor_pt1, 1.0); + vec4_multiply_scalar(&sensor_pt1, 0.5); + + double min_pt_size = 1.0; + double max_pt_size = 15.0; + + reset_ir_object(&state->usr.ir_object[0]); + reset_ir_object(&state->usr.ir_object[1]); + + if (sensor_pt0.x > 0 && sensor_pt0.x < 1 && + sensor_pt0.y > 0 && sensor_pt0.y < 1 && + sensor_pt0.z > 0 && sensor_pt0.z < 1) + { + state->usr.ir_object[0].x = round(sensor_pt0.x * 1023); + state->usr.ir_object[0].y = round(sensor_pt0.y * 767); + state->usr.ir_object[0].size = round(min_pt_size + + pow(1.0 - sensor_pt0.z, 2.0) * (max_pt_size - min_pt_size)); + } + + if (sensor_pt1.x > 0 && sensor_pt1.x < 1 && + sensor_pt1.y > 0 && sensor_pt1.y < 1 && + sensor_pt1.z > 0 && sensor_pt1.z < 1) + { + state->usr.ir_object[1].x = round(sensor_pt1.x * 1023); + state->usr.ir_object[1].y = round(sensor_pt1.y * 767); + state->usr.ir_object[1].size = round(min_pt_size + + pow(1.0 - sensor_pt1.z, 2.0) * (max_pt_size - min_pt_size)); + } + + set_accelerometer(state, &wiimote_mat); +} \ No newline at end of file diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/motion.h b/Firmware/RP2040/src/Wii/wiimote-lib/motion.h new file mode 100644 index 00000000..266e50ab --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/motion.h @@ -0,0 +1,8 @@ +#ifndef MOTION_H +#define MOTION_H + +#include "wiimote.h" + +void set_motion_state(struct wiimote_state * state, float pointer_x, float pointer_y); + +#endif \ No newline at end of file diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/sdp_consts.h b/Firmware/RP2040/src/Wii/wiimote-lib/sdp_consts.h new file mode 100644 index 00000000..4cdc0e59 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/sdp_consts.h @@ -0,0 +1,183 @@ +#include + +static const uint8_t resp0[14] = +{ 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00 }; + +static const uint8_t resp1[128] = +{ + 0x05, 0x00, 0x01, 0x00, 0x7B, 0x00, 0x76, 0x36, 0x01, 0xCC, 0x09, 0x00, 0x00, + 0x0A, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, 0x11, 0x24, + 0x09, 0x00, 0x04, 0x35, 0x0D, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, + 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10, 0x02, + 0x09, 0x00, 0x06, 0x35, 0x09, 0x09, 0x65, 0x6E, 0x09, 0x00, 0x6A, 0x09, 0x01, + 0x00, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24, 0x09, 0x01, + 0x00, 0x09, 0x00, 0x0D, 0x35, 0x0F, 0x35, 0x0D, 0x35, 0x06, 0x19, 0x01, 0x00, + 0x09, 0x00, 0x13, 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, 0x25, 0x13, + 0x4E, 0x69, 0x6E, 0x74, 0x65, 0x6E, 0x64, 0x6F, 0x20, 0x52, 0x56, 0x4C, 0x2D, + 0x43, 0x4E, 0x54, 0x2D, 0x30, 0x31, 0x09, 0x01, 0x02, 0x00, 0x76 +}; + +static const uint8_t resp2[128] = +{ + 0x05, 0x00, 0x02, 0x00, 0x7B, 0x00, 0x76, 0x01, 0x25, 0x13, 0x4E, 0x69, 0x6E, + 0x74, 0x65, 0x6E, 0x64, 0x6F, 0x20, 0x52, 0x56, 0x4C, 0x2D, 0x43, 0x4E, 0x54, + 0x2D, 0x30, 0x31, 0x09, 0x01, 0x02, 0x25, 0x08, 0x4E, 0x69, 0x6E, 0x74, 0x65, + 0x6E, 0x64, 0x6F, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02, 0x01, 0x09, + 0x01, 0x11, 0x09, 0x02, 0x02, 0x08, 0x04, 0x09, 0x02, 0x03, 0x08, 0x33, 0x09, + 0x02, 0x04, 0x28, 0x00, 0x09, 0x02, 0x05, 0x28, 0x01, 0x09, 0x02, 0x06, 0x35, + 0xDF, 0x35, 0xDD, 0x08, 0x22, 0x25, 0xD9, 0x05, 0x01, 0x09, 0x05, 0xA1, 0x01, + 0x85, 0x10, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x06, 0x00, + 0xFF, 0x09, 0x01, 0x91, 0x00, 0x85, 0x11, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x12, 0x95, 0x02, 0x09, 0x01, 0x91, 0x00, 0x02, 0x00, 0xEC +}; + +static const uint8_t resp3[128] = +{ + 0x05, 0x00, 0x03, 0x00, 0x7B, 0x00, 0x76, 0x85, 0x13, 0x95, 0x01, 0x09, 0x01, + 0x91, 0x00, 0x85, 0x14, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, 0x85, 0x15, 0x95, + 0x01, 0x09, 0x01, 0x91, 0x00, 0x85, 0x16, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x17, 0x95, 0x06, 0x09, 0x01, 0x91, 0x00, 0x85, 0x18, 0x95, 0x15, 0x09, + 0x01, 0x91, 0x00, 0x85, 0x19, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, 0x85, 0x1A, + 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, 0x85, 0x20, 0x95, 0x06, 0x09, 0x01, 0x81, + 0x00, 0x85, 0x21, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, 0x85, 0x22, 0x95, 0x04, + 0x09, 0x01, 0x81, 0x00, 0x85, 0x30, 0x95, 0x02, 0x09, 0x01, 0x81, 0x00, 0x85, + 0x31, 0x95, 0x05, 0x09, 0x01, 0x81, 0x00, 0x85, 0x32, 0x95, 0x0A, 0x09, 0x01, + 0x81, 0x00, 0x85, 0x33, 0x95, 0x11, 0x09, 0x01, 0x02, 0x01, 0x62 +}; + +static const uint8_t resp4[117] = +{ + 0x05, 0x00, 0x04, 0x00, 0x70, 0x00, 0x6D, 0x81, 0x00, 0x85, 0x34, 0x95, 0x15, + 0x09, 0x01, 0x81, 0x00, 0x85, 0x35, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, 0x85, + 0x36, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, 0x85, 0x37, 0x95, 0x15, 0x09, 0x01, + 0x81, 0x00, 0x85, 0x3D, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, 0x85, 0x3E, 0x95, + 0x15, 0x09, 0x01, 0x81, 0x00, 0x85, 0x3F, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0xC0, 0x09, 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09, 0x04, 0x09, 0x09, 0x01, + 0x00, 0x09, 0x02, 0x08, 0x28, 0x00, 0x09, 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, + 0x0A, 0x28, 0x01, 0x09, 0x02, 0x0B, 0x09, 0x01, 0x00, 0x09, 0x02, 0x0C, 0x09, + 0x0C, 0x80, 0x09, 0x02, 0x0D, 0x28, 0x00, 0x09, 0x02, 0x0E, 0x28, 0x00, 0x00 +}; + + +static const uint8_t wiimote_report_descriptor[] = { +0x05, 0x01, // Usage Page (Generic Desktop Ctrls) +0x09, 0x05, // Usage (Game Pad) +0xA1, 0x01, // Collection (Application) +0x85, 0x10, // Report ID (16) +0x15, 0x00, // Logical Minimum (0) +0x26, 0xFF, 0x00, // Logical Maximum (255) +0x75, 0x08, // Report Size (8) +0x95, 0x01, // Report Count (1) +0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x11, // Report ID (17) +0x75, 0x08, // Report Size (8) +0x95, 0x01, // Report Count (1) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x12, // Report ID (18) +0x75, 0x08, // Report Size (8) +0x95, 0x02, // Report Count (2) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x13, // Report ID (19) +0x75, 0x08, // Report Size (8) +0x95, 0x01, // Report Count (1) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x14, // Report ID (20) +0x75, 0x08, // Report Size (8) +0x95, 0x01, // Report Count (1) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x15, // Report ID (21) +0x75, 0x08, // Report Size (8) +0x95, 0x01, // Report Count (1) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x16, // Report ID (22) +0x75, 0x08, // Report Size (8) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x17, // Report ID (23) +//0x95, 0x06, // Report Count (6) +0x75, 0x08, // Report Size (8) +0x95, 0x06, // Report Count (6) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x18, // Report ID (24) +0x75, 0x08, // Report Size (8) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x19, // Report ID (25) +0x75, 0x08, // Report Size (8) +0x95, 0x01, // Report Count (1) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x1A, // Report ID (26) +0x75, 0x08, // Report Size (8) +0x95, 0x01, // Report Count (1) +0x09, 0x01, // Usage (0x01) +0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) +0x85, 0x20, // Report ID (32) +0x95, 0x06, // Report Count (6) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x21, // Report ID (33) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x22, // Report ID (34) +0x95, 0x04, // Report Count (4) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x30, // Report ID (48) +0x95, 0x02, // Report Count (2) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x31, // Report ID (49) +0x95, 0x05, // Report Count (5) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x32, // Report ID (50) +0x95, 0x0A, // Report Count (10) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x33, // Report ID (51) +0x95, 0x11, // Report Count (17) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x34, // Report ID (52) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x35, // Report ID (53) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x36, // Report ID (54) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x37, // Report ID (55) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x3D, // Report ID (61) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x3E, // Report ID (62) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0x85, 0x3F, // Report ID (63) +0x95, 0x15, // Report Count (21) +0x09, 0x01, // Usage (0x01) +0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) +0xC0, // End Collection +0x00 // Unknown (bTag: 0x00, bType: 0x00) +}; diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/vector_math.h b/Firmware/RP2040/src/Wii/wiimote-lib/vector_math.h new file mode 100644 index 00000000..87138e3a --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/vector_math.h @@ -0,0 +1,263 @@ +#ifndef VECTOR_MATH_H +#define VECTOR_MATH_H + +#include + +//for debug/printing functions +#include + +typedef struct +{ + double x; + double y; + double z; +} vec3; + +typedef struct +{ + double x; + double y; + double z; + double w; +} vec4; + +typedef struct +{ + vec3 v0; + vec3 v1; + vec3 v2; +} mat3; + +typedef struct +{ + vec4 v0; + vec4 v1; + vec4 v2; + vec4 v3; +} mat4; + +double vec3_len(const vec3 * vec) +{ + return sqrt(vec->x * vec->x + vec->y * vec->y + vec->z * vec->z); +} + +void vec3_normalize(vec3 * vec) +{ + double len = vec3_len(vec); + vec->x /= len; + vec->y /= len; + vec->z /= len; +} + +void vec3_cross(vec3 * out, const vec3 * first, const vec3 * second) +{ + out->x = first->y * second->z - first->z * second->y; + out->y = first->z * second->x - first->x * second->z; + out->z = first->x * second->y - first->y * second->x; +} + +void mat4_make_translation(mat4 * mat, const vec3 * translate) +{ + mat->v0 = (vec4){ 1.0, 0.0, 0.0, 0.0 }; + mat->v1 = (vec4){ 0.0, 1.0, 0.0, 0.0 }; + mat->v2 = (vec4){ 0.0, 0.0, 1.0, 0.0 }; + mat->v3 = (vec4){ translate->x, translate->y, translate->z, 1.0 }; +} + +void mat4_mult(mat4 * a, const mat4 * b) +{ + double a11 = a->v0.x, a12 = a->v1.x, a13 = a->v2.x, a14 = a->v3.x; + double a21 = a->v0.y, a22 = a->v1.y, a23 = a->v2.y, a24 = a->v3.y; + double a31 = a->v0.z, a32 = a->v1.z, a33 = a->v2.z, a34 = a->v3.z; + double a41 = a->v0.w, a42 = a->v1.w, a43 = a->v2.w, a44 = a->v3.w; + + double b11 = b->v0.x, b12 = b->v1.x, b13 = b->v2.x, b14 = b->v3.x; + double b21 = b->v0.y, b22 = b->v1.y, b23 = b->v2.y, b24 = b->v3.y; + double b31 = b->v0.z, b32 = b->v1.z, b33 = b->v2.z, b34 = b->v3.z; + double b41 = b->v0.w, b42 = b->v1.w, b43 = b->v2.w, b44 = b->v3.w; + + a->v0.x = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; + a->v1.x = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; + a->v2.x = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; + a->v3.x = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + + a->v0.y = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; + a->v1.y = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; + a->v2.y = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; + a->v3.y = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + + a->v0.z = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; + a->v1.z = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; + a->v2.z = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; + a->v3.z = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + + a->v0.w = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; + a->v1.w = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; + a->v2.w = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; + a->v3.w = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; +} + +void mat4_invert(mat4 * m) +{ + double n11 = m->v0.x, n21 = m->v0.y, n31 = m->v0.z, n41 = m->v0.w, + n12 = m->v1.x, n22 = m->v1.y, n32 = m->v1.z, n42 = m->v1.w, + n13 = m->v2.x, n23 = m->v2.y, n33 = m->v2.z, n43 = m->v2.w, + n14 = m->v3.x, n24 = m->v3.y, n34 = m->v3.z, n44 = m->v3.w; + + double t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44; + double t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44; + double t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44; + double t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + + double det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; + + if (det == 0) + { + return; + } + + double detInv = 1 / det; + + m->v0.x = t11 * detInv; + m->v0.y = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv; + m->v0.z = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv; + m->v0.w = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv; + + m->v1.x = t12 * detInv; + m->v1.y = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv; + m->v1.z = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv; + m->v1.w = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv; + + m->v2.x = t13 * detInv; + m->v2.y = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv; + m->v2.z = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv; + m->v2.w = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv; + + m->v3.x = t14 * detInv; + m->v3.y = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv; + m->v3.z = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv; + m->v3.w = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv; +} + +void vec4_apply_mat4(vec4 * vec, const mat4 * mat) +{ + double x = vec->x, y = vec->y, z = vec->z, w = vec->w; + + vec->x = mat->v0.x * x + mat->v1.x * y + mat->v2.x * z + mat->v3.x * w; + vec->y = mat->v0.y * x + mat->v1.y * y + mat->v2.y * z + mat->v3.y * w; + vec->z = mat->v0.z * x + mat->v1.z * y + mat->v2.z * z + mat->v3.z * w; + vec->w = mat->v0.w * x + mat->v1.w * y + mat->v2.w * z + mat->v3.w * w; +} + +void vec3_apply_mat3(vec3 * vec, const mat3 * mat) +{ + double x = vec->x, y = vec->y, z = vec->z; + + vec->x = mat->v0.x * x + mat->v1.x * y + mat->v2.x * z; + vec->y = mat->v0.y * x + mat->v1.y * y + mat->v2.y * z; + vec->z = mat->v0.z * x + mat->v1.z * y + mat->v2.z * z; +} + +void vec4_multiply_scalar(vec4 * vec, double scalar) +{ + vec->x *= scalar; + vec->y *= scalar; + vec->z *= scalar; + vec->w *= scalar; +} + +void vec4_add_scalar(vec4 * vec, double scalar) +{ + vec->x += scalar; + vec->y += scalar; + vec->z += scalar; + vec->w += scalar; +} + +void vec3_multiply_scalar(vec3 * vec, double scalar) +{ + vec->x *= scalar; + vec->y *= scalar; + vec->z *= scalar; +} + +void vec3_add_scalar(vec3 * vec, double scalar) +{ + vec->x += scalar; + vec->y += scalar; + vec->z += scalar; +} + +void mat3_invert(mat3 * m) +{ + double n11 = m->v0.x, n21 = m->v0.y, n31 = m->v0.z, + n12 = m->v1.x, n22 = m->v1.y, n32 = m->v1.z, + n13 = m->v2.x, n23 = m->v2.y, n33 = m->v2.z; + + double t11 = n33 * n22 - n32 * n23; + double t12 = n32 * n13 - n33 * n12; + double t13 = n23 * n12 - n22 * n13; + + double det = n11 * t11 + n21 * t12 + n31 * t13; + + if (det == 0) + { + return; + } + + double detInv = 1 / det; + + m->v0.x = t11 * detInv; + m->v0.y = (n31 * n23 - n33 * n21) * detInv; + m->v0.z = (n32 * n21 - n31 * n22) * detInv; + + m->v1.x = t12 * detInv; + m->v1.y = (n33 * n11 - n31 * n13) * detInv; + m->v1.z = (n31 * n12 - n32 * n11) * detInv; + + m->v2.x = t13 * detInv; + m->v2.y = (n21 * n13 - n23 * n11) * detInv; + m->v2.z = (n22 * n11 - n21 * n12) * detInv; +} + +void mat3_transpose(mat3 * m) +{ + double tmp; + tmp = m->v0.y; m->v0.y = m->v1.x; m->v1.x = tmp; + tmp = m->v0.z; m->v0.z = m->v2.x; m->v2.x = tmp; + tmp = m->v1.z; m->v1.z = m->v2.y; m->v2.y = tmp; +} + +void mat3_from_mat4(mat3 * out, const mat4 * mat) +{ + out->v0 = (vec3){ mat->v0.x, mat->v0.y, mat->v0.z }; + out->v1 = (vec3){ mat->v1.x, mat->v1.y, mat->v1.z }; + out->v2 = (vec3){ mat->v2.x, mat->v2.y, mat->v2.z }; +} + +void vec3_print(const vec3 * vec) +{ + printf("%f %f %f\n", vec->x, vec->y, vec->z); +} + +void vec4_print(const vec4 * vec) +{ + printf("%f %f %f %f\n", vec->x, vec->y, vec->z, vec->w); +} + +void mat3_print(const mat3 * mat) +{ + printf("%f %f %f\n", mat->v0.x, mat->v1.x, mat->v2.x); + printf("%f %f %f\n", mat->v0.y, mat->v1.y, mat->v2.y); + printf("%f %f %f\n", mat->v0.z, mat->v1.z, mat->v2.z); +} + +void mat4_print(const mat4 * mat) +{ + printf("%f %f %f %f\n", mat->v0.x, mat->v1.x, mat->v2.x, mat->v3.x); + printf("%f %f %f %f\n", mat->v0.y, mat->v1.y, mat->v2.y, mat->v3.y); + printf("%f %f %f %f\n", mat->v0.z, mat->v1.z, mat->v2.z, mat->v3.z); + printf("%f %f %f %f\n", mat->v0.w, mat->v1.w, mat->v2.w, mat->v3.w); +} + +#endif diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wiimote.c b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote.c new file mode 100644 index 00000000..b220a710 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote.c @@ -0,0 +1,860 @@ +#include +#include +#include + +#include "inet.h" +#include "wiimote.h" +#include "wm_reports.h" +#include "eeprom.bin.h" + +static uint8_t *eeprom_bin; +int tries = 0; + +static uint8_t classic_calibration[16] = +{ + // 0xF8, 0x04, 0x7A, 0xF8, 0x04, 0x7A, 0xF8, 0x04, 0x7A, 0xF8, 0x04, 0x7A, 0x00, 0x00, 0x00, 0x00 + 0xE1, 0x19, 0x7C, 0xEF, 0x22, 0x7C, 0xE6, 0x1E, 0x85, 0xDE, 0x15, 0x8B, 0x0E, 0x22, 0x8F, 0xE4 +}; + +static uint8_t nunchuk_calibration[16] = +{ + 0x81, 0x80, 0x7F, 0x22, 0xB5, 0xB3, 0xB3, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x83, 0x14, 0x69 +}; + +int process_report(struct wiimote_state *state, const uint8_t * buf, int len) +{ + struct report_data * data = (struct report_data *)buf; + + //every output report contains rumble info + state->sys.rumble = data->buf[0] & 0x01; + + switch (data->type) + { + case 0x11: //player LEDs + { + struct report_leds * rpt = (struct report_leds *)data->buf; + + state->sys.led_1 = rpt->led_1; + state->sys.led_2 = rpt->led_2; + state->sys.led_3 = rpt->led_3; + state->sys.led_4 = rpt->led_4; + + report_queue_push_ack(state, data->type, 0x00); + break; + } + case 0x12: //data reporting mode + { + struct report_mode * rpt = (struct report_mode *)data->buf; + + state->sys.reporting_continuous = rpt->continuous; + state->sys.reporting_mode = rpt->mode; + + report_queue_push_ack(state, data->type, 0x00); + break; + } + case 0x13: + case 0x1a: //ir camera enable + { + struct report_ir_enable * rpt = (struct report_ir_enable *)data->buf; + + state->sys.ircam_enabled = rpt->enabled; + + report_queue_push_ack(state, data->type, 0x00); + break; + } + case 0x14: + case 0x19: //speaker enable + { + struct report_speaker_enable * rpt = (struct report_speaker_enable *)data->buf; + + state->sys.speaker_enabled = !rpt->muted; + + report_queue_push_ack(state, data->type, 0x00); + break; + } + case 0x15: //status information request + //send a status report 0x20 + report_queue_push_status(state); + break; + case 0x16: //write memory + { + struct report_mem_write * rpt = (struct report_mem_write *)data->buf; + + if (rpt->source0 || rpt->source1) + { + write_register(state, ntohl(OFFSET24(rpt->offset)), rpt->size, rpt->data); + } + else + { + write_eeprom(state, ntohl(OFFSET24(rpt->offset)), rpt->size, rpt->data); + } + break; + } + case 0x17: //read memory + { + struct report_mem_read * rpt = (struct report_mem_read *)data->buf; + + if (rpt->source0 || rpt->source1) + { + read_register(state, ntohl(OFFSET24(rpt->offset)), ntohs(rpt->size)); + } + else + { + read_eeprom(state, ntohl(OFFSET24(rpt->offset)), ntohs(rpt->size)); + } + + break; + } + } + + return 0; +} + +int generate_report(struct wiimote_state * state, uint8_t * buf) +{ + int len; + + struct report_data * data = (struct report_data *)buf; + uint8_t * contents; + + if (state->usr.connected_extension_type != state->sys.connected_extension_type) + { + if (state->sys.extension_connected) + { + state->sys.extension_connected = 0; + state->sys.connected_extension_type = NoExtension; + state->sys.extension_hotplug_timer = 30; + report_queue_push_status(state); + } + + bool extension_connected = (state->usr.connected_extension_type != NoExtension); + if (extension_connected && --state->sys.extension_hotplug_timer <= 0) + { + state->sys.extension_connected = extension_connected; + state->sys.connected_extension_type = state->usr.connected_extension_type; + report_queue_push_status(state); + init_extension(state); + } + } + + if (!state->sys.reporting_continuous && !state->sys.report_changed && state->sys.queue == NULL) + return 0; + + if (state->sys.queue == NULL) + { + //regular report + memset(data, 0, sizeof(struct report_data)); + len = 2; + data->io = 0xa1; + data->type = state->sys.reporting_mode; + } + else + { + //queued report (acknowledgement, response, etc) + struct report * rpt; + rpt = report_queue_peek(state); + len = rpt->len; + memcpy(data, &rpt->data, sizeof(struct report_data)); + report_queue_pop(state); + } + + contents = data->buf; + + //fill report + switch (data->type) + { + case 0x30: // core buttons + report_append_buttons(state, contents); + len += 2; + break; + case 0x31: // core buttons + accelerometer + report_append_buttons(state, contents); + report_append_accelerometer(state, contents); + len += 2 + 3; + break; + case 0x32: // core buttons + 8 extension bytes + report_append_buttons(state, contents); + len += 2 + 8; + break; + case 0x33: // core buttons + accelerometer + 12 ir bytes + report_append_buttons(state, contents); + report_append_accelerometer(state, contents); + report_append_ir_12(state, contents + 5); + len += 2 + 3 + 12; + break; + case 0x34: // core buttons + 19 extension bytes + report_append_buttons(state, contents); + report_append_extension(state, contents + 2, 19); + len += 2 + 19; + break; + case 0x35: // core buttons + accelerometer + 16 extension bytes + report_append_buttons(state, contents); + report_append_accelerometer(state, contents); + report_append_extension(state, contents + 5, 16); + len += 2 + 3 + 16; + break; + case 0x36: // core buttons + 10 ir bytes + 9 extension bytes + report_append_buttons(state, contents); + report_append_ir_10(state, contents + 2); + report_append_extension(state, contents + 12, 9); + len += 2 + 10 + 9; + break; + case 0x37: // core buttons + accelerometer + 10 ir bytes + 6 extension bytes + report_append_buttons(state, contents); + report_append_accelerometer(state, contents); + report_append_ir_10(state, contents + 5); + report_append_extension(state, contents + 15, 6); + len += 2 + 3 + 10 + 6; + break; + case 0x3d: // 21 extension bytes + report_append_extension(state, contents, 21); + len += 21; + break; + case 0x3e: // interleaved core buttons + accelerometer with 36 ir bytes pt I + case 0x3f: // interleaved core buttons + accelerometer with 36 ir bytes pt II + report_append_buttons(state, contents); + report_append_interleaved(state, contents); + len += 21; + break; + default: // special output report (acknowledgement, status, or memory read) + report_append_buttons(state, contents); + break; + } + + return len; +} + +void read_eeprom(struct wiimote_state * state, uint32_t offset, uint16_t size) +{ + uint8_t *file; + uint8_t *buffer; + struct report * rpt; + int i; + + offset = offset & 0xFFFF; + + //addresses greater than 0x16FF cannot be read or written + if (offset + size > 0x16FF) + { + rpt = report_queue_push(state); + report_format_mem_resp(state, rpt, 0x10, 0x8, offset, NULL, false); + return; + } + + //fseek + file = &eeprom_bin[0 + offset]; + + buffer = (uint8_t *)malloc(size); + if (!buffer) + { + return; + } + + //fread + memcpy(buffer, file, size); + + //equivalent to ceil(size / 0x10) + int total_packets = (size + 0x10 - 1) / 0x10; + + //allocate all the needed reports + for (i = 0; i < total_packets; i++) + { + report_queue_push(state); + } + + //copy packet data + struct queued_report * queue_item = state->sys.queue; + + for (i = 0; i < total_packets; i++) + { + rpt = &queue_item->rpt; + int packet_size = (i == total_packets - 1) ? (size - i * 0x10) : 0x10; + report_format_mem_resp(state, rpt, packet_size, 0x0, offset + i*0x10, &buffer[i*0x10], false); + queue_item = queue_item->next; + } + + free(buffer); +} + +void write_eeprom(struct wiimote_state * state, uint32_t offset, uint8_t size, const uint8_t * buf) +{ + uint8_t *file; + struct report * rpt; + + offset = offset & 0xFFFF; + + //addresses greater than 0x16FF cannot be read or written + if (offset + size > 0x16FF) + { + rpt = report_queue_push(state); + report_format_mem_resp(state, rpt, 0x10, 0x8, offset, NULL, false); + return; + } + + //fseek + file = &eeprom_bin[0 + offset]; + + //fwrite + memcpy(file, buf, size); + report_queue_push_ack(state, 0x16, 0x00); +} + +void read_register(struct wiimote_state *state, uint32_t offset, uint16_t size) +{ + uint8_t * buffer; + struct report * rpt; + int i; + bool encrypt = false; + + switch ((offset >> 16) & 0xfe) //select register, ignore lsb + { + case 0xa2: //speaker + buffer = state->sys.register_a2 + (offset & 0xff); + break; + case 0xa4: //extension + if (state->sys.wmp_state == 1) + { + //i guess this isn't needed after all + //^^this is an old comment, so is this needed or not? + if (((offset & 0xff) == 0xf6) || ((offset & 0xff) == 0xf7)) + { + tries += 1; + printf("%d \n", tries); + if (tries == 5) + { + state->sys.register_a6[0xf7] = 0x0e; + } + } + + buffer = state->sys.register_a6 + (offset & 0xff); + } + else + { + buffer = state->sys.register_a4 + (offset & 0xff); + } + + if (state->sys.extension_encrypted) + { + encrypt = true; + } + + break; + case 0xa6: //motionplus + if (state->sys.wmp_state == 1) + { + rpt = report_queue_push(state); + report_format_mem_resp(state, rpt, 0x10, 0x7, offset, NULL, false); + return; + } + buffer = state->sys.register_a6 + (offset & 0xff); + break; + case 0xb0: //ir camera + buffer = state->sys.register_b0 + (offset & 0xff); + break; + default: //??? + break; + } + + //equivalent to ceil(size / 0x10) + int total_packets = (size + 0x10 - 1) / 0x10; + + //allocate all the needed reports + for (i = 0; i < total_packets; i++) + { + report_queue_push(state); + } + + struct queued_report * queue_item = state->sys.queue; + + for (i = 0; i < total_packets; i++) + { + rpt = &queue_item->rpt; + int packet_size = (i == total_packets - 1) ? (size - i * 0x10) : 0x10; + report_format_mem_resp(state, rpt, packet_size, 0x0, offset + i*0x10, &buffer[i*0x10], encrypt); + queue_item = queue_item->next; + } +} + +void write_register(struct wiimote_state *state, uint32_t offset, uint8_t size, const uint8_t * buf) +{ + uint8_t * reg; + int result = 0x00; + + switch ((offset >> 16) & 0xfe) //select register, ignore lsb + { + case 0xa2: //speaker + reg = state->sys.register_a2; + memcpy(reg + (offset & 0xff), buf, size); + break; + case 0xa4: //extension + reg = (state->sys.wmp_state == 1) ? state->sys.register_a6 : state->sys.register_a4; + + memcpy(reg + (offset & 0xff), buf, size); + + //TODO: double check what this does, the buf location it's looking for + if (((offset & 0xff) == 0xf0) && (buf[0] == 0x55) && (state->sys.wmp_state == 1)) //deactivate wmp + { + state->sys.wmp_state = 3; + + init_extension(state); + + report_queue_push_ack(state, 0x16, 0x00); + state->sys.extension_connected = 0; + report_queue_push_status(state); + state->sys.extension_connected = 1; + report_queue_push_status(state); + return; + } + else if (((offset & 0xff) == 0xfe) && (buf[0] == 0x00) && (state->sys.wmp_state == 1)) //also deactivate wmp? + { + state->sys.wmp_state = 0; + + init_extension(state); + + report_queue_push_ack(state, 0x16, 0x00); + state->sys.extension_connected = 0; + report_queue_push_status(state); + state->sys.extension_connected = 1; + report_queue_push_status(state); + return; + } + else if ((offset & 0xff) == 0x4c) //last part of encryption code + { + ext_generate_tables(&state->sys.extension_crypto_state, ®[0x40]); + state->sys.extension_encrypted = 1; + } + else if ((offset & 0xff) == 0xf0) + { + if (buf[0] == 0xaa) + { + state->sys.extension_encrypted = 1; + } + else if (buf[0] == 0x55) + { + state->sys.extension_encrypted = 0; + } + } + else if ((offset & 0xff) == 0xf1) + { + state->sys.register_a6[0xf7] = 0x1a; + + //idk why or how, but sometimes this must be updated + state->sys.register_a6[0x50] = 0xe7; + state->sys.register_a6[0x51] = 0x98; + state->sys.register_a6[0x52] = 0x31; + state->sys.register_a6[0x53] = 0x8a; + state->sys.register_a6[0x54] = 0x18; + state->sys.register_a6[0x55] = 0x82; + state->sys.register_a6[0x56] = 0x37; + state->sys.register_a6[0x57] = 0x5e; + state->sys.register_a6[0x58] = 0x02; + state->sys.register_a6[0x59] = 0x4f; + state->sys.register_a6[0x5a] = 0x68; + state->sys.register_a6[0x5b] = 0x47; + state->sys.register_a6[0x5c] = 0x78; + state->sys.register_a6[0x5d] = 0xef; + state->sys.register_a6[0x5e] = 0xbb; + state->sys.register_a6[0x5f] = 0xd7; + + state->sys.register_a6[0x60] = 0x86; + state->sys.register_a6[0x61] = 0xc8; + state->sys.register_a6[0x62] = 0x95; + state->sys.register_a6[0x63] = 0xbd; + state->sys.register_a6[0x64] = 0x20; + state->sys.register_a6[0x65] = 0x9b; + state->sys.register_a6[0x66] = 0xeb; + state->sys.register_a6[0x67] = 0x8b; + state->sys.register_a6[0x68] = 0x79; + state->sys.register_a6[0x69] = 0x81; + state->sys.register_a6[0x6a] = 0xdc; + state->sys.register_a6[0x6b] = 0x61; + state->sys.register_a6[0x6c] = 0x13; + state->sys.register_a6[0x6d] = 0x54; + state->sys.register_a6[0x6e] = 0x79; + state->sys.register_a6[0x6f] = 0x4c; + + state->sys.register_a6[0x70] = 0xb7; + state->sys.register_a6[0x71] = 0x26; + state->sys.register_a6[0x72] = 0x82; + state->sys.register_a6[0x73] = 0x17; + state->sys.register_a6[0x74] = 0xe8; + state->sys.register_a6[0x75] = 0x0f; + state->sys.register_a6[0x76] = 0xa9; + state->sys.register_a6[0x77] = 0xb5; + state->sys.register_a6[0x78] = 0x45; + state->sys.register_a6[0x79] = 0xa0; + state->sys.register_a6[0x7a] = 0x38; + state->sys.register_a6[0x7b] = 0x8e; + state->sys.register_a6[0x7c] = 0x9e; + state->sys.register_a6[0x7d] = 0x86; + state->sys.register_a6[0x7e] = 0x72; + state->sys.register_a6[0x7f] = 0x55; + + state->sys.register_a6[0x80] = 0x3d; + state->sys.register_a6[0x81] = 0x46; + state->sys.register_a6[0x82] = 0x2e; + state->sys.register_a6[0x83] = 0x3e; + state->sys.register_a6[0x84] = 0x10; + state->sys.register_a6[0x85] = 0x1f; + state->sys.register_a6[0x86] = 0x8e; + state->sys.register_a6[0x87] = 0x0c; + state->sys.register_a6[0x88] = 0xf4; + state->sys.register_a6[0x89] = 0x04; + state->sys.register_a6[0x8a] = 0x89; + state->sys.register_a6[0x8b] = 0x4c; + state->sys.register_a6[0x8c] = 0xca; + state->sys.register_a6[0x8d] = 0x3e; + state->sys.register_a6[0x8e] = 0x9f; + state->sys.register_a6[0x8f] = 0x36; + } + + break; + case 0xa6: //motionplus + reg = state->sys.register_a6; + memcpy(reg + (offset & 0xff), buf, size); + + if (((offset & 0xff) == 0xfe) && ((buf[0] >> 2) & 0x1)) //activate wmp + { + state->sys.wmp_state = 1; + state->sys.extension_report_type = (buf[0] & 0x7); + printf("activate wmp\n"); + + init_extension(state); + + report_queue_push_ack(state, 0x16, 0x00); + state->sys.extension_connected = 0; + report_queue_push_status(state); + state->sys.extension_connected = 1; + report_queue_push_status(state); + return; + } + + break; + case 0xb0: //ir camera + reg = state->sys.register_b0; + memcpy(reg + (offset & 0xff), buf, size); + break; + default: //??? + break; + } + + report_queue_push_ack(state, 0x16, result); +} + +void reset_ir_object(struct wiimote_ir_object * ir_object) +{ + memset(ir_object, 0xff, sizeof(struct wiimote_ir_object)); +} + +void reset_input_ir(struct wiimote_ir_object ir_object[4]) +{ + memset(ir_object, 0xff, sizeof(struct wiimote_ir_object) * 4); +} + +void reset_input_nunchuk(struct wiimote_nunchuk * nunchuk) +{ + memset(nunchuk, 0, sizeof(struct wiimote_nunchuk)); + + nunchuk->x = 128; + nunchuk->y = 128; + nunchuk->accel_x = 512; + nunchuk->accel_y = 512; + nunchuk->accel_z = 760; +} + +void reset_input_classic(struct wiimote_classic * classic) +{ + memset(classic, 0, sizeof(struct wiimote_classic)); + + classic->ls_x = 32; + classic->ls_y = 32; + classic->rs_x = 15; + classic->rs_y = 15; +} + +void reset_input_motionplus(struct wiimote_motionplus * motionplus) +{ + memset(motionplus, 0, sizeof(struct wiimote_motionplus)); + + motionplus->yaw_down = 0x1F7F; + motionplus->roll_left = 0x1F7F; + motionplus->pitch_left = 0x1F7F; + motionplus->yaw_slow = 1; + motionplus->roll_slow = 1; + motionplus->pitch_slow = 1; +} + +void init_extension(struct wiimote_state * state) +{ + if (state->sys.connected_extension_type == NoExtension) + { + memset(state->sys.register_a4, 0xff, sizeof(state->sys.register_a4)); + } + else + { + memset(state->sys.register_a4, 0, sizeof(state->sys.register_a4)); + } + + if (state->sys.wmp_state == 1) + { + //register_a6[0xfa] = 0x00; + //register_a6[0xfb] = 0x00; + //register_a6[0xfc] = 0xa4; + //register_a6[0xfd] = 0x20; + //this might not be needed now that memory is proper + //register_a6[0xfe] = state->sys.extension_report_type; + //register_a6[0xff] = 0x05; + state->sys.register_a6[0xfc] = 0xa4; + + state->sys.extension_encrypted = 0; + + //random guess, pulled from wiimote, not sure what this is for + state->sys.register_a6[0xf0] = 0x55; + state->sys.register_a6[0xf1] = 0xff; + state->sys.register_a6[0xf2] = 0xff; + state->sys.register_a6[0xf3] = 0xff; + state->sys.register_a6[0xf4] = 0xff; + state->sys.register_a6[0xf5] = 0xff; + state->sys.register_a6[0xf6] = 0x00; + + //a4 40 post init + // state->sys.register_a6[0x40] = 0x81; + // state->sys.register_a6[0x41] = 0x80; + // state->sys.register_a6[0x42] = 0x80; + // state->sys.register_a6[0x43] = 0x28; + // state->sys.register_a6[0x44] = 0xb4; + // state->sys.register_a6[0x45] = 0xb3; + // state->sys.register_a6[0x46] = 0xb3; + // state->sys.register_a6[0x47] = 0x26; + // state->sys.register_a6[0x48] = 0xe3; + // state->sys.register_a6[0x49] = 0x22; + // state->sys.register_a6[0x4a] = 0x7a; + // state->sys.register_a6[0x4b] = 0xd8; + // state->sys.register_a6[0x4c] = 0x1b; + // state->sys.register_a6[0x4d] = 0x81; + // state->sys.register_a6[0x4e] = 0x31; + // state->sys.register_a6[0x4f] = 0x86; + + state->sys.register_a6[0x20] = 0x7c; + state->sys.register_a6[0x21] = 0x97; + state->sys.register_a6[0x22] = 0x7f; + state->sys.register_a6[0x23] = 0x0a; + state->sys.register_a6[0x24] = 0x7c; + state->sys.register_a6[0x25] = 0xa8; + state->sys.register_a6[0x26] = 0x33; + state->sys.register_a6[0x27] = 0xb7; + state->sys.register_a6[0x28] = 0xcc; + state->sys.register_a6[0x29] = 0x12; + state->sys.register_a6[0x2a] = 0x33; + state->sys.register_a6[0x2b] = 0x08; + state->sys.register_a6[0x2c] = 0xc8; + state->sys.register_a6[0x2d] = 0x01; + state->sys.register_a6[0x2e] = 0x72; + state->sys.register_a6[0x2f] = 0xd4; + + state->sys.register_a6[0x30] = 0x7c; + state->sys.register_a6[0x31] = 0x53; + state->sys.register_a6[0x32] = 0x87; + state->sys.register_a6[0x33] = 0x58; + state->sys.register_a6[0x34] = 0x7c; + state->sys.register_a6[0x35] = 0x9f; + state->sys.register_a6[0x36] = 0x36; + state->sys.register_a6[0x37] = 0xb2; + state->sys.register_a6[0x38] = 0xc9; + state->sys.register_a6[0x39] = 0x34; + state->sys.register_a6[0x3a] = 0x35; + state->sys.register_a6[0x3b] = 0xf8; + state->sys.register_a6[0x3c] = 0x2d; + state->sys.register_a6[0x3d] = 0x60; + state->sys.register_a6[0x3e] = 0xd7; + state->sys.register_a6[0x3f] = 0xd5; + + //not sure block, this may not be needed + state->sys.register_a6[0x50] = 0x15; + state->sys.register_a6[0x51] = 0x6d; + state->sys.register_a6[0x52] = 0xe0; + state->sys.register_a6[0x53] = 0x23; + state->sys.register_a6[0x54] = 0x20; + state->sys.register_a6[0x55] = 0x79; + state->sys.register_a6[0x56] = 0xd3; + state->sys.register_a6[0x57] = 0x73; + state->sys.register_a6[0x58] = 0x01; + state->sys.register_a6[0x59] = 0xa9; + state->sys.register_a6[0x5a] = 0xf0; + state->sys.register_a6[0x5b] = 0x25; + state->sys.register_a6[0x5c] = 0xb0; + state->sys.register_a6[0x5d] = 0xbc; + state->sys.register_a6[0x5e] = 0xff; + state->sys.register_a6[0x5f] = 0xe1; + + state->sys.register_a6[0x60] = 0xd8; + state->sys.register_a6[0x61] = 0x3f; + state->sys.register_a6[0x62] = 0x82; + state->sys.register_a6[0x63] = 0x52; + state->sys.register_a6[0x64] = 0x75; + state->sys.register_a6[0x65] = 0x99; + state->sys.register_a6[0x66] = 0xbe; + state->sys.register_a6[0x67] = 0xdb; + state->sys.register_a6[0x68] = 0xcb; + state->sys.register_a6[0x69] = 0x61; + state->sys.register_a6[0x6a] = 0x60; + state->sys.register_a6[0x6b] = 0x0f; + state->sys.register_a6[0x6c] = 0x35; + state->sys.register_a6[0x6d] = 0xbd; + state->sys.register_a6[0x6e] = 0xd4; + state->sys.register_a6[0x6f] = 0x4d; + + state->sys.register_a6[0x70] = 0x5c; + state->sys.register_a6[0x71] = 0x9f; + state->sys.register_a6[0x72] = 0x5d; + state->sys.register_a6[0x73] = 0x81; + state->sys.register_a6[0x74] = 0x71; + state->sys.register_a6[0x75] = 0xde; + state->sys.register_a6[0x76] = 0x22; + state->sys.register_a6[0x77] = 0xe6; + state->sys.register_a6[0x78] = 0xb9; + state->sys.register_a6[0x79] = 0x23; + state->sys.register_a6[0x7a] = 0xa4; + state->sys.register_a6[0x7b] = 0x58; + state->sys.register_a6[0x7c] = 0xb7; + state->sys.register_a6[0x7d] = 0x62; + state->sys.register_a6[0x7e] = 0x33; + state->sys.register_a6[0x7f] = 0xa4; + + state->sys.register_a6[0x80] = 0xcd; + state->sys.register_a6[0x81] = 0x8b; + state->sys.register_a6[0x82] = 0x3a; + state->sys.register_a6[0x83] = 0xfe; + state->sys.register_a6[0x84] = 0x98; + state->sys.register_a6[0x85] = 0xf0; + state->sys.register_a6[0x86] = 0xd9; + state->sys.register_a6[0x87] = 0x57; + state->sys.register_a6[0x88] = 0x0c; + state->sys.register_a6[0x89] = 0xe8; + state->sys.register_a6[0x8a] = 0x27; + state->sys.register_a6[0x8b] = 0x51; + state->sys.register_a6[0x8c] = 0xb6; + state->sys.register_a6[0x8d] = 0xea; + state->sys.register_a6[0x8e] = 0xe5; + state->sys.register_a6[0x8f] = 0x78; + + + //init progress byte, set it to done + state->sys.register_a6[0xf7] = 0x0c; + state->sys.register_a6[0xf8] = 0x00; + state->sys.register_a6[0xf9] = 0x00; + } + else + { + //state->sys.register_a6[0xf7] = 0x0c; + + state->sys.register_a6[0xf0] = 0x55; + state->sys.register_a6[0xf1] = 0xff; + state->sys.register_a6[0xf2] = 0xff; + state->sys.register_a6[0xf3] = 0xff; + state->sys.register_a6[0xf4] = 0xff; + state->sys.register_a6[0xf5] = 0xff; + state->sys.register_a6[0xf6] = 0xff; + state->sys.register_a6[0xf7] = 0x02; + state->sys.register_a6[0xf8] = 0xff; + state->sys.register_a6[0xf9] = 0xff; + state->sys.register_a6[0xfa] = 0x01; + state->sys.register_a6[0xfb] = 0x00; + state->sys.register_a6[0xfc] = 0xa6; + state->sys.register_a6[0xfd] = 0x20; + state->sys.register_a6[0xfe] = 0x00; + state->sys.register_a6[0xff] = 0x05; + + if (state->sys.connected_extension_type == NoExtension) + { + return; + } + + memset(&state->sys.register_a4[0xf0], 0x0, 0x10); + + state->sys.register_a4[0xf0] = 0x55; + state->sys.register_a4[0xfc] = 0xa4; + state->sys.register_a4[0xfd] = 0x20; + + switch (state->sys.connected_extension_type) + { + default: + case Nunchuk: + state->sys.register_a4[0xfe] = 0x00; + state->sys.register_a4[0xff] = 0x00; + memcpy(&state->sys.register_a4[0x20], nunchuk_calibration, 0x10); + memcpy(&state->sys.register_a4[0x30], nunchuk_calibration, 0x10); + break; + case Classic: + state->sys.register_a4[0xfe] = 0x01; + state->sys.register_a4[0xff] = 0x01; + memcpy(&state->sys.register_a4[0x20], classic_calibration, 0x10); + memcpy(&state->sys.register_a4[0x30], classic_calibration, 0x10); + break; + case BalanceBoard: + state->sys.register_a4[0xfe] = 0x04; + state->sys.register_a4[0xff] = 0x02; + break; + } + + state->sys.extension_report_type = state->sys.register_a4[0xfe]; + state->sys.extension_type = state->sys.register_a4[0xff]; + } +} + +void wiimote_destroy(struct wiimote_state *state) +{ + while (state->sys.queue != NULL) + { + struct queued_report * rpt = state->sys.queue; + state->sys.queue = rpt->next; + free(rpt); + } +} + +void wiimote_init(struct wiimote_state *state) +{ + + /*INIT EEPROM*/ + //eeprom allocate memory + eeprom_bin = (uint8_t*)malloc(TOTAL_SIZE_EEPROM * sizeof(uint8_t)); + //Copy the first data + memcpy(eeprom_bin, &eeprom_bin_1[0], sizeof(eeprom_bin_1)); + //Copy the last data + memcpy(&eeprom_bin[LAST_DATA_BEGIN_POS], &eeprom_bin_2[0], sizeof(eeprom_bin_2)); + /*INIT EEPROM*/ + + memset(state, 0, sizeof(struct wiimote_state)); + + //flat + state->usr.accel_x = 0x82 << 2; + state->usr.accel_y = 0x82 << 2; + state->usr.accel_z = 0x9f << 2; + + reset_input_ir(state->usr.ir_object); + reset_input_nunchuk(&state->usr.nunchuk); + reset_input_classic(&state->usr.classic); + reset_input_motionplus(&state->usr.motionplus); + + state->usr.connected_extension_type = NoExtension; + + wiimote_reset(state); + + //power on report + struct report * rpt = report_queue_push(state); + rpt->len = 4; + rpt->data.io = 0xa1; + rpt->data.type = 0x30; +} + +void wiimote_reset(struct wiimote_state *state) +{ + memset(&state->sys, 0, sizeof(struct wiimote_state_sys)); + + state->sys.reporting_mode = 0x30; + state->sys.battery_level = 0xff; + + state->sys.connected_extension_type = NoExtension; + + init_extension(state); +} diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wiimote.h b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote.h new file mode 100644 index 00000000..18b49895 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote.h @@ -0,0 +1,229 @@ +#ifndef WIIMOTE_H +#define WIIMOTE_H + +#include +#include +#include "wm_crypto.h" + +enum wiimote_connected_extension_type +{ + Nunchuk = 0x0, + Classic = 0x1, + BalanceBoard = 0x2, + NoExtension = 0xff +}; + +struct wiimote_ir_object +{ + uint16_t x; + uint16_t y; + uint8_t size; + uint8_t xmin; + uint8_t ymin; + uint8_t xmax; + uint8_t ymax; + uint8_t intensity; +}; + +struct wiimote_nunchuk +{ + uint16_t accel_x; + uint16_t accel_y; + uint16_t accel_z; + uint8_t x; + uint8_t y; + bool c; + bool z; +}; + +struct wiimote_classic +{ + bool a; + bool b; + bool x; + bool y; + bool minus; + bool plus; + bool rtrigger; + bool ltrigger; + bool home; + bool rz; + bool lz; + bool up; + bool down; + bool left; + bool right; + uint8_t ls_x; + uint8_t ls_y; + uint8_t rs_x; + uint8_t rs_y; + uint8_t lt; + uint8_t rt; + +}; + +struct wiimote_motionplus +{ + uint16_t yaw_down; + uint16_t roll_left; + uint16_t pitch_left; + bool yaw_slow; + bool roll_slow; + bool pitch_slow; +}; + +struct wiimote_state_usr +{ + bool a; + bool b; + bool minus; + bool plus; + bool home; + bool one; + bool two; + bool up; + bool down; + bool left; + bool right; + + //special buttons + bool sync; + bool power; + + //accelerometer (10 bit range) + //0 acceleration is approximately 0x200 + uint16_t accel_x; + uint16_t accel_y; + uint16_t accel_z; + + struct wiimote_ir_object ir_object[4]; + + enum wiimote_connected_extension_type connected_extension_type; + + struct wiimote_nunchuk nunchuk; + struct wiimote_classic classic; + struct wiimote_motionplus motionplus; +}; + +void reset_ir_object(struct wiimote_ir_object * object); +void reset_input_ir(struct wiimote_ir_object ir_object[4]); +void reset_input_nunchuk(struct wiimote_nunchuk * nunchuk); +void reset_input_classic(struct wiimote_classic * classic); +void reset_input_motionplus(struct wiimote_motionplus * motionplus); + +struct wiimote_state_sys +{ + bool led_1; + bool led_2; + bool led_3; + bool led_4; + + bool rumble; + + bool ircam_enabled; + bool speaker_enabled; + + uint8_t battery_level; + bool low_battery; + + int extension_hotplug_timer; + bool extension_connected; + enum wiimote_connected_extension_type connected_extension_type; + + struct ext_crypto_state extension_crypto_state; + bool extension_report; + bool extension_encrypted; + uint8_t extension_report_type; + uint8_t extension_type; + uint8_t wmp_state; //0 inactive, 1 active, 2 deactivated + + uint8_t reporting_mode; + bool reporting_continuous; + bool report_changed; + + struct queued_report * queue; + struct queued_report * queue_end; + + uint8_t register_a2[10]; //speaker + uint8_t register_a4[256]; //extension + uint8_t register_a6[256]; //wii motion plus + uint8_t register_b0[52]; //ir camera +}; + +struct wiimote_state +{ + struct wiimote_state_sys sys; + struct wiimote_state_usr usr; +}; + +//new adding -> only buttons struture for wiimote +struct wiimote_buttons{ + + bool a; + bool b; + bool minus; + bool plus; + bool home; + bool one; + bool two; + bool up; + bool down; + bool left; + bool right; + + //special buttons + bool sync; + bool power; + + //accelerometer (10 bit range) + //0 acceleration is approximately 0x200 + uint16_t accel_x; + uint16_t accel_y; + uint16_t accel_z; + + //ir + int8_t ir_x; + int8_t ir_y; +}; + +struct wii_console_info{ + uint8_t wii_addr_saved; + uint8_t wii_addr[6]; +}; + +//new adding -> wiimote + classic +typedef struct{ + struct wiimote_buttons wiimote; + struct wiimote_nunchuk nunchuk; + struct wiimote_classic classic; + uint8_t switch_mode; + uint8_t mode; + uint8_t reset_ir; + uint8_t fake_motion; + uint8_t center_accel; + uint8_t sideway; + struct wii_console_info console_info; +}WiimoteReport; + +enum MODE_WIIMOTE{ + NO_EXTENSION = 0xFF, + WIIMOTE_AND_NUNCHUCK = 0x00, + CLASSIC_CONTROLLER = 0x01 +}; + +void wiimote_init(struct wiimote_state *state); +void wiimote_destroy(struct wiimote_state *state); + +void wiimote_reset(struct wiimote_state *state); + +int process_report(struct wiimote_state *state, const uint8_t *buf, int len); +int generate_report(struct wiimote_state * state, uint8_t * buf); + +void read_eeprom(struct wiimote_state * state, uint32_t offset, uint16_t size); +void write_eeprom(struct wiimote_state * state, uint32_t offset, uint8_t size, const uint8_t * buf); +void read_register(struct wiimote_state *state, uint32_t offset, uint16_t size); +void write_register(struct wiimote_state *state, uint32_t offset, uint8_t size, const uint8_t * buf); + +void init_extension(struct wiimote_state *state); + +#endif //WIIMOTE_H diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.c b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.c new file mode 100644 index 00000000..9283a5b9 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.c @@ -0,0 +1,559 @@ +#include "wiimote_btstack.h" +#include +#include +#include "btstack.h" + +#include "sdp_consts.h" +#include "wiimote.h" +#include "motion.h" +#include +#include "pico/flash.h" +#include "utils.h" + +#define SDP_RESPONSE_BUFFER_SIZE (HCI_ACL_PAYLOAD_SIZE-L2CAP_HEADER_SIZE) + +// TAG to store remote device address in TLV +#define TLV_TAG_HIDR ((((uint32_t) 'H') << 24 ) | (((uint32_t) 'I') << 16) | (((uint32_t) 'D') << 8) | 'R') + +// used to store remote device in TLV +static const btstack_tlv_t * btstack_tlv_singleton_impl; +static void * btstack_tlv_singleton_context; +bd_addr_t wii_baddr; +static uint8_t hid_service_buffer[700]; +static uint8_t pnp_service_buffer[200]; +static const char hid_device_name[] = "Nintendo RVL-CNT-01"; +static uint16_t hid_cid; +static struct wiimote_state wiimote; +static uint8_t buf[256]; +static int len; +static btstack_timer_source_t loop_wii; +static btstack_timer_source_t led_state; +void (*callback_led_func[2])(); +int state = -1; +//convert_data +static const double pointer_margin = 0.5; +float pointer_x = 0.5; +float pointer_y = 0.5; +volatile WiimoteReport *input_report; + +static void l2cap_sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +static void input_update_wiimote(); + + +/** + * The default command format always writes 2 IACs, but we only want one + * @param num_current_iac must be 1 + * @param iac_lap + */ +static const hci_cmd_t hci_write_current_iac_lap_one_iac = { + HCI_OPCODE_HCI_WRITE_CURRENT_IAC_LAP_TWO_IACS, "13" +}; + +static btstack_packet_callback_registration_t hci_event_callback_registration; + +static uint16_t sdp_server_l2cap_cid; +static uint16_t sdp_server_response_size; +static uint8_t sdp_response_buffer[SDP_RESPONSE_BUFFER_SIZE]; + + +static void send_data(){ + input_update_wiimote(); + process_report(&wiimote, buf, len); + len = generate_report(&wiimote, buf); + if (len > 0){ + hid_device_send_interrupt_message(hid_cid, &buf[0], len); + } +} + + +static void get_data_wii(uint16_t cid, hid_report_type_t report_type, uint16_t report_id, int report_size, uint8_t * report){ + + UNUSED(cid); + + if(report_type == HID_REPORT_TYPE_OUTPUT){ + buf[0] = 0xA2; + buf[1] = report_id; + memcpy(&buf[2], report, report_size); + len = report_size + 2; + } + +} + +void task_wiimote(struct btstack_timer_source *ts){ + + hid_device_request_can_send_now_event(hid_cid); + + // Restart timer + btstack_run_loop_set_timer(ts, 1); + btstack_run_loop_add_timer(ts); + +} + +static void wiimote_emulator_reset(void) +{ + printf("Resetting...\n"); + + if (sdp_server_l2cap_cid) { + l2cap_disconnect(sdp_server_l2cap_cid); + sdp_server_l2cap_cid = 0; + } + + // Reset buffer data + memset(buf, 0, sizeof(buf)); + len = 0; +} + + +static void sdp_respond(void) +{ + if (!sdp_server_response_size || !sdp_server_l2cap_cid) { + return; + } + + // update state before sending packet + uint16_t size = sdp_server_response_size; + sdp_server_response_size = 0; + l2cap_send(sdp_server_l2cap_cid, sdp_response_buffer, size); + +} + + + +static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t* packet, uint16_t size) +{ + UNUSED(channel); + UNUSED(size); + + static int set_iac_lap = 0; + + uint8_t status; + + // We only care about HCI packets + if (packet_type != HCI_EVENT_PACKET) { + return; + } + + // printf("hci_packet_handler %x\n", hci_event_packet_get_type(packet)); + + switch(hci_event_packet_get_type(packet)) { + case BTSTACK_EVENT_STATE: + // Wait for the stack to enter the initializing state, before setting the IAC LAP + if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) { + set_iac_lap = 1; + btstack_tlv_get_instance(&btstack_tlv_singleton_impl, &btstack_tlv_singleton_context); + // Load last Wii address from TLV for auto-connect (like a real Wiimote) + if (btstack_tlv_singleton_impl && input_report) { + int len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, TLV_TAG_HIDR, + (uint8_t *)input_report->console_info.wii_addr, 6); + if (len == 6) { + input_report->console_info.wii_addr_saved = 1; + printf("Auto-connect: loaded last Wii address from flash\n"); + } + } + } + break; + case HCI_EVENT_COMMAND_COMPLETE: + // Check IAC LAP result + if (hci_event_command_complete_get_command_opcode(packet) == hci_write_current_iac_lap_one_iac.opcode) { + uint8_t status = hci_event_command_complete_get_return_parameters(packet)[0]; + printf("Set IAC LAP: %s\n", (status != ERROR_CODE_SUCCESS) ? "Failed" : "OK"); + memcpy(wii_baddr, (const uint8_t *)input_report->console_info.wii_addr, 6); + // Only initiate connection if we have a saved Wii address (non-zero). Otherwise stay discoverable and let Wii/PC connect to us. + int addr_valid = (wii_baddr[0] | wii_baddr[1] | wii_baddr[2] | wii_baddr[3] | wii_baddr[4] | wii_baddr[5]) != 0; + if (addr_valid) { + hid_device_connect(wii_baddr, &hid_cid); + } else { + printf("No Wii addr saved; discoverable as Nintendo RVL-CNT-01 (press Sync on Wii or pair from PC)\n"); + } + } + break; + case HCI_EVENT_PIN_CODE_REQUEST: + // inform about pin code request + uint8_t pin_code[6]; + hci_event_pin_code_request_get_bd_addr(packet, wii_baddr); + reverse_bd_addr(wii_baddr, pin_code); + //printf_hexdump(pin_code, sizeof(pin_code)); + gap_pin_code_response_binary(wii_baddr, pin_code, sizeof(pin_code)); + break; + case L2CAP_EVENT_CHANNEL_OPENED: { + uint16_t cid = l2cap_event_channel_opened_get_local_cid(packet); + uint8_t status = l2cap_event_channel_opened_get_status(packet); + + if (status == ERROR_CODE_SUCCESS) { + printf("L2CAP channel opened (cid %d)\n", (int)cid); + } else { + if (status == L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_SECURITY) { + // Assume remote has forgotten link key, delete it and try again + printf("Dropping link key due to L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_SECURITY\n"); + bd_addr_t addr; + l2cap_event_channel_opened_get_address(packet, addr); + gap_drop_link_key_for_bd_addr(addr); + gap_disconnect(l2cap_event_channel_opened_get_handle(packet)); + } else { + printf("L2CAP connection failed (cid %d, status 0x%02x)\n", (int)cid, (int)status); + } + } + } + break; + case HCI_EVENT_HID_META: + switch (hci_event_hid_meta_get_subevent_code(packet)){ + case HID_SUBEVENT_CONNECTION_OPENED: + status = hid_subevent_connection_opened_get_status(packet); + if (status != ERROR_CODE_SUCCESS) { + // outgoing connection failed + printf("Connection failed, status 0x%x\n", status); + hid_cid = 0; + // Authentication Failure -> Need to Sync again with the console + if(status == 0x66){ + input_report->console_info.wii_addr_saved = 0; + if (btstack_tlv_singleton_impl) + btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, TLV_TAG_HIDR); + printf("Fail to connect -> Need to Sync again\n"); + } + return; + } + hid_cid = hid_subevent_connection_opened_get_hid_cid(packet); + /* Always get remote address from event (for incoming connection we didn't have it yet) */ + hid_subevent_connection_opened_get_bd_addr(packet, wii_baddr); + printf("Connected to "); + printf_hexdump(wii_baddr, sizeof(wii_baddr)); + /* Update console_info and TLV so next boot we auto-connect to this Wii */ + memcpy((uint8_t *)input_report->console_info.wii_addr, wii_baddr, 6); + input_report->console_info.wii_addr_saved = 1; + flash_safe_execute(save_wii_addr, wii_baddr, 100); + if (btstack_tlv_singleton_impl) + btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, TLV_TAG_HIDR, (const uint8_t *) &wii_baddr, sizeof(bd_addr_t)); + printf("Wii addr saved for auto-connect\n"); + // Remove timer led + btstack_run_loop_remove_timer(&led_state); + // Set the led on + (*callback_led_func[1])(); + // Run wiimote process + btstack_run_loop_set_timer(&loop_wii, 1); + btstack_run_loop_add_timer(&loop_wii); + break; + case HID_SUBEVENT_CONNECTION_CLOSED: + printf("HID Disconnected\n"); + hid_cid = 0; + // Stop wiimote process + btstack_run_loop_remove_timer(&loop_wii); + // Start led timer + btstack_run_loop_set_timer(&led_state, 100); + btstack_run_loop_add_timer(&led_state); + hid_device_connect(wii_baddr, &hid_cid); + break; + case HID_SUBEVENT_CAN_SEND_NOW: + send_data(); + break; + default: + break; + } + break; + default: + break; + } + + // Write IAC LAP when ready + if (set_iac_lap && hci_can_send_command_packet_now()) { + set_iac_lap = 0; + // Limited Inquiry Access Code + hci_send_cmd(&hci_write_current_iac_lap_one_iac, 1, GAP_IAC_LIMITED_INQUIRY); + + // Set device discoverable now, to emit a write scan enable after IAC LAP is set + gap_discoverable_control(1); + + // It's weird but this fix the lag on sticks + gap_set_default_link_policy_settings(LM_LINK_POLICY_ENABLE_SNIFF_MODE); + + // HID Device + hid_device_init(1, sizeof(wiimote_report_descriptor),wiimote_report_descriptor); + + // HID Device report callback + hid_device_register_report_data_callback(&get_data_wii); + } +} + + +static void l2cap_sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +{ + // printf("sdp_packet_handler %x\n", packet_type); + + switch (packet_type) { + case L2CAP_DATA_PACKET: { + + uint16_t transaction_id = big_endian_read_16(packet, 1); + + //printf("SDP Request: type %u, transaction id %u, len %u, mtu %u\n", pdu_id, transaction_id, param_len, remote_mtu); + + //use the transaction id to determine the response to send + state = transaction_id; + + if (state >= 0){ + switch (state) { + case 0: + sdp_server_response_size = sizeof(resp0); + memcpy(sdp_response_buffer, resp0, sizeof(resp0)); + break; + case 1: + sdp_server_response_size = sizeof(resp1); + memcpy(sdp_response_buffer, resp1, sizeof(resp1)); + break; + case 2: + sdp_server_response_size = sizeof(resp2); + memcpy(sdp_response_buffer, resp2, sizeof(resp2)); + break; + case 3: + sdp_server_response_size = sizeof(resp3); + memcpy(sdp_response_buffer, resp3, sizeof(resp3)); + break; + case 4: + sdp_server_response_size = sizeof(resp4); + memcpy(sdp_response_buffer, resp4, sizeof(resp4)); + break; + default: + break; + } + } + + if (!sdp_server_response_size) { + break; + } + + l2cap_request_can_send_now_event(sdp_server_l2cap_cid); + break; + } + + case HCI_EVENT_PACKET: + switch (hci_event_packet_get_type(packet)) { + case L2CAP_EVENT_INCOMING_CONNECTION: + if (sdp_server_l2cap_cid) { + // Just reject other incoming connections + l2cap_decline_connection(channel); + break; + } + + // Accept connection + sdp_server_l2cap_cid = channel; + sdp_server_response_size = 0; + l2cap_accept_connection(sdp_server_l2cap_cid); + break; + case L2CAP_EVENT_CHANNEL_OPENED: + // Reset if open failed + if (packet[2]) { + wiimote_emulator_reset(); + } + break; + case L2CAP_EVENT_CAN_SEND_NOW: + sdp_respond(); + break; + case L2CAP_EVENT_CHANNEL_CLOSED: + // Reset if channel closed + if (channel == sdp_server_l2cap_cid) { + wiimote_emulator_reset(); + } + break; + default: + break; + } + break; + default: + break; + } +} + + +static void led_handler(struct btstack_timer_source *ts) +{ + // Invert the led + static uint8_t led_on = 0; + led_on = !led_on; + (*callback_led_func[led_on])(); + + // Restart timer + btstack_run_loop_set_timer(ts, 100); + btstack_run_loop_add_timer(ts); +} + + +void wiimote_emulator(void *report){ + + printf("Init Wiimote Emulator\n"); + + // Data from gamepad + input_report = report; + + // Disable SSP + gap_ssp_set_enable(0); + + // Set device connectable + gap_connectable_control(1); + + // Set device non discoverable for now, we'll set this after setting IAC LAP + gap_discoverable_control(0); + + // Set device bondable + gap_set_bondable_mode(1); + + // Set local name + gap_set_local_name("Nintendo RVL-CNT-01"); + + // Set class + gap_set_class_of_device(0x002504); + + // Register HCI callback to set IAC LAP once HCI is working + // and to catch the connection handle + hci_event_callback_registration.callback = &hci_packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // init L2CAP + l2cap_init(); + + // Register SDP service with max possible MTU + l2cap_register_service(l2cap_sdp_packet_handler, BLUETOOTH_PSM_SDP, 0xffff, LEVEL_0); + + // SDP Server + sdp_init(); + memset(hid_service_buffer, 0, sizeof(hid_service_buffer)); + + hid_sdp_record_t hid_sdp_record = { + // hid sevice subclass 2504 Gamepad?, hid counntry code 33 US + 0x2504, + 33, + 1, + 1, + 1, + 0, + 0, + 0xFFFF, + 0xFFFF, + 3200, + wiimote_report_descriptor, + sizeof(wiimote_report_descriptor), + hid_device_name + }; + + + hid_create_sdp_record(hid_service_buffer, sdp_create_service_record_handle(), &hid_sdp_record); + btstack_assert(de_get_len( hid_service_buffer) <= sizeof(hid_service_buffer)); + sdp_register_service(hid_service_buffer); + + // See https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers if you don't have a USB Vendor ID and need a Bluetooth Vendor ID + // device info: BlueKitchen GmbH, product 1, version 1 + device_id_create_sdp_record(pnp_service_buffer, sdp_create_service_record_handle(), DEVICE_ID_VENDOR_ID_SOURCE_BLUETOOTH, BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH, 1, 1); + btstack_assert(de_get_len(pnp_service_buffer) <= sizeof(pnp_service_buffer)); + sdp_register_service(pnp_service_buffer); + + // register for HID events + hid_device_register_packet_handler(&hci_packet_handler); + + // Power on! + hci_power_control(HCI_POWER_ON); + + // Init wiimote structure + wiimote_init(&wiimote); + + //No extension for default + reset_input_ir(wiimote.usr.ir_object); + wiimote.usr.connected_extension_type = NoExtension; + + // Loop control to send report + loop_wii.process = &task_wiimote; + + btstack_run_loop_execute(); +} + + +static void input_update_wiimote(){ + + if(input_report->reset_ir){ + reset_input_classic(&wiimote.usr.classic); + reset_input_nunchuk(&wiimote.usr.nunchuk); + reset_input_ir(wiimote.usr.ir_object); + // Change the extension too + wiimote.usr.connected_extension_type = input_report->mode; + input_report->reset_ir = 0; + } + + switch(input_report->mode){ + case NO_EXTENSION:{ + float pointer_delta_x = 0, pointer_delta_y = 0; + + memcpy(&wiimote.usr, &input_report->wiimote, 14); + + pointer_delta_x += (input_report->wiimote.ir_x / 127.0) * 0.008; + pointer_delta_y += (input_report->wiimote.ir_y / 127.0) * 0.008; + + pointer_x = fmax(-pointer_margin, fmin(1.0 + pointer_margin, pointer_x + pointer_delta_x)); + pointer_y = fmax(-pointer_margin, fmin(1.0 + pointer_margin, pointer_y + pointer_delta_y)); + + set_motion_state(&wiimote, pointer_x, pointer_y); + } + break; + case WIIMOTE_AND_NUNCHUCK:{ + // Wiimote + float pointer_delta_x = 0, pointer_delta_y = 0; + memcpy(&wiimote.usr, &input_report->wiimote, 14); + + // Nunchuck + memcpy(&wiimote.usr.nunchuk, &input_report->nunchuk, sizeof(struct wiimote_nunchuk)); + + pointer_delta_x += (input_report->wiimote.ir_x / 127.0) * 0.008; + pointer_delta_y += (input_report->wiimote.ir_y / 127.0) * 0.008; + + pointer_x = fmax(-pointer_margin, fmin(1.0 + pointer_margin, pointer_x + pointer_delta_x)); + pointer_y = fmax(-pointer_margin, fmin(1.0 + pointer_margin, pointer_y + pointer_delta_y)); + + set_motion_state(&wiimote, pointer_x, pointer_y); + + if(input_report->fake_motion || input_report->center_accel){ + + if(input_report->fake_motion) { + static int step = 48; + + if(input_report->wiimote.accel_x >= 1000 || input_report->wiimote.accel_x <= 100){ + step = -step; + } + + // Start moving all directions + + int temp_value = step + input_report->wiimote.accel_x; + + input_report->wiimote.accel_x = (uint16_t)temp_value; + input_report->nunchuk.accel_x = (uint16_t)temp_value; + + input_report->wiimote.accel_y = (uint16_t)temp_value; + input_report->nunchuk.accel_y = (uint16_t)temp_value; + + input_report->wiimote.accel_z = (uint16_t)temp_value; + input_report->nunchuk.accel_z = (uint16_t)temp_value; + } + + wiimote.usr.accel_x = input_report->wiimote.accel_x; + wiimote.usr.accel_y = input_report->wiimote.accel_y; + wiimote.usr.accel_z = input_report->wiimote.accel_z; + + if(input_report->center_accel){ + input_report->center_accel = 0; + } + } + } + break; + case CLASSIC_CONTROLLER: + memcpy(&wiimote.usr.classic, &input_report->classic, sizeof(struct wiimote_classic)); + break; + default: + break; + } + +} + + +void wiimote_emulator_set_led(void (*led_on)(), void (*led_off)()){ + callback_led_func[0] = led_off; + callback_led_func[1] = led_on; + + led_state.process = &led_handler; + btstack_run_loop_set_timer(&led_state, 100); + btstack_run_loop_add_timer(&led_state); +} + diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.h b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.h new file mode 100644 index 00000000..c97d099c --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wiimote_btstack.h @@ -0,0 +1,8 @@ +#ifndef _WIIMOTE_BTSTACK_H_ +#define _WIIMOTE_BTSTACK_H_ + +void wiimote_emulator_set_led(void (*led_on)(), void (*led_off)()); + +void wiimote_emulator(void *report); + +#endif // _WIIMOTE_BTSTACK_H_ diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.c b/Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.c new file mode 100644 index 00000000..a425f0ae --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.c @@ -0,0 +1,239 @@ +#include "wm_crypto.h" + +//extension crypto (2602 bytes) + +static const uint8_t ans_tbl[7][6] = { + {0xA8,0x77,0xA6,0xE0,0xF7,0x43}, + {0x5A,0x35,0x85,0xE2,0x72,0x97}, + {0x8F,0xB7,0x1A,0x62,0x87,0x38}, + { 0xD,0x67,0xC7,0xBE,0x4F,0x3E}, + {0x20,0x76,0x37,0x8F,0x68,0xB7}, + {0xA9,0x26,0x3F,0x2B,0x10,0xE3}, + {0x30,0x7E,0x90, 0xE,0x85, 0xA} +}; + +static const uint8_t sboxes[10][256] = { + { + 0x70,0x51, 3,0x86,0x40, 0xD,0x4F,0xEB,0x3E,0xCC,0xD1,0x87,0x35,0xBD,0xF5, 0xB, + 0x5E,0xD0,0xF8,0xF2,0xD5,0xE2,0x6C,0x31, 0xC,0xAD,0xFC,0x21,0xC3,0x78,0xC1, 6, + 0xC2,0x4C,0x55,0xE6,0x4A,0x34,0x48,0x11,0x1E,0xDA,0xE7,0x1A,0x84,0xA0,0x96,0xA7, + 0xE3,0x7F,0xAF,0x63,0x9C,0xFA,0x23,0x5B,0x79,0xC8,0x9E,0xBA,0xB2,0xC9,0x22,0x12, + 0x4B,0xB3,0xA1,0xB6,0x32,0x49,0xA2,0xE1,0x89,0x39,0x10,0x66,0xC5, 7,0x8F,0x54, + 0xEA,0x91,0xCA,0x3F,0xF9,0x19,0xF0,0xD7,0x46,0xBC,0x28,0x1B,0x61,0xE8,0x2F,0x6A, + 0xAE,0x9D,0xF6,0x4E, 9,0x14,0x77,0x4D,0xDB,0x1F,0x2E,0x7B,0x7C,0xF1,0x43,0xA3, + 0,0xB8,0x13,0x8C,0x85,0xB9,0x29,0x75,0x88,0xFD,0xD2,0x56,0x1C,0x50,0x97,0x41, + 0xE5,0x3B,0x60,0xB5,0xC0,0x64,0xEE,0x98,0xD6,0x2D,0x25,0xA4,0xAA,0xCD,0x7D,0xA8, + 0x83,0xC6,0xAB,0xBE,0x44,0x99,0x26,0x3C,0xCE,0x9F,0xBF,0xD3,0xCB,0x76,0x7A,0x7E, + 0x82, 1,0x8A,0x9A,0x80,0x1D, 0xE,0xB0,0x5C,0xD4,0x38,0x62,0xF4,0x30,0xE0,0x8E, + 0x53,0xB7, 2,0x57,0xAC,0xA6,0x52, 0xA,0x6D,0x92,0x65,0x17,0x24,0x33,0x45,0x72, + 0x74,0xB1,0xB4,0xF7,0x5D,0xED,0x2C,0xFF,0x47,0x37,0x5A,0x90,0xBB,0xDF,0x2A,0x16, + 0x59,0x95,0xD9,0xC4,0x27,0x67,0x73,0xC7,0x68,0xFE,0xA5,0xDD,0x6B,0x5F,0x93,0xD8, + 0xEC, 5,0x3A,0x8D,0x6E,0xFB,0x3D,0xA9,0x69,0x36,0xF3,0x94,0xDE,0xEF,0x15,0x6F, + 0x8B,0x9B, 8, 0xF,0xDC,0x81,0x18,0x20, 4,0xE4,0x71,0xCF,0xE9,0x2B,0x42,0x58, + }, + { + 1,0xA0,0xA9,0x62,0xD6,0x3F,0x85,0xA7,0xB6,0xD4,0xFA,0x15,0x66,0x17, 9,0xBD, + 0x5D,0x14,0x34,0x26,0x59,0x72,0x91,0x54, 6,0x4F,0xF8,0xB0,0x5B,0x74,0x93,0x99, + 0x8C,0xF2,0x45,0xCD,0xEA,0x4E,0xAD,0x10,0x4A,0xE5,0xCA,0xEE,0xDF,0xC6,0x6F,0x9F, + 0x88,0x8E, 2,0xCC, 8,0xA8,0x77,0x94,0x6D,0x21,0xB1,0x28,0xE4,0x39,0x79,0x96, + 0x60,0x71,0x81,0x16,0x2E,0xE6,0x78,0xB9,0xC4,0x46,0x9A,0x42,0xAE,0xB7,0x7C,0x43, + 0xB3,0x22,0x1A,0x86,0xC2,0x32,0x3D,0x2D,0x9C,0xD2,0x29,0xE9,0x63,0x9B,0xD1,0x31, + 0x38,0x5E,0x1E,0x36,0x41,0xBB, 3,0x18,0x2B,0x3E,0xBF,0x68,0x61,0xFC,0x52,0xC0, + 0xDE,0xE0, 0xA,0x58,0x13,0x5A, 0,0xBE,0x1C,0x90, 0xE,0x53,0x12,0xFD,0xE2,0x6E, + 0xBA,0xCE,0x24,0x27,0x44,0x7F,0x87,0xA3,0xA1,0xD5,0x50,0x40,0xE3,0xF9,0x83,0xF7, + 0xC7,0xA2,0x35,0xC8,0xDB,0x19,0xAB,0x2F,0x11,0x25,0xED,0x33,0x9E,0x55,0xE1,0x48, + 0xAF,0x73,0x84,0xDA,0x2A,0xAA,0x51,0xEB,0x9D,0x95,0xB2,0xCB,0xE7,0x70,0x80,0xFE, + 0x4C,0x65, 4,0xEF,0xC5,0xF1,0xC3,0x3A,0xB4,0xF5,0x5F,0x23,0x89,0xDD,0x30,0xA5, + 0x8B,0xD3,0xF6,0xDC,0x4D,0x64,0xD7,0xF0,0x8F,0xEC,0x56,0x37,0x5C,0xA4, 0xD, 7, + 0x76,0x8A,0x2C, 0xB,0xB5,0xD8,0xC1,0x1F,0xE8,0x3B,0xF4,0x4B,0x1B,0x47,0x6C,0x49, + 0x67,0x7B,0x92,0xCF,0x75,0x7E,0x20,0xD9,0x7D,0x3C,0x97,0x7A,0xD0, 5,0x6B, 0xF, + 0x1D,0xFB,0x82,0x98,0x57,0x8D,0xF3,0x6A,0xBC,0xAC,0xC9,0xA6,0xFF,0xB8,0x69, 0xC, + }, + { + 0x4C,0x4D,0x72, 7,0x5A,0x49,0x33,0x8D,0xA2,0xAB,0x46,0x3D,0x63, 0xD,0xA0,0x97, + 0xFF,0xF0,0xF5,0xFA,0xC0,0xE9,0xDB,0x62,0xE4,0xE1,0x74,0x43,0xDC,0x86,0x18,0x29, + 0x37,0xF4, 6,0xE2,0xED,0x6F,0x90,0x48,0x1E,0x2D,0x1D,0xEA,0x73,0x94,0x54,0xDF, + 0x25,0xF6,0x47,0x27,0xD9,0x11,0x77,0xC9,0x84,0x1C,0x5B,0x5C,0x51,0x81,0xA6,0x22, + 0x3E,0x24,0x96,0xC8,0x8A,0xEC,0x82,0x7C, 9,0xB8,0x45,0x4A,0x57,0xBB,0x2F,0x50, + 0x75,0x8E,0x61,0x70,0x8C,0x6C,0xAF,0xD0,0xFD,0xB4,0x1B,0xAE,0xDE,0xFE,0x3B,0xB5, + 0x36,0xBD,0x55, 1, 0xE,0x9C,0x41,0x56,0x5F,0xB3,0x26, 3,0x83,0xBA,0x13,0x4B, + 0xCA,0xC5, 0xA,0xF8,0x60,0xA5,0xB9,0xC7,0xC3,0x98,0x32,0xFB,0x12,0xF9,0xA7,0x92, + 0xAA,0x68,0xF3,0x78,0x7E, 5,0x20,0x21, 2,0xE8,0xBF,0xF2,0xB0,0x59,0x8F,0xD2, + 0xCB,0x87,0x65,0x15,0xF1,0x1A,0xB2,0x30,0xAD,0xEE,0x58,0xA3,0x8B,0x66,0x1F,0x2C, + 0xD7,0x5D,0x19,0x85,0xA8,0xE6,0xD3,0x6B,0xA1, 0xC,0x91,0x93,0x6A,0x5E, 0xB,0x79, + 0xE3,0xDD, 0,0x4F,0x3C,0x89,0x6E,0x71,0x69,0xA9,0xAC,0x40,0xE5,0x99,0x28,0xC6, + 0x31,0x4E,0x7A,0xCD, 8,0x9E,0x7D,0xEF,0x17,0xFC,0x88,0xD8,0xA4,0x6D,0x44,0x95, + 0xD1,0xB7,0xD4,0x9B,0xBE,0x2A,0x34,0x64,0x2B,0xCF,0x2E,0xEB,0x38,0xCE,0x23,0xE0, + 0x3A,0x3F,0xF7,0x7B,0x9F,0x10,0x53,0xBC,0x52,0x67,0x16,0xE7,0x80,0x76, 4,0xC4, + 0xB6,0xC1,0xC2,0x7F,0x9A,0xDA,0xD5,0x39,0x42,0x14,0x9D,0xB1, 0xF,0x35,0xD6,0xCC, + }, + { + 0xB9,0xDA,0x38, 0xC,0xA2,0x9C, 9,0x1F, 6,0xB1,0xB6,0xFD,0x1A,0x69,0x23,0x30, + 0xC4,0xDE, 1,0xD1,0xF4,0x58,0x29,0x37,0x1C,0x7D,0xD5,0xBF,0xFF,0xBD,0xC8,0xC9, + 0xCF,0x65,0xBE,0x7B,0x78,0x97,0x98,0x67, 8,0xB3,0x26,0x57,0xF7,0xFA,0x40,0xAD, + 0x8E,0x75,0xA6,0x7C,0xDB,0x91,0x8B,0x51,0x99,0xD4,0x17,0x7A,0x90,0x8D,0xCE,0x63, + 0xCB,0x4E,0xA0,0xAB,0x18,0x3A,0x5B,0x50,0x7F,0x21,0x74,0xC1,0xBB,0xB8,0xB7,0xBA, + 0xB,0x35,0x95,0x31,0x59,0x9A,0x4D, 4, 7,0x1E,0x5A,0x76,0x13,0xF3,0x71,0x83, + 0xD0,0x86, 3,0xA8,0x39,0x42,0xAA,0x28,0xE6,0xE4,0xD8,0x5D,0xD3,0xD0,0x6E,0x6F, + 0x96,0xFB,0x5E,0xBC,0x56,0xC2,0x5F,0x85,0x9B,0xE7,0xAF,0xD2,0x3B,0x84,0x6A,0xA7, + 0x53,0xC5,0x44,0x49,0xA5,0xF9,0x36,0x72,0x3D,0x2C,0xD9,0x1B,0xA1,0xF5,0x4F,0x93, + 0x9D,0x68,0x47,0x41,0x16,0xCA,0x2A,0x4C,0xA3,0x87,0xD6,0xE5,0x19,0x2E,0x77,0x15, + 0x6D,0x70,0xC0,0xDF,0xB2, 0,0x46,0xED,0xC6,0x6C,0x43,0x60,0x92,0x2D,0xA9,0x22, + 0x45,0x8F,0x34,0x55,0xAE,0xA4, 0xA,0x66,0x32,0xE0,0xDC, 2,0xAC,0xE8,0x20,0x8C, + 0x89,0x62,0x4A,0xFE,0xEE,0xC3,0xE3,0x3C,0xF1,0x79, 5,0xE9,0xF6,0x27,0x33,0xCC, + 0xF2,0x9E,0x11,0x81,0x7E,0x80,0x10,0x8A,0x82,0x9F,0x48, 0xD,0xD7,0xB4,0xFC,0x2F, + 0xB5,0xC7,0xDD,0x88,0x14,0x6B,0x2B,0x54,0xEA,0x1D,0x94,0x5C,0xB0,0xEF,0x12,0x24, + 0xCD,0xEB,0xE1,0xE2,0x64,0x73,0x3F, 0xE,0x52,0x61,0x25,0x3E,0xF8, 0xF,0x4B,0xEC, + }, + { + 0xC0, 0,0x30,0xF6, 2,0x49,0x3D,0x10,0x6E,0x20,0xC9,0xA6,0x2F,0xFE,0x2C,0x2B, + 0x75,0x2E,0x45,0x26,0xAB,0x48,0xA9,0x80,0xFC, 4,0xCC,0xD3,0xB5,0xBA,0xA3,0x38, + 0x31,0x7D, 1,0xD9,0xA7,0x7B,0x96,0xB6,0x63,0x69,0x4E,0xF7,0xDE,0xE0,0x78,0xCA, + 0x50,0xAA,0x41,0x91,0x65,0x88,0xE4,0x21,0x85,0xDA,0x3A,0x27,0xBE,0x1C,0x3E,0x42, + 0x5E,0x17,0x52,0x7F,0x1F,0x89,0x24,0x6F,0x8F,0x5C,0x67,0x74, 0xE,0x12,0x87,0x8D, + 0xE9,0x34,0xED,0x73,0xC4,0xF8,0x61,0x5B, 5,0xDF,0x59,0x4C,0x97,0x79,0x83,0x18, + 0xA4,0x55,0x95,0xEB,0xBD,0x53,0xF5,0xF1,0x57,0x66,0x46,0x9F,0xB2,0x81, 9,0x51, + 0x86,0x22,0x16,0xDD,0x23,0x93,0x76,0x29,0xC2,0xD7,0x1D,0xD4,0xBF,0x36,0x3F,0xEA, + 0x4B,0x11,0x32,0xB9,0x62,0x54,0x60,0xD6,0x6D,0x43,0x9A, 0xD,0x92,0x9C,0xB0,0xEF, + 0x58,0x6C,0x9D,0x77,0x2D,0x70,0xFA,0xF3,0xB3, 0xB,0xE2,0x40,0x7E,0xF4,0x8A,0xE5, + 0x8C,0x3C,0x56,0x71,0xD1,0x64,0xE1,0x82, 0xA,0xCB,0x13,0x15,0x90,0xEC, 3,0x99, + 0xAF,0x14,0x5D, 0xF,0x33,0x4A,0x94,0xA5,0xA8,0x35,0x1B,0xE3,0x6A,0xC6,0x28,0xFF, + 0x4D,0xE7,0x25,0x84,0xAC, 8,0xAE,0xC5,0xA2,0x2A,0xB8,0x37, 0xC,0x7A,0xA0,0xC3, + 0xCE,0xAD, 6,0x1A,0x9E,0x8B,0xFB,0xD5,0xD0,0xC1,0x1E,0xD0,0xB4,0x9B,0xB1,0x44, + 0xF2,0x47,0xC7,0x68,0xCF,0x72,0xBB,0x4F,0x5A,0xF9,0xDC,0x6B,0xDB,0xD2,0xE8,0x7C, + 0xC8,0xEE,0x98,0xA1,0xE6,0xD8,0x39, 7,0x5F,0xFD,0x8E,0x19,0xB7,0x3B,0xBC,0xCD, + }, + { + 0x7C,0xE3,0x81,0x73,0xB2,0x11,0xBF,0x6F,0x20,0x98,0xFE,0x75,0x96,0xEF,0x6C,0xDA, + 0x50,0xE1, 9,0x72,0x54,0x45,0xBA,0x34,0x80,0x5B,0xED,0x3E,0x53,0x2C,0x87,0xA4, + 0x57,0xF3,0x33,0x3F,0x3C,0xB7,0x67,0xB4,0xA3,0x25,0x60,0x4F, 7,0x6B,0x1B,0x47, + 0x15, 0xF,0xE4, 0xA,0xEA,0xD1,0x32,0x78,0x36,0x49,0x8D,0x4B,0xD2,0xBC,0xA5,0xDC, + 0x1D, 0xD,0x4D,0xCD,0x9A,0x82,0x5F,0xFC,0x94,0x65,0xBE,0xE2,0xF4,0xC9,0x1E,0x44, + 0xCB,0x9E, 0xC,0x64,0x71,0x26,0x63,0xB3,0x14,0xE8,0x40,0x70,0x8A, 0xE,0x19,0x42, + 0x6D,0xAC,0x88,0x10,0x5C,0xDF,0x41,0xA9,0xAD,0xE5,0xFB,0x74,0xCC,0xD5, 6,0x8E, + 0x59,0x86,0xCE,0x1F,0x3D,0x76,0xE0,0x8F,0xB9,0x77,0x27,0x7B,0xA6,0xD8,0x29,0xD3, + 0xEC,0xB8,0x13,0xF7,0xFA,0xC3,0x51,0x6A,0xDE,0x4A,0x5A,0xEB,0xC2,0x8B,0x23,0x48, + 0x92,0xCF,0x62,0xA8,0x99,0xF8,0xD0,0x2E,0x85,0x61,0x43,0xC8,0xBD,0xF0, 5,0x93, + 0xCA,0x4E,0xF1,0x7D,0x30,0xFD,0xC4,0x69,0x66,0x2F, 8,0xB1,0x52,0xF9,0x21,0xE6, + 0x7A,0x2B,0xDD,0x39,0x84,0xFF,0xC0,0x91,0xD6,0x37,0xD4,0x7F,0x2D,0x9B,0x5D,0xA1, + 0x3B,0x6E,0xB5,0xC5,0x46, 4,0xF5,0x90,0xEE,0x7E,0x83,0x1C, 3,0x56,0xB6,0xAA, + 0,0x17, 1,0x35,0x55,0x79, 0xB,0x12,0xBB,0x1A,0x31,0xE7, 2,0x28,0x16,0xC1, + 0xF6,0xA2,0xDB,0x18,0x9C,0x89,0x68,0x38,0x97,0xAB,0xC7,0x2A,0xD7,0x3A,0xF2,0xC6, + 0x24,0x4C,0xB0,0x58,0xA0,0x22,0x5E,0x9D,0xD9,0xA7,0xE9,0xAE,0xAF,0x8C,0x95,0x9F, + }, + { + 0x28,0xB7,0x20,0xD7,0xB0,0x30,0xC3, 9,0x19,0xC0,0x67,0xD6, 0,0x3C,0x7E,0xE7, + 0xE9,0xF4, 8,0x5A,0xF8,0xB8,0x2E, 5,0xA6,0x25,0x9E,0x5C,0xD8,0x15, 0xD,0xE1, + 0xF6,0x11,0x54,0x6B,0xCD,0x21,0x46,0x66,0x5E,0x84,0xAD, 6,0x38,0x29,0x44,0xC5, + 0xA2,0xCE,0xF1,0xAA,0xC1,0x40,0x71,0x86,0xB5,0xEF,0xFC,0x36,0xA8,0xCB, 0xA,0x48, + 0x27,0x45,0x64,0xA3,0xAF,0x8C,0xB2,0xC6,0x9F, 7,0x89,0xDC,0x17,0xD3,0x49,0x79, + 0xFB,0xFE,0x1D,0xD0,0xB9,0x88,0x43,0x52,0xBC, 1,0x78,0x2B,0x7D,0x94,0xC7, 0xE, + 0xDE,0xA5,0xD5,0x9B,0xCC,0xF7,0x61,0x7A,0xC2,0x74,0x81,0x39, 3,0xAB,0x96,0xA0, + 0x37,0xBD,0x2D,0x72,0x75,0x3F,0xC9,0xD4,0x8E,0x6F,0xF9,0x8D,0xED,0x62,0xDB,0x1C, + 0xDF, 4,0xAC,0x1B,0x6C,0x14,0x4B,0x63,0xD0,0xBF,0xB4,0x82,0xEC,0x7B,0x1A,0x59, + 0x92,0xD2,0x10,0x60,0xB6,0x3D,0x5F,0xE6,0x80,0x6E,0x70,0xC4,0xF2,0x35,0xD9,0x7C, + 0xEE,0xE5,0x41,0xA4,0x5B,0x50,0xDD,0xBB,0x4C,0xF3,0x1F,0x9D,0x5D,0x57,0x55,0x51, + 0x97,0xE3,0x58,0x42,0x4D,0x9C,0x73,0xBA,0xC8,0x77,0x31,0x69,0x26,0xAE,0xEA,0x8A, + 0xDA,0x22,0xB3,0x87,0x56,0xFA,0x93, 0xB,0x34,0x16,0x33,0xE8,0xE4,0x53,0xBE,0xA9, + 0xB1,0x3A,0x3E,0xF5,0x90,0x6A,0xCF,0x3B,0x12,0xFD,0x8F,0x9A,0xA7,0x47,0x91,0x99, + 0xEB, 0xF,0x24,0xFF,0x23,0x18,0x85,0x4E,0x7F, 0xC,0xE0,0xA1,0xD2,0xD1,0x2C,0x2A, + 0x4A, 2,0x4F,0x1E,0x95,0x68,0x8B,0x98,0x83,0x6D,0x76,0xCA,0x65,0x32,0x13,0x2F, + }, + { + 0xC3,0x82,0x9A,0xA4,0xBA,0x81,0x60,0x37,0x34,0x35,0xFC,0x80,0xA8,0x51,0x65,0x67, + 0xED,0x30,0x5F,0x10,0xD3,0x4A,0x27,0x2F,0x13,0xB9,0x2A,0xD2,0xCC,0xE1,0xEF,0xAE, + 0xEB,0xBE,0xF4,0xBD,0xCF,0x43,0xB3,0xC5,0x88,0x84,0xB7,0xDD,0x39,0x40,0xCE,0x48, + 0x6D,0x9B,0x72,0x61,0x7E,0xE7,0xA1,0x4E,0x53,0x2E,0x77,0x3B,0xE2,0xC9,0x36,0x22, + 0x1B,0x6E,0x73,0xB1, 3,0xB2,0x4C,0x87,0xA9,0xD4,0x4D, 0xF,0xD8,0x15,0x6C,0xAA, + 0x18,0xF6,0x49,0x57,0x5D,0xFB,0x7A,0x14,0x94,0x63,0xA0,0x11,0xB0,0x9E,0xDE, 5, + 0x46,0xC8,0xEE,0x47,0xDB,0xDC,0x24,0x89,0x9C,0x91,0x97,0x29,0xE9,0x7B,0xC1, 7, + 0x1E,0xB8,0xFD,0xFE,0xAC,0xC6,0x62,0x98,0x4F,0xF1,0x79,0xE0,0xE8,0x6B,0x78,0x56, + 0xB6,0x8D, 4,0x50,0x86,0xCA,0x6F,0x20,0xE6,0xEA,0xE5,0x76,0x17,0x1C,0x74,0x7F, + 0xBC, 0xD,0x2C,0x85,0xF7,0x66,0x96,0xE4,0x8B,0x75,0x3F,0x4B,0xD9,0x38,0xAF,0x7C, + 0xDA, 0xB,0x83,0x2D,0x31,0x32,0xA2,0xF5,0x1D,0x59,0x41,0x45,0xBF,0x3C,0x1F,0xF8, + 0xF9,0x8A,0xD0,0x16,0x25,0x69,0x12,0x99,0x9D,0x21,0x95,0xAB, 1,0xA6,0xD7,0xB5, + 0xC0,0x7D,0xFF,0x58, 0xE,0x3A,0x92,0xD1,0x55,0xE3, 8,0x9F,0xD6,0x3E,0x52,0x8E, + 0xFA,0xA3,0xC7, 2,0xCD,0xDF,0x8F,0x64,0x19,0x8C,0xF3,0xA7, 0xC,0x5E, 0xA,0x6A, + 9,0xF0,0x93,0x5B,0x42,0xC2, 6,0x23,0xEC,0x71,0xAD,0xB4,0xCB,0xBB,0x70,0x28, + 0xD5,0x1A,0x5C,0x33,0x68,0x5A, 0,0x44,0x90,0xA5,0xC4,0x26,0x3D,0x2B,0xF2,0x54, + }, + { + 0x96,0xAD,0xDA,0x1F,0xED,0x33,0xE1,0x81,0x69, 8, 0xD, 0xA,0xDB,0x35,0x77,0x9A, + 0x64,0xD1,0xFC,0x78,0xAA,0x1B,0xD0,0x67,0xA0,0xDD,0xFA,0x6C,0x63,0x71, 5,0x84, + 0x17,0x6A,0x89,0x4F,0x66,0x7F,0xC6,0x50,0x55,0x92,0x6F,0xBD,0xE7,0xD2,0x40,0x72, + 0x8D,0xBB,0xEC, 6,0x42,0x8A,0xE4,0x88,0x9D,0x7E,0x7A,0x82,0x27,0x13,0x41,0x1A, + 0xAF,0xC8,0xA4,0x76,0xB4,0xC2,0xFE,0x6D,0x1C,0xD9,0x61,0x30,0xB3,0x7C,0xEA,0xF7, + 0x29, 0xF,0xF2,0x3B,0x51,0xC1,0xDE,0x5F,0xE5,0x2A,0x2F,0x99, 0xB,0x5D,0xA3,0x2B, + 0x4A,0xAB,0x95,0xA5,0xD3,0x58,0x56,0xEE,0x28,0x31, 0,0xCC,0x15,0x46,0xCA,0xE6, + 0x86,0x38,0x3C,0x65,0xF5,0xE3,0x9F,0xD6,0x5B, 9,0x49,0x83,0x70,0x2D,0x53,0xA9, + 0x7D,0xE2,0xC4,0xAC,0x8E,0x5E,0xB8,0x25,0xF4,0xB9,0x57,0xF3,0xF1,0x68,0x47,0xB2, + 0xA2,0x59,0x20,0xCE,0x34,0x79,0x5C,0x90, 0xE,0x1E,0xBE,0xD5,0x22,0x23,0xB1,0xC9, + 0x18,0x62,0x16,0x2E,0x91,0x3E, 7,0x8F,0xD8,0x3F,0x93,0x3D,0xD4,0x9B,0xDF,0x85, + 0x21,0xFB,0x11,0x74,0x97,0xC7,0xD7,0xDC,0x4C,0x19,0x45,0x98,0xE9,0x43, 2,0x4B, + 0xBC,0xC3, 4,0x9C,0x6B,0xF0,0x75,0x52,0xA7,0x26,0xF6,0xC5,0xBA,0xCF,0xB0,0xB7, + 0xAE,0x5A,0xA1,0xBF, 3,0x8B,0x80,0x12,0x6E, 0xC,0xEB,0xF9,0xC0,0x44,0x24,0xEF, + 0x10,0xF8,0xA8,0x8C,0xE8,0x7B,0xFF,0x9E,0x2C,0xCD,0x60,0x36,0x87,0xB5,0x94,0xA6, + 0x54,0x73,0x3A,0x14,0x4E, 1,0x1D,0xB6,0xFD,0x37,0x48,0x4D,0x39,0xCB,0xE0,0x32, + } +}; + +static inline uint8_t ror8(uint8_t a, uint8_t b) +{ + return (a>>b) | ((a<<(8-b))&0xff); +} + +void ext_generate_tables(struct ext_crypto_state * state, const uint8_t key[16]) +{ + int idx, i; + const uint8_t * ans; + uint8_t t0[10]; + + //determine idx with simple brute force + for (idx = 0; idx < 7; idx++) + { + ans = ans_tbl[idx]; + + for(i = 0; i < 10; i++) + { + t0[i] = sboxes[0][key[9 - i]]; + } + + //todo: clean up this nasty mess + if ((key[0xf] == (uint8_t)((ror8(ans[0]^t0[5],t0[2]%8) - t0[9]) ^ t0[4])) && + (key[0xe] == (uint8_t)((ror8(ans[1]^t0[1],t0[0]%8) - t0[5]) ^ t0[7])) && + (key[0xd] == (uint8_t)((ror8(ans[2]^t0[6],t0[8]%8) - t0[2]) ^ t0[0])) && + (key[0xc] == (uint8_t)((ror8(ans[3]^t0[4],t0[7]%8) - t0[3]) ^ t0[2])) && + (key[0xb] == (uint8_t)((ror8(ans[4]^t0[1],t0[6]%8) - t0[3]) ^ t0[4])) && + (key[0xa] == (uint8_t)((ror8(ans[5]^t0[7],t0[8]%8) - t0[5]) ^ t0[9]))) + { + break; + } + } + + state->ft[0] = sboxes[idx+1][key[0xb]] ^ sboxes[idx+2][key[0x6]]; + state->ft[1] = sboxes[idx+1][key[0xd]] ^ sboxes[idx+2][key[0x4]]; + state->ft[2] = sboxes[idx+1][key[0xa]] ^ sboxes[idx+2][key[0x2]]; + state->ft[3] = sboxes[idx+1][key[0xf]] ^ sboxes[idx+2][key[0x7]]; + state->ft[4] = sboxes[idx+1][key[0xe]] ^ sboxes[idx+2][key[0x5]]; + state->ft[5] = sboxes[idx+1][key[0xc]] ^ sboxes[idx+2][key[0x0]]; + state->ft[6] = sboxes[idx+1][key[0x9]] ^ sboxes[idx+2][key[0x3]]; + state->ft[7] = sboxes[idx+1][key[0x8]] ^ sboxes[idx+2][key[0x1]]; + + state->sb[0] = sboxes[idx+1][key[0xf]] ^ sboxes[idx+2][key[0x8]]; + state->sb[1] = sboxes[idx+1][key[0xa]] ^ sboxes[idx+2][key[0x5]]; + state->sb[2] = sboxes[idx+1][key[0xc]] ^ sboxes[idx+2][key[0x9]]; + state->sb[3] = sboxes[idx+1][key[0xd]] ^ sboxes[idx+2][key[0x0]]; + state->sb[4] = sboxes[idx+1][key[0xb]] ^ sboxes[idx+2][key[0x2]]; + state->sb[5] = sboxes[idx+1][key[0xe]] ^ sboxes[idx+2][key[0x1]]; + state->sb[6] = sboxes[idx+1][key[0x6]] ^ sboxes[idx+2][key[0x4]]; + state->sb[7] = sboxes[idx+1][key[0x7]] ^ sboxes[idx+2][key[0x3]]; +} + +void ext_encrypt_bytes(const struct ext_crypto_state * state, uint8_t * buffer, + int addr_offset, int length) +{ + for (int i = 0; i < length; i++) + { + buffer[i] = (buffer[i] - state->ft[(i + addr_offset) % 8]) ^ state->sb[(i + addr_offset) % 8]; + } +} \ No newline at end of file diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.h b/Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.h new file mode 100644 index 00000000..46812774 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wm_crypto.h @@ -0,0 +1,16 @@ +#ifndef WM_CRYPTO_H +#define WM_CRYPTO_H + +#include + +struct ext_crypto_state +{ + uint8_t ft[8]; + uint8_t sb[8]; +}; + +void ext_generate_tables(struct ext_crypto_state * state, const uint8_t key[16]); +void ext_encrypt_bytes(const struct ext_crypto_state * state, uint8_t * buffer, + int addr_offset, int length); + +#endif diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.c b/Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.c new file mode 100644 index 00000000..0f8f90c1 --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.c @@ -0,0 +1,440 @@ +#include "wm_reports.h" +#include "wm_crypto.h" +#include "inet.h" + +#include +#include + +struct report * report_queue_push(struct wiimote_state * state) +{ + struct queued_report * rpt; + + //allocate new report + rpt = (struct queued_report *)malloc(sizeof(struct queued_report)); + memset(rpt, 0, sizeof(struct queued_report)); + + //append to the end of the queue + if (state->sys.queue_end != NULL) + { + state->sys.queue_end->next = rpt; + } + else + { + state->sys.queue = rpt; + } + state->sys.queue_end = rpt; + + return &(rpt->rpt); +} + +struct report * report_queue_peek(struct wiimote_state * state) +{ + if (state->sys.queue == NULL) return NULL; //empty queue + + return &(state->sys.queue->rpt); +} + +void report_queue_pop(struct wiimote_state * state) +{ + struct queued_report * rpt; + + if (state->sys.queue == NULL) return; //nothing to remove + + //remove from the queue + rpt = state->sys.queue; + if (state->sys.queue_end == rpt) + { + state->sys.queue_end = NULL; + } + state->sys.queue = rpt->next; + + //free report mem + free(rpt); +} + +void report_queue_push_ack(struct wiimote_state *state, uint8_t report, uint8_t result) +{ + //push acknowledgement report x22 + struct report * rpt = report_queue_push(state); + rpt->len = 6; + rpt->data.io = 0xa1; + rpt->data.type = 0x22; + + struct report_ack * ack = (struct report_ack *)rpt->data.buf; + ack->report = report; + ack->result = result; +} + +void report_queue_push_status(struct wiimote_state * state) +{ + //push status report x20 + struct report * rpt = report_queue_push(state); + rpt->len = 8; + rpt->data.io = 0xa1; + rpt->data.type = 0x20; + + struct report_status * status = (struct report_status *)rpt->data.buf; + status->low_battery = state->sys.low_battery; + status->extension_connected = state->sys.extension_connected; + status->speaker_enabled = state->sys.speaker_enabled; + status->ircam_enabled = state->sys.ircam_enabled; + status->led_1 = state->sys.led_1; + status->led_2 = state->sys.led_2; + status->led_3 = state->sys.led_3; + status->led_4 = state->sys.led_4; + status->battery_level = state->sys.battery_level; +} + +void report_format_mem_resp(struct wiimote_state * state, struct report * rpt, + int size, int error, uint16_t addr, uint8_t * buf, bool encrypt) +{ + struct report_mem_resp * resp = (struct report_mem_resp *)rpt->data.buf; + + rpt->len = 23; + rpt->data.io = 0xa1; + rpt->data.type = 0x21; + + resp->size = size - 1; + resp->error = error; + resp->addr = htons(addr); + if (buf != NULL) //buf will be null for error reports + { + memcpy(resp->data, buf, size); + + if (encrypt) + { + ext_encrypt_bytes(&state->sys.extension_crypto_state, resp->data, addr & 0x7, size); + } + } +} + +void report_append_buttons(struct wiimote_state * state, uint8_t * buf) +{ + struct report_buttons * rpt = (struct report_buttons *)buf; + + rpt->left = state->usr.left; + rpt->right = state->usr.right; + rpt->down = state->usr.down; + rpt->up = state->usr.up; + rpt->one = state->usr.one; + rpt->two = state->usr.two; + rpt->a = state->usr.a; + rpt->b = state->usr.b; + rpt->plus = state->usr.plus; + rpt->minus = state->usr.minus; + rpt->home = state->usr.home; +} + +void report_append_accelerometer(struct wiimote_state * state, uint8_t * buf) +{ + struct report_accelerometer * rpt = (struct report_accelerometer *)buf; + + rpt->buttons.accel_0 = state->usr.accel_x; + rpt->buttons.accel_1 = (state->usr.accel_z & 0x2) | + ((state->usr.accel_y >> 1) & 0x1); + + rpt->x = state->usr.accel_x >> 2; + rpt->y = state->usr.accel_y >> 2; + rpt->z = state->usr.accel_z >> 2; +} + +void report_append_ir_10(struct wiimote_state * state, uint8_t * buf) +{ + struct report_ir_basic * rpt = (struct report_ir_basic *)buf; + + rpt->x1_lo = state->usr.ir_object[0].x; + rpt->y1_lo = state->usr.ir_object[0].y; + rpt->x1_hi = state->usr.ir_object[0].x >> 8; + rpt->y1_hi = state->usr.ir_object[0].y >> 8; + + rpt->x2_lo = state->usr.ir_object[1].x; + rpt->y2_lo = state->usr.ir_object[1].y; + rpt->x2_hi = state->usr.ir_object[1].x >> 8; + rpt->y2_hi = state->usr.ir_object[1].y >> 8; + + rpt->x3_lo = state->usr.ir_object[2].x; + rpt->y3_lo = state->usr.ir_object[2].y; + rpt->x3_hi = state->usr.ir_object[2].x >> 8; + rpt->y3_hi = state->usr.ir_object[2].y >> 8; + + rpt->x4_lo = state->usr.ir_object[3].x; + rpt->y4_lo = state->usr.ir_object[3].y; + rpt->x4_hi = state->usr.ir_object[3].x >> 8; + rpt->y4_hi = state->usr.ir_object[3].y >> 8; + +} + +void report_append_ir_12(struct wiimote_state * state, uint8_t * buf) +{ + struct report_ir_ext * rpt = (struct report_ir_ext *)buf; + int i; + + for (i=0; i<4; i++) + { + rpt->obj[i].x_lo = state->usr.ir_object[i].x; + rpt->obj[i].y_lo = state->usr.ir_object[i].y; + rpt->obj[i].x_hi = state->usr.ir_object[i].x >> 8; + rpt->obj[i].y_hi = state->usr.ir_object[i].y >> 8; + rpt->obj[i].size = state->usr.ir_object[i].size; + } + +} + +void report_append_interleaved(struct wiimote_state * state, uint8_t * buf) +{ + struct report_interleaved * rpt = (struct report_interleaved *)buf; + int i; + + if (state->sys.reporting_mode == 0x3e) + { + rpt->buttons.accel_0 = state->usr.accel_z >> 4; + rpt->buttons.accel_1 = state->usr.accel_z >> 6; + rpt->accel = state->usr.accel_x >> 2; + + for (i=0; i<2; i++) + { + rpt->obj[i].x_lo = state->usr.ir_object[i].x; + rpt->obj[i].y_lo = state->usr.ir_object[i].y; + rpt->obj[i].x_hi = state->usr.ir_object[i].x >> 8; + rpt->obj[i].y_hi = state->usr.ir_object[i].y >> 8; + rpt->obj[i].size = state->usr.ir_object[i].size; + rpt->obj[i].x_min = state->usr.ir_object[i].xmin; + rpt->obj[i].y_min = state->usr.ir_object[i].ymin; + rpt->obj[i].y_max = state->usr.ir_object[i].xmax; + rpt->obj[i].y_max = state->usr.ir_object[i].ymax; + rpt->obj[i].intensity = state->usr.ir_object[i].intensity; + } + + state->sys.reporting_mode = 0x3f; + } + else + { + rpt->buttons.accel_0 = state->usr.accel_z; + rpt->buttons.accel_1 = state->usr.accel_z >> 2; + rpt->accel = state->usr.accel_y >> 2; + + for (i=0; i<2; i++) + { + rpt->obj[i].x_lo = state->usr.ir_object[i+2].x; + rpt->obj[i].y_lo = state->usr.ir_object[i+2].y; + rpt->obj[i].x_hi = state->usr.ir_object[i+2].x >> 8; + rpt->obj[i].y_hi = state->usr.ir_object[i+2].y >> 8; + rpt->obj[i].size = state->usr.ir_object[i+2].size; + rpt->obj[i].x_min = state->usr.ir_object[i+2].xmin; + rpt->obj[i].y_min = state->usr.ir_object[i+2].ymin; + rpt->obj[i].y_max = state->usr.ir_object[i+2].xmax; + rpt->obj[i].y_max = state->usr.ir_object[i+2].ymax; + rpt->obj[i].intensity = state->usr.ir_object[i+2].intensity; + } + + state->sys.reporting_mode = 0x3e; + } +} + +void report_append_extension(struct wiimote_state * state, uint8_t * buf, uint8_t bytes) +{ + //a600fe = 0x04 activate motionplus, 0x05 activate nunchuk passthrough, 0x07 activate classic passthrough + //if no other extension, send 0x20 + + //a600f0 = 0x55 deactivate motionplus + //send report 0x20 twice (once for unplugged, once for plugged in) + + //0xa400fa contents + //0000 A420 0000 Nunchuk + //0000 A420 0101 Classic + //0000 A420 0405 WMP + //0000 A420 0505 WMP nunchuk + //0000 A420 0705 WMP classic + + //0000 A620 0005 Inactive WMP + // ^=6 Deactivated WMP + + //these should be set to the the address offset of the extension data + //and the length in bytes of the extesnion data + //right now, they are always the same in all situations + int addr_offset = 0x08, length = 6; + + switch (state->sys.extension_report_type) + { + case 0x00: //nunchuk + { + struct report_ext_nunchuk * rpt = (struct report_ext_nunchuk *)buf; + + rpt->x = state->usr.nunchuk.x; + rpt->y = state->usr.nunchuk.y; + + rpt->accel_x_hi = state->usr.nunchuk.accel_x >> 2; + rpt->accel_y_hi = state->usr.nunchuk.accel_y >> 2; + rpt->accel_z_hi = state->usr.nunchuk.accel_z >> 2; + rpt->accel_x_lo = state->usr.nunchuk.accel_x; + rpt->accel_y_lo = state->usr.nunchuk.accel_y; + rpt->accel_z_lo = state->usr.nunchuk.accel_z; + + rpt->c = !state->usr.nunchuk.c; + rpt->z = !state->usr.nunchuk.z; + + break; + } + case 0x01: //classic + { + struct report_ext_classic * rpt = (struct report_ext_classic *)buf; + + rpt->lx = state->usr.classic.ls_x; + rpt->ly = state->usr.classic.ls_y; + rpt->rx_hi = state->usr.classic.rs_x >> 3; + rpt->rx_m = state->usr.classic.rs_x >> 1; + rpt->rx_lo = state->usr.classic.rs_x; + rpt->ry = state->usr.classic.rs_y; + + rpt->lt_hi = state->usr.classic.lt >> 3; + rpt->lt_lo = state->usr.classic.lt; + rpt->rt = state->usr.classic.rt; + + rpt->left = !state->usr.classic.left; + rpt->right = !state->usr.classic.right; + rpt->up = !state->usr.classic.up; + rpt->down = !state->usr.classic.down; + rpt->ltrigger = !state->usr.classic.ltrigger; + rpt->rtrigger = !state->usr.classic.rtrigger; + rpt->lz = !state->usr.classic.lz; + rpt->rz = !state->usr.classic.rz; + rpt->a = !state->usr.classic.a; + rpt->b = !state->usr.classic.b; + rpt->x = !state->usr.classic.x; + rpt->y = !state->usr.classic.y; + rpt->plus = !state->usr.classic.plus; + rpt->minus = !state->usr.classic.minus; + rpt->home = !state->usr.classic.home; + + rpt->unused = 1; + + break; + } + case 0x04: //motionplus + { + struct report_ext_motionplus * rpt = (struct report_ext_motionplus *)buf; + + rpt->yaw_hi = state->usr.motionplus.yaw_down >> 8; + rpt->yaw_lo = state->usr.motionplus.yaw_down; + rpt->roll_hi = state->usr.motionplus.roll_left >> 8; + rpt->roll_lo = state->usr.motionplus.roll_left; + rpt->pitch_hi = state->usr.motionplus.pitch_left >> 8; + rpt->pitch_lo = state->usr.motionplus.pitch_left; + + rpt->yaw_slow = state->usr.motionplus.yaw_slow; + rpt->pitch_slow = state->usr.motionplus.pitch_slow; + rpt->roll_slow = state->usr.motionplus.roll_slow; + + rpt->ext = 0; + rpt->unused_0 = 1; + + break; + } + case 0x05: //motionplus + nunchuk + if (state->sys.extension_report) + { + struct report_ext_motionplus * rpt = (struct report_ext_motionplus *)buf; + + rpt->yaw_hi = state->usr.motionplus.yaw_down >> 8; + rpt->yaw_lo = state->usr.motionplus.yaw_down; + rpt->roll_hi = state->usr.motionplus.roll_left >> 8; + rpt->roll_lo = state->usr.motionplus.roll_left; + rpt->pitch_hi = state->usr.motionplus.pitch_left >> 8; + rpt->pitch_lo = state->usr.motionplus.pitch_left; + + rpt->yaw_slow = state->usr.motionplus.yaw_slow; + rpt->pitch_slow = state->usr.motionplus.pitch_slow; + rpt->roll_slow = state->usr.motionplus.roll_slow; + + rpt->ext = 1; + rpt->unused_0 = 1; + + state->sys.extension_report = 0; + } + else + { + struct report_ext_nunchuk_pt * rpt = (struct report_ext_nunchuk_pt *)buf; + + rpt->x = state->usr.nunchuk.x; + rpt->y = state->usr.nunchuk.y; + + rpt->accel_x_hi = state->usr.nunchuk.accel_x >> 2; + rpt->accel_y_hi = state->usr.nunchuk.accel_y >> 2; + rpt->accel_z_hi = state->usr.nunchuk.accel_z >> 3; + rpt->accel_x_lo = state->usr.nunchuk.accel_x >> 1; + rpt->accel_y_lo = state->usr.nunchuk.accel_y >> 1; + rpt->accel_z_lo = state->usr.nunchuk.accel_z >> 1; + + rpt->c = !state->usr.nunchuk.c; + rpt->z = !state->usr.nunchuk.z; + + rpt->ext = 1; + + state->sys.extension_report = 1; + } + break; + case 0x07: //motionplus + classic + if (state->sys.extension_report) + { + struct report_ext_motionplus * rpt = (struct report_ext_motionplus *)buf; + + rpt->yaw_hi = state->usr.motionplus.yaw_down >> 8; + rpt->yaw_lo = state->usr.motionplus.yaw_down; + rpt->roll_hi = state->usr.motionplus.roll_left >> 8; + rpt->roll_lo = state->usr.motionplus.roll_left; + rpt->pitch_hi = state->usr.motionplus.pitch_left >> 8; + rpt->pitch_lo = state->usr.motionplus.pitch_left; + + rpt->yaw_slow = state->usr.motionplus.yaw_slow; + rpt->pitch_slow = state->usr.motionplus.pitch_slow; + rpt->roll_slow = state->usr.motionplus.roll_slow; + + rpt->ext = 1; + rpt->unused_0 = 1; + + state->sys.extension_report = 0; + } + else + { + struct report_ext_classic_pt * rpt = (struct report_ext_classic_pt *)buf; + + rpt->lx = state->usr.classic.ls_x >> 1; + rpt->ly = state->usr.classic.ls_y >> 1; + rpt->rx_hi = state->usr.classic.rs_x >> 3; + rpt->rx_m = state->usr.classic.rs_x >> 1; + rpt->rx_lo = state->usr.classic.rs_x; + rpt->ry = state->usr.classic.rs_y; + + rpt->lt_hi = state->usr.classic.lt >> 3; + rpt->lt_lo = state->usr.classic.lt; + rpt->rt = state->usr.classic.rt; + + rpt->left = !state->usr.classic.left; + rpt->right = !state->usr.classic.right; + rpt->up = !state->usr.classic.up; + rpt->down = !state->usr.classic.down; + rpt->ltrigger = !state->usr.classic.ltrigger; + rpt->rtrigger = !state->usr.classic.rtrigger; + rpt->lz = !state->usr.classic.lz; + rpt->rz = !state->usr.classic.rz; + rpt->a = !state->usr.classic.a; + rpt->b = !state->usr.classic.b; + rpt->x = !state->usr.classic.x; + rpt->y = !state->usr.classic.y; + rpt->plus = !state->usr.classic.plus; + rpt->minus = !state->usr.classic.minus; + rpt->home = !state->usr.classic.home; + + rpt->ext = 1; + + state->sys.extension_report = 1; + } + break; + } + + + if (state->sys.extension_encrypted) + { + ext_encrypt_bytes(&state->sys.extension_crypto_state, buf, addr_offset, length); + } +} diff --git a/Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.h b/Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.h new file mode 100644 index 00000000..8d8d1edb --- /dev/null +++ b/Firmware/RP2040/src/Wii/wiimote-lib/wm_reports.h @@ -0,0 +1,381 @@ +//Portability note: may need modifcation for different targets (endianness, etc.) + +#ifndef WM_REPORTS_H +#define WM_REPORTS_H + +#include "wiimote.h" +#include + +#define OFFSET24(offset32) ((offset32)<<8) + +struct report_data +{ + uint8_t io; + uint8_t type; + uint8_t buf[21]; + uint8_t padding; +} __attribute__((packed)); + +struct report +{ + uint32_t len; //data (packet) length + struct report_data data; +}; + +struct queued_report +{ + struct queued_report * next; + struct report rpt; +}; + +/* Output reports (from controller) */ + +struct report_buttons +{ + int left:1; + int right:1; + int down:1; + int up:1; + int plus:1; + int accel_0:2; + int unused:1; + + int two:1; + int one:1; + int b:1; + int a:1; + int minus:1; + int accel_1:2; + int home:1; +} __attribute__((packed)); + +struct report_accelerometer +{ + struct report_buttons buttons; + + uint8_t x; + uint8_t y; + uint8_t z; +} __attribute__((packed)); + +struct report_ir_basic +{ + uint8_t x1_lo; + uint8_t y1_lo; + + int x2_hi:2; + int y2_hi:2; + int x1_hi:2; + int y1_hi:2; + + uint8_t x2_lo; + uint8_t y2_lo; + + uint8_t x3_lo; + uint8_t y3_lo; + + int x4_hi:2; + int y4_hi:2; + int x3_hi:2; + int y3_hi:2; + + uint8_t x4_lo; + uint8_t y4_lo; +} __attribute__((packed)); + +struct report_ir_ext_obj +{ + uint8_t x_lo; + uint8_t y_lo; + + int size:4; + int x_hi:2; + int y_hi:2; +} __attribute__((packed)); + +struct report_ir_ext +{ + struct report_ir_ext_obj obj[4]; +} __attribute__((packed)); + +struct report_ir_full_obj +{ + uint8_t x_lo; + uint8_t y_lo; + + int size:4; + int x_hi:2; + int y_hi:2; + + int x_min:7; + int unused0:1; + int y_min:7; + int unused1:1; + int x_max:7; + int unused2:1; + int y_max:7; + int unused3:1; + + uint8_t unused4; + uint8_t intensity; +} __attribute__((packed)); + +struct report_interleaved +{ + struct report_buttons buttons; + + uint8_t accel; + + struct report_ir_full_obj obj[2]; +} __attribute__((packed)); + +struct report_ext_nunchuk +{ + uint8_t x; + uint8_t y; + uint8_t accel_x_hi; + uint8_t accel_y_hi; + uint8_t accel_z_hi; + + int z:1; + int c:1; + int accel_x_lo:2; + int accel_y_lo:2; + int accel_z_lo:2; +} __attribute__((packed)); + +struct report_ext_nunchuk_pt +{ + //different format if in passthrough mode with motionplus + uint8_t x; + uint8_t y; + uint8_t accel_x_hi; + uint8_t accel_y_hi; + + int accel_z_hi:7; + int ext:1; + + int unused:2; + int z:1; + int c:1; + int accel_x_lo:1; + int accel_y_lo:1; + int accel_z_lo:2; +} __attribute__((packed)); + +struct report_ext_classic +{ + int lx:6; + int rx_hi:2; + + int ly:6; + int rx_m:2; + + int ry:5; + int lt_hi:2; + int rx_lo:1; + + int rt:5; + int lt_lo:3; + + int unused:1; + int rtrigger:1; + int plus:1; + int home:1; + int minus:1; + int ltrigger:1; + int down:1; + int right:1; + + int up:1; + int left:1; + int rz:1; + int x:1; + int a:1; + int y:1; + int b:1; + int lz:1; +} __attribute__((packed)); + +struct report_ext_classic_pt +{ + //different format if in passthrough mode with motionplus + int up:1; + int lx:5; + int rx_hi:2; + + int left:1; + int ly:5; + int rx_m:2; + + int ry:5; + int lt_hi:2; + int rx_lo:1; + + int lt_lo:3; + int rt:5; + + int ext:1; + int rtrigger:1; + int plus:1; + int home:1; + int minus:1; + int ltrigger:1; + int down:1; + int right:1; + + int unused:2; + int rz:1; + int x:1; + int a:1; + int y:1; + int b:1; + int lz:1; +} __attribute__((packed)); + +struct report_ext_motionplus +{ + uint8_t yaw_lo; + uint8_t roll_lo; + uint8_t pitch_lo; + + int pitch_slow:1; + int yaw_slow:1; + int yaw_hi:6; + + int ext:1; + int roll_slow:1; + int roll_hi:6; + + int unused_1:1; + int unused_0:1; + int pitch_hi:6; +} __attribute__((packed)); + +struct report_status +{ + struct report_buttons buttons; + + int low_battery:1; + int extension_connected:1; + int speaker_enabled:1; + int ircam_enabled:1; + int led_1:1; + int led_2:1; + int led_3:1; + int led_4:1; + + uint8_t unused0; + uint8_t unused1; + + uint8_t battery_level; +} __attribute__((packed)); + +struct report_mem_resp +{ + struct report_buttons buttons; + + int error:4; + int size:4; + + uint16_t addr; //big endian + + uint8_t data[16]; +} __attribute__((packed)); + +struct report_ack +{ + struct report_buttons buttons; + + uint8_t report; + uint8_t result; +} __attribute__((packed)); + +/* Input reports (from wii) */ + +struct report_rumble +{ + int rumble:1; + int unused:7; +} __attribute__((packed)); + +struct report_leds +{ + int rumble:1; + int unused:3; + int led_1:1; + int led_2:1; + int led_3:1; + int led_4:1; +} __attribute__((packed)); + +struct report_mode +{ + int rumble:1; + int unused1:1; + int continuous:1; + int unused0:5; + + uint8_t mode; +} __attribute__((packed)); + +struct report_ir_enable +{ + int rumble:1; + int ack_requested:1; + int enabled:1; + int unused0:5; +} __attribute__((packed)); + +struct report_speaker_enable +{ + int rumble:1; + int unused1:1; + int muted:1; + int unused0:5; +} __attribute__((packed)); + +struct report_mem_read +{ + int rumble:1; + int unused1:1; + int source0:1; + int source1:1; + int unused0:4; + + uint32_t offset:24; //big endian + uint16_t size; //big endian +} __attribute__((packed)); + +struct report_mem_write +{ + int rumble:1; + int unused1:1; + int source0:1; + int source1:1; + int unused0:4; + + uint32_t offset:24; //big endian + uint8_t size; + + uint8_t data[16]; +} __attribute__((packed)); + +struct report * report_queue_push(struct wiimote_state * state); +struct report * report_queue_peek(struct wiimote_state * state); +void report_queue_pop(struct wiimote_state * state); + +void report_queue_push_ack(struct wiimote_state *state, uint8_t report, uint8_t result); +void report_queue_push_status(struct wiimote_state * state); + +void report_format_mem_resp(struct wiimote_state * state, struct report * rpt, + int size, int error, uint16_t addr, uint8_t * buf, bool encrypt); + +void report_append_buttons(struct wiimote_state * state, uint8_t * buf); +void report_append_accelerometer(struct wiimote_state * state, uint8_t * buf); +void report_append_ir_10(struct wiimote_state * state, uint8_t * buf); +void report_append_ir_12(struct wiimote_state * state, uint8_t * buf); +void report_append_interleaved(struct wiimote_state * state, uint8_t * buf); +void report_append_extension(struct wiimote_state * state, uint8_t * buf, uint8_t bytes); + +#endif diff --git a/Firmware/RP2040/src/main.cpp b/Firmware/RP2040/src/main.cpp index 51f2254e..0fb12b1b 100644 --- a/Firmware/RP2040/src/main.cpp +++ b/Firmware/RP2040/src/main.cpp @@ -1,18 +1,33 @@ #include +#include #include "OGXMini/OGXMini.h" #include "pico/stdlib.h" #include "pico/flash.h" -#include +#include "hardware/uart.h" +#include "hardware/gpio.h" + +#ifndef PICO_DEFAULT_UART_BAUD_RATE +#define PICO_DEFAULT_UART_BAUD_RATE 115200 +#endif int main() { stdio_init_all(); - uart_init(uart0, 115200); // Initialize UART0 at 115200 baud - gpio_set_function(0, GPIO_FUNC_UART); // TX - gpio_set_function(1, GPIO_FUNC_UART); // RX + +#if defined(PICO_DEFAULT_UART_TX_PIN) && defined(PICO_DEFAULT_UART_RX_PIN) + // Use build-defined UART pins (e.g. Debug: GP4/GP5 UART1 for Pico W/2W) + uart_inst_t* uart = (PICO_DEFAULT_UART == 0) ? uart0 : uart1; + uart_init(uart, PICO_DEFAULT_UART_BAUD_RATE); + gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART); + gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART); +#else + uart_init(uart0, PICO_DEFAULT_UART_BAUD_RATE); + gpio_set_function(0, GPIO_FUNC_UART); + gpio_set_function(1, GPIO_FUNC_UART); +#endif printf("Debug ready\n"); - flash_safe_execute_core_init(); + flash_safe_execute_core_init(); OGXMini::initialize(); OGXMini::run(); diff --git a/README.md b/README.md index b004a922..e14adc8f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles - Playstation Classic - DInput - Wii U (GameCube Adapter) +- **Wii (Wiimote)** — Pico W / Pico 2 W only; build with `-DOGXM_FIXED_DRIVER=WII`. See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). + +**RP2040 output modes (USB device):** XInput (Xbox 360 + XSM3), DInput, PS3, Switch, Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. On Pico 2 W, Bluetooth runs on Core1 and USB on Core0; you can build with a fixed mode or use button combos to switch at runtime (Start + D-pad held ~3 s). **Wii is not in the combo list** — use a Wii-only build to get Wiimote output. ## Changing platforms By default the OGX-Mini will emulate an OG Xbox controller, you must hold a button combo for 3 seconds to change which platform you want to play on. Your chosen mode will persist after powering off the device. @@ -38,6 +41,7 @@ Start = Plus (Switch) = Options (Dualsense/DS4) - Web Application Mode - Start + Left Bumper + Right Bumper +**Wii (Wiimote)** is not selectable by combo. Build with `-DOGXM_FIXED_DRIVER=WII` for a Wii-only firmware; see [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). After a new mode is stored, the RP2040 will reset itself so you don't need to unplug it. @@ -89,7 +93,10 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. ==== Version 1.0.0.4a === +- **Wii (Wiimote) output mode** — On Pico W and Pico 2 W, build with `-DOGXM_FIXED_DRIVER=WII` for a Wii-only firmware. The adapter appears as a Wiimote over Bluetooth; use a USB gamepad on the external PIO USB port. Supports No Extension, Nunchuk, and Classic Controller report modes (cycle with Home + D-pad Down). See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). _Approach and mappings based on [PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)._ - Xbox 360 no longer requires the USB patch to authenticate, uses the same authentication as Joypad-OS to do official handshake with Retail consoles. Homebrew/ Jailbreaking is no longer required to use the XINPUT mode on 360 but it will no longer output to PC. +- **Rumble fix for Xbox 360 controllers** — Rumble on 360 pads is now handled correctly when using the adapter (including wireless RUMBLE_ENABLE sequence). _Xbox 360 host rumble handling based on [GP2040-CE](https://github.com/OpenStickCommunity/GP2040-CE)._ +- **Pico 2 / Pico 2 W build fixes** — Firmware builds and runs correctly on RP2350 (Pico 2 and Pico 2 W). - Improved latency on Xbox 360 and PS3 controllers. - Added build flags so you can make it only output in a specific mode and disable mode switching. - Using a PS5 controller allows you to tap the touchpad to enable or disable the adaptive triggers. @@ -150,9 +157,8 @@ If your third party controller isn't working, but the original version is listed ## Build ### RP2040 -You can compile this for different boards with the CMake argument ```OGXM_BOARD``` while configuring the project. +Build with **CMake** from the `Firmware/RP2040` directory. You can compile for different boards with the CMake argument ```OGXM_BOARD```: -The options are: - ```PI_PICO``` - ```PI_PICO2``` - ```PI_PICOW``` @@ -163,7 +169,7 @@ The options are: - ```ESP32_BLUERETRO_I2C``` - ```EXTERNAL_4CH_I2C``` -You can also set ```MAX_GAMEPADS``` which, if greater than one, will only support DInput (PS3) and Switch. +You can also set ```MAX_GAMEPADS``` (if > 1, only DInput/PS3 and Switch are supported). **Optional:** ```OGXM_FIXED_DRIVER``` to lock output mode (e.g. ```XINPUT```, ```PS3```); ```OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON``` to keep combos when fixed. ```MAIN_LOOP_DELAY_US``` (default ```0```) sets main-loop delay for lower CPU use (e.g. ```250```). You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. Here's an example on Windows: ``` @@ -172,7 +178,16 @@ cd OGX-Mini-2026/Firmware/RP2040 cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DOGXM_BOARD=PI_PICOW -DMAX_GAMEPADS=1 cmake --build build ``` -Or just install the GCC ARM toolchain and use the CMake Tools extension in VSCode. +Outputs (`.elf`, `.uf2`, etc.) are in the build directory; flash the `.uf2` to the board. Or use the GCC ARM toolchain and CMake Tools extension in VSCode. + +**Latency:** The adapter sends the latest gamepad state whenever the USB endpoint is free (XInput and similar), and the main loop has no added delay by default, so the host gets updates at its poll rate with minimal latency. See [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md#latency-reduction) for details. + +### Firmware documentation +| Document | Description | +|---------|-------------| +| [Wii_Mode_Guide.md](Firmware/RP2040/docs/Wii_Mode_Guide.md) | Wii mode (build-option only): No Extension / Nunchuk / Classic, USB host, sync and auto-connect, button mapping. | +| [PICO2W_WII_USB_SETUP.md](Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | +| [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360. | ### ESP32 Please see the Hardware directory for a diagram showing how to hookup the ESP32 to your RP2040. @@ -186,9 +201,10 @@ When you build with ESP-IDF, Cmake will run a python script that copies the nece ## Other projects that have helped enhance this fork -- **[Joypad OS](https://github.com/joypad-ai/joypad-os)** — Reference for Xbox 360 (XSM3) authentication with retail consoles; XInput mode on 360 follows the same approach. +- **[Joypad OS](https://github.com/joypad-ai/joypad-os)** — Reference for Xbox 360 (XSM3) authentication with retail consoles; XInput mode on 360 follows the same approach. Descriptors and XSM3 flow are aligned with joypad-os; single config, full XSM3 security string, init/verify in main loop; USB is initialized before Core1 so the 360 can enumerate while BT loads. - **[Bluepad32](https://github.com/ricardoquesada/bluepad32)** — Bluetooth controller support (Pico W / Pico 2 W). -- **[GP2040-CE](https://github.com/OpenStickCommunity/GP2040-CE)** — USB device output modes (credited in the root LICENSE). +- **[GP2040-CE](https://github.com/OpenStickCommunity/GP2040-CE)** — USB device output modes and Xbox 360 controller rumble fix (host-side rumble handling, including wireless RUMBLE_ENABLE sequence); credited in the root LICENSE. +- **[PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)** — Wii (Wiimote) output mode: approach of USB gamepad on PIO USB with Bluetooth reserved for the Wiimote link, and button/stick mappings for No Extension, Nunchuk, and Classic Controller report modes. ## Licenses and third-party code From 723437d6f38af2efe721c67182edd23f491ec0fd Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Wed, 4 Mar 2026 16:32:19 -0500 Subject: [PATCH 23/42] Switch Pro emulation, v1.0.0a5, README and build exclusions - Switch mode: full Nintendo Switch Pro Controller emulation (report format, subcommands, init handshake) - SwitchPro.h: correct Pro report button byte layout (Y/X/B/A bits per hardware reference) - Switch device: face-button mapping and SwitchProDevice.h descriptors - README: Switch Pro emulation description, retro-pico-switch attribution, version 1.0.0.5a - Version bump to v1.0.0a5 (FWDefines.cmake) - .gitignore: exclude Firmware/RP2040/build_* (release build dirs) Made-with: Cursor --- .gitignore | 1 + Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/CMakeLists.txt | 7 + Firmware/RP2040/docs/IMPROVEMENTS.md | 26 +- Firmware/RP2040/src/Board/Config.h | 8 +- Firmware/RP2040/src/Descriptors/PS3.h | 3 +- Firmware/RP2040/src/Descriptors/SwitchPro.h | 396 ++++++---------- .../RP2040/src/Descriptors/SwitchProDevice.h | 55 +++ .../RP2040/src/OGXMini/Board/Standard.cpp | 2 +- Firmware/RP2040/src/OGXMini/OGXMini.cpp | 5 + .../src/USBDevice/DeviceDriver/PS3/PS3.cpp | 46 +- .../src/USBDevice/DeviceDriver/PS3/PS3.h | 2 + .../USBDevice/DeviceDriver/Switch/Switch.cpp | 438 ++++++++++++++---- .../USBDevice/DeviceDriver/Switch/Switch.h | 36 +- .../DeviceDriver/XboxOG/XboxOG_GP.cpp | 62 ++- .../USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h | 6 + LICENSE | 4 + README.md | 25 +- 18 files changed, 713 insertions(+), 411 deletions(-) create mode 100644 Firmware/RP2040/src/Descriptors/SwitchProDevice.h diff --git a/.gitignore b/.gitignore index af8cf84d..e83f8035 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ Firmware/.vscode Firmware/RP2040/build +Firmware/RP2040/build_* Firmware/RP2040/scripts Firmware/RP2040/.ignore Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid_xremote_rom.h diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index c425732b..0328032e 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a4") \ No newline at end of file +set(FW_VERSION "v1.0.0a5") \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 839577b3..a6010a36 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -183,6 +183,13 @@ elseif(OGXM_BOARD STREQUAL "ESP32_BLUERETRO_I2C") add_compile_definitions(OGXM_RETAIL=1) endif() +elseif(OGXM_BOARD STREQUAL "RP2350_USB_A") + add_compile_definitions(CONFIG_OGXM_BOARD_RP2350_USB_A=1) + set(EN_USB_HOST TRUE) + set(PICO_PLATFORM rp2350) + set(EN_RGB TRUE) + set(FLASH_SIZE_MB 2) + else() message(FATAL_ERROR "Invalid OGXM_BOARD value. See options in src/board_config.h") diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index c692c16e..92b65011 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -35,11 +35,11 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad --- -## PS3 mode — input delays and stuck inputs +## PS3 mode — input delays, stuck inputs, Home button, and analog stick emulation -**Source:** Fixes from [OGX-Mini-Plus](https://github.com/guimaraf/OGX-Mini-Plus) (v1.1.1) — *“PS3 Driver Fixes - Fixed input delays and stuck inputs.”* +**Source:** Fixes from [OGX-Mini-Plus](https://github.com/guimaraf/OGX-Mini-Plus) (v1.1.1) — *“PS3 Driver Fixes - Fixed input delays and stuck inputs.”* Plus subsequent improvements for Home (PS) button and DS3-accurate analog sticks. -**File:** `src/USBDevice/DeviceDriver/PS3/PS3.cpp` +**Files:** `src/USBDevice/DeviceDriver/PS3/PS3.cpp`, `src/Descriptors/PS3.h` ### Changes @@ -47,12 +47,13 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad - `report_in_.l2_axis` and `report_in_.r2_axis` are now set from `gp_in.trigger_l` and `gp_in.trigger_r`. - Previously left at zero, which could cause stuck or incorrect trigger behaviour on PS3. Filling these is required for many PS3 games. -2. **Joystick centre and deadzone** - - Replaced generic `Scale::int16_to_uint8()` (centre 128) with PS3-specific mapping: - - Centre **0x7F (127)** and ~5% deadzone (~1640 on a ±32768 scale). - - In deadzone, sticks report exactly 0x7F so the console does not see drift. - - Outside deadzone, values are scaled into 0–254 so 127 remains the logical centre. - - Avoids stick drift and “stuck” stick behaviour caused by wrong centre or jitter. +2. **DualShock 3–accurate analog sticks** + - Sticks now match the real DS3/Sixaxis HID spec: + - **Range:** 0–255 (full 8-bit; was 0–254). + - **Center:** **0x80 (128)** at rest and in deadzone (was 0x7F). Matches Linux gamepad spec and HID logical max 255. + - **Deadzone:** ~1.5% (512 on ±32768) so small movements register without drift; in deadzone the report sends 0x80. + - **Scaling:** Linear map from signed 16-bit input to 0–255 with correct rounding so center (0) → 128. + - Reduces stick drift and matches console expectations for DS3-compatible games. 3. **D-pad in analog mode** - When `gamepad.analog_enabled()` is true, D-pad axes (`up_axis`, `down_axis`, `left_axis`, `right_axis`) are now derived from the **digital** D-pad bits instead of `gp_in.analog[ANALOG_OFF_*]`. @@ -65,6 +66,11 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad - `square_axis` = BUTTON_X (was BUTTON_A) - Circle / Cross / Square now match the intended face buttons. +5. **Home (PS) button** + - Report is built only when `tud_hid_ready()` (right before send), using `gamepad.get_pad_in()` so the console gets the latest state (helps with DS4/DS5 over Bluetooth). + - **PS button latch:** When `BUTTON_SYS` is set, the driver latches the PS bit for 8 consecutive report frames so short taps are not missed by timing. `buttons[2]` bit 0 (PS) and bit 1 (Touchpad) are set from `BUTTON_SYS` and `BUTTON_MISC`. + - If Home does not work over Bluetooth, try a wired controller (some consoles only react to the first controller's Home). + --- ## Latency reduction @@ -110,5 +116,5 @@ In XInput mode, the adapter no longer sends a report only when `gamepad.new_pad_ | Area | Improvement | |------|-------------| | **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). | -| **PS3** | Stuck inputs and input delays addressed via L2/R2 axes, joystick centre/deadzone, D-pad handling, and face button mapping. | +| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. | | **Latency** | Main loop delay default **0 µs** (low latency); XInput always sends latest state when USB is ready for lower latency with PS5/Xbox One over BT. | diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index a40ecf60..32b3a1e8 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -9,7 +9,8 @@ #define ESP32_BLUERETRO_I2C 5 #define EXTERNAL_4CH_I2C 6 #define INTERNAL_4CH_I2C 7 -#define BOARDS_COUNT 8 +#define RP2350_USB_A 8 +#define BOARDS_COUNT 9 #define SYSCLOCK_KHZ 240000 @@ -99,6 +100,11 @@ #define MAX_GAMEPADS 1 #endif +#elif defined(CONFIG_OGXM_BOARD_RP2350_USB_A) + #define OGXM_BOARD RP2350_USB_A + #define PIO_USB_DP_PIN 12 + #define RGB_PXL_PIN 16 + #else #error "Invalid OGXMini board selected" diff --git a/Firmware/RP2040/src/Descriptors/PS3.h b/Firmware/RP2040/src/Descriptors/PS3.h index 72516d67..64fde73e 100644 --- a/Firmware/RP2040/src/Descriptors/PS3.h +++ b/Firmware/RP2040/src/Descriptors/PS3.h @@ -8,7 +8,8 @@ namespace PS3 { static constexpr uint8_t MAGIC_BYTES[8] = { 0x21, 0x26, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - static constexpr uint8_t JOYSTICK_MID = 0x7F; + // DS3/Sixaxis analog sticks: 8-bit range 0–255, center 0x80 (128) per HID spec + static constexpr uint8_t JOYSTICK_MID = 0x80; static constexpr uint16_t SIXAXIS_MID = 0xFF01; namespace ReportID diff --git a/Firmware/RP2040/src/Descriptors/SwitchPro.h b/Firmware/RP2040/src/Descriptors/SwitchPro.h index 6b209efd..eb4ed0de 100644 --- a/Firmware/RP2040/src/Descriptors/SwitchPro.h +++ b/Firmware/RP2040/src/Descriptors/SwitchPro.h @@ -1,270 +1,134 @@ -#ifndef SWITCH_PRO_DESCRIPTORS_H_ -#define SWITCH_PRO_DESCRIPTORS_H_ +#ifndef _SWITCH_PRO_DESCRIPTORS_H_ +#define _SWITCH_PRO_DESCRIPTORS_H_ #include -namespace SwitchPro +/** + * Shared Switch Pro Controller types for both USB Host (parsing a real Pro) + * and USB Device (emulating a Pro). Host uses InReport, OutReport, CMD, Buttons*. + * Device uses the same InReport (as SwitchReport), Btn, HAT_*, and descriptors from SwitchProDevice.h. + */ +namespace SwitchPro { - static constexpr uint8_t INFO_CONN_MASK = 0xAB; - static constexpr uint8_t INFO_BATTERY_MASK = 0x0F; - - namespace CMD - { - static constexpr uint8_t HID = 0x80; - static constexpr uint8_t RUMBLE_ONLY = 0x10; - static constexpr uint8_t AND_RUMBLE = 0x01; - static constexpr uint8_t LED = 0x30; - static constexpr uint8_t LED_HOME = 0x38; - static constexpr uint8_t GYRO = 0x40; - static constexpr uint8_t MODE = 0x03; - static constexpr uint8_t FULL_REPORT_MODE = 0x30; - static constexpr uint8_t HANDSHAKE = 0x02; - static constexpr uint8_t DISABLE_TIMEOUT = 0x04; - } - - namespace Buttons0 - { - static constexpr uint8_t Y = 0x01; - static constexpr uint8_t X = 0x02; - static constexpr uint8_t B = 0x04; - static constexpr uint8_t A = 0x08; - static constexpr uint8_t R = 0x40; - static constexpr uint8_t ZR = 0x80; - }; - - namespace Buttons1 - { - static constexpr uint8_t MINUS = 0x01; - static constexpr uint8_t PLUS = 0x02; - static constexpr uint8_t L3 = 0x04; - static constexpr uint8_t R3 = 0x08; - static constexpr uint8_t HOME = 0x10; - static constexpr uint8_t CAPTURE = 0x20; - }; - - namespace Buttons2 - { - static constexpr uint8_t DPAD_DOWN = 0x01; - static constexpr uint8_t DPAD_UP = 0x02; - static constexpr uint8_t DPAD_RIGHT = 0x04; - static constexpr uint8_t DPAD_LEFT = 0x08; - static constexpr uint8_t L = 0x40; - static constexpr uint8_t ZL = 0x80; - }; - - #pragma pack(push, 1) - struct InReport - { - uint8_t report_id; - uint8_t timer; - - // uint8_t connInfo : 4; - // uint8_t battery : 4; - uint8_t info; - - uint8_t buttons[3]; - - // uint16_t leftX : 12; - // uint16_t leftY : 12; - // uint16_t rightX : 12; - // uint16_t rightY : 12; - uint8_t joysticks[6]; - - uint8_t vibrator; - - uint16_t accelerX; - uint16_t accelerY; - uint16_t accelerZ; - - uint16_t velocityX; - uint16_t velocityY; - uint16_t velocityZ; - }; - static_assert(sizeof(InReport) == 25, "InReport size is not correct"); - - struct OutReport - { - uint8_t command; - uint8_t sequence_counter; - uint8_t rumble_l[4]; - uint8_t rumble_r[4]; - uint8_t sub_command; - uint8_t sub_command_args[3]; - }; - static_assert(sizeof(OutReport) == 14, "OutReport size is not correct"); - #pragma pack(pop) - - -// static const uint8_t switch_pro_string_language[] = { 0x09, 0x04 }; -// static const uint8_t switch_pro_string_manufacturer[] = "Nintnedo Co., Ltd."; -// static const uint8_t switch_pro_string_product[] = "Pro Controller"; -// static const uint8_t switch_pro_string_version[] = "000000000001"; - -// static const uint8_t *switch_pro_string_descriptors[] __attribute__((unused)) = -// { -// switch_pro_string_language, -// switch_pro_string_product, // switch these? -// switch_pro_string_manufacturer, // ? -// switch_pro_string_version -// }; - -// static const uint8_t switch_pro_device_descriptor[] = -// { -// 0x12, // bLength -// 0x01, // bDescriptorType (Device) -// 0x00, 0x02, // bcdUSB 2.00 -// 0x00, // bDeviceClass (Use class information in the Interface Descriptors) -// 0x00, // bDeviceSubClass -// 0x00, // bDeviceProtocol -// 0x40, // bMaxPacketSize0 64 -// 0x7E, 0x05, // idVendor 0x057E -// 0x09, 0x20, // idProduct 0x2009 -// 0x00, 0x02, // bcdDevice 4.00 -// 0x01, // iManufacturer (String Index) -// 0x02, // iProduct (String Index) -// 0x03, // iSerialNumber (String Index) -// 0x01, // bNumConfigurations 1 -// }; - -// static const uint8_t switch_pro_configuration_descriptor[] = -// { -// 0x09, // bLength -// 0x02, // bDescriptorType (Configuration) -// 0x29, 0x00, // wTotalLength 41 -// 0x01, // bNumInterfaces 1 -// 0x01, // bConfigurationValue -// 0x00, // iConfiguration (String Index) -// 0xA0, // bmAttributes Remote Wakeup -// 0xFA, // bMaxPower 500mA - -// 0x09, // bLength -// 0x04, // bDescriptorType (Interface) -// 0x00, // bInterfaceNumber 0 -// 0x00, // bAlternateSetting -// 0x02, // bNumEndpoints 2 -// 0x03, // bInterfaceClass -// 0x00, // bInterfaceSubClass -// 0x00, // bInterfaceProtocol -// 0x00, // iInterface (String Index) - -// 0x09, // bLength -// 0x21, // bDescriptorType (HID) -// 0x11, 0x01, // bcdHID 1.11 -// 0x00, // bCountryCode -// 0x01, // bNumDescriptors -// 0x22, // bDescriptorType[0] (HID) -// 0xCB, 0x00, // wDescriptorLength[0] 203 - -// 0x07, // bLength -// 0x05, // bDescriptorType (Endpoint) -// 0x81, // bEndpointAddress (IN/D2H) -// 0x03, // bmAttributes (Interrupt) -// 0x40, 0x00, // wMaxPacketSize 64 -// 0x08, // bInterval 8 (unit depends on device speed) - -// 0x07, // bLength -// 0x05, // bDescriptorType (Endpoint) -// 0x01, // bEndpointAddress (OUT/H2D) -// 0x03, // bmAttributes (Interrupt) -// 0x40, 0x00, // wMaxPacketSize 64 -// 0x08, // bInterval 8 (unit depends on device speed) -// }; - -// static const uint8_t switch_pro_report_descriptor[] = -// { -// 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) -// 0x15, 0x00, // Logical Minimum (0) -// 0x09, 0x04, // Usage (Joystick) -// 0xA1, 0x01, // Collection (Application) -// 0x85, 0x30, // Report ID (48) -// 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) -// 0x05, 0x09, // Usage Page (Button) -// 0x19, 0x01, // Usage Minimum (0x01) -// 0x29, 0x0A, // Usage Maximum (0x0A) -// 0x15, 0x00, // Logical Minimum (0) -// 0x25, 0x01, // Logical Maximum (1) -// 0x75, 0x01, // Report Size (1) -// 0x95, 0x0A, // Report Count (10) -// 0x55, 0x00, // Unit Exponent (0) -// 0x65, 0x00, // Unit (None) -// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x05, 0x09, // Usage Page (Button) -// 0x19, 0x0B, // Usage Minimum (0x0B) -// 0x29, 0x0E, // Usage Maximum (0x0E) -// 0x15, 0x00, // Logical Minimum (0) -// 0x25, 0x01, // Logical Maximum (1) -// 0x75, 0x01, // Report Size (1) -// 0x95, 0x04, // Report Count (4) -// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x75, 0x01, // Report Size (1) -// 0x95, 0x02, // Report Count (2) -// 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x0B, 0x01, 0x00, 0x01, 0x00, // Usage (0x010001) -// 0xA1, 0x00, // Collection (Physical) -// 0x0B, 0x30, 0x00, 0x01, 0x00, // Usage (0x010030) -// 0x0B, 0x31, 0x00, 0x01, 0x00, // Usage (0x010031) -// 0x0B, 0x32, 0x00, 0x01, 0x00, // Usage (0x010032) -// 0x0B, 0x35, 0x00, 0x01, 0x00, // Usage (0x010035) -// 0x15, 0x00, // Logical Minimum (0) -// 0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65534) -// 0x75, 0x10, // Report Size (16) -// 0x95, 0x04, // Report Count (4) -// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0xC0, // End Collection -// 0x0B, 0x39, 0x00, 0x01, 0x00, // Usage (0x010039) -// 0x15, 0x00, // Logical Minimum (0) -// 0x25, 0x07, // Logical Maximum (7) -// 0x35, 0x00, // Physical Minimum (0) -// 0x46, 0x3B, 0x01, // Physical Maximum (315) -// 0x65, 0x14, // Unit (System: English Rotation, Length: Centimeter) -// 0x75, 0x04, // Report Size (4) -// 0x95, 0x01, // Report Count (1) -// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x05, 0x09, // Usage Page (Button) -// 0x19, 0x0F, // Usage Minimum (0x0F) -// 0x29, 0x12, // Usage Maximum (0x12) -// 0x15, 0x00, // Logical Minimum (0) -// 0x25, 0x01, // Logical Maximum (1) -// 0x75, 0x01, // Report Size (1) -// 0x95, 0x04, // Report Count (4) -// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x75, 0x08, // Report Size (8) -// 0x95, 0x34, // Report Count (52) -// 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) -// 0x85, 0x21, // Report ID (33) -// 0x09, 0x01, // Usage (0x01) -// 0x75, 0x08, // Report Size (8) -// 0x95, 0x3F, // Report Count (63) -// 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x85, 0x81, // Report ID (-127) -// 0x09, 0x02, // Usage (0x02) -// 0x75, 0x08, // Report Size (8) -// 0x95, 0x3F, // Report Count (63) -// 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -// 0x85, 0x01, // Report ID (1) -// 0x09, 0x03, // Usage (0x03) -// 0x75, 0x08, // Report Size (8) -// 0x95, 0x3F, // Report Count (63) -// 0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile) -// 0x85, 0x10, // Report ID (16) -// 0x09, 0x04, // Usage (0x04) -// 0x75, 0x08, // Report Size (8) -// 0x95, 0x3F, // Report Count (63) -// 0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile) -// 0x85, 0x80, // Report ID (-128) -// 0x09, 0x05, // Usage (0x05) -// 0x75, 0x08, // Report Size (8) -// 0x95, 0x3F, // Report Count (63) -// 0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile) -// 0x85, 0x82, // Report ID (-126) -// 0x09, 0x06, // Usage (0x06) -// 0x75, 0x08, // Report Size (8) -// 0x95, 0x3F, // Report Count (63) -// 0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile) -// 0xC0, // End Collection -// }; - -}; // namespace SwitchPro - -#endif // SWITCH_PRO_DESCRIPTORS_H_ \ No newline at end of file +#pragma pack(push, 1) + struct InReport + { + uint8_t batteryConnection; + uint8_t buttons[3]; + union + { + uint8_t joysticks[6]; + struct { uint8_t l[3]; uint8_t r[3]; }; + }; + }; + static_assert(sizeof(InReport) == 10, "InReport must be 10 bytes"); + + struct OutReport + { + uint8_t command; + uint8_t sequence_counter; + uint8_t rumble_l[4]; + uint8_t rumble_r[4]; + uint8_t sub_command; + uint8_t sub_command_args[5]; + }; +#pragma pack(pop) + + namespace CMD + { + static constexpr uint8_t RUMBLE_ONLY = 0x10; + static constexpr uint8_t HID = 0x11; + static constexpr uint8_t HANDSHAKE = 0x00; + static constexpr uint8_t DISABLE_TIMEOUT = 0x01; + static constexpr uint8_t AND_RUMBLE = 0x12; + static constexpr uint8_t LED = 0x30; + static constexpr uint8_t LED_HOME = 0x38; + static constexpr uint8_t MODE = 0x03; + static constexpr uint8_t FULL_REPORT_MODE = 0x30; + static constexpr uint8_t GYRO = 0x40; + } + + // First report byte (buttons_right): bit layout per real hardware / Bluepad32 parse_report_30_pro_controller + namespace Buttons0 + { + static constexpr uint8_t Y = (1U << 0); + static constexpr uint8_t X = (1U << 1); + static constexpr uint8_t B = (1U << 2); + static constexpr uint8_t A = (1U << 3); + static constexpr uint8_t R = (1U << 6); + static constexpr uint8_t ZR = (1U << 7); + } + namespace Buttons1 + { + static constexpr uint8_t MINUS = (1U << 0); + static constexpr uint8_t PLUS = (1U << 1); + static constexpr uint8_t L3 = (1U << 2); + static constexpr uint8_t R3 = (1U << 3); + static constexpr uint8_t HOME = (1U << 4); + static constexpr uint8_t CAPTURE = (1U << 5); + } + namespace Buttons2 + { + static constexpr uint8_t DPAD_UP = (1U << 0); + static constexpr uint8_t DPAD_DOWN = (1U << 1); + static constexpr uint8_t DPAD_LEFT = (1U << 2); + static constexpr uint8_t DPAD_RIGHT= (1U << 3); + static constexpr uint8_t L = (1U << 6); + static constexpr uint8_t ZL = (1U << 7); + } + + using SwitchReport = InReport; + + namespace Btn + { + static constexpr uint8_t Y = Buttons0::Y; + static constexpr uint8_t B = Buttons0::B; + static constexpr uint8_t A = Buttons0::A; + static constexpr uint8_t X = Buttons0::X; + static constexpr uint8_t R = Buttons0::R; + static constexpr uint8_t ZR = Buttons0::ZR; + static constexpr uint8_t MINUS = Buttons1::MINUS; + static constexpr uint8_t PLUS = Buttons1::PLUS; + static constexpr uint8_t L3 = Buttons1::L3; + static constexpr uint8_t R3 = Buttons1::R3; + static constexpr uint8_t HOME = Buttons1::HOME; + static constexpr uint8_t CAPTURE = Buttons1::CAPTURE; + static constexpr uint8_t L = Buttons2::L; + static constexpr uint8_t ZL = Buttons2::ZL; + } + + static constexpr uint8_t HAT_NEUTRAL = 0x00; + static constexpr uint8_t HAT_DOWN = 0x01; + static constexpr uint8_t HAT_UP = 0x02; + static constexpr uint8_t HAT_RIGHT = 0x04; + static constexpr uint8_t HAT_LEFT = 0x08; + static constexpr uint8_t HAT_DOWN_RIGHT = 0x05; + static constexpr uint8_t HAT_DOWN_LEFT = 0x09; + static constexpr uint8_t HAT_UP_RIGHT = 0x06; + static constexpr uint8_t HAT_UP_LEFT = 0x0A; + + static constexpr uint16_t STICK_MIN = 0x000; + static constexpr uint16_t STICK_MID = 0x7FF; + static constexpr uint16_t STICK_MAX = 0xFFF; + + static constexpr uint8_t REPORT_ID_STANDARD = 0x30; + static constexpr uint8_t REPORT_ID_SUBCMD = 0x21; + static constexpr uint8_t REPORT_ID_USB_INIT = 0x81; + static constexpr int REPORT_SIZE = 64; + static constexpr int USB_INIT_REPORT_SIZE = 64; + + static constexpr uint8_t SUBCMD_BT_PAIR = 0x01; + static constexpr uint8_t SUBCMD_DEVICE_INFO = 0x02; + static constexpr uint8_t SUBCMD_SET_MODE = 0x03; + static constexpr uint8_t SUBCMD_TRIGGER = 0x04; + static constexpr uint8_t SUBCMD_SHIPMENT = 0x08; + static constexpr uint8_t SUBCMD_SPI_READ = 0x10; + static constexpr uint8_t SUBCMD_NFC_IR_CFG = 0x21; + static constexpr uint8_t SUBCMD_NFC_IR_STATE= 0x22; + static constexpr uint8_t SUBCMD_SET_PLAYER = 0x30; + static constexpr uint8_t SUBCMD_IMU = 0x40; + static constexpr uint8_t SUBCMD_IMU_SENS = 0x41; + static constexpr uint8_t SUBCMD_VIBRATION = 0x48; +} + +#endif diff --git a/Firmware/RP2040/src/Descriptors/SwitchProDevice.h b/Firmware/RP2040/src/Descriptors/SwitchProDevice.h new file mode 100644 index 00000000..6b039fb6 --- /dev/null +++ b/Firmware/RP2040/src/Descriptors/SwitchProDevice.h @@ -0,0 +1,55 @@ +#ifndef _SWITCH_PRO_DEVICE_DESCRIPTORS_H_ +#define _SWITCH_PRO_DEVICE_DESCRIPTORS_H_ + +#include "Descriptors/SwitchPro.h" + +/** + * Nintendo Switch Pro Controller USB device descriptors (emulation). + * VID 0x057E, PID 0x2009. Report ID 0x30, 64-byte reports. + */ +namespace SwitchPro +{ + static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 }; + static const char STRING_MANUFACTURER[] = "Nintendo Co., Ltd."; + static const char STRING_PRODUCT[] = "Pro Controller"; + static const char STRING_VERSION[] = "000000000001"; + + static const uint8_t DEVICE_DESCRIPTOR[] = + { + 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x7E, 0x05, 0x09, 0x20, 0x10, 0x02, 0x01, 0x02, 0x03, 0x01 + }; + + static const uint8_t CONFIGURATION_DESCRIPTOR[] = + { + 0x09, 0x02, 0x29, 0x00, 0x01, 0x01, 0x00, 0xA0, 0xFA, + 0x09, 0x04, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, + 0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0xCB, 0x00, + 0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x08, + 0x07, 0x05, 0x01, 0x03, 0x40, 0x00, 0x08 + }; + + static const uint8_t REPORT_DESCRIPTOR[] = + { + 0x05, 0x01, 0x15, 0x00, 0x09, 0x04, 0xA1, 0x01, + 0x85, 0x30, 0x05, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0A, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0A, 0x55, 0x00, 0x65, 0x00, 0x81, 0x02, + 0x05, 0x09, 0x19, 0x0B, 0x29, 0x0E, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x04, 0x81, 0x02, + 0x75, 0x01, 0x95, 0x02, 0x81, 0x03, + 0x0B, 0x01, 0x00, 0x01, 0x00, 0xA1, 0x00, + 0x0B, 0x30, 0x00, 0x01, 0x00, 0x0B, 0x31, 0x00, 0x01, 0x00, 0x0B, 0x32, 0x00, 0x01, 0x00, 0x0B, 0x35, 0x00, 0x01, 0x00, + 0x15, 0x00, 0x27, 0xFF, 0xFF, 0x00, 0x00, 0x75, 0x10, 0x95, 0x04, 0x81, 0x02, + 0xC0, + 0x0B, 0x39, 0x00, 0x01, 0x00, 0x15, 0x00, 0x25, 0x07, 0x35, 0x00, 0x46, 0x3B, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x02, + 0x05, 0x09, 0x19, 0x0F, 0x29, 0x12, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x04, 0x81, 0x02, + 0x75, 0x08, 0x95, 0x34, 0x81, 0x03, + 0x06, 0x00, 0xFF, 0x85, 0x21, 0x09, 0x01, 0x75, 0x08, 0x95, 0x3F, 0x81, 0x03, + 0x85, 0x81, 0x09, 0x02, 0x75, 0x08, 0x95, 0x3F, 0x81, 0x03, + 0x85, 0x01, 0x09, 0x03, 0x75, 0x08, 0x95, 0x3F, 0x91, 0x83, + 0x85, 0x10, 0x09, 0x04, 0x75, 0x08, 0x95, 0x3F, 0x91, 0x83, + 0x85, 0x80, 0x09, 0x05, 0x75, 0x08, 0x95, 0x3F, 0x91, 0x83, + 0x85, 0x82, 0x09, 0x06, 0x75, 0x08, 0x95, 0x3F, 0x91, 0x83, + 0xC0 + }; +} + +#endif diff --git a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp index 575b4e0c..096350e6 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp @@ -1,6 +1,6 @@ #include "Board/Config.h" #include "OGXMini/Board/Standard.h" -#if ((OGXM_BOARD == PI_PICO) || (OGXM_BOARD == RP2040_ZERO) || (OGXM_BOARD == ADAFRUIT_FEATHER)) +#if ((OGXM_BOARD == PI_PICO) || (OGXM_BOARD == RP2040_ZERO) || (OGXM_BOARD == ADAFRUIT_FEATHER) || (OGXM_BOARD == RP2350_USB_A)) #include #include diff --git a/Firmware/RP2040/src/OGXMini/OGXMini.cpp b/Firmware/RP2040/src/OGXMini/OGXMini.cpp index a754c630..fd134dcc 100644 --- a/Firmware/RP2040/src/OGXMini/OGXMini.cpp +++ b/Firmware/RP2040/src/OGXMini/OGXMini.cpp @@ -22,6 +22,7 @@ namespace OGXMini { esp32_br_i2c::initialize, // ESP32_BLUERETRO_I2C four_ch_i2c::initialize, // EXTERNAL_4CH_I2C four_ch_i2c::initialize, // INTERNAL_4CH_I2C + standard::initialize, // RP2350_USB_A }; static constexpr RunFunc run_func[BOARDS_COUNT] = { @@ -33,6 +34,7 @@ namespace OGXMini { esp32_br_i2c::run, // ESP32_BLUERETRO_I2C four_ch_i2c::run, // EXTERNAL_4CH_I2C four_ch_i2c::run, // INTERNAL_4CH_I2C + standard::run, // RP2350_USB_A }; static constexpr HostMountedFunc host_mount_func[BOARDS_COUNT] = { @@ -44,6 +46,7 @@ namespace OGXMini { nullptr, // ESP32_BLUERETRO_I2C four_ch_i2c::host_mounted, // EXTERNAL_4CH_I2C four_ch_i2c::host_mounted, // INTERNAL_4CH_I2C + standard::host_mounted, // RP2350_USB_A }; static constexpr HostMountedWTypeFunc host_mount_w_type_func[BOARDS_COUNT] = { @@ -55,6 +58,7 @@ namespace OGXMini { nullptr, // ESP32_BLUERETRO_I2C four_ch_i2c::host_mounted_w_type, // EXTERNAL_4CH_I2C four_ch_i2c::host_mounted_w_type, // INTERNAL_4CH_I2C + nullptr, // RP2350_USB_A }; static constexpr WirelessConnectedFunc wl_conn_func[BOARDS_COUNT] = { @@ -66,6 +70,7 @@ namespace OGXMini { nullptr, // ESP32_BLUERETRO_I2C four_ch_i2c::wireless_connected, // EXTERNAL_4CH_I2C four_ch_i2c::wireless_connected, // INTERNAL_4CH_I2C + nullptr, // RP2350_USB_A }; void initialize() { diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp index dd12a038..e4fa4b49 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp @@ -20,7 +20,14 @@ void PS3Device::initialize() void PS3Device::process(const uint8_t idx, Gamepad& gamepad) { - if (gamepad.new_pad_in()) + // Build report only when we're about to send so the console gets the freshest state + // (helps Home button and analog timing with DS4/DS5 over Bluetooth). + if (tud_suspended()) + { + tud_remote_wakeup(); + } + + if (tud_hid_ready()) { Gamepad::PadIn gp_in = gamepad.get_pad_in(); report_in_ = PS3::InReport(); @@ -65,7 +72,13 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) if (gp_in.buttons & Gamepad::BUTTON_START) report_in_.buttons[0] |= PS3::Buttons0::START; if (gp_in.buttons & Gamepad::BUTTON_L3) report_in_.buttons[0] |= PS3::Buttons0::L3; if (gp_in.buttons & Gamepad::BUTTON_R3) report_in_.buttons[0] |= PS3::Buttons0::R3; - if (gp_in.buttons & Gamepad::BUTTON_SYS) report_in_.buttons[2] |= PS3::Buttons2::SYS; + // DS3 report: buttons[2] byte = PS (bit0), Touchpad (bit1). Latch PS so DS4/DS5 over BT short taps aren't missed. + if (gp_in.buttons & Gamepad::BUTTON_SYS) + sys_button_latch_frames_ = 8; + if (sys_button_latch_frames_ > 0) { + report_in_.buttons[2] |= PS3::Buttons2::SYS; + sys_button_latch_frames_--; + } if (gp_in.buttons & Gamepad::BUTTON_MISC) report_in_.buttons[2] |= PS3::Buttons2::TP; if (gp_in.trigger_l) report_in_.buttons[1] |= PS3::Buttons1::L2; @@ -75,22 +88,24 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) report_in_.l2_axis = gp_in.trigger_l; report_in_.r2_axis = gp_in.trigger_r; - // PS3 uses 0x7F (127) as joystick center; 5% deadzone avoids drift/stuck inputs - constexpr int16_t DEADZONE_LEFT = 1640; // ~5% of 32768 - constexpr int16_t DEADZONE_RIGHT = 1640; - constexpr uint8_t PS3_CENTER = 0x7F; + // Emulate DS3/Sixaxis sticks: 8-bit range 0–255, center 0x80 (128). Small deadzone (~1.5%) like real hardware. + constexpr int16_t DEADZONE = 512; // ~1.5% of 32768 + constexpr uint8_t PS3_CENTER = PS3::JOYSTICK_MID; // 0x80 auto joystick_to_ps3 = [](int16_t value, int16_t deadzone) -> uint8_t { if (value > -deadzone && value < deadzone) return PS3_CENTER; - int32_t scaled = ((static_cast(value) + 32768) * 254) / 65535; + int32_t in = static_cast(value) + 32768; + int32_t scaled = (in * 255 + 32768) / 65535; + if (scaled < 0) scaled = 0; + if (scaled > 255) scaled = 255; return static_cast(scaled); }; - report_in_.joystick_lx = joystick_to_ps3(gp_in.joystick_lx, DEADZONE_LEFT); - report_in_.joystick_ly = joystick_to_ps3(gp_in.joystick_ly, DEADZONE_LEFT); - report_in_.joystick_rx = joystick_to_ps3(gp_in.joystick_rx, DEADZONE_RIGHT); - report_in_.joystick_ry = joystick_to_ps3(gp_in.joystick_ry, DEADZONE_RIGHT); + report_in_.joystick_lx = joystick_to_ps3(gp_in.joystick_lx, DEADZONE); + report_in_.joystick_ly = joystick_to_ps3(gp_in.joystick_ly, DEADZONE); + report_in_.joystick_rx = joystick_to_ps3(gp_in.joystick_rx, DEADZONE); + report_in_.joystick_ry = joystick_to_ps3(gp_in.joystick_ry, DEADZONE); if (gamepad.analog_enabled()) { @@ -121,16 +136,7 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) report_in_.r1_axis = (gp_in.buttons & Gamepad::BUTTON_RB) ? 0xFF : 0; report_in_.l1_axis = (gp_in.buttons & Gamepad::BUTTON_LB) ? 0xFF : 0; } - } - if (tud_suspended()) - { - tud_remote_wakeup(); - } - - if (tud_hid_ready()) - { - //PS3 seems to start using stale data if a report isn't sent every frame tud_hid_report(0, reinterpret_cast(&report_in_), sizeof(PS3::InReport)); } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.h index 97f511a0..629540f2 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.h @@ -27,6 +27,8 @@ class PS3Device : public DeviceDriver PS3::BTInfo bt_info_; uint8_t ef_byte_; bool new_report_out_{false}; + // Latch PS button so short taps (DS4/DS5 over BT) aren't missed due to cross-core timing. + uint8_t sys_button_latch_frames_{0}; }; #endif // _PS3_DEVICE_H_ diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp index 2604e347..55cb5486 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp @@ -1,136 +1,388 @@ #include +#include "pico/time.h" + +#include "Board/ogxm_log.h" #include "USBDevice/DeviceDriver/Switch/Switch.h" +#include "Gamepad/Gamepad.h" +#include "Gamepad/Range.h" + +namespace +{ + constexpr uint8_t VIB_OPTS[4] = { 0x0A, 0x0C, 0x0B, 0x09 }; +} -void SwitchDevice::initialize() +void SwitchDevice::initialize() { - class_driver_ = - { + class_driver_ = { .name = TUD_DRV_NAME("SWITCH"), .init = hidd_init, - .deinit = hidd_deinit, + .deinit = hidd_deinit, .reset = hidd_reset, .open = hidd_open, .control_xfer_cb = hidd_control_xfer_cb, .xfer_cb = hidd_xfer_cb, .sof = NULL }; + switch_report_.batteryConnection = 0x81; + std::memset(report_.data(), 0, report_.size()); + std::memset(pending_output_.data(), 0, pending_output_.size()); + std::memset(report_81_.data(), 0, report_81_.size()); + has_pending_81_ = false; + OGXM_LOG("Switch: device init (Pro Controller emulation)\n"); +} + +void SwitchDevice::set_timer() +{ + if (timestamp_ms_ == 0) + { + timestamp_ms_ = to_ms_since_boot(get_absolute_time()); + report_[0] = 0x00; + return; + } + uint32_t now = to_ms_since_boot(get_absolute_time()); + uint32_t delta = now - timestamp_ms_; + uint32_t ticks = static_cast(delta * 4u); + timer_ = (timer_ + static_cast(ticks)) & 0xFF; + report_[0] = timer_; + timestamp_ms_ = now; +} + +void SwitchDevice::gamepad_to_switch_report(const Gamepad::PadIn& gp_in, SwitchPro::SwitchReport& out, const Gamepad& gamepad) +{ + out.batteryConnection = 0x81; + out.buttons[0] = 0; + out.buttons[1] = 0; + out.buttons[2] = 0; + + // Face: match project convention. SwitchPro host (SwitchPro.cpp) maps Pro→gamepad as: + // Pro Y→MAP_X, Pro B→MAP_A, Pro A→MAP_B, Pro X→MAP_Y. So device must output inverse: + // internal A→Pro B, B→Pro A, X→Pro Y, Y→Pro X. (PS: Cross=A→Pro B, Circle=B→Pro A, Square=X→Pro Y, Triangle=Y→Pro X.) + if (gp_in.buttons & Gamepad::BUTTON_A) out.buttons[0] |= SwitchPro::Btn::B; + if (gp_in.buttons & Gamepad::BUTTON_B) out.buttons[0] |= SwitchPro::Btn::A; + if (gp_in.buttons & Gamepad::BUTTON_X) out.buttons[0] |= SwitchPro::Btn::Y; + if (gp_in.buttons & Gamepad::BUTTON_Y) out.buttons[0] |= SwitchPro::Btn::X; + if (gp_in.buttons & gamepad.MAP_BUTTON_RB) out.buttons[0] |= SwitchPro::Btn::R; + if (gp_in.trigger_r) out.buttons[0] |= SwitchPro::Btn::ZR; + + if (gp_in.buttons & gamepad.MAP_BUTTON_BACK) out.buttons[1] |= SwitchPro::Btn::MINUS; + if (gp_in.buttons & gamepad.MAP_BUTTON_START) out.buttons[1] |= SwitchPro::Btn::PLUS; + if (gp_in.buttons & gamepad.MAP_BUTTON_L3) out.buttons[1] |= SwitchPro::Btn::L3; + if (gp_in.buttons & gamepad.MAP_BUTTON_R3) out.buttons[1] |= SwitchPro::Btn::R3; + if (gp_in.buttons & gamepad.MAP_BUTTON_SYS) out.buttons[1] |= SwitchPro::Btn::HOME; + if (gp_in.buttons & gamepad.MAP_BUTTON_MISC) out.buttons[1] |= SwitchPro::Btn::CAPTURE; + + uint8_t hat = SwitchPro::HAT_NEUTRAL; + if (gp_in.dpad & gamepad.MAP_DPAD_UP) hat |= SwitchPro::HAT_UP; + if (gp_in.dpad & gamepad.MAP_DPAD_DOWN) hat |= SwitchPro::HAT_DOWN; + if (gp_in.dpad & gamepad.MAP_DPAD_LEFT) hat |= SwitchPro::HAT_LEFT; + if (gp_in.dpad & gamepad.MAP_DPAD_RIGHT) hat |= SwitchPro::HAT_RIGHT; + out.buttons[2] = hat; + if (gp_in.buttons & gamepad.MAP_BUTTON_LB) out.buttons[2] |= SwitchPro::Btn::L; + if (gp_in.trigger_l) out.buttons[2] |= SwitchPro::Btn::ZL; + + // Sticks: int16 -> 12-bit (0x000–0xFFF), center 0x7FF. Small deadzone. + constexpr int16_t DZ = 512; + auto to12 = [](int16_t val) -> uint16_t { + if (val > -DZ && val < DZ) + return SwitchPro::STICK_MID; + int32_t v = static_cast(val) + 32768; + int32_t u = (v * 4095 + 32767) / 65535; + if (u < 0) u = 0; + if (u > 4095) u = 4095; + return static_cast(u); + }; + uint16_t lx = to12(gp_in.joystick_lx); + uint16_t ly = to12(gp_in.joystick_ly); + uint16_t rx = to12(gp_in.joystick_rx); + uint16_t ry = to12(gp_in.joystick_ry); + // Invert Y axes so up/down match Switch expectation (both sticks were reversed) + ly = static_cast(0xFFF - ly); + ry = static_cast(0xFFF - ry); + + out.l[0] = static_cast(lx & 0xFF); + out.l[1] = static_cast(((ly & 0x0F) << 4) | (lx >> 8)); + out.l[2] = static_cast(ly >> 4); + out.r[0] = static_cast(rx & 0xFF); + out.r[1] = static_cast(((ry & 0x0F) << 4) | (rx >> 8)); + out.r[2] = static_cast(ry >> 4); +} + +void SwitchDevice::build_standard_report(const SwitchPro::SwitchReport& sw) +{ + std::memset(report_.data(), 0, report_.size()); + set_timer(); + std::memcpy(report_.data() + 1, &sw, sizeof(SwitchPro::SwitchReport)); + if (vibration_enabled_) + { + vibration_idx_ = (vibration_idx_ + 1) % 4; + vibration_report_ = VIB_OPTS[vibration_idx_]; + } + report_[11] = vibration_report_; +} + +void SwitchDevice::build_subcommand_reply(const SwitchPro::SwitchReport& sw) +{ + std::memset(report_.data(), 0, report_.size()); + set_timer(); + std::memcpy(report_.data() + 1, &sw, sizeof(SwitchPro::SwitchReport)); + report_[11] = vibration_report_; + // Reply data starts at byte 12 in payload (timer=0, SwitchReport=1-10, vib=11, reply=12+) + uint8_t* r = report_.data() + 12; - in_report_.fill(SwitchWired::InReport()); + // Subcommand at byte 10 of host output report (retro-pico-switch layout) + uint8_t sub = pending_output_[10]; + OGXM_LOG("Switch: replying to subcmd=0x%02x\n", (unsigned)sub); + switch (sub) + { + case SwitchPro::SUBCMD_BT_PAIR: + r[0] = 0x81; r[1] = 0x01; r[2] = 0x03; + break; + case SwitchPro::SUBCMD_DEVICE_INFO: + r[0] = 0x82; r[1] = 0x02; r[2] = 0x03; r[3] = 0x48; r[4] = 0x03; r[5] = 0x02; + std::memcpy(r + 6, addr_.data(), 6); + r[12] = 0x01; r[13] = 0x01; + break; + case SwitchPro::SUBCMD_SHIPMENT: + r[0] = 0x80; r[1] = 0x08; + break; + case SwitchPro::SUBCMD_SET_MODE: + r[0] = 0x80; r[1] = 0x03; + break; + case SwitchPro::SUBCMD_TRIGGER: + r[0] = 0x83; r[1] = 0x04; + break; + case SwitchPro::SUBCMD_IMU: + r[0] = 0x80; r[1] = 0x40; + break; + case SwitchPro::SUBCMD_IMU_SENS: + r[0] = 0x80; r[1] = 0x41; + break; + case SwitchPro::SUBCMD_VIBRATION: + r[0] = 0x80; r[1] = 0x48; + vibration_enabled_ = true; + vibration_idx_ = 0; + vibration_report_ = VIB_OPTS[0]; + break; + case SwitchPro::SUBCMD_SET_PLAYER: + r[0] = 0x80; r[1] = 0x30; + break; + case SwitchPro::SUBCMD_NFC_IR_STATE: + r[0] = 0x80; r[1] = 0x22; + break; + case SwitchPro::SUBCMD_NFC_IR_CFG: + r[0] = 0xA0; r[1] = 0x21; + r[2] = 0x01; r[3] = 0x00; r[4] = 0xFF; r[5] = 0x00; r[6] = 0x08; r[7] = 0x00; r[8] = 0x1B; r[9] = 0x01; + r[37] = 0xC8; + break; + case SwitchPro::SUBCMD_SPI_READ: + { + r[0] = 0x90; r[1] = 0x10; + uint8_t addr_lo = pending_output_[11]; + uint8_t addr_hi = pending_output_[12]; + uint8_t read_len = pending_output_[15]; + r[2] = addr_lo; r[3] = addr_hi; r[6] = read_len; + if (addr_hi == 0x60 && addr_lo == 0x00) + std::memset(r + 7, 0xFF, 16); + else if (addr_hi == 0x60 && addr_lo == 0x50) + { + std::memset(r + 7, 0x32, 3); + std::memset(r + 10, 0xFF, 3); + std::memset(r + 13, 0xFF, 7); + } + else if (addr_hi == 0x60 && addr_lo == 0x80) + { + r[7] = 0x50; r[8] = 0xFD; r[9] = 0x00; r[10] = 0x00; r[11] = 0xC6; r[12] = 0x0F; + const uint8_t params[18] = { 0x0F, 0x30, 0x61, 0x96, 0x30, 0xF3, 0xD4, 0x14, 0x54, 0x41, 0x15, 0x54, 0xC7, 0x79, 0x9C, 0x33, 0x36, 0x63 }; + std::memcpy(r + 13, params, 18); + } + else if (addr_hi == 0x60 && addr_lo == 0x98) + { + const uint8_t params[18] = { 0x0F, 0x30, 0x61, 0x96, 0x30, 0xF3, 0xD4, 0x14, 0x54, 0x41, 0x15, 0x54, 0xC7, 0x79, 0x9C, 0x33, 0x36, 0x63 }; + std::memcpy(r + 7, params, 18); + } + else if (addr_hi == 0x80 && addr_lo == 0x10) + std::memset(r + 7, 0xFF, 3); + else if (addr_hi == 0x60 && addr_lo == 0x3D) + { + const uint8_t l_cal[9] = { 0xD4, 0x75, 0x61, 0xE5, 0x87, 0x7C, 0xEC, 0x55, 0x61 }; + const uint8_t r_cal[9] = { 0x5D, 0xD8, 0x7F, 0x18, 0xE6, 0x61, 0x86, 0x65, 0x5D }; + std::memcpy(r + 7, l_cal, 9); + std::memcpy(r + 16, r_cal, 9); + r[25] = 0xFF; + std::memset(r + 26, 0x32, 3); + std::memset(r + 29, 0xFF, 3); + } + else if (addr_hi == 0x60 && addr_lo == 0x20) + { + const uint8_t sa[24] = { 0xCC, 0x00, 0x40, 0x00, 0x91, 0x01, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0xE7, 0xFF, 0x0E, 0x00, 0xDC, 0xFF, 0x3B, 0x34, 0x3B, 0x34, 0x3B, 0x34 }; + std::memcpy(r + 7, sa, 24); + } + else + std::memset(r + 7, 0xFF, read_len); + break; + } + default: + r[0] = 0x80; r[1] = sub; + break; + } } -void SwitchDevice::process(const uint8_t idx, Gamepad& gamepad) +void SwitchDevice::process(const uint8_t idx, Gamepad& gamepad) { - SwitchWired::InReport& in_report = in_report_[idx]; - - if (gamepad.new_pad_in()) - { - Gamepad::PadIn gp_in = gamepad.get_pad_in(); - - switch (gp_in.dpad) - { - case Gamepad::DPAD_UP: - in_report.dpad = SwitchWired::DPad::UP; - break; - case Gamepad::DPAD_DOWN: - in_report.dpad = SwitchWired::DPad::DOWN; - break; - case Gamepad::DPAD_LEFT: - in_report.dpad = SwitchWired::DPad::LEFT; - break; - case Gamepad::DPAD_RIGHT: - in_report.dpad = SwitchWired::DPad::RIGHT; - break; - case Gamepad::DPAD_UP_LEFT: - in_report.dpad = SwitchWired::DPad::UP_LEFT; - break; - case Gamepad::DPAD_UP_RIGHT: - in_report.dpad = SwitchWired::DPad::UP_RIGHT; - break; - case Gamepad::DPAD_DOWN_LEFT: - in_report.dpad = SwitchWired::DPad::DOWN_LEFT; - break; - case Gamepad::DPAD_DOWN_RIGHT: - in_report.dpad = SwitchWired::DPad::DOWN_RIGHT; - break; - default: - in_report.dpad = SwitchWired::DPad::CENTER; - break; - } - - in_report.buttons = 0; - - if (gp_in.buttons & Gamepad::BUTTON_X) in_report.buttons |= SwitchWired::Buttons::Y; - if (gp_in.buttons & Gamepad::BUTTON_A) in_report.buttons |= SwitchWired::Buttons::B; - if (gp_in.buttons & Gamepad::BUTTON_Y) in_report.buttons |= SwitchWired::Buttons::X; - if (gp_in.buttons & Gamepad::BUTTON_B) in_report.buttons |= SwitchWired::Buttons::A; - if (gp_in.buttons & Gamepad::BUTTON_LB) in_report.buttons |= SwitchWired::Buttons::L; - if (gp_in.buttons & Gamepad::BUTTON_RB) in_report.buttons |= SwitchWired::Buttons::R; - if (gp_in.buttons & Gamepad::BUTTON_BACK) in_report.buttons |= SwitchWired::Buttons::MINUS; - if (gp_in.buttons & Gamepad::BUTTON_START) in_report.buttons |= SwitchWired::Buttons::PLUS; - if (gp_in.buttons & Gamepad::BUTTON_L3) in_report.buttons |= SwitchWired::Buttons::L3; - if (gp_in.buttons & Gamepad::BUTTON_R3) in_report.buttons |= SwitchWired::Buttons::R3; - if (gp_in.buttons & Gamepad::BUTTON_SYS) in_report.buttons |= SwitchWired::Buttons::HOME; - if (gp_in.buttons & Gamepad::BUTTON_MISC) in_report.buttons |= SwitchWired::Buttons::CAPTURE; - - if (gp_in.trigger_l) in_report.buttons |= SwitchWired::Buttons::ZL; - if (gp_in.trigger_r) in_report.buttons |= SwitchWired::Buttons::ZR; - - in_report.joystick_lx = Scale::int16_to_uint8(gp_in.joystick_lx); - in_report.joystick_ly = Scale::int16_to_uint8(gp_in.joystick_ly); - in_report.joystick_rx = Scale::int16_to_uint8(gp_in.joystick_rx); - in_report.joystick_ry = Scale::int16_to_uint8(gp_in.joystick_ry); - } + (void)idx; + Gamepad::PadIn gp_in = gamepad.get_pad_in(); + gamepad_to_switch_report(gp_in, switch_report_, gamepad); if (tud_suspended()) - { tud_remote_wakeup(); - } - if (tud_hid_n_ready(idx)) - { - tud_hid_n_report(idx, 0, reinterpret_cast(&in_report), sizeof(SwitchWired::InReport)); - } + + // USB init: host reads 0x81 from interrupt IN after sending 0x80 0x01/0x02/ etc. Push it first. + if (has_pending_81_ && tud_hid_n_ready(0)) + { + tud_hid_n_report(0, SwitchPro::REPORT_ID_USB_INIT, report_81_.data() + 1, 63); + has_pending_81_ = false; + return; + } + + bool is_subcommand = has_pending_output_; + if (has_pending_output_) + build_subcommand_reply(switch_report_); + else + build_standard_report(switch_report_); + + if (tud_hid_n_ready(0)) + { + tud_hid_n_report(0, is_subcommand ? SwitchPro::REPORT_ID_SUBCMD : SwitchPro::REPORT_ID_STANDARD, report_.data(), 63); + if (is_subcommand) + { + has_pending_output_ = false; + std::memset(pending_output_.data(), 0, pending_output_.size()); + } + } + else if (is_subcommand) + OGXM_LOG("Switch: HID not ready, subcommand reply dropped\n"); } -uint16_t SwitchDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) +uint16_t SwitchDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { - if (report_type != HID_REPORT_TYPE_INPUT || itf >= MAX_GAMEPADS) - { - return 0; - } - std::memcpy(buffer, &in_report_[itf], sizeof(SwitchWired::InReport)); - return sizeof(SwitchWired::InReport); + (void)itf; + // Log init and subcommand report requests (standard 0x30 polling is very frequent) + if (report_id == SwitchPro::REPORT_ID_USB_INIT) + OGXM_LOG("Switch: get_report id=0x81 (USB init) reqlen=%u\n", (unsigned)reqlen); + if (report_id == SwitchPro::REPORT_ID_SUBCMD) + OGXM_LOG("Switch: get_report id=0x21 (subcmd reply) reqlen=%u\n", (unsigned)reqlen); + if (report_type != HID_REPORT_TYPE_INPUT) + { + OGXM_LOG("Switch: get_report rejected (bad type)\n"); + return 0; + } + // Report ID 0x81: USB init handshake reply (MAC, handshake, timeout ack) + if (report_id == SwitchPro::REPORT_ID_USB_INIT) + { + if (!has_pending_81_ || reqlen < 2) + return 0; + uint16_t copy_len = reqlen < SwitchPro::USB_INIT_REPORT_SIZE ? reqlen : SwitchPro::USB_INIT_REPORT_SIZE; + std::memcpy(buffer, report_81_.data(), copy_len); + has_pending_81_ = false; + return copy_len; + } + if (report_id != SwitchPro::REPORT_ID_STANDARD && report_id != SwitchPro::REPORT_ID_SUBCMD) + { + OGXM_LOG("Switch: get_report rejected (bad id)\n"); + return 0; + } + if (reqlen < SwitchPro::REPORT_SIZE) + { + OGXM_LOG("Switch: get_report rejected (reqlen %u < %d)\n", (unsigned)reqlen, SwitchPro::REPORT_SIZE); + return 0; + } + buffer[0] = report_id; + std::memcpy(buffer + 1, report_.data(), 63); + return SwitchPro::REPORT_SIZE; } -void SwitchDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) {} +void SwitchDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) +{ + (void)itf; + (void)report_type; + OGXM_LOG("Switch: set_report id=0x%02x type=%u len=%u\n", (unsigned)report_id, (unsigned)report_type, (unsigned)bufsize); + if (bufsize > 12) + OGXM_LOG("Switch: cmd=0x%02x seq=0x%02x subcmd=0x%02x\n", + (unsigned)buffer[0], (unsigned)buffer[1], (unsigned)buffer[10]); + OGXM_LOG_HEX(buffer, bufsize > 64 ? 64 : bufsize); + if (bufsize > SwitchPro::REPORT_SIZE) + bufsize = SwitchPro::REPORT_SIZE; + std::memcpy(pending_output_.data(), buffer, bufsize); + // USB init: 2-byte reports [0x80, subtype] require reply on report ID 0x81 (Chromium / Switch console). + if (bufsize >= 2 && buffer[0] == 0x80) + { + uint8_t subtype = buffer[1]; + std::memset(report_81_.data(), 0, report_81_.size()); + report_81_[0] = SwitchPro::REPORT_ID_USB_INIT; + report_81_[1] = subtype; + if (subtype == 0x01) // Request MAC: subtype, padding, device_type (0x03 = Pro), mac[6] + { + report_81_[2] = 0x00; + report_81_[3] = 0x03; // kUsbDeviceTypeProController + std::memcpy(report_81_.data() + 4, addr_.data(), 6); + } + has_pending_81_ = true; + } + // Only queue a subcommand reply when the report has a subcommand at byte 10 (len >= 11). + else if (bufsize >= 11) + has_pending_output_ = true; + // Rumble: report_id 0x01/0x10/0x11, bytes 2-5 and 6-9 contain rumble data; we don't drive physical rumble here +} -bool SwitchDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +bool SwitchDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { - return false; + (void)rhport; + OGXM_LOG("Switch: vendor_control stage=%u bmReqType=0x%02x bReq=0x%02x wVal=0x%04x wIdx=0x%04x wLen=%u\n", + (unsigned)stage, (unsigned)request->bmRequestType, (unsigned)request->bRequest, + (unsigned)request->wValue, (unsigned)request->wIndex, (unsigned)request->wLength); + return false; } -const uint16_t* SwitchDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) +const uint16_t* SwitchDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) { - const char *value = reinterpret_cast(SwitchWired::STRING_DESCRIPTORS[index]); - return get_string_descriptor(value, index); + (void)langid; + OGXM_LOG("Switch: get_descriptor_string index=%u\n", (unsigned)index); + if (index == 0) + { + static uint16_t lang[2] = { 0x0304, 0x0409 }; + return lang; + } + const char* str = nullptr; + if (index == 1) str = SwitchPro::STRING_MANUFACTURER; + else if (index == 2) str = SwitchPro::STRING_PRODUCT; + else if (index == 3) str = SwitchPro::STRING_VERSION; + if (!str) + return nullptr; + return get_string_descriptor(str, index); } -const uint8_t* SwitchDevice::get_descriptor_device_cb() +const uint8_t* SwitchDevice::get_descriptor_device_cb() { - return SwitchWired::DEVICE_DESCRIPTORS; + OGXM_LOG("Switch: get_descriptor device\n"); + return SwitchPro::DEVICE_DESCRIPTOR; } -const uint8_t* SwitchDevice::get_hid_descriptor_report_cb(uint8_t itf) +const uint8_t* SwitchDevice::get_hid_descriptor_report_cb(uint8_t itf) { - return SwitchWired::REPORT_DESCRIPTORS; + (void)itf; + OGXM_LOG("Switch: get_descriptor HID report\n"); + return SwitchPro::REPORT_DESCRIPTOR; } -const uint8_t* SwitchDevice::get_descriptor_configuration_cb(uint8_t index) +const uint8_t* SwitchDevice::get_descriptor_configuration_cb(uint8_t index) { - return SwitchWired::CONFIGURATION_DESCRIPTORS; + (void)index; + OGXM_LOG("Switch: get_descriptor configuration\n"); + return SwitchPro::CONFIGURATION_DESCRIPTOR; } -const uint8_t* SwitchDevice::get_descriptor_device_qualifier_cb() +const uint8_t* SwitchDevice::get_descriptor_device_qualifier_cb() { return nullptr; -} \ No newline at end of file +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h index a0d016f9..c9e32a3e 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h @@ -3,26 +3,46 @@ #include #include +#include #include "USBDevice/DeviceDriver/DeviceDriver.h" -#include "Descriptors/SwitchWired.h" +#include "Descriptors/SwitchProDevice.h" -class SwitchDevice : public DeviceDriver +class SwitchDevice : public DeviceDriver { public: void initialize() override; void process(const uint8_t idx, Gamepad& gamepad) override; - uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) override; - void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) override; - bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) override; const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; const uint8_t* get_descriptor_device_cb() override; - const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; const uint8_t* get_descriptor_device_qualifier_cb() override; private: - std::array in_report_; + void gamepad_to_switch_report(const Gamepad::PadIn& gp_in, SwitchPro::SwitchReport& out, const Gamepad& gamepad); + void build_standard_report(const SwitchPro::SwitchReport& sw); + void build_subcommand_reply(const SwitchPro::SwitchReport& sw); + void set_timer(); + + std::array report_{}; + SwitchPro::SwitchReport switch_report_{}; + std::array pending_output_{}; + bool has_pending_output_ = false; + + uint8_t timer_ = 0; + uint32_t timestamp_ms_ = 0; + uint8_t vibration_report_ = 0x00; + uint8_t vibration_idx_ = 0; + bool vibration_enabled_ = false; + std::array addr_ = { 0x7C, 0xBB, 0x8A, 0x12, 0x34, 0x56 }; + + // USB init handshake: reply to 0x80 0x01 (MAC), 0x80 0x02 (handshake), 0x80 0x04/0x05 (timeout) + std::array report_81_{}; + bool has_pending_81_ = false; }; -#endif // _SWITCH_DEVICE_H_ +#endif diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp index eeda9c0c..aa3b6252 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp @@ -1,8 +1,9 @@ #include -#include +#include "pico/time.h" #include "USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h" +#include "Gamepad/Gamepad.h" void XboxOGDevice::initialize() { @@ -20,6 +21,65 @@ void XboxOGDevice::process(const uint8_t idx, Gamepad& gamepad) std::memset(&in_report_.buttons, 0, 8); Gamepad::PadIn gp_in = gamepad.get_pad_in(); + // Guide (SYS) button: tap = Start, hold 1s = soft IGR (LT+RT+Start+Back), hold 3s = shutdown (LT+RT+Up+Back) + bool sys_pressed = (gp_in.buttons & Gamepad::BUTTON_SYS) != 0; + if (sys_pressed && !sys_button_pressed_) + { + sys_button_pressed_ = true; + sys_button_press_time_ = get_absolute_time(); + sys_button_combo_sent_ = false; + } + else if (!sys_pressed && sys_button_pressed_) + { + sys_button_pressed_ = false; + uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); + if (hold_time_ms >= 3000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.dpad |= Gamepad::DPAD_UP; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else if (hold_time_ms >= 1000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_START; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else + { + gp_in.buttons |= Gamepad::BUTTON_START; + sys_button_combo_sent_ = true; + } + } + else if (sys_pressed && !sys_button_combo_sent_) + { + uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); + if (hold_time_ms >= 3000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.dpad |= Gamepad::DPAD_UP; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else if (hold_time_ms >= 1000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_START; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else + { + gp_in.buttons |= Gamepad::BUTTON_START; + } + } + switch (gp_in.dpad) { case Gamepad::DPAD_UP: diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h index cdd63c3f..1eeb3e05 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h @@ -3,6 +3,7 @@ #include +#include "pico/time.h" #include "USBDevice/DeviceDriver/DeviceDriver.h" #include "Descriptors/XboxOG.h" @@ -23,6 +24,11 @@ class XboxOGDevice : public DeviceDriver private: XboxOG::GP::InReport in_report_; XboxOG::GP::OutReport out_report_; + + // Guide (SYS) button: tap = Start, hold 1s = soft IGR, hold 3s = shutdown + bool sys_button_pressed_{false}; + bool sys_button_combo_sent_{false}; + absolute_time_t sys_button_press_time_; }; #endif // _XBOXGOG_DEVICE_H_ diff --git a/LICENSE b/LICENSE index e01d42e2..14b8de53 100644 --- a/LICENSE +++ b/LICENSE @@ -13,6 +13,10 @@ v2.1 (or later). A copy of the LGPL v2.1 is included in Firmware/external/libxsm3/LICENSE.txt. libxsm3 also uses ExCrypt (3-clause BSD); see Firmware/external/libxsm3/README.md for credits. +Xbox 360 controller rumble/vibration: Host-side rumble handling (including +wireless RUMBLE_ENABLE sequence) is attributed to faithvoid +(https://github.com/faithvoid). + Copyright (c) 2024 wiredOpposite (wiredopposite.com) Copyright (c) 2024 OpenStickCommunity (gp2040-ce.info) Copyright (c) 2021 Jason Skuby (mytechtoybox.com) diff --git a/README.md b/README.md index e14adc8f..8eb71c27 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ # OGX-Mini 2026 ![OGX-Mini Boards](images/OGX-Mini-github.jpg "OGX-Mini Boards") -Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. +Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Waveshare RP2350-USB-A, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. [**Visit the web app here**](https://wiredopposite.github.io/OGX-Mini-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app via USB, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect via USB" in the web app and select the OGX-Mini. You can also pair via Bluetooth, no extra steps are needed in that case. ## Supported platforms - Original Xbox - Playstation 3 -- Nintendo Switch 1 & 2 (docked) +- Nintendo Switch 1 & 2 (docked) — **Switch Pro Controller** emulation over USB - XInput (Xbox 360, UsbdSecPatch no longer required) - Playstation Classic - DInput - Wii U (GameCube Adapter) - **Wii (Wiimote)** — Pico W / Pico 2 W only; build with `-DOGXM_FIXED_DRIVER=WII`. See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). -**RP2040 output modes (USB device):** XInput (Xbox 360 + XSM3), DInput, PS3, Switch, Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. On Pico 2 W, Bluetooth runs on Core1 and USB on Core0; you can build with a fixed mode or use button combos to switch at runtime (Start + D-pad held ~3 s). **Wii is not in the combo list** — use a Wii-only build to get Wiimote output. +**RP2040 output modes (USB device):** XInput (Xbox 360 + XSM3), DInput, PS3, **Switch Pro** (Nintendo Switch Pro Controller emulation), Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. On Pico 2 W, Bluetooth runs on Core1 and USB on Core0; you can build with a fixed mode or use button combos to switch at runtime (Start + D-pad held ~3 s). **Wii is not in the combo list** — use a Wii-only build to get Wiimote output. ## Changing platforms By default the OGX-Mini will emulate an OG Xbox controller, you must hold a button combo for 3 seconds to change which platform you want to play on. Your chosen mode will persist after powering off the device. @@ -30,7 +30,7 @@ Start = Plus (Switch) = Options (Dualsense/DS4) - Start + Dpad Right + Right Bumper - Original Xbox DVD Remote - Start + Dpad Right + Left Bumper -- Switch +- Switch (Pro Controller emulation) - Start + Dpad Down - PlayStation 3 - Start + Dpad Left @@ -92,12 +92,16 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. -==== Version 1.0.0.4a === +==== Version 1.0.0.5a === +- **Switch Pro emulation** — Switch output mode now emulates a **Nintendo Switch Pro Controller** over USB (report format, subcommands, init handshake). Face-button and report layout follow the standard Pro Controller protocol (bit layout aligned with hardware/reference). _Switch Pro protocol and button report layout reference: [retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch) (N64/GameCube → Pico → Switch); Bluepad32 Switch parser used for validation._ - **Wii (Wiimote) output mode** — On Pico W and Pico 2 W, build with `-DOGXM_FIXED_DRIVER=WII` for a Wii-only firmware. The adapter appears as a Wiimote over Bluetooth; use a USB gamepad on the external PIO USB port. Supports No Extension, Nunchuk, and Classic Controller report modes (cycle with Home + D-pad Down). See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). _Approach and mappings based on [PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)._ - Xbox 360 no longer requires the USB patch to authenticate, uses the same authentication as Joypad-OS to do official handshake with Retail consoles. Homebrew/ Jailbreaking is no longer required to use the XINPUT mode on 360 but it will no longer output to PC. -- **Rumble fix for Xbox 360 controllers** — Rumble on 360 pads is now handled correctly when using the adapter (including wireless RUMBLE_ENABLE sequence). _Xbox 360 host rumble handling based on [GP2040-CE](https://github.com/OpenStickCommunity/GP2040-CE)._ +- **Rumble fix for Xbox 360 controllers** — Rumble on 360 pads is now handled correctly when using the adapter (including wireless RUMBLE_ENABLE sequence). _Xbox 360 vibration/rumble handling attributed to [faithvoid](https://github.com/faithvoid) on GitHub._ - **Pico 2 / Pico 2 W build fixes** — Firmware builds and runs correctly on RP2350 (Pico 2 and Pico 2 W). +- **Waveshare RP2350-USB-A board support** — Build with `-DOGXM_BOARD=RP2350_USB_A` for the Waveshare RP2350-USB-A (wired USB host + RGB LED). _Board support from upstream [OGX-Mini](https://github.com/wiredopposite/OGX-Mini/commit/68bdec451077a33b0b1247ce01ed30e470163dea)._ +- **Original Xbox (OG) Guide button behavior** — In OG Xbox mode, the Guide (SYS) button is mapped to Start; **tap** = Start, **hold 1 s** = soft IGR (LT+RT+Start+Back), **hold 3 s** = system shutdown (LT+RT+D-pad Up+Back). _Implementation based on [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ - Improved latency on Xbox 360 and PS3 controllers. +- **PS3 mode:** Home (PS) button works with DS4/DS5 over Bluetooth (8-frame latch so short taps register). Analog sticks now match DualShock 3 spec: full 0–255 range, center 0x80 (128), ~1.5% deadzone for accurate emulation. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md#ps3-mode--input-delays-stuck-inputs-home-button-and-analog-stick-emulation). - Added build flags so you can make it only output in a specific mode and disable mode switching. - Using a PS5 controller allows you to tap the touchpad to enable or disable the adaptive triggers. @@ -133,7 +137,8 @@ Note: These features have been added to the Pico W/ Pico 2 W firmware support, I - Button macros - Rumble settings (intensity, enabled/disable, etc.) -## Planned additions for this fork +## Planned additions for this fork +- **Web app bindings for OG Xbox mode** — Allow users to rebind the Guide tap (Start) and the IGR/shutdown hold combos (e.g. which button triggers 1 s soft IGR or 3 s shutdown) via the web app. - Output to the following consoles: - GameCube - PS2 @@ -164,12 +169,13 @@ Build with **CMake** from the `Firmware/RP2040` directory. You can compile for d - ```PI_PICOW``` - ```PI_PICO2W``` - ```RP2040_ZERO``` +- ```RP2350_USB_A``` (Waveshare RP2350-USB-A) - ```ADAFRUIT_FEATHER``` - ```ESP32_BLUEPAD32_I2C``` - ```ESP32_BLUERETRO_I2C``` - ```EXTERNAL_4CH_I2C``` -You can also set ```MAX_GAMEPADS``` (if > 1, only DInput/PS3 and Switch are supported). **Optional:** ```OGXM_FIXED_DRIVER``` to lock output mode (e.g. ```XINPUT```, ```PS3```); ```OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON``` to keep combos when fixed. ```MAIN_LOOP_DELAY_US``` (default ```0```) sets main-loop delay for lower CPU use (e.g. ```250```). +You can also set ```MAX_GAMEPADS``` (if > 1, only DInput/PS3 and Switch Pro are supported). **Optional:** ```OGXM_FIXED_DRIVER``` to lock output mode (e.g. ```XINPUT```, ```PS3```); ```OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON``` to keep combos when fixed. ```MAIN_LOOP_DELAY_US``` (default ```0```) sets main-loop delay for lower CPU use (e.g. ```250```). You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. Here's an example on Windows: ``` @@ -203,8 +209,9 @@ When you build with ESP-IDF, Cmake will run a python script that copies the nece - **[Joypad OS](https://github.com/joypad-ai/joypad-os)** — Reference for Xbox 360 (XSM3) authentication with retail consoles; XInput mode on 360 follows the same approach. Descriptors and XSM3 flow are aligned with joypad-os; single config, full XSM3 security string, init/verify in main loop; USB is initialized before Core1 so the 360 can enumerate while BT loads. - **[Bluepad32](https://github.com/ricardoquesada/bluepad32)** — Bluetooth controller support (Pico W / Pico 2 W). -- **[GP2040-CE](https://github.com/OpenStickCommunity/GP2040-CE)** — USB device output modes and Xbox 360 controller rumble fix (host-side rumble handling, including wireless RUMBLE_ENABLE sequence); credited in the root LICENSE. +- **[faithvoid](https://github.com/faithvoid)** — Xbox 360 controller vibration/rumble fix (host-side rumble handling, including wireless RUMBLE_ENABLE sequence). - **[PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)** — Wii (Wiimote) output mode: approach of USB gamepad on PIO USB with Bluetooth reserved for the Wiimote link, and button/stick mappings for No Extension, Nunchuk, and Classic Controller report modes. +- **[retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch)** — Reference for Nintendo Switch Pro Controller protocol and report layout (N64/GameCube → Raspberry Pi Pico → Switch via USB or Bluetooth). Used to align OGX-Mini’s Switch mode with correct Pro Controller button byte layout and emulation behavior. ## Licenses and third-party code From f7fc181d5e1d9cc88a418d5ef50ffd872b57390d Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:34:09 -0500 Subject: [PATCH 24/42] Add Discord link to README Added a link to join the Discord community for support. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8eb71c27..e03d0b98 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles [**Visit the web app here**](https://wiredopposite.github.io/OGX-Mini-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app via USB, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect via USB" in the web app and select the OGX-Mini. You can also pair via Bluetooth, no extra steps are needed in that case. +[**Join the discord here!**](https://discord.gg/guaBh9JZQ) + ## Supported platforms - Original Xbox - Playstation 3 From 75ed9009f10dac85540255091538b11096ca673b Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Thu, 5 Mar 2026 06:24:37 -0500 Subject: [PATCH 25/42] Add RP2350_ZERO, RP2040_XIAO, RP2354; 8BitDo XInput fix; Switch stick sensitivity; docs - Board support: RP2350_ZERO, RP2040_XIAO, RP2354 (Config.h, OGXMini.cpp, Standard.cpp, CMakeLists.txt) - Xbox360: 8BitDo LED keepalive for VID 0x2DC8 / PID 0x3016, 0x3106 - Switch: analog stick sensitivity gain (1.2x, STICK_GAIN in Switch.cpp) - Main loop: tud_task() before process() in PicoW, Standard, Four_Channel_I2C for latency - README: new build options, features (boards, 8BitDo, Switch sensitivity), Sakura attribution - IMPROVEMENTS.md: board support, 8BitDo fix, Switch sensitivity sections and summary Made-with: Cursor --- Firmware/RP2040/CMakeLists.txt | 20 +++++++- Firmware/RP2040/docs/IMPROVEMENTS.md | 51 ++++++++++++++++++- Firmware/RP2040/src/Board/Config.h | 22 +++++++- .../src/OGXMini/Board/Four_Channel_I2C.cpp | 4 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 4 +- .../RP2040/src/OGXMini/Board/Standard.cpp | 9 ++-- Firmware/RP2040/src/OGXMini/OGXMini.cpp | 15 ++++++ .../USBDevice/DeviceDriver/Switch/Switch.cpp | 8 ++- .../src/USBHost/HostDriver/XInput/Xbox360.cpp | 14 +++++ .../src/USBHost/HostDriver/XInput/Xbox360.h | 1 + README.md | 23 ++++++--- 11 files changed, 149 insertions(+), 22 deletions(-) diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index a6010a36..eb9f9859 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -190,8 +190,26 @@ elseif(OGXM_BOARD STREQUAL "RP2350_USB_A") set(EN_RGB TRUE) set(FLASH_SIZE_MB 2) +elseif(OGXM_BOARD STREQUAL "RP2350_ZERO") + add_compile_definitions(CONFIG_OGXM_BOARD_RP2350_ZERO=1) + set(EN_USB_HOST TRUE) + set(PICO_PLATFORM rp2350) + set(EN_RGB TRUE) + set(FLASH_SIZE_MB 2) + +elseif(OGXM_BOARD STREQUAL "RP2040_XIAO") + add_compile_definitions(CONFIG_OGXM_BOARD_RP2040_XIAO=1) + set(EN_USB_HOST TRUE) + set(EN_RGB TRUE) + +elseif(OGXM_BOARD STREQUAL "RP2354") + add_compile_definitions(CONFIG_OGXM_BOARD_RP2354=1) + set(EN_USB_HOST TRUE) + set(PICO_PLATFORM rp2350) + set(FLASH_SIZE_MB 2) + else() - message(FATAL_ERROR "Invalid OGXM_BOARD value. See options in src/board_config.h") + message(FATAL_ERROR "Invalid OGXM_BOARD value. See options in src/Board/Config.h") endif() diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 92b65011..eb061d54 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -96,6 +96,17 @@ In XInput mode, the adapter no longer sends a report only when `gamepad.new_pad_ **File:** `src/USBDevice/DeviceDriver/XInput/XInput.cpp` — `process()` always builds and sends the report; no gate on `new_pad_in()`. +### Switch and PS3: latest state when USB ready + +- **Switch (Pro emulation):** Each `process()` call reads fresh `get_pad_in()`, builds the report, and sends when `tud_hid_n_ready(0)`. No `new_pad_in()` gate — the host gets the latest state every time the IN endpoint is free. +- **PS3:** Report is built only when `tud_hid_ready()`; when ready, it uses `get_pad_in()` so the console always receives the latest state. Same low-latency pattern as XInput. + +### Main loop order: tud_task() before process() + +The main loop now calls **`tud_task()` before** `device_driver->process()`. That way the USB stack updates completion status of the previous IN transfer first; then `process()` sees the endpoint as ready and can send the next report immediately with the latest gamepad state. Reduces latency by up to one main-loop iteration (avoids sending only every other loop when the host polls frequently). + +**Files:** `src/OGXMini/Board/PicoW.cpp`, `Standard.cpp`, `Four_Channel_I2C.cpp` — order is `process_tasks()` → `tud_task()` → `process()` for each gamepad. + ### How to use | Goal | Setting | @@ -111,10 +122,46 @@ In XInput mode, the adapter no longer sends a report only when `gamepad.new_pad_ --- +## Additional board support (RP2350_ZERO, RP2040_XIAO, RP2354) + +**Source:** [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing). + +Three additional boards use the same Standard (PIO-USB host) code path as PI_PICO, RP2040_ZERO, ADAFRUIT_FEATHER, and RP2350_USB_A: + +| Board | CMake option | Notes | +|-------|--------------|--------| +| Waveshare RP2350-Zero | `OGXM_BOARD=RP2350_ZERO` | PIO USB D+ = GP10, RGB = GP16; RP2350. | +| Seeed Studio XIAO RP2040 | `OGXM_BOARD=RP2040_XIAO` | PIO USB D+ = GP0, RGB = GP12, LED = GP17. | +| RP2354 | `OGXM_BOARD=RP2354` | PIO USB D+ = GP0, LED = GP25; RP2350. | + +**Files:** `src/Board/Config.h` (board IDs and pin defines), `src/OGXMini/OGXMini.cpp` (init/run/host_mounted tables), `src/OGXMini/Board/Standard.cpp` (extended `#if`), `CMakeLists.txt` (board branches). + +--- + +## 8BitDo XInput (Xbox 360) host fix + +**Source:** [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing). + +Some 8BitDo wired XInput controllers (VID 0x2DC8, PID 0x3016 or 0x3106) can disconnect or behave oddly if the host leaves the controller LED on. The Xbox 360 host driver now detects these devices by VID/PID and schedules a repeating delayed task (every 1 s) that sends “LED off” to the controller. Other controllers are unchanged (LED stays on as before). + +**File:** `src/USBHost/HostDriver/XInput/Xbox360.cpp` — `initialize()` calls `tuh_vid_pid_get()`, and if 8BitDo, queues `TaskQueue::Core1::queue_delayed_task(..., 1000, true, set_led(..., false))`. + +--- + +## Switch Pro — analog stick sensitivity + +A configurable sensitivity gain is applied to the analog sticks in Switch Pro emulation. Raw stick values (outside the deadzone) are scaled by **STICK_GAIN_NUM / STICK_GAIN_DEN** (default 120/100 = 1.2×) before mapping to the 12-bit Switch report. The same physical deflection produces slightly larger output for a more responsive feel. + +**File:** `src/USBDevice/DeviceDriver/Switch/Switch.cpp` — `gamepad_to_switch_report()`; tune via `STICK_GAIN_NUM` and `STICK_GAIN_DEN`. + +--- + ## Summary | Area | Improvement | |------|-------------| -| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). | +| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. | | **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. | -| **Latency** | Main loop delay default **0 µs** (low latency); XInput always sends latest state when USB is ready for lower latency with PS5/Xbox One over BT. | +| **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. | +| **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). | +| **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). | diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index 32b3a1e8..820b4573 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -10,7 +10,10 @@ #define EXTERNAL_4CH_I2C 6 #define INTERNAL_4CH_I2C 7 #define RP2350_USB_A 8 -#define BOARDS_COUNT 9 +#define RP2350_ZERO 9 +#define RP2040_XIAO 10 +#define RP2354 11 +#define BOARDS_COUNT 12 #define SYSCLOCK_KHZ 240000 @@ -105,6 +108,23 @@ #define PIO_USB_DP_PIN 12 #define RGB_PXL_PIN 16 +#elif defined(CONFIG_OGXM_BOARD_RP2350_ZERO) + #define OGXM_BOARD RP2350_ZERO + #define PIO_USB_DP_PIN 10 // DM = 11 + #define RGB_PXL_PIN 16 + +#elif defined(CONFIG_OGXM_BOARD_RP2040_XIAO) + #define OGXM_BOARD RP2040_XIAO + #define RGB_PXL_PIN 12 + #define RGB_PWR_PIN 11 + #define PIO_USB_DP_PIN 0 // DM = 1 + #define LED_INDICATOR_PIN 17 + +#elif defined(CONFIG_OGXM_BOARD_RP2354) + #define OGXM_BOARD RP2354 + #define PIO_USB_DP_PIN 0 // DM = 1 + #define LED_INDICATOR_PIN 25 + #else #error "Invalid OGXMini board selected" diff --git a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp index f70ee88a..9c0f3c70 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp @@ -449,9 +449,9 @@ void four_ch_i2c::run() { if (I2C::role() == I2C::Role::MASTER) { while (true) { TaskQueue::Core0::process_tasks(); + tud_task(); I2C::Master::process(); device_driver->process(0, _gamepads[0]); - tud_task(); #if MAIN_LOOP_DELAY_US > 0 sleep_us(MAIN_LOOP_DELAY_US); #endif @@ -459,8 +459,8 @@ void four_ch_i2c::run() { } else { while (true) { TaskQueue::Core0::process_tasks(); - device_driver->process(0, _gamepads[0]); tud_task(); + device_driver->process(0, _gamepads[0]); #if MAIN_LOOP_DELAY_US > 0 sleep_us(MAIN_LOOP_DELAY_US); #endif diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index cbb8d8c3..7f4d289b 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -200,12 +200,12 @@ void pico_w::run() { static uint32_t loop_count = 0; while (true) { TaskQueue::Core0::process_tasks(); - + if (!wii_mode) + tud_task(); for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { device_driver->process(i, _gamepads[i]); } if (!wii_mode) { - tud_task(); if (tud_mounted() && !mounted_logged) { mounted_logged = true; OGXM_LOG("PicoW run: USB configured\n"); diff --git a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp index 096350e6..5d9b199f 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp @@ -1,6 +1,6 @@ #include "Board/Config.h" #include "OGXMini/Board/Standard.h" -#if ((OGXM_BOARD == PI_PICO) || (OGXM_BOARD == RP2040_ZERO) || (OGXM_BOARD == ADAFRUIT_FEATHER) || (OGXM_BOARD == RP2350_USB_A)) +#if ((OGXM_BOARD == PI_PICO) || (OGXM_BOARD == RP2040_ZERO) || (OGXM_BOARD == ADAFRUIT_FEATHER) || (OGXM_BOARD == RP2350_USB_A) || (OGXM_BOARD == RP2350_ZERO) || (OGXM_BOARD == RP2040_XIAO) || (OGXM_BOARD == RP2354)) #include #include @@ -121,21 +121,20 @@ void standard::run() { while (true) { TaskQueue::Core0::process_tasks(); - + tud_task(); for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { device_driver->process(i, _gamepads[i]); } - tud_task(); #if MAIN_LOOP_DELAY_US > 0 sleep_us(MAIN_LOOP_DELAY_US); #endif } } -// #else // OGXM_BOARD == PI_PICO || OGXM_BOARD == RP2040_ZERO || OGXM_BOARD == ADAFRUIT_FEATHER +// #else // OGXM_BOARD == PI_PICO || ... || RP2354 // void standard::host_mounted(bool host_mounted) {} // void standard::initialize() {} // void standard::run() {} -#endif // OGXM_BOARD == PI_PICO || OGXM_BOARD == RP2040_ZERO || OGXM_BOARD == ADAFRUIT_FEATHER \ No newline at end of file +#endif // PI_PICO || RP2040_ZERO || ADAFRUIT_FEATHER || RP2350_USB_A || RP2350_ZERO || RP2040_XIAO || RP2354 \ No newline at end of file diff --git a/Firmware/RP2040/src/OGXMini/OGXMini.cpp b/Firmware/RP2040/src/OGXMini/OGXMini.cpp index fd134dcc..d0e96454 100644 --- a/Firmware/RP2040/src/OGXMini/OGXMini.cpp +++ b/Firmware/RP2040/src/OGXMini/OGXMini.cpp @@ -23,6 +23,9 @@ namespace OGXMini { four_ch_i2c::initialize, // EXTERNAL_4CH_I2C four_ch_i2c::initialize, // INTERNAL_4CH_I2C standard::initialize, // RP2350_USB_A + standard::initialize, // RP2350_ZERO + standard::initialize, // RP2040_XIAO + standard::initialize, // RP2354 }; static constexpr RunFunc run_func[BOARDS_COUNT] = { @@ -35,6 +38,9 @@ namespace OGXMini { four_ch_i2c::run, // EXTERNAL_4CH_I2C four_ch_i2c::run, // INTERNAL_4CH_I2C standard::run, // RP2350_USB_A + standard::run, // RP2350_ZERO + standard::run, // RP2040_XIAO + standard::run, // RP2354 }; static constexpr HostMountedFunc host_mount_func[BOARDS_COUNT] = { @@ -47,6 +53,9 @@ namespace OGXMini { four_ch_i2c::host_mounted, // EXTERNAL_4CH_I2C four_ch_i2c::host_mounted, // INTERNAL_4CH_I2C standard::host_mounted, // RP2350_USB_A + standard::host_mounted, // RP2350_ZERO + standard::host_mounted, // RP2040_XIAO + standard::host_mounted, // RP2354 }; static constexpr HostMountedWTypeFunc host_mount_w_type_func[BOARDS_COUNT] = { @@ -59,6 +68,9 @@ namespace OGXMini { four_ch_i2c::host_mounted_w_type, // EXTERNAL_4CH_I2C four_ch_i2c::host_mounted_w_type, // INTERNAL_4CH_I2C nullptr, // RP2350_USB_A + nullptr, // RP2350_ZERO + nullptr, // RP2040_XIAO + nullptr, // RP2354 }; static constexpr WirelessConnectedFunc wl_conn_func[BOARDS_COUNT] = { @@ -71,6 +83,9 @@ namespace OGXMini { four_ch_i2c::wireless_connected, // EXTERNAL_4CH_I2C four_ch_i2c::wireless_connected, // INTERNAL_4CH_I2C nullptr, // RP2350_USB_A + nullptr, // RP2350_ZERO + nullptr, // RP2040_XIAO + nullptr, // RP2354 }; void initialize() { diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp index 55cb5486..7d282145 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp @@ -81,12 +81,16 @@ void SwitchDevice::gamepad_to_switch_report(const Gamepad::PadIn& gp_in, SwitchP if (gp_in.buttons & gamepad.MAP_BUTTON_LB) out.buttons[2] |= SwitchPro::Btn::L; if (gp_in.trigger_l) out.buttons[2] |= SwitchPro::Btn::ZL; - // Sticks: int16 -> 12-bit (0x000–0xFFF), center 0x7FF. Small deadzone. + // Sticks: int16 -> 12-bit (0x000–0xFFF), center 0x7FF. Small deadzone + slight sensitivity boost. constexpr int16_t DZ = 512; + constexpr int STICK_GAIN_NUM = 120, STICK_GAIN_DEN = 100; // 1.2x sensitivity auto to12 = [](int16_t val) -> uint16_t { if (val > -DZ && val < DZ) return SwitchPro::STICK_MID; - int32_t v = static_cast(val) + 32768; + int32_t scaled = (static_cast(val) * STICK_GAIN_NUM) / STICK_GAIN_DEN; + if (scaled > 32767) scaled = 32767; + if (scaled < -32768) scaled = -32768; + int32_t v = scaled + 32768; int32_t u = (v * 4095 + 32767) / 65535; if (u < 0) u = 0; if (u > 4095) u = 4095; diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp index 58e75051..d0a30f73 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp @@ -1,6 +1,7 @@ #include #include "host/usbh.h" +#include "TaskQueue/TaskQueue.h" #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/XInput/Xbox360.h" @@ -8,6 +9,19 @@ void Xbox360Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { tuh_xinput::set_led(address, instance, idx_ + 1, true); + + uint16_t vid, pid; + tuh_vid_pid_get(address, &vid, &pid); + bool is_8bitdo = (vid == 0x2DC8) && (pid == 0x3016 || pid == 0x3106); + + if (is_8bitdo) + { + tid_keepalive_ = TaskQueue::Core1::get_new_task_id(); + TaskQueue::Core1::queue_delayed_task(tid_keepalive_, 1000, true, [address, instance, this] { + tuh_xinput::set_led(address, instance, idx_ + 1, false); + }); + } + tuh_xinput::receive_report(address, instance); } diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.h index 63511e5d..76c703ea 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.h @@ -17,6 +17,7 @@ class Xbox360Host : public HostDriver bool send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) override; private: + uint32_t tid_keepalive_{0}; XInput::InReport prev_in_report_; }; diff --git a/README.md b/README.md index e03d0b98..2787303d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # OGX-Mini 2026 ![OGX-Mini Boards](images/OGX-Mini-github.jpg "OGX-Mini Boards") -Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Waveshare RP2350-USB-A, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. +Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Waveshare RP2350-USB-A, Waveshare RP2350-Zero, Seeed Studio XIAO RP2040, RP2354, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. [**Visit the web app here**](https://wiredopposite.github.io/OGX-Mini-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app via USB, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect via USB" in the web app and select the OGX-Mini. You can also pair via Bluetooth, no extra steps are needed in that case. @@ -94,20 +94,25 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. -==== Version 1.0.0.5a === +### Version 1.0.0.5a - **Switch Pro emulation** — Switch output mode now emulates a **Nintendo Switch Pro Controller** over USB (report format, subcommands, init handshake). Face-button and report layout follow the standard Pro Controller protocol (bit layout aligned with hardware/reference). _Switch Pro protocol and button report layout reference: [retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch) (N64/GameCube → Pico → Switch); Bluepad32 Switch parser used for validation._ +- **Waveshare RP2350-USB-A board support** — Build with `-DOGXM_BOARD=RP2350_USB_A` for the Waveshare RP2350-USB-A (wired USB host + RGB LED). _Board support from upstream [OGX-Mini](https://github.com/wiredopposite/OGX-Mini/commit/68bdec451077a33b0b1247ce01ed30e470163dea)._ +- **Additional board support** — **RP2350_ZERO** (Waveshare RP2350-Zero), **RP2040_XIAO** (Seeed Studio XIAO RP2040), and **RP2354**. All use the same Standard (PIO-USB host) firmware path; build with `-DOGXM_BOARD=RP2350_ZERO`, `RP2040_XIAO`, or `RP2354`. _Board support from [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ +- **8BitDo XInput (Xbox 360) fix** — Wired 8BitDo controllers (VID 0x2DC8, PID 0x3016 / 0x3106) are detected and sent a repeating LED-off keepalive so they stay connected and stable. _From [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ +- **Switch analog stick sensitivity** — Slight sensitivity increase (1.2× gain) for analog sticks in Switch Pro emulation mode; configurable via `STICK_GAIN_NUM` / `STICK_GAIN_DEN` in `Switch.cpp`. +- **Original Xbox (OG) Guide button behavior** — In OG Xbox mode, the Guide (SYS) button is mapped to Start; **tap** = Start, **hold 1 s** = soft IGR (LT+RT+Start+Back), **hold 3 s** = system shutdown (LT+RT+D-pad Up+Back). _Implementation based on [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ + +### Version 1.0.0.4a - **Wii (Wiimote) output mode** — On Pico W and Pico 2 W, build with `-DOGXM_FIXED_DRIVER=WII` for a Wii-only firmware. The adapter appears as a Wiimote over Bluetooth; use a USB gamepad on the external PIO USB port. Supports No Extension, Nunchuk, and Classic Controller report modes (cycle with Home + D-pad Down). See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). _Approach and mappings based on [PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)._ - Xbox 360 no longer requires the USB patch to authenticate, uses the same authentication as Joypad-OS to do official handshake with Retail consoles. Homebrew/ Jailbreaking is no longer required to use the XINPUT mode on 360 but it will no longer output to PC. - **Rumble fix for Xbox 360 controllers** — Rumble on 360 pads is now handled correctly when using the adapter (including wireless RUMBLE_ENABLE sequence). _Xbox 360 vibration/rumble handling attributed to [faithvoid](https://github.com/faithvoid) on GitHub._ - **Pico 2 / Pico 2 W build fixes** — Firmware builds and runs correctly on RP2350 (Pico 2 and Pico 2 W). -- **Waveshare RP2350-USB-A board support** — Build with `-DOGXM_BOARD=RP2350_USB_A` for the Waveshare RP2350-USB-A (wired USB host + RGB LED). _Board support from upstream [OGX-Mini](https://github.com/wiredopposite/OGX-Mini/commit/68bdec451077a33b0b1247ce01ed30e470163dea)._ -- **Original Xbox (OG) Guide button behavior** — In OG Xbox mode, the Guide (SYS) button is mapped to Start; **tap** = Start, **hold 1 s** = soft IGR (LT+RT+Start+Back), **hold 3 s** = system shutdown (LT+RT+D-pad Up+Back). _Implementation based on [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ - Improved latency on Xbox 360 and PS3 controllers. - **PS3 mode:** Home (PS) button works with DS4/DS5 over Bluetooth (8-frame latch so short taps register). Analog sticks now match DualShock 3 spec: full 0–255 range, center 0x80 (128), ~1.5% deadzone for accurate emulation. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md#ps3-mode--input-delays-stuck-inputs-home-button-and-analog-stick-emulation). - Added build flags so you can make it only output in a specific mode and disable mode switching. - Using a PS5 controller allows you to tap the touchpad to enable or disable the adaptive triggers. - -=== Version 1.0.0.3a patched === + +### Version 1.0.0.3a patched - Ability to emulate the GameCube controller adapter for Wii U. (Also tested on Switch 1/ 2) - Wii U & Switch Pro controllers are supported fully with working LT and RT - Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. @@ -170,8 +175,11 @@ Build with **CMake** from the `Firmware/RP2040` directory. You can compile for d - ```PI_PICO2``` - ```PI_PICOW``` - ```PI_PICO2W``` -- ```RP2040_ZERO``` +- ```RP2040_ZERO``` (Waveshare RP2040-Zero) - ```RP2350_USB_A``` (Waveshare RP2350-USB-A) +- ```RP2350_ZERO``` (Waveshare RP2350-Zero) +- ```RP2040_XIAO``` (Seeed Studio XIAO RP2040) +- ```RP2354``` - ```ADAFRUIT_FEATHER``` - ```ESP32_BLUEPAD32_I2C``` - ```ESP32_BLUERETRO_I2C``` @@ -209,6 +217,7 @@ When you build with ESP-IDF, Cmake will run a python script that copies the nece ## Other projects that have helped enhance this fork +- **[Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)** — OG Xbox Guide button (tap/hold IGR/shutdown), board support for RP2350_ZERO, RP2040_XIAO, RP2354, and 8BitDo XInput (Xbox 360) LED keepalive fix. - **[Joypad OS](https://github.com/joypad-ai/joypad-os)** — Reference for Xbox 360 (XSM3) authentication with retail consoles; XInput mode on 360 follows the same approach. Descriptors and XSM3 flow are aligned with joypad-os; single config, full XSM3 security string, init/verify in main loop; USB is initialized before Core1 so the 360 can enumerate while BT loads. - **[Bluepad32](https://github.com/ricardoquesada/bluepad32)** — Bluetooth controller support (Pico W / Pico 2 W). - **[faithvoid](https://github.com/faithvoid)** — Xbox 360 controller vibration/rumble fix (host-side rumble handling, including wireless RUMBLE_ENABLE sequence). From 08780e38f5481467177f80ecbea8fbedd390c361 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Fri, 6 Mar 2026 12:01:03 -0500 Subject: [PATCH 26/42] v1.0.0a6: BT input queue, DS4/DS5 latency docs, GPIO/Dreamcast/GC/N64/PS1PS2, version bump - Gamepad: 2-entry pad_in queue to avoid dropping fast button/stick inputs (BT vs main loop race) - FWDefines: bump version to v1.0.0a6 - Docs: BLUEPAD32_PS4_PS5_PARSING (Xbox vs DS4/DS5), Dreamcast_Port, GPIO_Output_Pinout_and_Mappings - Bluepad32 parser: skip gyro/accel/touchpad for DS4/DS5 (Xbox-style path for lower latency); patch in patches/bluepad32_ps4_ps5_latency.diff - GPIO output: Dreamcast, GameCube, N64, PS1/PS2 device drivers and GPIOHost (joybus, maple, psx) - README, CMake, DeviceManager, UserSettings, HostManager updates for new modes and boards Made-with: Cursor --- .gitignore | 5 +- Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/CMakeLists.txt | 22 + Firmware/RP2040/docs/Dreamcast_Port.md | 75 ++++ .../docs/GPIO_Output_Pinout_and_Mappings.md | 190 ++++++++ Firmware/RP2040/docs/IMPROVEMENTS.md | 31 +- Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 77 +++- Firmware/RP2040/src/Bluepad32/Bluepad32.h | 4 + Firmware/RP2040/src/Board/ogxm_log.cpp | 2 + Firmware/RP2040/src/Gamepad/Gamepad.h | 44 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 91 +++- .../RP2040/src/OGXMini/Board/Standard.cpp | 121 +++++- .../DeviceDriver/DeviceDriverTypes.h | 4 + .../DeviceDriver/Dreamcast/Dreamcast.cpp | 184 ++++++++ .../DeviceDriver/Dreamcast/Dreamcast.h | 30 ++ .../DeviceDriver/GameCube/GameCube.cpp | 106 +++++ .../DeviceDriver/GameCube/GameCube.h | 28 ++ .../DeviceDriver/GameCube/gamecube_device.c | 101 +++++ .../DeviceDriver/GameCube/gc_simulator.h | 35 ++ .../DeviceDriver/GameCube/joybus.pio | 27 ++ .../src/USBDevice/DeviceDriver/N64/N64.cpp | 98 +++++ .../src/USBDevice/DeviceDriver/N64/N64.h | 24 ++ .../USBDevice/DeviceDriver/N64/n64_device.c | 112 +++++ .../USBDevice/DeviceDriver/N64/n64_device.h | 30 ++ .../USBDevice/DeviceDriver/N64/n64send.pio | 37 ++ .../USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp | 130 ++++++ .../USBDevice/DeviceDriver/PS1PS2/PS1PS2.h | 31 ++ .../PS1PS2/controller_simulator.c | 408 ++++++++++++++++++ .../USBDevice/DeviceDriver/PS1PS2/psxSPI.pio | 87 ++++ .../DeviceDriver/PS1PS2/psx_simulator.h | 39 ++ .../USBDevice/DeviceDriver/Switch/Switch.cpp | 30 +- .../USBDevice/DeviceDriver/XInput/XInput.cpp | 4 +- .../RP2040/src/USBDevice/DeviceManager.cpp | 23 +- Firmware/RP2040/src/USBDevice/DeviceManager.h | 4 +- .../RP2040/src/USBDevice/tud_callbacks.cpp | 6 + .../RP2040/src/USBHost/GPIOHost/GPIOHost.cpp | 274 ++++++++++++ .../RP2040/src/USBHost/GPIOHost/GPIOHost.h | 32 ++ .../GPIOHost/dreamcast_host/MapleBus.cpp | 349 +++++++++++++++ .../GPIOHost/dreamcast_host/MapleBus.h | 87 ++++ .../GPIOHost/dreamcast_host/MaplePacket.hpp | 102 +++++ .../GPIOHost/dreamcast_host/PioProgram.hpp | 15 + .../dreamcast_host/dreamcast_constants.h | 35 ++ .../dreamcast_host/dreamcast_structures.h | 40 ++ .../GPIOHost/dreamcast_host/maple_config.h | 28 ++ .../GPIOHost/dreamcast_host/maple_in.pio | 54 +++ .../GPIOHost/dreamcast_host/maple_out.pio | 64 +++ .../GPIOHost/dreamcast_host/maple_utils.h | 3 + .../GPIOHost/joybus_host/controller.pio | 59 +++ .../GPIOHost/joybus_host/joybus_controller.c | 62 +++ .../GPIOHost/joybus_host/joybus_controller.h | 24 ++ .../USBHost/GPIOHost/joybus_host/n64_host.c | 73 ++++ .../USBHost/GPIOHost/joybus_host/n64_host.h | 23 + .../src/USBHost/GPIOHost/psx_host/clock.pio | 40 ++ .../src/USBHost/GPIOHost/psx_host/psx_host.c | 95 ++++ .../src/USBHost/GPIOHost/psx_host/psx_host.h | 21 + .../RP2040/src/USBHost/HostDriver/PS4/PS4.cpp | 1 + Firmware/RP2040/src/USBHost/HostManager.h | 26 +- .../RP2040/src/UserSettings/UserSettings.cpp | 111 ++++- .../RP2040/src/UserSettings/UserSettings.h | 18 + Firmware/cmake/patch_libs.cmake | 1 + .../patches/bluepad32_ps4_ps5_latency.diff | 176 ++++++++ README.md | 32 +- 62 files changed, 4000 insertions(+), 87 deletions(-) create mode 100644 Firmware/RP2040/docs/Dreamcast_Port.md create mode 100644 Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gamecube_device.c create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gc_simulator.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/joybus.pio create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.c create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64send.pio create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psxSPI.pio create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.cpp create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.cpp create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MaplePacket.hpp create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/PioProgram.hpp create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_constants.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_structures.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_config.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_in.pio create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_out.pio create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_utils.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/controller.pio create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.c create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.c create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.h create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/psx_host/clock.pio create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.c create mode 100644 Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.h create mode 100644 Firmware/external/patches/bluepad32_ps4_ps5_latency.diff diff --git a/.gitignore b/.gitignore index e83f8035..6852505f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ Firmware/external/pico-sdk Firmware/external/picotool Tools/dvd-dongle-rom.bin -# Local comparison doc (not for GitHub) -Firmware/RP2040/docs/XInput_joypad-os_comparison.md \ No newline at end of file +# Local docs (not for GitHub) +Firmware/RP2040/docs/XInput_joypad-os_comparison.md +Firmware/RP2040/docs/BLUEPAD32_PS4_PS5_PARSING.md \ No newline at end of file diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index 0328032e..88237715 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a5") \ No newline at end of file +set(FW_VERSION "v1.0.0a6") \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index eb9f9859..d4745f1b 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -70,6 +70,13 @@ set(SOURCES_BOARD ${SRC}/USBDevice/DeviceDriver/Switch/Switch.cpp ${SRC}/USBDevice/DeviceDriver/WiiU/WiiU.cpp ${SRC}/USBDevice/DeviceDriver/Wii/Wii.cpp + ${SRC}/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp + ${SRC}/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c + ${SRC}/USBDevice/DeviceDriver/GameCube/GameCube.cpp + ${SRC}/USBDevice/DeviceDriver/GameCube/gamecube_device.c + ${SRC}/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp + ${SRC}/USBDevice/DeviceDriver/N64/N64.cpp + ${SRC}/USBDevice/DeviceDriver/N64/n64_device.c ${SRC}/USBDevice/DeviceDriver/XInput/XInput.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/XboxOG_SB.cpp @@ -78,6 +85,12 @@ set(SOURCES_BOARD ${SRC}/USBDevice/DeviceDriver/WebApp/WebApp.cpp ${SRC}/USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.cpp ${SRC}/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.cpp + + ${SRC}/USBHost/GPIOHost/GPIOHost.cpp + ${SRC}/USBHost/GPIOHost/psx_host/psx_host.c + ${SRC}/USBHost/GPIOHost/joybus_host/joybus_controller.c + ${SRC}/USBHost/GPIOHost/joybus_host/n64_host.c + ${SRC}/USBHost/GPIOHost/dreamcast_host/MapleBus.cpp # libxsm3 for Xbox 360 (XSM3) authentication in XInput mode ${EXTERNAL_DIR}/libxsm3/xsm3.c ${EXTERNAL_DIR}/libxsm3/usbdsec.c @@ -501,6 +514,15 @@ target_compile_definitions(${FW_NAME} PRIVATE XSM3_NO_DEBUGGING=1 XSM3_EMBEDDED= if(EN_RGB) pico_generate_pio_header(${FW_NAME} ${SRC}/Board/Pico_WS2812/WS2812.pio) endif() +pico_generate_pio_header(${FW_NAME} ${SRC}/USBDevice/DeviceDriver/PS1PS2/psxSPI.pio) +pico_generate_pio_header(${FW_NAME} ${SRC}/USBDevice/DeviceDriver/GameCube/joybus.pio) +pico_generate_pio_header(${FW_NAME} ${SRC}/USBDevice/DeviceDriver/N64/n64send.pio) +pico_generate_pio_header(${FW_NAME} ${SRC}/USBHost/GPIOHost/psx_host/clock.pio) +pico_generate_pio_header(${FW_NAME} ${SRC}/USBHost/GPIOHost/joybus_host/controller.pio) +pico_generate_pio_header(${FW_NAME} ${SRC}/USBHost/GPIOHost/dreamcast_host/maple_in.pio) +pico_generate_pio_header(${FW_NAME} ${SRC}/USBHost/GPIOHost/dreamcast_host/maple_out.pio) + +target_include_directories(${FW_NAME} PRIVATE ${SRC}/USBHost/GPIOHost/dreamcast_host) include_directories(${INC_DIRS_BOARD}) diff --git a/Firmware/RP2040/docs/Dreamcast_Port.md b/Firmware/RP2040/docs/Dreamcast_Port.md new file mode 100644 index 00000000..d79a5445 --- /dev/null +++ b/Firmware/RP2040/docs/Dreamcast_Port.md @@ -0,0 +1,75 @@ +# Dreamcast (Maple Bus) Port from DreamPicoPort + +OGX-Mini has **stub** support for Dreamcast: you can select **Start + Y** for Dreamcast mode and **Start + Select** to cycle input source to **Dreamcast GPIO**, but the actual Maple Bus protocol is not yet implemented. This document describes how to complete the port from [DreamPicoPort](https://github.com/OrangeFox86/DreamPicoPort) (Dreamcast to USB gamepad converter for Raspberry Pi Pico). + +## What DreamPicoPort Provides + +- **Maple Bus**: Sega’s serial protocol for Dreamcast controllers and peripherals. Two wires (A and B), bidirectional, frame-based with CRC. +- **Host mode**: Read a real Dreamcast controller → USB (or in our case, fill `Gamepad::PadIn`). +- **Client mode**: USB gamepad → emulate a Dreamcast controller (we feed from `Gamepad::PadIn` and respond to the console). + +DreamPicoPort uses: + +- Two PIO programs: `maple_in.pio` (read) and `maple_out.pio` (write), on **different PIO blocks** (each block has a 32-instruction limit). +- DMA for TX/RX, IRQ on completion. +- **Pin A** and **Pin B** = two consecutive GPIOs (e.g. 10 and 11). Optional **direction pin** for a transceiver. +- Packet format: `MaplePacket` (frame word, payload, 8-bit CRC). Commands: device info, GET_CONDITION (controller state), etc. +- Controller condition: 8-byte `controller_condition_t` (buttons, analog L/R, sticks). See `inc/dreamcast_structures.h`. + +## Files to Port from DreamPicoPort + +1. **Maple Bus HAL** + - `inc/hal/MapleBus/MapleBusInterface.hpp` + - `inc/hal/MapleBus/MaplePacket.hpp` + - `src/hal/MapleBus/MapleBus.hpp` + - `src/hal/MapleBus/MapleBus.cpp` + - `src/hal/MapleBus/PioProgram.hpp` + - `src/hal/MapleBus/maple_in.pio` + - `src/hal/MapleBus/maple_out.pio` + +2. **Dreamcast types** + - `inc/dreamcast_constants.h` (commands, device functions) + - `inc/dreamcast_structures.h` (`controller_condition_t`) + +3. **Configuration** + - Provide a small `configuration.h` (or equivalent) with: + - `MAPLE_OPEN_LINE_CHECK_TIME_US`, `MAPLE_NS_PER_BIT`, `MAPLE_RESPONSE_TIMEOUT_US`, etc. + - Pins: e.g. `P1_BUS_START_PIN` (pin A), `P1_DIR_PIN` (-1 if no direction pin). + - DreamPicoPort uses a **forked pico-sdk**; we use the stock SDK, so any SDK-specific code may need minor adjustments. + +4. **Client (output to Dreamcast)** + - Either port `DreamcastController` + `DreamcastMainPeripheral` / `DreamcastPeripheral` (full state machine), or implement a **minimal controller** that: + - Responds to **device info** and **GET_CONDITION**. + - Builds `controller_condition_t` from `Gamepad::PadIn` (see `Gamepad::PadIn` ↔ `controller_condition_t` mapping in DreamPicoPort’s `DreamcastController` / host code). + - Run this loop on **core1** (like PS1/PS2 and GameCube), replacing the stub in `Dreamcast.cpp` / `dreamcast_core1_entry()`. + +5. **Host (read Dreamcast controller)** + - Port the host path that sends GET_CONDITION and reads the response (e.g. hostLib code that uses `MapleBus::write(..., autostartRead=true)` and parses the reply). + - In `GPIOHost::dreamcast_host_init()` create and configure the Maple Bus (pin A, optional dir pin; use one PIO for in and one for out). + - In `GPIOHost::dreamcast_host_poll()` send GET_CONDITION, read response, fill `controller_condition_t`, convert to `Gamepad::PadIn`, call `gamepad.set_pad_in()`. + +## OGX-Mini Integration Points + +- **Device (output)** + - `USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp` + - `DreamcastDevice::initialize()`: one-time Maple Bus + minimal controller setup. + - `DreamcastDevice::process(idx, gamepad)`: not used for USB; core1 loop reads a shared report (e.g. a `controller_condition_t` or `PadIn` updated from the main loop). + - `dreamcast_core1_entry()`: run the Maple Bus **device** loop (wait for console commands, respond with device info / condition from the shared report). + +- **Host (input)** + - `USBHost/GPIOHost/GPIOHost.cpp` + - `dreamcast_host_init(pio_in_index, pio_out_index, pin_a, dir_pin)`: create MapleBus instance(s), configure pins. + - `dreamcast_host_poll(gamepad)`: send GET_CONDITION, parse response into `controller_condition_t`, map to `PadIn`, `gamepad.set_pad_in()`. + +- **Board** + - Standard and PicoW already treat `DeviceDriverType::DREAMCAST` as GPIO device mode (no USB device, core1 runs `dreamcast_core1_entry`). + - When input source is `DREAMCAST_GPIO`, they call `dreamcast_host_init()` and `dreamcast_host_poll()`. + +- **Pins** + - DreamPicoPort defaults: e.g. P1 bus = GPIO 10 (A), 11 (B); direction pin 6. We use `dreamcast_host_init(1, 0, 10, -1)` in the stub (PIO1 for in, PIO0 for out, pin A 10, no dir pin). Adjust in your config to match hardware. + +## References + +- [DreamPicoPort](https://github.com/OrangeFox86/DreamPicoPort) – source for Maple Bus and Dreamcast controller logic. +- [Maple Bus (Dreamcast wiki)](https://dreamcast.wiki/Maple_bus) – protocol overview. +- DreamPicoPort README: Maple Bus implementation, PIO data handoff, timeouts. diff --git a/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md b/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md new file mode 100644 index 00000000..8abc4172 --- /dev/null +++ b/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md @@ -0,0 +1,190 @@ +# GPIO Output Modes: Pin-Outs and Default Controller Mappings + +This document lists the **pin connections** and **default button/stick mappings** for the GPIO-based output modes (PS1/PS2, Dreamcast, GameCube, N64) on OGX-Mini. + +**Why two kinds of pin numbers?** +- **GPIO numbers** (e.g. 19, 20, 21) are **RP2040 GPIO pins** used for data. The firmware uses these; you wire each signal to the matching GPIO on the Pico. +- **“Connector” numbers** (e.g. connector pin 4, pin 5) are the **pin positions on the console or controller plug** (the physical port). VCC and GND are **not** GPIOs — they’re power rails. On the **adapter (Pico) side** you use the board’s **3V3** and **GND** pins (the Pico’s power pins, not GPIO). On the **console/controller side** you use the plug’s VCC and GND positions (connector pin X, Y) so your cable is wired correctly. So: data = GPIO numbers on the Pico; power = Pico 3V3/GND on the adapter side, and connector pin numbers on the plug side. + +**Conventions:** +- **Output mode** = adapter emulates a controller and connects to the console’s controller port. +- **Input (host) mode** = adapter reads a real console controller over GPIO and uses it as input (e.g. to send to Switch/Xbox over USB). +- PadIn = internal gamepad state (from USB/BT or from a GPIO host). Mappings below are **PadIn → console**. +- **Power:** Adapter side = Pico **3V3** and **GND** (board power pins). Console/controller side = **connector pin** numbers for VCC and GND on the plug. When **outputting** to the console, only connect adapter GND to the port’s GND. When **reading** a real controller, connect Pico **3V3** to the plug’s VCC pin and Pico **GND** to the plug’s GND pin. + +--- + +## 1. PlayStation 1 / PlayStation 2 (PS1/PS2) + +### Pin-out (output to console and input from real controller) + +PS1/PS2 use a **9-pin** controller connector. Below: **GPIO** = RP2040 pin (adapter); **connector** = plug pin # (console/controller cable). + +| Signal | Adapter (Pico) | Console/controller plug | Notes | +|---------------|----------------|--------------------------|---------------------------------| +| DATA | **GPIO 19** | Connector 1 | Bidirectional data line | +| COMMAND (CMD) | **GPIO 20** | Connector 2 | | +| GND | **GND** | Connector 4 | Not a GPIO — Pico GND pin | +| VCC | **3V3** | Connector 5 | Not a GPIO — Pico 3V3 pin; only when powering a controller | +| ATTENTION/SEL | **GPIO 21** | Connector 6 | Select / Attention | +| CLOCK (CLK) | **GPIO 22** | Connector 7 | | +| ACKNOWLEDGE | **GPIO 26** | Connector 9 | ACK from controller to console | + +**Output mode:** Connect each GPIO to the same-numbered connector pin and Pico **GND** to connector **4** (do not use console VCC). **Input mode:** Same GPIO↔connector data mapping; connect Pico **3V3** → plug pin **5**, Pico **GND** → plug pin **4** to power the controller. + +### Default controller mapping (PadIn → PS1/PS2) + +| Console (PS1/PS2) | Adapter input (PadIn) | +|-------------------|------------------------| +| D-pad Up/Down/Left/Right | D-pad Up/Down/Left/Right | +| Select | Back (Select) | +| Start | Start | +| L3 | L3 (left stick click) | +| R3 | R3 (right stick click) | +| L1 | LB (left bumper) | +| R1 | RB (right bumper) | +| L2 | Left trigger (digital + analog) | +| R2 | Right trigger (digital + analog) | +| Triangle | Y | +| Circle | B | +| Cross | A | +| Square | X | +| Right stick X/Y | joystick_rx / joystick_ry | +| Left stick X/Y | joystick_lx / joystick_ly | + +Sticks use 0x80 (128) as center; full range 0–255. + +--- + +## 2. Dreamcast (Maple Bus) + +### Pin-out (output to console and input from real controller) + +Dreamcast uses a **5-pin** controller connector. **GPIO** = RP2040 (adapter); **connector** = plug pin #. + +| Signal | Adapter (Pico) | Console/controller plug | Notes | +|--------|----------------|--------------------------|-------------------------------| +| D0 | **GPIO 10** | Connector 1 | Maple Bus data line A | +| VCC | — | Connector 2 | +5 V from console (not 3V3) | +| GND | **GND** | Connector 3 | Not a GPIO — Pico GND pin | +| Sense | — | Connector 4 | Grounded by controller | +| D1 | **GPIO 11** | Connector 5 | Maple Bus data line B | + +**Output mode:** Connect **GPIO 10** and **11** to connector 1 and 5, and Pico **GND** to connector **3**. Do not connect console 5V to the Pico. **Input mode:** Same data + GND. To power a Dreamcast controller you need +5V (Pico is 3.3V — use console port or external 5V). + +No direction pin is used in the default configuration (`dir_pin = -1`). + +### Default controller mapping (PadIn → Dreamcast) + +| Console (Dreamcast) | Adapter input (PadIn) | +|---------------------|------------------------| +| D-pad Up/Down/Left/Right | D-pad Up/Down/Left/Right | +| A | A | +| B | B | +| X | X | +| Y | Y | +| Start | Start | +| C | RB | +| Z | LB | +| D (extra) | MISC | +| L trigger (analog) | trigger_l (0–255) | +| R trigger (analog) | trigger_r (0–255) | +| Left stick | joystick_lx / joystick_ly | +| Right stick | joystick_rx / joystick_ry | + +Dreamcast uses inverted logic for buttons (0 = pressed). Sticks are 0–255, 128 center. + +--- + +## 3. GameCube / Wii (GameCube ports) + +### Pin-out (output to console and input from real controller) + +GameCube controller port is a **7-pin** connector. **GPIO** = RP2040 (adapter); **connector** = plug pin #. + +| Signal | Adapter (Pico) | Console/controller plug | Notes | +|--------|----------------|--------------------------|------------------------------------| +| — | — | Connector 1 | 5 V rumble (not used for logic) | +| DATA | **GPIO 19** | Connector 2 | Single-wire JoyBus data | +| GND | **GND** | Connector 3, 4 | Not a GPIO — Pico GND pin | +| 3.3 V | **3V3** | Connector 6 | Not a GPIO — Pico 3V3; only when powering a controller | + +**Output mode:** Connect **GPIO 19** to connector **2** and Pico **GND** to connector **3** (and/or **4**). Do not connect console 5V or 3.3V to the Pico. **Input mode:** Same DATA and GND; connect Pico **3V3** → plug **6** to power the controller. + +### Default controller mapping (PadIn → GameCube) + +| Console (GameCube) | Adapter input (PadIn) | +|--------------------|------------------------| +| D-pad Up/Down/Left/Right | D-pad Up/Down/Left/Right | +| A | A | +| B | B | +| X | X | +| Y | Y | +| Start | Start | +| Z | MISC | +| L | LB | +| R | RB | +| L trigger (analog) | trigger_l (0–255) | +| R trigger (analog) | trigger_r (0–255) | +| Left stick | joystick_lx / joystick_ly | +| C-stick (right) | joystick_rx / joystick_ry | + +Sticks use 0x80 (128) as center; full range 0–255. + +--- + +## 4. Nintendo 64 (N64) + +### Pin-out (output to console and input from real controller) + +N64 controller port is a **3-pin** connector. **GPIO** = RP2040 (adapter); **connector** = plug pin #. + +| Signal | Adapter (Pico) | Console/controller plug | Notes | +|--------|----------------|--------------------------|------------------------------------| +| VCC | **3V3** | Connector 1 | Not a GPIO — Pico 3V3; only when powering a controller | +| DATA | **GPIO 19** | Connector 2 | Single-wire data (3.3 V logic) | +| GND | **GND** | Connector 3 | Not a GPIO — Pico GND pin | + +**Output mode:** Connect **GPIO 19** to connector **2** and Pico **GND** to connector **3**. Do not connect console 3.3V to the Pico. **Input mode:** Same DATA and GND; connect Pico **3V3** → plug **1** to power the controller. + +Same physical pin (GP19) as GameCube; only one of N64 or GameCube is active at a time. + +### Default controller mapping (PadIn → N64) + +| Console (N64) | Adapter input (PadIn) | +|---------------|------------------------| +| D-pad Up/Down/Left/Right | D-pad Up/Down/Left/Right | +| A | A | +| B | B | +| Z | MISC | +| Start | Start | +| L | LB | +| R | RB | +| C-Up | Right stick Y negative (threshold 4000) | +| C-Down | Right stick Y positive (threshold 4000) | +| C-Left | Right stick X negative (threshold 4000) | +| C-Right | Right stick X positive (threshold 4000) | +| Joystick X/Y | joystick_lx / joystick_ly | + +N64 stick is signed 8-bit, 0x80 center. C-buttons are derived from the right analog stick with a ±4000 threshold; diagonals combine. + +--- + +## Summary table (output mode: Pico GPIO + power) + +| Mode | Pico: data (GPIO) | Pico: power | Plug: GND | Plug: VCC (input mode only) | +|----------|---------------------|--------------|------------|------------------------------| +| PS1/PS2 | 19, 20, 21, 22, 26 | GND | Connector 4 | Connector 5 (Pico 3V3) | +| Dreamcast| 10, 11 | GND | Connector 3 | Connector 2 (5V from console) | +| GameCube | 19 | GND | Connector 3 or 4 | Connector 6 (Pico 3V3) | +| N64 | 19 | GND | Connector 3 | Connector 1 (Pico 3V3) | + +Data lines use **GPIO** numbers on the Pico. Power uses the Pico’s **GND** and **3V3** pins (not GPIO). Connector columns are the **plug pin numbers** on the console/controller cable. When **reading** a controller, also connect Pico 3V3 to the plug’s VCC pin (except Dreamcast, which needs 5V from the console or another source). + +**Note:** GameCube and N64 share GP19. Do not use both at the same time on the same pin; switch output mode (and input source if using GPIO input) as needed. + +--- + +## Changing mappings + +Default mappings are fixed in the device drivers. User-configurable button remapping is available for **USB device** modes (e.g. Switch, XInput) via the web app; GPIO output modes (PS1/PS2, Dreamcast, GameCube, N64) currently use the defaults above only. To change them you would need to edit the corresponding driver source (e.g. `PS1PS2.cpp`, `Dreamcast.cpp`, `GameCube.cpp`, `N64.cpp`) and rebuild. diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index eb061d54..7de53a8f 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -90,16 +90,21 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad - `src/OGXMini/Board/Standard.cpp`, `PicoW.cpp`, `Four_Channel_I2C.cpp` — use `sleep_us(MAIN_LOOP_DELAY_US)` when `> 0`. - `CMakeLists.txt` — `MAIN_LOOP_DELAY_US` cache variable (default 0). -### XInput: always send latest state +### XInput (360): report always fresh; send when ready (minimal latency) -In XInput mode, the adapter no longer sends a report only when `gamepad.new_pad_in()` is true. It **always** reads the current gamepad state and sends whenever the USB IN endpoint is free. That way the host (e.g. 360) gets updates at its poll interval (4 ms) with the freshest state, instead of being limited by how often the BT stack sets “new input.” Reduces perceived latency with PS5/Xbox One over Bluetooth. +Same goal as Switch Pro and PS3: the only added latency when using a wireless controller is the Bluetooth radio. -**File:** `src/USBDevice/DeviceDriver/XInput/XInput.cpp` — `process()` always builds and sends the report; no gate on `new_pad_in()`. +- **Every** `process()` call: read `get_pad_in()` and build `in_report_` (buttons, triggers, sticks). Then, if suspended, wake; call `tud_xinput::send_report(&in_report_)`. `send_report()` only actually transmits when the IN endpoint is free (`send_report_ready()`); otherwise we keep the latest `in_report_` so that (1) the host’s `get_report_cb` returns current state if it polls, and (2) the next time the endpoint is free we send that report. No `new_pad_in()` gate. +- **File:** `src/USBDevice/DeviceDriver/XInput/XInput.cpp` — `process()` always builds `in_report_` every loop; `tud_xinput::send_report()` sends only when `send_report_ready()` (see `tud_xinput.cpp`). -### Switch and PS3: latest state when USB ready +### Switch Pro and PS3: report always fresh; send when ready (minimal latency) -- **Switch (Pro emulation):** Each `process()` call reads fresh `get_pad_in()`, builds the report, and sends when `tud_hid_n_ready(0)`. No `new_pad_in()` gate — the host gets the latest state every time the IN endpoint is free. -- **PS3:** Report is built only when `tud_hid_ready()`; when ready, it uses `get_pad_in()` so the console always receives the latest state. Same low-latency pattern as XInput. +**Goal:** For Switch Pro and PS3 output modes, the only added latency should be wireless Bluetooth (radio) when using a BT controller. The adapter does not batch, throttle, or delay reports. + +- **Switch Pro:** Every `process()` call reads `get_pad_in()`, builds `switch_report_`, and builds the standard or subcommand report into `report_` **before** any USB decisions. So (1) the host’s `get_report` (poll) always gets the latest `report_`, and (2) when `tud_hid_n_ready(0)` we push that same report. Init reply (0x81) is sent first when pending, then the standard report. No “only build when ready” — report is always current. +- **PS3:** Every `process()` call reads `get_pad_in()` and builds `report_in_` (full DS3 report). Then, when `tud_hid_ready()`, we send it. So (1) the host’s `get_report_cb` always returns the latest `report_in_`, and (2) we push that report whenever the IN endpoint is free. No “only build when ready” — report is always current. + +Both modes: no `new_pad_in()` gate; main loop runs with `MAIN_LOOP_DELAY_US=0` by default; `tud_task()` runs before `process()` so the endpoint is ready when we try to send. ### Main loop order: tud_task() before process() @@ -148,6 +153,16 @@ Some 8BitDo wired XInput controllers (VID 0x2DC8, PID 0x3016 or 0x3106) can disc --- +## PS5 (DualSense) over Bluetooth — reducing perceived delay vs Xbox One + +**Why PS5 can feel slower than Xbox One over BT:** DualSense sends larger reports (78 bytes, with gyro/accel), and Bluepad32’s DS5 parser does more work per report (calibration, etc.). Xbox One reports are smaller and the parser is lighter. Bluetooth poll/report rate and radio latency dominate; the adapter’s job is to not add extra delay. + +**Change in this firmware:** The PS5 adaptive-trigger toggle (touchpad/mute button) now runs **after** `set_pad_in(gp_in)`. Previously it ran at the start of the callback; when you pressed the touchpad it could send two output reports (left/right trigger effect) before updating gamepad state, which could delay the next main-loop read. Now the gamepad state is always written first, then the trigger effect is sent, so input is not held up by the trigger command. + +**If you need minimum latency with a DualSense:** Use the controller **wired** on the PIO USB host port when possible; wired PS5 uses the same low-latency path as other USB host controllers and avoids BT report size and rate limits. + +--- + ## Switch Pro — analog stick sensitivity A configurable sensitivity gain is applied to the analog sticks in Switch Pro emulation. Raw stick values (outside the deadzone) are scaled by **STICK_GAIN_NUM / STICK_GAIN_DEN** (default 120/100 = 1.2×) before mapping to the 12-bit Switch report. The same physical deflection produces slightly larger output for a more responsive feel. @@ -160,8 +175,8 @@ A configurable sensitivity gain is applied to the analog sticks in Switch Pro em | Area | Improvement | |------|-------------| -| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. | +| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. Report built every loop, send when endpoint ready — same minimal-latency pattern as Switch/PS3. | | **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. | | **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. | | **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). | -| **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). | +| **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). Switch Pro and PS3 always build report every loop so host poll (`get_report`) and IN push both see current state — only remaining delay is BT radio when wireless. | diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index 8a122925..42f0ed93 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -36,9 +36,24 @@ btstack_timer_source_t led_timer_; bool led_timer_set_{false}; bool feedback_timer_set_{false}; +static constexpr uint32_t GPIO_PROCESS_INTERVAL_MS = 4; +static btstack_timer_source_t gpio_process_timer_; +static void (*gpio_process_cb_)(void*) = nullptr; +static void* gpio_process_ctx_ = nullptr; + +static void gpio_process_timer_cb(btstack_timer_source_t* ts) { + if (gpio_process_cb_ != nullptr && gpio_process_ctx_ != nullptr) { + gpio_process_cb_(gpio_process_ctx_); + } + btstack_run_loop_set_timer(ts, GPIO_PROCESS_INTERVAL_MS); + btstack_run_loop_add_timer(ts); +} + // PS5: touchpad click toggles adaptive triggers (per-controller state) static bool adaptive_trigger_enabled_[MAX_GAMEPADS]{false}; static bool prev_touchpad_clicked_[MAX_GAMEPADS]{false}; +// Defer sending adaptive trigger effect out of BT callback to avoid l2cap_send in callback (reduces input lag) +static bool pending_adaptive_trigger_send_[MAX_GAMEPADS]{false}; bool any_connected() { @@ -187,6 +202,7 @@ static void device_disconnected_cb(uni_hid_device_t* device) { bt_devices_[idx].connected = false; prev_touchpad_clicked_[idx] = false; + pending_adaptive_trigger_send_[idx] = false; bt_devices_[idx].gamepad->reset_pad_in(); if (!led_timer_set_ && !any_connected()) { @@ -258,24 +274,6 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr uni_gamepad_t *uni_gp = &controller->gamepad; int idx = uni_hid_device_get_idx_for_instance(device); - // PS5: capture/mute button toggles adaptive triggers (touchpad click not in Bluepad32 misc_buttons) - if (device->controller_type == CONTROLLER_TYPE_PS5Controller && idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { - bool touchpad_clicked = (uni_gp->misc_buttons & MISC_BUTTON_CAPTURE) != 0; - if (touchpad_clicked && !prev_touchpad_clicked_[idx]) { - adaptive_trigger_enabled_[idx] = !adaptive_trigger_enabled_[idx]; - if (adaptive_trigger_enabled_[idx]) { - ds5_adaptive_trigger_effect_t on = ds5_new_adaptive_trigger_effect_feedback(5, 4); - ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &on); - ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &on); - } else { - ds5_adaptive_trigger_effect_t off = ds5_new_adaptive_trigger_effect_off(); - ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &off); - ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &off); - } - } - prev_touchpad_clicked_[idx] = touchpad_clicked; - } - #if BLUEPAD32_UART_LOG_INPUT { bool changed = std::memcmp(uni_gp, &prev_uni_gp[idx], sizeof(uni_gamepad_t)) != 0; @@ -393,6 +391,16 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr gamepad->set_pad_in(gp_in); + // PS5: defer adaptive trigger send to main loop so callback never does l2cap_send (reduces input lag) + if (device->controller_type == CONTROLLER_TYPE_PS5Controller && idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { + bool touchpad_clicked = (uni_gp->misc_buttons & MISC_BUTTON_CAPTURE) != 0; + if (touchpad_clicked && !prev_touchpad_clicked_[idx]) { + adaptive_trigger_enabled_[idx] = !adaptive_trigger_enabled_[idx]; + pending_adaptive_trigger_send_[idx] = true; + } + prev_touchpad_clicked_[idx] = touchpad_clicked; + } + #if BLUEPAD32_UART_LOG_INPUT if (idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { std::memcpy(&prev_uni_gp[idx], uni_gp, sizeof(uni_gamepad_t)); @@ -405,6 +413,27 @@ const uni_property_t* get_property_cb(uni_property_idx_t idx) return nullptr; } +void process_pending_adaptive_triggers() +{ + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + if (!pending_adaptive_trigger_send_[i]) + continue; + pending_adaptive_trigger_send_[i] = false; + uni_hid_device_t* device = uni_hid_device_get_instance_for_idx(static_cast(i)); + if (!device || device->controller_type != CONTROLLER_TYPE_PS5Controller) + continue; + if (adaptive_trigger_enabled_[i]) { + ds5_adaptive_trigger_effect_t on = ds5_new_adaptive_trigger_effect_feedback(5, 4); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &on); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &on); + } else { + ds5_adaptive_trigger_effect_t off = ds5_new_adaptive_trigger_effect_off(); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &off); + ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &off); + } + } +} + uni_platform* get_driver() { static uni_platform driver = @@ -425,6 +454,11 @@ uni_platform* get_driver() //Public API +void set_gpio_device_process_callback(void (*callback)(void* ctx), void* ctx) { + gpio_process_cb_ = callback; + gpio_process_ctx_ = ctx; +} + void init(Gamepad(&gamepads)[MAX_GAMEPADS]) { for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) @@ -440,6 +474,13 @@ void init(Gamepad(&gamepads)[MAX_GAMEPADS]) led_timer_.context = nullptr; btstack_run_loop_set_timer(&led_timer_, LED_CHECK_TIME_MS); btstack_run_loop_add_timer(&led_timer_); + + if (gpio_process_cb_ != nullptr) { + gpio_process_timer_.process = gpio_process_timer_cb; + gpio_process_timer_.context = nullptr; + btstack_run_loop_set_timer(&gpio_process_timer_, GPIO_PROCESS_INTERVAL_MS); + btstack_run_loop_add_timer(&gpio_process_timer_); + } } void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]) diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.h b/Firmware/RP2040/src/Bluepad32/Bluepad32.h index c823ed92..47a95123 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.h +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.h @@ -12,4 +12,8 @@ namespace bluepad32 { void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]); void init(Gamepad(&gamepads)[MAX_GAMEPADS]); + /** Call from main loop to send deferred PS5 adaptive-trigger updates (keeps BT callback fast). */ + void process_pending_adaptive_triggers(); + /** Optional: when set, a timer in the BT run loop calls this every ~4 ms (for GPIO device modes: PS1/PS2, GameCube). Call before run_task(). */ + void set_gpio_device_process_callback(void (*callback)(void* ctx), void* ctx); } \ No newline at end of file diff --git a/Firmware/RP2040/src/Board/ogxm_log.cpp b/Firmware/RP2040/src/Board/ogxm_log.cpp index 9fb6fc44..817af601 100644 --- a/Firmware/RP2040/src/Board/ogxm_log.cpp +++ b/Firmware/RP2040/src/Board/ogxm_log.cpp @@ -26,6 +26,8 @@ std::ostream& operator<<(std::ostream& os, DeviceDriverType type) { case DeviceDriverType::SWITCH: os << "SWITCH"; break; case DeviceDriverType::WIIU: os << "WIIU"; break; case DeviceDriverType::WII: os << "WII"; break; + case DeviceDriverType::PS1PS2: os << "PS1PS2"; break; + case DeviceDriverType::GAMECUBE: os << "GAMECUBE"; break; case DeviceDriverType::WEBAPP: os << "WEBAPP"; break; case DeviceDriverType::UART_BRIDGE: os << "UART_BRIDGE"; break; default: os << "UNKNOWN"; break; diff --git a/Firmware/RP2040/src/Gamepad/Gamepad.h b/Firmware/RP2040/src/Gamepad/Gamepad.h index 9e751c6d..e1c90307 100644 --- a/Firmware/RP2040/src/Gamepad/Gamepad.h +++ b/Firmware/RP2040/src/Gamepad/Gamepad.h @@ -158,10 +158,18 @@ class Gamepad inline PadIn get_pad_in() { mutex_enter_blocking(&pad_in_mutex_); - PadIn pad_in = pad_in_; - new_pad_in_.store(false); + PadIn pad_in; + if (pad_in_count_ > 0) { + pad_in = pad_in_queue_[pad_in_head_]; + pad_in_head_ = (pad_in_head_ + 1) % PAD_IN_QUEUE_SIZE; + pad_in_count_--; + last_pad_in_ = pad_in; + if (pad_in_count_ == 0) + new_pad_in_.store(false); + } else { + pad_in = last_pad_in_; + } mutex_exit(&pad_in_mutex_); - return pad_in; } @@ -213,7 +221,16 @@ class Gamepad inline void set_pad_in(PadIn pad_in) { mutex_enter_blocking(&pad_in_mutex_); - pad_in_ = pad_in; + if (pad_in_count_ < PAD_IN_QUEUE_SIZE) { + pad_in_queue_[pad_in_tail_] = pad_in; + pad_in_tail_ = (pad_in_tail_ + 1) % PAD_IN_QUEUE_SIZE; + pad_in_count_++; + } else { + /* Queue full: drop oldest, keep newest so fast taps (press+release) both get sent */ + pad_in_head_ = (pad_in_head_ + 1) % PAD_IN_QUEUE_SIZE; + pad_in_queue_[pad_in_tail_] = pad_in; + pad_in_tail_ = (pad_in_tail_ + 1) % PAD_IN_QUEUE_SIZE; + } new_pad_in_.store(true); mutex_exit(&pad_in_mutex_); } @@ -237,10 +254,13 @@ class Gamepad void set_stick_y_positive_is_up(bool v) { stick_y_positive_is_up_ = v; } bool stick_y_positive_is_up() const { return stick_y_positive_is_up_; } - inline void reset_pad_in() - { + inline void reset_pad_in() + { mutex_enter_blocking(&pad_in_mutex_); - pad_in_ = PadIn(); + pad_in_head_ = 0; + pad_in_tail_ = 0; + pad_in_count_ = 0; + last_pad_in_ = PadIn(); mutex_exit(&pad_in_mutex_); new_pad_in_.store(true); } @@ -354,13 +374,19 @@ class Gamepad : trigger_value; } -private: + static constexpr unsigned PAD_IN_QUEUE_SIZE = 2; + +private: mutex_t pad_in_mutex_; mutex_t pad_out_mutex_; mutex_t chatpad_in_mutex_; PadOut pad_out_; - PadIn pad_in_; + PadIn pad_in_queue_[PAD_IN_QUEUE_SIZE]; + unsigned pad_in_head_{0}; + unsigned pad_in_tail_{0}; + unsigned pad_in_count_{0}; + PadIn last_pad_in_{}; ChatpadIn chatpad_in_{0}; std::atomic new_pad_in_{false}; diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index 7f4d289b..4a9114a2 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -12,8 +12,15 @@ #include "bsp/board_api.h" #include "USBDevice/DeviceManager.h" +#include "USBDevice/DeviceDriver/DeviceDriver.h" #include "USBDevice/DeviceDriver/DeviceDriverTypes.h" +#include "USBDevice/DeviceDriver/PS1PS2/psx_simulator.h" +#include "USBDevice/DeviceDriver/GameCube/gc_simulator.h" +#include "USBDevice/DeviceDriver/Dreamcast/Dreamcast.h" +#include "USBDevice/DeviceDriver/N64/N64.h" +#include "USBHost/GPIOHost/GPIOHost.h" #include "UserSettings/UserSettings.h" +#include "Board/Config.h" #include "Board/board_api.h" #include "Board/ogxm_log.h" #include "Bluepad32/Bluepad32.h" @@ -46,6 +53,27 @@ extern "C" void wii_led_off(void) { board_api::set_led(false); } Gamepad _gamepads[MAX_GAMEPADS]; +static DeviceDriver* s_gpio_device_driver = nullptr; +static void gpio_device_process_cb(void* ctx) { + (void)ctx; + if (s_gpio_device_driver) { + HostInputSource input_src = UserSettings::get_instance().get_input_source(); + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::DREAMCAST_GPIO) { + GPIOHost::dreamcast_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_poll(_gamepads[0]); + } + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + s_gpio_device_driver->process(i, _gamepads[i]); + } + bluepad32::process_pending_adaptive_triggers(); + } +} + #if defined(CONFIG_EN_USB_HOST) constexpr uint32_t FEEDBACK_DELAY_MS = 200; @@ -172,8 +200,10 @@ void pico_w::run() { UserSettings& user_settings = UserSettings::get_instance(); DeviceDriver* device_driver = DeviceManager::get_instance().get_driver(); - const bool wii_mode = (user_settings.get_current_driver() == DeviceDriverType::WII); - OGXM_LOG("PicoW run: wii_mode=" + std::string(wii_mode ? "1" : "0") + "\n"); + DeviceDriverType current_driver = user_settings.get_current_driver(); + const bool wii_mode = (current_driver == DeviceDriverType::WII); + const bool gpio_device_mode = (current_driver == DeviceDriverType::PS1PS2 || current_driver == DeviceDriverType::GAMECUBE || current_driver == DeviceDriverType::DREAMCAST); + OGXM_LOG("PicoW run: wii_mode=" + std::string(wii_mode ? "1" : "0") + " gpio_device_mode=" + std::string(gpio_device_mode ? "1" : "0") + "\n"); #if defined(CONFIG_EN_USB_HOST) if (wii_mode) { @@ -185,11 +215,52 @@ void pico_w::run() { wiimote_emulator(&s_wiimote_report); // never returns: BT run loop, LED blinks until connected } else #endif - { + if (gpio_device_mode) { + OGXM_LOG("PicoW run: GPIO device mode (PS1/PS2 or GameCube), Core1 = protocol, Core0 = BT\n"); + HostInputSource input_src = user_settings.get_input_source(); + if (current_driver == DeviceDriverType::DREAMCAST) { + dreamcast_set_core1_device_mode(input_src != HostInputSource::DREAMCAST_GPIO); + } + if (current_driver == DeviceDriverType::PS1PS2) { + multicore_launch_core1(psx_device_main); + } else if (current_driver == DeviceDriverType::GAMECUBE) { + multicore_launch_core1(gamecube_core1_entry); + } else if (current_driver == DeviceDriverType::N64) { + multicore_launch_core1(n64_core1_entry); + } else { + multicore_launch_core1(dreamcast_core1_entry); + } + s_gpio_device_driver = device_driver; + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_init(0, 20, 19); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_init(0, 19); + } else if (input_src == HostInputSource::DREAMCAST_GPIO) { + GPIOHost::dreamcast_host_init(1, 0, 10, -1); + } else if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_init(0, 19); + } + bluepad32::set_gpio_device_process_callback(gpio_device_process_cb, nullptr); + board_api::init_bluetooth(); + board_api::set_led(true); + BLEServer::init_server(_gamepads); + bluepad32::run_task(_gamepads); // never returns: BT run loop + process timer + } else { tud_init(BOARD_TUD_RHPORT); OGXM_LOG("PicoW run: tud_init done, launching Core1 (BT)\n"); multicore_launch_core1(core1_task); OGXM_LOG("PicoW run: Core1 (BT) launched\n"); + + HostInputSource input_src = user_settings.get_input_source(); + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_init(0, 20, 19); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_init(0, 19); + } else if (input_src == HostInputSource::DREAMCAST_GPIO) { + GPIOHost::dreamcast_host_init(1, 0, 10, -1); + } else if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_init(0, 19); + } } uint32_t tid_gp_check = TaskQueue::Core0::get_new_task_id(); @@ -200,11 +271,23 @@ void pico_w::run() { static uint32_t loop_count = 0; while (true) { TaskQueue::Core0::process_tasks(); - if (!wii_mode) + if (!wii_mode) { tud_task(); + HostInputSource input_src = UserSettings::get_instance().get_input_source(); + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::DREAMCAST_GPIO) { + GPIOHost::dreamcast_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_poll(_gamepads[0]); + } + } for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { device_driver->process(i, _gamepads[i]); } + bluepad32::process_pending_adaptive_triggers(); if (!wii_mode) { if (tud_mounted() && !mounted_logged) { mounted_logged = true; diff --git a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp index 5d9b199f..f41f3584 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp @@ -10,9 +10,16 @@ #include "pio_usb.h" #include "USBHost/HostManager.h" +#include "USBHost/GPIOHost/GPIOHost.h" #include "USBDevice/DeviceManager.h" +#include "USBDevice/DeviceDriver/DeviceDriverTypes.h" +#include "USBDevice/DeviceDriver/PS1PS2/psx_simulator.h" +#include "USBDevice/DeviceDriver/GameCube/gc_simulator.h" +#include "USBDevice/DeviceDriver/Dreamcast/Dreamcast.h" +#include "USBDevice/DeviceDriver/N64/N64.h" #include "TaskQueue/TaskQueue.h" #include "Gamepad/Gamepad.h" +#include "UserSettings/UserSettings.h" #include "Board/board_api.h" #include "Board/ogxm_log.h" @@ -53,10 +60,13 @@ void set_gp_check_timer(uint32_t task_id) { TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, [&user_settings] { - //Check gamepad inputs for button combo to change usb device driver - if (user_settings.check_for_driver_change(_gamepads[0])) { + // Check for input source change (Start+Select when in PS1PS2/GAMECUBE mode) + if (user_settings.check_for_input_source_change(_gamepads[0])) { + // No reboot; input source stored + } + // Check gamepad inputs for button combo to change usb device driver + else if (user_settings.check_for_driver_change(_gamepads[0])) { OGXM_LOG("Driver change detected, storing new driver.\n"); - //This will store the new mode and reboot the pico user_settings.store_driver_type(user_settings.get_current_driver()); } }); @@ -70,6 +80,11 @@ void standard::host_mounted(bool host_mounted) { static std::atomic tud_is_inited = false; board_api::set_led(host_mounted); + DeviceDriverType dt = DeviceManager::get_instance().get_driver_type(); + if (dt == DeviceDriverType::PS1PS2 || dt == DeviceDriverType::GAMECUBE || dt == DeviceDriverType::DREAMCAST) { + return; + } + if (!host_mounted && tud_is_inited.load()) { TaskQueue::Core0::queue_task([]() { OGXM_LOG("USB disconnected, rebooting.\n"); @@ -77,8 +92,8 @@ void standard::host_mounted(bool host_mounted) { board_api::reboot(); }); } else if (!tud_is_inited.load()) { - TaskQueue::Core0::queue_task([]() { - tud_init(BOARD_TUD_RHPORT); + TaskQueue::Core0::queue_task([]() { + tud_init(BOARD_TUD_RHPORT); tud_is_inited.store(true); }); } @@ -98,20 +113,74 @@ void standard::initialize() { } void standard::run() { - multicore_reset_core1(); - multicore_launch_core1(core1_task); - DeviceDriverType current_driver = UserSettings::get_instance().get_current_driver(); + const bool gpio_device_mode = (current_driver == DeviceDriverType::PS1PS2 || current_driver == DeviceDriverType::GAMECUBE || current_driver == DeviceDriverType::DREAMCAST); - if (current_driver != DeviceDriverType::WEBAPP) { - // Wait for something to call host_mounted() - while (!tud_inited()) { + if (gpio_device_mode) { + HostManager& host_manager = HostManager::get_instance(); + host_manager.initialize(_gamepads); + + while (!board_api::usb::host_connected()) { TaskQueue::Core0::process_tasks(); sleep_ms(100); } + + pio_usb_configuration_t pio_cfg = PIO_USB_CONFIG; + tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); + tuh_init(BOARD_TUH_RHPORT); + + uint32_t tid_feedback = TaskQueue::Core0::get_new_task_id(); + TaskQueue::Core0::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, [&host_manager]() { + host_manager.send_feedback(); + }); + + HostInputSource input_src = UserSettings::get_instance().get_input_source(); + if (current_driver == DeviceDriverType::DREAMCAST) { + dreamcast_set_core1_device_mode(input_src != HostInputSource::DREAMCAST_GPIO); + } + multicore_reset_core1(); + if (current_driver == DeviceDriverType::PS1PS2) { + multicore_launch_core1(psx_device_main); + } else if (current_driver == DeviceDriverType::GAMECUBE) { + multicore_launch_core1(gamecube_core1_entry); + } else if (current_driver == DeviceDriverType::N64) { + multicore_launch_core1(n64_core1_entry); + } else { + multicore_launch_core1(dreamcast_core1_entry); + } + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_init(0, 20, 19); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_init(0, 19); + } + if (input_src == HostInputSource::DREAMCAST_GPIO) { + GPIOHost::dreamcast_host_init(1, 0, 10, -1); + } + if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_init(0, 19); + } } else { - //Connect immediately in WebApp mode - host_mounted(true); + multicore_reset_core1(); + multicore_launch_core1(core1_task); + + if (current_driver != DeviceDriverType::WEBAPP) { + while (!tud_inited()) { + TaskQueue::Core0::process_tasks(); + sleep_ms(100); + } + } else { + host_mounted(true); + } + + /* GPIO input when output is USB (e.g. real PS1/PS2/GC controller → Switch/Xbox/DInput) */ + HostInputSource input_src = UserSettings::get_instance().get_input_source(); + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_init(0, 20, 19); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_init(0, 19); + } else if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_init(0, 19); + } } uint32_t tid_gp_check = TaskQueue::Core0::get_new_task_id(); @@ -121,7 +190,31 @@ void standard::run() { while (true) { TaskQueue::Core0::process_tasks(); - tud_task(); + if (gpio_device_mode) { + tuh_task(); + HostInputSource input_src = UserSettings::get_instance().get_input_source(); + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::DREAMCAST_GPIO) { + GPIOHost::dreamcast_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_poll(_gamepads[0]); + } + } else { + tud_task(); + HostInputSource input_src = UserSettings::get_instance().get_input_source(); + if (input_src == HostInputSource::PSX_GPIO) { + GPIOHost::psx_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + GPIOHost::joybus_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::DREAMCAST_GPIO) { + GPIOHost::dreamcast_host_poll(_gamepads[0]); + } else if (input_src == HostInputSource::N64_GPIO) { + GPIOHost::n64_host_poll(_gamepads[0]); + } + } for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { device_driver->process(i, _gamepads[i]); } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h index 0ba091ca..9b8842c8 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h @@ -16,6 +16,10 @@ enum class DeviceDriverType : uint8_t SWITCH, WIIU, WII, // Wiimote (Pico W/2W: controller on PIO USB, BT for Wii link) + PS1PS2, // PS1/PS2 controller over GPIO (no USB device; output to console port) + GAMECUBE, // GameCube controller over GPIO (single wire; no USB device) + DREAMCAST, // Dreamcast controller over Maple Bus GPIO (no USB device; output/input to console) + N64, // N64 controller over GPIO (single wire; no USB device; output to N64 console) WEBAPP = 100, UART_BRIDGE }; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp new file mode 100644 index 00000000..b7e0e4a0 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp @@ -0,0 +1,184 @@ +/* Dreamcast Maple Bus output (device). USB/BT gamepad -> adapter -> Dreamcast. */ + +#include "USBDevice/DeviceDriver/Dreamcast/Dreamcast.h" +#include "Gamepad/Gamepad.h" +#include "USBHost/GPIOHost/dreamcast_host/MapleBus.h" +#include "USBHost/GPIOHost/dreamcast_host/MaplePacket.hpp" +#include "USBHost/GPIOHost/dreamcast_host/dreamcast_constants.h" +#include "USBHost/GPIOHost/dreamcast_host/dreamcast_structures.h" +#include "USBHost/GPIOHost/dreamcast_host/maple_config.h" +#include +#include +#include +#include + +static bool s_core1_device_mode = false; +static controller_condition_t s_device_condition; +static mutex_t s_condition_mutex; + +/* Standard controller device info (28 words). Layout from BlueRetro / Maple spec. */ +#define DC_ID_CTRL 0x00000001 +#define DC_DESC_CTRL 0x000F06FE +#define DC_PWR_CTRL 0xAE01F401 + +static const uint8_t s_ctrl_area_dir_name[32] = { + 0x72, 0x44, 0x00, 0xFF, 0x63, 0x6D, 0x61, 0x65, 0x20, 0x74, 0x73, 0x61, 0x74, 0x6E, 0x6F, 0x43, + 0x6C, 0x6C, 0x6F, 0x72, 0x20, 0x20, 0x72, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +}; +static const uint8_t s_brand[32] = { + 'O', 'G', 'X', '-', 'M', 'i', 'n', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', +}; + +static void fill_device_info_payload(uint32_t* out) { + out[0] = DC_ID_CTRL; + out[1] = DC_DESC_CTRL; + out[2] = 0u; + out[3] = 0u; + memcpy(&out[4], s_ctrl_area_dir_name, 32); + memcpy(&out[12], s_brand, 32); + for (int i = 20; i < 27; i++) out[i] = 0u; + out[27] = DC_PWR_CTRL; +} + +void dreamcast_set_core1_device_mode(bool enable) { + s_core1_device_mode = enable; +} + +static void pad_in_to_controller_condition(const Gamepad::PadIn& pad, controller_condition_t& cond) { + memset(&cond, 0, sizeof(cond)); + cond.l = pad.trigger_l; + cond.r = pad.trigger_r; + cond.a = (pad.buttons & Gamepad::BUTTON_A) ? 0 : 1; + cond.b = (pad.buttons & Gamepad::BUTTON_B) ? 0 : 1; + cond.x = (pad.buttons & Gamepad::BUTTON_X) ? 0 : 1; + cond.y = (pad.buttons & Gamepad::BUTTON_Y) ? 0 : 1; + cond.start = (pad.buttons & Gamepad::BUTTON_START) ? 0 : 1; + cond.c = (pad.buttons & Gamepad::BUTTON_RB) ? 0 : 1; + cond.z = (pad.buttons & Gamepad::BUTTON_LB) ? 0 : 1; + cond.d = (pad.buttons & Gamepad::BUTTON_MISC) ? 0 : 1; + cond.up = (pad.dpad & Gamepad::DPAD_UP) ? 0 : 1; + cond.down = (pad.dpad & Gamepad::DPAD_DOWN) ? 0 : 1; + cond.left = (pad.dpad & Gamepad::DPAD_LEFT) ? 0 : 1; + cond.right= (pad.dpad & Gamepad::DPAD_RIGHT) ? 0 : 1; + cond.upb = cond.downb = cond.leftb = cond.rightb = 1; + /* Sticks: int16 -32767..32767 -> 0..255, 128 center */ + auto stick16_to_8 = [](int16_t v) -> uint8_t { + int32_t x = (int32_t)v * 127 / 32767 + 128; + if (x < 0) x = 0; + if (x > 255) x = 255; + return (uint8_t)x; + }; + cond.lAnalogLR = stick16_to_8(pad.joystick_lx); + cond.lAnalogUD = stick16_to_8(pad.joystick_ly); + cond.rAnalogLR = stick16_to_8(pad.joystick_rx); + cond.rAnalogUD = stick16_to_8(pad.joystick_ry); +} + +void DreamcastDevice::initialize() { + mutex_init(&s_condition_mutex); + memset(&s_device_condition, 0, sizeof(s_device_condition)); + s_device_condition.up = s_device_condition.down = s_device_condition.left = s_device_condition.right = 1; + s_device_condition.a = s_device_condition.b = s_device_condition.c = s_device_condition.x = 1; + s_device_condition.y = s_device_condition.z = s_device_condition.d = s_device_condition.start = 1; + s_device_condition.upb = s_device_condition.downb = s_device_condition.leftb = s_device_condition.rightb = 1; + s_device_condition.lAnalogLR = s_device_condition.lAnalogUD = 128; + s_device_condition.rAnalogLR = s_device_condition.rAnalogUD = 128; +} + +void DreamcastDevice::process(const uint8_t idx, Gamepad& gamepad) { + if (idx != 0) return; + Gamepad::PadIn pad = gamepad.get_pad_in(); + controller_condition_t cond; + pad_in_to_controller_condition(pad, cond); + mutex_enter_blocking(&s_condition_mutex); + memcpy(&s_device_condition, &cond, sizeof(s_device_condition)); + mutex_exit(&s_condition_mutex); +} + +void dreamcast_core1_entry(void) { + if (!s_core1_device_mode) { + while (true) sleep_ms(1); + return; + } + const uint32_t pinA = 10; + MapleBus bus(pinA, -1, true); + MaplePacket reqPacket, respPacket; + respPacket.payloadByteOrder = MaplePacket::ByteOrder::HOST; + + while (true) { + if (!bus.startRead(0, MaplePacket::ByteOrder::HOST)) + continue; + uint64_t deadline = time_us_64() + MAPLE_RESPONSE_TIMEOUT_US + 2000; + MapleBus::Status st; + while (time_us_64() < deadline) { + st = bus.processEvents(time_us_64()); + if (st.phase == MapleBus::Phase::READ_COMPLETE || st.phase == MapleBus::Phase::READ_FAILED) + break; + sleep_us(20); + } + if (st.phase != MapleBus::Phase::READ_COMPLETE || !st.readBuffer || st.readBufferLen < 1) + continue; + + uint32_t frameWord = st.readBuffer[0]; + uint8_t cmd = MaplePacket::Frame::getFrameCommand(frameWord, st.rxByteOrder); + uint8_t recipient = MaplePacket::Frame::getFrameRecipientAddr(frameWord, st.rxByteOrder); + uint8_t sender = MaplePacket::Frame::getFrameSenderAddr(frameWord, st.rxByteOrder); + + if (cmd == COMMAND_DEVICE_INFO_REQUEST) { + respPacket.setFrame(COMMAND_RESPONSE_DEVICE_INFO, MAPLE_HOST_ADDR, MAPLE_CTRL_ADDR, 28); + fill_device_info_payload(respPacket.payload); + respPacket.payloadCount = 28; + } else if (cmd == COMMAND_GET_CONDITION) { + mutex_enter_blocking(&s_condition_mutex); + uint32_t condWords[2]; + memcpy(condWords, &s_device_condition, sizeof(condWords)); + mutex_exit(&s_condition_mutex); + respPacket.setFrame(COMMAND_RESPONSE_DATA_XFER, MAPLE_HOST_ADDR, MAPLE_CTRL_ADDR, 3); + respPacket.payload[0] = DEVICE_FN_CONTROLLER; + respPacket.payload[1] = condWords[0]; + respPacket.payload[2] = condWords[1]; + respPacket.payloadCount = 3; + } else { + continue; + } + + if (!bus.write(respPacket, false)) + continue; + deadline = time_us_64() + 5000; + while (time_us_64() < deadline && bus.isBusy()) { + bus.processEvents(time_us_64()); + sleep_us(50); + } + } +} + +uint16_t DreamcastDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) { + (void)itf; (void)report_id; (void)report_type; (void)buffer; (void)req_len; + return 0; +} +void DreamcastDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) { + (void)itf; (void)report_id; (void)report_type; (void)buffer; (void)buffer_size; +} +bool DreamcastDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { + (void)rhport; (void)stage; (void)request; + return false; +} +const uint16_t* DreamcastDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void)index; (void)langid; + return nullptr; +} +const uint8_t* DreamcastDevice::get_descriptor_device_cb() { + return nullptr; +} +const uint8_t* DreamcastDevice::get_hid_descriptor_report_cb(uint8_t itf) { + (void)itf; + return nullptr; +} +const uint8_t* DreamcastDevice::get_descriptor_configuration_cb(uint8_t index) { + (void)index; + return nullptr; +} +const uint8_t* DreamcastDevice::get_descriptor_device_qualifier_cb() { + return nullptr; +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.h new file mode 100644 index 00000000..76eb6df2 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.h @@ -0,0 +1,30 @@ +/* Dreamcast Maple Bus output (device) – stub until DreamPicoPort Maple Bus HAL is ported. + * See Firmware/RP2040/docs/Dreamcast_Port.md for port steps from https://github.com/OrangeFox86/DreamPicoPort */ + +#ifndef _D_DREAMCAST_DRIVER_H_ +#define _D_DREAMCAST_DRIVER_H_ + +#include "USBDevice/DeviceDriver/DeviceDriver.h" + +class DreamcastDevice : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, class Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; +}; + +/** Entry point for core1 when driver is DREAMCAST (Maple Bus device loop). */ +void dreamcast_core1_entry(void); + +/** Call before launching core1: true = run as Maple device (USB/BT -> DC); false = bus used as host only. */ +void dreamcast_set_core1_device_mode(bool enable); + +#endif diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp new file mode 100644 index 00000000..8a92ddee --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp @@ -0,0 +1,106 @@ +#include +#include "USBDevice/DeviceDriver/GameCube/GameCube.h" +#include "USBDevice/DeviceDriver/GameCube/gc_simulator.h" + +#ifndef GAMECUBE_DATA_PIN +#define GAMECUBE_DATA_PIN 19 +#endif + +static GCReport* s_gc_report = nullptr; + +void gamecube_core1_entry(void) { + gc_device_main(0, s_gc_report, GAMECUBE_DATA_PIN); +} + +namespace { + constexpr uint8_t GC_A = 0x01; + constexpr uint8_t GC_B = 0x02; + constexpr uint8_t GC_X = 0x04; + constexpr uint8_t GC_Y = 0x08; + constexpr uint8_t GC_START = 0x10; + constexpr uint8_t GC_DPAD_LEFT = 0x01; + constexpr uint8_t GC_DPAD_RIGHT = 0x02; + constexpr uint8_t GC_DPAD_DOWN = 0x04; + constexpr uint8_t GC_DPAD_UP = 0x08; + constexpr uint8_t GC_Z = 0x10; + constexpr uint8_t GC_R = 0x20; + constexpr uint8_t GC_L = 0x40; + constexpr uint8_t GC_BYTE2_MSB = 0x80; + constexpr uint8_t STICK_CENTER = 0x80; +} + +void GameCubeDevice::initialize() { + std::memset(&gc_report_, 0, sizeof(gc_report_)); + s_gc_report = &gc_report_; + gc_report_.lx = STICK_CENTER; + gc_report_.ly = STICK_CENTER; + gc_report_.rx = STICK_CENTER; + gc_report_.ry = STICK_CENTER; + gc_report_.buttons2 = GC_BYTE2_MSB; +} + +void GameCubeDevice::process(const uint8_t idx, Gamepad& gamepad) { + (void)idx; + if (!gamepad.new_pad_in()) + return; + + Gamepad::PadIn gp = gamepad.get_pad_in(); + + gc_report_.buttons1 = 0; + if (gp.buttons & Gamepad::BUTTON_A) gc_report_.buttons1 |= GC_A; + if (gp.buttons & Gamepad::BUTTON_B) gc_report_.buttons1 |= GC_B; + if (gp.buttons & Gamepad::BUTTON_X) gc_report_.buttons1 |= GC_X; + if (gp.buttons & Gamepad::BUTTON_Y) gc_report_.buttons1 |= GC_Y; + if (gp.buttons & Gamepad::BUTTON_START) gc_report_.buttons1 |= GC_START; + + gc_report_.buttons2 = GC_BYTE2_MSB; + if (gp.dpad & Gamepad::DPAD_LEFT) gc_report_.buttons2 |= GC_DPAD_LEFT; + if (gp.dpad & Gamepad::DPAD_RIGHT) gc_report_.buttons2 |= GC_DPAD_RIGHT; + if (gp.dpad & Gamepad::DPAD_DOWN) gc_report_.buttons2 |= GC_DPAD_DOWN; + if (gp.dpad & Gamepad::DPAD_UP) gc_report_.buttons2 |= GC_DPAD_UP; + if (gp.buttons & Gamepad::BUTTON_MISC) gc_report_.buttons2 |= GC_Z; + if (gp.buttons & Gamepad::BUTTON_RB) gc_report_.buttons2 |= GC_R; + if (gp.buttons & Gamepad::BUTTON_LB) gc_report_.buttons2 |= GC_L; + + gc_report_.l = gp.trigger_l; + gc_report_.r = gp.trigger_r; + + int32_t lx = (int32_t)gp.joystick_lx * 127 / 32767 + STICK_CENTER; + int32_t ly = (int32_t)gp.joystick_ly * -127 / 32767 + STICK_CENTER; + int32_t rx = (int32_t)gp.joystick_rx * 127 / 32767 + STICK_CENTER; + int32_t ry = (int32_t)gp.joystick_ry * -127 / 32767 + STICK_CENTER; + if (lx < 0) lx = 0; else if (lx > 255) lx = 255; + if (ly < 0) ly = 0; else if (ly > 255) ly = 255; + if (rx < 0) rx = 0; else if (rx > 255) rx = 255; + if (ry < 0) ry = 0; else if (ry > 255) ry = 255; + gc_report_.lx = (uint8_t)lx; + gc_report_.ly = (uint8_t)ly; + gc_report_.rx = (uint8_t)rx; + gc_report_.ry = (uint8_t)ry; +} + +uint16_t GameCubeDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) { + (void)itf; (void)report_id; (void)report_type; (void)buffer; (void)req_len; + return 0; +} +void GameCubeDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) { + (void)itf; (void)report_id; (void)report_type; (void)buffer; (void)buffer_size; +} +bool GameCubeDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { + (void)rhport; (void)stage; (void)request; + return false; +} +const uint16_t* GameCubeDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void)index; (void)langid; + return nullptr; +} +const uint8_t* GameCubeDevice::get_descriptor_device_cb() { return nullptr; } +const uint8_t* GameCubeDevice::get_hid_descriptor_report_cb(uint8_t itf) { + (void)itf; + return nullptr; +} +const uint8_t* GameCubeDevice::get_descriptor_configuration_cb(uint8_t index) { + (void)index; + return nullptr; +} +const uint8_t* GameCubeDevice::get_descriptor_device_qualifier_cb() { return nullptr; } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.h new file mode 100644 index 00000000..ebac1e7f --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.h @@ -0,0 +1,28 @@ +#ifndef _D_GAMECUBE_DRIVER_H_ +#define _D_GAMECUBE_DRIVER_H_ + +#include +#include "USBDevice/DeviceDriver/DeviceDriver.h" +#include "USBDevice/DeviceDriver/GameCube/gc_simulator.h" + +class GameCubeDevice : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; + + GCReport& get_gc_report() { return gc_report_; } + +private: + GCReport gc_report_{}; +}; + +#endif // _D_GAMECUBE_DRIVER_H_ diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gamecube_device.c b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gamecube_device.c new file mode 100644 index 00000000..4246be41 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gamecube_device.c @@ -0,0 +1,101 @@ +/* GameCube JoyBus device. Ported from PicoGamepadConverter (Loc15). */ + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/clocks.h" +#include "joybus.pio.h" +#include "USBDevice/DeviceDriver/GameCube/gc_simulator.h" + +void __time_critical_func(convertToPio)(const uint8_t* command, const int len, uint32_t* result, int* resultLen) { + if (len == 0) { + *resultLen = 0; + return; + } + *resultLen = len / 2 + 1; + for (int i = 0; i < *resultLen; i++) + result[i] = 0; + for (int i = 0; i < len; i++) { + for (int j = 0; j < 8; j++) { + result[i / 2] += 1u << (2 * (8 * (i % 2) + j) + 1); + result[i / 2] += (!!(command[i] & (0x80u >> j))) << (2 * (8 * (i % 2) + j)); + } + } + result[len / 2] += 3u << (2 * (8 * (len % 2))); +} + +#define ORG 127 + +void gc_device_main(unsigned pio, GCReport* data, int data_pin) { + volatile GCReport* gcReport = data; + PIO gamecube_pio = pio ? pio1 : pio0; + + gpio_init(data_pin); + gpio_set_dir(data_pin, GPIO_IN); + gpio_pull_up(data_pin); + + sleep_us(100); + + uint offset = pio_add_program(gamecube_pio, &joybus_program); + uint sm = pio_claim_unused_sm(gamecube_pio, true); + pio_sm_config config = joybus_program_get_default_config(offset); + pio_gpio_init(gamecube_pio, data_pin); + sm_config_set_in_pins(&config, data_pin); + sm_config_set_out_pins(&config, data_pin, 1); + sm_config_set_set_pins(&config, data_pin, 1); + float div = (float)clock_get_hz(clk_sys) / (25e6f); + sm_config_set_clkdiv(&config, div); + sm_config_set_out_shift(&config, true, false, 32); + sm_config_set_in_shift(&config, false, true, 8); + + pio_sm_init(gamecube_pio, sm, offset, &config); + pio_sm_set_enabled(gamecube_pio, sm, true); + + while (true) { + uint8_t buffer[3]; + buffer[0] = (uint8_t)pio_sm_get_blocking(gamecube_pio, sm); + if (buffer[0] == 0) { + uint8_t probeResponse[3] = { 0x09, 0x00, 0x03 }; + uint32_t result[2]; + int resultLen; + convertToPio(probeResponse, 3, result, &resultLen); + sleep_us(6); + + pio_sm_set_enabled(gamecube_pio, sm, false); + pio_sm_init(gamecube_pio, sm, offset + joybus_offset_outmode, &config); + pio_sm_set_enabled(gamecube_pio, sm, true); + for (int i = 0; i < resultLen; i++) + pio_sm_put_blocking(gamecube_pio, sm, result[i]); + } else if (buffer[0] == 0x41) { + uint8_t originResponse[10] = { 0x00, 0x80, ORG, ORG, ORG, ORG, 0, 0, 0, 0 }; + uint32_t result[6]; + int resultLen; + convertToPio(originResponse, 10, result, &resultLen); + + pio_sm_set_enabled(gamecube_pio, sm, false); + pio_sm_init(gamecube_pio, sm, offset + joybus_offset_outmode, &config); + pio_sm_set_enabled(gamecube_pio, sm, true); + for (int i = 0; i < resultLen; i++) + pio_sm_put_blocking(gamecube_pio, sm, result[i]); + } else if (buffer[0] == 0x40) { + buffer[0] = (uint8_t)pio_sm_get_blocking(gamecube_pio, sm); + + uint32_t result[5]; + int resultLen; + convertToPio((const uint8_t*)gcReport, 8, result, &resultLen); + + (void)pio_sm_get_blocking(gamecube_pio, sm); + sleep_us(7); + + pio_sm_set_enabled(gamecube_pio, sm, false); + pio_sm_init(gamecube_pio, sm, offset + joybus_offset_outmode, &config); + pio_sm_set_enabled(gamecube_pio, sm, true); + for (int i = 0; i < resultLen; i++) + pio_sm_put_blocking(gamecube_pio, sm, result[i]); + } else { + pio_sm_set_enabled(gamecube_pio, sm, false); + sleep_us(400); + pio_sm_init(gamecube_pio, sm, offset + joybus_offset_inmode, &config); + pio_sm_set_enabled(gamecube_pio, sm, true); + } + } +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gc_simulator.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gc_simulator.h new file mode 100644 index 00000000..1e250d3d --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/gc_simulator.h @@ -0,0 +1,35 @@ +/* GameCube controller protocol (device side). Ported from PicoGamepadConverter by Loc15. + * https://github.com/Loc15/PicoGamepadConverter + * Single-wire JoyBus; output to GameCube/Wii console. */ + +#ifndef GAMECUBE_GC_SIMULATOR_H_ +#define GAMECUBE_GC_SIMULATOR_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct __attribute__((packed, aligned(1))) { + uint8_t buttons1; /* A, B, X, Y, Start */ + uint8_t buttons2; /* D-pad, Z, R, L, 0x80 */ + uint8_t lx; /* left stick X, 0x80 center */ + uint8_t ly; /* left stick Y */ + uint8_t rx; /* right stick X (C-stick) */ + uint8_t ry; /* right stick Y */ + uint8_t l; /* L analog 0–255 */ + uint8_t r; /* R analog 0–255 */ +} GCReport; + +/* Run on core1; blocks forever. pio: 0 or 1, data_pin: GPIO for DATA line (e.g. 19). */ +void gc_device_main(unsigned pio, GCReport* data, int data_pin); + +/* Entry for core1 when using OGX-Mini GameCube driver (uses report set in initialize). */ +void gamecube_core1_entry(void); + +#ifdef __cplusplus +} +#endif + +#endif /* GAMECUBE_GC_SIMULATOR_H_ */ diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/joybus.pio b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/joybus.pio new file mode 100644 index 00000000..f0ff2b5b --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/joybus.pio @@ -0,0 +1,27 @@ +; GameCube JoyBus protocol (device side). From PicoGamepadConverter (Loc15). +; THIS PIO PROGRAM EXPECTS THE SYSTEM CLOCK TO BE 125MHz +; Single wire bidirectional; clock is /5 => 25MHz + +.program joybus +PUBLIC inmode: + set pindirs, 0 +inagain: + wait 0 pin 0 [31] + nop [31] + in pins, 1 + wait 1 pin 0 + jmp inagain + +PUBLIC outmode: + set pins, 1 + set pindirs, 1 +outagain: + pull ifempty block + out X, 1 + out Y, 1 + jmp !Y inmode + set pins, 0 [ 24 ] + mov pins, X [ 24 ] + mov pins, X [ 24 ] + set pins, 1 [ 19 ] + jmp outagain diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp new file mode 100644 index 00000000..86101461 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp @@ -0,0 +1,98 @@ +/* N64 controller output (device). Any USB/BT gamepad -> adapter -> N64 console. Ported from pdaxrom/usb2n64-adapter. */ + +#include +#include "USBDevice/DeviceDriver/N64/N64.h" +#include "Gamepad/Gamepad.h" + +#ifndef N64_DATA_PIN +#define N64_DATA_PIN 19 +#endif + +void n64_core1_entry(void) { + n64_device_main(N64_DATA_PIN); +} + +namespace { + /* N64 report format matches host input: byte0 A,B,Z,START,D-pad; byte1 L,R,C; byte2/3 joy_x, joy_y (signed, 0 center). */ + constexpr uint8_t N64_A = 0x80; + constexpr uint8_t N64_B = 0x40; + constexpr uint8_t N64_Z = 0x20; + constexpr uint8_t N64_START = 0x10; + constexpr uint8_t N64_R = 0x10; + constexpr uint8_t N64_L = 0x20; + constexpr uint8_t N64_C_UP = 0x08; + constexpr uint8_t N64_C_DOWN = 0x04; + constexpr uint8_t N64_C_LEFT = 0x02; + constexpr uint8_t N64_C_RIGHT = 0x01; +} + +void N64Device::initialize() { + N64Report r = {}; + r.buttons1 = 0; + r.buttons2 = 0; + r.joy_x = 0; + r.joy_y = 0; + n64_device_set_report(&r); +} + +void N64Device::process(const uint8_t idx, Gamepad& gamepad) { + (void)idx; + if (!gamepad.new_pad_in()) + return; + + Gamepad::PadIn gp = gamepad.get_pad_in(); + N64Report r = {}; + uint8_t dpad = 0; + if (gp.dpad & Gamepad::DPAD_UP) dpad |= 0x08; + if (gp.dpad & Gamepad::DPAD_DOWN) dpad |= 0x04; + if (gp.dpad & Gamepad::DPAD_LEFT) dpad |= 0x02; + if (gp.dpad & Gamepad::DPAD_RIGHT) dpad |= 0x01; + r.buttons1 = dpad; + if (gp.buttons & Gamepad::BUTTON_A) r.buttons1 |= N64_A; + if (gp.buttons & Gamepad::BUTTON_B) r.buttons1 |= N64_B; + if (gp.buttons & Gamepad::BUTTON_MISC) r.buttons1 |= N64_Z; + if (gp.buttons & Gamepad::BUTTON_START) r.buttons1 |= N64_START; + + r.buttons2 = 0; + if (gp.buttons & Gamepad::BUTTON_LB) r.buttons2 |= N64_L; + if (gp.buttons & Gamepad::BUTTON_RB) r.buttons2 |= N64_R; + if (gp.joystick_ry < -4000) r.buttons2 |= N64_C_UP; + if (gp.joystick_ry > 4000) r.buttons2 |= N64_C_DOWN; + if (gp.joystick_rx < -4000) r.buttons2 |= N64_C_LEFT; + if (gp.joystick_rx > 4000) r.buttons2 |= N64_C_RIGHT; + + int32_t jx = (int32_t)gp.joystick_lx * 127 / 32767; + int32_t jy = (int32_t)gp.joystick_ly * -127 / 32767; + if (jx < -128) jx = -128; else if (jx > 127) jx = 127; + if (jy < -128) jy = -128; else if (jy > 127) jy = 127; + r.joy_x = (int8_t)jx; + r.joy_y = (int8_t)jy; + + n64_device_set_report(&r); +} + +uint16_t N64Device::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) { + (void)itf; (void)report_id; (void)report_type; (void)buffer; (void)req_len; + return 0; +} +void N64Device::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) { + (void)itf; (void)report_id; (void)report_type; (void)buffer; (void)buffer_size; +} +bool N64Device::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { + (void)rhport; (void)stage; (void)request; + return false; +} +const uint16_t* N64Device::get_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void)index; (void)langid; + return nullptr; +} +const uint8_t* N64Device::get_descriptor_device_cb() { return nullptr; } +const uint8_t* N64Device::get_hid_descriptor_report_cb(uint8_t itf) { + (void)itf; + return nullptr; +} +const uint8_t* N64Device::get_descriptor_configuration_cb(uint8_t index) { + (void)index; + return nullptr; +} +const uint8_t* N64Device::get_descriptor_device_qualifier_cb() { return nullptr; } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.h new file mode 100644 index 00000000..a2f059e1 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.h @@ -0,0 +1,24 @@ +#ifndef _D_N64_DRIVER_H_ +#define _D_N64_DRIVER_H_ + +#include "USBDevice/DeviceDriver/DeviceDriver.h" +#include "USBDevice/DeviceDriver/N64/n64_device.h" + +void n64_core1_entry(void); + +class N64Device : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; +}; + +#endif // _D_N64_DRIVER_H_ diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.c b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.c new file mode 100644 index 00000000..1ebd8b27 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.c @@ -0,0 +1,112 @@ +/* N64 controller device (output to N64 console). Ported from pdaxrom/usb2n64-adapter. */ + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/dma.h" +#include "hardware/clocks.h" +#include "n64send.pio.h" +#include "n64_device.h" + +#define N64SEND_DATA(d0, d1, b) ((((b) - 1) << 16) | ((uint32_t)(d0) << 8) | (uint32_t)(d1)) + +/* Shared report from Core0; Core1 reads when handling poll. */ +static volatile N64Report s_n64_report; + +void n64_device_set_report(const N64Report* report) { + if (report) { + s_n64_report.buttons1 = report->buttons1; + s_n64_report.buttons2 = report->buttons2; + s_n64_report.joy_x = report->joy_x; + s_n64_report.joy_y = report->joy_y; + } +} + +static __not_in_flash_func(uint32_t) read_bits(int pin, int num_bits) { + uint32_t value = 0; + for (int i = 0; i < num_bits; i++) { + busy_wait_us(2); + value = (value << 1) | (gpio_get(pin) ? 1u : 0u); + } + return value; +} + +/* Wait for console to pull line low (start of command). */ +static __not_in_flash_func(void) wait_for_line_low(int pin) { + while (gpio_get(pin)) { } +} + +static PIO s_n64_pio; +static uint s_n64_sm; +static uint s_n64_offset; +static uint s_n64_dma_chan; + +static __not_in_flash_func(void) send_response(uint32_t* dma_buf, int num_words) { + pio_sm_exec(s_n64_pio, s_n64_sm, pio_encode_jmp(s_n64_offset + n64send_dma_offset_loop)); + dma_channel_transfer_from_buffer_now(s_n64_dma_chan, dma_buf, num_words); + dma_channel_wait_for_finish_blocking(s_n64_dma_chan); + while (pio_sm_get_pc(s_n64_pio, s_n64_sm) != (s_n64_offset + n64send_dma_offset_stop)) { } +} + +static uint32_t s_dma_buf[8]; + +void n64_device_main(int data_pin) { + gpio_init(data_pin); + gpio_put(data_pin, 0); + gpio_pull_up(data_pin); + gpio_set_dir(data_pin, GPIO_IN); + + PIO pio = pio0; + uint offset = pio_add_program(pio, &n64send_dma_program); + uint sm = pio_claim_unused_sm(pio, true); + s_n64_pio = pio; + s_n64_sm = sm; + s_n64_offset = offset; + + uint dma_chan = dma_claim_unused_channel(true); + s_n64_dma_chan = dma_chan; + + dma_channel_config cfg = dma_channel_get_default_config(dma_chan); + channel_config_set_transfer_data_size(&cfg, DMA_SIZE_32); + channel_config_set_read_increment(&cfg, true); + channel_config_set_write_increment(&cfg, false); + channel_config_set_dreq(&cfg, pio_get_dreq(pio, sm, true)); + dma_channel_configure(dma_chan, &cfg, &pio->txf[sm], NULL, 0, false); + + pio_sm_config c = n64send_dma_program_get_default_config(offset); + sm_config_set_out_shift(&c, false, false, 32); + sm_config_set_in_shift(&c, false, false, 32); + sm_config_set_out_pins(&c, data_pin, 1); + sm_config_set_set_pins(&c, data_pin, 1); + pio_gpio_init(pio, data_pin); + pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, false); + sm_config_set_clkdiv(&c, 16.625f); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); + pio_sm_init(pio, sm, offset, &c); + pio_sm_set_enabled(pio, sm, true); + + for (;;) { + wait_for_line_low(data_pin); + uint32_t cmd = read_bits(data_pin, 9); + /* Command byte is bits 1-8 (bit 0 is start). */ + uint8_t cmd_byte = (uint8_t)(cmd >> 1); + + if (cmd_byte == 0x00 || cmd_byte == 0xFF) { + /* Identity: standard controller 0x05, 0x00; then 0x01 (1 byte). */ + s_dma_buf[0] = N64SEND_DATA(0x05, 0x00, 16); + s_dma_buf[1] = N64SEND_DATA(0x01, 0x00, 8); + s_dma_buf[2] = 0; + send_response(s_dma_buf, 3); + } else if (cmd_byte == 0x01) { + /* Poll: 4 bytes = buttons1, buttons2, joy_x, joy_y */ + uint8_t b0 = s_n64_report.buttons1; + uint8_t b1 = s_n64_report.buttons2; + int8_t jx = s_n64_report.joy_x; + int8_t jy = s_n64_report.joy_y; + s_dma_buf[0] = N64SEND_DATA(b0, b1, 16); + s_dma_buf[1] = N64SEND_DATA((uint8_t)jx, (uint8_t)jy, 16); + s_dma_buf[2] = 0; + send_response(s_dma_buf, 3); + } + /* Ignore 0x02/0x03 (memory pak) and 0x13 (keyboard) for now. */ + } +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.h new file mode 100644 index 00000000..29be7334 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64_device.h @@ -0,0 +1,30 @@ +/* N64 controller device (output to N64 console). Ported from pdaxrom/usb2n64-adapter. */ + +#ifndef N64_DEVICE_H_ +#define N64_DEVICE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 4-byte report: buttons1, buttons2, joy_x, joy_y (same format as N64 host input). */ +typedef struct __attribute__((packed)) { + uint8_t buttons1; + uint8_t buttons2; + int8_t joy_x; + int8_t joy_y; +} N64Report; + +/* Run on core1; blocks forever. data_pin = GPIO for N64 data line (e.g. 19). */ +void n64_device_main(int data_pin); + +/* Set report from Core0 (called by N64Device::process). */ +void n64_device_set_report(const N64Report* report); + +#ifdef __cplusplus +} +#endif + +#endif /* N64_DEVICE_H_ */ diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64send.pio b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64send.pio new file mode 100644 index 00000000..d42b7c46 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/n64send.pio @@ -0,0 +1,37 @@ +; N64 controller response output. Ported from pdaxrom/usb2n64-adapter. +; Sends bits with N64 timing: pull 32-bit word (bit_count in high 16, bytes in low 16), send bits then stop. + +.program n64send_dma + SET PINS, 0 + SET PINDIRS, 0 + +public loop: + PULL BLOCK + OUT Y, 16 + JMP !Y, send_stop + +pull_and_send: + OUT X, 1 + JMP !X send_0 + JMP send_1 + +send_0: + SET PINDIRS, 1 [30] + NOP [4] + SET PINDIRS, 0 [7] + JMP Y-- pull_and_send + JMP loop + +send_1: + SET PINDIRS, 1 [11] + SET PINDIRS, 0 [31] + JMP Y-- pull_and_send + JMP loop + +send_stop: + SET PINDIRS, 1 [22] + SET PINDIRS, 0 +public stop: + JMP stop + +.wrap diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp new file mode 100644 index 00000000..bb56fffe --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp @@ -0,0 +1,130 @@ +#include +#include "pico/multicore.h" +#include "USBDevice/DeviceDriver/PS1PS2/PS1PS2.h" +#include "USBDevice/DeviceDriver/PS1PS2/psx_simulator.h" + +namespace { + constexpr uint8_t PSX_SELECT = 0x01; + constexpr uint8_t PSX_L3 = 0x02; + constexpr uint8_t PSX_R3 = 0x04; + constexpr uint8_t PSX_START = 0x08; + constexpr uint8_t PSX_UP = 0x10; + constexpr uint8_t PSX_RIGHT = 0x20; + constexpr uint8_t PSX_DOWN = 0x40; + constexpr uint8_t PSX_LEFT = 0x80; + constexpr uint8_t PSX_L2 = 0x01; + constexpr uint8_t PSX_R2 = 0x02; + constexpr uint8_t PSX_L1 = 0x04; + constexpr uint8_t PSX_R1 = 0x08; + constexpr uint8_t PSX_TRI = 0x10; + constexpr uint8_t PSX_CIR = 0x20; + constexpr uint8_t PSX_CROSS = 0x40; + constexpr uint8_t PSX_SQU = 0x80; + constexpr uint8_t STICK_CENTER = 0x80; +} + +void PS1PS2Device::core1_restart_cb() { + multicore_reset_core1(); + multicore_launch_core1(psx_device_main); +} + +void PS1PS2Device::initialize() { + std::memset(&psx_report_, 0, sizeof(psx_report_)); + psx_report_.lx = STICK_CENTER; + psx_report_.ly = STICK_CENTER; + psx_report_.rx = STICK_CENTER; + psx_report_.ry = STICK_CENTER; + psx_device_init(0, &psx_report_, &PS1PS2Device::core1_restart_cb); +} + +void PS1PS2Device::process(const uint8_t idx, Gamepad& gamepad) { + (void)idx; + if (!gamepad.new_pad_in()) + return; + + Gamepad::PadIn gp = gamepad.get_pad_in(); + + psx_report_.buttons1 = 0; + if (gp.dpad & Gamepad::DPAD_UP) psx_report_.buttons1 |= PSX_UP; + if (gp.dpad & Gamepad::DPAD_RIGHT) psx_report_.buttons1 |= PSX_RIGHT; + if (gp.dpad & Gamepad::DPAD_DOWN) psx_report_.buttons1 |= PSX_DOWN; + if (gp.dpad & Gamepad::DPAD_LEFT) psx_report_.buttons1 |= PSX_LEFT; + if (gp.buttons & Gamepad::BUTTON_BACK) psx_report_.buttons1 |= PSX_SELECT; + if (gp.buttons & Gamepad::BUTTON_L3) psx_report_.buttons1 |= PSX_L3; + if (gp.buttons & Gamepad::BUTTON_R3) psx_report_.buttons1 |= PSX_R3; + if (gp.buttons & Gamepad::BUTTON_START) psx_report_.buttons1 |= PSX_START; + + psx_report_.buttons2 = 0; + if (gp.buttons & Gamepad::BUTTON_LB) psx_report_.buttons2 |= PSX_L1; + if (gp.buttons & Gamepad::BUTTON_RB) psx_report_.buttons2 |= PSX_R1; + if (gp.buttons & Gamepad::BUTTON_Y) psx_report_.buttons2 |= PSX_TRI; + if (gp.buttons & Gamepad::BUTTON_B) psx_report_.buttons2 |= PSX_CIR; + if (gp.buttons & Gamepad::BUTTON_A) psx_report_.buttons2 |= PSX_CROSS; + if (gp.buttons & Gamepad::BUTTON_X) psx_report_.buttons2 |= PSX_SQU; + if (gp.trigger_l > 0) psx_report_.buttons2 |= PSX_L2; + if (gp.trigger_r > 0) psx_report_.buttons2 |= PSX_R2; + + psx_report_.l2 = gp.trigger_l; + psx_report_.r2 = gp.trigger_r; + + int32_t lx = static_cast(gp.joystick_lx) * 127 / 32767 + STICK_CENTER; + int32_t ly = static_cast(gp.joystick_ly) * -127 / 32767 + STICK_CENTER; + int32_t rx = static_cast(gp.joystick_rx) * 127 / 32767 + STICK_CENTER; + int32_t ry = static_cast(gp.joystick_ry) * -127 / 32767 + STICK_CENTER; + if (lx < 0) lx = 0; else if (lx > 255) lx = 255; + if (ly < 0) ly = 0; else if (ly > 255) ly = 255; + if (rx < 0) rx = 0; else if (rx > 255) rx = 255; + if (ry < 0) ry = 0; else if (ry > 255) ry = 255; + psx_report_.lx = static_cast(lx); + psx_report_.ly = static_cast(ly); + psx_report_.rx = static_cast(rx); + psx_report_.ry = static_cast(ry); +} + +uint16_t PS1PS2Device::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) { + (void)itf; + (void)report_id; + (void)report_type; + (void)buffer; + (void)req_len; + return 0; +} + +void PS1PS2Device::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) { + (void)itf; + (void)report_id; + (void)report_type; + (void)buffer; + (void)buffer_size; +} + +bool PS1PS2Device::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { + (void)rhport; + (void)stage; + (void)request; + return false; +} + +const uint16_t* PS1PS2Device::get_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void)index; + (void)langid; + return nullptr; +} + +const uint8_t* PS1PS2Device::get_descriptor_device_cb() { + return nullptr; +} + +const uint8_t* PS1PS2Device::get_hid_descriptor_report_cb(uint8_t itf) { + (void)itf; + return nullptr; +} + +const uint8_t* PS1PS2Device::get_descriptor_configuration_cb(uint8_t index) { + (void)index; + return nullptr; +} + +const uint8_t* PS1PS2Device::get_descriptor_device_qualifier_cb() { + return nullptr; +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.h new file mode 100644 index 00000000..79e67fdb --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.h @@ -0,0 +1,31 @@ +#ifndef _D_PS1PS2_DRIVER_H_ +#define _D_PS1PS2_DRIVER_H_ + +#include + +#include "USBDevice/DeviceDriver/DeviceDriver.h" +#include "USBDevice/DeviceDriver/PS1PS2/psx_simulator.h" + +class PS1PS2Device : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t buffer_size) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; + + PSXInputState& get_psx_state() { return psx_report_; } + +private: + static void core1_restart_cb(); + + PSXInputState psx_report_{}; +}; + +#endif // _D_PS1PS2_DRIVER_H_ diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c new file mode 100644 index 00000000..f9fa3dd3 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c @@ -0,0 +1,408 @@ +/* PS1/PS2 controller protocol (device side). Ported from PicoGamepadConverter (Loc15). + * https://github.com/Loc15/PicoGamepadConverter */ + +#include +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/gpio.h" +#include "pico/multicore.h" +#include "psxSPI.pio.h" +#include "USBDevice/DeviceDriver/PS1PS2/psx_simulator.h" + +#define MODE_DIGITAL 0x41 +#define MODE_ANALOG 0x73 +#define MODE_ANALOG_PRESSURE 0x79 +#define MODE_CONFIG 0xF3 + +#define CMD_PRES_CONFIG 0x40 +#define CMD_POLL_CONFIG_STATUS 0x41 +#define CMD_POLL 0x42 +#define CMD_CONFIG 0x43 +#define CMD_STATUS 0x45 +#define CMD_CONST_46 0x46 +#define CMD_CONST_47 0x47 +#define CMD_CONST_4C 0x4C +#define CMD_ENABLE_RUMBLE 0x4D +#define CMD_POLL_CONFIG 0x4F +#define CMD_ANALOG_SWITCH 0x44 + +#define UP 0x10 +#define RIGHT 0x20 +#define DOWN 0x40 +#define LEFT 0x80 +#define L2 0x01 +#define R2 0x02 +#define L1 0x04 +#define R1 0x08 +#define TRI 0x10 +#define CIR 0x20 +#define X 0x40 +#define SQU 0x80 + +static PIO psx_device_pio; +static uint smCmdReader; +static uint smDatWriter; +static uint offsetCmdReader; +static uint offsetDatWriter; + +volatile PSXInputState *inputState; +static void (*core1_function)(void); + +static uint8_t mode = MODE_DIGITAL; +static bool config = false; +static bool analogLock = false; +static uint8_t motorBytes[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static uint8_t pollConfig[4] = { 0x00, 0x00, 0x00, 0x00 }; + +static void cancel_ack(void) { + pio_sm_exec(psx_device_pio, smCmdReader, pio_encode_jmp(offsetCmdReader)); +} + +static void SEND(uint8_t byte) { + write_byte_blocking(psx_device_pio, smDatWriter, byte); +} + +static uint8_t RECV_CMD(void) { + return read_byte_blocking(psx_device_pio, smCmdReader); +} + +static void initController(void) { + mode = MODE_DIGITAL; + config = false; + analogLock = false; + memset(motorBytes, 0xFF, sizeof(motorBytes)); + pollConfig[0] = 0xFF; + pollConfig[1] = 0xFF; + pollConfig[2] = 0x03; + pollConfig[3] = 0x00; +} + +static void processRumble(uint8_t index, uint8_t value) { + (void)index; + (void)value; +} + +static void processPresConfig(void) { + if (!config) return; + uint8_t buf[7] = { 0x5A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5A }; + for (uint8_t i = 0; i < 7; i++) { + SEND(buf[i]); + RECV_CMD(); + } +} + +static void processPollConfigStatus(void) { + if (!config) return; + uint8_t buf[7] = { 0x5A, (mode == MODE_DIGITAL) ? 0x00 : 0xFF, (mode == MODE_DIGITAL) ? 0x00 : 0xFF, (mode == MODE_DIGITAL) ? 0x00 : 0x03, (mode == MODE_DIGITAL) ? 0x00 : 0x00, 0x00, (mode == MODE_DIGITAL) ? 0x00 : 0x5A }; + for (uint8_t i = 0; i < 7; i++) { + SEND(buf[i]); + RECV_CMD(); + } +} + +static void processPoll(void) { + config = false; + switch (mode) { + case MODE_DIGITAL: { + uint8_t buf[3] = { 0x5A, inputState->buttons1, inputState->buttons2 }; + for (uint8_t i = 0; i < 3; i++) { + SEND(buf[i]); + processRumble(i, RECV_CMD()); + } + break; + } + case MODE_ANALOG: { + uint8_t buf[7] = { 0x5A, inputState->buttons1, inputState->buttons2, inputState->rx, inputState->ry, inputState->lx, inputState->ly }; + for (uint8_t i = 0; i < 7; i++) { + SEND(buf[i]); + processRumble(i, RECV_CMD()); + } + break; + } + case MODE_ANALOG_PRESSURE: { + uint8_t buf[19] = { + 0x5A, inputState->buttons1, inputState->buttons2, inputState->rx, inputState->ry, inputState->lx, inputState->ly, + (inputState->buttons1 & RIGHT) ? 0x00 : 0xFF, (inputState->buttons1 & LEFT) ? 0x00 : 0xFF, + (inputState->buttons1 & UP) ? 0x00 : 0xFF, (inputState->buttons1 & DOWN) ? 0x00 : 0xFF, + (inputState->buttons2 & TRI) ? 0x00 : 0xFF, (inputState->buttons2 & CIR) ? 0x00 : 0xFF, + (inputState->buttons2 & X) ? 0x00 : 0xFF, (inputState->buttons2 & SQU) ? 0x00 : 0xFF, + (inputState->buttons2 & L1) ? 0x00 : 0xFF, (inputState->buttons2 & R1) ? 0x00 : 0xFF, + inputState->l2, inputState->r2 + }; + for (uint8_t i = 0; i < 19; i++) { + SEND(buf[i]); + processRumble(i, RECV_CMD()); + } + break; + } + default: + break; + } +} + +static void processConfig(void) { + switch (config ? MODE_CONFIG : mode) { + case MODE_CONFIG: + for (uint8_t i = 0; i < 7; i++) { + SEND((i == 0) ? 0x5A : 0x00); + if (i != 1) + RECV_CMD(); + else + config = RECV_CMD(); + } + break; + case MODE_DIGITAL: { + uint8_t buf[3] = { 0x5A, inputState->buttons1, inputState->buttons2 }; + for (uint8_t i = 0; i < 3; i++) { + SEND(buf[i]); + if (i != 1) + RECV_CMD(); + else + config = RECV_CMD(); + } + break; + } + case MODE_ANALOG: { + uint8_t buf[7] = { 0x5A, inputState->buttons1, inputState->buttons2, inputState->rx, inputState->ry, inputState->lx, inputState->ly }; + for (uint8_t i = 0; i < 7; i++) { + SEND(buf[i]); + if (i != 1) + RECV_CMD(); + else + config = RECV_CMD(); + } + break; + } + case MODE_ANALOG_PRESSURE: { + uint8_t buf[19] = { + 0x5A, inputState->buttons1, inputState->buttons2, inputState->rx, inputState->ry, inputState->lx, inputState->ly, + (inputState->buttons1 & RIGHT) ? 0x00 : 0xFF, (inputState->buttons1 & LEFT) ? 0x00 : 0xFF, + (inputState->buttons1 & UP) ? 0x00 : 0xFF, (inputState->buttons1 & DOWN) ? 0x00 : 0xFF, + (inputState->buttons2 & TRI) ? 0x00 : 0xFF, (inputState->buttons2 & CIR) ? 0x00 : 0xFF, + (inputState->buttons2 & X) ? 0x00 : 0xFF, (inputState->buttons2 & SQU) ? 0x00 : 0xFF, + (inputState->buttons2 & L1) ? 0x00 : 0xFF, (inputState->buttons2 & R1) ? 0x00 : 0xFF, + inputState->l2, inputState->r2 + }; + for (uint8_t i = 0; i < 19; i++) { + SEND(buf[i]); + if (i != 1) + RECV_CMD(); + else + config = RECV_CMD(); + } + break; + } + default: + break; + } +} + +static uint8_t detectAnalog(void) { + if ((pollConfig[0] + pollConfig[1] + pollConfig[2] + pollConfig[3]) > 0) + return MODE_ANALOG_PRESSURE; + return MODE_ANALOG; +} + +static void processAnalogSwitch(void) { + if (!config) return; + for (uint8_t i = 0; i < 7; i++) { + switch (i) { + case 0: + SEND(0x5A); + RECV_CMD(); + break; + case 1: + SEND(0x00); + mode = (RECV_CMD() == 0x01) ? detectAnalog() : MODE_DIGITAL; + break; + case 2: + SEND(0x00); + analogLock = (RECV_CMD() == 0x03) ? 1 : 0; + break; + default: + SEND(0x00); + RECV_CMD(); + break; + } + } +} + +static void processStatus(void) { + if (!config) return; + uint8_t buf[7] = { 0x5A, 0x03, 0x02, (mode == MODE_DIGITAL) ? 0x00 : 0x01, 0x02, 0x01, 0x00 }; + for (uint8_t i = 0; i < 7; i++) { + SEND(buf[i]); + RECV_CMD(); + } +} + +static void processConst46(void) { + if (!config) return; + SEND(0x5A); + RECV_CMD(); + SEND(0x00); + uint8_t offset = RECV_CMD(); + uint8_t buf[5] = { 0x00, 0x01, (offset == 0x00) ? 0x02 : 0x01, (offset == 0x00) ? 0x00 : 0x01, 0x0F }; + for (uint8_t i = 0; i < 5; i++) { + SEND(buf[i]); + RECV_CMD(); + } +} + +static void processConst47(void) { + if (!config) return; + uint8_t buf[7] = { 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00 }; + for (uint8_t i = 0; i < 7; i++) { + SEND(buf[i]); + RECV_CMD(); + } +} + +static void processConst4c(void) { + if (!config) return; + SEND(0x5A); + RECV_CMD(); + SEND(0x00); + uint8_t offset = RECV_CMD(); + uint8_t buf[5] = { 0x00, 0x00, (offset == 0x00) ? 0x04 : 0x07, 0x00, 0x00 }; + for (uint8_t i = 0; i < 5; i++) { + SEND(buf[i]); + RECV_CMD(); + } +} + +static void processEnableRumble(void) { + if (!config) return; + for (uint8_t i = 0; i < 7; i++) { + if (i == 0) { + SEND(0x5A); + RECV_CMD(); + } else { + SEND(motorBytes[i - 1]); + motorBytes[i - 1] = RECV_CMD(); + } + } +} + +static void processPollConfig(void) { + if (!config) return; + for (int i = 0; i < 7; i++) { + if (i >= 1 && i <= 4) { + SEND(0x00); + pollConfig[i - 1] = RECV_CMD(); + } else { + SEND((i == 0 || i == 6) ? 0x5A : 0x00); + RECV_CMD(); + } + } + if ((pollConfig[0] + pollConfig[1] + pollConfig[2] + pollConfig[3]) != 0) + mode = MODE_ANALOG_PRESSURE; + else + mode = MODE_ANALOG; +} + +static void process_joy_req(void) { + SEND(config ? MODE_CONFIG : mode); + uint8_t cmd = RECV_CMD(); + switch (cmd) { + case CMD_POLL: + processPoll(); + break; + case CMD_CONFIG: + processConfig(); + break; + case CMD_STATUS: + processStatus(); + break; + case CMD_CONST_46: + processConst46(); + break; + case CMD_CONST_47: + processConst47(); + break; + case CMD_CONST_4C: + processConst4c(); + break; + case CMD_POLL_CONFIG_STATUS: + processPollConfigStatus(); + break; + case CMD_ENABLE_RUMBLE: + processEnableRumble(); + break; + case CMD_POLL_CONFIG: + processPollConfig(); + break; + case CMD_PRES_CONFIG: + processPresConfig(); + break; + case CMD_ANALOG_SWITCH: + processAnalogSwitch(); + break; + default: + break; + } +} + +void psx_device_main(void) { + initController(); + while (true) { + if (RECV_CMD() == 0x01) + process_joy_req(); + } +} + +static void __time_critical_func(restart_pio_sm)(void) { + pio_set_sm_mask_enabled(psx_device_pio, (1u << smCmdReader) | (1u << smDatWriter), false); + pio_restart_sm_mask(psx_device_pio, (1u << smCmdReader) | (1u << smDatWriter)); + pio_sm_exec(psx_device_pio, smCmdReader, pio_encode_jmp(offsetCmdReader)); + pio_sm_exec(psx_device_pio, smDatWriter, pio_encode_jmp(offsetDatWriter)); + pio_sm_clear_fifos(psx_device_pio, smCmdReader); + pio_sm_drain_tx_fifo(psx_device_pio, smDatWriter); + + multicore_reset_core1(); + if (core1_function) + core1_function(); + pio_enable_sm_mask_in_sync(psx_device_pio, (1u << smCmdReader) | (1u << smDatWriter)); +} + +static void __time_critical_func(sel_isr_callback)(void) { + gpio_acknowledge_irq(PIN_SEL, GPIO_IRQ_EDGE_RISE); + restart_pio_sm(); +} + +static void init_pio(void) { + gpio_set_dir(PIN_DAT, false); + gpio_set_dir(PIN_CMD, false); + gpio_set_dir(PIN_SEL, false); + gpio_set_dir(PIN_CLK, false); + gpio_set_dir(PIN_ACK, false); + gpio_disable_pulls(PIN_DAT); + gpio_disable_pulls(PIN_CMD); + gpio_disable_pulls(PIN_SEL); + gpio_disable_pulls(PIN_CLK); + gpio_disable_pulls(PIN_ACK); + + smCmdReader = pio_claim_unused_sm(psx_device_pio, true); + smDatWriter = pio_claim_unused_sm(psx_device_pio, true); + + offsetCmdReader = pio_add_program(psx_device_pio, &cmd_reader_program); + offsetDatWriter = pio_add_program(psx_device_pio, &dat_writer_program); + + cmd_reader_program_init(psx_device_pio, smCmdReader, offsetCmdReader); + dat_writer_program_init(psx_device_pio, smDatWriter, offsetDatWriter); +} + +void psx_device_init(unsigned pio, PSXInputState *data, void (*reset_pio)(void)) { + psx_device_pio = pio ? pio1 : pio0; + inputState = data; + core1_function = reset_pio; + + init_pio(); + + gpio_set_slew_rate(PIN_DAT, GPIO_SLEW_RATE_FAST); + gpio_set_drive_strength(PIN_DAT, GPIO_DRIVE_STRENGTH_12MA); + + gpio_set_irq_enabled(PIN_SEL, GPIO_IRQ_EDGE_RISE, true); + irq_set_exclusive_handler(IO_IRQ_BANK0, sel_isr_callback); + irq_set_enabled(IO_IRQ_BANK0, true); +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psxSPI.pio b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psxSPI.pio new file mode 100644 index 00000000..a6b4f3f9 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psxSPI.pio @@ -0,0 +1,87 @@ +; PS1/PS2 controller protocol (device side). From PicoGamepadConverter (Loc15). +; Interfaces with the modified SPI protocol used by PSX to communicate with controller/memory cards. +; Pinout for OGX-Mini (standard Pico): CMD=19, CLK=20, ATT/SEL=21, DAT=22, ACK=26 + +.define PUBLIC PIN_DAT 19 +.define PUBLIC PIN_CMD 20 +.define PUBLIC PIN_SEL 21 +.define PUBLIC PIN_CLK 22 +.define PUBLIC PIN_ACK 26 + +.program cmd_reader +; Samples CMD line during rising clock edges, waits for SEL low before starting +sel_high: +wait 0 gpio PIN_SEL +set x, 7 +.wrap_target +wait 0 gpio PIN_CLK +wait 1 gpio PIN_CLK +in pins 1 +.wrap + +.program dat_reader +sel_high: +wait 0 gpio PIN_SEL +.wrap_target +wait 0 gpio PIN_CLK +wait 1 gpio PIN_CLK +in pins 1 +.wrap + +.program dat_writer +.side_set 1 pindirs +set pindirs, 0 side 0 +wait 0 gpio PIN_SEL side 0 +.wrap_target +pull side 0 +nop side 1 [5] +set x, 7 side 0 [5] +sendbit: +wait 1 gpio PIN_CLK side 0 +wait 0 gpio PIN_CLK side 0 +out pindirs 1 side 0 +jmp x-- sendbit side 0 +.wrap + +% c-sdk { +#define SLOW_CLKDIV 50 + +static inline void cmd_reader_program_init(PIO pio, uint sm, uint offset) { + pio_sm_config c = cmd_reader_program_get_default_config(offset); + sm_config_set_in_pins(&c, PIN_CMD); + pio_sm_set_consecutive_pindirs(pio, sm, PIN_CMD, 1, false); + pio_sm_set_consecutive_pindirs(pio, sm, PIN_SEL, 1, false); + pio_sm_set_consecutive_pindirs(pio, sm, PIN_CLK, 1, false); + sm_config_set_in_shift(&c, true, true, 8); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); + sm_config_set_clkdiv_int_frac(&c, SLOW_CLKDIV, 0x00); + pio_sm_init(pio, sm, offset, &c); +} + +static inline void dat_writer_program_init(PIO pio, uint sm, uint offset) { + pio_sm_config c = dat_writer_program_get_default_config(offset); + sm_config_set_out_pins(&c, PIN_DAT, 1); + sm_config_set_set_pins(&c, PIN_DAT, 1); + sm_config_set_sideset_pins(&c, PIN_ACK); + pio_sm_set_pins_with_mask(pio, sm, 0, 1 << PIN_DAT); + pio_sm_set_consecutive_pindirs(pio, sm, PIN_DAT, 1, false); + pio_gpio_init(pio, PIN_DAT); + pio_sm_set_pins_with_mask(pio, sm, 0, 1 << PIN_ACK); + pio_sm_set_consecutive_pindirs(pio, sm, PIN_ACK, 1, false); + pio_gpio_init(pio, PIN_ACK); + pio_sm_set_consecutive_pindirs(pio, sm, PIN_SEL, 1, false); + pio_sm_set_consecutive_pindirs(pio, sm, PIN_CLK, 1, false); + sm_config_set_out_shift(&c, true, true, 8); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); + sm_config_set_clkdiv_int_frac(&c, SLOW_CLKDIV, 0x00); + pio_sm_init(pio, sm, offset, &c); +} + +static inline uint8_t read_byte_blocking(PIO pio, uint sm) { + return (uint8_t)(pio_sm_get_blocking(pio, sm) >> 24); +} + +static inline void write_byte_blocking(PIO pio, uint sm, uint32_t byte) { + pio_sm_put_blocking(pio, sm, ~byte & 0xFF); +} +%} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h new file mode 100644 index 00000000..81d8c556 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h @@ -0,0 +1,39 @@ +/* PS1/PS2 controller protocol (device side). Ported from PicoGamepadConverter by Loc15. + * https://github.com/Loc15/PicoGamepadConverter + * License: GPL-3.0. OGX-Mini uses this for GPIO output to PS1/PS2 console. */ + +#ifndef PS1PS2_PSX_SIMULATOR_H_ +#define PS1PS2_PSX_SIMULATOR_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct __attribute__((packed, aligned(1))) { + uint8_t buttons1; + uint8_t buttons2; + uint8_t lx; + uint8_t ly; + uint8_t rx; + uint8_t ry; + uint8_t l2; + uint8_t r2; +} PSXInputState; + +/* Initialize the PS1/PS2 controller simulator. Uses PIO and GPIO; call once before launching core1. + * pio: 0 = PIO0, 1 = PIO1. + * data: pointer to shared state (written by main loop, read by simulator on core1). + * reset_pio: callback to restart core1 (e.g. multicore_reset_core1 + multicore_launch_core1(psx_device_main)). */ +void psx_device_init(unsigned pio, PSXInputState* data, void (*reset_pio)(void)); + +/* Entry for core1: run this in an infinite loop. Blocks. */ +void psx_device_main(void); + +#ifdef __cplusplus +} +#endif + +#endif /* PS1PS2_PSX_SIMULATOR_H_ */ diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp index 7d282145..e46b8be6 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp @@ -81,17 +81,16 @@ void SwitchDevice::gamepad_to_switch_report(const Gamepad::PadIn& gp_in, SwitchP if (gp_in.buttons & gamepad.MAP_BUTTON_LB) out.buttons[2] |= SwitchPro::Btn::L; if (gp_in.trigger_l) out.buttons[2] |= SwitchPro::Btn::ZL; - // Sticks: int16 -> 12-bit (0x000–0xFFF), center 0x7FF. Small deadzone + slight sensitivity boost. - constexpr int16_t DZ = 512; - constexpr int STICK_GAIN_NUM = 120, STICK_GAIN_DEN = 100; // 1.2x sensitivity + // Sticks: int16 -> 12-bit (0x000–0xFFF), center 0x7FF. Use same sensitivity as Switch Pro + // wired host (SwitchProHost::normalize_axis): 12bit -> (value - 2047) * 22 -> int16. + // Inverse: 12bit = 2047 + int16/22, so emulated output matches wired Pro feel. + constexpr int16_t DZ = 256; + constexpr int32_t PRO_CENTER = 2047; // 0x7FF + constexpr int32_t PRO_GAIN_INV = 22; // host uses *22 so we use /22 auto to12 = [](int16_t val) -> uint16_t { if (val > -DZ && val < DZ) - return SwitchPro::STICK_MID; - int32_t scaled = (static_cast(val) * STICK_GAIN_NUM) / STICK_GAIN_DEN; - if (scaled > 32767) scaled = 32767; - if (scaled < -32768) scaled = -32768; - int32_t v = scaled + 32768; - int32_t u = (v * 4095 + 32767) / 65535; + return static_cast(SwitchPro::STICK_MID); + int32_t u = PRO_CENTER + (static_cast(val) / PRO_GAIN_INV); if (u < 0) u = 0; if (u > 4095) u = 4095; return static_cast(u); @@ -235,9 +234,16 @@ void SwitchDevice::build_subcommand_reply(const SwitchPro::SwitchReport& sw) void SwitchDevice::process(const uint8_t idx, Gamepad& gamepad) { (void)idx; + // Always read latest state and build report so get_report_cb and IN pushes both see current state (minimal latency). Gamepad::PadIn gp_in = gamepad.get_pad_in(); gamepad_to_switch_report(gp_in, switch_report_, gamepad); + bool is_subcommand = has_pending_output_; + if (has_pending_output_) + build_subcommand_reply(switch_report_); + else + build_standard_report(switch_report_); + if (tud_suspended()) tud_remote_wakeup(); @@ -249,12 +255,6 @@ void SwitchDevice::process(const uint8_t idx, Gamepad& gamepad) return; } - bool is_subcommand = has_pending_output_; - if (has_pending_output_) - build_subcommand_reply(switch_report_); - else - build_standard_report(switch_report_); - if (tud_hid_n_ready(0)) { tud_hid_n_report(0, is_subcommand ? SwitchPro::REPORT_ID_SUBCMD : SwitchPro::REPORT_ID_STANDARD, report_.data(), 63); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp index 32f4706a..92144606 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp @@ -53,10 +53,9 @@ void XInputDevice::process(const uint8_t idx, Gamepad& gamepad) // joypad-os: run XSM3 crypto in task loop, not in USB callback xsm3_process_pending(); - // Always read latest state and send when USB is ready (reduces latency vs only sending on new_pad_in()) + // Always read latest state and build report every loop so get_report_cb and IN send both see current state (minimal latency; only delay is BT radio when wireless). in_report_.buttons[0] = 0; in_report_.buttons[1] = 0; - Gamepad::PadIn gp_in = gamepad.get_pad_in(); switch (gp_in.dpad) @@ -113,6 +112,7 @@ void XInputDevice::process(const uint8_t idx, Gamepad& gamepad) if (tud_suspended()) tud_remote_wakeup(); + // send_report() only transmits when endpoint is free; otherwise we keep latest in_report_ for get_report_cb tud_xinput::send_report((uint8_t*)&in_report_, sizeof(XInput::InReport)); if (tud_xinput::receive_report(reinterpret_cast(&out_report_), sizeof(XInput::OutReport)) && diff --git a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp index 2cdef188..d87a8845 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp @@ -12,6 +12,10 @@ #include "USBDevice/DeviceDriver/XboxOG/XboxOG_SB.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_XR.h" #include "USBDevice/DeviceDriver/WebApp/WebApp.h" +#include "USBDevice/DeviceDriver/PS1PS2/PS1PS2.h" +#include "USBDevice/DeviceDriver/GameCube/GameCube.h" +#include "USBDevice/DeviceDriver/Dreamcast/Dreamcast.h" +#include "USBDevice/DeviceDriver/N64/N64.h" #include "USBDevice/DeviceManager.h" #if defined(CONFIG_EN_UART_BRIDGE) @@ -21,7 +25,8 @@ void DeviceManager::initialize_driver( DeviceDriverType driver_type, Gamepad(&gamepads)[MAX_GAMEPADS]) { //TODO: Put gamepad setup in the drivers themselves - bool has_analog = false; + bool has_analog = false; + current_driver_type_ = driver_type; printf("Attempting to allocate driver\n"); @@ -52,6 +57,22 @@ void DeviceManager::initialize_driver( DeviceDriverType driver_type, printf("WII Loaded\n"); device_driver_ = std::make_unique(); break; + case DeviceDriverType::PS1PS2: + printf("PS1/PS2 Loaded (GPIO output)\n"); + device_driver_ = std::make_unique(); + break; + case DeviceDriverType::GAMECUBE: + printf("GameCube Loaded (GPIO output)\n"); + device_driver_ = std::make_unique(); + break; + case DeviceDriverType::DREAMCAST: + printf("Dreamcast Loaded (GPIO Maple Bus)\n"); + device_driver_ = std::make_unique(); + break; + case DeviceDriverType::N64: + printf("N64 Loaded (GPIO output)\n"); + device_driver_ = std::make_unique(); + break; case DeviceDriverType::XINPUT: printf("XINPUT Loaded\n"); device_driver_ = std::make_unique(); diff --git a/Firmware/RP2040/src/USBDevice/DeviceManager.h b/Firmware/RP2040/src/USBDevice/DeviceManager.h index 8cb6b5a6..237ef50b 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceManager.h +++ b/Firmware/RP2040/src/USBDevice/DeviceManager.h @@ -21,12 +21,14 @@ class DeviceManager { void initialize_driver(DeviceDriverType driver_type, Gamepad(&gamepads)[MAX_GAMEPADS]); DeviceDriver* get_driver() { return device_driver_.get(); } - + DeviceDriverType get_driver_type() const { return current_driver_type_; } + private: DeviceManager() = default; ~DeviceManager() = default; std::unique_ptr device_driver_{nullptr}; + DeviceDriverType current_driver_type_{DeviceDriverType::NONE}; }; #endif // _DEVICE_MANAGER_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp index bf14304a..ed0df738 100644 --- a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp +++ b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp @@ -6,9 +6,15 @@ #include "device/usbd_pvt.h" #include "USBDevice/DeviceManager.h" +#include "USBDevice/DeviceDriver/DeviceDriverTypes.h" const usbd_class_driver_t *usbd_app_driver_get_cb(uint8_t *driver_count) { + DeviceDriverType dt = DeviceManager::get_instance().get_driver_type(); + if (dt == DeviceDriverType::PS1PS2 || dt == DeviceDriverType::GAMECUBE || dt == DeviceDriverType::DREAMCAST) { + *driver_count = 0; + return nullptr; + } *driver_count = 1; return DeviceManager::get_instance().get_driver()->get_class_driver(); } diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.cpp b/Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.cpp new file mode 100644 index 00000000..237a2a2e --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.cpp @@ -0,0 +1,274 @@ +#include "USBHost/GPIOHost/GPIOHost.h" +#include "Gamepad/Gamepad.h" +#include "USBHost/GPIOHost/psx_host/psx_host.h" +#include "USBHost/GPIOHost/joybus_host/joybus_controller.h" +#include "USBHost/GPIOHost/joybus_host/n64_host.h" +#include "USBHost/GPIOHost/dreamcast_host/MapleBus.h" +#include "USBHost/GPIOHost/dreamcast_host/MaplePacket.hpp" +#include "USBHost/GPIOHost/dreamcast_host/dreamcast_constants.h" +#include "USBHost/GPIOHost/dreamcast_host/dreamcast_structures.h" + +#include +#include + +namespace GPIOHost { + +/* PSX report: byte0=id, 1=buttons1 (dpad + start), 2=buttons2 (face + shoulders), 3=rx, 4=ry, 5=lx, 6=ly, 7,8 */ +static constexpr uint8_t PSX_UP = 0x10; +static constexpr uint8_t PSX_RIGHT = 0x20; +static constexpr uint8_t PSX_DOWN = 0x40; +static constexpr uint8_t PSX_LEFT = 0x80; +static constexpr uint8_t PSX_START = 0x08; +static constexpr uint8_t PSX_L2 = 0x01; +static constexpr uint8_t PSX_R2 = 0x02; +static constexpr uint8_t PSX_L1 = 0x04; +static constexpr uint8_t PSX_R1 = 0x08; +static constexpr uint8_t PSX_TRI = 0x10; +static constexpr uint8_t PSX_CIR = 0x20; +static constexpr uint8_t PSX_X = 0x40; +static constexpr uint8_t PSX_SQU = 0x80; + +static inline int16_t psx_stick_to_int16(uint8_t b) +{ + int32_t v = (int32_t)(b & 0xFFu) - 128; + if (v < -127) v = -127; + if (v > 127) v = 127; + return (int16_t)(v * 32767 / 127); +} + +void psx_host_init(unsigned pio_index, unsigned gpio_cmd, unsigned gpio_data) +{ + ::psx_host_init(pio_index, gpio_cmd, gpio_data); +} + +void psx_host_poll(Gamepad& gamepad) +{ + uint8_t buf[9]; + if (!::psx_host_take_data(buf)) + { + return; + } + Gamepad::PadIn pad_in; + std::memset(&pad_in, 0, sizeof(pad_in)); + + uint8_t b1 = buf[1]; + uint8_t b2 = buf[2]; + if (b1 & PSX_UP) pad_in.dpad |= Gamepad::DPAD_UP; + if (b1 & PSX_DOWN) pad_in.dpad |= Gamepad::DPAD_DOWN; + if (b1 & PSX_LEFT) pad_in.dpad |= Gamepad::DPAD_LEFT; + if (b1 & PSX_RIGHT) pad_in.dpad |= Gamepad::DPAD_RIGHT; + if (b1 & PSX_START) pad_in.buttons |= Gamepad::BUTTON_START; + if (b2 & PSX_X) pad_in.buttons |= Gamepad::BUTTON_A; + if (b2 & PSX_CIR) pad_in.buttons |= Gamepad::BUTTON_B; + if (b2 & PSX_TRI) pad_in.buttons |= Gamepad::BUTTON_X; + if (b2 & PSX_SQU) pad_in.buttons |= Gamepad::BUTTON_Y; + if (b2 & PSX_L1) pad_in.buttons |= Gamepad::BUTTON_LB; + if (b2 & PSX_R1) pad_in.buttons |= Gamepad::BUTTON_RB; + pad_in.trigger_l = (b2 & PSX_L2) ? 0xFF : 0; + pad_in.trigger_r = (b2 & PSX_R2) ? 0xFF : 0; + + pad_in.joystick_rx = psx_stick_to_int16(buf[3]); + pad_in.joystick_ry = psx_stick_to_int16(buf[4]); + pad_in.joystick_lx = psx_stick_to_int16(buf[5]); + pad_in.joystick_ly = psx_stick_to_int16(buf[6]); + + gamepad.set_pad_in(pad_in); +} + +/* GameCube report: buttons1, buttons2, lx, ly, rx, ry, l, r (same as GCReport). */ +static constexpr uint8_t GC_A = 0x01; +static constexpr uint8_t GC_B = 0x02; +static constexpr uint8_t GC_X = 0x04; +static constexpr uint8_t GC_Y = 0x08; +static constexpr uint8_t GC_START = 0x10; +static constexpr uint8_t GC_DPAD_LEFT = 0x01; +static constexpr uint8_t GC_DPAD_RIGHT = 0x02; +static constexpr uint8_t GC_DPAD_DOWN = 0x04; +static constexpr uint8_t GC_DPAD_UP = 0x08; +static constexpr uint8_t GC_Z = 0x10; +static constexpr uint8_t GC_R = 0x20; +static constexpr uint8_t GC_L = 0x40; +static constexpr uint8_t STICK_CENTER = 0x80; + +static int16_t gc_stick_to_int16(uint8_t b) +{ + int32_t v = (int32_t)(b & 0xFFu) - (int32_t)STICK_CENTER; + if (v < -127) v = -127; + if (v > 127) v = 127; + return (int16_t)(v * 32767 / 127); +} + +void joybus_host_init(unsigned pio_index, unsigned data_pin) +{ + ::joybus_host_init(pio_index, data_pin); +} + +void joybus_host_poll(Gamepad& gamepad) +{ + static const uint8_t poll_cmd[] = { 0x40, 0x03 }; + ::joybus_send_data(poll_cmd, 2, 8); + const uint8_t *r = ::joybus_get_response(); + + Gamepad::PadIn pad_in; + std::memset(&pad_in, 0, sizeof(pad_in)); + + uint8_t b1 = r[0]; + uint8_t b2 = r[1]; + if (b2 & GC_DPAD_UP) pad_in.dpad |= Gamepad::DPAD_UP; + if (b2 & GC_DPAD_DOWN) pad_in.dpad |= Gamepad::DPAD_DOWN; + if (b2 & GC_DPAD_LEFT) pad_in.dpad |= Gamepad::DPAD_LEFT; + if (b2 & GC_DPAD_RIGHT) pad_in.dpad |= Gamepad::DPAD_RIGHT; + if (b1 & GC_START) pad_in.buttons |= Gamepad::BUTTON_START; + if (b1 & GC_A) pad_in.buttons |= Gamepad::BUTTON_A; + if (b1 & GC_B) pad_in.buttons |= Gamepad::BUTTON_B; + if (b1 & GC_X) pad_in.buttons |= Gamepad::BUTTON_X; + if (b1 & GC_Y) pad_in.buttons |= Gamepad::BUTTON_Y; + if (b2 & GC_L) pad_in.buttons |= Gamepad::BUTTON_LB; + if (b2 & GC_R) pad_in.buttons |= Gamepad::BUTTON_RB; + if (b2 & GC_Z) pad_in.buttons |= Gamepad::BUTTON_MISC; + pad_in.trigger_l = r[6]; + pad_in.trigger_r = r[7]; + + pad_in.joystick_lx = gc_stick_to_int16(r[2]); + pad_in.joystick_ly = gc_stick_to_int16(r[3]); + pad_in.joystick_rx = gc_stick_to_int16(r[4]); + pad_in.joystick_ry = gc_stick_to_int16(r[5]); + + gamepad.set_pad_in(pad_in); +} + +/* N64 report: 4 bytes from PicoGamepadConverter layout. byte0: A=0x80, B=0x40, Z=0x20, START=0x10, D-pad low nibble. */ +/* byte1: R=0x10, L=0x20, C buttons low nibble (C_UP=8, C_DOWN=4, C_LEFT=2, C_RIGHT=1). byte2/3: joy X, Y (0x80 center). */ +static constexpr uint8_t N64_A = 0x80; +static constexpr uint8_t N64_B = 0x40; +static constexpr uint8_t N64_Z = 0x20; +static constexpr uint8_t N64_START = 0x10; +static constexpr uint8_t N64_DPAD = 0x0F; +static constexpr uint8_t N64_R = 0x10; +static constexpr uint8_t N64_L = 0x20; +static constexpr uint8_t N64_C = 0x0F; +static constexpr uint8_t N64_C_UP = 0x08; +static constexpr uint8_t N64_C_DOWN = 0x04; +static constexpr uint8_t N64_C_LEFT = 0x02; +static constexpr uint8_t N64_C_RIGHT = 0x01; +static constexpr uint8_t N64_JOY_CENTER = 0x80; + +static int16_t n64_stick_to_int16(uint8_t b) +{ + int32_t v = (int32_t)(b & 0xFFu) - (int32_t)N64_JOY_CENTER; + if (v < -127) v = -127; + if (v > 127) v = 127; + return (int16_t)(v * 32767 / 127); +} + +void n64_host_init(unsigned pio_index, unsigned data_pin) +{ + ::n64_host_init(pio_index, data_pin); +} + +void n64_host_poll(Gamepad& gamepad) +{ + ::n64_host_poll(); + const uint8_t* r = ::n64_host_get_response(); + + Gamepad::PadIn pad_in; + std::memset(&pad_in, 0, sizeof(pad_in)); + + uint8_t b0 = r[0]; + uint8_t b1 = r[1]; + uint8_t dpad_nibble = b0 & N64_DPAD; + if (dpad_nibble == 0x08 || dpad_nibble == 0x09 || dpad_nibble == 0x0A) pad_in.dpad |= Gamepad::DPAD_UP; + if (dpad_nibble == 0x04 || dpad_nibble == 0x05 || dpad_nibble == 0x06) pad_in.dpad |= Gamepad::DPAD_DOWN; + if (dpad_nibble == 0x02 || dpad_nibble == 0x06 || dpad_nibble == 0x0A) pad_in.dpad |= Gamepad::DPAD_LEFT; + if (dpad_nibble == 0x01 || dpad_nibble == 0x05 || dpad_nibble == 0x09) pad_in.dpad |= Gamepad::DPAD_RIGHT; + + if (b0 & N64_START) pad_in.buttons |= Gamepad::BUTTON_START; + if (b0 & N64_A) pad_in.buttons |= Gamepad::BUTTON_A; + if (b0 & N64_B) pad_in.buttons |= Gamepad::BUTTON_B; + if (b0 & N64_Z) pad_in.buttons |= Gamepad::BUTTON_MISC; + if (b1 & N64_L) pad_in.buttons |= Gamepad::BUTTON_LB; + if (b1 & N64_R) pad_in.buttons |= Gamepad::BUTTON_RB; + /* C buttons -> right stick (diagonals combine) */ + uint8_t c_nibble = b1 & N64_C; + pad_in.joystick_rx = ((c_nibble & N64_C_RIGHT) ? 32767 : 0) - ((c_nibble & N64_C_LEFT) ? 32767 : 0); + pad_in.joystick_ry = ((c_nibble & N64_C_DOWN) ? 32767 : 0) - ((c_nibble & N64_C_UP) ? 32767 : 0); + + pad_in.joystick_lx = n64_stick_to_int16(r[2]); + pad_in.joystick_ly = n64_stick_to_int16(r[3]); + + gamepad.set_pad_in(pad_in); +} + +static std::unique_ptr s_dreamcast_bus; + +void dreamcast_host_init(unsigned /* pio_in_index */, unsigned /* pio_out_index */, unsigned pin_a, int dir_pin) { + s_dreamcast_bus = std::make_unique(pin_a, dir_pin, true); +} + +static void controller_condition_to_pad_in(const controller_condition_t& cond, Gamepad::PadIn& pad) { + std::memset(&pad, 0, sizeof(pad)); + /* Dreamcast: 0 = pressed. PadIn: bit set = pressed */ + if (!cond.up) pad.dpad |= Gamepad::DPAD_UP; + if (!cond.down) pad.dpad |= Gamepad::DPAD_DOWN; + if (!cond.left) pad.dpad |= Gamepad::DPAD_LEFT; + if (!cond.right) pad.dpad |= Gamepad::DPAD_RIGHT; + if (!cond.a) pad.buttons |= Gamepad::BUTTON_A; + if (!cond.b) pad.buttons |= Gamepad::BUTTON_B; + if (!cond.x) pad.buttons |= Gamepad::BUTTON_X; + if (!cond.y) pad.buttons |= Gamepad::BUTTON_Y; + if (!cond.start) pad.buttons |= Gamepad::BUTTON_START; + if (!cond.c) pad.buttons |= Gamepad::BUTTON_RB; + if (!cond.z) pad.buttons |= Gamepad::BUTTON_LB; + if (!cond.d) pad.buttons |= Gamepad::BUTTON_MISC; + pad.trigger_l = cond.l; + pad.trigger_r = cond.r; + /* Sticks: 0–255, 128 center -> int16 -32767..32767 */ + auto stick8_to_16 = [](uint8_t v) -> int16_t { + int32_t x = (int32_t)(v & 0xFFu) - 128; + if (x < -127) x = -127; + if (x > 127) x = 127; + return (int16_t)(x * 32767 / 127); + }; + pad.joystick_lx = stick8_to_16(cond.lAnalogLR); + pad.joystick_ly = stick8_to_16(cond.lAnalogUD); + pad.joystick_rx = stick8_to_16(cond.rAnalogLR); + pad.joystick_ry = stick8_to_16(cond.rAnalogUD); +} + +void dreamcast_host_poll(Gamepad& gamepad) { + if (!s_dreamcast_bus) return; + MapleBus& bus = *s_dreamcast_bus; + if (bus.isBusy()) { + MapleBus::Status st = bus.processEvents(time_us_64()); + (void)st; + return; + } + MaplePacket req; + req.setFrame(COMMAND_GET_CONDITION, MAPLE_CTRL_ADDR, MAPLE_HOST_ADDR, 0); + req.payloadCount = 0; + req.payloadByteOrder = MaplePacket::ByteOrder::HOST; + if (!bus.write(req, true, MAPLE_RESPONSE_TIMEOUT_US, MaplePacket::ByteOrder::HOST)) + return; + uint64_t deadline = time_us_64() + MAPLE_RESPONSE_TIMEOUT_US + 500; + while (time_us_64() < deadline) { + MapleBus::Status st = bus.processEvents(time_us_64()); + if (st.phase == MapleBus::Phase::READ_COMPLETE && st.readBuffer && st.readBufferLen >= 3) { + uint32_t frame = st.readBuffer[0]; + uint8_t cmd = MaplePacket::Frame::getFrameCommand(frame, st.rxByteOrder); + if (cmd == COMMAND_RESPONSE_DATA_XFER) { + const uint32_t* pl = st.readBuffer + 1; + controller_condition_t cond; + memcpy(&cond, pl + 1, sizeof(cond)); /* skip function code word */ + Gamepad::PadIn pad; + controller_condition_to_pad_in(cond, pad); + gamepad.set_pad_in(pad); + } + return; + } + if (st.phase == MapleBus::Phase::READ_FAILED || st.phase == MapleBus::Phase::WRITE_FAILED) + return; + busy_wait_us(50); + } +} + +} // namespace GPIOHost diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.h b/Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.h new file mode 100644 index 00000000..b77e9765 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/GPIOHost.h @@ -0,0 +1,32 @@ +#ifndef USBHOST_GPIOHOST_GPIOHOST_H_ +#define USBHOST_GPIOHOST_GPIOHOST_H_ + +class Gamepad; + +namespace GPIOHost { + +/** Initialize PSX host. CMD pin = gpio_cmd (CLK=+1, ATT=+2), DATA=gpio_data. Call when input source is PSX_GPIO. */ +void psx_host_init(unsigned pio_index, unsigned gpio_cmd, unsigned gpio_data); + +/** Poll PSX controller and update gamepad if new data. Call from main loop when input is PSX_GPIO. */ +void psx_host_poll(Gamepad& gamepad); + +/** Initialize GameCube JoyBus host. data_pin = single wire. Call when input source is GAMECUBE_GPIO. */ +void joybus_host_init(unsigned pio_index, unsigned data_pin); + +/** Poll GameCube controller and update gamepad. Call from main loop when input is GAMECUBE_GPIO. */ +void joybus_host_poll(Gamepad& gamepad); + +/** Dreamcast Maple Bus host: init (stub until DreamPicoPort is ported). Pin A = first of two consecutive GPIOs. */ +void dreamcast_host_init(unsigned pio_in_index, unsigned pio_out_index, unsigned pin_a, int dir_pin); +/** Poll Dreamcast controller and update gamepad (stub until port). */ +void dreamcast_host_poll(Gamepad& gamepad); + +/** Initialize N64 controller host (1-wire data pin). Call when input source is N64_GPIO. */ +void n64_host_init(unsigned pio_index, unsigned data_pin); +/** Poll N64 controller and update gamepad. Call from main loop when input is N64_GPIO. */ +void n64_host_poll(Gamepad& gamepad); + +} // namespace GPIOHost + +#endif /* USBHOST_GPIOHOST_GPIOHOST_H_ */ diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.cpp b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.cpp new file mode 100644 index 00000000..70b0a6f2 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.cpp @@ -0,0 +1,349 @@ +/* Maple Bus host implementation. Ported from DreamPicoPort (OrangeFox86). */ + +#include "MapleBus.h" +#include "maple_config.h" +#include "maple_utils.h" +#include +#include +#include +#include +#include + +#define MAPLE_OUT_PIO pio0 +#define MAPLE_IN_PIO pio1 + +static MapleBus* s_bus_for_write_irq = nullptr; +static MapleBus* s_bus_for_read_irq = nullptr; + +static void maple_write_irq_handler(void) { + if (s_bus_for_write_irq) s_bus_for_write_irq->writeIsr(); +} +static void maple_read_irq_handler(void) { + if (s_bus_for_read_irq) s_bus_for_read_irq->readIsr(); +} + +MapleBus::MapleBus(uint32_t pinA, int32_t dirPin, bool dirOutHigh) + : mPinA(pinA) + , mPinB(pinA + 1) + , mDirPin(dirPin) + , mDirOutHigh(dirOutHigh) + , mMaskA(1u << pinA) + , mMaskB(1u << (pinA + 1)) + , mMaskAB(mMaskA | mMaskB) + , mOutOffset(pio_add_program(MAPLE_OUT_PIO, &maple_out_program)) + , mInOffset(pio_add_program(MAPLE_IN_PIO, &maple_in_program)) + , mSmOut(pio_claim_unused_sm(MAPLE_OUT_PIO, true)) + , mSmIn(pio_claim_unused_sm(MAPLE_IN_PIO, true)) + , mDmaWriteChannel(dma_claim_unused_channel(true)) + , mDmaReadChannel(dma_claim_unused_channel(true)) + , mCurrentPhase(Phase::IDLE) + , mExpectingResponse(false) + , mResponseTimeoutUs(MAPLE_RESPONSE_TIMEOUT_US) + , mProcKillTime(UINT64_MAX) + , mLastReceivedWordTimeUs(0) + , mLastReadTransferCount(0) +{ + /* Out SM: clock from MAPLE_NS_PER_BIT and maple_out DOUBLE_PHASE_TICKS */ + pio_sm_config cOut = maple_out_program_get_default_config(mOutOffset); + sm_config_set_sideset_pins(&cOut, mPinA); + sm_config_set_set_pins(&cOut, mPinA, 2); + sm_config_set_out_shift(&cOut, false, true, 32); + float div = (MAPLE_CPU_FREQ_KHZ * (MAPLE_NS_PER_BIT / 3.0f * 2.0f)) / maple_out_DOUBLE_PHASE_TICKS / 1000000.0f; + sm_config_set_clkdiv(&cOut, div); + pio_sm_init(MAPLE_OUT_PIO, mSmOut, mOutOffset, &cOut); + + /* In SM */ + pio_sm_config cIn = maple_in_program_get_default_config(mInOffset); + sm_config_set_in_pins(&cIn, mPinA); + sm_config_set_jmp_pin(&cIn, mPinA); + sm_config_set_out_shift(&cIn, true, false, 32); + sm_config_set_in_shift(&cIn, false, true, 32); + sm_config_set_clkdiv(&cIn, 1.0f); + pio_sm_init(MAPLE_IN_PIO, mSmIn, mInOffset, &cIn); + + gpio_set_dir_in_masked(mMaskAB); + gpio_set_pulls(mPinA, true, false); + gpio_set_pulls(mPinB, true, false); + + if (mDirPin >= 0) { + gpio_init((uint)mDirPin); + setDirection(false); + gpio_set_dir((uint)mDirPin, true); + } + + /* One bus per host: register for IRQ */ + if (!s_bus_for_write_irq) { + s_bus_for_write_irq = this; + irq_set_exclusive_handler(PIO0_IRQ_0, maple_write_irq_handler); + irq_set_enabled(PIO0_IRQ_0, true); + pio_set_irq0_source_enabled(MAPLE_OUT_PIO, pis_interrupt0, true); + } + if (!s_bus_for_read_irq) { + s_bus_for_read_irq = this; + irq_set_exclusive_handler(PIO1_IRQ_0, maple_read_irq_handler); + irq_set_enabled(PIO1_IRQ_0, true); + pio_set_irq0_source_enabled(MAPLE_IN_PIO, pis_interrupt0, true); + } + + /* DMA write: memory -> PIO TX FIFO, bswap */ + dma_channel_config dc = dma_channel_get_default_config(mDmaWriteChannel); + channel_config_set_read_increment(&dc, true); + channel_config_set_write_increment(&dc, false); + channel_config_set_bswap(&dc, true); + channel_config_set_dreq(&dc, pio_get_dreq(MAPLE_OUT_PIO, mSmOut, true)); + dma_channel_configure(mDmaWriteChannel, &dc, + &MAPLE_OUT_PIO->txf[mSmOut], mWriteBuffer, 1, false); + + /* DMA read: PIO RX FIFO -> memory, bswap */ + dma_channel_config dr = dma_channel_get_default_config(mDmaReadChannel); + channel_config_set_read_increment(&dr, false); + channel_config_set_write_increment(&dr, true); + channel_config_set_bswap(&dr, true); + channel_config_set_dreq(&dr, pio_get_dreq(MAPLE_IN_PIO, mSmIn, false)); + dma_channel_configure(mDmaReadChannel, &dr, + mReadBuffer, &MAPLE_IN_PIO->rxf[mSmIn], sizeof(mReadBuffer) / sizeof(mReadBuffer[0]), false); +} + +static void crc8_word(uint32_t word, uint8_t& crc) { + const uint8_t* p = (const uint8_t*)&word; + for (unsigned i = 0; i < 4; i++) crc ^= p[i]; +} +static void crc8_words(const uint32_t* src, uint32_t len, uint8_t& crc) { + for (; len; len--, src++) crc8_word(*src, crc); +} + +bool MapleBus::lineCheck() { +#if (MAPLE_OPEN_LINE_CHECK_TIME_US > 0) + uint64_t end = time_us_64() + MAPLE_OPEN_LINE_CHECK_TIME_US + 1; + while (time_us_64() < end) { + if ((gpio_get_all() & mMaskAB) != mMaskAB) return false; + } +#endif + return true; +} + +void MapleBus::setDirection(bool output) { + if (!output) { + gpio_set_dir_in_masked(mMaskAB); + gpio_set_function(mPinB, GPIO_FUNC_SIO); + gpio_set_function(mPinA, GPIO_FUNC_SIO); + } + if (mDirPin >= 0) + gpio_put((uint)mDirPin, mDirOutHigh ? output : !output); +} + +void MapleBus::writeIsr() { + pio_interrupt_clear(MAPLE_OUT_PIO, 1u); + pio_sm_set_enabled(MAPLE_OUT_PIO, mSmOut, false); + if (!mExpectingResponse) { + gpio_set_mask(mMaskAB); + gpio_set_dir_out_masked(mMaskAB); + } else { + gpio_set_pulls(mPinB, false, true); + } + gpio_set_dir_in_masked(mMaskAB); + gpio_set_function(mPinB, GPIO_FUNC_SIO); + gpio_set_function(mPinA, GPIO_FUNC_SIO); + + if (mExpectingResponse) { + pio_sm_clear_fifos(MAPLE_IN_PIO, mSmIn); + pio_sm_restart(MAPLE_IN_PIO, mSmIn); + pio_sm_clkdiv_restart(MAPLE_IN_PIO, mSmIn); + pio_sm_exec(MAPLE_IN_PIO, mSmIn, pio_encode_jmp(mInOffset)); + pio_sm_set_consecutive_pindirs(MAPLE_IN_PIO, mSmIn, mPinA, 2, false); + pio_gpio_init(MAPLE_IN_PIO, mPinA); + pio_gpio_init(MAPLE_IN_PIO, mPinB); + pio_sm_set_enabled(MAPLE_IN_PIO, mSmIn, true); + setDirection(false); + gpio_set_pulls(mPinB, true, false); + mProcKillTime = (mResponseTimeoutUs == UINT64_MAX) ? UINT64_MAX : (time_us_64() + mResponseTimeoutUs); + mCurrentPhase = Phase::WAITING_FOR_READ_START; + } else { + setDirection(false); + mCurrentPhase = Phase::WRITE_COMPLETE; + } +} + +void MapleBus::readIsr() { + pio_interrupt_clear(MAPLE_IN_PIO, 1u); + if (mCurrentPhase == Phase::WAITING_FOR_READ_START) { + mCurrentPhase = Phase::READ_IN_PROGRESS; + mLastReceivedWordTimeUs = time_us_64(); + } else if (mCurrentPhase == Phase::READ_IN_PROGRESS) { + pio_sm_set_enabled(MAPLE_IN_PIO, mSmIn, false); + gpio_set_dir_in_masked(mMaskAB); + gpio_set_function(mPinB, GPIO_FUNC_SIO); + gpio_set_function(mPinA, GPIO_FUNC_SIO); + mCurrentPhase = Phase::READ_COMPLETE; + } +} + +bool MapleBus::write(const MaplePacket& packet, bool autostartRead, uint64_t readTimeoutUs, MaplePacket::ByteOrder rxByteOrder) { + if (mCurrentPhase != Phase::IDLE) return false; + + dma_channel_abort(mDmaWriteChannel); + dma_channel_abort(mDmaReadChannel); + + uint8_t crc = 0; + uint32_t frameWord = packet.getFrameWord(); + crc8_word(frameWord, crc); + for (unsigned i = 0; i < packet.payloadCount; i++) crc8_word(packet.payload[i], crc); + + bool flipBytes = (packet.payloadByteOrder != MaplePacket::ByteOrder::NETWORK); + uint32_t totalBits = MaplePacket::getNumTotalBits((uint32_t)packet.payloadCount); + unsigned len = 0; + mWriteBuffer[len++] = flipBytes ? MaplePacket::flipWordBytes(totalBits) : totalBits; + mWriteBuffer[len++] = frameWord; + for (unsigned i = 0; i < packet.payloadCount; i++) + mWriteBuffer[len++] = packet.payload[i]; + mWriteBuffer[len++] = flipBytes ? (uint32_t)crc : ((uint32_t)crc << 24); + + if (!lineCheck()) return false; + + mExpectingResponse = autostartRead; + mResponseTimeoutUs = readTimeoutUs; + mRxByteOrder = rxByteOrder; + mCurrentPhase = Phase::WRITE_IN_PROGRESS; + + if (autostartRead) { + mLastReadTransferCount = sizeof(mReadBuffer) / sizeof(mReadBuffer[0]); + dma_channel_transfer_to_buffer_now(mDmaReadChannel, mReadBuffer, mLastReadTransferCount); + pio_sm_clear_fifos(MAPLE_IN_PIO, mSmIn); + pio_sm_restart(MAPLE_IN_PIO, mSmIn); + pio_sm_clkdiv_restart(MAPLE_IN_PIO, mSmIn); + pio_sm_exec(MAPLE_IN_PIO, mSmIn, pio_encode_jmp(mInOffset)); + pio_sm_set_consecutive_pindirs(MAPLE_IN_PIO, mSmIn, mPinA, 2, false); + } + + setDirection(true); + pio_sm_clear_fifos(MAPLE_OUT_PIO, mSmOut); + pio_sm_restart(MAPLE_OUT_PIO, mSmOut); + pio_sm_clkdiv_restart(MAPLE_OUT_PIO, mSmOut); + pio_sm_exec(MAPLE_OUT_PIO, mSmOut, pio_encode_jmp(mOutOffset)); + pio_sm_set_consecutive_pindirs(MAPLE_OUT_PIO, mSmOut, mPinA, 2, false); + pio_gpio_init(MAPLE_OUT_PIO, mPinA); + pio_gpio_init(MAPLE_OUT_PIO, mPinB); + pio_sm_set_enabled(MAPLE_OUT_PIO, mSmOut, true); + dma_channel_transfer_from_buffer_now(mDmaWriteChannel, mWriteBuffer, len); + + uint32_t txNs = MaplePacket::getTxTimeNs((uint32_t)packet.payloadCount, MAPLE_NS_PER_BIT); + txNs = txNs * (100 + MAPLE_WRITE_TIMEOUT_EXTRA_PERCENT) / 100; + mProcKillTime = time_us_64() + MAPLE_INT_DIVIDE_CEILING(txNs, 1000); + return true; +} + +bool MapleBus::startRead(uint64_t readTimeoutUs, MaplePacket::ByteOrder rxByteOrder) { + if (mCurrentPhase != Phase::IDLE) return false; + dma_channel_abort(mDmaWriteChannel); + dma_channel_abort(mDmaReadChannel); + mRxByteOrder = rxByteOrder; + bool flipBytes = (rxByteOrder != MaplePacket::ByteOrder::NETWORK); + dma_channel_config c = dma_channel_get_default_config(mDmaReadChannel); + channel_config_set_read_increment(&c, false); + channel_config_set_write_increment(&c, true); + channel_config_set_bswap(&c, flipBytes); + channel_config_set_dreq(&c, pio_get_dreq(MAPLE_IN_PIO, mSmIn, false)); + dma_channel_configure(mDmaReadChannel, &c, mReadBuffer, &MAPLE_IN_PIO->rxf[mSmIn], + sizeof(mReadBuffer) / sizeof(mReadBuffer[0]), false); + mLastReadTransferCount = sizeof(mReadBuffer) / sizeof(mReadBuffer[0]); + dma_channel_transfer_to_buffer_now(mDmaReadChannel, mReadBuffer, mLastReadTransferCount); + mProcKillTime = (readTimeoutUs == 0) ? UINT64_MAX : (time_us_64() + readTimeoutUs); + mCurrentPhase = Phase::WAITING_FOR_READ_START; + setDirection(false); + pio_sm_clear_fifos(MAPLE_IN_PIO, mSmIn); + pio_sm_restart(MAPLE_IN_PIO, mSmIn); + pio_sm_clkdiv_restart(MAPLE_IN_PIO, mSmIn); + pio_sm_exec(MAPLE_IN_PIO, mSmIn, pio_encode_jmp(mInOffset)); + pio_sm_set_consecutive_pindirs(MAPLE_IN_PIO, mSmIn, mPinA, 2, false); + pio_gpio_init(MAPLE_IN_PIO, mPinA); + pio_gpio_init(MAPLE_IN_PIO, mPinB); + pio_sm_set_enabled(MAPLE_IN_PIO, mSmIn, true); + return true; +} + +MapleBus::Status MapleBus::processEvents(uint64_t currentTimeUs) { + Status st; + st.phase = mCurrentPhase; + st.readBuffer = nullptr; + st.readBufferLen = 0; + + if (st.phase == Phase::READ_COMPLETE) { + uint64_t t0 = time_us_64(); + while (!pio_sm_is_rx_fifo_empty(MAPLE_IN_PIO, mSmIn) && (time_us_64() - t0 < 1000)) + tight_loop_contents(); + uint32_t total = sizeof(mReadBuffer) / sizeof(mReadBuffer[0]); + uint32_t left = dma_channel_hw_addr(mDmaReadChannel)->transfer_count; + uint32_t dmaWordsRead = total - left; + + if (dmaWordsRead > 1) { + uint8_t len = (mRxByteOrder != MaplePacket::ByteOrder::NETWORK) + ? (mReadBuffer[0] & 0xFF) : (mReadBuffer[0] >> 24); + uint8_t expectedCrc = (mRxByteOrder != MaplePacket::ByteOrder::NETWORK) + ? (mReadBuffer[dmaWordsRead - 1] & 0xFF) : (mReadBuffer[dmaWordsRead - 1] >> 24); + + if (len <= dmaWordsRead - 2) { + for (uint32_t i = 0; i < dmaWordsRead - 1; i++) mLastRead[i] = mReadBuffer[i]; + uint8_t crc = 0; + crc8_words(mLastRead, dmaWordsRead - 1, crc); + if (crc == expectedCrc) { + st.readBuffer = mLastRead; + st.readBufferLen = dmaWordsRead - 1; + st.rxByteOrder = mRxByteOrder; + } else { + st.phase = Phase::READ_FAILED; + st.failureReason = FailureReason::CRC_INVALID; + } + } else { + st.phase = Phase::READ_FAILED; + st.failureReason = FailureReason::MISSING_DATA; + } + } else { + st.phase = Phase::READ_FAILED; + st.failureReason = FailureReason::MISSING_DATA; + } + mCurrentPhase = Phase::IDLE; + return st; + } + + if (st.phase == Phase::WRITE_COMPLETE) { + mCurrentPhase = Phase::IDLE; + return st; + } + + if (st.phase == Phase::READ_IN_PROGRESS) { + uint32_t tc = dma_channel_hw_addr(mDmaReadChannel)->transfer_count; + if (tc == 0) { + st.phase = Phase::READ_FAILED; + st.failureReason = FailureReason::BUFFER_OVERFLOW; + mCurrentPhase = Phase::IDLE; + } else if (tc == mLastReadTransferCount) { + if (currentTimeUs > mLastReceivedWordTimeUs && + (currentTimeUs - mLastReceivedWordTimeUs) >= MAPLE_INTER_WORD_READ_TIMEOUT_US) { + pio_sm_set_enabled(MAPLE_IN_PIO, mSmIn, false); + st.phase = Phase::READ_FAILED; + st.failureReason = FailureReason::TIMEOUT; + mCurrentPhase = Phase::IDLE; + } + } else { + mLastReadTransferCount = tc; + mLastReceivedWordTimeUs = currentTimeUs; + } + return st; + } + + if (st.phase != Phase::IDLE && currentTimeUs >= mProcKillTime) { + if (st.phase == Phase::WAITING_FOR_READ_START) { + pio_sm_set_enabled(MAPLE_IN_PIO, mSmIn, false); + st.phase = Phase::READ_FAILED; + st.failureReason = FailureReason::TIMEOUT; + } else { + pio_sm_set_enabled(MAPLE_OUT_PIO, mSmOut, false); + pio_sm_set_enabled(MAPLE_IN_PIO, mSmIn, false); + setDirection(false); + st.phase = Phase::WRITE_FAILED; + st.failureReason = FailureReason::TIMEOUT; + } + mCurrentPhase = Phase::IDLE; + } + return st; +} diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.h b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.h new file mode 100644 index 00000000..786d0117 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MapleBus.h @@ -0,0 +1,87 @@ +/* Maple Bus host. Ported from DreamPicoPort. */ + +#pragma once + +#include "MaplePacket.hpp" +#include "maple_config.h" +#include "hardware/pio.h" +#include "hardware/dma.h" +#include + +/* Generated by pico_generate_pio_header */ +#include "maple_in.pio.h" +#include "maple_out.pio.h" + +class MapleBus { +public: + enum class Phase : uint8_t { + IDLE = 0, + WRITE_IN_PROGRESS, + WRITE_FAILED, + WRITE_COMPLETE, + WAITING_FOR_READ_START, + READ_IN_PROGRESS, + READ_FAILED, + READ_COMPLETE, + }; + enum class FailureReason : uint8_t { + NONE = 0, + CRC_INVALID, + MISSING_DATA, + BUFFER_OVERFLOW, + TIMEOUT, + }; + struct Status { + Phase phase; + FailureReason failureReason; + const uint32_t* readBuffer; + uint32_t readBufferLen; + MaplePacket::ByteOrder rxByteOrder; + }; + + MapleBus(uint32_t pinA, int32_t dirPin = -1, bool dirOutHigh = true); + + bool write(const MaplePacket& packet, bool autostartRead, + uint64_t readTimeoutUs = MAPLE_RESPONSE_TIMEOUT_US, + MaplePacket::ByteOrder rxByteOrder = MaplePacket::ByteOrder::HOST); + + /** Start listening for an incoming packet (device mode). No write; use processEvents until READ_COMPLETE. */ + bool startRead(uint64_t readTimeoutUs = 0, MaplePacket::ByteOrder rxByteOrder = MaplePacket::ByteOrder::HOST); + + void writeIsr(); + void readIsr(); + + Status processEvents(uint64_t currentTimeUs); + + bool isBusy() const { return mCurrentPhase != Phase::IDLE; } + +private: + bool lineCheck(); + void setDirection(bool output); + + const uint32_t mPinA; + const uint32_t mPinB; + const int32_t mDirPin; + const bool mDirOutHigh; + const uint32_t mMaskA; + const uint32_t mMaskB; + const uint32_t mMaskAB; + const uint mOutOffset; + const uint mInOffset; + const uint mSmOut; + const uint mSmIn; + const int mDmaWriteChannel; + const int mDmaReadChannel; + + volatile uint32_t mWriteBuffer[258]; + volatile uint32_t mReadBuffer[258]; + uint32_t mLastRead[256]; + + Phase mCurrentPhase; + bool mExpectingResponse; + uint64_t mResponseTimeoutUs; + MaplePacket::ByteOrder mRxByteOrder; + uint64_t mProcKillTime; + uint64_t mLastReceivedWordTimeUs; + uint32_t mLastReadTransferCount; +}; diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MaplePacket.hpp b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MaplePacket.hpp new file mode 100644 index 00000000..cf76be72 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/MaplePacket.hpp @@ -0,0 +1,102 @@ +/* Minimal Maple packet for host GET_CONDITION. Ported from DreamPicoPort MaplePacket.hpp. */ + +#pragma once + +#include +#include +#include "dreamcast_constants.h" +#include "maple_config.h" + +struct MaplePacket { + enum class ByteOrder { HOST, NETWORK }; + + struct Frame { + uint8_t command; + uint8_t recipientAddr; + uint8_t senderAddr; + uint8_t length; + + static constexpr uint32_t LEN_POSITION_HOST = 0; + static constexpr uint32_t SENDER_ADDR_POSITION_HOST = 8; + static constexpr uint32_t RECIPIENT_ADDR_POSITION_HOST = 16; + static constexpr uint32_t COMMAND_POSITION_HOST = 24; + static constexpr uint32_t LEN_POSITION_NETWORK = 24; + static constexpr uint32_t SENDER_ADDR_POSITION_NETWORK = 8; + static constexpr uint32_t RECIPIENT_ADDR_POSITION_NETWORK = 16; + static constexpr uint32_t COMMAND_POSITION_NETWORK = 0; + + static uint8_t getFramePacketLength(uint32_t frameWord, ByteOrder byteOrder = ByteOrder::HOST) { + return (frameWord >> (byteOrder == ByteOrder::NETWORK ? LEN_POSITION_NETWORK : LEN_POSITION_HOST)) & 0xFF; + } + static uint8_t getFrameSenderAddr(uint32_t frameWord, ByteOrder byteOrder = ByteOrder::HOST) { + return (frameWord >> (byteOrder == ByteOrder::NETWORK ? SENDER_ADDR_POSITION_NETWORK : SENDER_ADDR_POSITION_HOST)) & 0xFF; + } + static uint8_t getFrameRecipientAddr(uint32_t frameWord, ByteOrder byteOrder = ByteOrder::HOST) { + return (frameWord >> (byteOrder == ByteOrder::NETWORK ? RECIPIENT_ADDR_POSITION_NETWORK : RECIPIENT_ADDR_POSITION_HOST)) & 0xFF; + } + static uint8_t getFrameCommand(uint32_t frameWord, ByteOrder byteOrder = ByteOrder::HOST) { + return (frameWord >> (byteOrder == ByteOrder::NETWORK ? COMMAND_POSITION_NETWORK : COMMAND_POSITION_HOST)) & 0xFF; + } + + void setFromFrameWord(uint32_t frameWord, ByteOrder byteOrder = ByteOrder::HOST) { + length = getFramePacketLength(frameWord, byteOrder); + senderAddr = getFrameSenderAddr(frameWord, byteOrder); + recipientAddr = getFrameRecipientAddr(frameWord, byteOrder); + command = getFrameCommand(frameWord, byteOrder); + } + + uint32_t toWord(ByteOrder byteOrder = ByteOrder::HOST) const { + if (byteOrder == ByteOrder::NETWORK) + return (uint32_t)length << LEN_POSITION_NETWORK | + (uint32_t)senderAddr << SENDER_ADDR_POSITION_NETWORK | + (uint32_t)recipientAddr << RECIPIENT_ADDR_POSITION_NETWORK | + (uint32_t)command << COMMAND_POSITION_NETWORK; + return (uint32_t)length << LEN_POSITION_HOST | + (uint32_t)senderAddr << SENDER_ADDR_POSITION_HOST | + (uint32_t)recipientAddr << RECIPIENT_ADDR_POSITION_HOST | + (uint32_t)command << COMMAND_POSITION_HOST; + } + + bool isValid() const { return command != COMMAND_INVALID; } + }; + + Frame frame; + static constexpr unsigned MAX_PAYLOAD = 32; + uint32_t payload[MAX_PAYLOAD]; + unsigned payloadCount; + ByteOrder payloadByteOrder; + + MaplePacket() : frame{}, payload{}, payloadCount(0), payloadByteOrder(ByteOrder::HOST) { + frame.command = COMMAND_INVALID; + } + + void setFrame(uint8_t cmd, uint8_t recipient, uint8_t sender, uint8_t len) { + frame.command = cmd; + frame.recipientAddr = recipient; + frame.senderAddr = sender; + frame.length = len; + payloadCount = len; + } + + uint32_t getFrameWord() const { + Frame f = frame; + f.length = (uint8_t)payloadCount; + return f.toWord(payloadByteOrder); + } + + static uint32_t getNumTotalBits(uint32_t numPayloadWords) { + return ((numPayloadWords + 1) * 4 + 1) * 8; + } + uint32_t getNumTotalBits() const { return getNumTotalBits((uint32_t)payloadCount); } + + static uint32_t getTxTimeNs(uint32_t numPayloadWords, uint32_t nsPerBit) { + return (getNumTotalBits(numPayloadWords) + 14) * nsPerBit; + } + uint32_t getTxTimeNs() const { return getTxTimeNs((uint32_t)payloadCount, MAPLE_NS_PER_BIT); } + + static uint32_t flipWordBytes(uint32_t word) { + return (word << 24) | ((word << 8) & 0xFF0000) | ((word >> 8) & 0xFF00) | (word >> 24); + } + + bool isValid() const { return frame.isValid() && frame.length == payloadCount; } +}; diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/PioProgram.hpp b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/PioProgram.hpp new file mode 100644 index 00000000..d0d208fa --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/PioProgram.hpp @@ -0,0 +1,15 @@ +/* PIO program holder. Ported from DreamPicoPort. */ + +#pragma once + +#include "hardware/pio.h" + +class PioProgram { +public: + PioProgram(pio_hw_t* pio, const pio_program_t* program) + : mPio(pio), mProgram(program), mProgramOffset(pio_add_program(pio, program)) {} + + pio_hw_t* const mPio; + const pio_program_t* const mProgram; + const uint mProgramOffset; +}; diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_constants.h b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_constants.h new file mode 100644 index 00000000..2b39a99b --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_constants.h @@ -0,0 +1,35 @@ +/* Dreamcast Maple Bus commands. Ported from DreamPicoPort. */ + +#pragma once + +#include + +#define DEVICE_FN_CONTROLLER 0x00000001 + +enum DreamcastCommand : uint8_t { + COMMAND_DEVICE_INFO_REQUEST = 0x01, + COMMAND_EXT_DEVICE_INFO_REQUEST = 0x02, + COMMAND_RESET = 0x03, + COMMAND_SHUTDOWN = 0x04, + COMMAND_RESPONSE_DEVICE_INFO = 0x05, + COMMAND_RESPONSE_EXT_DEVICE_INFO = 0x06, + COMMAND_RESPONSE_ACK = 0x07, + COMMAND_RESPONSE_DATA_XFER = 0x08, + COMMAND_GET_CONDITION = 0x09, + COMMAND_GET_MEMORY_INFORMATION = 0x0A, + COMMAND_BLOCK_READ = 0x0B, + COMMAND_BLOCK_WRITE = 0x0C, + COMMAND_GET_LAST_ERROR = 0x0D, + COMMAND_SET_CONDITION = 0x0E, + COMMAND_RESPONSE_AR_ERROR = 0xF9, + COMMAND_RESPONSE_LCD_ERROR = 0xFA, + COMMAND_RESPONSE_FILE_ERROR = 0xFB, + COMMAND_RESPONSE_REQUEST_RESEND = 0xFC, + COMMAND_RESPONSE_UNKNOWN_COMMAND = 0xFD, + COMMAND_RESPONSE_FUNCTION_CODE_NOT_SUPPORTED = 0xFE, + COMMAND_INVALID = 0xFF +}; + +/* Host (console) address; controller is typically 0 on port A */ +#define MAPLE_HOST_ADDR 0x20 +#define MAPLE_CTRL_ADDR 0x00 diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_structures.h b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_structures.h new file mode 100644 index 00000000..b9e317e4 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/dreamcast_structures.h @@ -0,0 +1,40 @@ +/* Dreamcast controller structures. Ported from DreamPicoPort (OrangeFox86). + * https://github.com/OrangeFox86/DreamPicoPort */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 8-byte controller condition (little endian). 0 = pressed for buttons. */ +typedef struct controller_condition_s { + uint8_t l; /* 0 released .. 255 pressed */ + uint8_t r; + unsigned z : 1; + unsigned y : 1; + unsigned x : 1; + unsigned d : 1; + unsigned upb : 1; + unsigned downb : 1; + unsigned leftb : 1; + unsigned rightb : 1; + unsigned c : 1; + unsigned b : 1; + unsigned a : 1; + unsigned start : 1; + unsigned up : 1; + unsigned down : 1; + unsigned left : 1; + unsigned right : 1; + uint8_t rAnalogUD; /* 0 up, 128 neutral, 255 down */ + uint8_t rAnalogLR; + uint8_t lAnalogUD; + uint8_t lAnalogLR; +} __attribute__((packed)) controller_condition_t; + +#ifdef __cplusplus +} +#endif diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_config.h b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_config.h new file mode 100644 index 00000000..a37ad85b --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_config.h @@ -0,0 +1,28 @@ +/* Maple Bus timing and pin config. Adapted from DreamPicoPort configuration.h */ + +#pragma once + +#ifndef MAPLE_OPEN_LINE_CHECK_TIME_US +#define MAPLE_OPEN_LINE_CHECK_TIME_US 10 +#endif + +#ifndef MAPLE_NS_PER_BIT +#define MAPLE_NS_PER_BIT 480 +#endif + +#ifndef MAPLE_WRITE_TIMEOUT_EXTRA_PERCENT +#define MAPLE_WRITE_TIMEOUT_EXTRA_PERCENT 20 +#endif + +#ifndef MAPLE_RESPONSE_TIMEOUT_US +#define MAPLE_RESPONSE_TIMEOUT_US 1000 +#endif + +#ifndef MAPLE_INTER_WORD_READ_TIMEOUT_US +#define MAPLE_INTER_WORD_READ_TIMEOUT_US 300 +#endif + +/* CPU frequency in kHz (RP2040 default 125000) */ +#ifndef MAPLE_CPU_FREQ_KHZ +#define MAPLE_CPU_FREQ_KHZ 125000 +#endif diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_in.pio b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_in.pio new file mode 100644 index 00000000..a24d51c0 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_in.pio @@ -0,0 +1,54 @@ +; Maple Bus input (read). Ported from DreamPicoPort (OrangeFox86). +; Waits for start sequence, samples data bits (A=clock, B=data), detects end. + +.program maple_in + +wait_start: +mov y, ~NULL +b_toggle_loop: +jmp pin check_toggle_count +mov osr, pins +out x 2 +jmp x-- b_toggle_loop +wait 1 pin 1 +jmp pin wait_start +jmp y-- b_toggle_loop + +check_toggle_count: +mov y, ~y +set x, 4 +jmp x!=y wait_start + +data_start: +irq set 0 rel +wait 0 pin 0 + +.wrap_target +data_loop: +set y, 1 +end_detect_b_toggle: +mov osr, pins +out x 1 +jmp !x sample_b_from_osr +out x 1 +jmp !y end_detect_b_to_low +end_detect_b_to_high: +jmp !x end_detect_b_toggle +jmp y-- end_detect_b_toggle +end_detect_b_to_low: +jmp x-- end_detect_b_toggle + +end_detected: +in null 24 +irq wait 0 rel + +sample_b_from_osr: +in osr 1 + +sample_a: +wait 1 pin 1 +wait 0 pin 1 +in pins 1 +wait 1 pin 0 + +.wrap diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_out.pio b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_out.pio new file mode 100644 index 00000000..faea5d3f --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_out.pio @@ -0,0 +1,64 @@ +; Maple Bus output (write). Ported from DreamPicoPort (OrangeFox86). +; First word = number of bits to send; then frame + payload + CRC. + +.program maple_out +.side_set 2 opt + +.define public MASK_A 0x1 +.define public MASK_B 0x2 +.define public MASK_AB 0x3 +.define public DOUBLE_PHASE_TICKS 4 +.define public SINGLE_PHASE_TICKS 2 + +maple_out_start: +out x, 32 side MASK_AB + +start_sequence: +set pindirs MASK_AB side MASK_AB [DOUBLE_PHASE_TICKS - 1] +set y, 3 side MASK_B [DOUBLE_PHASE_TICKS - 1] +start_b_toggle_loop: +nop side 0 [DOUBLE_PHASE_TICKS - 1] +nop side MASK_B [DOUBLE_PHASE_TICKS - 2] +jmp y-- start_b_toggle_loop +jmp x--, first_clock_a_data_b side MASK_AB + +first_clock_a_data_b: +out y, 1 side MASK_AB +jmp !y, clock_a_data_b_zero side MASK_AB +jmp first_clock_a_data_b_one side MASK_AB + +clock_a_data_b: +out y, 1 side MASK_A [SINGLE_PHASE_TICKS - 2] +jmp !y clock_a_data_b_zero +clock_a_data_b_one: +nop side MASK_AB [SINGLE_PHASE_TICKS - 1] +first_clock_a_data_b_one: +jmp x-- clock_b_data_a side MASK_B [SINGLE_PHASE_TICKS - 1] + +clock_a_data_b_zero: +nop side MASK_A [SINGLE_PHASE_TICKS - 1] +jmp x-- clock_b_data_a side 0 [SINGLE_PHASE_TICKS - 1] + +clock_b_data_a: +out y, 1 side MASK_B [SINGLE_PHASE_TICKS - 2] +jmp !y clock_b_data_a_zero +clock_b_data_a_one: +nop side MASK_AB [SINGLE_PHASE_TICKS - 1] +jmp x-- clock_a_data_b side MASK_A [SINGLE_PHASE_TICKS - 1] + +.wrap + +clock_b_data_a_zero: +nop side MASK_B [SINGLE_PHASE_TICKS - 1] +jmp x-- clock_a_data_b side 0 [SINGLE_PHASE_TICKS - 1] + +.wrap_target + +end_sequence: +out y, 24 side MASK_A [SINGLE_PHASE_TICKS - 1] +nop side MASK_AB [DOUBLE_PHASE_TICKS - 1] +nop side MASK_A [DOUBLE_PHASE_TICKS - 1] +nop side 0 [DOUBLE_PHASE_TICKS - 1] +nop side MASK_A [DOUBLE_PHASE_TICKS - 1] +nop side 0 [DOUBLE_PHASE_TICKS - 1] +irq wait 0 rel side MASK_A diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_utils.h b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_utils.h new file mode 100644 index 00000000..9d8dad61 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/dreamcast_host/maple_utils.h @@ -0,0 +1,3 @@ +#pragma once + +#define MAPLE_INT_DIVIDE_CEILING(x, y) (((x) + (y) - 1) / (y)) diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/controller.pio b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/controller.pio new file mode 100644 index 00000000..23f35b49 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/controller.pio @@ -0,0 +1,59 @@ +; JoyBus host (read GameCube controller). Ported from PicoGamepadConverter (Loc15). +; Single pin: output to send, input to receive. + +.program controller +.side_set 1 opt pindirs +.define public T1 4 +.define public T2 12 + +.wrap_target + out y, 5 side 0 ; load # of bytes expected in response +sendData: + out x, 1 side 0 [T1 - 1]; send data bit by bit + jmp !x do_zero side 1 [T1 - 1] ; set 0 for 4 cycles +do_one: + jmp !OSRE sendData side 0 [T1 * 2 - 1] ; set 1 for 10 cycles + jmp sendStop [T1 - 1] +do_zero: + jmp !OSRE sendData [T1 * 2 - 1]; set 1 + jmp sendStop side 0 [T1 - 1] +sendStop: + nop side 1 [T1 - 1] ; send the stop bit (1) + nop side 0 + +receiveByte: + set x, 7 +getBit: + wait 0 pin 0 [T1 + 1]; wait until the line goes low + in pins 1 ; read + wait 1 pin 0 ; wait for a 1 if it's a 0 + jmp x-- getBit ; get the next bit + jmp y-- receiveByte ; get the next byte + +.wrap + + +% c-sdk { +#include "hardware/clocks.h" +#include "hardware/pio.h" + +static inline void controller_program_init(PIO pio, uint sm, uint offset, uint pin_controller, pio_sm_config *c) { + pio_sm_set_consecutive_pindirs(pio, sm, pin_controller, 1, false); + pio_gpio_init(pio, pin_controller); + + sm_config_set_in_pins(c, pin_controller); + sm_config_set_sideset_pins(c, pin_controller); + sm_config_set_jmp_pin(c, pin_controller); + sm_config_set_out_shift(c, false, true, 13); + sm_config_set_in_shift(c, false, true, 8); + + int cyclesPerBit = (controller_T1 + controller_T2) / 4; + float frequency = 1000000; + float clockDiv = clock_get_hz(clk_sys) / (cyclesPerBit * frequency); + sm_config_set_clkdiv(c, clockDiv); + + pio_sm_init(pio, sm, offset, c); + pio_sm_set_enabled(pio, sm, true); +} + +%} diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.c b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.c new file mode 100644 index 00000000..9508ad69 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.c @@ -0,0 +1,62 @@ +/* JoyBus host (read GameCube controller). Ported from PicoGamepadConverter (Loc15). */ + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "controller.pio.h" + +#define JOYBUS_STATE_BYTES 8 + +static PIO joybus_pio; +static uint joybus_sm; +static pio_sm_config joybus_config; +static uint joybus_offset; +static uint8_t controller_state[JOYBUS_STATE_BYTES]; + +static void update_pio_output_size(uint8_t auto_pull_length) +{ + pio_sm_set_enabled(joybus_pio, joybus_sm, false); + joybus_pio->sm[joybus_sm].shiftctrl = (joybus_pio->sm[joybus_sm].shiftctrl & 0xA00FFFFF) | + (0x8u << 20) | + (((auto_pull_length + 5) & 0x1Fu) << 25); + joybus_pio->ctrl |= 1u << (4 + joybus_sm); + pio_sm_set_enabled(joybus_pio, joybus_sm, true); +} + +void joybus_host_init(uint pio_index, uint pin) +{ + joybus_pio = pio_index ? pio1 : pio0; + joybus_offset = pio_add_program(joybus_pio, &controller_program); + joybus_sm = pio_claim_unused_sm(joybus_pio, true); + joybus_config = controller_program_get_default_config(joybus_offset); + controller_program_init(joybus_pio, joybus_sm, joybus_offset, pin, &joybus_config); + update_pio_output_size(2); /* first transfer is poll: 2 bytes request */ +} + +void joybus_send_data(const uint8_t *request, uint8_t data_length, uint8_t response_length) +{ + uint32_t data_with_response_length = ((response_length - 1) & 0x1Fu) << 27; + for (int i = 0; i < data_length; i++) + { + data_with_response_length |= (uint32_t)request[i] << (19 - i * 8); + } + pio_sm_put_blocking(joybus_pio, joybus_sm, data_with_response_length); + + int16_t remaining = (int16_t)response_length; + while (remaining > 0) + { + absolute_time_t timeout = make_timeout_time_us(600); + while (pio_sm_is_rx_fifo_empty(joybus_pio, joybus_sm) && !time_reached(timeout)) + { + } + uint32_t data = pio_sm_get(joybus_pio, joybus_sm); + controller_state[response_length - remaining] = (uint8_t)(data & 0xFFu); + remaining--; + } + /* Next transfer will send data_length bytes (e.g. 2 for poll). */ + update_pio_output_size(data_length); +} + +const uint8_t* joybus_get_response(void) +{ + return controller_state; +} diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.h b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.h new file mode 100644 index 00000000..5acf394e --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/joybus_controller.h @@ -0,0 +1,24 @@ +#ifndef USBHOST_GPIOHOST_JOYBUS_JOYBUS_CONTROLLER_H_ +#define USBHOST_GPIOHOST_JOYBUS_JOYBUS_CONTROLLER_H_ + +#include "hardware/pio.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Initialize JoyBus host (GameCube controller). pio_index 0 or 1, pin = data line. */ +void joybus_host_init(uint pio_index, uint pin); + +/** Send request and read response. request/response lengths in bytes. Response written to internal buffer. */ +void joybus_send_data(const uint8_t *request, uint8_t data_length, uint8_t response_length); + +/** Get pointer to last response buffer (8 bytes for GameCube). Valid until next joybus_send_data. */ +const uint8_t* joybus_get_response(void); + +#ifdef __cplusplus +} +#endif + +#endif /* USBHOST_GPIOHOST_JOYBUS_JOYBUS_CONTROLLER_H_ */ diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.c b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.c new file mode 100644 index 00000000..201a73a7 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.c @@ -0,0 +1,73 @@ +/* N64 controller host (1-wire). Ported from PicoGamepadConverter (Loc15) / joybus_host. */ + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "controller.pio.h" + +#define N64_RESPONSE_BYTES 4 + +static PIO n64_pio; +static uint n64_sm; +static pio_sm_config n64_config; +static uint n64_offset; +static uint8_t n64_state[N64_RESPONSE_BYTES]; + +static void n64_update_pio_output_size(uint8_t auto_pull_length) +{ + pio_sm_set_enabled(n64_pio, n64_sm, false); + n64_pio->sm[n64_sm].shiftctrl = (n64_pio->sm[n64_sm].shiftctrl & 0xA00FFFFF) | + (0x8u << 20) | + (((auto_pull_length + 5) & 0x1Fu) << 25); + n64_pio->ctrl |= 1u << (4 + n64_sm); + pio_sm_set_enabled(n64_pio, n64_sm, true); +} + +static void n64_send_data(const uint8_t *request, uint8_t data_length, uint8_t response_length) +{ + uint32_t data_with_response_length = ((response_length - 1) & 0x1Fu) << 27; + for (int i = 0; i < data_length; i++) + { + data_with_response_length |= (uint32_t)request[i] << (19 - i * 8); + } + pio_sm_put_blocking(n64_pio, n64_sm, data_with_response_length); + + int16_t remaining = (int16_t)response_length; + while (remaining > 0) + { + absolute_time_t timeout = make_timeout_time_us(600); + while (pio_sm_is_rx_fifo_empty(n64_pio, n64_sm) && !time_reached(timeout)) + { + } + uint32_t data = pio_sm_get(n64_pio, n64_sm); + n64_state[response_length - remaining] = (uint8_t)(data & 0xFFu); + remaining--; + } + n64_update_pio_output_size(data_length); +} + +void n64_host_init(uint pio_index, uint data_pin) +{ + n64_pio = pio_index ? pio1 : pio0; + n64_offset = pio_add_program(n64_pio, &controller_program); + n64_sm = pio_claim_unused_sm(n64_pio, true); + n64_config = controller_program_get_default_config(n64_offset); + controller_program_init(n64_pio, n64_sm, n64_offset, data_pin, &n64_config); + n64_update_pio_output_size(1); + + /* N64 init: send 0x00, expect 1 byte (identify). */ + const uint8_t init_cmd[] = { 0x00 }; + n64_send_data(init_cmd, 1, 1); + sleep_us(200); +} + +void n64_host_poll(void) +{ + const uint8_t poll_cmd[] = { 0x01 }; + n64_send_data(poll_cmd, 1, N64_RESPONSE_BYTES); + busy_wait_us(500); +} + +const uint8_t* n64_host_get_response(void) +{ + return n64_state; +} diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.h b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.h new file mode 100644 index 00000000..8dd78131 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/joybus_host/n64_host.h @@ -0,0 +1,23 @@ +#ifndef USBHOST_GPIOHOST_JOYBUS_N64_HOST_H_ +#define USBHOST_GPIOHOST_JOYBUS_N64_HOST_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Initialize N64 controller host (1-wire, same protocol as PicoGamepadConverter). Uses same controller.pio as JoyBus. */ +void n64_host_init(uint pio_index, uint data_pin); + +/** Poll N64 controller (sends 0x01, reads 4 bytes). Call from main loop when input source is N64_GPIO. */ +void n64_host_poll(void); + +/** Get pointer to last poll response (4 bytes: buttons1, buttons2, joy_x, joy_y). Valid until next n64_host_poll. */ +const uint8_t* n64_host_get_response(void); + +#ifdef __cplusplus +} +#endif + +#endif /* USBHOST_GPIOHOST_JOYBUS_N64_HOST_H_ */ diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/clock.pio b/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/clock.pio new file mode 100644 index 00000000..21fada27 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/clock.pio @@ -0,0 +1,40 @@ +; PS1/PS2 controller host (read real controller). Ported from PicoGamepadConverter (Loc15). +; CMD, CLK, ATT are outputs; DATA is input. + +.program clock +.side_set 1 opt +.wrap_target + set y, 2 [7] ; Commands counter -> 3 bytes command + set pins, 0b11 [7] side 1 ; Set ATTENTION, CLK and CMD -> HIGH + pull [7] ; Pull 32 bits data + set pins, 0b01 [2] ; Set ATTENTION -> LOW + +set_counter: + set x, 7 [7] ; 8 bit counter + delay between bytes + +bitloop: + out pins, 1 ; Pull a bit + set pins, 0b00 ; Driver pin low + in pins, 1 ; Read a bit + set pins, 0b01 ; Drive pin high + jmp set_clock ; Jump to set_clock + +set_clock: + jmp x-- bitloop + jmp y-- set_counter + set y, 5 ; Data counter -> 6 bytes data + +set_counter2: + set x, 7 [7] ; 8 bit counter + delay between bytes + +bitloop2: + set pins, 0b00 [1] ; Driver pin low + in pins, 1 ; Read a bit + set pins, 0b01 ; Driver pin high + jmp set_clock2 ; Jump to set_clock + +set_clock2: + jmp x-- bitloop2 + jmp y-- set_counter2 + +.wrap diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.c b/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.c new file mode 100644 index 00000000..96b29ab4 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.c @@ -0,0 +1,95 @@ +/* PS1/PS2 controller host (read real controller). Ported from PicoGamepadConverter (Loc15). + * https://github.com/Loc15/PicoGamepadConverter */ + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/dma.h" +#include "hardware/clocks.h" + +#include "clock.pio.h" + +#define N_BYTES 9 + +static PIO psx_pio; +static uint psx_sm; +static int psx_dma_chan; +static uint32_t data_psx[N_BYTES]; +static const uint32_t cmd = 0x01u | (0x42u << 8); + +static volatile uint8_t psx_host_buffer[N_BYTES]; +static volatile bool psx_host_ready; + +static void __not_in_flash_func(dma_handler)(void) +{ + dma_hw->ints0 = 1u << psx_dma_chan; + dma_channel_set_read_addr(psx_dma_chan, &psx_pio->rxf[psx_sm], false); + dma_channel_set_write_addr(psx_dma_chan, (void *)&data_psx[0], false); + dma_channel_set_trans_count(psx_dma_chan, N_BYTES, false); + dma_channel_start(psx_dma_chan); + + for (int i = 0; i < N_BYTES; i++) + { + psx_host_buffer[i] = (uint8_t)(data_psx[i] & 0xFFu); + } + psx_host_ready = true; + + pio_sm_put_blocking(psx_pio, psx_sm, cmd); +} + +void psx_host_init(uint pio_index, uint gpio_output, uint gpio_input) +{ + psx_pio = pio_index ? pio1 : pio0; + psx_host_ready = false; + + uint offset = pio_add_program(psx_pio, &clock_program); + psx_sm = pio_claim_unused_sm(psx_pio, true); + pio_sm_config c = clock_program_get_default_config(offset); + sm_config_set_set_pins(&c, gpio_output + 1, 2); + sm_config_set_out_pins(&c, gpio_output, 1); + sm_config_set_sideset_pins(&c, gpio_output); + sm_config_set_in_pins(&c, gpio_input); + sm_config_set_in_shift(&c, true, true, 8); + pio_gpio_init(psx_pio, gpio_output); + pio_gpio_init(psx_pio, gpio_output + 1); + pio_gpio_init(psx_pio, gpio_output + 2); + pio_gpio_init(psx_pio, gpio_input); + gpio_pull_up(gpio_input); + gpio_pull_up(gpio_output + 1); + gpio_pull_up(gpio_output + 2); + pio_sm_set_consecutive_pindirs(psx_pio, psx_sm, gpio_output, 3, true); + pio_sm_set_consecutive_pindirs(psx_pio, psx_sm, gpio_input, 1, false); + float div = (float)clock_get_hz(clk_sys) / (6.0f * 12500.0f); + sm_config_set_clkdiv(&c, div); + pio_sm_init(psx_pio, psx_sm, offset, &c); + pio_sm_set_enabled(psx_pio, psx_sm, true); + + psx_dma_chan = dma_claim_unused_channel(true); + dma_channel_config c_dma = dma_channel_get_default_config(psx_dma_chan); + channel_config_set_transfer_data_size(&c_dma, DMA_SIZE_32); + channel_config_set_read_increment(&c_dma, false); + channel_config_set_write_increment(&c_dma, true); + channel_config_set_dreq(&c_dma, pio_get_dreq(psx_pio, psx_sm, false)); + dma_channel_configure(psx_dma_chan, &c_dma, + (void *)&data_psx[0], + &psx_pio->rxf[psx_sm], + N_BYTES, + false); + dma_channel_set_irq0_enabled(psx_dma_chan, true); + irq_set_exclusive_handler(DMA_IRQ_0, dma_handler); + irq_set_enabled(DMA_IRQ_0, true); + dma_handler(); +} + +bool psx_host_take_data(uint8_t *out) +{ + if (!psx_host_ready) + { + return false; + } + for (int i = 0; i < N_BYTES; i++) + { + out[i] = psx_host_buffer[i]; + } + psx_host_ready = false; + return true; +} diff --git a/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.h b/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.h new file mode 100644 index 00000000..524f9476 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/GPIOHost/psx_host/psx_host.h @@ -0,0 +1,21 @@ +#ifndef USBHOST_GPIOHOST_PSX_HOST_PSX_HOST_H_ +#define USBHOST_GPIOHOST_PSX_HOST_PSX_HOST_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Initialize PSX controller host. gpio_output = CMD pin (CLK=gpio_output+1, ATT=gpio_output+2); gpio_input = DATA. */ +void psx_host_init(uint pio_index, uint gpio_output, uint gpio_input); + +/** Copy latest 9-byte report if available and clear ready. Returns true if data was copied. */ +bool psx_host_take_data(uint8_t *out); + +#ifdef __cplusplus +} +#endif + +#endif /* USBHOST_GPIOHOST_PSX_HOST_PSX_HOST_H_ */ diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp index 8b8b39d8..05c58d22 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp @@ -21,6 +21,7 @@ void PS4Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance in_report_.buttons[2] &= PS4::COUNTER_MASK; if (std::memcmp(reinterpret_cast(report), &prev_in_report_, sizeof(PS4::InReport)) == 0) { + tuh_hid_receive_report(address, instance); return; } diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index 7a04fd62..87783e83 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -10,6 +10,8 @@ #include "Board/Config.h" #include "Board/ogxm_log.h" +#include "UserSettings/UserSettings.h" +#include "USBDevice/DeviceDriver/DeviceDriverTypes.h" #include "USBHost/HardwareIDs.h" #if defined(CONFIG_OGXM_DEBUG) @@ -328,19 +330,35 @@ class HostManager inline uint8_t find_free_gamepad() { - uint8_t count = 0; - + bool used[MAX_GAMEPADS] = {false}; + UserSettings& us = UserSettings::get_instance(); + DeviceDriverType dr = us.get_current_driver(); + HostInputSource src = us.get_input_source(); + if ((dr == DeviceDriverType::PS1PS2 && src == HostInputSource::PSX_GPIO) || + (dr == DeviceDriverType::GAMECUBE && src == HostInputSource::GAMECUBE_GPIO) || + (dr == DeviceDriverType::DREAMCAST && src == HostInputSource::DREAMCAST_GPIO) || + (src == HostInputSource::N64_GPIO)) + { + used[0] = true; + } for (auto& device_slot : device_slots_) { for (auto& interface : device_slot.interfaces) { if (interface.gamepad_idx != INVALID_IDX) { - ++count; + used[interface.gamepad_idx] = true; } } } - return (count < MAX_GAMEPADS) ? count : INVALID_IDX; + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) + { + if (!used[i]) + { + return i; + } + } + return INVALID_IDX; } inline uint8_t get_device_slot(uint8_t address) diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.cpp b/Firmware/RP2040/src/UserSettings/UserSettings.cpp index 84f1fcb1..259367b6 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/UserSettings.cpp @@ -24,6 +24,10 @@ namespace ButtonCombo { static constexpr uint32_t XBOXOG_SB = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_RB, Gamepad::DPAD_RIGHT); static constexpr uint32_t XBOXOG_XR = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB, Gamepad::DPAD_RIGHT); static constexpr uint32_t PSCLASSIC = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_A); + static constexpr uint32_t PS1PS2 = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_B); + static constexpr uint32_t GAMECUBE = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_X); + static constexpr uint32_t DREAMCAST = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_Y); + static constexpr uint32_t N64 = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_RB); static constexpr uint32_t WEBAPP = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB | Gamepad::BUTTON_RB); // WII is build-option only (OGXM_FIXED_DRIVER=WII), not in combo map }; @@ -58,7 +62,11 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::WII, DeviceDriverType::WEBAPP, DeviceDriverType::PS3, - DeviceDriverType::PSCLASSIC, + DeviceDriverType::PSCLASSIC, + DeviceDriverType::PS1PS2, + DeviceDriverType::GAMECUBE, + DeviceDriverType::DREAMCAST, + DeviceDriverType::N64, DeviceDriverType::XINPUT, #if defined(XREMOTE_ROM_AVAILABLE) DeviceDriverType::XBOXOG_XR, @@ -72,7 +80,7 @@ struct ComboMap { DeviceDriverType driver; }; -static constexpr std::array BUTTON_COMBO_MAP = {{ +static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::XBOXOG, DeviceDriverType::XBOXOG }, { ButtonCombo::XBOXOG_SB, DeviceDriverType::XBOXOG_SB }, { ButtonCombo::XBOXOG_XR, DeviceDriverType::XBOXOG_XR }, @@ -82,7 +90,11 @@ static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::WIIU, DeviceDriverType::WIIU }, { ButtonCombo::XINPUT, DeviceDriverType::XINPUT }, { ButtonCombo::PS3, DeviceDriverType::PS3 }, - { ButtonCombo::PSCLASSIC, DeviceDriverType::PSCLASSIC } + { ButtonCombo::PSCLASSIC, DeviceDriverType::PSCLASSIC }, + { ButtonCombo::PS1PS2, DeviceDriverType::PS1PS2 }, + { ButtonCombo::GAMECUBE, DeviceDriverType::GAMECUBE }, + { ButtonCombo::DREAMCAST, DeviceDriverType::DREAMCAST }, + { ButtonCombo::N64, DeviceDriverType::N64 } }}; const std::string UserSettings::INIT_FLAG_KEY() @@ -105,6 +117,11 @@ const std::string UserSettings::DRIVER_TYPE_KEY() return std::string("driver_type"); } +const std::string UserSettings::INPUT_SOURCE_KEY() +{ + return std::string("input_source"); +} + const std::string UserSettings::DATETIME_KEY() { return std::string("datetime"); @@ -372,6 +389,91 @@ DeviceDriverType UserSettings::get_current_driver() #endif // !(CONFIG_OGXM_FIXED_DRIVER && !CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) } +HostInputSource UserSettings::get_input_source() +{ + if (!input_source_loaded_) + { + uint8_t stored = 0; + if (nvs_tool_.read(INPUT_SOURCE_KEY(), &stored, sizeof(uint8_t)) && stored <= 3) + { + current_input_source_ = static_cast(stored); + } + input_source_loaded_ = true; + } + return current_input_source_; +} + +void UserSettings::store_input_source(HostInputSource source) +{ + uint8_t v = static_cast(source); + nvs_tool_.write(INPUT_SOURCE_KEY(), &v, sizeof(uint8_t)); + current_input_source_ = source; + input_source_loaded_ = true; +} + +static constexpr uint32_t INPUT_SOURCE_COMBO = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_BACK, 0); +static constexpr unsigned INPUT_SOURCE_CHECK_COUNT = 2500 / 600; /* 2.5s hold to cycle input source */ + +bool UserSettings::check_for_input_source_change(Gamepad& gamepad) +{ + Gamepad::PadIn gp = gamepad.get_pad_in(); + uint32_t combo = BUTTON_COMBO(gp.buttons, gp.dpad); + static uint32_t last_combo = 0; + static uint8_t hold_count = 0; + + if (combo != INPUT_SOURCE_COMBO) + { + last_combo = combo; + hold_count = 0; + return false; + } + if (last_combo != INPUT_SOURCE_COMBO) + { + hold_count = 0; + } + last_combo = INPUT_SOURCE_COMBO; + ++hold_count; + if (hold_count < INPUT_SOURCE_CHECK_COUNT) + { + return false; + } + hold_count = 0; + DeviceDriverType dr = get_current_driver(); + HostInputSource cur = get_input_source(); + HostInputSource next = HostInputSource::USB; + if (dr == DeviceDriverType::PS1PS2) + { + next = (cur == HostInputSource::USB) ? HostInputSource::PSX_GPIO : HostInputSource::USB; + } + else if (dr == DeviceDriverType::GAMECUBE) + { + next = (cur == HostInputSource::USB) ? HostInputSource::GAMECUBE_GPIO : HostInputSource::USB; + } + else if (dr == DeviceDriverType::DREAMCAST) + { + next = (cur == HostInputSource::USB) ? HostInputSource::DREAMCAST_GPIO : HostInputSource::USB; + } + else + { + /* Any other output (Switch, DInput, Xbox, etc.): cycle USB -> PSX_GPIO -> GAMECUBE_GPIO -> DREAMCAST_GPIO -> N64_GPIO -> USB */ + if (cur == HostInputSource::USB) + next = HostInputSource::PSX_GPIO; + else if (cur == HostInputSource::PSX_GPIO) + next = HostInputSource::GAMECUBE_GPIO; + else if (cur == HostInputSource::GAMECUBE_GPIO) + next = HostInputSource::DREAMCAST_GPIO; + else if (cur == HostInputSource::DREAMCAST_GPIO) + next = HostInputSource::N64_GPIO; + else if (cur == HostInputSource::N64_GPIO) + next = HostInputSource::USB; + else + next = HostInputSource::USB; + } + store_input_source(next); + OGXM_LOG("Input source changed to " + std::to_string(static_cast(next)) + "\n"); + return true; +} + void UserSettings::write_datetime() { nvs_tool_.write(DATETIME_KEY(), DATETIME_TAG.c_str(), DATETIME_TAG.size() + 1); @@ -411,6 +513,9 @@ void UserSettings::initialize_flash() uint8_t device_mode_buffer = static_cast(DEFAULT_DRIVER()); nvs_tool_.write(DRIVER_TYPE_KEY(), &device_mode_buffer, sizeof(uint8_t)); + uint8_t input_source_buffer = static_cast(HostInputSource::USB); + nvs_tool_.write(INPUT_SOURCE_KEY(), &input_source_buffer, sizeof(uint8_t)); + OGXM_LOG("Writing default profile ids\n"); for (uint8_t i = 0; i < MAX_GAMEPADS; i++) diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.h b/Firmware/RP2040/src/UserSettings/UserSettings.h index 0fc75386..fce3cbdd 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.h +++ b/Firmware/RP2040/src/UserSettings/UserSettings.h @@ -10,6 +10,16 @@ #include "UserSettings/NVSTool.h" #include "Gamepad/Gamepad.h" +/** Input source for gamepad 0: USB/BT (default) or GPIO (PS1/PS2, GameCube, or Dreamcast controller). */ +enum class HostInputSource : uint8_t +{ + USB = 0, + PSX_GPIO = 1, + GAMECUBE_GPIO = 2, + DREAMCAST_GPIO = 3, + N64_GPIO = 4 +}; + /* Only write/store flash from Core0 */ class UserSettings { @@ -31,6 +41,11 @@ class UserSettings DeviceDriverType get_current_driver(); bool check_for_driver_change(Gamepad& gamepad); + + HostInputSource get_input_source(); + void store_input_source(HostInputSource source); + /** When driver is PS1PS2 or GAMECUBE, returns true if Start+Select held long enough and cycles input source (stores and returns true). */ + bool check_for_input_source_change(Gamepad& gamepad); UserProfile get_profile_by_index(const uint8_t index); UserProfile get_profile_by_id(const uint8_t profile_id); @@ -62,7 +77,10 @@ class UserSettings const std::string PROFILE_KEY(const uint8_t profile_id); const std::string ACTIVE_PROFILE_KEY(const uint8_t index); const std::string DRIVER_TYPE_KEY(); + const std::string INPUT_SOURCE_KEY(); const std::string DATETIME_KEY(); + HostInputSource current_input_source_{HostInputSource::USB}; + bool input_source_loaded_{false}; }; #endif // _USER_SETTINGS_H_ \ No newline at end of file diff --git a/Firmware/cmake/patch_libs.cmake b/Firmware/cmake/patch_libs.cmake index d991aea0..737a8713 100644 --- a/Firmware/cmake/patch_libs.cmake +++ b/Firmware/cmake/patch_libs.cmake @@ -40,4 +40,5 @@ function(apply_lib_patches EXTERNAL_DIR) else () message(FATAL_ERROR "Failed to apply Bluepad32 patch: ${BLUEPAD32_PATCH_ERROR}") endif () + endfunction() \ No newline at end of file diff --git a/Firmware/external/patches/bluepad32_ps4_ps5_latency.diff b/Firmware/external/patches/bluepad32_ps4_ps5_latency.diff new file mode 100644 index 00000000..74357105 --- /dev/null +++ b/Firmware/external/patches/bluepad32_ps4_ps5_latency.diff @@ -0,0 +1,176 @@ +diff --git a/src/components/bluepad32/parser/uni_hid_parser_ds4.c b/src/components/bluepad32/parser/uni_hid_parser_ds4.c +index e2622a2..147d13e 100644 +--- a/src/components/bluepad32/parser/uni_hid_parser_ds4.c ++++ b/src/components/bluepad32/parser/uni_hid_parser_ds4.c +@@ -425,6 +425,43 @@ static void ds4_parse_input_report_01(uni_hid_device_t* d, const ds4_input_repor + ctl->gamepad.throttle = r->throttle * 4; + } + ++/* Parse only gamepad from first 9 bytes of payload when report is short. Ensures we never drop a report (like Xbox One): every packet delivers at least gamepad state. */ ++static void ds4_parse_input_report_11_minimal(uni_hid_device_t* d, const uint8_t* report, uint16_t len) { ++ uni_controller_t* ctl = &d->controller; ++ if (len < 3 + 9) ++ return; ++ const uint8_t* p = &report[3]; ++ ctl->gamepad.axis_x = (p[0] - 127) * 4; ++ ctl->gamepad.axis_y = (p[1] - 127) * 4; ++ ctl->gamepad.axis_rx = (p[2] - 127) * 4; ++ ctl->gamepad.axis_ry = (p[3] - 127) * 4; ++ uint8_t value = p[4] & 0xf; ++ if (value > 7) ++ value = 0xff; ++ ctl->gamepad.dpad = uni_hid_parser_hat_to_dpad(value); ++ ctl->gamepad.buttons = 0; ++ ctl->gamepad.misc_buttons = 0; ++ if (p[4] & 0x10) ctl->gamepad.buttons |= BUTTON_X; ++ if (p[4] & 0x20) ctl->gamepad.buttons |= BUTTON_A; ++ if (p[4] & 0x40) ctl->gamepad.buttons |= BUTTON_B; ++ if (p[4] & 0x80) ctl->gamepad.buttons |= BUTTON_Y; ++ if (p[5] & 0x01) ctl->gamepad.buttons |= BUTTON_SHOULDER_L; ++ if (p[5] & 0x02) ctl->gamepad.buttons |= BUTTON_SHOULDER_R; ++ if (p[5] & 0x04) ctl->gamepad.buttons |= BUTTON_TRIGGER_L; ++ if (p[5] & 0x08) ctl->gamepad.buttons |= BUTTON_TRIGGER_R; ++ if (p[5] & 0x10) ctl->gamepad.misc_buttons |= MISC_BUTTON_SELECT; ++ if (p[5] & 0x20) ctl->gamepad.misc_buttons |= MISC_BUTTON_START; ++ if (p[5] & 0x40) ctl->gamepad.buttons |= BUTTON_THUMB_L; ++ if (p[5] & 0x80) ctl->gamepad.buttons |= BUTTON_THUMB_R; ++ if (p[6] & 0x01) ctl->gamepad.misc_buttons |= MISC_BUTTON_SYSTEM; ++ ctl->gamepad.brake = p[7] * 4; ++ ctl->gamepad.throttle = p[8] * 4; ++ for (size_t i = 0; i < ARRAY_SIZE(ctl->gamepad.gyro); i++) ++ ctl->gamepad.gyro[i] = 0; ++ for (size_t i = 0; i < ARRAY_SIZE(ctl->gamepad.accel); i++) ++ ctl->gamepad.accel[i] = 0; ++} ++ + static void ds4_parse_input_report_11(uni_hid_device_t* d, const ds4_input_report_11_t* r) { + ds4_instance_t* ins = get_ds4_instance(d); + uni_controller_t* ctl = &d->controller; +@@ -500,9 +537,14 @@ static void ds4_parse_input_report_11(uni_hid_device_t* d, const ds4_input_repor + } + + void uni_hid_parser_ds4_parse_input_report(uni_hid_device_t* d, const uint8_t* report, uint16_t len) { +- if (report[0] == 0x11 && len == 78) { +- const ds4_input_report_11_t* r = (ds4_input_report_11_t*)&report[3]; +- ds4_parse_input_report_11(d, r); ++ if (report[0] == 0x11 && len >= 12) { ++ if (len >= 78) { ++ const ds4_input_report_11_t* r = (ds4_input_report_11_t*)&report[3]; ++ ds4_parse_input_report_11(d, r); ++ } else { ++ /* Short report (e.g. 77 bytes over BT): parse gamepad only so we don't drop packets. */ ++ ds4_parse_input_report_11_minimal(d, report, len); ++ } + } else if (report[0] == 0x01 && len == 10) { + const ds4_input_report_01_t* r = (ds4_input_report_01_t*)&report[1]; + ds4_parse_input_report_01(d, r); +diff --git a/src/components/bluepad32/parser/uni_hid_parser_ds5.c b/src/components/bluepad32/parser/uni_hid_parser_ds5.c +index 9316260..111595e 100644 +--- a/src/components/bluepad32/parser/uni_hid_parser_ds5.c ++++ b/src/components/bluepad32/parser/uni_hid_parser_ds5.c +@@ -554,26 +554,97 @@ void uni_hid_parser_ds5_parse_feature_report(uni_hid_device_t* d, const uint8_t* + } + } + ++/* Parse only gamepad from first 10 bytes of payload when report is short. Ensures we never drop a report (like Xbox One): every packet delivers at least gamepad state. */ ++static void ds5_parse_input_report_minimal(uni_hid_device_t* d, const uint8_t* report, uint16_t len) { ++ uni_controller_t* ctl = &d->controller; ++ if (len < 2 + 10) ++ return; ++ const uint8_t* p = &report[2]; ++ ctl->gamepad.axis_x = (p[0] - 127) * 4; ++ ctl->gamepad.axis_y = (p[1] - 127) * 4; ++ ctl->gamepad.axis_rx = (p[2] - 127) * 4; ++ ctl->gamepad.axis_ry = (p[3] - 127) * 4; ++ ctl->gamepad.brake = p[4] * 4; ++ ctl->gamepad.throttle = p[5] * 4; ++ uint8_t value = p[7] & 0xf; ++ if (value > 7) ++ value = 0xff; ++ ctl->gamepad.dpad = uni_hid_parser_hat_to_dpad(value); ++ ctl->gamepad.buttons = 0; ++ ctl->gamepad.misc_buttons = 0; ++ if (p[7] & 0x10) ctl->gamepad.buttons |= BUTTON_X; ++ if (p[7] & 0x20) ctl->gamepad.buttons |= BUTTON_A; ++ if (p[7] & 0x40) ctl->gamepad.buttons |= BUTTON_B; ++ if (p[7] & 0x80) ctl->gamepad.buttons |= BUTTON_Y; ++ if (p[8] & 0x01) ctl->gamepad.buttons |= BUTTON_SHOULDER_L; ++ if (p[8] & 0x02) ctl->gamepad.buttons |= BUTTON_SHOULDER_R; ++ if (p[8] & 0x04) ctl->gamepad.buttons |= BUTTON_TRIGGER_L; ++ if (p[8] & 0x08) ctl->gamepad.buttons |= BUTTON_TRIGGER_R; ++ if (p[8] & 0x10) ctl->gamepad.misc_buttons |= MISC_BUTTON_SELECT; ++ if (p[8] & 0x20) ctl->gamepad.misc_buttons |= MISC_BUTTON_START; ++ if (p[8] & 0x40) ctl->gamepad.buttons |= BUTTON_THUMB_L; ++ if (p[8] & 0x80) ctl->gamepad.buttons |= BUTTON_THUMB_R; ++ if (p[9] & 0x01) ctl->gamepad.misc_buttons |= MISC_BUTTON_SYSTEM; ++ if (p[9] & 0x04) ctl->gamepad.misc_buttons |= MISC_BUTTON_CAPTURE; ++ for (size_t i = 0; i < ARRAY_SIZE(ctl->gamepad.gyro); i++) ++ ctl->gamepad.gyro[i] = 0; ++ for (size_t i = 0; i < ARRAY_SIZE(ctl->gamepad.accel); i++) ++ ctl->gamepad.accel[i] = 0; ++} ++ + void uni_hid_parser_ds5_parse_input_report(uni_hid_device_t* d, const uint8_t* report, uint16_t len) { + ds5_instance_t* ins = get_ds5_instance(d); +- +- // Don't process reports until state is ready. Prevents possible div-by-0 on calibration +- // and ignores other warnings. +- if (ins->state != DS5_STATE_READY) +- return; ++ uni_controller_t* ctl = &d->controller; + + if (report[0] != 0x31) { + loge("DS5: Unexpected report type: got 0x%02x, want: 0x31\n", report[0]); + return; + } +- if (len != 78) { +- loge("DS5: Unexpected report len: got %d, want: 78\n", len); ++ /* Accept any length that has at least gamepad bytes (2+10=12). Never reject a report and leave state zeroed (like Xbox One). */ ++ if (len < 12) { ++ loge("DS5: Report too short: got %d, need >= 12\n", len); ++ return; ++ } ++ ++ if (len < 76) { ++ ds5_parse_input_report_minimal(d, report, len); + return; + } + +- uni_controller_t* ctl = &d->controller; + const ds5_input_report_t* r = (ds5_input_report_t*)&report[2]; + ++ /* When not READY, still deliver gamepad (no gyro/accel) so input is responsive during calibration. */ ++ if (ins->state != DS5_STATE_READY) { ++ ctl->gamepad.buttons = 0; ++ ctl->gamepad.misc_buttons = 0; ++ ctl->gamepad.axis_x = (r->x - 127) * 4; ++ ctl->gamepad.axis_y = (r->y - 127) * 4; ++ ctl->gamepad.axis_rx = (r->rx - 127) * 4; ++ ctl->gamepad.axis_ry = (r->ry - 127) * 4; ++ ctl->gamepad.brake = r->brake * 4; ++ ctl->gamepad.throttle = r->throttle * 4; ++ uint8_t value = r->buttons[0] & 0xf; ++ if (value > 7) ++ value = 0xff; ++ ctl->gamepad.dpad = uni_hid_parser_hat_to_dpad(value); ++ if (r->buttons[0] & 0x10) ctl->gamepad.buttons |= BUTTON_X; ++ if (r->buttons[0] & 0x20) ctl->gamepad.buttons |= BUTTON_A; ++ if (r->buttons[0] & 0x40) ctl->gamepad.buttons |= BUTTON_B; ++ if (r->buttons[0] & 0x80) ctl->gamepad.buttons |= BUTTON_Y; ++ if (r->buttons[1] & 0x01) ctl->gamepad.buttons |= BUTTON_SHOULDER_L; ++ if (r->buttons[1] & 0x02) ctl->gamepad.buttons |= BUTTON_SHOULDER_R; ++ if (r->buttons[1] & 0x04) ctl->gamepad.buttons |= BUTTON_TRIGGER_L; ++ if (r->buttons[1] & 0x08) ctl->gamepad.buttons |= BUTTON_TRIGGER_R; ++ if (r->buttons[1] & 0x10) ctl->gamepad.misc_buttons |= MISC_BUTTON_SELECT; ++ if (r->buttons[1] & 0x20) ctl->gamepad.misc_buttons |= MISC_BUTTON_START; ++ if (r->buttons[1] & 0x40) ctl->gamepad.buttons |= BUTTON_THUMB_L; ++ if (r->buttons[1] & 0x80) ctl->gamepad.buttons |= BUTTON_THUMB_R; ++ if (r->buttons[2] & 0x01) ctl->gamepad.misc_buttons |= MISC_BUTTON_SYSTEM; ++ if (r->buttons[2] & 0x04) ctl->gamepad.misc_buttons |= MISC_BUTTON_CAPTURE; ++ ctl->battery = (r->status & DS5_STATUS_BATTERY_CAPACITY) * 25 + 1; ++ return; ++ } ++ + // Axis + ctl->gamepad.axis_x = (r->x - 127) * 4; + ctl->gamepad.axis_y = (r->y - 127) * 4; diff --git a/README.md b/README.md index 2787303d..8ef51869 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,12 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles - DInput - Wii U (GameCube Adapter) - **Wii (Wiimote)** — Pico W / Pico 2 W only; build with `-DOGXM_FIXED_DRIVER=WII`. See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). +- **PlayStation 1 & 2** — GPIO output to console controller port (DualShock-style). +- **Dreamcast** — GPIO output over Maple Bus to console controller port. +- **GameCube / Wii (GameCube ports)** — GPIO output over single-wire JoyBus. +- **Nintendo 64** — GPIO output over single-wire to controller port. -**RP2040 output modes (USB device):** XInput (Xbox 360 + XSM3), DInput, PS3, **Switch Pro** (Nintendo Switch Pro Controller emulation), Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. On Pico 2 W, Bluetooth runs on Core1 and USB on Core0; you can build with a fixed mode or use button combos to switch at runtime (Start + D-pad held ~3 s). **Wii is not in the combo list** — use a Wii-only build to get Wiimote output. +**RP2040 output modes:** **USB device:** XInput (Xbox 360 + XSM3), DInput, PS3, **Switch Pro** (Nintendo Switch Pro Controller emulation), Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. **GPIO (no USB device):** PS1/PS2, Dreamcast, GameCube, N64 — use any wired USB or (on Pico W / Pico 2 W) Bluetooth controller as input. On Pico 2 W, Bluetooth runs on Core1 and USB on Core0; you can build with a fixed mode or use button combos to switch at runtime (Start + D-pad held ~3 s). **Wii is not in the combo list** — use a Wii-only build to get Wiimote output. ## Changing platforms By default the OGX-Mini will emulate an OG Xbox controller, you must hold a button combo for 3 seconds to change which platform you want to play on. Your chosen mode will persist after powering off the device. @@ -38,8 +42,16 @@ Start = Plus (Switch) = Options (Dualsense/DS4) - Start + Dpad Left - PlayStation Classic - Start + A (Cross for PlayStation and B for Switch gamepads) +- PlayStation 1 / PlayStation 2 (GPIO output) + - Start + B +- GameCube / Wii GameCube ports (GPIO output) + - Start + X +- Dreamcast (GPIO output) + - Start + Y - Wii U (GameCube Adapter) - Start + Left Bumper + D-Pad Down +- N64 (GPIO output) + - Start + Right Bumper - Web Application Mode - Start + Left Bumper + Right Bumper @@ -52,7 +64,8 @@ For most controllers pressing and holding Start+Select (+/-, etc) for the contro For the OUYA controller there is no Start+Select, the disconnection combo has been set to L3+R3. ## Supported devices -### Wired controllers +### Wired controllers (USB input) +The following work when the adapter is outputting to any supported platform (Xbox, Switch, XInput, PS3, DInput, **PS1/PS2**, **Dreamcast**, **GameCube**, **N64**, etc.): - Original Xbox Duke and S - Xbox 360, One, Series, and Elite - Dualshock 3 (PS3) @@ -73,7 +86,7 @@ Note: There are some third party controllers that can change their VID/PID, thes - Most wireless adapters that present themselves as Switch/XInput/PlayStation controllers should work ### Wireless Bluetooth controllers (Pico W & ESP32) -**Note:** Bluetooth functionality is in early testing, some may have quirks. +**Note:** Bluetooth functionality is in early testing, some may have quirks. Bluetooth controllers work as input when outputting to **PS1/PS2**, **Dreamcast**, **GameCube**, or **N64** (same as wired USB in those modes). - Xbox Series, One, and Elite 2 - Dualshock 3 - Dualshock 4 @@ -94,6 +107,15 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. +### Version 1.0.0.6a +- **PS1/PS2 (GPIO) output mode** — The adapter can output to a PS1 or PS2 console as a controller over GPIO (no USB device in this mode). Select via button combo **Start + B** or set a fixed driver build. **Wiring (standard Pico):** connect the board to the console’s controller port using DATA=GP19, COMMAND=GP20, ATTENTION/SEL=GP21, CLOCK=GP22, ACKNOWLEDGE=GP26. Plug your USB gamepad into the adapter’s USB port; the console sees a DualShock-style controller. _Protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ +- **GameCube (GPIO) output mode** — The adapter can output to a GameCube or Wii (GameCube ports) as a controller over a single DATA line. Select via button combo **Start + X** or set a fixed driver build. **Wiring (standard Pico):** DATA=GP19, GND=GND; connect to the console’s controller port (single wire + ground). Plug your USB gamepad into the adapter’s USB port. _JoyBus protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ +- **N64 (GPIO) output mode** — The adapter can output to a Nintendo 64 console as a controller over a single DATA line. Select via button combo **Start + Right Bumper** or set a fixed driver build. **Wiring (standard Pico):** DATA=GP19, GND=GND; connect to the N64 controller port (same pin as GameCube). Use any **wired (USB)** or **Bluetooth** (Pico W / Pico 2 W) gamepad as input. _Protocol and PIO send code ported from [pdaxrom/usb2n64-adapter](https://github.com/pdaxrom/usb2n64-adapter). Memory pak and rumble pak are not emulated._ +- **Dreamcast (Maple Bus)** — **Input:** Read a real Dreamcast controller over GPIO (Pin A=GP10, B=GP11). **Output:** Use a USB or **Bluetooth** gamepad to control a Dreamcast: select **Start + Y** for Dreamcast mode, connect your BT or USB pad, wire the adapter’s Maple Bus (GP10/GP11) to the console’s controller port. Core1 runs the Maple device (responds to device info and GET_CONDITION); Core0 feeds gamepad state from USB/BT. When input source is **Dreamcast GPIO**, the bus is used as host only (read a DC pad). See [Dreamcast Port guide](Firmware/RP2040/docs/Dreamcast_Port.md). Maple Bus from [DreamPicoPort](https://github.com/OrangeFox86/DreamPicoPort). +- **Pin-outs and default mappings** — See [GPIO Output Pin-Out and Mappings](Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md) for pin numbers (PS1/PS2, Dreamcast, GameCube, N64) and default button/stick mappings for each mode. +- **Bluetooth input for PS1/PS2, GameCube, Dreamcast, and N64** — On **Pico W** (or Pico 2 W), you can use a **Bluetooth controller** as input while outputting to PS1, PS2, GameCube, Dreamcast, or N64. Select the mode (**Start + B**, **Start + X**, **Start + Y**, or **Start + Right Bumper**) as usual; pair your BT gamepad; the console sees the adapter as a controller. Wiring is the same for each mode (PS1/PS2: DATA/CMD/ATT/CLK/ACK; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10/GP11). +- **GPIO input from real PS1/PS2, GameCube, N64, or Dreamcast controllers** — You can use a **real wired PS1/PS2, GameCube, N64, or Dreamcast controller** as the adapter’s input in two ways: (1) **Output to other consoles (Switch, Xbox, DInput, etc.):** set output mode (e.g. **Start + D-pad Down** for Switch), then hold **Start + Select** for ~2.5 s until the input source cycles to **PSX GPIO**, **GameCube GPIO**, **Dreamcast GPIO**, or **N64 GPIO**; plug the real controller into the GPIO pins and connect the adapter’s USB to the target console. (2) **Output to PS1/PS2, GameCube, or Dreamcast:** in that output mode, hold **Start + Select** to set input to the matching GPIO and plug in the real controller (same pins). **Wiring:** PS1/PS2: DATA=GP19, CMD=GP20, ATT=GP21, CLK=GP22; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10, GP11. _PSX host, JoyBus host, N64 host ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ + ### Version 1.0.0.5a - **Switch Pro emulation** — Switch output mode now emulates a **Nintendo Switch Pro Controller** over USB (report format, subcommands, init handshake). Face-button and report layout follow the standard Pro Controller protocol (bit layout aligned with hardware/reference). _Switch Pro protocol and button report layout reference: [retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch) (N64/GameCube → Pico → Switch); Bluepad32 Switch parser used for validation._ - **Waveshare RP2350-USB-A board support** — Build with `-DOGXM_BOARD=RP2350_USB_A` for the Waveshare RP2350-USB-A (wired USB host + RGB LED). _Board support from upstream [OGX-Mini](https://github.com/wiredopposite/OGX-Mini/commit/68bdec451077a33b0b1247ce01ed30e470163dea)._ @@ -147,8 +169,8 @@ Note: These features have been added to the Pico W/ Pico 2 W firmware support, I ## Planned additions for this fork - **Web app bindings for OG Xbox mode** — Allow users to rebind the Guide tap (Start) and the IGR/shutdown hold combos (e.g. which button triggers 1 s soft IGR or 3 s shutdown) via the web app. - Output to the following consoles: - - GameCube - - PS2 + - ~~PS2~~ (done: PS1/PS2 GPIO mode, see changelog) + - ~~GameCube~~ (done: GameCube GPIO mode, see changelog) - DreamCast - NES - SNES From 8bb536a532a0228956e1353e505537b41cd70d94 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Fri, 6 Mar 2026 12:13:07 -0500 Subject: [PATCH 27/42] Docs: PS2 controller port power note in GPIO pinout (3.3V possible but not recommended) Made-with: Cursor --- Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md b/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md index 8abc4172..0e33001b 100644 --- a/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md +++ b/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md @@ -32,6 +32,9 @@ PS1/PS2 use a **9-pin** controller connector. Below: **GPIO** = RP2040 pin (adap **Output mode:** Connect each GPIO to the same-numbered connector pin and Pico **GND** to connector **4** (do not use console VCC). **Input mode:** Same GPIO↔connector data mapping; connect Pico **3V3** → plug pin **5**, Pico **GND** → plug pin **4** to power the controller. +**Can the Pico be powered by the PS2 controller port?** +The PS1/PS2 controller port provides **3.3 V** on connector pin **5** (VCC) and **GND** on pin **4**. In theory you could power the Pico from the port by connecting pin 5 to the Pico’s **VSYS** (e.g. pin 39 on the Pico), since VSYS accepts about 1.8–5.5 V. **This is not recommended:** the port is designed to power a small controller, not an MCU; current may be limited and the adapter’s draw (especially with USB or Bluetooth) can exceed what the port safely supplies. The supported setup is to power the Pico via USB or an external 3.3 V / 5 V supply and only connect **GND** and the data lines to the console. + ### Default controller mapping (PadIn → PS1/PS2) | Console (PS1/PS2) | Adapter input (PadIn) | From 6bf5211baa5bc37884fbc468a571b305a28aa8d8 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Tue, 10 Mar 2026 05:53:32 -0400 Subject: [PATCH 28/42] Firmware and docs: DualSense/OG Xbox input fix, gitignore local docs, RP2040 docs README - PS5 host: always push every DualSense report (no skip) so OG Xbox mode does not drop inputs - IMPROVEMENTS.md: document DualSense/OG Xbox change and Xbox OG latency behaviour - .gitignore: ignore local-only docs (Input_Controllers_Research, Other_Projects_Output_Modes, Wired_Retro_Controllers) - Firmware/RP2040/docs/README.md: add GPIO pinout, Dreamcast port, update IMPROVEMENTS description - Other staged changes: board/PS1PS2/GameCube/N64/Dreamcast/UserSettings/PicoW/bluepad32-related Made-with: Cursor --- .gitignore | 5 +- Firmware/RP2040/CMakeLists.txt | 14 +- Firmware/RP2040/docs/IMPROVEMENTS.md | 9 + Firmware/RP2040/docs/README.md | 4 +- .../Board/board_api_private/board_api_bt.cpp | 7 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 65 +++-- .../DeviceDriver/Dreamcast/Dreamcast.cpp | 2 + .../DeviceDriver/GameCube/GameCube.cpp | 4 + .../src/USBDevice/DeviceDriver/N64/N64.cpp | 2 + .../PS1PS2/controller_simulator.c | 50 +++- .../DeviceDriver/PS1PS2/psx_simulator.h | 6 + .../DeviceDriver/XboxOG/XboxOG_GP.cpp | 233 +++++++++--------- .../RP2040/src/USBHost/HostDriver/PS5/PS5.cpp | 9 +- .../RP2040/src/UserSettings/UserSettings.cpp | 5 +- README.md | 22 +- 15 files changed, 275 insertions(+), 162 deletions(-) diff --git a/.gitignore b/.gitignore index 6852505f..94c41ded 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,7 @@ Tools/dvd-dongle-rom.bin # Local docs (not for GitHub) Firmware/RP2040/docs/XInput_joypad-os_comparison.md -Firmware/RP2040/docs/BLUEPAD32_PS4_PS5_PARSING.md \ No newline at end of file +Firmware/RP2040/docs/BLUEPAD32_PS4_PS5_PARSING.md +docs/Input_Controllers_Research.md +docs/Other_Projects_Output_Modes.md +docs/Wired_Retro_Controllers.md \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index d4745f1b..68083927 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -227,11 +227,11 @@ else() endif() # Optional: default or lock USB output mode. -# OGXM_FIXED_DRIVER = one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP. +# OGXM_FIXED_DRIVER = one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64. # Empty = use first valid driver as default, combos enabled. # Set = use that mode as default (first boot / NVS init). If OGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF (default): # combos disabled, mode locked. If OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON: default is this mode, combos still work. -set(OGXM_FIXED_DRIVER "" CACHE STRING "Default/lock output mode. One of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP. Empty = combos enabled.") +set(OGXM_FIXED_DRIVER "" CACHE STRING "Default/lock output mode. One of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64. Empty = combos enabled.") set(OGXM_FIXED_DRIVER_ALLOW_COMBOS OFF CACHE BOOL "If OGXM_FIXED_DRIVER is set: ON = use it as default but allow combos to change mode; OFF = lock to that mode, combos disabled.") if(OGXM_FIXED_DRIVER) add_compile_definitions(CONFIG_OGXM_FIXED_DRIVER=1) @@ -259,10 +259,18 @@ if(OGXM_FIXED_DRIVER) add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=9) elseif(OGXM_FIXED_DRIVER STREQUAL "WII") add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=10) + elseif(OGXM_FIXED_DRIVER STREQUAL "PS1PS2") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=11) + elseif(OGXM_FIXED_DRIVER STREQUAL "GAMECUBE") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=12) + elseif(OGXM_FIXED_DRIVER STREQUAL "DREAMCAST") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=13) + elseif(OGXM_FIXED_DRIVER STREQUAL "N64") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=14) elseif(OGXM_FIXED_DRIVER STREQUAL "WEBAPP") add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=100) else() - message(FATAL_ERROR "OGXM_FIXED_DRIVER must be one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP") + message(FATAL_ERROR "OGXM_FIXED_DRIVER must be one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64") endif() if(OGXM_FIXED_DRIVER STREQUAL "WII") message(STATUS "Wii-only build: ${OGXM_FIXED_DRIVER} (combos disabled, build option only)") diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 7de53a8f..987fd081 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -106,6 +106,15 @@ Same goal as Switch Pro and PS3: the only added latency when using a wireless co Both modes: no `new_pad_in()` gate; main loop runs with `MAIN_LOOP_DELAY_US=0` by default; `tud_task()` runs before `process()` so the endpoint is ready when we try to send. +### Xbox OG (Duke) gamepad: report always fresh; send when ready (minimal latency) + +Same goal as XInput/PS3: reduce input delay when using e.g. a DualShock (DS3/DS4/DualSense) as input while outputting to Original Xbox. + +- **Every** `process()` call: read `get_pad_in()`, build `in_report_` (buttons, triggers, sticks, SYS hold logic), then call `tud_xid::send_report()` when `send_report_ready(0)`. No `new_pad_in()` gate. The XID layer’s `ep_in_buffer` (used for GET_REPORT and interrupt IN) is updated every loop so the console always sees the latest state. +- **File:** `src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp` — `process()` always builds and sends when ready; previously it only updated when `new_pad_in()`, which added one poll period or more of latency. + +**DualSense (PS5) input when outputting to OG Xbox:** The PS5 USB host no longer skips reports that are byte-identical to the previous one. Previously, “unchanged” reports did not call `set_pad_in()`, so with a polled output (OG Xbox) some transitions or sustained input could be dropped when the host loop was slower than the DualSense report rate. Every DualSense report is now pushed into the gamepad queue so the OG Xbox device always has the latest state. **File:** `src/USBHost/HostDriver/PS5/PS5.cpp` — removed the unchanged-report early return; every report is parsed and passed to `gamepad.set_pad_in()`. + ### Main loop order: tud_task() before process() The main loop now calls **`tud_task()` before** `device_driver->process()`. That way the USB stack updates completion status of the previous IN transfer first; then `process()` sees the endpoint as ready and can send the next report immediately with the latest gamepad state. Reduces latency by up to one main-loop iteration (avoids sending only every other loop when the host polls frequently). diff --git a/Firmware/RP2040/docs/README.md b/Firmware/RP2040/docs/README.md index 19a3a987..45bf8522 100644 --- a/Firmware/RP2040/docs/README.md +++ b/Firmware/RP2040/docs/README.md @@ -8,4 +8,6 @@ See the [project README](../../README.md) for overview, supported platforms, bui |----------|-------------| | [Wii_Mode_Guide.md](Wii_Mode_Guide.md) | Wii mode (build-option only): No Extension / Nunchuk / Classic, USB host, sync and auto-connect, button mapping, supported controllers. | | [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | -| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360. | +| [GPIO_Output_Pinout_and_Mappings.md](GPIO_Output_Pinout_and_Mappings.md) | GPIO pin-outs and default button/stick mappings for PS1/PS2, Dreamcast, GameCube, and N64 output (and input) modes. | +| [Dreamcast_Port.md](Dreamcast_Port.md) | Dreamcast (Maple Bus) port status and notes for completing the port from DreamPicoPort (stub only in firmware for now). | +| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements: Xbox 360 (XInput), PS3 fixes, latency reduction, Xbox OG, DualSense/OG Xbox input, main loop order. | diff --git a/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp b/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp index c6f5d00b..760b3ded 100644 --- a/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp +++ b/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp @@ -5,6 +5,7 @@ #include #include "Board/board_api_private/board_api_private.h" +#include "Board/ogxm_log.h" #if defined(CYW43_WL_GPIO_LED_PIN) && defined(LED_INDICATOR_PIN) static_assert(CYW43_WL_GPIO_LED_PIN != LED_INDICATOR_PIN, "CYW43_WL_GPIO_LED_PIN cannot be the same as LED_INDICATOR_PIN"); @@ -15,18 +16,22 @@ namespace board_api_bt { std::atomic inited{false}; void init() { - if (cyw43_arch_init() != 0) { + if (cyw43_arch_init() != 0) { + OGXM_LOG("board_api_bt: CYW43 init failed\n"); panic("CYW43 init failed"); } else { inited.store(true); + OGXM_LOG("board_api_bt: CYW43 init OK\n"); } } void set_led(bool state) { if (!inited.load()) { + OGXM_LOG("board_api_bt: set_led skipped (not inited)\n"); return; } cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, state ? 1 : 0); + OGXM_LOG(state ? "board_api_bt: set_led ON\n" : "board_api_bt: set_led OFF\n"); } } // namespace board_api_bt diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index 4a9114a2..42924cad 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -150,9 +150,13 @@ void core1_task_wii_usb_host() { #endif void core1_task() { + OGXM_LOG("PicoW Core1: entry\n"); board_api::init_bluetooth(); + OGXM_LOG("PicoW Core1: init_bluetooth done\n"); board_api::set_led(true); + OGXM_LOG("PicoW Core1: set_led(true) done\n"); BLEServer::init_server(_gamepads); + OGXM_LOG("PicoW Core1: BLEServer init done, entering run_task\n"); bluepad32::run_task(_gamepads); } @@ -216,24 +220,19 @@ void pico_w::run() { } else #endif if (gpio_device_mode) { - OGXM_LOG("PicoW run: GPIO device mode (PS1/PS2 or GameCube), Core1 = protocol, Core0 = BT\n"); - HostInputSource input_src = user_settings.get_input_source(); - if (current_driver == DeviceDriverType::DREAMCAST) { - dreamcast_set_core1_device_mode(input_src != HostInputSource::DREAMCAST_GPIO); - } - if (current_driver == DeviceDriverType::PS1PS2) { - multicore_launch_core1(psx_device_main); - } else if (current_driver == DeviceDriverType::GAMECUBE) { - multicore_launch_core1(gamecube_core1_entry); - } else if (current_driver == DeviceDriverType::N64) { - multicore_launch_core1(n64_core1_entry); - } else { - multicore_launch_core1(dreamcast_core1_entry); + /* PS1PS2 on Pico W: run BT on Core1 (same as normal path) so LED and pairing work; drive PS2 protocol from Core0 main loop via psx_device_poll(). */ + const bool ps2_poll_mode = (current_driver == DeviceDriverType::PS1PS2); + if (ps2_poll_mode) { + psx_device_set_poll_mode(true); + OGXM_LOG("PicoW run: PS2 poll mode set\n"); } + OGXM_LOG("PicoW run: GPIO device mode, Core1 = BT (PS2 poll on Core0)\n"); + HostInputSource input_src = user_settings.get_input_source(); s_gpio_device_driver = device_driver; if (input_src == HostInputSource::PSX_GPIO) { GPIOHost::psx_host_init(0, 20, 19); - } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + } else if (input_src == HostInputSource::GAMECUBE_GPIO && current_driver != DeviceDriverType::GAMECUBE) { + /* Skip joybus host when in GameCube device mode: Core1 uses GPIO 19 for console output. */ GPIOHost::joybus_host_init(0, 19); } else if (input_src == HostInputSource::DREAMCAST_GPIO) { GPIOHost::dreamcast_host_init(1, 0, 10, -1); @@ -241,10 +240,30 @@ void pico_w::run() { GPIOHost::n64_host_init(0, 19); } bluepad32::set_gpio_device_process_callback(gpio_device_process_cb, nullptr); - board_api::init_bluetooth(); - board_api::set_led(true); - BLEServer::init_server(_gamepads); - bluepad32::run_task(_gamepads); // never returns: BT run loop + process timer + if (ps2_poll_mode) { + /* PS2: init BT/LED/BLEServer only on Core1 to avoid CYW43 gpio_add_raw_irq_handler conflict (double-init assert). */ + OGXM_LOG("PicoW run: launching Core1 (BT inited there), no Core0 BT init\n"); + multicore_launch_core1(core1_task); /* BT on Core1; Core0 main loop will call psx_device_poll() */ + } else { + OGXM_LOG("PicoW run: Core0 calling init_bluetooth/set_led/BLEServer\n"); + board_api::init_bluetooth(); + board_api::set_led(true); + BLEServer::init_server(_gamepads); + OGXM_LOG("PicoW run: Core0 BT/LED/BLEServer done, launching Core1\n"); + if (current_driver == DeviceDriverType::DREAMCAST) { + dreamcast_set_core1_device_mode(input_src != HostInputSource::DREAMCAST_GPIO); + } + if (current_driver == DeviceDriverType::GAMECUBE) { + multicore_launch_core1(gamecube_core1_entry); + } else if (current_driver == DeviceDriverType::N64) { + multicore_launch_core1(n64_core1_entry); + } else { + multicore_launch_core1(dreamcast_core1_entry); + } + /* Let Core1 reach flash_safe_execute_core_init() before we enter run_task (BT stack may touch flash). */ + sleep_ms(100); + bluepad32::run_task(_gamepads); /* never returns */ + } } else { tud_init(BOARD_TUD_RHPORT); OGXM_LOG("PicoW run: tud_init done, launching Core1 (BT)\n"); @@ -272,11 +291,12 @@ void pico_w::run() { while (true) { TaskQueue::Core0::process_tasks(); if (!wii_mode) { - tud_task(); + if (!gpio_device_mode) + tud_task(); HostInputSource input_src = UserSettings::get_instance().get_input_source(); if (input_src == HostInputSource::PSX_GPIO) { GPIOHost::psx_host_poll(_gamepads[0]); - } else if (input_src == HostInputSource::GAMECUBE_GPIO) { + } else if (input_src == HostInputSource::GAMECUBE_GPIO && UserSettings::get_instance().get_current_driver() != DeviceDriverType::GAMECUBE) { GPIOHost::joybus_host_poll(_gamepads[0]); } else if (input_src == HostInputSource::DREAMCAST_GPIO) { GPIOHost::dreamcast_host_poll(_gamepads[0]); @@ -284,6 +304,11 @@ void pico_w::run() { GPIOHost::n64_host_poll(_gamepads[0]); } } + if (gpio_device_mode && current_driver == DeviceDriverType::PS1PS2) { + psx_device_poll(); + if (loop_count != 0 && (loop_count % 10000u) == 0) + OGXM_LOG("PicoW run: main loop psx_device_poll tick " + std::to_string(loop_count) + "\n"); + } for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { device_driver->process(i, _gamepads[i]); } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp index b7e0e4a0..119a28f1 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Dreamcast/Dreamcast.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include static bool s_core1_device_mode = false; @@ -97,6 +98,7 @@ void DreamcastDevice::process(const uint8_t idx, Gamepad& gamepad) { } void dreamcast_core1_entry(void) { + flash_safe_execute_core_init(); // allow Core0 to perform flash operations (e.g. UserSettings) if (!s_core1_device_mode) { while (true) sleep_ms(1); return; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp index 8a92ddee..8510a32d 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/GameCube/GameCube.cpp @@ -1,4 +1,5 @@ #include +#include "pico/flash.h" #include "USBDevice/DeviceDriver/GameCube/GameCube.h" #include "USBDevice/DeviceDriver/GameCube/gc_simulator.h" @@ -9,6 +10,9 @@ static GCReport* s_gc_report = nullptr; void gamecube_core1_entry(void) { + flash_safe_execute_core_init(); // allow Core0 to perform flash operations (e.g. UserSettings) + if (s_gc_report == nullptr) + return; // driver not initialized; avoid null deref in gc_device_main gc_device_main(0, s_gc_report, GAMECUBE_DATA_PIN); } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp index 86101461..913bd01a 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/N64/N64.cpp @@ -1,6 +1,7 @@ /* N64 controller output (device). Any USB/BT gamepad -> adapter -> N64 console. Ported from pdaxrom/usb2n64-adapter. */ #include +#include "pico/flash.h" #include "USBDevice/DeviceDriver/N64/N64.h" #include "Gamepad/Gamepad.h" @@ -9,6 +10,7 @@ #endif void n64_core1_entry(void) { + flash_safe_execute_core_init(); // allow Core0 to perform flash operations (e.g. UserSettings) n64_device_main(N64_DATA_PIN); } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c index f9fa3dd3..00ec3659 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c @@ -9,6 +9,15 @@ #include "psxSPI.pio.h" #include "USBDevice/DeviceDriver/PS1PS2/psx_simulator.h" +#if defined(CONFIG_OGXM_BOARD_PI_PICOW) || defined(CONFIG_OGXM_BOARD_PI_PICO2W) +/* Pico W / Pico 2 W: do not use GPIO IRQ for PIN_SEL; CYW43 uses gpio_add_raw_irq_handler and conflicts. */ +#define PSX_DEVICE_POLLED_SEL 1 +#else +#include "hardware/irq.h" +#include "hardware/structs/io_bank0.h" +#define PSX_DEVICE_POLLED_SEL 0 +#endif + #define MODE_DIGITAL 0x41 #define MODE_ANALOG 0x73 #define MODE_ANALOG_PRESSURE 0x79 @@ -47,6 +56,7 @@ static uint offsetDatWriter; volatile PSXInputState *inputState; static void (*core1_function)(void); +static bool poll_mode = false; static uint8_t mode = MODE_DIGITAL; static bool config = false; @@ -359,16 +369,26 @@ static void __time_critical_func(restart_pio_sm)(void) { pio_sm_clear_fifos(psx_device_pio, smCmdReader); pio_sm_drain_tx_fifo(psx_device_pio, smDatWriter); + if (poll_mode) + goto enable_sm; multicore_reset_core1(); if (core1_function) core1_function(); +enable_sm: pio_enable_sm_mask_in_sync(psx_device_pio, (1u << smCmdReader) | (1u << smDatWriter)); } +#if !PSX_DEVICE_POLLED_SEL +/* Shared handler: IO_IRQ_BANK0 is used by CYW43/GPIO elsewhere; only run when our pin triggered. */ static void __time_critical_func(sel_isr_callback)(void) { + uint32_t word = io_bank0_hw->intr[PIN_SEL / 8]; + uint32_t shift = 4u * (PIN_SEL % 8); + if (!((word >> shift) & 0xFu)) + return; gpio_acknowledge_irq(PIN_SEL, GPIO_IRQ_EDGE_RISE); restart_pio_sm(); } +#endif static void init_pio(void) { gpio_set_dir(PIN_DAT, false); @@ -392,6 +412,32 @@ static void init_pio(void) { dat_writer_program_init(psx_device_pio, smDatWriter, offsetDatWriter); } +void psx_device_set_poll_mode(bool enable) { + poll_mode = enable; +} + +/* One iteration of the protocol when in poll mode (Core0-driven, e.g. Pico W with BT on Core1). Return 1 if a poll was processed. */ +int psx_device_poll(void) { + static bool controller_inited = false; +#if PSX_DEVICE_POLLED_SEL + static bool last_sel_high = false; + bool sel_high = gpio_get(PIN_SEL); + if (sel_high && !last_sel_high) + restart_pio_sm(); + last_sel_high = sel_high; +#endif + if (!controller_inited) { + initController(); + controller_inited = true; + } + if (pio_sm_get_rx_fifo_level(psx_device_pio, smCmdReader) == 0) + return 0; + uint8_t cmd = (uint8_t)(pio_sm_get(psx_device_pio, smCmdReader) >> 24); + if (cmd == 0x01) + process_joy_req(); + return 1; +} + void psx_device_init(unsigned pio, PSXInputState *data, void (*reset_pio)(void)) { psx_device_pio = pio ? pio1 : pio0; inputState = data; @@ -402,7 +448,9 @@ void psx_device_init(unsigned pio, PSXInputState *data, void (*reset_pio)(void)) gpio_set_slew_rate(PIN_DAT, GPIO_SLEW_RATE_FAST); gpio_set_drive_strength(PIN_DAT, GPIO_DRIVE_STRENGTH_12MA); +#if !PSX_DEVICE_POLLED_SEL gpio_set_irq_enabled(PIN_SEL, GPIO_IRQ_EDGE_RISE, true); - irq_set_exclusive_handler(IO_IRQ_BANK0, sel_isr_callback); + irq_add_shared_handler(IO_IRQ_BANK0, sel_isr_callback, 0u); irq_set_enabled(IO_IRQ_BANK0, true); +#endif } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h index 81d8c556..630787a9 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h @@ -32,6 +32,12 @@ void psx_device_init(unsigned pio, PSXInputState* data, void (*reset_pio)(void)) /* Entry for core1: run this in an infinite loop. Blocks. */ void psx_device_main(void); +/* When enabled, SEL IRQ only restarts PIO (no Core1 reset). Use with psx_device_poll() on Core0 (e.g. Pico W: BT on Core1, PS2 on Core0). */ +void psx_device_set_poll_mode(bool enable); + +/* One poll iteration; call from Core0 main loop when in poll mode. Returns 1 if a command was processed. */ +int psx_device_poll(void); + #ifdef __cplusplus } #endif diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp index aa3b6252..97315031 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp @@ -16,140 +16,139 @@ void XboxOGDevice::initialize() void XboxOGDevice::process(const uint8_t idx, Gamepad& gamepad) { - if (gamepad.new_pad_in()) + // Build report every loop (same low-latency pattern as XInput/PS3) so GET_REPORT and + // interrupt IN always see latest state; send when endpoint is ready. + std::memset(&in_report_.buttons, 0, 8); + Gamepad::PadIn gp_in = gamepad.get_pad_in(); + + // Guide (SYS) button: tap = Start, hold 1s = soft IGR (LT+RT+Start+Back), hold 3s = shutdown (LT+RT+Up+Back) + bool sys_pressed = (gp_in.buttons & Gamepad::BUTTON_SYS) != 0; + if (sys_pressed && !sys_button_pressed_) { - std::memset(&in_report_.buttons, 0, 8); - Gamepad::PadIn gp_in = gamepad.get_pad_in(); - - // Guide (SYS) button: tap = Start, hold 1s = soft IGR (LT+RT+Start+Back), hold 3s = shutdown (LT+RT+Up+Back) - bool sys_pressed = (gp_in.buttons & Gamepad::BUTTON_SYS) != 0; - if (sys_pressed && !sys_button_pressed_) + sys_button_pressed_ = true; + sys_button_press_time_ = get_absolute_time(); + sys_button_combo_sent_ = false; + } + else if (!sys_pressed && sys_button_pressed_) + { + sys_button_pressed_ = false; + uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); + if (hold_time_ms >= 3000) { - sys_button_pressed_ = true; - sys_button_press_time_ = get_absolute_time(); - sys_button_combo_sent_ = false; + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.dpad |= Gamepad::DPAD_UP; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; } - else if (!sys_pressed && sys_button_pressed_) + else if (hold_time_ms >= 1000) { - sys_button_pressed_ = false; - uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); - if (hold_time_ms >= 3000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.dpad |= Gamepad::DPAD_UP; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else if (hold_time_ms >= 1000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.buttons |= Gamepad::BUTTON_START; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else - { - gp_in.buttons |= Gamepad::BUTTON_START; - sys_button_combo_sent_ = true; - } + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_START; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; } - else if (sys_pressed && !sys_button_combo_sent_) + else { - uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); - if (hold_time_ms >= 3000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.dpad |= Gamepad::DPAD_UP; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else if (hold_time_ms >= 1000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.buttons |= Gamepad::BUTTON_START; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else - { - gp_in.buttons |= Gamepad::BUTTON_START; - } + gp_in.buttons |= Gamepad::BUTTON_START; + sys_button_combo_sent_ = true; } - - switch (gp_in.dpad) + } + else if (sys_pressed && !sys_button_combo_sent_) + { + uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); + if (hold_time_ms >= 3000) { - case Gamepad::DPAD_UP: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP; - break; - case Gamepad::DPAD_DOWN: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN; - break; - case Gamepad::DPAD_LEFT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_LEFT; - break; - case Gamepad::DPAD_RIGHT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_RIGHT; - break; - case Gamepad::DPAD_UP_LEFT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_LEFT; - break; - case Gamepad::DPAD_UP_RIGHT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_RIGHT; - break; - case Gamepad::DPAD_DOWN_LEFT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_LEFT; - break; - case Gamepad::DPAD_DOWN_RIGHT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_RIGHT; - break; - default: - break; + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.dpad |= Gamepad::DPAD_UP; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; } - - if (gp_in.buttons & Gamepad::BUTTON_BACK) in_report_.buttons |= XboxOG::GP::Buttons::BACK; - if (gp_in.buttons & Gamepad::BUTTON_START) in_report_.buttons |= XboxOG::GP::Buttons::START; - if (gp_in.buttons & Gamepad::BUTTON_L3) in_report_.buttons |= XboxOG::GP::Buttons::L3; - if (gp_in.buttons & Gamepad::BUTTON_R3) in_report_.buttons |= XboxOG::GP::Buttons::R3; - - if (gamepad.analog_enabled()) + else if (hold_time_ms >= 1000) { - in_report_.a = gp_in.analog[Gamepad::ANALOG_OFF_A]; - in_report_.b = gp_in.analog[Gamepad::ANALOG_OFF_B]; - in_report_.x = gp_in.analog[Gamepad::ANALOG_OFF_X]; - in_report_.y = gp_in.analog[Gamepad::ANALOG_OFF_Y]; - in_report_.white = gp_in.analog[Gamepad::ANALOG_OFF_LB]; - in_report_.black = gp_in.analog[Gamepad::ANALOG_OFF_RB]; + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_START; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; } else { - if (gp_in.buttons & Gamepad::BUTTON_X) in_report_.x = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_A) in_report_.a = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_Y) in_report_.y = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_B) in_report_.b = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_LB) in_report_.white = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_RB) in_report_.black = 0xFF; + gp_in.buttons |= Gamepad::BUTTON_START; } + } - in_report_.trigger_l = gp_in.trigger_l; - in_report_.trigger_r = gp_in.trigger_r; + switch (gp_in.dpad) + { + case Gamepad::DPAD_UP: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP; + break; + case Gamepad::DPAD_DOWN: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN; + break; + case Gamepad::DPAD_LEFT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_LEFT; + break; + case Gamepad::DPAD_RIGHT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_RIGHT; + break; + case Gamepad::DPAD_UP_LEFT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_LEFT; + break; + case Gamepad::DPAD_UP_RIGHT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_RIGHT; + break; + case Gamepad::DPAD_DOWN_LEFT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_LEFT; + break; + case Gamepad::DPAD_DOWN_RIGHT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_RIGHT; + break; + default: + break; + } - in_report_.joystick_lx = gp_in.joystick_lx; - in_report_.joystick_ly = Range::invert(gp_in.joystick_ly); - in_report_.joystick_rx = gp_in.joystick_rx; - in_report_.joystick_ry = Range::invert(gp_in.joystick_ry); + if (gp_in.buttons & Gamepad::BUTTON_BACK) in_report_.buttons |= XboxOG::GP::Buttons::BACK; + if (gp_in.buttons & Gamepad::BUTTON_START) in_report_.buttons |= XboxOG::GP::Buttons::START; + if (gp_in.buttons & Gamepad::BUTTON_L3) in_report_.buttons |= XboxOG::GP::Buttons::L3; + if (gp_in.buttons & Gamepad::BUTTON_R3) in_report_.buttons |= XboxOG::GP::Buttons::R3; - if (tud_suspended()) - { - tud_remote_wakeup(); - } - if (tud_xid::send_report_ready(0)) - { - tud_xid::send_report(0, reinterpret_cast(&in_report_), sizeof(XboxOG::GP::InReport)); - } + if (gamepad.analog_enabled()) + { + in_report_.a = gp_in.analog[Gamepad::ANALOG_OFF_A]; + in_report_.b = gp_in.analog[Gamepad::ANALOG_OFF_B]; + in_report_.x = gp_in.analog[Gamepad::ANALOG_OFF_X]; + in_report_.y = gp_in.analog[Gamepad::ANALOG_OFF_Y]; + in_report_.white = gp_in.analog[Gamepad::ANALOG_OFF_LB]; + in_report_.black = gp_in.analog[Gamepad::ANALOG_OFF_RB]; + } + else + { + if (gp_in.buttons & Gamepad::BUTTON_X) in_report_.x = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_A) in_report_.a = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_Y) in_report_.y = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_B) in_report_.b = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_LB) in_report_.white = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_RB) in_report_.black = 0xFF; + } + + in_report_.trigger_l = gp_in.trigger_l; + in_report_.trigger_r = gp_in.trigger_r; + + in_report_.joystick_lx = gp_in.joystick_lx; + in_report_.joystick_ly = Range::invert(gp_in.joystick_ly); + in_report_.joystick_rx = gp_in.joystick_rx; + in_report_.joystick_ry = Range::invert(gp_in.joystick_ry); + + if (tud_suspended()) + { + tud_remote_wakeup(); + } + if (tud_xid::send_report_ready(0)) + { + tud_xid::send_report(0, reinterpret_cast(&in_report_), sizeof(XboxOG::GP::InReport)); } if (tud_xid::receive_report(0, reinterpret_cast(&out_report_), sizeof(XboxOG::GP::OutReport))) diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp index a6e821b7..15f83966 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp @@ -34,12 +34,9 @@ void PS5Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance { const PS5::InReport* in_report = reinterpret_cast(report); - if (std::memcmp(&prev_in_report_.joystick_lx, &in_report->joystick_lx, sizeof(uint8_t) * 6) == 0 && - std::memcmp(prev_in_report_.buttons, in_report->buttons, sizeof(in_report->buttons)) == 0) - { - tuh_hid_receive_report(address, instance); - return; - } + // Do not skip "unchanged" reports: polled outputs (e.g. OG Xbox) need every report so + // quick transitions and sustained input are not dropped when the host loop is slower + // than the DualSense report rate or when comparing only a subset of the report. Gamepad::PadIn gp_in; diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.cpp b/Firmware/RP2040/src/UserSettings/UserSettings.cpp index 259367b6..67dc5c88 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/UserSettings.cpp @@ -80,7 +80,8 @@ struct ComboMap { DeviceDriverType driver; }; -static constexpr std::array BUTTON_COMBO_MAP = {{ +// GAMECUBE and N64 are build-only (fixed driver), not in combo map; use -DOGXM_FIXED_DRIVER=GAMECUBE or N64. +static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::XBOXOG, DeviceDriverType::XBOXOG }, { ButtonCombo::XBOXOG_SB, DeviceDriverType::XBOXOG_SB }, { ButtonCombo::XBOXOG_XR, DeviceDriverType::XBOXOG_XR }, @@ -92,9 +93,7 @@ static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::PS3, DeviceDriverType::PS3 }, { ButtonCombo::PSCLASSIC, DeviceDriverType::PSCLASSIC }, { ButtonCombo::PS1PS2, DeviceDriverType::PS1PS2 }, - { ButtonCombo::GAMECUBE, DeviceDriverType::GAMECUBE }, { ButtonCombo::DREAMCAST, DeviceDriverType::DREAMCAST }, - { ButtonCombo::N64, DeviceDriverType::N64 } }}; const std::string UserSettings::INIT_FLAG_KEY() diff --git a/README.md b/README.md index 8ef51869..4387a27a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Waveshare RP2350-USB-A, Waveshare RP2350-Zero, Seeed Studio XIAO RP2040, RP2354, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. -[**Visit the web app here**](https://wiredopposite.github.io/OGX-Mini-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app via USB, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect via USB" in the web app and select the OGX-Mini. You can also pair via Bluetooth, no extra steps are needed in that case. +[**Visit the web app here**](https://megacadedev.github.io/OGX-Mini-2026-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app via USB, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect via USB" in the web app and select the OGX-Mini. You can also pair via Bluetooth, no extra steps are needed in that case. [**Join the discord here!**](https://discord.gg/guaBh9JZQ) @@ -18,10 +18,10 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles - **Wii (Wiimote)** — Pico W / Pico 2 W only; build with `-DOGXM_FIXED_DRIVER=WII`. See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). - **PlayStation 1 & 2** — GPIO output to console controller port (DualShock-style). - **Dreamcast** — GPIO output over Maple Bus to console controller port. -- **GameCube / Wii (GameCube ports)** — GPIO output over single-wire JoyBus. -- **Nintendo 64** — GPIO output over single-wire to controller port. +- **GameCube / Wii (GameCube ports)** — GPIO output over single-wire JoyBus. **Build-only (no combo):** use `-DOGXM_FIXED_DRIVER=GAMECUBE`; see below. +- **Nintendo 64** — GPIO output over single-wire to controller port. **Build-only (no combo):** use `-DOGXM_FIXED_DRIVER=N64`; see below. -**RP2040 output modes:** **USB device:** XInput (Xbox 360 + XSM3), DInput, PS3, **Switch Pro** (Nintendo Switch Pro Controller emulation), Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. **GPIO (no USB device):** PS1/PS2, Dreamcast, GameCube, N64 — use any wired USB or (on Pico W / Pico 2 W) Bluetooth controller as input. On Pico 2 W, Bluetooth runs on Core1 and USB on Core0; you can build with a fixed mode or use button combos to switch at runtime (Start + D-pad held ~3 s). **Wii is not in the combo list** — use a Wii-only build to get Wiimote output. +**RP2040 output modes:** **USB device:** XInput (Xbox 360 + XSM3), DInput, PS3, **Switch Pro** (Nintendo Switch Pro Controller emulation), Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. **GPIO (no USB device):** PS1/PS2, Dreamcast, GameCube, N64 — use any wired USB or (on Pico W / Pico 2 W) Bluetooth controller as input. **Wii, GameCube, and N64 are not in the combo list** — use a dedicated build for those modes (see below). ## Changing platforms By default the OGX-Mini will emulate an OG Xbox controller, you must hold a button combo for 3 seconds to change which platform you want to play on. Your chosen mode will persist after powering off the device. @@ -44,18 +44,22 @@ Start = Plus (Switch) = Options (Dualsense/DS4) - Start + A (Cross for PlayStation and B for Switch gamepads) - PlayStation 1 / PlayStation 2 (GPIO output) - Start + B -- GameCube / Wii GameCube ports (GPIO output) - - Start + X - Dreamcast (GPIO output) - Start + Y - Wii U (GameCube Adapter) - Start + Left Bumper + D-Pad Down -- N64 (GPIO output) - - Start + Right Bumper - Web Application Mode - Start + Left Bumper + Right Bumper -**Wii (Wiimote)** is not selectable by combo. Build with `-DOGXM_FIXED_DRIVER=WII` for a Wii-only firmware; see [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). +**Wii, GameCube, and N64 are not selectable by combo.** Use a dedicated build for those modes: + +- **Wii (Wiimote):** `-DOGXM_FIXED_DRIVER=WII`. See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). +- **GameCube (GPIO):** `-DOGXM_FIXED_DRIVER=GAMECUBE`. Example (Pico 2 W Debug): + `cmake -DOGXM_BOARD=PI_PICO2W -DCMAKE_BUILD_TYPE=Debug -DOGXM_FIXED_DRIVER=GAMECUBE ..` then `ninja`. Flash `OGX-Mini-*-GAMECUBE.uf2`. Use `PI_PICOW` for Pico W. +- **N64 (GPIO):** `-DOGXM_FIXED_DRIVER=N64`. Example (Pico 2 W Debug): + `cmake -DOGXM_BOARD=PI_PICO2W -DCMAKE_BUILD_TYPE=Debug -DOGXM_FIXED_DRIVER=N64 ..` then `ninja`. Flash `OGX-Mini-*-N64.uf2`. + +Input for GPIO modes is Bluetooth or USB; no combo switching in these builds. After a new mode is stored, the RP2040 will reset itself so you don't need to unplug it. From 0182afde5863e7b70f8d34ba6f5485e68ecc558c Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Sun, 15 Mar 2026 17:04:00 -0400 Subject: [PATCH 29/42] Build scripts, FW v1.0.0a7, all-board support, ESP32/4CH build fixes --- .gitignore | 4 + Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/CMakeLists.txt | 2 + Firmware/RP2040/docs/IMPROVEMENTS.md | 29 +- Firmware/RP2040/src/Descriptors/PS3.h | 2 +- .../src/OGXMini/Board/Four_Channel_I2C.cpp | 4 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 31 +- .../USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp | 48 +-- .../PS1PS2/controller_simulator.c | 35 ++- .../DeviceDriver/PS1PS2/psx_simulator.h | 3 + .../src/USBDevice/DeviceDriver/PS3/PS3.cpp | 37 ++- .../USBDevice/DeviceDriver/XInput/XInput.cpp | 36 ++- .../DeviceDriver/XboxOG/XboxOG_GP.cpp | 273 ++++++++++-------- .../DeviceDriver/XboxOG/tud_xid/tud_xid.cpp | 27 ++ README.md | 17 +- scripts/build.ps1 | 158 ++++++++++ scripts/build.sh | 161 +++++++++++ 17 files changed, 698 insertions(+), 171 deletions(-) create mode 100644 scripts/build.ps1 create mode 100644 scripts/build.sh diff --git a/.gitignore b/.gitignore index 94c41ded..b00d5b9e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ Firmware/.vscode Firmware/RP2040/build Firmware/RP2040/build_* + +# Build dirs created by scripts/build.sh and scripts/build_all_boards.sh +scripts/build +scripts/build_* Firmware/RP2040/scripts Firmware/RP2040/.ignore Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid_xremote_rom.h diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index 88237715..f21b319f 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a6") \ No newline at end of file +set(FW_VERSION "v1.0.0a7") \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 68083927..886a79db 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -400,6 +400,8 @@ if(EN_ESP32) endif() list(APPEND LIBS_BOARD hardware_i2c + hardware_pio + hardware_dma ) endif() diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 987fd081..5f8b0054 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -31,6 +31,13 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. 4. **Control handling** - Vendor and class control requests are forwarded to the active driver so XSM3 traffic reaches the XInput handler. +5. **Wake console from standby (remote wakeup)** + - When the Xbox 360 has been turned off via **Guide → Turn off console** (not the front power button), the console may keep USB power and put the bus in suspend. The adapter can then wake the console by signaling USB remote wakeup when you: + - **Press Guide (Home)** on the controller, or + - **Hold Start for 3 seconds** (avoids holding Guide on Xbox One/PS5 pads, which can turn the controller off). + - Remote wakeup is advertised in the configuration descriptor; the stack defaults it enabled when supported so wake works even if the host did not send SET_FEATURE before standby. + - **Disclaimer:** Wake only works when the console was previously powered on with the adapter connected and then turned off via the controller (soft shutdown). It **cannot** power on the console from a cold start—e.g. if the console was just plugged in, lost power completely, or was turned off with the front power button. In those cases use the console’s power button to turn it on first. + Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad-ai/joypad-os); a local comparison doc may be kept out of the repo for reference. --- @@ -71,6 +78,11 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad - **PS button latch:** When `BUTTON_SYS` is set, the driver latches the PS bit for 8 consecutive report frames so short taps are not missed by timing. `buttons[2]` bit 0 (PS) and bit 1 (Touchpad) are set from `BUTTON_SYS` and `BUTTON_MISC`. - If Home does not work over Bluetooth, try a wired controller (some consoles only react to the first controller's Home). +6. **Wake console from standby (remote wakeup)** + - The configuration descriptor now advertises **remote wakeup** (`bmAttributes` 0xA0) so the PS3 can suspend the USB bus in standby and the adapter can signal wake. When the console is in standby (turned off via **PS button → Turn off system** or similar, not full power loss), you can wake it by **pressing PS (Home)** or **holding Start for 3 seconds**—**only if the console keeps USB power when off**. + - **Many PS3s cut power to the USB ports** when shut down, so the adapter and controller disconnect and wake is not possible. If your controller stays powered (e.g. charging LED) when the PS3 is off, that model may keep USB in standby and wake may work. Same disclaimer as 360: no wake from cold start; use the console power button first if needed. + - **Recovery Mode:** Even when wake from standby is not possible (e.g. console cuts USB when off), the adapter is **confirmed working in PS3 Recovery Mode** — you can use it to navigate and select options in Recovery. + --- ## Latency reduction @@ -106,12 +118,11 @@ Same goal as Switch Pro and PS3: the only added latency when using a wireless co Both modes: no `new_pad_in()` gate; main loop runs with `MAIN_LOOP_DELAY_US=0` by default; `tud_task()` runs before `process()` so the endpoint is ready when we try to send. -### Xbox OG (Duke) gamepad: report always fresh; send when ready (minimal latency) +### Xbox OG (Duke) gamepad: send only on new input (stability on real hardware) -Same goal as XInput/PS3: reduce input delay when using e.g. a DualShock (DS3/DS4/DualSense) as input while outputting to Original Xbox. +On the Original Xbox, sending a report every poll cycle caused **random disconnects**. The driver was reverted to **only** build and send the HID report when `gamepad.new_pad_in()` is true (v1.0.0a5 behaviour). Rumble handling is unchanged. This differs from XInput/PS3/Switch, which send every loop; the OG Xbox console is sensitive to report timing and the “send when new input” rule avoids disconnects while keeping input responsive. -- **Every** `process()` call: read `get_pad_in()`, build `in_report_` (buttons, triggers, sticks, SYS hold logic), then call `tud_xid::send_report()` when `send_report_ready(0)`. No `new_pad_in()` gate. The XID layer’s `ep_in_buffer` (used for GET_REPORT and interrupt IN) is updated every loop so the console always sees the latest state. -- **File:** `src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp` — `process()` always builds and sends when ready; previously it only updated when `new_pad_in()`, which added one poll period or more of latency. +- **File:** `src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp` — `process()` builds `in_report_` and calls `tud_xid::send_report()` only when `new_pad_in()` and `send_report_ready(0)`. **DualSense (PS5) input when outputting to OG Xbox:** The PS5 USB host no longer skips reports that are byte-identical to the previous one. Previously, “unchanged” reports did not call `set_pad_in()`, so with a polled output (OG Xbox) some transitions or sustained input could be dropped when the host loop was slower than the DualSense report rate. Every DualSense report is now pushed into the gamepad queue so the OG Xbox device always has the latest state. **File:** `src/USBHost/HostDriver/PS5/PS5.cpp` — removed the unchanged-report early return; every report is parsed and passed to `gamepad.set_pad_in()`. @@ -121,6 +132,16 @@ The main loop now calls **`tud_task()` before** `device_driver->process()`. That **Files:** `src/OGXMini/Board/PicoW.cpp`, `Standard.cpp`, `Four_Channel_I2C.cpp` — order is `process_tasks()` → `tud_task()` → `process()` for each gamepad. +--- + +## PS2 (GPIO) / Open PS2 Loader stability + +**Issue:** With a “primed” first response byte (0xFF) before the mode byte, Open PS2 Loader could hang at startup (black screen) when the adapter was connected. + +**Fix:** The PS2 controller (device) response was reverted so the **first response byte is the mode byte** (no leading 0xFF). Protocol and escape-mode response lengths otherwise follow PicoGamepadConverter and DS4toPS2. The main loop drains all pending PS2 transactions each tick so rapid pad init (e.g. OPL at boot) does not desync. Core1 runs Bluetooth when used; Core0 runs the main loop and `psx_device_poll()` so the console sees input correctly. + +**File:** `src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c` — first response byte is the mode byte; no `prime_first_byte()` / leading 0xFF. + ### How to use | Goal | Setting | diff --git a/Firmware/RP2040/src/Descriptors/PS3.h b/Firmware/RP2040/src/Descriptors/PS3.h index 64fde73e..9c9532ce 100644 --- a/Firmware/RP2040/src/Descriptors/PS3.h +++ b/Firmware/RP2040/src/Descriptors/PS3.h @@ -341,7 +341,7 @@ namespace PS3 0x01, // bNumInterfaces 1 0x01, // bConfigurationValue 0x00, // iConfiguration (String Index) - 0x80, // bmAttributes + 0xA0, // bmAttributes (bus powered, remote wakeup — for wake from standby via PS or Start) 0xFA, // bMaxPower 500mA 0x09, // bLength diff --git a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp index 9c0f3c70..a614c528 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp @@ -187,7 +187,7 @@ namespace I2C { }; static constexpr size_t NUM_SLAVES = MAX_GAMEPADS - 1; - static_assert(NUM_SLAVES > 0, "I2CMaster::NUM_SLAVES must be greater than 0 to use I2C"); + // NUM_SLAVES may be 0 when MAX_GAMEPADS==1 (slave-only or master with no I2C slaves) std::array _slaves; @@ -264,7 +264,7 @@ namespace I2C { } static void xbox360w_connect(bool connected, uint8_t idx) { - if (idx < 1 || idx >= MAX_GAMEPADS) { + if (idx < 1 || idx > NUM_SLAVES) { return; } // This function can be called from core1 diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index 42924cad..e70dfcd7 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -220,13 +220,13 @@ void pico_w::run() { } else #endif if (gpio_device_mode) { - /* PS1PS2 on Pico W: run BT on Core1 (same as normal path) so LED and pairing work; drive PS2 protocol from Core0 main loop via psx_device_poll(). */ + /* PS2 on Pico W: same as Switch/PS3 – Core1 = BT, Core0 = main loop. Core1 writes _gamepads, Core0 reads and calls process() + psx_device_poll(). */ const bool ps2_poll_mode = (current_driver == DeviceDriverType::PS1PS2); if (ps2_poll_mode) { psx_device_set_poll_mode(true); - OGXM_LOG("PicoW run: PS2 poll mode set\n"); + OGXM_LOG("PicoW run: PS2 poll mode (BT on Core1, protocol on Core0)\n"); } - OGXM_LOG("PicoW run: GPIO device mode, Core1 = BT (PS2 poll on Core0)\n"); + OGXM_LOG("PicoW run: GPIO device mode\n"); HostInputSource input_src = user_settings.get_input_source(); s_gpio_device_driver = device_driver; if (input_src == HostInputSource::PSX_GPIO) { @@ -241,9 +241,9 @@ void pico_w::run() { } bluepad32::set_gpio_device_process_callback(gpio_device_process_cb, nullptr); if (ps2_poll_mode) { - /* PS2: init BT/LED/BLEServer only on Core1 to avoid CYW43 gpio_add_raw_irq_handler conflict (double-init assert). */ - OGXM_LOG("PicoW run: launching Core1 (BT inited there), no Core0 BT init\n"); - multicore_launch_core1(core1_task); /* BT on Core1; Core0 main loop will call psx_device_poll() */ + /* PS2: BT on Core1 (like Switch/PS3); Core0 main loop does process() + psx_device_poll(). */ + OGXM_LOG("PicoW run: launching Core1 (BT)\n"); + multicore_launch_core1(core1_task); } else { OGXM_LOG("PicoW run: Core0 calling init_bluetooth/set_led/BLEServer\n"); board_api::init_bluetooth(); @@ -288,7 +288,18 @@ void pico_w::run() { static bool mounted_logged = false; static uint32_t loop_count = 0; + const bool ps2_poll_mode = gpio_device_mode && (current_driver == DeviceDriverType::PS1PS2); while (true) { + /* PS2 first: drain before any other work so we respond within byte time (reduces OPL pad-init hang). */ + if (ps2_poll_mode) { + while (psx_device_poll() != 0) + ; + /* Short burst: update report and drain again to catch OPL's rapid init. */ + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) + device_driver->process(i, _gamepads[i]); + while (psx_device_poll() != 0) + ; + } TaskQueue::Core0::process_tasks(); if (!wii_mode) { if (!gpio_device_mode) @@ -304,8 +315,9 @@ void pico_w::run() { GPIOHost::n64_host_poll(_gamepads[0]); } } - if (gpio_device_mode && current_driver == DeviceDriverType::PS1PS2) { - psx_device_poll(); + if (ps2_poll_mode) { + while (psx_device_poll() != 0) + ; if (loop_count != 0 && (loop_count % 10000u) == 0) OGXM_LOG("PicoW run: main loop psx_device_poll tick " + std::to_string(loop_count) + "\n"); } @@ -323,7 +335,8 @@ void pico_w::run() { } loop_count++; #if MAIN_LOOP_DELAY_US > 0 - sleep_us(MAIN_LOOP_DELAY_US); + if (!ps2_poll_mode) + sleep_us(MAIN_LOOP_DELAY_US); #endif } } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp index bb56fffe..88bebae2 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp @@ -30,6 +30,9 @@ void PS1PS2Device::core1_restart_cb() { void PS1PS2Device::initialize() { std::memset(&psx_report_, 0, sizeof(psx_report_)); + /* PS2 protocol is active-low: 0xFF = released, 0 = pressed. Default to all released. */ + psx_report_.buttons1 = 0xFF; + psx_report_.buttons2 = 0xFF; psx_report_.lx = STICK_CENTER; psx_report_.ly = STICK_CENTER; psx_report_.rx = STICK_CENTER; @@ -39,36 +42,35 @@ void PS1PS2Device::initialize() { void PS1PS2Device::process(const uint8_t idx, Gamepad& gamepad) { (void)idx; - if (!gamepad.new_pad_in()) - return; - + /* Always refresh report from gamepad so Core1 (psx_device_main) sees current/last state when it reads inputState. */ Gamepad::PadIn gp = gamepad.get_pad_in(); - psx_report_.buttons1 = 0; - if (gp.dpad & Gamepad::DPAD_UP) psx_report_.buttons1 |= PSX_UP; - if (gp.dpad & Gamepad::DPAD_RIGHT) psx_report_.buttons1 |= PSX_RIGHT; - if (gp.dpad & Gamepad::DPAD_DOWN) psx_report_.buttons1 |= PSX_DOWN; - if (gp.dpad & Gamepad::DPAD_LEFT) psx_report_.buttons1 |= PSX_LEFT; - if (gp.buttons & Gamepad::BUTTON_BACK) psx_report_.buttons1 |= PSX_SELECT; - if (gp.buttons & Gamepad::BUTTON_L3) psx_report_.buttons1 |= PSX_L3; - if (gp.buttons & Gamepad::BUTTON_R3) psx_report_.buttons1 |= PSX_R3; - if (gp.buttons & Gamepad::BUTTON_START) psx_report_.buttons1 |= PSX_START; - - psx_report_.buttons2 = 0; - if (gp.buttons & Gamepad::BUTTON_LB) psx_report_.buttons2 |= PSX_L1; - if (gp.buttons & Gamepad::BUTTON_RB) psx_report_.buttons2 |= PSX_R1; - if (gp.buttons & Gamepad::BUTTON_Y) psx_report_.buttons2 |= PSX_TRI; - if (gp.buttons & Gamepad::BUTTON_B) psx_report_.buttons2 |= PSX_CIR; - if (gp.buttons & Gamepad::BUTTON_A) psx_report_.buttons2 |= PSX_CROSS; - if (gp.buttons & Gamepad::BUTTON_X) psx_report_.buttons2 |= PSX_SQU; - if (gp.trigger_l > 0) psx_report_.buttons2 |= PSX_L2; - if (gp.trigger_r > 0) psx_report_.buttons2 |= PSX_R2; + /* Active-low: start all released (0xFF), clear bit when pressed */ + psx_report_.buttons1 = 0xFF; + if (gp.dpad & Gamepad::DPAD_UP) psx_report_.buttons1 &= ~PSX_UP; + if (gp.dpad & Gamepad::DPAD_RIGHT) psx_report_.buttons1 &= ~PSX_RIGHT; + if (gp.dpad & Gamepad::DPAD_DOWN) psx_report_.buttons1 &= ~PSX_DOWN; + if (gp.dpad & Gamepad::DPAD_LEFT) psx_report_.buttons1 &= ~PSX_LEFT; + if (gp.buttons & Gamepad::BUTTON_BACK) psx_report_.buttons1 &= ~PSX_SELECT; + if (gp.buttons & Gamepad::BUTTON_L3) psx_report_.buttons1 &= ~PSX_L3; + if (gp.buttons & Gamepad::BUTTON_R3) psx_report_.buttons1 &= ~PSX_R3; + if (gp.buttons & Gamepad::BUTTON_START) psx_report_.buttons1 &= ~PSX_START; + + psx_report_.buttons2 = 0xFF; + if (gp.buttons & Gamepad::BUTTON_LB) psx_report_.buttons2 &= ~PSX_L1; + if (gp.buttons & Gamepad::BUTTON_RB) psx_report_.buttons2 &= ~PSX_R1; + if (gp.buttons & Gamepad::BUTTON_Y) psx_report_.buttons2 &= ~PSX_TRI; + if (gp.buttons & Gamepad::BUTTON_B) psx_report_.buttons2 &= ~PSX_CIR; + if (gp.buttons & Gamepad::BUTTON_A) psx_report_.buttons2 &= ~PSX_CROSS; + if (gp.buttons & Gamepad::BUTTON_X) psx_report_.buttons2 &= ~PSX_SQU; + if (gp.trigger_l > 0) psx_report_.buttons2 &= ~PSX_L2; + if (gp.trigger_r > 0) psx_report_.buttons2 &= ~PSX_R2; psx_report_.l2 = gp.trigger_l; psx_report_.r2 = gp.trigger_r; int32_t lx = static_cast(gp.joystick_lx) * 127 / 32767 + STICK_CENTER; - int32_t ly = static_cast(gp.joystick_ly) * -127 / 32767 + STICK_CENTER; + int32_t ly = static_cast(gp.joystick_ly) * 127 / 32767 + STICK_CENTER; /* PS2 left stick Y: up = lower value */ int32_t rx = static_cast(gp.joystick_rx) * 127 / 32767 + STICK_CENTER; int32_t ry = static_cast(gp.joystick_ry) * -127 / 32767 + STICK_CENTER; if (lx < 0) lx = 0; else if (lx > 255) lx = 255; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c index 00ec3659..7d57bed1 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c @@ -58,7 +58,7 @@ volatile PSXInputState *inputState; static void (*core1_function)(void); static bool poll_mode = false; -static uint8_t mode = MODE_DIGITAL; +static uint8_t mode = MODE_ANALOG; static bool config = false; static bool analogLock = false; static uint8_t motorBytes[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -77,7 +77,7 @@ static uint8_t RECV_CMD(void) { } static void initController(void) { - mode = MODE_DIGITAL; + mode = MODE_ANALOG; /* default to DualShock (analog) so sticks work from first poll */ config = false; analogLock = false; memset(motorBytes, 0xFF, sizeof(motorBytes)); @@ -410,13 +410,31 @@ static void init_pio(void) { cmd_reader_program_init(psx_device_pio, smCmdReader, offsetCmdReader); dat_writer_program_init(psx_device_pio, smDatWriter, offsetDatWriter); + pio_enable_sm_mask_in_sync(psx_device_pio, (1u << smCmdReader) | (1u << smDatWriter)); } void psx_device_set_poll_mode(bool enable) { poll_mode = enable; } -/* One iteration of the protocol when in poll mode (Core0-driven, e.g. Pico W with BT on Core1). Return 1 if a poll was processed. */ +#if PSX_DEVICE_POLLED_SEL +/* When Core1 runs psx_device_main(), Core0 must not read the CMD FIFO. Call this from Core0 + * main loop to handle SEL rising edge (restart PIO) only. Does not read from FIFO. */ +void psx_device_sel_restart_check(void) { + static bool last_sel_high = false; + bool sel_high = gpio_get(PIN_SEL); + if (sel_high && !last_sel_high) + restart_pio_sm(); + last_sel_high = sel_high; +} +#else +void psx_device_sel_restart_check(void) { (void)0; } +#endif + +/* One iteration of the protocol when in poll mode (Core0-driven, e.g. Pico W with BT on Core1). + * Return 1 if a transaction was processed, 0 if no data or after desync drain. + * If the first byte is not 0x01 we are desynced (e.g. missed a transaction); drain the RX FIFO + * so the next SEL transaction starts clean. Caller should loop until 0 so OPL/rapid init don't fall behind. */ int psx_device_poll(void) { static bool controller_inited = false; #if PSX_DEVICE_POLLED_SEL @@ -432,9 +450,14 @@ int psx_device_poll(void) { } if (pio_sm_get_rx_fifo_level(psx_device_pio, smCmdReader) == 0) return 0; - uint8_t cmd = (uint8_t)(pio_sm_get(psx_device_pio, smCmdReader) >> 24); - if (cmd == 0x01) - process_joy_req(); + uint8_t first = (uint8_t)(pio_sm_get(psx_device_pio, smCmdReader) >> 24); + if (first != 0x01) { + /* Desynced: drain RX FIFO so next transaction (after SEL cycle) is clean. */ + while (pio_sm_get_rx_fifo_level(psx_device_pio, smCmdReader) > 0) + (void)pio_sm_get(psx_device_pio, smCmdReader); + return 0; + } + process_joy_req(); return 1; } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h index 630787a9..2c691c87 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/psx_simulator.h @@ -35,6 +35,9 @@ void psx_device_main(void); /* When enabled, SEL IRQ only restarts PIO (no Core1 reset). Use with psx_device_poll() on Core0 (e.g. Pico W: BT on Core1, PS2 on Core0). */ void psx_device_set_poll_mode(bool enable); +/* SEL rising-edge check and PIO restart only; does not read CMD FIFO. Use from Core0 when Core1 runs psx_device_main() (Pico W PS2 + OPL). */ +void psx_device_sel_restart_check(void); + /* One poll iteration; call from Core0 main loop when in poll mode. Returns 1 if a command was processed. */ int psx_device_poll(void); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp index e4fa4b49..3e54f120 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp @@ -1,6 +1,7 @@ #include #include +#include "pico/time.h" #include "USBDevice/DeviceDriver/PS3/PS3.h" void PS3Device::initialize() @@ -20,13 +21,41 @@ void PS3Device::initialize() void PS3Device::process(const uint8_t idx, Gamepad& gamepad) { - // Build report only when we're about to send so the console gets the freshest state - // (helps Home button and analog timing with DS4/DS5 over Bluetooth). - if (tud_suspended()) + // Remote wake when host has suspended the bus (e.g. PS3 standby): PS button or Start held 3s (same as 360). { - tud_remote_wakeup(); + static bool start_wake_sent = false; + static bool start_held = false; + static absolute_time_t start_hold_begin = { 0 }; + Gamepad::PadIn gp_wake = gamepad.get_pad_in(); + bool start_pressed = (gp_wake.buttons & Gamepad::BUTTON_START) != 0; + if (start_pressed) + { + if (!start_held) + { + start_held = true; + start_hold_begin = get_absolute_time(); + } + else + { + uint64_t hold_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(start_hold_begin); + if (hold_ms >= 3000 && tud_suspended() && !start_wake_sent) + { + tud_remote_wakeup(); + start_wake_sent = true; + } + } + } + else + { + start_held = false; + start_wake_sent = false; + } + if (tud_suspended() && (gp_wake.buttons & Gamepad::BUTTON_SYS)) + tud_remote_wakeup(); } + // Build report only when we're about to send so the console gets the freshest state + // (helps Home button and analog timing with DS4/DS5 over Bluetooth). if (tud_hid_ready()) { Gamepad::PadIn gp_in = gamepad.get_pad_in(); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp index 92144606..a6c206cc 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XInput/XInput.cpp @@ -1,6 +1,7 @@ #include #include +#include "pico/time.h" #include "tusb.h" #include "USBDevice/DeviceDriver/XInput/tud_xinput/tud_xinput.h" #include "USBDevice/DeviceDriver/XInput/XInput.h" @@ -109,8 +110,39 @@ void XInputDevice::process(const uint8_t idx, Gamepad& gamepad) in_report_.joystick_rx = gp_in.joystick_rx; in_report_.joystick_ry = Range::invert(gp_in.joystick_ry); - if (tud_suspended()) - tud_remote_wakeup(); + // Remote wake when host has suspended the bus (e.g. 360 "off" with USB power kept): + // - Guide (Home) press, or + // - Start held for 3 seconds (avoids holding Guide on Xbox One/PS5 pads, which can turn the controller off). + { + static bool start_wake_sent = false; + static bool start_held = false; + static absolute_time_t start_hold_begin = { 0 }; + bool start_pressed = (gp_in.buttons & Gamepad::BUTTON_START) != 0; + if (start_pressed) + { + if (!start_held) + { + start_held = true; + start_hold_begin = get_absolute_time(); + } + else + { + uint64_t hold_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(start_hold_begin); + if (hold_ms >= 3000 && tud_suspended() && !start_wake_sent) + { + tud_remote_wakeup(); + start_wake_sent = true; + } + } + } + else + { + start_held = false; + start_wake_sent = false; + } + if (tud_suspended() && (gp_in.buttons & Gamepad::BUTTON_SYS)) + tud_remote_wakeup(); + } // send_report() only transmits when endpoint is free; otherwise we keep latest in_report_ for get_report_cb tud_xinput::send_report((uint8_t*)&in_report_, sizeof(XInput::InReport)); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp index 97315031..c1ae1b25 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp @@ -4,151 +4,182 @@ #include "USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h" #include "Gamepad/Gamepad.h" +#if defined(CONFIG_OGXM_DEBUG) +#include +#include "Board/ogxm_log.h" +#endif -void XboxOGDevice::initialize() +void XboxOGDevice::initialize() { +#if defined(CONFIG_OGXM_DEBUG) + OGXM_LOG("XboxOG: initialize\n"); +#endif tud_xid::initialize(tud_xid::Type::GAMEPAD); class_driver_ = *tud_xid::class_driver(); std::memset(&in_report_, 0, sizeof(XboxOG::GP::InReport)); in_report_.report_len = sizeof(XboxOG::GP::InReport); +#if defined(CONFIG_OGXM_DEBUG) + OGXM_LOG("XboxOG: init done\n"); +#endif } void XboxOGDevice::process(const uint8_t idx, Gamepad& gamepad) { - // Build report every loop (same low-latency pattern as XInput/PS3) so GET_REPORT and - // interrupt IN always see latest state; send when endpoint is ready. - std::memset(&in_report_.buttons, 0, 8); - Gamepad::PadIn gp_in = gamepad.get_pad_in(); - - // Guide (SYS) button: tap = Start, hold 1s = soft IGR (LT+RT+Start+Back), hold 3s = shutdown (LT+RT+Up+Back) - bool sys_pressed = (gp_in.buttons & Gamepad::BUTTON_SYS) != 0; - if (sys_pressed && !sys_button_pressed_) + /* Reverted to v1.0.0a5 behaviour: only build/send report when new input (avoids random disconnects on OG Xbox). */ +#if defined(CONFIG_OGXM_DEBUG) + static uint32_t s_process_ticks = 0; + static uint32_t s_send_count = 0; + static uint32_t s_new_pad_in_count = 0; + s_process_ticks++; +#endif + if (gamepad.new_pad_in()) { - sys_button_pressed_ = true; - sys_button_press_time_ = get_absolute_time(); - sys_button_combo_sent_ = false; - } - else if (!sys_pressed && sys_button_pressed_) - { - sys_button_pressed_ = false; - uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); - if (hold_time_ms >= 3000) +#if defined(CONFIG_OGXM_DEBUG) + s_new_pad_in_count++; +#endif + std::memset(&in_report_.buttons, 0, 8); + Gamepad::PadIn gp_in = gamepad.get_pad_in(); + + // Guide (SYS) button: tap = Start, hold 1s = soft IGR (LT+RT+Start+Back), hold 3s = shutdown (LT+RT+Up+Back) + bool sys_pressed = (gp_in.buttons & Gamepad::BUTTON_SYS) != 0; + if (sys_pressed && !sys_button_pressed_) { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.dpad |= Gamepad::DPAD_UP; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; + sys_button_pressed_ = true; + sys_button_press_time_ = get_absolute_time(); + sys_button_combo_sent_ = false; } - else if (hold_time_ms >= 1000) + else if (!sys_pressed && sys_button_pressed_) { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.buttons |= Gamepad::BUTTON_START; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; + sys_button_pressed_ = false; + uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); + if (hold_time_ms >= 3000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.dpad |= Gamepad::DPAD_UP; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else if (hold_time_ms >= 1000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_START; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else + { + gp_in.buttons |= Gamepad::BUTTON_START; + sys_button_combo_sent_ = true; + } } - else + else if (sys_pressed && !sys_button_combo_sent_) { - gp_in.buttons |= Gamepad::BUTTON_START; - sys_button_combo_sent_ = true; + uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); + if (hold_time_ms >= 3000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.dpad |= Gamepad::DPAD_UP; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else if (hold_time_ms >= 1000) + { + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_START; + gp_in.buttons |= Gamepad::BUTTON_BACK; + sys_button_combo_sent_ = true; + } + else + { + gp_in.buttons |= Gamepad::BUTTON_START; + } } - } - else if (sys_pressed && !sys_button_combo_sent_) - { - uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); - if (hold_time_ms >= 3000) + + switch (gp_in.dpad) { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.dpad |= Gamepad::DPAD_UP; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; + case Gamepad::DPAD_UP: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP; + break; + case Gamepad::DPAD_DOWN: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN; + break; + case Gamepad::DPAD_LEFT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_LEFT; + break; + case Gamepad::DPAD_RIGHT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_RIGHT; + break; + case Gamepad::DPAD_UP_LEFT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_LEFT; + break; + case Gamepad::DPAD_UP_RIGHT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_RIGHT; + break; + case Gamepad::DPAD_DOWN_LEFT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_LEFT; + break; + case Gamepad::DPAD_DOWN_RIGHT: + in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_RIGHT; + break; + default: + break; } - else if (hold_time_ms >= 1000) + + if (gp_in.buttons & Gamepad::BUTTON_BACK) in_report_.buttons |= XboxOG::GP::Buttons::BACK; + if (gp_in.buttons & Gamepad::BUTTON_START) in_report_.buttons |= XboxOG::GP::Buttons::START; + if (gp_in.buttons & Gamepad::BUTTON_L3) in_report_.buttons |= XboxOG::GP::Buttons::L3; + if (gp_in.buttons & Gamepad::BUTTON_R3) in_report_.buttons |= XboxOG::GP::Buttons::R3; + + if (gamepad.analog_enabled()) { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.buttons |= Gamepad::BUTTON_START; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; + in_report_.a = gp_in.analog[Gamepad::ANALOG_OFF_A]; + in_report_.b = gp_in.analog[Gamepad::ANALOG_OFF_B]; + in_report_.x = gp_in.analog[Gamepad::ANALOG_OFF_X]; + in_report_.y = gp_in.analog[Gamepad::ANALOG_OFF_Y]; + in_report_.white = gp_in.analog[Gamepad::ANALOG_OFF_LB]; + in_report_.black = gp_in.analog[Gamepad::ANALOG_OFF_RB]; } else { - gp_in.buttons |= Gamepad::BUTTON_START; + if (gp_in.buttons & Gamepad::BUTTON_X) in_report_.x = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_A) in_report_.a = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_Y) in_report_.y = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_B) in_report_.b = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_LB) in_report_.white = 0xFF; + if (gp_in.buttons & Gamepad::BUTTON_RB) in_report_.black = 0xFF; } - } - switch (gp_in.dpad) - { - case Gamepad::DPAD_UP: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP; - break; - case Gamepad::DPAD_DOWN: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN; - break; - case Gamepad::DPAD_LEFT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_LEFT; - break; - case Gamepad::DPAD_RIGHT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_RIGHT; - break; - case Gamepad::DPAD_UP_LEFT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_LEFT; - break; - case Gamepad::DPAD_UP_RIGHT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_UP | XboxOG::GP::Buttons::DPAD_RIGHT; - break; - case Gamepad::DPAD_DOWN_LEFT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_LEFT; - break; - case Gamepad::DPAD_DOWN_RIGHT: - in_report_.buttons = XboxOG::GP::Buttons::DPAD_DOWN | XboxOG::GP::Buttons::DPAD_RIGHT; - break; - default: - break; - } + in_report_.trigger_l = gp_in.trigger_l; + in_report_.trigger_r = gp_in.trigger_r; - if (gp_in.buttons & Gamepad::BUTTON_BACK) in_report_.buttons |= XboxOG::GP::Buttons::BACK; - if (gp_in.buttons & Gamepad::BUTTON_START) in_report_.buttons |= XboxOG::GP::Buttons::START; - if (gp_in.buttons & Gamepad::BUTTON_L3) in_report_.buttons |= XboxOG::GP::Buttons::L3; - if (gp_in.buttons & Gamepad::BUTTON_R3) in_report_.buttons |= XboxOG::GP::Buttons::R3; + in_report_.joystick_lx = gp_in.joystick_lx; + in_report_.joystick_ly = Range::invert(gp_in.joystick_ly); + in_report_.joystick_rx = gp_in.joystick_rx; + in_report_.joystick_ry = Range::invert(gp_in.joystick_ry); - if (gamepad.analog_enabled()) - { - in_report_.a = gp_in.analog[Gamepad::ANALOG_OFF_A]; - in_report_.b = gp_in.analog[Gamepad::ANALOG_OFF_B]; - in_report_.x = gp_in.analog[Gamepad::ANALOG_OFF_X]; - in_report_.y = gp_in.analog[Gamepad::ANALOG_OFF_Y]; - in_report_.white = gp_in.analog[Gamepad::ANALOG_OFF_LB]; - in_report_.black = gp_in.analog[Gamepad::ANALOG_OFF_RB]; - } - else - { - if (gp_in.buttons & Gamepad::BUTTON_X) in_report_.x = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_A) in_report_.a = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_Y) in_report_.y = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_B) in_report_.b = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_LB) in_report_.white = 0xFF; - if (gp_in.buttons & Gamepad::BUTTON_RB) in_report_.black = 0xFF; - } - - in_report_.trigger_l = gp_in.trigger_l; - in_report_.trigger_r = gp_in.trigger_r; - - in_report_.joystick_lx = gp_in.joystick_lx; - in_report_.joystick_ly = Range::invert(gp_in.joystick_ly); - in_report_.joystick_rx = gp_in.joystick_rx; - in_report_.joystick_ry = Range::invert(gp_in.joystick_ry); - - if (tud_suspended()) - { - tud_remote_wakeup(); - } - if (tud_xid::send_report_ready(0)) - { - tud_xid::send_report(0, reinterpret_cast(&in_report_), sizeof(XboxOG::GP::InReport)); + if (tud_suspended()) + { +#if defined(CONFIG_OGXM_DEBUG) + OGXM_LOG("XboxOG: tud_remote_wakeup\n"); +#endif + tud_remote_wakeup(); + } + bool ready = tud_xid::send_report_ready(0); +#if defined(CONFIG_OGXM_DEBUG) + if (ready) + s_send_count++; + if (s_process_ticks % 5000 == 0) + OGXM_LOG("XboxOG: process tick " + std::to_string(s_process_ticks) + " new_pad_in=" + std::to_string(s_new_pad_in_count) + " send_ready=" + std::to_string(ready) + " sent=" + std::to_string(s_send_count) + "\n"); +#endif + if (ready) + { + tud_xid::send_report(0, reinterpret_cast(&in_report_), sizeof(XboxOG::GP::InReport)); + } } if (tud_xid::receive_report(0, reinterpret_cast(&out_report_), sizeof(XboxOG::GP::OutReport))) @@ -160,8 +191,14 @@ void XboxOGDevice::process(const uint8_t idx, Gamepad& gamepad) } } -uint16_t XboxOGDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) +uint16_t XboxOGDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { +#if defined(CONFIG_OGXM_DEBUG) + static uint32_t s_get_report_count = 0; + s_get_report_count++; + if (s_get_report_count <= 5 || s_get_report_count % 1000 == 0) + OGXM_LOG("XboxOG: get_report_cb #" + std::to_string(s_get_report_count) + "\n"); +#endif std::memcpy(buffer, &in_report_, sizeof(in_report_)); return sizeof(XboxOG::GP::InReport); } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.cpp index be40d424..3dc41984 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.cpp @@ -12,6 +12,9 @@ #else #define XREMOTE_ENABLED 0 #endif +#if defined(CONFIG_OGXM_DEBUG) +#include "Board/ogxm_log.h" +#endif namespace tud_xid { @@ -284,6 +287,25 @@ bool xid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c uint8_t index = get_idx_by_itf(static_cast(request->wIndex)); TU_VERIFY(index != 0xFF, false); +#if defined(CONFIG_OGXM_DEBUG) + { + static uint32_t s_ctl_count = 0; + s_ctl_count++; + RequestType rt = get_request_type(request); + const char* rt_str = "UNKNOWN"; + switch (rt) { + case RequestType::GET_REPORT: rt_str = "GET_REPORT"; break; + case RequestType::SET_REPORT: rt_str = "SET_REPORT"; break; + case RequestType::GET_DESC: rt_str = "GET_DESC"; break; + case RequestType::GET_CAPABILITIES_IN: rt_str = "GET_CAP_IN"; break; + case RequestType::GET_CAPABILITIES_OUT: rt_str = "GET_CAP_OUT"; break; + default: break; + } + if (s_ctl_count <= 15 || s_ctl_count % 500 == 0) + OGXM_LOG("XboxOG XID: ctrl #%lu stage=%u %s\n", (unsigned long)s_ctl_count, (unsigned)stage, rt_str); + } +#endif + Interface& interface = interfaces_[index]; bool ret = false; @@ -338,6 +360,11 @@ bool xid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c request->bmRequestType, request->bRequest, request->wValue); +#if defined(CONFIG_OGXM_DEBUG) + OGXM_LOG("XboxOG XID: STALL wIndex=%02x bmReq=%02x bReq=%02x wVal=%04x\n", + (unsigned)request->wIndex, (unsigned)request->bmRequestType, + (unsigned)request->bRequest, (unsigned)request->wValue); +#endif return false; } diff --git a/README.md b/README.md index 4387a27a..7369fec2 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,12 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork: Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. +### Version 1.0.0.7a +- **OG Xbox mode stability** — Report sending was reverted to v1.0.0a5 behaviour: the adapter only builds and sends the HID report when new gamepad input is available (`new_pad_in()`). Sending every poll cycle caused random disconnects on the Original Xbox; the reversion restores stable operation. Rumble handling is unchanged. +- **PS2 (GPIO) / OPL stability** — The PS2 controller protocol response was reverted so the first response byte is the mode byte (no leading 0xFF). This restores compatibility with Open PS2 Loader and games; OPL no longer hangs at startup with the adapter connected. Core layout: Core1 runs Bluetooth when used; Core0 runs the main loop and PS2 device poll. +- **Xbox 360 (XInput) wake from standby** — When the 360 was turned off via **Guide → Turn off console** (soft shutdown), you can power it back on with the controller: **press Guide (Home)** or **hold Start for 3 seconds** (Start is preferred on Xbox One/PS5 pads so the controller doesn’t turn off). **Disclaimer:** The console must have been started at least once with the adapter connected; wake does **not** work from a cold start (e.g. console just plugged in or after a full power loss). In that case turn the console on with the front power button first. +- **PS3 wake from standby** — Same idea as 360: when the PS3 is in standby (turned off via **PS button → Turn off system**), you can wake it with **PS (Home)** or **hold Start for 3 seconds**—**only if the console keeps USB power when off**. Many PS3s cut power to the USB ports when shut down, so the adapter and controller disconnect; in that case wake is not possible. If your controller stays powered (e.g. charging light on) when the PS3 is off, wake may work. Same disclaimer as 360: no wake from cold start. + ### Version 1.0.0.6a - **PS1/PS2 (GPIO) output mode** — The adapter can output to a PS1 or PS2 console as a controller over GPIO (no USB device in this mode). Select via button combo **Start + B** or set a fixed driver build. **Wiring (standard Pico):** connect the board to the console’s controller port using DATA=GP19, COMMAND=GP20, ATTENTION/SEL=GP21, CLOCK=GP22, ACKNOWLEDGE=GP26. Plug your USB gamepad into the adapter’s USB port; the console sees a DualShock-style controller. _Protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ - **GameCube (GPIO) output mode** — The adapter can output to a GameCube or Wii (GameCube ports) as a controller over a single DATA line. Select via button combo **Start + X** or set a fixed driver build. **Wiring (standard Pico):** DATA=GP19, GND=GND; connect to the console’s controller port (single wire + ground). Plug your USB gamepad into the adapter’s USB port. _JoyBus protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ @@ -120,6 +126,12 @@ Note: These features have been added to the Pico W/ Pico 2 W firmware support, I - **Bluetooth input for PS1/PS2, GameCube, Dreamcast, and N64** — On **Pico W** (or Pico 2 W), you can use a **Bluetooth controller** as input while outputting to PS1, PS2, GameCube, Dreamcast, or N64. Select the mode (**Start + B**, **Start + X**, **Start + Y**, or **Start + Right Bumper**) as usual; pair your BT gamepad; the console sees the adapter as a controller. Wiring is the same for each mode (PS1/PS2: DATA/CMD/ATT/CLK/ACK; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10/GP11). - **GPIO input from real PS1/PS2, GameCube, N64, or Dreamcast controllers** — You can use a **real wired PS1/PS2, GameCube, N64, or Dreamcast controller** as the adapter’s input in two ways: (1) **Output to other consoles (Switch, Xbox, DInput, etc.):** set output mode (e.g. **Start + D-pad Down** for Switch), then hold **Start + Select** for ~2.5 s until the input source cycles to **PSX GPIO**, **GameCube GPIO**, **Dreamcast GPIO**, or **N64 GPIO**; plug the real controller into the GPIO pins and connect the adapter’s USB to the target console. (2) **Output to PS1/PS2, GameCube, or Dreamcast:** in that output mode, hold **Start + Select** to set input to the matching GPIO and plug in the real controller (same pins). **Wiring:** PS1/PS2: DATA=GP19, CMD=GP20, ATT=GP21, CLK=GP22; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10, GP11. _PSX host, JoyBus host, N64 host ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ +**PS2 output mode improvements (v1.0.0.6a):** +- **Button polarity (active-low)** — The PS2 controller protocol uses active-low button bytes: **0xFF = released**, **0 = pressed**. The driver was sending 0 when no button was pressed, so the console read all buttons as pressed (e.g. constant D-pad Up and menu scrolling). Fixed by initialising the report with `buttons1 = buttons2 = 0xFF` and clearing bits when a button is pressed, so neutral/no-controller state is correct. +- **Left stick Y axis** — Left analog stick up/down was inverted on output. The mapping for left stick Y was corrected so physical stick up corresponds to the value the PS2 expects for up. +- **Protocol flow** — PS2 device (controller) protocol and escape-mode response lengths follow [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter) and [DS4toPS2](https://github.com/TonyMacDonald1995/DS4toPS2) (single response byte then command, 7-byte escape responses with leading 0x5A) for broad console compatibility. +- **OPL (Open PS2 Loader)** — On Pico W, the main loop now drains all pending PS2 transactions each tick so rapid pad init (e.g. OPL at startup) does not desync or hang. **Keep the controller connected at boot** when using OPL; the PS2 pad driver typically does not re-detect controllers plugged in after an app has started, so unplugging then replugging will not give input in OPL. If OPL hangs (black screen) or inputs stop being registered, **power-cycle the Pico** (unplug and replug the adapter) so the PS2 link resets; the adapter also primes 0xFF after a desync drain so the next transaction is valid. **DualSense (PS5) over Bluetooth:** the Options button (Start) may not be reported as Start by the BT stack in some cases; if Options doesn’t work in OPL or in-game, try an Xbox or other controller, or use the DualSense over USB if your board supports it. + ### Version 1.0.0.5a - **Switch Pro emulation** — Switch output mode now emulates a **Nintendo Switch Pro Controller** over USB (report format, subcommands, init handshake). Face-button and report layout follow the standard Pro Controller protocol (bit layout aligned with hardware/reference). _Switch Pro protocol and button report layout reference: [retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch) (N64/GameCube → Pico → Switch); Bluepad32 Switch parser used for validation._ - **Waveshare RP2350-USB-A board support** — Build with `-DOGXM_BOARD=RP2350_USB_A` for the Waveshare RP2350-USB-A (wired USB host + RGB LED). _Board support from upstream [OGX-Mini](https://github.com/wiredopposite/OGX-Mini/commit/68bdec451077a33b0b1247ce01ed30e470163dea)._ @@ -213,7 +225,10 @@ Build with **CMake** from the `Firmware/RP2040` directory. You can compile for d You can also set ```MAX_GAMEPADS``` (if > 1, only DInput/PS3 and Switch Pro are supported). **Optional:** ```OGXM_FIXED_DRIVER``` to lock output mode (e.g. ```XINPUT```, ```PS3```); ```OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON``` to keep combos when fixed. ```MAIN_LOOP_DELAY_US``` (default ```0```) sets main-loop delay for lower CPU use (e.g. ```250```). -You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. Here's an example on Windows: +You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. + +**Interactive build scripts:** From the project root, run **`scripts/build.sh`** (Linux/macOS) or **`scripts/build.ps1`** (Windows PowerShell) to be guided through board selection, default vs fixed output mode, Release/Debug, and build. The script checks for required tools, creates **`scripts/build`** for the build output, and on failure can optionally save a log in the `scripts` folder. +Here's an example on Windows (manual build): ``` git clone --recursive https://github.com/MegaCadeDev/OGX-Mini-2026.git cd OGX-Mini-2026/Firmware/RP2040 diff --git a/scripts/build.ps1 b/scripts/build.ps1 new file mode 100644 index 00000000..ecc39981 --- /dev/null +++ b/scripts/build.ps1 @@ -0,0 +1,158 @@ +# OGX-Mini 2026 firmware build script (Windows PowerShell) +# Run from anywhere. Creates scripts\build\ and runs CMake/Ninja there; source is Firmware/RP2040. Optional log in scripts\ on failure. + +$ErrorActionPreference = "Stop" +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$RepoRoot = (Resolve-Path (Join-Path $ScriptDir "..")).Path +$FirmwareRp2040 = Join-Path $RepoRoot "Firmware\RP2040" + +if (-not (Test-Path (Join-Path $FirmwareRp2040 "CMakeLists.txt"))) { + Write-Host "Error: Firmware/RP2040/CMakeLists.txt not found. Run this script from the OGX-Mini-2026 repo (scripts\ folder)." -ForegroundColor Red + exit 1 +} + +$Boards = @( + @{ Id = "PI_PICO"; Desc = "Pi Pico" }, + @{ Id = "PI_PICO2"; Desc = "Pi Pico 2" }, + @{ Id = "PI_PICOW"; Desc = "Pi Pico W" }, + @{ Id = "PI_PICO2W"; Desc = "Pi Pico 2 W" }, + @{ Id = "RP2040_ZERO"; Desc = "Waveshare RP2040-Zero" }, + @{ Id = "RP2350_ZERO"; Desc = "Waveshare RP2350-Zero" }, + @{ Id = "RP2350_USB_A"; Desc = "Waveshare RP2350-USB-A" }, + @{ Id = "RP2040_XIAO"; Desc = "Seeed Studio XIAO RP2040" }, + @{ Id = "RP2354"; Desc = "RP2354" }, + @{ Id = "ADAFRUIT_FEATHER"; Desc = "Adafruit Feather USB Host" }, + @{ Id = "EXTERNAL_4CH_I2C"; Desc = "External 4CH I2C" }, + @{ Id = "ESP32_BLUEPAD32_I2C"; Desc = "ESP32 Bluepad32 I2C" }, + @{ Id = "ESP32_BLUERETRO_I2C"; Desc = "ESP32 BlueRetro I2C" } +) + +$FixedDrivers = @( + @{ Id = "XINPUT"; Desc = "Xbox 360 (XInput)" }, + @{ Id = "XBOXOG"; Desc = "Original Xbox (Gamepad)" }, + @{ Id = "PS3"; Desc = "PlayStation 3" }, + @{ Id = "SWITCH"; Desc = "Nintendo Switch Pro" }, + @{ Id = "WIIU"; Desc = "Wii U (GameCube Adapter)" }, + @{ Id = "WII"; Desc = "Wii (Wiimote)" }, + @{ Id = "PS1PS2"; Desc = "PlayStation 1/2 (GPIO)" }, + @{ Id = "GAMECUBE"; Desc = "GameCube (GPIO)" }, + @{ Id = "DREAMCAST"; Desc = "Dreamcast (GPIO)" }, + @{ Id = "N64"; Desc = "Nintendo 64 (GPIO)" }, + @{ Id = "DINPUT"; Desc = "DInput" }, + @{ Id = "PSCLASSIC"; Desc = "PlayStation Classic" }, + @{ Id = "WEBAPP"; Desc = "Web App" } +) + +function Test-Command($name) { + $null -ne (Get-Command $name -ErrorAction SilentlyContinue) +} + +Write-Host "=== OGX-Mini 2026 Build Script ===" -ForegroundColor Cyan +Write-Host "" + +# --- Prerequisites --- +$Missing = @() +if (-not (Test-Command "git")) { $Missing += "git" } +if (-not (Test-Command "python") -and -not (Test-Command "py")) { $Missing += "python" } +if (-not (Test-Command "cmake")) { $Missing += "cmake" } +if (-not (Test-Command "ninja")) { $Missing += "ninja" } +if (-not (Test-Command "arm-none-eabi-gcc")) { $Missing += "arm-none-eabi-gcc" } + +if ($Missing.Count -gt 0) { + Write-Host "Missing required tools: $($Missing -join ', ')" -ForegroundColor Red + Write-Host "" + Write-Host "Install options:" + Write-Host " - Chocolatey: choco install git python cmake ninja gcc-arm-embedded" + Write-Host " - ARM GCC: https://developer.arm.com/downloads/-/gnu-rm (add to PATH)" + Write-Host " - See README.md in the project root for details." + Write-Host "" + $ans = Read-Host "Exit now? [Y/n]" + if ($ans -ne "n" -and $ans -ne "N") { exit 1 } +} + +# --- Board selection --- +Write-Host "Select board:" +for ($i = 0; $i -lt $Boards.Count; $i++) { + Write-Host " $($i+1)) $($Boards[$i].Desc) ($($Boards[$i].Id))" +} +Write-Host " $($Boards.Count + 1)) Cancel" +$boardChoice = Read-Host "Choice [1-$($Boards.Count)]" +if ([int]$boardChoice -eq $Boards.Count + 1) { Write-Host "Cancelled."; exit 0 } +if ([int]$boardChoice -lt 1 -or [int]$boardChoice -gt $Boards.Count) { Write-Host "Invalid choice."; exit 1 } +$OGXM_BOARD = $Boards[[int]$boardChoice - 1].Id + +# --- Combo vs fixed driver --- +Write-Host "" +Write-Host "Build type:" +Write-Host " 1) Default (combos enabled, all modes selectable)" +Write-Host " 2) Fixed output mode (combos disabled, single mode)" +$buildTypeChoice = Read-Host "Choice [1-2]" +$OGXM_FIXED_DRIVER = "" +if ($buildTypeChoice -eq "2") { + Write-Host "Select fixed output mode:" + for ($i = 0; $i -lt $FixedDrivers.Count; $i++) { + Write-Host " $($i+1)) $($FixedDrivers[$i].Desc) ($($FixedDrivers[$i].Id))" + } + Write-Host " $($FixedDrivers.Count + 1)) Cancel" + $driverChoice = Read-Host "Choice [1-$($FixedDrivers.Count)]" + if ([int]$driverChoice -eq $FixedDrivers.Count + 1) { Write-Host "Cancelled."; exit 0 } + if ([int]$driverChoice -lt 1 -or [int]$driverChoice -gt $FixedDrivers.Count) { Write-Host "Invalid choice."; exit 1 } + $OGXM_FIXED_DRIVER = $FixedDrivers[[int]$driverChoice - 1].Id +} + +# --- Release vs Debug --- +Write-Host "" +Write-Host "Build configuration:" +Write-Host " 1) Release (smaller, faster)" +Write-Host " 2) Debug (UART logging, no optimization)" +$configChoice = Read-Host "Choice [1-2]" +$CMAKE_BUILD_TYPE = if ($configChoice -eq "2") { "Debug" } else { "Release" } + +# --- Run build --- +$BuildDir = Join-Path $ScriptDir "build" +if (Test-Path $BuildDir) { Remove-Item -Recurse -Force $BuildDir } +New-Item -ItemType Directory -Path $BuildDir | Out-Null + +Write-Host "" +$fixedInfo = if ($OGXM_FIXED_DRIVER) { " fixed=$OGXM_FIXED_DRIVER" } else { "" } +Write-Host "Building: board=$OGXM_BOARD type=$CMAKE_BUILD_TYPE$fixedInfo" +Write-Host "Output directory: $BuildDir" +Write-Host "" + +$cmakeArgs = @( + "-G", "Ninja", + "-DOGXM_BOARD=$OGXM_BOARD", + "-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" +) +if ($OGXM_FIXED_DRIVER) { + $cmakeArgs += "-DOGXM_FIXED_DRIVER=$OGXM_FIXED_DRIVER" + $cmakeArgs += "-DOGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF" +} + +$buildLog = Join-Path $env:TEMP "ogxm_build_log.txt" +$buildSuccess = $false +try { + Push-Location $BuildDir + & cmake $cmakeArgs $FirmwareRp2040 2>&1 | Tee-Object -FilePath $buildLog + if ($LASTEXITCODE -ne 0) { throw "CMake failed" } + & ninja 2>&1 | Tee-Object -FilePath $buildLog -Append + if ($LASTEXITCODE -ne 0) { throw "Ninja failed" } + $buildSuccess = $true +} finally { + Pop-Location +} + +if ($buildSuccess) { + Write-Host "" + Write-Host "Build completed successfully. Output is in: $BuildDir" -ForegroundColor Green +} else { + Write-Host "" + Write-Host "Build failed. You can save the output to a log file for troubleshooting." -ForegroundColor Yellow + $logPath = Join-Path $ScriptDir "build_log.txt" + $saveLog = Read-Host "Save log to $logPath? [y/N]" + if ($saveLog -match "^[yY]") { + Copy-Item $buildLog $logPath -Force + Write-Host "Log saved to $logPath" + } + exit 1 +} diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 00000000..ca4f1da4 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +# OGX-Mini 2026 firmware build script (Linux / macOS) +# Run from anywhere. Creates scripts/build/ and runs CMake/Ninja there; source is Firmware/RP2040. Optional log in scripts/ on failure. + +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +FIRMWARE_RP2040="$REPO_ROOT/Firmware/RP2040" + +if [ ! -f "$FIRMWARE_RP2040/CMakeLists.txt" ]; then + echo "Error: Firmware/RP2040/CMakeLists.txt not found. Run this script from the OGX-Mini-2026 repo (scripts/ folder)." + exit 1 +fi + +BOARDS=( + "PI_PICO:Pi Pico" + "PI_PICO2:Pi Pico 2" + "PI_PICOW:Pi Pico W" + "PI_PICO2W:Pi Pico 2 W" + "RP2040_ZERO:Waveshare RP2040-Zero" + "RP2350_ZERO:Waveshare RP2350-Zero" + "RP2350_USB_A:Waveshare RP2350-USB-A" + "RP2040_XIAO:Seeed Studio XIAO RP2040" + "RP2354:RP2354" + "ADAFRUIT_FEATHER:Adafruit Feather USB Host" + "EXTERNAL_4CH_I2C:External 4CH I2C" + "ESP32_BLUEPAD32_I2C:ESP32 Bluepad32 I2C" + "ESP32_BLUERETRO_I2C:ESP32 BlueRetro I2C" +) + +FIXED_DRIVERS=( + "XINPUT:Xbox 360 (XInput)" + "XBOXOG:Original Xbox (Gamepad)" + "PS3:PlayStation 3" + "SWITCH:Nintendo Switch Pro" + "WIIU:Wii U (GameCube Adapter)" + "WII:Wii (Wiimote)" + "PS1PS2:PlayStation 1/2 (GPIO)" + "GAMECUBE:GameCube (GPIO)" + "DREAMCAST:Dreamcast (GPIO)" + "N64:Nintendo 64 (GPIO)" + "DINPUT:DInput" + "PSCLASSIC:PlayStation Classic" + "WEBAPP:Web App" +) + +check_cmd() { command -v "$1" &>/dev/null; } + +echo "=== OGX-Mini 2026 Build Script ===" +echo "" + +# --- Prerequisites --- +MISSING=() +check_cmd git || MISSING+=(git) +check_cmd python3 || MISSING+=(python3) +check_cmd cmake || MISSING+=(cmake) +check_cmd ninja || MISSING+=(ninja) +check_cmd arm-none-eabi-gcc || MISSING+=(arm-none-eabi-gcc) + +if [ ${#MISSING[@]} -gt 0 ]; then + echo "Missing required tools: ${MISSING[*]}" + echo "" + echo "Install instructions:" + if check_cmd apt-get; then + echo " Debian/Ubuntu: sudo apt install git python3 cmake ninja-build gcc-arm-none-eabi" + elif check_cmd dnf; then + echo " Fedora: sudo dnf install git python3 cmake ninja gcc-arm-none-eabi-toolchain" + elif check_cmd pacman; then + echo " Arch: sudo pacman -S git python cmake ninja arm-none-eabi-gcc" + elif check_cmd brew; then + echo " macOS (Homebrew): brew install git python cmake ninja arm-none-eabi-gcc" + else + echo " Install: git, python3, cmake, ninja, and the ARM GCC toolchain (arm-none-eabi-gcc)." + echo " See README.md in the project root for details." + fi + echo "" + read -r -p "Exit now? [Y/n] " ans + case "${ans:-Y}" in [nN]) ;; *) exit 1;; esac +fi + +# --- Board selection --- +echo "Select board:" +for i in "${!BOARDS[@]}"; do + IFS=: read -r id desc <<< "${BOARDS[$i]}" + echo " $((i+1))) $desc ($id)" +done +echo " $(( ${#BOARDS[@]} + 1 ))) Cancel" +read -r -p "Choice [1-${#BOARDS[@]}]: " board_choice +if [ "$board_choice" = "$(( ${#BOARDS[@]} + 1 ))" ]; then echo "Cancelled."; exit 0; fi +if [ "$board_choice" -lt 1 ] || [ "$board_choice" -gt ${#BOARDS[@]} ]; then echo "Invalid choice."; exit 1; fi +IFS=: read -r OGXM_BOARD _ <<< "${BOARDS[$((board_choice-1))]}" + +# --- Combo vs fixed driver --- +echo "" +echo "Build type:" +echo " 1) Default (combos enabled, all modes selectable)" +echo " 2) Fixed output mode (combos disabled, single mode)" +read -r -p "Choice [1-2]: " build_type_choice +OGXM_FIXED_DRIVER="" +if [ "$build_type_choice" = "2" ]; then + echo "Select fixed output mode:" + for i in "${!FIXED_DRIVERS[@]}"; do + IFS=: read -r id desc <<< "${FIXED_DRIVERS[$i]}" + echo " $((i+1))) $desc ($id)" + done + echo " $(( ${#FIXED_DRIVERS[@]} + 1 ))) Cancel" + read -r -p "Choice [1-${#FIXED_DRIVERS[@]}]: " driver_choice + if [ "$driver_choice" = "$(( ${#FIXED_DRIVERS[@]} + 1 ))" ]; then echo "Cancelled."; exit 0; fi + if [ "$driver_choice" -lt 1 ] || [ "$driver_choice" -gt ${#FIXED_DRIVERS[@]} ]; then echo "Invalid choice."; exit 1; fi + IFS=: read -r OGXM_FIXED_DRIVER _ <<< "${FIXED_DRIVERS[$((driver_choice-1))]}" +fi + +# --- Release vs Debug --- +echo "" +echo "Build configuration:" +echo " 1) Release (smaller, faster)" +echo " 2) Debug (UART logging, no optimization)" +read -r -p "Choice [1-2]: " config_choice +if [ "$config_choice" = "2" ]; then + CMAKE_BUILD_TYPE=Debug +else + CMAKE_BUILD_TYPE=Release +fi + +# --- Run build --- +BUILD_DIR="$SCRIPT_DIR/build" +rm -rf "$BUILD_DIR" +mkdir -p "$BUILD_DIR" + +echo "" +echo "Building: board=$OGXM_BOARD type=$CMAKE_BUILD_TYPE ${OGXM_FIXED_DRIVER:+fixed=$OGXM_FIXED_DRIVER}" +echo "Output directory: $BUILD_DIR" +echo "" + +BUILD_LOG=$(mktemp) +trap "rm -f '$BUILD_LOG'" EXIT + +( + cd "$BUILD_DIR" + CMAKE_ARGS=(-G Ninja -DOGXM_BOARD="$OGXM_BOARD" -DCMAKE_BUILD_TYPE="$CMAKE_BUILD_TYPE") + [ -n "$OGXM_FIXED_DRIVER" ] && CMAKE_ARGS+=(-DOGXM_FIXED_DRIVER="$OGXM_FIXED_DRIVER" -DOGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF) + cmake "${CMAKE_ARGS[@]}" "$FIRMWARE_RP2040" + ninja +) 2>&1 | tee "$BUILD_LOG" +BUILD_STATUS=${PIPESTATUS[0]} + +if [ "$BUILD_STATUS" -eq 0 ]; then + echo "" + echo "Build completed successfully. Output is in: $BUILD_DIR" +else + echo "" + echo "Build failed. You can save the output to a log file for troubleshooting." + read -r -p "Save log to $SCRIPT_DIR/build_log.txt? [y/N] " save_log + case "${save_log:-N}" in + [yY]|[yY][eE][sS]) + cp "$BUILD_LOG" "$SCRIPT_DIR/build_log.txt" + echo "Log saved to $SCRIPT_DIR/build_log.txt" + ;; + esac + exit 1 +fi From bbaa6a1776256774deece6504338b0f7f522c0ad Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Wed, 18 Mar 2026 14:39:31 -0400 Subject: [PATCH 30/42] v1.0.0a8: Pico W DS4/BT stability, docs, Flydigi, FW version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - FW_VERSION v1.0.0a8 (FWDefines.cmake) - Bluepad32: BLE ads off during Classic ACL, BR inquiry pause, DS4 Pico path, Xbox BLE stale-slot reconnect (submodule → MegaCadeDev/bluepad32 fork) - Tinyusb: default remote wakeup when config advertises RW (submodule fork) - .gitmodules: bluepad32 & tinyusb → MegaCadeDev forks (see Firmware/docs/Submodule_forks.md) - README, CHANGELOG, IMPROVEMENTS, Wired_Controllers; PS2/OG Xbox IGR, etc. Made-with: Cursor --- .gitmodules | 4 +- CHANGELOG.md | 83 ++++ Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/CMakeLists.txt | 2 + Firmware/RP2040/docs/IMPROVEMENTS.md | 88 +++- Firmware/RP2040/docs/Wired_Controllers.md | 123 ++++++ Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 136 +++++- .../board_api_private/board_api_usbh.cpp | 2 +- Firmware/RP2040/src/Gamepad/Gamepad.h | 28 +- .../src/OGXMini/Board/Four_Channel_I2C.cpp | 2 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 11 +- .../RP2040/src/OGXMini/Board/Standard.cpp | 8 +- .../USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp | 15 + .../DeviceDriver/XboxOG/XboxOG_GP.cpp | 118 +++--- .../USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h | 6 - Firmware/RP2040/src/USBHost/HardwareIDs.h | 399 +++++++++++++++++- Firmware/RP2040/src/USBHost/HostManager.h | 19 +- Firmware/docs/Submodule_forks.md | 28 ++ Firmware/external/bluepad32 | 2 +- Firmware/external/tinyusb | 2 +- README.md | 142 ++++--- 21 files changed, 1050 insertions(+), 170 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 Firmware/RP2040/docs/Wired_Controllers.md create mode 100644 Firmware/docs/Submodule_forks.md diff --git a/.gitmodules b/.gitmodules index 55128a87..ac54d661 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "Firmware/external/bluepad32"] path = Firmware/external/bluepad32 - url = https://github.com/ricardoquesada/bluepad32.git + url = https://github.com/MegaCadeDev/bluepad32.git [submodule "Firmware/external/tinyusb"] path = Firmware/external/tinyusb - url = https://github.com/hathach/tinyusb.git + url = https://github.com/MegaCadeDev/tinyusb.git [submodule "Tools/dump-dvd-kit"] path = Tools/dump-dvd-kit url = https://github.com/XboxDev/dump-dvd-kit.git diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..79024c95 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,83 @@ +# Changelog / Version history + +Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). + +--- + +### Version 1.0.0.8a + +- **PS4 (DualShock 4) over Bluetooth (Pico W)** — **OGX-Mini BLE advertising** (phone setup app) runs continuously on the same **CYW43439** radio as **Classic BR/EDR** (DS4). That mix commonly **drops the DS4 link** right after the blue LED. **Fix:** **`gap_advertisements_enable(0)`** before DS4 HID setup and whenever any **ACL** gamepad is ready; **re-enable** when the last Classic pad disconnects (BLE-only pads e.g. DualSense unchanged). Still: **BR inquiry off** during ACL, **no DS4 virtual mouse**, **6 s** PS4 rumble grace. **Docs:** [README](README.md) (Wireless Bluetooth), [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth*). +- **New controller support** — **Flydigi Vader 4 Pro** (DInput mode) added: VID `0xEED1`, PID `0x04B4` in `DINPUT_IDS` in `HardwareIDs.h`. A full list of supported wired controllers by driver type is in [Firmware/RP2040/docs/Wired_Controllers.md](Firmware/RP2040/docs/Wired_Controllers.md); the main [README](README.md) “Adding supported controllers” section explains how to get VID/PID to request more. +- **Bluetooth random disconnect fix (Pico W)** — The main loop on Pico W / Pico 2 W now uses **`sleep_ms(1)`** each iteration (matching [Team-Resurgent/OGX-Mini](https://github.com/Team-Resurgent/OGX-Mini)), so Core1 (BT stack) gets enough CPU time. This reduces random Bluetooth disconnects from Core0 starving the radio stack. (Separate from the **stall watchdog** below, which only disconnects when HID input **stops arriving** while the link still looks connected.) +- **Reconnect after disconnect (OG Xbox / BT)** — After the controller disconnects (e.g. idle), the dongle would show pairing mode but the controller could not reconnect without unplugging the dongle. When the last device disconnects, the platform now calls **`uni_bt_enable_new_connections_unsafe(true)`** so scanning is explicitly re-enabled and the controller can reconnect without power-cycling the dongle. +- **Xbox Series controller (1914) over BLE (Pico 2 W)** — Series pads often send **HID only when inputs change**, unlike 1708 (classic BT) which polls constantly. The **input-stall watchdog** (no HID for N seconds → force disconnect) was **firing while the pad was simply idle**, so the link dropped within ~1 minute and reconnect looked broken. **Fix:** **No stall disconnect for BLE Xbox** (`hids_cid` path). **Keepalive** (zero rumble write every **12 s**) remains so idle sessions stay alive. **Reconnect:** if the same Xbox BLE pad advertises again while a **disconnected-but-ready** slot still exists (before HCI teardown), Bluepad32 used to **ignore** the ad — **now** that stale Xbox BLE slot is **deleted** so pairing can complete and inputs work. +- **BT input path — avoid stalling the stack (root cause mitigation)** — HID callbacks run on **Core1**; they previously called **`set_pad_in()`**, which used a **blocking mutex** also taken by Core0. If Core0 held the lock (e.g. during `get_pad_in()`), Core1 could block **inside the Bluetooth stack** for a long time, starving HCI/L2CAP and contributing to “connected but no inputs” / zombie-link behaviour. **Fix:** Bluetooth now uses **`set_pad_in_from_bluetooth()`** — lock-free staging merged into the queue on Core0 inside **`get_pad_in()`**. Wired/USB hosts still use **`set_pad_in()`**. Pad-in queue depth increased **2 → 8** for extra headroom. +- **BT “zombie link” (inputs die, stick stuck, can’t reconnect)** — If the link still dies with no HID delivery (controller firmware / radio / CYW43), OG Xbox mode keeps the **last** USB report until disconnect. **Safety net:** if **no gamepad HID callback** for **8 seconds**, we **`uni_hid_device_disconnect()`** so you can reconnect without power-cycling the dongle. +- **OG Xbox random disconnect** — Already addressed in 1.0.0.7a: reports are built and sent only when `new_pad_in()` is true (Team-Resurgent timing). Sending every poll caused disconnects on some OG Xbox setups. +- **PS2 (GPIO) loads as controller faster** — On Pico W, the main loop runs **PS2 poll first** each tick: drain all pending PS2 transactions, then update the report and drain again so the adapter responds within byte time. This reduces OPL pad-init hang and helps the console see the controller quickly at boot. Together with the first response byte being the mode byte (no leading 0xFF), PS2/OPL compatibility and “load as controller” speed are improved. +- **IGR and shutdown combos (OG Xbox and PS2)** + - **PS2 (GPIO):** **Home only** = IGR → sends **L1+L2+R1+R2+Start+Select** (triggers full). **Home+Start** = shutdown → sends **L1+L2+R1+R2+L3+R3** (triggers full). + - **OG Xbox:** **Guide only** = IGR → **LT+RT+Start+Back**. **Shutdown** = **LT+RT+Back+White** (triggers full): hold **Guide + Menu (Start)** *or* **Guide + View (Back)**. Xbox BT often does not report Menu while Guide is held, so **Guide+View** is the reliable chord on Xbox pads. Physical Start is cleared on shutdown so the console does not see an extra Start (that prevented some softmods from accepting the combo). +- **Build scripts for new users** — Interactive build scripts let you build firmware without memorizing CMake options. From the project root: **Linux/macOS:** `./scripts/build.sh`; **Windows (PowerShell):** `.\scripts\build.ps1`. The script checks prerequisites (git, python3, cmake, ninja, arm-none-eabi-gcc), prompts for board, default vs fixed output mode, and Release/Debug, then builds into `scripts/build/`. See the main [README](README.md) Build section for details. + +--- + +### Version 1.0.0.7a +- **OG Xbox mode stability** — Report sending matches Team-Resurgent: the adapter only builds and sends the HID report when new gamepad input is available (`new_pad_in()`). Sending every poll cycle caused random disconnects on the Original Xbox. Guide combos kept: **Guide only** = IGR, **Guide+Start** = shutdown. Rumble handling is unchanged. +- **PS2 (GPIO) / OPL stability** — The PS2 controller protocol response was reverted so the first response byte is the mode byte (no leading 0xFF). This restores compatibility with Open PS2 Loader and games; OPL no longer hangs at startup with the adapter connected. Core layout: Core1 runs Bluetooth when used; Core0 runs the main loop and PS2 device poll. +- **PS2 and OG Xbox — Home/Guide IGR and shutdown** — Same interaction on both: **Home only** = **restart (IGR)**; **Home+Start** = **shutdown**. PS2: Home only sends L1+L2+R1+R2+Start+Select (OPL IGR), Home+Start sends L1+L2+R1+R2+L3+R3. OG Xbox: Guide only sends LT+RT+Start+Back (IGR), Guide+Start sends LT+RT+Back+White. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md#ps2-gpio-and-og-xbox--homeguide-igr-and-shutdown). +- **Xbox 360 (XInput) wake from standby** — When the 360 was turned off via **Guide → Turn off console** (soft shutdown), you can power it back on with the controller: **press Guide (Home)** or **hold Start for 3 seconds** (Start is preferred on Xbox One/PS5 pads so the controller doesn't turn off). **Disclaimer:** The console must have been started at least once with the adapter connected; wake does **not** work from a cold start (e.g. console just plugged in or after a full power loss). In that case turn the console on with the front power button first. +- **PS3 wake from standby** — Same idea as 360: when the PS3 is in standby (turned off via **PS button → Turn off system**), you can wake it with **PS (Home)** or **hold Start for 3 seconds**—**only if the console keeps USB power when off**. Many PS3s cut power to the USB ports when shut down, so the adapter and controller disconnect; in that case wake is not possible. If your controller stays powered (e.g. charging light on) when the PS3 is off, wake may work. Same disclaimer as 360: no wake from cold start. + +### Version 1.0.0.6a +- **PS1/PS2 (GPIO) output mode** — The adapter can output to a PS1 or PS2 console as a controller over GPIO (no USB device in this mode). Select via button combo **Start + B** or set a fixed driver build. **Wiring (standard Pico):** connect the board to the console's controller port using DATA=GP19, COMMAND=GP20, ATTENTION/SEL=GP21, CLOCK=GP22, ACKNOWLEDGE=GP26. Plug your USB gamepad into the adapter's USB port; the console sees a DualShock-style controller. _Protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ +- **GameCube (GPIO) output mode** — The adapter can output to a GameCube or Wii (GameCube ports) as a controller over a single DATA line. Select via button combo **Start + X** or set a fixed driver build. **Wiring (standard Pico):** DATA=GP19, GND=GND; connect to the console's controller port (single wire + ground). Plug your USB gamepad into the adapter's USB port. _JoyBus protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ +- **N64 (GPIO) output mode** — The adapter can output to a Nintendo 64 console as a controller over a single DATA line. Select via button combo **Start + Right Bumper** or set a fixed driver build. **Wiring (standard Pico):** DATA=GP19, GND=GND; connect to the N64 controller port (same pin as GameCube). Use any **wired (USB)** or **Bluetooth** (Pico W / Pico 2 W) gamepad as input. _Protocol and PIO send code ported from [pdaxrom/usb2n64-adapter](https://github.com/pdaxrom/usb2n64-adapter). Memory pak and rumble pak are not emulated._ +- **Dreamcast (Maple Bus)** — **Input:** Read a real Dreamcast controller over GPIO (Pin A=GP10, B=GP11). **Output:** Use a USB or **Bluetooth** gamepad to control a Dreamcast: select **Start + Y** for Dreamcast mode, connect your BT or USB pad, wire the adapter's Maple Bus (GP10/GP11) to the console's controller port. Core1 runs the Maple device (responds to device info and GET_CONDITION); Core0 feeds gamepad state from USB/BT. When input source is **Dreamcast GPIO**, the bus is used as host only (read a DC pad). See [Dreamcast Port guide](Firmware/RP2040/docs/Dreamcast_Port.md). Maple Bus from [DreamPicoPort](https://github.com/OrangeFox86/DreamPicoPort). +- **Pin-outs and default mappings** — See [GPIO Output Pin-Out and Mappings](Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md) for pin numbers (PS1/PS2, Dreamcast, GameCube, N64) and default button/stick mappings for each mode. +- **Bluetooth input for PS1/PS2, GameCube, Dreamcast, and N64** — On **Pico W** (or Pico 2 W), you can use a **Bluetooth controller** as input while outputting to PS1, PS2, GameCube, Dreamcast, or N64. Select the mode (**Start + B**, **Start + X**, **Start + Y**, or **Start + Right Bumper**) as usual; pair your BT gamepad; the console sees the adapter as a controller. Wiring is the same for each mode (PS1/PS2: DATA/CMD/ATT/CLK/ACK; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10/GP11). +- **GPIO input from real PS1/PS2, GameCube, N64, or Dreamcast controllers** — You can use a **real wired PS1/PS2, GameCube, N64, or Dreamcast controller** as the adapter's input in two ways: (1) **Output to other consoles (Switch, Xbox, DInput, etc.):** set output mode (e.g. **Start + D-pad Down** for Switch), then hold **Start + Select** for ~2.5 s until the input source cycles to **PSX GPIO**, **GameCube GPIO**, **Dreamcast GPIO**, or **N64 GPIO**; plug the real controller into the GPIO pins and connect the adapter's USB to the target console. (2) **Output to PS1/PS2, GameCube, or Dreamcast:** in that output mode, hold **Start + Select** to set input to the matching GPIO and plug in the real controller (same pins). **Wiring:** PS1/PS2: DATA=GP19, CMD=GP20, ATT=GP21, CLK=GP22; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10, GP11. _PSX host, JoyBus host, N64 host ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ + +**PS2 output mode improvements (v1.0.0.6a):** +- **Button polarity (active-low)** — The PS2 controller protocol uses active-low button bytes: **0xFF = released**, **0 = pressed**. The driver was sending 0 when no button was pressed, so the console read all buttons as pressed (e.g. constant D-pad Up and menu scrolling). Fixed by initialising the report with `buttons1 = buttons2 = 0xFF` and clearing bits when a button is pressed, so neutral/no-controller state is correct. +- **Left stick Y axis** — Left analog stick up/down was inverted on output. The mapping for left stick Y was corrected so physical stick up corresponds to the value the PS2 expects for up. +- **Protocol flow** — PS2 device (controller) protocol and escape-mode response lengths follow [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter) and [DS4toPS2](https://github.com/TonyMacDonald1995/DS4toPS2) (single response byte then command, 7-byte escape responses with leading 0x5A) for broad console compatibility. +- **OPL (Open PS2 Loader)** — On Pico W, the main loop now drains all pending PS2 transactions each tick so rapid pad init (e.g. OPL at startup) does not desync or hang. **Keep the controller connected at boot** when using OPL; the PS2 pad driver typically does not re-detect controllers plugged in after an app has started, so unplugging then replugging will not give input in OPL. If OPL hangs (black screen) or inputs stop being registered, **power-cycle the Pico** (unplug and replug the adapter) so the PS2 link resets; the adapter also primes 0xFF after a desync drain so the next transaction is valid. **DualSense (PS5) over Bluetooth:** the Options button (Start) may not be reported as Start by the BT stack in some cases; if Options doesn't work in OPL or in-game, try an Xbox or other controller, or use the DualSense over USB if your board supports it. + +### Version 1.0.0.5a +- **Switch Pro emulation** — Switch output mode now emulates a **Nintendo Switch Pro Controller** over USB (report format, subcommands, init handshake). Face-button and report layout follow the standard Pro Controller protocol (bit layout aligned with hardware/reference). _Switch Pro protocol and button report layout reference: [retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch) (N64/GameCube → Pico → Switch); Bluepad32 Switch parser used for validation._ +- **Waveshare RP2350-USB-A board support** — Build with `-DOGXM_BOARD=RP2350_USB_A` for the Waveshare RP2350-USB-A (wired USB host + RGB LED). _Board support from upstream [OGX-Mini](https://github.com/wiredopposite/OGX-Mini/commit/68bdec451077a33b0b1247ce01ed30e470163dea)._ +- **Additional board support** — **RP2350_ZERO** (Waveshare RP2350-Zero), **RP2040_XIAO** (Seeed Studio XIAO RP2040), and **RP2354**. All use the same Standard (PIO-USB host) firmware path; build with `-DOGXM_BOARD=RP2350_ZERO`, `RP2040_XIAO`, or `RP2354`. _Board support from [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ +- **8BitDo XInput (Xbox 360) fix** — Wired 8BitDo controllers (VID 0x2DC8, PID 0x3016 / 0x3106) are detected and sent a repeating LED-off keepalive so they stay connected and stable. _From [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ +- **Switch analog stick sensitivity** — Slight sensitivity increase (1.2× gain) for analog sticks in Switch Pro emulation mode; configurable via `STICK_GAIN_NUM` / `STICK_GAIN_DEN` in `Switch.cpp`. +- **Original Xbox (OG) Guide button behavior** — In OG Xbox mode, the Guide (SYS) button is mapped to Start; **tap** = Start, **hold 1 s** = soft IGR (LT+RT+Start+Back), **hold 3 s** = system shutdown (LT+RT+D-pad Up+Back). _Implementation based on [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ + +### Version 1.0.0.4a +- **Wii (Wiimote) output mode** — On Pico W and Pico 2 W, build with `-DOGXM_FIXED_DRIVER=WII` for a Wii-only firmware. The adapter appears as a Wiimote over Bluetooth; use a USB gamepad on the external PIO USB port. Supports No Extension, Nunchuk, and Classic Controller report modes (cycle with Home + D-pad Down). See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). _Approach and mappings based on [PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)._ +- Xbox 360 no longer requires the USB patch to authenticate, uses the same authentication as Joypad-OS to do official handshake with Retail consoles. Homebrew/ Jailbreaking is no longer required to use the XINPUT mode on 360 but it will no longer output to PC. +- **Rumble fix for Xbox 360 controllers** — Rumble on 360 pads is now handled correctly when using the adapter (including wireless RUMBLE_ENABLE sequence). _Xbox 360 vibration/rumble handling attributed to [faithvoid](https://github.com/faithvoid) on GitHub._ +- **Pico 2 / Pico 2 W build fixes** — Firmware builds and runs correctly on RP2350 (Pico 2 and Pico 2 W). +- Improved latency on Xbox 360 and PS3 controllers. +- **PS3 mode:** Home (PS) button works with DS4/DS5 over Bluetooth (8-frame latch so short taps register). Analog sticks now match DualShock 3 spec: full 0–255 range, center 0x80 (128), ~1.5% deadzone for accurate emulation. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md#ps3-mode--input-delays-stuck-inputs-home-button-and-analog-stick-emulation). +- Added build flags so you can make it only output in a specific mode and disable mode switching. +- Using a PS5 controller allows you to tap the touchpad to enable or disable the adaptive triggers. + +### Version 1.0.0.3a patched +- Ability to emulate the GameCube controller adapter for Wii U. (Also tested on Switch 1/ 2) +- Wii U & Switch Pro controllers are supported fully with working LT and RT +- Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. +- Disconnection Combo has been added: Start+Select for most controllers, L3+R3 for OUYA controllers. + +## Features new to v1.0.0 +- Bluetooth functionality for the Pico W, Pico 2 W, and Pico+ESP32. +- Web application (connectable via USB or Bluetooth) for configuring deadzones and buttons mappings, supports up to 8 saved profiles. +- Pi Pico 2 and Pico 2 W (RP2350) support. +- Reduced latency by about 3-4 ms, graphs showing comparisons are coming. +- 4 channel functionality, connect 4 Picos and use one Xbox 360 wireless adapter to control all 4. +- Delayed USB mount until a controller is plugged in, useful for internal installation (non-Bluetooth boards only). +- Generic HID controller support. +- Dualshock 3 emulation (minus gyros), rumble now works. +- Steel Battalion controller emulation with a wireless Xbox 360 chatpad. +- Xbox DVD dongle emulation. You must provide or dump your own dongle firmware, see the Tools directory. +- Analog button support on OG Xbox and PS3. +- RGB LED support for RP2040-Zero and Adafruit Feather boards. diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index f21b319f..6996e011 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a7") \ No newline at end of file +set(FW_VERSION "v1.0.0a8") \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 886a79db..f23b9b1f 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -542,6 +542,8 @@ endif() if(EN_BLUETOOTH) add_subdirectory(${BLUEPAD32_ROOT}/src/components/bluepad32 libbluepad32) + # Propagate to bluepad32 sources (e.g. DS4 parser): CYW43-specific link + setup path + target_compile_definitions(bluepad32 PRIVATE OGXM_BLUEPAD32_PICO_W=1) endif() add_subdirectory(${LIBFIXMATH_PATH} libfixmath) diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 5f8b0054..7899e728 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -2,7 +2,7 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. -**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). +**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). --- @@ -118,9 +118,9 @@ Same goal as Switch Pro and PS3: the only added latency when using a wireless co Both modes: no `new_pad_in()` gate; main loop runs with `MAIN_LOOP_DELAY_US=0` by default; `tud_task()` runs before `process()` so the endpoint is ready when we try to send. -### Xbox OG (Duke) gamepad: send only on new input (stability on real hardware) +### Xbox OG (Duke) gamepad: send only on new input (match Team-Resurgent) -On the Original Xbox, sending a report every poll cycle caused **random disconnects**. The driver was reverted to **only** build and send the HID report when `gamepad.new_pad_in()` is true (v1.0.0a5 behaviour). Rumble handling is unchanged. This differs from XInput/PS3/Switch, which send every loop; the OG Xbox console is sensitive to report timing and the “send when new input” rule avoids disconnects while keeping input responsive. +Report build/send timing matches [Team-Resurgent/OGX-Mini](https://github.com/Team-Resurgent/OGX-Mini): the HID report is built and sent **only** when `gamepad.new_pad_in()` is true. Sending every poll caused random disconnects on some OG Xbox setups; the “send when new input” rule avoids that. Guide (SYS) combos are kept: **Guide only** = IGR (LT+RT+Start+Back), **Guide+Start** = shutdown (LT+RT+Back+White). Rumble handling is unchanged. - **File:** `src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp` — `process()` builds `in_report_` and calls `tud_xid::send_report()` only when `new_pad_in()` and `send_report_ready(0)`. @@ -142,6 +142,26 @@ The main loop now calls **`tud_task()` before** `device_driver->process()`. That **File:** `src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c` — first response byte is the mode byte; no `prime_first_byte()` / leading 0xFF. +--- + +## PS2 (GPIO) and OG Xbox — Home/Guide IGR and shutdown + +**Goal:** Use the Home (PS2) or Guide (OG Xbox) button for in-game reset (IGR) and console shutdown with the same interaction pattern on both platforms: **Home only** = restart (IGR), **Home+Start** = shutdown. + +### PS2 (GPIO) mode + +**Files:** `src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp`, `PS1PS2.h` + +- **Home only** — Sends the OPL in-game reset combo: **L1+L2+R1+R2+Start+Select** (triggers full). The console restarts the game / returns to OPL. +- **Home+Start** — Sends shutdown combo: **L1+L2+R1+R2+L3+R3** (triggers full). The console shuts down. + +### OG Xbox mode + +**Files:** `src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp`, `XboxOG_GP.h` + +- **Guide only** — Sends IGR (restart) combo: **LT+RT+Start+Back** (triggers full). The console performs a soft reset / returns to dashboard (or IGR handler). +- **Guide+Start** — Sends shutdown combo: **LT+RT+Back+White** (triggers full). The console shuts down. + ### How to use | Goal | Setting | @@ -193,6 +213,51 @@ Some 8BitDo wired XInput controllers (VID 0x2DC8, PID 0x3016 or 0x3106) can disc --- +## Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth (BR/EDR) stability + +**Context:** On **CYW43439** (Pico W / Pico 2 W), **BLE** and **Classic Bluetooth (BR/EDR)** share one radio. **DualShock 4** uses **Classic ACL** only. **DualSense**, **Xbox Series (BLE)**, and **Switch Pro** (typical pairing) use **LE** — so DS4 was uniquely sensitive to how the stack used the radio at the same time as other activity. + +### 1. BLE advertising vs Classic ACL (main DS4 drop fix) + +**OGX-Mini** starts **BLE advertising** via **BLEServer** so the **phone / web app** can discover the adapter. If that advertising stays on while a **Classic** gamepad (DS4, DualShock 3 BT, Xbox 360 wireless) holds an **ACL** link, the connection often **dies within seconds** (e.g. blue LED then disconnect). + +- **`gap_advertisements_enable(0)`** at the **start of DS4 HID setup** (before lightbar / calibration traffic), and again whenever **any** ready gamepad uses **`GAP_CONNECTION_ACL`**. +- **`gap_advertisements_enable(1)`** when the **last** Classic pad disconnects (BLE-only controllers, e.g. DualSense still connected, are unaffected by this rule). + +**Files:** `Firmware/external/bluepad32/.../parser/uni_hid_parser_ds4.c` (OGXM Pico path), `Firmware/RP2040/src/Bluepad32/Bluepad32.cpp`. + +**User impact:** While a **Classic Bluetooth** controller is connected, the adapter **does not advertise** for the BLE web app. Disconnect that controller (or use **USB** for setup) to use **Bluetooth** in the web app again. + +### 2. BR/EDR inquiry while Classic is connected + +**Periodic inquiry** (scanning for new gamepads) **plus** an active **Classic ACL** also contends on the same radio and contributed to **short-lived DS4** links. + +- **`uni_bt_bredr_scan_stop()`** at the beginning of DS4 setup and when any **ACL** pad becomes **ready**. +- **`uni_bt_bredr_scan_start()`** when the **last** Classic pad disconnects (if scanning is still enabled globally). + +**File:** `Bluepad32.cpp` (and DS4 setup in `uni_hid_parser_ds4.c`). + +### 3. DS4 virtual “touchpad mouse” disabled on Pico + +Bluepad32 can register a **second virtual HID device** (mouse) on the same DS4 link. On Pico W that path was linked to **unstable links**; the OGX build (**`OGXM_BLUEPAD32_PICO_W`**) **does not create** that virtual device. **DualSense** still uses its normal setup (virtual child rejected in `device_ready` where applicable). + +**File:** `uni_hid_parser_ds4.c` (CMake defines `OGXM_BLUEPAD32_PICO_W=1` for the Bluepad32 library in `Firmware/RP2040/CMakeLists.txt`). + +### 4. PS4 rumble / FF grace period + +For **`CONTROLLER_TYPE_PS4Controller`**, **rumble output** is **delayed ~6 seconds** after connect so the host cannot push force-feedback during the fragile init window. + +**File:** `Bluepad32.cpp` — `send_feedback_cb` / `device_ready_cb`. + +### 5. Related Pico W Bluetooth improvements (see also Summary table) + +- **Core0 `sleep_ms(1)`** in the main loop so Core1 (BT stack) gets CPU time ([Team-Resurgent/OGX-Mini](https://github.com/Team-Resurgent/OGX-Mini) pattern). +- **Lock-free Bluetooth input path** (`set_pad_in_from_bluetooth`) so HID callbacks never block on Core0’s mutex. +- **Reconnect:** last device disconnect calls **`uni_bt_enable_new_connections_unsafe(true)`** so pairing can resume without power-cycling. +- **8 s input-stall disconnect** (non-virtual, non-BLE-Xbox) to clear zombie links; **BLE Xbox** uses keepalive instead of stall disconnect. + +--- + ## Switch Pro — analog stick sensitivity A configurable sensitivity gain is applied to the analog sticks in Switch Pro emulation. Raw stick values (outside the deadzone) are scaled by **STICK_GAIN_NUM / STICK_GAIN_DEN** (default 120/100 = 1.2×) before mapping to the 12-bit Switch report. The same physical deflection produces slightly larger output for a more responsive feel. @@ -201,12 +266,29 @@ A configurable sensitivity gain is applied to the analog sticks in Switch Pro em --- +## Build scripts (new users) + +To build firmware without memorizing CMake options, use the interactive build scripts from the **project root**: + +| Platform | Command | +|----------|---------| +| **Linux / macOS** | `./scripts/build.sh` | +| **Windows (PowerShell)** | `.\scripts\build.ps1` | + +The script checks for required tools (git, python3, cmake, ninja, arm-none-eabi-gcc) and prints install hints if something is missing. It then prompts for: (1) board (Pi Pico, Pico W, Pico 2 W, RP2040-Zero, XIAO, Feather, 4CH I2C, ESP32 hybrid, etc.); (2) default (all modes via combos) or fixed output mode (e.g. Wii, GameCube, N64); (3) Release or Debug. Build output (`.uf2`, `.elf`) is written to **`scripts/build/`**; on failure you can save a log to `scripts/build_log.txt`. See the main [README](../../../README.md) Build section for the full description. + +--- + ## Summary | Area | Improvement | |------|-------------| | **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. Report built every loop, send when endpoint ready — same minimal-latency pattern as Switch/PS3. | | **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. | +| **PS2 (GPIO)** | Home only = IGR (L1+L2+R1+R2+Start+Select); Home+Start = shutdown (L1+L2+R1+R2+L3+R3). OPL and protocol stability (first response byte = mode byte). | +| **OG Xbox** | Guide only = IGR. Shutdown = LT+RT+Back+White via **Guide+Start** or **Guide+View (Back)**; Xbox BT often omits Start while Guide is held. Shutdown report strips Start so the chord matches BIOS/softmod expectations. | | **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. | | **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). | | **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). Switch Pro and PS3 always build report every loop so host poll (`get_report`) and IN push both see current state — only remaining delay is BT radio when wireless. | +| **Build** | Interactive scripts `scripts/build.sh` (Linux/macOS) and `scripts/build.ps1` (Windows) for board selection, fixed/default mode, and Release/Debug; output in `scripts/build/`. See [README](../../../README.md) Build section. | +| **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in; re-enable scan on last disconnect. | diff --git a/Firmware/RP2040/docs/Wired_Controllers.md b/Firmware/RP2040/docs/Wired_Controllers.md new file mode 100644 index 00000000..0eff25e6 --- /dev/null +++ b/Firmware/RP2040/docs/Wired_Controllers.md @@ -0,0 +1,123 @@ +# Wired controllers (USB input) + +This document lists controllers supported when connected to the OGX-Mini adapter **via a wired (USB) connection**. These work as input when the adapter is outputting to any supported platform (Original Xbox, Xbox 360, Switch, PS3, DInput, PS1/PS2 GPIO, Dreamcast, GameCube, N64, etc.). + +**Note:** Some third‑party controllers change their VID/PID depending on mode; they may need to be set to the correct mode (e.g. XInput, DInput, or Switch) to be recognized. + +--- + +## By driver type + +### XInput (Xbox 360, Xbox One, Xbox Series) + +- **Microsoft:** Xbox 360 (wired and wireless with PC receiver), Xbox One, Xbox Series, Xbox Elite +- **Third‑party:** Controllers that identify as XInput over USB (e.g. many 8BitDo, PowerA, PDP, Afterglow when in XInput mode) + +*Matched by USB class; no fixed VID/PID list. UsbdSecPatch is not required on Xbox 360.* + +--- + +### PlayStation 3 (DualShock 3 and compatible) + +- Sony DualShock 3 (Dualshock 3 / Batoh) +- Sony DualShock 3 (alternate/clone VID) +- Razer Panthera (PS3) +- Afterglow PS3 (multiple models) +- Bigben, Gioteck, Hori (Fighting Commander, Horipad, Fightstick), Mad Catz (Fightstick, Fightpad), PDP, PowerA, Nyko, and other PS3‑protocol controllers + +*See `PS3_IDS` in `HardwareIDs.h` for the full VID/PID list.* + +--- + +### PlayStation 4 (DualShock 4 and compatible) + +- Sony DualShock 4 (all revisions) +- Sony DS4 wireless adapter (USB dongle) +- Hori Fighting Commander 4, Hori PS4 Mini +- Brook, Nacon, PDP, PowerA, Razer (Raiju), Scuf, Victrix, and other DS4‑protocol controllers + +*See `PS4_IDS` in `HardwareIDs.h` for the full VID/PID list.* + +--- + +### PlayStation 5 (DualSense and compatible) + +- Sony DualSense (PS5) +- Sony DualSense Edge (PS5) +- Sony PS5 Access Controller + +*See `PS5_IDS` in `HardwareIDs.h` for the full VID/PID list.* + +--- + +### Nintendo Switch (Pro and wired) + +- **Switch Pro / Joy‑Con / Wii U Pro:** + Nintendo Switch Pro Controller, Wii U Pro Controller, Joy‑Con (L/R), Nintendo Switch 2 Pro Controller +- **Wired Switch:** + PowerA (wired, Enhanced, Fusion, Spectra, Arcade Stick, Fusion Pro), Hori (Pokken, Horipad for Switch / Switch 2), Afterglow Deluxe, Faceoff Deluxe, and other wired Switch controllers + +*See `SWITCH_PRO_IDS` and `SWITCH_WIRED_IDS` in `HardwareIDs.h` for the full VID/PID list.* + +--- + +### PlayStation Classic + +- PlayStation Classic controller (official) + +*See `PSCLASSIC_IDS` in `HardwareIDs.h`.* + +--- + +### Nintendo 64 (USB) + +- Retrolink N64 USB gamepad +- Hyperkin Admiral N64, Hyperkin N64 Controller Adapter +- Mayflash N64 Adapter + +*See `N64_IDS` in `HardwareIDs.h` for the full VID/PID list.* + +--- + +### Original Xbox (USB host) + +- Original Xbox Duke and S (via USB adapter/converter) + +*Used when the adapter is in OG Xbox output mode with a compatible USB host path.* + +--- + +### DInput / Generic HID + +Controllers that use the standard HID gamepad (DInput) protocol, including: + +- **Logitech:** F310, F510, F710, RumblePad 2, Dual Action, WingMan, ChillStream, etc. +- **8BitDo:** Many models in DInput/HID mode (e.g. Pro 2, Pro 3, Ultimate, Lite, FC30 Pro, F30 Arcade, GameCube, Dogbone) +- **Hori:** Fightsticks, Fighting Commander, Horipad (various), Taiko Controller, etc. +- **Mad Catz:** Fightsticks, Fightpad, CTRLR, etc. +- **Qanba, Mayflash, Brook:** Arcade sticks and adapters +- **PowerA, PDP, Afterglow:** Various Xbox/PC controllers in HID mode +- **GameSir:** G3, G4, T3, T4, G7 Pro, etc. +- **Razer:** Kishi, Hydra, Serval, Raiju (PC/HID) +- **Steam:** Steam Controller, Steam Deck (when presenting as gamepad) +- **Sony:** DualShock 2 (via USB adapter), Steam Virtual Gamepad +- **Flydigi:** Vader 4 Pro (DInput mode) +- **Scuf:** Envision (Linux/HID) +- **Elecom:** Various gamepads and adapters +- **Other:** ThrustMaster, BigBen, Capcom Home Arcade, Cthulhu, XinMo, Zenaim, Datel, and other generic DInput/HID gamepads and arcade sticks + +*See `DINPUT_IDS` in `HardwareIDs.h` for the full VID/PID list. This list is large and includes many fightsticks and third‑party pads.* + +--- + +### Generic HID (unspecified mapping) + +- Other HID gamepad‑like devices may work; button and axis mappings might need to be adjusted in the [web app](https://megacadedev.github.io/OGX-Mini-2026-WebApp/). + +--- + +## Reference + +- **VID/PID lists:** `Firmware/RP2040/src/USBHost/HardwareIDs.h` +- **Host drivers:** `Firmware/RP2040/src/USBHost/HostDriver/` +- **Platform selection:** See the main [README](../../../README.md) for button combos to change output platform. diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index 42f0ed93..c8839f10 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -4,10 +4,15 @@ #include #include #include +#include #include "btstack_run_loop.h" +#include "gap.h" #include "uni.h" +#include "bt/uni_bt.h" +#include "bt/uni_bt_bredr.h" #include "parser/uni_hid_parser_ds5.h" +#include "parser/uni_hid_parser_xboxone.h" #include "sdkconfig.h" #include "Bluepad32/Bluepad32.h" @@ -24,6 +29,18 @@ namespace bluepad32 { static constexpr uint32_t FEEDBACK_TIME_MS = 250; static constexpr uint32_t LED_CHECK_TIME_MS = 500; +/** If no HID input report reaches us for this long while "connected", the BT link is zombie + * (L2CAP stops delivering; OG Xbox then holds last USB report). Force disconnect so user can reconnect. */ +static constexpr uint32_t BT_INPUT_STALL_DISCONNECT_MS = 8000; +/** BLE Xbox: host→pad output while idle (no rumble) or controller sleeps link ~1 min */ +static constexpr uint32_t XBOX_BLE_KEEPALIVE_MS = 12000; + +static uint32_t s_last_bt_input_ms[MAX_GAMEPADS]{}; +static uint32_t s_xbox_ble_ka_last_ms[MAX_GAMEPADS]{}; +/** Ignore Start+Select disconnect combo for this long after connect (DS4 can glitch both on first reports). */ +static uint32_t s_bt_disconnect_combo_grace_until_ms[MAX_GAMEPADS]{}; +/** DS4 BT: delay rumble output (host can request rumble immediately; early FF reports can drop link). */ +static uint32_t s_ps4_rumble_ok_ms[MAX_GAMEPADS]{}; struct BTDevice { bool connected{false}; @@ -130,19 +147,51 @@ void set_rumble(uni_hid_device_t* bp_device, uint16_t length, uint8_t rumble_l, static void send_feedback_cb(btstack_timer_source *ts) { uni_hid_device_t* bp_device = nullptr; + const uint32_t now_ms = to_ms_since_boot(get_absolute_time()); for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { - if (!bt_devices_[i].connected || + if (!bt_devices_[i].connected || !(bp_device = uni_hid_device_get_instance_for_idx(i))) { continue; } + /* Virtual slot (e.g. DS4's BT "mouse"): never gets gamepad HID → would always stall-disconnect + * and drop the real controller. */ + if (uni_hid_device_is_virtual_device(bp_device)) + goto after_stall_check; + /* BLE Xbox (Series) often sends HID only on change — idle sticks look like "stall" and we + * would disconnect every few seconds. BR/EDR Xbox (1708) polls constantly; stall OK there. */ + if (!(bp_device->controller_type == CONTROLLER_TYPE_XBoxOneController && bp_device->hids_cid != 0)) + { + if (s_last_bt_input_ms[i] != 0 && (now_ms - s_last_bt_input_ms[i]) > BT_INPUT_STALL_DISCONNECT_MS) + { + printf("[Bluepad32] BT input stalled (%u ms); forcing disconnect (slot %u)\n", + static_cast(now_ms - s_last_bt_input_ms[i]), static_cast(i)); + uni_hid_device_disconnect(bp_device); + continue; + } + } + after_stall_check: Gamepad::PadOut gp_out = bt_devices_[i].gamepad->get_pad_out(); + if (bp_device->controller_type == CONTROLLER_TYPE_XBoxOneController && bp_device->hids_cid != 0 && + gp_out.rumble_l == 0 && gp_out.rumble_r == 0) + { + const uint32_t last_ka = s_xbox_ble_ka_last_ms[i]; + if (last_ka == 0u || (now_ms - last_ka) >= XBOX_BLE_KEEPALIVE_MS) + { + uni_hid_parser_xboxone_ble_keepalive(bp_device); + s_xbox_ble_ka_last_ms[i] = now_ms; + } + } if (gp_out.rumble_l > 0 || gp_out.rumble_r > 0) { - set_rumble(bp_device, static_cast(FEEDBACK_TIME_MS), gp_out.rumble_l, gp_out.rumble_r); + if (bp_device->controller_type == CONTROLLER_TYPE_PS4Controller && + now_ms < s_ps4_rumble_ok_ms[i]) + ; + else + set_rumble(bp_device, static_cast(FEEDBACK_TIME_MS), gp_out.rumble_l, gp_out.rumble_r); } } @@ -194,6 +243,44 @@ static uni_error_t device_discovered_cb(bd_addr_t addr, const char* name, uint16 static void device_connected_cb(uni_hid_device_t* device) { } +/** CYW43: resume OGX BLE advertising when no Classic (BR/EDR) gamepad remains connected. */ +static void ogxm_resume_ble_ads_if_no_acl_pad(int disconnected_idx) { +#if defined(CONFIG_TARGET_PICO_W) + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + if (i == static_cast(disconnected_idx)) + continue; + if (!bt_devices_[i].connected) + continue; + uni_hid_device_t* d = uni_hid_device_get_instance_for_idx(static_cast(i)); + if (!d || uni_bt_conn_get_state(&d->conn) != UNI_BT_CONN_STATE_DEVICE_READY) + continue; + if (gap_get_connection_type(d->conn.handle) == GAP_CONNECTION_ACL) + return; + } + gap_advertisements_enable(1); +#endif +} + +/** CYW43: periodic BR/EDR inquiry while a Classic ACL link is up can drop DS4/PS3 in ~1–2 s. */ +static void maybe_restart_bredr_inquiry_after_disconnect(int disconnected_idx) { +#if defined(CONFIG_TARGET_PICO_W) + if (!uni_bt_enable_new_connections_is_enabled()) + return; + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + if (i == static_cast(disconnected_idx)) + continue; + if (!bt_devices_[i].connected) + continue; + uni_hid_device_t* d = uni_hid_device_get_instance_for_idx(static_cast(i)); + if (!d || uni_bt_conn_get_state(&d->conn) != UNI_BT_CONN_STATE_DEVICE_READY) + continue; + if (gap_get_connection_type(d->conn.handle) == GAP_CONNECTION_ACL) + return; + } + uni_bt_bredr_scan_start(); +#endif +} + static void device_disconnected_cb(uni_hid_device_t* device) { int idx = uni_hid_device_get_idx_for_instance(device); if (idx >= MAX_GAMEPADS || idx < 0) { @@ -201,6 +288,10 @@ static void device_disconnected_cb(uni_hid_device_t* device) { } bt_devices_[idx].connected = false; + s_last_bt_input_ms[idx] = 0; + s_xbox_ble_ka_last_ms[idx] = 0; + s_bt_disconnect_combo_grace_until_ms[idx] = 0; + s_ps4_rumble_ok_ms[idx] = 0; prev_touchpad_clicked_[idx] = false; pending_adaptive_trigger_send_[idx] = false; bt_devices_[idx].gamepad->reset_pad_in(); @@ -216,15 +307,41 @@ static void device_disconnected_cb(uni_hid_device_t* device) { feedback_timer_set_ = false; btstack_run_loop_remove_timer(&feedback_timer_); } + maybe_restart_bredr_inquiry_after_disconnect(idx); + ogxm_resume_ble_ads_if_no_acl_pad(idx); + // Re-enable scanning when last device disconnects so the controller can reconnect without + // power-cycling the dongle (fixes "pairing mode but controller won't reconnect" in OG Xbox / BT mode). + if (!any_connected()) { + uni_bt_enable_new_connections_unsafe(true); + } } -static uni_error_t device_ready_cb(uni_hid_device_t* device) { +static uni_error_t device_ready_cb(uni_hid_device_t* device) { + /* DS4/DS5 BT create a second "virtual mouse" device on the same ACL. OGX-Mini only uses + * gamepad input; accepting the virtual slot destabilized the link (disconnect ~2 s). */ + if (uni_hid_device_is_virtual_device(device)) + return UNI_ERROR_INVALID_CONTROLLER; + int idx = uni_hid_device_get_idx_for_instance(device); if (idx >= MAX_GAMEPADS || idx < 0) { return UNI_ERROR_SUCCESS; } bt_devices_[idx].connected = true; +#if defined(CONFIG_TARGET_PICO_W) + if (gap_get_connection_type(device->conn.handle) == GAP_CONNECTION_ACL) { + uni_bt_bredr_scan_stop(); + gap_advertisements_enable(0); + } +#endif + const uint32_t tnow = to_ms_since_boot(get_absolute_time()); + s_last_bt_input_ms[idx] = tnow; + s_bt_disconnect_combo_grace_until_ms[idx] = tnow + 3500u; + if (device->controller_type == CONTROLLER_TYPE_PS4Controller) + s_ps4_rumble_ok_ms[idx] = tnow + 6000u; + /* Xbox BLE: 0 = send keepalive on next feedback tick (wakes Series/SW2 pad link immediately). */ + if (device->controller_type == CONTROLLER_TYPE_XBoxOneController && device->hids_cid != 0) + s_xbox_ble_ka_last_ms[idx] = 0; // Set controller player LED to match slot (e.g. Wii U: LED 1 = player 1, LED 2 = player 2). // Same as Bluepad32 NINA platform: set_player_leds(d, BIT(idx)). @@ -273,6 +390,8 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr uni_gamepad_t *uni_gp = &controller->gamepad; int idx = uni_hid_device_get_idx_for_instance(device); + if (idx >= 0 && idx < static_cast(MAX_GAMEPADS)) + s_last_bt_input_ms[static_cast(idx)] = to_ms_since_boot(get_absolute_time()); #if BLUEPAD32_UART_LOG_INPUT { @@ -349,12 +468,17 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr // Check for disconnect combo: Start+Select for most controllers, L3+R3 for OUYA (no Start/Select) static uint32_t disconnect_combo_hold_time[MAX_GAMEPADS] = {0}; + const uint32_t now_cb = to_ms_since_boot(get_absolute_time()); + const bool combo_grace = + (idx >= 0 && idx < MAX_GAMEPADS && now_cb < s_bt_disconnect_combo_grace_until_ms[idx]); bool is_ouya = (device->controller_type == CONTROLLER_TYPE_OUYAController); bool combo_pressed = is_ouya ? ((uni_gp->buttons & BUTTON_THUMB_L) && (uni_gp->buttons & BUTTON_THUMB_R)) : ((uni_gp->misc_buttons & MISC_BUTTON_START) && (uni_gp->misc_buttons & MISC_BUTTON_BACK)); - - if (combo_pressed) { + + if (combo_grace) { + disconnect_combo_hold_time[idx] = 0; + } else if (combo_pressed) { disconnect_combo_hold_time[idx]++; // Require combo to be held for ~500ms (assuming ~60Hz callback rate, ~30 frames) if (disconnect_combo_hold_time[idx] >= 30) { @@ -389,7 +513,7 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad->scale_joystick_l<10>(uni_gp->axis_x, uni_gp->axis_y); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad->scale_joystick_r<10>(uni_gp->axis_rx, uni_gp->axis_ry); - gamepad->set_pad_in(gp_in); + gamepad->set_pad_in_from_bluetooth(gp_in); // PS5: defer adaptive trigger send to main loop so callback never does l2cap_send (reduces input lag) if (device->controller_type == CONTROLLER_TYPE_PS5Controller && idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { diff --git a/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp b/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp index ec20f5d4..c864b1a1 100644 --- a/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp +++ b/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp @@ -37,7 +37,7 @@ void init() { gpio_init(VCC_EN_PIN); gpio_set_dir(VCC_EN_PIN, GPIO_OUT); gpio_put(VCC_EN_PIN, 1); -#endif +#endif gpio_init(PIO_USB_DP_PIN); gpio_set_dir(PIO_USB_DP_PIN, GPIO_IN); diff --git a/Firmware/RP2040/src/Gamepad/Gamepad.h b/Firmware/RP2040/src/Gamepad/Gamepad.h index e1c90307..d3f98048 100644 --- a/Firmware/RP2040/src/Gamepad/Gamepad.h +++ b/Firmware/RP2040/src/Gamepad/Gamepad.h @@ -158,6 +158,21 @@ class Gamepad inline PadIn get_pad_in() { mutex_enter_blocking(&pad_in_mutex_); + /* Bluetooth HID runs on Core1; never block there on this mutex (would stall HCI/L2CAP). + * Latest BT report is staged lock-free and merged here on Core0. */ + if (bt_pad_staged_.exchange(false, std::memory_order_acq_rel)) { + const PadIn& p = bt_pending_pad_; + if (pad_in_count_ < PAD_IN_QUEUE_SIZE) { + pad_in_queue_[pad_in_tail_] = p; + pad_in_tail_ = (pad_in_tail_ + 1) % PAD_IN_QUEUE_SIZE; + pad_in_count_++; + } else { + pad_in_head_ = (pad_in_head_ + 1) % PAD_IN_QUEUE_SIZE; + pad_in_queue_[pad_in_tail_] = p; + pad_in_tail_ = (pad_in_tail_ + 1) % PAD_IN_QUEUE_SIZE; + } + new_pad_in_.store(true); + } PadIn pad_in; if (pad_in_count_ > 0) { pad_in = pad_in_queue_[pad_in_head_]; @@ -235,6 +250,14 @@ class Gamepad mutex_exit(&pad_in_mutex_); } + /** Bluetooth (Core1): never blocks on Core0 — avoids stalling the BT stack in HID callbacks. */ + inline void set_pad_in_from_bluetooth(const PadIn& pad_in) + { + bt_pending_pad_ = pad_in; + bt_pad_staged_.store(true, std::memory_order_release); + new_pad_in_.store(true, std::memory_order_release); + } + inline void set_pad_out(const PadOut& pad_out) { mutex_enter_blocking(&pad_out_mutex_); @@ -256,6 +279,7 @@ class Gamepad inline void reset_pad_in() { + bt_pad_staged_.store(false, std::memory_order_relaxed); mutex_enter_blocking(&pad_in_mutex_); pad_in_head_ = 0; pad_in_tail_ = 0; @@ -374,9 +398,11 @@ class Gamepad : trigger_value; } - static constexpr unsigned PAD_IN_QUEUE_SIZE = 2; + static constexpr unsigned PAD_IN_QUEUE_SIZE = 8; private: + PadIn bt_pending_pad_{}; + std::atomic bt_pad_staged_{false}; mutex_t pad_in_mutex_; mutex_t pad_out_mutex_; mutex_t chatpad_in_mutex_; diff --git a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp index a614c528..63bfee31 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp @@ -355,7 +355,7 @@ void core1_task() { tuh_init(BOARD_TUH_RHPORT); uint32_t tid_feedback = TaskQueue::Core1::get_new_task_id(); - TaskQueue::Core1::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, + TaskQueue::Core1::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, [&host_manager] { host_manager.send_feedback(); }); diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index e70dfcd7..09ae5b48 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -240,6 +240,9 @@ void pico_w::run() { GPIOHost::n64_host_init(0, 19); } bluepad32::set_gpio_device_process_callback(gpio_device_process_cb, nullptr); + /* Present as USB device to console immediately so PS2/GC/Dreamcast see the adapter at boot. */ + tud_init(BOARD_TUD_RHPORT); + OGXM_LOG("PicoW run: tud_init done (GPIO device mode)\n"); if (ps2_poll_mode) { /* PS2: BT on Core1 (like Switch/PS3); Core0 main loop does process() + psx_device_poll(). */ OGXM_LOG("PicoW run: launching Core1 (BT)\n"); @@ -302,8 +305,7 @@ void pico_w::run() { } TaskQueue::Core0::process_tasks(); if (!wii_mode) { - if (!gpio_device_mode) - tud_task(); + tud_task(); HostInputSource input_src = UserSettings::get_instance().get_input_source(); if (input_src == HostInputSource::PSX_GPIO) { GPIOHost::psx_host_poll(_gamepads[0]); @@ -334,10 +336,9 @@ void pico_w::run() { OGXM_LOG("PicoW run: Wii main loop tick\n"); } loop_count++; -#if MAIN_LOOP_DELAY_US > 0 + // Match Team-Resurgent: 1 ms delay so Core1 (BT stack) gets CPU; prevents random BT disconnect. if (!ps2_poll_mode) - sleep_us(MAIN_LOOP_DELAY_US); -#endif + sleep_ms(1); } } diff --git a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp index f41f3584..a0a96437 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp @@ -31,7 +31,7 @@ void core1_task() { HostManager& host_manager = HostManager::get_instance(); host_manager.initialize(_gamepads); - //Pico-PIO-USB will not reliably detect a hot plug on some boards, + //Pico-PIO-USB will not reliably detect a hot plug on some boards, //monitor and init host stack after connection while(!board_api::usb::host_connected()) { sleep_ms(100); @@ -43,7 +43,7 @@ void core1_task() { tuh_init(BOARD_TUH_RHPORT); uint32_t tid_feedback = TaskQueue::Core1::get_new_task_id(); - TaskQueue::Core1::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, + TaskQueue::Core1::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, [&host_manager] { host_manager.send_feedback(); }); @@ -159,6 +159,9 @@ void standard::run() { if (input_src == HostInputSource::N64_GPIO) { GPIOHost::n64_host_init(0, 19); } + /* Present as USB device to console immediately so PS2/GC/Dreamcast see the adapter at boot + * (host_mounted() returns early for these drivers and never calls tud_init). */ + tud_init(BOARD_TUD_RHPORT); } else { multicore_reset_core1(); multicore_launch_core1(core1_task); @@ -192,6 +195,7 @@ void standard::run() { TaskQueue::Core0::process_tasks(); if (gpio_device_mode) { tuh_task(); + tud_task(); HostInputSource input_src = UserSettings::get_instance().get_input_source(); if (input_src == HostInputSource::PSX_GPIO) { GPIOHost::psx_host_poll(_gamepads[0]); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp index 88bebae2..d497c3f2 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/PS1PS2.cpp @@ -81,6 +81,21 @@ void PS1PS2Device::process(const uint8_t idx, Gamepad& gamepad) { psx_report_.ly = static_cast(ly); psx_report_.rx = static_cast(rx); psx_report_.ry = static_cast(ry); + + /* Home only = IGR (L1+L2+R1+R2+Start+Select); Home+Start = shutdown (L1+L2+R1+R2+L3+R3) */ + bool home_pressed = (gp.buttons & Gamepad::BUTTON_SYS) != 0; + bool start_pressed = (gp.buttons & Gamepad::BUTTON_START) != 0; + if (home_pressed && start_pressed) { + psx_report_.buttons1 &= ~(PSX_L3 | PSX_R3); + psx_report_.buttons2 &= ~(PSX_L1 | PSX_L2 | PSX_R1 | PSX_R2); + psx_report_.l2 = 0xFF; + psx_report_.r2 = 0xFF; + } else if (home_pressed) { + psx_report_.buttons1 &= ~(PSX_SELECT | PSX_START); + psx_report_.buttons2 &= ~(PSX_L1 | PSX_L2 | PSX_R1 | PSX_R2); + psx_report_.l2 = 0xFF; + psx_report_.r2 = 0xFF; + } } uint16_t PS1PS2Device::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t req_len) { diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp index c1ae1b25..9af1802b 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp @@ -1,6 +1,5 @@ #include -#include "pico/time.h" #include "USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h" #include "Gamepad/Gamepad.h" @@ -26,78 +25,47 @@ void XboxOGDevice::initialize() void XboxOGDevice::process(const uint8_t idx, Gamepad& gamepad) { - /* Reverted to v1.0.0a5 behaviour: only build/send report when new input (avoids random disconnects on OG Xbox). */ + /* Build/send only when new input (match Team-Resurgent timing). Guide/Guide+Start combos for IGR/shutdown kept. */ #if defined(CONFIG_OGXM_DEBUG) static uint32_t s_process_ticks = 0; static uint32_t s_send_count = 0; static uint32_t s_new_pad_in_count = 0; + static uint32_t s_last_new_pad_in_tick = 0; + static uint32_t s_ready_false_count = 0; // had new_pad_in but send_report_ready(0) was false s_process_ticks++; #endif if (gamepad.new_pad_in()) { #if defined(CONFIG_OGXM_DEBUG) s_new_pad_in_count++; + s_last_new_pad_in_tick = s_process_ticks; #endif std::memset(&in_report_.buttons, 0, 8); Gamepad::PadIn gp_in = gamepad.get_pad_in(); - // Guide (SYS) button: tap = Start, hold 1s = soft IGR (LT+RT+Start+Back), hold 3s = shutdown (LT+RT+Up+Back) - bool sys_pressed = (gp_in.buttons & Gamepad::BUTTON_SYS) != 0; - if (sys_pressed && !sys_button_pressed_) + // Guide only = IGR (LT+RT+Start+Back). + // Shutdown = LT+RT+Back+White only (no Start on the wire — extra Start breaks many BIOSes). + // Guide+Menu (Start): works on PS5 / some pads. Xbox BT often drops Menu while Guide is held; + // use Guide+View (Back) instead on Xbox controllers. + bool guide_pressed = (gp_in.buttons & Gamepad::BUTTON_SYS) != 0; + bool start_pressed = (gp_in.buttons & Gamepad::BUTTON_START) != 0; + bool view_pressed = (gp_in.buttons & Gamepad::BUTTON_BACK) != 0; + const bool shutdown_combo = + guide_pressed && (start_pressed || view_pressed); + if (shutdown_combo) { - sys_button_pressed_ = true; - sys_button_press_time_ = get_absolute_time(); - sys_button_combo_sent_ = false; + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_BACK; + gp_in.buttons |= Gamepad::BUTTON_LB; // White + gp_in.buttons &= ~Gamepad::BUTTON_START; // chord must not include Start } - else if (!sys_pressed && sys_button_pressed_) + else if (guide_pressed) { - sys_button_pressed_ = false; - uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); - if (hold_time_ms >= 3000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.dpad |= Gamepad::DPAD_UP; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else if (hold_time_ms >= 1000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.buttons |= Gamepad::BUTTON_START; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else - { - gp_in.buttons |= Gamepad::BUTTON_START; - sys_button_combo_sent_ = true; - } - } - else if (sys_pressed && !sys_button_combo_sent_) - { - uint64_t hold_time_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(sys_button_press_time_); - if (hold_time_ms >= 3000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.dpad |= Gamepad::DPAD_UP; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else if (hold_time_ms >= 1000) - { - gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); - gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); - gp_in.buttons |= Gamepad::BUTTON_START; - gp_in.buttons |= Gamepad::BUTTON_BACK; - sys_button_combo_sent_ = true; - } - else - { - gp_in.buttons |= Gamepad::BUTTON_START; - } + gp_in.trigger_l = gamepad.scale_trigger_l(0xFF); + gp_in.trigger_r = gamepad.scale_trigger_r(0xFF); + gp_in.buttons |= Gamepad::BUTTON_START; + gp_in.buttons |= Gamepad::BUTTON_BACK; } switch (gp_in.dpad) @@ -173,8 +141,12 @@ void XboxOGDevice::process(const uint8_t idx, Gamepad& gamepad) #if defined(CONFIG_OGXM_DEBUG) if (ready) s_send_count++; - if (s_process_ticks % 5000 == 0) - OGXM_LOG("XboxOG: process tick " + std::to_string(s_process_ticks) + " new_pad_in=" + std::to_string(s_new_pad_in_count) + " send_ready=" + std::to_string(ready) + " sent=" + std::to_string(s_send_count) + "\n"); + else + { + s_ready_false_count++; + if (s_ready_false_count <= 3 || s_ready_false_count % 2000 == 0) + OGXM_LOG("XboxOG: new_pad_in but send_report_ready=false (count=" + std::to_string(s_ready_false_count) + ")\n"); + } #endif if (ready) { @@ -182,8 +154,29 @@ void XboxOGDevice::process(const uint8_t idx, Gamepad& gamepad) } } +#if defined(CONFIG_OGXM_DEBUG) + // Periodic status every 10000 process ticks to see why it might stop responding + if (s_process_ticks > 0 && s_process_ticks % 10000 == 0) + { + uint32_t ticks_since_input = s_process_ticks - s_last_new_pad_in_tick; + OGXM_LOG("XboxOG: tick=" + std::to_string(s_process_ticks) + + " new_pad_in=" + std::to_string(s_new_pad_in_count) + + " sent=" + std::to_string(s_send_count) + + " ready_false=" + std::to_string(s_ready_false_count) + + " ticks_since_input=" + std::to_string(ticks_since_input) + "\n"); + if (ticks_since_input > 20000) + OGXM_LOG("XboxOG: WARNING no new input for " + std::to_string(ticks_since_input) + " ticks (controller/driver may be idle or not sending)\n"); + } +#endif + if (tud_xid::receive_report(0, reinterpret_cast(&out_report_), sizeof(XboxOG::GP::OutReport))) { +#if defined(CONFIG_OGXM_DEBUG) + static uint32_t s_rumble_recv_count = 0; + s_rumble_recv_count++; + if (s_rumble_recv_count <= 3 || s_rumble_recv_count % 2000 == 0) + OGXM_LOG("XboxOG: rumble recv #" + std::to_string(s_rumble_recv_count) + "\n"); +#endif Gamepad::PadOut gp_out; gp_out.rumble_l = Scale::uint16_to_uint8(out_report_.rumble_l); gp_out.rumble_r = Scale::uint16_to_uint8(out_report_.rumble_r); @@ -195,9 +188,14 @@ uint16_t XboxOGDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_ { #if defined(CONFIG_OGXM_DEBUG) static uint32_t s_get_report_count = 0; + static uint32_t s_last_logged_get_report = 0; s_get_report_count++; - if (s_get_report_count <= 5 || s_get_report_count % 1000 == 0) - OGXM_LOG("XboxOG: get_report_cb #" + std::to_string(s_get_report_count) + "\n"); + // Log first 5, then every 2000 so we see if Xbox stops polling (get_report_cb stops being called) + if (s_get_report_count <= 5 || s_get_report_count - s_last_logged_get_report >= 2000) + { + OGXM_LOG("XboxOG: get_report_cb #" + std::to_string(s_get_report_count) + " (Xbox polling)\n"); + s_last_logged_get_report = s_get_report_count; + } #endif std::memcpy(buffer, &in_report_, sizeof(in_report_)); return sizeof(XboxOG::GP::InReport); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h index 1eeb3e05..cdd63c3f 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h @@ -3,7 +3,6 @@ #include -#include "pico/time.h" #include "USBDevice/DeviceDriver/DeviceDriver.h" #include "Descriptors/XboxOG.h" @@ -24,11 +23,6 @@ class XboxOGDevice : public DeviceDriver private: XboxOG::GP::InReport in_report_; XboxOG::GP::OutReport out_report_; - - // Guide (SYS) button: tap = Start, hold 1s = soft IGR, hold 3s = shutdown - bool sys_button_pressed_{false}; - bool sys_button_combo_sent_{false}; - absolute_time_t sys_button_press_time_; }; #endif // _XBOXGOG_DEVICE_H_ diff --git a/Firmware/RP2040/src/USBHost/HardwareIDs.h b/Firmware/RP2040/src/USBHost/HardwareIDs.h index faff4776..e77b3bac 100644 --- a/Firmware/RP2040/src/USBHost/HardwareIDs.h +++ b/Firmware/RP2040/src/USBHost/HardwareIDs.h @@ -11,6 +11,7 @@ struct HardwareID uint16_t pid; }; +// DInput / generic HID; includes Xbox controllers when presented as HID (XInput uses class driver when possible) static const HardwareID DINPUT_IDS[] = { {0x044F, 0xB324}, // ThrustMaster Dual Trigger (PS3 mode) @@ -19,28 +20,371 @@ static const HardwareID DINPUT_IDS[] = {0x146B, 0x0902}, // BigBen Interactive Wired Mini PS3 Game Controller {0x2563, 0x0575}, // SHANWAN 2In1 USB Joystick {0x046D, 0xC218}, // Logitech RumblePad 2 + // Microsoft Xbox (045E) not in DINPUT: driven only by XInput. Adding them here causes + // double driver on Adafruit Feather (HID + XInput) and "vibrates but no input". See upstream OGX-Mini. + {0x2DC8, 0x3016}, // 8BitDo wired XInput (HID fallback) + {0x2DC8, 0x3106}, // 8BitDo wired XInput (HID fallback) + {0x2DC8, 0x2101}, // 8BitDo Xbox One SN30 Pro + {0x0E6F, 0x0131}, // Afterglow Xbox + {0x0E6F, 0x0132}, // Afterglow Xbox + {0x0E6F, 0x0134}, // Afterglow Xbox + {0x0E6F, 0x1314}, // Afterglow Xbox + {0x0E6F, 0x0113}, // Afterglow Xbox Controller + {0x0E6F, 0x0213}, // Afterglow Xbox Controller + {0x0E6F, 0x0413}, // Afterglow Xbox Controller + {0x0E6F, 0x0139}, // Afterglow Xbox + {0x12AB, 0x0301}, // Afterglow Xbox + {0x1BAD, 0xF900}, // Afterglow Xbox + {0x1BAD, 0x00FD}, // Xbox 360 Controller (PDP/hub) + {0x1BAD, 0x01FD}, // Xbox 360 Controller + {0x1BAD, 0x16F0}, // Xbox 360 Controller + {0x1BAD, 0x028E}, // Xbox 360 Controller + {0x0F0D, 0x0086}, // Hori Fighting Commander Xbox 360 + {0x0F0D, 0x00BA}, // Hori Fighting Commander Xbox 360 + {0x0738, 0x4718}, // Mad Catz Street Fighter 4 Xbox 360 FightStick + {0x0738, 0x4716}, // Xbox 360 Controller + {0x0738, 0x4520}, // Xbox 360 Controller + {0x0738, 0x4426}, // Xbox 360 Controller + {0x0738, 0x4726}, // Xbox 360 Controller + {0x0738, 0xB726}, // Xbox 360 Controller + {0x0738, 0x4736}, // Xbox 360 Controller + {0x0738, 0x4728}, // Xbox 360 Fightpad + {0x0738, 0x4516}, // Xbox Controller + {0x0738, 0x4526}, // Xbox Controller + {0x0738, 0x4536}, // Xbox Controller + {0x0738, 0x4586}, // Xbox Controller + // Microsoft SideWinder / legacy (VID 045E) + {0x045E, 0x0028}, // Microsoft Dual Strike + {0x045E, 0x0003}, // Microsoft SideWinder + {0x045E, 0x0007}, // Microsoft SideWinder + {0x045E, 0x000E}, // Microsoft SideWinder Freestyle Pro + {0x045E, 0x0027}, // Microsoft SideWinder Plug and Play + {0x120C, 0x8802}, // Nyko Air Flo Xbox + {0x120C, 0x880A}, // Xbox Controller + {0x120C, 0x8810}, // Xbox Controller + {0x162E, 0xBEEF}, // Xbox 360 Controller (generic) + {0x24C6, 0x5300}, // Xbox 360 Controller + {0x24C6, 0xFAFD}, // Xbox 360 Controller + {0x062A, 0x0020}, // Xbox Controller + // GameSir (multi-mode HID fallback, from SDL_GameControllerDB) + {0x05AC, 0x033D}, // GameSir G3 + {0x05AC, 0x055B}, // GameSir G3w + {0x05AC, 0x022D}, // GameSir G4 + {0x05AC, 0x044D}, // GameSir G4 (alt) + {0x05AC, 0x061A}, // GameSir T3 2.02 + {0x3537, 0x1022}, // GameSir G7 Pro + {0x3537, 0x1004}, // GameSir T4 Kaleid + {0x3537, 0x1094}, // GameSir Tegenaria Lite + // 8BitDo multi-mode (from SDL_GameControllerDB, HID fallback) + {0x2DC8, 0x3019}, // 8BitDo 64 + {0x2DC8, 0x5109}, // 8BitDo Dogbone + {0x2DC8, 0x9000}, // 8BitDo FC30 Pro + {0x2DC8, 0x5112}, // 8BitDo Lite 2 + {0x2DC8, 0x5111}, // 8BitDo Lite SE + {0x2DC8, 0x286A}, // 8BitDo GameCube + {0x2DC8, 0x6003}, // 8BitDo Pro 2 + {0x2DC8, 0x6006}, // 8BitDo Pro 2 + {0x2DC8, 0x6103}, // 8BitDo Pro 2 + {0x2DC8, 0x6009}, // 8BitDo Pro 3 + {0x2DC8, 0x3012}, // 8BitDo Ultimate + {0x2DC8, 0x3011}, // 8BitDo Ultimate Wired + {0x2DC8, 0x3013}, // 8BitDo Ultimate Wireless + {0x2DC8, 0x3100}, // 8BitDo Adapter + {0x2DC8, 0x3105}, // 8BitDo Adapter 2 + {0x2DC8, 0x3101}, // 8BitDo Receiver + {0x2DC8, 0x3102}, // 8BitDo Receiver + {0x2DC8, 0x3103}, // 8BitDo Receiver + {0x2DC8, 0x3104}, // 8BitDo Receiver + // Flydigi (multi-mode; DInput fallback when not in XInput) + {0xEED1, 0x04B4}, // Flydigi Vader 4 Pro (DInput mode) + // Fightsticks / arcade sticks (from SDL_GameControllerDB PC/Arcade + PC/PlayStation) + {0x8000, 0x1002}, // 8BitDo F30 + {0x1235, 0xAB11}, // 8BitDo F30 Arcade Joystick + {0x2DC8, 0x2810}, // 8BitDo F30 Arcade Joystick + {0x2DC8, 0xAB11}, // 8BitDo F30 Arcade Joystick + {0x1080, 0x0009}, // 8BitDo F30 Arcade Stick + {0x2DC8, 0x3810}, // 8BitDo F30 Pro + {0x1C5A, 0x0024}, // Capcom Home Arcade + {0x1C5B, 0x0024}, // Capcom Home Arcade + {0x1C5B, 0x0025}, // Capcom Home Arcade + {0x14D8, 0xCD07}, // Cthulhu + {0x14D8, 0xFACE}, // Cthulhu + {0x14D8, 0x6208}, // HitBox Edition Cthulhu + {0x0F0D, 0x0010}, // Hori Fightstick + {0x0F0D, 0x0032}, // Hori Fightstick 3W + {0x0F0D, 0x00C0}, // Hori Fightstick 4 + {0x0F0D, 0x000D}, // Hori Fightstick EX2 + {0x0F0D, 0x0137}, // Hori Fightstick Mini + {0x0F0D, 0x0040}, // Hori Fightstick Mini 3 + {0x0F0D, 0x0021}, // Hori Fightstick V3 + {0x0F0D, 0x0027}, // Hori Fightstick V3 + {0x0F0D, 0x0011}, // Hori Real Arcade Pro 3 + {0x0F0D, 0x0026}, // Hori Real Arcade Pro 3P + {0x0F0D, 0x004B}, // Hori Real Arcade Pro 3W + {0x0F0D, 0x006A}, // Hori Real Arcade Pro 4 + {0x0F0D, 0x006B}, // Hori Real Arcade Pro 4 + {0x0F0D, 0x008A}, // Hori Real Arcade Pro 4 + {0x0F0D, 0x008B}, // Hori Real Arcade Pro 4 + {0x0F0D, 0x006F}, // Hori Real Arcade Pro 4 VLX + {0x0F0D, 0x0070}, // Hori Real Arcade Pro 4 VLX + {0x0F0D, 0x003D}, // Hori Real Arcade Pro N3 + {0x0F0D, 0x00AE}, // Hori Real Arcade Pro N4 + {0x0F0D, 0x008C}, // Hori Real Arcade Pro P4 + {0x0F0D, 0x00AA}, // Hori Real Arcade Pro S + {0x0F0D, 0x00D8}, // Hori Real Arcade Pro S + {0x0F0D, 0x0022}, // Hori Real Arcade Pro V3 + {0x0F0D, 0x005B}, // Hori Real Arcade Pro V4 + {0x0F0D, 0x005C}, // Hori Real Arcade Pro V4 + {0x0F0D, 0x00AF}, // Hori Real Arcade Pro VHS + {0x0F0D, 0x001B}, // Hori Real Arcade Pro VX + {0x1BAD, 0xF502}, // Hori Real Arcade Pro VX + {0x0F0D, 0x0025}, // Hori Fighting Commander 3 + {0x0F0D, 0x002D}, // Hori Fighting Commander 3 Pro + {0x0F0D, 0x0084}, // Hori Fighting Commander 5 + {0x0F0D, 0x0162}, // Hori Fighting Commander Octa + {0x0F0D, 0x0164}, // Hori Fighting Commander Octa + {0x0738, 0xB738}, // Mad Catz Fightstick TE + {0x0738, 0x3187}, // Mad Catz PlayStation Fightstick + {0x0738, 0x4738}, // Street Fighter Fightstick TE + {0x0925, 0x2801}, // Mayflash Arcade Stick + {0x0079, 0x1830}, // Mayflash F300 Arcade Joystick + {0x2F24, 0x0039}, // Mayflash F300 Elite Arcade Joystick + {0x1BAD, 0xF03E}, // MLG Fightstick TE + {0x1BAD, 0xF028}, // Fightpad (Xbox) + {0x1BAD, 0xF02E}, // Fightpad (Xbox) + {0x1BAD, 0xF038}, // Fightpad TE (Xbox) + {0x1292, 0x4E47}, // NeoGeo X Arcade Stick + {0x0F30, 0x1101}, // Qanba 2 + {0x0F30, 0x1102}, // Qanba 2P + {0x0F30, 0x1100}, // Qanba Arcade Stick 1008 + {0x0F30, 0x1116}, // Qanba Arcade Stick 4018 + {0x0F30, 0x1112}, // Qanba Joystick + {0x0F30, 0x1012}, // Qanba Joystick Plus + {0x1A34, 0x0401}, // Qanba Joystick Q4RAF + {0x2C22, 0x2500}, // Qanba Dragon Arcade Joystick + {0x2C22, 0x2000}, // Qanba Drone Arcade Stick + {0x2C22, 0x2302}, // Qanba Obsidian Arcade Stick PS3 (PC mode) + {0x1DD8, 0x000E}, // iBuffalo AC02 Arcade Joystick + {0x16C0, 0x05E1}, // XinMo Dual Arcade + {0x3507, 0x0004}, // Zenaim Arcade Controller + {0x1C1A, 0x0100}, // Datel Arcade Joystick + {0x0E6F, 0x0185}, // PDP Fightpad Pro GameCube + // PowerA (PC/Xbox-style from SDL_GameControllerDB; Switch PowerA are in SWITCH_WIRED_IDS) + {0x20D6, 0xA711}, // PowerA Core Controller (HID/DInput; same VID:PID as OpenSteamController emulation) + {0x20D6, 0x4033}, // PowerA OPS Pro Wireless Controller + {0x20D6, 0x4026}, // PowerA OPS Wireless Controller + {0x20D6, 0xCA6D}, // PowerA Pro Ex + {0x24C6, 0x543A}, // PowerA Xbox One (Mac/HID) + {0x20D6, 0x4050}, // PowerA Advantage Xbox Series (Linux/HID) + {0x20D6, 0x4001}, // PowerA Fusion Pro 2 (Linux/HID) + {0x24C6, 0x531A}, // PowerA Mini Pro Ex (Linux/HID) + {0x20D6, 0x2002}, // PowerA Xbox One Controller (Linux/HID) + {0x20D6, 0x2828}, // PowerA Xbox One Controller (Linux/HID) + {0x24C6, 0x581A}, // PowerA Xbox One (Linux/HID) + {0x20D6, 0x4002}, // PowerA Xbox One Spectra Infinity (Linux/HID) + {0x20D6, 0x2050}, // PowerA Xbox Series Controller (Linux/HID) + {0x20D6, 0x2064}, // PowerA Xbox Series X Wired Controller (e.g. Red) + {0x20D6, 0x200B}, // PowerA Xbox Series Controller (Linux/HID) + {0x20D6, 0x200F}, // PowerA Xbox Series Controller (Linux/HID) + // Elecom (from SDL_GameControllerDB) + {0x056E, 0x200A}, // Elecom DUX60 MMO + {0x056E, 0x2003}, // Elecom U3613M + {0x056E, 0x2005}, // Elecom P301U PlayStation Controller Adapter + {0x056E, 0x2007}, // Elecom W01U + {0x056E, 0x200E}, // Elecom U3912T + {0x056E, 0x200F}, // Elecom U4013S + {0x056E, 0x2010}, // Elecom U4113S + {0x056E, 0x2013}, // Elecom U4113 + {0x05B8, 0x1004}, // Elecom Gamepad + {0x05B8, 0x1006}, // Elecom Gamepad + {0x1241, 0x5044}, // Elecom U1012 + {0x0925, 0x1802}, // Elecom PlayStation Adapter (Mayflash OEM) + // Brook adapters (DInput; Brook Mars PS4 in PS4_IDS) + {0x120C, 0x0C31}, // Brook Super Converter + {0x120C, 0x0EF1}, // Brook PS2 Adapter + // Mad Catz PC / generic (from SDL_GameControllerDB) + {0x0738, 0x5262}, // Mad Catz Micro CTRLR + {0x0738, 0x5263}, // Mad Catz CTRLR + {0x0738, 0x5266}, // Mad Catz CTRLR + {0x0738, 0x3282}, // Mad Catz PlayStation Brawlpad + // Hori pads / misc (remaining from SDL_GameControllerDB) + {0x0F0D, 0x000A}, // Hori DOA + {0x0F0D, 0x0009}, // Hori Pad 3 Turbo + {0x0F0D, 0x0013}, // Horipad 3W + {0x0F0D, 0x0042}, // Horipad A + {0x0F0D, 0x004D}, // Hori Pad A + {0x0F0D, 0x0054}, // Hori Pad 3 + {0x0F0D, 0x0055}, // Horipad 4 FPS + {0x0F0D, 0x0064}, // Horipad 3TP + {0x0F0D, 0x0067}, // Horipad One + {0x0F0D, 0x00A0}, // Hori Grip TAC4 + {0x0F0D, 0x009C}, // Hori TAC Pro + {0x0F0D, 0x00C9}, // Hori Taiko Controller + {0x0F0D, 0x0101}, // Hori Mini Hatsune Miku FT + {0x0F0D, 0x0138}, // Hori PC Engine Mini Controller + {0x0F0D, 0x0196}, // Horipad Steam + {0x1BAD, 0xF501}, // Horipad EXT2 + // Sony PlayStation (adapters / DualShock 2; DS3/DS4/DS5 in dedicated arrays) + {0x0E8F, 0x1009}, // Sony DualShock 2 + {0x05E3, 0x0596}, // Sony PlayStation Adapter + {0x14FE, 0x232A}, // Sony PlayStation Adapter + {0x6666, 0x0667}, // Sony PlayStation Adapter + {0x04D9, 0x0F16}, // Sony PlayStation Controller Adapter + // Steam / Valve (from SDL_GameControllerDB) + {0x28DE, 0x11FC}, // Steam Virtual Gamepad + {0x28DE, 0x11FF}, // Steam Virtual Gamepad + {0x28DE, 0x1102}, // Steam Controller + {0x28DE, 0x1105}, // Steam Controller + {0x28DE, 0x1106}, // Steam Controller + {0x28DE, 0x1142}, // Steam Controller + {0x28DE, 0x1201}, // Steam Controller + {0x28DE, 0x1205}, // Steam Deck + // Scuf Envision (Scuf PS4 in PS4_IDS; Envision PC/HID) + {0x2E95, 0x434B}, // Scuf Envision (Linux/HID) + {0x2E95, 0x434D}, // Scuf Envision (Linux/HID) + {0x2E95, 0x434E}, // Scuf Envision (Linux/HID) + // Logitech (from SDL_GameControllerDB; one entry already above) + {0x046D, 0xC209}, // Logitech WingMan + {0x046D, 0xC20A}, // Logitech WingMan RumblePad + {0x046D, 0xC20B}, // Logitech WingMan Action Pad + {0x046D, 0xC21A}, // Logitech Precision + {0x046D, 0xC21D}, // Logitech F310 + {0x046D, 0xC21E}, // Logitech F510 + {0x046D, 0xC21F}, // Logitech F710 + {0x046D, 0xC216}, // Logitech Dual Action + {0x046D, 0xC211}, // Logitech Cordless Wingman + {0x046D, 0xCAD1}, // Logitech ChillStream + {0x046D, 0xCAD2}, // Logitech Cordless Precision + // Razer (from SDL_GameControllerDB; PS4 Razer in PS4_IDS) + {0x27F8, 0x0BBF}, // Razer Kishi + {0x1532, 0x0300}, // Razer Hydra + {0x1532, 0x0900}, // Razer Serval + {0x1532, 0x1000}, // Razer Raiju + {0x1532, 0x0705}, // Razer Raiju Mobile + {0x1532, 0x0707}, // Razer Raiju Mobile + {0x1532, 0x1007}, // Razer Raiju TE + {0x1532, 0x100A}, // Razer Raiju TE + {0x1532, 0x1004}, // Razer Raiju UE + {0x1532, 0x1009}, // Razer Raiju UE }; +// PS3 controllers (from SDL_GameControllerDB + existing); many third-party pads use PS3 protocol static const HardwareID PS3_IDS[] = { - {0x054C, 0x0268}, // Sony Batoh (Dualshock 3) + {0x054C, 0x0268}, // Sony Dualshock 3 (Batoh) + {0x7331, 0x0001}, // Sony DualShock 3 (alt/clone VID) + {0x1532, 0x0402}, // Razer Panthera PS3 + {0x1A34, 0x0836}, // Afterglow PS3 + {0x0E6F, 0x6302}, // Afterglow PS3 + {0x0E6F, 0x0111}, // Afterglow PS3 + {0x0E6F, 0x0114}, // Afterglow PS3 + {0x0E6F, 0x0214}, // Afterglow PS3 + {0x0E6F, 0x0119}, // Afterglow PS3 + {0x0E6F, 0x011A}, // Afterglow PS3 + {0x0010, 0x0082}, // Akishop Customs PS360 + {0x0E6F, 0x0132}, // Battlefield 4 PS3 + {0x146B, 0x0055}, // Bigben PS3 + {0x146B, 0x0301}, // Bigben PS3 + {0x25F0, 0xC121}, // Gioteck PS3 + {0x25F0, 0xC131}, // Gioteck PS3 + {0x0F0D, 0x0049}, // Hatsune Miku / Hori PS3 + {0x0F0D, 0x0085}, // Hori Fighting Commander 2016 PS3 + {0x0F0D, 0x005F}, // Hori Fighting Commander 4 PS3 + {0x0F0D, 0x0051}, // Hori Fighting Commander PS3 + {0x0F0D, 0x0088}, // Hori Fighting Stick mini 4 PS3 + {0x0F0D, 0x006E}, // Horipad 4 PS3 + {0x0E6F, 0x0124}, // Injustice Fightstick PS3 + {0x0079, 0x0002}, // King PS3 + {0x0738, 0x8838}, // Mad Catz Arcade Fightstick TE S+ PS3 + {0x0738, 0x3285}, // Mad Catz Arcade Fightstick TE S PS3 + {0x0738, 0x3250}, // Mad Catz Fightpad Pro PS3 + {0x0738, 0x3180}, // Mad Catz FightStick Alpha PS3 + {0x0738, 0x3384}, // Mad Catz Fightstick TE S PS3 + {0x0738, 0x3481}, // Mad Catz Fightstick TE2 PS3 + {0x0738, 0xA856}, // Mad Catz PS3 + {0x0738, 0x8818}, // Mad Catz SFIV Fightstick PS3 + {0x0738, 0x3480}, // Mad Catz TE2 PS3 Fightstick + {0x0738, 0x8263}, // MLG PS3 + {0x20D6, 0x571D}, // Nyko Airflo PS3 + {0x20D6, 0x576D}, // OPP PS3 + {0x0E6F, 0x0109}, // PDP PS3 Versus Fighting + {0x0662, 0x70D5}, // PowerA PS3 (SDL DB VID) + {0x2606, 0x70D5}, // PowerA PS3 (alt VID) + {0x20D6, 0x5795}, // Pro Elite PS3 + {0x20D6, 0x319F}, // Pro Ex mini PS3 + {0x20D6, 0x57C7}, // Pro Ex mini PS3 + {0x120A, 0x0001}, // PS3 Controller (generic) + {0x120C, 0x0713}, // PS3 Controller (generic) + {0x120C, 0xF11C}, // PS3 Controller (generic) + {0x120C, 0x0EF9}, // PS3 Controller (generic) + {0x2509, 0x1801}, // PS3 Controller (generic) + {0x2509, 0x0005}, // PS3 Controller (generic) + {0x1F4F, 0x0008}, // PS3 Controller (generic) + {0x2563, 0x0575}, // SHANWAN / generic PS3 + {0x8888, 0x0308}, // PS3 Controller (generic) + {0x8888, 0x0408}, // PS3 Controller (generic) }; +// PS4 controllers (from SDL_GameControllerDB + existing) static const HardwareID PS4_IDS[] = { - {0x054C, 0x05C4}, // DS4 - {0x054C, 0x09CC}, // DS4 - {0x054C, 0x0BA0}, // DS4 wireless adapter + {0x054C, 0x05C4}, // Sony DS4 + {0x054C, 0x09CC}, // Sony DS4 + {0x054C, 0x0BA0}, // Sony DS4 wireless adapter {0x2563, 0x0357}, // MPOW Wired Gamepad (ShenZhen ShanWan) - {0x0F0D, 0x005E}, // Hori FC4 + {0x0F0D, 0x005E}, // Hori Fighting Commander 4 PS4 {0x0F0D, 0x00EE}, // Hori PS4 Mini (PS4-099U) - {0x1F4F, 0x1002} // ASW GG Xrd controller + {0x1F4F, 0x1002}, // ASW GG Xrd controller + {0x9886, 0x0025}, // Astro C40 TR PS4 + {0x20D6, 0x792A}, // BDA PS4 Fightpad + {0x120C, 0x0E20}, // Brook Mars PS4 + {0x120C, 0x0E21}, // Brook Mars PS4 + {0x11C0, 0x4001}, // GameStop PS4 Fun Controller + {0x0F0D, 0x0087}, // Hori Fighting Stick mini 4 PS4 + {0x0F0D, 0x00A5}, // Hori Miku Project Diva X HD PS4 + {0x0F0D, 0x00A6}, // Hori Miku Project Diva X HD PS4 + {0x0F0D, 0x0123}, // Hori PS4 Controller Light + {0x0F0D, 0x0066}, // Horipad 4 PS4 + {0x0738, 0x8250}, // Mad Catz Fightpad Pro PS4 + {0x0738, 0x8384}, // Mad Catz Fightstick TE S PS4 + {0x0738, 0x8481}, // Mad Catz Fightstick TE2 PS4 + {0x0738, 0x8180}, // Mad Catz SFV Arcade Fightstick Alpha PS4 + {0x0738, 0x8480}, // Mad Catz TE2 PS4 Fightstick + {0x146B, 0x0611}, // Nacon Revolution 3 PS4 + {0x146B, 0x0D10}, // Nacon Revolution Infinity PS4 + {0x120C, 0x0708}, // PS4 Controller (generic) + {0x120C, 0x1E11}, // PS4 Controller (generic) + {0x120C, 0x1E12}, // PS4 Controller (generic) + {0x120C, 0x0E13}, // PS4 Controller (generic) + {0x120C, 0x0E15}, // PS4 Controller (generic) + {0x120C, 0x0E18}, // PS4 Controller (generic) + {0x120C, 0x1E18}, // PS4 Controller (generic) + {0x120C, 0x1E19}, // PS4 Controller (generic) + {0x120C, 0x0E1E}, // PS4 Controller (generic) + {0x120C, 0x57A9}, // PS4 Controller (generic) + {0x120C, 0x57AA}, // PS4 Controller (generic) + {0x120C, 0x1CF2}, // PS4 Controller (generic) + {0x120C, 0x1CF3}, // PS4 Controller (generic) + {0x120C, 0x1CF4}, // PS4 Controller (generic) + {0x120C, 0x1CF5}, // PS4 Controller (generic) + {0x120C, 0x0EF7}, // PS4 Controller (generic) + {0x120E, 0x0C12}, // PS4 Controller (generic) + {0x160E, 0x0C12}, // PS4 Controller (generic) + {0x1E1A, 0x0C12}, // PS4 Controller (generic) + {0x2C22, 0x2300}, // Qanba Obsidian Arcade Stick PS4 + {0x1532, 0x0401}, // Razer Panthera PS4 + {0x1532, 0x1100}, // Razer Raion PS4 Fightpad + {0x2E95, 0x7725}, // Scuf PS4 + {0x120C, 0x1E1C}, // SnakeByte 4S PS4 + {0x120C, 0x0E16}, // Steel Play Metaltech PS4 + {0x0079, 0x181A}, // Venom PS4 Arcade Joystick }; static const HardwareID PS5_IDS[] = { - {0x054C, 0x0CE6}, // dualsense - {0x054C, 0x0DF2} // dualsense edge + {0x054C, 0x0CE6}, // Sony DualSense (PS5) + {0x054C, 0x0DF2}, // Sony DualSense Edge (PS5) + {0x054C, 0x0E5F} // Sony PS5 Access Controller }; static const HardwareID PSCLASSIC_IDS[] = @@ -48,24 +392,57 @@ static const HardwareID PSCLASSIC_IDS[] = {0x054C, 0x0CDA} // psclassic }; +// Switch Pro / Joy-Con / Wii U Pro (from SDL_GameControllerDB + existing) static const HardwareID SWITCH_PRO_IDS[] = { - {0x057E, 0x2009}, // Switch Pro - {0x057E, 0x0330} // Wii U Pro + {0x057E, 0x2009}, // Nintendo Switch Pro Controller + {0x057E, 0x0330}, // Wii U Pro + {0x057E, 0x2006}, // Joy-Con (L) + {0x057E, 0x2007}, // Joy-Con (R) + {0x057E, 0x2069}, // Nintendo Switch 2 Pro Controller // {0x20D6, 0xA711}, // OpenSteamController, emulated pro controller }; +// Wired Switch controllers (from SDL_GameControllerDB + existing) static const HardwareID SWITCH_WIRED_IDS[] = { {0x20D6, 0xA719}, // PowerA wired {0x20D6, 0xA713}, // PowerA Enhanced wired + {0x20D6, 0xA712}, // PowerA Fusion Fight Pad + {0x20D6, 0xA714}, // PowerA Spectra + {0x62DD, 0xA715}, // PowerA Fusion Arcade Stick + {0x62DD, 0xA716}, // PowerA Fusion Pro {0x0F0D, 0x0092}, // Hori Pokken Tournament Pro {0x0F0D, 0x00C1}, // Hori Pokken Horipad + {0x0F0D, 0x00F6}, // Hori Horipad Nintendo Switch + {0x0F0D, 0x0202}, // Hori Horipad O Nintendo Switch 2 + {0x0F0D, 0x00DC}, // Hori Horipad Switch + {0x0E6F, 0x0188}, // Afterglow Deluxe Nintendo Switch + {0x0E6F, 0x0184}, // Faceoff Deluxe Nintendo Switch + {0x0E6F, 0x0181}, // Faceoff Deluxe Pro Nintendo Switch + {0x0E6F, 0x0180}, // Faceoff Pro Nintendo Switch + {0x0E6F, 0x0189}, // PDP Realmz Nintendo Switch + {0x0E6F, 0x0187}, // Rock Candy Nintendo Switch + {0x146B, 0x0D08}, // Nacon Revolution Unlimited Pro + {0x146B, 0x0D01}, // Nacon Revolution Pro Controller + {0x146B, 0x0D02}, // Nacon Revolution Pro Controller 2 + {0x146B, 0x0D13}, // Nacon Revolution Pro Controller 3 + {0x11EC, 0xA7E1}, // Nintendo Switch (generic) + {0x044F, 0xD00E}, // Thrustmaster eSwap Pro Controller + {0x1DD8, 0x000B}, // Buffalo BSGP1601 (from SDL_GameControllerDB) + {0x1DD8, 0x000F}, // iBuffalo BSGP1204 + {0x1DD8, 0x0010}, // iBuffalo BSGP1204P }; static const HardwareID N64_IDS[] = { - {0x0079, 0x0006} // Retrolink N64 USB gamepad + {0x0079, 0x0006}, // Retrolink N64 USB gamepad + {0x2E24, 0x200B}, // Hyperkin Admiral N64 (from SDL_GameControllerDB) + {0x0079, 0x954E}, // Hyperkin N64 Controller Adapter + {0x0079, 0x1879}, // Mayflash N64 Adapter + {0x2F24, 0x00F4}, // Mayflash N64 Adapter + {0x057E, 0x2019}, // NSO N64 Controller + {0x1234, 0x0004}, // RetroUSB N64 RetroPort }; struct HostTypeMap diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index 87783e83..11673343 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -160,7 +160,7 @@ class HostManager { for (auto& device_slot : device_slots_) { - if (device_slot.address == address && + if (device_slot.address == address && device_slot.interfaces[instance].driver && device_slot.interfaces[instance].gamepad) { @@ -285,6 +285,23 @@ class HostManager return false; } + /** True if this device address already has any host driver (e.g. HID). Used to prefer XInput over HID for the same device. */ + inline bool address_has_driver(uint8_t address) const + { + for (const auto& device_slot : device_slots_) + { + if (device_slot.address != address) + continue; + for (const auto& iface : device_slot.interfaces) + { + if (iface.driver != nullptr) + return true; + } + return false; + } + return false; + } + private: static constexpr uint8_t INVALID_IDX = 0xFF; diff --git a/Firmware/docs/Submodule_forks.md b/Firmware/docs/Submodule_forks.md new file mode 100644 index 00000000..dbd8e2a1 --- /dev/null +++ b/Firmware/docs/Submodule_forks.md @@ -0,0 +1,28 @@ +# Pushing submodule forks (bluepad32 & tinyusb) + +`.gitmodules` points **bluepad32** and **tinyusb** at **MegaCadeDev** forks so OGX-Mini patches are fetchable. If those repos do not exist yet: + +1. On GitHub, **fork** [ricardoquesada/bluepad32](https://github.com/ricardoquesada/bluepad32) → `MegaCadeDev/bluepad32`. +2. **Fork** [hathach/tinyusb](https://github.com/hathach/tinyusb) → `MegaCadeDev/tinyusb`. + +Then push the patched branches **before** (or right after) pushing **OGX-Mini-2026**: + +```bash +# From repo root — bluepad32 (branch ogxm-mini-2026) +cd Firmware/external/bluepad32 +git remote add megacade https://github.com/MegaCadeDev/bluepad32.git 2>/dev/null || true +git push megacade ogxm-mini-2026:main + +# tinyusb +cd ../tinyusb +git remote add megacade https://github.com/MegaCadeDev/tinyusb.git 2>/dev/null || true +git push megacade ogxm-mini-2026:main +``` + +If `main` on the fork rejects (non-fast-forward), use a named branch instead, e.g. `git push megacade ogxm-mini-2026:ogxm-mini-2026`, then set the fork’s default branch to that or merge via PR. + +After forks are updated, clone with: + +```bash +git clone --recursive https://github.com/MegaCadeDev/OGX-Mini-2026.git +``` diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index 2152d0b7..1e3efe99 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit 2152d0b7aba0b7cf5f54146e56b21c35dbb87024 +Subproject commit 1e3efe991927c2c3fee58898e0164046b357ccfc diff --git a/Firmware/external/tinyusb b/Firmware/external/tinyusb index cb22301f..8a0c0c06 160000 --- a/Firmware/external/tinyusb +++ b/Firmware/external/tinyusb @@ -1 +1 @@ -Subproject commit cb22301f91f0465a5578be35d9be284657ddd31d +Subproject commit 8a0c0c0643db0f8b0b7a76d85968d2c4e79411fd diff --git a/README.md b/README.md index 7369fec2..1a0559b1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ # OGX-Mini 2026 + +**Support development** — If this firmware helps you, consider **[donating on Ko-fi](https://ko-fi.com/megacadedev)**. Contributions go toward testing and adding support for **more boards and controllers** so the project can grow for everyone. + +--- + ![OGX-Mini Boards](images/OGX-Mini-github.jpg "OGX-Mini Boards") Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Waveshare RP2350-USB-A, Waveshare RP2350-Zero, Seeed Studio XIAO RP2040, RP2354, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. @@ -69,7 +74,7 @@ For the OUYA controller there is no Start+Select, the disconnection combo has be ## Supported devices ### Wired controllers (USB input) -The following work when the adapter is outputting to any supported platform (Xbox, Switch, XInput, PS3, DInput, **PS1/PS2**, **Dreamcast**, **GameCube**, **N64**, etc.): +See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a full list by driver type. The following work when the adapter is outputting to any supported platform (Xbox, Switch, XInput, PS3, DInput, **PS1/PS2**, **Dreamcast**, **GameCube**, **N64**, etc.): - Original Xbox Duke and S - Xbox 360, One, Series, and Elite - Dualshock 3 (PS3) @@ -90,7 +95,17 @@ Note: There are some third party controllers that can change their VID/PID, thes - Most wireless adapters that present themselves as Switch/XInput/PlayStation controllers should work ### Wireless Bluetooth controllers (Pico W & ESP32) -**Note:** Bluetooth functionality is in early testing, some may have quirks. Bluetooth controllers work as input when outputting to **PS1/PS2**, **Dreamcast**, **GameCube**, or **N64** (same as wired USB in those modes). +**Note:** Bluetooth functionality is in early testing; some controllers may have quirks. BT pads work as input in **any** USB output mode (OG Xbox, XInput, PS3, Switch, etc.) on Pico W / Pico 2 W, and also when outputting over **GPIO** to **PS1/PS2**, **Dreamcast**, **GameCube**, or **N64** (same as wired USB in those modes). + +**Pico W / Pico 2 W — important for DualShock 4 (DS4):** DS4 uses **Classic Bluetooth (BR/EDR)**. The same CYW43 radio also runs **BLE advertising** for the **phone / web app**. Running both at once often **drops the DS4 link** seconds after connect (blue LED then off). Firmware therefore **pauses BLE advertising** while a **Classic BT** gamepad is connected (DS4, DS3 over BT, Xbox 360 wireless adapter style links). **DualSense** and **Xbox Series (BLE)** mostly use **LE** and are unaffected by that pause. + +| Situation | What to do | +|-----------|------------| +| Use **DS4 / Classic BT** pad | Connect and play; web app BLE discovery is off until that pad disconnects. | +| Use **Bluetooth** in the **web app** | Disconnect **Classic BT** controllers first, **or** plug the adapter in via **USB** and use **Connect via USB** in the app. | + +Full technical detail: **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)** → *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth stability*. + - Xbox Series, One, and Elite 2 - Dualshock 3 - Dualshock 4 @@ -108,67 +123,11 @@ Note: There are some third party controllers that can change their VID/PID, thes Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supported_gamepads/) for a more comprehensive list of supported controllers and Bluetooth pairing instructions. -# Features new to this fork: -Note: These features have been added to the Pico W/ Pico 2 W firmware support, I do not have the other boards to test and implement the same fixes at this time. - -### Version 1.0.0.7a -- **OG Xbox mode stability** — Report sending was reverted to v1.0.0a5 behaviour: the adapter only builds and sends the HID report when new gamepad input is available (`new_pad_in()`). Sending every poll cycle caused random disconnects on the Original Xbox; the reversion restores stable operation. Rumble handling is unchanged. -- **PS2 (GPIO) / OPL stability** — The PS2 controller protocol response was reverted so the first response byte is the mode byte (no leading 0xFF). This restores compatibility with Open PS2 Loader and games; OPL no longer hangs at startup with the adapter connected. Core layout: Core1 runs Bluetooth when used; Core0 runs the main loop and PS2 device poll. -- **Xbox 360 (XInput) wake from standby** — When the 360 was turned off via **Guide → Turn off console** (soft shutdown), you can power it back on with the controller: **press Guide (Home)** or **hold Start for 3 seconds** (Start is preferred on Xbox One/PS5 pads so the controller doesn’t turn off). **Disclaimer:** The console must have been started at least once with the adapter connected; wake does **not** work from a cold start (e.g. console just plugged in or after a full power loss). In that case turn the console on with the front power button first. -- **PS3 wake from standby** — Same idea as 360: when the PS3 is in standby (turned off via **PS button → Turn off system**), you can wake it with **PS (Home)** or **hold Start for 3 seconds**—**only if the console keeps USB power when off**. Many PS3s cut power to the USB ports when shut down, so the adapter and controller disconnect; in that case wake is not possible. If your controller stays powered (e.g. charging light on) when the PS3 is off, wake may work. Same disclaimer as 360: no wake from cold start. - -### Version 1.0.0.6a -- **PS1/PS2 (GPIO) output mode** — The adapter can output to a PS1 or PS2 console as a controller over GPIO (no USB device in this mode). Select via button combo **Start + B** or set a fixed driver build. **Wiring (standard Pico):** connect the board to the console’s controller port using DATA=GP19, COMMAND=GP20, ATTENTION/SEL=GP21, CLOCK=GP22, ACKNOWLEDGE=GP26. Plug your USB gamepad into the adapter’s USB port; the console sees a DualShock-style controller. _Protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ -- **GameCube (GPIO) output mode** — The adapter can output to a GameCube or Wii (GameCube ports) as a controller over a single DATA line. Select via button combo **Start + X** or set a fixed driver build. **Wiring (standard Pico):** DATA=GP19, GND=GND; connect to the console’s controller port (single wire + ground). Plug your USB gamepad into the adapter’s USB port. _JoyBus protocol and PIO code ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ -- **N64 (GPIO) output mode** — The adapter can output to a Nintendo 64 console as a controller over a single DATA line. Select via button combo **Start + Right Bumper** or set a fixed driver build. **Wiring (standard Pico):** DATA=GP19, GND=GND; connect to the N64 controller port (same pin as GameCube). Use any **wired (USB)** or **Bluetooth** (Pico W / Pico 2 W) gamepad as input. _Protocol and PIO send code ported from [pdaxrom/usb2n64-adapter](https://github.com/pdaxrom/usb2n64-adapter). Memory pak and rumble pak are not emulated._ -- **Dreamcast (Maple Bus)** — **Input:** Read a real Dreamcast controller over GPIO (Pin A=GP10, B=GP11). **Output:** Use a USB or **Bluetooth** gamepad to control a Dreamcast: select **Start + Y** for Dreamcast mode, connect your BT or USB pad, wire the adapter’s Maple Bus (GP10/GP11) to the console’s controller port. Core1 runs the Maple device (responds to device info and GET_CONDITION); Core0 feeds gamepad state from USB/BT. When input source is **Dreamcast GPIO**, the bus is used as host only (read a DC pad). See [Dreamcast Port guide](Firmware/RP2040/docs/Dreamcast_Port.md). Maple Bus from [DreamPicoPort](https://github.com/OrangeFox86/DreamPicoPort). -- **Pin-outs and default mappings** — See [GPIO Output Pin-Out and Mappings](Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md) for pin numbers (PS1/PS2, Dreamcast, GameCube, N64) and default button/stick mappings for each mode. -- **Bluetooth input for PS1/PS2, GameCube, Dreamcast, and N64** — On **Pico W** (or Pico 2 W), you can use a **Bluetooth controller** as input while outputting to PS1, PS2, GameCube, Dreamcast, or N64. Select the mode (**Start + B**, **Start + X**, **Start + Y**, or **Start + Right Bumper**) as usual; pair your BT gamepad; the console sees the adapter as a controller. Wiring is the same for each mode (PS1/PS2: DATA/CMD/ATT/CLK/ACK; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10/GP11). -- **GPIO input from real PS1/PS2, GameCube, N64, or Dreamcast controllers** — You can use a **real wired PS1/PS2, GameCube, N64, or Dreamcast controller** as the adapter’s input in two ways: (1) **Output to other consoles (Switch, Xbox, DInput, etc.):** set output mode (e.g. **Start + D-pad Down** for Switch), then hold **Start + Select** for ~2.5 s until the input source cycles to **PSX GPIO**, **GameCube GPIO**, **Dreamcast GPIO**, or **N64 GPIO**; plug the real controller into the GPIO pins and connect the adapter’s USB to the target console. (2) **Output to PS1/PS2, GameCube, or Dreamcast:** in that output mode, hold **Start + Select** to set input to the matching GPIO and plug in the real controller (same pins). **Wiring:** PS1/PS2: DATA=GP19, CMD=GP20, ATT=GP21, CLK=GP22; GameCube/N64: DATA=GP19 + GND; Dreamcast: GP10, GP11. _PSX host, JoyBus host, N64 host ported from [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter)._ - -**PS2 output mode improvements (v1.0.0.6a):** -- **Button polarity (active-low)** — The PS2 controller protocol uses active-low button bytes: **0xFF = released**, **0 = pressed**. The driver was sending 0 when no button was pressed, so the console read all buttons as pressed (e.g. constant D-pad Up and menu scrolling). Fixed by initialising the report with `buttons1 = buttons2 = 0xFF` and clearing bits when a button is pressed, so neutral/no-controller state is correct. -- **Left stick Y axis** — Left analog stick up/down was inverted on output. The mapping for left stick Y was corrected so physical stick up corresponds to the value the PS2 expects for up. -- **Protocol flow** — PS2 device (controller) protocol and escape-mode response lengths follow [PicoGamepadConverter](https://github.com/Loc15/PicoGamepadConverter) and [DS4toPS2](https://github.com/TonyMacDonald1995/DS4toPS2) (single response byte then command, 7-byte escape responses with leading 0x5A) for broad console compatibility. -- **OPL (Open PS2 Loader)** — On Pico W, the main loop now drains all pending PS2 transactions each tick so rapid pad init (e.g. OPL at startup) does not desync or hang. **Keep the controller connected at boot** when using OPL; the PS2 pad driver typically does not re-detect controllers plugged in after an app has started, so unplugging then replugging will not give input in OPL. If OPL hangs (black screen) or inputs stop being registered, **power-cycle the Pico** (unplug and replug the adapter) so the PS2 link resets; the adapter also primes 0xFF after a desync drain so the next transaction is valid. **DualSense (PS5) over Bluetooth:** the Options button (Start) may not be reported as Start by the BT stack in some cases; if Options doesn’t work in OPL or in-game, try an Xbox or other controller, or use the DualSense over USB if your board supports it. - -### Version 1.0.0.5a -- **Switch Pro emulation** — Switch output mode now emulates a **Nintendo Switch Pro Controller** over USB (report format, subcommands, init handshake). Face-button and report layout follow the standard Pro Controller protocol (bit layout aligned with hardware/reference). _Switch Pro protocol and button report layout reference: [retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch) (N64/GameCube → Pico → Switch); Bluepad32 Switch parser used for validation._ -- **Waveshare RP2350-USB-A board support** — Build with `-DOGXM_BOARD=RP2350_USB_A` for the Waveshare RP2350-USB-A (wired USB host + RGB LED). _Board support from upstream [OGX-Mini](https://github.com/wiredopposite/OGX-Mini/commit/68bdec451077a33b0b1247ce01ed30e470163dea)._ -- **Additional board support** — **RP2350_ZERO** (Waveshare RP2350-Zero), **RP2040_XIAO** (Seeed Studio XIAO RP2040), and **RP2354**. All use the same Standard (PIO-USB host) firmware path; build with `-DOGXM_BOARD=RP2350_ZERO`, `RP2040_XIAO`, or `RP2354`. _Board support from [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ -- **8BitDo XInput (Xbox 360) fix** — Wired 8BitDo controllers (VID 0x2DC8, PID 0x3016 / 0x3106) are detected and sent a repeating LED-off keepalive so they stay connected and stable. _From [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ -- **Switch analog stick sensitivity** — Slight sensitivity increase (1.2× gain) for analog sticks in Switch Pro emulation mode; configurable via `STICK_GAIN_NUM` / `STICK_GAIN_DEN` in `Switch.cpp`. -- **Original Xbox (OG) Guide button behavior** — In OG Xbox mode, the Guide (SYS) button is mapped to Start; **tap** = Start, **hold 1 s** = soft IGR (LT+RT+Start+Back), **hold 3 s** = system shutdown (LT+RT+D-pad Up+Back). _Implementation based on [Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)._ - -### Version 1.0.0.4a -- **Wii (Wiimote) output mode** — On Pico W and Pico 2 W, build with `-DOGXM_FIXED_DRIVER=WII` for a Wii-only firmware. The adapter appears as a Wiimote over Bluetooth; use a USB gamepad on the external PIO USB port. Supports No Extension, Nunchuk, and Classic Controller report modes (cycle with Home + D-pad Down). See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). _Approach and mappings based on [PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)._ -- Xbox 360 no longer requires the USB patch to authenticate, uses the same authentication as Joypad-OS to do official handshake with Retail consoles. Homebrew/ Jailbreaking is no longer required to use the XINPUT mode on 360 but it will no longer output to PC. -- **Rumble fix for Xbox 360 controllers** — Rumble on 360 pads is now handled correctly when using the adapter (including wireless RUMBLE_ENABLE sequence). _Xbox 360 vibration/rumble handling attributed to [faithvoid](https://github.com/faithvoid) on GitHub._ -- **Pico 2 / Pico 2 W build fixes** — Firmware builds and runs correctly on RP2350 (Pico 2 and Pico 2 W). -- Improved latency on Xbox 360 and PS3 controllers. -- **PS3 mode:** Home (PS) button works with DS4/DS5 over Bluetooth (8-frame latch so short taps register). Analog sticks now match DualShock 3 spec: full 0–255 range, center 0x80 (128), ~1.5% deadzone for accurate emulation. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md#ps3-mode--input-delays-stuck-inputs-home-button-and-analog-stick-emulation). -- Added build flags so you can make it only output in a specific mode and disable mode switching. -- Using a PS5 controller allows you to tap the touchpad to enable or disable the adaptive triggers. - -### Version 1.0.0.3a patched -- Ability to emulate the GameCube controller adapter for Wii U. (Also tested on Switch 1/ 2) -- Wii U & Switch Pro controllers are supported fully with working LT and RT -- Wii Remotes are supported along with the following controllers connected: Nunchuck/ GameCube/ Wii Gamepad. -- Disconnection Combo has been added: Start+Select for most controllers, L3+R3 for OUYA controllers. - -## Features new to v1.0.0 -- Bluetooth functionality for the Pico W, Pico 2 W, and Pico+ESP32. -- Web application (connectable via USB or Bluetooth) for configuring deadzones and buttons mappings, supports up to 8 saved profiles. -- Pi Pico 2 and Pico 2 W (RP2350) support. -- Reduced latency by about 3-4 ms, graphs showing comparisons are coming. -- 4 channel functionality, connect 4 Picos and use one Xbox 360 wireless adapter to control all 4. -- Delayed USB mount until a controller is plugged in, useful for internal installation (non-Bluetooth boards only). -- Generic HID controller support. -- Dualshock 3 emulation (minus gyros), rumble now works. -- Steel Battalion controller emulation with a wireless Xbox 360 chatpad. -- Xbox DVD dongle emulation. You must provide or dump your own dongle firmware, see the Tools directory. -- Analog button support on OG Xbox and PS3. -- RGB LED support for RP2040-Zero and Adafruit Feather boards. +# Features new to this fork + +Version history and release notes are in **[CHANGELOG.md](CHANGELOG.md)**. For detailed firmware improvements — **PS3**, **XInput / XSM3**, **OG Xbox**, **PS2/OPL**, **latency**, **Pico W Bluetooth (DS4 Classic BT, BLE coexistence, Xbox Series BLE)**, etc. — see **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)**. + +*Note: Many features were added and tested on Pico W / Pico 2 W; other boards may not have been tested for every change.* ## Planned additions from the original creator - More accurate report parser for unknown HID controllers @@ -203,11 +162,39 @@ I've designed a PCB for the RP2040-Zero so you can make a small form-factor adap If you would like a prebuilt unit, you can purchase one, with cable and Xbox adapter included, from the original creators store: [**Etsy store**](https://www.etsy.com/listing/1426992904/ogx-mini-controller-adapter-for-original). ## Adding supported controllers -If your third party controller isn't working, but the original version is listed above, send me the device's VID and PID and I'll add it so it's recognized properly. + +If your third‑party controller isn’t working but a similar one (e.g. same brand or protocol) is listed in [Wired Controllers](Firmware/RP2040/docs/Wired_Controllers.md), we can add support by registering its **VID** (Vendor ID) and **PID** (Product ID). Send those two values (and the controller name/model if you know it) so they can be added to the right list in `Firmware/RP2040/src/USBHost/HardwareIDs.h`. + +### How to get VID and PID + +**Windows** + +- **Device Manager:** Plug in the controller → open Device Manager → find it under “Sound, video and game controllers” or “Human Interface Devices” → right‑click → **Properties** → **Details** → **Property:** “Hardware Ids”. You’ll see something like `HID\VID_054C&PID_09CC`; **VID** is the hex after `VID_`, **PID** is the hex after `PID_` (e.g. VID `054C`, PID `09CC`). +- **USBDeview** (NirSoft): Lists all USB devices with VID and PID in columns. + +**Linux** + +- Run `lsusb` with the controller plugged in. Each line is `Bus ... Device ... ID **vid:pid** Manufacturer Product`. Use the `vid` and `pid` from the line that matches your controller (e.g. `054c:09cc` → VID `054C`, PID `09CC`; we use uppercase hex in the code). +- Alternatively: `lsusb -v` and look at `idVendor` and `idProduct` for the gamepad interface. + +**macOS** + +- **System Information:** Apple menu → **About This Mac** → **System Report** → **USB** (or **Bluetooth** if wireless). Select the controller; **Vendor ID** and **Product ID** are shown (often in decimal — convert to hex for the code, e.g. 1356 decimal → `054C` hex). +- Or use **System Profiler** and open the USB section. + +**Web / gamepad API** + +- Some browser-based tools (e.g. [gamepad tester](https://gamepad-tester.com/) or similar) show the connected gamepad’s VID/PID in the page or in the browser’s device/Gamepad API info. Check the site’s instructions. + +When submitting, include **VID**, **PID**, and controller name (e.g. “8BitDo Pro 2 in DInput mode”). If the controller has multiple modes (XInput / DInput / Switch), note which mode you used when reading the IDs. ## Build ### RP2040 -Build with **CMake** from the `Firmware/RP2040` directory. You can compile for different boards with the CMake argument ```OGXM_BOARD```: +Build with **CMake** from the `Firmware/RP2040` directory (or use the build scripts below). Prerequisites: git, python3, CMake, Ninja, and the GCC ARM toolchain. CMake will patch Bluepad32/BTStack and fetch submodules as needed. + +#### Board options (OGXM_BOARD) + +Use one of these values for **`OGXM_BOARD`** in a manual build, or pick the same board from the build script’s numbered list: - ```PI_PICO``` - ```PI_PICO2``` @@ -218,7 +205,7 @@ Build with **CMake** from the `Firmware/RP2040` directory. You can compile for d - ```RP2350_ZERO``` (Waveshare RP2350-Zero) - ```RP2040_XIAO``` (Seeed Studio XIAO RP2040) - ```RP2354``` -- ```ADAFRUIT_FEATHER``` +- ```ADAFRUIT_FEATHER``` use the board’s **USB Type-A** port for the controller; 5V enable is GPIO 18, D+/D− are GPIO 16/17. If the controller is not detected, plug it in **after** the board has booted and ensure the green 5V LED next to the USB-A port is on.) - ```ESP32_BLUEPAD32_I2C``` - ```ESP32_BLUERETRO_I2C``` - ```EXTERNAL_4CH_I2C``` @@ -227,8 +214,27 @@ You can also set ```MAX_GAMEPADS``` (if > 1, only DInput/PS3 and Switch Pro a You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. -**Interactive build scripts:** From the project root, run **`scripts/build.sh`** (Linux/macOS) or **`scripts/build.ps1`** (Windows PowerShell) to be guided through board selection, default vs fixed output mode, Release/Debug, and build. The script checks for required tools, creates **`scripts/build`** for the build output, and on failure can optionally save a log in the `scripts` folder. -Here's an example on Windows (manual build): +#### Build scripts (recommended for new users) + +We provide interactive build scripts so you can build firmware without memorizing CMake options: + +| Platform | Command (run from project root) | +|----------|----------------------------------| +| **Linux / macOS** | `./scripts/build.sh` | +| **Windows (PowerShell)** | `.\scripts\build.ps1` | + +The script will: + +1. **Check prerequisites** — Verifies that `git`, `python3` (or `python`), `cmake`, `ninja`, and `arm-none-eabi-gcc` are installed. If something is missing, it prints install hints (e.g. `apt install` on Debian/Ubuntu, `brew install` on macOS, Chocolatey on Windows). +2. **Ask for your board** — Choose from a numbered list (Pi Pico, Pi Pico W, Pi Pico 2 W, RP2040-Zero, XIAO, Adafruit Feather, 4CH I2C, ESP32 hybrid, etc.). +3. **Ask for build type** — **Default** (all output modes available via button combos) or **Fixed output mode** (e.g. Wii, GameCube, N64 — one mode only, no combo switching). +4. **Ask for configuration** — **Release** (smaller, faster) or **Debug** (UART logging for troubleshooting). + +Build output (`.uf2`, `.elf`, etc.) is written to **`scripts/build/`**. To flash the board, copy the `.uf2` file from that folder to the Pico’s USB drive. If the build fails, the script can save a log to `scripts/build_log.txt` for debugging. + +#### Manual build (CMake from command line) + +If you prefer to run CMake yourself or use an IDE (e.g. VSCode CMake Tools), use the same options the scripts pass. Example (Windows, Pico W, Release): ``` git clone --recursive https://github.com/MegaCadeDev/OGX-Mini-2026.git cd OGX-Mini-2026/Firmware/RP2040 From e20164bc9e7cbbe2bd955e52e6b505c741a09146 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Wed, 25 Mar 2026 06:03:10 -0400 Subject: [PATCH 31/42] Switch 2 Pro (0x2069) wired USB host, v1.0.0a9 - Switch2ProHost: full digital mapping from 10-byte payload; bulk bring-up - Optional OGXM_SWITCH2_HID_RAW_LOG (Debug); build scripts prompt - Docs: Wired_Controllers, README, CHANGELOG; FW v1.0.0a9 - ogxm_log via stdio UART; controller_capture tooling --- .gitignore | 4 + CHANGELOG.md | 10 + Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/CMakeLists.txt | 11 +- Firmware/RP2040/docs/IMPROVEMENTS.md | 52 +- Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md | 17 +- Firmware/RP2040/docs/Wired_Controllers.md | 5 + Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 114 +- Firmware/RP2040/src/Bluepad32/Bluepad32.h | 11 + Firmware/RP2040/src/Board/Config.h | 5 - Firmware/RP2040/src/Board/board_api.cpp | 46 + Firmware/RP2040/src/Board/board_api.h | 2 + .../board_api_private/board_api_private.h | 6 + .../board_api_private/board_api_usbh.cpp | 43 +- Firmware/RP2040/src/Board/ogxm_log.cpp | 11 +- Firmware/RP2040/src/Descriptors/SwitchPro.h | 4 + Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 277 +++- Firmware/RP2040/src/OGXMini/Board/PicoW.h | 4 + .../src/USBDevice/DeviceDriver/PS3/PS3.cpp | 13 +- Firmware/RP2040/src/USBHost/HardwareIDs.h | 11 +- .../src/USBHost/HostDriver/HostDriverTypes.h | 2 + .../RP2040/src/USBHost/HostDriver/PS3/PS3.cpp | 79 + .../RP2040/src/USBHost/HostDriver/PS3/PS3.h | 17 + .../RP2040/src/USBHost/HostDriver/PS4/PS4.cpp | 25 + .../SwitchPro/Switch2ProCaptureTables.h | 126 ++ .../HostDriver/SwitchPro/Switch2ProHost.cpp | 190 +++ .../HostDriver/SwitchPro/Switch2ProHost.h | 32 + .../SwitchPro/Switch2UsbInitPackets.h | 51 + .../HostDriver/SwitchPro/SwitchPro.cpp | 388 ++++- .../USBHost/HostDriver/SwitchPro/SwitchPro.h | 36 +- .../XInput/tuh_xinput/tuh_xinput.cpp | 11 + Firmware/RP2040/src/USBHost/HostManager.h | 266 +++- Firmware/RP2040/src/USBHost/tuh_callbacks.cpp | 13 +- Firmware/RP2040/src/tusb_config.h | 3 + README.md | 30 +- Tools/README.md | 11 +- Tools/controller_capture/README.md | 117 ++ .../controller_capture/analyze_hidraw_xor.py | 106 ++ .../controller_capture/controller_capture.py | 1299 +++++++++++++++++ .../hidraw_full_report_dump.py | 139 ++ Tools/controller_capture/raw_hid_capture.py | 458 ++++++ Tools/controller_capture/requirements.txt | 4 + Tools/controller_capture/switch2_usb_init.py | 373 +++++ scripts/build.ps1 | 26 +- scripts/build.sh | 24 +- 45 files changed, 4332 insertions(+), 142 deletions(-) create mode 100644 Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProCaptureTables.h create mode 100644 Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp create mode 100644 Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h create mode 100644 Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h create mode 100644 Tools/controller_capture/README.md create mode 100644 Tools/controller_capture/analyze_hidraw_xor.py create mode 100644 Tools/controller_capture/controller_capture.py create mode 100644 Tools/controller_capture/hidraw_full_report_dump.py create mode 100644 Tools/controller_capture/raw_hid_capture.py create mode 100644 Tools/controller_capture/requirements.txt create mode 100644 Tools/controller_capture/switch2_usb_init.py diff --git a/.gitignore b/.gitignore index b00d5b9e..cb502ec9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,10 @@ Firmware/external/pico-sdk Firmware/external/picotool Tools/dvd-dongle-rom.bin +# Python +**/__pycache__/ +*.py[cod] + # Local docs (not for GitHub) Firmware/RP2040/docs/XInput_joypad-os_comparison.md Firmware/RP2040/docs/BLUEPAD32_PS4_PS5_PARSING.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 79024c95..b0d62543 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ Features and fixes added in this fork. For the latest firmware improvements (PS3 --- +### Version 1.0.0.9a *(planned / next release)* + +- **Nintendo Switch 2 Pro (USB PID 0x2069), wired** — **Switch2ProHost** now maps **face buttons, d‑pad, LB/RB, L3, R3, Start, Guide/SYS, Minus (Back), ZL/ZR as LT/RT** from the stable **10‑byte** input payload after report **0x09** (extended / IMU bytes unused to avoid flicker). **GL**, **GR**, and **Chat** are documented in code but intentionally unmapped. **Wired USB to the adapter only** (see [Wired_Controllers.md](Firmware/RP2040/docs/Wired_Controllers.md)). Debug: optional **`OGXM_SWITCH2_HID_RAW_LOG`** logs when the **three digital button bytes** change (UART). +- **Bluetooth (Pico W / Pico 2 W)** — **~1 second connection rumble** when a wireless controller reaches **device ready**, so you get haptic feedback that pairing completed. **DualShock 4** uses a **delayed start** before rumble (same spirit as the existing PS4 FF grace period). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Next version* and *§6. Connection rumble*). +- **PS3 mode on Windows PC** — **Host rumble** forwarded to the Bluetooth pad no longer **sticks on at idle**: deadzone on the **large motor** byte and **small motor on only when the host sends `1`** (DS3 semantics). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*PS3 mode* item 7). +- **Pico W / Pico 2 W — PIO USB wired unplug** — Unplugging the gamepad from the adapter’s **USB host** port is detected reliably: **PIO-owned D+/D−** often never looks “disconnected” to GPIO/HCD alone. Firmware now uses **debounced** **HCD port status**, **no `tuh_mounted` device** (all TinyUSB address slots), and a **no-input** watchdog (**~3 s** without `process_report` / setup activity) before **`tuh_deinit`** and restoring **GPIO line IRQ** monitoring so **Bluetooth** can resume without power-cycling. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Pico W / Pico 2 W — PIO USB wired controller unplug detection*). +- **DualShock 3 — USB Bluetooth pairing on adapters with BT** — Plugging a **DS3** into the **USB host** port automatically sends **HID feature report `0xF5`** with this device’s **Bluetooth address** (same idea as [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/)), so you can **unplug** and press **PS** to use the pad wirelessly. If the stack has not published the local BD_ADDR yet, pairing runs on a later report. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — automatic USB programming for Bluetooth pairing*). + +--- + ### Version 1.0.0.8a - **PS4 (DualShock 4) over Bluetooth (Pico W)** — **OGX-Mini BLE advertising** (phone setup app) runs continuously on the same **CYW43439** radio as **Classic BR/EDR** (DS4). That mix commonly **drops the DS4 link** right after the blue LED. **Fix:** **`gap_advertisements_enable(0)`** before DS4 HID setup and whenever any **ACL** gamepad is ready; **re-enable** when the last Classic pad disconnects (BLE-only pads e.g. DualSense unchanged). Still: **BR inquiry off** during ACL, **no DS4 virtual mouse**, **6 s** PS4 rumble grace. **Docs:** [README](README.md) (Wireless Bluetooth), [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth*). diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index 6996e011..a0b89deb 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a8") \ No newline at end of file +set(FW_VERSION "v1.0.0a9") \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index f23b9b1f..955e2a93 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -119,6 +119,8 @@ set(INC_DIRS_BOARD # Config options +option(OGXM_SWITCH2_HID_RAW_LOG "UART: log Switch 2 Pro (0x2069) 64B HID when the 3 digital button bytes change only (Debug)" OFF) + set(MAX_GAMEPADS 1 CACHE STRING "Set number of gamepads, 1 to 4") if (MAX_GAMEPADS GREATER 4 OR MAX_GAMEPADS LESS 1) message(FATAL_ERROR "MAX_GAMEPADS must be between 1 and 4") @@ -297,6 +299,7 @@ if(EN_USB_HOST) ${SRC}/USBHost/HostDriver/PSClassic/PSClassic.cpp ${SRC}/USBHost/HostDriver/SwitchWired/SwitchWired.cpp ${SRC}/USBHost/HostDriver/SwitchPro/SwitchPro.cpp + ${SRC}/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp ${SRC}/USBHost/HostDriver/PS5/PS5.cpp ${SRC}/USBHost/HostDriver/PS4/PS4.cpp ${SRC}/USBHost/HostDriver/PS3/PS3.cpp @@ -453,7 +456,7 @@ add_executable(${FW_NAME} ${SOURCES_BOARD}) set(BUILD_STR "") if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Debug build enabled (UART logging).") + message(STATUS "Debug build enabled (UART logging at 115200; TinyUSB host prevents USB CDC stdio — use UART TX pin, see CMakeLists UART message).") set(BUILD_STR "-Debug") # Pico W/2W: use UART1 on GP4 (TX) / GP5 (RX) - valid UART pins, avoids PIO USB (GP0/1) in Wii mode @@ -472,6 +475,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS "UART port: ${UART_PORT}, TX: ${TX_PIN}, RX: ${RX_PIN}") + # USB CDC stdio is disabled by Pico SDK when TinyUSB host is linked; OGXM_LOG uses printf → UART only. pico_enable_stdio_usb(${FW_NAME} 0) pico_enable_stdio_uart(${FW_NAME} 1) target_compile_definitions(${FW_NAME} PRIVATE @@ -484,6 +488,11 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_definitions(OGXM_DEBUG=1) add_compile_definitions(CONFIG_OGXM_DEBUG=1) + if(OGXM_SWITCH2_HID_RAW_LOG) + target_compile_definitions(${FW_NAME} PRIVATE OGXM_SWITCH2_HID_RAW_LOG=1) + message(STATUS "OGXM_SWITCH2_HID_RAW_LOG: UART hex when Switch 2 Pro 3 digital button bytes change") + endif() + target_compile_options(${FW_NAME} PRIVATE -Wall # Enable most warnings -Wextra # Enable extra warnings diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 7899e728..7293d134 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -4,6 +4,13 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. **Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). +**Next version (e.g. v1.0.0.9a) — documented here for release notes:** + +- **Bluetooth (Pico W / Pico 2 W):** ~**1 second** haptic **connection rumble** when a wireless controller reaches **device ready** (so you can feel that pairing completed). **DualShock 4** uses a **longer start delay** before rumble (same idea as the existing PS4 FF grace window) so early force-feedback does not destabilize the link. **File:** `src/Bluepad32/Bluepad32.cpp` — `ogxm_play_connection_rumble()` from `device_ready_cb`. +- **PS3 mode with the adapter plugged into a Windows PC:** **Host output rumble** forwarded to the Bluetooth pad no longer stays on at idle. Windows DInput often sends a **small non-zero** large-motor byte or a **small-motor byte other than 0/1**; the driver now applies a **deadzone** on the large motor and treats the small motor as on **only when the byte is `1`** (DS3 output semantics). **File:** `src/USBDevice/DeviceDriver/PS3/PS3.cpp` — `new_report_out_` path. +- **Pico W / Pico 2 W — PIO USB wired unplug:** **Reliable disconnect** when the gamepad cable is removed from the adapter’s PIO USB host port (see [§ Pico W / Pico 2 W — PIO USB wired controller unplug detection](#pico-w--pico-2-w--pio-usb-wired-controller-unplug-detection)). **Files:** `src/OGXMini/Board/PicoW.cpp`, `src/USBHost/HostManager.h`. +- **DualShock 3 — automatic Bluetooth pairing over USB (boards with Bluetooth):** When a **PS3 / DualShock 3** controller is used **wired** on the USB host, after the normal USB HID init the firmware sends **HID feature report `0xF5`** with the adapter’s **local BD_ADDR** (same as [Bluepad32’s sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/)), so the user can **unplug USB** and connect with **PS**. If `uni_local_bd_addr` is not ready yet, pairing is **deferred** until the first reports where the address is valid. **File:** `src/USBHost/HostDriver/PS3/PS3.cpp` (guarded by `CONFIG_EN_BLUETOOTH`). + --- ## Xbox 360 (XInput) support @@ -83,6 +90,11 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad - **Many PS3s cut power to the USB ports** when shut down, so the adapter and controller disconnect and wake is not possible. If your controller stays powered (e.g. charging LED) when the PS3 is off, that model may keep USB in standby and wake may work. Same disclaimer as 360: no wake from cold start; use the console power button first if needed. - **Recovery Mode:** Even when wake from standby is not possible (e.g. console cuts USB when off), the adapter is **confirmed working in PS3 Recovery Mode** — you can use it to navigate and select options in Recovery. +7. **Host rumble → Bluetooth pad (PS3 mode on PC)** *(next version)* + When the adapter is in **PS3 output mode** and connected to a **Windows** host, the OS still sends **HID output** (rumble) to the device. That output is forwarded to the **Bluetooth** gamepad as `PadOut` rumble. Some Windows stacks leave **noise** in the report (small large-motor values, or non‑`0`/`1` small-motor bytes). Forwarding that blindly caused **constant vibration** on the wireless controller at idle. + **Fix:** Ignore large-motor values **below a small threshold** (deadzone), and treat the **small motor as on only when the host byte is `1`** (not “any non-zero”). + **File:** `PS3.cpp` — block that runs when `new_report_out_` is set after `set_report_cb` parses the DS3 output report. + --- ## Latency reduction @@ -213,6 +225,34 @@ Some 8BitDo wired XInput controllers (VID 0x2DC8, PID 0x3016 or 0x3106) can disc --- +## Pico W / Pico 2 W — PIO USB wired controller unplug detection + +**Problem:** On **Pico W / Pico 2 W**, the **USB gamepad** plugs into a **PIO USB** host. While PIO owns **D+ / D−**, reading line state with **`gpio_get()`** (as in **`pio_usb_bus_get_line_state()`** / **`hcd_port_connect_status()`**) often **does not** show a clean **SE0** after you pull the cable — lines can **float** or sit in a state that still looks like full-speed idle. The firmware could keep thinking the port was **connected**, so **TinyUSB** stayed up, **HostManager** still had a slot, and **Bluetooth** stayed blocked (wired takeover) until a power-cycle or “shorting” the port. + +**Approach:** In **`pico_w_pio_usb_bt_mux_tick()`** (`src/OGXMini/Board/PicoW.cpp`), treat **unplug** when **`HostManager::any_mounted()`** is still true **and** **any** of these **hints** fires (all share one **debounce**, ~**60 ms** wall time): + +1. **`!hcd_port_connect_status(BOARD_TUH_RHPORT)`** — line-based disconnect when the HCD stack *does* see disconnect. +2. **No configured TinyUSB device** — loop device addresses **`1 … CFG_TUH_DEVICE_MAX + CFG_TUH_HUB`** (matches TinyUSB’s internal **`TOTAL_DEVICES`**) and require **`tuh_mounted(d)`** for at least one address. If the stack has dropped configuration, tear down even if the line hint lied. +3. **No USB host input for several seconds** — **`HostManager::usb_host_input_idle_ms()`** (default threshold **3000 ms** in `PicoW.cpp`) — after unplug, **IN transfers** and **`process_report()`** usually stop even if (1) and (2) lag. **`record_usb_host_input_activity()`** is called from **`process_report()`** and after successful **`setup_driver()`** (`src/USBHost/HostManager.h`). **`HostManager::initialize()`** seeds **`last_usb_host_input_ms_`** from **`board_api::ms_since_boot()`** so idle time is not huge before the first device. + +After debounced confirmation, **`pico_w_usb_host_full_stop()`** runs **`tuh_deinit`**, stops the SOF timer, clears unplug debounce state, and **`board_api_usbh::enable_host_line_irq_monitoring()`** so normal **GPIO unplug/plug** IRQs work again; **Bluetooth** release paths run as before. + +**Tuning:** If unplug feels slow, lower **`USB_UNPLUG_NO_INPUT_MS`** in `PicoW.cpp`. If a controller that **rarely sends reports** when idle ever mis-triggers unplug, raise that constant slightly. + +--- + +## DualShock 3 — automatic USB programming for Bluetooth pairing + +**Background:** The **DualShock 3** does not implement standard Bluetooth pairing. The host’s **BD_ADDR** must be written to the pad over **USB** using a **HID feature report** (report ID **`0xF5`**, 8 bytes: id + padding + 6-byte MAC). This is what the [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/) utility does from a PC. + +**Behavior in this firmware:** On builds with **`CONFIG_EN_BLUETOOTH`** (e.g. **Pico W / Pico 2 W**, ESP32 hybrids with Bluepad32), after the existing **PS3 USB init** (`GET_REPORT` **0xF2** sequence) completes, **`PS3Host`** sends **`SET_REPORT`** **feature 0xF5** with **`uni_bt_get_local_bd_addr_safe()`**, then continues with the usual rumble **OUT** report. If the local address is still **all zeros** (Bluetooth stack not finished starting), the code sets a **deferred** flag and **`try_deferred_ds3_bt_pair()`** runs at the start of **`process_report()`** until the address is valid, then sends **0xF5** once. + +**User steps:** Plug the **DS3 into the adapter’s USB host port** (wait for it to work wired if you like), then **unplug** and press **PS** to use it wirelessly — same as the manual pairing flow documented for Bluepad32. + +**Files:** `src/USBHost/HostDriver/PS3/PS3.cpp`, `PS3.h`. + +--- + ## Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth (BR/EDR) stability **Context:** On **CYW43439** (Pico W / Pico 2 W), **BLE** and **Classic Bluetooth (BR/EDR)** share one radio. **DualShock 4** uses **Classic ACL** only. **DualSense**, **Xbox Series (BLE)**, and **Switch Pro** (typical pairing) use **LE** — so DS4 was uniquely sensitive to how the stack used the radio at the same time as other activity. @@ -256,6 +296,12 @@ For **`CONTROLLER_TYPE_PS4Controller`**, **rumble output** is **delayed ~6 secon - **Reconnect:** last device disconnect calls **`uni_bt_enable_new_connections_unsafe(true)`** so pairing can resume without power-cycling. - **8 s input-stall disconnect** (non-virtual, non-BLE-Xbox) to clear zombie links; **BLE Xbox** uses keepalive instead of stall disconnect. +### 6. Connection rumble when the wireless controller is ready *(next version)* + +When Bluepad32 reports **`device_ready`** for a non-virtual gamepad, the firmware plays about **one second** of **dual-motor rumble** (via `play_dual_rumble` when the controller supports it) so you can **feel** that the Bluetooth link is up. **DualShock 4** uses a **~1.2 s delay** before starting that rumble so it does not overlap the fragile post-connect window (aligned with the existing PS4 rumble grace logic). Other controller types use a shorter default delay. + +**File:** `src/Bluepad32/Bluepad32.cpp` — `ogxm_play_connection_rumble()`, called from `device_ready_cb`. + --- ## Switch Pro — analog stick sensitivity @@ -284,11 +330,13 @@ The script checks for required tools (git, python3, cmake, ninja, arm-none-eabi- | Area | Improvement | |------|-------------| | **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. Report built every loop, send when endpoint ready — same minimal-latency pattern as Switch/PS3. | -| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. | +| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **Next version:** PC host rumble deadzone + strict small-motor `0`/`1` so idle rumble does not stick on the BT pad. | | **PS2 (GPIO)** | Home only = IGR (L1+L2+R1+R2+Start+Select); Home+Start = shutdown (L1+L2+R1+R2+L3+R3). OPL and protocol stability (first response byte = mode byte). | | **OG Xbox** | Guide only = IGR. Shutdown = LT+RT+Back+White via **Guide+Start** or **Guide+View (Back)**; Xbox BT often omits Start while Guide is held. Shutdown report strips Start so the chord matches BIOS/softmod expectations. | | **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. | | **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). | | **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). Switch Pro and PS3 always build report every loop so host poll (`get_report`) and IN push both see current state — only remaining delay is BT radio when wireless. | | **Build** | Interactive scripts `scripts/build.sh` (Linux/macOS) and `scripts/build.ps1` (Windows) for board selection, fixed/default mode, and Release/Debug; output in `scripts/build/`. See [README](../../../README.md) Build section. | -| **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in; re-enable scan on last disconnect. | +| **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in; re-enable scan on last disconnect. **Next version:** ~**1 s connection rumble** at `device_ready` (DS4 delayed start). | +| **PIO USB host (Pico W)** | **Wired unplug:** Debounced combo of **HCD connect**, **`tuh_mounted` over all device addresses**, and **no `process_report` / setup activity** (~**3 s**) so disconnect registers when D+/D− line state is wrong under PIO; **`tuh_deinit`** + restore GPIO line IRQs + BT release. See [§ Pico W — PIO USB wired controller unplug detection](#pico-w--pico-2-w--pio-usb-wired-controller-unplug-detection). | +| **DS3 + Bluetooth** | **USB auto-pair:** After PS3 wired init, **feature `0xF5`** programs the **DS3** with the adapter’s **BD_ADDR** (`CONFIG_EN_BLUETOOTH`); deferred if BT address not ready. See [§ DualShock 3 — automatic USB programming for Bluetooth pairing](#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). | diff --git a/Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md b/Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md index 7757099a..f2c34a55 100644 --- a/Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md +++ b/Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md @@ -75,7 +75,18 @@ Example (from `Firmware/RP2040`): --- -## 6. Debug / UART logging (crash debugging) +## 6. External USB in other output modes (Pico W / Pico 2 W) + +For firmware built for **Pico W / Pico 2 W** with **USB host** enabled but **not** Wii-only (e.g. combo builds, Xbox/Switch/PS output over Bluetooth or USB device), the **same external PIO USB port** (D+/D− on GP0/GP1 per §3) can host a **wired gamepad**. Input is merged with the normal gamepad path and appears on the chosen output. + +- **Mutual exclusion with Bluetooth:** If **any** Bluetooth gamepad is already connected, the firmware does **not** bring up PIO USB host for that tick; wired devices on the external port are **ignored** until **all** Bluetooth gamepads disconnect. Conversely, when a wired controller **enumerates** on the external port, **all** Bluetooth gamepads are disconnected and **new** Bluetooth connections are disabled until that wired device is **unplugged** (then Bluetooth pairing/connect is allowed again). +- **No external port required:** If you do **not** wire the external connector, the firmware **debounces** D+/D− activity before starting the host; builds behave like **Bluetooth-only** adapters with no dependency on the port being present. + +**Wii-only builds** (`-DOGXM_FIXED_DRIVER=WII`) still use the dedicated Wii USB host path on Core 1 as before; this section applies to **non-Wii** Pico W / Pico 2 W builds that include `CONFIG_EN_USB_HOST`. + +--- + +## 7. Debug / UART logging (crash debugging) To see where the firmware gets to when switching to Wii mode (or if it crashes), build in **Debug** so that **UART logging** is enabled. Logs go to **UART1** on **GP4 (TX)** and **GP5 (RX)** so they do not conflict with PIO USB on GP0/GP1. (GP10/11 are not valid UART pins on RP2040/RP2350.) @@ -85,14 +96,14 @@ To see where the firmware gets to when switching to Wii mode (or if it crashes), --- -## 7. Troubleshooting +## 8. Troubleshooting | Symptom | Likely cause | What to do | |--------|----------------|------------| | Controller vibrates, no LED, doesn’t sync | Host using native USB instead of PIO USB | Ensure Wii mode uses PIO USB (roothub 1) as in §2. | | Same | D+ and D− swapped on cable | Set `PIO_USB_SWAP_DP_DM 1` in config and rebuild, or swap D+ and D− wires. | | No response at all | Wrong port or no VBUS | Use the **external** USB (PIO USB) and ensure VBUS has 5 V. | -| Crash when switching to Wii | Debug with UART (GP4/5) | Build Debug, connect UART to GP4/5 @ 115200; see §6. | +| Crash when switching to Wii | Debug with UART (GP4/5) | Build Debug, connect UART to GP4/5 @ 115200; see §7. | --- diff --git a/Firmware/RP2040/docs/Wired_Controllers.md b/Firmware/RP2040/docs/Wired_Controllers.md index 0eff25e6..8ec2284d 100644 --- a/Firmware/RP2040/docs/Wired_Controllers.md +++ b/Firmware/RP2040/docs/Wired_Controllers.md @@ -59,6 +59,11 @@ This document lists controllers supported when connected to the OGX-Mini adapter *See `SWITCH_PRO_IDS` and `SWITCH_WIRED_IDS` in `HardwareIDs.h` for the full VID/PID list.* +**Switch 2–family USB (Pro Controller 2, Joy‑Con 2, NSO GameCube, etc.):** +The firmware runs the same vendor **bulk OUT** bring‑up on **USB configuration 1, interface 1** as the PC capture tool (`Tools/controller_capture/switch2_usb_init.py` / HandHeldLegend ProCon 2 enabler), then continues with the normal Switch Pro **HID** init (handshake, full report mode, etc.). Wired input reports may use report ID **0x09** (with a 1‑byte counter after the ID). + +**Switch 2 Pro (PID 0x2069), wired USB only:** After the same **bulk OUT** bring‑up on **config 1 / interface 1**, **Switch2ProHost** parses the standard **64‑byte** HID report (ID **0x09**, 1‑byte counter, then **10‑byte** `SwitchPro::InReport` payload). Digitals use **Switch‑2‑specific** bit positions (not classic **Buttons0/1/2**): face **B/A/Y/X**, **RB**, **LB** (Home bit), **Minus** → Back, **Plus** / d‑pad directions, **L3**, **Start** (classic R), **R3** (classic ZR bit), **SYS** (classic `bl` d‑pad up), **ZL/ZR** → **LT/RT** (digital full press from captured bits), and **Capture** is still not mapped to **MISC**. **GL**, **GR**, and **Chat** are **documented in source** (`Switch2ProHost.cpp`) but **left unmapped**. Extended report bytes are not used for decoding (avoids IMU coupling / flicker). **Bluetooth** for this model is **not** covered here—use a **wired** connection to the adapter’s USB host port. Other Switch 2–family PIDs keep **SwitchProHost**. + --- ### PlayStation Classic diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index c8839f10..bfb0a3da 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -6,15 +6,23 @@ #include #include +#include #include "btstack_run_loop.h" #include "gap.h" #include "uni.h" #include "bt/uni_bt.h" #include "bt/uni_bt_bredr.h" +#include "uni_hid_device.h" #include "parser/uni_hid_parser_ds5.h" #include "parser/uni_hid_parser_xboxone.h" #include "sdkconfig.h" + +#if defined(CONFIG_TARGET_PICO_W) && defined(CONFIG_EN_USB_HOST) +/** Core0 USB mux reads this while Core1 BT stack updates connections — mirror bt_devices_[].connected. */ +static std::atomic s_bt_any_connected_cached{false}; +#endif + #include "Bluepad32/Bluepad32.h" #include "Board/board_api.h" #include "Board/ogxm_log.h" @@ -35,6 +43,14 @@ static constexpr uint32_t BT_INPUT_STALL_DISCONNECT_MS = 8000; /** BLE Xbox: host→pad output while idle (no rumble) or controller sleeps link ~1 min */ static constexpr uint32_t XBOX_BLE_KEEPALIVE_MS = 12000; +/** One-second rumble when a pad becomes ready so the user knows it is connected. */ +static constexpr uint16_t CONNECT_RUMBLE_DURATION_MS = 1000; +static constexpr uint8_t CONNECT_RUMBLE_WEAK = 160; +static constexpr uint8_t CONNECT_RUMBLE_STRONG = 160; +/** DS4: defer FF slightly — early output reports can destabilize the link (see s_ps4_rumble_ok_ms). */ +static constexpr uint16_t CONNECT_RUMBLE_DELAY_PS4_MS = 1200; +static constexpr uint16_t CONNECT_RUMBLE_DELAY_DEFAULT_MS = 300; + static uint32_t s_last_bt_input_ms[MAX_GAMEPADS]{}; static uint32_t s_xbox_ble_ka_last_ms[MAX_GAMEPADS]{}; /** Ignore Start+Select disconnect combo for this long after connect (DS4 can glitch both on first reports). */ @@ -58,6 +74,26 @@ static btstack_timer_source_t gpio_process_timer_; static void (*gpio_process_cb_)(void*) = nullptr; static void* gpio_process_ctx_ = nullptr; +static void (*s_pico_w_pio_usb_mux_tick)(void) = nullptr; +static btstack_timer_source_t s_pico_w_usb_mux_timer_; +static btstack_context_callback_registration_t s_pico_w_usb_mux_main_reg; + +// Timer callbacks must not call sleep_* (Pico panics). TinyUSB host enumeration does; run mux on main thread. +static void pico_w_usb_mux_run_on_main(void* ctx) { + (void)ctx; + if (s_pico_w_pio_usb_mux_tick != nullptr) { + s_pico_w_pio_usb_mux_tick(); + } +} + +static void pico_w_usb_mux_timer_cb(btstack_timer_source_t* ts) { + s_pico_w_usb_mux_main_reg.callback = pico_w_usb_mux_run_on_main; + s_pico_w_usb_mux_main_reg.context = nullptr; + btstack_run_loop_execute_on_main_thread(&s_pico_w_usb_mux_main_reg); + btstack_run_loop_set_timer(ts, 1); + btstack_run_loop_add_timer(ts); +} + static void gpio_process_timer_cb(btstack_timer_source_t* ts) { if (gpio_process_cb_ != nullptr && gpio_process_ctx_ != nullptr) { gpio_process_cb_(gpio_process_ctx_); @@ -74,6 +110,9 @@ static bool pending_adaptive_trigger_send_[MAX_GAMEPADS]{false}; bool any_connected() { +#if defined(CONFIG_TARGET_PICO_W) && defined(CONFIG_EN_USB_HOST) + return s_bt_any_connected_cached.load(std::memory_order_acquire); +#else for (auto& device : bt_devices_) { if (device.connected) @@ -82,6 +121,7 @@ bool any_connected() } } return false; +#endif } bool is_wii_controller_connected(uint8_t idx) @@ -205,7 +245,13 @@ static void check_led_cb(btstack_timer_source *ts) led_state = !led_state; - board_api::set_led(any_connected() ? true : led_state); +#if defined(CONFIG_TARGET_PICO_W) && defined(CONFIG_EN_USB_HOST) + const bool wired_host_pad = board_api::usb::host_any_pad_mounted(); +#else + const bool wired_host_pad = false; +#endif + /* Solid LED when a BT pad is connected or a wired USB host controller is active (Pico W mux). */ + board_api::set_led((any_connected() || wired_host_pad) ? true : led_state); btstack_run_loop_set_timer(ts, LED_CHECK_TIME_MS); btstack_run_loop_add_timer(ts); @@ -288,6 +334,16 @@ static void device_disconnected_cb(uni_hid_device_t* device) { } bt_devices_[idx].connected = false; + bool any_other_connected = false; + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + if (bt_devices_[i].connected) { + any_other_connected = true; + break; + } + } +#if defined(CONFIG_TARGET_PICO_W) && defined(CONFIG_EN_USB_HOST) + s_bt_any_connected_cached.store(any_other_connected, std::memory_order_release); +#endif s_last_bt_input_ms[idx] = 0; s_xbox_ble_ka_last_ms[idx] = 0; s_bt_disconnect_combo_grace_until_ms[idx] = 0; @@ -296,14 +352,14 @@ static void device_disconnected_cb(uni_hid_device_t* device) { pending_adaptive_trigger_send_[idx] = false; bt_devices_[idx].gamepad->reset_pad_in(); - if (!led_timer_set_ && !any_connected()) { + if (!led_timer_set_ && !any_other_connected) { led_timer_set_ = true; led_timer_.process = check_led_cb; led_timer_.context = nullptr; btstack_run_loop_set_timer(&led_timer_, LED_CHECK_TIME_MS); btstack_run_loop_add_timer(&led_timer_); } - if (feedback_timer_set_ && !any_connected()) { + if (feedback_timer_set_ && !any_other_connected) { feedback_timer_set_ = false; btstack_run_loop_remove_timer(&feedback_timer_); } @@ -311,11 +367,28 @@ static void device_disconnected_cb(uni_hid_device_t* device) { ogxm_resume_ble_ads_if_no_acl_pad(idx); // Re-enable scanning when last device disconnects so the controller can reconnect without // power-cycling the dongle (fixes "pairing mode but controller won't reconnect" in OG Xbox / BT mode). - if (!any_connected()) { + if (!any_other_connected) { uni_bt_enable_new_connections_unsafe(true); } } +static void ogxm_play_connection_rumble(uni_hid_device_t* device) +{ + if (device == nullptr || device->report_parser.play_dual_rumble == nullptr) { + return; + } + const uint16_t start_delay = + (device->controller_type == CONTROLLER_TYPE_PS4Controller) + ? CONNECT_RUMBLE_DELAY_PS4_MS + : CONNECT_RUMBLE_DELAY_DEFAULT_MS; + device->report_parser.play_dual_rumble( + device, + start_delay, + CONNECT_RUMBLE_DURATION_MS, + CONNECT_RUMBLE_WEAK, + CONNECT_RUMBLE_STRONG); +} + static uni_error_t device_ready_cb(uni_hid_device_t* device) { /* DS4/DS5 BT create a second "virtual mouse" device on the same ACL. OGX-Mini only uses * gamepad input; accepting the virtual slot destabilized the link (disconnect ~2 s). */ @@ -328,6 +401,9 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { } bt_devices_[idx].connected = true; +#if defined(CONFIG_TARGET_PICO_W) && defined(CONFIG_EN_USB_HOST) + s_bt_any_connected_cached.store(true, std::memory_order_release); +#endif #if defined(CONFIG_TARGET_PICO_W) if (gap_get_connection_type(device->conn.handle) == GAP_CONNECTION_ACL) { uni_bt_bredr_scan_stop(); @@ -369,6 +445,9 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { btstack_run_loop_set_timer(&feedback_timer_, FEEDBACK_TIME_MS); btstack_run_loop_add_timer(&feedback_timer_); } + + ogxm_play_connection_rumble(device); + return UNI_ERROR_SUCCESS; } @@ -583,6 +662,26 @@ void set_gpio_device_process_callback(void (*callback)(void* ctx), void* ctx) { gpio_process_ctx_ = ctx; } +void set_pico_w_pio_usb_mux_tick(void (*tick_cb)(void)) { + s_pico_w_pio_usb_mux_tick = tick_cb; +} + +void wired_usb_takeover_disconnect_bt() { +#if defined(CONFIG_TARGET_PICO_W) && defined(CONFIG_EN_USB_HOST) + /* Core0 mux uses this atomic; disconnect callbacks run async on Core1. Clear immediately so + * we do not treat BT as active and tuh_deinit() wired USB during the disconnect window. */ + s_bt_any_connected_cached.store(false, std::memory_order_release); +#endif + for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + uni_bt_disconnect_device_safe(i); + } + uni_bt_enable_new_connections_safe(false); +} + +void wired_usb_release_enable_bt_pairing() { + uni_bt_enable_new_connections_safe(true); +} + void init(Gamepad(&gamepads)[MAX_GAMEPADS]) { for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) @@ -605,6 +704,13 @@ void init(Gamepad(&gamepads)[MAX_GAMEPADS]) btstack_run_loop_set_timer(&gpio_process_timer_, GPIO_PROCESS_INTERVAL_MS); btstack_run_loop_add_timer(&gpio_process_timer_); } + + if (s_pico_w_pio_usb_mux_tick != nullptr) { + s_pico_w_usb_mux_timer_.process = pico_w_usb_mux_timer_cb; + s_pico_w_usb_mux_timer_.context = nullptr; + btstack_run_loop_set_timer(&s_pico_w_usb_mux_timer_, 1); + btstack_run_loop_add_timer(&s_pico_w_usb_mux_timer_); + } } void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]) diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.h b/Firmware/RP2040/src/Bluepad32/Bluepad32.h index 47a95123..ac41ed15 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.h +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.h @@ -10,8 +10,19 @@ and kept away from tinyusb due to naming conflicts */ namespace bluepad32 { + /** True if any Bluetooth gamepad is connected (Classic or LE). */ + bool any_connected(); void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]); void init(Gamepad(&gamepads)[MAX_GAMEPADS]); + /** + * Pico W / Pico 2 W only: register a 1 ms callback from the Bluetooth run loop for + * PIO USB host + BT mutual exclusion. Call once before run_task(); pass nullptr to disable. + */ + void set_pico_w_pio_usb_mux_tick(void (*tick_cb)(void)); + /** Disconnect all BT gamepads and block new connections (PIO wired USB took over). */ + void wired_usb_takeover_disconnect_bt(); + /** Re-enable BT pairing after wired USB device unplugged. */ + void wired_usb_release_enable_bt_pairing(); /** Call from main loop to send deferred PS5 adaptive-trigger updates (keeps BT callback fast). */ void process_pending_adaptive_triggers(); /** Optional: when set, a timer in the BT run loop calls this every ~4 ms (for GPIO device modes: PS1/PS2, GameCube). Call before run_task(). */ diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index 820b4573..6afa03fe 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -130,11 +130,6 @@ #endif -#if defined(CONFIG_OGXM_DEBUG) - //Pins and port are defined in CMakeLists.txt - #define DEBUG_UART_PORT __CONCAT(uart,PICO_DEFAULT_UART) -#endif // defined(CONFIG_OGXM_DEBUG) - #if defined(I2C_SDA_PIN) #define I2C_BAUDRATE 400 * 1000 #define I2C_PORT ((I2C_SDA_PIN == 2 ) || \ diff --git a/Firmware/RP2040/src/Board/board_api.cpp b/Firmware/RP2040/src/Board/board_api.cpp index fe78315c..c57dae29 100644 --- a/Firmware/RP2040/src/Board/board_api.cpp +++ b/Firmware/RP2040/src/Board/board_api.cpp @@ -1,16 +1,54 @@ #include #include #include +#include #include +#include #include "tusb.h" +#if defined(CONFIG_EN_USB_HOST) +#include "pio_usb.h" +#endif + #include "Board/Config.h" #include "Board/board_api.h" #include "Board/ogxm_log.h" #include "Board/board_api_private/board_api_private.h" #include "TaskQueue/TaskQueue.h" +#if defined(CONFIG_EN_USB_HOST) +#include "USBHost/HostManager.h" +#endif + +extern "C" { + +// TUSB_OPT_TIME_CALLBACK=1: TinyUSB expects the platform to supply millis; the SDK helper may +// not be linked in this configuration. Used by our tusb_time_delay_ms_api override and TinyUSB. +uint32_t tusb_time_millis_api(void) { + return time_us_32() / 1000u; +} + +// Overrides TinyUSB's weak default (busy-wait on millis only). With PIO USB host and +// skip_alarm_pool there is no hardware 1 kHz SOF interrupt — pio_usb_host_frame() must run +// about once per millisecond. Enumeration calls tusb_time_delay_ms_api() for 50+ ms resets +// from inside tuh_task(); without servicing PIO here, SOFs stop and control transfers fail +// ("Enumeration attempt N" retries, controller never works). +void tusb_time_delay_ms_api(uint32_t ms) { + const uint32_t start = tusb_time_millis_api(); + while ((tusb_time_millis_api() - start) < ms) { +#if defined(CONFIG_EN_USB_HOST) + pio_usb_host_frame(); + const uint32_t now = tusb_time_millis_api(); + while (tusb_time_millis_api() == now) { + tight_loop_contents(); + } +#endif + } +} + +} // extern "C" + namespace board_api { mutex_t gpio_mutex_; @@ -22,6 +60,14 @@ bool usb::host_connected() { return false; } +bool usb::host_any_pad_mounted() { +#if defined(CONFIG_EN_USB_HOST) + return HostManager::get_instance().any_mounted(); +#else + return false; +#endif +} + //Only call this from core0 void usb::disconnect_all() { OGXM_LOG("Disconnecting USB and resetting Core1\n"); diff --git a/Firmware/RP2040/src/Board/board_api.h b/Firmware/RP2040/src/Board/board_api.h index e5f82322..1fb3769a 100644 --- a/Firmware/RP2040/src/Board/board_api.h +++ b/Firmware/RP2040/src/Board/board_api.h @@ -14,6 +14,8 @@ namespace board_api { namespace usb { bool host_connected(); void disconnect_all(); + /** True if TinyUSB host has at least one mounted gamepad driver (wired controller active). */ + bool host_any_pad_mounted(); } } diff --git a/Firmware/RP2040/src/Board/board_api_private/board_api_private.h b/Firmware/RP2040/src/Board/board_api_private/board_api_private.h index f2cb9c6f..3ab43037 100644 --- a/Firmware/RP2040/src/Board/board_api_private/board_api_private.h +++ b/Firmware/RP2040/src/Board/board_api_private/board_api_private.h @@ -24,6 +24,12 @@ namespace board_api_rgb { namespace board_api_usbh { void init() __attribute__((weak)); bool host_connected() __attribute__((weak)); + /** Stop edge IRQs on D+/D− before PIO USB reclaims pins (avoids IO_IRQ storm / BT stall). */ + void suspend_line_irq(); + /** While PIO owns D+/D−, update the same flag GPIO IRQs used (from hcd_port_connect_status). */ + void store_host_line_connected(bool connected); + /** After tuh_deinit / PIO release path, re-enable D+/D− edge IRQs for the next cable attach. */ + void enable_host_line_irq_monitoring(); } #endif // BOARD_API_PRIVATE_H \ No newline at end of file diff --git a/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp b/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp index c864b1a1..116e4663 100644 --- a/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp +++ b/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp @@ -11,25 +11,32 @@ namespace board_api_usbh { std::atomic host_connected_ = false; void host_pin_isr(uint gpio, uint32_t events) { + (void)gpio; + (void)events; + // Do not leave IRQs disabled while a device is attached — that prevented unplug edges from + // ever being seen and could strand host_connected_ out of sync with the pins. + const uint32_t dp_state = gpio_get(PIO_USB_DP_PIN); + const uint32_t dm_state = gpio_get(PIO_USB_DP_PIN + 1); + host_connected_.store((dp_state != 0u) || (dm_state != 0u)); +} + +bool host_connected() { + return host_connected_.load(); +} + +void suspend_line_irq() { gpio_set_irq_enabled(PIO_USB_DP_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false); gpio_set_irq_enabled(PIO_USB_DP_PIN + 1, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false); +} - if (gpio == PIO_USB_DP_PIN || gpio == PIO_USB_DP_PIN + 1) { - uint32_t dp_state = gpio_get(PIO_USB_DP_PIN); - uint32_t dm_state = gpio_get(PIO_USB_DP_PIN + 1); - - if (dp_state || dm_state) { - host_connected_.store(true); - } else { - host_connected_.store(false); - gpio_set_irq_enabled(PIO_USB_DP_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true); - gpio_set_irq_enabled(PIO_USB_DP_PIN + 1, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true); - } - } +void store_host_line_connected(bool connected) { + host_connected_.store(connected); } -bool host_connected() { - return host_connected_.load(); +void enable_host_line_irq_monitoring() { + gpio_set_irq_enabled_with_callback(PIO_USB_DP_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &host_pin_isr); + gpio_set_irq_enabled_with_callback(PIO_USB_DP_PIN + 1, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &host_pin_isr); + host_pin_isr(0, 0); } void init() { @@ -57,4 +64,12 @@ void init() { } // namespace board_api_usbh +#else // !defined(CONFIG_EN_USB_HOST) + +namespace board_api_usbh { +void suspend_line_irq() {} +void store_host_line_connected(bool) {} +void enable_host_line_irq_monitoring() {} +} // namespace board_api_usbh + #endif // defined(CONFIG_EN_USB_HOST) \ No newline at end of file diff --git a/Firmware/RP2040/src/Board/ogxm_log.cpp b/Firmware/RP2040/src/Board/ogxm_log.cpp index 817af601..b63cbb35 100644 --- a/Firmware/RP2040/src/Board/ogxm_log.cpp +++ b/Firmware/RP2040/src/Board/ogxm_log.cpp @@ -2,13 +2,12 @@ #if defined(CONFIG_OGXM_DEBUG) #include +#include #include #include #include #include #include -#include -#include #include "USBDevice/DeviceDriver/DeviceDriverTypes.h" #include "Board/ogxm_log.h" @@ -38,9 +37,8 @@ std::ostream& operator<<(std::ostream& os, DeviceDriverType type) { namespace ogxm_log { void init() { - uart_init(DEBUG_UART_PORT, PICO_DEFAULT_UART_BAUD_RATE); - gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART); - gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART); + // Debug: pico_stdio_uart only (host stack disables USB CDC stdio). main/init_board set PICO_DEFAULT_UART pins. + setvbuf(stdout, nullptr, _IONBF, 0); } void log(const std::string& message) { @@ -54,7 +52,8 @@ void log(const std::string& message) { std::string formatted_msg = "OGXM: " + message; - uart_puts(DEBUG_UART_PORT, formatted_msg.c_str()); + printf("%s", formatted_msg.c_str()); + fflush(stdout); mutex_exit(&log_mutex); } diff --git a/Firmware/RP2040/src/Descriptors/SwitchPro.h b/Firmware/RP2040/src/Descriptors/SwitchPro.h index eb4ed0de..767a8ce9 100644 --- a/Firmware/RP2040/src/Descriptors/SwitchPro.h +++ b/Firmware/RP2040/src/Descriptors/SwitchPro.h @@ -112,6 +112,10 @@ namespace SwitchPro static constexpr uint16_t STICK_MAX = 0xFFF; static constexpr uint8_t REPORT_ID_STANDARD = 0x30; + /** Switch 2 Pro (USB) full input reports use 0x09; layout matches 0x30 after id + timer. */ + static constexpr uint8_t REPORT_ID_SWITCH2_FULL = 0x09; + /** Alternate full-report id seen on some Switch-family USB stacks. */ + static constexpr uint8_t REPORT_ID_FULL_ALT = 0x31; static constexpr uint8_t REPORT_ID_SUBCMD = 0x21; static constexpr uint8_t REPORT_ID_USB_INIT = 0x81; static constexpr int REPORT_SIZE = 64; diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index 09ae5b48..dd217389 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -5,9 +5,9 @@ #include #include #include +#include #include #include - #include "tusb.h" #include "bsp/board_api.h" @@ -22,6 +22,7 @@ #include "UserSettings/UserSettings.h" #include "Board/Config.h" #include "Board/board_api.h" +#include "Board/board_api_private/board_api_private.h" #include "Board/ogxm_log.h" #include "Bluepad32/Bluepad32.h" #include "BLEServer/BLEServer.h" @@ -29,6 +30,7 @@ #include "TaskQueue/TaskQueue.h" #if defined(CONFIG_EN_USB_HOST) +#include "host/hcd.h" #include "pio_usb.h" #include "USBHost/HostManager.h" #include @@ -53,6 +55,232 @@ extern "C" void wii_led_off(void) { board_api::set_led(false); } Gamepad _gamepads[MAX_GAMEPADS]; +#if defined(CONFIG_EN_USB_HOST) +// PIO USB host normally uses an alarm_pool SOF timer (~1 kHz). On Pico W that collides with BTstack / TaskQueue +// timer IRQs (see prior irq_set_exclusive_handler assert) and fixed alarm indices (alarm 3 "already claimed"). +// Use skip_alarm_pool + pio_usb_host_frame() every ~1 ms from Core0 main loop (or Wii Core1 loop). +// Do not run this from BTstack timers / execute_on_main_thread — TinyUSB uses sleep_ms during enumeration. + +// Debounce D+/D- in real time before tuh_init (not "N mux calls") so we can safely run multiple +// host frames per main-loop visit when catching up SOFs without shortening this delay. +constexpr int32_t PIO_LINE_STABLE_US = 40 * 1000; +/** Wall-time spacing for send_feedback — do not tie to SOF catch-up tick count (bursts would hammer the device). */ +constexpr uint32_t USB_FEEDBACK_INTERVAL_MS = 200; + +static bool s_pio_usb_tuh_inited = false; +/** When true, `pio_usb_host_frame()` runs from SDK repeating_timer at 1 kHz (not from main-loop catch-up). */ +static bool s_pico_w_usb_sof_hw_timer = false; +static repeating_timer_t s_pico_w_usb_sof_timer; +static bool s_bt_new_conn_off_for_usb = false; +/** Line high continuously since this time (valid while s_usb_line_debounce_armed). */ +static absolute_time_t s_usb_line_high_since; +static bool s_usb_line_debounce_armed = false; +static uint32_t s_last_usb_feedback_wall_ms = 0; + +static bool pico_w_usb_sof_timer_cb(repeating_timer_t* rt) { + (void)rt; + pio_usb_host_frame(); + return true; +} + +static void pico_w_usb_sof_timer_start() { + if (s_pico_w_usb_sof_hw_timer) { + return; + } + /* skip_alarm_pool: PIO-USB does not start its own SOF timer. Main-loop + sleep_ms(1) cannot hold 1 kHz + * SOF under CYW43/BT load — wired input dies in ~1–2 s. Use SDK repeating_timer (separate from + * the alarm_pool that collides on Pico W) like a dedicated Core1 loop in Wii mode. */ + if (add_repeating_timer_us(-1000, pico_w_usb_sof_timer_cb, nullptr, &s_pico_w_usb_sof_timer)) { + s_pico_w_usb_sof_hw_timer = true; + } +} + +static void pico_w_usb_sof_timer_stop() { + if (!s_pico_w_usb_sof_hw_timer) { + return; + } + cancel_repeating_timer(&s_pico_w_usb_sof_timer); + s_pico_w_usb_sof_hw_timer = false; +} + +/** Debounce any unplug hint (line / stack / idle) past USB bus reset glitches (10–50 ms). */ +constexpr int32_t USB_UNPLUG_DEBOUNCE_US = 60 * 1000; +/** If D+/D− never read as SE0 under PIO, IN reports stop when the cable is pulled — detect unplug this way. + * Keep high enough that HID pads that only report on change are not mistaken for unplug. */ +constexpr uint32_t USB_UNPLUG_NO_INPUT_MS = 3000; +static bool s_usb_unplug_debounce_armed = false; +static absolute_time_t s_usb_unplug_debounce_since; + +static bool pico_w_tuh_any_device_configured() { + /* usbh.c: TOTAL_DEVICES = CFG_TUH_DEVICE_MAX + CFG_TUH_HUB (hub consumes one address slot). */ + const uint8_t addr_max = static_cast(CFG_TUH_DEVICE_MAX + CFG_TUH_HUB); + for (uint8_t d = 1; d <= addr_max; ++d) { + if (tuh_mounted(d)) { + return true; + } + } + return false; +} + +static void pico_w_usb_host_full_stop() { + pico_w_usb_sof_timer_stop(); + (void)tuh_deinit(BOARD_TUH_RHPORT); + s_pio_usb_tuh_inited = false; + s_usb_line_debounce_armed = false; + s_usb_unplug_debounce_armed = false; + /* GPIO IRQs were suspended for PIO; restore so unplug/plug is visible again without "shorting" the port. */ + board_api_usbh::enable_host_line_irq_monitoring(); +} + +/** + * Runs every ~1 ms from Core0 (normal Pico W modes) or from Core1 (GPIO modes that block Core0 in run_task). + * - If any BT gamepad is connected: PIO USB host is not initialized (wired ignored until BT disconnects). + * - If a wired device enumerates on the PIO port: disconnect BT pads and block new BT connections until unplugged. + */ +static void pico_w_pio_usb_bt_mux_tick() { + HostManager& hm = HostManager::get_instance(); + const bool bt_active = bluepad32::any_connected(); + const bool wired_mounted = hm.any_mounted(); + + /* Only tear down PIO USB host for BT when no wired pad is mounted. Otherwise a slow BT + * disconnect after wired takeover (or a stray ACL/device_ready) leaves s_bt_any_connected_cached + * true for ~seconds while USB is working — we would tuh_deinit() here and kill wired input + * until replug. Wired wins while HostManager still has a device slot. */ + if (bt_active && !wired_mounted) { + if (s_pio_usb_tuh_inited) { + pico_w_usb_host_full_stop(); + } + return; + } + + /* Unplug: pio_usb_bus_get_line_state() uses gpio_get on D+/D− while PIO owns them — often never + * reads SE0 when the cable is removed (floating FS-idle), so HCD "connect" stays true. Use any of: + * HCD line, TinyUSB configured device gone, or no process_report() for USB_UNPLUG_NO_INPUT_MS. */ + if (s_pio_usb_tuh_inited) { + const bool hcd_line_connected = hcd_port_connect_status(BOARD_TUH_RHPORT); + board_api_usbh::store_host_line_connected(hcd_line_connected); + + const bool tuh_still_has_device = pico_w_tuh_any_device_configured(); + const uint32_t input_idle_ms = hm.usb_host_input_idle_ms(); + + const bool unplug_hint = wired_mounted && + (!hcd_line_connected || !tuh_still_has_device || (input_idle_ms >= USB_UNPLUG_NO_INPUT_MS)); + + if (unplug_hint) { + if (!s_usb_unplug_debounce_armed) { + s_usb_unplug_debounce_armed = true; + s_usb_unplug_debounce_since = get_absolute_time(); + } else if (absolute_time_diff_us(s_usb_unplug_debounce_since, get_absolute_time()) >= USB_UNPLUG_DEBOUNCE_US) { + pico_w_usb_host_full_stop(); + s_bt_new_conn_off_for_usb = false; + bluepad32::wired_usb_release_enable_bt_pairing(); + return; + } + } else { + s_usb_unplug_debounce_armed = false; + } + } + + if (!s_pio_usb_tuh_inited) { + // Sample D+/D− directly: host_connected() is IRQ-driven and can stay false if an edge was + // missed (Core0 load, CYW43), or the ISR left IRQs disabled while lines were high. + // Pins are still GPIO inputs here; PIO has not taken over yet. + const bool line = (gpio_get(PIO_USB_DP_PIN) != 0) || (gpio_get(PIO_USB_DP_PIN + 1) != 0); + if (!line) { + s_usb_line_debounce_armed = false; + return; + } + if (!s_usb_line_debounce_armed) { + s_usb_line_high_since = get_absolute_time(); + s_usb_line_debounce_armed = true; + } + if (absolute_time_diff_us(s_usb_line_high_since, get_absolute_time()) < PIO_LINE_STABLE_US) { + return; + } + // main() already called flash_safe_execute_core_init() on Core0; do not call from Core1 BT timer (deadlock risk). + hm.initialize(_gamepads); + // PIO USB takes over D+/D−; GPIO edge IRQs on those pins must be off or IO_IRQ floods and BT stalls. + board_api_usbh::suspend_line_irq(); + pio_usb_configuration_t pio_cfg = PIO_USB_CONFIG; + pio_cfg.alarm_pool = nullptr; + pio_cfg.skip_alarm_pool = true; + pio_cfg.tx_ch = 2; + tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); + if (!tuh_init(BOARD_TUH_RHPORT)) { + s_usb_line_debounce_armed = false; + return; + } + s_pio_usb_tuh_inited = true; + pico_w_usb_sof_timer_start(); + } + + if (!s_pico_w_usb_sof_hw_timer) { + pio_usb_host_frame(); + } + + // Host drivers (e.g. Xbox360W chatpad) queue Core1 delayed tasks; safe to drain from Core0 (spinlocks). + TaskQueue::Core1::process_tasks(); + + tuh_task(); + + { + const uint32_t now_ms = to_ms_since_boot(get_absolute_time()); + if ((now_ms - s_last_usb_feedback_wall_ms) >= USB_FEEDBACK_INTERVAL_MS) { + s_last_usb_feedback_wall_ms = now_ms; + hm.send_feedback(); + } + } + + if (wired_mounted) { + if (!s_bt_new_conn_off_for_usb) { + bluepad32::wired_usb_takeover_disconnect_bt(); + s_bt_new_conn_off_for_usb = true; + } + } else { + if (s_bt_new_conn_off_for_usb) { + bluepad32::wired_usb_release_enable_bt_pairing(); + s_bt_new_conn_off_for_usb = false; + } + } +} + +void pico_w::poll_usb_host_mux_from_core0() { + static absolute_time_t next_usb_mux; + static bool usb_mux_time_inited = false; + if (!usb_mux_time_inited) { + next_usb_mux = get_absolute_time(); + usb_mux_time_inited = true; + } + absolute_time_t now = get_absolute_time(); + + if (!s_pio_usb_tuh_inited) { + if (absolute_time_diff_us(next_usb_mux, now) < 0) { + return; + } + next_usb_mux = delayed_by_us(next_usb_mux, 1000); + pico_w_pio_usb_bt_mux_tick(); + return; + } + + if (s_pico_w_usb_sof_hw_timer) { + /* SOF is 1 kHz from repeating_timer; run TinyUSB + mux every visit (no 1 ms gate). */ + pico_w_pio_usb_bt_mux_tick(); + return; + } + + if (absolute_time_diff_us(next_usb_mux, now) < 0) { + return; + } + // Fallback if hardware SOF timer failed: manual frames + catch-up (Wii Core1–style burst). + constexpr int k_max_catchup_frames = 500; + for (int n = 0; n < k_max_catchup_frames && absolute_time_diff_us(next_usb_mux, now) >= 0; ++n) { + next_usb_mux = delayed_by_us(next_usb_mux, 1000); + pico_w_pio_usb_bt_mux_tick(); + now = get_absolute_time(); + } +} +#endif // CONFIG_EN_USB_HOST + static DeviceDriver* s_gpio_device_driver = nullptr; static void gpio_device_process_cb(void* ctx) { (void)ctx; @@ -94,10 +322,9 @@ void core1_task_wii_usb_host() { } OGXM_LOG("WII Core1: host_connected\n"); - // Use an unused hardware alarm for PIO USB host so TaskQueue Core1 can keep alarm 2 (avoids conflict; alarm 3 may be claimed on Pico 2 W) - static alarm_pool_t* s_wii_usb_alarm_pool = alarm_pool_create_with_unused_hardware_alarm(1); pio_usb_configuration_t pio_cfg = PIO_USB_CONFIG; - pio_cfg.alarm_pool = s_wii_usb_alarm_pool; + pio_cfg.alarm_pool = nullptr; + pio_cfg.skip_alarm_pool = true; // CYW43 (BT on Core0) claims DMA 0 and 1; use channel 2 for PIO USB TX to avoid "DMA channel 0 is already claimed" pio_cfg.tx_ch = 2; tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); @@ -117,15 +344,22 @@ void core1_task_wii_usb_host() { uint32_t gp_check_ticks = 0; #endif + absolute_time_t next_pio_host_frame = get_absolute_time(); while (true) { + absolute_time_t now = get_absolute_time(); + while (absolute_time_diff_us(next_pio_host_frame, now) >= 0) { + pio_usb_host_frame(); + next_pio_host_frame = delayed_by_us(next_pio_host_frame, 1000); + now = get_absolute_time(); + } TaskQueue::Core1::process_tasks(); tuh_task(); Wii::gamepad_to_wiimote_report(_gamepads[0], &s_wiimote_report); #if !defined(CONFIG_OGXM_FIXED_DRIVER) || defined(CONFIG_OGXM_FIXED_DRIVER_ALLOW_COMBOS) - uint32_t now = board_api::ms_since_boot(); - if (now - last_gp_check_ms >= static_cast(UserSettings::GP_CHECK_DELAY_MS)) { - last_gp_check_ms = now; + const uint32_t now_ms = board_api::ms_since_boot(); + if (now_ms - last_gp_check_ms >= static_cast(UserSettings::GP_CHECK_DELAY_MS)) { + last_gp_check_ms = now_ms; UserSettings& user_settings = UserSettings::get_instance(); bool changed = user_settings.check_for_driver_change(_gamepads[0]); #if defined(CONFIG_OGXM_DEBUG) @@ -157,6 +391,7 @@ void core1_task() { OGXM_LOG("PicoW Core1: set_led(true) done\n"); BLEServer::init_server(_gamepads); OGXM_LOG("PicoW Core1: BLEServer init done, entering run_task\n"); + /* PIO USB mux runs on Core0 main loop (poll_usb_host_mux_from_core0), not here — avoids sleep_ms panic. */ bluepad32::run_task(_gamepads); } @@ -195,6 +430,9 @@ void pico_w::initialize() { DeviceManager& device_manager = DeviceManager::get_instance(); device_manager.initialize_driver(user_settings.get_current_driver(), _gamepads); +#if defined(CONFIG_EN_USB_HOST) + HostManager::get_instance().initialize(_gamepads); +#endif OGXM_LOG("PicoW init: driver inited\n"); } @@ -265,6 +503,9 @@ void pico_w::run() { } /* Let Core1 reach flash_safe_execute_core_init() before we enter run_task (BT stack may touch flash). */ sleep_ms(100); +#if defined(CONFIG_EN_USB_HOST) + bluepad32::set_pico_w_pio_usb_mux_tick(pico_w_pio_usb_bt_mux_tick); +#endif bluepad32::run_task(_gamepads); /* never returns */ } } else { @@ -336,9 +577,25 @@ void pico_w::run() { OGXM_LOG("PicoW run: Wii main loop tick\n"); } loop_count++; - // Match Team-Resurgent: 1 ms delay so Core1 (BT stack) gets CPU; prevents random BT disconnect. - if (!ps2_poll_mode) - sleep_ms(1); + /* Run USB host mux after all heavy work (device_driver->process, etc.) so pio_usb_host_frame + * catch-up covers the whole iteration; otherwise SOFs can lag for tens of ms and wired input dies. */ +#if defined(CONFIG_EN_USB_HOST) + if (!wii_mode) { + pico_w::poll_usb_host_mux_from_core0(); + } +#endif + /* With hardware SOF timer, Core0 can sleep briefly; wired USB still needs tuh_task often. + * sleep_ms(1) alone starved TinyUSB vs Wii Core1's tight loop. */ + if (!ps2_poll_mode) { +#if defined(CONFIG_EN_USB_HOST) + if (!wii_mode && s_pio_usb_tuh_inited && HostManager::get_instance().any_mounted()) { + sleep_us(400); + } else +#endif + { + sleep_ms(1); + } + } } } diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.h b/Firmware/RP2040/src/OGXMini/Board/PicoW.h index 2a153035..3b5a86fd 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.h +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.h @@ -5,4 +5,8 @@ namespace pico_w { void initialize(); void run(); +#if defined(CONFIG_EN_USB_HOST) + /** Core0: ~1 kHz PIO USB host + BT/wired mux (must not run from BT timer / execute_on_main_thread). */ + void poll_usb_host_mux_from_core0(); +#endif } // namespace pico_w \ No newline at end of file diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp index 3e54f120..467b838f 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp @@ -172,8 +172,17 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) if (new_report_out_) { Gamepad::PadOut gp_out; - gp_out.rumble_l = report_out_.rumble.left_motor_force; - gp_out.rumble_r = report_out_.rumble.right_motor_on ? Range::MAX : 0; + /* Windows DInput often leaves a small non-zero large-motor byte or sets the small-motor + * field to values other than 0/1; forwarding that blindly causes constant rumble on the BT pad. */ + constexpr uint8_t HOST_LARGE_MOTOR_DEADZONE = 12; + uint8_t lf = report_out_.rumble.left_motor_force; + if (lf < HOST_LARGE_MOTOR_DEADZONE) { + lf = 0; + } + gp_out.rumble_l = lf; + /* DS3 output uses 0/1 for the small motor; only 0x01 counts as on (not "any non-zero"). */ + const uint8_t rm = report_out_.rumble.right_motor_on; + gp_out.rumble_r = (rm == 1u) ? Range::MAX : 0; gamepad.set_pad_out(gp_out); new_report_out_ = false; } diff --git a/Firmware/RP2040/src/USBHost/HardwareIDs.h b/Firmware/RP2040/src/USBHost/HardwareIDs.h index e77b3bac..ace3c584 100644 --- a/Firmware/RP2040/src/USBHost/HardwareIDs.h +++ b/Firmware/RP2040/src/USBHost/HardwareIDs.h @@ -399,10 +399,18 @@ static const HardwareID SWITCH_PRO_IDS[] = {0x057E, 0x0330}, // Wii U Pro {0x057E, 0x2006}, // Joy-Con (L) {0x057E, 0x2007}, // Joy-Con (R) - {0x057E, 0x2069}, // Nintendo Switch 2 Pro Controller + {0x057E, 0x2067}, // Joy-Con 2 (L) — same USB bulk bring-up as Pro 2 + {0x057E, 0x2066}, // Joy-Con 2 (R) + {0x057E, 0x2073}, // NSO GameCube Controller (Switch 2–family USB) // {0x20D6, 0xA711}, // OpenSteamController, emulated pro controller }; +// Switch 2 Pro only — uses Switch2ProHost (same InReport decode as SwitchProHost; see Wired_Controllers.md) +static const HardwareID SWITCH_PRO_2_IDS[] = +{ + {0x057E, 0x2069}, // Nintendo Switch 2 Pro Controller +}; + // Wired Switch controllers (from SDL_GameControllerDB + existing) static const HardwareID SWITCH_WIRED_IDS[] = { @@ -459,6 +467,7 @@ static const HostTypeMap HOST_TYPE_MAP[] = { PS5_IDS, sizeof(PS5_IDS) / sizeof(HardwareID), HostDriverType::PS5 }, { PS3_IDS, sizeof(PS3_IDS) / sizeof(HardwareID), HostDriverType::PS3 }, { SWITCH_WIRED_IDS, sizeof(SWITCH_WIRED_IDS) / sizeof(HardwareID), HostDriverType::SWITCH }, + { SWITCH_PRO_2_IDS, sizeof(SWITCH_PRO_2_IDS) / sizeof(HardwareID), HostDriverType::SWITCH_PRO_2 }, { SWITCH_PRO_IDS, sizeof(SWITCH_PRO_IDS) / sizeof(HardwareID), HostDriverType::SWITCH_PRO }, { PSCLASSIC_IDS, sizeof(PSCLASSIC_IDS) / sizeof(HardwareID), HostDriverType::PSCLASSIC }, { N64_IDS, sizeof(N64_IDS) / sizeof(HardwareID), HostDriverType::N64 }, diff --git a/Firmware/RP2040/src/USBHost/HostDriver/HostDriverTypes.h b/Firmware/RP2040/src/USBHost/HostDriver/HostDriverTypes.h index 9099d191..1c06142f 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/HostDriverTypes.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/HostDriverTypes.h @@ -7,6 +7,8 @@ enum class HostDriverType { UNKNOWN = 0, SWITCH_PRO, + /** Nintendo Switch 2 Pro (PID 0x2069): wired USB; Switch2ProHost maps full digital + sticks + ZL/ZR (see Wired_Controllers.md) */ + SWITCH_PRO_2, SWITCH, PSCLASSIC, DINPUT, diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp index 075acfbb..863309a2 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp @@ -5,6 +5,15 @@ #include "USBHost/HostDriver/PS3/PS3.h" +#if defined(CONFIG_EN_BLUETOOTH) +extern "C" { +/* Do not include bt/uni_bt.h here: it pulls BTstack, whose btstack_hid.h redefines + * HID_REPORT_TYPE_* / hid_report_type_t and breaks compilation with TinyUSB hid.h. */ +typedef uint8_t uni_bt_bd_addr_t[6]; +void uni_bt_get_local_bd_addr_safe(uni_bt_bd_addr_t addr); +} +#endif + const tusb_control_request_t PS3Host::RUMBLE_REQUEST = { .bmRequestType = 0x21, @@ -14,6 +23,52 @@ const tusb_control_request_t PS3Host::RUMBLE_REQUEST = .wLength = sizeof(PS3::OutReport) }; +#if defined(CONFIG_EN_BLUETOOTH) +/* Same as bluepad32/tools/sixaxispairer — DualShock 3 stores host BD_ADDR for Bluetooth. */ +const tusb_control_request_t PS3Host::BT_MAC_FEATURE_REQUEST = { + .bmRequestType = 0x21, + .bRequest = 0x09, // SET_REPORT + .wValue = static_cast((HID_REPORT_TYPE_FEATURE << 8) | 0xF5), + .wIndex = 0x0000, + .wLength = 8, +}; + +bool PS3Host::local_bt_addr_is_nonzero(const uint8_t addr[6]) { + for (int i = 0; i < 6; ++i) { + if (addr[i] != 0) { + return true; + } + } + return false; +} + +void PS3Host::bt_pair_complete_cb(tuh_xfer_s* xfer) { + auto* init_state = reinterpret_cast(xfer->user_data); + if (init_state == nullptr) { + return; + } + init_state->stage = InitStage::DONE; + init_state->reports_enabled = true; + send_control_xfer(init_state->dev_addr, &PS3Host::RUMBLE_REQUEST, reinterpret_cast(init_state->out_report), nullptr, 0); +} + +void PS3Host::try_deferred_ds3_bt_pair(uint8_t address) { + if (!ds3_bt_pair_deferred_) { + return; + } + uni_bt_bd_addr_t addr{}; + uni_bt_get_local_bd_addr_safe(addr); + if (!local_bt_addr_is_nonzero(addr)) { + return; + } + ds3_bt_pair_deferred_ = false; + bt_pair_buf_[0] = 0xF5; + bt_pair_buf_[1] = 0; + std::memcpy(bt_pair_buf_.data() + 2, addr, 6); + (void)send_control_xfer(address, &BT_MAC_FEATURE_REQUEST, bt_pair_buf_.data(), nullptr, 0); +} +#endif + void PS3Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { gamepad.set_analog_host(true); @@ -28,6 +83,11 @@ void PS3Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, co init_state_.out_report = &out_report_; init_state_.dev_addr = address; init_state_.init_buffer.fill(0); + init_state_.bt_pair_report.fill(0); +#if defined(CONFIG_EN_BLUETOOTH) + init_state_.defer_bt_pair = &ds3_bt_pair_deferred_; + ds3_bt_pair_deferred_ = false; +#endif tusb_control_request_t init_request = { @@ -86,6 +146,22 @@ void PS3Host::get_report_complete_cb(tuh_xfer_s *xfer) send_control_xfer(init_state->dev_addr, &init_request, init_state->init_buffer.data(), get_report_complete_cb, xfer->user_data); break; case InitStage::RESP3: +#if defined(CONFIG_EN_BLUETOOTH) + { + uni_bt_bd_addr_t addr{}; + uni_bt_get_local_bd_addr_safe(addr); + if (local_bt_addr_is_nonzero(addr)) { + init_state->bt_pair_report[0] = 0xF5; + init_state->bt_pair_report[1] = 0; + std::memcpy(init_state->bt_pair_report.data() + 2, addr, 6); + send_control_xfer(init_state->dev_addr, &BT_MAC_FEATURE_REQUEST, init_state->bt_pair_report.data(), bt_pair_complete_cb, xfer->user_data); + break; + } + if (init_state->defer_bt_pair != nullptr) { + *init_state->defer_bt_pair = true; + } + } +#endif init_state->stage = InitStage::DONE; init_state->reports_enabled = true; send_control_xfer(init_state->dev_addr, &PS3Host::RUMBLE_REQUEST, reinterpret_cast(init_state->out_report), nullptr, 0); @@ -97,6 +173,9 @@ void PS3Host::get_report_complete_cb(tuh_xfer_s *xfer) void PS3Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) { +#if defined(CONFIG_EN_BLUETOOTH) + try_deferred_ds3_bt_pair(address); +#endif const PS3::InReport* in_report = reinterpret_cast(report); if (std::memcmp(&prev_in_report_, in_report, std::min(static_cast(len), static_cast(26))) == 0) { diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h index 12655dde..b9d7b8d0 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h @@ -27,18 +27,35 @@ class PS3Host : public HostDriver uint8_t dev_addr{0xFF}; InitStage stage{InitStage::RESP1}; std::array init_buffer; + std::array bt_pair_report{}; PS3::OutReport* out_report{nullptr}; bool reports_enabled{false}; + /** If set, points to PS3Host::ds3_bt_pair_deferred_ — BT addr was not ready during init. */ + bool* defer_bt_pair{nullptr}; }; static const tusb_control_request_t RUMBLE_REQUEST; +#if defined(CONFIG_EN_BLUETOOTH) + /** HID feature report: program DualShock 3 master Bluetooth address (see Bluepad32 sixaxispairer). */ + static const tusb_control_request_t BT_MAC_FEATURE_REQUEST; +#endif PS3::InReport prev_in_report_; PS3::OutReport out_report_; InitState init_state_; +#if defined(CONFIG_EN_BLUETOOTH) + /** Persistent buffer for async SET_REPORT (feature 0xF5). */ + std::array bt_pair_buf_{}; + bool ds3_bt_pair_deferred_{false}; +#endif static bool send_control_xfer(uint8_t dev_addr, const tusb_control_request_t* req, uint8_t* buffer, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static void get_report_complete_cb(tuh_xfer_s *xfer); +#if defined(CONFIG_EN_BLUETOOTH) + static void bt_pair_complete_cb(tuh_xfer_s* xfer); + static bool local_bt_addr_is_nonzero(const uint8_t addr[6]); + void try_deferred_ds3_bt_pair(uint8_t address); +#endif }; #endif // _PS3_HOST_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp index 05c58d22..a693cb16 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp @@ -4,14 +4,39 @@ #include "host/usbh.h" #include "class/hid/hid_host.h" +#include "Board/Config.h" +#if defined(CONFIG_EN_USB_HOST) +#include "pio_usb.h" +#endif + #include "USBHost/HostDriver/PS4/PS4.h" void PS4Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { + (void)gamepad; + (void)report_desc; + (void)desc_len; + out_report_.report_id = 0x05; out_report_.set_led = 1; out_report_.lightbar_blue = 0xFF / 2; + /* PS5Host pushes an initial OUT report; PS4 did not. Composite XInput+HID pads often need this + * before IN starts. Periodic send_feedback only runs when new_pad_out/has_rumble, so the LED + * and input path never woke when we stopped using XInput for feedback on these devices. */ + uint32_t attempts = 0; + while (!tuh_hid_send_report(address, instance, 0, reinterpret_cast(&out_report_), sizeof(PS4::OutReport))) + { +#if defined(CONFIG_EN_USB_HOST) + pio_usb_host_frame(); +#endif + tuh_task(); + if (++attempts > 4000u) + { + break; + } + } + tuh_hid_receive_report(address, instance); } diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProCaptureTables.h b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProCaptureTables.h new file mode 100644 index 00000000..494f791e --- /dev/null +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProCaptureTables.h @@ -0,0 +1,126 @@ +/* Reference only — firmware does not include this header (hidraw XOR bytes 16–17 drift with IMU). + * Autogenerated from Nintendo_Switch_2_Pro_Controller_20260324_063034.txt + * Sparse (idx, mask, val): for each changed byte i in [2,20], mask = baseline^active, + * val = active[i] & mask. Match: (report[i] & mask) == val for all tuples. + * Regenerate: Tools/controller_capture (same JSON extraction as Switch2ProCaptureTables). */ +#pragma once +#include + +namespace Switch2ProCapture { + +enum class Btn : uint8_t { + FACE_B = 0, + FACE_A = 1, + FACE_Y = 2, + FACE_X = 3, + SHOULDER_R = 4, + TRIGGER_ZR = 5, + SHOULDER_L = 6, + TRIGGER_ZL = 7, + CENTER_MINUS = 8, + CENTER_PLUS = 9, + CENTER_HOME = 10, + CENTER_CAPTURE = 11, + DPAD_UP = 12, + DPAD_DOWN = 13, + DPAD_LEFT = 14, + DPAD_RIGHT = 15, + STICK_L3 = 16, + STICK_R3 = 17, + COUNT +}; + +static constexpr uint8_t CAPTURE_BYTE_LO = 2; +static constexpr uint8_t CAPTURE_BYTE_HI = 20; + +static constexpr uint8_t FACE_B_N = 4; +static constexpr uint8_t FACE_B_IDX[4] = {7, 9, 16, 17}; +static constexpr uint8_t FACE_B_MASK[4] = {0x70, 0x07, 0x62, 0x05}; +static constexpr uint8_t FACE_B_VAL[4] = {0x40, 0x03, 0x20, 0x04}; + +static constexpr uint8_t FACE_A_N = 3; +static constexpr uint8_t FACE_A_IDX[3] = {6, 16, 17}; +static constexpr uint8_t FACE_A_MASK[3] = {0x01, 0xd5, 0x02}; +static constexpr uint8_t FACE_A_VAL[3] = {0x01, 0x10, 0x00}; + +static constexpr uint8_t FACE_Y_N = 3; +static constexpr uint8_t FACE_Y_IDX[3] = {6, 16, 17}; +static constexpr uint8_t FACE_Y_MASK[3] = {0x01, 0xb3, 0x7f}; +static constexpr uint8_t FACE_Y_VAL[3] = {0x00, 0x33, 0x3d}; + +static constexpr uint8_t FACE_X_N = 5; +static constexpr uint8_t FACE_X_IDX[5] = {6, 9, 10, 16, 17}; +static constexpr uint8_t FACE_X_MASK[5] = {0x01, 0x07, 0x70, 0xd4, 0x07}; +static constexpr uint8_t FACE_X_VAL[5] = {0x00, 0x04, 0x40, 0x94, 0x06}; + +static constexpr uint8_t SHOULDER_R_N = 4; +static constexpr uint8_t SHOULDER_R_IDX[4] = {6, 10, 16, 17}; +static constexpr uint8_t SHOULDER_R_MASK[4] = {0x01, 0x70, 0x43, 0x07}; +static constexpr uint8_t SHOULDER_R_VAL[4] = {0x00, 0x30, 0x02, 0x07}; + +static constexpr uint8_t TRIGGER_ZR_N = 4; +static constexpr uint8_t TRIGGER_ZR_IDX[4] = {6, 10, 16, 17}; +static constexpr uint8_t TRIGGER_ZR_MASK[4] = {0x01, 0x70, 0xcb, 0x09}; +static constexpr uint8_t TRIGGER_ZR_VAL[4] = {0x00, 0x40, 0x02, 0x09}; + +static constexpr uint8_t SHOULDER_L_N = 3; +static constexpr uint8_t SHOULDER_L_IDX[3] = {6, 16, 17}; +static constexpr uint8_t SHOULDER_L_MASK[3] = {0x01, 0x38, 0x75}; +static constexpr uint8_t SHOULDER_L_VAL[3] = {0x01, 0x08, 0x35}; + +static constexpr uint8_t TRIGGER_ZL_N = 3; +static constexpr uint8_t TRIGGER_ZL_IDX[3] = {6, 16, 17}; +static constexpr uint8_t TRIGGER_ZL_MASK[3] = {0x01, 0x3a, 0x0a}; +static constexpr uint8_t TRIGGER_ZL_VAL[3] = {0x01, 0x3a, 0x00}; + +static constexpr uint8_t CENTER_MINUS_N = 6; +static constexpr uint8_t CENTER_MINUS_IDX[6] = {6, 7, 9, 10, 16, 17}; +static constexpr uint8_t CENTER_MINUS_MASK[6] = {0x01, 0x70, 0x07, 0x70, 0x92, 0x77}; +static constexpr uint8_t CENTER_MINUS_VAL[6] = {0x00, 0x30, 0x04, 0x30, 0x80, 0x36}; + +static constexpr uint8_t CENTER_PLUS_N = 4; +static constexpr uint8_t CENTER_PLUS_IDX[4] = {6, 7, 16, 17}; +static constexpr uint8_t CENTER_PLUS_MASK[4] = {0x01, 0x70, 0xbc, 0x08}; +static constexpr uint8_t CENTER_PLUS_VAL[4] = {0x00, 0x30, 0xb4, 0x00}; + +static constexpr uint8_t CENTER_HOME_N = 3; +static constexpr uint8_t CENTER_HOME_IDX[3] = {9, 16, 17}; +static constexpr uint8_t CENTER_HOME_MASK[3] = {0x07, 0x37, 0x0b}; +static constexpr uint8_t CENTER_HOME_VAL[3] = {0x03, 0x36, 0x08}; + +static constexpr uint8_t CENTER_CAPTURE_N = 5; +static constexpr uint8_t CENTER_CAPTURE_IDX[5] = {6, 9, 10, 16, 17}; +static constexpr uint8_t CENTER_CAPTURE_MASK[5] = {0x12, 0x07, 0x10, 0x0d, 0x06}; +static constexpr uint8_t CENTER_CAPTURE_VAL[5] = {0x02, 0x03, 0x00, 0x05, 0x06}; + +static constexpr uint8_t DPAD_UP_N = 7; +static constexpr uint8_t DPAD_UP_IDX[7] = {6, 7, 8, 9, 10, 16, 17}; +static constexpr uint8_t DPAD_UP_MASK[7] = {0x07, 0x70, 0x07, 0xd4, 0x40, 0x22, 0x0e}; +static constexpr uint8_t DPAD_UP_VAL[7] = {0x03, 0x00, 0x04, 0x84, 0x40, 0x00, 0x02}; + +static constexpr uint8_t DPAD_DOWN_N = 4; +static constexpr uint8_t DPAD_DOWN_IDX[4] = {7, 10, 16, 17}; +static constexpr uint8_t DPAD_DOWN_MASK[4] = {0xf0, 0x30, 0x86, 0x0e}; +static constexpr uint8_t DPAD_DOWN_VAL[4] = {0x70, 0x20, 0x04, 0x0a}; + +static constexpr uint8_t DPAD_LEFT_N = 3; +static constexpr uint8_t DPAD_LEFT_IDX[3] = {7, 16, 17}; +static constexpr uint8_t DPAD_LEFT_MASK[3] = {0x10, 0x20, 0x7d}; +static constexpr uint8_t DPAD_LEFT_VAL[3] = {0x10, 0x00, 0x31}; + +static constexpr uint8_t DPAD_RIGHT_N = 5; +static constexpr uint8_t DPAD_RIGHT_IDX[5] = {4, 9, 10, 16, 17}; +static constexpr uint8_t DPAD_RIGHT_MASK[5] = {0x02, 0x01, 0x30, 0x7a, 0x04}; +static constexpr uint8_t DPAD_RIGHT_VAL[5] = {0x02, 0x01, 0x20, 0x0a, 0x04}; + +static constexpr uint8_t STICK_L3_N = 5; +static constexpr uint8_t STICK_L3_IDX[5] = {6, 7, 10, 16, 17}; +static constexpr uint8_t STICK_L3_MASK[5] = {0x03, 0x70, 0x30, 0x3a, 0x07}; +static constexpr uint8_t STICK_L3_VAL[5] = {0x02, 0x30, 0x10, 0x28, 0x06}; + +static constexpr uint8_t STICK_R3_N = 6; +static constexpr uint8_t STICK_R3_IDX[6] = {6, 7, 8, 9, 16, 17}; +static constexpr uint8_t STICK_R3_MASK[6] = {0x3f, 0xa0, 0xf2, 0x07, 0x86, 0x75}; +static constexpr uint8_t STICK_R3_VAL[6] = {0x14, 0x20, 0x82, 0x03, 0x82, 0x35}; + +} // namespace Switch2ProCapture diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp new file mode 100644 index 00000000..a617f121 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp @@ -0,0 +1,190 @@ +#include +#include + +#include "host/usbh.h" +#include "class/hid/hid_host.h" + +#include "USBHost/HostDriver/SwitchPro/Switch2ProHost.h" + +#include "Board/ogxm_log.h" + +namespace { + +/** Same 10-byte payload resolution as SwitchProHost (report id 0x09 / 0x30 / 0x31 + timer, or raw 10). */ +const uint8_t* switch2_payload(const uint8_t* report, uint16_t len, uint16_t& out_payload_len) +{ + out_payload_len = len; + if (len == sizeof(SwitchPro::InReport)) + { + return report; + } + if (len >= 2U + sizeof(SwitchPro::InReport)) + { + const uint8_t rid = report[0]; + if (rid == SwitchPro::REPORT_ID_STANDARD || rid == SwitchPro::REPORT_ID_SWITCH2_FULL || + rid == SwitchPro::REPORT_ID_FULL_ALT) + { + out_payload_len = static_cast(len - 2U); + return report + 2; + } + } + return nullptr; +} + +} // namespace + +void Switch2ProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, + uint16_t len) +{ + if (switch2_bringup_active_) + { + tuh_hid_receive_report(address, instance); + return; + } + + if (init_state_ != InitState::DONE) + { + init_switch_host(gamepad, address, instance); + return; + } + +#ifdef OGXM_SWITCH2_HID_RAW_LOG + if (len > 0) + { + const std::uint16_t n = len < kSwitch2RawLogCap ? len : kSwitch2RawLogCap; + // Log only when the three digital button bytes change. Timer (byte1), sticks (6–11), and IMU (12+) + // all move nearly every packet and will flood UART if included in the compare. + std::uint8_t btn[3]{}; + bool have_btn = false; + if (len >= 2U + sizeof(SwitchPro::InReport)) + { + const std::uint8_t rid = report[0]; + if ((rid == SwitchPro::REPORT_ID_STANDARD || rid == SwitchPro::REPORT_ID_SWITCH2_FULL || + rid == SwitchPro::REPORT_ID_FULL_ALT) && + len >= 6U) + { + btn[0] = report[3]; + btn[1] = report[4]; + btn[2] = report[5]; + have_btn = true; + } + } + else if (len == sizeof(SwitchPro::InReport)) + { + btn[0] = report[1]; + btn[1] = report[2]; + btn[2] = report[3]; + have_btn = true; + } + const bool btn_changed = + have_btn && + (!switch2_dbg_have_btn_ || std::memcmp(btn, switch2_dbg_prev_btn_, sizeof(btn)) != 0); + const bool len_changed = (switch2_dbg_prev_len_ != n); + if (have_btn && (btn_changed || len_changed)) + { + OGXM_LOG("S2Pro HID len=%u (3 digital btn bytes changed; full dump follows)\n", static_cast(len)); + OGXM_LOG_HEX(report, n); + std::memcpy(switch2_dbg_prev_, report, n); + switch2_dbg_prev_len_ = n; + std::memcpy(switch2_dbg_prev_btn_, btn, sizeof(btn)); + switch2_dbg_have_btn_ = true; + } + } +#endif + + uint16_t payload_len = 0; + const uint8_t* payload = switch2_payload(report, len, payload_len); + if (payload == nullptr || payload_len < sizeof(SwitchPro::InReport)) + { + tuh_hid_receive_report(address, instance); + return; + } + + const SwitchPro::InReport* in_report = reinterpret_cast(payload); + if (std::memcmp(&prev_in_report_.buttons, in_report->buttons, 9) == 0) + { + tuh_hid_receive_report(address, instance); + return; + } + + Gamepad::PadIn gp_in{}; + + // Switch 2 Pro (USB 0x2069): same 10-byte InReport offsets as the original Pro, but the three + // "button" bytes do not follow classic Buttons0/1/2 semantics. Layout from maintainer capture. + const uint8_t br = in_report->buttons[0]; + const uint8_t bm = in_report->buttons[1]; + const uint8_t bl = in_report->buttons[2]; + + // Face: hardware order is B,A,Y,X on bits 0–3 (classic Pro uses Y,X,B,A on the same bits). + if (br & (1U << 2)) + gp_in.buttons |= gamepad.MAP_BUTTON_X; // west → Xbox X + if (br & (1U << 0)) + gp_in.buttons |= gamepad.MAP_BUTTON_A; // south → Xbox A + if (br & (1U << 1)) + gp_in.buttons |= gamepad.MAP_BUTTON_B; // east → Xbox B + if (br & (1U << 3)) + gp_in.buttons |= gamepad.MAP_BUTTON_Y; // north → Xbox Y + + // Bit 4 in first byte: hardware RB (capture: pressed 0x10, released 0x00 in bytes [3][4][5]). + if (br & (1U << 4)) + gp_in.buttons |= gamepad.MAP_BUTTON_RB; + + // Right byte: classic R / ZR are Start and stick R3 on this device. + if (br & SwitchPro::Buttons0::R) + gp_in.buttons |= gamepad.MAP_BUTTON_START; + if (br & SwitchPro::Buttons0::ZR) + gp_in.buttons |= gamepad.MAP_BUTTON_R3; + + // Bit 5 in misc byte: hardware ZL digital (capture: 00 20 00 vs released; classic CAPTURE bit). + // Bit 5 in first byte: hardware ZR / RT digital (capture: 20 00 00 vs released; classic ZR is bit 7 → R3). + // Analog travel may exist elsewhere in the 64-byte report; these are full-digital paths. + const bool zl_on = (bm & (1U << 5)) != 0; + const bool zr_on = (br & (1U << 5)) != 0; + + // Bit 6 in misc byte: hardware Minus (−) → Back/Select (capture: 00 40 00 vs released 00 00 00). + if (bm & (1U << 6)) + gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + + // Bit 7 in misc byte: hardware L3 (capture: 00 80 00 vs released; not classic Buttons1::L3 bit 2). + if (bm & (1U << 7)) + gp_in.buttons |= gamepad.MAP_BUTTON_L3; + + // "Misc" byte: d-pad uses some classic − / + / L3 / R3 bit positions; L uses the Home bit. + // L3 here is d-pad left (capture: 00 04 00); stick L3 is bm bit 7 above. + if (bm & SwitchPro::Buttons1::MINUS) + gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (bm & SwitchPro::Buttons1::L3) + gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + if (bm & SwitchPro::Buttons1::PLUS) + gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + if (bm & SwitchPro::Buttons1::R3) + gp_in.dpad |= gamepad.MAP_DPAD_UP; + if (bm & SwitchPro::Buttons1::HOME) + gp_in.buttons |= gamepad.MAP_BUTTON_LB; + + // "Left" byte: Home on classic d-pad-up bit; Capture shares classic d-pad-down (left unmapped). + // + // Reference only — GL / GR / Chat (intentionally unmapped), all in bl: GL bit 3 (00 00 08); + // GR bit 2 (00 00 04); Chat bit 4 (00 00 10); released 00 00 00. + if (bl & SwitchPro::Buttons2::DPAD_UP) + gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + + gp_in.trigger_l = zl_on ? Range::MAX : Range::MIN; + gp_in.trigger_r = zr_on ? Range::MAX : Range::MIN; + + uint16_t joy_lx = in_report->joysticks[0] | ((in_report->joysticks[1] & 0xF) << 8); + uint16_t joy_ly = (in_report->joysticks[1] >> 4) | (in_report->joysticks[2] << 4); + uint16_t joy_rx = in_report->joysticks[3] | ((in_report->joysticks[4] & 0xF) << 8); + uint16_t joy_ry = (in_report->joysticks[4] >> 4) | (in_report->joysticks[5] << 4); + + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = + gamepad.scale_joystick_l(normalize_axis(joy_lx), normalize_axis(joy_ly), true); + + std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = + gamepad.scale_joystick_r(normalize_axis(joy_rx), normalize_axis(joy_ry), true); + + gamepad.set_pad_in(gp_in); + std::memcpy(&prev_in_report_, in_report, sizeof(SwitchPro::InReport)); + + tuh_hid_receive_report(address, instance); +} diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h new file mode 100644 index 00000000..2eac2558 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h @@ -0,0 +1,32 @@ +#ifndef _SWITCH_2_PRO_HOST_H_ +#define _SWITCH_2_PRO_HOST_H_ + +#include + +#include "USBHost/HostDriver/SwitchPro/SwitchPro.h" + +/** + * Nintendo Switch 2 Pro Controller (USB PID 0x2069): same bulk bring-up + HID init as SwitchProHost. + * Decoding is **InReport only** (10-byte payload). Matching on bytes 10 / 16–17 (IMU + stick coupling) + * caused random presses and flicker on hardware — do not reintroduce without stable fields or debounce + * tuned on-device. + */ +class Switch2ProHost : public SwitchProHost +{ +public: + explicit Switch2ProHost(uint8_t idx) + : SwitchProHost(idx) {} + + void process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) override; + +#ifdef OGXM_SWITCH2_HID_RAW_LOG +private: + static constexpr std::uint16_t kSwitch2RawLogCap = 64; + std::uint8_t switch2_dbg_prev_[kSwitch2RawLogCap]{}; + std::uint16_t switch2_dbg_prev_len_{0}; + std::uint8_t switch2_dbg_prev_btn_[3]{}; + bool switch2_dbg_have_btn_{false}; +#endif +}; + +#endif diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h new file mode 100644 index 00000000..2e7724a7 --- /dev/null +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h @@ -0,0 +1,51 @@ +/* Nintendo Switch 2–family USB bulk bring-up (interface 1), same sequence as + * Tools/controller_capture/switch2_usb_init.py / HandHeldLegend procon2tool. */ +#pragma once + +#include + +static const uint8_t S2_PKT_0[16] = { 0x03,0x91,0x00,0x0d,0x00,0x08,0x00,0x00,0x01,0x00,0xff,0xff,0xff,0xff,0xff,0xff }; +static const uint8_t S2_PKT_1[8] = { 0x07,0x91,0x00,0x01,0x00,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_2[8] = { 0x16,0x91,0x00,0x01,0x00,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_3[23] = { 0x15,0x91,0x00,0x01,0x00,0x0e,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; +static const uint8_t S2_PKT_4[25] = { 0x15,0x91,0x00,0x02,0x00,0x11,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; +static const uint8_t S2_PKT_5[9] = { 0x15,0x91,0x00,0x03,0x00,0x01,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_6[16] = { 0x09,0x91,0x00,0x07,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_7[12] = { 0x0c,0x91,0x00,0x02,0x00,0x04,0x00,0x00,0x27,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_8[8] = { 0x11,0x91,0x00,0x03,0x00,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_9[29] = { 0x0a,0x91,0x00,0x08,0x00,0x14,0x00,0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x35,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_10[12] = { 0x0c,0x91,0x00,0x04,0x00,0x04,0x00,0x00,0x27,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_11[12] = { 0x03,0x91,0x00,0x0a,0x00,0x04,0x00,0x00,0x09,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_12[8] = { 0x10,0x91,0x00,0x01,0x00,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_13[8] = { 0x01,0x91,0x00,0x0c,0x00,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_14[7] = { 0x03,0x91,0x00,0x01,0x00,0x00,0x00 }; +static const uint8_t S2_PKT_15[11] = { 0x0a,0x91,0x00,0x02,0x00,0x04,0x00,0x00,0x03,0x00,0x00 }; +static const uint8_t S2_PKT_16[16] = { 0x09,0x91,0x00,0x07,0x00,0x08,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + +struct Switch2UsbBulkPacket { + const uint8_t* data; + uint8_t len; +}; + +static const Switch2UsbBulkPacket SWITCH2_USB_BULK_PACKETS[] = { + { S2_PKT_0, sizeof(S2_PKT_0) }, + { S2_PKT_1, sizeof(S2_PKT_1) }, + { S2_PKT_2, sizeof(S2_PKT_2) }, + { S2_PKT_3, sizeof(S2_PKT_3) }, + { S2_PKT_4, sizeof(S2_PKT_4) }, + { S2_PKT_5, sizeof(S2_PKT_5) }, + { S2_PKT_6, sizeof(S2_PKT_6) }, + { S2_PKT_7, sizeof(S2_PKT_7) }, + { S2_PKT_8, sizeof(S2_PKT_8) }, + { S2_PKT_9, sizeof(S2_PKT_9) }, + { S2_PKT_10, sizeof(S2_PKT_10) }, + { S2_PKT_11, sizeof(S2_PKT_11) }, + { S2_PKT_12, sizeof(S2_PKT_12) }, + { S2_PKT_13, sizeof(S2_PKT_13) }, + { S2_PKT_14, sizeof(S2_PKT_14) }, + { S2_PKT_15, sizeof(S2_PKT_15) }, + { S2_PKT_16, sizeof(S2_PKT_16) }, +}; + +static constexpr unsigned SWITCH2_USB_BULK_PACKET_COUNT = + sizeof(SWITCH2_USB_BULK_PACKETS) / sizeof(SWITCH2_USB_BULK_PACKETS[0]); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp index 105f3081..5762e0b6 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp @@ -3,13 +3,255 @@ #include "host/usbh.h" #include "class/hid/hid_host.h" +#include "common/tusb_types.h" #include "USBHost/HostDriver/SwitchPro/SwitchPro.h" +#include "USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h" -void SwitchProHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) +bool SwitchProHost::is_switch2_usb_family(uint16_t vid, uint16_t pid) { + if (vid != 0x057Eu) + { + return false; + } + switch (pid) + { + case 0x2066u: + case 0x2067u: + case 0x2069u: + case 0x2073u: + return true; + default: + return false; + } +} + +void SwitchProHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, + const uint8_t* report_desc, uint16_t desc_len) +{ + (void)report_desc; + (void)desc_len; + std::memset(&out_report_, 0, sizeof(out_report_)); - init_switch_host(gamepad, address, instance); + hid_instance_ = instance; + switch2_dev_addr_ = address; + switch2_gamepad_ = &gamepad; + init_state_ = InitState::HANDSHAKE; + + uint16_t vid = 0; + uint16_t pid = 0; + tuh_vid_pid_get(address, &vid, &pid); + + if (is_switch2_usb_family(vid, pid)) + { + switch2_bringup_active_ = true; + switch2_pkt_idx_ = 0; + switch2_ep_out_ = 0; + switch2_ep_in_ = 0; + switch2_start_config_read(); + } + else + { + switch2_bringup_active_ = false; + init_switch_host(gamepad, address, instance); + } +} + +void SwitchProHost::switch2_start_config_read() +{ + if (!tuh_descriptor_get_configuration( + switch2_dev_addr_, + 0, + switch2_cfg_buf_.data(), + static_cast(switch2_cfg_buf_.size()), + switch2_cfg_cb, + reinterpret_cast(this))) + { + switch2_finish_bringup(); + } +} + +bool SwitchProHost::switch2_parse_open_iface1(const uint8_t* desc_cfg, uint16_t buflen) +{ + switch2_ep_out_ = 0; + switch2_ep_in_ = 0; + + if (buflen < sizeof(tusb_desc_configuration_t)) + { + return false; + } + + auto const* cfg = reinterpret_cast(desc_cfg); + uint16_t total = tu_le16toh(cfg->wTotalLength); + uint16_t len = TU_MIN(total, buflen); + uint8_t const* end = desc_cfg + len; + uint8_t const* p = tu_desc_next(desc_cfg); + + while (p < end) + { + if (tu_desc_type(p) != TUSB_DESC_INTERFACE) + { + p = tu_desc_next(p); + continue; + } + + auto const* itf = reinterpret_cast(p); + if (itf->bInterfaceNumber != 1 || itf->bAlternateSetting != 0) + { + p = tu_desc_next(p); + continue; + } + + p = tu_desc_next(p); + int endpoint = 0; + while (endpoint < itf->bNumEndpoints && p < end) + { + if (tu_desc_type(p) != TUSB_DESC_ENDPOINT) + { + p = tu_desc_next(p); + continue; + } + + auto const* ep = reinterpret_cast(p); + if (ep->bmAttributes.xfer == TUSB_XFER_BULK) + { + if (!tuh_edpt_open(switch2_dev_addr_, ep)) + { + return false; + } + if (tu_edpt_dir(ep->bEndpointAddress) == TUSB_DIR_OUT && switch2_ep_out_ == 0) + { + switch2_ep_out_ = ep->bEndpointAddress; + } + else if (tu_edpt_dir(ep->bEndpointAddress) == TUSB_DIR_IN && switch2_ep_in_ == 0) + { + switch2_ep_in_ = ep->bEndpointAddress; + } + } + endpoint++; + p = tu_desc_next(p); + } + + return switch2_ep_out_ != 0; + } + + return false; +} + +void SwitchProHost::switch2_cfg_cb(tuh_xfer_s* xfer) +{ + auto* self = reinterpret_cast(xfer->user_data); + if (self == nullptr || !self->switch2_bringup_active_) + { + return; + } + + if (xfer->result != XFER_RESULT_SUCCESS || + xfer->actual_len < sizeof(tusb_desc_configuration_t)) + { + self->switch2_finish_bringup(); + return; + } + + uint16_t actual = static_cast(xfer->actual_len); + if (!self->switch2_parse_open_iface1(self->switch2_cfg_buf_.data(), actual)) + { + self->switch2_finish_bringup(); + return; + } + + self->switch2_pkt_idx_ = 0; + self->switch2_submit_out_packet(); +} + +void SwitchProHost::switch2_out_cb(tuh_xfer_s* xfer) +{ + auto* self = reinterpret_cast(xfer->user_data); + if (self == nullptr || !self->switch2_bringup_active_) + { + return; + } + + if (self->switch2_ep_in_ != 0) + { + self->switch2_submit_in_read(); + } + else + { + self->switch2_after_packet_round(); + } +} + +void SwitchProHost::switch2_in_cb(tuh_xfer_s* xfer) +{ + auto* self = reinterpret_cast(xfer->user_data); + if (self == nullptr || !self->switch2_bringup_active_) + { + return; + } + (void)xfer; + self->switch2_after_packet_round(); +} + +void SwitchProHost::switch2_submit_out_packet() +{ + const Switch2UsbBulkPacket& pkt = SWITCH2_USB_BULK_PACKETS[switch2_pkt_idx_]; + if (pkt.len > switch2_bulk_out_buf_.size()) + { + switch2_finish_bringup(); + return; + } + + std::memcpy(switch2_bulk_out_buf_.data(), pkt.data, pkt.len); + + tuh_xfer_t xfer{}; + xfer.daddr = switch2_dev_addr_; + xfer.ep_addr = switch2_ep_out_; + xfer.buflen = pkt.len; + xfer.buffer = switch2_bulk_out_buf_.data(); + xfer.complete_cb = switch2_out_cb; + xfer.user_data = reinterpret_cast(this); + + if (!tuh_edpt_xfer(&xfer)) + { + switch2_after_packet_round(); + } +} + +void SwitchProHost::switch2_submit_in_read() +{ + tuh_xfer_t xfer{}; + xfer.daddr = switch2_dev_addr_; + xfer.ep_addr = switch2_ep_in_; + xfer.buflen = 64; + xfer.buffer = switch2_bulk_in_buf_.data(); + xfer.complete_cb = switch2_in_cb; + xfer.user_data = reinterpret_cast(this); + + if (!tuh_edpt_xfer(&xfer)) + { + switch2_after_packet_round(); + } +} + +void SwitchProHost::switch2_after_packet_round() +{ + switch2_pkt_idx_++; + if (switch2_pkt_idx_ >= SWITCH2_USB_BULK_PACKET_COUNT) + { + switch2_finish_bringup(); + return; + } + switch2_submit_out_packet(); +} + +void SwitchProHost::switch2_finish_bringup() +{ + switch2_bringup_active_ = false; + if (switch2_gamepad_ != nullptr) + { + init_switch_host(*switch2_gamepad_, switch2_dev_addr_, hid_instance_); + } } uint8_t SwitchProHost::get_output_sequence_counter() @@ -36,12 +278,12 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t out_report_.rumble_l[0] = 0x00; out_report_.rumble_l[1] = 0x01; out_report_.rumble_l[2] = 0x40; - out_report_.rumble_l[3] = 0x40; + out_report_.rumble_l[3] = 0x40; out_report_.rumble_r[0] = 0x00; out_report_.rumble_r[1] = 0x01; out_report_.rumble_r[2] = 0x40; - out_report_.rumble_r[3] = 0x40; + out_report_.rumble_r[3] = 0x40; switch (init_state_) { @@ -51,7 +293,7 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t out_report_.command = SwitchPro::CMD::HID; out_report_.sequence_counter = SwitchPro::CMD::HANDSHAKE; - if(tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) { init_state_ = InitState::TIMEOUT; } @@ -62,7 +304,7 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t out_report_.command = SwitchPro::CMD::HID; out_report_.sequence_counter = SwitchPro::CMD::DISABLE_TIMEOUT; - if(tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) { init_state_ = InitState::LED; } @@ -74,7 +316,7 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t out_report_.sub_command = SwitchPro::CMD::LED; out_report_.sub_command_args[0] = idx_ + 1; - if(tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) { init_state_ = InitState::LED_HOME; } @@ -88,7 +330,7 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t out_report_.sub_command_args[1] = (0xF /* LED start intensity */ << 4) | 0x0 /* Number of full cycles */; out_report_.sub_command_args[2] = (0xF /* Mini Cycle 1 LED intensity */ << 4) | 0x0 /* Mini Cycle 2 LED intensity */; - if(tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) { init_state_ = InitState::FULL_REPORT; } @@ -99,7 +341,7 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t out_report_.command = SwitchPro::CMD::AND_RUMBLE; out_report_.sub_command = SwitchPro::CMD::MODE; out_report_.sub_command_args[0] = SwitchPro::CMD::FULL_REPORT_MODE; - + if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) { init_state_ = InitState::IMU; @@ -107,11 +349,11 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t break; case InitState::IMU: report_size = 12; - + out_report_.command = SwitchPro::CMD::AND_RUMBLE; out_report_.sub_command = SwitchPro::CMD::GYRO; out_report_.sub_command_args[0] = 1 ? 1 : 0; - + if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) { init_state_ = InitState::DONE; @@ -121,44 +363,93 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t default: break; } +} - // tuh_hid_receive_report(address, instance); +static const uint8_t* switchpro_report_payload(const uint8_t* report, uint16_t len, uint16_t& out_payload_len) +{ + out_payload_len = len; + if (len == sizeof(SwitchPro::InReport)) + { + return report; + } + if (len >= 2U + sizeof(SwitchPro::InReport)) + { + const uint8_t rid = report[0]; + if (rid == SwitchPro::REPORT_ID_STANDARD || rid == SwitchPro::REPORT_ID_SWITCH2_FULL || + rid == SwitchPro::REPORT_ID_FULL_ALT) + { + out_payload_len = static_cast(len - 2U); + return report + 2; + } + } + return nullptr; } -void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) +void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, + uint16_t len) { + if (switch2_bringup_active_) + { + tuh_hid_receive_report(address, instance); + return; + } + if (init_state_ != InitState::DONE) { init_switch_host(gamepad, address, instance); return; } - const SwitchPro::InReport* in_report = reinterpret_cast(report); - if (std::memcmp(&prev_in_report_.buttons, in_report->buttons, 9) == 0) + uint16_t payload_len = 0; + const uint8_t* payload = switchpro_report_payload(report, len, payload_len); + if (payload == nullptr || payload_len < sizeof(SwitchPro::InReport)) { tuh_hid_receive_report(address, instance); return; } - Gamepad::PadIn gp_in; - - if (in_report->buttons[0] & SwitchPro::Buttons0::Y) gp_in.buttons |= gamepad.MAP_BUTTON_X; - if (in_report->buttons[0] & SwitchPro::Buttons0::B) gp_in.buttons |= gamepad.MAP_BUTTON_A; - if (in_report->buttons[0] & SwitchPro::Buttons0::A) gp_in.buttons |= gamepad.MAP_BUTTON_B; - if (in_report->buttons[0] & SwitchPro::Buttons0::X) gp_in.buttons |= gamepad.MAP_BUTTON_Y; - if (in_report->buttons[2] & SwitchPro::Buttons2::L) gp_in.buttons |= gamepad.MAP_BUTTON_LB; - if (in_report->buttons[0] & SwitchPro::Buttons0::R) gp_in.buttons |= gamepad.MAP_BUTTON_RB; - if (in_report->buttons[1] & SwitchPro::Buttons1::L3) gp_in.buttons |= gamepad.MAP_BUTTON_L3; - if (in_report->buttons[1] & SwitchPro::Buttons1::R3) gp_in.buttons |= gamepad.MAP_BUTTON_R3; - if (in_report->buttons[1] & SwitchPro::Buttons1::MINUS) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; - if (in_report->buttons[1] & SwitchPro::Buttons1::PLUS) gp_in.buttons |= gamepad.MAP_BUTTON_START; - if (in_report->buttons[1] & SwitchPro::Buttons1::HOME) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (in_report->buttons[1] & SwitchPro::Buttons1::CAPTURE) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + const SwitchPro::InReport* in_report = reinterpret_cast(payload); + if (std::memcmp(&prev_in_report_.buttons, in_report->buttons, 9) == 0) + { + tuh_hid_receive_report(address, instance); + return; + } - if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; - if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; - if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; - if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + Gamepad::PadIn gp_in; + + if (in_report->buttons[0] & SwitchPro::Buttons0::Y) + gp_in.buttons |= gamepad.MAP_BUTTON_X; + if (in_report->buttons[0] & SwitchPro::Buttons0::B) + gp_in.buttons |= gamepad.MAP_BUTTON_A; + if (in_report->buttons[0] & SwitchPro::Buttons0::A) + gp_in.buttons |= gamepad.MAP_BUTTON_B; + if (in_report->buttons[0] & SwitchPro::Buttons0::X) + gp_in.buttons |= gamepad.MAP_BUTTON_Y; + if (in_report->buttons[2] & SwitchPro::Buttons2::L) + gp_in.buttons |= gamepad.MAP_BUTTON_LB; + if (in_report->buttons[0] & SwitchPro::Buttons0::R) + gp_in.buttons |= gamepad.MAP_BUTTON_RB; + if (in_report->buttons[1] & SwitchPro::Buttons1::L3) + gp_in.buttons |= gamepad.MAP_BUTTON_L3; + if (in_report->buttons[1] & SwitchPro::Buttons1::R3) + gp_in.buttons |= gamepad.MAP_BUTTON_R3; + if (in_report->buttons[1] & SwitchPro::Buttons1::MINUS) + gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + if (in_report->buttons[1] & SwitchPro::Buttons1::PLUS) + gp_in.buttons |= gamepad.MAP_BUTTON_START; + if (in_report->buttons[1] & SwitchPro::Buttons1::HOME) + gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + if (in_report->buttons[1] & SwitchPro::Buttons1::CAPTURE) + gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + + if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_UP) + gp_in.dpad |= gamepad.MAP_DPAD_UP; + if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_DOWN) + gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_LEFT) + gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_RIGHT) + gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; gp_in.trigger_l = in_report->buttons[2] & SwitchPro::Buttons2::ZL ? Range::MAX : Range::MIN; gp_in.trigger_r = in_report->buttons[0] & SwitchPro::Buttons0::ZR ? Range::MAX : Range::MIN; @@ -168,10 +459,10 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in uint16_t joy_rx = in_report->joysticks[3] | ((in_report->joysticks[4] & 0xF) << 8); uint16_t joy_ry = (in_report->joysticks[4] >> 4) | (in_report->joysticks[5] << 4); - std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(normalize_axis(joy_lx), normalize_axis(joy_ly), true); - - std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = + + std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(normalize_axis(joy_rx), normalize_axis(joy_ry), true); gamepad.set_pad_in(gp_in); @@ -182,6 +473,11 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) { + if (switch2_bringup_active_) + { + return false; + } + if (init_state_ != InitState::DONE) { init_switch_host(gamepad, address, instance); @@ -201,24 +497,24 @@ bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t ins Gamepad::PadOut gp_out = gamepad.get_pad_out(); - if (gp_out.rumble_l > 0) + if (gp_out.rumble_l > 0) { uint8_t amplitude_l = static_cast(((gp_out.rumble_l / 255.0f) * 0.8f + 0.5f) * (0xC0 - 0x40) + 0x40); out_report_.rumble_l[0] = amplitude_l; out_report_.rumble_l[1] = 0x88; out_report_.rumble_l[2] = amplitude_l / 2; - out_report_.rumble_l[3] = 0x61; - } - else + out_report_.rumble_l[3] = 0x61; + } + else { out_report_.rumble_l[0] = 0x00; out_report_.rumble_l[1] = 0x01; out_report_.rumble_l[2] = 0x40; - out_report_.rumble_l[3] = 0x40; + out_report_.rumble_l[3] = 0x40; } - if (gp_out.rumble_r > 0) + if (gp_out.rumble_r > 0) { uint8_t amplitude_r = static_cast(((gp_out.rumble_r / 255.0f) * 0.8f + 0.5f) * (0xC0 - 0x40) + 0x40); @@ -226,14 +522,14 @@ bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t ins out_report_.rumble_r[1] = 0x88; out_report_.rumble_r[2] = amplitude_r / 2; out_report_.rumble_r[3] = 0x61; - } - else + } + else { out_report_.rumble_r[0] = 0x00; out_report_.rumble_r[1] = 0x01; out_report_.rumble_r[2] = 0x40; - out_report_.rumble_r[3] = 0x40; + out_report_.rumble_r[3] = 0x40; } return tuh_hid_send_report(address, instance, 0, &out_report_, report_size); -} \ No newline at end of file +} diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h index a599b722..67ee7dc9 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h @@ -1,11 +1,13 @@ #ifndef _SWITCH_PRO_HOST_H_ #define _SWITCH_PRO_HOST_H_ +#include #include #include "Descriptors/SwitchPro.h" #include "USBHost/HostDriver/HostDriver.h" -#include "Board/ogxm_log.h" + +struct tuh_xfer_s; class SwitchProHost : public HostDriver { @@ -17,7 +19,9 @@ class SwitchProHost : public HostDriver void process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) override; bool send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) override; -private: + static bool is_switch2_usb_family(uint16_t vid, uint16_t pid); + +protected: enum class InitState { HANDSHAKE, @@ -35,18 +39,34 @@ class SwitchProHost : public HostDriver SwitchPro::InReport prev_in_report_{}; SwitchPro::OutReport out_report_{}; + uint8_t hid_instance_{0}; + uint8_t switch2_dev_addr_{0}; + uint8_t switch2_ep_out_{0}; + uint8_t switch2_ep_in_{0}; + bool switch2_bringup_active_{false}; + Gamepad* switch2_gamepad_{nullptr}; + std::array switch2_cfg_buf_{}; + std::array switch2_bulk_out_buf_{}; + std::array switch2_bulk_in_buf_{}; + unsigned switch2_pkt_idx_{0}; + + void switch2_start_config_read(); + bool switch2_parse_open_iface1(const uint8_t* desc_cfg, uint16_t buflen); + void switch2_submit_out_packet(); + void switch2_submit_in_read(); + void switch2_after_packet_round(); + void switch2_finish_bringup(); + + static void switch2_cfg_cb(tuh_xfer_s* xfer); + static void switch2_out_cb(tuh_xfer_s* xfer); + static void switch2_in_cb(tuh_xfer_s* xfer); + void init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t instance); uint8_t get_output_sequence_counter(); static inline int16_t normalize_axis(uint16_t value) { - /* 12bit value from the controller doesnt cover the full 12bit range seemingly, - isn't completely centered at 2047 either so I may be missing something here. - Tried to get as close as possible with the multiplier */ - - OGXM_LOG("Value: %d\n", value); int32_t normalized_value = (value - 2047) * 22; - OGXM_LOG("Normalized value: %d\n", normalized_value); return Range::clamp(normalized_value); } }; diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp index e88e9789..ba277239 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp @@ -8,6 +8,11 @@ #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput_cmd.h" +#include "Board/Config.h" +#if defined(CONFIG_EN_USB_HOST) +#include "pio_usb.h" +#endif + namespace tuh_xinput { static constexpr uint8_t MAX_INTERFACES = CFG_TUH_XINPUT * 2; @@ -101,6 +106,9 @@ static void std_sleep_ms(uint32_t ms) while ( std::chrono::duration_cast( std::chrono::high_resolution_clock::now() - start).count() < ms) { +#if defined(CONFIG_EN_USB_HOST) + pio_usb_host_frame(); +#endif tuh_task(); } } @@ -109,6 +117,9 @@ static void wait_for_tx_complete(uint8_t dev_addr, uint8_t ep_addr) { while (usbh_edpt_busy(dev_addr, ep_addr)) { +#if defined(CONFIG_EN_USB_HOST) + pio_usb_host_frame(); +#endif tuh_task(); } } diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index 11673343..067a1cba 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -9,7 +9,11 @@ #include #include "Board/Config.h" +#include "Board/board_api.h" #include "Board/ogxm_log.h" +#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) +#include "pio_usb.h" +#endif #include "UserSettings/UserSettings.h" #include "USBDevice/DeviceDriver/DeviceDriverTypes.h" #include "USBHost/HardwareIDs.h" @@ -28,6 +32,7 @@ #include "USBHost/HostDriver/DInput/DInput.h" #include "USBHost/HostDriver/SwitchWired/SwitchWired.h" #include "USBHost/HostDriver/SwitchPro/SwitchPro.h" +#include "USBHost/HostDriver/SwitchPro/Switch2ProHost.h" #include "USBHost/HostDriver/XInput/XboxOne.h" #include "USBHost/HostDriver/XInput/Xbox360.h" #include "USBHost/HostDriver/XInput/Xbox360W.h" @@ -35,7 +40,9 @@ #include "USBHost/HostDriver/N64/N64.h" #include "USBHost/HostDriver/HIDGeneric/HIDGeneric.h" -#define MAX_INTERFACES MAX_GAMEPADS //This may change if support is added for audio or other chatpads beside 360 wireless +/** Per USB device: TinyUSB HID instance indices and XInput instance indices are separate namespaces + * (both often start at 0). Reserve [0 .. MAX_GAMEPADS-1] for HID and [MAX_GAMEPADS .. 2*MAX-1] for XInput. */ +#define MAX_INTERFACES (MAX_GAMEPADS * 2) class HostManager { @@ -57,13 +64,14 @@ class HostManager { gamepads_[i] = &gamepads[i]; } + last_usb_host_input_ms_ = board_api::ms_since_boot(); } //XInput doesn't need report_desc or desc_len - inline bool setup_driver(const HostDriverType driver_type, const uint8_t address, const uint8_t instance, uint8_t const* report_desc = nullptr, uint16_t desc_len = 0) + inline bool setup_driver(const HostDriverType driver_type, DriverClass dclass, const uint8_t address, const uint8_t instance, uint8_t const* report_desc = nullptr, uint16_t desc_len = 0) { - uint8_t gp_idx = find_free_gamepad(); - if (gp_idx == INVALID_IDX || instance >= MAX_INTERFACES) + const uint8_t si = host_storage_index(dclass, instance); + if (si == INVALID_IDX || si >= MAX_INTERFACES) { return false; } @@ -77,7 +85,44 @@ class HostManager } Device& device_slot = device_slots_[dev_idx]; - Interface& interface = device_slot.interfaces[instance]; + + /* One physical pad on a composite that exposes both XInput and HID (e.g. some third-party + * controllers): share gamepad index. Multiple XInput interfaces (Xbox 360 wireless dongle) + * must each get their own slot — do not reuse across same class. */ + uint8_t gp_idx = INVALID_IDX; + if (device_slot.address == address) + { + for (uint8_t i = 0; i < MAX_INTERFACES; ++i) + { + if (i == si) + { + continue; + } + const Interface& other = device_slot.interfaces[i]; + if (!other.driver || other.gamepad_idx == INVALID_IDX || other.driver_class == DriverClass::NONE) + { + continue; + } + const bool complementary = + (dclass == DriverClass::HID && other.driver_class == DriverClass::XINPUT) || + (dclass == DriverClass::XINPUT && other.driver_class == DriverClass::HID); + if (complementary) + { + gp_idx = other.gamepad_idx; + break; + } + } + } + if (gp_idx == INVALID_IDX) + { + gp_idx = find_free_gamepad(); + } + if (gp_idx == INVALID_IDX) + { + return false; + } + + Interface& interface = device_slot.interfaces[si]; debug_printf("Attempting to allocate driver for index %d\n", gp_idx); @@ -103,6 +148,10 @@ class HostManager debug_printf("SWITCH Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); break; + case HostDriverType::SWITCH_PRO_2: + debug_printf("SWITCH PRO 2 Loaded\n"); fflush(stdout); + interface.driver = std::make_unique(gp_idx); + break; case HostDriverType::SWITCH_PRO: debug_printf("SWITCH PRO Loaded\n"); fflush(stdout); interface.driver = std::make_unique(gp_idx); @@ -144,7 +193,18 @@ class HostManager break; } + { + HostDriverType stored_type = driver_type; + if (stored_type == HostDriverType::UNKNOWN && dclass == DriverClass::HID && interface.driver) + { + stored_type = HostDriverType::HID_GENERIC; + } + interface.host_driver_type = stored_type; + } + device_slot.address = address; + interface.driver_class = dclass; + interface.usb_instance = instance; interface.gamepad_idx = gp_idx; interface.gamepad = gamepads_[gp_idx]; // Wii U GC adapter: Xbox controllers report positive Y for up; Nintendo use negative @@ -153,44 +213,88 @@ class HostManager interface.gamepad->set_stick_y_positive_is_up(xbox_stick_y); interface.driver->initialize(*interface.gamepad, device_slot.address, instance, report_desc, desc_len); + record_usb_host_input_activity(); return true; } - inline void process_report(uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) + inline void process_report(DriverClass dclass, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) { + record_usb_host_input_activity(); + + /* Same physical pad often exposes XInput + PS HID. Both were calling set_pad_in() on one Gamepad: + * inverted sticks, missed input, and flaky state. Prefer HID for DS4/DS5; drop XInput *processing* + * only (still re-arm IN below). */ + if (dclass == DriverClass::XINPUT) + { + for (const auto& device_slot : device_slots_) + { + if (device_slot.address != address) + { + continue; + } + for (const auto& iface : device_slot.interfaces) + { + if (iface.driver && iface.driver_class == DriverClass::HID && + (iface.host_driver_type == HostDriverType::PS4 || iface.host_driver_type == HostDriverType::PS5)) + { + (void)report; + (void)len; + tuh_xinput::receive_report(address, instance); + return; + } + } + break; + } + } + + const uint8_t si = host_storage_index(dclass, instance); + if (si >= MAX_INTERFACES) + { + return; + } for (auto& device_slot : device_slots_) { if (device_slot.address == address && - device_slot.interfaces[instance].driver && - device_slot.interfaces[instance].gamepad) + device_slot.interfaces[si].driver && + device_slot.interfaces[si].gamepad) { - device_slot.interfaces[instance].driver->process_report(*device_slot.interfaces[instance].gamepad, address, instance, report, len); + device_slot.interfaces[si].driver->process_report(*device_slot.interfaces[si].gamepad, address, instance, report, len); } } } - inline void connect_cb(uint8_t address, uint8_t instance) + inline void connect_cb(DriverClass dclass, uint8_t address, uint8_t instance) { + const uint8_t si = host_storage_index(dclass, instance); + if (si >= MAX_INTERFACES) + { + return; + } for (auto& device_slot : device_slots_) { if (device_slot.address == address && - device_slot.interfaces[instance].driver && - device_slot.interfaces[instance].gamepad) + device_slot.interfaces[si].driver && + device_slot.interfaces[si].gamepad) { - device_slot.interfaces[instance].driver->connect_cb(*device_slot.interfaces[instance].gamepad, address, instance); + device_slot.interfaces[si].driver->connect_cb(*device_slot.interfaces[si].gamepad, address, instance); } } } - inline void disconnect_cb(uint8_t address, uint8_t instance) + inline void disconnect_cb(DriverClass dclass, uint8_t address, uint8_t instance) { + const uint8_t si = host_storage_index(dclass, instance); + if (si >= MAX_INTERFACES) + { + return; + } for (auto& device_slot : device_slots_) { if (device_slot.address == address && - device_slot.interfaces[instance].driver && - device_slot.interfaces[instance].gamepad) + device_slot.interfaces[si].driver && + device_slot.interfaces[si].gamepad) { - device_slot.interfaces[instance].driver->disconnect_cb(*device_slot.interfaces[instance].gamepad, address, instance); + device_slot.interfaces[si].driver->disconnect_cb(*device_slot.interfaces[si].gamepad, address, instance); } } } @@ -198,32 +302,110 @@ class HostManager //Call on a timer inline void send_feedback() { + const uint32_t now_ms = board_api::ms_since_boot(); for (auto& device_slot : device_slots_) { if (device_slot.address == INVALID_IDX) { continue; } + /* Composite "PS4 mode" pads often expose both XInput (GIP) and HID. Sending Xbox rumble + + * PS4 HID output together breaks many third-party firmwares (input dies after a few seconds). */ + bool ps_style_hid = false; + for (const auto& iface : device_slot.interfaces) + { + if (!iface.driver || iface.driver_class != DriverClass::HID) + { + continue; + } + if (iface.host_driver_type == HostDriverType::PS4 || iface.host_driver_type == HostDriverType::PS5) + { + ps_style_hid = true; + break; + } + } for (uint8_t i = 0; i < MAX_INTERFACES; ++i) { - if (device_slot.interfaces[i].driver && - (device_slot.interfaces[i].gamepad->new_pad_out() || device_slot.interfaces[i].gamepad->has_rumble())) + Interface& iface = device_slot.interfaces[i]; + if (!iface.driver) { - device_slot.interfaces[i].driver->send_feedback(*device_slot.interfaces[i].gamepad, device_slot.address, i); - tuh_task(); + continue; } + /* PS4-only (no GIP): 200 ms OUT refresh is OK. Composite pads choke if we OUT at 200 ms — + * use rare keepalive + init + console-driven updates only. */ + const bool ps4_hid_periodic = + iface.driver_class == DriverClass::HID && iface.host_driver_type == HostDriverType::PS4 && + !ps_style_hid; + bool ps4_composite_keepalive = false; + if (ps_style_hid && iface.driver_class == DriverClass::HID && + iface.host_driver_type == HostDriverType::PS4 && iface.gamepad_idx < MAX_GAMEPADS) + { + const uint8_t gi = iface.gamepad_idx; + if (now_ms >= ps4_composite_next_keepalive_ms_[gi]) + { + ps4_composite_next_keepalive_ms_[gi] = now_ms + 4000u; + ps4_composite_keepalive = true; + } + } + if (!(iface.gamepad->new_pad_out() || iface.gamepad->has_rumble() || ps4_hid_periodic || + ps4_composite_keepalive)) + { + continue; + } + if (ps_style_hid && iface.driver_class == DriverClass::XINPUT) + { + continue; + } + iface.driver->send_feedback(*iface.gamepad, device_slot.address, iface.usb_instance); + tuh_task(); +#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) + /* Nested tuh_task during OUT must not starve PIO USB SOF or wired IN dies in ~1–2 s. */ + pio_usb_host_frame(); +#endif } } } void deinit_driver(DriverClass driver_class, uint8_t address, uint8_t instance) { + const uint8_t si = host_storage_index(driver_class, instance); + if (si >= MAX_INTERFACES) + { + return; + } for (auto& device_slot : device_slots_) { - if (device_slot.address == address) + if (device_slot.address != address) + { + continue; + } + Interface& iface = device_slot.interfaces[si]; + const uint8_t cleared_gamepad_idx = iface.gamepad_idx; + iface.driver.reset(); + iface.driver_class = DriverClass::NONE; + iface.host_driver_type = HostDriverType::UNKNOWN; + iface.gamepad_idx = INVALID_IDX; + iface.gamepad = nullptr; + iface.usb_instance = INVALID_IDX; + + bool any_driver = false; + for (auto& i : device_slot.interfaces) + { + if (i.driver) + { + any_driver = true; + break; + } + } + if (!any_driver) { + if (cleared_gamepad_idx < MAX_GAMEPADS) + { + ps4_composite_next_keepalive_ms_[cleared_gamepad_idx] = 0; + } device_slot.reset(); } + return; } } @@ -263,11 +445,16 @@ class HostManager inline uint8_t get_gamepad_idx(DriverClass driver_class, uint8_t address, uint8_t instance) { + const uint8_t si = host_storage_index(driver_class, instance); + if (si >= MAX_INTERFACES) + { + return INVALID_IDX; + } for (auto& device_slot : device_slots_) { - if (device_slot.address == address && instance < MAX_INTERFACES) + if (device_slot.address == address) { - return device_slot.interfaces[instance].gamepad_idx; + return device_slot.interfaces[si].gamepad_idx; } } return INVALID_IDX; @@ -285,6 +472,17 @@ class HostManager return false; } + /** Last time a USB IN report reached process_report (Pico W unplug watchdog when D+/D− GPIO lies under PIO). */ + inline void record_usb_host_input_activity() + { + last_usb_host_input_ms_ = board_api::ms_since_boot(); + } + + inline uint32_t usb_host_input_idle_ms() const + { + return board_api::ms_since_boot() - last_usb_host_input_ms_; + } + /** True if this device address already has any host driver (e.g. HID). Used to prefer XInput over HID for the same device. */ inline bool address_has_driver(uint8_t address) const { @@ -305,11 +503,25 @@ class HostManager private: static constexpr uint8_t INVALID_IDX = 0xFF; + static inline uint8_t host_storage_index(DriverClass cls, uint8_t tinusb_instance) + { + if (tinusb_instance >= MAX_GAMEPADS) + { + return INVALID_IDX; + } + const uint8_t off = (cls == DriverClass::XINPUT) ? MAX_GAMEPADS : 0; + return static_cast(tinusb_instance + off); + } + struct Interface { std::unique_ptr driver{nullptr}; Gamepad* gamepad{nullptr}; uint8_t gamepad_idx{INVALID_IDX}; + /** TinyUSB HID or XInput instance number for control/out transfers */ + uint8_t usb_instance{INVALID_IDX}; + DriverClass driver_class{DriverClass::NONE}; + HostDriverType host_driver_type{HostDriverType::UNKNOWN}; }; struct Device { @@ -322,14 +534,20 @@ class HostManager for (auto& interface : interfaces) { interface.driver.reset(); + interface.driver_class = DriverClass::NONE; + interface.host_driver_type = HostDriverType::UNKNOWN; interface.gamepad_idx = INVALID_IDX; interface.gamepad = nullptr; + interface.usb_instance = INVALID_IDX; } } }; Device device_slots_[MAX_GAMEPADS]; Gamepad* gamepads_[MAX_GAMEPADS]; + /** PS4+GIP composite: wall-time spacing for optional lightbar/rumble OUT refresh (see send_feedback). */ + uint32_t ps4_composite_next_keepalive_ms_[MAX_GAMEPADS]{}; + uint32_t last_usb_host_input_ms_{0}; HostManager() {} diff --git a/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp b/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp index 379e795e..c23f2bc0 100644 --- a/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp +++ b/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp @@ -21,7 +21,8 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re HostManager& host_manager = HostManager::get_instance(); - if (host_manager.setup_driver(HostManager::get_type({ vid, pid }), dev_addr, instance, desc_report, desc_len)) { + if (host_manager.setup_driver(HostManager::get_type({ vid, pid }), HostManager::DriverClass::HID, + dev_addr, instance, desc_report, desc_len)) { OGXMini::host_mounted(true); } } @@ -36,7 +37,7 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { } void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { - HostManager::get_instance().process_report(dev_addr, instance, report, len); + HostManager::get_instance().process_report(HostManager::DriverClass::HID, dev_addr, instance, report, len); } //XINPUT @@ -45,7 +46,7 @@ void tuh_xinput::mount_cb(uint8_t dev_addr, uint8_t instance, const tuh_xinput:: HostManager& host_manager = HostManager::get_instance(); HostDriverType host_type = HostManager::get_type(interface->dev_type); - if (host_manager.setup_driver(host_type, dev_addr, instance)) { + if (host_manager.setup_driver(host_type, HostManager::DriverClass::XINPUT, dev_addr, instance)) { OGXMini::host_mounted(true, host_type); } } @@ -60,19 +61,19 @@ void tuh_xinput::unmount_cb(uint8_t dev_addr, uint8_t instance, const tuh_xinput } void tuh_xinput::report_received_cb(uint8_t dev_addr, uint8_t instance, const uint8_t* report, uint16_t len) { - HostManager::get_instance().process_report(dev_addr, instance, report, len); + HostManager::get_instance().process_report(HostManager::DriverClass::XINPUT, dev_addr, instance, report, len); } void tuh_xinput::xbox360w_connect_cb(uint8_t dev_addr, uint8_t instance) { uint8_t idx = HostManager::get_instance().get_gamepad_idx( HostManager::DriverClass::XINPUT, dev_addr, instance); OGXMini::wireless_connected(true, idx); - HostManager::get_instance().connect_cb(dev_addr, instance); + HostManager::get_instance().connect_cb(HostManager::DriverClass::XINPUT, dev_addr, instance); } void tuh_xinput::xbox360w_disconnect_cb(uint8_t dev_addr, uint8_t instance) { uint8_t idx = HostManager::get_instance().get_gamepad_idx( HostManager::DriverClass::XINPUT, dev_addr, instance); OGXMini::wireless_connected(false, idx); - HostManager::get_instance().disconnect_cb(dev_addr, instance); + HostManager::get_instance().disconnect_cb(HostManager::DriverClass::XINPUT, dev_addr, instance); } \ No newline at end of file diff --git a/Firmware/RP2040/src/tusb_config.h b/Firmware/RP2040/src/tusb_config.h index 2021a814..4d3db526 100644 --- a/Firmware/RP2040/src/tusb_config.h +++ b/Firmware/RP2040/src/tusb_config.h @@ -156,6 +156,9 @@ #define CFG_TUH_HID_EPIN_BUFSIZE 64 #define CFG_TUH_HID_EPOUT_BUFSIZE 64 +/* Required for Switch 2 Pro bulk bring-up (tuh_edpt_xfer completion callbacks). */ +#define CFG_TUH_API_EDPT_XFER 1 + #endif //defined(CONFIG_EN_USB_HOST) #ifdef __cplusplus diff --git a/README.md b/README.md index 1a0559b1..aa53b194 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Waveshare RP2350-USB-A, Waveshare RP2350-Zero, Seeed Studio XIAO RP2040, RP2354, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. +**Development & maintainer support:** Firmware development, testing, and issue triage focus on **official or OEM boards**—hardware from the original creators, named retail/partner boards in this repo’s build options, and equivalent OEM designs. Unofficial clones, random AliExpress spin-offs, or homebrew PCBs that only “look like” a supported board are **not** guaranteed to work and are **out of scope** for development support (you may still flash and experiment at your own risk). + [**Visit the web app here**](https://megacadedev.github.io/OGX-Mini-2026-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app via USB, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect via USB" in the web app and select the OGX-Mini. You can also pair via Bluetooth, no extra steps are needed in that case. [**Join the discord here!**](https://discord.gg/guaBh9JZQ) @@ -81,7 +83,7 @@ See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a ful - Dualshock 4 (PS4) - Dualsense (PS5) - Nintendo Switch Pro -- Nintendo Switch wired +- Nintendo Switch wired (including **Switch 2 Pro** PID `0x2069` when **wired**—see [Wired Controllers](Firmware/RP2040/docs/Wired_Controllers.md)) - Nintendo 64 Generic USB - Playstation Classic - Generic DInput @@ -89,6 +91,8 @@ See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a ful Note: There are some third party controllers that can change their VID/PID, these might not work correctly. +**Requesting support for a new controller:** run the capture tool in **[Tools/controller_capture](Tools/controller_capture/README.md)** on your PC, save the report, and attach it when you ask for a new **VID/PID** or mapping. + ### Wireless adapters - Xbox 360 PC adapter (Microsoft or clones) - 8Bitdo v1 and v2 Bluetooth adapters (set to XInput mode) @@ -97,6 +101,8 @@ Note: There are some third party controllers that can change their VID/PID, thes ### Wireless Bluetooth controllers (Pico W & ESP32) **Note:** Bluetooth functionality is in early testing; some controllers may have quirks. BT pads work as input in **any** USB output mode (OG Xbox, XInput, PS3, Switch, etc.) on Pico W / Pico 2 W, and also when outputting over **GPIO** to **PS1/PS2**, **Dreamcast**, **GameCube**, or **N64** (same as wired USB in those modes). +**DualShock 3 (PS3) — USB pairing to the adapter’s Bluetooth (Pico W / Pico 2 W):** The DS3 does not pair like a normal Bluetooth device. If you plug a **DualShock 3 into the adapter’s USB host port** while the firmware is running, it will **automatically program the controller with this Pico’s Bluetooth address** (same mechanism as the [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/) tool). Then **unplug the USB cable** and press the **PS** button to connect wirelessly. If the radio was not ready at the moment the pad enumerated, pairing is retried on the next input reports until the address is available. + **Pico W / Pico 2 W — important for DualShock 4 (DS4):** DS4 uses **Classic Bluetooth (BR/EDR)**. The same CYW43 radio also runs **BLE advertising** for the **phone / web app**. Running both at once often **drops the DS4 link** seconds after connect (blue LED then off). Firmware therefore **pauses BLE advertising** while a **Classic BT** gamepad is connected (DS4, DS3 over BT, Xbox 360 wireless adapter style links). **DualSense** and **Xbox Series (BLE)** mostly use **LE** and are unaffected by that pause. | Situation | What to do | @@ -125,7 +131,11 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork -Version history and release notes are in **[CHANGELOG.md](CHANGELOG.md)**. For detailed firmware improvements — **PS3**, **XInput / XSM3**, **OG Xbox**, **PS2/OPL**, **latency**, **Pico W Bluetooth (DS4 Classic BT, BLE coexistence, Xbox Series BLE)**, etc. — see **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)**. +Version history and release notes are in **[CHANGELOG.md](CHANGELOG.md)**. For detailed firmware improvements — **PS3**, **XInput / XSM3**, **OG Xbox**, **PS2/OPL**, **latency**, **Pico W Bluetooth (DS4 Classic BT, BLE coexistence, Xbox Series BLE)**, **Pico W / Pico 2 W PIO USB wired unplug detection**, etc. — see **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)**. + +Highlights: + +- **Pico W / Pico 2 W — PIO USB wired unplug:** When you unplug the gamepad from the adapter’s USB host port, the firmware now **detects disconnect reliably** even though PIO USB owns D+/D− (GPIO line state often never shows a true “disconnected” idle). Detection uses **debounced** hints: **HCD port connect status**, **no TinyUSB configured device** (all `tuh_mounted` addresses), and **no host input reports** for a few seconds — so the TinyUSB/PIO host can **tear down**, **GPIO line IRQ monitoring** can resume, and **Bluetooth pairing** can work again without power-cycling or “shorting” the port. Details: [IMPROVEMENTS.md — Pico W PIO USB unplug](Firmware/RP2040/docs/IMPROVEMENTS.md#pico-w--pico-2-w--pio-usb-wired-controller-unplug-detection). *Note: Many features were added and tested on Pico W / Pico 2 W; other boards may not have been tested for every change.* @@ -163,7 +173,17 @@ If you would like a prebuilt unit, you can purchase one, with cable and Xbox ada ## Adding supported controllers -If your third‑party controller isn’t working but a similar one (e.g. same brand or protocol) is listed in [Wired Controllers](Firmware/RP2040/docs/Wired_Controllers.md), we can add support by registering its **VID** (Vendor ID) and **PID** (Product ID). Send those two values (and the controller name/model if you know it) so they can be added to the right list in `Firmware/RP2040/src/USBHost/HardwareIDs.h`. +If your controller isn’t working but a similar one (e.g. same brand or protocol) is listed in [Wired Controllers](Firmware/RP2040/docs/Wired_Controllers.md), support often starts by registering its **VID** (Vendor ID) and **PID** (Product ID) in `Firmware/RP2040/src/USBHost/HardwareIDs.h`. + +**VID/PID alone is not always enough.** Many pads need the correct **USB mode** (XInput vs DInput vs Switch), matching **report layout**, or **driver-specific** handling. Dropping IDs into the list may do nothing or behave wrong if the device doesn’t match an existing parser. + +**What to do first:** run the **[controller capture tool](Tools/controller_capture/README.md)** on your PC, save the capture, and attach it when you ask for support (see that README for steps). Captures give us descriptors and traffic so we can see what the pad is really doing. + +**If a capture still isn’t enough to add support remotely:** **[donations via Ko-fi](https://ko-fi.com/megacadedev)** may be used toward **buying the same controller** so it can be tested and supported **when time and stock allow**—this is not a guaranteed timeline or commitment for every request. + +**What we prioritize for support (disclaimer):** Maintainer effort focuses on **OEM and name‑brand** controllers (first‑party console pads and established third‑party brands with stable USB identities). **Knock‑offs, unbranded clones, and “compatible” pads** that reuse random VID/PIDs or change behavior by batch are often **not practical to support**: we may be unable to source the **exact same** unit, and fixes may not transfer to other clones. You can still open an issue or share a capture; just expect clone/no‑name hardware to be **lower priority or declined**. + +When you write in, include **VID**, **PID**, controller **name/model**, and (if possible) a **capture** from the tool above. If the controller has multiple modes (XInput / DInput / Switch), say which mode you used. ### How to get VID and PID @@ -186,7 +206,7 @@ If your third‑party controller isn’t working but a similar one (e.g. same br - Some browser-based tools (e.g. [gamepad tester](https://gamepad-tester.com/) or similar) show the connected gamepad’s VID/PID in the page or in the browser’s device/Gamepad API info. Check the site’s instructions. -When submitting, include **VID**, **PID**, and controller name (e.g. “8BitDo Pro 2 in DInput mode”). If the controller has multiple modes (XInput / DInput / Switch), note which mode you used when reading the IDs. +When submitting without a full capture, still include **VID**, **PID**, and controller name (e.g. “8BitDo Pro 2 in DInput mode”), and note which mode you used when reading the IDs. ## Build ### RP2040 @@ -250,7 +270,7 @@ Outputs (`.elf`, `.uf2`, etc.) are in the build directory; flash the `.uf2` to t |---------|-------------| | [Wii_Mode_Guide.md](Firmware/RP2040/docs/Wii_Mode_Guide.md) | Wii mode (build-option only): No Extension / Nunchuk / Classic, USB host, sync and auto-connect, button mapping. | | [PICO2W_WII_USB_SETUP.md](Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | -| [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360. | +| [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360, Pico W Bluetooth, **Pico W PIO USB wired unplug detection**. | ### ESP32 Please see the Hardware directory for a diagram showing how to hookup the ESP32 to your RP2040. diff --git a/Tools/README.md b/Tools/README.md index 9b181361..e8ec30c2 100644 --- a/Tools/README.md +++ b/Tools/README.md @@ -1,2 +1,9 @@ -# Dumping Xbox DVD dongle firmware -The firmware for the DVD Playback Kit is not included here, but you can dump your own or place a `.BIN` dump in this directory. Whichever you do, you'll have to run `dump-xremote-firmware.py` to have it included with the firmware when you compile it. \ No newline at end of file +# Tools + +## Controller mapping capture (new gamepad support) + +See **[controller_capture/README.md](controller_capture/README.md)**. Run `controller_capture.py` on your PC to record button/axis mappings and VID/PID for maintainers when requesting support for a new controller. + +## Dumping Xbox DVD dongle firmware + +The firmware for the DVD Playback Kit is not included here, but you can dump your own or place a `.BIN` dump in this directory. Whichever you do, you'll have to run `dump-xremote-firmware.py` to have it included with the firmware when you compile it. \ No newline at end of file diff --git a/Tools/controller_capture/README.md b/Tools/controller_capture/README.md new file mode 100644 index 00000000..03059f02 --- /dev/null +++ b/Tools/controller_capture/README.md @@ -0,0 +1,117 @@ +# Controller mapping capture (`controller_capture.py`) + +Interactive helper for **OGX-Mini** users who want a **new gamepad** supported. It records how your PC sees the controller through **SDL / pygame** (button indices, axis indices, hat values, SDL GUID) and **USB VID:PID**, then writes a **single text file** you can attach to an issue or send to a maintainer. + +**USB and Bluetooth** are both supported: if the OS exposes the pad to SDL (pair Bluetooth in system settings first), it will appear in the list. + +### Nintendo Switch 2 Pro / Joy-Con 2 (USB) + +**Switch 2–family** pads (e.g. **Pro Controller 2**, **Joy-Con 2**) often **do not show up in SDL** on a PC until a host sends Nintendo’s **USB bulk** bring-up sequence on **interface 1** (same approach as [HandHeldLegend’s ProCon 2 Enabler](https://github.com/HandHeldLegend/handheldlegend.github.io) — `procon2tool`). + +In this tool, pick the platform: + +**“Nintendo Switch 2 Pro / Joy-Con 2 (USB — libusb handshake, then capture)”** + +The script will run **`switch2_usb_init.py`** (PyUSB + **libusb**) first, then start pygame so you can map controls. You still need **PyUSB** and OS access to the device (Linux: `libusb-1.0` + permissions; Windows: may need **WinUSB** on the bulk interface via Zadig). + +This does **not** flash firmware; it only runs on your computer. + +## Requirements + +- **Python 3.10+** +- `pygame` 2.x +- **Windows, macOS, or Linux** (same script; VID/PID auto-detection is only attempted on Linux) + +```bash +cd Tools/controller_capture +python3 -m pip install -r requirements.txt +python3 controller_capture.py +``` + +On Windows you may use `py` instead of `python3`. + +Optional CLI flags: + +- `python3 controller_capture.py -o my_report.txt` — set the output path up front (`-o` wins over auto-naming). +- `python3 controller_capture.py --use-sdl-name` — use the **SDL joystick name** as `controller_full_name` (no typing). +- `python3 controller_capture.py --auto-output-name` — save as **`_.txt`** without filename prompt (implies save; only when `-o` is not set). +- Combine: `python3 controller_capture.py --use-sdl-name --auto-output-name` for a quick non-interactive name + file. +- **`python3 controller_capture.py --raw-hid-only`** — **Linux only**: skips SDL/pygame entirely; runs only the **hidraw** hex capture (pick the same platform layout for prompts; use the **Switch 2 USB** platform if you need the bulk handshake first). Pair with `--auto-output-name` to save without prompts. + +Interactive shortcuts (without flags): + +- At the controller name prompt, **press Enter** to use the SDL-reported name. +- When saving, the suggested default filename is **`_.txt`** (press Enter to accept). + +## What you’ll do + +1. Choose the **platform layout** your controller matches (Xbox, PlayStation, Switch, etc.). +2. Pick the **controller** from the list SDL sees (**USB cable or paired Bluetooth**). +3. Enter the **full product name** of the pad (box / manufacturer name), **or press Enter** to use the SDL name, **or** run with **`--use-sdl-name`**. The report records the source (`controller_full_name_source` in JSON). +4. For each on-screen prompt, press **only** that button or move that stick direction. After each capture, **release everything and re-center the sticks** — the script waits for a neutral pose before the next prompt so it doesn’t pick up the previous control again. +5. At the end, follow the **on-screen steps** to find **VID and PID** for your OS (Windows / macOS / Linux). On Linux, values may be pre-filled; you can confirm or override. +6. Save the generated **`.txt` file** (default suggestion is derived from the controller name) and upload it when requesting support. + +On **Linux**, after SDL mapping the tool will ask whether to capture **raw HID input reports** from **`/dev/hidraw*`** (full report bytes in hex, per control, with an XOR diff vs idle). **Say yes** when asking for firmware support — that data matches what embedded code decodes (not SDL indices alone). + +On **Linux**, after VID/PID is known the tool asks whether to record **raw HID** **alongside pygame**: after each SDL capture it reads the latest **hidraw** packet, so **pygame decides when** you pressed (no IMU/timer false triggers). Those fields live on each binding: `hidraw_baseline_hex`, `hidraw_active_hex`, `hidraw_xor_hex`. Use **`--no-hidraw-sidecar`** to skip that prompt. + +The file includes both **human-readable** lines and a **JSON** block (`schema_version` **9**) with the same data for tooling. When the **Linux hidraw sidecar** is enabled, each binding includes **full** `hidraw_*_hex` strings plus lengths; the text report also has a **“Full hidraw packets”** section (16 bytes per line) so you do not need a separate dump script for that run. **`capture_mode`** is `full` (SDL, optional raw) or `raw_hid_only`. **`hidraw_gated_by_sdl`** summarizes the sidecar path. Optional **`raw_hid_reports`** is from the separate interactive hidraw walkthrough. **`controller_full_name_source`** is `sdl`, `user_entered`, or `hidraw` (raw-only). Use **`hidraw_full_report_dump.py`** only if you want a **live** stream unrelated to the SDL prompts. + +Use **`python3 controller_capture.py --skip-raw-hid`** if you only want SDL/VID capture and no hidraw walkthrough. + +## Finding which HID bytes a control uses (for firmware) + +When SDL indices are not enough (common on **Switch 2 Pro USB**), you need the **`hidraw_*` hex** on each binding. + +1. **Capture** with **Linux + SDL+hidraw sidecar** (or raw-hid flow) so every binding has `hidraw_baseline_hex` and `hidraw_active_hex` (same length, typically **64** bytes for full reports). +2. **XOR** baseline and active byte-for-byte. Any index where the result is **non‑zero** changed between “idle” and “pressed” for that sample. +3. **Ignore index 1** when reasoning about buttons: it is usually the **USB report timer** and toggles every frame. +4. **Start with indices 2–12** (report id + timer + the **10‑byte Nintendo “core”**: battery, three button bytes, six stick bytes). Many controls only touch those. If two different physical controls share the same XOR pattern, you need **more bytes** in the signature or a different test (see below). +5. **Sticks share bytes with some digitals** on Switch 2–style reports: the same byte may encode stick data *and* a button transition. Always compare your candidate XOR to **every axis binding** in the same file (`axis_lstick_*`, `axis_rstick_*`). If an axis **active** report matches the same **(byte21, byte22, …)** pattern as a button, a firmware decoder cannot use that short prefix alone. +6. **Indices 13+** often include **IMU / vendor fields** that move every frame even at rest. Treat them as **high risk** for ghost inputs unless you prove they are stable when idle on real hardware, or you use **relative** decoding (difference from a calibrated neutral) plus debouncing. +7. **Baselines differ per prompt**: each binding’s `hidraw_baseline_hex` was taken when you were “neutral” for *that* step, so absolute values at index 21+ are **not** comparable across rows—**XOR within the same row** is the reliable operation. + +**Helper script** (prints XOR indices and `active[21:24]` for collision spotting): + +```bash +python3 analyze_hidraw_xor.py Nintendo_Switch_2_Pro_Controller_YYYYMMDD_HHMMSS.txt --skip-timer +``` + +**Live full-report dump** (Linux): stream every hidraw read as one hex line so you can press **one** button at a time and see which indices change, separate from the interactive mapper: + +```bash +cd Tools/controller_capture +python3 hidraw_full_report_dump.py --vid 057e --pid 2069 +# or: python3 hidraw_full_report_dump.py --path /dev/hidraw4 +# only print when something changes: +python3 hidraw_full_report_dump.py --vid 057e --pid 2069 --diff +# ignore pure IMU tail jitter; print when “core” bytes 2:12 (masked) change: +python3 hidraw_full_report_dump.py --vid 057e --pid 2069 --diff-core +``` + +Redirect to a file if you want a log: `… > dump.txt`. Compare **idle** vs **held** lines by eye or `diff`; bytes that **always** change every line even at rest are not good solo signatures. + +After you identify a safe **mask + value** (or multi-byte signature), add it to the host driver and **verify on hardware** with sticks moved to extremes while tapping the control. + +## What maintainers use this for + +- **`capture_mode`**: `full` (SDL bindings + optional raw) vs `raw_hid_only` (hex only, no pygame indices). +- **`controller_full_name`**: human-readable name for changelog / Wired Controllers lists / issue tracking (retail name, SDL name, or hidraw `HID_NAME`). +- **`controller_full_name_source`**: `sdl`, `user_entered`, or `hidraw`. +- **`connection_guess`**: on Linux, best-effort `usb` / `bluetooth` / `unknown` from sysfs (optional context). +- **`HardwareIDs.h`**: `{ VID, PID }` entries for the right host driver (DInput, PS3, PS4, …). +- **SDL name/GUID**: cross-check with other databases and real device names. +- **Binding table**: map logical controls to **button / axis / hat indices** as the host stack reports them (cross-check vs other hosts). +- **Per-binding `hidraw_*` fields** (Linux, SDL+hidraw sidecar): raw bytes when pygame saw the control — preferred over the standalone walkthrough for Nintendo pads. +- **`raw_hid_reports`** (optional second phase): interactive hid-only capture — use **`xor_hex`** if you need it; often redundant if sidecar succeeded. + +## Limitations + +- Captures **what your OS + SDL expose** for the mapping table. If the device is in the wrong mode (e.g. XInput vs DInput), unplug/replug or toggle mode per the manual and run again. +- **Bluetooth** must be **paired and connected** in the OS before running; if capture is unstable, try **USB** for the same mapping run. +- **Raw hidraw** capture is **Linux-only** (needs a matching `/dev/hidraw` for your VID:PID and read access). On Windows/macOS, use Linux for the hex dump or a USB analyzer; the SDL mapping file is still useful alone. + +## Troubleshooting + +The script prints tips if inputs don’t register (Steam Input, USB ports, drivers, Linux permissions, Bluetooth pairing, etc.). See also the main repo **[Wired Controllers](../../Firmware/RP2040/docs/Wired_Controllers.md)** doc. diff --git a/Tools/controller_capture/analyze_hidraw_xor.py b/Tools/controller_capture/analyze_hidraw_xor.py new file mode 100644 index 00000000..0b3c9eb0 --- /dev/null +++ b/Tools/controller_capture/analyze_hidraw_xor.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +""" +Load a controller_capture .txt (schema_version 8+ JSON) and summarize hidraw XOR patterns. + +Use this to find which report byte indices change for each control, and to check +collisions (same bytes changing for two different controls — often means you need +more bytes in the signature or a different neutral pose). + +Usage: + python3 analyze_hidraw_xor.py path/to/capture.txt + python3 analyze_hidraw_xor.py path/to/capture.txt --max-index 31 +""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from pathlib import Path + + +def load_json_block(path: Path) -> dict: + text = path.read_text(encoding="utf-8") + start = text.find('{\n "schema_version"') + if start < 0: + start = text.find('{"schema_version"') + if start < 0: + raise ValueError("No JSON block with schema_version found") + depth = 0 + for i in range(start, len(text)): + if text[i] == "{": + depth += 1 + elif text[i] == "}": + depth -= 1 + if depth == 0: + return json.loads(text[start : i + 1]) + raise ValueError("Unclosed JSON") + + +def hx(s: str) -> bytes: + s = re.sub(r"\s+", "", s) + return bytes.fromhex(s) + + +def nz(x: bytes, hi: int) -> list[tuple[int, int]]: + return [(i, x[i]) for i in range(min(len(x), hi)) if x[i] != 0] + + +def main() -> int: + ap = argparse.ArgumentParser(description="Summarize hidraw XOR per binding from capture JSON") + ap.add_argument("capture_txt", type=Path) + ap.add_argument("--max-index", type=int, default=24, help="Max byte index to list (exclusive)") + ap.add_argument("--skip-timer", action="store_true", help="Omit index 1 from printed XOR list") + args = ap.parse_args() + + data = load_json_block(args.capture_txt) + bindings = data.get("maintainer_fields", {}).get("bindings", {}) + if not bindings: + print("No bindings in JSON", file=sys.stderr) + return 1 + + hi = max(16, args.max_index) + rows: list[tuple[str, bytes, bytes]] = [] + for name in sorted(bindings.keys()): + b = bindings[name] + if "hidraw_baseline_hex" not in b or "hidraw_active_hex" not in b: + continue + base = hx(b["hidraw_baseline_hex"]) + act = hx(b["hidraw_active_hex"]) + if len(base) != len(act): + print(f"{name}: baseline/active length mismatch", file=sys.stderr) + continue + x = bytes(a ^ b for a, b in zip(base, act)) + rows.append((name, x, act)) + + print(f"# Report length: {len(rows[0][1])} bytes (first binding)\n") + for name, x, act in rows: + pairs = nz(x, hi) + if args.skip_timer: + pairs = [(i, v) for i, v in pairs if i != 1] + sig = act[21:24].hex() if len(act) >= 24 else "" + print(f"{name}:") + print(f" xor[0..{hi}): " + " ".join(f"{i:02d}:{v:02x}" for i, v in pairs)) + if sig: + print(f" active[21:24]: {sig}") + print() + + # Collision check on active[21:22] for controls that have hidraw + d: dict[tuple[int, int], list[str]] = {} + for name, _x, act in rows: + if len(act) < 23: + continue + key = (act[21], act[22]) + d.setdefault(key, []).append(name) + dup = {k: v for k, v in d.items() if len(v) > 1} + if dup: + print("# active[21:22] collisions (need longer signature or not discriminant):") + for k, names in sorted(dup.items()): + print(f" {k[0]:02x} {k[1]:02x}: {', '.join(names)}") + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/Tools/controller_capture/controller_capture.py b/Tools/controller_capture/controller_capture.py new file mode 100644 index 00000000..41da830d --- /dev/null +++ b/Tools/controller_capture/controller_capture.py @@ -0,0 +1,1299 @@ +#!/usr/bin/env python3 +""" +OGX-Mini controller input capture tool. + +Walks the user through selecting a target platform, choosing a connected +gamepad (via SDL/pygame), then mapping each control. Works with **USB** and +**Bluetooth** controllers as long as the OS exposes them to SDL. Produces a +text/JSON report for maintainers to add HardwareIDs / HID layout support. + +Usage: + python3 controller_capture.py + python3 controller_capture.py -o my_pad.txt + python3 controller_capture.py --skip-raw-hid # SDL/VID only; no hidraw hex phase + python3 controller_capture.py --use-sdl-name --auto-output-name # SDL name + auto .txt filename + python3 controller_capture.py --raw-hid-only --auto-output-name # Linux: hidraw hex only, no pygame + python3 controller_capture.py --no-hidraw-sidecar # SDL only; no hidraw alongside pygame +""" + +from __future__ import annotations + +import argparse +import json +import os +import re +import platform +import sys +import textwrap +import time +from dataclasses import dataclass, field +from datetime import datetime, timezone +from typing import Any + +from switch2_usb_init import platform_requires_switch2_usb_init, run_switch2_usb_handshake + +# --------------------------------------------------------------------------- +# Platform → ordered list of logical controls to capture +# Labels are what we show the user; ids are stable keys in the output. +# --------------------------------------------------------------------------- + +_SWITCH_PRO_LAYOUT: list[tuple[str, str]] = [ + ("face_b", "B (bottom)"), + ("face_a", "A (right)"), + ("face_y", "Y (left)"), + ("face_x", "X (top)"), + ("shoulder_l", "L"), + ("shoulder_r", "R"), + ("trigger_zl", "ZL — press fully"), + ("trigger_zr", "ZR — press fully"), + ("center_minus", "Minus (−)"), + ("center_plus", "Plus (+)"), + ("center_home", "Home"), + ("center_capture", "Capture (or skip)"), + ("stick_l3", "Left stick click"), + ("stick_r3", "Right stick click"), + ("dpad_up", "D-pad UP"), + ("dpad_down", "D-pad DOWN"), + ("dpad_left", "D-pad LEFT"), + ("dpad_right", "D-pad RIGHT"), + ("axis_lstick_left", "Left stick — fully LEFT"), + ("axis_lstick_right", "Left stick — fully RIGHT"), + ("axis_lstick_up", "Left stick — fully UP"), + ("axis_lstick_down", "Left stick — fully DOWN"), + ("axis_rstick_left", "Right stick — fully LEFT"), + ("axis_rstick_right", "Right stick — fully RIGHT"), + ("axis_rstick_up", "Right stick — fully UP"), + ("axis_rstick_down", "Right stick — fully DOWN"), +] + +PLATFORM_CONTROLS: dict[str, list[tuple[str, str]]] = { + "Xbox / XInput (360, One, Series, Elite)": [ + ("face_a", "A (bottom face)"), + ("face_b", "B (right face)"), + ("face_x", "X (left face)"), + ("face_y", "Y (top face)"), + ("shoulder_lb", "Left bumper (LB)"), + ("shoulder_rb", "Right bumper (RB)"), + ("trigger_lt", "Left trigger (LT) — press fully"), + ("trigger_rt", "Right trigger (RT) — press fully"), + ("center_view", "View / Back / Select"), + ("center_menu", "Menu / Start"), + ("center_guide", "Guide / Xbox / Nexus button"), + ("stick_l3", "Left stick click (L3)"), + ("stick_r3", "Right stick click (R3)"), + ("dpad_up", "D-pad UP"), + ("dpad_down", "D-pad DOWN"), + ("dpad_left", "D-pad LEFT"), + ("dpad_right", "D-pad RIGHT"), + ("axis_lstick_left", "Left stick — push fully LEFT"), + ("axis_lstick_right", "Left stick — push fully RIGHT"), + ("axis_lstick_up", "Left stick — push fully UP"), + ("axis_lstick_down", "Left stick — push fully DOWN"), + ("axis_rstick_left", "Right stick — push fully LEFT"), + ("axis_rstick_right", "Right stick — push fully RIGHT"), + ("axis_rstick_up", "Right stick — push fully UP"), + ("axis_rstick_down", "Right stick — push fully DOWN"), + ], + "PlayStation (DS3 / DS4 / DualSense / generic)": [ + ("face_cross", "Cross (×)"), + ("face_circle", "Circle (○)"), + ("face_square", "Square (□)"), + ("face_triangle", "Triangle (△)"), + ("shoulder_l1", "L1"), + ("shoulder_r1", "R1"), + ("trigger_l2", "L2 — press fully"), + ("trigger_r2", "R2 — press fully"), + ("center_share", "Share / Select"), + ("center_options", "Options / Start"), + ("center_ps", "PlayStation / PS button"), + ("touchpad_click", "Touchpad click (or skip if none)"), + ("stick_l3", "L3 (left stick click)"), + ("stick_r3", "R3 (right stick click)"), + ("dpad_up", "D-pad UP"), + ("dpad_down", "D-pad DOWN"), + ("dpad_left", "D-pad LEFT"), + ("dpad_right", "D-pad RIGHT"), + ("axis_lstick_left", "Left stick — fully LEFT"), + ("axis_lstick_right", "Left stick — fully RIGHT"), + ("axis_lstick_up", "Left stick — fully UP"), + ("axis_lstick_down", "Left stick — fully DOWN"), + ("axis_rstick_left", "Right stick — fully LEFT"), + ("axis_rstick_right", "Right stick — fully RIGHT"), + ("axis_rstick_up", "Right stick — fully UP"), + ("axis_rstick_down", "Right stick — fully DOWN"), + ], + "Nintendo Switch Pro / wired Switch layout": list(_SWITCH_PRO_LAYOUT), + # Switch 2 / Joy-Con 2: PC does not expose SDL input until USB bulk handshake (see switch2_usb_init.py). + "Nintendo Switch 2 Pro / Joy-Con 2 (USB — libusb handshake, then capture)": list(_SWITCH_PRO_LAYOUT), + "Generic DInput / PC gamepad": [ + ("face_1", "Primary action (often '1' or South)"), + ("face_2", "Secondary (often '2' or East)"), + ("face_3", "Tertiary"), + ("face_4", "Quaternary"), + ("shoulder_l", "Left shoulder"), + ("shoulder_r", "Right shoulder"), + ("trigger_l", "Left trigger — fully"), + ("trigger_r", "Right trigger — fully"), + ("select", "Select / Back"), + ("start", "Start"), + ("mode", "Mode / Home / Guide (if present)"), + ("stick_l3", "Left stick click"), + ("stick_r3", "Right stick click"), + ("dpad_up", "D-pad UP"), + ("dpad_down", "D-pad DOWN"), + ("dpad_left", "D-pad LEFT"), + ("dpad_right", "D-pad RIGHT"), + ("axis_lstick_left", "Left stick — fully LEFT"), + ("axis_lstick_right", "Left stick — fully RIGHT"), + ("axis_lstick_up", "Left stick — fully UP"), + ("axis_lstick_down", "Left stick — fully DOWN"), + ("axis_rstick_left", "Right stick — fully LEFT"), + ("axis_rstick_right", "Right stick — fully RIGHT"), + ("axis_rstick_up", "Right stick — fully UP"), + ("axis_rstick_down", "Right stick — fully DOWN"), + ], + "Wii / Wii U style (Classic / adapter — what PC sees)": [ + ("face_a", "A"), + ("face_b", "B"), + ("face_x", "X"), + ("face_y", "Y"), + ("shoulder_l", "L"), + ("shoulder_r", "R"), + ("trigger_zl", "ZL"), + ("trigger_zr", "ZR"), + ("minus", "Minus"), + ("plus", "Plus"), + ("home", "Home"), + ("stick_l3", "Left stick click (if any)"), + ("stick_r3", "Right stick click (if any)"), + ("dpad_up", "D-pad UP"), + ("dpad_down", "D-pad DOWN"), + ("dpad_left", "D-pad LEFT"), + ("dpad_right", "D-pad RIGHT"), + ("axis_lstick_left", "Left stick — LEFT"), + ("axis_lstick_right", "Left stick — RIGHT"), + ("axis_lstick_up", "Left stick — UP"), + ("axis_lstick_down", "Left stick — DOWN"), + ("axis_rstick_left", "Right stick — LEFT"), + ("axis_rstick_right", "Right stick — RIGHT"), + ("axis_rstick_up", "Right stick — UP"), + ("axis_rstick_down", "Right stick — DOWN"), + ], + "Original Xbox (Duke / S) — if exposed as HID on PC": [ + ("face_a", "A"), + ("face_b", "B"), + ("face_x", "X"), + ("face_y", "Y"), + ("black", "Black"), + ("white", "White"), + ("trigger_l", "Left trigger"), + ("trigger_r", "Right trigger"), + ("back", "Back"), + ("start", "Start"), + ("stick_l3", "Left stick click"), + ("stick_r3", "Right stick click"), + ("dpad_up", "D-pad UP"), + ("dpad_down", "D-pad DOWN"), + ("dpad_left", "D-pad LEFT"), + ("dpad_right", "D-pad RIGHT"), + ("axis_lstick_left", "Left stick — LEFT"), + ("axis_lstick_right", "Left stick — RIGHT"), + ("axis_lstick_up", "Left stick — UP"), + ("axis_lstick_down", "Left stick — DOWN"), + ("axis_rstick_left", "Right stick — LEFT"), + ("axis_rstick_right", "Right stick — RIGHT"), + ("axis_rstick_up", "Right stick — UP"), + ("axis_rstick_down", "Right stick — DOWN"), + ], + "Other / not listed (custom list)": [ + ("ctrl_01", "Control 1 — press or move as instructed next"), + ("ctrl_02", "Control 2"), + ("ctrl_03", "Control 3"), + ("ctrl_04", "Control 4"), + ("ctrl_05", "Control 5"), + ("ctrl_06", "Control 6"), + ("ctrl_07", "Control 7"), + ("ctrl_08", "Control 8"), + ("ctrl_09", "Control 9"), + ("ctrl_10", "Control 10"), + ("ctrl_11", "Control 11"), + ("ctrl_12", "Control 12"), + ], +} + +TROUBLESHOOTING = """ +If this program does not see your controller or inputs do not register: + + • USB: unplug and replug; try a different port (USB 2.0 often best) and a + data-capable cable (many cables are charge-only). + • Bluetooth: pair and connect the controller in **Windows Settings / macOS + System Settings / Linux BlueZ** first, then run this script. Put the pad in + pairing mode if it won’t connect. Stay within range; low battery can drop input. + • If Bluetooth is flaky, try **USB** for this capture (same mapping is still useful). + • Close Steam (Steam Input can remap or hide raw gamepad input). In Steam: + Settings → Controller → disable Steam Input for the gamepad, or exit Steam. + • On Windows: check Device Manager — controller should appear under + "Human Interface Devices", "Bluetooth", or "Xbox peripherals" without a yellow + warning. Update or reinstall the vendor driver if needed. + • On Linux: your user may need access to /dev/input/js* and event nodes. + Install `steam-devices` or add a udev rule; try: `sudo chmod a+r /dev/input/*` + temporarily to test (not a permanent fix). + • Multi-mode pads (8BitDo, etc.): switch to DInput, XInput, or Switch mode + per the manual — use the mode that matches how OGX-Mini will see the pad. + • Run this script from a normal terminal with the gamepad connected before start. + • If nothing helps: note your OS version, controller model, USB vs Bluetooth, + and how it appears in Device Manager / System Information / `lsusb`, and send + that with your mapping file. +""" + + +def print_troubleshooting() -> None: + print(TROUBLESHOOTING) + + +# --------------------------------------------------------------------------- +# USB VID:PID (Linux sysfs) +# --------------------------------------------------------------------------- + + +def try_linux_connection_guess(js_index: int) -> str: + """Best-effort: whether the js device path looks USB- or Bluetooth-attached.""" + try: + path = os.path.realpath(f"/sys/class/input/js{js_index}/device") + except OSError: + return "unknown" + segments = [s.lower() for s in path.split(os.sep)] + if "bluetooth" in segments: + return "bluetooth" + for seg in segments: + if len(seg) >= 4 and seg.startswith("usb") and seg[3:].isdigit(): + return "usb" + if "/usb" in path.replace("\\", "/").lower(): + return "usb" + return "unknown" + + +def try_linux_vid_pid_for_js(js_index: int) -> tuple[str | None, str | None, str | None]: + """Walk sysfs from /sys/class/input/jsN to find idVendor/idProduct.""" + base = f"/sys/class/input/js{js_index}/device" + if not os.path.isdir(base): + return None, None, None + path = os.path.realpath(base) + for _ in range(12): + vid_p = os.path.join(path, "idVendor") + pid_p = os.path.join(path, "idProduct") + if os.path.isfile(vid_p) and os.path.isfile(pid_p): + try: + with open(vid_p, encoding="utf-8") as f: + vid = f.read().strip().lower() + with open(pid_p, encoding="utf-8") as f: + pid = f.read().strip().lower() + return vid, pid, path + except OSError: + break + parent = os.path.dirname(path) + if parent == path: + break + path = parent + return None, None, None + + +def print_vid_pid_instructions() -> None: + """Step-by-step VID/PID lookup for the current OS (for HardwareIDs.h).""" + sysname = platform.system() + print( + textwrap.dedent( + """ + Why we need VID and PID + ----------------------- + Maintainers add a line like { VID, PID } in HardwareIDs.h so the + firmware recognizes your controller. The values are **four hex digits + each** (Vendor ID and Product ID), e.g. VID 045e and PID 0b12. + + """ + ).rstrip() + ) + + if sysname == "Windows": + print( + textwrap.dedent( + """ + Windows — find VID & PID + ------------------------ + 1. Right-click **Start** → **Device Manager**. + 2. Find your controller. Try expanding: + • **Human Interface Devices** (many gamepads) + • **Xbox peripherals** (some Microsoft / Xbox pads) + • **Bluetooth** (if you use the controller wirelessly) + 3. Right-click the device → **Properties**. + 4. Open the **Details** tab. + 5. In **Property**, choose **Hardware Ids** (or **Device instance path**). + 6. In the list, look for a line containing **VID_xxxx** and **PID_yyyy** + (example: `USB\\VID_045E&PID_0B12` or `HID\\VID_045E&PID_0B12`). + 7. Copy **xxxx** as the VID and **yyyy** as the PID (hex, no 0x prefix + needed when you type them below). + + Tip: If you see multiple lines, prefer the one that matches **USB** or + **HID** for the gamepad you are holding. + + """ + ).rstrip() + ) + elif sysname == "Darwin": + print( + textwrap.dedent( + """ + macOS — find VID & PID + ---------------------- + **Option A — System Information** + 1. Hold **Option** → click the Apple menu → **System Information**. + 2. Under **Hardware**, click **USB** (wired) or **Bluetooth** (wireless). + 3. Select your controller in the list. + 4. Look for **Vendor ID** and **Product ID** (often shown in hex). + + **Option B — Terminal (works for many devices)** + • USB: open **Terminal** and run: + system_profiler SPUSBDataType + Scroll to your controller and note **Vendor ID** and **Product ID**. + • Bluetooth: run: + system_profiler SPBluetoothDataType + Find your device; note vendor/product if listed. + + Use the hex values (you may see 0x054C — type **054c** for VID below). + + """ + ).rstrip() + ) + else: + # Linux and other Unix-like + print( + textwrap.dedent( + """ + Linux — find VID & PID + ---------------------- + **USB controller** + 1. Plug the controller in, then in a terminal run: + lsusb + 2. Find the line for your device (name on the right). The form is: + Bus 001 Device 012: ID **1234:5678** Vendor Name + Here **1234** is the VID and **5678** is the PID (hex). + + **Bluetooth controller** + 1. Pair and connect the controller first. + 2. Try: + lsusb + Some adapters show the pad here. If not, try: + bluetoothctl devices + (VID/PID may still appear in **udev** for the input device.) + 3. With the controller connected, replace **0** with your joystick index + if needed (often **js0**): + udevadm info -q property -n /dev/input/js0 | grep -E 'ID_VENDOR_ID|ID_MODEL_ID' + You should see **ID_VENDOR_ID**= and **ID_MODEL_ID**= in hex (0x prefix OK). + + If this script auto-detected VID/PID on Linux, you can still verify with + the commands above. + + """ + ).rstrip() + ) + + +# --------------------------------------------------------------------------- +# Pygame capture +# --------------------------------------------------------------------------- + + +@dataclass +class CaptureState: + """User-provided retail name plus SDL-reported identity for maintainer tracking.""" + + platform: str + controller_full_name: str + pygame_name: str + pygame_guid: str + num_axes: int + num_buttons: int + num_hats: int + os_name: str + vid: str | None = None + pid: str | None = None + vid_pid_source: str = "unknown" + connection_guess: str | None = None # "usb" | "bluetooth" | "unknown" (Linux); None if N/A + bindings: dict[str, Any] = field(default_factory=dict) + baseline_axes: list[float] = field(default_factory=list) + notes: str = "" + skipped: list[str] = field(default_factory=list) + # Result of Switch 2–family USB bulk init (PyUSB), if that platform was selected. + switch2_usb_handshake: dict[str, Any] | None = None + # Linux hidraw: per-control raw input report hex (baseline vs active, xor) for firmware decode. + raw_hid_reports: dict[str, Any] | None = None + # Linux: raw hidraw bytes sampled right after pygame saw each control (no idle guessing). + hidraw_gated_by_sdl: dict[str, Any] | None = None + # Whether controller_full_name was typed by the user, SDL, or Linux hidraw HID_NAME. + controller_full_name_source: str = "user_entered" # "user_entered" | "sdl" | "hidraw" + # "full" = SDL capture (optional raw phase); "raw_hid_only" = --raw-hid-only (Linux). + capture_mode: str = "full" + + +def sanitize_filename_stem(name: str, max_len: int = 80) -> str: + """Make a single path component from a controller name (no dirs).""" + s = name.strip() + for c in '<>:"/\\|?\x00-\x1f': + s = s.replace(c, "_") + s = re.sub(r"\s+", "_", s) + s = re.sub(r"_+", "_", s).strip("._ ") + return (s or "controller")[:max_len] + + +def default_report_filename(st: CaptureState) -> str: + """Suggested report path under cwd: _.txt""" + stem = sanitize_filename_stem(st.controller_full_name) + ts = datetime.now().strftime("%Y%m%d_%H%M%S") + return f"{stem}_{ts}.txt" + + +def init_pygame() -> None: + os.environ.setdefault("SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", "1") + import pygame + + pygame.init() + pygame.joystick.init() + + +def poll_joystick_state(joy) -> tuple[list[float], list[int], list[tuple[int, int]]]: + import pygame + + axes = [float(joy.get_axis(i)) for i in range(joy.get_numaxes())] + buttons = [joy.get_button(i) for i in range(joy.get_numbuttons())] + hats = [] + for i in range(joy.get_numhats()): + hats.append(joy.get_hat(i)) + return axes, buttons, hats + + +def wait_for_quiet(joy, settle_s: float = 0.35) -> tuple[list[float], list[int], list[tuple[int, int]]]: + """Read stable resting state.""" + import pygame + + last: tuple | None = None + stable_since: float | None = None + while True: + pygame.event.pump() + state = poll_joystick_state(joy) + if last is not None and state == last: + if stable_since is None: + stable_since = time.monotonic() + elif time.monotonic() - stable_since >= settle_s: + return state + else: + stable_since = None + last = state + time.sleep(0.02) + + +def rebaseline_for_capture(joy) -> tuple[list[float], list[int], list[tuple[int, int]]]: + """ + Clear pygame's queue and sample a new neutral pose before listening for the + *next* control. Without this, a held button or deflected stick from the + previous step immediately matches the next prompt (false 'auto' capture). + """ + import pygame + + pygame.event.clear() + return wait_for_quiet(joy) + + +def _joy_event_matches(event, joy) -> bool: + """Pygame 2 uses instance_id on events; older code used joy index.""" + if hasattr(event, "instance_id"): + try: + return int(event.instance_id) == int(joy.get_instance_id()) + except (AttributeError, TypeError): + pass + return getattr(event, "joy", None) == joy.get_id() + + +def capture_next_input( + joy, + baseline_axes: list[float], + baseline_buttons: list[int], + baseline_hats: list[tuple[int, int]], + timeout_s: float = 45.0, + axis_threshold: float = 0.45, +) -> tuple[str, dict[str, Any]] | tuple[None, None]: + """ + Block until a new button, hat, or significant axis change vs baseline. + Returns (kind, detail_dict). + """ + import pygame + + from pygame import JOYBUTTONDOWN, JOYHATMOTION, JOYAXISMOTION, QUIT + + pygame.event.clear() + + start = time.monotonic() + while time.monotonic() - start < timeout_s: + for event in pygame.event.get(): + if event.type == QUIT: + return None, None + if event.type == JOYBUTTONDOWN and _joy_event_matches(event, joy): + bi = event.button + if bi < len(baseline_buttons) and baseline_buttons[bi]: + continue + return "button", {"button": bi} + if event.type == JOYHATMOTION and _joy_event_matches(event, joy): + if event.value != (0, 0): + return "hat", {"hat": event.hat, "value": list(event.value)} + if event.type == JOYAXISMOTION and _joy_event_matches(event, joy): + ax = event.axis + val = event.value + if ax < len(baseline_axes) and abs(val - baseline_axes[ax]) >= axis_threshold: + return "axis", {"axis": ax, "value": val, "delta_vs_baseline": val - baseline_axes[ax]} + + pygame.event.pump() + axes, buttons, hats = poll_joystick_state(joy) + # Polling fallback for buttons not seen as events on some drivers + for bi, b in enumerate(buttons): + if bi < len(baseline_buttons) and b and not baseline_buttons[bi]: + return "button", {"button": bi} + for hi, h in enumerate(hats): + if hi < len(baseline_hats) and h != baseline_hats[hi] and h != (0, 0): + return "hat", {"hat": hi, "value": list(h)} + for ai, val in enumerate(axes): + if ai < len(baseline_axes) and abs(val - baseline_axes[ai]) >= axis_threshold: + return "axis", {"axis": ai, "value": val, "delta_vs_baseline": val - baseline_axes[ai]} + time.sleep(0.01) + + return None, None + + +def choose_platform() -> str: + names = list(PLATFORM_CONTROLS.keys()) + print("\nSelect the platform / layout this physical controller is meant for:\n") + for i, n in enumerate(names, 1): + print(f" {i}. {n}") + while True: + raw = input("\nEnter number (or 'q' to quit): ").strip().lower() + if raw == "q": + sys.exit(0) + try: + idx = int(raw) + if 1 <= idx <= len(names): + return names[idx - 1] + except ValueError: + pass + print("Invalid choice.") + + +def choose_joystick(): + import pygame + + n = pygame.joystick.get_count() + if n == 0: + print("\nNo joysticks detected. Connect a controller and try again.\n") + print_troubleshooting() + sys.exit(1) + print( + "\nConnected controllers (USB **or** Bluetooth — pair BT devices in the OS first):\n" + ) + for i in range(n): + j = pygame.joystick.Joystick(i) + j.init() + print(f" {i}. {j.get_name()}") + j.quit() + while True: + raw = input("\nEnter index of the controller to capture (or 'q'): ").strip().lower() + if raw == "q": + sys.exit(0) + try: + idx = int(raw) + if 0 <= idx < n: + joy = pygame.joystick.Joystick(idx) + joy.init() + return joy, idx + except ValueError: + pass + print("Invalid index.") + + +def prompt_controller_full_name( + sdl_reported_name: str, + *, + use_sdl_only: bool = False, +) -> tuple[str, str]: + """ + Ask for the full retail / marketing name, or use SDL's name. + + Returns (controller_full_name, source) where source is 'user_entered' or 'sdl'. + """ + header = "\n" + "=" * 72 + "\nController identity\n" + "=" * 72 + "\n\n" + + if use_sdl_only: + print( + header + + "Using **SDL-reported name** as the controller full name (`--use-sdl-name`):\n " + f"{sdl_reported_name!r}\n" + ) + return sdl_reported_name, "sdl" + + print( + header + + "Enter the **full product name** of this controller " + "(as printed on the box, manual, or the manufacturer’s website).\n\n" + f"Your PC / SDL currently reports this device as:\n {sdl_reported_name!r}\n\n" + "**Press Enter** to use that SDL name as-is (optional shortcut).\n\n" + "Examples if you prefer to type a retail name: “Sony DualSense Wireless Controller”, " + "“PowerA Enhanced Wired Controller for Xbox Series X|S”, " + "“8BitDo Pro 2”.\n" + ) + name = input("Full controller name (Enter = use SDL name): ").strip() + if name: + return name, "user_entered" + return sdl_reported_name, "sdl" + + +def prompt_vid_pid_with_instructions(st: CaptureState) -> None: + """ + Show OS-specific VID/PID instructions, then optional manual entry or override. + Updates st.vid, st.pid, st.vid_pid_source in place. + """ + had_auto = bool(st.vid and st.pid) + + print("\n" + "=" * 72) + print("USB Vendor ID (VID) and Product ID (PID)") + print("=" * 72 + "\n") + + print_vid_pid_instructions() + + if had_auto: + print( + f"\n>>> This session already detected: VID: {st.vid} PID: {st.pid}\n" + f" Source: {st.vid_pid_source}\n" + "\n Leave the next two lines **empty** to keep these values in the report,\n" + " or type new hex values if you verified different ones using the steps above.\n" + ) + else: + print( + "\nEnter the **VID** and **PID** you found (hex digits only, no 0x prefix required).\n" + "Leave both **empty** to skip — the report will still help, but adding VID/PID\n" + "makes it much easier to add your controller to the firmware list.\n" + ) + + v = input("VID (hex, or Enter to " + ("keep auto-detected" if had_auto else "skip") + "): ").strip().lower().replace("0x", "") + p = input("PID (hex, or Enter to " + ("keep auto-detected" if had_auto else "skip") + "): ").strip().lower().replace("0x", "") + + if v and p: + st.vid, st.pid = v, p + st.vid_pid_source = "user entered" + elif v or p: + print("\nNeed **both** VID and PID, or leave **both** blank. Keeping previous values.\n") + elif not had_auto: + # leave st.vid/st.pid as None + pass + # else: had_auto and blank input — keep sysfs values already in st + + +def run_capture_loop( + joy, + platform_name: str, + js_index: int, + *, + switch2_usb_handshake: dict[str, Any] | None = None, + use_sdl_name: bool = False, + enable_hidraw_sidecar: bool = True, +) -> CaptureState: + import pygame + + name = joy.get_name() + controller_full_name, name_src = prompt_controller_full_name(name, use_sdl_only=use_sdl_name) + guid = joy.get_guid() + na = joy.get_numaxes() + nb = joy.get_numbuttons() + nh = joy.get_numhats() + + st = CaptureState( + platform=platform_name, + controller_full_name=controller_full_name, + controller_full_name_source=name_src, + pygame_name=name, + pygame_guid=guid, + num_axes=na, + num_buttons=nb, + num_hats=nh, + os_name=f"{platform.system()} {platform.release()}", + switch2_usb_handshake=switch2_usb_handshake, + ) + + if platform.system() == "Linux": + st.connection_guess = try_linux_connection_guess(js_index) + vid, pid, sysfs = try_linux_vid_pid_for_js(js_index) + if vid and pid: + st.vid, st.pid = vid, pid + st.vid_pid_source = f"linux sysfs ({sysfs})" + else: + st.vid_pid_source = "not found in sysfs — use instructions at end" + elif platform.system() == "Windows": + st.vid_pid_source = "not auto-detected — use instructions at end" + else: + st.vid_pid_source = "not auto-detected — use instructions at end" + + controls = PLATFORM_CONTROLS[platform_name] + + hidraw_fd: int | None = None + hidraw_path: str | None = None + if ( + enable_hidraw_sidecar + and platform.system() == "Linux" + and st.vid + and st.pid + ): + try: + vid_i, pid_i = int(st.vid, 16), int(st.pid, 16) + except ValueError: + vid_i = pid_i = -1 + if vid_i >= 0: + from raw_hid_capture import try_open_hidraw_for_sidecar + + side_ans = input( + "\nRecord **raw HID bytes** from hidraw when **pygame** sees each press " + "(recommended on Linux — avoids false captures from IMU/timer noise)? [Y/n]: " + ).strip().lower() + if side_ans in ("", "y", "yes"): + hidraw_fd, hidraw_path = try_open_hidraw_for_sidecar(vid_i, pid_i) + + print( + "\n" + + "=" * 72 + + "\nFor each prompt, press or move ONLY that control.\n" + "After each capture, return sticks to center and release all buttons — the\n" + "script waits for neutral before the next step (avoids false inputs).\n" + "Type 's' + Enter to skip a control, 'r' + Enter to re-capture the previous,\n" + "'t' + Enter to print troubleshooting tips, 'q' + Enter to quit.\n" + + "=" * 72 + + "\n" + ) + + print("Release all buttons and sticks to neutral. Calibrating rest position...") + pygame.event.clear() + axes, buttons, hats = wait_for_quiet(joy) + st.baseline_axes = axes + baseline_buttons = buttons + baseline_hats = hats + + print(f"Baseline axes (approx): {[round(x, 3) for x in axes]}") + print(f"Buttons: {nb}, Axes: {na}, Hats: {nh}\n") + + prev_binding: tuple[str, Any] | None = None + i = 0 + try: + while i < len(controls): + cid, label = controls[i] + print(f"\n>>> [{i + 1}/{len(controls)}] {label}") + print(" Release all buttons and center the sticks — sampling neutral...") + axes, baseline_buttons, baseline_hats = rebaseline_for_capture(joy) + st.baseline_axes = axes + + baseline_hid: bytes | None = None + if hidraw_fd is not None: + from raw_hid_capture import peek_latest_hidraw + + baseline_hid = peek_latest_hidraw(hidraw_fd, 0.08) + + print(" Press or move ONLY the control named above.") + print(" Waiting for input... ", end="", flush=True) + kind, detail = capture_next_input(joy, st.baseline_axes, baseline_buttons, baseline_hats) + if kind is None: + print("\n\nNo input detected for a long time.\n") + print_troubleshooting() + ans = input("\nTry again this step? [Y/n/s=skip]: ").strip().lower() + if ans == "s": + st.skipped.append(cid) + i += 1 + continue + if ans == "n": + break + print("Release all controls to neutral (re-calibrating)...") + pygame.event.clear() + axes, buttons, hats = wait_for_quiet(joy) + st.baseline_axes = axes + baseline_buttons = buttons + baseline_hats = hats + continue + + print(f"captured: {kind} {detail}") + binding: dict[str, Any] = {"type": kind, **detail} + if hidraw_fd is not None: + from raw_hid_capture import peek_latest_hidraw, xor_hex_reports + + active_hid = peek_latest_hidraw(hidraw_fd, 0.12) + if baseline_hid and active_hid and baseline_hid == active_hid: + time.sleep(0.03) + active_hid = peek_latest_hidraw(hidraw_fd, 0.18) + if baseline_hid is not None and active_hid is not None: + binding["hidraw_baseline_hex"] = baseline_hid.hex() + binding["hidraw_active_hex"] = active_hid.hex() + xor_s = xor_hex_reports(baseline_hid, active_hid) + binding["hidraw_xor_hex"] = xor_s + binding["hidraw_baseline_len"] = len(baseline_hid) + binding["hidraw_active_len"] = len(active_hid) + print( + "\n [hidraw] Full baseline packet " + f"(len={len(baseline_hid)}):\n " + + _wrap_hex_lines(baseline_hid.hex()).replace("\n", "\n ") + + "\n [hidraw] Full active packet " + f"(len={len(active_hid)}):\n " + + _wrap_hex_lines(active_hid.hex()).replace("\n", "\n ") + + "\n [hidraw] XOR (baseline ⊕ active):\n " + + _wrap_hex_lines(xor_s).replace("\n", "\n ") + ) + else: + binding["hidraw_note"] = "partial (could not read baseline or active packet)" + + st.bindings[cid] = binding + prev_binding = (cid, st.bindings[cid]) + i += 1 + + # Optional command from user after each capture (stdin) + hint = input("Enter=s continue | s=skip | r=redo last | t=tips | q=quit : ").strip().lower() + if hint == "q": + break + if hint == "t": + print_troubleshooting() + elif hint == "s" and i < len(controls): + cid2, _ = controls[i] + st.skipped.append(cid2) + i += 1 + elif hint == "r" and prev_binding is not None: + i -= 1 + del st.bindings[prev_binding[0]] + finally: + if hidraw_fd is not None: + from raw_hid_capture import close_hidraw_fd + + close_hidraw_fd(hidraw_fd) + + if hidraw_path and any("hidraw_active_hex" in v for v in st.bindings.values() if isinstance(v, dict)): + st.hidraw_gated_by_sdl = { + "hidraw_path": hidraw_path, + "method": "Pygame detects input; latest hidraw report read immediately after (baseline after neutral).", + } + elif hidraw_path: + st.hidraw_gated_by_sdl = { + "hidraw_path": hidraw_path, + "method": "hidraw opened but no complete per-control samples (check hidraw_note on bindings).", + } + + extra = input("\nAny extra notes for the developer (optional): ").strip() + if extra: + st.notes = extra + + prompt_vid_pid_with_instructions(st) + + return st + + +def resolve_vid_pid_for_raw_capture(st: CaptureState) -> tuple[int, int] | None: + """VID/PID as integers for hidraw matching (Linux sysfs or Switch 2 handshake).""" + if st.vid and st.pid: + try: + return int(st.vid, 16), int(st.pid, 16) + except ValueError: + pass + h = st.switch2_usb_handshake + if h and h.get("product_id"): + try: + return 0x057E, int(str(h["product_id"]), 16) + except ValueError: + pass + return None + + +def run_raw_hid_only_capture( + platform_name: str, + switch2_handshake: dict[str, Any] | None, +) -> CaptureState: + """ + Linux only: skip pygame; open hidraw by VID/PID and run per-control raw hex capture. + """ + if platform.system() != "Linux": + print("Error: --raw-hid-only requires Linux (/dev/hidraw*).") + sys.exit(1) + + vid: str | None = None + pid: str | None = None + vid_pid_src = "unknown" + + if switch2_handshake and switch2_handshake.get("ok") and switch2_handshake.get("product_id"): + vid = "057e" + pid = str(switch2_handshake["product_id"]).lower().replace("0x", "") + vid_pid_src = "switch2_usb_handshake" + + if not vid or not pid: + print("\nUSB **VID** and **PID** (hex) are required to find the hidraw node.\n") + v = input("VID [Enter = 057e Nintendo]: ").strip().lower().replace("0x", "") + p = input("PID: ").strip().lower().replace("0x", "") + if not p: + print("PID is required for raw-hid-only.") + sys.exit(1) + vid = v or "057e" + pid = p + vid_pid_src = "user entered (raw-hid-only)" + + from raw_hid_capture import try_capture_raw_hid_reports + + raw = try_capture_raw_hid_reports(int(vid, 16), int(pid, 16), PLATFORM_CONTROLS[platform_name]) + label = (raw.get("hid_name") or "").strip() or f"VID_{vid}_PID_{pid}" + + return CaptureState( + platform=platform_name, + controller_full_name=label, + controller_full_name_source="hidraw", + pygame_name="(SDL/pygame not used — raw-hid-only)", + pygame_guid="", + num_axes=0, + num_buttons=0, + num_hats=0, + os_name=f"{platform.system()} {platform.release()}", + vid=vid, + pid=pid, + vid_pid_source=vid_pid_src, + connection_guess="usb", + switch2_usb_handshake=switch2_handshake, + raw_hid_reports=raw, + capture_mode="raw_hid_only", + ) + + +def _wrap_hex_lines(hexstr: str, step: int = 32) -> str: + """Split hex string into lines (default step=32 nibbles = 16 bytes per line).""" + if not hexstr: + return "" + return "\n".join(hexstr[i : i + step] for i in range(0, len(hexstr), step)) + + +def dump_report(st: CaptureState) -> dict[str, Any]: + return { + "schema_version": 9, + "generated_utc": datetime.now(timezone.utc).isoformat(), + "purpose": "OGX-Mini controller support — maintainer mapping capture", + "maintainer_fields": { + "capture_mode": st.capture_mode, + "controller_full_name": st.controller_full_name, + "controller_full_name_source": st.controller_full_name_source, + "connection_guess": st.connection_guess, + "hardware_id": { + "vid_hex": st.vid, + "pid_hex": st.pid, + "vid_pid_source": st.vid_pid_source, + }, + "sdl": { + "name": st.pygame_name, + "guid": st.pygame_guid, + "axes": st.num_axes, + "buttons": st.num_buttons, + "hats": st.num_hats, + }, + "target_platform_label": st.platform, + "bindings": st.bindings, + "baseline_axes": st.baseline_axes, + "skipped_controls": st.skipped, + "user_notes": st.notes, + "host_os": st.os_name, + "switch2_usb_handshake": st.switch2_usb_handshake, + "raw_hid_reports": st.raw_hid_reports, + "hidraw_gated_by_sdl": st.hidraw_gated_by_sdl, + }, + } + + +def render_human_text(st: CaptureState, data: dict[str, Any]) -> str: + lines = [ + "OGX-Mini Controller Mapping Capture", + "===================================", + f"Generated (UTC): {data['generated_utc']}", + f"Host OS: {st.os_name}", + "", + "Controller full name (for tracking supported devices):", + f" {st.controller_full_name}", + " Source: " + + ( + "SDL / OS reported name" + if st.controller_full_name_source == "sdl" + else "Linux hidraw HID_NAME" + if st.controller_full_name_source == "hidraw" + else "user-entered retail name" + ), + "", + "Connection (best guess; Linux sysfs only — USB and Bluetooth both supported):", + f" {st.connection_guess if st.connection_guess is not None else 'not determined (use USB or Bluetooth; both work with this tool)'}", + "", + f"Capture mode: {st.capture_mode}", + f"Target platform (user selected): {st.platform}", + f"SDL joystick name (OS report): {st.pygame_name}", + f"SDL GUID: {st.pygame_guid}", + f"Axes: {st.num_axes} Buttons: {st.num_buttons} Hats: {st.num_hats}", + "", + "USB identifiers (for HardwareIDs.h / driver matching):", + f" VID: {st.vid or '(unknown)'}", + f" PID: {st.pid or '(unknown)'}", + f" Source: {st.vid_pid_source}", + "", + ] + if st.switch2_usb_handshake: + lines.append("Switch 2–family USB bulk handshake (PyUSB, before SDL capture):") + lines.extend(textwrap.indent(json.dumps(st.switch2_usb_handshake, indent=2), " ").splitlines()) + lines.append("") + if st.raw_hid_reports: + lines.append("Raw HID input reports (Linux hidraw — for firmware bit/byte mapping):") + lines.extend(textwrap.indent(json.dumps(st.raw_hid_reports, indent=2), " ").splitlines()) + lines.append("") + if st.hidraw_gated_by_sdl: + lines.append("Raw HID alongside SDL (pygame detected input; hidraw bytes in each binding below):") + lines.extend(textwrap.indent(json.dumps(st.hidraw_gated_by_sdl, indent=2), " ").splitlines()) + lines.append("") + lines.append("Per-control mapping (SDL/pygame indices as seen on this PC):") + if st.capture_mode == "raw_hid_only" and not st.bindings: + lines.append(" (none — raw-hid-only run; see raw JSON above for hex per control)") + else: + for cid, val in sorted(st.bindings.items()): + lines.append(f" {cid}: {val}") + + hidraw_blocks: list[str] = [] + for cid, val in sorted(st.bindings.items()): + if not isinstance(val, dict) or "hidraw_active_hex" not in val: + continue + hidraw_blocks.append(f" [{cid}]") + if "hidraw_baseline_len" in val: + hidraw_blocks.append(f" baseline_len: {val['hidraw_baseline_len']}") + if "hidraw_active_len" in val: + hidraw_blocks.append(f" active_len: {val['hidraw_active_len']}") + bh = val.get("hidraw_baseline_hex", "") + ah = val.get("hidraw_active_hex", "") + xh = val.get("hidraw_xor_hex", "") + hidraw_blocks.append(" baseline_hex:") + for ln in _wrap_hex_lines(bh).splitlines() or [""]: + hidraw_blocks.append(f" {ln}") + hidraw_blocks.append(" active_hex:") + for ln in _wrap_hex_lines(ah).splitlines() or [""]: + hidraw_blocks.append(f" {ln}") + hidraw_blocks.append(" xor_hex:") + for ln in _wrap_hex_lines(xh).splitlines() or [""]: + hidraw_blocks.append(f" {ln}") + hidraw_blocks.append("") + if hidraw_blocks: + lines.append("") + lines.append("Full hidraw packets (per control — same data as JSON bindings; 16 bytes per line):") + lines.extend(hidraw_blocks) + if st.skipped: + lines.append("") + lines.append("Skipped:") + for s in st.skipped: + lines.append(f" - {s}") + if st.notes: + lines.append("") + lines.append("User notes:") + lines.append(textwrap.indent(st.notes, " ")) + lines.append("") + lines.append("--- JSON (same data, machine-readable) ---") + lines.append(json.dumps(data, indent=2)) + return "\n".join(lines) + + +def main() -> None: + parser = argparse.ArgumentParser(description="Capture gamepad mappings for OGX-Mini support.") + parser.add_argument( + "-o", + "--output", + help="Write report to this file (UTF-8). If omitted, prompted at end.", + ) + parser.add_argument( + "--skip-raw-hid", + action="store_true", + help="Do not offer the Linux hidraw raw report capture phase (SDL/VID capture only).", + ) + parser.add_argument( + "--use-sdl-name", + action="store_true", + help="Use the SDL joystick name as controller_full_name (skip typing a retail name).", + ) + parser.add_argument( + "--auto-output-name", + action="store_true", + help="Save the report as _.txt without asking (ignored if -o is set).", + ) + parser.add_argument( + "--raw-hid-only", + action="store_true", + help="Linux only: skip SDL/pygame mapping; only run hidraw raw hex capture (use with Switch 2 USB handshake platform as needed).", + ) + parser.add_argument( + "--no-hidraw-sidecar", + action="store_true", + help="Do not offer hidraw sampling alongside pygame (Linux).", + ) + args = parser.parse_args() + + if args.raw_hid_only and args.skip_raw_hid: + parser.error("--raw-hid-only and --skip-raw-hid cannot be used together.") + + if args.raw_hid_only: + print( + textwrap.dedent( + """ + OGX-Mini — Raw HID capture only (Linux hidraw) + ----------------------------------------------- + Skips SDL/pygame. You map each control against **raw report bytes** only. + Pick the same **platform layout** as your controller so prompts match. + For Switch 2 USB, choose the Switch 2 platform so the bulk handshake runs first. + """ + ).strip() + ) + else: + print( + textwrap.dedent( + """ + OGX-Mini — Controller mapping capture + ------------------------------------- + This tool records how your PC sees each stick, button, and trigger + (via SDL/pygame). Use a **USB** cable **or** **Bluetooth** — if the + controller shows up in the list below, you can capture it. + Upload the saved file when requesting support for a new controller + in OGX-Mini. + """ + ).strip() + ) + + platform_name = choose_platform() + switch2_handshake: dict[str, Any] | None = None + if platform_requires_switch2_usb_init(platform_name): + print( + textwrap.dedent( + """ + + ------------------------------------------------------------------ + Switch 2 Pro / Joy-Con 2 (USB) — USB bulk handshake + ------------------------------------------------------------------ + These controllers often do **not** appear in SDL until a host sends + Nintendo's USB vendor sequence on **interface 1** (same idea as + HandHeldLegend's ProCon 2 Enabler in Chrome). + + • Install: pip install pyusb + • Linux: needs **libusb**; you may need **udev** rules or run + briefly with sudo if access to the device is denied. + • Windows: interface 1 may need **WinUSB** (e.g. Zadig) — YMMV. + • Use a **data** USB cable; plug the controller in **before** Enter. + + """ + ).rstrip() + ) + input("Press Enter when the controller is connected over USB… ") + switch2_handshake = run_switch2_usb_handshake() + print(switch2_handshake.get("message", "")) + if not switch2_handshake.get("ok"): + if args.raw_hid_only: + print( + "\nHandshake did not complete. You can still enter VID/PID manually for hidraw " + "(e.g. PID 2069 for Pro Controller 2).\n" + ) + else: + cont = input("Handshake failed. Try SDL capture anyway? [y/N]: ").strip().lower() + if cont not in ("y", "yes"): + print("Exiting.") + return + time.sleep(0.8) + + if args.raw_hid_only: + st = run_raw_hid_only_capture(platform_name, switch2_handshake) + else: + init_pygame() + joy, js_index = choose_joystick() + + try: + st = run_capture_loop( + joy, + platform_name, + js_index, + switch2_usb_handshake=switch2_handshake, + use_sdl_name=args.use_sdl_name, + enable_hidraw_sidecar=not args.no_hidraw_sidecar, + ) + finally: + joy.quit() + import pygame + + pygame.quit() + + # Optional second phase: full raw HID report bytes (Linux hidraw) for maintainers. + if ( + not args.raw_hid_only + and not args.skip_raw_hid + and platform.system() == "Linux" + and st.raw_hid_reports is None + ): + pair = resolve_vid_pid_for_raw_capture(st) + if pair is not None: + vid_i, pid_i = pair + has_sdl_hidraw = any( + isinstance(v, dict) and "hidraw_active_hex" in v for v in st.bindings.values() + ) + if has_sdl_hidraw: + ans = ( + input( + "\nThis report already has **raw hidraw hex** on each binding (SDL detected the press).\n" + "Run the **extra** interactive hidraw walkthrough too (idle-based)? Usually **not** needed. [y/N]: " + ) + .strip() + .lower() + ) + do_walkthrough = ans in ("y", "yes") + else: + ans = ( + input( + "\nAlso capture **raw HID** in the **interactive hidraw-only** walkthrough?\n" + "(Enable **SDL+hidraw** sidecar next time to avoid this — pygame gates each sample.) [Y/n]: " + ) + .strip() + .lower() + ) + do_walkthrough = ans in ("", "y", "yes") + if do_walkthrough: + from raw_hid_capture import try_capture_raw_hid_reports + + st.raw_hid_reports = try_capture_raw_hid_reports( + vid_i, pid_i, PLATFORM_CONTROLS[platform_name] + ) + if not st.raw_hid_reports.get("ok"): + print(st.raw_hid_reports.get("message", "Raw hidraw capture did not complete.")) + else: + print( + "\n(Skip raw hidraw: no VID/PID in report — fill VID/PID at end of capture next time, " + "or use Switch 2 USB handshake so product_id is known.)" + ) + + data = dump_report(st) + text = render_human_text(st, data) + + out_path = args.output + if not out_path: + suggested = default_report_filename(st) + if args.auto_output_name: + out_path = suggested + else: + ans = input("\nSave report to file? [Y/n]: ").strip().lower() + if ans in ("", "y", "yes"): + path = input(f"Filename [{suggested}]: ").strip() or suggested + out_path = path + + if out_path: + with open(out_path, "w", encoding="utf-8") as f: + f.write(text) + print(f"\nWrote: {out_path}\n") + else: + print("\n--- Report ---\n") + print(text) + + print("Thank you. Attach the file to your issue or send it to the maintainer.") + + +if __name__ == "__main__": + main() diff --git a/Tools/controller_capture/hidraw_full_report_dump.py b/Tools/controller_capture/hidraw_full_report_dump.py new file mode 100644 index 00000000..cab89f1b --- /dev/null +++ b/Tools/controller_capture/hidraw_full_report_dump.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +""" +Stream every full HID input report from Linux hidraw as hex (one line per read). + +Use this to see **which byte indices** change when you hold one button vs idle, without +going through the interactive per-control capture. Helps separate: + - stable button bits (good for firmware) + - byte 1 (timer) and IMU tail bytes that move every frame (bad to match naïvely) + +Examples: + python3 hidraw_full_report_dump.py --vid 057e --pid 2069 + python3 hidraw_full_report_dump.py --path /dev/hidraw4 --diff + python3 hidraw_full_report_dump.py --vid 057e --pid 2069 --diff-core --max 500 + +Requires: Linux, read access on /dev/hidraw* (plugdev/udev). +""" + +from __future__ import annotations + +import argparse +import os +import select +import sys +import time + +from raw_hid_capture import _idle_compare_key, choose_hidraw_device, list_hidraw_nodes_for_vid_pid + + +def _open_nonblock(path: str) -> int: + return os.open(path, os.O_RDONLY | os.O_NONBLOCK) + + +def _drain_one_report(fd: int, bufsize: int = 512) -> bytes | None: + r, _, _ = select.select([fd], [], [], 0.25) + if not r: + return None + try: + return os.read(fd, bufsize) + except BlockingIOError: + return None + + +def main() -> int: + ap = argparse.ArgumentParser(description="Dump full hidraw input reports as hex (Linux).") + ap.add_argument("--vid", help="USB VID hex, e.g. 057e") + ap.add_argument("--pid", help="USB PID hex, e.g. 2069") + ap.add_argument("--path", help="Explicit hidraw device (skips VID/PID lookup)") + ap.add_argument( + "--diff", + action="store_true", + help="Only print lines when the full report differs from the previous printed line.", + ) + ap.add_argument( + "--diff-core", + action="store_true", + help="Only print when Nintendo-style core key (bytes 2:12, stick LSBs masked) changes. " + "Useful to ignore pure IMU tail jitter while still seeing button/stick-core changes.", + ) + ap.add_argument("--max", type=int, default=0, metavar="N", help="Stop after N printed lines (0 = unlimited)") + ap.add_argument("--count", action="store_true", help="Prefix each line with a monotonic line number") + args = ap.parse_args() + + if sys.platform != "linux" and not sys.platform.startswith("linux"): + print("This tool only runs on Linux (hidraw).", file=sys.stderr) + return 1 + + path: str | None = args.path + if not path: + if not args.vid or not args.pid: + print("Provide --path or both --vid and --pid.", file=sys.stderr) + return 1 + try: + vid = int(args.vid, 16) + pid = int(args.pid, 16) + except ValueError: + print("Invalid --vid or --pid (use hex, e.g. 057e).", file=sys.stderr) + return 1 + candidates = list_hidraw_nodes_for_vid_pid(vid, pid) + if not candidates: + print(f"No hidraw node for VID {vid:04x} PID {pid:04x}.", file=sys.stderr) + return 1 + chosen = candidates[0] if len(candidates) == 1 else choose_hidraw_device(candidates) + if chosen is None: + return 1 + path = chosen["path"] + print(f"# {chosen.get('hid_name', '')} {path} {chosen.get('hid_id', '')}", flush=True) + + assert path is not None + try: + fd = _open_nonblock(path) + except OSError as e: + print(f"Open {path}: {e}", file=sys.stderr) + return 1 + + print( + "# byte indices (hex): " + " ".join(f"{i:02x}" for i in range(16)), + "\n# " + " ".join(f"{i:02x}" for i in range(16, 32)), + "\n# Ctrl+C to stop.\n", + sep="", + flush=True, + ) + + prev_full: bytes | None = None + prev_key: bytes | None = None + n_printed = 0 + line_no = 0 + try: + while args.max <= 0 or n_printed < args.max: + pkt = _drain_one_report(fd) + if pkt is None: + continue + + if args.diff_core: + key = _idle_compare_key(pkt) + if prev_key is not None and key == prev_key: + continue + prev_key = key + elif args.diff: + if prev_full is not None and pkt == prev_full: + continue + prev_full = pkt + else: + prev_full = pkt + + line_no += 1 + h = pkt.hex() + prefix = f"{line_no:6d} " if args.count else "" + print(f"{prefix}len={len(pkt):3d} {h}", flush=True) + n_printed += 1 + except KeyboardInterrupt: + print("\n# stopped", flush=True) + finally: + os.close(fd) + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/Tools/controller_capture/raw_hid_capture.py b/Tools/controller_capture/raw_hid_capture.py new file mode 100644 index 00000000..bbe0f652 --- /dev/null +++ b/Tools/controller_capture/raw_hid_capture.py @@ -0,0 +1,458 @@ +#!/usr/bin/env python3 +""" +Read raw HID input reports from Linux hidraw nodes (by USB VID/PID). + +Used by controller_capture.py so maintainers get **actual report bytes** (hex), +not only SDL button/axis indices — needed to match SwitchPro-style packed layouts +in firmware. +""" + +from __future__ import annotations + +import glob +import os +import select +import sys +import time +from typing import Any + + +def _parse_uevent(content: str) -> dict[str, str]: + out: dict[str, str] = {} + for line in content.splitlines(): + if "=" in line: + k, v = line.split("=", 1) + out[k.strip()] = v.strip() + return out + + +def list_hidraw_nodes_for_vid_pid(vid: int, pid: int) -> list[dict[str, Any]]: + """Return hidraw device paths whose HID_ID matches vid:pid (USB HID).""" + found: list[dict[str, Any]] = [] + for hidraw_dir in sorted(glob.glob("/sys/class/hidraw/hidraw*")): + uevent_path = os.path.join(hidraw_dir, "device", "uevent") + if not os.path.isfile(uevent_path): + continue + try: + with open(uevent_path, encoding="utf-8") as f: + props = _parse_uevent(f.read()) + except OSError: + continue + hid_id = props.get("HID_ID") + if not hid_id: + continue + parts = hid_id.split(":") + if len(parts) != 3: + continue + try: + _bus, v_s, p_s = parts + v = int(v_s, 16) + p = int(p_s, 16) + except ValueError: + continue + if v != vid or p != pid: + continue + name = os.path.basename(hidraw_dir) + found.append( + { + "path": f"/dev/{name}", + "hid_name": props.get("HID_NAME", ""), + "hid_id": hid_id, + "sysfs": hidraw_dir, + } + ) + return found + + +def _open_hidraw_nonblock(path: str) -> int: + return os.open(path, os.O_RDONLY | os.O_NONBLOCK) + + +def _read_latest_packet(fd: int, timeout_s: float, bufsize: int = 512) -> bytes | None: + """Drain readable data within timeout; return last chunk read (one report per read typical).""" + deadline = time.monotonic() + timeout_s + last: bytes | None = None + while time.monotonic() < deadline: + r, _, _ = select.select([fd], [], [], min(0.08, max(0.0, deadline - time.monotonic()))) + if not r: + continue + try: + while True: + chunk = os.read(fd, bufsize) + if not chunk: + break + last = chunk + except BlockingIOError: + break + return last + + +# Pro / Switch 2 style full input: byte0 report ID, byte1 timer/counter, then 10-byte +# SwitchPro::InReport (battery + 3 button bytes + 6 stick bytes). IMU follows in tail. +_NINTENDO_FULL_INPUT_IDS = frozenset({0x30, 0x09, 0x31}) + + +def _nintendo_gamepad_core_key(pkt: bytes) -> bytes: + """10 bytes at offset 2; relax stick packing bytes (indices 4..9) for idle match.""" + core = bytearray(pkt[2:12]) + if len(core) >= 10: + for i in range(4, 10): + core[i] &= 0xFC # stronger than 0xFE — Switch 2 sticks often jitter 1–2 LSBs + return bytes(core) + + +def _idle_compare_key(pkt: bytes) -> bytes: + """ + Bytes that should stay fixed at neutral. Full 64-byte reports include a + per-frame timer (byte 1) and IMU tail — never compare the whole packet. + + Switch 2 Pro often uses report ID **0x09** (not 0x30); layout matches the same core. + """ + if len(pkt) >= 12 and pkt[0] in _NINTENDO_FULL_INPUT_IDS: + return _nintendo_gamepad_core_key(pkt) + # Long reports (other vendors): compare head only, drop IMU tail. + if len(pkt) >= 48: + head = bytearray(pkt[:24]) + for i in range(3, min(24, len(head))): + if i >= 6: + head[i] &= 0xFC + return bytes(head) + return pkt + + +def _wait_stable_report( + fd: int, + *, + settle_s: float = 0.22, + overall_timeout_s: float = 45.0, +) -> bytes | None: + """Wait until consecutive samples match on idle-compare key (not full packet).""" + last_pkt: bytes | None = None + last_key: bytes | None = None + stable_since: float | None = None + start = time.monotonic() + packet_count = 0 + last_progress = start + saw_packet = False + + while time.monotonic() - start < overall_timeout_s: + elapsed = time.monotonic() - start + # After input, sticks may take a moment to settle; allow shorter "quiet" window. + effective_settle = settle_s + if elapsed > 8.0: + effective_settle = min(settle_s, 0.14) + if elapsed > 16.0: + effective_settle = min(effective_settle, 0.09) + if elapsed > 24.0: + effective_settle = min(effective_settle, 0.06) + + pkt = _read_latest_packet(fd, timeout_s=0.12) + now = time.monotonic() + + if pkt is None: + if saw_packet and now - last_progress >= 0.6: + print( + "\r … waiting for hidraw data (move a stick slightly if nothing arrives) ", + end="", + flush=True, + ) + last_progress = now + time.sleep(0.02) + continue + + saw_packet = True + packet_count += 1 + key = _idle_compare_key(pkt) + + if now - last_progress >= 0.45: + print( + f"\r … {packet_count} reports, last len={len(pkt)} byte0=0x{pkt[0]:02x} (idle: core bytes 2:12) ", + end="", + flush=True, + ) + last_progress = now + + if last_key is not None and key == last_key: + last_pkt = pkt # keep latest full frame while idle-core is stable + if stable_since is None: + stable_since = now + elif now - stable_since >= effective_settle: + print() # newline after progress + return last_pkt + else: + stable_since = None + last_pkt = pkt + last_key = key + time.sleep(0.008) + + print() + return last_pkt + + +def _wait_changed_report(fd: int, baseline: bytes, timeout_s: float = 60.0) -> bytes | None: + base_key = _idle_compare_key(baseline) + start = time.monotonic() + while time.monotonic() - start < timeout_s: + pkt = _read_latest_packet(fd, timeout_s=0.12) + if pkt is not None and _idle_compare_key(pkt) != base_key: + return pkt + time.sleep(0.008) + return None + + +def _hex(b: bytes) -> str: + return b.hex() + + +def peek_latest_hidraw(fd: int, timeout_s: float = 0.1) -> bytes | None: + """Drain hidraw within timeout; return the last full report read (for SDL-gated sampling).""" + return _read_latest_packet(fd, timeout_s) + + +def xor_hex_reports(a: bytes, b: bytes) -> str: + """Hex string of a XOR b (padded to max length).""" + return _xor_hex(a, b) + + +def _xor_hex(a: bytes, b: bytes) -> str: + n = max(len(a), len(b)) + aa = a.ljust(n, b"\x00") + bb = b.ljust(n, b"\x00") + return bytes(x ^ y for x, y in zip(aa, bb)).hex() + + +def choose_hidraw_device( + candidates: list[dict[str, Any]], + *, + quit_hint: str = "q to skip", +) -> dict[str, Any] | None: + if not candidates: + return None + if len(candidates) == 1: + return candidates[0] + print("\nMultiple hidraw nodes match this VID:PID. Pick the one that is the **gamepad** input:\n") + for i, c in enumerate(candidates, 1): + hn = c.get("hid_name") or "(no HID_NAME)" + print(f" {i}. {c['path']}\n HID_NAME: {hn}\n {c['hid_id']}") + while True: + raw = input(f"\nEnter number (or '{quit_hint}'): ").strip().lower() + if raw == "q": + return None + try: + idx = int(raw) + if 1 <= idx <= len(candidates): + return candidates[idx - 1] + except ValueError: + pass + print("Invalid choice.") + + +def try_open_hidraw_for_sidecar(vid: int, pid: int) -> tuple[int | None, str | None]: + """ + Open one hidraw fd for SDL-gated sampling: pygame decides *when* input happened; + caller peeks this fd right after. + """ + candidates = list_hidraw_nodes_for_vid_pid(vid, pid) + if not candidates: + print( + f"(No /dev/hidraw* for VID {vid:04x} PID {pid:04x} — raw bytes will not be recorded alongside SDL.)" + ) + return None, None + if len(candidates) == 1: + chosen = candidates[0] + else: + print("\nSeveral hidraw nodes match — pick the **gamepad** for raw HID alongside pygame:") + chosen = choose_hidraw_device(candidates, quit_hint="q to skip sidecar") + if chosen is None: + return None, None + path = chosen["path"] + try: + fd = _open_hidraw_nonblock(path) + print( + f"(Opened {path} for raw HID. **Pygame** still decides when you pressed; we only read bytes then.)\n" + ) + return fd, path + except OSError as e: + print(f"(Could not open hidraw for sidecar: {e})") + return None, None + + +def close_hidraw_fd(fd: int | None) -> None: + if fd is not None: + try: + os.close(fd) + except OSError: + pass + + +def try_capture_raw_hid_reports( + vid: int, + pid: int, + controls: list[tuple[str, str]], + *, + hidraw_path: str | None = None, +) -> dict[str, Any]: + """ + Interactive session: for each logical control, capture baseline vs active raw report. + + Returns a dict suitable for JSON under maintainer_fields.raw_hid_reports. + """ + if sys.platform != "linux" and not sys.platform.startswith("linux"): + return { + "ok": False, + "platform": "non-linux", + "message": "Raw hidraw capture is only implemented on Linux. Use Linux for full byte dumps, " + "or attach a USB capture / Wireshark for other OSes.", + } + + candidates = list_hidraw_nodes_for_vid_pid(vid, pid) + if not candidates: + return { + "ok": False, + "platform": "linux_hidraw", + "message": f"No /dev/hidraw* found for VID {vid:04x} PID {pid:04x}. " + "Check lsusb, permissions (plugdev/udev), and that the controller exposes HID.", + "vid_hex": f"{vid:04x}", + "pid_hex": f"{pid:04x}", + } + + chosen = None + if hidraw_path: + for c in candidates: + if c["path"] == hidraw_path: + chosen = c + break + if chosen is None: + return { + "ok": False, + "platform": "linux_hidraw", + "message": f"Given hidraw path {hidraw_path!r} does not match enumerated nodes for this VID:PID.", + "candidates": candidates, + } + else: + chosen = choose_hidraw_device(candidates, quit_hint="q to skip raw capture") + if chosen is None: + return { + "ok": False, + "platform": "linux_hidraw", + "skipped": True, + "message": "User skipped hidraw selection.", + } + + path = chosen["path"] + fd: int | None = None + try: + fd = _open_hidraw_nonblock(path) + except OSError as e: + return { + "ok": False, + "platform": "linux_hidraw", + "path": path, + "message": f"Could not open {path}: {e}. Try udev rules or `sudo` for a one-off test.", + "candidates": candidates, + } + + samples: list[dict[str, Any]] = [] + max_len = 0 + + print( + "\n" + + "=" * 72 + + "\nRaw HID reports (linux hidraw)\n" + + "=" * 72 + + f"\nReading from: {path}\n" + f"HID_NAME: {chosen.get('hid_name', '')}\n\n" + "For each step: return to **neutral** (release buttons, center sticks), then press/move **only**\n" + "the named control. The tool records full report bytes (hex) for firmware maintainers.\n\n" + "Note: Nintendo full reports change every frame (timer + IMU). Idle detection uses bytes **2:12**\n" + "(gamepad core; works for report IDs **0x30** and **Switch 2’s 0x09**). If neutral takes long after a\n" + "button, release fully and center sticks — settle time shortens automatically after ~8s.\n" + "Commands: Enter=continue s=skip control q=quit raw phase\n" + ) + + try: + i = 0 + while i < len(controls): + cid, label = controls[i] + print(f"\n>>> [{i + 1}/{len(controls)}] RAW {label}") + print(" Release everything; center sticks — waiting for stable idle report...") + baseline = _wait_stable_report(fd) + if baseline is None: + print(" No HID data (timeout). Wiggle a stick slightly or press a button once, then release.") + retry = input(" Retry this step? [Y/n/q quit]: ").strip().lower() + if retry == "q": + break + if retry == "n": + samples.append( + { + "control_id": cid, + "label": label, + "error": "timeout waiting for stable baseline", + } + ) + i += 1 + continue + + max_len = max(max_len, len(baseline)) + print(f" Baseline length: {len(baseline)} bytes") + print(" Now press or move ONLY the control above. Waiting for report change...") + active = _wait_changed_report(fd, baseline) + if active is None: + print(" No change seen.") + ans = input(" Retry [Y/n/s skip]: ").strip().lower() + if ans == "q": + break + if ans == "s": + samples.append( + { + "control_id": cid, + "label": label, + "baseline_hex": _hex(baseline), + "skipped": True, + } + ) + i += 1 + continue + + max_len = max(max_len, len(active)) + samples.append( + { + "control_id": cid, + "label": label, + "baseline_hex": _hex(baseline), + "active_hex": _hex(active), + "xor_hex": _xor_hex(baseline, active), + "baseline_len": len(baseline), + "active_len": len(active), + } + ) + print(f" Captured: +{len(active) - len(baseline)} len delta" if len(active) != len(baseline) else " Captured.") + i += 1 + cmd = input("Enter=continue | s=skip next | q=quit raw: ").strip().lower() + if cmd == "q": + break + if cmd == "s" and i < len(controls): + cid2, lab2 = controls[i] + samples.append({"control_id": cid2, "label": lab2, "skipped": True}) + i += 1 + finally: + if fd is not None: + os.close(fd) + + session_ok = bool(samples) + return { + "ok": session_ok, + "platform": "linux_hidraw", + "path": path, + "hid_name": chosen.get("hid_name", ""), + "hid_id": chosen.get("hid_id", ""), + "vid_hex": f"{vid:04x}", + "pid_hex": f"{pid:04x}", + "max_report_len_seen": max_len, + "sample_count": len(samples), + "samples": samples, + "note": "Bytes are as returned by read(2) on hidraw (typically includes report ID as byte 0). " + "Compare xor_hex to map bits/bytes for firmware decode tables. " + "Idle detection uses bytes 2:12 gamepad core (report IDs 0x30 / 0x09 / 0x31), not timer/IMU; " + "stick bytes masked with 0xFC for neutral matching.", + } diff --git a/Tools/controller_capture/requirements.txt b/Tools/controller_capture/requirements.txt new file mode 100644 index 00000000..de9b227a --- /dev/null +++ b/Tools/controller_capture/requirements.txt @@ -0,0 +1,4 @@ +# Controller mapping capture for OGX-Mini maintainers +pygame>=2.5.0 +# Switch 2 Pro / Joy-Con 2 USB bulk handshake (needs system libusb-1.0) +pyusb>=1.2.0 diff --git a/Tools/controller_capture/switch2_usb_init.py b/Tools/controller_capture/switch2_usb_init.py new file mode 100644 index 00000000..1ec533fb --- /dev/null +++ b/Tools/controller_capture/switch2_usb_init.py @@ -0,0 +1,373 @@ +""" +Nintendo Switch 2–family USB bulk handshake for PC capture. + +The Pro Controller 2 (PID 0x2069), Joy-Con 2 L/R (0x2067/0x2066), and related +devices do not stream standard HID gamepad input over USB until the host sends +a vendor protocol on USB interface 1 (bulk OUT), matching the sequence used +by HandHeldLegend's browser tool: + + https://github.com/HandHeldLegend/handheldlegend.github.io + (procon2tool/index.html — "ProCon 2 Enabler Tool") + +After this runs, the OS may expose the pad to SDL/pygame for mapping capture. + +Requires: PyUSB + system libusb (Linux: libusb-1.0; Windows often needs WinUSB via Zadig for the bulk interface). +""" + +from __future__ import annotations + +import time +from typing import Any + +# Nintendo Co., Ltd. +VENDOR_ID = 0x057E + +# Switch 2–era USB IDs (same as HHL dumper / enabler) +PRODUCT_IDS: dict[int, str] = { + 0x2066: "Joy-Con 2 (R)", + 0x2067: "Joy-Con 2 (L)", + 0x2069: "Pro Controller 2", + 0x2073: "NSO GameCube Controller", +} + +USB_CONFIGURATION = 1 +USB_INTERFACE = 1 + +# Packets copied from handheldlegend.github.io procon2tool/index.html (auto sequence on USB connect). +# Placeholder 0xFF bytes in MAC/LTK fields match the reference tool for PC use. + +_INIT_COMMAND_0x03 = bytes( + [ + 0x03, + 0x91, + 0x00, + 0x0D, + 0x00, + 0x08, + 0x00, + 0x00, + 0x01, + 0x00, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + ] +) + +_UNKNOWN_COMMAND_0x07 = bytes([0x07, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]) + +_UNKNOWN_COMMAND_0x16 = bytes([0x16, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]) + +_REQUEST_CONTROLLER_MAC = bytes( + [ + 0x15, + 0x91, + 0x00, + 0x01, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x02, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + ] +) + +_LTK_REQUEST = bytes( + [ + 0x15, + 0x91, + 0x00, + 0x02, + 0x00, + 0x11, + 0x00, + 0x00, + 0x00, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + ] +) + +_UNKNOWN_COMMAND_0x15_ARG_0x03 = bytes([0x15, 0x91, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00]) + +_UNKNOWN_COMMAND_0x09 = bytes( + [ + 0x09, + 0x91, + 0x00, + 0x07, + 0x00, + 0x08, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ] +) + +_IMU_COMMAND_0x02 = bytes([0x0C, 0x91, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00]) + +_OUT_UNKNOWN_COMMAND_0x11 = bytes([0x11, 0x91, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00]) + +_UNKNOWN_COMMAND_0x0A = bytes( + [ + 0x0A, + 0x91, + 0x00, + 0x08, + 0x00, + 0x14, + 0x00, + 0x00, + 0x01, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x35, + 0x00, + 0x46, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ] +) + +_IMU_COMMAND_0x04 = bytes([0x0C, 0x91, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00]) + +_ENABLE_HAPTICS = bytes([0x03, 0x91, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00]) + +_OUT_UNKNOWN_COMMAND_0x10 = bytes([0x10, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]) + +_OUT_UNKNOWN_COMMAND_0x01 = bytes([0x01, 0x91, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00]) + +_OUT_UNKNOWN_COMMAND_0x03 = bytes([0x03, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00]) + +_OUT_UNKNOWN_COMMAND_0x0A_ALT = bytes([0x0A, 0x91, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00]) + +_SET_PLAYER_LED = bytes( + [ + 0x09, + 0x91, + 0x00, + 0x07, + 0x00, + 0x08, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ] +) + +# Same order as HHL connectUsb() automatic sequence (SPI reads omitted there too). +SWITCH2_USB_INIT_PACKETS: list[bytes] = [ + _INIT_COMMAND_0x03, + _UNKNOWN_COMMAND_0x07, + _UNKNOWN_COMMAND_0x16, + _REQUEST_CONTROLLER_MAC, + _LTK_REQUEST, + _UNKNOWN_COMMAND_0x15_ARG_0x03, + _UNKNOWN_COMMAND_0x09, + _IMU_COMMAND_0x02, + _OUT_UNKNOWN_COMMAND_0x11, + _UNKNOWN_COMMAND_0x0A, + _IMU_COMMAND_0x04, + _ENABLE_HAPTICS, + _OUT_UNKNOWN_COMMAND_0x10, + _OUT_UNKNOWN_COMMAND_0x01, + _OUT_UNKNOWN_COMMAND_0x03, + _OUT_UNKNOWN_COMMAND_0x0A_ALT, + _SET_PLAYER_LED, +] + + +def _find_bulk_endpoints(interface) -> tuple[Any, Any]: + import usb.util + + ep_out = None + ep_in = None + for ep in interface: + t = usb.util.endpoint_type(ep.bEndpointAddress) + d = usb.util.endpoint_direction(ep.bEndpointAddress) + if t != usb.util.ENDPOINT_TYPE_BULK: + continue + if d == usb.util.ENDPOINT_OUT: + ep_out = ep + elif d == usb.util.ENDPOINT_IN: + ep_in = ep + return ep_out, ep_in + + +def run_switch2_usb_handshake( + *, + read_timeout_ms: int = 80, + pause_s: float = 0.012, + read_size: int = 64, +) -> dict[str, Any]: + """ + Open the first matching Switch 2–family device, claim interface 1, send init packets. + + Returns a dict with keys: ok (bool), product_id, product_name, message, error (optional). + """ + try: + import usb.core + import usb.util + except ImportError as e: + return { + "ok": False, + "product_id": None, + "product_name": None, + "message": "PyUSB is not installed. Run: pip install pyusb", + "error": str(e), + } + + dev = None + found_pid = None + for pid in PRODUCT_IDS: + dev = usb.core.find(idVendor=VENDOR_ID, idProduct=pid) + if dev is not None: + found_pid = pid + break + + if dev is None: + return { + "ok": False, + "product_id": None, + "product_name": None, + "message": ( + f"No USB device found for VID {VENDOR_ID:04X} and PIDs " + + ", ".join(f"{p:04X}" for p in PRODUCT_IDS) + + ". Plug the controller in with a data cable and try again." + ), + "error": None, + } + + name = PRODUCT_IDS.get(found_pid or 0, "unknown") + out: dict[str, Any] = { + "ok": False, + "product_id": f"{found_pid:04x}" if found_pid is not None else None, + "product_name": name, + "message": "", + "error": None, + } + + detached_kernel = False + try: + try: + if dev.is_kernel_driver_active(USB_INTERFACE): + dev.detach_kernel_driver(USB_INTERFACE) + detached_kernel = True + out["detached_kernel_driver"] = True + else: + out["detached_kernel_driver"] = False + except (NotImplementedError, ValueError, usb.core.USBError): + out["detached_kernel_driver"] = None + + try: + dev.set_configuration() + except usb.core.USBError: + pass # already configured + + cfg = dev.get_active_configuration() + intf = cfg[(USB_INTERFACE, 0)] + ep_out, ep_in = _find_bulk_endpoints(intf) + + if ep_out is None: + out["message"] = "No bulk OUT endpoint on interface 1 — wrong device or driver?" + out["error"] = "missing_bulk_out" + return out + + usb.util.claim_interface(dev, USB_INTERFACE) + try: + for pkt in SWITCH2_USB_INIT_PACKETS: + ep_out.write(pkt) + time.sleep(pause_s) + if ep_in is not None: + try: + ep_in.read(read_size, timeout=read_timeout_ms) + except usb.core.USBError: + pass + out["ok"] = True + out["packets_sent"] = len(SWITCH2_USB_INIT_PACKETS) + out["message"] = ( + f"Handshake OK ({name}, PID {found_pid:04X}). " + "Wait a moment, then SDL should list the controller." + ) + finally: + usb.util.release_interface(dev, USB_INTERFACE) + + except Exception as e: + out["message"] = f"USB handshake failed: {e}" + out["error"] = repr(e) + try: + usb.util.dispose_resources(dev) + except Exception: + pass + return out + finally: + if detached_kernel: + try: + dev.attach_kernel_driver(USB_INTERFACE) + except (usb.core.USBError, NotImplementedError, ValueError): + pass + + return out + + +def platform_requires_switch2_usb_init(platform_label: str) -> bool: + """True for the capture platform that runs the HHL-compatible bulk handshake first.""" + return "libusb handshake" in platform_label diff --git a/scripts/build.ps1 b/scripts/build.ps1 index ecc39981..8cb9ed72 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -108,6 +108,16 @@ Write-Host " 2) Debug (UART logging, no optimization)" $configChoice = Read-Host "Choice [1-2]" $CMAKE_BUILD_TYPE = if ($configChoice -eq "2") { "Debug" } else { "Release" } +$OGXM_SWITCH2_HID_RAW_LOG = $false +if ($configChoice -eq "2") { + Write-Host "" + Write-Host "Switch 2 Pro USB (PID 0x2069) debugging (Debug builds only):" + Write-Host " 1) Off (default)" + Write-Host " 2) UART: raw HID hex when report buffer changes (-DOGXM_SWITCH2_HID_RAW_LOG=ON)" + $s2RawChoice = Read-Host "Choice [1-2]" + if ($s2RawChoice -eq "2") { $OGXM_SWITCH2_HID_RAW_LOG = $true } +} + # --- Run build --- $BuildDir = Join-Path $ScriptDir "build" if (Test-Path $BuildDir) { Remove-Item -Recurse -Force $BuildDir } @@ -115,7 +125,8 @@ New-Item -ItemType Directory -Path $BuildDir | Out-Null Write-Host "" $fixedInfo = if ($OGXM_FIXED_DRIVER) { " fixed=$OGXM_FIXED_DRIVER" } else { "" } -Write-Host "Building: board=$OGXM_BOARD type=$CMAKE_BUILD_TYPE$fixedInfo" +$s2Info = if ($OGXM_SWITCH2_HID_RAW_LOG) { " switch2_raw_hid=ON" } else { "" } +Write-Host "Building: board=$OGXM_BOARD type=$CMAKE_BUILD_TYPE$fixedInfo$s2Info" Write-Host "Output directory: $BuildDir" Write-Host "" @@ -128,6 +139,9 @@ if ($OGXM_FIXED_DRIVER) { $cmakeArgs += "-DOGXM_FIXED_DRIVER=$OGXM_FIXED_DRIVER" $cmakeArgs += "-DOGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF" } +if ($OGXM_SWITCH2_HID_RAW_LOG) { + $cmakeArgs += "-DOGXM_SWITCH2_HID_RAW_LOG=ON" +} $buildLog = Join-Path $env:TEMP "ogxm_build_log.txt" $buildSuccess = $false @@ -145,6 +159,16 @@ try { if ($buildSuccess) { Write-Host "" Write-Host "Build completed successfully. Output is in: $BuildDir" -ForegroundColor Green + if ($CMAKE_BUILD_TYPE -eq "Debug") { + Write-Host "" + Write-Host "Debug logging (OGXM_LOG, Switch 2 raw HID): UART only at 115200 8N1 — not the Pico USB cable." -ForegroundColor Yellow + if ($OGXM_BOARD -eq "PI_PICOW" -or $OGXM_BOARD -eq "PI_PICO2W") { + Write-Host " Wire USB-serial RX to GP4 (board TX), GND to GND." + } else { + Write-Host " Wire USB-serial RX to GP0 (board TX), GND to GND." + } + Write-Host " Then open that COM port in PuTTY / VS Code Serial Monitor at 115200." + } } else { Write-Host "" Write-Host "Build failed. You can save the output to a log file for troubleshooting." -ForegroundColor Yellow diff --git a/scripts/build.sh b/scripts/build.sh index ca4f1da4..f60bcb63 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -122,13 +122,25 @@ else CMAKE_BUILD_TYPE=Release fi +OGXM_SWITCH2_HID_RAW_LOG=OFF +if [ "$config_choice" = "2" ]; then + echo "" + echo "Switch 2 Pro USB (PID 0x2069) debugging (Debug builds only):" + echo " 1) Off (default)" + echo " 2) UART: raw HID hex when report buffer changes (-DOGXM_SWITCH2_HID_RAW_LOG=ON)" + read -r -p "Choice [1-2]: " s2_raw_choice + if [ "$s2_raw_choice" = "2" ]; then + OGXM_SWITCH2_HID_RAW_LOG=ON + fi +fi + # --- Run build --- BUILD_DIR="$SCRIPT_DIR/build" rm -rf "$BUILD_DIR" mkdir -p "$BUILD_DIR" echo "" -echo "Building: board=$OGXM_BOARD type=$CMAKE_BUILD_TYPE ${OGXM_FIXED_DRIVER:+fixed=$OGXM_FIXED_DRIVER}" +echo "Building: board=$OGXM_BOARD type=$CMAKE_BUILD_TYPE ${OGXM_FIXED_DRIVER:+fixed=$OGXM_FIXED_DRIVER}${OGXM_SWITCH2_HID_RAW_LOG:+ switch2_raw_hid=ON}" echo "Output directory: $BUILD_DIR" echo "" @@ -139,6 +151,7 @@ trap "rm -f '$BUILD_LOG'" EXIT cd "$BUILD_DIR" CMAKE_ARGS=(-G Ninja -DOGXM_BOARD="$OGXM_BOARD" -DCMAKE_BUILD_TYPE="$CMAKE_BUILD_TYPE") [ -n "$OGXM_FIXED_DRIVER" ] && CMAKE_ARGS+=(-DOGXM_FIXED_DRIVER="$OGXM_FIXED_DRIVER" -DOGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF) + [ "$OGXM_SWITCH2_HID_RAW_LOG" = "ON" ] && CMAKE_ARGS+=(-DOGXM_SWITCH2_HID_RAW_LOG=ON) cmake "${CMAKE_ARGS[@]}" "$FIRMWARE_RP2040" ninja ) 2>&1 | tee "$BUILD_LOG" @@ -147,6 +160,15 @@ BUILD_STATUS=${PIPESTATUS[0]} if [ "$BUILD_STATUS" -eq 0 ]; then echo "" echo "Build completed successfully. Output is in: $BUILD_DIR" + if [ "$CMAKE_BUILD_TYPE" = "Debug" ]; then + echo "" + echo "Debug logging (OGXM_LOG, Switch 2 raw HID): UART only at 115200 8N1 — not the Pico USB cable." + case "$OGXM_BOARD" in + PI_PICOW|PI_PICO2W) echo " Wire USB-serial RX to GP4 (board TX), GND to GND. (UART1; avoids PIO USB on GP0/1.)" ;; + *) echo " Wire USB-serial RX to GP0 (board TX), GND to GND." ;; + esac + echo " Then: minicom -D /dev/ttyUSB0 -b 115200 (or screen, PuTTY, VS Code Serial Monitor)" + fi else echo "" echo "Build failed. You can save the output to a log file for troubleshooting." From 58ad3ece880083c9995b2ebde9ca1e33fa0eda31 Mon Sep 17 00:00:00 2001 From: Gary L <81448614+MegaCadeDev@users.noreply.github.com> Date: Mon, 30 Mar 2026 07:55:33 -0400 Subject: [PATCH 32/42] Revise controller support and hardware compatibility info Updated controller support details and hardware notes. --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index aa53b194..82c18014 100644 --- a/README.md +++ b/README.md @@ -91,10 +91,8 @@ See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a ful Note: There are some third party controllers that can change their VID/PID, these might not work correctly. -**Requesting support for a new controller:** run the capture tool in **[Tools/controller_capture](Tools/controller_capture/README.md)** on your PC, save the report, and attach it when you ask for a new **VID/PID** or mapping. - ### Wireless adapters -- Xbox 360 PC adapter (Microsoft or clones) +- Xbox 360 PC adapter (Microsoft) - 8Bitdo v1 and v2 Bluetooth adapters (set to XInput mode) - Most wireless adapters that present themselves as Switch/XInput/PlayStation controllers should work @@ -156,11 +154,17 @@ Highlights: - Output to the following consoles: - ~~PS2~~ (done: PS1/PS2 GPIO mode, see changelog) - ~~GameCube~~ (done: GameCube GPIO mode, see changelog) - - DreamCast + - ~~DreamCast~~ - NES - SNES - Genesis - Master System + - Sega Saturn + - PS4/ PS5 + - Xbox One + - Atari + - PS2 MultiTap + - PS1 MultiTap ## Hardware For Pi Pico, RP2040-Zero, 4 channel, and ESP32 configurations, please see the hardware folder for diagrams. @@ -214,11 +218,15 @@ Build with **CMake** from the `Firmware/RP2040` directory (or use the build scri #### Board options (OGXM_BOARD) +Please Note that I currently only have Pico W/ 2 W, Waveshare RP2350 USB A and AdaFruit Feather. I am unable to test on other boards at this time, if you wish for more boards to be tested and compatible with my build please consider a donation on KoFi. There may be unexpected bugs on other boards that I am unable to test directly until the board is made available to me. + +Additionally, clone boards or knock offs are not supported. I cannot source and test everything on every variation of clone boards as their builds may effect other official boards as well and break other features. If you wish for your clone board to be supported you will need to edit and compile the firmware yourself. + Use one of these values for **`OGXM_BOARD`** in a manual build, or pick the same board from the build script’s numbered list: - ```PI_PICO``` - ```PI_PICO2``` -- ```PI_PICOW``` +- ```PI_PICOW``` - ```PI_PICO2W``` - ```RP2040_ZERO``` (Waveshare RP2040-Zero) - ```RP2350_USB_A``` (Waveshare RP2350-USB-A) From 31483e92971c57435f625da985931205bd94a152 Mon Sep 17 00:00:00 2001 From: 0xSt0le <233301452+0xSt0le@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:19:01 +0200 Subject: [PATCH 33/42] Fix wired DS4 PS/touchpad button masking in PS4 USB host parser --- Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp index a693cb16..9d09d983 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp @@ -43,7 +43,7 @@ void PS4Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, co void PS4Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) { std::memcpy(&in_report_, report, std::min(static_cast(len), sizeof(PS4::InReport))); - in_report_.buttons[2] &= PS4::COUNTER_MASK; + in_report_.buttons[2] &= static_cast(~PS4::COUNTER_MASK); if (std::memcmp(reinterpret_cast(report), &prev_in_report_, sizeof(PS4::InReport)) == 0) { tuh_hid_receive_report(address, instance); From 7037768d328a522dacbd8c19cf20386c512eb107 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Thu, 18 Jun 2026 13:57:55 -0400 Subject: [PATCH 34/42] Joy-Con pair merge, latency fixes, Switch 2 BT, docs, and Discord link. --- CHANGELOG.md | 12 +- Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/CMakeLists.txt | 5 + Firmware/RP2040/docs/IMPROVEMENTS.md | 169 +++++++++- Firmware/RP2040/docs/README.md | 2 +- Firmware/RP2040/docs/Wired_Controllers.md | 7 +- Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 237 ++++++++++--- .../Board/board_api_private/board_api_bt.cpp | 1 - Firmware/RP2040/src/Board/ogxm_log.cpp | 1 + Firmware/RP2040/src/Descriptors/PS4Usb.h | 126 +++++++ Firmware/RP2040/src/Gamepad/Gamepad.h | 46 ++- .../DeviceDriver/DeviceDriverTypes.h | 1 + .../src/USBDevice/DeviceDriver/PS3/PS3.cpp | 91 ++++- .../src/USBDevice/DeviceDriver/PS4/PS4.cpp | 312 ++++++++++++++++++ .../src/USBDevice/DeviceDriver/PS4/PS4.h | 33 ++ .../RP2040/src/USBDevice/DeviceManager.cpp | 6 + .../RP2040/src/USBHost/HostDriver/PS5/PS5.cpp | 9 +- .../RP2040/src/UserSettings/UserSettings.cpp | 6 +- Firmware/RP2040/src/sdkconfig.h | 11 +- Firmware/external/bluepad32 | 2 +- README.md | 14 +- 21 files changed, 1018 insertions(+), 75 deletions(-) create mode 100644 Firmware/RP2040/src/Descriptors/PS4Usb.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.h diff --git a/CHANGELOG.md b/CHANGELOG.md index b0d62543..b5114067 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,18 @@ # Changelog / Version history -Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). +Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, **Switch 2 Pro + Joy-Con 2 BLE**, **Switch 1 Joy-Con L+R merge**, **Joy-Con dual-half latency fixes**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). --- -### Version 1.0.0.9a *(planned / next release)* +### Version 1.0.0.10a + +- **Nintendo Switch 2 — wireless on Pico W / Pico 2 W** — New **Bluepad32 BLE GATT client** (`uni_hid_parser_switch2`) connects **Switch 2 Pro** (PID **0x2069**), **Joy-Con 2 Left** (**0x2067**), and **Joy-Con 2 Right** (**0x2066**) over **Bluetooth LE** (non-standard pairing; not Windows Bluetooth settings). **Joy-Con 2 L+R** merge into **one player** (pair **Left** first, then **Right** while left stays connected). Parses **63-byte** input notifications (composed button dword at offset **4**), maps buttons, sticks, motion, rumble, and **Home → PS / Guide (SYS)** with a short **Home latch** so single-frame BLE pulses are not lost before the USB output driver runs. **Rumble keepalive** on the vibration characteristic keeps the link up. **NSO GameCube** (PID **0x2073**) is registered but not yet confirmed. Protocol references: [Nadeflore/switch2-controllers](https://github.com/Nadeflore/switch2-controllers), [TommyWabg/switch2-controllers-windows10-gyro](https://github.com/TommyWabg/switch2-controllers-windows10-gyro), and community notes in [BlueRetro #1249](https://github.com/darthcloud/BlueRetro/issues/1249). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Nintendo Switch 2 — Bluetooth*). +- **Switch 1 Joy-Con (Classic Bluetooth) — L+R pair merge** — Original **Joy-Con (L/R)** (PIDs **0x2006** / **0x2007**) use the same **Left first, then Right** flow as Joy-Con 2. Merged input maps to one gamepad slot; solo Joy-Con keeps **BR/EDR inquiry** for the partner. Requires **`CONFIG_BLUEPAD32_MAX_DEVICES=2`** on single-player builds. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Nintendo Switch 2 — Bluetooth*, item 8). +- **Joy-Con pair latency (Switch 1 + Switch 2)** — Fixed lag and missed edges when **both** merged halves have buttons pressed at once. **Half-cache merge** (always merge from latest L and R state, emit once through primary), **2-slot** Bluetooth pad staging on Core1→Core0, **Switch 1:** IMU disabled when paired; **Switch 2:** deferred merge emit, reduced/alternating keepalive, Joy-Con–only stick parse, no hot-path raw UART logging. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Joy-Con pair merge — latency when both halves are active*). + +--- + +### Version 1.0.0.9a - **Nintendo Switch 2 Pro (USB PID 0x2069), wired** — **Switch2ProHost** now maps **face buttons, d‑pad, LB/RB, L3, R3, Start, Guide/SYS, Minus (Back), ZL/ZR as LT/RT** from the stable **10‑byte** input payload after report **0x09** (extended / IMU bytes unused to avoid flicker). **GL**, **GR**, and **Chat** are documented in code but intentionally unmapped. **Wired USB to the adapter only** (see [Wired_Controllers.md](Firmware/RP2040/docs/Wired_Controllers.md)). Debug: optional **`OGXM_SWITCH2_HID_RAW_LOG`** logs when the **three digital button bytes** change (UART). - **Bluetooth (Pico W / Pico 2 W)** — **~1 second connection rumble** when a wireless controller reaches **device ready**, so you get haptic feedback that pairing completed. **DualShock 4** uses a **delayed start** before rumble (same spirit as the existing PS4 FF grace period). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Next version* and *§6. Connection rumble*). diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index a0b89deb..b513216e 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a9") \ No newline at end of file +set(FW_VERSION "v1.0.0a10") \ No newline at end of file diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 955e2a93..4d9b9058 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -67,6 +67,7 @@ set(SOURCES_BOARD ${SRC}/USBDevice/DeviceDriver/DeviceDriver.cpp ${SRC}/USBDevice/DeviceDriver/PSClassic/PSClassic.cpp ${SRC}/USBDevice/DeviceDriver/PS3/PS3.cpp + ${SRC}/USBDevice/DeviceDriver/PS4/PS4.cpp ${SRC}/USBDevice/DeviceDriver/Switch/Switch.cpp ${SRC}/USBDevice/DeviceDriver/WiiU/WiiU.cpp ${SRC}/USBDevice/DeviceDriver/Wii/Wii.cpp @@ -553,6 +554,10 @@ if(EN_BLUETOOTH) add_subdirectory(${BLUEPAD32_ROOT}/src/components/bluepad32 libbluepad32) # Propagate to bluepad32 sources (e.g. DS4 parser): CYW43-specific link + setup path target_compile_definitions(bluepad32 PRIVATE OGXM_BLUEPAD32_PICO_W=1) + target_include_directories(bluepad32 PRIVATE ${SRC}) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(bluepad32 PRIVATE CONFIG_OGXM_DEBUG=1) + endif() endif() add_subdirectory(${LIBFIXMATH_PATH} libfixmath) diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 7293d134..b0191bee 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -2,9 +2,9 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. -**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). +**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). **v1.0.0.10a** adds **Nintendo Switch 2** wireless support (**Pro 2** and **Joy-Con 2**) over **BLE**, **Switch 1 Joy-Con L+R merge**, and **Joy-Con dual-half latency fixes** (see *Nintendo Switch 2 — Bluetooth* and *Joy-Con pair merge — latency* below). -**Next version (e.g. v1.0.0.9a) — documented here for release notes:** +**Version 1.0.0.9a — documented here for release notes:** - **Bluetooth (Pico W / Pico 2 W):** ~**1 second** haptic **connection rumble** when a wireless controller reaches **device ready** (so you can feel that pairing completed). **DualShock 4** uses a **longer start delay** before rumble (same idea as the existing PS4 FF grace window) so early force-feedback does not destabilize the link. **File:** `src/Bluepad32/Bluepad32.cpp` — `ogxm_play_connection_rumble()` from `device_ready_cb`. - **PS3 mode with the adapter plugged into a Windows PC:** **Host output rumble** forwarded to the Bluetooth pad no longer stays on at idle. Windows DInput often sends a **small non-zero** large-motor byte or a **small-motor byte other than 0/1**; the driver now applies a **deadzone** on the large motor and treats the small motor as on **only when the byte is `1`** (DS3 output semantics). **File:** `src/USBDevice/DeviceDriver/PS3/PS3.cpp` — `new_report_out_` path. @@ -13,6 +13,95 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. --- +## Nintendo Switch 2 — Bluetooth (Pico W / Pico 2 W) + +**Goal:** Use **Nintendo Switch 2** controllers as **wireless input** on **Pico W** and **Pico 2 W**, in any USB or GPIO output mode (e.g. PS3, XInput, OG Xbox, Switch Pro emulation). + +**Confirmed wireless (BLE):** + +| Controller | Product ID | Notes | +|------------|------------|--------| +| **Switch 2 Pro** | **0x2069** | Full gamepad; same 63-byte composed report path as Joy-Con 2. | +| **Joy-Con 2 (L)** | **0x2067** | Solo or **merged pair** with Joy-Con R → one player. | +| **Joy-Con 2 (R)** | **0x2066** | Solo or merged with Joy-Con L (pair L first, then SYNC R). | + +**Not yet confirmed:** **NSO GameCube** (**0x2073**) — PID registered; GC-style report path exists in the parser. + +Switch 2 controllers use a **proprietary BLE GATT protocol**, not standard HID-over-GATT. They advertise as **“Nintendo Switch”** with manufacturer data and require a **custom pairing / SYNC** command sequence before encrypted input notifications arrive. + +**References (protocol reverse engineering — thank you to these projects):** + +| Project | Contribution | +|---------|----------------| +| **[Nadeflore/switch2-controllers](https://github.com/Nadeflore/switch2-controllers)** | Foundational Switch 2 **BLE discovery, pairing, and GATT** flow for Joy-Con 2 / Pro 2 on PC. | +| **[TommyWabg/switch2-controllers-windows10-gyro](https://github.com/TommyWabg/switch2-controllers-windows10-gyro)** | Extended fork with **63-byte composed input report** layout (button dword @ offset 4, sticks @ 10/13, IMU @ 48), **init / feature / rumble** command formats, and **Pro Controller** rumble packet structure. | +| **[BlueRetro #1249](https://github.com/darthcloud/BlueRetro/issues/1249)** (darthcloud) | Early community notes on **63-byte reports**, **notify handle 0x000A**, and Switch 2 **button bitfield** layout. | +| **`Switch2ProHost.cpp`** (this repo) | **Wired USB** bit layout for PID **0x2069** — cross-check for face / d-pad / **Home → SYS** mapping on PS3-oriented builds. | + +### Changes + +1. **New Bluepad32 parser** — `Firmware/external/bluepad32/.../parser/uni_hid_parser_switch2.c` (+ `.h`): GATT service discovery, **SYNC / pair** subcommands, calibration read, **input notify** on handle **0x0A**, **command** write/notify, **Pro** and **Joy-Con** vibration characteristics (keepalive rumble), connection parameter update (~7.5 ms), and teardown on disconnect. Supports PIDs **0x2069** (Pro), **0x2066** (Joy-Con R), **0x2067** (Joy-Con L). + +2. **LE advertisement hook** — `uni_bt_le.c` detects Switch 2 manufacturer data and routes connect to the Switch 2 parser instead of generic BLE HID. + +3. **Input decode** — **63-byte** notify: little-endian **button dword** at offset **4** (masks verified on hardware). Face, d-pad, ±, L3/R3, shoulders, ZL/ZR digital, **Home** (`0x100000` / `0x1000`), and **Capture** mapped into Bluepad32 `uni_gamepad_t`. Sticks calibrated from factory data; gyro/accel forwarded when present. + +4. **Home → PS / Guide** — Home sets `MISC_BUTTON_SYSTEM` → `MAP_BUTTON_SYS` in `Bluepad32.cpp` → PS3 / XInput / etc. **Home latch** (~24 frames) in the parser so Nintendo’s often **single-frame** Home pulse is not dropped by the lock-free Core1→Core0 pad staging buffer before the PS3 **8-frame SYS latch** runs. + +5. **Link stability** — Periodic **rumble keepalive** (zero-amplitude vibration write every ~5–8 ms) prevents **HCI disconnect (0x08)** when the pad would otherwise go idle without output reports. + +6. **OGX integration** — `Bluepad32.cpp`: rumble routing, motion source `MOTION_SRC_SWITCH_PRO`, stall-watchdog exemption, keepalive timer for Switch 2 BLE devices. + +7. **Joy-Con 2 pair merge** — When **Left** and **Right** Joy-Con 2 are both connected, input is **merged into one gamepad** (player slot = lower BT index, typically player 1). Left half: left stick, L/ZL, d-pad; right half: face buttons, right stick, R/ZR. Solo Joy-Con keeps BLE scan on for the partner; disconnecting one half unpairs and the other continues solo. + +8. **Switch 1 Joy-Con pair merge** — Original **Joy-Con (L/R)** over **Classic Bluetooth** (PIDs **0x2006** / **0x2007**) use the same **L first, then R** flow in `uni_hid_parser_switch.c`. When paired, each half uses **Pro-style** stick/button layout before merge; solo Joy-Con keeps **BR/EDR inquiry** running for the partner. Requires **two** Bluepad32 device slots (`CONFIG_BLUEPAD32_MAX_DEVICES=2`) even on single-player USB builds. + +9. **Joy-Con pair latency (Switch 1 + Switch 2)** — When **both** halves send input at once, merged pairs no longer feel laggy or drop button edges. See [§ Joy-Con pair merge — latency when both halves are active](#joy-con-pair-merge--latency-when-both-halves-are-active) below. + +**Pairing (user):** Put the **Pro 2** or **Joy-Con 2** in pairing mode (SYNC / hold the pairing button per Nintendo instructions). The adapter scans and connects; **do not** pair the pad in Windows/macOS Bluetooth settings first. + +**Joy-Con 2 as one controller (like Switch):** Pair the **Left** Joy-Con first, then put the **Right** Joy-Con in SYNC mode while the left is still connected. The firmware **merges** both halves into **one player** (gamepad slot **1** / the lower BT slot index). Left stick, d-pad, L/ZL map from the left Joy-Con; face buttons, right stick, R/ZR from the right. If only one Joy-Con is connected, it works solo and BLE scan stays on so you can add the partner. + +**Switch 1 Joy-Con (same user flow):** Pair **Left** first (hold **SYNC** on the rail), then **Right** while left stays connected. Uses Classic BT inquiry instead of BLE scan. Solo horizontal Joy-Con layout applies until the pair is formed; merged input uses a full gamepad layout. **Wired USB** for Switch 2–family pads remains in **Switch2ProHost** / **SwitchProHost** — see [Wired_Controllers.md](Wired_Controllers.md). + +**Files:** `uni_hid_parser_switch2.c`, `uni_hid_parser_switch2.h`, `uni_hid_parser_switch.c`, `uni_hid_parser_switch.h`, `uni_bt_le.c`, `uni_bt_bredr.c`, `uni_hid_device.c`, `uni_controller_list.h`, `src/Bluepad32/Bluepad32.cpp`. + +--- + +## Joy-Con pair merge — latency when both halves are active + +**Problem:** With **Left + Right** Joy-Cons merged into one player (Switch 1 Classic BT or Switch 2 BLE), pressing buttons on **both** halves at the same time could feel **laggy** or miss rapid edges. Switch 1 Pro / solo Joy-Con and Switch 2 Pro were unaffected. + +**Root causes:** + +1. **Stale merge** — Each half’s report was merged using the partner’s last parsed `controller.gamepad`, which could be **one frame behind** when L and R updated in the same interval. +2. **Dropped Core1→Core0 reports** — Bluetooth HID runs on **Core1**; a **single** lock-free staging slot could be **overwritten** before Core0 drained it when L and R fired back-to-back. +3. **Switch 2 radio / BT-thread load** — Dual BLE links plus **keepalive vibration writes** and **verbose raw-input logging** on button changes competed with inbound notifications on the shared CYW43439 radio. + +### Changes + +#### Shared (Switch 1 + Switch 2 parsers + Gamepad) + +1. **Per-half cached state** — Each Joy-Con slot stores its latest parsed `uni_gamepad_t` in a half cache (`sw1_joycon_half_gp` / `sw2_joycon_half_gp`). On any report from either half, merge reads **both caches** and emits **once** through the **primary** (left) device slot only. +2. **2-slot Bluetooth pad staging** — `Gamepad::set_pad_in_from_bluetooth()` uses a **two-entry ring** instead of one overwrite buffer, so rapid L-then-R reports are less likely to lose a frame before Core0 merges them into the main pad-in queue. **File:** `src/Gamepad/Gamepad.h`. + +#### Switch 1 (Classic Bluetooth) + +3. **IMU off when paired** — After L+R pair is established, both halves receive **SUBCMD_ENABLE_IMU (0)** so 0x30 reports carry less motion traffic and parsing skips IMU while paired. **File:** `uni_hid_parser_switch.c` — `switch_set_imu_enabled()`, `switch_establish_joycon_pair()`. + +#### Switch 2 (BLE) + +4. **Deferred merge emit** — When paired, L/R input notifications **update the half cache immediately** but schedule a **0 ms** run-loop timer to merge and call `uni_hid_device_process_controller()` **once** per BT tick if both halves updated in the same loop iteration. +5. **Keepalive traffic reduced** — Removed **keepalive on every input notification** (timer already maintains the link). **Secondary** Joy-Con **stops** its 5 ms keepalive timer when paired; **primary** alternates idle rumble between L and R every **10 ms** (one GATT write per tick). Keepalive is **deferred briefly** while either half is actively reporting. **Bluepad32** skips redundant feedback-path keepalive when the parser timer is already running. +6. **Joy-Con–specific parse** — Joy-Con 2 L/R parse **only their physical stick** (not both sticks + IMU on every 63-byte packet). Raw hex input logging on button change is **disabled** by default (`SW2_DEBUG_RAW_INPUT=0`) so UART work does not stall the BT thread during gameplay. +7. **Connection interval** — **7.5 ms** connection parameter update is requested on **both** halves when the pair is formed. + +**Files:** `uni_hid_parser_switch.c`, `uni_hid_parser_switch2.c`, `uni_hid_parser_switch2.h`, `src/Gamepad/Gamepad.h`, `src/Bluepad32/Bluepad32.cpp`. + +**User impact:** Paired Joy-Cons (Switch 1 or Switch 2) should feel as responsive when using **both** halves simultaneously as when using one half alone. Pairing flow unchanged: **Left first**, then **Right** (SYNC on the partner while left stays connected). + +--- + ## Xbox 360 (XInput) support **Goal:** Use the adapter in XInput mode on Xbox 360 with Bluetooth controllers (e.g. PS5, Xbox One). The 360 requires XSM3 authentication and specific USB descriptors. @@ -90,7 +179,7 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad - **Many PS3s cut power to the USB ports** when shut down, so the adapter and controller disconnect and wake is not possible. If your controller stays powered (e.g. charging LED) when the PS3 is off, that model may keep USB in standby and wake may work. Same disclaimer as 360: no wake from cold start; use the console power button first if needed. - **Recovery Mode:** Even when wake from standby is not possible (e.g. console cuts USB when off), the adapter is **confirmed working in PS3 Recovery Mode** — you can use it to navigate and select options in Recovery. -7. **Host rumble → Bluetooth pad (PS3 mode on PC)** *(next version)* +7. **Host rumble → Bluetooth pad (PS3 mode on PC)** *(v1.0.0.9a)* When the adapter is in **PS3 output mode** and connected to a **Windows** host, the OS still sends **HID output** (rumble) to the device. That output is forwarded to the **Bluetooth** gamepad as `PadOut` rumble. Some Windows stacks leave **noise** in the report (small large-motor values, or non‑`0`/`1` small-motor bytes). Forwarding that blindly caused **constant vibration** on the wireless controller at idle. **Fix:** Ignore large-motor values **below a small threshold** (deadzone), and treat the **small motor as on only when the host byte is `1`** (not “any non-zero”). **File:** `PS3.cpp` — block that runs when `new_report_out_` is set after `set_report_cb` parses the DS3 output report. @@ -292,11 +381,11 @@ For **`CONTROLLER_TYPE_PS4Controller`**, **rumble output** is **delayed ~6 secon ### 5. Related Pico W Bluetooth improvements (see also Summary table) - **Core0 `sleep_ms(1)`** in the main loop so Core1 (BT stack) gets CPU time ([Team-Resurgent/OGX-Mini](https://github.com/Team-Resurgent/OGX-Mini) pattern). -- **Lock-free Bluetooth input path** (`set_pad_in_from_bluetooth`) so HID callbacks never block on Core0’s mutex. +- **Lock-free Bluetooth input path** (`set_pad_in_from_bluetooth`) so HID callbacks never block on Core0’s mutex. **Joy-Con pairs:** **2-slot** staging ring so back-to-back L/R reports are not overwritten before Core0 drains (see [§ Joy-Con pair merge — latency](#joy-con-pair-merge--latency-when-both-halves-are-active)). - **Reconnect:** last device disconnect calls **`uni_bt_enable_new_connections_unsafe(true)`** so pairing can resume without power-cycling. - **8 s input-stall disconnect** (non-virtual, non-BLE-Xbox) to clear zombie links; **BLE Xbox** uses keepalive instead of stall disconnect. -### 6. Connection rumble when the wireless controller is ready *(next version)* +### 6. Connection rumble when the wireless controller is ready *(v1.0.0.9a)* When Bluepad32 reports **`device_ready`** for a non-virtual gamepad, the firmware plays about **one second** of **dual-motor rumble** (via `play_dual_rumble` when the controller supports it) so you can **feel** that the Bluetooth link is up. **DualShock 4** uses a **~1.2 s delay** before starting that rumble so it does not overlap the fragile post-connect window (aligned with the existing PS4 rumble grace logic). Other controller types use a shorter default delay. @@ -325,18 +414,82 @@ The script checks for required tools (git, python3, cmake, ninja, arm-none-eabi- --- +## Future planned + +Work that is **not implemented** in current firmware but has been researched. These items are **not** a matter of adding a VID/PID to a table — they need new host drivers and/or radio stacks. + +### Xbox Wireless Adapter for Windows (`045e:02e6`, `045e:02fe`) + +**Devices:** + +| VID:PID | Model | USB product string | Status | +|---------|-------|-------------------|--------| +| **`045e:02e6`** | 1713 | Xbox Wireless Adapter for Windows (older) | **Not supported** | +| **`045e:02fe`** | 1790 | **XBOX ACC** (newer) | **Not supported** | + +These are **USB dongles** that receive **Xbox Wireless** (proprietary 2.4 GHz) from Xbox One and Xbox Series controllers. They are **not** gamepads and do **not** enumerate as XInput devices. + +**Do not confuse with the Xbox 360 PC receiver** — that **is supported** today: + +| VID:PID | Device | Why it works | +|---------|--------|--------------| +| **`045e:0719`** (typical) | Xbox 360 wireless **PC receiver** | Presents a standard XInput-style USB interface (`bInterfaceSubClass=0x5D`, `bInterfaceProtocol=0x81`). Handled by `tuh_xinput` / `Xbox360WHost`. | + +The One/Series dongles use a **completely different USB shape** (vendor bulk, not XInput interrupt). + +#### What the dongle looks like on USB + +From hardware dumps (e.g. [ControllersInfo adapter descriptor](https://github.com/DJm00n/ControllersInfo/blob/master/xboxone/DescriptorDump_Adapter%20(Xbox%20Wireless%20Adapter%20for%20Windows).txt)): + +- **Device class:** vendor-specific (`0xFF/0xFF/0xFF`), product name **"XBOX ACC"** +- **Endpoints:** **bulk** IN/OUT (512-byte packets on USB 2.0), not the interrupt endpoints used by **wired** Xbox One pads +- **Inside the stick:** a **Mediatek MT76** Wi‑Fi chipset that must run **dongle firmware** before it can talk to controllers + +OGX-Mini’s existing **wired Xbox One GIP** path (`tuh_xinput`, subclass `0x47` / protocol `0xD0`, `XboxOneHost`) parses GIP **after** the controller is already connected over USB. The wireless adapter never exposes that interface — the host must drive the **dongle radio** first. + +#### Why this is not a simple port + +1. **Firmware upload** — Linux [xone](https://github.com/medusalix/xone) / [xow](https://github.com/medusalix/xow) load **`xow_dongle.bin`** / variant blobs (e.g. **`xone_dongle_02fe.bin`**) into the MT76 chip over USB before the device is useful. That blob must be shipped in flash and the load sequence reimplemented on RP2040. + +2. **Wireless stack, not HID** — The driver brings up **MT76** (channels, pairing scan, client join/leave, optional encryption), wraps **GIP** payloads in **802.11-style data frames**, and sends them on bulk OUT queues. Inbound bulk IN carries WLAN frames that must be parsed to extract GIP input. This is the bulk of [xone `transport/dongle.c`](https://github.com/medusalix/xone/blob/master/transport/dongle.c) + [`transport/mt76.c`](https://github.com/medusalix/xone/blob/master/transport/mt76.c) — thousands of lines, not a report-descriptor tweak. + +3. **Resource cost** — xone uses many bulk URBs, WLAN buffers up to tens of KB per packet, and ongoing radio work. RP2040 flash/RAM and Core1 USB host timing are tight compared to a PC kernel driver. + +4. **Pairing model** — Controllers must be **paired to the dongle** (Sync on the pad while the dongle is in pairing mode). Pads previously used over **USB** or **Bluetooth** will not auto-attach until re-paired to the dongle — same as on Windows with xone. + +5. **Reuse is partial only** — Once a wireless client is connected and GIP input arrives, decoding could **reuse** existing GIP constants and mapping from `Descriptors/XboxOne.h` / `XboxOneHost.cpp`. Everything **before** that (USB dongle + radio + framing) is new work — comparable in scope to adding Switch 2 bulk bring-up, but **larger** because of firmware + Wi‑Fi. + +**Rough implementation phases (if pursued):** + +1. New TinyUSB **vendor bulk** class driver; claim `045e:02e6` / `045e:02fe`; embed firmware; port MT76 init from xone. +2. Bulk I/O loops, pairing, client add/remove (mirror `Xbox360W` connect callbacks in `HostManager`). +3. Bridge decoded GIP `0x20` / `0x07` reports into `XboxOneHost` (or a shared GIP parser). +4. Rumble/LED over wireless GIP OUT path. + +**Practical alternatives today:** + +- **Xbox 360 wireless receiver** + 360 pads — already supported (`Xbox360WHost`). +- **Xbox One / Series controller** — **Bluetooth** on Pico W / Pico 2 W (Bluepad32), or **wired USB** (`XboxOneHost`). + +**References:** [medusalix/xone](https://github.com/medusalix/xone), [medusalix/xow](https://github.com/medusalix/xow), [SDL discussion of 02fe vs XInput PID](https://github.com/libsdl-org/SDL/pull/8683), [ControllersInfo dongle descriptor dump](https://github.com/DJm00n/ControllersInfo/tree/master/xboxone). + +**Files that would be touched (when implemented):** new `tuh_xbox_dongle` (or similar) under `USBHost/HostDriver/XInput/`, `HostManager.h`, `tuh_callbacks.cpp`, `tusb_config.h`; possible shared GIP layer with `XboxOne.cpp`. + +--- + ## Summary | Area | Improvement | |------|-------------| -| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. Report built every loop, send when endpoint ready — same minimal-latency pattern as Switch/PS3. | -| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **Next version:** PC host rumble deadzone + strict small-motor `0`/`1` so idle rumble does not stick on the BT pad. | +| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). **360 wireless PC receiver** supported (`Xbox360WHost`). **Xbox One/Series wireless dongle (`045e:02e6` / `02fe`)** — see [Future planned](#future-planned). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. Report built every loop, send when endpoint ready — same minimal-latency pattern as Switch/PS3. | +| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **v1.0.0.9a:** PC host rumble deadzone + strict small-motor `0`/`1` so idle rumble does not stick on the BT pad. | | **PS2 (GPIO)** | Home only = IGR (L1+L2+R1+R2+Start+Select); Home+Start = shutdown (L1+L2+R1+R2+L3+R3). OPL and protocol stability (first response byte = mode byte). | | **OG Xbox** | Guide only = IGR. Shutdown = LT+RT+Back+White via **Guide+Start** or **Guide+View (Back)**; Xbox BT often omits Start while Guide is held. Shutdown report strips Start so the chord matches BIOS/softmod expectations. | | **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. | +| **Switch 2** | **Pro 2** (wired **0x2069**): **Switch2ProHost**. **Pro 2 + Joy-Con 2 L/R** (BLE): **uni_hid_parser_switch2** — GATT pairing, 63-byte input, rumble keepalive, Home → SYS latch, **L+R pair merge**, **dual-half latency fixes**. See [§ Nintendo Switch 2 — Bluetooth](#nintendo-switch-2--bluetooth-pico-w--pico-2-w) and [§ Joy-Con pair latency](#joy-con-pair-merge--latency-when-both-halves-are-active). | | **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). | | **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). Switch Pro and PS3 always build report every loop so host poll (`get_report`) and IN push both see current state — only remaining delay is BT radio when wireless. | | **Build** | Interactive scripts `scripts/build.sh` (Linux/macOS) and `scripts/build.ps1` (Windows) for board selection, fixed/default mode, and Release/Debug; output in `scripts/build/`. See [README](../../../README.md) Build section. | -| **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in; re-enable scan on last disconnect. **Next version:** ~**1 s connection rumble** at `device_ready` (DS4 delayed start). | +| **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **Switch 2 (BLE):** Pro 2 + Joy-Con 2 L/R — custom GATT parser, rumble keepalive, Home latch, **L+R merge**, **dual-half latency fixes**. **Switch 1 Joy-Con (Classic BT):** L+R merge, IMU off when paired, same latency path as SW2. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in (**2-slot** staging for Joy-Con pairs); re-enable scan on last disconnect. **v1.0.0.9a:** ~**1 s connection rumble** at `device_ready` (DS4 delayed start). | | **PIO USB host (Pico W)** | **Wired unplug:** Debounced combo of **HCD connect**, **`tuh_mounted` over all device addresses**, and **no `process_report` / setup activity** (~**3 s**) so disconnect registers when D+/D− line state is wrong under PIO; **`tuh_deinit`** + restore GPIO line IRQs + BT release. See [§ Pico W — PIO USB wired controller unplug detection](#pico-w--pico-2-w--pio-usb-wired-controller-unplug-detection). | | **DS3 + Bluetooth** | **USB auto-pair:** After PS3 wired init, **feature `0xF5`** programs the **DS3** with the adapter’s **BD_ADDR** (`CONFIG_EN_BLUETOOTH`); deferred if BT address not ready. See [§ DualShock 3 — automatic USB programming for Bluetooth pairing](#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). | diff --git a/Firmware/RP2040/docs/README.md b/Firmware/RP2040/docs/README.md index 45bf8522..c7a16c48 100644 --- a/Firmware/RP2040/docs/README.md +++ b/Firmware/RP2040/docs/README.md @@ -10,4 +10,4 @@ See the [project README](../../README.md) for overview, supported platforms, bui | [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | | [GPIO_Output_Pinout_and_Mappings.md](GPIO_Output_Pinout_and_Mappings.md) | GPIO pin-outs and default button/stick mappings for PS1/PS2, Dreamcast, GameCube, and N64 output (and input) modes. | | [Dreamcast_Port.md](Dreamcast_Port.md) | Dreamcast (Maple Bus) port status and notes for completing the port from DreamPicoPort (stub only in firmware for now). | -| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements: Xbox 360 (XInput), PS3 fixes, latency reduction, Xbox OG, DualSense/OG Xbox input, main loop order. | +| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements and **Future planned** (e.g. Xbox One/Series wireless dongle `045e:02e6` / `02fe`); PS3 fixes, latency, XInput/360, Pico W Bluetooth, Switch 2 / Joy-Con merge, PIO USB unplug detection. | diff --git a/Firmware/RP2040/docs/Wired_Controllers.md b/Firmware/RP2040/docs/Wired_Controllers.md index 8ec2284d..369f5dc9 100644 --- a/Firmware/RP2040/docs/Wired_Controllers.md +++ b/Firmware/RP2040/docs/Wired_Controllers.md @@ -10,7 +10,8 @@ This document lists controllers supported when connected to the OGX-Mini adapter ### XInput (Xbox 360, Xbox One, Xbox Series) -- **Microsoft:** Xbox 360 (wired and wireless with PC receiver), Xbox One, Xbox Series, Xbox Elite +- **Microsoft:** Xbox 360 (wired and **360 PC wireless receiver**), Xbox One / Series **wired USB**, Xbox Elite +- **Not supported (planned):** Xbox One / Series **wireless USB dongle** (`045e:02e6`, `045e:02fe`) — see [IMPROVEMENTS.md — Future planned](IMPROVEMENTS.md#future-planned) - **Third‑party:** Controllers that identify as XInput over USB (e.g. many 8BitDo, PowerA, PDP, Afterglow when in XInput mode) *Matched by USB class; no fixed VID/PID list. UsbdSecPatch is not required on Xbox 360.* @@ -53,7 +54,7 @@ This document lists controllers supported when connected to the OGX-Mini adapter ### Nintendo Switch (Pro and wired) - **Switch Pro / Joy‑Con / Wii U Pro:** - Nintendo Switch Pro Controller, Wii U Pro Controller, Joy‑Con (L/R), Nintendo Switch 2 Pro Controller + Nintendo Switch Pro Controller, Wii U Pro Controller, Joy‑Con (L/R), Nintendo Switch 2 Pro Controller, Joy‑Con 2 (L/R) - **Wired Switch:** PowerA (wired, Enhanced, Fusion, Spectra, Arcade Stick, Fusion Pro), Hori (Pokken, Horipad for Switch / Switch 2), Afterglow Deluxe, Faceoff Deluxe, and other wired Switch controllers @@ -62,7 +63,7 @@ This document lists controllers supported when connected to the OGX-Mini adapter **Switch 2–family USB (Pro Controller 2, Joy‑Con 2, NSO GameCube, etc.):** The firmware runs the same vendor **bulk OUT** bring‑up on **USB configuration 1, interface 1** as the PC capture tool (`Tools/controller_capture/switch2_usb_init.py` / HandHeldLegend ProCon 2 enabler), then continues with the normal Switch Pro **HID** init (handshake, full report mode, etc.). Wired input reports may use report ID **0x09** (with a 1‑byte counter after the ID). -**Switch 2 Pro (PID 0x2069), wired USB only:** After the same **bulk OUT** bring‑up on **config 1 / interface 1**, **Switch2ProHost** parses the standard **64‑byte** HID report (ID **0x09**, 1‑byte counter, then **10‑byte** `SwitchPro::InReport` payload). Digitals use **Switch‑2‑specific** bit positions (not classic **Buttons0/1/2**): face **B/A/Y/X**, **RB**, **LB** (Home bit), **Minus** → Back, **Plus** / d‑pad directions, **L3**, **Start** (classic R), **R3** (classic ZR bit), **SYS** (classic `bl` d‑pad up), **ZL/ZR** → **LT/RT** (digital full press from captured bits), and **Capture** is still not mapped to **MISC**. **GL**, **GR**, and **Chat** are **documented in source** (`Switch2ProHost.cpp`) but **left unmapped**. Extended report bytes are not used for decoding (avoids IMU coupling / flicker). **Bluetooth** for this model is **not** covered here—use a **wired** connection to the adapter’s USB host port. Other Switch 2–family PIDs keep **SwitchProHost**. +**Switch 2 Pro (PID 0x2069), wired USB:** After the same **bulk OUT** bring‑up on **config 1 / interface 1**, **Switch2ProHost** parses the standard **64‑byte** HID report (ID **0x09**, 1‑byte counter, then **10‑byte** `SwitchPro::InReport` payload). Digitals use **Switch‑2‑specific** bit positions (not classic **Buttons0/1/2**): face **B/A/Y/X**, **RB**, **LB** (Home bit), **Minus** → Back, **Plus** / d‑pad directions, **L3**, **Start** (classic R), **R3** (classic ZR bit), **SYS** (classic `bl` d‑pad up), **ZL/ZR** → **LT/RT** (digital full press from captured bits), and **Capture** is still not mapped to **MISC**. **GL**, **GR**, and **Chat** are **documented in source** (`Switch2ProHost.cpp`) but **left unmapped**. Extended report bytes are not used for decoding (avoids IMU coupling / flicker). **Bluetooth LE** for **Pro 2** and **Joy-Con 2** (**0x2066** / **0x2067**) on **Pico W / Pico 2 W** is documented in [IMPROVEMENTS.md](IMPROVEMENTS.md#nintendo-switch-2--bluetooth-pico-w--pico-2-w) (custom GATT — not wired USB). Other Switch 2–family PIDs keep **SwitchProHost**. --- diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index bfb0a3da..f5fa8c97 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -12,9 +12,8 @@ #include "uni.h" #include "bt/uni_bt.h" #include "bt/uni_bt_bredr.h" +#include "bt/uni_bt_le.h" #include "uni_hid_device.h" -#include "parser/uni_hid_parser_ds5.h" -#include "parser/uni_hid_parser_xboxone.h" #include "sdkconfig.h" @@ -31,10 +30,54 @@ static std::atomic s_bt_any_connected_cached{false}; #error "Pico W must use BLUEPAD32_PLATFORM_CUSTOM" #endif -static_assert((CONFIG_BLUEPAD32_MAX_DEVICES == MAX_GAMEPADS), "Mismatch between BP32 and Gamepad max devices"); +static_assert((CONFIG_BLUEPAD32_MAX_DEVICES >= MAX_GAMEPADS), + "Bluepad32 must allow at least as many BT devices as USB gamepad slots"); namespace bluepad32 { +static bool bp32_is_switch_joycon(const uni_hid_device_t* d) { + return d != nullptr && (d->controller_type == CONTROLLER_TYPE_SwitchJoyConLeft || + d->controller_type == CONTROLLER_TYPE_SwitchJoyConRight); +} + +static bool bp32_is_joycon_pair_secondary(const uni_hid_device_t* d) { + if (uni_hid_parser_switch2_is_ble_device(d)) + return uni_hid_parser_switch2_is_joycon_pair_secondary(d); + if (bp32_is_switch_joycon(d)) + return uni_hid_parser_switch_is_joycon_pair_secondary(d); + return false; +} + +static int bp32_get_gamepad_output_idx(uni_hid_device_t* d) { + if (uni_hid_parser_switch2_is_ble_device(d)) + return uni_hid_parser_switch2_get_gamepad_output_idx(d); + if (bp32_is_switch_joycon(d)) + return uni_hid_parser_switch_get_gamepad_output_idx(d); + return uni_hid_device_get_idx_for_instance(d); +} + +static int bp32_get_pair_partner_idx(uni_hid_device_t* d) { + if (uni_hid_parser_switch2_is_ble_device(d)) + return uni_hid_parser_switch2_get_pair_partner_idx(d); + if (bp32_is_switch_joycon(d)) + return uni_hid_parser_switch_get_pair_partner_idx(d); + return -1; +} + +static void bp32_disconnect_controller_and_joycon_partner(uni_hid_device_t* d) { + if (!d) + return; + const int partner_idx = bp32_get_pair_partner_idx(d); + if (partner_idx >= 0 && partner_idx < CONFIG_BLUEPAD32_MAX_DEVICES) { + uni_hid_device_t* partner = uni_hid_device_get_instance_for_idx(partner_idx); + if (partner && partner != d) { + printf("[BP32] Disconnect combo: also disconnecting Joy-Con partner slot %d\n", partner_idx); + uni_hid_device_disconnect(partner); + } + } + uni_hid_device_disconnect(d); +} + static constexpr uint32_t FEEDBACK_TIME_MS = 250; static constexpr uint32_t LED_CHECK_TIME_MS = 500; /** If no HID input report reaches us for this long while "connected", the BT link is zombie @@ -42,6 +85,8 @@ static constexpr uint32_t LED_CHECK_TIME_MS = 500; static constexpr uint32_t BT_INPUT_STALL_DISCONNECT_MS = 8000; /** BLE Xbox: host→pad output while idle (no rumble) or controller sleeps link ~1 min */ static constexpr uint32_t XBOX_BLE_KEEPALIVE_MS = 12000; +/** Switch 2 Pro BLE drops link (HCI 0x08) without periodic vibration writes. */ +static constexpr uint32_t SW2_BLE_KEEPALIVE_MS = 8; /** One-second rumble when a pad becomes ready so the user knows it is connected. */ static constexpr uint16_t CONNECT_RUMBLE_DURATION_MS = 1000; @@ -51,8 +96,9 @@ static constexpr uint8_t CONNECT_RUMBLE_STRONG = 160; static constexpr uint16_t CONNECT_RUMBLE_DELAY_PS4_MS = 1200; static constexpr uint16_t CONNECT_RUMBLE_DELAY_DEFAULT_MS = 300; -static uint32_t s_last_bt_input_ms[MAX_GAMEPADS]{}; -static uint32_t s_xbox_ble_ka_last_ms[MAX_GAMEPADS]{}; +static uint32_t s_last_bt_input_ms[CONFIG_BLUEPAD32_MAX_DEVICES]{}; +static uint32_t s_xbox_ble_ka_last_ms[CONFIG_BLUEPAD32_MAX_DEVICES]{}; +static uint32_t s_sw2_ble_ka_last_ms[CONFIG_BLUEPAD32_MAX_DEVICES]{}; /** Ignore Start+Select disconnect combo for this long after connect (DS4 can glitch both on first reports). */ static uint32_t s_bt_disconnect_combo_grace_until_ms[MAX_GAMEPADS]{}; /** DS4 BT: delay rumble output (host can request rumble immediately; early FF reports can drop link). */ @@ -63,7 +109,7 @@ struct BTDevice { Gamepad* gamepad{nullptr}; }; -BTDevice bt_devices_[MAX_GAMEPADS]; +BTDevice bt_devices_[CONFIG_BLUEPAD32_MAX_DEVICES]; btstack_timer_source_t feedback_timer_; btstack_timer_source_t led_timer_; bool led_timer_set_{false}; @@ -179,6 +225,11 @@ void set_rumble(uni_hid_device_t* bp_device, uint16_t length, uint8_t rumble_l, case CONTROLLER_TYPE_SwitchJoyConLeft: uni_hid_parser_switch_play_dual_rumble(bp_device, 0, length, rumble_l, rumble_r); break; + case CONTROLLER_TYPE_Switch2ProController: + case CONTROLLER_TYPE_Switch2JoyConRight: + case CONTROLLER_TYPE_Switch2JoyConLeft: + uni_hid_parser_switch2_play_dual_rumble(bp_device, 0, length, rumble_l, rumble_r); + break; default: break; } @@ -189,32 +240,50 @@ static void send_feedback_cb(btstack_timer_source *ts) uni_hid_device_t* bp_device = nullptr; const uint32_t now_ms = to_ms_since_boot(get_absolute_time()); - for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) + for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { if (!bt_devices_[i].connected || !(bp_device = uni_hid_device_get_instance_for_idx(i))) { continue; } + /* BLE Xbox (Series) and Switch 2 BLE may not send reports every poll interval. */ + const bool skip_stall_disconnect = + (bp_device->controller_type == CONTROLLER_TYPE_XBoxOneController && bp_device->hids_cid != 0) || + uni_hid_parser_switch2_is_ble_device(bp_device); /* Virtual slot (e.g. DS4's BT "mouse"): never gets gamepad HID → would always stall-disconnect * and drop the real controller. */ if (uni_hid_device_is_virtual_device(bp_device)) goto after_stall_check; - /* BLE Xbox (Series) often sends HID only on change — idle sticks look like "stall" and we - * would disconnect every few seconds. BR/EDR Xbox (1708) polls constantly; stall OK there. */ - if (!(bp_device->controller_type == CONTROLLER_TYPE_XBoxOneController && bp_device->hids_cid != 0)) + if (uni_hid_parser_switch2_is_joycon_pair_secondary(bp_device)) + goto after_stall_check; + if (bp32_is_joycon_pair_secondary(bp_device)) + goto after_stall_check; + if (!skip_stall_disconnect) { - if (s_last_bt_input_ms[i] != 0 && (now_ms - s_last_bt_input_ms[i]) > BT_INPUT_STALL_DISCONNECT_MS) + const int stall_idx = bp32_get_gamepad_output_idx(bp_device); + const unsigned stall_slot = + (stall_idx >= 0 && stall_idx < static_cast(MAX_GAMEPADS)) + ? static_cast(stall_idx) + : static_cast(i); + if (s_last_bt_input_ms[stall_slot] != 0 && + (now_ms - s_last_bt_input_ms[stall_slot]) > BT_INPUT_STALL_DISCONNECT_MS) { printf("[Bluepad32] BT input stalled (%u ms); forcing disconnect (slot %u)\n", - static_cast(now_ms - s_last_bt_input_ms[i]), static_cast(i)); + static_cast(now_ms - s_last_bt_input_ms[stall_slot]), static_cast(i)); uni_hid_device_disconnect(bp_device); continue; } } after_stall_check: - Gamepad::PadOut gp_out = bt_devices_[i].gamepad->get_pad_out(); + const int out_i = bp32_get_gamepad_output_idx(bp_device); + const int gp_idx = + (out_i >= 0 && out_i < static_cast(MAX_GAMEPADS)) ? out_i : static_cast(i); + if (gp_idx < 0 || gp_idx >= static_cast(MAX_GAMEPADS) || bt_devices_[gp_idx].gamepad == nullptr) + continue; + + Gamepad::PadOut gp_out = bt_devices_[gp_idx].gamepad->get_pad_out(); if (bp_device->controller_type == CONTROLLER_TYPE_XBoxOneController && bp_device->hids_cid != 0 && gp_out.rumble_l == 0 && gp_out.rumble_r == 0) { @@ -225,13 +294,33 @@ static void send_feedback_cb(btstack_timer_source *ts) s_xbox_ble_ka_last_ms[i] = now_ms; } } + if (uni_hid_parser_switch2_is_ble_device(bp_device) && uni_hid_parser_switch2_is_ready(bp_device) && + !uni_hid_parser_switch2_is_joycon_pair_secondary(bp_device) && + !uni_hid_parser_switch2_keepalive_timer_active(bp_device) && + gp_out.rumble_l == 0 && gp_out.rumble_r == 0) + { + const uint32_t last_ka = s_sw2_ble_ka_last_ms[i]; + if (last_ka == 0u || (now_ms - last_ka) >= SW2_BLE_KEEPALIVE_MS) + { + uni_hid_parser_switch2_send_keepalive(bp_device); + s_sw2_ble_ka_last_ms[i] = now_ms; + } + } if (gp_out.rumble_l > 0 || gp_out.rumble_r > 0) { if (bp_device->controller_type == CONTROLLER_TYPE_PS4Controller && now_ms < s_ps4_rumble_ok_ms[i]) ; - else + else if (!bp32_is_joycon_pair_secondary(bp_device)) + { set_rumble(bp_device, static_cast(FEEDBACK_TIME_MS), gp_out.rumble_l, gp_out.rumble_r); + const int partner = bp32_get_pair_partner_idx(bp_device); + if (partner >= 0 && partner < CONFIG_BLUEPAD32_MAX_DEVICES) { + uni_hid_device_t* pd = uni_hid_device_get_instance_for_idx(partner); + if (pd) + set_rumble(pd, static_cast(FEEDBACK_TIME_MS), gp_out.rumble_l, gp_out.rumble_r); + } + } } } @@ -272,6 +361,7 @@ static void init_complete_cb(void) { uni_bt_enable_new_connections_unsafe(true); // uni_bt_del_keys_unsafe(); uni_property_dump_all(); + OGXM_LOG("BT: stack ready — BR/EDR inquiry + BLE scan (hold Pro 2 SYNC to pair)\n"); } static uni_error_t device_discovered_cb(bd_addr_t addr, const char* name, uint16_t cod, uint8_t rssi) { @@ -287,12 +377,18 @@ static uni_error_t device_discovered_cb(bd_addr_t addr, const char* name, uint16 } static void device_connected_cb(uni_hid_device_t* device) { + if (device == nullptr) { + return; + } + if (uni_hid_parser_switch2_is_ble_device(device)) { + OGXM_LOG("SW2: connected pid=0x%04x — waiting for encryption/GATT\n", device->product_id); + } } /** CYW43: resume OGX BLE advertising when no Classic (BR/EDR) gamepad remains connected. */ static void ogxm_resume_ble_ads_if_no_acl_pad(int disconnected_idx) { #if defined(CONFIG_TARGET_PICO_W) - for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { if (i == static_cast(disconnected_idx)) continue; if (!bt_devices_[i].connected) @@ -312,7 +408,7 @@ static void maybe_restart_bredr_inquiry_after_disconnect(int disconnected_idx) { #if defined(CONFIG_TARGET_PICO_W) if (!uni_bt_enable_new_connections_is_enabled()) return; - for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { if (i == static_cast(disconnected_idx)) continue; if (!bt_devices_[i].connected) @@ -329,13 +425,17 @@ static void maybe_restart_bredr_inquiry_after_disconnect(int disconnected_idx) { static void device_disconnected_cb(uni_hid_device_t* device) { int idx = uni_hid_device_get_idx_for_instance(device); - if (idx >= MAX_GAMEPADS || idx < 0) { + if (idx >= CONFIG_BLUEPAD32_MAX_DEVICES || idx < 0) { return; } + if (uni_hid_parser_switch2_is_ble_device(device)) { + OGXM_LOG("SW2: disconnected slot %d\n", idx); + } + bt_devices_[idx].connected = false; bool any_other_connected = false; - for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { if (bt_devices_[i].connected) { any_other_connected = true; break; @@ -346,6 +446,7 @@ static void device_disconnected_cb(uni_hid_device_t* device) { #endif s_last_bt_input_ms[idx] = 0; s_xbox_ble_ka_last_ms[idx] = 0; + s_sw2_ble_ka_last_ms[idx] = 0; s_bt_disconnect_combo_grace_until_ms[idx] = 0; s_ps4_rumble_ok_ms[idx] = 0; prev_touchpad_clicked_[idx] = false; @@ -396,38 +497,60 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { return UNI_ERROR_INVALID_CONTROLLER; int idx = uni_hid_device_get_idx_for_instance(device); - if (idx >= MAX_GAMEPADS || idx < 0) { + if (idx < 0 || idx >= CONFIG_BLUEPAD32_MAX_DEVICES) { return UNI_ERROR_SUCCESS; } + const int out_idx = bp32_get_gamepad_output_idx(device); + bt_devices_[idx].connected = true; +#if defined(CONFIG_OGXM_DEBUG) + if (uni_hid_parser_switch2_is_ble_device(device)) { + OGXM_LOG("SW2: READY slot %d pid=0x%04x out=%d — input active\n", idx, device->product_id, out_idx); + } else if (bp32_is_switch_joycon(device)) { + OGXM_LOG("SW1: READY slot %d Joy-Con out=%d — input active\n", idx, out_idx); + } +#endif #if defined(CONFIG_TARGET_PICO_W) && defined(CONFIG_EN_USB_HOST) s_bt_any_connected_cached.store(true, std::memory_order_release); #endif #if defined(CONFIG_TARGET_PICO_W) if (gap_get_connection_type(device->conn.handle) == GAP_CONNECTION_ACL) { - uni_bt_bredr_scan_stop(); gap_advertisements_enable(0); + if (uni_hid_parser_switch_solo_needs_partner(device)) { + /* Solo Joy-Con (L or R): keep inquiry + page scan for the partner; pause BLE scan. */ + uni_bt_le_scan_stop(); + gap_connectable_control(1); + uni_bt_bredr_scan_start(); + } else if (!uni_hid_parser_switch_any_awaiting_partner()) { + uni_bt_bredr_scan_stop(); + } } #endif const uint32_t tnow = to_ms_since_boot(get_absolute_time()); - s_last_bt_input_ms[idx] = tnow; - s_bt_disconnect_combo_grace_until_ms[idx] = tnow + 3500u; + const int pad_idx = (out_idx >= 0 && out_idx < static_cast(MAX_GAMEPADS)) + ? out_idx + : (idx < static_cast(MAX_GAMEPADS) ? idx : 0); + s_last_bt_input_ms[pad_idx] = tnow; + s_bt_disconnect_combo_grace_until_ms[pad_idx] = tnow + 3500u; if (device->controller_type == CONTROLLER_TYPE_PS4Controller) - s_ps4_rumble_ok_ms[idx] = tnow + 6000u; + s_ps4_rumble_ok_ms[pad_idx] = tnow + 6000u; /* Xbox BLE: 0 = send keepalive on next feedback tick (wakes Series/SW2 pad link immediately). */ if (device->controller_type == CONTROLLER_TYPE_XBoxOneController && device->hids_cid != 0) s_xbox_ble_ka_last_ms[idx] = 0; + if (uni_hid_parser_switch2_is_ble_device(device)) + s_sw2_ble_ka_last_ms[idx] = 0; // Set controller player LED to match slot (e.g. Wii U: LED 1 = player 1, LED 2 = player 2). - // Same as Bluepad32 NINA platform: set_player_leds(d, BIT(idx)). - if (device->report_parser.set_player_leds != nullptr) { - device->report_parser.set_player_leds(device, static_cast(1u << idx)); + // Joy-Con pairs set LEDs in the parser when merged; skip secondary to avoid player-2 LED. + if (device->report_parser.set_player_leds != nullptr && + !bp32_is_joycon_pair_secondary(device)) { + device->report_parser.set_player_leds(device, static_cast(1u << pad_idx)); } // PS5: start with adaptive triggers off; touchpad click toggles them. if (device->controller_type == CONTROLLER_TYPE_PS5Controller) { - adaptive_trigger_enabled_[idx] = false; + adaptive_trigger_enabled_[pad_idx] = false; ds5_adaptive_trigger_effect_t off = ds5_new_adaptive_trigger_effect_off(); ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_LEFT, &off); ds5_set_adaptive_trigger_effect(device, UNI_ADAPTIVE_TRIGGER_TYPE_RIGHT, &off); @@ -457,8 +580,12 @@ static void oob_event_cb(uni_platform_oob_event_t event, void* data) { // Set to 1 to print all Bluepad32 controller inputs to UART (only when state changes) #ifndef BLUEPAD32_UART_LOG_INPUT +#if defined(CONFIG_OGXM_DEBUG) +#define BLUEPAD32_UART_LOG_INPUT 1 +#else #define BLUEPAD32_UART_LOG_INPUT 0 #endif +#endif static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* controller) { static uni_gamepad_t prev_uni_gp[MAX_GAMEPADS] = {}; @@ -468,14 +595,23 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr } uni_gamepad_t *uni_gp = &controller->gamepad; - int idx = uni_hid_device_get_idx_for_instance(device); - if (idx >= 0 && idx < static_cast(MAX_GAMEPADS)) - s_last_bt_input_ms[static_cast(idx)] = to_ms_since_boot(get_absolute_time()); + const int bt_slot = uni_hid_device_get_idx_for_instance(device); + int idx = bp32_get_gamepad_output_idx(device); + if (idx < 0) + idx = bt_slot; + if (idx < 0 || idx >= static_cast(MAX_GAMEPADS)) + return; + { + const uint32_t now_cb = to_ms_since_boot(get_absolute_time()); + s_last_bt_input_ms[static_cast(idx)] = now_cb; + if (bt_slot >= 0 && bt_slot < CONFIG_BLUEPAD32_MAX_DEVICES && bt_slot != idx) + s_last_bt_input_ms[static_cast(bt_slot)] = now_cb; + } #if BLUEPAD32_UART_LOG_INPUT { bool changed = std::memcmp(uni_gp, &prev_uni_gp[idx], sizeof(uni_gamepad_t)) != 0; - if (changed) { + if (changed && device->controller_type != CONTROLLER_TYPE_Switch2ProController) { printf("[BP32 idx=%d] dpad=0x%02x btns=0x%04x misc=0x%02x brake=%u throttle=%u " "Lx=%d Ly=%d Rx=%d Ry=%d\n", idx, (unsigned)uni_gp->dpad, (unsigned)uni_gp->buttons, (unsigned)uni_gp->misc_buttons, @@ -562,7 +698,7 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr // Require combo to be held for ~500ms (assuming ~60Hz callback rate, ~30 frames) if (disconnect_combo_hold_time[idx] >= 30) { printf("[BP32] Disconnect combo detected, disconnecting controller %d\n", idx); - uni_hid_device_disconnect(device); + bp32_disconnect_controller_and_joycon_partner(device); disconnect_combo_hold_time[idx] = 0; return; // Don't process further input after disconnect } @@ -592,8 +728,37 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad->scale_joystick_l<10>(uni_gp->axis_x, uni_gp->axis_y); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad->scale_joystick_r<10>(uni_gp->axis_rx, uni_gp->axis_ry); + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_NONE; + switch (device->controller_type) { + case CONTROLLER_TYPE_PS4Controller: + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_DS4; + break; + case CONTROLLER_TYPE_PS5Controller: + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_DS5; + break; + case CONTROLLER_TYPE_SwitchProController: + case CONTROLLER_TYPE_Switch2ProController: + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_SWITCH_PRO; + break; + default: + break; + } + if (gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_NONE) { + for (int i = 0; i < 3; i++) { + gp_in.accel[i] = uni_gp->accel[i]; + gp_in.gyro[i] = uni_gp->gyro[i]; + } + } + gamepad->set_pad_in_from_bluetooth(gp_in); +#if BLUEPAD32_UART_LOG_INPUT + if (idx >= 0 && idx < static_cast(MAX_GAMEPADS) && + device->controller_type != CONTROLLER_TYPE_Switch2ProController) { + std::memcpy(&prev_uni_gp[idx], uni_gp, sizeof(uni_gamepad_t)); + } +#endif + // PS5: defer adaptive trigger send to main loop so callback never does l2cap_send (reduces input lag) if (device->controller_type == CONTROLLER_TYPE_PS5Controller && idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { bool touchpad_clicked = (uni_gp->misc_buttons & MISC_BUTTON_CAPTURE) != 0; @@ -603,12 +768,6 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr } prev_touchpad_clicked_[idx] = touchpad_clicked; } - -#if BLUEPAD32_UART_LOG_INPUT - if (idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { - std::memcpy(&prev_uni_gp[idx], uni_gp, sizeof(uni_gamepad_t)); - } -#endif } const uni_property_t* get_property_cb(uni_property_idx_t idx) @@ -672,7 +831,7 @@ void wired_usb_takeover_disconnect_bt() { * we do not treat BT as active and tuh_deinit() wired USB during the disconnect window. */ s_bt_any_connected_cached.store(false, std::memory_order_release); #endif - for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { + for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { uni_bt_disconnect_device_safe(i); } uni_bt_enable_new_connections_safe(false); diff --git a/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp b/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp index 760b3ded..63da26fa 100644 --- a/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp +++ b/Firmware/RP2040/src/Board/board_api_private/board_api_bt.cpp @@ -31,7 +31,6 @@ void set_led(bool state) { return; } cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, state ? 1 : 0); - OGXM_LOG(state ? "board_api_bt: set_led ON\n" : "board_api_bt: set_led OFF\n"); } } // namespace board_api_bt diff --git a/Firmware/RP2040/src/Board/ogxm_log.cpp b/Firmware/RP2040/src/Board/ogxm_log.cpp index b63cbb35..92a54704 100644 --- a/Firmware/RP2040/src/Board/ogxm_log.cpp +++ b/Firmware/RP2040/src/Board/ogxm_log.cpp @@ -20,6 +20,7 @@ std::ostream& operator<<(std::ostream& os, DeviceDriverType type) { case DeviceDriverType::XBOXOG_XR: os << "XBOXOG_XR"; break; case DeviceDriverType::XINPUT: os << "XINPUT"; break; case DeviceDriverType::PS3: os << "PS3"; break; + case DeviceDriverType::PS4: os << "PS4"; break; case DeviceDriverType::DINPUT: os << "DINPUT"; break; case DeviceDriverType::PSCLASSIC: os << "PSCLASSIC"; break; case DeviceDriverType::SWITCH: os << "SWITCH"; break; diff --git a/Firmware/RP2040/src/Descriptors/PS4Usb.h b/Firmware/RP2040/src/Descriptors/PS4Usb.h new file mode 100644 index 00000000..adb6fd35 --- /dev/null +++ b/Firmware/RP2040/src/Descriptors/PS4Usb.h @@ -0,0 +1,126 @@ +#ifndef _PS4_USB_DESCRIPTORS_H_ +#define _PS4_USB_DESCRIPTORS_H_ + +#include + +/* + * USB IDs and 467-byte HID report descriptor captured from Brook → DS4 (CUH-ZCT1x) mode + * (see Resources/Brook/brook-lsusb-v.txt, brook-usbhid-dump.txt 001:032:000). + */ + +namespace PS4Usb +{ + static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 }; + static const uint8_t STRING_MANUFACTURER[] = "Sony Computer Entertainment"; + static const uint8_t STRING_PRODUCT[] = "Wireless Controller"; + static const uint8_t STRING_VERSION[] = "1.0"; + + static const uint8_t *STRING_DESCRIPTORS[] __attribute__((unused)) = + { + STRING_LANGUAGE, + STRING_MANUFACTURER, + STRING_PRODUCT, + STRING_VERSION + }; + + static const uint8_t DEVICE_DESCRIPTORS[] = + { + 0x12, + 0x01, + 0x00, 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x4C, 0x05, + 0xC4, 0x05, + 0x00, 0x01, + 0x01, + 0x02, + 0x00, + 0x01, + }; + + static const uint8_t REPORT_DESCRIPTORS[] = + { + 0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, + 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x04, 0x81, 0x02, 0x09, 0x39, 0x15, 0x00, 0x25, + 0x07, 0x35, 0x00, 0x46, 0x3b, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x65, 0x00, + 0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0e, 0x81, 0x02, + 0x06, 0x00, 0xff, 0x09, 0x20, 0x75, 0x06, 0x95, 0x01, 0x15, 0x00, 0x25, 0x7f, 0x81, 0x02, 0x05, + 0x01, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x02, 0x81, 0x02, + 0x06, 0x00, 0xff, 0x09, 0x21, 0x95, 0x36, 0x81, 0x02, 0x85, 0x05, 0x09, 0x22, 0x95, 0x1f, 0x91, + 0x02, 0x85, 0x04, 0x09, 0x23, 0x95, 0x24, 0xb1, 0x02, 0x85, 0x02, 0x09, 0x24, 0x95, 0x24, 0xb1, + 0x02, 0x85, 0x08, 0x09, 0x25, 0x95, 0x03, 0xb1, 0x02, 0x85, 0x10, 0x09, 0x26, 0x95, 0x04, 0xb1, + 0x02, 0x85, 0x11, 0x09, 0x27, 0x95, 0x02, 0xb1, 0x02, 0x85, 0x12, 0x06, 0x02, 0xff, 0x09, 0x21, + 0x95, 0x0f, 0xb1, 0x02, 0x85, 0x13, 0x09, 0x22, 0x95, 0x16, 0xb1, 0x02, 0x85, 0x14, 0x06, 0x05, + 0xff, 0x09, 0x20, 0x95, 0x10, 0xb1, 0x02, 0x85, 0x15, 0x09, 0x21, 0x95, 0x2c, 0xb1, 0x02, 0x06, + 0x80, 0xff, 0x85, 0x80, 0x09, 0x20, 0x95, 0x06, 0xb1, 0x02, 0x85, 0x81, 0x09, 0x21, 0x95, 0x06, + 0xb1, 0x02, 0x85, 0x82, 0x09, 0x22, 0x95, 0x05, 0xb1, 0x02, 0x85, 0x83, 0x09, 0x23, 0x95, 0x01, + 0xb1, 0x02, 0x85, 0x84, 0x09, 0x24, 0x95, 0x04, 0xb1, 0x02, 0x85, 0x85, 0x09, 0x25, 0x95, 0x06, + 0xb1, 0x02, 0x85, 0x86, 0x09, 0x26, 0x95, 0x06, 0xb1, 0x02, 0x85, 0x87, 0x09, 0x27, 0x95, 0x23, + 0xb1, 0x02, 0x85, 0x88, 0x09, 0x28, 0x95, 0x22, 0xb1, 0x02, 0x85, 0x89, 0x09, 0x29, 0x95, 0x02, + 0xb1, 0x02, 0x85, 0x90, 0x09, 0x30, 0x95, 0x05, 0xb1, 0x02, 0x85, 0x91, 0x09, 0x31, 0x95, 0x03, + 0xb1, 0x02, 0x85, 0x92, 0x09, 0x32, 0x95, 0x03, 0xb1, 0x02, 0x85, 0x93, 0x09, 0x33, 0x95, 0x0c, + 0xb1, 0x02, 0x85, 0xa0, 0x09, 0x40, 0x95, 0x06, 0xb1, 0x02, 0x85, 0xa1, 0x09, 0x41, 0x95, 0x01, + 0xb1, 0x02, 0x85, 0xa2, 0x09, 0x42, 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa3, 0x09, 0x43, 0x95, 0x30, + 0xb1, 0x02, 0x85, 0xa4, 0x09, 0x44, 0x95, 0x0d, 0xb1, 0x02, 0x85, 0xa5, 0x09, 0x45, 0x95, 0x15, + 0xb1, 0x02, 0x85, 0xa6, 0x09, 0x46, 0x95, 0x15, 0xb1, 0x02, 0x85, 0xf0, 0x09, 0x47, 0x95, 0x3f, + 0xb1, 0x02, 0x85, 0xf1, 0x09, 0x48, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf2, 0x09, 0x49, 0x95, 0x0f, + 0xb1, 0x02, 0x85, 0xa7, 0x09, 0x4a, 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa8, 0x09, 0x4b, 0x95, 0x01, + 0xb1, 0x02, 0x85, 0xa9, 0x09, 0x4c, 0x95, 0x08, 0xb1, 0x02, 0x85, 0xaa, 0x09, 0x4e, 0x95, 0x01, + 0xb1, 0x02, 0x85, 0xab, 0x09, 0x4f, 0x95, 0x39, 0xb1, 0x02, 0x85, 0xac, 0x09, 0x50, 0x95, 0x39, + 0xb1, 0x02, 0x85, 0xad, 0x09, 0x51, 0x95, 0x0b, 0xb1, 0x02, 0x85, 0xae, 0x09, 0x52, 0x95, 0x01, + 0xb1, 0x02, 0x85, 0xaf, 0x09, 0x53, 0x95, 0x02, 0xb1, 0x02, 0x85, 0xb0, 0x09, 0x54, 0x95, 0x3f, + 0xb1, 0x02, 0xc0, + }; + + static_assert(sizeof(REPORT_DESCRIPTORS) == 467, "Brook DS4 report descriptor length"); + + static const uint8_t CONFIGURATION_DESCRIPTORS[] = + { + 0x09, + 0x02, + 0x29, 0x00, + 0x01, + 0x01, + 0x00, + 0xA0, + 0xFA, + + 0x09, + 0x04, + 0x00, + 0x00, + 0x02, + 0x03, + 0x00, + 0x00, + 0x00, + + 0x09, + 0x21, + 0x11, 0x01, + 0x00, + 0x01, + 0x22, + 0xD3, 0x01, + + 0x07, + 0x05, + 0x84, + 0x03, + 0x40, 0x00, + 0x05, + + 0x07, + 0x05, + 0x03, + 0x03, + 0x40, 0x00, + 0x05, + }; + +} // namespace PS4Usb + +#endif diff --git a/Firmware/RP2040/src/Gamepad/Gamepad.h b/Firmware/RP2040/src/Gamepad/Gamepad.h index d3f98048..73f59b52 100644 --- a/Firmware/RP2040/src/Gamepad/Gamepad.h +++ b/Firmware/RP2040/src/Gamepad/Gamepad.h @@ -96,6 +96,13 @@ class Gamepad #pragma pack(push, 1) struct PadIn { + /** IMU for PS3 Sixaxis mapping: only DS4/DS5/Switch Pro paths set this (see motion_source). */ + static constexpr uint8_t MOTION_SRC_NONE = 0; + static constexpr uint8_t MOTION_SRC_DS4 = 1; + static constexpr uint8_t MOTION_SRC_DS5 = 2; + static constexpr uint8_t MOTION_SRC_SWITCH_PRO = 3; + static constexpr uint8_t MOTION_SRC_DS5_USB = 4; + uint8_t dpad; uint16_t buttons; uint8_t trigger_l; @@ -105,7 +112,13 @@ class Gamepad int16_t joystick_rx; int16_t joystick_ry; uint8_t analog[10]; - + + /** Bluepad: int32 accel (DS4 units/g) and gyro (DS4 rate units); USB PS5: raw int16 widened. */ + int32_t accel[3]; + int32_t gyro[3]; + /** If MOTION_SRC_NONE, PS3 mode leaves Sixaxis at neutral; else maps to DS3 report. */ + uint8_t motion_source; + PadIn() { std::memset(this, 0, sizeof(PadIn)); @@ -159,9 +172,10 @@ class Gamepad { mutex_enter_blocking(&pad_in_mutex_); /* Bluetooth HID runs on Core1; never block there on this mutex (would stall HCI/L2CAP). - * Latest BT report is staged lock-free and merged here on Core0. */ - if (bt_pad_staged_.exchange(false, std::memory_order_acq_rel)) { - const PadIn& p = bt_pending_pad_; + * Latest BT reports are staged lock-free (2 slots) and merged here on Core0. */ + while (bt_pad_staged_count_.load(std::memory_order_acquire) > 0) { + const unsigned ri = bt_pad_staged_read_.load(std::memory_order_relaxed) % BT_PAD_STAGING_SLOTS; + const PadIn& p = bt_pending_pads_[ri]; if (pad_in_count_ < PAD_IN_QUEUE_SIZE) { pad_in_queue_[pad_in_tail_] = p; pad_in_tail_ = (pad_in_tail_ + 1) % PAD_IN_QUEUE_SIZE; @@ -171,6 +185,8 @@ class Gamepad pad_in_queue_[pad_in_tail_] = p; pad_in_tail_ = (pad_in_tail_ + 1) % PAD_IN_QUEUE_SIZE; } + bt_pad_staged_read_.store((ri + 1) % BT_PAD_STAGING_SLOTS, std::memory_order_relaxed); + bt_pad_staged_count_.fetch_sub(1, std::memory_order_acq_rel); new_pad_in_.store(true); } PadIn pad_in; @@ -253,8 +269,15 @@ class Gamepad /** Bluetooth (Core1): never blocks on Core0 — avoids stalling the BT stack in HID callbacks. */ inline void set_pad_in_from_bluetooth(const PadIn& pad_in) { - bt_pending_pad_ = pad_in; - bt_pad_staged_.store(true, std::memory_order_release); + if (bt_pad_staged_count_.load(std::memory_order_acquire) >= BT_PAD_STAGING_SLOTS) { + const unsigned drop = bt_pad_staged_read_.load(std::memory_order_relaxed) % BT_PAD_STAGING_SLOTS; + bt_pad_staged_read_.store((drop + 1) % BT_PAD_STAGING_SLOTS, std::memory_order_relaxed); + bt_pad_staged_count_.fetch_sub(1, std::memory_order_acq_rel); + } + const unsigned wi = bt_pad_staged_write_.load(std::memory_order_relaxed) % BT_PAD_STAGING_SLOTS; + bt_pending_pads_[wi] = pad_in; + bt_pad_staged_write_.store((wi + 1) % BT_PAD_STAGING_SLOTS, std::memory_order_release); + bt_pad_staged_count_.fetch_add(1, std::memory_order_release); new_pad_in_.store(true, std::memory_order_release); } @@ -279,7 +302,9 @@ class Gamepad inline void reset_pad_in() { - bt_pad_staged_.store(false, std::memory_order_relaxed); + bt_pad_staged_write_.store(0, std::memory_order_relaxed); + bt_pad_staged_read_.store(0, std::memory_order_relaxed); + bt_pad_staged_count_.store(0, std::memory_order_relaxed); mutex_enter_blocking(&pad_in_mutex_); pad_in_head_ = 0; pad_in_tail_ = 0; @@ -399,10 +424,13 @@ class Gamepad } static constexpr unsigned PAD_IN_QUEUE_SIZE = 8; + static constexpr unsigned BT_PAD_STAGING_SLOTS = 2; private: - PadIn bt_pending_pad_{}; - std::atomic bt_pad_staged_{false}; + PadIn bt_pending_pads_[BT_PAD_STAGING_SLOTS]{}; + std::atomic bt_pad_staged_write_{0}; + std::atomic bt_pad_staged_read_{0}; + std::atomic bt_pad_staged_count_{0}; mutex_t pad_in_mutex_; mutex_t pad_out_mutex_; mutex_t chatpad_in_mutex_; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h index 9b8842c8..53d7b3cb 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h @@ -20,6 +20,7 @@ enum class DeviceDriverType : uint8_t GAMECUBE, // GameCube controller over GPIO (single wire; no USB device) DREAMCAST, // Dreamcast controller over Maple Bus GPIO (no USB device; output/input to console) N64, // N64 controller over GPIO (single wire; no USB device; output to N64 console) + PS4, // DualShock 4 USB HID (CUH-ZCT1x-class descriptor) WEBAPP = 100, UART_BRIDGE }; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp index 467b838f..9cc899e9 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp @@ -4,6 +4,84 @@ #include "pico/time.h" #include "USBDevice/DeviceDriver/PS3/PS3.h" +namespace { + +/* + * DS3 Sixaxis wire format (Linux drivers/hid/hid-sony.c): bytes 41–48 are MSB-first 16-bit values; + * accel layout X @ 41–42, Z @ 43–44, Y @ 45–46; kernel uses 10-bit–style center 511. + * PadIn accel/gyro follow Bluepad DS4 units (accel, gyro[2] for yaw rate). + */ +void apply_pad_imu_to_ps3_sixaxis(PS3::InReport& rep, const Gamepad::PadIn& gp_in) +{ + constexpr int32_t kDs4UnitsPerG = 8192; + constexpr int32_t kDs3CountsPerG = 113; + constexpr int32_t kGyroPerDps = 1024; + + int32_t ax = gp_in.accel[0]; + int32_t ay = gp_in.accel[1]; + int32_t az = gp_in.accel[2]; + + auto iabs = [](int32_t v) -> int64_t { + const int64_t w = static_cast(v); + return w >= 0 ? w : -w; + }; + const int64_t l1 = iabs(ax) + iabs(ay) + iabs(az); + constexpr int64_t kNearZeroL1 = 512; + if (l1 < kNearZeroL1) { + ax = 0; + ay = 0; + az = kDs4UnitsPerG; + } + + auto ds4_to_ds3_delta = [](int32_t ds4_units) -> int32_t { + return static_cast((static_cast(ds4_units) * kDs3CountsPerG) / kDs4UnitsPerG); + }; + + auto encode_accel = [&ds4_to_ds3_delta](int32_t ds4_units, bool kernel_inverts) -> uint16_t { + int32_t d = ds4_to_ds3_delta(ds4_units); + if (d > 511) { + d = 511; + } + if (d < -512) { + d = -512; + } + int32_t raw = kernel_inverts ? (511 - d) : (511 + d); + if (raw < 0) { + raw = 0; + } + if (raw > 1023) { + raw = 1023; + } + return static_cast(raw); + }; + + const uint16_t raw_x = encode_accel(ax, false); + const uint16_t raw_z_wire = encode_accel(az, true); + const uint16_t raw_y_wire = encode_accel(ay, true); + + rep.acceler_x = __builtin_bswap16(raw_x); + rep.acceler_y = __builtin_bswap16(raw_z_wire); + rep.acceler_z = __builtin_bswap16(raw_y_wire); + + int32_t gz = static_cast((static_cast(gp_in.gyro[2]) * 511) / (kGyroPerDps * 64)); + if (gz > 511) { + gz = 511; + } + if (gz < -512) { + gz = -512; + } + int32_t raw_g_i = 511 + gz; + if (raw_g_i < 0) { + raw_g_i = 0; + } + if (raw_g_i > 1023) { + raw_g_i = 1023; + } + rep.gyro_z = __builtin_bswap16(static_cast(raw_g_i)); +} + +} // namespace + void PS3Device::initialize() { class_driver_ = @@ -54,9 +132,7 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) tud_remote_wakeup(); } - // Build report only when we're about to send so the console gets the freshest state - // (helps Home button and analog timing with DS4/DS5 over Bluetooth). - if (tud_hid_ready()) + /* Rebuild report_in_ every frame so GET_REPORT and IMU stay current; send on HID IN when ready. */ { Gamepad::PadIn gp_in = gamepad.get_pad_in(); report_in_ = PS3::InReport(); @@ -166,6 +242,15 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) report_in_.l1_axis = (gp_in.buttons & Gamepad::BUTTON_LB) ? 0xFF : 0; } + /* Sixaxis only when IMU is parsed for DS4/DS5 BT or Switch Pro (not other pads or USB PS5). */ + if (gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_DS4 || + gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_DS5 || + gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_SWITCH_PRO) { + apply_pad_imu_to_ps3_sixaxis(report_in_, gp_in); + } + } + + if (tud_hid_ready()) { tud_hid_report(0, reinterpret_cast(&report_in_), sizeof(PS3::InReport)); } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp new file mode 100644 index 00000000..757a0919 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp @@ -0,0 +1,312 @@ +#include +#include + +#include "pico/time.h" +#include "USBDevice/DeviceDriver/PS4/PS4.h" +#include "Descriptors/PS4Usb.h" + +namespace { + +constexpr uint8_t kReportIdIn = 0x01; + +uint8_t joystick_to_u8(int16_t value, int16_t deadzone) +{ + constexpr uint8_t center = PS4::JOYSTICK_MID; + if (value > -deadzone && value < deadzone) { + return center; + } + int32_t in = static_cast(value) + 32768; + int32_t scaled = (in * 255 + 32768) / 65535; + if (scaled < 0) { + scaled = 0; + } + if (scaled > 255) { + scaled = 255; + } + return static_cast(scaled); +} + +/* Brook-style scaling (gyro/8, accel/64). Truncating division zeros small Bluetooth IMU samples; + * use symmetric rounding so light motion still reaches the host. */ +int16_t scale_i32_to_i16_rounded(int32_t v, int32_t div) +{ + if (div <= 0) { + div = 1; + } + const int64_t num = static_cast(v); + const int64_t d = static_cast(div); + const int64_t q = (num >= 0) ? (num + d / 2) / d : (num - d / 2) / d; + if (q > 32767) { + return 32767; + } + if (q < -32768) { + return -32768; + } + return static_cast(q); +} + +/* Brook capture: int16 LE gyro @ 13–18, accel @ 19–24 in report id 1. IMU is only filled from + * Bluetooth (Bluepad): DS4 / DualSense / Switch Pro — not USB host controllers. */ +void apply_pad_imu_to_ps4_report(std::array& rep, const Gamepad::PadIn& gp_in) +{ + if (gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_DS4 && + gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_DS5 && + gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_SWITCH_PRO) { + return; + } + + const int16_t gx = scale_i32_to_i16_rounded(gp_in.gyro[0], 8); + const int16_t gy = scale_i32_to_i16_rounded(gp_in.gyro[1], 8); + const int16_t gz = scale_i32_to_i16_rounded(gp_in.gyro[2], 8); + const int16_t ax = scale_i32_to_i16_rounded(gp_in.accel[0], 64); + const int16_t ay = scale_i32_to_i16_rounded(gp_in.accel[1], 64); + const int16_t az = scale_i32_to_i16_rounded(gp_in.accel[2], 64); + + std::memcpy(&rep[13], &gx, 2); + std::memcpy(&rep[15], &gy, 2); + std::memcpy(&rep[17], &gz, 2); + std::memcpy(&rep[19], &ax, 2); + std::memcpy(&rep[21], &ay, 2); + std::memcpy(&rep[23], &az, 2); +} + +} // namespace + +void PS4Device::initialize() +{ + class_driver_ = { + .name = TUD_DRV_NAME("PS4"), + .init = hidd_init, + .deinit = hidd_deinit, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL + }; + std::memset(report_in_.data(), 0, report_in_.size()); + report_in_[0] = kReportIdIn; + report_in_[1] = report_in_[2] = report_in_[3] = report_in_[4] = PS4::JOYSTICK_MID; + report_out_.report_id = 0x05; +} + +void PS4Device::process(const uint8_t idx, Gamepad& gamepad) +{ + (void)idx; + { + static bool start_wake_sent = false; + static bool start_held = false; + static absolute_time_t start_hold_begin = { 0 }; + Gamepad::PadIn gp_wake = gamepad.get_pad_in(); + bool start_pressed = (gp_wake.buttons & Gamepad::BUTTON_START) != 0; + if (start_pressed) { + if (!start_held) { + start_held = true; + start_hold_begin = get_absolute_time(); + } else { + uint64_t hold_ms = to_ms_since_boot(get_absolute_time()) - to_ms_since_boot(start_hold_begin); + if (hold_ms >= 3000 && tud_suspended() && !start_wake_sent) { + tud_remote_wakeup(); + start_wake_sent = true; + } + } + } else { + start_held = false; + start_wake_sent = false; + } + if (tud_suspended() && (gp_wake.buttons & Gamepad::BUTTON_SYS)) { + tud_remote_wakeup(); + } + } + + Gamepad::PadIn gp_in = gamepad.get_pad_in(); + std::memset(report_in_.data(), 0, report_in_.size()); + report_in_[0] = kReportIdIn; + + constexpr int16_t DEADZONE = 512; + report_in_[1] = joystick_to_u8(gp_in.joystick_lx, DEADZONE); + report_in_[2] = joystick_to_u8(gp_in.joystick_ly, DEADZONE); + report_in_[3] = joystick_to_u8(gp_in.joystick_rx, DEADZONE); + report_in_[4] = joystick_to_u8(gp_in.joystick_ry, DEADZONE); + + uint8_t b0 = PS4::Buttons0::DPAD_CENTER; + switch (gp_in.dpad) + { + case Gamepad::DPAD_UP: + b0 = PS4::Buttons0::DPAD_UP; + break; + case Gamepad::DPAD_DOWN: + b0 = PS4::Buttons0::DPAD_DOWN; + break; + case Gamepad::DPAD_LEFT: + b0 = PS4::Buttons0::DPAD_LEFT; + break; + case Gamepad::DPAD_RIGHT: + b0 = PS4::Buttons0::DPAD_RIGHT; + break; + case Gamepad::DPAD_UP_RIGHT: + b0 = PS4::Buttons0::DPAD_UP_RIGHT; + break; + case Gamepad::DPAD_DOWN_RIGHT: + b0 = PS4::Buttons0::DPAD_RIGHT_DOWN; + break; + case Gamepad::DPAD_DOWN_LEFT: + b0 = PS4::Buttons0::DPAD_DOWN_LEFT; + break; + case Gamepad::DPAD_UP_LEFT: + b0 = PS4::Buttons0::DPAD_LEFT_UP; + break; + default: + break; + } + + uint8_t b1 = 0; + uint8_t b2 = 0; + + if (gp_in.buttons & Gamepad::BUTTON_X) { + b0 |= PS4::Buttons0::SQUARE; + } + if (gp_in.buttons & Gamepad::BUTTON_A) { + b0 |= PS4::Buttons0::CROSS; + } + if (gp_in.buttons & Gamepad::BUTTON_B) { + b0 |= PS4::Buttons0::CIRCLE; + } + if (gp_in.buttons & Gamepad::BUTTON_Y) { + b0 |= PS4::Buttons0::TRIANGLE; + } + if (gp_in.buttons & Gamepad::BUTTON_LB) { + b1 |= PS4::Buttons1::L1; + } + if (gp_in.buttons & Gamepad::BUTTON_RB) { + b1 |= PS4::Buttons1::R1; + } + if (gp_in.buttons & Gamepad::BUTTON_L3) { + b1 |= PS4::Buttons1::L3; + } + if (gp_in.buttons & Gamepad::BUTTON_R3) { + b1 |= PS4::Buttons1::R3; + } + if (gp_in.buttons & Gamepad::BUTTON_BACK) { + b1 |= PS4::Buttons1::SHARE; + } + if (gp_in.buttons & Gamepad::BUTTON_START) { + b1 |= PS4::Buttons1::OPTIONS; + } + if (gp_in.buttons & Gamepad::BUTTON_SYS) { + sys_button_latch_frames_ = 8; + } + if (sys_button_latch_frames_ > 0) { + b2 |= PS4::Buttons2::PS; + sys_button_latch_frames_--; + } + if (gp_in.buttons & Gamepad::BUTTON_MISC) { + b2 |= PS4::Buttons2::TP; + } + + if (gp_in.trigger_l) { + b1 |= PS4::Buttons1::L2; + } + if (gp_in.trigger_r) { + b1 |= PS4::Buttons1::R2; + } + + report_in_[5] = b0; + report_in_[6] = b1; + touch_seq_ = static_cast((touch_seq_ + 1u) & 0x3Fu); + b2 = static_cast(b2 | static_cast(static_cast(touch_seq_ << 2))); + report_in_[7] = b2; + + report_in_[8] = gp_in.trigger_l; + report_in_[9] = gp_in.trigger_r; + + frame_seq_++; + std::memcpy(&report_in_[10], &frame_seq_, sizeof(frame_seq_)); + report_in_[12] = 0; + + apply_pad_imu_to_ps4_report(report_in_, gp_in); + + if (tud_hid_ready()) { + tud_hid_report(0, report_in_.data(), static_cast(report_in_.size())); + } + + if (new_report_out_) { + Gamepad::PadOut gp_out; + gp_out.rumble_l = report_out_.motor_left; + gp_out.rumble_r = report_out_.motor_right; + gamepad.set_pad_out(gp_out); + new_report_out_ = false; + } +} + +uint16_t PS4Device::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) +{ + (void)itf; + if (report_type == HID_REPORT_TYPE_INPUT) { + if (report_id == 0 || report_id == kReportIdIn) { + const uint16_t n = static_cast(std::min(reqlen, report_in_.size())); + std::memcpy(buffer, report_in_.data(), n); + return n; + } + } else if (report_type == HID_REPORT_TYPE_FEATURE) { + std::memset(buffer, 0, reqlen); + return reqlen; + } + return 0; +} + +void PS4Device::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) +{ + (void)itf; + if (report_type != HID_REPORT_TYPE_OUTPUT) { + return; + } + uint8_t rid = report_id; + const uint8_t *buf = buffer; + uint16_t len = bufsize; + if (rid == 0 && len > 0) { + rid = buffer[0]; + len = static_cast(len - 1u); + buf = &buffer[1]; + } + if (rid == 0x05 && len >= sizeof(PS4::OutReport)) { + std::memcpy(&report_out_, buf, sizeof(PS4::OutReport)); + new_report_out_ = true; + } +} + +bool PS4Device::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +{ + (void)rhport; + (void)stage; + (void)request; + return false; +} + +const uint16_t* PS4Device::get_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + const char *value = reinterpret_cast(PS4Usb::STRING_DESCRIPTORS[index]); + return get_string_descriptor(value, index); +} + +const uint8_t* PS4Device::get_descriptor_device_cb() +{ + return PS4Usb::DEVICE_DESCRIPTORS; +} + +const uint8_t* PS4Device::get_hid_descriptor_report_cb(uint8_t itf) +{ + (void)itf; + return PS4Usb::REPORT_DESCRIPTORS; +} + +const uint8_t* PS4Device::get_descriptor_configuration_cb(uint8_t index) +{ + (void)index; + return PS4Usb::CONFIGURATION_DESCRIPTORS; +} + +const uint8_t* PS4Device::get_descriptor_device_qualifier_cb() +{ + return nullptr; +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.h new file mode 100644 index 00000000..e0b70b94 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.h @@ -0,0 +1,33 @@ +#ifndef _PS4_DEVICE_H_ +#define _PS4_DEVICE_H_ + +#include +#include + +#include "USBDevice/DeviceDriver/DeviceDriver.h" +#include "Descriptors/PS4.h" + +class PS4Device : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; + +private: + std::array report_in_{}; + PS4::OutReport report_out_{}; + bool new_report_out_{false}; + uint16_t frame_seq_{0}; + uint8_t touch_seq_{0}; + uint8_t sys_button_latch_frames_{0}; +}; + +#endif diff --git a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp index d87a8845..d6bd9c4b 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp @@ -8,6 +8,7 @@ #include "USBDevice/DeviceDriver/Wii/Wii.h" #include "USBDevice/DeviceDriver/DInput/DInput.h" #include "USBDevice/DeviceDriver/PS3/PS3.h" +#include "USBDevice/DeviceDriver/PS4/PS4.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_SB.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_XR.h" @@ -41,6 +42,11 @@ void DeviceManager::initialize_driver( DeviceDriverType driver_type, has_analog = true; device_driver_ = std::make_unique(); break; + case DeviceDriverType::PS4: + printf("PS4 Loaded\n"); + has_analog = true; + device_driver_ = std::make_unique(); + break; case DeviceDriverType::PSCLASSIC: printf("PSCLASSIC Loaded\n"); device_driver_ = std::make_unique(); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp index 15f83966..b646c007 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp @@ -92,7 +92,14 @@ void PS5Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report->joystick_lx, in_report->joystick_ly); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report->joystick_rx, in_report->joystick_ry); - + + /* DualSense USB: map motion for PS3 gadget path (same int16 sensor layout as DS5 HID). */ + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_DS5_USB; + for (int i = 0; i < 3; i++) { + gp_in.accel[i] = static_cast(static_cast(in_report->accel[i])); + gp_in.gyro[i] = static_cast(static_cast(in_report->gyro[i])); + } + gamepad.set_pad_in(gp_in); tuh_hid_receive_report(address, instance); diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.cpp b/Firmware/RP2040/src/UserSettings/UserSettings.cpp index 67dc5c88..f2c4cf8b 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/UserSettings.cpp @@ -16,6 +16,7 @@ static constexpr uint32_t BUTTON_COMBO(const uint16_t& buttons, const uint8_t& d namespace ButtonCombo { static constexpr uint32_t PS3 = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_LEFT); + static constexpr uint32_t PS4 = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB, Gamepad::DPAD_LEFT); static constexpr uint32_t DINPUT = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_RB, Gamepad::DPAD_LEFT); static constexpr uint32_t XINPUT = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_UP); static constexpr uint32_t SWITCH = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_DOWN); @@ -38,6 +39,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::XBOXOG_SB, DeviceDriverType::XINPUT, DeviceDriverType::PS3, + DeviceDriverType::PS4, DeviceDriverType::PSCLASSIC, DeviceDriverType::WIIU, DeviceDriverType::WII, @@ -62,6 +64,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::WII, DeviceDriverType::WEBAPP, DeviceDriverType::PS3, + DeviceDriverType::PS4, DeviceDriverType::PSCLASSIC, DeviceDriverType::PS1PS2, DeviceDriverType::GAMECUBE, @@ -81,7 +84,7 @@ struct ComboMap { }; // GAMECUBE and N64 are build-only (fixed driver), not in combo map; use -DOGXM_FIXED_DRIVER=GAMECUBE or N64. -static constexpr std::array BUTTON_COMBO_MAP = {{ +static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::XBOXOG, DeviceDriverType::XBOXOG }, { ButtonCombo::XBOXOG_SB, DeviceDriverType::XBOXOG_SB }, { ButtonCombo::XBOXOG_XR, DeviceDriverType::XBOXOG_XR }, @@ -91,6 +94,7 @@ static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::WIIU, DeviceDriverType::WIIU }, { ButtonCombo::XINPUT, DeviceDriverType::XINPUT }, { ButtonCombo::PS3, DeviceDriverType::PS3 }, + { ButtonCombo::PS4, DeviceDriverType::PS4 }, { ButtonCombo::PSCLASSIC, DeviceDriverType::PSCLASSIC }, { ButtonCombo::PS1PS2, DeviceDriverType::PS1PS2 }, { ButtonCombo::DREAMCAST, DeviceDriverType::DREAMCAST }, diff --git a/Firmware/RP2040/src/sdkconfig.h b/Firmware/RP2040/src/sdkconfig.h index cb3ffce6..88b61d71 100644 --- a/Firmware/RP2040/src/sdkconfig.h +++ b/Firmware/RP2040/src/sdkconfig.h @@ -6,7 +6,12 @@ // // Emulate "menuconfig" // +/* Joy-Con L+R pair needs two BLE connections while USB may still expose one player. */ +#if MAX_GAMEPADS >= 2 #define CONFIG_BLUEPAD32_MAX_DEVICES MAX_GAMEPADS +#else +#define CONFIG_BLUEPAD32_MAX_DEVICES 2 +#endif #define CONFIG_BLUEPAD32_MAX_ALLOWLIST 4 #define CONFIG_BLUEPAD32_GAP_SECURITY 1 #define CONFIG_BLUEPAD32_ENABLE_BLE_BY_DEFAULT 1 @@ -15,7 +20,11 @@ #define CONFIG_BLUEPAD32_PLATFORM_CUSTOM #define CONFIG_TARGET_PICO_W -// 2 == Info +// 2 == Info (Debug builds only; Release stays silent) +#if defined(CONFIG_OGXM_DEBUG) +#define CONFIG_BLUEPAD32_LOG_LEVEL 2 +#else #define CONFIG_BLUEPAD32_LOG_LEVEL 0 +#endif #endif //_SDK_CONFIG_H_ \ No newline at end of file diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index 1e3efe99..06bbc474 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit 1e3efe991927c2c3fee58898e0164046b357ccfc +Subproject commit 06bbc474101fba30ae96fad4c6ac8de2e9de7cec diff --git a/README.md b/README.md index 82c18014..7dd8192e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles [**Visit the web app here**](https://megacadedev.github.io/OGX-Mini-2026-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app via USB, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect via USB" in the web app and select the OGX-Mini. You can also pair via Bluetooth, no extra steps are needed in that case. -[**Join the discord here!**](https://discord.gg/guaBh9JZQ) +[**Join the discord here!**](https://discord.gg/HhZuSaSc4) ## Supported platforms - Original Xbox @@ -83,7 +83,7 @@ See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a ful - Dualshock 4 (PS4) - Dualsense (PS5) - Nintendo Switch Pro -- Nintendo Switch wired (including **Switch 2 Pro** PID `0x2069` when **wired**—see [Wired Controllers](Firmware/RP2040/docs/Wired_Controllers.md)) +- Nintendo Switch wired (including **Switch 2** family — **Pro 2** `0x2069`, **Joy-Con 2** `0x2066`/`0x2067`; **wired USB** or **Bluetooth LE** on Pico W / Pico 2 W; see [Wired Controllers](Firmware/RP2040/docs/Wired_Controllers.md) and [IMPROVEMENTS — Switch 2 BLE](Firmware/RP2040/docs/IMPROVEMENTS.md#nintendo-switch-2--bluetooth-pico-w--pico-2-w)) - Nintendo 64 Generic USB - Playstation Classic - Generic DInput @@ -110,11 +110,14 @@ Note: There are some third party controllers that can change their VID/PID, thes Full technical detail: **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)** → *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth stability*. +**Nintendo Switch 2 (Pico W / Pico 2 W):** **Switch 2 Pro** (PID **0x2069**) and **Joy-Con 2** Left (**0x2067**) / Right (**0x2066**) use a **custom BLE GATT protocol** (not standard gamepad HID). Put the controller in **pairing / SYNC** mode; the adapter discovers and connects automatically — **do not** pair it in your PC or phone Bluetooth settings first. **Joy-Con 2:** pair **Left** first, then **Right** while left stays connected — both merge into **player 1** like on a Switch. **Home** maps to **PS / Guide (SYS)** on PS3, XInput, OG Xbox, etc. Protocol credits: [Nadeflore/switch2-controllers](https://github.com/Nadeflore/switch2-controllers), [TommyWabg/switch2-controllers-windows10-gyro](https://github.com/TommyWabg/switch2-controllers-windows10-gyro), and [BlueRetro #1249](https://github.com/darthcloud/BlueRetro/issues/1249). Details: [IMPROVEMENTS — Switch 2 Bluetooth](Firmware/RP2040/docs/IMPROVEMENTS.md#nintendo-switch-2--bluetooth-pico-w--pico-2-w). + - Xbox Series, One, and Elite 2 - Dualshock 3 - Dualshock 4 - Dualsense - Switch Pro +- **Switch 2 Pro** and **Joy-Con 2 (L/R)** (BLE on Pico W / Pico 2 W; wired USB also supported) - Steam - Stadia - Wii U Pro @@ -129,7 +132,7 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork -Version history and release notes are in **[CHANGELOG.md](CHANGELOG.md)**. For detailed firmware improvements — **PS3**, **XInput / XSM3**, **OG Xbox**, **PS2/OPL**, **latency**, **Pico W Bluetooth (DS4 Classic BT, BLE coexistence, Xbox Series BLE)**, **Pico W / Pico 2 W PIO USB wired unplug detection**, etc. — see **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)**. +Version history and release notes are in **[CHANGELOG.md](CHANGELOG.md)**. For detailed firmware improvements — **PS3**, **XInput / XSM3**, **OG Xbox**, **PS2/OPL**, **latency**, **Pico W Bluetooth (DS4 Classic BT, BLE coexistence, Xbox Series BLE, Switch 2 Pro + Joy-Con 2 BLE)**, **Pico W / Pico 2 W PIO USB wired unplug detection**, etc. — see **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)**. Highlights: @@ -278,7 +281,7 @@ Outputs (`.elf`, `.uf2`, etc.) are in the build directory; flash the `.uf2` to t |---------|-------------| | [Wii_Mode_Guide.md](Firmware/RP2040/docs/Wii_Mode_Guide.md) | Wii mode (build-option only): No Extension / Nunchuk / Classic, USB host, sync and auto-connect, button mapping. | | [PICO2W_WII_USB_SETUP.md](Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | -| [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360, Pico W Bluetooth, **Pico W PIO USB wired unplug detection**. | +| [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360, Pico W Bluetooth, **Switch 2 Pro + Joy-Con 2 BLE**, **Pico W PIO USB wired unplug detection**. | ### ESP32 Please see the Hardware directory for a diagram showing how to hookup the ESP32 to your RP2040. @@ -298,6 +301,9 @@ When you build with ESP-IDF, Cmake will run a python script that copies the nece - **[faithvoid](https://github.com/faithvoid)** — Xbox 360 controller vibration/rumble fix (host-side rumble handling, including wireless RUMBLE_ENABLE sequence). - **[PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)** — Wii (Wiimote) output mode: approach of USB gamepad on PIO USB with Bluetooth reserved for the Wiimote link, and button/stick mappings for No Extension, Nunchuk, and Classic Controller report modes. - **[retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch)** — Reference for Nintendo Switch Pro Controller protocol and report layout (N64/GameCube → Raspberry Pi Pico → Switch via USB or Bluetooth). Used to align OGX-Mini’s Switch mode with correct Pro Controller button byte layout and emulation behavior. +- **[Nadeflore/switch2-controllers](https://github.com/Nadeflore/switch2-controllers)** — Foundational **Switch 2** BLE discovery, pairing, and GATT protocol work used to implement wireless **Switch 2 Pro** support on Pico W / Pico 2 W. +- **[TommyWabg/switch2-controllers-windows10-gyro](https://github.com/TommyWabg/switch2-controllers-windows10-gyro)** — Extended Switch 2 fork: **63-byte composed input report**, button bitfield, init/feature commands, and **Pro Controller** rumble packet format (fork of Nadeflore’s project). +- **[BlueRetro #1249](https://github.com/darthcloud/BlueRetro/issues/1249)** (darthcloud) — Community reverse engineering of Switch 2 **63-byte BLE reports** and GATT notify handles. ## Licenses and third-party code From b78d16b222e249bde9c299bddd531fcfa26c5585 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Fri, 19 Jun 2026 09:33:06 -0400 Subject: [PATCH 35/42] Xbox BLE fixes and wired DS4 PS/touchpad mask fix. --- Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 7 ++++++- Firmware/external/bluepad32 | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index f5fa8c97..423f82a4 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -515,7 +515,12 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { s_bt_any_connected_cached.store(true, std::memory_order_release); #endif #if defined(CONFIG_TARGET_PICO_W) - if (gap_get_connection_type(device->conn.handle) == GAP_CONNECTION_ACL) { + if (device->controller_type == CONTROLLER_TYPE_XBoxOneController && device->hids_cid != 0) { + /* CYW43439: BLE scan + BR inquiry during an active Xbox LE link causes supervision timeout. */ + uni_bt_le_scan_stop(); + uni_bt_bredr_scan_stop(); + gap_advertisements_enable(0); + } else if (gap_get_connection_type(device->conn.handle) == GAP_CONNECTION_ACL) { gap_advertisements_enable(0); if (uni_hid_parser_switch_solo_needs_partner(device)) { /* Solo Joy-Con (L or R): keep inquiry + page scan for the partner; pause BLE scan. */ diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index 06bbc474..6c8dc3ab 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit 06bbc474101fba30ae96fad4c6ac8de2e9de7cec +Subproject commit 6c8dc3ab3dc4e8d36f9b62984d8f3b0563e39d63 From 2d0a4fc06b9950b5bb6366705f95faf1ffa265fb Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Thu, 25 Jun 2026 13:01:45 -0400 Subject: [PATCH 36/42] v1.0.0.11a: PIO USB wired host fixes for Switch Pro, PS3, and 360 receiver. Reliable wired USB host on PIO adapters (RP2350-USB-A validated): SOF servicing, Switch 1/2 Pro init and mapping, DualShock 3 enable/keepalive, 360 wireless receiver four-port sync, Pico W unplug watchdog, and I2C pad wire format fix. Co-authored-by: Cursor --- CHANGELOG.md | 13 +- Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/docs/IMPROVEMENTS.md | 123 ++++- Firmware/RP2040/docs/Wired_Controllers.md | 8 +- Firmware/RP2040/src/Board/Config.h | 8 + Firmware/RP2040/src/Board/board_api.cpp | 8 + .../board_api_private/board_api_private.h | 2 + .../board_api_private/board_api_usbh.cpp | 3 + Firmware/RP2040/src/Descriptors/SwitchPro.h | 11 + Firmware/RP2040/src/Gamepad/I2CWirePad.h | 55 +++ .../src/OGXMini/Board/ESP32_Bluepad32_I2C.cpp | 5 +- .../src/OGXMini/Board/Four_Channel_I2C.cpp | 7 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 5 +- .../RP2040/src/OGXMini/Board/Standard.cpp | 93 +++- .../RP2040/src/USBHost/HostDriver/PS3/PS3.cpp | 214 ++++++--- .../RP2040/src/USBHost/HostDriver/PS3/PS3.h | 18 + .../HostDriver/SwitchPro/Switch2ProHost.cpp | 10 +- .../HostDriver/SwitchPro/SwitchPro.cpp | 444 +++++++++++++----- .../USBHost/HostDriver/SwitchPro/SwitchPro.h | 30 +- .../USBHost/HostDriver/XInput/Xbox360W.cpp | 146 +++--- .../src/USBHost/HostDriver/XInput/Xbox360W.h | 5 +- .../XInput/tuh_xinput/tuh_xinput.cpp | 98 +++- .../HostDriver/XInput/tuh_xinput/tuh_xinput.h | 7 + Firmware/RP2040/src/USBHost/HostManager.h | 188 +++++++- Firmware/RP2040/src/USBHost/tuh_callbacks.cpp | 6 + Firmware/RP2040/src/tusb_config.h | 2 +- 26 files changed, 1210 insertions(+), 301 deletions(-) create mode 100644 Firmware/RP2040/src/Gamepad/I2CWirePad.h diff --git a/CHANGELOG.md b/CHANGELOG.md index b5114067..ed7c1b43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ # Changelog / Version history -Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, **Switch 2 Pro + Joy-Con 2 BLE**, **Switch 1 Joy-Con L+R merge**, **Joy-Con dual-half latency fixes**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). +Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, **Switch 2 Pro + Joy-Con 2 BLE**, **Waveshare RP2350-USB-A wired host fixes (Switch Pro, PS3, Xbox 360 receiver)**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). + +--- + +### Version 1.0.0.11a + +- **PIO USB host — SOF servicing and teardown (all PIO host boards)** — PIO USB has no hardware SOF; wired IN/OUT stalls without periodic **`pio_usb_host_frame()`**. **Standard** path (RP2350-USB-A, Pico, Feather, RP2350-Zero, etc.): Core1 runs a **~1 kHz repeating hardware timer** plus **`pio_usb_host_frame()`** in the main host loop; **`skip_alarm_pool`** on PIO config avoids timer pool conflicts. **`HostManager::send_feedback()`** calls **`pio_usb_host_frame()`** after OUT on **every** `CONFIG_EN_USB_HOST` build (previously Pico W only). **`board_api_usbh::stop_pio_usb_host()`** stops the SOF timer, resets Core1, and **`tuh_deinit`** before USB device disconnect/reboot. **Button-combo output mode change** sets **`s_driver_reboot_pending`** so **`host_mounted(false)`** does not queue a spurious second disconnect reboot during an intentional driver switch. **Files:** `Standard.cpp`, `HostManager.h`, `board_api.cpp`, `board_api_usbh.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*PIO USB host — wired connection fixes*, shared HostManager section). +- **Waveshare RP2350-USB-A — wired Switch Pro (PIO USB host)** — Primary validation on **Waveshare RP2350-USB-A** (`OGXM_BOARD=RP2350_USB_A`); driver code is **shared** with all **PIO USB host** builds (`CONFIG_EN_USB_HOST`). **Switch 1 Pro** (PID **0x2009**): replaced Bluetooth-style **0x11** init with **Chromium-style wired USB** sequence — report **0x80** (MAC → handshake → baud → handshake → disable timeout) then **0x12** + subcommand **0x33** probe, LED / full report / IMU subcommands; non-blocking HID OUT with **`pio_usb_host_frame()`** in the feedback path; init advances per IN report with **timeout fallback**; **D-pad** (UP↔DOWN, LEFT↔RIGHT) and **L3↔R3** mapping fixes. **Switch 2 Pro** (PID **0x2069**): **17-packet bulk OUT** bring-up on **USB config 1 / interface 1** (~**12 ms** between packets, same sequence as `Tools/controller_capture/switch2_usb_init.py` / HandHeldLegend ProCon 2 enabler); after bulk completes the pad goes straight to **DONE** — **no** Switch 1 **0x80** HID init; **Switch2ProHost** decodes report **0x09**. **Hot-swap / unplug:** **`disconnect_cb`** cancels bulk bring-up and aborts endpoints; async bulk callbacks resolve the driver by **`(address, instance)`** via **`HostManager::get_switch_pro_host()`** so swapping Switch 1 ↔ Switch 2 Pro does not corrupt state. **Bluetooth** (Pico W / Pico 2 W) unchanged. Protocol references: [Chromium gamepad](https://chromium.googlesource.com/chromium/src/+/main/device/gamepad/) (Switch wired USB init), [HandHeldLegend procon2tool](https://github.com/HandHeldLegend/procon2tool), local **`Tools/controller_capture/switch2_usb_init.py`**. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*PIO USB host — wired connection fixes*) and [Wired_Controllers.md](Firmware/RP2040/docs/Wired_Controllers.md). +- **DualShock 3 / PS3 controller — wired USB host (PIO USB)** — **DualShock 3** over **USB cable** now connects reliably on PIO USB host boards (validated on **RP2350-USB-A**). Replaced gadget-style default OUT report with **USB Host Shield** host layout; **synchronous init** sends **SET feature 0xF4** `{0x42,0x0c,0,0}` (enable USB reports) then a **player LED OUT** report, with **`pio_usb_host_frame()`** polled during control transfers so init completes under PIO USB. **1 Hz keepalive OUT** on PIO USB (`KEEPALIVE_MS`) so the pad stays connected when idle; **`HostManager`** calls **`send_feedback()`** for PS3 on the feedback timer. **Bluetooth auto-pair** (feature **0xF5**) unchanged on Pico W builds — runs after wired init when `CONFIG_EN_BLUETOOTH` is set. **File:** `PS3Host.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — wired USB host*). +- **Xbox 360 wireless USB receiver — wired host (PIO USB)** — **Microsoft PC wireless receiver** (`045e:0719`) + **Xbox 360 wireless pad** sync and input fixed on PIO USB host when **`MAX_GAMEPADS=1`**. **`OGXM_TUH_XINPUT_INSTANCES=4`** when `MAX_GAMEPADS < 4` so all **four RF ports** are polled; **`HostManager`** shares one **`Xbox360WHost`** driver across receiver interfaces and routes **`process_report` / connect / disconnect** to the live driver. **`tuh_xinput`:** **`prime_port_for_pairing()`** sends **RUMBLE_ENABLE + LED** on idle ports; controller-present detection uses **byte1 bit 7 (`0x80`)** (not headset-only **0x40**); accepts report size **0x13** or **0x14**; removed **1 s sleep** on connect; **`service_wireless_ports()`** from feedback timer. **`Xbox360WHost`:** byte-offset decode for wireless input reports; tracks **active instance** for rumble. **Files:** `Config.h`, `HostManager.h`, `tuh_xinput.cpp`, `Xbox360W.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Xbox 360 wireless receiver — wired USB host*). +- **Pico W / Pico 2 W — wired unplug watchdog (360 receiver)** — **No-input** unplug timeout raised from **~3 s** to **~10 s** so a **360 wireless PC receiver** plugged into the adapter’s PIO USB host port (which keeps sending status IN even with no pad paired) is not mistaken for unplug and torn down while Bluetooth should stay available. **File:** `PicoW.cpp`. +- **Four-channel / ESP32 I2C — pad wire format** — **`I2CWirePadIn`** fixed **23-byte** payload for master/slave I2C **`PacketIn`** links; excludes **`Gamepad::PadIn` IMU fields** added for DS4/DS5/Switch Pro that broke the **32-byte** wire layout on **Four_Channel_I2C** and **ESP32_Bluepad32_I2C** boards. **Files:** `I2CWirePad.h`, `Four_Channel_I2C.cpp`, `ESP32_Bluepad32_I2C.cpp`. --- diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index b513216e..4971ccb9 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a10") \ No newline at end of file +set(FW_VERSION "v1.0.0a11") \ No newline at end of file diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index b0191bee..3531f03e 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -2,7 +2,7 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. -**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). **v1.0.0.10a** adds **Nintendo Switch 2** wireless support (**Pro 2** and **Joy-Con 2**) over **BLE**, **Switch 1 Joy-Con L+R merge**, and **Joy-Con dual-half latency fixes** (see *Nintendo Switch 2 — Bluetooth* and *Joy-Con pair merge — latency* below). +**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). **v1.0.0.10a** adds **Nintendo Switch 2** wireless support (**Pro 2** and **Joy-Con 2**) over **BLE**, **Switch 1 Joy-Con L+R merge**, and **Joy-Con dual-half latency fixes** (see *Nintendo Switch 2 — Bluetooth* and *Joy-Con pair merge — latency* below). **v1.0.0.11a** adds **PIO USB host wired connection fixes** — **Switch 1/2 Pro**, **DualShock 3**, and **Xbox 360 wireless receiver** — validated on **Waveshare RP2350-USB-A** (see *PIO USB host — wired connection fixes* below). **Version 1.0.0.9a — documented here for release notes:** @@ -102,6 +102,115 @@ Switch 2 controllers use a **proprietary BLE GATT protocol**, not standard HID-o --- +## PIO USB host — wired connection fixes (Waveshare RP2350-USB-A) + +**Primary test platform:** **Waveshare RP2350-USB-A** (`OGXM_BOARD=RP2350_USB_A`, build option **7** in `scripts/build.sh`). Firmware uses the **Standard** path: **Core1** runs **`tuh_task()`** plus a **1 ms SOF timer** for PIO USB host. + +**Scope:** Changes live in **shared USB host drivers** and **`HostManager`**, not board-specific `#ifdef`s. Any build with **`CONFIG_EN_USB_HOST`** (Pico, Feather, RP2350-Zero, RP2350-USB-A, etc.) gets the same wired-host behavior. **Pico W / Pico 2 W Bluetooth** (Bluepad32) is **unchanged**. + +**Goal:** Reliable **wired USB host** input on PIO USB adapters for **Switch Pro 1/2**, **DualShock 3**, and the **Xbox 360 wireless PC receiver** + pad — without starving the PIO stack during init or OUT transfers. + +### Shared — HostManager and PIO USB servicing + +1. **`pio_usb_host_frame()` on all PIO USB host boards** — Previously gated to **Pico W only**; now runs after **`send_feedback()`** / nested **`tuh_task()`** on **every** `CONFIG_EN_USB_HOST` build so wired IN reports do not die after ~1–2 s when the host sends OUT. +2. **Periodic feedback for init-heavy HID drivers** — **`HostManager::send_feedback()`** now always invokes **`send_feedback()`** for **PS3** and **Switch Pro / Switch 2 Pro** (not only on rumble / `new_pad_out()`), so wired init steps and keepalives run on a timer. +3. **`disconnect_cb()` on unmount** — Drivers get a clean teardown hook when a device is removed (bulk cancel for Switch 2, state reset for 360 wireless, etc.). +4. **XInput instance storage** — **`MAX_INTERFACES = MAX_GAMEPADS + OGXM_TUH_XINPUT_INSTANCES`**; **`OGXM_TUH_XINPUT_INSTANCES = 4`** when `MAX_GAMEPADS < 4` so the **360 wireless receiver’s four ports** each have a TinyUSB slot even on single-player builds. + +**Files:** `HostManager.h`, `Board/Config.h`. + +### Nintendo Switch Pro — wired USB + +**References:** + +| Project | Contribution | +|---------|----------------| +| **[Chromium `device/gamepad`](https://chromium.googlesource.com/chromium/src/+/main/device/gamepad/)** | **Switch 1 Pro wired USB** init: report **0x80** subcommands (MAC, handshake, baud, disable timeout), **0x81** ack handling, **0x12** output + subcommands for LED / mode / IMU. | +| **`Tools/controller_capture/switch2_usb_init.py`** (this repo) | Captured **Switch 2–family bulk OUT** packet sequence used on PC before HID reports work. | +| **[HandHeldLegend/procon2tool](https://github.com/HandHeldLegend/procon2tool)** | **ProCon 2 enabler** — same bulk bring-up pattern as the capture tool; cross-check for **17-packet** interface **1** sequence. | +| **Bluepad32 `uni_hid_parser_switch.c`** | **Switch 1** button bit layout (`Buttons0/1/2`) for wired report decode validation. | +| **`Switch2ProHost.cpp`** (v1.0.0.9a) | **Switch 2 Pro wired** digitals from report **0x09** — extended here with bulk-only bring-up (no post-bulk Switch 1 init). | + +### Switch 1 Pro (PID 0x2009) — wired USB init + +1. **Wired USB state machine** — `InitState` phases: **USB_MAC** → **USB_HANDSHAKE1** → **USB_BAUD** → **USB_HANDSHAKE2** → **USB_NO_TIMEOUT** → **LED** → **LED_HOME** → **FULL_REPORT** → **IMU** → **DONE**. +2. **0x80 path** — OUT on report ID **`SwitchPro::REPORT_ID_USB_OUT` (0x80)** with subcommands **`USB_SUB_MAC`**, **`USB_SUB_HANDSHAKE`**, **`USB_SUB_BAUD`**, **`USB_SUB_DISABLE_TIMEOUT` (0x04)**; advance on matching **0x81** IN ack bytes. +3. **0x12 + 0x33 probe** — After disable-timeout, send **`CMD::AND_RUMBLE` (0x12)** with subcommand **`USB_PROBE` (0x33)**; on **0x21** subcommand ack, continue to player LED and **full report mode** subcommands. +4. **PIO-friendly OUT** — **`try_hid_out_id()`** checks **`tuh_hid_send_ready()`**; **`send_feedback()`** calls **`pio_usb_host_frame()`** + **`tuh_task()`** during init so Core1 keeps the PIO host alive. +5. **Per-IN advancement** — Init steps also run from **`process_report()`** on each IN packet, not only from the feedback timer. +6. **Timeout fallback** — If **USB_NO_TIMEOUT** ack is slow, **8 retries** in **`send_feedback()`** force advance to **LED** so init does not hang indefinitely. +7. **Input mapping fixes** — D-pad **UP↔DOWN** and **LEFT↔RIGHT** swapped; **L3↔R3** swapped in **`SwitchProHost::process_report()`**. + +### Switch 2 Pro (PID 0x2069) and Switch 2–family USB — bulk bring-up + +Applies to Nintendo VID **0x057E** PIDs **0x2066**, **0x2067**, **0x2069**, **0x2073** (`is_switch2_usb_family()`). + +1. **Bulk sequence** — Read configuration descriptor, open **interface 1** bulk IN/OUT, send **17 packets** from **`Switch2UsbInitPackets.h`** (~**12 ms** spacing between rounds), optional bulk IN read per round when an IN endpoint exists. +2. **No post-bulk Switch 1 init** — On successful bulk completion, **`init_state_ = DONE`** immediately and **`tuh_hid_receive_report()`** starts — **Switch 1 `0x80` HID init is skipped** for Switch 2–family devices. +3. **Switch2ProHost** — Parses **64-byte** HID report ID **0x09** (1-byte counter + **10-byte** payload) with **Switch 2–specific** button bits (see v1.0.0.9a / [Wired_Controllers.md](Wired_Controllers.md)). +4. **Async safety** — Bulk callbacks use **`switch2_make_cb_token(daddr, instance)`** and **`HostManager::get_switch_pro_host()`** to look up the live driver; safe after hot-swap or unplug. +5. **Teardown** — **`disconnect_cb()`** / destructor call **`switch2_cancel_bringup()`**: abort in-flight bulk transfers, clear pending retry state. + +### DualShock 3 — wired USB host + +**Problem:** **DualShock 3** over **USB cable** failed to connect or dropped shortly after plug-in on **PIO USB host** boards. Init used the **USB gadget** default OUT template (leading **`0x01`**) and **async-only** control transfers without servicing **`pio_usb_host_frame()`**, so enable/LED commands never completed reliably. + +**Reference:** [USB Host Shield PS3](https://github.com/felis/USB_Host_Shield_2.0) host report buffer / feature **0xF4** enable sequence. + +#### Changes + +1. **Host OUT report layout** — **`init_host_out_report()`** builds the **USB Host Shield `PS3_REPORT_BUFFER`** layout (player LED bitmap **`0x02 << player`**, per-LED timing fields) instead of copying gadget **`DEFAULT_OUT_REPORT`**. +2. **Synchronous wired init** — On plug-in: **SET feature 0xF4** `{0x42, 0x0c, 0x00, 0x00}` then **synchronous OUT** (rumble/LED report) via **`send_control_xfer_wait()`**, polling **`pio_usb_host_frame()` + `tuh_task()`** up to **150 ms** per step. +3. **Immediate input** — Wired path sets **`reports_enabled`** and **`InitStage::DONE`** after enable + LED OUT; **`tuh_hid_receive_report()`** starts without waiting on the old multi-stage **GET feature 0xF2** chain (that chain remains for **Bluetooth auto-pair** on `CONFIG_EN_BLUETOOTH` builds only). +4. **PIO keepalive** — **`KEEPALIVE_MS = 1000`** on USB host sends periodic neutral OUT so the DS3 stays connected when idle; **`HostManager`** includes PS3 in periodic **`send_feedback()`**. +5. **Async OUT for rumble** — Runtime rumble/keepalive uses non-blocking **`send_control_output_async()`** so feedback does not stall IN. + +**File:** `src/USBHost/HostDriver/PS3/PS3.cpp`, `PS3.h`. + +**User testing (Waveshare RP2350-USB-A):** **DualShock 3 wired** connects and holds input after flash. + +### Xbox 360 wireless receiver — wired USB host + +**Problem:** **Microsoft Xbox 360 wireless PC receiver** (`045e:0719`) plugged into the adapter’s **PIO USB host** port often failed to **sync** a wireless pad or delivered **no input** when **`MAX_GAMEPADS=1`**. Only one of four receiver interfaces was stored; **controller-present** was mis-detected (**headset `0x40`** treated as paired); connect path **slept 1 s** and blocked PIO servicing; **`Xbox360WHost`** assumed a fixed struct layout for variable-length wireless reports. + +#### Changes + +1. **Four XInput instances on single-player builds** — **`OGXM_TUH_XINPUT_INSTANCES = 4`** when `MAX_GAMEPADS < 4`; **`MAX_INTERFACES = MAX_GAMEPADS + OGXM_TUH_XINPUT_INSTANCES`**; **`host_storage_index()`** maps XInput instances to **`MAX_GAMEPADS + instance`**. +2. **One driver, four ports** — **`HostManager`** treats sibling **`XBOX360W`** interfaces as sharing one gamepad slot when `MAX_GAMEPADS=1`; **`process_report` / `connect_cb` / `disconnect_cb`** fall back to the mounted **`Xbox360WHost`** when the per-instance slot has no driver pointer. +3. **`tuh_xinput` pairing** — **`prime_port_for_pairing()`** on each idle port: **RUMBLE_ENABLE + player LED** (quadrant from interface number **0/2/4/6**); called at **set_config** and periodically via **`service_wireless_ports()`** from **`HostManager::send_feedback()`**. +4. **Connect detection** — Controller present when **IN byte1 & 0x80** (not merely non-zero / headset **0x40**); on connect: **RUMBLE_ENABLE**, **`wait_for_tx_complete()`** (200 ms cap), **LED** — **no 1 s sleep**. +5. **Input reports** — Accept **report size 0x13 or 0x14**; **`Xbox360WHost::process_report()`** decodes **button word, triggers, sticks** from raw byte offsets; tracks **`active_instance_`** for rumble on the port that last connected. +6. **Rumble** — **`set_rumble()`** skips **RUMBLE_ENABLE** when already connected; returns false if port not connected (avoids spurious OUT on idle RF slots). + +**Files:** `Board/Config.h`, `HostManager.h`, `HostDriver/XInput/tuh_xinput/tuh_xinput.cpp`, `HostDriver/XInput/Xbox360W.cpp`. + +**User testing (Waveshare RP2350-USB-A):** **360 wireless receiver + pad** sync and input confirmed over PIO USB host. + +### Hot-swap (Switch 1 ↔ Switch 2 Pro) + +Unplug during bulk or HID init runs **`HostManager::disconnect_cb()`** → driver **`disconnect_cb()`** → bulk cancel. Plugging the other model starts a fresh init path (Switch 1 **0x80** vs Switch 2 bulk) without requiring an adapter power cycle. + +### Files (all wired-host fixes) + +| File | Role | +|------|------| +| `src/USBHost/HostManager.h` | PIO **`pio_usb_host_frame()`** on all host boards; PS3/Switch periodic feedback; 360W driver routing; **`disconnect_cb`** on unmount; **`get_switch_pro_host()`** | +| `src/Board/Config.h` | **`OGXM_TUH_XINPUT_INSTANCES`** (4 when `MAX_GAMEPADS < 4`) | +| `src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp` | Switch 1 wired init, Switch 2 bulk bring-up, Switch 1 input mapping, PIO USB service loop | +| `src/USBHost/HostDriver/SwitchPro/SwitchPro.h` | Init state machine, bulk bring-up members, `disconnect_cb` | +| `src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp` | Switch 2 Pro wired button decode | +| `src/USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h` | 17 bulk OUT packets (capture tool / HHL) | +| `src/Descriptors/SwitchPro.h` | Wired USB constants (`REPORT_ID_USB_OUT`, `USB_SUB_*`, `USB_PROBE`) | +| `src/USBHost/HostDriver/PS3/PS3.cpp` | DualShock 3 wired init, sync control xfer, 1 Hz keepalive | +| `src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp` | 360 wireless receiver port priming, connect detect, **`service_wireless_ports()`** | +| `src/USBHost/HostDriver/XInput/Xbox360W.cpp` | Wireless input decode from byte offsets, active instance rumble | + +**Build:** `./scripts/build.sh` → board **RP2350_USB_A**; typical **`-DMAX_GAMEPADS=1`**. Optional **`-DOGXM_SWITCH2_HID_RAW_LOG=ON`** for UART hex when Switch 2 Pro digital button bytes change. + +**User testing (Waveshare RP2350-USB-A):** **Switch 2 Pro wired**, **DualShock 3 wired**, and **Xbox 360 wireless receiver + pad** confirmed on PIO USB host. **Switch 1 Pro wired** — init and mapping updated; retest after flash if a prior S2 regression was seen. + +--- + ## Xbox 360 (XInput) support **Goal:** Use the adapter in XInput mode on Xbox 360 with Bluetooth controllers (e.g. PS5, Xbox One). The 360 requires XSM3 authentication and specific USB descriptors. @@ -481,15 +590,15 @@ OGX-Mini’s existing **wired Xbox One GIP** path (`tuh_xinput`, subclass `0x47` | Area | Improvement | |------|-------------| -| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). **360 wireless PC receiver** supported (`Xbox360WHost`). **Xbox One/Series wireless dongle (`045e:02e6` / `02fe`)** — see [Future planned](#future-planned). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. Report built every loop, send when endpoint ready — same minimal-latency pattern as Switch/PS3. | -| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **v1.0.0.9a:** PC host rumble deadzone + strict small-motor `0`/`1` so idle rumble does not stick on the BT pad. | +| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). **360 wireless PC receiver** supported (`Xbox360WHost`). **v1.0.0.11a:** PIO USB wired receiver — **4 XInput instances** when `MAX_GAMEPADS=1`, port **priming**, **0x80** connect detect, byte-offset decode. **Xbox One/Series wireless dongle (`045e:02e6` / `02fe`)** — see [Future planned](#future-planned). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. | +| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **v1.0.0.9a:** PC host rumble deadzone + strict small-motor `0`/`1`. **v1.0.0.11a:** **DualShock 3 wired USB host** — USB Host Shield init, sync control xfer + PIO service, **1 Hz keepalive**. | | **PS2 (GPIO)** | Home only = IGR (L1+L2+R1+R2+Start+Select); Home+Start = shutdown (L1+L2+R1+R2+L3+R3). OPL and protocol stability (first response byte = mode byte). | | **OG Xbox** | Guide only = IGR. Shutdown = LT+RT+Back+White via **Guide+Start** or **Guide+View (Back)**; Xbox BT often omits Start while Guide is held. Shutdown report strips Start so the chord matches BIOS/softmod expectations. | -| **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. | -| **Switch 2** | **Pro 2** (wired **0x2069**): **Switch2ProHost**. **Pro 2 + Joy-Con 2 L/R** (BLE): **uni_hid_parser_switch2** — GATT pairing, 63-byte input, rumble keepalive, Home → SYS latch, **L+R pair merge**, **dual-half latency fixes**. See [§ Nintendo Switch 2 — Bluetooth](#nintendo-switch-2--bluetooth-pico-w--pico-2-w) and [§ Joy-Con pair latency](#joy-con-pair-merge--latency-when-both-halves-are-active). | -| **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). | +| **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. **v1.0.0.11a:** **Switch 1/2 Pro wired** on PIO USB host — Chromium **0x80** init, bulk bring-up, mapping fixes. See [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | +| **Switch 2** | **Pro 2** (wired **0x2069**): **Switch2ProHost** + bulk bring-up (v1.0.0.11a). **Pro 2 + Joy-Con 2 L/R** (BLE): **uni_hid_parser_switch2** — GATT pairing, 63-byte input, rumble keepalive, Home → SYS latch, **L+R pair merge**, **dual-half latency fixes**. See [§ Nintendo Switch 2 — Bluetooth](#nintendo-switch-2--bluetooth-pico-w--pico-2-w) and [§ Joy-Con pair latency](#joy-con-pair-merge--latency-when-both-halves-are-active). | +| **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). **RP2350-USB-A (Waveshare):** v1.0.0.11a validation for **Switch Pro, DualShock 3, 360 wireless receiver** wired host. | | **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). Switch Pro and PS3 always build report every loop so host poll (`get_report`) and IN push both see current state — only remaining delay is BT radio when wireless. | | **Build** | Interactive scripts `scripts/build.sh` (Linux/macOS) and `scripts/build.ps1` (Windows) for board selection, fixed/default mode, and Release/Debug; output in `scripts/build/`. See [README](../../../README.md) Build section. | | **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **Switch 2 (BLE):** Pro 2 + Joy-Con 2 L/R — custom GATT parser, rumble keepalive, Home latch, **L+R merge**, **dual-half latency fixes**. **Switch 1 Joy-Con (Classic BT):** L+R merge, IMU off when paired, same latency path as SW2. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in (**2-slot** staging for Joy-Con pairs); re-enable scan on last disconnect. **v1.0.0.9a:** ~**1 s connection rumble** at `device_ready` (DS4 delayed start). | -| **PIO USB host (Pico W)** | **Wired unplug:** Debounced combo of **HCD connect**, **`tuh_mounted` over all device addresses**, and **no `process_report` / setup activity** (~**3 s**) so disconnect registers when D+/D− line state is wrong under PIO; **`tuh_deinit`** + restore GPIO line IRQs + BT release. See [§ Pico W — PIO USB wired controller unplug detection](#pico-w--pico-2-w--pio-usb-wired-controller-unplug-detection). | +| **PIO USB host (Pico W)** | **Wired unplug:** Debounced combo of **HCD connect**, **`tuh_mounted` over all device addresses**, and **no `process_report` / setup activity** (~**3 s**) so disconnect registers when D+/D− line state is wrong under PIO; **`tuh_deinit`** + restore GPIO line IRQs + BT release. **v1.0.0.11a (all PIO host boards):** **`pio_usb_host_frame()`** after feedback OUT; wired **Switch Pro / PS3 / 360 receiver** connection fixes — see [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | | **DS3 + Bluetooth** | **USB auto-pair:** After PS3 wired init, **feature `0xF5`** programs the **DS3** with the adapter’s **BD_ADDR** (`CONFIG_EN_BLUETOOTH`); deferred if BT address not ready. See [§ DualShock 3 — automatic USB programming for Bluetooth pairing](#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). | diff --git a/Firmware/RP2040/docs/Wired_Controllers.md b/Firmware/RP2040/docs/Wired_Controllers.md index 369f5dc9..b98ec25c 100644 --- a/Firmware/RP2040/docs/Wired_Controllers.md +++ b/Firmware/RP2040/docs/Wired_Controllers.md @@ -16,6 +16,8 @@ This document lists controllers supported when connected to the OGX-Mini adapter *Matched by USB class; no fixed VID/PID list. UsbdSecPatch is not required on Xbox 360.* +**Xbox 360 wireless PC receiver (`045e:0719`), wired to adapter USB host:** Plug the **receiver** into the adapter’s host port; sync a **wireless 360 pad** to any quadrant. On **PIO USB host** boards (Waveshare RP2350-USB-A, Pico, Feather, etc.), v1.0.0.11a polls **all four RF ports** even when `MAX_GAMEPADS=1` and primes idle ports for sync. See [IMPROVEMENTS.md — PIO USB host wired fixes](IMPROVEMENTS.md#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). + --- ### PlayStation 3 (DualShock 3 and compatible) @@ -28,6 +30,8 @@ This document lists controllers supported when connected to the OGX-Mini adapter *See `PS3_IDS` in `HardwareIDs.h` for the full VID/PID list.* +**DualShock 3 over USB cable (PIO USB host):** v1.0.0.11a sends **SET feature 0xF4** and a **player LED OUT** report at connect (USB Host Shield sequence) with **`pio_usb_host_frame()`** during init, plus a **1 Hz keepalive OUT** so the pad stays connected. On **Pico W / Pico 2 W**, Bluetooth **auto-pair** (feature **0xF5**) still runs after wired init when enabled. See [IMPROVEMENTS.md — DualShock 3 wired USB host](IMPROVEMENTS.md#dualshock-3--wired-usb-host). + --- ### PlayStation 4 (DualShock 4 and compatible) @@ -60,8 +64,10 @@ This document lists controllers supported when connected to the OGX-Mini adapter *See `SWITCH_PRO_IDS` and `SWITCH_WIRED_IDS` in `HardwareIDs.h` for the full VID/PID list.* +**Switch 1 Pro (PID 0x2009), wired USB:** Uses **Chromium-style wired USB init** (report **0x80** subcommands: MAC, handshake, baud, disable timeout; then **0x12** + subcommand **0x33** probe, player LED, full report mode, IMU). **Not** the Bluetooth **0x11** handshake path. After init, standard **SwitchProHost** decodes the **10-byte** `SwitchPro::InReport` payload (report IDs **0x30** / **0x31** or raw 10 bytes). D-pad and **L3/R3** mapping corrected for wired layout. See [IMPROVEMENTS.md](IMPROVEMENTS.md#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). + **Switch 2–family USB (Pro Controller 2, Joy‑Con 2, NSO GameCube, etc.):** -The firmware runs the same vendor **bulk OUT** bring‑up on **USB configuration 1, interface 1** as the PC capture tool (`Tools/controller_capture/switch2_usb_init.py` / HandHeldLegend ProCon 2 enabler), then continues with the normal Switch Pro **HID** init (handshake, full report mode, etc.). Wired input reports may use report ID **0x09** (with a 1‑byte counter after the ID). +The firmware runs the same vendor **bulk OUT** bring‑up on **USB configuration 1, interface 1** as the PC capture tool (`Tools/controller_capture/switch2_usb_init.py` / [HandHeldLegend procon2tool](https://github.com/HandHeldLegend/procon2tool)). **Switch 2–family devices do not run Switch 1 `0x80` HID init after bulk** — bring-up completes at **`DONE`** and HID input reports begin immediately. Wired input reports may use report ID **0x09** (with a 1‑byte counter after the ID). **Switch 2 Pro (PID 0x2069), wired USB:** After the same **bulk OUT** bring‑up on **config 1 / interface 1**, **Switch2ProHost** parses the standard **64‑byte** HID report (ID **0x09**, 1‑byte counter, then **10‑byte** `SwitchPro::InReport` payload). Digitals use **Switch‑2‑specific** bit positions (not classic **Buttons0/1/2**): face **B/A/Y/X**, **RB**, **LB** (Home bit), **Minus** → Back, **Plus** / d‑pad directions, **L3**, **Start** (classic R), **R3** (classic ZR bit), **SYS** (classic `bl` d‑pad up), **ZL/ZR** → **LT/RT** (digital full press from captured bits), and **Capture** is still not mapped to **MISC**. **GL**, **GR**, and **Chat** are **documented in source** (`Switch2ProHost.cpp`) but **left unmapped**. Extended report bytes are not used for decoding (avoids IMU coupling / flicker). **Bluetooth LE** for **Pro 2** and **Joy-Con 2** (**0x2066** / **0x2067**) on **Pico W / Pico 2 W** is documented in [IMPROVEMENTS.md](IMPROVEMENTS.md#nintendo-switch-2--bluetooth-pico-w--pico-2-w) (custom GATT — not wired USB). Other Switch 2–family PIDs keep **SwitchProHost**. diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index 6afa03fe..48768b8a 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -21,6 +21,14 @@ #define MAX_GAMEPADS 1 #endif +/** TinyUSB XInput host instances. The 360 wireless USB receiver exposes 4 controller interfaces; + * all 4 must be polled even when MAX_GAMEPADS is 1 so sync works on any RF slot. */ +#if MAX_GAMEPADS < 4 + #define OGXM_TUH_XINPUT_INSTANCES 4 +#else + #define OGXM_TUH_XINPUT_INSTANCES MAX_GAMEPADS +#endif + /** Main loop delay (device/core0) in microseconds. 0 = low latency (default). 250+ = lower CPU. */ #ifndef MAIN_LOOP_DELAY_US #define MAIN_LOOP_DELAY_US 0 diff --git a/Firmware/RP2040/src/Board/board_api.cpp b/Firmware/RP2040/src/Board/board_api.cpp index c57dae29..5ab11da6 100644 --- a/Firmware/RP2040/src/Board/board_api.cpp +++ b/Firmware/RP2040/src/Board/board_api.cpp @@ -73,7 +73,15 @@ void usb::disconnect_all() { OGXM_LOG("Disconnecting USB and resetting Core1\n"); TaskQueue::suspend_delayed_tasks(); +#if defined(CONFIG_EN_USB_HOST) + if (board_api_usbh::stop_pio_usb_host) { + board_api_usbh::stop_pio_usb_host(); + } else { + multicore_reset_core1(); + } +#else multicore_reset_core1(); +#endif sleep_ms(500); tud_disconnect(); sleep_ms(500); diff --git a/Firmware/RP2040/src/Board/board_api_private/board_api_private.h b/Firmware/RP2040/src/Board/board_api_private/board_api_private.h index 3ab43037..6b02aed4 100644 --- a/Firmware/RP2040/src/Board/board_api_private/board_api_private.h +++ b/Firmware/RP2040/src/Board/board_api_private/board_api_private.h @@ -30,6 +30,8 @@ namespace board_api_usbh { void store_host_line_connected(bool connected); /** After tuh_deinit / PIO release path, re-enable D+/D− edge IRQs for the next cable attach. */ void enable_host_line_irq_monitoring(); + /** Stop PIO USB host (SOF timer, tuh_deinit) before core reset / reboot. Standard boards. */ + void stop_pio_usb_host() __attribute__((weak)); } #endif // BOARD_API_PRIVATE_H \ No newline at end of file diff --git a/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp b/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp index 116e4663..e9f04995 100644 --- a/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp +++ b/Firmware/RP2040/src/Board/board_api_private/board_api_usbh.cpp @@ -39,6 +39,9 @@ void enable_host_line_irq_monitoring() { host_pin_isr(0, 0); } +void stop_pio_usb_host() __attribute__((weak)); +void stop_pio_usb_host() {} + void init() { #if defined(VCC_EN_PIN) gpio_init(VCC_EN_PIN); diff --git a/Firmware/RP2040/src/Descriptors/SwitchPro.h b/Firmware/RP2040/src/Descriptors/SwitchPro.h index 767a8ce9..2e79e04a 100644 --- a/Firmware/RP2040/src/Descriptors/SwitchPro.h +++ b/Firmware/RP2040/src/Descriptors/SwitchPro.h @@ -46,6 +46,14 @@ namespace SwitchPro static constexpr uint8_t MODE = 0x03; static constexpr uint8_t FULL_REPORT_MODE = 0x30; static constexpr uint8_t GYRO = 0x40; + /** Unrecognized subcommand; sent after 0x80 0x04 so init gets a 0x21 ack. */ + static constexpr uint8_t USB_PROBE = 0x33; + /** Wired USB output report ID and subcommands (not Bluetooth 0x11 path). */ + static constexpr uint8_t USB_OUT = 0x80; + static constexpr uint8_t USB_SUB_MAC = 0x01; + static constexpr uint8_t USB_SUB_HANDSHAKE = 0x02; + static constexpr uint8_t USB_SUB_BAUD = 0x03; + static constexpr uint8_t USB_SUB_DISABLE_TIMEOUT = 0x04; } // First report byte (buttons_right): bit layout per real hardware / Bluepad32 parse_report_30_pro_controller @@ -111,6 +119,8 @@ namespace SwitchPro static constexpr uint16_t STICK_MID = 0x7FF; static constexpr uint16_t STICK_MAX = 0xFFF; + static constexpr uint8_t REPORT_ID_OUTPUT_SUBCMD = 0x01; + static constexpr uint8_t REPORT_ID_OUTPUT_RUMBLE = 0x10; static constexpr uint8_t REPORT_ID_STANDARD = 0x30; /** Switch 2 Pro (USB) full input reports use 0x09; layout matches 0x30 after id + timer. */ static constexpr uint8_t REPORT_ID_SWITCH2_FULL = 0x09; @@ -118,6 +128,7 @@ namespace SwitchPro static constexpr uint8_t REPORT_ID_FULL_ALT = 0x31; static constexpr uint8_t REPORT_ID_SUBCMD = 0x21; static constexpr uint8_t REPORT_ID_USB_INIT = 0x81; + static constexpr uint8_t REPORT_ID_USB_OUT = 0x80; static constexpr int REPORT_SIZE = 64; static constexpr int USB_INIT_REPORT_SIZE = 64; diff --git a/Firmware/RP2040/src/Gamepad/I2CWirePad.h b/Firmware/RP2040/src/Gamepad/I2CWirePad.h new file mode 100644 index 00000000..260b08e8 --- /dev/null +++ b/Firmware/RP2040/src/Gamepad/I2CWirePad.h @@ -0,0 +1,55 @@ +#ifndef _I2C_WIRE_PAD_H_ +#define _I2C_WIRE_PAD_H_ + +#include + +#include "Gamepad/Gamepad.h" + +/** Fixed-size pad payload for I2C master/slave links (32-byte PacketIn). Excludes IMU + * fields added to Gamepad::PadIn for DS4/DS5/Switch Pro — not used between 4ch boards. */ +#pragma pack(push, 1) +struct I2CWirePadIn { + uint8_t dpad; + uint16_t buttons; + uint8_t trigger_l; + uint8_t trigger_r; + int16_t joystick_lx; + int16_t joystick_ly; + int16_t joystick_rx; + int16_t joystick_ry; + uint8_t analog[10]; +}; +#pragma pack(pop) +static_assert(sizeof(I2CWirePadIn) == 23, "I2CWirePadIn size mismatch"); + +inline I2CWirePadIn i2c_wire_pad_from(const Gamepad::PadIn& pad_in) +{ + I2CWirePadIn wire{}; + wire.dpad = pad_in.dpad; + wire.buttons = pad_in.buttons; + wire.trigger_l = pad_in.trigger_l; + wire.trigger_r = pad_in.trigger_r; + wire.joystick_lx = pad_in.joystick_lx; + wire.joystick_ly = pad_in.joystick_ly; + wire.joystick_rx = pad_in.joystick_rx; + wire.joystick_ry = pad_in.joystick_ry; + std::memcpy(wire.analog, pad_in.analog, sizeof(wire.analog)); + return wire; +} + +inline Gamepad::PadIn i2c_pad_from_wire(const I2CWirePadIn& wire) +{ + Gamepad::PadIn pad_in; + pad_in.dpad = wire.dpad; + pad_in.buttons = wire.buttons; + pad_in.trigger_l = wire.trigger_l; + pad_in.trigger_r = wire.trigger_r; + pad_in.joystick_lx = wire.joystick_lx; + pad_in.joystick_ly = wire.joystick_ly; + pad_in.joystick_rx = wire.joystick_rx; + pad_in.joystick_ry = wire.joystick_ry; + std::memcpy(pad_in.analog, wire.analog, sizeof(pad_in.analog)); + return pad_in; +} + +#endif diff --git a/Firmware/RP2040/src/OGXMini/Board/ESP32_Bluepad32_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/ESP32_Bluepad32_I2C.cpp index b98203df..923247af 100644 --- a/Firmware/RP2040/src/OGXMini/Board/ESP32_Bluepad32_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/ESP32_Bluepad32_I2C.cpp @@ -16,6 +16,7 @@ #include "Board/board_api.h" #include "Board/esp32_api.h" #include "Gamepad/Gamepad.h" +#include "Gamepad/I2CWirePad.h" #include "TaskQueue/TaskQueue.h" enum class PacketID : uint8_t { @@ -31,7 +32,7 @@ struct PacketIn { PacketID packet_id{PacketID::SET_PAD}; uint8_t index{0}; DeviceDriverType device_type{DeviceDriverType::NONE}; - Gamepad::PadIn pad_in{Gamepad::PadIn()}; + I2CWirePadIn pad_in{}; uint8_t reserved[5]{0}; }; static_assert(sizeof(PacketIn) == 32, "i2c_driver_esp::PacketIn size mismatch"); @@ -73,7 +74,7 @@ static inline void slave_handler(i2c_inst_t *i2c, i2c_slave_event_t event) { switch (packet_in.packet_id) { case PacketID::SET_PAD: if (packet_in.index < MAX_GAMEPADS) { - _gamepads[packet_in.index].set_pad_in(packet_in.pad_in); + _gamepads[packet_in.index].set_pad_in(i2c_pad_from_wire(packet_in.pad_in)); } break; case PacketID::SET_DRIVER: diff --git a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp index 63bfee31..7711f6ce 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp @@ -20,6 +20,7 @@ #include "Board/ogxm_log.h" #include "UserSettings/UserSettings.h" #include "Gamepad/Gamepad.h" +#include "Gamepad/I2CWirePad.h" #include "TaskQueue/TaskQueue.h" constexpr uint32_t FEEDBACK_DELAY_MS = 250; @@ -54,7 +55,7 @@ namespace I2C { struct PacketIn { uint8_t packet_len{sizeof(PacketIn)}; PacketID packet_id{PacketID::PAD}; - Gamepad::PadIn pad_in{Gamepad::PadIn()}; + I2CWirePadIn pad_in{}; Gamepad::ChatpadIn chatpad_in{0}; uint8_t reserved[4]{0}; }; @@ -128,7 +129,7 @@ namespace I2C { // instance_->packet_in_ = *packet_in_p; // *packet_out_p = instance_->packet_out_; // instance_->new_pad_in_.store(true); - _gamepads[0].set_pad_in(packet_in_p->pad_in); + _gamepads[0].set_pad_in(i2c_pad_from_wire(packet_in_p->pad_in)); if (_gamepads[0].new_pad_out()) { packet_out_p->pad_out = _gamepads[0].get_pad_out(); } @@ -249,7 +250,7 @@ namespace I2C { if (packet_cmd.status == Status::READY) { Gamepad& gamepad = _gamepads[i + 1]; PacketIn packet_in; - packet_in.pad_in = gamepad.get_pad_in(); + packet_in.pad_in = i2c_wire_pad_from(gamepad.get_pad_in()); packet_in.chatpad_in = gamepad.get_chatpad_in(); if (write_blocking(slave.address, &packet_in, sizeof(PacketIn))) { diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index dd217389..a5e5dabd 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -106,8 +106,9 @@ static void pico_w_usb_sof_timer_stop() { /** Debounce any unplug hint (line / stack / idle) past USB bus reset glitches (10–50 ms). */ constexpr int32_t USB_UNPLUG_DEBOUNCE_US = 60 * 1000; /** If D+/D− never read as SE0 under PIO, IN reports stop when the cable is pulled — detect unplug this way. - * Keep high enough that HID pads that only report on change are not mistaken for unplug. */ -constexpr uint32_t USB_UNPLUG_NO_INPUT_MS = 3000; + * Keep high enough that HID pads that only report on change are not mistaken for unplug. + * 360 wireless receiver sends status even with no controller paired. */ +constexpr uint32_t USB_UNPLUG_NO_INPUT_MS = 10000; static bool s_usb_unplug_debounce_armed = false; static absolute_time_t s_usb_unplug_debounce_since; diff --git a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp index a0a96437..8e863776 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "tusb.h" #include "bsp/board_api.h" @@ -21,12 +22,87 @@ #include "Gamepad/Gamepad.h" #include "UserSettings/UserSettings.h" #include "Board/board_api.h" +#include "Board/board_api_private/board_api_private.h" #include "Board/ogxm_log.h" constexpr uint32_t FEEDBACK_DELAY_MS = 200; Gamepad _gamepads[MAX_GAMEPADS]; +static repeating_timer_t s_pio_usb_sof_timer; +static bool s_pio_usb_sof_hw_timer = false; +/** Set during intentional mode-change reboot so host_mounted(false) does not queue a second teardown. */ +static std::atomic s_driver_reboot_pending{false}; + +static void pio_usb_sof_timer_stop() { + if (!s_pio_usb_sof_hw_timer) { + return; + } + cancel_repeating_timer(&s_pio_usb_sof_timer); + s_pio_usb_sof_hw_timer = false; +} + +static bool pio_usb_sof_timer_cb(repeating_timer_t* rt) { + (void)rt; + pio_usb_host_frame(); + return true; +} + +static void pio_usb_sof_timer_start() { + if (s_pio_usb_sof_hw_timer) { + return; + } + if (add_repeating_timer_us(-1000, pio_usb_sof_timer_cb, nullptr, &s_pio_usb_sof_timer)) { + s_pio_usb_sof_hw_timer = true; + } +} + +/** PIO USB has no hardware SOF; run pio_usb_host_frame() at ~1 kHz or IN/OUT transfers stall. */ +static void pio_usb_sof_service_due_frames() { + if (s_pio_usb_sof_hw_timer) { + return; + } + static absolute_time_t next_pio_frame; + static bool next_inited = false; + if (!next_inited) { + next_pio_frame = get_absolute_time(); + next_inited = true; + } + absolute_time_t now = get_absolute_time(); + while (absolute_time_diff_us(next_pio_frame, now) >= 0) { + pio_usb_host_frame(); + next_pio_frame = delayed_by_us(next_pio_frame, 1000); + now = get_absolute_time(); + } +} + +static void configure_pio_usb_host() { + pio_usb_configuration_t pio_cfg = PIO_USB_CONFIG; + pio_cfg.skip_alarm_pool = true; + tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); +} + +static void pio_usb_host_loop_tick() { + pio_usb_sof_service_due_frames(); + tuh_task(); +} + +namespace board_api_usbh { + +void stop_pio_usb_host() { + pio_usb_sof_timer_stop(); + multicore_reset_core1(); + sleep_ms(50); + (void)tuh_deinit(BOARD_TUH_RHPORT); + for (int i = 0; i < 20; ++i) { + tuh_task(); + sleep_ms(1); + } + enable_host_line_irq_monitoring(); +} + +} // namespace board_api_usbh + void core1_task() { HostManager& host_manager = HostManager::get_instance(); host_manager.initialize(_gamepads); @@ -37,10 +113,10 @@ void core1_task() { sleep_ms(100); } - pio_usb_configuration_t pio_cfg = PIO_USB_CONFIG; - tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); - + configure_pio_usb_host(); + board_api_usbh::suspend_line_irq(); tuh_init(BOARD_TUH_RHPORT); + pio_usb_sof_timer_start(); uint32_t tid_feedback = TaskQueue::Core1::get_new_task_id(); TaskQueue::Core1::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, @@ -49,6 +125,7 @@ void core1_task() { }); while (true) { + pio_usb_sof_service_due_frames(); TaskQueue::Core1::process_tasks(); tuh_task(); } @@ -67,6 +144,7 @@ void set_gp_check_timer(uint32_t task_id) { // Check gamepad inputs for button combo to change usb device driver else if (user_settings.check_for_driver_change(_gamepads[0])) { OGXM_LOG("Driver change detected, storing new driver.\n"); + s_driver_reboot_pending = true; user_settings.store_driver_type(user_settings.get_current_driver()); } }); @@ -85,7 +163,7 @@ void standard::host_mounted(bool host_mounted) { return; } - if (!host_mounted && tud_is_inited.load()) { + if (!host_mounted && tud_is_inited.load() && !s_driver_reboot_pending.load()) { TaskQueue::Core0::queue_task([]() { OGXM_LOG("USB disconnected, rebooting.\n"); board_api::usb::disconnect_all(); @@ -125,9 +203,10 @@ void standard::run() { sleep_ms(100); } - pio_usb_configuration_t pio_cfg = PIO_USB_CONFIG; - tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); + configure_pio_usb_host(); + board_api_usbh::suspend_line_irq(); tuh_init(BOARD_TUH_RHPORT); + pio_usb_sof_timer_start(); uint32_t tid_feedback = TaskQueue::Core0::get_new_task_id(); TaskQueue::Core0::queue_delayed_task(tid_feedback, FEEDBACK_DELAY_MS, true, [&host_manager]() { @@ -194,7 +273,7 @@ void standard::run() { while (true) { TaskQueue::Core0::process_tasks(); if (gpio_device_mode) { - tuh_task(); + pio_usb_host_loop_tick(); tud_task(); HostInputSource input_src = UserSettings::get_instance().get_input_source(); if (input_src == HostInputSource::PSX_GPIO) { diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp index 863309a2..a7e9f831 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp @@ -3,6 +3,12 @@ #include "host/usbh.h" #include "class/hid/hid_host.h" +#include "Board/Config.h" +#if defined(CONFIG_EN_USB_HOST) +#include "pio_usb.h" +#endif +#include "pico/time.h" + #include "USBHost/HostDriver/PS3/PS3.h" #if defined(CONFIG_EN_BLUETOOTH) @@ -14,6 +20,38 @@ void uni_bt_get_local_bd_addr_safe(uni_bt_bd_addr_t addr); } #endif +namespace { + +struct SyncXferCtx { + bool done{false}; +}; + +void sync_xfer_cb(tuh_xfer_s* xfer) { + auto* ctx = reinterpret_cast(xfer->user_data); + ctx->done = true; +} + +#if defined(CONFIG_EN_USB_HOST) +void service_usb_host() { + pio_usb_host_frame(); + tuh_task(); +} +#else +void service_usb_host() { + tuh_task(); +} +#endif + +} // namespace + +const tusb_control_request_t PS3Host::ENABLE_USB_REQUEST = { + .bmRequestType = 0x21, + .bRequest = 0x09, // SET_REPORT + .wValue = static_cast((HID_REPORT_TYPE_FEATURE << 8) | PS3::ReportID::FEATURE_F4), + .wIndex = 0x0000, + .wLength = 4, +}; + const tusb_control_request_t PS3Host::RUMBLE_REQUEST = { .bmRequestType = 0x21, @@ -49,7 +87,7 @@ void PS3Host::bt_pair_complete_cb(tuh_xfer_s* xfer) { } init_state->stage = InitStage::DONE; init_state->reports_enabled = true; - send_control_xfer(init_state->dev_addr, &PS3Host::RUMBLE_REQUEST, reinterpret_cast(init_state->out_report), nullptr, 0); + send_control_output_async(init_state->dev_addr, init_state->out_report); } void PS3Host::try_deferred_ds3_bt_pair(uint8_t address) { @@ -69,38 +107,18 @@ void PS3Host::try_deferred_ds3_bt_pair(uint8_t address) { } #endif -void PS3Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) +void PS3Host::init_host_out_report(PS3::OutReport& out, uint8_t player_idx) { - gamepad.set_analog_host(true); - - std::memcpy(reinterpret_cast(&out_report_), - PS3::DEFAULT_OUT_REPORT, - std::min(sizeof(PS3::OutReport), sizeof(PS3::DEFAULT_OUT_REPORT))); - - out_report_.leds_bitmap = 0x1 << (idx_ + 1); - out_report_.leds[idx_].time_enabled = 0xFF; - - init_state_.out_report = &out_report_; - init_state_.dev_addr = address; - init_state_.init_buffer.fill(0); - init_state_.bt_pair_report.fill(0); -#if defined(CONFIG_EN_BLUETOOTH) - init_state_.defer_bt_pair = &ds3_bt_pair_deferred_; - ds3_bt_pair_deferred_ = false; -#endif - - tusb_control_request_t init_request = - { - .bmRequestType = 0xA1, - .bRequest = 0x01, // GET_REPORT - .wValue = (HID_REPORT_TYPE_FEATURE << 8) | 0xF2, - .wIndex = 0x0000, - .wLength = 17 - }; - - send_control_xfer(address, &init_request, init_state_.init_buffer.data(), get_report_complete_cb, reinterpret_cast(&init_state_)); - - tuh_hid_receive_report(address, instance); + /* USB Host Shield PS3_REPORT_BUFFER layout — not gadget DEFAULT_OUT_REPORT (leading 0x01). */ + std::memset(&out, 0, sizeof(out)); + for (int i = 0; i < 4; ++i) { + out.leds[i].time_enabled = 0xFF; + out.leds[i].duty_length = 0x27; + out.leds[i].enabled = 0x10; + out.leds[i].duty_off = 0x00; + out.leds[i].duty_on = 0x32; + } + out.leds_bitmap = static_cast(0x02u << player_idx); } bool PS3Host::send_control_xfer(uint8_t dev_addr, const tusb_control_request_t* request, uint8_t* buffer, tuh_xfer_cb_t complete_cb, uintptr_t user_data) @@ -117,10 +135,33 @@ bool PS3Host::send_control_xfer(uint8_t dev_addr, const tusb_control_request_t* return tuh_control_xfer(&transfer); } -void PS3Host::get_report_complete_cb(tuh_xfer_s *xfer) +bool PS3Host::send_control_xfer_wait(uint8_t dev_addr, const tusb_control_request_t* request, uint8_t* buffer, + uint32_t max_attempts_ms) { - InitState* init_state = reinterpret_cast(xfer->user_data); - if (init_state == nullptr || init_state->stage == InitStage::DONE) + SyncXferCtx ctx; + if (!send_control_xfer(dev_addr, request, buffer, sync_xfer_cb, reinterpret_cast(&ctx))) { + return false; + } + for (uint32_t i = 0; !ctx.done && i < max_attempts_ms; ++i) { + service_usb_host(); + sleep_ms(1); + } + return ctx.done; +} + +bool PS3Host::send_control_output_sync(uint8_t address, PS3::OutReport* report) +{ + return send_control_xfer_wait(address, &RUMBLE_REQUEST, reinterpret_cast(report), 150u); +} + +bool PS3Host::send_control_output_async(uint8_t address, PS3::OutReport* report) +{ + return send_control_xfer(address, &RUMBLE_REQUEST, reinterpret_cast(report), nullptr, 0); +} + +void PS3Host::send_init_get_report(InitState* init_state) +{ + if (init_state == nullptr) { return; } @@ -131,19 +172,75 @@ void PS3Host::get_report_complete_cb(tuh_xfer_s *xfer) .bRequest = 0x01, // GET_REPORT .wValue = (HID_REPORT_TYPE_FEATURE << 8) | 0xF2, .wIndex = 0x0000, - .wLength = 17 + .wLength = (init_state->stage == InitStage::RESP3) ? static_cast(8) : static_cast(17) }; + send_control_xfer(init_state->dev_addr, &init_request, init_state->init_buffer.data(), get_report_complete_cb, + reinterpret_cast(init_state)); +} + +void PS3Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) +{ + (void)report_desc; + (void)desc_len; + + gamepad.set_analog_host(true); + + init_host_out_report(out_report_, idx_); + + init_state_ = InitState{}; + init_state_.out_report = &out_report_; + init_state_.dev_addr = address; + init_state_.usb_instance = instance; +#if defined(CONFIG_EN_BLUETOOTH) + init_state_.defer_bt_pair = &ds3_bt_pair_deferred_; + ds3_bt_pair_deferred_ = false; +#endif + + /* DualShock 3 USB: SET feature 0xF4 {0x42,0x0c,0,0} then one LED OUT (USB Host Shield). */ + uint8_t enable_usb_data[] = {0x42, 0x0c, 0x00, 0x00}; + (void)send_control_xfer_wait(address, &ENABLE_USB_REQUEST, enable_usb_data, 150u); + (void)send_control_output_sync(address, &out_report_); + + init_state_.reports_enabled = true; + init_state_.stage = InitStage::DONE; + last_keepalive_ms_ = time_us_32() / 1000; + +#if defined(CONFIG_EN_BLUETOOTH) + send_init_get_report(&init_state_); +#endif + + tuh_hid_receive_report(address, instance); +} + +void PS3Host::get_report_complete_cb(tuh_xfer_s *xfer) +{ + InitState* init_state = reinterpret_cast(xfer->user_data); + if (init_state == nullptr || init_state->stage == InitStage::DONE) + { + return; + } + + if (xfer->result != XFER_RESULT_SUCCESS) + { + if (init_state->init_retries < MAX_INIT_RETRIES) + { + ++init_state->init_retries; + send_init_get_report(init_state); + } + return; + } + init_state->init_retries = 0; + switch (init_state->stage) { case InitStage::RESP1: init_state->stage = InitStage::RESP2; - send_control_xfer(init_state->dev_addr, &init_request, init_state->init_buffer.data(), get_report_complete_cb, xfer->user_data); + send_init_get_report(init_state); break; case InitStage::RESP2: init_state->stage = InitStage::RESP3; - init_request.wLength = 8; - send_control_xfer(init_state->dev_addr, &init_request, init_state->init_buffer.data(), get_report_complete_cb, xfer->user_data); + send_init_get_report(init_state); break; case InitStage::RESP3: #if defined(CONFIG_EN_BLUETOOTH) @@ -164,7 +261,7 @@ void PS3Host::get_report_complete_cb(tuh_xfer_s *xfer) #endif init_state->stage = InitStage::DONE; init_state->reports_enabled = true; - send_control_xfer(init_state->dev_addr, &PS3Host::RUMBLE_REQUEST, reinterpret_cast(init_state->out_report), nullptr, 0); + send_control_output_async(init_state->dev_addr, init_state->out_report); break; default: break; @@ -230,25 +327,28 @@ void PS3Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance bool PS3Host::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) { - static uint32_t last_rumble_ms = 0; + (void)instance; - uint32_t current_ms = time_us_32() / 1000; - - //Spamming set_report doesn't work, limit the rate - if (init_state_.reports_enabled && - current_ms - last_rumble_ms >= 300) - { - Gamepad::PadOut gp_out = gamepad.get_pad_out(); + if (!init_state_.reports_enabled) { + return false; + } - out_report_.rumble.right_duration = (gp_out.rumble_r > 0) ? 20 : 0; - out_report_.rumble.right_motor_on = (gp_out.rumble_r > 0) ? 1 : 0; + const uint32_t current_ms = time_us_32() / 1000; + Gamepad::PadOut gp_out = gamepad.get_pad_out(); + const bool has_rumble = (gp_out.rumble_l != 0 || gp_out.rumble_r != 0); + const bool keepalive_due = + KEEPALIVE_MS != 0u && (current_ms - last_keepalive_ms_ >= KEEPALIVE_MS); - out_report_.rumble.left_duration = (gp_out.rumble_l > 0) ? 20 : 0; - out_report_.rumble.left_motor_force = gp_out.rumble_l; + if (!has_rumble && !gamepad.new_pad_out() && !keepalive_due) { + return true; + } - last_rumble_ms = current_ms; + out_report_.rumble.right_duration = (gp_out.rumble_r > 0) ? 20 : 0; + out_report_.rumble.right_motor_on = (gp_out.rumble_r > 0) ? 1 : 0; + out_report_.rumble.left_duration = (gp_out.rumble_l > 0) ? 20 : 0; + out_report_.rumble.left_motor_force = gp_out.rumble_l; + out_report_.leds_bitmap = static_cast(0x02u << idx_); - return send_control_xfer(address, &PS3Host::RUMBLE_REQUEST, reinterpret_cast(&out_report_), nullptr, 0); - } - return true; -} \ No newline at end of file + last_keepalive_ms_ = current_ms; + return send_control_output_async(address, &out_report_); +} diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h index b9d7b8d0..9ea55218 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h @@ -26,14 +26,26 @@ class PS3Host : public HostDriver { uint8_t dev_addr{0xFF}; InitStage stage{InitStage::RESP1}; + uint8_t init_retries{0}; std::array init_buffer; std::array bt_pair_report{}; PS3::OutReport* out_report{nullptr}; + uint8_t usb_instance{0}; bool reports_enabled{false}; /** If set, points to PS3Host::ds3_bt_pair_deferred_ — BT addr was not ready during init. */ bool* defer_bt_pair{nullptr}; }; + static constexpr uint8_t MAX_INIT_RETRIES = 3; + + static void send_init_get_report(InitState* init_state); + static void init_host_out_report(PS3::OutReport& out, uint8_t player_idx); + static bool send_control_xfer_wait(uint8_t dev_addr, const tusb_control_request_t* req, uint8_t* buffer, + uint32_t max_attempts_ms); + static bool send_control_output_sync(uint8_t address, PS3::OutReport* report); + static bool send_control_output_async(uint8_t address, PS3::OutReport* report); + + static const tusb_control_request_t ENABLE_USB_REQUEST; static const tusb_control_request_t RUMBLE_REQUEST; #if defined(CONFIG_EN_BLUETOOTH) /** HID feature report: program DualShock 3 master Bluetooth address (see Bluepad32 sixaxispairer). */ @@ -43,6 +55,12 @@ class PS3Host : public HostDriver PS3::InReport prev_in_report_; PS3::OutReport out_report_; InitState init_state_; + uint32_t last_keepalive_ms_{0}; +#if defined(CONFIG_EN_USB_HOST) + static constexpr uint32_t KEEPALIVE_MS = 1000u; +#else + static constexpr uint32_t KEEPALIVE_MS = 0u; +#endif #if defined(CONFIG_EN_BLUETOOTH) /** Persistent buffer for async SET_REPORT (feature 0xF5). */ std::array bt_pair_buf_{}; diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp index a617f121..e2244bbe 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp @@ -36,15 +36,9 @@ const uint8_t* switch2_payload(const uint8_t* report, uint16_t len, uint16_t& ou void Switch2ProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) { - if (switch2_bringup_active_) + if (switch2_bringup_active_ || init_state_ != InitState::DONE) { - tuh_hid_receive_report(address, instance); - return; - } - - if (init_state_ != InitState::DONE) - { - init_switch_host(gamepad, address, instance); + SwitchProHost::process_report(gamepad, address, instance, report, len); return; } diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp index 5762e0b6..46fe4250 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp @@ -5,8 +5,43 @@ #include "class/hid/hid_host.h" #include "common/tusb_types.h" +#include "Board/Config.h" +#include "Board/board_api.h" +#if defined(CONFIG_EN_USB_HOST) +#include "pio_usb.h" +#endif + #include "USBHost/HostDriver/SwitchPro/SwitchPro.h" #include "USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h" +#include "USBHost/HostManager.h" + +namespace { + +#if defined(CONFIG_EN_USB_HOST) +void service_usb_host() { + pio_usb_host_frame(); + tuh_task(); +} +#else +void service_usb_host() { + tuh_task(); +} +#endif + +bool try_hid_out_id(uint8_t address, uint8_t instance, uint8_t report_id, const void* report, uint16_t len) { + if (!tuh_hid_send_ready(address, instance)) { + return false; + } + return tuh_hid_send_report(address, instance, report_id, report, len); +} + +bool try_hid_out(uint8_t address, uint8_t instance, const void* report, uint16_t len) { + return try_hid_out_id(address, instance, 0, report, len); +} + +constexpr uint8_t kInitForceAdvanceRetries = 8; + +} // namespace bool SwitchProHost::is_switch2_usb_family(uint16_t vid, uint16_t pid) { @@ -26,6 +61,52 @@ bool SwitchProHost::is_switch2_usb_family(uint16_t vid, uint16_t pid) } } +SwitchProHost::~SwitchProHost() +{ + switch2_cancel_bringup(); +} + +void SwitchProHost::disconnect_cb(Gamepad& gamepad, uint8_t address, uint8_t instance) +{ + (void)gamepad; + (void)address; + (void)instance; + switch2_cancel_bringup(); +} + +uintptr_t SwitchProHost::switch2_make_cb_token(uint8_t daddr, uint8_t instance) +{ + return (static_cast(instance) << 8) | daddr; +} + +SwitchProHost* SwitchProHost::switch2_lookup(uint8_t daddr, uint8_t instance) +{ + return HostManager::get_instance().get_switch_pro_host(daddr, instance); +} + +void SwitchProHost::switch2_cancel_bringup() +{ + switch2_bringup_active_ = false; + switch2_bringup_pending_retry_ = false; + switch2_next_packet_ms_ = 0; + switch2_pkt_idx_ = 0; + + if (switch2_dev_addr_ != 0) + { + if (switch2_ep_out_ != 0) + { + (void)tuh_edpt_abort_xfer(switch2_dev_addr_, switch2_ep_out_); + } + if (switch2_ep_in_ != 0) + { + (void)tuh_edpt_abort_xfer(switch2_dev_addr_, switch2_ep_in_); + } + } + + switch2_ep_out_ = 0; + switch2_ep_in_ = 0; +} + void SwitchProHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { @@ -33,10 +114,17 @@ void SwitchProHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instan (void)desc_len; std::memset(&out_report_, 0, sizeof(out_report_)); + std::memset(&prev_in_report_, 0, sizeof(prev_in_report_)); + sequence_counter_ = 0; hid_instance_ = instance; switch2_dev_addr_ = address; switch2_gamepad_ = &gamepad; - init_state_ = InitState::HANDSHAKE; + init_state_ = InitState::USB_MAC; + pending_usb_ack_ = 0; + pending_subcmd_ack_ = 0; + init_step_retries_ = 0; + usb_timeout_sent_ = false; + switch2_cancel_bringup(); uint16_t vid = 0; uint16_t pid = 0; @@ -44,19 +132,24 @@ void SwitchProHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instan if (is_switch2_usb_family(vid, pid)) { - switch2_bringup_active_ = true; - switch2_pkt_idx_ = 0; - switch2_ep_out_ = 0; - switch2_ep_in_ = 0; - switch2_start_config_read(); + switch2_start_bringup(); } else { - switch2_bringup_active_ = false; - init_switch_host(gamepad, address, instance); + start_usb_wired_init(address, instance); } } +void SwitchProHost::switch2_start_bringup() +{ + switch2_bringup_active_ = true; + switch2_pkt_idx_ = 0; + switch2_ep_out_ = 0; + switch2_ep_in_ = 0; + switch2_next_packet_ms_ = 0; + switch2_start_config_read(); +} + void SwitchProHost::switch2_start_config_read() { if (!tuh_descriptor_get_configuration( @@ -65,7 +158,7 @@ void SwitchProHost::switch2_start_config_read() switch2_cfg_buf_.data(), static_cast(switch2_cfg_buf_.size()), switch2_cfg_cb, - reinterpret_cast(this))) + switch2_make_cb_token(switch2_dev_addr_, hid_instance_))) { switch2_finish_bringup(); } @@ -140,7 +233,9 @@ bool SwitchProHost::switch2_parse_open_iface1(const uint8_t* desc_cfg, uint16_t void SwitchProHost::switch2_cfg_cb(tuh_xfer_s* xfer) { - auto* self = reinterpret_cast(xfer->user_data); + const uint8_t daddr = xfer->daddr; + const uint8_t instance = static_cast(xfer->user_data >> 8); + SwitchProHost* self = switch2_lookup(daddr, instance); if (self == nullptr || !self->switch2_bringup_active_) { return; @@ -154,6 +249,23 @@ void SwitchProHost::switch2_cfg_cb(tuh_xfer_s* xfer) } uint16_t actual = static_cast(xfer->actual_len); + auto const* cfg = reinterpret_cast(self->switch2_cfg_buf_.data()); + const uint16_t total = tu_le16toh(cfg->wTotalLength); + if (total > actual && total <= self->switch2_cfg_buf_.size()) + { + if (!tuh_descriptor_get_configuration( + self->switch2_dev_addr_, + 0, + self->switch2_cfg_buf_.data(), + total, + switch2_cfg_cb, + switch2_make_cb_token(self->switch2_dev_addr_, self->hid_instance_))) + { + self->switch2_finish_bringup(); + } + return; + } + if (!self->switch2_parse_open_iface1(self->switch2_cfg_buf_.data(), actual)) { self->switch2_finish_bringup(); @@ -166,12 +278,20 @@ void SwitchProHost::switch2_cfg_cb(tuh_xfer_s* xfer) void SwitchProHost::switch2_out_cb(tuh_xfer_s* xfer) { - auto* self = reinterpret_cast(xfer->user_data); + const uint8_t daddr = xfer->daddr; + const uint8_t instance = static_cast(xfer->user_data >> 8); + SwitchProHost* self = switch2_lookup(daddr, instance); if (self == nullptr || !self->switch2_bringup_active_) { return; } + if (xfer->result != XFER_RESULT_SUCCESS) + { + self->switch2_finish_bringup(); + return; + } + if (self->switch2_ep_in_ != 0) { self->switch2_submit_in_read(); @@ -184,7 +304,9 @@ void SwitchProHost::switch2_out_cb(tuh_xfer_s* xfer) void SwitchProHost::switch2_in_cb(tuh_xfer_s* xfer) { - auto* self = reinterpret_cast(xfer->user_data); + const uint8_t daddr = xfer->daddr; + const uint8_t instance = static_cast(xfer->user_data >> 8); + SwitchProHost* self = switch2_lookup(daddr, instance); if (self == nullptr || !self->switch2_bringup_active_) { return; @@ -210,11 +332,11 @@ void SwitchProHost::switch2_submit_out_packet() xfer.buflen = pkt.len; xfer.buffer = switch2_bulk_out_buf_.data(); xfer.complete_cb = switch2_out_cb; - xfer.user_data = reinterpret_cast(this); + xfer.user_data = switch2_make_cb_token(switch2_dev_addr_, hid_instance_); if (!tuh_edpt_xfer(&xfer)) { - switch2_after_packet_round(); + switch2_next_packet_ms_ = board_api::ms_since_boot() + 12U; } } @@ -226,11 +348,11 @@ void SwitchProHost::switch2_submit_in_read() xfer.buflen = 64; xfer.buffer = switch2_bulk_in_buf_.data(); xfer.complete_cb = switch2_in_cb; - xfer.user_data = reinterpret_cast(this); + xfer.user_data = switch2_make_cb_token(switch2_dev_addr_, hid_instance_); if (!tuh_edpt_xfer(&xfer)) { - switch2_after_packet_round(); + switch2_next_packet_ms_ = board_api::ms_since_boot() + 12U; } } @@ -242,122 +364,184 @@ void SwitchProHost::switch2_after_packet_round() switch2_finish_bringup(); return; } + switch2_next_packet_ms_ = board_api::ms_since_boot() + 12U; +} + +void SwitchProHost::switch2_poll_bringup() +{ + if (!switch2_bringup_active_ || switch2_next_packet_ms_ == 0) + { + return; + } + if (board_api::ms_since_boot() < switch2_next_packet_ms_) + { + return; + } + switch2_next_packet_ms_ = 0; switch2_submit_out_packet(); } void SwitchProHost::switch2_finish_bringup() { + const bool bulk_complete = switch2_pkt_idx_ >= SWITCH2_USB_BULK_PACKET_COUNT; switch2_bringup_active_ = false; - if (switch2_gamepad_ != nullptr) + switch2_next_packet_ms_ = 0; + + if (switch2_gamepad_ == nullptr) { - init_switch_host(*switch2_gamepad_, switch2_dev_addr_, hid_instance_); + return; + } + + if (bulk_complete) + { + /* Switch 2–family: bulk bring-up replaces Switch 1 wired 0x80 HID init. */ + init_state_ = InitState::DONE; + pending_usb_ack_ = 0; + pending_subcmd_ack_ = 0; + tuh_hid_receive_report(switch2_dev_addr_, hid_instance_); + return; } + + switch2_bringup_pending_retry_ = true; } -uint8_t SwitchProHost::get_output_sequence_counter() +bool SwitchProHost::send_usb_wired_command(uint8_t address, uint8_t instance, uint8_t subcmd) { - uint8_t counter = sequence_counter_; - sequence_counter_ = (sequence_counter_ + 1) & 0x0F; - return counter; + uint8_t payload[63] = {0}; + payload[0] = subcmd; + pending_usb_ack_ = subcmd; + return try_hid_out_id(address, instance, SwitchPro::REPORT_ID_USB_OUT, payload, sizeof(payload)); } -// The other way is to write a class driver just for switch pro, we'll see if there are issues with this -void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t instance) +void SwitchProHost::start_usb_wired_init(uint8_t address, uint8_t instance) { - // See: https://github.com/Dan611/hid-procon - // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering - // https://github.com/HisashiKato/USB_Host_Shield_Library_2.0 + init_state_ = InitState::USB_MAC; + pending_usb_ack_ = SwitchPro::CMD::USB_SUB_MAC; + (void)send_usb_wired_command(address, instance, SwitchPro::CMD::USB_SUB_MAC); + tuh_hid_receive_report(address, instance); +} - std::memset(&out_report_, 0, sizeof(out_report_)); +void SwitchProHost::fill_neutral_rumble(SwitchPro::OutReport& out) +{ + out.rumble_l[0] = 0x00; + out.rumble_l[1] = 0x01; + out.rumble_l[2] = 0x40; + out.rumble_l[3] = 0x40; + out.rumble_r[0] = 0x00; + out.rumble_r[1] = 0x01; + out.rumble_r[2] = 0x40; + out.rumble_r[3] = 0x40; +} - uint8_t report_size = 10; +void SwitchProHost::advance_after_usb_ack(Gamepad& gamepad, uint8_t address, uint8_t instance) +{ + switch (init_state_) + { + case InitState::USB_MAC: + init_state_ = InitState::USB_HANDSHAKE1; + (void)send_usb_wired_command(address, instance, SwitchPro::CMD::USB_SUB_HANDSHAKE); + break; + case InitState::USB_HANDSHAKE1: + init_state_ = InitState::USB_BAUD; + (void)send_usb_wired_command(address, instance, SwitchPro::CMD::USB_SUB_BAUD); + break; + case InitState::USB_BAUD: + init_state_ = InitState::USB_HANDSHAKE2; + (void)send_usb_wired_command(address, instance, SwitchPro::CMD::USB_SUB_HANDSHAKE); + break; + case InitState::USB_HANDSHAKE2: + init_state_ = InitState::USB_NO_TIMEOUT; + send_usb_disable_timeout_and_probe(address, instance); + break; + default: + break; + } +} - out_report_.command = SwitchPro::CMD::RUMBLE_ONLY; - out_report_.sequence_counter = get_output_sequence_counter(); +void SwitchProHost::send_usb_disable_timeout_and_probe(uint8_t address, uint8_t instance) +{ + uint8_t usb_out[63] = {0}; + usb_out[0] = SwitchPro::CMD::USB_SUB_DISABLE_TIMEOUT; + (void)try_hid_out_id(address, instance, SwitchPro::REPORT_ID_USB_OUT, usb_out, sizeof(usb_out)); - out_report_.rumble_l[0] = 0x00; - out_report_.rumble_l[1] = 0x01; - out_report_.rumble_l[2] = 0x40; - out_report_.rumble_l[3] = 0x40; + std::memset(&out_report_, 0, sizeof(out_report_)); + fill_neutral_rumble(out_report_); + out_report_.command = SwitchPro::CMD::AND_RUMBLE; + out_report_.sequence_counter = get_output_sequence_counter(); + out_report_.sub_command = SwitchPro::CMD::USB_PROBE; + pending_subcmd_ack_ = SwitchPro::CMD::USB_PROBE; + (void)try_hid_out(address, instance, &out_report_, 11); + usb_timeout_sent_ = true; + init_step_retries_ = 0; +} - out_report_.rumble_r[0] = 0x00; - out_report_.rumble_r[1] = 0x01; - out_report_.rumble_r[2] = 0x40; - out_report_.rumble_r[3] = 0x40; +void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t instance) +{ + (void)gamepad; - switch (init_state_) + if (init_state_ <= InitState::USB_HANDSHAKE2) { - case InitState::HANDSHAKE: - report_size = 2; + if (pending_usb_ack_ != 0) + { + (void)send_usb_wired_command(address, instance, pending_usb_ack_); + } + return; + } - out_report_.command = SwitchPro::CMD::HID; - out_report_.sequence_counter = SwitchPro::CMD::HANDSHAKE; + if (init_state_ == InitState::USB_NO_TIMEOUT) + { + if (!usb_timeout_sent_) + { + send_usb_disable_timeout_and_probe(address, instance); + } + return; + } - if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) - { - init_state_ = InitState::TIMEOUT; - } - break; - case InitState::TIMEOUT: - report_size = 2; + if (!tuh_hid_send_ready(address, instance)) + { + return; + } - out_report_.command = SwitchPro::CMD::HID; - out_report_.sequence_counter = SwitchPro::CMD::DISABLE_TIMEOUT; + std::memset(&out_report_, 0, sizeof(out_report_)); + fill_neutral_rumble(out_report_); + out_report_.command = SwitchPro::CMD::AND_RUMBLE; + out_report_.sequence_counter = get_output_sequence_counter(); - if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) - { - init_state_ = InitState::LED; - } - break; + switch (init_state_) + { case InitState::LED: - report_size = 12; - - out_report_.command = SwitchPro::CMD::AND_RUMBLE; out_report_.sub_command = SwitchPro::CMD::LED; out_report_.sub_command_args[0] = idx_ + 1; - - if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + if (try_hid_out(address, instance, &out_report_, 12)) { init_state_ = InitState::LED_HOME; } break; case InitState::LED_HOME: - report_size = 14; - - out_report_.command = SwitchPro::CMD::AND_RUMBLE; out_report_.sub_command = SwitchPro::CMD::LED_HOME; - out_report_.sub_command_args[0] = (0 /* Number of cycles */ << 4) | (true ? 0xF : 0); - out_report_.sub_command_args[1] = (0xF /* LED start intensity */ << 4) | 0x0 /* Number of full cycles */; - out_report_.sub_command_args[2] = (0xF /* Mini Cycle 1 LED intensity */ << 4) | 0x0 /* Mini Cycle 2 LED intensity */; - - if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + out_report_.sub_command_args[0] = static_cast((0 << 4) | 0xF); + out_report_.sub_command_args[1] = static_cast((0xF << 4) | 0x0); + out_report_.sub_command_args[2] = static_cast((0xF << 4) | 0x0); + if (try_hid_out(address, instance, &out_report_, 14)) { init_state_ = InitState::FULL_REPORT; } break; case InitState::FULL_REPORT: - report_size = 12; - - out_report_.command = SwitchPro::CMD::AND_RUMBLE; out_report_.sub_command = SwitchPro::CMD::MODE; out_report_.sub_command_args[0] = SwitchPro::CMD::FULL_REPORT_MODE; - - if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + if (try_hid_out(address, instance, &out_report_, 12)) { init_state_ = InitState::IMU; } break; case InitState::IMU: - report_size = 12; - - out_report_.command = SwitchPro::CMD::AND_RUMBLE; out_report_.sub_command = SwitchPro::CMD::GYRO; - out_report_.sub_command_args[0] = 1 ? 1 : 0; - - if (tuh_hid_send_report(address, instance, 0, &out_report_, report_size)) + out_report_.sub_command_args[0] = 1; + if (try_hid_out(address, instance, &out_report_, 12)) { init_state_ = InitState::DONE; - tuh_hid_receive_report(address, instance); + pending_subcmd_ack_ = 0; } break; default: @@ -365,6 +549,13 @@ void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t } } +uint8_t SwitchProHost::get_output_sequence_counter() +{ + uint8_t counter = sequence_counter_; + sequence_counter_ = (sequence_counter_ + 1) & 0x0F; + return counter; +} + static const uint8_t* switchpro_report_payload(const uint8_t* report, uint16_t len, uint16_t& out_payload_len) { out_payload_len = len; @@ -396,7 +587,27 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in if (init_state_ != InitState::DONE) { - init_switch_host(gamepad, address, instance); + if (len >= 2 && report[0] == SwitchPro::REPORT_ID_USB_INIT && + init_state_ <= InitState::USB_HANDSHAKE2) + { + const uint8_t ack = report[1]; + if (ack == pending_usb_ack_) + { + advance_after_usb_ack(gamepad, address, instance); + } + } + else if (init_state_ == InitState::USB_NO_TIMEOUT && + len >= 1 && report[0] == SwitchPro::REPORT_ID_SUBCMD) + { + init_state_ = InitState::LED; + pending_subcmd_ack_ = 0; + init_switch_host(gamepad, address, instance); + } + else if (init_state_ > InitState::USB_NO_TIMEOUT) + { + init_switch_host(gamepad, address, instance); + } + tuh_hid_receive_report(address, instance); return; } @@ -430,9 +641,9 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in if (in_report->buttons[0] & SwitchPro::Buttons0::R) gp_in.buttons |= gamepad.MAP_BUTTON_RB; if (in_report->buttons[1] & SwitchPro::Buttons1::L3) - gp_in.buttons |= gamepad.MAP_BUTTON_L3; - if (in_report->buttons[1] & SwitchPro::Buttons1::R3) gp_in.buttons |= gamepad.MAP_BUTTON_R3; + if (in_report->buttons[1] & SwitchPro::Buttons1::R3) + gp_in.buttons |= gamepad.MAP_BUTTON_L3; if (in_report->buttons[1] & SwitchPro::Buttons1::MINUS) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; if (in_report->buttons[1] & SwitchPro::Buttons1::PLUS) @@ -443,13 +654,13 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in gp_in.buttons |= gamepad.MAP_BUTTON_MISC; if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_UP) - gp_in.dpad |= gamepad.MAP_DPAD_UP; - if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_DOWN) + gp_in.dpad |= gamepad.MAP_DPAD_UP; if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_LEFT) - gp_in.dpad |= gamepad.MAP_DPAD_LEFT; - if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + if (in_report->buttons[2] & SwitchPro::Buttons2::DPAD_RIGHT) + gp_in.dpad |= gamepad.MAP_DPAD_LEFT; gp_in.trigger_l = in_report->buttons[2] & SwitchPro::Buttons2::ZL ? Range::MAX : Range::MIN; gp_in.trigger_r = in_report->buttons[0] & SwitchPro::Buttons0::ZR ? Range::MAX : Range::MIN; @@ -473,27 +684,48 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) { - if (switch2_bringup_active_) + uint16_t vid = 0; + uint16_t pid = 0; + tuh_vid_pid_get(address, &vid, &pid); + const bool switch2_device = is_switch2_usb_family(vid, pid); + + if (switch2_device && switch2_bringup_active_) + { + switch2_poll_bringup(); + service_usb_host(); + return false; + } + + if (switch2_device && switch2_bringup_pending_retry_) { + switch2_bringup_pending_retry_ = false; + switch2_start_bringup(); + service_usb_host(); return false; } if (init_state_ != InitState::DONE) { + if (init_state_ == InitState::USB_NO_TIMEOUT) + { + if (++init_step_retries_ >= kInitForceAdvanceRetries) + { + init_state_ = InitState::LED; + pending_subcmd_ack_ = 0; + usb_timeout_sent_ = false; + } + } init_switch_host(gamepad, address, instance); + tuh_hid_receive_report(address, instance); + service_usb_host(); return false; } - // See: https://github.com/Dan611/hid-procon - // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering - // https://github.com/HisashiKato/USB_Host_Shield_Library_2.0 - std::memset(&out_report_, 0, sizeof(out_report_)); - uint8_t report_size = 10; - out_report_.command = SwitchPro::CMD::RUMBLE_ONLY; out_report_.sequence_counter = get_output_sequence_counter(); + fill_neutral_rumble(out_report_); Gamepad::PadOut gp_out = gamepad.get_pad_out(); @@ -506,13 +738,6 @@ bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t ins out_report_.rumble_l[2] = amplitude_l / 2; out_report_.rumble_l[3] = 0x61; } - else - { - out_report_.rumble_l[0] = 0x00; - out_report_.rumble_l[1] = 0x01; - out_report_.rumble_l[2] = 0x40; - out_report_.rumble_l[3] = 0x40; - } if (gp_out.rumble_r > 0) { @@ -523,13 +748,10 @@ bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t ins out_report_.rumble_r[2] = amplitude_r / 2; out_report_.rumble_r[3] = 0x61; } - else + + if (!tuh_hid_send_ready(address, instance)) { - out_report_.rumble_r[0] = 0x00; - out_report_.rumble_r[1] = 0x01; - out_report_.rumble_r[2] = 0x40; - out_report_.rumble_r[3] = 0x40; + return false; } - - return tuh_hid_send_report(address, instance, 0, &out_report_, report_size); + return tuh_hid_send_report(address, instance, 0, &out_report_, 10); } diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h index 67ee7dc9..032e778a 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h @@ -18,23 +18,32 @@ class SwitchProHost : public HostDriver void initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) override; void process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) override; bool send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) override; + void disconnect_cb(Gamepad& gamepad, uint8_t address, uint8_t instance) override; + ~SwitchProHost() override; static bool is_switch2_usb_family(uint16_t vid, uint16_t pid); protected: enum class InitState { - HANDSHAKE, - TIMEOUT, - FULL_REPORT, + USB_MAC, + USB_HANDSHAKE1, + USB_BAUD, + USB_HANDSHAKE2, + USB_NO_TIMEOUT, LED, LED_HOME, + FULL_REPORT, IMU, DONE }; - InitState init_state_{InitState::HANDSHAKE}; + InitState init_state_{InitState::USB_MAC}; uint8_t sequence_counter_{0}; + uint8_t pending_usb_ack_{0}; + uint8_t pending_subcmd_ack_{0}; + uint8_t init_step_retries_{0}; + bool usb_timeout_sent_{false}; SwitchPro::InReport prev_in_report_{}; SwitchPro::OutReport out_report_{}; @@ -49,8 +58,16 @@ class SwitchProHost : public HostDriver std::array switch2_bulk_out_buf_{}; std::array switch2_bulk_in_buf_{}; unsigned switch2_pkt_idx_{0}; + uint32_t switch2_next_packet_ms_{0}; + bool switch2_bringup_pending_retry_{false}; + void switch2_poll_bringup(); + void switch2_start_bringup(); void switch2_start_config_read(); + void switch2_cancel_bringup(); + + static uintptr_t switch2_make_cb_token(uint8_t daddr, uint8_t instance); + static SwitchProHost* switch2_lookup(uint8_t daddr, uint8_t instance); bool switch2_parse_open_iface1(const uint8_t* desc_cfg, uint16_t buflen); void switch2_submit_out_packet(); void switch2_submit_in_read(); @@ -62,6 +79,11 @@ class SwitchProHost : public HostDriver static void switch2_in_cb(tuh_xfer_s* xfer); void init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t instance); + void start_usb_wired_init(uint8_t address, uint8_t instance); + bool send_usb_wired_command(uint8_t address, uint8_t instance, uint8_t subcmd); + void advance_after_usb_ack(Gamepad& gamepad, uint8_t address, uint8_t instance); + void send_usb_disable_timeout_and_probe(uint8_t address, uint8_t instance); + void fill_neutral_rumble(SwitchPro::OutReport& out); uint8_t get_output_sequence_counter(); static inline int16_t normalize_axis(uint16_t value) diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.cpp index 39a4803e..f516c8de 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.cpp @@ -9,6 +9,7 @@ #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/XInput/Xbox360W.h" #include "Board/ogxm_log.h" +#include "Descriptors/XInput.h" Xbox360WHost::~Xbox360WHost() { @@ -17,99 +18,124 @@ Xbox360WHost::~Xbox360WHost() void Xbox360WHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { - tuh_xinput::receive_report(address, instance); + (void)gamepad; + (void)address; + (void)instance; + (void)report_desc; + (void)desc_len; + /* IN polling is started from tuh_xinput set_config for every wireless port. */ } void Xbox360WHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) { - const XInput::InReportWireless* in_report = reinterpret_cast(report); - - if (in_report->command[1] & 2) + if (report[1] & 2) { - if (in_report->chatpad_status == 0x00) - { - Gamepad::ChatpadIn gp_in_chatpad; - gp_in_chatpad[0] = in_report->chatpad[0]; - gp_in_chatpad[1] = in_report->chatpad[1]; - gp_in_chatpad[2] = in_report->chatpad[2]; - - gamepad.set_chatpad_in(gp_in_chatpad); - } - else if (in_report->chatpad_status == 0xF0 && in_report->chatpad[0] == 0x03) + if (len >= sizeof(XInput::InReportWireless)) { - tuh_xinput::xbox360_chatpad_init(address, instance); + const XInput::InReportWireless* in_report = reinterpret_cast(report); + if (in_report->chatpad_status == 0x00) + { + Gamepad::ChatpadIn gp_in_chatpad; + gp_in_chatpad[0] = in_report->chatpad[0]; + gp_in_chatpad[1] = in_report->chatpad[1]; + gp_in_chatpad[2] = in_report->chatpad[2]; + gamepad.set_chatpad_in(gp_in_chatpad); + } + else if (in_report->chatpad_status == 0xF0 && in_report->chatpad[0] == 0x03) + { + tuh_xinput::xbox360_chatpad_init(address, instance); + } } tuh_xinput::receive_report(address, instance); return; } - if (!(in_report->command[1] & 1) || - !(in_report->report_size == 0x13) || - std::memcmp(&prev_in_report_, in_report, std::min(static_cast(len), sizeof(XInput::InReportWireless))) == 0) + if (!(report[1] & 1) || len < 18 || + (report[5] != 0x13 && report[5] != 0x14)) + { + tuh_xinput::receive_report(address, instance); + return; + } + + if (std::memcmp(prev_in_report_, report, std::min(static_cast(len), sizeof(prev_in_report_))) == 0) { tuh_xinput::receive_report(address, instance); return; } + const uint16_t wButtons = static_cast(report[6]) | + (static_cast(report[7]) << 8); + Gamepad::PadIn gp_in; - if (in_report->buttons[0] & XInput::Buttons0::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; - if (in_report->buttons[0] & XInput::Buttons0::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; - if (in_report->buttons[0] & XInput::Buttons0::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; - if (in_report->buttons[0] & XInput::Buttons0::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; - - if (in_report->buttons[0] & XInput::Buttons0::START) gp_in.buttons |= gamepad.MAP_BUTTON_START; - if (in_report->buttons[0] & XInput::Buttons0::BACK) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; - if (in_report->buttons[0] & XInput::Buttons0::L3) gp_in.buttons |= gamepad.MAP_BUTTON_L3; - if (in_report->buttons[0] & XInput::Buttons0::R3) gp_in.buttons |= gamepad.MAP_BUTTON_R3; - if (in_report->buttons[1] & XInput::Buttons1::LB) gp_in.buttons |= gamepad.MAP_BUTTON_LB; - if (in_report->buttons[1] & XInput::Buttons1::RB) gp_in.buttons |= gamepad.MAP_BUTTON_RB; - if (in_report->buttons[1] & XInput::Buttons1::HOME) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (in_report->buttons[1] & XInput::Buttons1::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; - if (in_report->buttons[1] & XInput::Buttons1::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; - if (in_report->buttons[1] & XInput::Buttons1::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; - if (in_report->buttons[1] & XInput::Buttons1::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; - - gp_in.trigger_l = gamepad.scale_trigger_l(in_report->trigger_l); - gp_in.trigger_r = gamepad.scale_trigger_r(in_report->trigger_r); - - std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report->joystick_lx, in_report->joystick_ly, true); - std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report->joystick_rx, in_report->joystick_ry, true); + if (wButtons & (1U << 0)) gp_in.dpad |= gamepad.MAP_DPAD_UP; + if (wButtons & (1U << 1)) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (wButtons & (1U << 2)) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + if (wButtons & (1U << 3)) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + if (wButtons & (1U << 4)) gp_in.buttons |= gamepad.MAP_BUTTON_START; + if (wButtons & (1U << 5)) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + if (wButtons & (1U << 6)) gp_in.buttons |= gamepad.MAP_BUTTON_L3; + if (wButtons & (1U << 7)) gp_in.buttons |= gamepad.MAP_BUTTON_R3; + if (wButtons & (1U << 8)) gp_in.buttons |= gamepad.MAP_BUTTON_LB; + if (wButtons & (1U << 9)) gp_in.buttons |= gamepad.MAP_BUTTON_RB; + if (wButtons & (1U << 10)) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + if (wButtons & (1U << 12)) gp_in.buttons |= gamepad.MAP_BUTTON_A; + if (wButtons & (1U << 13)) gp_in.buttons |= gamepad.MAP_BUTTON_B; + if (wButtons & (1U << 14)) gp_in.buttons |= gamepad.MAP_BUTTON_X; + if (wButtons & (1U << 15)) gp_in.buttons |= gamepad.MAP_BUTTON_Y; + + gp_in.trigger_l = gamepad.scale_trigger_l(report[8]); + gp_in.trigger_r = gamepad.scale_trigger_r(report[9]); + + const int16_t joy_lx = static_cast(static_cast(report[10]) | + (static_cast(report[11]) << 8)); + const int16_t joy_ly = static_cast(static_cast(report[12]) | + (static_cast(report[13]) << 8)); + const int16_t joy_rx = static_cast(static_cast(report[14]) | + (static_cast(report[15]) << 8)); + const int16_t joy_ry = static_cast(static_cast(report[16]) | + (static_cast(report[17]) << 8)); + + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(joy_lx, joy_ly, true); + std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(joy_rx, joy_ry, true); gamepad.set_pad_in(gp_in); + std::memcpy(prev_in_report_, report, std::min(static_cast(len), sizeof(prev_in_report_))); tuh_xinput::receive_report(address, instance); - prev_in_report_ = *in_report; } bool Xbox360WHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) { - Gamepad::PadOut gp_out = gamepad.get_pad_out(); - return tuh_xinput::set_rumble(address, instance, gp_out.rumble_l, gp_out.rumble_r, false); + const uint8_t rumble_instance = + (active_address_ == address && active_instance_ != 0xFF) ? active_instance_ : instance; + if (!tuh_xinput::is_connected(address, rumble_instance)) + { + return false; + } + Gamepad::PadOut gp_out = gamepad.get_pad_out(); + if (gp_out.rumble_l == 0 && gp_out.rumble_r == 0) + { + return false; + } + return tuh_xinput::set_rumble(address, rumble_instance, gp_out.rumble_l, gp_out.rumble_r, false); } void Xbox360WHost::connect_cb(Gamepad& gamepad, uint8_t address, uint8_t instance) { - tid_chatpad_keepalive_ = TaskQueue::Core1::get_new_task_id(); - - //Might not be ready for leds yet, needs delay - TaskQueue::Core1::queue_delayed_task(TaskQueue::Core1::get_new_task_id(), 1000, false, - [address, instance, this] - { - tuh_xinput::set_led(address, instance, idx_ + 1, false); - tuh_xinput::xbox360_chatpad_init(address, instance); - - TaskQueue::Core1::queue_delayed_task(tid_chatpad_keepalive_, tuh_xinput::KEEPALIVE_MS, true, - [address, instance] - { - OGXM_LOG("XInput Chatpad Keepalive\r\n"); - tuh_xinput::xbox360_chatpad_keepalive(address, instance); - }); - }); + (void)gamepad; + active_address_ = address; + active_instance_ = instance; } void Xbox360WHost::disconnect_cb(Gamepad& gamepad, uint8_t address, uint8_t instance) { + (void)gamepad; + (void)address; + (void)instance; TaskQueue::Core1::cancel_delayed_task(tid_chatpad_keepalive_); -} \ No newline at end of file + std::memset(prev_in_report_, 0, sizeof(prev_in_report_)); + active_instance_ = 0xFF; + active_address_ = 0xFF; +} diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.h index e048f2d0..dcbee3c5 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360W.h @@ -3,7 +3,6 @@ #include -#include "Descriptors/XInput.h" #include "USBHost/HostDriver/HostDriver.h" class Xbox360WHost : public HostDriver @@ -23,7 +22,9 @@ class Xbox360WHost : public HostDriver private: uint32_t tid_chatpad_keepalive_{0}; - XInput::InReportWireless prev_in_report_; + uint8_t prev_in_report_[32]{0}; + uint8_t active_instance_{0xFF}; + uint8_t active_address_{0xFF}; }; #endif // _XBOX360_WIRELESS_HOST_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp index ba277239..3cfdc4e6 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp @@ -113,10 +113,17 @@ static void std_sleep_ms(uint32_t ms) } } -static void wait_for_tx_complete(uint8_t dev_addr, uint8_t ep_addr) +static void wait_for_tx_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t timeout_ms = 200) { + const auto start = std::chrono::high_resolution_clock::now(); while (usbh_edpt_busy(dev_addr, ep_addr)) { + const auto elapsed = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - start).count(); + if (static_cast(elapsed) >= timeout_ms) + { + return; + } #if defined(CONFIG_EN_USB_HOST) pio_usb_host_frame(); #endif @@ -124,6 +131,8 @@ static void wait_for_tx_complete(uint8_t dev_addr, uint8_t ep_addr) } } +static void prime_port_for_pairing(uint8_t dev_addr, uint8_t instance); + bool send_ctrl_xfer(uint8_t dev_addr, const tusb_control_request_t* request, uint8_t* buffer, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tuh_xfer_s transfer = @@ -277,6 +286,12 @@ static bool set_config(uint8_t dev_addr, uint8_t itf_num) mount_cb(dev_addr, instance, interface); } + if (interface->dev_type == DevType::XBOX360W) + { + receive_report(dev_addr, instance); + prime_port_for_pairing(dev_addr, instance); + } + usbh_driver_set_config_complete(dev_addr, interface->itf_num); return true; } @@ -293,16 +308,22 @@ static bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin { if (dir == TUSB_DIR_IN) { - report_received_cb(dev_addr, instance, interface->ep_in_buffer.data(), interface->ep_in_size); + receive_report(dev_addr, instance); } else if (report_sent_cb) { report_sent_cb(dev_addr, instance, interface->ep_out_buffer.data(), interface->ep_out_size); } + return true; } if (dir == TUSB_DIR_IN) { + if (host_activity_cb) + { + host_activity_cb(dev_addr, instance); + } + bool new_pad_data = false; uint8_t* in_buffer = interface->ep_in_buffer.data(); @@ -317,15 +338,16 @@ static bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin case DevType::XBOX360W: if (in_buffer[0] & 0x08) { - if (in_buffer[1] != 0x00 && !interface->connected) + /* Byte1 bit7 = controller present (0x80). Do not treat headset-only 0x40 as paired. */ + if ((in_buffer[1] & 0x80) && !interface->connected) { interface->connected = true; TU_LOG1("Xbox 360 wireless controller connected\n"); - //I think some 3rd party adapters need this: - std_sleep_ms(1000); send_report(dev_addr, instance, Xbox360W::RUMBLE_ENABLE, sizeof(Xbox360W::RUMBLE_ENABLE)); + wait_for_tx_complete(dev_addr, interface->ep_out); + set_led(dev_addr, instance, wireless_led_quadrant(dev_addr, instance), true); if (xbox360w_connect_cb) { @@ -345,7 +367,9 @@ static bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin } } } - if ((in_buffer[1] & 1 && in_buffer[5] == 0x13) || (in_buffer[1] & 2)) + if (((in_buffer[1] & 1) && xferred_bytes >= 18 && + (in_buffer[5] == 0x13 || in_buffer[5] == 0x14)) || + (in_buffer[1] & 2)) { new_pad_data = true; } @@ -477,6 +501,40 @@ bool receive_report(uint8_t dev_addr, uint8_t instance) return true; } +bool is_connected(uint8_t dev_addr, uint8_t instance) +{ + Interface* interface = get_itf_by_instance(dev_addr, instance); + return interface != nullptr && interface->connected; +} + +uint8_t wireless_led_quadrant(uint8_t dev_addr, uint8_t instance) +{ + Interface* interface = get_itf_by_instance(dev_addr, instance); + if (interface == nullptr || interface->dev_type != DevType::XBOX360W) + { + return static_cast(instance + 1); + } + /* Receiver USB layout: controller ports on interface numbers 0,2,4,6. */ + return static_cast((interface->itf_num / 2) + 1); +} + +void service_wireless_ports(uint8_t dev_addr) +{ + Device* device = get_device_by_addr(dev_addr); + if (device == nullptr) + { + return; + } + for (uint8_t i = 0; i < device->interfaces.size(); ++i) + { + if (device->interfaces[i].dev_type == DevType::XBOX360W && + device->interfaces[i].itf_num != INVALID_IDX) + { + prime_port_for_pairing(dev_addr, i); + } + } +} + bool set_led(uint8_t dev_addr, uint8_t instance, uint8_t quadrant, bool block) { Interface* interface = get_itf_by_instance(dev_addr, instance); @@ -509,6 +567,23 @@ bool set_led(uint8_t dev_addr, uint8_t instance, uint8_t quadrant, bool block) return ret; } +/** RUMBLE_ENABLE + player LED on an idle wireless port so sync can complete on any RF slot. */ +static void prime_port_for_pairing(uint8_t dev_addr, uint8_t instance) +{ + Interface* interface = get_itf_by_instance(dev_addr, instance); + if (interface == nullptr || interface->dev_type != DevType::XBOX360W || + interface->connected || interface->itf_num == INVALID_IDX) + { + return; + } + if (usbh_edpt_busy(dev_addr, interface->ep_out)) + { + return; + } + send_report(dev_addr, instance, Xbox360W::RUMBLE_ENABLE, sizeof(Xbox360W::RUMBLE_ENABLE)); + set_led(dev_addr, instance, wireless_led_quadrant(dev_addr, instance), false); +} + bool set_rumble(uint8_t dev_addr, uint8_t instance, uint8_t rumble_l, uint8_t rumble_r, bool block) { Interface* interface = get_itf_by_instance(dev_addr, instance); @@ -520,9 +595,10 @@ bool set_rumble(uint8_t dev_addr, uint8_t instance, uint8_t rumble_l, uint8_t ru switch (interface->dev_type) { case DevType::XBOX360W: - send_report(dev_addr, instance, Xbox360W::RUMBLE_ENABLE, sizeof(Xbox360W::RUMBLE_ENABLE)); - wait_for_tx_complete(dev_addr, interface->ep_out); - + if (!interface->connected) + { + return false; + } std::memcpy(buffer, Xbox360W::RUMBLE, sizeof(Xbox360W::RUMBLE)); buffer[5] = rumble_l; buffer[6] = rumble_r; @@ -567,7 +643,7 @@ void xbox360_chatpad_init(uint8_t address, uint8_t instance) { TU_LOG1("XInput Chatpad Init\r\n"); - Interface* interface = get_itf_by_itf_num(address, instance); + Interface* interface = get_itf_by_instance(address, instance); TU_VERIFY(interface != nullptr && interface->connected, ); TU_VERIFY(interface->dev_type == DevType::XBOX360W, ); //Only supported on Xbox 360 Wireless atm, wired is more complicated @@ -591,7 +667,7 @@ void xbox360_chatpad_init(uint8_t address, uint8_t instance) bool xbox360_chatpad_keepalive(uint8_t address, uint8_t instance) { - Interface* interface = get_itf_by_itf_num(address, instance); + Interface* interface = get_itf_by_instance(address, instance); TU_VERIFY(interface != nullptr, false); TU_VERIFY(interface->connected && interface->chatpad_inited, false); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h index 76d46bc6..f10ed918 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h @@ -87,6 +87,11 @@ namespace tuh_xinput bool receive_report(uint8_t address, uint8_t instance); bool set_rumble(uint8_t address, uint8_t instance, uint8_t rumble_l, uint8_t rumble_r, bool block); bool set_led(uint8_t address, uint8_t instance, uint8_t led_number, bool block); + bool is_connected(uint8_t address, uint8_t instance); + /** Player LED quadrant (1–4) from wireless receiver USB interface number (0,2,4,6). */ + uint8_t wireless_led_quadrant(uint8_t address, uint8_t instance); + /** Keep all four wireless ports primed (RUMBLE_ENABLE + LED) until a pad connects. */ + void service_wireless_ports(uint8_t dev_addr); //Wireless only atm void xbox360_chatpad_init(uint8_t address, uint8_t instance); @@ -99,6 +104,8 @@ namespace tuh_xinput TU_ATTR_WEAK void report_sent_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); TU_ATTR_WEAK void xbox360w_connect_cb(uint8_t dev_addr, uint8_t instance); TU_ATTR_WEAK void xbox360w_disconnect_cb(uint8_t dev_addr, uint8_t instance); + /** Called on every successful XInput IN transfer (keepalive for host idle watchdog). */ + TU_ATTR_WEAK void host_activity_cb(uint8_t dev_addr, uint8_t instance); void report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); }; // namespace tuh_xinput diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index 067a1cba..27e0a645 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -11,7 +11,7 @@ #include "Board/Config.h" #include "Board/board_api.h" #include "Board/ogxm_log.h" -#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) +#if defined(CONFIG_EN_USB_HOST) #include "pio_usb.h" #endif #include "UserSettings/UserSettings.h" @@ -41,8 +41,9 @@ #include "USBHost/HostDriver/HIDGeneric/HIDGeneric.h" /** Per USB device: TinyUSB HID instance indices and XInput instance indices are separate namespaces - * (both often start at 0). Reserve [0 .. MAX_GAMEPADS-1] for HID and [MAX_GAMEPADS .. 2*MAX-1] for XInput. */ -#define MAX_INTERFACES (MAX_GAMEPADS * 2) + * (both often start at 0). Reserve [0 .. MAX_GAMEPADS-1] for HID and [MAX_GAMEPADS ..] for XInput. + * OGXM_TUH_XINPUT_INSTANCES is 4 when MAX_GAMEPADS < 4 (360 wireless receiver). */ +#define MAX_INTERFACES (MAX_GAMEPADS + OGXM_TUH_XINPUT_INSTANCES) class HostManager { @@ -86,9 +87,26 @@ class HostManager Device& device_slot = device_slots_[dev_idx]; + /* Xbox 360 wireless receiver: one HostManager driver, four tuh_xinput instances. */ + if (driver_type == HostDriverType::XBOX360W && device_slot.address == address) + { + for (uint8_t i = 0; i < MAX_INTERFACES; ++i) + { + if (i == si) + { + continue; + } + const Interface& other = device_slot.interfaces[i]; + if (other.driver && other.host_driver_type == HostDriverType::XBOX360W) + { + return true; + } + } + } + /* One physical pad on a composite that exposes both XInput and HID (e.g. some third-party - * controllers): share gamepad index. Multiple XInput interfaces (Xbox 360 wireless dongle) - * must each get their own slot — do not reuse across same class. */ + * controllers): share gamepad index. Xbox 360 wireless receiver: 4 XInput interfaces share + * one gamepad when MAX_GAMEPADS is 1. */ uint8_t gp_idx = INVALID_IDX; if (device_slot.address == address) { @@ -106,7 +124,10 @@ class HostManager const bool complementary = (dclass == DriverClass::HID && other.driver_class == DriverClass::XINPUT) || (dclass == DriverClass::XINPUT && other.driver_class == DriverClass::HID); - if (complementary) + const bool xbox360w_sibling = + (driver_type == HostDriverType::XBOX360W && + other.host_driver_type == HostDriverType::XBOX360W); + if (complementary || xbox360w_sibling) { gp_idx = other.gamepad_idx; break; @@ -254,12 +275,32 @@ class HostManager } for (auto& device_slot : device_slots_) { - if (device_slot.address == address && - device_slot.interfaces[si].driver && - device_slot.interfaces[si].gamepad) + if (device_slot.address != address) + { + continue; + } + HostDriver* driver = device_slot.interfaces[si].driver.get(); + Gamepad* gamepad = device_slot.interfaces[si].gamepad; + if (!driver || !gamepad) + { + /* 360 wireless receiver: one HostManager driver serves all TinyUSB instances. */ + for (const auto& iface : device_slot.interfaces) + { + if (iface.driver && iface.gamepad && + iface.driver_class == DriverClass::XINPUT && + iface.host_driver_type == HostDriverType::XBOX360W) + { + driver = iface.driver.get(); + gamepad = iface.gamepad; + break; + } + } + } + if (driver && gamepad) { - device_slot.interfaces[si].driver->process_report(*device_slot.interfaces[si].gamepad, address, instance, report, len); + driver->process_report(*gamepad, address, instance, report, len); } + break; } } @@ -272,12 +313,31 @@ class HostManager } for (auto& device_slot : device_slots_) { - if (device_slot.address == address && - device_slot.interfaces[si].driver && - device_slot.interfaces[si].gamepad) + if (device_slot.address != address) + { + continue; + } + HostDriver* driver = device_slot.interfaces[si].driver.get(); + Gamepad* gamepad = device_slot.interfaces[si].gamepad; + if (!driver || !gamepad) + { + for (const auto& iface : device_slot.interfaces) + { + if (iface.driver && iface.gamepad && + iface.driver_class == DriverClass::XINPUT && + iface.host_driver_type == HostDriverType::XBOX360W) + { + driver = iface.driver.get(); + gamepad = iface.gamepad; + break; + } + } + } + if (driver && gamepad) { - device_slot.interfaces[si].driver->connect_cb(*device_slot.interfaces[si].gamepad, address, instance); + driver->connect_cb(*gamepad, address, instance); } + break; } } @@ -290,12 +350,31 @@ class HostManager } for (auto& device_slot : device_slots_) { - if (device_slot.address == address && - device_slot.interfaces[si].driver && - device_slot.interfaces[si].gamepad) + if (device_slot.address != address) + { + continue; + } + HostDriver* driver = device_slot.interfaces[si].driver.get(); + Gamepad* gamepad = device_slot.interfaces[si].gamepad; + if (!driver || !gamepad) { - device_slot.interfaces[si].driver->disconnect_cb(*device_slot.interfaces[si].gamepad, address, instance); + for (const auto& iface : device_slot.interfaces) + { + if (iface.driver && iface.gamepad && + iface.driver_class == DriverClass::XINPUT && + iface.host_driver_type == HostDriverType::XBOX360W) + { + driver = iface.driver.get(); + gamepad = iface.gamepad; + break; + } + } } + if (driver && gamepad) + { + driver->disconnect_cb(*gamepad, address, instance); + } + break; } } @@ -331,11 +410,23 @@ class HostManager { continue; } + if (iface.host_driver_type == HostDriverType::XBOX360W) + { + tuh_xinput::service_wireless_ports(device_slot.address); + } /* PS4-only (no GIP): 200 ms OUT refresh is OK. Composite pads choke if we OUT at 200 ms — * use rare keepalive + init + console-driven updates only. */ const bool ps4_hid_periodic = iface.driver_class == DriverClass::HID && iface.host_driver_type == HostDriverType::PS4 && !ps_style_hid; + /* PS3: invoke send_feedback on timer; driver rate-limits OUT to 1 Hz on PIO USB. */ + const bool ps3_hid_periodic = + iface.driver_class == DriverClass::HID && iface.host_driver_type == HostDriverType::PS3; + /* Switch Pro / Pro 2: init steps and idle rumble keepalive need periodic OUT on PIO USB. */ + const bool switch_pro_hid_periodic = + iface.driver_class == DriverClass::HID && + (iface.host_driver_type == HostDriverType::SWITCH_PRO || + iface.host_driver_type == HostDriverType::SWITCH_PRO_2); bool ps4_composite_keepalive = false; if (ps_style_hid && iface.driver_class == DriverClass::HID && iface.host_driver_type == HostDriverType::PS4 && iface.gamepad_idx < MAX_GAMEPADS) @@ -348,7 +439,7 @@ class HostManager } } if (!(iface.gamepad->new_pad_out() || iface.gamepad->has_rumble() || ps4_hid_periodic || - ps4_composite_keepalive)) + ps3_hid_periodic || switch_pro_hid_periodic || ps4_composite_keepalive)) { continue; } @@ -358,7 +449,7 @@ class HostManager } iface.driver->send_feedback(*iface.gamepad, device_slot.address, iface.usb_instance); tuh_task(); -#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) +#if defined(CONFIG_EN_USB_HOST) /* Nested tuh_task during OUT must not starve PIO USB SOF or wired IN dies in ~1–2 s. */ pio_usb_host_frame(); #endif @@ -381,6 +472,10 @@ class HostManager } Interface& iface = device_slot.interfaces[si]; const uint8_t cleared_gamepad_idx = iface.gamepad_idx; + if (iface.driver && iface.gamepad) + { + iface.driver->disconnect_cb(*iface.gamepad, address, instance); + } iface.driver.reset(); iface.driver_class = DriverClass::NONE; iface.host_driver_type = HostDriverType::UNKNOWN; @@ -452,14 +547,54 @@ class HostManager } for (auto& device_slot : device_slots_) { - if (device_slot.address == address) + if (device_slot.address != address) + { + continue; + } + if (device_slot.interfaces[si].gamepad_idx != INVALID_IDX) { return device_slot.interfaces[si].gamepad_idx; } + for (const auto& iface : device_slot.interfaces) + { + if (iface.driver_class == DriverClass::XINPUT && + iface.host_driver_type == HostDriverType::XBOX360W && + iface.gamepad_idx != INVALID_IDX) + { + return iface.gamepad_idx; + } + } + break; } return INVALID_IDX; } + /** Live Switch Pro / Switch 2 Pro host driver for async bulk bring-up callbacks. */ + inline SwitchProHost* get_switch_pro_host(uint8_t address, uint8_t instance) const + { + const uint8_t si = host_storage_index(DriverClass::HID, instance); + if (si >= MAX_INTERFACES) + { + return nullptr; + } + for (const auto& device_slot : device_slots_) + { + if (device_slot.address != address) + { + continue; + } + const Interface& iface = device_slot.interfaces[si]; + if (!iface.driver || + (iface.host_driver_type != HostDriverType::SWITCH_PRO && + iface.host_driver_type != HostDriverType::SWITCH_PRO_2)) + { + return nullptr; + } + return static_cast(iface.driver.get()); + } + return nullptr; + } + inline bool any_mounted() { for (auto& device_slot : device_slots_) @@ -505,12 +640,19 @@ class HostManager static inline uint8_t host_storage_index(DriverClass cls, uint8_t tinusb_instance) { + if (cls == DriverClass::XINPUT) + { + if (tinusb_instance >= OGXM_TUH_XINPUT_INSTANCES) + { + return INVALID_IDX; + } + return static_cast(MAX_GAMEPADS + tinusb_instance); + } if (tinusb_instance >= MAX_GAMEPADS) { return INVALID_IDX; } - const uint8_t off = (cls == DriverClass::XINPUT) ? MAX_GAMEPADS : 0; - return static_cast(tinusb_instance + off); + return tinusb_instance; } struct Interface diff --git a/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp b/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp index c23f2bc0..726a8881 100644 --- a/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp +++ b/Firmware/RP2040/src/USBHost/tuh_callbacks.cpp @@ -76,4 +76,10 @@ void tuh_xinput::xbox360w_disconnect_cb(uint8_t dev_addr, uint8_t instance) { dev_addr, instance); OGXMini::wireless_connected(false, idx); HostManager::get_instance().disconnect_cb(HostManager::DriverClass::XINPUT, dev_addr, instance); +} + +void tuh_xinput::host_activity_cb(uint8_t dev_addr, uint8_t instance) { + (void)dev_addr; + (void)instance; + HostManager::get_instance().record_usb_host_input_activity(); } \ No newline at end of file diff --git a/Firmware/RP2040/src/tusb_config.h b/Firmware/RP2040/src/tusb_config.h index 4d3db526..bc84dff9 100644 --- a/Firmware/RP2040/src/tusb_config.h +++ b/Firmware/RP2040/src/tusb_config.h @@ -148,7 +148,7 @@ #define CFG_TUH_MSC 0 #define CFG_TUH_VENDOR 0 -#define CFG_TUH_XINPUT MAX_GAMEPADS +#define CFG_TUH_XINPUT OGXM_TUH_XINPUT_INSTANCES // max device support (excluding hub device) #define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports From 0a1bd59a6a3f9e0f63a27a26690c1bdbe6a4d3bd Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Fri, 26 Jun 2026 12:22:54 -0400 Subject: [PATCH 37/42] v1.0.0.11a: Add Razer Atrox Xbox One GIP arcade stick support. Vendor GIP init and 30-byte XBOFS input path for 1532:0a00 on PIO USB host; document Atrox and related arcade sticks in wired controller lists. Co-authored-by: Cursor --- CHANGELOG.md | 3 +- Firmware/RP2040/docs/IMPROVEMENTS.md | 40 ++- Firmware/RP2040/docs/Wired_Controllers.md | 6 +- .../src/USBHost/HostDriver/XInput/Xbox360.cpp | 22 +- .../HostDriver/XInput/XboxArcadeStick.h | 136 ++++++++++ .../src/USBHost/HostDriver/XInput/XboxOne.cpp | 158 +++++++----- .../src/USBHost/HostDriver/XInput/XboxOne.h | 10 +- .../XInput/tuh_xinput/tuh_xinput.cpp | 238 ++++++++++++++++-- .../HostDriver/XInput/tuh_xinput/tuh_xinput.h | 13 + .../XInput/tuh_xinput/tuh_xinput_cmd.h | 4 + Firmware/RP2040/src/USBHost/HostManager.h | 5 + README.md | 1 + 12 files changed, 546 insertions(+), 90 deletions(-) create mode 100644 Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxArcadeStick.h diff --git a/CHANGELOG.md b/CHANGELOG.md index ed7c1b43..c7596614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog / Version history -Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, **Switch 2 Pro + Joy-Con 2 BLE**, **Waveshare RP2350-USB-A wired host fixes (Switch Pro, PS3, Xbox 360 receiver)**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). +Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, **Switch 2 Pro + Joy-Con 2 BLE**, **Waveshare RP2350-USB-A wired host fixes (Switch Pro, PS3, Xbox 360 receiver, Razer Atrox XBO)**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). --- @@ -12,6 +12,7 @@ Features and fixes added in this fork. For the latest firmware improvements (PS3 - **Xbox 360 wireless USB receiver — wired host (PIO USB)** — **Microsoft PC wireless receiver** (`045e:0719`) + **Xbox 360 wireless pad** sync and input fixed on PIO USB host when **`MAX_GAMEPADS=1`**. **`OGXM_TUH_XINPUT_INSTANCES=4`** when `MAX_GAMEPADS < 4` so all **four RF ports** are polled; **`HostManager`** shares one **`Xbox360WHost`** driver across receiver interfaces and routes **`process_report` / connect / disconnect** to the live driver. **`tuh_xinput`:** **`prime_port_for_pairing()`** sends **RUMBLE_ENABLE + LED** on idle ports; controller-present detection uses **byte1 bit 7 (`0x80`)** (not headset-only **0x40**); accepts report size **0x13** or **0x14**; removed **1 s sleep** on connect; **`service_wireless_ports()`** from feedback timer. **`Xbox360WHost`:** byte-offset decode for wireless input reports; tracks **active instance** for rumble. **Files:** `Config.h`, `HostManager.h`, `tuh_xinput.cpp`, `Xbox360W.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Xbox 360 wireless receiver — wired USB host*). - **Pico W / Pico 2 W — wired unplug watchdog (360 receiver)** — **No-input** unplug timeout raised from **~3 s** to **~10 s** so a **360 wireless PC receiver** plugged into the adapter’s PIO USB host port (which keeps sending status IN even with no pad paired) is not mistaken for unplug and torn down while Bluetooth should stay available. **File:** `PicoW.cpp`. - **Four-channel / ESP32 I2C — pad wire format** — **`I2CWirePadIn`** fixed **23-byte** payload for master/slave I2C **`PacketIn`** links; excludes **`Gamepad::PadIn` IMU fields** added for DS4/DS5/Switch Pro that broke the **32-byte** wire layout on **Four_Channel_I2C** and **ESP32_Bluepad32_I2C** boards. **Files:** `I2CWirePad.h`, `Four_Channel_I2C.cpp`, `ESP32_Bluepad32_I2C.cpp`. +- **Razer Atrox Xbox One — wired USB host (PIO USB)** — **Razer Atrox Arcade Stick** for **Xbox One** (`1532:0a00`) now connects and reports inputs on PIO USB host boards (validated on **RP2350-USB-A**). Vendor-class **GIP** interface opened via **`tuh_xinput`**; init follows **[XBOFS.win](https://github.com/OOPMan/XBOFS.win)** (`05 20 00 01 00` **POWER_ON**, wait for OUT, then **30-byte** IN read loop). Input uses the XBOFS byte layout (dpad byte 5, face/LT/RT on byte 22). **`start_xboxone()`** deferred **50 ms** after mount; **`service_gip()`** re-arms stalled IN only (no repeated **POWER_ON**, which caused power cycling). Standard **Xbox One** wired pads keep the **64-byte** Linux xpad GIP path. **Xbox 360 Atrox** (`24c6:5000`) unchanged — standard XInput with digital trigger bytes. **Files:** `XboxArcadeStick.h`, `tuh_xinput.cpp`, `XboxOne.cpp`, `HostManager.h`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Razer Atrox Xbox One — GIP arcade stick*) and [Wired_Controllers.md](Firmware/RP2040/docs/Wired_Controllers.md). --- diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index 3531f03e..ca5b290d 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -2,7 +2,7 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. -**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). **v1.0.0.10a** adds **Nintendo Switch 2** wireless support (**Pro 2** and **Joy-Con 2**) over **BLE**, **Switch 1 Joy-Con L+R merge**, and **Joy-Con dual-half latency fixes** (see *Nintendo Switch 2 — Bluetooth* and *Joy-Con pair merge — latency* below). **v1.0.0.11a** adds **PIO USB host wired connection fixes** — **Switch 1/2 Pro**, **DualShock 3**, and **Xbox 360 wireless receiver** — validated on **Waveshare RP2350-USB-A** (see *PIO USB host — wired connection fixes* below). +**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). **v1.0.0.10a** adds **Nintendo Switch 2** wireless support (**Pro 2** and **Joy-Con 2**) over **BLE**, **Switch 1 Joy-Con L+R merge**, and **Joy-Con dual-half latency fixes** (see *Nintendo Switch 2 — Bluetooth* and *Joy-Con pair merge — latency* below). **v1.0.0.11a** adds **PIO USB host wired connection fixes** — **Switch 1/2 Pro**, **DualShock 3**, **Xbox 360 wireless receiver**, and **Razer Atrox Xbox One** (`1532:0a00`) — validated on **Waveshare RP2350-USB-A** (see *PIO USB host — wired connection fixes* below). **Version 1.0.0.9a — documented here for release notes:** @@ -108,7 +108,7 @@ Switch 2 controllers use a **proprietary BLE GATT protocol**, not standard HID-o **Scope:** Changes live in **shared USB host drivers** and **`HostManager`**, not board-specific `#ifdef`s. Any build with **`CONFIG_EN_USB_HOST`** (Pico, Feather, RP2350-Zero, RP2350-USB-A, etc.) gets the same wired-host behavior. **Pico W / Pico 2 W Bluetooth** (Bluepad32) is **unchanged**. -**Goal:** Reliable **wired USB host** input on PIO USB adapters for **Switch Pro 1/2**, **DualShock 3**, and the **Xbox 360 wireless PC receiver** + pad — without starving the PIO stack during init or OUT transfers. +**Goal:** Reliable **wired USB host** input on PIO USB adapters for **Switch Pro 1/2**, **DualShock 3**, the **Xbox 360 wireless PC receiver** + pad, and **Xbox One GIP arcade sticks** (e.g. **Razer Atrox XBO**) — without starving the PIO stack during init or OUT transfers. ### Shared — HostManager and PIO USB servicing @@ -186,6 +186,29 @@ Applies to Nintendo VID **0x057E** PIDs **0x2066**, **0x2067**, **0x2069**, **0x **User testing (Waveshare RP2350-USB-A):** **360 wireless receiver + pad** sync and input confirmed over PIO USB host. +### Razer Atrox Xbox One — GIP arcade stick (wired USB host) + +**Problem:** **Razer Atrox Arcade Stick** for **Xbox One** (`1532:0a00`) enumerates as a **vendor-class GIP** device (not standard Microsoft `0x47/0xD0` XInput). On PIO USB host it would **mount** (adapter LED on) but the stick **lit briefly then powered off** with **no inputs** — or **flashed on/off** when the host retried **POWER_ON** too often. + +**References:** + +| Project | Contribution | +|---------|----------------| +| **[OOPMan/XBOFS.win](https://github.com/OOPMan/XBOFS.win)** | Atrox-specific **GIP init** (`05 20 00 01 00`), **30-byte** IN reads, input layout (face/LT/RT on **byte 22**). | +| **Linux `xpad`** | Generic Xbox One **POWER_ON** packet and **64-byte** IN for standard gamepads; **MAP_TRIGGERS_TO_BUTTONS** quirk for `1532:0a00` in the device table. | + +#### Changes + +1. **Vendor GIP detection** — **`tuh_xinput::open()`** claims interface **0** for known XBO arcade sticks (`1532:0a00`, Mad Catz TE2, PDP, Hori, etc.) via **`XboxArcadeStick.h`** VID/PID table. +2. **Arcade init path (XBOFS)** — **`start_xboxone()`** (deferred **50 ms** after mount from **`XboxOneHost::initialize()`**): send **POWER_ON** once, **`wait_for_tx_complete()`** on OUT with **`pio_usb_host_frame()`**, then arm **30-byte** IN polling. Standard Xbox One pads keep **IN-first** + full **`xboxone_init()`** with **64-byte** reads. +3. **Input decode** — **`XboxOneHost`** uses **XBOFS byte layout** for arcade VID/PIDs; standard pads use **`GipWireButtons`** / **`InReport`** layout. +4. **PIO keepalive** — **`service_gip()`** from **`HostManager::send_feedback()`** re-arms stalled IN every **250 ms** for arcade sticks only. **Does not** repeat **POWER_ON** (repeated power commands caused visible **on/off flashing**). +5. **Xbox 360 Atrox** (`24c6:5000`) — unchanged: standard **XInput** with **digital trigger** bytes in **`Xbox360Host`**. + +**Files:** `src/USBHost/HostDriver/XInput/XboxArcadeStick.h`, `tuh_xinput/tuh_xinput.cpp`, `tuh_xinput/tuh_xinput.h`, `XboxOne.cpp`, `XboxOne.h`, `HostManager.h`. + +**User testing (Waveshare RP2350-USB-A):** **Razer Atrox Xbox One** (`1532:0a00`) — connect, stay powered, and full button input confirmed. + ### Hot-swap (Switch 1 ↔ Switch 2 Pro) Unplug during bulk or HID init runs **`HostManager::disconnect_cb()`** → driver **`disconnect_cb()`** → bulk cancel. Plugging the other model starts a fresh init path (Switch 1 **0x80** vs Switch 2 bulk) without requiring an adapter power cycle. @@ -202,12 +225,15 @@ Unplug during bulk or HID init runs **`HostManager::disconnect_cb()`** → drive | `src/USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h` | 17 bulk OUT packets (capture tool / HHL) | | `src/Descriptors/SwitchPro.h` | Wired USB constants (`REPORT_ID_USB_OUT`, `USB_SUB_*`, `USB_PROBE`) | | `src/USBHost/HostDriver/PS3/PS3.cpp` | DualShock 3 wired init, sync control xfer, 1 Hz keepalive | -| `src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp` | 360 wireless receiver port priming, connect detect, **`service_wireless_ports()`** | +| `src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp` | 360 wireless receiver port priming, connect detect, **`service_wireless_ports()`**, **`start_xboxone()`**, **`service_gip()`** | +| `src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h` | GIP arcade interface state (`gip_power_sent`, IN stall tracking) | +| `src/USBHost/HostDriver/XInput/XboxArcadeStick.h` | XBO arcade VID/PIDs, **30-byte** xfer size, XBOFS report parser | +| `src/USBHost/HostDriver/XInput/XboxOne.cpp` | Arcade vs standard GIP decode; deferred **`start_xboxone()`** | | `src/USBHost/HostDriver/XInput/Xbox360W.cpp` | Wireless input decode from byte offsets, active instance rumble | **Build:** `./scripts/build.sh` → board **RP2350_USB_A**; typical **`-DMAX_GAMEPADS=1`**. Optional **`-DOGXM_SWITCH2_HID_RAW_LOG=ON`** for UART hex when Switch 2 Pro digital button bytes change. -**User testing (Waveshare RP2350-USB-A):** **Switch 2 Pro wired**, **DualShock 3 wired**, and **Xbox 360 wireless receiver + pad** confirmed on PIO USB host. **Switch 1 Pro wired** — init and mapping updated; retest after flash if a prior S2 regression was seen. +**User testing (Waveshare RP2350-USB-A):** **Switch 2 Pro wired**, **DualShock 3 wired**, **Xbox 360 wireless receiver + pad**, and **Razer Atrox Xbox One** (`1532:0a00`) confirmed on PIO USB host. **Switch 1 Pro wired** — init and mapping updated; retest after flash if a prior S2 regression was seen. --- @@ -590,15 +616,15 @@ OGX-Mini’s existing **wired Xbox One GIP** path (`tuh_xinput`, subclass `0x47` | Area | Improvement | |------|-------------| -| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). **360 wireless PC receiver** supported (`Xbox360WHost`). **v1.0.0.11a:** PIO USB wired receiver — **4 XInput instances** when `MAX_GAMEPADS=1`, port **priming**, **0x80** connect detect, byte-offset decode. **Xbox One/Series wireless dongle (`045e:02e6` / `02fe`)** — see [Future planned](#future-planned). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. | +| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). **360 wireless PC receiver** supported (`Xbox360WHost`). **v1.0.0.11a:** PIO USB wired receiver — **4 XInput instances** when `MAX_GAMEPADS=1`, port **priming**, **0x80** connect detect, byte-offset decode. **Razer Atrox XBO** (`1532:0a00`) — vendor GIP arcade path via **XBOFS** init + **30-byte** IN + XBOFS input layout; **POWER_ON** once only. **Xbox One/Series wireless dongle (`045e:02e6` / `02fe`)** — see [Future planned](#future-planned). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. | | **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **v1.0.0.9a:** PC host rumble deadzone + strict small-motor `0`/`1`. **v1.0.0.11a:** **DualShock 3 wired USB host** — USB Host Shield init, sync control xfer + PIO service, **1 Hz keepalive**. | | **PS2 (GPIO)** | Home only = IGR (L1+L2+R1+R2+Start+Select); Home+Start = shutdown (L1+L2+R1+R2+L3+R3). OPL and protocol stability (first response byte = mode byte). | | **OG Xbox** | Guide only = IGR. Shutdown = LT+RT+Back+White via **Guide+Start** or **Guide+View (Back)**; Xbox BT often omits Start while Guide is held. Shutdown report strips Start so the chord matches BIOS/softmod expectations. | | **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. **v1.0.0.11a:** **Switch 1/2 Pro wired** on PIO USB host — Chromium **0x80** init, bulk bring-up, mapping fixes. See [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | | **Switch 2** | **Pro 2** (wired **0x2069**): **Switch2ProHost** + bulk bring-up (v1.0.0.11a). **Pro 2 + Joy-Con 2 L/R** (BLE): **uni_hid_parser_switch2** — GATT pairing, 63-byte input, rumble keepalive, Home → SYS latch, **L+R pair merge**, **dual-half latency fixes**. See [§ Nintendo Switch 2 — Bluetooth](#nintendo-switch-2--bluetooth-pico-w--pico-2-w) and [§ Joy-Con pair latency](#joy-con-pair-merge--latency-when-both-halves-are-active). | -| **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). **RP2350-USB-A (Waveshare):** v1.0.0.11a validation for **Switch Pro, DualShock 3, 360 wireless receiver** wired host. | +| **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). **RP2350-USB-A (Waveshare):** v1.0.0.11a validation for **Switch Pro, DualShock 3, 360 wireless receiver**, and **Razer Atrox XBO** wired host. | | **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). Switch Pro and PS3 always build report every loop so host poll (`get_report`) and IN push both see current state — only remaining delay is BT radio when wireless. | | **Build** | Interactive scripts `scripts/build.sh` (Linux/macOS) and `scripts/build.ps1` (Windows) for board selection, fixed/default mode, and Release/Debug; output in `scripts/build/`. See [README](../../../README.md) Build section. | | **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **Switch 2 (BLE):** Pro 2 + Joy-Con 2 L/R — custom GATT parser, rumble keepalive, Home latch, **L+R merge**, **dual-half latency fixes**. **Switch 1 Joy-Con (Classic BT):** L+R merge, IMU off when paired, same latency path as SW2. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in (**2-slot** staging for Joy-Con pairs); re-enable scan on last disconnect. **v1.0.0.9a:** ~**1 s connection rumble** at `device_ready` (DS4 delayed start). | -| **PIO USB host (Pico W)** | **Wired unplug:** Debounced combo of **HCD connect**, **`tuh_mounted` over all device addresses**, and **no `process_report` / setup activity** (~**3 s**) so disconnect registers when D+/D− line state is wrong under PIO; **`tuh_deinit`** + restore GPIO line IRQs + BT release. **v1.0.0.11a (all PIO host boards):** **`pio_usb_host_frame()`** after feedback OUT; wired **Switch Pro / PS3 / 360 receiver** connection fixes — see [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | +| **PIO USB host (Pico W)** | **Wired unplug:** Debounced combo of **HCD connect**, **`tuh_mounted` over all device addresses**, and **no `process_report` / setup activity** (~**3 s**) so disconnect registers when D+/D− line state is wrong under PIO; **`tuh_deinit`** + restore GPIO line IRQs + BT release. **v1.0.0.11a (all PIO host boards):** **`pio_usb_host_frame()`** after feedback OUT; wired **Switch Pro / PS3 / 360 receiver / Razer Atrox XBO** connection fixes — see [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | | **DS3 + Bluetooth** | **USB auto-pair:** After PS3 wired init, **feature `0xF5`** programs the **DS3** with the adapter’s **BD_ADDR** (`CONFIG_EN_BLUETOOTH`); deferred if BT address not ready. See [§ DualShock 3 — automatic USB programming for Bluetooth pairing](#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). | diff --git a/Firmware/RP2040/docs/Wired_Controllers.md b/Firmware/RP2040/docs/Wired_Controllers.md index b98ec25c..fef89367 100644 --- a/Firmware/RP2040/docs/Wired_Controllers.md +++ b/Firmware/RP2040/docs/Wired_Controllers.md @@ -13,8 +13,12 @@ This document lists controllers supported when connected to the OGX-Mini adapter - **Microsoft:** Xbox 360 (wired and **360 PC wireless receiver**), Xbox One / Series **wired USB**, Xbox Elite - **Not supported (planned):** Xbox One / Series **wireless USB dongle** (`045e:02e6`, `045e:02fe`) — see [IMPROVEMENTS.md — Future planned](IMPROVEMENTS.md#future-planned) - **Third‑party:** Controllers that identify as XInput over USB (e.g. many 8BitDo, PowerA, PDP, Afterglow when in XInput mode) +- **Razer Atrox Arcade Stick:** **Xbox One** (`1532:0a00`, vendor GIP); **Xbox 360** (`24c6:5000`, standard XInput, digital LT/RT) +- **Other Xbox One GIP arcade sticks:** Mad Catz FightStick TE 2 (`0738:4a01`), PDP Xbox One Arcade Stick (`0e6f:015c`), Hori RAP Hayabusa / V Kai / Fighting Commander ONE — see `XBOX_ONE_GIP_IDS` in `XboxArcadeStick.h` -*Matched by USB class; no fixed VID/PID list. UsbdSecPatch is not required on Xbox 360.* +*Matched by USB class for standard XInput pads; arcade sticks above use explicit VID/PID + GIP init. UsbdSecPatch is not required on Xbox 360.* + +**Razer Atrox arcade stick (wired USB host):** **Xbox One** model (`1532:0a00`) uses GIP on interface 0. Init follows **XBOFS.win** (`05 20 00 01 00`, wait for OUT, then **30-byte** IN read loop); input uses XBOFS byte layout (face/LT/RT on byte 22). Standard Xbox One pads use 64-byte Linux xpad GIP. **Xbox 360** model (`24c6:5000`) uses standard XInput with digital trigger bytes. **Xbox 360 wireless PC receiver (`045e:0719`), wired to adapter USB host:** Plug the **receiver** into the adapter’s host port; sync a **wireless 360 pad** to any quadrant. On **PIO USB host** boards (Waveshare RP2350-USB-A, Pico, Feather, etc.), v1.0.0.11a polls **all four RF ports** even when `MAX_GAMEPADS=1` and primes idle ports for sync. See [IMPROVEMENTS.md — PIO USB host wired fixes](IMPROVEMENTS.md#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp index d0a30f73..04fdca3d 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/Xbox360.cpp @@ -5,6 +5,7 @@ #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/XInput/Xbox360.h" +#include "USBHost/HostDriver/XInput/XboxArcadeStick.h" void Xbox360Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { @@ -53,8 +54,25 @@ void Xbox360Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t inst if (in_report_->buttons[1] & XInput::Buttons1::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; if (in_report_->buttons[1] & XInput::Buttons1::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; - gp_in.trigger_l = gamepad.scale_trigger_l(in_report_->trigger_l); - gp_in.trigger_r = gamepad.scale_trigger_r(in_report_->trigger_r); + uint16_t vid = 0; + uint16_t pid = 0; + tuh_vid_pid_get(address, &vid, &pid); + if (XboxArcadeStick::is_xbox360_digital_triggers(vid, pid)) + { + if (in_report_->trigger_l != 0) + { + gp_in.trigger_l = 0xFF; + } + if (in_report_->trigger_r != 0) + { + gp_in.trigger_r = 0xFF; + } + } + else + { + gp_in.trigger_l = gamepad.scale_trigger_l(in_report_->trigger_l); + gp_in.trigger_r = gamepad.scale_trigger_r(in_report_->trigger_r); + } std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report_->joystick_lx, in_report_->joystick_ly, true); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report_->joystick_rx, in_report_->joystick_ry, true); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxArcadeStick.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxArcadeStick.h new file mode 100644 index 00000000..c665d05c --- /dev/null +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxArcadeStick.h @@ -0,0 +1,136 @@ +#ifndef _XBOX_ARCADE_STICK_H_ +#define _XBOX_ARCADE_STICK_H_ + +#include + +#include "Gamepad/Gamepad.h" +#include "USBHost/HardwareIDs.h" + +/** Xbox One GIP arcade sticks (Razer Atrox XBO, Mad Catz TE2, etc.) + * Init/read from OOPMan/XBOFS.win; standard pads use 64-byte Linux xpad GIP. */ +namespace XboxArcadeStick +{ + /** XBOFS: WinUsb_ReadPipe(..., 30). */ + static constexpr uint16_t GIP_IN_XFER_SIZE = 30; + + static constexpr HardwareID XBOX_ONE_GIP_IDS[] = { + {0x1532, 0x0a00}, // Razer Atrox Arcade Stick (Xbox One) + {0x0738, 0x4a01}, // Mad Catz FightStick TE 2 (Xbox One) + {0x0e6f, 0x015c}, // PDP Xbox One Arcade Stick + {0x0f0d, 0x0063}, // Hori RAP Hayabusa (Xbox One) + {0x0f0d, 0x0078}, // Hori RAP V Kai (Xbox One) + {0x0f0d, 0x00c5}, // Hori Fighting Commander ONE + }; + + static constexpr HardwareID XBOX360_DIGITAL_TRIGGER_IDS[] = { + {0x24c6, 0x5000}, // Razer Atrox Arcade Stick (Xbox 360) + {0x0738, 0x4758}, // Mad Catz Arcade Game Stick + {0x0738, 0x4728}, // Mad Catz Fightpad + {0x0738, 0x4738}, // Mad Catz SFIV Fightstick + {0x146b, 0x0604}, // Bigben DAIJA Arcade Stick + }; + + inline bool matches_id(uint16_t vid, uint16_t pid, const HardwareID* ids, size_t count) + { + for (size_t i = 0; i < count; ++i) + { + if (ids[i].vid == vid && ids[i].pid == pid) + { + return true; + } + } + return false; + } + + inline bool is_xbox_one_gip(uint16_t vid, uint16_t pid) + { + return matches_id(vid, pid, XBOX_ONE_GIP_IDS, + sizeof(XBOX_ONE_GIP_IDS) / sizeof(XBOX_ONE_GIP_IDS[0])); + } + + inline bool is_xbox360_digital_triggers(uint16_t vid, uint16_t pid) + { + return matches_id(vid, pid, XBOX360_DIGITAL_TRIGGER_IDS, + sizeof(XBOX360_DIGITAL_TRIGGER_IDS) / sizeof(XBOX360_DIGITAL_TRIGGER_IDS[0])); + } + + /** XBOFS GIP 0x20 layout (face/LT/RT on byte 22). */ + inline void map_gip_arcade_report(const uint8_t* data, uint16_t len, Gamepad& gamepad, Gamepad::PadIn& gp_in) + { + if (len < 23) + { + return; + } + + if (data[4] & 0x04) + { + gp_in.buttons |= gamepad.MAP_BUTTON_START; + } + if (data[4] & 0x08) + { + gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + } + + if (data[5] & 0x01) + { + gp_in.dpad |= gamepad.MAP_DPAD_UP; + } + if (data[5] & 0x02) + { + gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + } + if (data[5] & 0x04) + { + gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + } + if (data[5] & 0x08) + { + gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + } + + const uint8_t face = data[22]; + if (face & 0x01) + { + gp_in.buttons |= gamepad.MAP_BUTTON_X; + } + if (face & 0x02) + { + gp_in.buttons |= gamepad.MAP_BUTTON_Y; + } + if (face & 0x10) + { + gp_in.buttons |= gamepad.MAP_BUTTON_A; + } + if (face & 0x20) + { + gp_in.buttons |= gamepad.MAP_BUTTON_B; + } + if (face & 0x04) + { + gp_in.buttons |= gamepad.MAP_BUTTON_RB; + } + if (face & 0x08) + { + gp_in.buttons |= gamepad.MAP_BUTTON_LB; + } + if (face & 0x40) + { + gp_in.trigger_r = 0xFF; + } + if (face & 0x80) + { + gp_in.trigger_l = 0xFF; + } + } + + inline bool gip_arcade_report_changed(const uint8_t* data, uint16_t len, const uint8_t* prev, uint16_t prev_len) + { + if (len < 23 || prev_len < 23) + { + return true; + } + return data[4] != prev[4] || data[5] != prev[5] || data[22] != prev[22]; + } +} + +#endif // _XBOX_ARCADE_STICK_H_ diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp index 914917bf..9790e112 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.cpp @@ -2,15 +2,59 @@ #include "host/usbh.h" #include "Board/board_api.h" +#include "TaskQueue/TaskQueue.h" #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/XInput/XboxOne.h" +#include "USBHost/HostDriver/XInput/XboxArcadeStick.h" -static constexpr uint32_t GUIDE_STALE_MS = 400u; // clear Guide if no 0x07 packet this long (stuck/noise) +static constexpr uint32_t GUIDE_STALE_MS = 400u; void XboxOneHost::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { - tuh_xinput::receive_report(address, instance); + uint16_t vid = 0; + uint16_t pid = 0; + tuh_vid_pid_get(address, &vid, &pid); + gip_arcade_stick_ = XboxArcadeStick::is_xbox_one_gip(vid, pid); + prev_arcade_len_ = 0; + std::memset(&prev_in_report_, 0, sizeof(prev_in_report_)); + (void)gamepad; + (void)report_desc; + (void)desc_len; + const uint8_t addr = address; + const uint8_t inst = instance; + TaskQueue::Core1::queue_delayed_task( + TaskQueue::Core1::get_new_task_id(), 50, false, + [addr, inst]() { tuh_xinput::start_xboxone(addr, inst); }); +} + +static void map_gip_buttons(Gamepad& gamepad, const XboxOne::InReport* in_report, Gamepad::PadIn& gp_in, + uint8_t guide_pressed) +{ + const uint16_t b = in_report->buttons; + if (b & XboxOne::GipWireButtons::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; + if (b & XboxOne::GipWireButtons::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; + if (b & XboxOne::GipWireButtons::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; + if (b & XboxOne::GipWireButtons::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; + + if (b & XboxOne::GipWireButtons::LEFT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_L3; + if (b & XboxOne::GipWireButtons::RIGHT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_R3; + if (b & XboxOne::GipWireButtons::LEFT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_LB; + if (b & XboxOne::GipWireButtons::RIGHT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_RB; + if (b & XboxOne::GipWireButtons::BACK) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; + if (b & XboxOne::GipWireButtons::START) gp_in.buttons |= gamepad.MAP_BUTTON_START; + if (b & XboxOne::GipWireButtons::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + if (guide_pressed) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + if (b & XboxOne::GipWireButtons::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; + if (b & XboxOne::GipWireButtons::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; + if (b & XboxOne::GipWireButtons::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; + if (b & XboxOne::GipWireButtons::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; + + gp_in.trigger_l = gamepad.scale_trigger_l(static_cast(in_report->trigger_l >> 2)); + gp_in.trigger_r = gamepad.scale_trigger_r(static_cast(in_report->trigger_r >> 2)); + + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report->joystick_lx, in_report->joystick_ly, true); + std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report->joystick_rx, in_report->joystick_ry, true); } void XboxOneHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) @@ -19,37 +63,25 @@ void XboxOneHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t inst if (cmd == XboxOne::GIP_CMD_VIRTUAL_KEY) { last_guide_07_ms_ = board_api::ms_since_boot(); - // Guide (Home) in 0x07: payload byte 4 = pressed (bit 0) / released; or keycode 0x5B at 4, pressed at 5 if (len >= 5) { if (report[4] == 0x5B && len >= 6) - guide_pressed_ = (report[5] & 0x01) ? 1 : 0; // keycode then pressed + guide_pressed_ = (report[5] & 0x01) ? 1 : 0; else - guide_pressed_ = (report[4] & 0x01) ? 1 : 0; // pressed bit in first payload byte + guide_pressed_ = (report[4] & 0x01) ? 1 : 0; } - // Push state immediately so Guide registers (next 0x20 might be unchanged and skip set_pad_in) - const XboxOne::InReport* prev = &prev_in_report_; Gamepad::PadIn gp_in; - const uint16_t b = prev->buttons; - if (b & XboxOne::GipWireButtons::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; - if (b & XboxOne::GipWireButtons::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; - if (b & XboxOne::GipWireButtons::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; - if (b & XboxOne::GipWireButtons::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; - if (b & XboxOne::GipWireButtons::LEFT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_L3; - if (b & XboxOne::GipWireButtons::RIGHT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_R3; - if (b & XboxOne::GipWireButtons::LEFT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_LB; - if (b & XboxOne::GipWireButtons::RIGHT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_RB; - if (b & XboxOne::GipWireButtons::BACK) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; - if (b & XboxOne::GipWireButtons::START) gp_in.buttons |= gamepad.MAP_BUTTON_START; - if (b & XboxOne::GipWireButtons::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; - if (guide_pressed_) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (b & XboxOne::GipWireButtons::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; - if (b & XboxOne::GipWireButtons::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; - if (b & XboxOne::GipWireButtons::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; - if (b & XboxOne::GipWireButtons::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; - gp_in.trigger_l = gamepad.scale_trigger_l(static_cast(prev->trigger_l >> 2)); - gp_in.trigger_r = gamepad.scale_trigger_r(static_cast(prev->trigger_r >> 2)); - std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(prev->joystick_lx, prev->joystick_ly, true); - std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(prev->joystick_rx, prev->joystick_ry, true); + if (gip_arcade_stick_ && prev_arcade_len_ >= 23) + { + XboxArcadeStick::map_gip_arcade_report(prev_arcade_report_.data(), prev_arcade_len_, gamepad, gp_in); + } + else + { + map_gip_buttons(gamepad, &prev_in_report_, gp_in, guide_pressed_); + } + if (guide_pressed_) + { + gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + } gamepad.set_pad_in(gp_in); tuh_xinput::receive_report(address, instance); return; @@ -61,8 +93,44 @@ void XboxOneHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t inst return; } + if (gip_arcade_stick_) + { + bool guide_cleared = false; + if (guide_pressed_ && (board_api::ms_since_boot() - last_guide_07_ms_) > GUIDE_STALE_MS) + { + guide_pressed_ = 0; + guide_cleared = true; + } + if (!guide_cleared && + !XboxArcadeStick::gip_arcade_report_changed(report, len, prev_arcade_report_.data(), prev_arcade_len_)) + { + tuh_xinput::receive_report(address, instance); + return; + } + + Gamepad::PadIn gp_in; + XboxArcadeStick::map_gip_arcade_report(report, len, gamepad, gp_in); + if (guide_pressed_) + { + gp_in.buttons |= gamepad.MAP_BUTTON_SYS; + } + + gamepad.set_pad_in(gp_in); + tuh_xinput::receive_report(address, instance); + + const uint16_t copy_len = std::min(len, static_cast(prev_arcade_report_.size())); + std::memcpy(prev_arcade_report_.data(), report, copy_len); + prev_arcade_len_ = copy_len; + return; + } + + if (len < sizeof(XboxOne::InReport)) + { + tuh_xinput::receive_report(address, instance); + return; + } + const XboxOne::InReport* in_report = reinterpret_cast(report); - // Clear Guide if we haven't seen a 0x07 packet in a while (stuck / noise) bool guide_cleared = false; if (guide_pressed_ && (board_api::ms_since_boot() - last_guide_07_ms_) > GUIDE_STALE_MS) { guide_pressed_ = 0; @@ -75,41 +143,15 @@ void XboxOneHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t inst } Gamepad::PadIn gp_in; - - // Raw GIP 0x20 uses Microsoft bit layout; map to project Gamepad (then WiiReportConverter → Wii) - const uint16_t b = in_report->buttons; - if (b & XboxOne::GipWireButtons::DPAD_UP) gp_in.dpad |= gamepad.MAP_DPAD_UP; - if (b & XboxOne::GipWireButtons::DPAD_DOWN) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; - if (b & XboxOne::GipWireButtons::DPAD_LEFT) gp_in.dpad |= gamepad.MAP_DPAD_LEFT; - if (b & XboxOne::GipWireButtons::DPAD_RIGHT) gp_in.dpad |= gamepad.MAP_DPAD_RIGHT; - - if (b & XboxOne::GipWireButtons::LEFT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_L3; - if (b & XboxOne::GipWireButtons::RIGHT_THUMB) gp_in.buttons |= gamepad.MAP_BUTTON_R3; - if (b & XboxOne::GipWireButtons::LEFT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_LB; - if (b & XboxOne::GipWireButtons::RIGHT_SHOULDER) gp_in.buttons |= gamepad.MAP_BUTTON_RB; - if (b & XboxOne::GipWireButtons::BACK) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; - if (b & XboxOne::GipWireButtons::START) gp_in.buttons |= gamepad.MAP_BUTTON_START; - if (b & XboxOne::GipWireButtons::SYNC) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; - if (guide_pressed_) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (b & XboxOne::GipWireButtons::A) gp_in.buttons |= gamepad.MAP_BUTTON_A; - if (b & XboxOne::GipWireButtons::B) gp_in.buttons |= gamepad.MAP_BUTTON_B; - if (b & XboxOne::GipWireButtons::X) gp_in.buttons |= gamepad.MAP_BUTTON_X; - if (b & XboxOne::GipWireButtons::Y) gp_in.buttons |= gamepad.MAP_BUTTON_Y; - - gp_in.trigger_l = gamepad.scale_trigger_l(static_cast(in_report->trigger_l >> 2)); - gp_in.trigger_r = gamepad.scale_trigger_r(static_cast(in_report->trigger_r >> 2)); - - std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report->joystick_lx, in_report->joystick_ly, true); - std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report->joystick_rx, in_report->joystick_ry, true); - + map_gip_buttons(gamepad, in_report, gp_in, guide_pressed_); gamepad.set_pad_in(gp_in); tuh_xinput::receive_report(address, instance); - std::memcpy(&prev_in_report_, in_report, 18); + std::memcpy(&prev_in_report_, in_report, sizeof(XboxOne::InReport)); } bool XboxOneHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) { Gamepad::PadOut gp_out = gamepad.get_pad_out(); return tuh_xinput::set_rumble(address, instance, gp_out.rumble_l, gp_out.rumble_r, false); -} \ No newline at end of file +} diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h index 13dabe0a..58951bb7 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/XboxOne.h @@ -1,6 +1,7 @@ #ifndef _XBOX_ONE_HOST_H_ #define _XBOX_ONE_HOST_H_ +#include #include #include "Descriptors/XboxOne.h" @@ -18,8 +19,11 @@ class XboxOneHost : public HostDriver private: XboxOne::InReport prev_in_report_; - uint8_t guide_pressed_{0}; // Guide (Home) from GIP 0x07; not in 0x20 report - uint32_t last_guide_07_ms_{0}; // when we last saw 0x07; clear Guide if no 0x07 for a while + std::array prev_arcade_report_{}; + uint16_t prev_arcade_len_{0}; + bool gip_arcade_stick_{false}; + uint8_t guide_pressed_{0}; + uint32_t last_guide_07_ms_{0}; }; -#endif // _XBOX_ONE_HOST_H_ \ No newline at end of file +#endif // _XBOX_ONE_HOST_H_ diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp index 3cfdc4e6..203ac895 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.cpp @@ -7,8 +7,10 @@ #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h" #include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput_cmd.h" +#include "USBHost/HostDriver/XInput/XboxArcadeStick.h" #include "Board/Config.h" +#include "Board/board_api.h" #if defined(CONFIG_EN_USB_HOST) #include "pio_usb.h" #endif @@ -133,6 +135,23 @@ static void wait_for_tx_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t tim static void prime_port_for_pairing(uint8_t dev_addr, uint8_t instance); +#if defined(CONFIG_EN_USB_HOST) +static void service_usb_host_frames(uint8_t frames = 4) +{ + for (uint8_t i = 0; i < frames; ++i) + { + pio_usb_host_frame(); + tuh_task(); + } +} +#else +static void service_usb_host_frames(uint8_t frames = 4) +{ + (void)frames; + tuh_task(); +} +#endif + bool send_ctrl_xfer(uint8_t dev_addr, const tusb_control_request_t* request, uint8_t* buffer, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tuh_xfer_s transfer = @@ -147,28 +166,71 @@ bool send_ctrl_xfer(uint8_t dev_addr, const tusb_control_request_t* request, uin return tuh_control_xfer(&transfer); } +static bool send_gip_packet(Interface* interface, uint8_t dev_addr, uint8_t instance, + const uint8_t* packet, uint16_t len, bool assign_seq = true) +{ + uint8_t buf[ENDPOINT_SIZE]; + if (len > sizeof(buf)) + { + return false; + } + std::memcpy(buf, packet, len); + if (assign_seq && len >= 3) + { + buf[2] = interface->gip_out_seq++; + } + return send_report(dev_addr, instance, buf, len); +} + +static void xboxone_ack_virtual_key(Interface* interface, uint8_t dev_addr, uint8_t instance, uint8_t seq) +{ + uint8_t ack[sizeof(XboxOne::VIRTUAL_KEY_ACK)]; + std::memcpy(ack, XboxOne::VIRTUAL_KEY_ACK, sizeof(ack)); + ack[2] = seq; + send_gip_packet(interface, dev_addr, instance, ack, sizeof(ack), false); +} + +static void xboxone_send_power_on(Interface* interface, uint8_t dev_addr, uint8_t instance) +{ + if (interface->gip_power_sent) + { + return; + } + send_gip_packet(interface, dev_addr, instance, XboxOne::POWER_ON, sizeof(XboxOne::POWER_ON)); + interface->gip_power_sent = true; +} + static void xboxone_init(Interface *interface, uint8_t dev_addr, uint8_t instance) { uint16_t PID, VID; tuh_vid_pid_get(dev_addr, &VID, &PID); - send_report(dev_addr, instance, XboxOne::POWER_ON, sizeof(XboxOne::POWER_ON)); + const bool arcade = interface->gip_arcade_stick || XboxArcadeStick::is_xbox_one_gip(VID, PID); + interface->gip_out_seq = 0; + + xboxone_send_power_on(interface, dev_addr, instance); + if (arcade) + { + return; + } wait_for_tx_complete(dev_addr, interface->ep_out); - send_report(dev_addr, instance, XboxOne::S_INIT, sizeof(XboxOne::S_INIT)); + + send_gip_packet(interface, dev_addr, instance, XboxOne::S_INIT, sizeof(XboxOne::S_INIT)); wait_for_tx_complete(dev_addr, interface->ep_out); if (VID == 0x045e && (PID == 0x0b00)) { - send_report(dev_addr, instance, XboxOne::EXTRA_INPUT_PACKET_INIT, sizeof(XboxOne::EXTRA_INPUT_PACKET_INIT)); + send_gip_packet(interface, dev_addr, instance, XboxOne::EXTRA_INPUT_PACKET_INIT, + sizeof(XboxOne::EXTRA_INPUT_PACKET_INIT)); wait_for_tx_complete(dev_addr, interface->ep_out); } //Required for PDP aftermarket controllers if (VID == 0x0e6f) { - send_report(dev_addr, instance, XboxOne::PDP_LED_ON, sizeof(XboxOne::PDP_LED_ON)); + send_gip_packet(interface, dev_addr, instance, XboxOne::PDP_LED_ON, sizeof(XboxOne::PDP_LED_ON)); wait_for_tx_complete(dev_addr, interface->ep_out); - send_report(dev_addr, instance, XboxOne::PDP_AUTH, sizeof(XboxOne::PDP_AUTH)); + send_gip_packet(interface, dev_addr, instance, XboxOne::PDP_AUTH, sizeof(XboxOne::PDP_AUTH)); wait_for_tx_complete(dev_addr, interface->ep_out); } } @@ -202,14 +264,29 @@ static bool open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * } else if (desc_itf->bInterfaceSubClass == 0x47 && desc_itf->bInterfaceProtocol == 0xD0) { - itf_type = ItfType::XID; - dev_type = DevType::XBOXONE; + if (desc_itf->bInterfaceNumber == 0) + { + itf_type = ItfType::XID; + dev_type = DevType::XBOXONE; + } } else if (desc_itf->bInterfaceClass == 0x58 && desc_itf->bInterfaceSubClass == 0x42) { itf_type = ItfType::XID; dev_type = DevType::XBOXOG; } + else if (desc_itf->bInterfaceClass == TUSB_CLASS_VENDOR_SPECIFIC && desc_itf->bNumEndpoints >= 2) + { + uint16_t vid = 0; + uint16_t pid = 0; + tuh_vid_pid_get(dev_addr, &vid, &pid); + if (desc_itf->bInterfaceNumber == 0 && + XboxArcadeStick::is_xbox_one_gip(vid, pid)) + { + itf_type = ItfType::XID; + dev_type = DevType::XBOXONE; + } + } TU_VERIFY(dev_type != DevType::UNKNOWN && itf_type != ItfType::UNKNOWN); @@ -237,6 +314,13 @@ static bool open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * interface->itf_type = itf_type; interface->dev_type = dev_type; interface->dev_addr = dev_addr; + if (dev_type == DevType::XBOXONE) + { + uint16_t vid = 0; + uint16_t pid = 0; + tuh_vid_pid_get(dev_addr, &vid, &pid); + interface->gip_arcade_stick = XboxArcadeStick::is_xbox_one_gip(vid, pid); + } if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_OUT) { @@ -274,9 +358,6 @@ static bool set_config(uint8_t dev_addr, uint8_t itf_num) send_report(dev_addr, instance, Xbox360W::INQUIRE_PRESENT, sizeof(Xbox360W::INQUIRE_PRESENT)); wait_for_tx_complete(dev_addr, interface->ep_out); break; - case DevType::XBOXONE: - xboxone_init(interface, dev_addr, instance); - break; default: break; } @@ -299,8 +380,9 @@ static bool set_config(uint8_t dev_addr, uint8_t itf_num) static bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { Interface* interface = get_itf_by_ep(dev_addr, ep_addr); + TU_VERIFY(interface != nullptr); uint8_t instance = get_instance_by_itf_num(dev_addr, interface->itf_num); - TU_VERIFY(interface != nullptr && instance != INVALID_IDX); + TU_VERIFY(instance != INVALID_IDX); const uint8_t dir = tu_edpt_dir(ep_addr); @@ -324,6 +406,11 @@ static bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin host_activity_cb(dev_addr, instance); } + if (interface->dev_type == DevType::XBOXONE) + { + interface->gip_last_in_ok_ms = board_api::ms_since_boot(); + } + bool new_pad_data = false; uint8_t* in_buffer = interface->ep_in_buffer.data(); @@ -381,19 +468,21 @@ static bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin new_pad_data = true; break; case XboxOne::GIP_CMD_VIRTUAL_KEY: - if (in_buffer[4] == 0x01 && !(in_buffer[4] & (1 << 1))) + if (in_buffer[1] == (XboxOne::GIP_OPT_ACK | XboxOne::GIP_OPT_INTERNAL)) { - in_buffer[4] |= (1 << 1); - new_pad_data = true; + xboxone_ack_virtual_key(interface, dev_addr, instance, in_buffer[2]); } - else if (in_buffer[4] == 0x00 && (in_buffer[4] & (1 << 1))) + if (xferred_bytes >= 5) { - in_buffer[4] &= ~(1 << 1); new_pad_data = true; } break; case XboxOne::GIP_CMD_ANNOUNCE: - xboxone_init(interface, dev_addr, instance); + if (interface->gip_arcade_stick && !interface->gip_power_sent && + !usbh_edpt_busy(dev_addr, interface->ep_out)) + { + xboxone_send_power_on(interface, dev_addr, instance); + } break; } break; @@ -447,6 +536,9 @@ void close(uint8_t dev_addr) TU_LOG1("XInput unmount\r\n"); device->interfaces[i].itf_num = 0xFF; device->interfaces[i].connected = false; + device->interfaces[i].gip_power_sent = false; + device->interfaces[i].gip_last_in_ok_ms = 0; + device->interfaces[i].gip_last_in_arm_ms = 0; } } } @@ -493,11 +585,27 @@ bool receive_report(uint8_t dev_addr, uint8_t instance) Interface* interface = get_itf_by_instance(dev_addr, instance); TU_VERIFY(interface != nullptr); - if (!usbh_edpt_xfer(dev_addr, interface->ep_in, interface->ep_in_buffer.data(), interface->ep_in_size)) + uint16_t in_size = interface->ep_in_size; + if (interface->dev_type == DevType::XBOXONE) + { + if (interface->gip_arcade_stick) + { + in_size = XboxArcadeStick::GIP_IN_XFER_SIZE; + } + else + { + in_size = ENDPOINT_SIZE; + } + } + + TU_VERIFY(usbh_edpt_claim(dev_addr, interface->ep_in)); + + if (!usbh_edpt_xfer(dev_addr, interface->ep_in, interface->ep_in_buffer.data(), in_size)) { usbh_edpt_release(dev_addr, interface->ep_in); return false; } + return true; } @@ -535,6 +643,99 @@ void service_wireless_ports(uint8_t dev_addr) } } +void start_xboxone(uint8_t dev_addr, uint8_t instance) +{ + Interface* interface = get_itf_by_instance(dev_addr, instance); + if (interface == nullptr || interface->dev_type != DevType::XBOXONE) + { + return; + } + + uint16_t vid = 0; + uint16_t pid = 0; + tuh_vid_pid_get(dev_addr, &vid, &pid); + const bool arcade = interface->gip_arcade_stick || XboxArcadeStick::is_xbox_one_gip(vid, pid); + + interface->gip_power_sent = false; + interface->gip_last_in_ok_ms = 0; + interface->gip_last_in_arm_ms = 0; + interface->gip_out_seq = 0; + + if (arcade) + { + /* XBOFS: write init, wait for OUT, then 30-byte read loop. */ + xboxone_send_power_on(interface, dev_addr, instance); + wait_for_tx_complete(dev_addr, interface->ep_out, 500); + service_usb_host_frames(8); + if (receive_report(dev_addr, instance)) + { + interface->gip_last_in_arm_ms = board_api::ms_since_boot(); + } + service_usb_host_frames(8); + return; + } + + if (receive_report(dev_addr, instance)) + { + interface->gip_last_in_arm_ms = board_api::ms_since_boot(); + } + service_usb_host_frames(); + xboxone_init(interface, dev_addr, instance); + service_usb_host_frames(); +} + +void service_gip(uint8_t dev_addr, uint8_t instance) +{ + Interface* interface = get_itf_by_instance(dev_addr, instance); + if (interface == nullptr || interface->dev_type != DevType::XBOXONE || + interface->itf_num == INVALID_IDX) + { + return; + } + + if (usbh_edpt_busy(dev_addr, interface->ep_in)) + { + return; + } + + const uint32_t now_ms = board_api::ms_since_boot(); + + if (interface->gip_arcade_stick) + { + static constexpr uint32_t ARCADE_REARM_MS = 250; + if (interface->gip_last_in_arm_ms != 0 && + (now_ms - interface->gip_last_in_arm_ms) < ARCADE_REARM_MS) + { + return; + } + if (receive_report(dev_addr, instance)) + { + interface->gip_last_in_arm_ms = now_ms; + } + return; + } + + static constexpr uint32_t IN_STALL_MS = 2000; + static constexpr uint32_t IN_REARM_MIN_MS = 500; + + if (interface->gip_last_in_ok_ms != 0 && + (now_ms - interface->gip_last_in_ok_ms) < IN_STALL_MS) + { + return; + } + + if (interface->gip_last_in_arm_ms != 0 && + (now_ms - interface->gip_last_in_arm_ms) < IN_REARM_MIN_MS) + { + return; + } + + if (receive_report(dev_addr, instance)) + { + interface->gip_last_in_arm_ms = now_ms; + } +} + bool set_led(uint8_t dev_addr, uint8_t instance, uint8_t quadrant, bool block) { Interface* interface = get_itf_by_instance(dev_addr, instance); @@ -615,6 +816,7 @@ bool set_rumble(uint8_t dev_addr, uint8_t instance, uint8_t rumble_l, uint8_t ru break; case DevType::XBOXONE: std::memcpy(buffer, XboxOne::RUMBLE, sizeof(XboxOne::RUMBLE)); + buffer[2] = interface->gip_out_seq++; buffer[8] = rumble_l / 2; // 0 - 128 buffer[9] = rumble_r / 2; // 0 - 128 len = sizeof(XboxOne::RUMBLE); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h index f10ed918..11e80773 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h @@ -59,6 +59,15 @@ namespace tuh_xinput struct Interface { bool connected{false}; + /** Vendor-class GIP arcade stick (Razer Atrox XBO, etc.) — xpad MAP_TRIGGERS_TO_BUTTONS layout. */ + bool gip_arcade_stick{false}; + /** GIP OUT sequence byte (Linux xpad odata_serial). */ + uint8_t gip_out_seq{0}; + /** Linux xpad sends xboxone_power_on once; repeats make arcade sticks flash/cycle power. */ + bool gip_power_sent{false}; + /** Last successful GIP IN xfer (ms); used to re-arm IN only when the chain stalls. */ + uint32_t gip_last_in_ok_ms{0}; + uint32_t gip_last_in_arm_ms{0}; DevType dev_type{DevType::UNKNOWN}; ItfType itf_type{ItfType::UNKNOWN}; @@ -92,6 +101,10 @@ namespace tuh_xinput uint8_t wireless_led_quadrant(uint8_t address, uint8_t instance); /** Keep all four wireless ports primed (RUMBLE_ENABLE + LED) until a pad connects. */ void service_wireless_ports(uint8_t dev_addr); + /** Arm IN + GIP OUT init (call from XboxOneHost::initialize after mount). */ + void start_xboxone(uint8_t dev_addr, uint8_t instance); + /** Re-arm stalled GIP IN on PIO USB (call from HostManager::send_feedback). */ + void service_gip(uint8_t dev_addr, uint8_t instance); //Wireless only atm void xbox360_chatpad_init(uint8_t address, uint8_t instance); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput_cmd.h b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput_cmd.h index 17c2bab2..03f96d9c 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput_cmd.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput_cmd.h @@ -42,6 +42,10 @@ namespace tuh_xinput static constexpr uint8_t POWER_ON[] = { GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(1), GIP_PWR_ON }; static constexpr uint8_t S_INIT[] = { GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(15), 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static constexpr uint8_t S_LED_INIT[] = { GIP_CMD_LED, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(3), 0x00, 0x01, 0x14 }; + static constexpr uint8_t VIRTUAL_KEY_ACK[] = { + GIP_CMD_ACK, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(9), + 0x00, GIP_CMD_VIRTUAL_KEY, GIP_OPT_INTERNAL, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 + }; static constexpr uint8_t EXTRA_INPUT_PACKET_INIT[] = { 0x4d, 0x10, GIP_SEQ0, 0x02, 0x07, 0x00 }; static constexpr uint8_t PDP_LED_ON[] = { GIP_CMD_LED, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(3), 0x00, GIP_LED_ON, 0x14 }; static constexpr uint8_t PDP_AUTH[] = { GIP_CMD_AUTHENTICATE, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(2), 0x01, 0x00 }; diff --git a/Firmware/RP2040/src/USBHost/HostManager.h b/Firmware/RP2040/src/USBHost/HostManager.h index 27e0a645..1769b720 100644 --- a/Firmware/RP2040/src/USBHost/HostManager.h +++ b/Firmware/RP2040/src/USBHost/HostManager.h @@ -414,6 +414,11 @@ class HostManager { tuh_xinput::service_wireless_ports(device_slot.address); } + if (iface.driver_class == DriverClass::XINPUT && + iface.host_driver_type == HostDriverType::XBOXONE) + { + tuh_xinput::service_gip(device_slot.address, iface.usb_instance); + } /* PS4-only (no GIP): 200 ms OUT refresh is OK. Composite pads choke if we OUT at 200 ms — * use rare keepalive + init + console-driven updates only. */ const bool ps4_hid_periodic = diff --git a/README.md b/README.md index 7dd8192e..d8e13fdf 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ For the OUYA controller there is no Start+Select, the disconnection combo has be See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a full list by driver type. The following work when the adapter is outputting to any supported platform (Xbox, Switch, XInput, PS3, DInput, **PS1/PS2**, **Dreamcast**, **GameCube**, **N64**, etc.): - Original Xbox Duke and S - Xbox 360, One, Series, and Elite +- **Razer Atrox Arcade Stick** (Xbox One `1532:0a00`, Xbox 360 `24c6:5000`; wired USB host) - Dualshock 3 (PS3) - Dualshock 4 (PS4) - Dualsense (PS5) From 0409cc372a2e8fbf243ef31307d7e4f9916b7822 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Sun, 19 Jul 2026 09:23:39 -0400 Subject: [PATCH 38/42] v1.0.0.12a: Steam mode, motion passthrough, Triton BT, and README refresh. Ship STEAM DualSense+touchpad mouse output, PS3/PS4 motion, Steam Controller 2026 BLE, and related Pico W fixes; update README with social links, branding images, and support guidance. Co-authored-by: Cursor --- CHANGELOG.md | 22 +- Firmware/RP2040/CMakeLists.txt | 29 +- Firmware/RP2040/docs/Controller_Mappings.md | 386 ++++++++++++++++++ .../docs/GPIO_Output_Pinout_and_Mappings.md | 2 +- Firmware/RP2040/docs/IMPROVEMENTS.md | 274 ++++++++++++- Firmware/RP2040/docs/README.md | 3 +- Firmware/RP2040/docs/Wii_Mode_Guide.md | 2 + Firmware/RP2040/docs/Wired_Controllers.md | 7 +- Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 283 ++++++++++++- Firmware/RP2040/src/Bluepad32/Bluepad32.h | 2 + Firmware/RP2040/src/Board/Config.h | 12 +- Firmware/RP2040/src/Board/board_api.cpp | 13 +- Firmware/RP2040/src/Board/ogxm_log.cpp | 1 + Firmware/RP2040/src/Descriptors/PS5Usb.h | 70 ++++ Firmware/RP2040/src/Descriptors/Steam.h | 47 +++ Firmware/RP2040/src/Gamepad/Gamepad.h | 136 ++++-- Firmware/RP2040/src/Gamepad/MotionImu.h | 355 ++++++++++++++++ .../src/OGXMini/Board/Four_Channel_I2C.cpp | 2 +- Firmware/RP2040/src/OGXMini/Board/PicoW.cpp | 11 +- .../RP2040/src/OGXMini/Board/Standard.cpp | 45 +- Firmware/RP2040/src/OGXMini/OGXMini.cpp | 6 +- Firmware/RP2040/src/TaskQueue/TaskQueue.cpp | 8 +- Firmware/RP2040/src/TaskQueue/TaskQueue.h | 2 +- .../DeviceDriver/DeviceDriverTypes.h | 1 + .../DeviceDriver/MotionOutputActive.h | 19 + .../PS1PS2/controller_simulator.c | 2 +- .../src/USBDevice/DeviceDriver/PS3/PS3.cpp | 34 +- .../src/USBDevice/DeviceDriver/PS4/PS4.cpp | 25 +- .../USBDevice/DeviceDriver/Steam/Steam.cpp | 172 ++++++++ .../src/USBDevice/DeviceDriver/Steam/Steam.h | 32 ++ .../DeviceDriver/Steam/SteamActive.h | 19 + .../DeviceDriver/Steam/SteamBtReport.h | 234 +++++++++++ .../USBDevice/DeviceDriver/Steam/SteamInput.h | 27 ++ .../DeviceDriver/Steam/SteamPassthrough.h | 37 ++ .../DeviceDriver/Steam/SteamTouchCache.h | 76 ++++ .../DeviceDriver/Steam/SteamTouchpad.cpp | 205 ++++++++++ .../DeviceDriver/Steam/SteamTouchpad.h | 32 ++ .../USBDevice/DeviceDriver/Switch/Switch.cpp | 80 +++- .../USBDevice/DeviceDriver/Switch/Switch.h | 7 + .../RP2040/src/USBDevice/DeviceManager.cpp | 11 + .../RP2040/src/USBDevice/tud_callbacks.cpp | 12 +- Firmware/RP2040/src/USBHost/HardwareIDs.h | 32 +- .../RP2040/src/USBHost/HostDriver/PS3/PS3.cpp | 126 ++---- .../RP2040/src/USBHost/HostDriver/PS3/PS3.h | 39 +- .../RP2040/src/USBHost/HostDriver/PS4/PS4.cpp | 17 +- .../RP2040/src/USBHost/HostDriver/PS4/PS4.h | 1 + .../RP2040/src/USBHost/HostDriver/PS5/PS5.cpp | 24 +- .../HostDriver/SwitchPro/Switch2ProHost.cpp | 30 +- .../HostDriver/SwitchPro/Switch2ProHost.h | 5 +- .../HostDriver/SwitchPro/SwitchPro.cpp | 86 +++- .../USBHost/HostDriver/SwitchPro/SwitchPro.h | 6 + .../src/UserSettings/JoystickSettings.cpp | 33 ++ .../src/UserSettings/JoystickSettings.h | 7 + .../RP2040/src/UserSettings/UserSettings.cpp | 50 ++- .../RP2040/src/Wii/WiiReportConverter.cpp | 2 +- Firmware/RP2040/src/Wii/WiiReportConverter.h | 2 +- Firmware/RP2040/src/btstack_config.h | 3 + Firmware/RP2040/src/tusb_config.h | 3 +- Firmware/external/bluepad32 | 2 +- README.md | 146 ++++++- images/logo.png | Bin 0 -> 988528 bytes images/platform-list.png | Bin 0 -> 1758961 bytes scripts/build.ps1 | 4 +- scripts/build.sh | 4 +- 64 files changed, 3021 insertions(+), 344 deletions(-) create mode 100644 Firmware/RP2040/docs/Controller_Mappings.md create mode 100644 Firmware/RP2040/src/Descriptors/PS5Usb.h create mode 100644 Firmware/RP2040/src/Descriptors/Steam.h create mode 100644 Firmware/RP2040/src/Gamepad/MotionImu.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/MotionOutputActive.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamActive.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamBtReport.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamInput.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamPassthrough.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchCache.h create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.cpp create mode 100644 Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.h create mode 100644 images/logo.png create mode 100644 images/platform-list.png diff --git a/CHANGELOG.md b/CHANGELOG.md index c7596614..254a2b4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,21 @@ # Changelog / Version history -Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **Pico W Bluetooth / DS4 Classic BT**, **Switch 2 Pro + Joy-Con 2 BLE**, **Waveshare RP2350-USB-A wired host fixes (Switch Pro, PS3, Xbox 360 receiver, Razer Atrox XBO)**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). +Features and fixes added in this fork. For the latest firmware improvements (PS3, XInput, latency, **SteamOS / Bazzite (STEAM mode — DualSense emulation + touchpad mouse)**, **Pico W Bluetooth / DS4 Classic BT**, **Xbox Series BLE disconnect reboot**, **Switch 2 Pro + Joy-Con 2 BLE**, **Steam Controller 2026 (Triton) BLE**, **DualShock 3 USB→BT auto-pair (`0xF5`)**, **Waveshare RP2350-USB-A wired host fixes (Switch Pro, PS3, Xbox 360 receiver, Razer Atrox XBO)**, **PS3 / PS4 motion passthrough**, etc.), see [Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md). + +--- + +### Version 1.0.0.12a + +- **DualShock 3 — USB → Bluetooth auto-pair restored** — Wiring a **DS3** into the adapter USB host again programs the pad with the Pico’s **BD_ADDR** (**HID feature `0xF5`**, same as sixaxispairer) so you can unplug and press **PS**. The PIO USB sync init path had marked init **DONE** before the old async **GET 0xF2** pair chain ran, so **`0xF5` never sent**. Fix: send **`0xF5` synchronously** right after **0xF4** + LED OUT (still deferred if the BT address is not ready yet). **Files:** `PS3.cpp` / `PS3.h` (USB host). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — automatic USB programming for Bluetooth pairing*). +- **Steam Controller 2026 (Triton) — Bluetooth LE** — New Bluepad32 parser so the **Steam Controller 2026** (`28de:1303` BLE, also registers `1302`/`1304`/`1305`) can pair with Pico W / Pico 2 W / **RP2354** BT adapters. Parses HID state report **`0x45`**, disables lizard mode, maps sticks/triggers/buttons, dual rumble (`0x80`). **Pairing:** hold **RB + B + Steam**; remove/disconnect the pad from PC/phone Bluetooth first (one host only). **LE Secure Connections** required (legacy SMP failed with `AUTH_REQUIREMENTS_MISMATCH`) — enabled in `btstack_config.h`; BLE pads (except Xbox/Switch 2) use **SC + Bonding**. **Latency:** request BLE connection interval **~7.5–11 ms** on connect. **Buttons:** Triton **View → Start**, **Menu → Back/Select** (SDL-style; Valve labels are not Xbox-style), **Steam → Guide/SYS**. **Files:** `uni_hid_parser_steam_triton.*`, `btstack_config.h`, `uni_bt_le.c`, `uni_controller_list.h`, `uni_hid_device.c`, `Bluepad32.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Steam Controller 2026 — Bluetooth*). +- **Switch 2 Pro — anti-deadzone drift and L3/R3** ([#64](https://github.com/MegaCadeDev/OGX-Mini-2026/issues/64)) — WebApp **Anti-Deadzone Circular/Square** amplified imperfect Switch 2 Pro stick centers into constant **bottom-left drift**. Idle readings are now gated with a small noise floor when anti-dz is active (without weakening the anti-dz curve). Circular anti-dz resize formula matched the WebApp (was incorrectly using `anti_dz_circle` instead of `anti_dz_square`). **L3/R3** stick clicks mapped to the correct physical sticks on wired Switch 2 Pro. **Follow-up:** inner-deadzone gate now uses **raw** stick magnitude (matches WebApp); adaptive idle gate scales with anti-dz strength; profile joystick settings stay enabled whenever the saved profile customizes sticks/triggers. **Switch 2 wired disconnect:** bulk **keepalive** every **2 s** plus **USB disable-timeout** after bulk bring-up (Switch 2 skipped Switch 1 init that sent this). **PIO USB** host unmount reboot is **debounced 1.5 s** so transient umount on Feather/Pico does not tear down the USB device stack. **Files:** `Gamepad.h`, `JoystickSettings.*`, `SwitchPro.cpp`, `Standard.cpp`, `Switch2ProHost.cpp`. +- **RP2354 — Bluetooth (Pi Radio Module 2)** — **`OGXM_BOARD=RP2354`** now uses the **Pico 2 W** board profile (`pico2_w` / CYW43439): **wireless gamepads** (Bluepad32 — DS4, DualSense, Switch Pro/2, Xbox Series, etc.) plus **PIO USB host** on **GP0/GP1** for wired pads or Wii mode. Same firmware path as **Pico W / Pico 2 W**. **Files:** `CMakeLists.txt`, `Config.h`, `OGXMini.cpp`, `PicoW.cpp`, `TaskQueue.*`. +- **STEAM mode — touchpad mouse only** — Removed the **right-stick mouse** fallback (**Start + Select/Back** / **LT/RT** clicks). The HID mouse interface moves only when the input controller has a **touchpad** (DualSense). Other pads still emulate DualSense as gamepad-only. **Files:** `Steam.cpp`; removed `SteamStickMouse.*`. +- **Switch mode — rumble passthrough** — Switch / Switch 2 console **HD rumble** (output reports **0x01** / **0x10** / **0x11**) was acknowledged but never written to **`PadOut`**, so Bluetooth pads (**DualSense**, **Xbox One S**, etc.) never vibrated. Decode HD rumble amplitude and forward to the wireless pad. **Files:** `Switch.cpp`, `Switch.h`. +- **XInput / Xbox 360 — stock stick feel** ([#38](https://github.com/MegaCadeDev/OGX-Mini-2026/issues/38)) — Modern pads (especially **Xbox Series over Bluetooth**) felt too twitchy vs a real 360 stick. In **XInput mode**, when the WebApp has **not** customized sticks, apply a **360-like** default: **~8–9% remapped inner deadzone**, response **curve 0.35** (quieter center / steeper outer), and **circular clamp** (`uncap_radius` off). WebApp custom stick settings still override. **Files:** `JoystickSettings.*`, `Gamepad.h`, board `initialize()` paths. +- **PS3 / PS4 output — motion passthrough** — **PS3** and **PS4 (DualShock 4 USB)** output modes forward **accelerometer** data (and **gyro** where the input pad provides it) into the emulated report. Supported **input** pads include **DualShock 4** and **DualSense** (**Bluetooth** on Pico W / Pico 2 W and **wired USB** host), **Switch Pro** / **Switch 2 Pro** (**Bluetooth** and **wired USB**), and **Wii Remote** (**Bluetooth** — accel report **0x31** / **0x35** requested automatically when motion output is active; Nunchuk stick maps to left stick). Motion is remapped into the DS4/Sixaxis playing frame; Wii Remote orientation is tuned for **IR end toward the TV**. **Switch** output does **not** pass through motion for now. **Console use:** OGX-Mini does **not** plug directly into a **PlayStation 3** or **PlayStation 4** for motion titles — you need an **additional USB adapter** between the console and OGX-Mini. **Tested with [Brook Wingman XE 2 Converter](https://www.brookaccessories.com/products/wingman-xe2).** The same setup works on **PS4** (select **PS4 output mode** on OGX-Mini; the Brook presents it to the console). **Files:** `MotionImu.h`, `Gamepad.h`, `PS3.cpp`, `PS4.cpp` (USB device), `Bluepad32.cpp`, `SwitchPro.cpp`, `Switch2ProHost.cpp`, `PS4.cpp` / `PS5.cpp` (USB host), `MotionOutputActive.h`, `DeviceManager.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*PS3 / PS4 output — motion passthrough*), [Controller_Mappings.md](Firmware/RP2040/docs/Controller_Mappings.md), and [README — Motion controls](README.md#ps3--ps4-motion-controls). +- **Pico W / Pico 2 W — Bluetooth reconnect after disconnect** — After a wireless pad fully connected (**device ready**) and then disconnected (**Home**, **Start+Select**, or link drop), **in-place BLE reconnect** (especially **Xbox Series**) often failed: LED solid or off, no rumble, no inputs, until the Pico was unplugged. Bonded re-encryption and leftover HIDS state do not match the working first-connect path. **Fix:** when the **last** ready BT controller disconnects, restore **pairing mode** immediately (LED blink + BT scan), then **watchdog reboot** after **~500 ms** so the next pair is identical to a fresh plug-in. Failed pair attempts do **not** reboot (avoids reboot loops while scanning). **Files:** `Bluepad32.cpp` (`device_disconnected_cb`, `device_ready_cb`), `board_api.cpp` (`watchdog_reboot`). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Pico W / Pico 2 W — Bluetooth disconnect reboot for clean reconnect*). +- **Pico W / Pico 2 W / RP2354 BT — USB resume restores pairing** — When the adapter stays plugged into a host that **USB-suspends** in standby (e.g. **Xbox 360** soft shutdown), Bluetooth **BR/LE scan** could stop even though no controller was connected, leaving the LED solid and no pairing. **`tud_resume_cb`** now restores pairing scans on wake (no full reboot). A **45 s idle watchdog** on the BT core restarts scans if they die during long suspend. **Files:** `Bluepad32.cpp`, `tud_callbacks.cpp`. --- @@ -8,11 +23,12 @@ Features and fixes added in this fork. For the latest firmware improvements (PS3 - **PIO USB host — SOF servicing and teardown (all PIO host boards)** — PIO USB has no hardware SOF; wired IN/OUT stalls without periodic **`pio_usb_host_frame()`**. **Standard** path (RP2350-USB-A, Pico, Feather, RP2350-Zero, etc.): Core1 runs a **~1 kHz repeating hardware timer** plus **`pio_usb_host_frame()`** in the main host loop; **`skip_alarm_pool`** on PIO config avoids timer pool conflicts. **`HostManager::send_feedback()`** calls **`pio_usb_host_frame()`** after OUT on **every** `CONFIG_EN_USB_HOST` build (previously Pico W only). **`board_api_usbh::stop_pio_usb_host()`** stops the SOF timer, resets Core1, and **`tuh_deinit`** before USB device disconnect/reboot. **Button-combo output mode change** sets **`s_driver_reboot_pending`** so **`host_mounted(false)`** does not queue a spurious second disconnect reboot during an intentional driver switch. **Files:** `Standard.cpp`, `HostManager.h`, `board_api.cpp`, `board_api_usbh.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*PIO USB host — wired connection fixes*, shared HostManager section). - **Waveshare RP2350-USB-A — wired Switch Pro (PIO USB host)** — Primary validation on **Waveshare RP2350-USB-A** (`OGXM_BOARD=RP2350_USB_A`); driver code is **shared** with all **PIO USB host** builds (`CONFIG_EN_USB_HOST`). **Switch 1 Pro** (PID **0x2009**): replaced Bluetooth-style **0x11** init with **Chromium-style wired USB** sequence — report **0x80** (MAC → handshake → baud → handshake → disable timeout) then **0x12** + subcommand **0x33** probe, LED / full report / IMU subcommands; non-blocking HID OUT with **`pio_usb_host_frame()`** in the feedback path; init advances per IN report with **timeout fallback**; **D-pad** (UP↔DOWN, LEFT↔RIGHT) and **L3↔R3** mapping fixes. **Switch 2 Pro** (PID **0x2069**): **17-packet bulk OUT** bring-up on **USB config 1 / interface 1** (~**12 ms** between packets, same sequence as `Tools/controller_capture/switch2_usb_init.py` / HandHeldLegend ProCon 2 enabler); after bulk completes the pad goes straight to **DONE** — **no** Switch 1 **0x80** HID init; **Switch2ProHost** decodes report **0x09**. **Hot-swap / unplug:** **`disconnect_cb`** cancels bulk bring-up and aborts endpoints; async bulk callbacks resolve the driver by **`(address, instance)`** via **`HostManager::get_switch_pro_host()`** so swapping Switch 1 ↔ Switch 2 Pro does not corrupt state. **Bluetooth** (Pico W / Pico 2 W) unchanged. Protocol references: [Chromium gamepad](https://chromium.googlesource.com/chromium/src/+/main/device/gamepad/) (Switch wired USB init), [HandHeldLegend procon2tool](https://github.com/HandHeldLegend/procon2tool), local **`Tools/controller_capture/switch2_usb_init.py`**. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*PIO USB host — wired connection fixes*) and [Wired_Controllers.md](Firmware/RP2040/docs/Wired_Controllers.md). -- **DualShock 3 / PS3 controller — wired USB host (PIO USB)** — **DualShock 3** over **USB cable** now connects reliably on PIO USB host boards (validated on **RP2350-USB-A**). Replaced gadget-style default OUT report with **USB Host Shield** host layout; **synchronous init** sends **SET feature 0xF4** `{0x42,0x0c,0,0}` (enable USB reports) then a **player LED OUT** report, with **`pio_usb_host_frame()`** polled during control transfers so init completes under PIO USB. **1 Hz keepalive OUT** on PIO USB (`KEEPALIVE_MS`) so the pad stays connected when idle; **`HostManager`** calls **`send_feedback()`** for PS3 on the feedback timer. **Bluetooth auto-pair** (feature **0xF5**) unchanged on Pico W builds — runs after wired init when `CONFIG_EN_BLUETOOTH` is set. **File:** `PS3Host.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — wired USB host*). +- **DualShock 3 / PS3 controller — wired USB host (PIO USB)** — **DualShock 3** over **USB cable** now connects reliably on PIO USB host boards (validated on **RP2350-USB-A**). Replaced gadget-style default OUT report with **USB Host Shield** host layout; **synchronous init** sends **SET feature 0xF4** `{0x42,0x0c,0,0}` (enable USB reports) then a **player LED OUT** report, with **`pio_usb_host_frame()`** polled during control transfers so init completes under PIO USB. **1 Hz keepalive OUT** on PIO USB (`KEEPALIVE_MS`) so the pad stays connected when idle; **`HostManager`** calls **`send_feedback()`** for PS3 on the feedback timer. **Bluetooth auto-pair** (feature **0xF5**) on Pico W / Pico 2 W / RP2354 BT builds runs as a **sync SET** after that wired init (see **1.0.0.12a** restore note). **File:** `PS3Host.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — wired USB host*). - **Xbox 360 wireless USB receiver — wired host (PIO USB)** — **Microsoft PC wireless receiver** (`045e:0719`) + **Xbox 360 wireless pad** sync and input fixed on PIO USB host when **`MAX_GAMEPADS=1`**. **`OGXM_TUH_XINPUT_INSTANCES=4`** when `MAX_GAMEPADS < 4` so all **four RF ports** are polled; **`HostManager`** shares one **`Xbox360WHost`** driver across receiver interfaces and routes **`process_report` / connect / disconnect** to the live driver. **`tuh_xinput`:** **`prime_port_for_pairing()`** sends **RUMBLE_ENABLE + LED** on idle ports; controller-present detection uses **byte1 bit 7 (`0x80`)** (not headset-only **0x40**); accepts report size **0x13** or **0x14**; removed **1 s sleep** on connect; **`service_wireless_ports()`** from feedback timer. **`Xbox360WHost`:** byte-offset decode for wireless input reports; tracks **active instance** for rumble. **Files:** `Config.h`, `HostManager.h`, `tuh_xinput.cpp`, `Xbox360W.cpp`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Xbox 360 wireless receiver — wired USB host*). - **Pico W / Pico 2 W — wired unplug watchdog (360 receiver)** — **No-input** unplug timeout raised from **~3 s** to **~10 s** so a **360 wireless PC receiver** plugged into the adapter’s PIO USB host port (which keeps sending status IN even with no pad paired) is not mistaken for unplug and torn down while Bluetooth should stay available. **File:** `PicoW.cpp`. - **Four-channel / ESP32 I2C — pad wire format** — **`I2CWirePadIn`** fixed **23-byte** payload for master/slave I2C **`PacketIn`** links; excludes **`Gamepad::PadIn` IMU fields** added for DS4/DS5/Switch Pro that broke the **32-byte** wire layout on **Four_Channel_I2C** and **ESP32_Bluepad32_I2C** boards. **Files:** `I2CWirePad.h`, `Four_Channel_I2C.cpp`, `ESP32_Bluepad32_I2C.cpp`. - **Razer Atrox Xbox One — wired USB host (PIO USB)** — **Razer Atrox Arcade Stick** for **Xbox One** (`1532:0a00`) now connects and reports inputs on PIO USB host boards (validated on **RP2350-USB-A**). Vendor-class **GIP** interface opened via **`tuh_xinput`**; init follows **[XBOFS.win](https://github.com/OOPMan/XBOFS.win)** (`05 20 00 01 00` **POWER_ON**, wait for OUT, then **30-byte** IN read loop). Input uses the XBOFS byte layout (dpad byte 5, face/LT/RT on byte 22). **`start_xboxone()`** deferred **50 ms** after mount; **`service_gip()`** re-arms stalled IN only (no repeated **POWER_ON**, which caused power cycling). Standard **Xbox One** wired pads keep the **64-byte** Linux xpad GIP path. **Xbox 360 Atrox** (`24c6:5000`) unchanged — standard XInput with digital trigger bytes. **Files:** `XboxArcadeStick.h`, `tuh_xinput.cpp`, `XboxOne.cpp`, `HostManager.h`. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Razer Atrox Xbox One — GIP arcade stick*) and [Wired_Controllers.md](Firmware/RP2040/docs/Wired_Controllers.md). +- **SteamOS / Bazzite (STEAM output mode)** — New USB output mode for **Linux desktop** / **Steam Deck desktop**: enumerates as **Sony DualSense** (`054c:0ce6`) with a second **HID mouse** interface. **Select:** **Start + Left Bumper + D-pad Up** (~3 s), web app **SteamOS / Bazzite**, or `-DOGXM_FIXED_DRIVER=STEAM` (build-script fixed mode). **DualSense emulation:** passthrough of real PS5 reports when input is DualSense (BT or wired USB host); other controllers get a synthesized DualSense report (face/shoulder/trigger/stick/D-pad/Share/Options/PS mapping). **Touchpad → mouse:** DualSense touchpad drag moves the cursor; tap = left click. Controllers without a touchpad are gamepad-only (no stick-mouse fallback). **Files:** `Steam.cpp`, `SteamPassthrough.h`, `SteamBtReport.h`, `SteamTouchpad.cpp`, `Descriptors/PS5Usb.h`, `Descriptors/Steam.h`, `Bluepad32.cpp`, `PS5.cpp` (wired host), `userSettings.js`. See [README — SteamOS / Bazzite](README.md#steamos--bazzite-output-mode), [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md#steam-mode--steamos--bazzite-linux-desktop), and [Controller_Mappings.md — STEAM](Firmware/RP2040/docs/Controller_Mappings.md#steamos--bazzite-steam-mode). --- @@ -30,7 +46,7 @@ Features and fixes added in this fork. For the latest firmware improvements (PS3 - **Bluetooth (Pico W / Pico 2 W)** — **~1 second connection rumble** when a wireless controller reaches **device ready**, so you get haptic feedback that pairing completed. **DualShock 4** uses a **delayed start** before rumble (same spirit as the existing PS4 FF grace period). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Next version* and *§6. Connection rumble*). - **PS3 mode on Windows PC** — **Host rumble** forwarded to the Bluetooth pad no longer **sticks on at idle**: deadzone on the **large motor** byte and **small motor on only when the host sends `1`** (DS3 semantics). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*PS3 mode* item 7). - **Pico W / Pico 2 W — PIO USB wired unplug** — Unplugging the gamepad from the adapter’s **USB host** port is detected reliably: **PIO-owned D+/D−** often never looks “disconnected” to GPIO/HCD alone. Firmware now uses **debounced** **HCD port status**, **no `tuh_mounted` device** (all TinyUSB address slots), and a **no-input** watchdog (**~3 s** without `process_report` / setup activity) before **`tuh_deinit`** and restoring **GPIO line IRQ** monitoring so **Bluetooth** can resume without power-cycling. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*Pico W / Pico 2 W — PIO USB wired controller unplug detection*). -- **DualShock 3 — USB Bluetooth pairing on adapters with BT** — Plugging a **DS3** into the **USB host** port automatically sends **HID feature report `0xF5`** with this device’s **Bluetooth address** (same idea as [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/)), so you can **unplug** and press **PS** to use the pad wirelessly. If the stack has not published the local BD_ADDR yet, pairing runs on a later report. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — automatic USB programming for Bluetooth pairing*). +- **DualShock 3 — USB Bluetooth pairing on adapters with BT** — Plugging a **DS3** into the **USB host** port automatically sends **HID feature report `0xF5`** with this device’s **Bluetooth address** (same idea as [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/)), so you can **unplug** and press **PS** to use the pad wirelessly. If the stack has not published the local BD_ADDR yet, pairing runs on a later report. **Note:** PIO USB wired-init in **1.0.0.11a** briefly broke this path; **1.0.0.12a** restores it with a **sync `0xF5`** after **0xF4** + LED. See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — automatic USB programming for Bluetooth pairing*). --- diff --git a/Firmware/RP2040/CMakeLists.txt b/Firmware/RP2040/CMakeLists.txt index 4d9b9058..fe2e4e96 100644 --- a/Firmware/RP2040/CMakeLists.txt +++ b/Firmware/RP2040/CMakeLists.txt @@ -68,6 +68,8 @@ set(SOURCES_BOARD ${SRC}/USBDevice/DeviceDriver/PSClassic/PSClassic.cpp ${SRC}/USBDevice/DeviceDriver/PS3/PS3.cpp ${SRC}/USBDevice/DeviceDriver/PS4/PS4.cpp + ${SRC}/USBDevice/DeviceDriver/Steam/Steam.cpp + ${SRC}/USBDevice/DeviceDriver/Steam/SteamTouchpad.cpp ${SRC}/USBDevice/DeviceDriver/Switch/Switch.cpp ${SRC}/USBDevice/DeviceDriver/WiiU/WiiU.cpp ${SRC}/USBDevice/DeviceDriver/Wii/Wii.cpp @@ -220,9 +222,11 @@ elseif(OGXM_BOARD STREQUAL "RP2040_XIAO") elseif(OGXM_BOARD STREQUAL "RP2354") add_compile_definitions(CONFIG_OGXM_BOARD_RP2354=1) + set(EN_BLUETOOTH TRUE) set(EN_USB_HOST TRUE) + set(PICO_BOARD pico2_w) set(PICO_PLATFORM rp2350) - set(FLASH_SIZE_MB 2) + set(FLASH_SIZE_MB 4) else() message(FATAL_ERROR "Invalid OGXM_BOARD value. See options in src/Board/Config.h") @@ -230,11 +234,11 @@ else() endif() # Optional: default or lock USB output mode. -# OGXM_FIXED_DRIVER = one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64. +# OGXM_FIXED_DRIVER = one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64, PS4, STEAM. # Empty = use first valid driver as default, combos enabled. # Set = use that mode as default (first boot / NVS init). If OGXM_FIXED_DRIVER_ALLOW_COMBOS=OFF (default): # combos disabled, mode locked. If OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON: default is this mode, combos still work. -set(OGXM_FIXED_DRIVER "" CACHE STRING "Default/lock output mode. One of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64. Empty = combos enabled.") +set(OGXM_FIXED_DRIVER "" CACHE STRING "Default/lock output mode. One of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64, PS4, STEAM. Empty = combos enabled.") set(OGXM_FIXED_DRIVER_ALLOW_COMBOS OFF CACHE BOOL "If OGXM_FIXED_DRIVER is set: ON = use it as default but allow combos to change mode; OFF = lock to that mode, combos disabled.") if(OGXM_FIXED_DRIVER) add_compile_definitions(CONFIG_OGXM_FIXED_DRIVER=1) @@ -270,10 +274,14 @@ if(OGXM_FIXED_DRIVER) add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=13) elseif(OGXM_FIXED_DRIVER STREQUAL "N64") add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=14) + elseif(OGXM_FIXED_DRIVER STREQUAL "PS4") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=15) + elseif(OGXM_FIXED_DRIVER STREQUAL "STEAM") + add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=16) elseif(OGXM_FIXED_DRIVER STREQUAL "WEBAPP") add_compile_definitions(OGXM_FIXED_DRIVER_TYPE=100) else() - message(FATAL_ERROR "OGXM_FIXED_DRIVER must be one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64") + message(FATAL_ERROR "OGXM_FIXED_DRIVER must be one of: XINPUT, DINPUT, XBOXOG, XBOXOG_SB, XBOXOG_XR, SWITCH, WIIU, WII, PS3, PSCLASSIC, WEBAPP, PS1PS2, GAMECUBE, DREAMCAST, N64, PS4, STEAM") endif() if(OGXM_FIXED_DRIVER STREQUAL "WII") message(STATUS "Wii-only build: ${OGXM_FIXED_DRIVER} (combos disabled, build option only)") @@ -349,7 +357,7 @@ if(EN_BLUETOOTH) ) # Wii mode: Wiimote BT emulator (Pico W/2W with USB host) - if(EN_USB_HOST AND (OGXM_BOARD STREQUAL "PI_PICOW" OR OGXM_BOARD STREQUAL "PI_PICO2W")) + if(EN_USB_HOST AND (OGXM_BOARD STREQUAL "PI_PICOW" OR OGXM_BOARD STREQUAL "PI_PICO2W" OR OGXM_BOARD STREQUAL "RP2354")) message(STATUS "Wii Wiimote lib enabled.") list(APPEND SOURCES_BOARD ${SRC}/Wii/utils.c @@ -431,8 +439,13 @@ if(EXISTS ${SRC}/USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid_xremote_rom.h) add_definitions(-DXREMOTE_ROM_AVAILABLE) endif() -# RP2040-only: force generic boot2 when no Bluetooth (pico2/pico2_w use board's boot2 choice) -if(NOT EN_BLUETOOTH AND NOT (OGXM_BOARD STREQUAL "PI_PICO2") AND NOT (OGXM_BOARD STREQUAL "PI_PICO2W")) +# RP2040-only: force generic boot2 when no Bluetooth (RP2350 boards use platform boot2) +if(NOT EN_BLUETOOTH + AND NOT (OGXM_BOARD STREQUAL "PI_PICO2") + AND NOT (OGXM_BOARD STREQUAL "PI_PICO2W") + AND NOT (OGXM_BOARD STREQUAL "RP2350_USB_A") + AND NOT (OGXM_BOARD STREQUAL "RP2350_ZERO") + AND NOT (OGXM_BOARD STREQUAL "RP2354")) add_compile_definitions(PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H=1) add_compile_definitions(PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64) endif() @@ -462,7 +475,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") # Pico W/2W: use UART1 on GP4 (TX) / GP5 (RX) - valid UART pins, avoids PIO USB (GP0/1) in Wii mode # Note: GP10/11 are not valid UART pins on RP2040/RP2350 - if(OGXM_BOARD STREQUAL "PI_PICOW" OR OGXM_BOARD STREQUAL "PI_PICO2W") + if(OGXM_BOARD STREQUAL "PI_PICOW" OR OGXM_BOARD STREQUAL "PI_PICO2W" OR OGXM_BOARD STREQUAL "RP2354") set(TX_PIN 4) set(RX_PIN 5) else() diff --git a/Firmware/RP2040/docs/Controller_Mappings.md b/Firmware/RP2040/docs/Controller_Mappings.md new file mode 100644 index 00000000..db15c91b --- /dev/null +++ b/Firmware/RP2040/docs/Controller_Mappings.md @@ -0,0 +1,386 @@ +# Controller button and stick mappings + +This document describes how OGX-Mini maps **input controllers** (USB host / Bluetooth) into the internal **`PadIn`** layout, and how each **output mode** maps **`PadIn`** to what the console or host sees. + +**Related docs** + +| Topic | Document | +|-------|----------| +| GPIO output (PS1/PS2, Dreamcast, GameCube, N64) pin-outs + mappings | [GPIO_Output_Pinout_and_Mappings.md](GPIO_Output_Pinout_and_Mappings.md) | +| Wii **output** mode (Wiimote over BT) | [Wii_Mode_Guide.md](Wii_Mode_Guide.md) | +| Supported wired USB pads (VID/PID lists) | [Wired_Controllers.md](Wired_Controllers.md) | +| PS3/PS4 motion (accel/gyro) | [IMPROVEMENTS.md — motion passthrough](IMPROVEMENTS.md#ps3--ps4-output--motion-passthrough) | +| Bluetooth pad list (Bluepad32) | [Bluepad32 supported gamepads](https://bluepad32.readthedocs.io/en/latest/supported_gamepads/) | + +--- + +## How mappings work + +```text +[Input controller] → PadIn → [Output driver] → Console / PC / GPIO + USB host ↑ USB gadget or GPIO protocol + Bluetooth (Bluepad32) │ + └── User profiles may remap MAP_* fields (web app) +``` + +**`PadIn`** is the firmware’s canonical gamepad state (`Gamepad::PadIn` in `Gamepad.h`). Names follow **Xbox-style** layout: + +| PadIn field | Meaning | +|-------------|---------| +| **A / B / X / Y** | Face buttons (A = south / Cross on PlayStation) | +| **LB / RB** | Bumpers | +| **trigger_l / trigger_r** | Analog triggers (0–255) | +| **Start / Back** | Menu buttons | +| **SYS** | Guide / Home / PS | +| **MISC** | Share / Capture / touchpad click (pad-dependent) | +| **L3 / R3** | Stick clicks | +| **dpad** | Up / Down / Left / Right (diagonals supported) | +| **joystick_lx/ly, joystick_rx/ry** | Sticks (−32768 … +32767, center 0) | +| **accel / gyro** | Motion (when input pad provides IMU) | + +**User remapping:** For most **USB output** modes, button and stick assignments can be changed in the [web app](https://megacadedev.github.io/OGX-Mini-2026-WebApp/) (saved profiles alter `Gamepad::MAP_*` fields). **GPIO output** modes and some specialty mappings use fixed defaults only (see [GPIO doc](GPIO_Output_Pinout_and_Mappings.md#changing-mappings)). + +**Source code index:** `Gamepad.h` (PadIn), `Bluepad32/Bluepad32.cpp` (BT → PadIn), `USBHost/HostDriver/*` (wired USB → PadIn), `USBDevice/DeviceDriver/*` and `Gamepad/*` GPIO drivers (PadIn → output). + +--- + +## Input → PadIn + +### Standard layout (most Bluetooth and USB pads) + +Bluepad32 (Pico W / Pico 2 W) and most USB host drivers (XInput, DualShock 3/4/5, etc.) map the physical controller into **`PadIn` using the Xbox-style table above** — face buttons, bumpers, triggers, sticks, and menu buttons align with their Xbox equivalents. PlayStation and Switch pads are normalized to this layout in the host/BT layer. + +| Physical (examples) | PadIn | +|---------------------|-------| +| Xbox A / DS Cross / Switch B | **A** | +| Xbox B / DS Circle / Switch A | **B** | +| Xbox X / DS Square / Switch Y | **X** | +| Xbox Y / DS Triangle / Switch X | **Y** | +| View / Select / Minus | **Back** | +| Menu / Start / Plus | **Start** | +| Guide / PS / Home | **SYS** | +| Share / Capture | **MISC** (when present) | + +**Disconnect combo (Bluetooth):** **Start + Back** (~0.5 s). **OUYA:** **L3 + R3** (no Start/Select). + +### Steam Controller 2026 / Triton (Bluetooth LE) + +Wireless only on **Pico W / Pico 2 W / RP2354** (`28de:1303`). Pairing and protocol: [IMPROVEMENTS — Steam Controller 2026](IMPROVEMENTS.md#steam-controller-2026-triton--bluetooth). + +Valve’s printed **View / Menu** labels do **not** match Xbox View/Menu. Firmware follows SDL: + +| Triton control | PadIn | +|----------------|-------| +| **View** | **Start** | +| **Menu** | **Back** | +| **Steam** (or QAM) | **SYS** | +| A / B / X / Y, LB / RB, L3 / R3, d-pad, LT / RT, sticks | Standard layout | +| L4 / L5 / R4 / R5 grips | Unmapped | + +--- + +### Wii Remote (Bluetooth input) + +Handheld Wiimotes (not Wii U Pro, Classic Controller, or Balance Board) are forced to **vertical (TV-style)** orientation on connect: `uni_hid_parser_wii_set_mode(WII_MODE_VERTICAL)` in `Bluepad32.cpp`. Hold the remote with the **IR end toward the TV**. Plug the **Nunchuk in before pairing** (or reconnect after attaching it) so extension init completes. + +| Wiimote (vertical) | PadIn | +|--------------------|-------| +| D-pad | D-pad | +| **B** (trigger under body) | **A** | +| **A** (large face button) | **B** | +| **1** | **X** (no Nunchuk) / **LB** (with Nunchuk) | +| **2** | **Y** (no Nunchuk) / **RB** (with Nunchuk) | +| **+** | **Start** | +| **−** | **Back** | +| **Home** | **SYS** | + +| Nunchuk | PadIn | +|---------|-------| +| **Stick** | **Left stick** (`joystick_lx` / `joystick_ly`) | +| **C** | **X** | +| **Z** | **Y** | + +**Motion:** In **PS3 / PS4 output mode**, continuous accel reports are requested: **`0x31`** (Wiimote only) or **`0x35`** (Wiimote + Nunchuk). **Switch** output does not request or pass through motion for now. See [motion passthrough](IMPROVEMENTS.md#ps3--ps4-output--motion-passthrough). + +**Triggers:** Wiimote **B** maps to **A**, not analog triggers. Shoulder/Z does not fill `trigger_l` / `trigger_r` when mapped as LB/RB. + +--- + +### Switch Pro Controller (wired USB host) + +Switch 1 Pro (`0x2009`) uses `SwitchProHost` with deliberate swaps vs a 1:1 Pro layout (`SwitchPro.cpp`): + +| Switch Pro physical | PadIn | +|---------------------|-------| +| **Y** | **X** | +| **B** | **A** | +| **A** | **B** | +| **X** | **Y** | +| **L / R** | **LB / RB** | +| **ZL / ZR** | **trigger_l / trigger_r** (digital full) | +| **− / +** | **Back / Start** | +| **Home** | **SYS** | +| **Capture** | **MISC** | +| **L3 / R3** | **R3 / L3** (swapped) | +| D-pad Up/Down/Left/Right | D-pad **Down/Up/Right/Left** (swapped) | + +Sticks are scaled to `PadIn` int16 range. IMU is available for **PS3/PS4 output** motion passthrough. + +--- + +### Switch 2 Pro (wired USB host) + +Switch 2 Pro (`0x2069`) uses `Switch2ProHost` with **Switch-2-specific** bit positions (not the classic `Buttons0/1/2` layout). See `Switch2ProHost.cpp` for bit definitions. Summary: + +| Switch 2 Pro | PadIn | +|--------------|-------| +| Face **B / A / Y / X** (bits 0–3) | **A / B / X / Y** | +| **RB** (bit 4) | **RB** | +| **LB** (Home bit on misc byte) | **LB** | +| **Minus** | **Back** | +| Classic **R** bit | **Start** | +| Stick **L3** (classic ZR bit) | **L3** | +| Stick **R3** (misc bit 7) | **R3** | +| **Home** (left byte) | **SYS** | +| **ZL / ZR** digital bits | **trigger_l / trigger_r** (digital) | +| D-pad (misc − / L3 / + / R3 bit positions) | D-pad | + +Sticks use the same 12-bit packing as Switch 1 Pro, with **Y inverted** into PadIn. **Anti-deadzone** profiles apply a small noise floor (~8%) when inner deadzone is unset so imperfect stick centers do not drift. + +**GL**, **GR**, and **Chat** are documented in source but intentionally unmapped. + +--- + +### Generic / DInput USB host + +Unknown HID pads use the generic host path; mapping depends on the report descriptor. Use the [controller capture tool](../../../Tools/controller_capture/README.md) when adding support. DInput **output** mode uses PlayStation names on the wire (see below). + +--- + +## PadIn → USB output modes + +Unless noted, **D-pad** and **sticks** map directly. **Triggers** map to analog axes where the protocol supports them. + +### XInput (Xbox 360) + +| PadIn | Xbox 360 | +|-------|----------| +| A / B / X / Y | A / B / X / Y | +| LB / RB | LB / RB | +| trigger_l / trigger_r | LT / RT | +| Back / Start | Back / Start | +| L3 / R3 | L3 / R3 | +| SYS | Guide | +| D-pad | D-pad | +| Sticks | Left / right stick | + +**Source:** `USBDevice/DeviceDriver/XInput/XInput.cpp` + +--- + +### PlayStation 3 (DualShock 3 / Sixaxis) + +| PadIn | DS3 | +|-------|-----| +| A | **Cross** | +| B | **Circle** | +| X | **Square** | +| Y | **Triangle** | +| LB / RB | L1 / R1 | +| trigger_l / trigger_r | L2 / R2 (+ analog axes) | +| Back / Start | Select / Start | +| L3 / R3 | L3 / R3 | +| SYS | **PS** (8-frame latch for BT taps) | +| MISC | Touchpad (byte bit; rarely used on DS3) | +| D-pad | D-pad | +| Sticks | Left / right (0–255, center 0x80) | +| accel / gyro | **Sixaxis** (when input provides motion) | + +**Source:** `USBDevice/DeviceDriver/PS3/PS3.cpp` + +--- + +### PlayStation 4 (DualShock 4 USB) + +| PadIn | DS4 | +|-------|-----| +| A / B / X / Y | Cross / Circle / Square / Triangle | +| LB / RB | L1 / R1 | +| trigger_l / trigger_r | L2 / R2 | +| Back / Start | Share / Options | +| L3 / R3 | L3 / R3 | +| SYS | PS | +| MISC | Touchpad click | +| D-pad / sticks | D-pad / sticks | +| accel / gyro | DS4 motion fields (when input provides motion) | + +**Source:** `USBDevice/DeviceDriver/PS4/PS4.cpp` + +--- + +### Nintendo Switch (Pro Controller emulation) + +Face buttons use **Nintendo names on the wire**; mapping from PadIn is **crossed** so PlayStation/Xbox inputs feel correct on Switch: + +| PadIn | Switch Pro output | +|-------|-------------------| +| **A** | **B** | +| **B** | **A** | +| **X** | **Y** | +| **Y** | **X** | +| LB / RB | **L / R** | +| trigger_l / trigger_r | **ZL / ZR** | +| Back / Start | **− / +** | +| L3 / R3 | L3 / R3 | +| SYS | **Home** | +| MISC | **Capture** | +| D-pad | D-pad | +| Sticks | Left / right (12-bit; Y inverted vs PadIn) | + +**Rumble (v1.0.0.12a):** Console **HD rumble** in output reports **`0x01` / `0x10` / `0x11`** is decoded into **`PadOut`** and forwarded to the input pad (Bluetooth DualSense / Xbox, etc.). See [IMPROVEMENTS — Switch HD rumble](IMPROVEMENTS.md#switch-mode--hd-rumble-passthrough). + +**Source:** `USBDevice/DeviceDriver/Switch/Switch.cpp` + +--- + +### DInput (DirectInput) + +| PadIn | DInput report | +|-------|----------------| +| A / B / X / Y | Cross / Circle / Square / Triangle | +| LB / RB | L1 / R1 | +| trigger_l / trigger_r | L2 / R2 axes | +| Back / Start | Select / Start | +| SYS / MISC | Mode / TP | +| L3 / R3 | L3 / R3 | +| D-pad / sticks | D-pad / sticks | + +**Source:** `USBDevice/DeviceDriver/DInput/DInput.cpp` + +--- + +### SteamOS / Bazzite (STEAM mode) + +**Select mode:** **Start + Left Bumper + D-pad Up** (~3 s). + +Enumerates as **DualSense** (`054c:0ce6`) plus a **HID mouse** interface. **DualSense input** (BT or wired USB): gamepad report is **passthrough**; touchpad → separate **mouse** interface. **Other input:** report is **synthesized** from PadIn using the mapping below; **no stick-mouse fallback**. + +| PadIn | DualSense USB | +|-------|----------------| +| A / B / X / Y | Cross / Circle / Square / Triangle | +| LB / RB | L1 / R1 | +| trigger_l / trigger_r | L2 / R2 | +| Back / Start | Share / Options | +| L3 / R3 | L3 / R3 | +| SYS | PS | +| MISC | Touchpad click | +| **DualSense touchpad** (input) | USB mouse movement + click (IF1) | + +**Source:** `USBDevice/DeviceDriver/Steam/*`, `SteamBtReport.h`, `SteamTouchpad.cpp` + +--- + +### Original Xbox (Gamepad) + +| PadIn | OG Xbox | +|-------|---------| +| A / B / X / Y | A / B / X / Y (digital or analog face per build) | +| LB / RB | White / Black | +| trigger_l / trigger_r | LT / RT | +| Back / Start | Back / Start | +| L3 / R3 | L3 / R3 | +| SYS | **Guide** (tap = Start; hold chords for IGR/shutdown — see README) | +| Sticks | Left / right (**Y inverted** on wire) | + +**Source:** `USBDevice/DeviceDriver/XboxOG/XboxOG_GP.cpp` + +--- + +### Original Xbox — Steel Battalion + +Uses a dedicated chatpad + gamepad map table (`XboxOG_SB.cpp`). See source `GP_MAP` / `CHATPAD_MAP` for the full SB control surface. + +--- + +### Original Xbox — DVD Remote (XRemote) + +| PadIn | Remote button | +|-------|----------------| +| SYS | Display | +| Start | Play | +| Back | Stop | +| A | Select | +| Y | Pause | +| X | Display | +| B | Back | +| LB / RB (alone or together) | Skip − / Skip + / Display | +| L3 / R3 (alone or together) | Title / Menu / Info | + +**Source:** `USBDevice/DeviceDriver/XboxOG/XboxOG_XR.cpp` + +--- + +### PlayStation Classic + +| PadIn | PS Classic | +|-------|------------| +| A / B / X / Y | Cross / Circle / Square / Triangle | +| LB / RB | L1 / R1 | +| Back / Start | Select / Start | +| D-pad / sticks | D-pad / sticks | + +**Source:** `USBDevice/DeviceDriver/PSClassic/PSClassic.cpp` + +--- + +### Wii U (GameCube adapter emulation) + +Emulates a **GameCube controller** on the Wii U adapter port. Face buttons are **swapped** to match GC layout: + +| PadIn | GameCube (Wii U report) | +|-------|-------------------------| +| **B** | **A** | +| **A** | **B** | +| **Y** | **X** | +| **X** | **Y** | +| Start | Start | +| RB | **Z** | +| trigger_l / trigger_r (full) | **L / R** digital | +| D-pad | D-pad | +| Left stick | Main stick (Y axis may invert for Xbox vs Nintendo hosts) | +| Right stick | C-stick | + +**LB** is not mapped to a GC button. **Source:** `USBDevice/DeviceDriver/WiiU/WiiU.cpp` + +--- + +## PadIn → GPIO output modes + +PS1/PS2, Dreamcast, GameCube, and N64 use fixed **PadIn → console** tables and pin-outs documented in: + +**[GPIO_Output_Pinout_and_Mappings.md](GPIO_Output_Pinout_and_Mappings.md)** + +--- + +## USB gamepad → Wii Remote (Wii output mode) + +When the firmware is built with **`-DOGXM_FIXED_DRIVER=WII`**, a USB/BT gamepad is converted into Wiimote (+ extension) reports over Bluetooth. Mappings for **No Extension**, **Nunchuk**, and **Classic Controller** are in: + +**[Wii_Mode_Guide.md — §5 Button and stick mapping](Wii_Mode_Guide.md#5-button-and-stick-mapping-by-mode)** + +--- + +## Quick reference: PlayStation ↔ PadIn ↔ Xbox + +| PlayStation | PadIn | Xbox | +|-------------|-------|------| +| Cross | **A** | A | +| Circle | **B** | B | +| Square | **X** | X | +| Triangle | **Y** | Y | +| L1 / R1 | LB / RB | LB / RB | +| L2 / R2 | triggers | LT / RT | +| Share / Options | Back / Start | View / Menu | +| PS | SYS | Guide | + +Use this table when reading any **PadIn → output** section above. diff --git a/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md b/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md index 0e33001b..7fae28e4 100644 --- a/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md +++ b/Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md @@ -190,4 +190,4 @@ Data lines use **GPIO** numbers on the Pico. Power uses the Pico’s **GND** and ## Changing mappings -Default mappings are fixed in the device drivers. User-configurable button remapping is available for **USB device** modes (e.g. Switch, XInput) via the web app; GPIO output modes (PS1/PS2, Dreamcast, GameCube, N64) currently use the defaults above only. To change them you would need to edit the corresponding driver source (e.g. `PS1PS2.cpp`, `Dreamcast.cpp`, `GameCube.cpp`, `N64.cpp`) and rebuild. +Default mappings are fixed in the device drivers. User-configurable button remapping is available for **USB device** modes (e.g. Switch, XInput) via the web app; GPIO output modes (PS1/PS2, Dreamcast, GameCube, N64) currently use the defaults above only. See **[Controller_Mappings.md](Controller_Mappings.md)** for the full mapping reference across all modes. diff --git a/Firmware/RP2040/docs/IMPROVEMENTS.md b/Firmware/RP2040/docs/IMPROVEMENTS.md index ca5b290d..dd6eed8d 100644 --- a/Firmware/RP2040/docs/IMPROVEMENTS.md +++ b/Firmware/RP2040/docs/IMPROVEMENTS.md @@ -2,14 +2,248 @@ Improvements and fixes applied to the OGX-Mini RP2040 firmware in this project. -**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). **v1.0.0.10a** adds **Nintendo Switch 2** wireless support (**Pro 2** and **Joy-Con 2**) over **BLE**, **Switch 1 Joy-Con L+R merge**, and **Joy-Con dual-half latency fixes** (see *Nintendo Switch 2 — Bluetooth* and *Joy-Con pair merge — latency* below). **v1.0.0.11a** adds **PIO USB host wired connection fixes** — **Switch 1/2 Pro**, **DualShock 3**, **Xbox 360 wireless receiver**, and **Razer Atrox Xbox One** (`1532:0a00`) — validated on **Waveshare RP2350-USB-A** (see *PIO USB host — wired connection fixes* below). +**Version:** From **v1.0.0a3** the version was bumped to **v1.0.0a4** to reflect Wii U controller fixes, Gamecube USB mode, PS3 driver fixes, latency improvements, and Xbox 360 (XInput) support (see below). **v1.0.0.8a+** documents **Pico W / Pico 2 W** work on **DualShock 4 (Classic Bluetooth)** vs **BLE advertising**, **BR inquiry**, and related BT stability (see *Pico W / Pico 2 W — DualShock 4 and Classic Bluetooth* below). **v1.0.0.10a** adds **Nintendo Switch 2** wireless support (**Pro 2** and **Joy-Con 2**) over **BLE**, **Switch 1 Joy-Con L+R merge**, and **Joy-Con dual-half latency fixes** (see *Nintendo Switch 2 — Bluetooth* and *Joy-Con pair merge — latency* below). **v1.0.0.11a** adds **PIO USB host wired connection fixes** — **Switch 1/2 Pro**, **DualShock 3**, **Xbox 360 wireless receiver**, and **Razer Atrox Xbox One** (`1532:0a00`) — validated on **Waveshare RP2350-USB-A**, plus **STEAM output mode** for **SteamOS / Bazzite** (see *STEAM mode* below). **v1.0.0.12a** adds **PS3 / PS4 motion passthrough**, **Bluetooth disconnect reboot**, **USB resume → restore BT pairing**, **XInput stock stick feel (#38)**, **Switch HD rumble passthrough**, **Switch 2 anti-deadzone / L3–R3 (#64)**, **RP2354 Bluetooth**, **STEAM touchpad-mouse-only**, **Steam Controller 2026 (Triton) BLE**, and **DualShock 3 USB → Bluetooth auto-pair restore** (sync feature **0xF5** after PIO USB wired init; see sections below). + +**Version 1.0.0.12a — documented here for release notes:** + +- **DualShock 3 — USB → Bluetooth auto-pair restored** — Sync **feature `0xF5`** after **0xF4** + LED (PIO USB sync init had skipped the old async F2→F5 path). See [§ DualShock 3 — automatic USB programming for Bluetooth pairing](#dualshock-3--automatic-usb-programming-for-bluetooth-pairing) and [§ DualShock 3 — wired USB host](#dualshock-3--wired-usb-host). +- **Steam Controller 2026 (Triton) — Bluetooth** — See [§ Steam Controller 2026 (Triton) — Bluetooth](#steam-controller-2026-triton--bluetooth) below. +- **PS3 / PS4 output — motion passthrough** — See [§ PS3 / PS4 output — motion passthrough](#ps3--ps4-output--motion-passthrough) below. +- **Pico W / Pico 2 W — Bluetooth disconnect reboot for clean reconnect** — See [§ Pico W / Pico 2 W — Bluetooth disconnect reboot for clean reconnect](#pico-w--pico-2-w--bluetooth-disconnect-reboot-for-clean-reconnect) below. +- **USB resume restores pairing scans** — See [§ Pico W / Pico 2 W / RP2354 BT — USB resume restores pairing scans](#pico-w--pico-2-w--rp2354-bt--usb-resume-restores-pairing-scans) below. +- **XInput / Xbox 360 — stock stick feel (#38)** — See [§ XInput / Xbox 360 — stock stick feel](#xinput--xbox-360--stock-stick-feel) below. +- **Switch mode — HD rumble passthrough** — See [§ Switch mode — HD rumble passthrough](#switch-mode--hd-rumble-passthrough) below. +- **Switch 2 Pro — anti-deadzone drift and L3/R3 (#64)** — See [§ Switch 2 Pro — anti-deadzone and L3/R3](#switch-2-pro--anti-deadzone-and-l3r3) below. +- **RP2354 Bluetooth** — Board profile uses Pico 2 W BT path; see [§ Additional board support](#additional-board-support-rp2350_zero-rp2040_xiao-rp2354). +- **STEAM mode** — Touchpad → mouse only (no stick-mouse); see [§ STEAM mode](#steam-mode--steamos--bazzite-linux-desktop). **Version 1.0.0.9a — documented here for release notes:** - **Bluetooth (Pico W / Pico 2 W):** ~**1 second** haptic **connection rumble** when a wireless controller reaches **device ready** (so you can feel that pairing completed). **DualShock 4** uses a **longer start delay** before rumble (same idea as the existing PS4 FF grace window) so early force-feedback does not destabilize the link. **File:** `src/Bluepad32/Bluepad32.cpp` — `ogxm_play_connection_rumble()` from `device_ready_cb`. - **PS3 mode with the adapter plugged into a Windows PC:** **Host output rumble** forwarded to the Bluetooth pad no longer stays on at idle. Windows DInput often sends a **small non-zero** large-motor byte or a **small-motor byte other than 0/1**; the driver now applies a **deadzone** on the large motor and treats the small motor as on **only when the byte is `1`** (DS3 output semantics). **File:** `src/USBDevice/DeviceDriver/PS3/PS3.cpp` — `new_report_out_` path. - **Pico W / Pico 2 W — PIO USB wired unplug:** **Reliable disconnect** when the gamepad cable is removed from the adapter’s PIO USB host port (see [§ Pico W / Pico 2 W — PIO USB wired controller unplug detection](#pico-w--pico-2-w--pio-usb-wired-controller-unplug-detection)). **Files:** `src/OGXMini/Board/PicoW.cpp`, `src/USBHost/HostManager.h`. -- **DualShock 3 — automatic Bluetooth pairing over USB (boards with Bluetooth):** When a **PS3 / DualShock 3** controller is used **wired** on the USB host, after the normal USB HID init the firmware sends **HID feature report `0xF5`** with the adapter’s **local BD_ADDR** (same as [Bluepad32’s sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/)), so the user can **unplug USB** and connect with **PS**. If `uni_local_bd_addr` is not ready yet, pairing is **deferred** until the first reports where the address is valid. **File:** `src/USBHost/HostDriver/PS3/PS3.cpp` (guarded by `CONFIG_EN_BLUETOOTH`). +- **DualShock 3 — automatic Bluetooth pairing over USB (boards with Bluetooth):** When a **PS3 / DualShock 3** controller is used **wired** on the USB host, right after **0xF4** + LED init the firmware sync-sends **HID feature report `0xF5`** with the adapter’s **local BD_ADDR** (same as [Bluepad32’s sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/)), so the user can **unplug USB** and connect with **PS**. If `uni_local_bd_addr` is not ready yet, pairing is **deferred** until a later report. **(Behavior as of v1.0.0.12a** — sync SET after PIO USB wired init; originally added in 1.0.0.9a.) **File:** `src/USBHost/HostDriver/PS3/PS3.cpp` (guarded by `CONFIG_EN_BLUETOOTH`). + +--- + +## Pico W / Pico 2 W — Bluetooth disconnect reboot for clean reconnect + +**Goal:** After a wireless controller fully connects and then disconnects, the next pair must work like a **fresh plug-in** — rumble, inputs, and pairing LED — without unplugging the Pico. + +**Problem:** In-place BLE reconnect (especially **Xbox Series / One over BLE**) does not reliably re-run the same path as first connect. Bonded **re-encryption**, leftover **HIDS** client / descriptor state, and scan flags left the adapter in a bad state: LED solid or off, no connection rumble, no gamepad input, until a power cycle. + +**Approach:** Treat a successful pad’s disconnect as a full reset of the radio stack, the same way unplugging the Pico does. + +| Item | Detail | +|------|--------| +| **When** | Last Bluetooth pad that reached **device ready** disconnects (**Home**, **Start+Select**, or link drop) | +| **Immediate** | Restore **pairing mode**: LED blink + BT scan / new connections enabled | +| **After ~500 ms** | **Watchdog reboot** (`watchdog_reboot`) — reliable from the BT core (Core1) | +| **Not when** | Failed pair attempts while already scanning (avoids reboot loops) | +| **Multi-pad** | No reboot while another BT pad is still connected | + +**User flow:** Disconnect pad → LED flashes (pairing) → brief reboot (USB may re-enumerate on the PC) → LED flashes again → press the controller’s connect button → normal first-connect rumble and inputs. + +**Files:** `src/Bluepad32/Bluepad32.cpp` (`device_ready_cb` sets `s_bt_slot_was_ready`; `device_disconnected_cb` restores pairing mode and schedules reboot), `src/Board/board_api.cpp` (`board_api::reboot()` via `watchdog_reboot`). + +--- + +## Pico W / Pico 2 W / RP2354 BT — USB resume restores pairing scans + +**Goal:** When the adapter stays plugged into a console that **USB-suspends** in standby (e.g. **Xbox 360** soft shutdown via Guide → Turn off console), Bluetooth **BR/EDR inquiry** and **BLE scan** must resume after the host wakes so the user can pair without unplugging the dongle. + +**Problem:** With no wireless pad connected, long USB suspend could leave Bluepad32’s “new connections enabled” flag **true** while the radio had **stopped scanning** — LED solid or off, no pairing blink. + +**Approach:** + +| Item | Detail | +|------|--------| +| **USB resume** | `tud_resume_cb` → `bluepad32::on_usb_device_resume()` (marshaled to BT core) → `restore_bt_pairing_mode(-1)` when no BT pad and no PIO wired host pad is active | +| **Idle watchdog** | Every **45 s** on the BT run loop, restart BR/LE scans if idle and pairing should be active | +| **No reboot on resume** | Unlike pad disconnect, console wake does **not** trigger watchdog reboot (avoids XSM3 re-auth every standby cycle) | +| **Wired host release** | `wired_usb_release_enable_bt_pairing()` uses the same scan-restore path (not only `enable_new_connections`, which is a no-op when the flag is already true) | + +**Files:** `src/Bluepad32/Bluepad32.cpp`, `src/USBDevice/tud_callbacks.cpp`. + +--- + +## XInput / Xbox 360 — stock stick feel + +**Goal:** Controllers used in **Xbox 360 (XInput) mode** — especially modern pads like **Xbox Series / One over Bluetooth** on Pico 2 W — should feel closer to a **stock 360** stick than a near-linear high-precision Series stick ([#38](https://github.com/MegaCadeDev/OGX-Mini-2026/issues/38)). + +**Problem:** Default profiles left sticks **uncurved** (`curve=1`, `dz_inner=0`, `uncap_radius=true`). Series pads report tiny physical deflections as strong USB values, so 360 games feel twitchy. A real 360 stick is quieter near center and firmer toward the rim. + +**Approach (XInput mode only):** + +| Item | Detail | +|------|--------| +| **When** | Current output driver is **XInput** and WebApp stick settings are still at defaults (not customized) | +| **Inner deadzone** | Remapped **~8%** left / **~9%** right (mild — not Microsoft’s ~24% software constant, so games that also deadzone are not double-dulled) | +| **Curve** | **0.35** (`mag^(1/curve)`): quieter center, steeper outer third | +| **Uncap** | **Off** — clamp to circular radius like a stock pad | +| **Override** | Any WebApp stick customization replaces these defaults | + +**Files:** `src/UserSettings/JoystickSettings.*`, `src/Gamepad/Gamepad.h`, board `initialize()` (`PicoW.cpp`, `Standard.cpp`, `Four_Channel_I2C.cpp`). + +--- + +## Switch mode — HD rumble passthrough + +**Goal:** When OGX-Mini enumerates as a **Switch Pro** controller, console **HD rumble** must reach the **input** pad (especially Bluetooth DualSense / Xbox). + +**Problem:** Output reports **`0x01`** / **`0x10`** / **`0x11`** (and related rumble commands) were acknowledged for Switch protocol bookkeeping but never decoded into **`PadOut`**, so wireless pads never vibrated in Switch mode. + +**Approach:** Parse left/right HD rumble motor blocks (dekuNukem-style amplitude decode), write **`rumble_l` / `rumble_r`** into `PadOut`, and let Bluepad32 / USB host feedback forward motors to the input controller. Applies to all boards that support Switch output (including Pico 2 W / RP2354 with BT pads). + +**Files:** `src/USBDevice/DeviceDriver/Switch/Switch.cpp`, `Switch.h`. + +--- + +## Switch 2 Pro — anti-deadzone and L3/R3 + +**Goal:** Fix WebApp **anti-deadzone** drift and **L3/R3** mapping on wired **Switch 2 Pro** ([#64](https://github.com/MegaCadeDev/OGX-Mini-2026/issues/64)). + +**Problem:** Anti-Deadzone Circular/Square amplified imperfect Switch 2 Pro stick centers into constant bottom-left drift. Circular resize used the wrong WebApp field (`anti_dz_circle` vs `anti_dz_square`). Wired **L3/R3** were mapped to the wrong physical sticks. + +**Approach:** + +| Item | Detail | +|------|--------| +| **Idle gate** | Small noise floor when anti-dz is active (raw magnitude; adaptive with anti-dz strength) | +| **Circular formula** | Match WebApp (`anti_dz_square` where intended) | +| **L3/R3** | Correct physical stick clicks on wired Switch 2 Pro | +| **Profiles** | Joystick settings stay enabled when the saved profile customizes sticks/triggers | +| **Wired disconnect** | Bulk **keepalive** every **2 s** + USB disable-timeout after Switch 2 bulk bring-up; PIO unmount reboot **debounced 1.5 s** | + +**Files:** `Gamepad.h`, `JoystickSettings.*`, `SwitchPro.cpp`, `Standard.cpp`, `Switch2ProHost.cpp`. + +--- + +## STEAM mode — SteamOS / Bazzite (Linux desktop) + +**Goal:** On **SteamOS**, **Bazzite**, or other **Linux desktops** (including **Steam Deck** in desktop mode), present a **PS5 DualSense** USB gamepad **and** route the **touchpad** to a separate **HID mouse** so the user can move the desktop cursor without Steam Input remapping. + +### Select mode (button combos and build options) + +| Method | Detail | +|--------|--------| +| **Button combo** | **Start + Left Bumper + D-pad Up** — hold ~3 s; saved to flash; RP2040 resets | +| **Web app** | Output mode **SteamOS / Bazzite** (value `16`) | +| **Fixed build** | **`-DOGXM_FIXED_DRIVER=STEAM`** — also option **13** in `scripts/build.sh` / `build.ps1` fixed-mode menu | + +**User docs:** [README — SteamOS / Bazzite output mode](../../../README.md#steamos--bazzite-output-mode). **Mappings:** [Controller_Mappings.md — STEAM mode](Controller_Mappings.md#steamos--bazzite-steam-mode). + +### DualSense USB emulation + +| Item | Detail | +|------|--------| +| **USB VID:PID** | `054c:0ce6` (Sony DualSense) | +| **Interfaces** | IF0: DualSense gamepad (64-byte HID report, ID `0x01`); IF1: relative HID mouse | +| **DualSense input (BT or wired USB host)** | **`SteamPassthrough`** — full **64-byte** report copied each frame (ControllerMedic-style PS5 passthrough); wired host sticks/triggers taken from raw PS5 IN when available | +| **Other input (Xbox, DS4, Switch Pro, etc.)** | **`SteamBtReport`** — synthesizes a DualSense **`PS5::InReport`** from PadIn / `uni_gamepad_t` (face → Cross/Circle/Square/Triangle, LB/RB → L1/R1, triggers, sticks, D-pad, Share/Options, PS, touchpad-click bit) | +| **Descriptors** | `Descriptors/PS5Usb.h` (gamepad), `Descriptors/Steam.h` (composite + mouse interface) | + +### Touchpad → mouse + +| Item | Detail | +|------|--------| +| **Input** | **DualSense (PS5)** — Bluetooth on Pico W / Pico 2 W (`uni_hid_parser_ds5_get_touchpad()`), or wired USB host (`PS5Host::process_report()` → `SteamPassthrough::store()`) | +| **Output** | **`SteamTouchpad`** — touch finger deltas → **relative mouse** on IF1; touchpad click (`TP` / `MISC`) → **left button** | +| **Report merge (BT)** | Raw touch bytes merged into USB report offset **33** (`SteamTouchpad::apply_to_passthrough()`) for Linux `hid-playstation` compatibility | +| **No touchpad** | Mouse interface stays idle — no right-stick mouse fallback | + +### How it works (code path) + +1. **`SteamDevice::process()`** — Builds the outgoing DualSense USB report (passthrough or synthesized), then sends mouse HID **only** when the input pad has a touchpad. +2. **Bluetooth** — `SteamBtReport::update_from_uni_gamepad()` + touchpad parser; `Bluepad32.cpp` sets `SteamPassthrough::input_has_touchpad` for DS5. +3. **Wired USB host** — `PS5Host::process_report()` stores the raw report when output driver is **STEAM**. +4. **Non-PS5 input** — `SteamBtReport::update_from_gamepad()` / `fill_report_from_pad()` maps any supported PadIn into DualSense layout. + +After changing to STEAM mode, **replug** the adapter USB cable on the PC so the composite device (gamepad + mouse) enumerates cleanly. + +**Verify on Linux:** + +```bash +lsusb -v -d 054c:0ce6 2>/dev/null | grep -E "iProduct|bNumInterfaces|bEndpointAddress" +sudo evtest # select the mouse interface; drag touchpad for REL_X / REL_Y +``` + +**Files:** `src/USBDevice/DeviceDriver/Steam/` (`Steam.cpp`, `SteamPassthrough.h`, `SteamBtReport.h`, `SteamTouchpad.cpp`), `src/Descriptors/PS5Usb.h`, `src/Descriptors/Steam.h`, `src/Bluepad32/Bluepad32.cpp`, `src/USBHost/HostDriver/PS5/PS5.cpp`, `WebApp/modules/userSettings.js` (mode label **SteamOS / Bazzite**). + +--- + +## PS3 / PS4 output — motion passthrough + +**Goal:** In **PS3** and **PS4 (DualShock 4 USB)** output modes, pass **accelerometer** (and **gyro** when available) from modern input controllers into the emulated report so titles that use tilt / gyro respond correctly. **Switch** output mode does **not** pass through motion for now (Pro report IMU bytes stay zero). + +**Important — console wiring (PS3/PS4):** OGX-Mini is a **USB gadget** (it emulates a controller to a **host**). It does **not** replace a Brook-style dongle on its own. To play **motion games on a real PlayStation 3 or PlayStation 4**, chain: + +```text +[Your input pad] → (BT or USB host on OGX-Mini) → OGX-Mini → USB → [USB adapter] → PS3 or PS4 +``` + +**Tested adapter:** **[Brook Wingman XE 2 Converter](https://www.brookaccessories.com/products/wingman-xe2)** — validated for **PS3** Sixaxis titles with OGX-Mini in **PS3 output mode**. The same Brook adapter also works on **PS4**: set OGX-Mini to **PS4 output mode** (**Start + Left Bumper + D-pad Left**), plug OGX-Mini into the Brook, and connect the Brook to the **PS4** USB port. + +| Item | Detail | +|------|--------| +| **Output modes** | **PS3** (Start + D-pad Left) — Sixaxis in the DS3 report; **PS4** (Start + LB + D-pad Left) — Brook-style accel/gyro in the DS4 report | +| **Input — Bluetooth (Pico W / Pico 2 W)** | **DualShock 4**, **DualSense**, **Switch Pro**, **Wii Remote** (accel only; **0x31** report requested when motion output is active) | +| **Input — wired USB host** | **DualShock 4**, **DualSense**, **Switch 1 Pro**, **Switch 2 Pro** (IMU parsed from full HID payload) | +| **Wii Remote hold** | Point **IR end toward the TV**; roll/pitch tuned for that orientation | +| **Wii Motion Plus gyro** | Not yet parsed from extension reports — accel only from Wii Remote | +| **PC / emulator testing** | Motion is also present when OGX-Mini is in PS3/PS4 mode on a **PC** (no Brook required) | + +### How it works + +1. **`Gamepad::PadIn`** — `accel[3]`, `gyro[3]`, and `motion_source` tag the active IMU (`MOTION_SRC_DS4`, `DS5`, `SWITCH_PRO`, `SWITCH_USB`, `DS4_USB`, `DS5_USB`, `WII_BT`, etc.). +2. **`MotionImu.h`** — Unit conversion for USB Switch/DS4/DS5 payloads; **`remap_to_ds4_playing_frame()`** rotates Switch Pro and Wii BT samples into the DS4/Sixaxis playing frame (+Z ≈ 1 G when level). +3. **`PS3.cpp`** — `apply_pad_imu_to_ps3_sixaxis()` encodes accel into Linux **hid-sony** Sixaxis layout (X @ 41–42, Y/Z swapped per kernel); **Wii** uses a dedicated pitch/gravity wire assignment. +4. **`PS4.cpp`** — Brook-style accel/gyro scaling into the 64-byte DS4 gadget report when `has_motion()`. +5. **`MotionOutputActive`** — PS3/PS4 drivers set a flag so Bluepad32 can request Wii accel reports without `WII_MODE_ACCEL` (that mode breaks button layouts). +6. **`Bluepad32.cpp`** — Maps DS4/DS5/Switch/Wii motion from Bluepad reports; on connect requests **continuous** Wii **0x31** (DRM_KA) or **0x35** (DRM_KAE with Nunchuk) when motion output is active. Nunchuk stick → **left stick**. `uni_hid_parser_wii.c` implements **DRM_KAE** parsing. + +**Files:** `src/Gamepad/MotionImu.h`, `src/Gamepad/Gamepad.h`, `src/USBDevice/DeviceDriver/PS3/PS3.cpp`, `src/USBDevice/DeviceDriver/PS4/PS4.cpp`, `src/USBDevice/DeviceDriver/MotionOutputActive.h`, `src/USBDevice/DeviceManager.cpp`, `src/Bluepad32/Bluepad32.cpp`, `src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp`, `src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp`, `src/USBHost/HostDriver/PS4/PS4.cpp`, `src/USBHost/HostDriver/PS5/PS5.cpp`. + +**User docs:** [README — Motion controls](../../../README.md#ps3--ps4-motion-controls). + +**Button mappings (all modes):** [Controller_Mappings.md](Controller_Mappings.md) + +--- + +## Steam Controller 2026 (Triton) — Bluetooth + +**Goal:** Pair the **Steam Controller 2026** (Valve “Triton”) over **Bluetooth LE** to **Pico W**, **Pico 2 W**, and **RP2354** (Pi Radio Module 2) adapters and use it as a normal gamepad input in any USB or GPIO output mode. + +| Variant | VID:PID | Role | +|---------|---------|------| +| Body USB | `28de:1302` | Wired USB (host stack — not this feature) | +| Body BLE | `28de:1303` | **Wireless input target** | +| Puck dongle | `28de:1304` | Valve RF puck (PID registered) | +| Nereid | `28de:1305` | Related PID (registered) | + +**Advertisement / services (validated on Linux):** Appearance **`0x03c4`** (gamepad), HID UUID **`00001812`**, Valve vendor service **`100f6c32-…`**, Modalias **`usb:v28DEp1303`**. Address type is typically **random**. + +Unlike the original Steam Controller (custom GATT only), Triton also exposes **standard HID-over-GATT**. Main input report ID **`0x45`** (`TritonMTUNoQuat_t`: buttons, hall triggers, dual sticks, trackpads). Feature report **ID 1** + message **`0x87`** disables **lizard mode** (desktop mouse/keyboard), refreshed about every **3 s**. Rumble uses output report **`0x80`** (`MsgHapticRumble`) with a **~40 ms** resend while active. + +### Pairing (user) + +1. **Remove** the controller from any PC/phone Bluetooth list and make sure it is **disconnected** (BLE is one host at a time). +2. Put OGX-Mini in pairing mode (LED blinking). +3. On the controller, hold **RB + B + Steam** until it advertises. +4. Wait for connection rumble / solid LED. **Do not** pair the pad in Windows/macOS/phone Bluetooth settings for OGX use. + +### Changes + +1. **Bluepad32 parser** — `uni_hid_parser_steam_triton.c` / `.h`: decode **`0x45`** / **`0x42`** / **`0x47`** state reports, battery **`0x43`**, lizard-off + rumble, teardown of timers on disconnect. +2. **Controller type** — `k_eControllerType_SteamControllerTriton` (**61**); PIDs **`0x1302`–`0x1305`** in `uni_controller_list.h`. +3. **LE Secure Connections** — Triton rejects legacy SMP with **`AUTH_REQUIREMENTS_MISMATCH`**. Enabled **`ENABLE_LE_SECURE_CONNECTIONS`** in `Firmware/RP2040/src/btstack_config.h`. Non–Xbox / non–Switch-2 BLE pads pair with **`SM_AUTHREQ_SECURE_CONNECTION | SM_AUTHREQ_BONDING`** (`uni_bt_le.c`); one Just-Works retry if AuthReq still mismatches. +4. **Connection interval** — On setup, request **6–9 × 1.25 ms (~7.5–11 ms)** like Xbox BLE (default intervals feel very laggy). +5. **Button map** — Face / LB/RB / L3/R3 / d-pad / triggers as normal. Triton **View → Start**, **Menu → Back/Select** (matches SDL; printed names are not Xbox View/Menu). **Steam** (and QAM) → **Guide / SYS**. Grip paddles L4/L5/R4/R5 left unmapped. +6. **OGX path** — Rumble routed in `Bluepad32.cpp`; stall-watchdog exemption so idle HID does not force-disconnect. + +**References:** [SDL3 `SDL_hidapi_steam_triton.c`](https://github.com/libsdl-org/SDL/blob/main/src/joystick/hidapi/SDL_hidapi_steam_triton.c), [`controller_structs.h`](https://github.com/libsdl-org/SDL/blob/main/src/joystick/hidapi/steam/controller_structs.h). + +**Files:** `uni_hid_parser_steam_triton.c` / `.h`, `btstack_config.h`, `uni_bt_le.c`, `uni_controller_type.h`, `uni_controller_list.h`, `uni_hid_device.c`, `uni_gamepad.c`, `Bluepad32.cpp`. --- @@ -161,9 +395,10 @@ Applies to Nintendo VID **0x057E** PIDs **0x2066**, **0x2067**, **0x2069**, **0x 1. **Host OUT report layout** — **`init_host_out_report()`** builds the **USB Host Shield `PS3_REPORT_BUFFER`** layout (player LED bitmap **`0x02 << player`**, per-LED timing fields) instead of copying gadget **`DEFAULT_OUT_REPORT`**. 2. **Synchronous wired init** — On plug-in: **SET feature 0xF4** `{0x42, 0x0c, 0x00, 0x00}` then **synchronous OUT** (rumble/LED report) via **`send_control_xfer_wait()`**, polling **`pio_usb_host_frame()` + `tuh_task()`** up to **150 ms** per step. -3. **Immediate input** — Wired path sets **`reports_enabled`** and **`InitStage::DONE`** after enable + LED OUT; **`tuh_hid_receive_report()`** starts without waiting on the old multi-stage **GET feature 0xF2** chain (that chain remains for **Bluetooth auto-pair** on `CONFIG_EN_BLUETOOTH` builds only). -4. **PIO keepalive** — **`KEEPALIVE_MS = 1000`** on USB host sends periodic neutral OUT so the DS3 stays connected when idle; **`HostManager`** includes PS3 in periodic **`send_feedback()`**. -5. **Async OUT for rumble** — Runtime rumble/keepalive uses non-blocking **`send_control_output_async()`** so feedback does not stall IN. +3. **Immediate input** — Wired path sets **`reports_enabled`** after enable + LED OUT (and BT **0xF5** when applicable); **`tuh_hid_receive_report()`** starts without the old multi-stage **GET feature 0xF2** chain. +4. **Bluetooth auto-pair (BT boards)** — After **0xF4** + LED, **`program_ds3_bt_host()`** sync-sends **feature 0xF5** with the adapter BD_ADDR (see section below). +5. **PIO keepalive** — **`KEEPALIVE_MS = 1000`** on USB host sends periodic neutral OUT so the DS3 stays connected when idle; **`HostManager`** includes PS3 in periodic **`send_feedback()`**. +6. **Async OUT for rumble** — Runtime rumble/keepalive uses non-blocking **`send_control_output_async()`** so feedback does not stall IN. **File:** `src/USBHost/HostDriver/PS3/PS3.cpp`, `PS3.h`. @@ -319,6 +554,9 @@ Descriptors and XSM3 flow are aligned with [joypad-os](https://github.com/joypad **Fix:** Ignore large-motor values **below a small threshold** (deadzone), and treat the **small motor as on only when the host byte is `1`** (not “any non-zero”). **File:** `PS3.cpp` — block that runs when `new_report_out_` is set after `set_report_cb` parses the DS3 output report. +8. **Sixaxis / motion passthrough** *(v1.0.0.12a)* + When the input gamepad provides IMU data (`has_motion()`), accel/gyro are encoded into the DS3 Sixaxis fields using Linux **hid-sony** wire layout. See [§ PS3 / PS4 output — motion passthrough](#ps3--ps4-output--motion-passthrough) for supported input pads, Wii Remote notes, and **Brook Wingman XE 2** console wiring. + --- ## Latency reduction @@ -423,7 +661,7 @@ Three additional boards use the same Standard (PIO-USB host) code path as PI_PIC |-------|--------------|--------| | Waveshare RP2350-Zero | `OGXM_BOARD=RP2350_ZERO` | PIO USB D+ = GP10, RGB = GP16; RP2350. | | Seeed Studio XIAO RP2040 | `OGXM_BOARD=RP2040_XIAO` | PIO USB D+ = GP0, RGB = GP12, LED = GP17. | -| RP2354 | `OGXM_BOARD=RP2354` | PIO USB D+ = GP0, LED = GP25; RP2350. | +| RP2354 | `OGXM_BOARD=RP2354` | **RP2350 + Pi Radio Module 2** (CYW43439, same class as **Pico 2 W**): **Bluetooth** wireless pads + PIO USB host on **GP0/GP1**, LED **GP25**. | **Files:** `src/Board/Config.h` (board IDs and pin defines), `src/OGXMini/OGXMini.cpp` (init/run/host_mounted tables), `src/OGXMini/Board/Standard.cpp` (extended `#if`), `CMakeLists.txt` (board branches). @@ -469,7 +707,9 @@ After debounced confirmation, **`pico_w_usb_host_full_stop()`** runs **`tuh_dein **Background:** The **DualShock 3** does not implement standard Bluetooth pairing. The host’s **BD_ADDR** must be written to the pad over **USB** using a **HID feature report** (report ID **`0xF5`**, 8 bytes: id + padding + 6-byte MAC). This is what the [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/) utility does from a PC. -**Behavior in this firmware:** On builds with **`CONFIG_EN_BLUETOOTH`** (e.g. **Pico W / Pico 2 W**, ESP32 hybrids with Bluepad32), after the existing **PS3 USB init** (`GET_REPORT` **0xF2** sequence) completes, **`PS3Host`** sends **`SET_REPORT`** **feature 0xF5** with **`uni_bt_get_local_bd_addr_safe()`**, then continues with the usual rumble **OUT** report. If the local address is still **all zeros** (Bluetooth stack not finished starting), the code sets a **deferred** flag and **`try_deferred_ds3_bt_pair()`** runs at the start of **`process_report()`** until the address is valid, then sends **0xF5** once. +**Behavior in this firmware:** On builds with **`CONFIG_EN_BLUETOOTH`** (e.g. **Pico W / Pico 2 W / RP2354**), after sync wired init (**feature 0xF4** + LED OUT), **`PS3Host::program_ds3_bt_host()`** sends **`SET_REPORT`** **feature 0xF5** with **`uni_bt_get_local_bd_addr_safe()`** using the same **synchronous control path** as **0xF4** (so PIO USB host frames complete the transfer). If the local address is still **all zeros**, a **deferred** flag is set and **`try_deferred_ds3_bt_pair()`** retries from **`process_report()`** until the address is valid, then sends **0xF5** once. + +**Regression note:** An earlier PIO USB wired-init change marked init complete before the old async **GET 0xF2 → SET 0xF5** chain ran, so **`0xF5` was never sent**. Pairing no longer depends on that F2 chain. **User steps:** Plug the **DS3 into the adapter’s USB host port** (wait for it to work wired if you like), then **unplug** and press **PS** to use it wirelessly — same as the manual pairing flow documented for Bluepad32. @@ -616,15 +856,19 @@ OGX-Mini’s existing **wired Xbox One GIP** path (`tuh_xinput`, subclass `0x47` | Area | Improvement | |------|-------------| -| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). **360 wireless PC receiver** supported (`Xbox360WHost`). **v1.0.0.11a:** PIO USB wired receiver — **4 XInput instances** when `MAX_GAMEPADS=1`, port **priming**, **0x80** connect detect, byte-offset decode. **Razer Atrox XBO** (`1532:0a00`) — vendor GIP arcade path via **XBOFS** init + **30-byte** IN + XBOFS input layout; **POWER_ON** once only. **Xbox One/Series wireless dongle (`045e:02e6` / `02fe`)** — see [Future planned](#future-planned). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. | -| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **v1.0.0.9a:** PC host rumble deadzone + strict small-motor `0`/`1`. **v1.0.0.11a:** **DualShock 3 wired USB host** — USB Host Shield init, sync control xfer + PIO service, **1 Hz keepalive**. | +| **XInput (360)** | XSM3 authentication and descriptors aligned with joypad-os; adapter works on Xbox 360 with BT controllers (PS5, Xbox One). **360 wireless PC receiver** supported (`Xbox360WHost`). **v1.0.0.11a:** PIO USB wired receiver — **4 XInput instances** when `MAX_GAMEPADS=1`, port **priming**, **0x80** connect detect, byte-offset decode. **Razer Atrox XBO** (`1532:0a00`) — vendor GIP arcade path via **XBOFS** init + **30-byte** IN + XBOFS input layout; **POWER_ON** once only. **Xbox One/Series wireless dongle (`045e:02e6` / `02fe`)** — see [Future planned](#future-planned). 8BitDo wired fix: LED keepalive for VID 0x2DC8 / PID 0x3016 or 0x3106. **v1.0.0.12a (#38):** default (non–WebApp-customized) sticks use **stock 360-like** feel — see [§ XInput stock stick feel](#xinput--xbox-360--stock-stick-feel). | +| **PS3** | Stuck inputs and delays addressed via L2/R2 axes; DS3-accurate sticks (0–255, center 0x80, ~1.5% deadzone); D-pad and face button mapping; Home (PS) button with 8-frame latch for BT controllers. **v1.0.0.9a:** PC host rumble deadzone + strict small-motor `0`/`1`. **v1.0.0.11a:** **DualShock 3 wired USB host** — USB Host Shield init, sync control xfer + PIO service, **1 Hz keepalive**. **v1.0.0.12a:** motion passthrough (see Motion row); **DS3 USB→BT auto-pair** sync **0xF5** restored on BT boards. | | **PS2 (GPIO)** | Home only = IGR (L1+L2+R1+R2+Start+Select); Home+Start = shutdown (L1+L2+R1+R2+L3+R3). OPL and protocol stability (first response byte = mode byte). | | **OG Xbox** | Guide only = IGR. Shutdown = LT+RT+Back+White via **Guide+Start** or **Guide+View (Back)**; Xbox BT often omits Start while Guide is held. Shutdown report strips Start so the chord matches BIOS/softmod expectations. | -| **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. **v1.0.0.11a:** **Switch 1/2 Pro wired** on PIO USB host — Chromium **0x80** init, bulk bring-up, mapping fixes. See [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | -| **Switch 2** | **Pro 2** (wired **0x2069**): **Switch2ProHost** + bulk bring-up (v1.0.0.11a). **Pro 2 + Joy-Con 2 L/R** (BLE): **uni_hid_parser_switch2** — GATT pairing, 63-byte input, rumble keepalive, Home → SYS latch, **L+R pair merge**, **dual-half latency fixes**. See [§ Nintendo Switch 2 — Bluetooth](#nintendo-switch-2--bluetooth-pico-w--pico-2-w) and [§ Joy-Con pair latency](#joy-con-pair-merge--latency-when-both-halves-are-active). | -| **Boards** | RP2350_ZERO, RP2040_XIAO, RP2354 supported (Standard/PIO-USB host path). **RP2350-USB-A (Waveshare):** v1.0.0.11a validation for **Switch Pro, DualShock 3, 360 wireless receiver**, and **Razer Atrox XBO** wired host. | +| **Switch Pro** | Analog stick sensitivity gain (default 1.2×) for more responsive sticks; configurable in `Switch.cpp`. **v1.0.0.11a:** **Switch 1/2 Pro wired** on PIO USB host — Chromium **0x80** init, bulk bring-up, mapping fixes. **v1.0.0.12a:** **HD rumble** from console → `PadOut` for BT/USB input pads. See [§ Switch HD rumble](#switch-mode--hd-rumble-passthrough) and [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | +| **Switch 2** | **Pro 2** (wired **0x2069**): **Switch2ProHost** + bulk bring-up (v1.0.0.11a). **Pro 2 + Joy-Con 2 L/R** (BLE): **uni_hid_parser_switch2** — GATT pairing, 63-byte input, rumble keepalive, Home → SYS latch, **L+R pair merge**, **dual-half latency fixes**. **v1.0.0.12a (#64):** anti-deadzone idle gate + L3/R3 / wired disconnect keepalives. See [§ Nintendo Switch 2 — Bluetooth](#nintendo-switch-2--bluetooth-pico-w--pico-2-w), [§ Joy-Con pair latency](#joy-con-pair-merge--latency-when-both-halves-are-active), [§ anti-deadzone](#switch-2-pro--anti-deadzone-and-l3r3). | +| **Steam Controller 2026** | **Triton BLE** (`28de:1303`) on Pico W / Pico 2 W / RP2354 — HOGP parser, **LE Secure Connections**, lizard-off, rumble, **~7.5–11 ms** conn interval, View→Start / Menu→Back. See [§ Steam Controller 2026](#steam-controller-2026-triton--bluetooth). | +| **Boards** | RP2350_ZERO, RP2040_XIAO supported (Standard/PIO-USB host). **RP2354:** RP2350 + **Pi Radio Module 2** — **Bluetooth** + PIO USB host (Pico 2 W firmware path). **RP2350-USB-A (Waveshare):** v1.0.0.11a validation for **Switch Pro, DualShock 3, 360 wireless receiver**, and **Razer Atrox XBO** wired host. | | **Latency** | Main loop delay default **0 µs**; `tud_task()` before `process()` so reports send every loop when ready; XInput/Switch/PS3 send latest state when USB ready (no `new_pad_in()` gate). Switch Pro and PS3 always build report every loop so host poll (`get_report`) and IN push both see current state — only remaining delay is BT radio when wireless. | -| **Build** | Interactive scripts `scripts/build.sh` (Linux/macOS) and `scripts/build.ps1` (Windows) for board selection, fixed/default mode, and Release/Debug; output in `scripts/build/`. See [README](../../../README.md) Build section. | -| **Bluetooth (Pico W)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s; stale-slot delete on reconnect. **Switch 2 (BLE):** Pro 2 + Joy-Con 2 L/R — custom GATT parser, rumble keepalive, Home latch, **L+R merge**, **dual-half latency fixes**. **Switch 1 Joy-Con (Classic BT):** L+R merge, IMU off when paired, same latency path as SW2. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in (**2-slot** staging for Joy-Con pairs); re-enable scan on last disconnect. **v1.0.0.9a:** ~**1 s connection rumble** at `device_ready` (DS4 delayed start). | +| **STEAM (SteamOS / Bazzite)** | **Start + LB + D-pad Up** (~3 s), web app, or **`-DOGXM_FIXED_DRIVER=STEAM`**. USB **DualSense** (`054c:0ce6`) + **HID mouse**. **DualSense input:** passthrough report + **touchpad → mouse** (BT or wired USB host). **Other pads:** synthesized DualSense report; **no stick-mouse fallback**. See [§ STEAM mode](#steam-mode--steamos--bazzite-linux-desktop). | +| **Motion (PS3/PS4 out)** | **v1.0.0.12a:** Accel/gyro passthrough into emulated DS3/DS4 from DS4/DS5/Switch Pro/SW2/Wii Remote. Console use needs **Brook Wingman XE 2** (or similar). See [§ motion passthrough](#ps3--ps4-output--motion-passthrough). | +| **Build** | Interactive scripts `scripts/build.sh` (Linux/macOS) and `scripts/build.ps1` (Windows) for board selection, fixed/default mode (**STEAM**, PS4, Wii, etc.), and Release/Debug; output in `scripts/build/`. See [README](../../../README.md) Build section. | +| **Bluetooth (Pico W / 2 W / RP2354)** | **DS4 / Classic ACL:** BLE advertising **paused** while Classic pad connected; **BR inquiry stopped** during ACL; **no DS4 virtual mouse**; **6 s PS4 rumble** grace. **Xbox Series (BLE):** no stall disconnect when idle; keepalive 12 s. **v1.0.0.12a:** after last **ready** pad disconnects, restore pairing mode then **watchdog reboot** (~500 ms); **USB resume** + **45 s** idle scan watchdog restore pairing without reboot; **LE Secure Connections** for pads that require it (e.g. Triton); **Steam Controller 2026** HOGP parser. **Switch 2 (BLE):** Pro 2 + Joy-Con 2 L/R — custom GATT parser, rumble keepalive, Home latch, **L+R merge**, **dual-half latency fixes**. **Switch 1 Joy-Con (Classic BT):** L+R merge, IMU off when paired. **General:** `sleep_ms(1)` main loop; lock-free BT pad-in (**2-slot** staging for Joy-Con pairs). **v1.0.0.9a:** ~**1 s connection rumble** at `device_ready` (DS4 delayed start). | | **PIO USB host (Pico W)** | **Wired unplug:** Debounced combo of **HCD connect**, **`tuh_mounted` over all device addresses**, and **no `process_report` / setup activity** (~**3 s**) so disconnect registers when D+/D− line state is wrong under PIO; **`tuh_deinit`** + restore GPIO line IRQs + BT release. **v1.0.0.11a (all PIO host boards):** **`pio_usb_host_frame()`** after feedback OUT; wired **Switch Pro / PS3 / 360 receiver / Razer Atrox XBO** connection fixes — see [§ PIO USB host — wired connection fixes](#pio-usb-host--wired-connection-fixes-waveshare-rp2350-usb-a). | -| **DS3 + Bluetooth** | **USB auto-pair:** After PS3 wired init, **feature `0xF5`** programs the **DS3** with the adapter’s **BD_ADDR** (`CONFIG_EN_BLUETOOTH`); deferred if BT address not ready. See [§ DualShock 3 — automatic USB programming for Bluetooth pairing](#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). | +| **DS3 + Bluetooth** | **USB auto-pair:** After sync **0xF4** + LED, **feature `0xF5`** programs the **DS3** with the adapter’s **BD_ADDR** (`CONFIG_EN_BLUETOOTH`); deferred if BT address not ready. **v1.0.0.12a:** restored after PIO USB wired-init regression (sync SET, no F2 chain). See [§ DualShock 3 — automatic USB programming for Bluetooth pairing](#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). | +| **Multi-adapter (same console)** | **Known limitation:** Two OGX-Mini units plugged into the **same** console usually collide — identical **VID/PID**, shared USB serial (e.g. XInput `"1.0"`), and on **Xbox 360** the same **XSM3 ID**. Workarounds without firmware changes: **one OGX + one native/other-brand pad**, or a **single multi-port** host (e.g. 360 wireless receiver). Unique per-unit identity is not implemented yet. | diff --git a/Firmware/RP2040/docs/README.md b/Firmware/RP2040/docs/README.md index c7a16c48..11fb0803 100644 --- a/Firmware/RP2040/docs/README.md +++ b/Firmware/RP2040/docs/README.md @@ -6,8 +6,9 @@ See the [project README](../../README.md) for overview, supported platforms, bui | Document | Description | |----------|-------------| +| [**Controller_Mappings.md**](Controller_Mappings.md) | **Master reference:** PadIn layout, input → PadIn (BT/USB), and PadIn → every output mode (XInput, PS3, PS4, Switch, STEAM, OG Xbox, Wii U, GPIO, Wii output). | | [Wii_Mode_Guide.md](Wii_Mode_Guide.md) | Wii mode (build-option only): No Extension / Nunchuk / Classic, USB host, sync and auto-connect, button mapping, supported controllers. | | [PICO2W_WII_USB_SETUP.md](PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | | [GPIO_Output_Pinout_and_Mappings.md](GPIO_Output_Pinout_and_Mappings.md) | GPIO pin-outs and default button/stick mappings for PS1/PS2, Dreamcast, GameCube, and N64 output (and input) modes. | | [Dreamcast_Port.md](Dreamcast_Port.md) | Dreamcast (Maple Bus) port status and notes for completing the port from DreamPicoPort (stub only in firmware for now). | -| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements and **Future planned** (e.g. Xbox One/Series wireless dongle `045e:02e6` / `02fe`); PS3 fixes, latency, XInput/360, Pico W Bluetooth, Switch 2 / Joy-Con merge, PIO USB unplug detection. | +| [IMPROVEMENTS.md](IMPROVEMENTS.md) | Firmware improvements and **Future planned** (e.g. Xbox One/Series wireless dongle `045e:02e6` / `02fe`); **STEAM mode**, **PS3/PS4 motion**, **XInput stock stick feel (#38)**, **Switch HD rumble**, **Switch 2 anti-dz (#64)**, Pico W Bluetooth, Switch 2 / Joy-Con merge, **Steam Controller 2026 (Triton) BLE**, USB resume pairing, PIO USB unplug detection. | diff --git a/Firmware/RP2040/docs/Wii_Mode_Guide.md b/Firmware/RP2040/docs/Wii_Mode_Guide.md index 87f0de09..3514ceee 100644 --- a/Firmware/RP2040/docs/Wii_Mode_Guide.md +++ b/Firmware/RP2040/docs/Wii_Mode_Guide.md @@ -61,6 +61,8 @@ The adapter can emulate three Wiimote “shapes” that many games support. You Mappings assume an **Xbox-style** USB gamepad (A/B/X/Y, Start, Back, Guide, D-pad, bumpers, triggers, two sticks). Other USB pads are mapped to the same logical layout by the host driver. +For the **full mapping reference** (all output modes, Bluetooth inputs including **Wii Remote vertical**, Switch Pro swaps, PS3/PS4, etc.), see **[Controller_Mappings.md](Controller_Mappings.md)**. + ### No Extension (Wiimote only) | Wiimote | USB gamepad | diff --git a/Firmware/RP2040/docs/Wired_Controllers.md b/Firmware/RP2040/docs/Wired_Controllers.md index fef89367..91a924ae 100644 --- a/Firmware/RP2040/docs/Wired_Controllers.md +++ b/Firmware/RP2040/docs/Wired_Controllers.md @@ -34,7 +34,9 @@ This document lists controllers supported when connected to the OGX-Mini adapter *See `PS3_IDS` in `HardwareIDs.h` for the full VID/PID list.* -**DualShock 3 over USB cable (PIO USB host):** v1.0.0.11a sends **SET feature 0xF4** and a **player LED OUT** report at connect (USB Host Shield sequence) with **`pio_usb_host_frame()`** during init, plus a **1 Hz keepalive OUT** so the pad stays connected. On **Pico W / Pico 2 W**, Bluetooth **auto-pair** (feature **0xF5**) still runs after wired init when enabled. See [IMPROVEMENTS.md — DualShock 3 wired USB host](IMPROVEMENTS.md#dualshock-3--wired-usb-host). +**Button mappings (all modes):** [Controller_Mappings.md](Controller_Mappings.md) + +**DualShock 3 over USB cable (PIO USB host):** v1.0.0.11a sends **SET feature 0xF4** and a **player LED OUT** report at connect (USB Host Shield sequence) with **`pio_usb_host_frame()`** during init, plus a **1 Hz keepalive OUT** so the pad stays connected. On **Pico W / Pico 2 W / RP2354** BT builds, **v1.0.0.12a** sync-sends Bluetooth **auto-pair** (feature **0xF5** with the adapter BD_ADDR) right after that wired init (deferred if the radio address is not ready yet). See [IMPROVEMENTS.md — DualShock 3 wired USB host](IMPROVEMENTS.md#dualshock-3--wired-usb-host) and [automatic USB programming for Bluetooth pairing](IMPROVEMENTS.md#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). --- @@ -115,7 +117,7 @@ Controllers that use the standard HID gamepad (DInput) protocol, including: - **PowerA, PDP, Afterglow:** Various Xbox/PC controllers in HID mode - **GameSir:** G3, G4, T3, T4, G7 Pro, etc. - **Razer:** Kishi, Hydra, Serval, Raiju (PC/HID) -- **Steam:** Steam Controller, Steam Deck (when presenting as gamepad) +- **Steam:** Steam Controller, Steam Deck (when presenting as gamepad). **Steam Controller 2026** body USB is **`28de:1302`** (generic HID if supported by the host stack). **Wireless BLE** (`28de:1303`) on Pico W / Pico 2 W / RP2354 is documented in [IMPROVEMENTS — Steam Controller 2026](IMPROVEMENTS.md#steam-controller-2026-triton--bluetooth). - **Sony:** DualShock 2 (via USB adapter), Steam Virtual Gamepad - **Flydigi:** Vader 4 Pro (DInput mode) - **Scuf:** Envision (Linux/HID) @@ -137,3 +139,4 @@ Controllers that use the standard HID gamepad (DInput) protocol, including: - **VID/PID lists:** `Firmware/RP2040/src/USBHost/HardwareIDs.h` - **Host drivers:** `Firmware/RP2040/src/USBHost/HostDriver/` - **Platform selection:** See the main [README](../../../README.md) for button combos to change output platform. +- **SteamOS / Bazzite (STEAM output):** USB presents **DualSense** (`054c:0ce6`) + **HID mouse**. **DualSense** input (wired or BT): passthrough gamepad + **touchpad → cursor**; other pads get synthesized DualSense mapping (gamepad only — no stick mouse). **Start + LB + D-pad Up** selects mode. See [README — SteamOS / Bazzite](../../../README.md#steamos--bazzite-output-mode), [IMPROVEMENTS — STEAM mode](IMPROVEMENTS.md#steam-mode--steamos--bazzite-linux-desktop), and [Controller_Mappings — STEAM](Controller_Mappings.md#steamos--bazzite-steam-mode). diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index 423f82a4..500e20f6 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -25,6 +25,15 @@ static std::atomic s_bt_any_connected_cached{false}; #include "Bluepad32/Bluepad32.h" #include "Board/board_api.h" #include "Board/ogxm_log.h" +#include "parser/uni_hid_parser_ds5.h" +#include "controller/uni_controller.h" +#include "parser/uni_hid_parser_wii.h" +#include "Gamepad/MotionImu.h" +#include "USBDevice/DeviceDriver/MotionOutputActive.h" +#include "USBDevice/DeviceDriver/Steam/SteamActive.h" +#include "USBDevice/DeviceDriver/Steam/SteamBtReport.h" +#include "USBDevice/DeviceDriver/Steam/SteamPassthrough.h" +#include "USBDevice/DeviceDriver/Steam/SteamTouchpad.h" #ifndef CONFIG_BLUEPAD32_PLATFORM_CUSTOM #error "Pico W must use BLUEPAD32_PLATFORM_CUSTOM" @@ -80,6 +89,8 @@ static void bp32_disconnect_controller_and_joycon_partner(uni_hid_device_t* d) { static constexpr uint32_t FEEDBACK_TIME_MS = 250; static constexpr uint32_t LED_CHECK_TIME_MS = 500; +/** Idle pairing health check — restarts BR/LE scan if they died during long USB suspend (e.g. 360 standby). */ +static constexpr uint32_t PAIRING_WATCHDOG_MS = 45000; /** If no HID input report reaches us for this long while "connected", the BT link is zombie * (L2CAP stops delivering; OG Xbox then holds last USB report). Force disconnect so user can reconnect. */ static constexpr uint32_t BT_INPUT_STALL_DISCONNECT_MS = 8000; @@ -191,6 +202,22 @@ bool any_wii_controller_connected() return false; } +/** TV-style Wiimote (not Wii U Pro, Classic, or Balance Board). */ +static bool ogxm_is_handheld_wiimote(const uni_hid_device_t* device) +{ + if (device == nullptr || device->controller_type != CONTROLLER_TYPE_WiiController) { + return false; + } + switch (device->controller_subtype) { + case CONTROLLER_SUBTYPE_WIIUPRO: + case CONTROLLER_SUBTYPE_WII_CLASSIC: + case CONTROLLER_SUBTYPE_WII_BALANCE_BOARD: + return false; + default: + return true; + } +} + //This solves a function pointer/crash issue with bluepad32 void set_rumble(uni_hid_device_t* bp_device, uint16_t length, uint8_t rumble_l, uint8_t rumble_r) { @@ -230,6 +257,9 @@ void set_rumble(uni_hid_device_t* bp_device, uint16_t length, uint8_t rumble_l, case CONTROLLER_TYPE_Switch2JoyConLeft: uni_hid_parser_switch2_play_dual_rumble(bp_device, 0, length, rumble_l, rumble_r); break; + case CONTROLLER_TYPE_SteamControllerTriton: + uni_hid_parser_steam_triton_play_dual_rumble(bp_device, 0, length, rumble_l, rumble_r); + break; default: break; } @@ -250,7 +280,8 @@ static void send_feedback_cb(btstack_timer_source *ts) /* BLE Xbox (Series) and Switch 2 BLE may not send reports every poll interval. */ const bool skip_stall_disconnect = (bp_device->controller_type == CONTROLLER_TYPE_XBoxOneController && bp_device->hids_cid != 0) || - uni_hid_parser_switch2_is_ble_device(bp_device); + uni_hid_parser_switch2_is_ble_device(bp_device) || + uni_hid_parser_steam_triton_is_device(bp_device); /* Virtual slot (e.g. DS4's BT "mouse"): never gets gamepad HID → would always stall-disconnect * and drop the real controller. */ if (uni_hid_device_is_virtual_device(bp_device)) @@ -418,11 +449,117 @@ static void maybe_restart_bredr_inquiry_after_disconnect(int disconnected_idx) { continue; if (gap_get_connection_type(d->conn.handle) == GAP_CONNECTION_ACL) return; + /* Xbox Series BLE also stops BR inquiry (same radio contention). */ + if (d->controller_type == CONTROLLER_TYPE_XBoxOneController && d->hids_cid != 0) + return; } uni_bt_bredr_scan_start(); #endif } +/** + * CYW43: Xbox Series (BLE) connect stops LE scan (and BR inquiry) to avoid supervision timeout, + * but leaves Bluepad32 "new connections" enabled. On disconnect, enable_new_connections(true) is a + * no-op, so LE scan never resumes and the pad cannot reconnect without power-cycling the Pico. + * Restart LE scan unless another pad still requires it off. + */ +static void maybe_restart_ble_scan_after_disconnect(int disconnected_idx) { +#if defined(CONFIG_TARGET_PICO_W) + if (!uni_bt_enable_new_connections_is_enabled()) + return; + for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { + if (i == static_cast(disconnected_idx)) + continue; + if (!bt_devices_[i].connected) + continue; + uni_hid_device_t* d = uni_hid_device_get_instance_for_idx(static_cast(i)); + if (!d || uni_bt_conn_get_state(&d->conn) != UNI_BT_CONN_STATE_DEVICE_READY) + continue; + if (d->controller_type == CONTROLLER_TYPE_XBoxOneController && d->hids_cid != 0) + return; + /* Solo Switch Joy-Con keeps LE scan off while waiting for partner over Classic BT. */ + if (uni_hid_parser_switch_solo_needs_partner(d)) + return; + } + uni_bt_le_scan_start(); +#endif +} + +/** Set in device_ready — only reboot after a fully working pad disconnects (not failed pair attempts). */ +static bool s_bt_slot_was_ready[CONFIG_BLUEPAD32_MAX_DEVICES]{}; + +/** Full chip reset after last ready BT pad drops — next pair is always a clean first connect. */ +static btstack_timer_source_t s_bt_disconnect_reboot_timer; +static bool s_bt_disconnect_reboot_pending = false; + +static void bt_disconnect_reboot_cb(btstack_timer_source_t* ts) { + (void)ts; + s_bt_disconnect_reboot_pending = false; + printf("[BP32] Last controller disconnected — restarting Pico for clean reconnect\n"); + board_api::reboot(); +} + +static void restore_bt_pairing_mode(int disconnected_idx); + +#if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) +static bool is_pairing_idle() { +#if defined(CONFIG_EN_USB_HOST) + if (board_api::usb::host_any_pad_mounted()) + return false; +#endif + return !any_connected(); +} + +/** Restart BR/LE scans when idle; no-op if a pad or wired host controller is active. */ +static void ensure_idle_pairing_scans(int disconnected_idx) { + if (!is_pairing_idle()) + return; + maybe_restart_bredr_inquiry_after_disconnect(disconnected_idx); + maybe_restart_ble_scan_after_disconnect(disconnected_idx); + ogxm_resume_ble_ads_if_no_acl_pad(disconnected_idx); + if (!uni_bt_enable_new_connections_is_enabled()) + uni_bt_enable_new_connections_unsafe(true); +} + +static btstack_timer_source_t s_pairing_watchdog_timer; + +static void pairing_watchdog_cb(btstack_timer_source_t* ts) { + ensure_idle_pairing_scans(-1); + btstack_run_loop_set_timer(ts, PAIRING_WATCHDOG_MS); + btstack_run_loop_add_timer(ts); +} + +static btstack_context_callback_registration_t s_usb_resume_bt_reg; + +static void usb_resume_on_bt_main(void* ctx) { + (void)ctx; + if (!is_pairing_idle()) + return; + printf("[BP32] USB resume — restoring BT pairing scans\n"); + restore_bt_pairing_mode(-1); +} +#endif /* CONFIG_EN_BLUETOOTH && CONFIG_TARGET_PICO_W */ + +static void restore_bt_pairing_mode(int disconnected_idx) { + if (led_timer_set_) + btstack_run_loop_remove_timer(&led_timer_); + led_timer_set_ = true; + led_timer_.process = check_led_cb; + led_timer_.context = nullptr; + btstack_run_loop_set_timer(&led_timer_, LED_CHECK_TIME_MS); + btstack_run_loop_add_timer(&led_timer_); + board_api::set_led(false); + +#if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) + ensure_idle_pairing_scans(disconnected_idx); +#else + maybe_restart_bredr_inquiry_after_disconnect(disconnected_idx); + maybe_restart_ble_scan_after_disconnect(disconnected_idx); + ogxm_resume_ble_ads_if_no_acl_pad(disconnected_idx); + uni_bt_enable_new_connections_unsafe(true); +#endif +} + static void device_disconnected_cb(uni_hid_device_t* device) { int idx = uni_hid_device_get_idx_for_instance(device); if (idx >= CONFIG_BLUEPAD32_MAX_DEVICES || idx < 0) { @@ -433,6 +570,9 @@ static void device_disconnected_cb(uni_hid_device_t* device) { OGXM_LOG("SW2: disconnected slot %d\n", idx); } + const bool was_ready = s_bt_slot_was_ready[idx]; + s_bt_slot_was_ready[idx] = false; + bt_devices_[idx].connected = false; bool any_other_connected = false; for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { @@ -452,24 +592,31 @@ static void device_disconnected_cb(uni_hid_device_t* device) { prev_touchpad_clicked_[idx] = false; pending_adaptive_trigger_send_[idx] = false; bt_devices_[idx].gamepad->reset_pad_in(); + SteamPassthrough::clear(); - if (!led_timer_set_ && !any_other_connected) { - led_timer_set_ = true; - led_timer_.process = check_led_cb; - led_timer_.context = nullptr; - btstack_run_loop_set_timer(&led_timer_, LED_CHECK_TIME_MS); - btstack_run_loop_add_timer(&led_timer_); - } if (feedback_timer_set_ && !any_other_connected) { feedback_timer_set_ = false; btstack_run_loop_remove_timer(&feedback_timer_); } - maybe_restart_bredr_inquiry_after_disconnect(idx); - ogxm_resume_ble_ads_if_no_acl_pad(idx); - // Re-enable scanning when last device disconnects so the controller can reconnect without - // power-cycling the dongle (fixes "pairing mode but controller won't reconnect" in OG Xbox / BT mode). - if (!any_other_connected) { - uni_bt_enable_new_connections_unsafe(true); + + if (any_other_connected) + return; + + /* Immediately show pairing mode (LED blink + BT scan). */ + restore_bt_pairing_mode(idx); + + /* + * Only reboot after a pad that reached device_ready. Failed pair attempts must + * not reboot or we never stay in pairing mode. Reboot clears BT/HIDS so the + * next successful pair matches a fresh plug-in. + */ + if (was_ready && !s_bt_disconnect_reboot_pending) { + s_bt_disconnect_reboot_pending = true; + s_bt_disconnect_reboot_timer.process = bt_disconnect_reboot_cb; + s_bt_disconnect_reboot_timer.context = nullptr; + btstack_run_loop_set_timer(&s_bt_disconnect_reboot_timer, 500); + btstack_run_loop_add_timer(&s_bt_disconnect_reboot_timer); + printf("[BP32] Pairing mode on — reboot in 500 ms for clean reconnect\n"); } } @@ -504,6 +651,7 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { const int out_idx = bp32_get_gamepad_output_idx(device); bt_devices_[idx].connected = true; + s_bt_slot_was_ready[idx] = true; #if defined(CONFIG_OGXM_DEBUG) if (uni_hid_parser_switch2_is_ble_device(device)) { OGXM_LOG("SW2: READY slot %d pid=0x%04x out=%d — input active\n", idx, device->product_id, out_idx); @@ -553,6 +701,36 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { device->report_parser.set_player_leds(device, static_cast(1u << pad_idx)); } + /* Wiimote: Bluepad32 defaults to sideways (horizontal) mapping; OGX uses TV-style vertical. + * set_mode() overwrites controller_subtype — save extension info first. */ + if (ogxm_is_handheld_wiimote(device)) { + const uint8_t saved_subtype = device->controller_subtype; + const bool has_nunchuk = + saved_subtype == CONTROLLER_SUBTYPE_WIIMOTE_NUNCHUK || + saved_subtype == CONTROLLER_SUBTYPE_WIIMOTE_NUNCHUK_ACCEL; + + uni_hid_parser_wii_set_mode(device, WII_MODE_VERTICAL); + + /* Motion output: request accel reports. With a nunchuk, DRM_KA (0x31) is ignored / + * has no extension bytes — use DRM_KAE (0x35) so stick + accel both work. + * Byte 0x04 = continuous reporting (wiibrew); without it the Wiimote only sends on + * large changes, so Switch gyro-pointer feels dead except when shaking hard. + * Keep mode VERTICAL (not WII_MODE_ACCEL) so button layouts stay correct. */ + if (MotionOutputActive::is_enabled()) { + if (has_nunchuk) { + device->controller_subtype = CONTROLLER_SUBTYPE_WIIMOTE_NUNCHUK_ACCEL; + static constexpr uint8_t kWiiReqAccelNunchuk[] = {0xa2, 0x12, 0x04, 0x35}; + uni_hid_device_send_intr_report(device, kWiiReqAccelNunchuk, sizeof(kWiiReqAccelNunchuk)); + } else { + device->controller_subtype = CONTROLLER_SUBTYPE_WIIMOTE_ACCEL; + static constexpr uint8_t kWiiReqAccel[] = {0xa2, 0x12, 0x04, 0x31}; + uni_hid_device_send_intr_report(device, kWiiReqAccel, sizeof(kWiiReqAccel)); + } + } else if (has_nunchuk) { + device->controller_subtype = CONTROLLER_SUBTYPE_WIIMOTE_NUNCHUK; + } + } + // PS5: start with adaptive triggers off; touchpad click toggles them. if (device->controller_type == CONTROLLER_TYPE_PS5Controller) { adaptive_trigger_enabled_[pad_idx] = false; @@ -730,8 +908,22 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr } } - std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad->scale_joystick_l<10>(uni_gp->axis_x, uni_gp->axis_y); - std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad->scale_joystick_r<10>(uni_gp->axis_rx, uni_gp->axis_ry); + /* Nunchuk stick is Bluepad's right axis; map to left stick for character movement. */ + const bool wii_nunchuk = + device->controller_type == CONTROLLER_TYPE_WiiController && + (device->controller_subtype == CONTROLLER_SUBTYPE_WIIMOTE_NUNCHUK || + device->controller_subtype == CONTROLLER_SUBTYPE_WIIMOTE_NUNCHUK_ACCEL); + if (wii_nunchuk) { + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = + gamepad->scale_joystick_l<10>(uni_gp->axis_rx, uni_gp->axis_ry); + gp_in.joystick_rx = 0; + gp_in.joystick_ry = 0; + } else { + std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = + gamepad->scale_joystick_l<10>(uni_gp->axis_x, uni_gp->axis_y); + std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = + gamepad->scale_joystick_r<10>(uni_gp->axis_rx, uni_gp->axis_ry); + } gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_NONE; switch (device->controller_type) { @@ -745,16 +937,52 @@ static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* contr case CONTROLLER_TYPE_Switch2ProController: gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_SWITCH_PRO; break; + case CONTROLLER_TYPE_WiiController: + if (device->controller_subtype == CONTROLLER_SUBTYPE_WIIMOTE_ACCEL || + device->controller_subtype == CONTROLLER_SUBTYPE_WIIMOTE_NUNCHUK_ACCEL) { + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_WII_BT; + } else { + const int32_t l1 = (uni_gp->accel[0] >= 0 ? uni_gp->accel[0] : -uni_gp->accel[0]) + + (uni_gp->accel[1] >= 0 ? uni_gp->accel[1] : -uni_gp->accel[1]) + + (uni_gp->accel[2] >= 0 ? uni_gp->accel[2] : -uni_gp->accel[2]); + if (l1 > 16) { + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_WII_BT; + } + } + break; default: break; } - if (gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_NONE) { + if (gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_WII_BT) { + MotionImu::fill_from_wii_bt(gp_in.accel, gp_in.gyro, uni_gp->accel); + /* Switch cursor/aim uses gyro; synthesize rate from accel (no MotionPlus parse yet). */ + if (idx >= 0 && idx < static_cast(MAX_GAMEPADS)) { + static MotionImu::WiiPseudoGyroState s_wii_gyro[MAX_GAMEPADS]{}; + MotionImu::apply_wii_pseudo_gyro(gp_in.accel, gp_in.gyro, s_wii_gyro[idx], + to_ms_since_boot(get_absolute_time())); + } + } else if (gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_NONE) { for (int i = 0; i < 3; i++) { gp_in.accel[i] = uni_gp->accel[i]; gp_in.gyro[i] = uni_gp->gyro[i]; } } + if (SteamActive::is_enabled()) { + SteamPassthrough::input_has_touchpad = + (device->controller_type == CONTROLLER_TYPE_PS5Controller); + SteamBtReport::update_from_uni_gamepad(uni_gp); + if (device->controller_type == CONTROLLER_TYPE_PS5Controller) { + uint8_t touch_points[8]{}; + bool touchpad_click = false; + uni_hid_parser_ds5_get_touchpad(device, touch_points, &touchpad_click); + SteamTouchpad::apply_to_passthrough(touch_points, touchpad_click); + std::memcpy(gp_in.touch_raw, touch_points, sizeof(gp_in.touch_raw)); + gp_in.touchpad_click = touchpad_click ? 1 : 0; + gp_in.touchpad_valid = 1; + } + } + gamepad->set_pad_in_from_bluetooth(gp_in); #if BLUEPAD32_UART_LOG_INPUT @@ -843,7 +1071,21 @@ void wired_usb_takeover_disconnect_bt() { } void wired_usb_release_enable_bt_pairing() { +#if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) + s_usb_resume_bt_reg.callback = usb_resume_on_bt_main; + s_usb_resume_bt_reg.context = nullptr; + btstack_run_loop_execute_on_main_thread(&s_usb_resume_bt_reg); +#else uni_bt_enable_new_connections_safe(true); +#endif +} + +void on_usb_device_resume() { +#if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) + s_usb_resume_bt_reg.callback = usb_resume_on_bt_main; + s_usb_resume_bt_reg.context = nullptr; + btstack_run_loop_execute_on_main_thread(&s_usb_resume_bt_reg); +#endif } void init(Gamepad(&gamepads)[MAX_GAMEPADS]) @@ -875,6 +1117,13 @@ void init(Gamepad(&gamepads)[MAX_GAMEPADS]) btstack_run_loop_set_timer(&s_pico_w_usb_mux_timer_, 1); btstack_run_loop_add_timer(&s_pico_w_usb_mux_timer_); } + +#if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) + s_pairing_watchdog_timer.process = pairing_watchdog_cb; + s_pairing_watchdog_timer.context = nullptr; + btstack_run_loop_set_timer(&s_pairing_watchdog_timer, PAIRING_WATCHDOG_MS); + btstack_run_loop_add_timer(&s_pairing_watchdog_timer); +#endif } void run_task(Gamepad(&gamepads)[MAX_GAMEPADS]) diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.h b/Firmware/RP2040/src/Bluepad32/Bluepad32.h index ac41ed15..c3068678 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.h +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.h @@ -23,6 +23,8 @@ namespace bluepad32 { void wired_usb_takeover_disconnect_bt(); /** Re-enable BT pairing after wired USB device unplugged. */ void wired_usb_release_enable_bt_pairing(); + /** Pico W / Pico 2 W / RP2354 BT: restore pairing scans after USB host resume (e.g. Xbox 360 standby wake). */ + void on_usb_device_resume(); /** Call from main loop to send deferred PS5 adaptive-trigger updates (keeps BT callback fast). */ void process_pending_adaptive_triggers(); /** Optional: when set, a timer in the BT run loop calls this every ~4 ms (for GPIO device modes: PS1/PS2, GameCube). Call before run_task(). */ diff --git a/Firmware/RP2040/src/Board/Config.h b/Firmware/RP2040/src/Board/Config.h index 48768b8a..0dea246c 100644 --- a/Firmware/RP2040/src/Board/Config.h +++ b/Firmware/RP2040/src/Board/Config.h @@ -130,7 +130,11 @@ #elif defined(CONFIG_OGXM_BOARD_RP2354) #define OGXM_BOARD RP2354 - #define PIO_USB_DP_PIN 0 // DM = 1 + /* RP2350 + Pi Radio Module 2 (CYW43439): same PIO USB host pins as Pico 2 W. */ + #define PIO_USB_DP_PIN 0 // D+ = GP0, D- = GP1 + #ifndef PIO_USB_SWAP_DP_DM + #define PIO_USB_SWAP_DP_DM 0 + #endif #define LED_INDICATOR_PIN 25 #else @@ -165,4 +169,10 @@ } #endif // defined(PIO_USB_DP_PIN) +/* Boards that run the Pico W firmware path (CYW43439 BT + optional PIO USB host mux). */ +#if defined(CONFIG_OGXM_BOARD_PI_PICOW) || defined(CONFIG_OGXM_BOARD_PI_PICO2W) || \ + (defined(CONFIG_OGXM_BOARD_RP2354) && defined(CONFIG_EN_BLUETOOTH)) + #define OGXM_BOARD_USES_PICO_W_FIRMWARE 1 +#endif + #endif // _BOARD_CONFIG_H_ \ No newline at end of file diff --git a/Firmware/RP2040/src/Board/board_api.cpp b/Firmware/RP2040/src/Board/board_api.cpp index 5ab11da6..6cea5de5 100644 --- a/Firmware/RP2040/src/Board/board_api.cpp +++ b/Firmware/RP2040/src/Board/board_api.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "tusb.h" @@ -105,14 +106,12 @@ void set_led(bool state) { } void reboot() { - #define AIRCR_REG (*((volatile uint32_t *)(0xE000ED0C))) - #define AIRCR_SYSRESETREQ (1 << 2) - #define AIRCR_VECTKEY (0x5FA << 16) - OGXM_LOG("Rebooting\n"); - - AIRCR_REG = AIRCR_VECTKEY | AIRCR_SYSRESETREQ; - while(1); + /* Watchdog reset is reliable from either core (BT runs on Core1). */ + watchdog_reboot(0, 0, 0); + while (1) { + tight_loop_contents(); + } } uint32_t ms_since_boot() { diff --git a/Firmware/RP2040/src/Board/ogxm_log.cpp b/Firmware/RP2040/src/Board/ogxm_log.cpp index 92a54704..bc0a20ab 100644 --- a/Firmware/RP2040/src/Board/ogxm_log.cpp +++ b/Firmware/RP2040/src/Board/ogxm_log.cpp @@ -21,6 +21,7 @@ std::ostream& operator<<(std::ostream& os, DeviceDriverType type) { case DeviceDriverType::XINPUT: os << "XINPUT"; break; case DeviceDriverType::PS3: os << "PS3"; break; case DeviceDriverType::PS4: os << "PS4"; break; + case DeviceDriverType::STEAM: os << "STEAM"; break; case DeviceDriverType::DINPUT: os << "DINPUT"; break; case DeviceDriverType::PSCLASSIC: os << "PSCLASSIC"; break; case DeviceDriverType::SWITCH: os << "SWITCH"; break; diff --git a/Firmware/RP2040/src/Descriptors/PS5Usb.h b/Firmware/RP2040/src/Descriptors/PS5Usb.h new file mode 100644 index 00000000..30231ace --- /dev/null +++ b/Firmware/RP2040/src/Descriptors/PS5Usb.h @@ -0,0 +1,70 @@ +#ifndef _PS5_USB_DESCRIPTORS_H_ +#define _PS5_USB_DESCRIPTORS_H_ + +#include + +/* + * DualSense (CFI-ZCT1) USB identity and 273-byte HID report descriptor. + * Configuration is HID-only (no audio interfaces) — sufficient for PC/Linux gamepad drivers. + */ + +namespace PS5Usb +{ + static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 }; + static const uint8_t STRING_MANUFACTURER[] = "Sony Interactive Entertainment"; + static const uint8_t STRING_PRODUCT[] = "Wireless Controller"; + static const uint8_t STRING_VERSION[] = "1.00"; + + static const uint8_t *STRING_DESCRIPTORS[] __attribute__((unused)) = + { + STRING_LANGUAGE, + STRING_MANUFACTURER, + STRING_PRODUCT, + STRING_VERSION + }; + + static const uint8_t DEVICE_DESCRIPTORS[] = + { + 0x12, + 0x01, + 0x00, 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x4C, 0x05, + 0xCE, 0x0C, + 0x00, 0x01, + 0x01, + 0x02, + 0x00, + 0x01, + }; + + static const uint8_t REPORT_DESCRIPTORS[] = + { + 0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, + 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0x06, + 0x00, 0xff, 0x09, 0x20, 0x95, 0x01, 0x81, 0x02, 0x05, 0x01, 0x09, 0x39, 0x15, 0x00, 0x25, 0x07, + 0x35, 0x00, 0x46, 0x3b, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x65, 0x00, 0x05, + 0x09, 0x19, 0x01, 0x29, 0x0f, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0f, 0x81, 0x02, 0x06, + 0x00, 0xff, 0x09, 0x21, 0x95, 0x0d, 0x81, 0x02, 0x06, 0x00, 0xff, 0x09, 0x22, 0x15, 0x00, 0x26, + 0xff, 0x00, 0x75, 0x08, 0x95, 0x34, 0x81, 0x02, 0x85, 0x02, 0x09, 0x23, 0x95, 0x2f, 0x91, 0x02, + 0x85, 0x05, 0x09, 0x33, 0x95, 0x28, 0xb1, 0x02, 0x85, 0x08, 0x09, 0x34, 0x95, 0x2f, 0xb1, 0x02, + 0x85, 0x09, 0x09, 0x24, 0x95, 0x13, 0xb1, 0x02, 0x85, 0x0a, 0x09, 0x25, 0x95, 0x1a, 0xb1, 0x02, + 0x85, 0x20, 0x09, 0x26, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x21, 0x09, 0x27, 0x95, 0x04, 0xb1, 0x02, + 0x85, 0x22, 0x09, 0x40, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x80, 0x09, 0x28, 0x95, 0x3f, 0xb1, 0x02, + 0x85, 0x81, 0x09, 0x29, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x82, 0x09, 0x2a, 0x95, 0x09, 0xb1, 0x02, + 0x85, 0x83, 0x09, 0x2b, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x84, 0x09, 0x2c, 0x95, 0x3f, 0xb1, 0x02, + 0x85, 0x85, 0x09, 0x2d, 0x95, 0x02, 0xb1, 0x02, 0x85, 0xa0, 0x09, 0x2e, 0x95, 0x01, 0xb1, 0x02, + 0x85, 0xe0, 0x09, 0x2f, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf0, 0x09, 0x30, 0x95, 0x3f, 0xb1, 0x02, + 0x85, 0xf1, 0x09, 0x31, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf2, 0x09, 0x32, 0x95, 0x0f, 0xb1, 0x02, + 0x85, 0xf4, 0x09, 0x35, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf5, 0x09, 0x36, 0x95, 0x03, 0xb1, 0x02, + 0xc0, + }; + + static_assert(sizeof(REPORT_DESCRIPTORS) == 273, "DualSense USB report descriptor length"); + +} // namespace PS5Usb + +#endif diff --git a/Firmware/RP2040/src/Descriptors/Steam.h b/Firmware/RP2040/src/Descriptors/Steam.h new file mode 100644 index 00000000..94f37656 --- /dev/null +++ b/Firmware/RP2040/src/Descriptors/Steam.h @@ -0,0 +1,47 @@ +#ifndef _STEAM_DESCRIPTORS_H_ +#define _STEAM_DESCRIPTORS_H_ + +#include + +#include "Descriptors/PS5Usb.h" + +/* + * SteamOS / Bazzite: DualSense gamepad (interface 0) + relative HID mouse (interface 1) + * for touchpad passthrough — same layout as ControllerMedic PS5MedicUsb. + */ +namespace Steam +{ + static constexpr uint8_t ITF_GAMEPAD = 0; + static constexpr uint8_t ITF_MOUSE = 1; + + static const uint8_t MOUSE_REPORT_DESCRIPTORS[] = + { + 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00, + 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01, + 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, + 0x81, 0x03, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, + 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06, 0xC0, 0xC0, + }; + + static_assert(sizeof(MOUSE_REPORT_DESCRIPTORS) == 50, "Steam mouse HID descriptor length"); + + /* DualSense gamepad (IF0, 273-byte report) + mouse (IF1, EP 0x85 IN). wTotalLength = 0x42. */ + static const uint8_t CONFIGURATION_DESCRIPTORS[] = + { + 0x09, 0x02, 0x42, 0x00, 0x02, 0x01, 0x00, 0xA0, 0xFA, + + 0x09, 0x04, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, + 0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0x11, 0x01, + 0x07, 0x05, 0x84, 0x03, 0x40, 0x00, 0x06, + 0x07, 0x05, 0x03, 0x03, 0x40, 0x00, 0x06, + + 0x09, 0x04, 0x01, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0x32, 0x00, + 0x07, 0x05, 0x85, 0x03, 0x04, 0x00, 0x0A, + }; + + static_assert(sizeof(CONFIGURATION_DESCRIPTORS) == 0x42, "Steam configuration descriptor length"); + +} // namespace Steam + +#endif diff --git a/Firmware/RP2040/src/Gamepad/Gamepad.h b/Firmware/RP2040/src/Gamepad/Gamepad.h index 73f59b52..65441b3d 100644 --- a/Firmware/RP2040/src/Gamepad/Gamepad.h +++ b/Firmware/RP2040/src/Gamepad/Gamepad.h @@ -16,6 +16,7 @@ #include "UserSettings/UserProfile.h" #include "UserSettings/JoystickSettings.h" #include "UserSettings/TriggerSettings.h" +#include "USBDevice/DeviceDriver/DeviceDriverTypes.h" #include "Board/ogxm_log.h" class Gamepad @@ -96,12 +97,15 @@ class Gamepad #pragma pack(push, 1) struct PadIn { - /** IMU for PS3 Sixaxis mapping: only DS4/DS5/Switch Pro paths set this (see motion_source). */ + /** IMU for PS3 Sixaxis / PS4 gadget: Sony, Switch Pro, Wii Remote, wired or BT. */ static constexpr uint8_t MOTION_SRC_NONE = 0; static constexpr uint8_t MOTION_SRC_DS4 = 1; static constexpr uint8_t MOTION_SRC_DS5 = 2; static constexpr uint8_t MOTION_SRC_SWITCH_PRO = 3; static constexpr uint8_t MOTION_SRC_DS5_USB = 4; + static constexpr uint8_t MOTION_SRC_DS4_USB = 5; + static constexpr uint8_t MOTION_SRC_SWITCH_USB = 6; + static constexpr uint8_t MOTION_SRC_WII_BT = 7; uint8_t dpad; uint16_t buttons; @@ -113,12 +117,30 @@ class Gamepad int16_t joystick_ry; uint8_t analog[10]; - /** Bluepad: int32 accel (DS4 units/g) and gyro (DS4 rate units); USB PS5: raw int16 widened. */ + /** Bluepad / USB DS4+DS5: int32 accel (DS4 units/g) and gyro (DS4 rate units). */ int32_t accel[3]; int32_t gyro[3]; /** If MOTION_SRC_NONE, PS3 mode leaves Sixaxis at neutral; else maps to DS3 report. */ uint8_t motion_source; + bool has_motion() const + { + return motion_source == MOTION_SRC_DS4 || + motion_source == MOTION_SRC_DS5 || + motion_source == MOTION_SRC_SWITCH_PRO || + motion_source == MOTION_SRC_DS5_USB || + motion_source == MOTION_SRC_DS4_USB || + motion_source == MOTION_SRC_SWITCH_USB || + motion_source == MOTION_SRC_WII_BT; + } + + /** DualSense touchpad raw bytes (Steam mode mouse). Wire format: 8 bytes at DS5 touch offset. */ + uint8_t touch_raw[8]; + uint8_t touchpad_click; + /** Set when touch_raw was filled from a DS5 report this frame. */ + uint8_t touchpad_valid; + uint8_t touchpad_reserved; + PadIn() { std::memset(this, 0, sizeof(PadIn)); @@ -243,10 +265,10 @@ class Gamepad } } - void set_profile(const UserProfile& user_profile) - { + void set_profile(const UserProfile& user_profile, DeviceDriverType driver = DeviceDriverType::NONE) + { set_profile_mappings(user_profile); - set_profile_settings(user_profile); + set_profile_settings(user_profile, driver); } inline void set_pad_in(PadIn pad_in) @@ -464,29 +486,62 @@ class Gamepad bool trig_settings_l_en_{false}; bool trig_settings_r_en_{false}; - void set_profile_settings(const UserProfile& profile) + void set_profile_settings(const UserProfile& profile, DeviceDriverType driver = DeviceDriverType::NONE) { profile_analog_enabled_ = profile.analog_enabled ? true : false; #if 0 OGXM_LOG("profile_analog_enabled_: %d\n", profile_analog_enabled_); #endif - if ((joy_settings_l_en_ = !joy_settings_l_.is_same(profile.joystick_settings_l))) + const bool xinput_stock = + (driver == DeviceDriverType::XINPUT); + + if (JoystickSettings::raw_has_customization(profile.joystick_settings_l)) + { + joy_settings_l_en_ = true; + if (!joy_settings_l_.is_same(profile.joystick_settings_l)) + { + joy_settings_l_.set_from_raw(profile.joystick_settings_l); + //This needs to be addressed in the webapp, just multiply here for now + joy_settings_l_.axis_restrict *= static_cast(100); + joy_settings_l_.angle_restrict *= static_cast(100); + joy_settings_l_.anti_dz_angular *= static_cast(100); + } + } + else if (xinput_stock) + { + joy_settings_l_.set_xbox360_stock_feel(false); + joy_settings_l_en_ = true; + } + else + { + joy_settings_l_ = JoystickSettings{}; + joy_settings_l_en_ = false; + } + + if (JoystickSettings::raw_has_customization(profile.joystick_settings_r)) + { + joy_settings_r_en_ = true; + if (!joy_settings_r_.is_same(profile.joystick_settings_r)) + { + joy_settings_r_.set_from_raw(profile.joystick_settings_r); + //This needs to be addressed in the webapp, just multiply here for now + joy_settings_r_.axis_restrict *= static_cast(100); + joy_settings_r_.angle_restrict *= static_cast(100); + joy_settings_r_.anti_dz_angular *= static_cast(100); + } + } + else if (xinput_stock) { - joy_settings_l_.set_from_raw(profile.joystick_settings_l); - //This needs to be addressed in the webapp, just multiply here for now - joy_settings_l_.axis_restrict *= static_cast(100); - joy_settings_l_.angle_restrict *= static_cast(100); - joy_settings_l_.anti_dz_angular *= static_cast(100); + joy_settings_r_.set_xbox360_stock_feel(true); + joy_settings_r_en_ = true; } - if ((joy_settings_r_en_ = !joy_settings_r_.is_same(profile.joystick_settings_r))) + else { - joy_settings_r_.set_from_raw(profile.joystick_settings_r); - //This needs to be addressed in the webapp, just multiply here for now - joy_settings_r_.axis_restrict *= static_cast(100); - joy_settings_r_.angle_restrict *= static_cast(100); - joy_settings_r_.anti_dz_angular *= static_cast(100); + joy_settings_r_ = JoystickSettings{}; + joy_settings_r_en_ = false; } + if ((trig_settings_l_en_ = !trig_settings_l_.is_same(profile.trigger_settings_l))) { trig_settings_l_.set_from_raw(profile.trigger_settings_l); @@ -580,13 +635,44 @@ class Gamepad ? FIX_0 : ((abs_y - set.axis_restrict) * inv_axis_restrict); + /* WebApp uses raw stick magnitude for the inner deadzone test (before axial restrict). */ + const Fix16 raw_magnitude = fix16::sqrt(fix16::sq(abs_x) + fix16::sq(abs_y)); Fix16 in_magnitude = fix16::sqrt(fix16::sq(axial_x) + fix16::sq(axial_y)); - if (in_magnitude < set.dz_inner) + /* Anti-deadzone pushes any non-zero reading to at least anti_dz_* magnitude. + * Switch Pro / Switch 2 Pro USB sticks are rarely perfect at the nominal + * center, so with dz_inner=0 that becomes a constant drift (often bottom-left + * after Y invert). Gate idle noise when anti-dz is active, but keep the + * user's dz_inner for the magnitude warp so anti-dz still applies fully. */ + const bool anti_dz_active = + set.anti_dz_square > FIX_EPSILON || set.anti_dz_circle > FIX_EPSILON || + set.anti_dz_square_y_scale > FIX_EPSILON || set.anti_dz_circle_y_scale > FIX_EPSILON; + static const Fix16 FIX_ANTI_DZ_NOISE_MIN(0.07f); + static const Fix16 FIX_ANTI_DZ_NOISE_MAX(0.12f); + Fix16 gate = set.dz_inner; + if (anti_dz_active && gate < FIX_ANTI_DZ_NOISE_MIN) + { + const Fix16 anti_ref = + (set.anti_dz_circle > set.anti_dz_square) ? set.anti_dz_circle : set.anti_dz_square; + Fix16 adaptive_gate = anti_ref * Fix16(0.4f); + if (adaptive_gate < FIX_ANTI_DZ_NOISE_MIN) + { + adaptive_gate = FIX_ANTI_DZ_NOISE_MIN; + } + if (adaptive_gate > FIX_ANTI_DZ_NOISE_MAX) + { + adaptive_gate = FIX_ANTI_DZ_NOISE_MAX; + } + gate = adaptive_gate; + } + + if (raw_magnitude <= gate) { return { 0, 0 }; } + const Fix16 dz_inner = set.dz_inner; + Fix16 angle = fix16::abs(axial_x) < FIX_EPSILON ? FIX_90 @@ -595,10 +681,10 @@ class Gamepad Fix16 anti_r_scale = (set.anti_dz_square_y_scale == FIX_0) ? set.anti_dz_square : set.anti_dz_square_y_scale; Fix16 anti_dz_c = set.anti_dz_circle; - if (anti_r_scale > FIX_0 && anti_dz_c > FIX_0) + if (set.anti_dz_circle_y_scale > FIX_0 && anti_dz_c > FIX_0) { - Fix16 anti_ellip_scale = anti_ellip_scale / anti_dz_c; - Fix16 ellipse_angle = fix16::atan((FIX_1 / anti_ellip_scale) * fix16::tan(fix16::rad2deg(rAngle))); + Fix16 anti_ellip_scale = set.anti_dz_circle_y_scale / anti_dz_c; + Fix16 ellipse_angle = fix16::atan((FIX_1 / anti_ellip_scale) * fix16::tan(fix16::deg2rad(rAngle))); ellipse_angle = (ellipse_angle < FIX_0) ? FIX_ELLIPSE_DEF : ellipse_angle; Fix16 ellipse_x = fix16::cos(ellipse_angle); @@ -606,9 +692,11 @@ class Gamepad anti_dz_c *= fix16::sqrt(fix16::sq(ellipse_x) + fix16::sq(ellipse_y)); } + /* Match WebApp: counter square anti-dz shrinkage (must use anti_dz_square, not circle). */ if (anti_dz_c > FIX_0) { - anti_dz_c = anti_dz_c / ((anti_dz_c * (FIX_1 - set.anti_dz_circle / set.dz_outer)) / (anti_dz_c * (FIX_1 - set.anti_dz_square))); + anti_dz_c = anti_dz_c / ((anti_dz_c * (FIX_1 - set.anti_dz_square / set.dz_outer)) / + (anti_dz_c * (FIX_1 - set.anti_dz_square))); } if (abs_x > set.axis_restrict && abs_y > set.axis_restrict) @@ -653,7 +741,7 @@ class Gamepad } //Deadzone Warp - Fix16 out_magnitude = (in_magnitude - set.dz_inner) / (set.anti_dz_outer - set.dz_inner); + Fix16 out_magnitude = (in_magnitude - dz_inner) / (set.anti_dz_outer - dz_inner); out_magnitude = fix16::pow(out_magnitude, (FIX_1 / set.curve)) * (set.dz_outer - anti_dz_c) + anti_dz_c; out_magnitude = (out_magnitude > set.dz_outer && !set.uncap_radius) ? set.dz_outer : out_magnitude; diff --git a/Firmware/RP2040/src/Gamepad/MotionImu.h b/Firmware/RP2040/src/Gamepad/MotionImu.h new file mode 100644 index 00000000..f778e8c3 --- /dev/null +++ b/Firmware/RP2040/src/Gamepad/MotionImu.h @@ -0,0 +1,355 @@ +#ifndef _MOTION_IMU_H_ +#define _MOTION_IMU_H_ + +#include +#include + +#include "Gamepad/Gamepad.h" + +namespace MotionImu +{ + +constexpr int32_t kDs4AccRange = 4 * 8192; +constexpr int32_t kDs4GyroRange = 2048 * 1024; +constexpr int32_t kRawSensDenom = 32767; + +constexpr int32_t kSwitchDefaultAccelScale = 16384; +constexpr int32_t kSwitchDefaultGyroScale = 13371; +constexpr int32_t kSwitchGyroPrecScale = 1000; +constexpr int32_t kWiiAccelCountsPerG = 0x6C; +constexpr int32_t kDs4UnitsPerG = 8192; + +#pragma pack(push, 1) +struct SwitchImuSample +{ + int16_t accel[3]; + int16_t gyro[3]; +}; +#pragma pack(pop) + +static_assert(sizeof(SwitchImuSample) == 12); + +inline int32_t ds4_ds5_usb_raw_to_units(int16_t raw, int32_t range) +{ + return static_cast((static_cast(range) * static_cast(raw)) / kRawSensDenom); +} + +inline void fill_from_ds4_usb_report(int32_t accel[3], int32_t gyro[3], const uint8_t* report) +{ + int16_t raw_g[3]; + int16_t raw_a[3]; + std::memcpy(&raw_g[0], &report[13], 2); + std::memcpy(&raw_g[1], &report[15], 2); + std::memcpy(&raw_g[2], &report[17], 2); + std::memcpy(&raw_a[0], &report[19], 2); + std::memcpy(&raw_a[1], &report[21], 2); + std::memcpy(&raw_a[2], &report[23], 2); + for (int i = 0; i < 3; i++) { + gyro[i] = ds4_ds5_usb_raw_to_units(raw_g[i], kDs4GyroRange); + accel[i] = ds4_ds5_usb_raw_to_units(raw_a[i], kDs4AccRange); + } +} + +inline void fill_from_ds5_usb_raw(int32_t accel[3], int32_t gyro[3], const uint16_t raw_accel[3], const uint16_t raw_gyro[3]) +{ + for (int i = 0; i < 3; i++) { + gyro[i] = ds4_ds5_usb_raw_to_units(static_cast(raw_gyro[i]), kDs4GyroRange); + accel[i] = ds4_ds5_usb_raw_to_units(static_cast(raw_accel[i]), kDs4AccRange); + } +} + +/* Bluepad default factory cal when SPI calib is unavailable (wired USB). */ +inline void fill_from_switch_usb_payload(int32_t accel[3], int32_t gyro[3], const uint8_t* payload, uint16_t payload_len) +{ + constexpr uint16_t kInReportSize = 10; + constexpr uint16_t kImuSampleSize = sizeof(SwitchImuSample); + + if (payload_len < kInReportSize + kImuSampleSize) { + for (int i = 0; i < 3; i++) { + accel[i] = 0; + gyro[i] = 0; + } + return; + } + + uint16_t imu_off = kInReportSize; + if (payload_len >= kInReportSize + (3 * kImuSampleSize)) { + imu_off = static_cast(kInReportSize + (2 * kImuSampleSize)); + } + + SwitchImuSample raw{}; + std::memcpy(&raw, payload + imu_off, sizeof(raw)); + + const int32_t accel_div = kSwitchDefaultAccelScale; + const int32_t gyro_div = kSwitchDefaultGyroScale; + for (int i = 0; i < 3; i++) { + if (accel_div != 0) { + accel[i] = (static_cast(raw.accel[i]) * kSwitchDefaultAccelScale) / accel_div; + } else { + accel[i] = raw.accel[i]; + } + if (gyro_div != 0) { + const int64_t num = static_cast(kSwitchGyroPrecScale) * static_cast(raw.gyro[i]); + gyro[i] = static_cast((num * kSwitchDefaultGyroScale) / gyro_div); + } else { + gyro[i] = raw.gyro[i]; + } + } +} + +inline bool switch_usb_imu_unchanged(const uint8_t* prev_imu, const uint8_t* payload, uint16_t payload_len) +{ + constexpr uint16_t kInReportSize = 10; + constexpr uint16_t kImuSampleSize = sizeof(SwitchImuSample); + if (payload_len < kInReportSize + kImuSampleSize) { + return true; + } + + uint16_t imu_off = kInReportSize; + if (payload_len >= kInReportSize + (3 * kImuSampleSize)) { + imu_off = static_cast(kInReportSize + (2 * kImuSampleSize)); + } + + return std::memcmp(prev_imu, payload + imu_off, kImuSampleSize) == 0; +} + +/* Bluepad Wii DRM_KA: centered int16 accel (~108 counts per G). */ +inline void fill_from_wii_bt(int32_t accel[3], int32_t gyro[3], const int32_t wii_accel[3]) +{ + for (int i = 0; i < 3; i++) { + accel[i] = static_cast((static_cast(wii_accel[i]) * kDs4UnitsPerG) / kWiiAccelCountsPerG); + gyro[i] = 0; + } +} + +/** + * Switch motion UIs integrate gyro (Linux ABS_RX/RY/RZ), not accel (ABS_X/Y/Z). + * Wiimote has no parsed MotionPlus gyro, so approximate rate from filtered gravity. + * + * hid-nintendo scales Pro gyro int16 by ~8k× (switch_raw 3 → ABS ~25k). Emit + * instantaneous d(accel)/dt only (no accumulation), cap ±1. PadIn.gyro is + * Switch-native int16. Still pose ⇒ gyro=0. + */ +struct WiiPseudoGyroState +{ + int32_t filt_accel[3]; + int32_t prev_filt[3]; + uint32_t prev_ms; + bool valid; +}; + +inline void apply_wii_pseudo_gyro(int32_t accel[3], int32_t gyro[3], WiiPseudoGyroState& st, uint32_t now_ms) +{ + gyro[0] = gyro[1] = gyro[2] = 0; + + if (!st.valid) { + for (int i = 0; i < 3; i++) { + st.filt_accel[i] = accel[i]; + st.prev_filt[i] = accel[i]; + } + st.prev_ms = now_ms; + st.valid = true; + return; + } + + for (int i = 0; i < 3; i++) { + st.filt_accel[i] = (st.filt_accel[i] * 2 + accel[i]) / 3; + accel[i] = st.filt_accel[i]; + } + + uint32_t dt = now_ms - st.prev_ms; + if (dt < 1) { + return; + } + if (dt > 40) { + dt = 40; + } + + /* ±1 → Linux ~8k; d=80 over 10 ms → raw 1. */ + constexpr int32_t kMaxRaw = 1; + for (int i = 0; i < 3; i++) { + int32_t d = st.filt_accel[i] - st.prev_filt[i]; + st.prev_filt[i] = st.filt_accel[i]; + + if (d > -20 && d < 20) { + continue; + } + + int32_t rate = d / (static_cast(dt) * 5); + if (rate > kMaxRaw) { + rate = kMaxRaw; + } else if (rate < -kMaxRaw) { + rate = -kMaxRaw; + } + gyro[i] = rate; + } + st.prev_ms = now_ms; +} + +/* + * Rotate accel/gyro into the DS4/Sixaxis playing frame (+Z = 1 G when level, sticks up). + * Switch Pro raw: X → triggers, Y → left, Z → out of face buttons. + * Wiimote pointed at TV: gravity mostly on -Y; map to DS4 +Z neutral. + */ +inline void remap_to_ds4_playing_frame(uint8_t motion_source, int32_t accel[3], int32_t gyro[3]) +{ + const int32_t ix = accel[0]; + const int32_t iy = accel[1]; + const int32_t iz = accel[2]; + const int32_t gx = gyro[0]; + const int32_t gy = gyro[1]; + const int32_t gz = gyro[2]; + + switch (motion_source) { + case Gamepad::PadIn::MOTION_SRC_WII_BT: + /* Wiimote IR toward TV: gravity on -Y; map into DS4 playing frame. */ + accel[0] = -ix; + accel[1] = iz; + accel[2] = -iy; + gyro[0] = -gx; + gyro[1] = gz; + gyro[2] = -gy; + break; + case Gamepad::PadIn::MOTION_SRC_SWITCH_PRO: + case Gamepad::PadIn::MOTION_SRC_SWITCH_USB: + accel[0] = -iy; + accel[1] = -ix; + accel[2] = -iz; + gyro[0] = -gy; + gyro[1] = -gx; + gyro[2] = -gz; + break; + default: + break; + } +} + +inline int16_t clamp_i16(int32_t v) +{ + if (v > 32767) { + return 32767; + } + if (v < -32768) { + return -32768; + } + return static_cast(v); +} + +/** + * Encode PadIn motion into one Switch Pro IMU sample (little-endian int16 + * accel[3] + gyro[3]). PadIn units: Switch sources use Pro-native accel and + * gyro*1000; DS4/DS5 use DS4 playing-frame units (8192/G); Wii uses Wiimote-frame + * accel (DS4 units/g) and **Switch-native** gyro (see apply_wii_pseudo_gyro). + */ +inline void encode_switch_imu_sample(SwitchImuSample& out, const Gamepad::PadIn& gp_in) +{ + if (!gp_in.has_motion()) { + out.accel[0] = 0; + out.accel[1] = 0; + out.accel[2] = static_cast(kSwitchDefaultAccelScale); /* +1 G face-up */ + out.gyro[0] = out.gyro[1] = out.gyro[2] = 0; + return; + } + + int32_t ax = gp_in.accel[0]; + int32_t ay = gp_in.accel[1]; + int32_t az = gp_in.accel[2]; + int32_t gx = gp_in.gyro[0]; + int32_t gy = gp_in.gyro[1]; + int32_t gz = gp_in.gyro[2]; + + int32_t sx = 0; + int32_t sy = 0; + int32_t sz = 0; + int32_t sgx = 0; + int32_t sgy = 0; + int32_t sgz = 0; + + switch (gp_in.motion_source) { + case Gamepad::PadIn::MOTION_SRC_SWITCH_PRO: + case Gamepad::PadIn::MOTION_SRC_SWITCH_USB: + out.accel[0] = clamp_i16(ax); + out.accel[1] = clamp_i16(ay); + out.accel[2] = clamp_i16(az); + out.gyro[0] = clamp_i16(gx / kSwitchGyroPrecScale); + out.gyro[1] = clamp_i16(gy / kSwitchGyroPrecScale); + out.gyro[2] = clamp_i16(gz / kSwitchGyroPrecScale); + return; + case Gamepad::PadIn::MOTION_SRC_WII_BT: + /* Accel: Wiimote → Switch frame (DS4 units → Pro scale). */ + sx = -az; + sy = ax; + sz = ay; + out.accel[0] = clamp_i16((sx * kSwitchDefaultAccelScale) / kDs4UnitsPerG); + out.accel[1] = clamp_i16((sy * kSwitchDefaultAccelScale) / kDs4UnitsPerG); + out.accel[2] = clamp_i16((sz * kSwitchDefaultAccelScale) / kDs4UnitsPerG); + /* Gyro already Switch-native; same axis remap (no /1000). */ + out.gyro[0] = clamp_i16(-gz); + out.gyro[1] = clamp_i16(gx); + out.gyro[2] = clamp_i16(gy); + return; + default: + /* DS4/DS5 PadIn is DS4 playing frame; invert Switch→DS4 remap. */ + sx = -ay; + sy = -ax; + sz = -az; + sgx = -gy; + sgy = -gx; + sgz = -gz; + break; + } + + out.accel[0] = clamp_i16((sx * kSwitchDefaultAccelScale) / kDs4UnitsPerG); + out.accel[1] = clamp_i16((sy * kSwitchDefaultAccelScale) / kDs4UnitsPerG); + out.accel[2] = clamp_i16((sz * kSwitchDefaultAccelScale) / kDs4UnitsPerG); + out.gyro[0] = clamp_i16(sgx / kSwitchGyroPrecScale); + out.gyro[1] = clamp_i16(sgy / kSwitchGyroPrecScale); + out.gyro[2] = clamp_i16(sgz / kSwitchGyroPrecScale); +} + +/** + * Write three IMU samples (36 bytes) at dest — Pro report 0x30 layout. + * Real Pro spaces samples ~5 ms apart; keep a short history so hosts that + * differentiate slots (or average them) see motion instead of three copies. + * + * Wii pseudo-gyro is a one-shot impulse: do **not** use history (it would + * re-emit old gyro in older slots for 2–3 reports). Only the newest slot gets + * gyro; the other two carry accel only. + */ +struct SwitchImuHistory +{ + SwitchImuSample samples[3]; + bool valid; +}; + +inline void encode_switch_imu_report(uint8_t* dest, const Gamepad::PadIn& gp_in, SwitchImuHistory& hist) +{ + SwitchImuSample sample{}; + encode_switch_imu_sample(sample, gp_in); + + if (gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_WII_BT) { + SwitchImuSample accel_only = sample; + accel_only.gyro[0] = accel_only.gyro[1] = accel_only.gyro[2] = 0; + std::memcpy(dest + 0 * sizeof(sample), &accel_only, sizeof(sample)); + std::memcpy(dest + 1 * sizeof(sample), &accel_only, sizeof(sample)); + std::memcpy(dest + 2 * sizeof(sample), &sample, sizeof(sample)); + hist.valid = false; + return; + } + + if (!hist.valid) { + hist.samples[0] = hist.samples[1] = hist.samples[2] = sample; + hist.valid = true; + } else { + hist.samples[0] = hist.samples[1]; + hist.samples[1] = hist.samples[2]; + hist.samples[2] = sample; + } + for (int i = 0; i < 3; i++) { + std::memcpy(dest + static_cast(i) * sizeof(sample), &hist.samples[i], sizeof(sample)); + } +} + +} // namespace MotionImu + +#endif // _MOTION_IMU_H_ diff --git a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp index 7711f6ce..bb2a3b36 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Four_Channel_I2C.cpp @@ -424,7 +424,7 @@ void four_ch_i2c::initialize() { board_api::init_board(); for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { - _gamepads[i].set_profile(user_settings.get_profile_by_index(i)); + _gamepads[i].set_profile(user_settings.get_profile_by_index(i), user_settings.get_current_driver()); } DeviceManager::get_instance().initialize_driver(user_settings.get_current_driver(), _gamepads); diff --git a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp index a5e5dabd..0d15c920 100644 --- a/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/PicoW.cpp @@ -1,6 +1,6 @@ #include "Board/Config.h" #include "OGXMini/Board/PicoW.h" -#if (OGXM_BOARD == PI_PICOW) +#if defined(OGXM_BOARD_USES_PICO_W_FIRMWARE) #include #include @@ -426,7 +426,7 @@ void pico_w::initialize() { #endif for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { - _gamepads[i].set_profile(user_settings.get_profile_by_index(i)); + _gamepads[i].set_profile(user_settings.get_profile_by_index(i), user_settings.get_current_driver()); } DeviceManager& device_manager = DeviceManager::get_instance(); @@ -600,9 +600,6 @@ void pico_w::run() { } } -// #else // (OGXM_BOARD == PI_PICOW) +// #else // OGXM_BOARD_USES_PICO_W_FIRMWARE -// void pico_w::initialize() {} -// void pico_w::run() {} - -#endif // (OGXM_BOARD == PI_PICOW) +#endif // OGXM_BOARD_USES_PICO_W_FIRMWARE diff --git a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp index 8e863776..71f84ac0 100644 --- a/Firmware/RP2040/src/OGXMini/Board/Standard.cpp +++ b/Firmware/RP2040/src/OGXMini/Board/Standard.cpp @@ -1,6 +1,6 @@ #include "Board/Config.h" #include "OGXMini/Board/Standard.h" -#if ((OGXM_BOARD == PI_PICO) || (OGXM_BOARD == RP2040_ZERO) || (OGXM_BOARD == ADAFRUIT_FEATHER) || (OGXM_BOARD == RP2350_USB_A) || (OGXM_BOARD == RP2350_ZERO) || (OGXM_BOARD == RP2040_XIAO) || (OGXM_BOARD == RP2354)) +#if ((OGXM_BOARD == PI_PICO) || (OGXM_BOARD == RP2040_ZERO) || (OGXM_BOARD == ADAFRUIT_FEATHER) || (OGXM_BOARD == RP2350_USB_A) || (OGXM_BOARD == RP2350_ZERO) || (OGXM_BOARD == RP2040_XIAO)) #include #include @@ -33,6 +33,9 @@ static repeating_timer_t s_pio_usb_sof_timer; static bool s_pio_usb_sof_hw_timer = false; /** Set during intentional mode-change reboot so host_mounted(false) does not queue a second teardown. */ static std::atomic s_driver_reboot_pending{false}; +/** Debounce transient PIO USB umount before tearing down the USB device stack. */ +static std::atomic s_host_teardown_scheduled{false}; +constexpr uint32_t HOST_UNMOUNT_DEBOUNCE_MS = 1500; static void pio_usb_sof_timer_stop() { if (!s_pio_usb_sof_hw_timer) { @@ -164,16 +167,32 @@ void standard::host_mounted(bool host_mounted) { } if (!host_mounted && tud_is_inited.load() && !s_driver_reboot_pending.load()) { - TaskQueue::Core0::queue_task([]() { - OGXM_LOG("USB disconnected, rebooting.\n"); - board_api::usb::disconnect_all(); - board_api::reboot(); - }); - } else if (!tud_is_inited.load()) { - TaskQueue::Core0::queue_task([]() { - tud_init(BOARD_TUD_RHPORT); - tud_is_inited.store(true); - }); + if (!s_host_teardown_scheduled.exchange(true)) { + TaskQueue::Core0::queue_delayed_task( + TaskQueue::Core0::get_new_task_id(), + HOST_UNMOUNT_DEBOUNCE_MS, + false, + []() { + s_host_teardown_scheduled.store(false); + if (s_driver_reboot_pending.load()) { + return; + } + if (HostManager::get_instance().any_mounted()) { + return; + } + OGXM_LOG("USB disconnected, rebooting.\n"); + board_api::usb::disconnect_all(); + board_api::reboot(); + }); + } + } else if (host_mounted) { + s_host_teardown_scheduled.store(false); + if (!tud_is_inited.load()) { + TaskQueue::Core0::queue_task([]() { + tud_init(BOARD_TUD_RHPORT); + tud_is_inited.store(true); + }); + } } } @@ -184,7 +203,7 @@ void standard::initialize() { user_settings.initialize_flash(); for (uint8_t i = 0; i < MAX_GAMEPADS; ++i) { - _gamepads[i].set_profile(user_settings.get_profile_by_index(i)); + _gamepads[i].set_profile(user_settings.get_profile_by_index(i), user_settings.get_current_driver()); } DeviceManager::get_instance().initialize_driver(user_settings.get_current_driver(), _gamepads); @@ -313,4 +332,4 @@ void standard::run() { // void standard::initialize() {} // void standard::run() {} -#endif // PI_PICO || RP2040_ZERO || ADAFRUIT_FEATHER || RP2350_USB_A || RP2350_ZERO || RP2040_XIAO || RP2354 \ No newline at end of file +#endif // PI_PICO || RP2040_ZERO || ADAFRUIT_FEATHER || RP2350_USB_A || RP2350_ZERO || RP2040_XIAO \ No newline at end of file diff --git a/Firmware/RP2040/src/OGXMini/OGXMini.cpp b/Firmware/RP2040/src/OGXMini/OGXMini.cpp index d0e96454..4030fc0e 100644 --- a/Firmware/RP2040/src/OGXMini/OGXMini.cpp +++ b/Firmware/RP2040/src/OGXMini/OGXMini.cpp @@ -25,7 +25,7 @@ namespace OGXMini { standard::initialize, // RP2350_USB_A standard::initialize, // RP2350_ZERO standard::initialize, // RP2040_XIAO - standard::initialize, // RP2354 + pico_w::initialize, // RP2354 (CYW43439 / Pi Radio Module 2) }; static constexpr RunFunc run_func[BOARDS_COUNT] = { @@ -40,7 +40,7 @@ namespace OGXMini { standard::run, // RP2350_USB_A standard::run, // RP2350_ZERO standard::run, // RP2040_XIAO - standard::run, // RP2354 + pico_w::run, // RP2354 }; static constexpr HostMountedFunc host_mount_func[BOARDS_COUNT] = { @@ -55,7 +55,7 @@ namespace OGXMini { standard::host_mounted, // RP2350_USB_A standard::host_mounted, // RP2350_ZERO standard::host_mounted, // RP2040_XIAO - standard::host_mounted, // RP2354 + nullptr, // RP2354 }; static constexpr HostMountedWTypeFunc host_mount_w_type_func[BOARDS_COUNT] = { diff --git a/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp b/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp index 33a596c2..81198cfc 100644 --- a/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp +++ b/Firmware/RP2040/src/TaskQueue/TaskQueue.cpp @@ -3,7 +3,9 @@ TaskQueue::TaskQueue(CoreNum core_num) { alarm_num_ = (core_num == CoreNum::Core0) ? 0 : 1; - alarm_num_ += (OGXM_BOARD == PI_PICOW) ? 1 : 0; // BTStack uses alarm 0; PicoW Wii mode gives PIO USB alarm 3 via config +#if defined(OGXM_BOARD_USES_PICO_W_FIRMWARE) + alarm_num_ += 1; // BTStack uses alarm 0; Pico W path offsets Core1 timer +#endif hw_set_bits(&timer_hw->inte, 1u << alarm_num_); @@ -196,7 +198,7 @@ void TaskQueue::timer_irq_handler() void TaskQueue::suspend_delayed_tasks() { get_core0().suspend_delayed(); -#if (OGXM_BOARD != PI_PICOW) && (OGXM_BOARD != PI_PICO2W) +#if !defined(OGXM_BOARD_USES_PICO_W_FIRMWARE) get_core1().suspend_delayed(); #endif } @@ -204,7 +206,7 @@ void TaskQueue::suspend_delayed_tasks() void TaskQueue::resume_delayed_tasks() { get_core0().resume_delayed(); -#if (OGXM_BOARD != PI_PICOW) && (OGXM_BOARD != PI_PICO2W) +#if !defined(OGXM_BOARD_USES_PICO_W_FIRMWARE) get_core1().resume_delayed(); #endif } diff --git a/Firmware/RP2040/src/TaskQueue/TaskQueue.h b/Firmware/RP2040/src/TaskQueue/TaskQueue.h index 90a3796f..cd0c5387 100644 --- a/Firmware/RP2040/src/TaskQueue/TaskQueue.h +++ b/Firmware/RP2040/src/TaskQueue/TaskQueue.h @@ -48,7 +48,7 @@ class TaskQueue } }; -#if (OGXM_BOARD != PI_PICOW) || defined(CONFIG_EN_USB_HOST) // PI_PICOW: Core1 for Wii USB host +#if !defined(OGXM_BOARD_USES_PICO_W_FIRMWARE) || defined(CONFIG_EN_USB_HOST) // Pico W path: Core1 for Wii USB host struct Core1 { static inline uint32_t get_new_task_id() diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h index 53d7b3cb..160a3441 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/DeviceDriverTypes.h @@ -21,6 +21,7 @@ enum class DeviceDriverType : uint8_t DREAMCAST, // Dreamcast controller over Maple Bus GPIO (no USB device; output/input to console) N64, // N64 controller over GPIO (single wire; no USB device; output to N64 console) PS4, // DualShock 4 USB HID (CUH-ZCT1x-class descriptor) + STEAM, // SteamOS/Bazzite: DualSense USB gamepad + HID mouse (touchpad passthrough) WEBAPP = 100, UART_BRIDGE }; diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/MotionOutputActive.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/MotionOutputActive.h new file mode 100644 index 00000000..8b56bc8d --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/MotionOutputActive.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +/** True while USB output is PS3 or PS4 (Sixaxis / DS4 IMU gadget). Switch motion disabled for now. */ +namespace MotionOutputActive +{ + inline std::atomic enabled{false}; + + inline void set(bool on) + { + enabled.store(on, std::memory_order_release); + } + + inline bool is_enabled() + { + return enabled.load(std::memory_order_acquire); + } +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c index 7d57bed1..2ce8abef 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS1PS2/controller_simulator.c @@ -9,7 +9,7 @@ #include "psxSPI.pio.h" #include "USBDevice/DeviceDriver/PS1PS2/psx_simulator.h" -#if defined(CONFIG_OGXM_BOARD_PI_PICOW) || defined(CONFIG_OGXM_BOARD_PI_PICO2W) +#if defined(CONFIG_OGXM_BOARD_PI_PICOW) || defined(CONFIG_OGXM_BOARD_PI_PICO2W) || defined(CONFIG_OGXM_BOARD_RP2354) /* Pico W / Pico 2 W: do not use GPIO IRQ for PIN_SEL; CYW43 uses gpio_add_raw_irq_handler and conflicts. */ #define PSX_DEVICE_POLLED_SEL 1 #else diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp index 9cc899e9..5e162ef4 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS3/PS3.cpp @@ -2,6 +2,7 @@ #include #include "pico/time.h" +#include "Gamepad/MotionImu.h" #include "USBDevice/DeviceDriver/PS3/PS3.h" namespace { @@ -17,9 +18,13 @@ void apply_pad_imu_to_ps3_sixaxis(PS3::InReport& rep, const Gamepad::PadIn& gp_i constexpr int32_t kDs3CountsPerG = 113; constexpr int32_t kGyroPerDps = 1024; - int32_t ax = gp_in.accel[0]; - int32_t ay = gp_in.accel[1]; - int32_t az = gp_in.accel[2]; + int32_t accel[3] = {gp_in.accel[0], gp_in.accel[1], gp_in.accel[2]}; + int32_t gyro[3] = {gp_in.gyro[0], gp_in.gyro[1], gp_in.gyro[2]}; + MotionImu::remap_to_ds4_playing_frame(gp_in.motion_source, accel, gyro); + + int32_t ax = accel[0]; + int32_t ay = accel[1]; + int32_t az = accel[2]; auto iabs = [](int32_t v) -> int64_t { const int64_t w = static_cast(v); @@ -55,15 +60,27 @@ void apply_pad_imu_to_ps3_sixaxis(PS3::InReport& rep, const Gamepad::PadIn& gp_i return static_cast(raw); }; + const bool wii_imu = gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_WII_BT; + const uint16_t raw_x = encode_accel(ax, false); - const uint16_t raw_z_wire = encode_accel(az, true); - const uint16_t raw_y_wire = encode_accel(ay, true); + /* Linux hid-sony: report Z bytes → kernel ABS_Z, report Y bytes → kernel ABS_Y. + * Real DS3 neutral gravity is on ABS_Y; Wii pitch was on ay and gravity on az in + * DS4 frame — swap wires so gravity lands on acceler_z (kernel Y). */ + uint16_t raw_z_wire; + uint16_t raw_y_wire; + if (wii_imu) { + raw_z_wire = encode_accel(ay, true); + raw_y_wire = encode_accel(az, true); + } else { + raw_z_wire = encode_accel(az, true); + raw_y_wire = encode_accel(ay, true); + } rep.acceler_x = __builtin_bswap16(raw_x); rep.acceler_y = __builtin_bswap16(raw_z_wire); rep.acceler_z = __builtin_bswap16(raw_y_wire); - int32_t gz = static_cast((static_cast(gp_in.gyro[2]) * 511) / (kGyroPerDps * 64)); + int32_t gz = static_cast((static_cast(gyro[2]) * 511) / (kGyroPerDps * 64)); if (gz > 511) { gz = 511; } @@ -242,10 +259,7 @@ void PS3Device::process(const uint8_t idx, Gamepad& gamepad) report_in_.l1_axis = (gp_in.buttons & Gamepad::BUTTON_LB) ? 0xFF : 0; } - /* Sixaxis only when IMU is parsed for DS4/DS5 BT or Switch Pro (not other pads or USB PS5). */ - if (gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_DS4 || - gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_DS5 || - gp_in.motion_source == Gamepad::PadIn::MOTION_SRC_SWITCH_PRO) { + if (gp_in.has_motion()) { apply_pad_imu_to_ps3_sixaxis(report_in_, gp_in); } } diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp index 757a0919..27d5224d 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/PS4/PS4.cpp @@ -2,6 +2,7 @@ #include #include "pico/time.h" +#include "Gamepad/MotionImu.h" #include "USBDevice/DeviceDriver/PS4/PS4.h" #include "Descriptors/PS4Usb.h" @@ -45,22 +46,24 @@ int16_t scale_i32_to_i16_rounded(int32_t v, int32_t div) return static_cast(q); } -/* Brook capture: int16 LE gyro @ 13–18, accel @ 19–24 in report id 1. IMU is only filled from - * Bluetooth (Bluepad): DS4 / DualSense / Switch Pro — not USB host controllers. */ +/* Brook capture: int16 LE gyro @ 13–18, accel @ 19–24 in report id 1. Filled from DS4/DS5 BT, + * Switch Pro, or wired DS4/DualSense USB host paths. */ void apply_pad_imu_to_ps4_report(std::array& rep, const Gamepad::PadIn& gp_in) { - if (gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_DS4 && - gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_DS5 && - gp_in.motion_source != Gamepad::PadIn::MOTION_SRC_SWITCH_PRO) { + if (!gp_in.has_motion()) { return; } - const int16_t gx = scale_i32_to_i16_rounded(gp_in.gyro[0], 8); - const int16_t gy = scale_i32_to_i16_rounded(gp_in.gyro[1], 8); - const int16_t gz = scale_i32_to_i16_rounded(gp_in.gyro[2], 8); - const int16_t ax = scale_i32_to_i16_rounded(gp_in.accel[0], 64); - const int16_t ay = scale_i32_to_i16_rounded(gp_in.accel[1], 64); - const int16_t az = scale_i32_to_i16_rounded(gp_in.accel[2], 64); + int32_t accel[3] = {gp_in.accel[0], gp_in.accel[1], gp_in.accel[2]}; + int32_t gyro[3] = {gp_in.gyro[0], gp_in.gyro[1], gp_in.gyro[2]}; + MotionImu::remap_to_ds4_playing_frame(gp_in.motion_source, accel, gyro); + + const int16_t gx = scale_i32_to_i16_rounded(gyro[0], 8); + const int16_t gy = scale_i32_to_i16_rounded(gyro[1], 8); + const int16_t gz = scale_i32_to_i16_rounded(gyro[2], 8); + const int16_t ax = scale_i32_to_i16_rounded(accel[0], 64); + const int16_t ay = scale_i32_to_i16_rounded(accel[1], 64); + const int16_t az = scale_i32_to_i16_rounded(accel[2], 64); std::memcpy(&rep[13], &gx, 2); std::memcpy(&rep[15], &gy, 2); diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.cpp new file mode 100644 index 00000000..af08d321 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.cpp @@ -0,0 +1,172 @@ +#include +#include + +#include "USBDevice/DeviceDriver/Steam/Steam.h" +#include "USBDevice/DeviceDriver/Steam/SteamPassthrough.h" +#include "USBDevice/DeviceDriver/Steam/SteamTouchpad.h" +#include "USBDevice/DeviceDriver/Steam/SteamBtReport.h" +#include "Descriptors/PS5Usb.h" +#include "Descriptors/Steam.h" + +namespace { + +constexpr uint8_t kReportIdIn = 0x01; + +void init_neutral_report(std::array& rep) +{ + std::memset(rep.data(), 0, rep.size()); + rep[0] = kReportIdIn; + rep[1] = rep[2] = rep[3] = rep[4] = PS5::JOYSTICK_MID; +} + +} // namespace + +void SteamDevice::initialize() +{ + class_driver_ = { + .name = TUD_DRV_NAME("STEAM"), + .init = hidd_init, + .deinit = hidd_deinit, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL + }; + + std::memcpy(device_descriptor_, PS5Usb::DEVICE_DESCRIPTORS, sizeof(device_descriptor_)); + init_neutral_report(report_in_); + report_out_.report_id = PS5::OutReportID::RUMBLE; +} + +void SteamDevice::process(const uint8_t idx, Gamepad& gamepad) +{ + (void)idx; + + const Gamepad::PadIn gp_in = gamepad.get_pad_in(); + + if (!SteamPassthrough::input_has_touchpad) { + PS5::InReport rep{}; + SteamBtReport::fill_report_from_pad(rep, gp_in, gamepad); + std::memcpy(report_in_.data(), &rep, sizeof(rep)); + if (report_in_.size() > sizeof(rep)) { + std::memset(report_in_.data() + sizeof(rep), 0, report_in_.size() - sizeof(rep)); + } + /* Core1 passthrough uses raw host axes (no profile axis-restrict) for sticks/triggers. */ + if (SteamPassthrough::has_report) { + auto* out = reinterpret_cast(report_in_.data()); + const auto* raw = reinterpret_cast(SteamPassthrough::report); + out->joystick_rx = raw->joystick_rx; + out->joystick_ry = raw->joystick_ry; + out->trigger_l = raw->trigger_l; + out->trigger_r = raw->trigger_r; + } + } else if (SteamPassthrough::has_report) { + std::memcpy(report_in_.data(), SteamPassthrough::report, SteamPassthrough::USB_REPORT_SIZE); + } else { + init_neutral_report(report_in_); + } + + /* Mouse only from DualSense (or other) touchpad — no right-stick mouse fallback. */ + if (SteamPassthrough::input_has_touchpad) { + SteamTouchpad::send_mouse_from_report(report_in_.data()); + } + + if (tud_hid_n_ready(Steam::ITF_GAMEPAD)) { + tud_hid_n_report(Steam::ITF_GAMEPAD, 0, report_in_.data(), static_cast(report_in_.size())); + } + + if (new_report_out_) { + Gamepad::PadOut gp_out; + gp_out.rumble_l = report_out_.motor_left; + gp_out.rumble_r = report_out_.motor_right; + gamepad.set_pad_out(gp_out); + new_report_out_ = false; + } +} + +uint16_t SteamDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) +{ + if (report_type == HID_REPORT_TYPE_INPUT) { + if (itf == Steam::ITF_MOUSE) { + const uint16_t n = static_cast(std::min(reqlen, 4)); + std::memset(buffer, 0, n); + const uint16_t copy = static_cast(std::min(n, sizeof(SteamTouchpad::last_mouse_report))); + std::memcpy(buffer, SteamTouchpad::last_mouse_report, copy); + return n; + } + if (itf == Steam::ITF_GAMEPAD && (report_id == 0 || report_id == kReportIdIn)) { + const uint16_t n = static_cast(std::min(reqlen, report_in_.size())); + std::memcpy(buffer, report_in_.data(), n); + return n; + } + } else if (report_type == HID_REPORT_TYPE_FEATURE) { + std::memset(buffer, 0, reqlen); + return reqlen; + } + return 0; +} + +void SteamDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) +{ + if (itf != Steam::ITF_GAMEPAD || report_type != HID_REPORT_TYPE_OUTPUT) { + return; + } + + uint8_t rid = report_id; + const uint8_t *buf = buffer; + uint16_t len = bufsize; + if (rid == 0 && len > 0) { + rid = buffer[0]; + len = static_cast(len - 1u); + buf = &buffer[1]; + } + + if ((rid == PS5::OutReportID::RUMBLE || rid == PS5::OutReportID::CONTROL) && + len >= sizeof(PS5::OutReport)) { + std::memcpy(&report_out_, buf, sizeof(PS5::OutReport)); + new_report_out_ = true; + } +} + +bool SteamDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +{ + (void)rhport; + (void)stage; + (void)request; + return false; +} + +const uint16_t* SteamDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + const char *value = reinterpret_cast(PS5Usb::STRING_DESCRIPTORS[index]); + return get_string_descriptor(value, index); +} + +const uint8_t* SteamDevice::get_descriptor_device_cb() +{ + device_descriptor_[8] = static_cast(SteamPassthrough::host_vid & 0xFF); + device_descriptor_[9] = static_cast((SteamPassthrough::host_vid >> 8) & 0xFF); + device_descriptor_[10] = static_cast(SteamPassthrough::host_pid & 0xFF); + device_descriptor_[11] = static_cast((SteamPassthrough::host_pid >> 8) & 0xFF); + return device_descriptor_; +} + +const uint8_t* SteamDevice::get_hid_descriptor_report_cb(uint8_t itf) +{ + if (itf == Steam::ITF_MOUSE) { + return Steam::MOUSE_REPORT_DESCRIPTORS; + } + return PS5Usb::REPORT_DESCRIPTORS; +} + +const uint8_t* SteamDevice::get_descriptor_configuration_cb(uint8_t index) +{ + (void)index; + return Steam::CONFIGURATION_DESCRIPTORS; +} + +const uint8_t* SteamDevice::get_descriptor_device_qualifier_cb() +{ + return nullptr; +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.h new file mode 100644 index 00000000..168955ac --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/Steam.h @@ -0,0 +1,32 @@ +#ifndef _STEAM_DEVICE_H_ +#define _STEAM_DEVICE_H_ + +#include +#include + +#include "USBDevice/DeviceDriver/DeviceDriver.h" +#include "Descriptors/PS5.h" +#include "USBDevice/DeviceDriver/Steam/SteamPassthrough.h" + +class SteamDevice : public DeviceDriver +{ +public: + void initialize() override; + void process(const uint8_t idx, Gamepad& gamepad) override; + uint16_t get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) override; + void set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) override; + bool vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) override; + const uint16_t* get_descriptor_string_cb(uint8_t index, uint16_t langid) override; + const uint8_t* get_descriptor_device_cb() override; + const uint8_t* get_hid_descriptor_report_cb(uint8_t itf) override; + const uint8_t* get_descriptor_configuration_cb(uint8_t index) override; + const uint8_t* get_descriptor_device_qualifier_cb() override; + +private: + std::array report_in_{}; + PS5::OutReport report_out_{}; + bool new_report_out_{false}; + uint8_t device_descriptor_[18]{}; +}; + +#endif diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamActive.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamActive.h new file mode 100644 index 00000000..300566ed --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamActive.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +/** True while the USB output driver is SteamDevice (touchpad → HID mouse). */ +namespace SteamActive +{ + inline std::atomic enabled{false}; + + inline void set(bool on) + { + enabled.store(on, std::memory_order_release); + } + + inline bool is_enabled() + { + return enabled.load(std::memory_order_acquire); + } +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamBtReport.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamBtReport.h new file mode 100644 index 00000000..fa241fd0 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamBtReport.h @@ -0,0 +1,234 @@ +#pragma once + +#include +#include +#include + +#include "Descriptors/PS5.h" +#include "Gamepad/Gamepad.h" +#include "USBDevice/DeviceDriver/Steam/SteamPassthrough.h" + +#if defined(CONFIG_EN_BLUETOOTH) +#include "controller/uni_gamepad.h" +#endif + +namespace SteamBtReport +{ + +#if defined(CONFIG_EN_BLUETOOTH) + +inline uint8_t ps5_stick_byte(int32_t axis) +{ + int32_t b = axis / 4 + 127; + if (b < 0) { + return 0; + } + if (b > 255) { + return 255; + } + return static_cast(b); +} + +inline uint8_t ps5_trigger_byte(int32_t value) +{ + int32_t b = value >> 2; + if (b < 0) { + return 0; + } + if (b > 255) { + return 255; + } + return static_cast(b); +} + +inline void update_from_uni_gamepad(const uni_gamepad_t* gp) +{ + PS5::InReport rep{}; + rep.report_id = 0x01; + rep.joystick_lx = ps5_stick_byte(gp->axis_x); + rep.joystick_ly = ps5_stick_byte(gp->axis_y); + rep.joystick_rx = ps5_stick_byte(gp->axis_rx); + rep.joystick_ry = ps5_stick_byte(gp->axis_ry); + rep.trigger_l = ps5_trigger_byte(gp->brake); + rep.trigger_r = ps5_trigger_byte(gp->throttle); + + uint8_t b0 = PS5::Buttons0::DPAD_CENTER; + switch (gp->dpad) { + case DPAD_UP: + b0 = PS5::Buttons0::DPAD_UP; + break; + case DPAD_DOWN: + b0 = PS5::Buttons0::DPAD_DOWN; + break; + case DPAD_LEFT: + b0 = PS5::Buttons0::DPAD_LEFT; + break; + case DPAD_RIGHT: + b0 = PS5::Buttons0::DPAD_RIGHT; + break; + case DPAD_UP | DPAD_RIGHT: + b0 = PS5::Buttons0::DPAD_UP_RIGHT; + break; + case DPAD_DOWN | DPAD_RIGHT: + b0 = PS5::Buttons0::DPAD_RIGHT_DOWN; + break; + case DPAD_DOWN | DPAD_LEFT: + b0 = PS5::Buttons0::DPAD_DOWN_LEFT; + break; + case DPAD_UP | DPAD_LEFT: + b0 = PS5::Buttons0::DPAD_LEFT_UP; + break; + default: + break; + } + if (gp->buttons & BUTTON_X) { + b0 |= PS5::Buttons0::SQUARE; + } + if (gp->buttons & BUTTON_A) { + b0 |= PS5::Buttons0::CROSS; + } + if (gp->buttons & BUTTON_B) { + b0 |= PS5::Buttons0::CIRCLE; + } + if (gp->buttons & BUTTON_Y) { + b0 |= PS5::Buttons0::TRIANGLE; + } + rep.buttons[0] = b0; + + uint8_t b1 = 0; + if (gp->buttons & BUTTON_SHOULDER_L) { + b1 |= PS5::Buttons1::L1; + } + if (gp->buttons & BUTTON_SHOULDER_R) { + b1 |= PS5::Buttons1::R1; + } + if (gp->misc_buttons & MISC_BUTTON_BACK) { + b1 |= PS5::Buttons1::SHARE; + } + if (gp->misc_buttons & MISC_BUTTON_START) { + b1 |= PS5::Buttons1::OPTIONS; + } + if (gp->buttons & BUTTON_THUMB_L) { + b1 |= PS5::Buttons1::L3; + } + if (gp->buttons & BUTTON_THUMB_R) { + b1 |= PS5::Buttons1::R3; + } + rep.buttons[1] = b1; + + uint8_t b2 = 0; + if (gp->misc_buttons & MISC_BUTTON_SYSTEM) { + b2 |= PS5::Buttons2::PS; + } + if (gp->misc_buttons & MISC_BUTTON_CAPTURE) { + b2 |= PS5::Buttons2::MUTE; + } + rep.buttons[2] = b2; + + uint8_t buf[SteamPassthrough::USB_REPORT_SIZE]{}; + std::memcpy(buf, &rep, sizeof(rep)); + SteamPassthrough::store(buf, sizeof(buf)); +} + +#endif /* CONFIG_EN_BLUETOOTH */ + +inline uint8_t pad_stick_byte(int16_t axis) +{ + int32_t scaled = (static_cast(axis) + 32768) * 255 / 65535; + if (scaled < 0) { + return 0; + } + if (scaled > 255) { + return 255; + } + return static_cast(scaled); +} + +inline void fill_report_from_pad(PS5::InReport& rep, const Gamepad::PadIn& gp_in, const Gamepad& gamepad) +{ + rep.report_id = 0x01; + rep.joystick_lx = pad_stick_byte(gp_in.joystick_lx); + rep.joystick_ly = pad_stick_byte(gp_in.joystick_ly); + rep.joystick_rx = pad_stick_byte(gp_in.joystick_rx); + rep.joystick_ry = pad_stick_byte(gp_in.joystick_ry); + rep.trigger_l = gp_in.trigger_l; + rep.trigger_r = gp_in.trigger_r; + + uint8_t b0 = PS5::Buttons0::DPAD_CENTER; + if (gp_in.dpad & gamepad.MAP_DPAD_UP) { + if (gp_in.dpad & gamepad.MAP_DPAD_LEFT) { + b0 = PS5::Buttons0::DPAD_LEFT_UP; + } else if (gp_in.dpad & gamepad.MAP_DPAD_RIGHT) { + b0 = PS5::Buttons0::DPAD_UP_RIGHT; + } else { + b0 = PS5::Buttons0::DPAD_UP; + } + } else if (gp_in.dpad & gamepad.MAP_DPAD_DOWN) { + if (gp_in.dpad & gamepad.MAP_DPAD_LEFT) { + b0 = PS5::Buttons0::DPAD_DOWN_LEFT; + } else if (gp_in.dpad & gamepad.MAP_DPAD_RIGHT) { + b0 = PS5::Buttons0::DPAD_RIGHT_DOWN; + } else { + b0 = PS5::Buttons0::DPAD_DOWN; + } + } else if (gp_in.dpad & gamepad.MAP_DPAD_LEFT) { + b0 = PS5::Buttons0::DPAD_LEFT; + } else if (gp_in.dpad & gamepad.MAP_DPAD_RIGHT) { + b0 = PS5::Buttons0::DPAD_RIGHT; + } + + if (gp_in.buttons & gamepad.MAP_BUTTON_X) { + b0 |= PS5::Buttons0::SQUARE; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_A) { + b0 |= PS5::Buttons0::CROSS; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_B) { + b0 |= PS5::Buttons0::CIRCLE; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_Y) { + b0 |= PS5::Buttons0::TRIANGLE; + } + rep.buttons[0] = b0; + + uint8_t b1 = 0; + if (gp_in.buttons & gamepad.MAP_BUTTON_LB) { + b1 |= PS5::Buttons1::L1; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_RB) { + b1 |= PS5::Buttons1::R1; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_BACK) { + b1 |= PS5::Buttons1::SHARE; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_START) { + b1 |= PS5::Buttons1::OPTIONS; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_L3) { + b1 |= PS5::Buttons1::L3; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_R3) { + b1 |= PS5::Buttons1::R3; + } + rep.buttons[1] = b1; + + uint8_t b2 = 0; + if (gp_in.buttons & gamepad.MAP_BUTTON_SYS) { + b2 |= PS5::Buttons2::PS; + } + if (gp_in.buttons & gamepad.MAP_BUTTON_MISC) { + b2 |= PS5::Buttons2::MUTE; + } + rep.buttons[2] = b2; +} + +inline void update_from_gamepad(Gamepad& gamepad) +{ + PS5::InReport rep{}; + fill_report_from_pad(rep, gamepad.get_pad_in(), gamepad); + uint8_t buf[SteamPassthrough::USB_REPORT_SIZE]{}; + std::memcpy(buf, &rep, sizeof(rep)); + SteamPassthrough::store(buf, sizeof(buf)); +} + +} // namespace SteamBtReport diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamInput.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamInput.h new file mode 100644 index 00000000..63f042f2 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamInput.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +/** Latest wired DualSense input for Steam mode touchpad → USB mouse (raw 64-byte wire layout). */ +namespace SteamInput +{ + static constexpr uint8_t USB_REPORT_SIZE = 64; + + inline uint8_t report[USB_REPORT_SIZE]{}; + inline volatile bool has_wired_report = false; + + inline void store_wired(const uint8_t* data, uint16_t len) + { + std::memset(report, 0, USB_REPORT_SIZE); + const uint16_t n = (len > USB_REPORT_SIZE) ? USB_REPORT_SIZE : len; + std::memcpy(report, data, n); + has_wired_report = true; + } + + inline void clear() + { + has_wired_report = false; + std::memset(report, 0, USB_REPORT_SIZE); + } +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamPassthrough.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamPassthrough.h new file mode 100644 index 00000000..c76b5f92 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamPassthrough.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +namespace SteamPassthrough +{ + static constexpr uint8_t USB_REPORT_SIZE = 64; + + inline uint8_t report[USB_REPORT_SIZE]{}; + inline volatile bool has_report = false; + /** Input device exposes a DualSense-style touchpad (BT or wired PS5). */ + inline volatile bool input_has_touchpad = false; + inline uint16_t host_vid = 0x054C; + inline uint16_t host_pid = 0x0CE6; + + inline void set_host_identity(uint16_t vid, uint16_t pid) + { + host_vid = vid; + host_pid = pid; + } + + inline void store(const uint8_t* data, uint16_t len) + { + std::memset(report, 0, USB_REPORT_SIZE); + const uint16_t n = (len > USB_REPORT_SIZE) ? USB_REPORT_SIZE : len; + std::memcpy(report, data, n); + has_report = true; + } + + inline void clear() + { + has_report = false; + input_has_touchpad = false; + std::memset(report, 0, USB_REPORT_SIZE); + } +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchCache.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchCache.h new file mode 100644 index 00000000..062db109 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchCache.h @@ -0,0 +1,76 @@ +#pragma once + +#include +#include +#include + +#include "USBDevice/DeviceDriver/Steam/SteamTouchpad.h" + +/** Core1 (Bluepad32) writes, Core0 (SteamDevice) reads — DualSense touchpad samples. */ +namespace SteamTouchCache +{ + inline uint8_t touch_points[8]{}; + inline uint8_t usb_report[64]{}; + inline bool touchpad_click = false; + inline std::atomic generation{0}; + + inline void store(const uint8_t points[8], bool click) + { + std::memcpy(touch_points, points, 8); + touchpad_click = click; + + std::memset(usb_report, 0, sizeof(usb_report)); + usb_report[0] = 0x01; + std::memcpy(&usb_report[SteamTouchpad::kReportTouchPointsOffset], points, 8); + if (click) { + usb_report[10] |= 0x02; /* PS5::Buttons2::TP */ + } + + generation.fetch_add(1, std::memory_order_release); + } + + /** Decode touch from a raw DualSense 0x31 Bluetooth input report. */ + inline void store_from_bt_report(const uint8_t* report, uint16_t len) + { + if (!report || len < 42 || report[0] != 0x31) { + return; + } + enum { kTouchOffset = 34 }; + if (len < kTouchOffset + 8) { + return; + } + const bool click = (len >= 12) ? ((report[11] & 0x02) != 0) : false; + store(&report[kTouchOffset], click); + } + + inline void clear() + { + touch_points[0] = 0x80; + touch_points[1] = touch_points[2] = touch_points[3] = 0; + touch_points[4] = 0x80; + touch_points[5] = touch_points[6] = touch_points[7] = 0; + touchpad_click = false; + std::memset(usb_report, 0, sizeof(usb_report)); + generation.store(0, std::memory_order_release); + } + + /** Returns false if no sample has been stored yet. */ + inline bool load(uint8_t out_points[8], bool& click) + { + for (int attempt = 0; attempt < 4; ++attempt) { + const uint32_t gen_before = generation.load(std::memory_order_acquire); + if (gen_before == 0) { + return false; + } + std::memcpy(out_points, touch_points, 8); + click = touchpad_click; + const uint32_t gen_after = generation.load(std::memory_order_acquire); + if (gen_before == gen_after) { + return true; + } + } + std::memcpy(out_points, touch_points, 8); + click = touchpad_click; + return generation.load(std::memory_order_acquire) != 0; + } +} diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.cpp new file mode 100644 index 00000000..c0eeb870 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.cpp @@ -0,0 +1,205 @@ +#include "USBDevice/DeviceDriver/Steam/SteamTouchpad.h" + +#include +#include + +#include "Descriptors/PS5.h" +#include "Descriptors/Steam.h" +#include "USBDevice/DeviceDriver/Steam/SteamPassthrough.h" +#include "tusb.h" + +namespace SteamTouchpad +{ + +uint8_t last_mouse_report[3]{}; + +namespace +{ + +constexpr int kDeltaDivisor = 1; +constexpr int kMaxDelta = 127; + +int clamp_delta(int v) +{ + if (v > kMaxDelta) { + return kMaxDelta; + } + if (v < -kMaxDelta) { + return -kMaxDelta; + } + return v; +} + +const uint8_t* touch_raw(const uint8_t report[64]) +{ + return &report[kReportTouchPointsOffset]; +} + +bool send_mouse_hid(uint8_t buttons, int8_t dx, int8_t dy) +{ + if (!tud_mounted() || !tud_hid_n_ready(Steam::ITF_MOUSE)) { + return false; + } + const uint8_t rep[3] = { + buttons, + static_cast(dx), + static_cast(dy), + }; + if (tud_hid_n_report(Steam::ITF_MOUSE, 0, rep, sizeof(rep))) { + std::memcpy(last_mouse_report, rep, sizeof(rep)); + return true; + } + return false; +} + +void send_mouse_deltas(uint8_t buttons, int cx, int cy, int& last_x, int& last_y, bool touching, + bool& was_touching, uint8_t& prev_buttons) +{ + int8_t dx = 0; + int8_t dy = 0; + + if (touching && was_touching && last_x >= 0) { + dx = static_cast(clamp_delta((cx - last_x) / kDeltaDivisor)); + dy = static_cast(clamp_delta((cy - last_y) / kDeltaDivisor)); + } + + if (dx != 0 || dy != 0 || buttons != prev_buttons) { + if (send_mouse_hid(buttons, dx, dy)) { + prev_buttons = buttons; + if (touching) { + last_x = cx; + last_y = cy; + } else { + last_x = -1; + last_y = -1; + } + was_touching = touching; + return; + } + } + + if (!touching) { + last_x = -1; + last_y = -1; + } + was_touching = touching; +} + +void decode_active_finger(const uint8_t touch_points[8], int& cx, int& cy, bool& touching) +{ + int x0 = 0; + int y0 = 0; + bool touch0 = false; + int x1 = 0; + int y1 = 0; + bool touch1 = false; + touchpoint_decode(&touch_points[0], x0, y0, touch0); + touchpoint_decode(&touch_points[4], x1, y1, touch1); + + touching = touch0 || touch1; + cx = touch0 ? x0 : x1; + cy = touch0 ? y0 : y1; +} + +} // namespace + +void touchpoint_decode(const uint8_t raw[4], int& x, int& y, bool& touching) +{ + touching = (raw[0] & 0x80) == 0; + const uint8_t x_lo = raw[1]; + const uint8_t x_hi = raw[2] & 0x0F; + const uint8_t y_lo = (raw[2] >> 4) & 0x0F; + const uint8_t y_hi = raw[3]; + x = (x_hi << 8) | x_lo; + y = (y_hi << 4) | y_lo; +} + +void touchpoint_encode(uint8_t raw[4], int x, int y, bool touching, uint8_t counter) +{ + if (x < 0) { + x = 0; + } + if (x > 1919) { + x = 1919; + } + if (y < 0) { + y = 0; + } + if (y > 1079) { + y = 1079; + } + raw[0] = static_cast((counter & 0x7F) | (touching ? 0 : 0x80)); + raw[1] = static_cast(x & 0xFF); + raw[2] = static_cast((x >> 8) & 0x0F) | static_cast((y & 0x0F) << 4); + raw[3] = static_cast((y >> 4) & 0xFF); +} + +void apply_to_passthrough(const uint8_t touch_points[8], bool touchpad_click) +{ + if (!SteamPassthrough::has_report) { + return; + } + + std::memcpy(&SteamPassthrough::report[kReportTouchPointsOffset], touch_points, 8); + + auto* in = reinterpret_cast(SteamPassthrough::report); + if (touchpad_click) { + in->buttons[2] |= static_cast(PS5::Buttons2::TP); + } else { + in->buttons[2] &= static_cast(~static_cast(PS5::Buttons2::TP)); + } +} + +void send_mouse_from_touch(const uint8_t touch_points[8], bool touchpad_click) +{ + static int last_x = -1; + static int last_y = -1; + static bool was_touching = false; + static uint8_t prev_buttons = 0; + + int cx = 0; + int cy = 0; + bool touching = false; + decode_active_finger(touch_points, cx, cy, touching); + + uint8_t buttons = touchpad_click ? 0x01u : 0x00u; + send_mouse_deltas(buttons, cx, cy, last_x, last_y, touching, was_touching, prev_buttons); +} + +void send_mouse_from_report(const uint8_t report[64]) +{ + const uint8_t* tp = touch_raw(report); + + int x0 = 0; + int y0 = 0; + bool touch0 = false; + int x1 = 0; + int y1 = 0; + bool touch1 = false; + touchpoint_decode(&tp[0], x0, y0, touch0); + touchpoint_decode(&tp[4], x1, y1, touch1); + + static int last_x = -1; + static int last_y = -1; + static bool was_touching = false; + static uint8_t prev_buttons = 0; + + const bool touching = touch0 || touch1; + const int cx = touch0 ? x0 : x1; + const int cy = touch0 ? y0 : y1; + + uint8_t buttons = 0; + const auto* in = reinterpret_cast(report); + if (in->buttons[2] & static_cast(PS5::Buttons2::TP)) { + buttons |= 0x01u; + } + + send_mouse_deltas(buttons, cx, cy, last_x, last_y, touching, was_touching, prev_buttons); +} + +bool send_mouse_packet(uint8_t buttons, int8_t dx, int8_t dy) +{ + return send_mouse_hid(buttons, dx, dy); +} + +} // namespace SteamTouchpad diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.h new file mode 100644 index 00000000..4d821fb7 --- /dev/null +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Steam/SteamTouchpad.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +namespace SteamTouchpad +{ + +/** First touch point in a 64-byte DualSense USB input report (report ID at [0]). */ +constexpr size_t kReportTouchPointsOffset = 33; + +void touchpoint_decode(const uint8_t raw[4], int& x, int& y, bool& touching); + +/** Encode one DualSense touch point (inverse of touchpoint_decode). */ +void touchpoint_encode(uint8_t raw[4], int x, int y, bool touching, uint8_t counter); + +/** Bluetooth: raw 8-byte touch region + physical click. */ +void send_mouse_from_touch(const uint8_t touch_points[8], bool touchpad_click); + +/** Wired USB: full 64-byte DualSense input report. */ +void send_mouse_from_report(const uint8_t report[64]); + +/** Merge touch bytes into the Steam passthrough USB input report. */ +void apply_to_passthrough(const uint8_t touch_points[8], bool touchpad_click); + +/** Last relative mouse HID packet sent (for GET_REPORT on interface 1). */ +extern uint8_t last_mouse_report[3]; + +/** Send a relative mouse HID report on the Steam mouse interface. */ +bool send_mouse_packet(uint8_t buttons, int8_t dx, int8_t dy); + +} // namespace SteamTouchpad diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp index e46b8be6..f240c09b 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.cpp @@ -10,6 +10,35 @@ namespace { constexpr uint8_t VIB_OPTS[4] = { 0x0A, 0x0C, 0x0B, 0x09 }; + + /** HD rumble motor block → 0–255 intensity (dekuNukem / Switch Pro reverse engineering). */ + uint8_t hd_rumble_amplitude(const uint8_t motor[4]) + { + if (motor[0] == 0x00 && motor[1] == 0x01 && motor[2] == 0x40 && motor[3] == 0x40) + return 0; + + const uint8_t hfa = static_cast((motor[1] >> 1) & 0x7F); + const uint16_t lfa = static_cast(motor[3] | ((static_cast(motor[2] & 0x80u)) << 1)); + + const uint8_t hfa_scaled = (hfa > 127) ? 255 : static_cast(hfa * 2); + const uint8_t lfa_scaled = (lfa > 255) ? 255 : static_cast(lfa); + return (hfa_scaled > lfa_scaled) ? hfa_scaled : lfa_scaled; + } + + bool is_rumble_output_cmd(uint8_t cmd) + { + return cmd == SwitchPro::REPORT_ID_OUTPUT_SUBCMD || + cmd == SwitchPro::REPORT_ID_OUTPUT_RUMBLE || + cmd == 0x11 || + cmd == SwitchPro::CMD::AND_RUMBLE; + } + + bool is_subcommand_output_cmd(uint8_t cmd) + { + return cmd == SwitchPro::REPORT_ID_OUTPUT_SUBCMD || + cmd == 0x11 || + cmd == SwitchPro::CMD::AND_RUMBLE; + } } void SwitchDevice::initialize() @@ -122,6 +151,7 @@ void SwitchDevice::build_standard_report(const SwitchPro::SwitchReport& sw) vibration_report_ = VIB_OPTS[vibration_idx_]; } report_[11] = vibration_report_; + /* IMU passthrough disabled for now (report bytes 12–47 stay zero). */ } void SwitchDevice::build_subcommand_reply(const SwitchPro::SwitchReport& sw) @@ -231,9 +261,47 @@ void SwitchDevice::build_subcommand_reply(const SwitchPro::SwitchReport& sw) } } +void SwitchDevice::parse_host_rumble(uint8_t report_id, uint8_t const* buffer, uint16_t bufsize) +{ + const uint8_t* motor_l = nullptr; + const uint8_t* motor_r = nullptr; + + /* OutReport layout: cmd, seq, rumble_l[4], rumble_r[4], … */ + if (bufsize >= 10 && is_rumble_output_cmd(buffer[0])) + { + motor_l = &buffer[2]; + motor_r = &buffer[6]; + } + /* TinyUSB stripped report ID: seq, rumble_l[4], rumble_r[4], … */ + else if (bufsize >= 9 && is_rumble_output_cmd(report_id)) + { + motor_l = &buffer[1]; + motor_r = &buffer[5]; + } + else + return; + + const uint8_t left = hd_rumble_amplitude(motor_l); + const uint8_t right = hd_rumble_amplitude(motor_r); + if (left == rumble_l_ && right == rumble_r_) + return; + rumble_l_ = left; + rumble_r_ = right; + rumble_dirty_ = true; +} + void SwitchDevice::process(const uint8_t idx, Gamepad& gamepad) { (void)idx; + if (rumble_dirty_) + { + Gamepad::PadOut gp_out; + gp_out.rumble_l = rumble_l_; + gp_out.rumble_r = rumble_r_; + gamepad.set_pad_out(gp_out); + rumble_dirty_ = false; + } + // Always read latest state and build report so get_report_cb and IN pushes both see current state (minimal latency). Gamepad::PadIn gp_in = gamepad.get_pad_in(); gamepad_to_switch_report(gp_in, switch_report_, gamepad); @@ -318,6 +386,9 @@ void SwitchDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type if (bufsize > SwitchPro::REPORT_SIZE) bufsize = SwitchPro::REPORT_SIZE; std::memcpy(pending_output_.data(), buffer, bufsize); + + parse_host_rumble(report_id, buffer, bufsize); + // USB init: 2-byte reports [0x80, subtype] require reply on report ID 0x81 (Chromium / Switch console). if (bufsize >= 2 && buffer[0] == 0x80) { @@ -333,10 +404,13 @@ void SwitchDevice::set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type } has_pending_81_ = true; } - // Only queue a subcommand reply when the report has a subcommand at byte 10 (len >= 11). + /* Subcommand reply only for rumble+subcmd reports — not rumble-only 0x10 (often 64-byte padded). */ else if (bufsize >= 11) - has_pending_output_ = true; - // Rumble: report_id 0x01/0x10/0x11, bytes 2-5 and 6-9 contain rumble data; we don't drive physical rumble here + { + const uint8_t cmd = (buffer[0] != 0) ? buffer[0] : report_id; + if (is_subcommand_output_cmd(cmd)) + has_pending_output_ = true; + } } bool SwitchDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) diff --git a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h index c9e32a3e..343191b4 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h +++ b/Firmware/RP2040/src/USBDevice/DeviceDriver/Switch/Switch.h @@ -27,6 +27,8 @@ class SwitchDevice : public DeviceDriver void build_standard_report(const SwitchPro::SwitchReport& sw); void build_subcommand_reply(const SwitchPro::SwitchReport& sw); void set_timer(); + /** Decode HD rumble from a console output report into rumble_l_/rumble_r_. */ + void parse_host_rumble(uint8_t report_id, uint8_t const* buffer, uint16_t bufsize); std::array report_{}; SwitchPro::SwitchReport switch_report_{}; @@ -40,6 +42,11 @@ class SwitchDevice : public DeviceDriver bool vibration_enabled_ = false; std::array addr_ = { 0x7C, 0xBB, 0x8A, 0x12, 0x34, 0x56 }; + // Latest rumble decoded from host 0x01/0x10/0x11 output; applied in process(). + uint8_t rumble_l_ = 0; + uint8_t rumble_r_ = 0; + bool rumble_dirty_ = false; + // USB init handshake: reply to 0x80 0x01 (MAC), 0x80 0x02 (handshake), 0x80 0x04/0x05 (timeout) std::array report_81_{}; bool has_pending_81_ = false; diff --git a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp index d6bd9c4b..4dd2304e 100644 --- a/Firmware/RP2040/src/USBDevice/DeviceManager.cpp +++ b/Firmware/RP2040/src/USBDevice/DeviceManager.cpp @@ -9,6 +9,9 @@ #include "USBDevice/DeviceDriver/DInput/DInput.h" #include "USBDevice/DeviceDriver/PS3/PS3.h" #include "USBDevice/DeviceDriver/PS4/PS4.h" +#include "USBDevice/DeviceDriver/Steam/Steam.h" +#include "USBDevice/DeviceDriver/Steam/SteamActive.h" +#include "USBDevice/DeviceDriver/MotionOutputActive.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_GP.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_SB.h" #include "USBDevice/DeviceDriver/XboxOG/XboxOG_XR.h" @@ -28,6 +31,9 @@ void DeviceManager::initialize_driver( DeviceDriverType driver_type, //TODO: Put gamepad setup in the drivers themselves bool has_analog = false; current_driver_type_ = driver_type; + SteamActive::set(driver_type == DeviceDriverType::STEAM); + MotionOutputActive::set(driver_type == DeviceDriverType::PS3 || + driver_type == DeviceDriverType::PS4); printf("Attempting to allocate driver\n"); @@ -47,6 +53,11 @@ void DeviceManager::initialize_driver( DeviceDriverType driver_type, has_analog = true; device_driver_ = std::make_unique(); break; + case DeviceDriverType::STEAM: + printf("STEAM Loaded\n"); + has_analog = true; + device_driver_ = std::make_unique(); + break; case DeviceDriverType::PSCLASSIC: printf("PSCLASSIC Loaded\n"); device_driver_ = std::make_unique(); diff --git a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp index ed0df738..e929adec 100644 --- a/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp +++ b/Firmware/RP2040/src/USBDevice/tud_callbacks.cpp @@ -8,6 +8,10 @@ #include "USBDevice/DeviceManager.h" #include "USBDevice/DeviceDriver/DeviceDriverTypes.h" +#if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) +#include "Bluepad32/Bluepad32.h" +#endif + const usbd_class_driver_t *usbd_app_driver_get_cb(uint8_t *driver_count) { DeviceDriverType dt = DeviceManager::get_instance().get_driver_type(); @@ -61,4 +65,10 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) uint8_t const* tud_descriptor_device_qualifier_cb() { return DeviceManager::get_instance().get_driver()->get_descriptor_device_qualifier_cb(); -} \ No newline at end of file +} + +#if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) +void tud_resume_cb(void) { + bluepad32::on_usb_device_resume(); +} +#endif \ No newline at end of file diff --git a/Firmware/RP2040/src/USBHost/HardwareIDs.h b/Firmware/RP2040/src/USBHost/HardwareIDs.h index ace3c584..c18b2db1 100644 --- a/Firmware/RP2040/src/USBHost/HardwareIDs.h +++ b/Firmware/RP2040/src/USBHost/HardwareIDs.h @@ -121,15 +121,12 @@ static const HardwareID DINPUT_IDS[] = {0x0F0D, 0x0011}, // Hori Real Arcade Pro 3 {0x0F0D, 0x0026}, // Hori Real Arcade Pro 3P {0x0F0D, 0x004B}, // Hori Real Arcade Pro 3W - {0x0F0D, 0x006A}, // Hori Real Arcade Pro 4 - {0x0F0D, 0x006B}, // Hori Real Arcade Pro 4 - {0x0F0D, 0x008A}, // Hori Real Arcade Pro 4 - {0x0F0D, 0x008B}, // Hori Real Arcade Pro 4 + // RAP4 PS3 (0x006A/0x006B) are in PS3_IDS. RAP4/RAP4 Kai PS4 (0x008A/0x008B) are in PS4_IDS. + // RAP4 PC/XInput (0x008C) is unlisted so tuh_xinput or HIDGeneric can claim it. {0x0F0D, 0x006F}, // Hori Real Arcade Pro 4 VLX {0x0F0D, 0x0070}, // Hori Real Arcade Pro 4 VLX {0x0F0D, 0x003D}, // Hori Real Arcade Pro N3 {0x0F0D, 0x00AE}, // Hori Real Arcade Pro N4 - {0x0F0D, 0x008C}, // Hori Real Arcade Pro P4 {0x0F0D, 0x00AA}, // Hori Real Arcade Pro S {0x0F0D, 0x00D8}, // Hori Real Arcade Pro S {0x0F0D, 0x0022}, // Hori Real Arcade Pro V3 @@ -169,23 +166,10 @@ static const HardwareID DINPUT_IDS[] = {0x3507, 0x0004}, // Zenaim Arcade Controller {0x1C1A, 0x0100}, // Datel Arcade Joystick {0x0E6F, 0x0185}, // PDP Fightpad Pro GameCube - // PowerA (PC/Xbox-style from SDL_GameControllerDB; Switch PowerA are in SWITCH_WIRED_IDS) - {0x20D6, 0xA711}, // PowerA Core Controller (HID/DInput; same VID:PID as OpenSteamController emulation) - {0x20D6, 0x4033}, // PowerA OPS Pro Wireless Controller - {0x20D6, 0x4026}, // PowerA OPS Wireless Controller - {0x20D6, 0xCA6D}, // PowerA Pro Ex - {0x24C6, 0x543A}, // PowerA Xbox One (Mac/HID) - {0x20D6, 0x4050}, // PowerA Advantage Xbox Series (Linux/HID) - {0x20D6, 0x4001}, // PowerA Fusion Pro 2 (Linux/HID) - {0x24C6, 0x531A}, // PowerA Mini Pro Ex (Linux/HID) - {0x20D6, 0x2002}, // PowerA Xbox One Controller (Linux/HID) - {0x20D6, 0x2828}, // PowerA Xbox One Controller (Linux/HID) - {0x24C6, 0x581A}, // PowerA Xbox One (Linux/HID) - {0x20D6, 0x4002}, // PowerA Xbox One Spectra Infinity (Linux/HID) - {0x20D6, 0x2050}, // PowerA Xbox Series Controller (Linux/HID) - {0x20D6, 0x2064}, // PowerA Xbox Series X Wired Controller (e.g. Red) - {0x20D6, 0x200B}, // PowerA Xbox Series Controller (Linux/HID) - {0x20D6, 0x200F}, // PowerA Xbox Series Controller (Linux/HID) + // PowerA Switch-mode pads are in SWITCH_WIRED_IDS (SwitchWiredHost). + // PowerA Xbox/PC pads are intentionally *not* listed here: DInputHost uses a fixed + // PS3-style report layout. On Sakura's minimal ID list these fall through to HIDGeneric + // (descriptor parse) or tuh_xinput — both work. Forcing DINPUT breaks them. // Elecom (from SDL_GameControllerDB) {0x056E, 0x200A}, // Elecom DUX60 MMO {0x056E, 0x2003}, // Elecom U3613M @@ -293,6 +277,8 @@ static const HardwareID PS3_IDS[] = {0x0F0D, 0x0051}, // Hori Fighting Commander PS3 {0x0F0D, 0x0088}, // Hori Fighting Stick mini 4 PS3 {0x0F0D, 0x006E}, // Horipad 4 PS3 + {0x0F0D, 0x006A}, // Hori Real Arcade Pro 4 PS3 + {0x0F0D, 0x006B}, // Hori Real Arcade Pro 4 PS3 (alt) {0x0E6F, 0x0124}, // Injustice Fightstick PS3 {0x0079, 0x0002}, // King PS3 {0x0738, 0x8838}, // Mad Catz Arcade Fightstick TE S+ PS3 @@ -334,6 +320,8 @@ static const HardwareID PS4_IDS[] = {0x2563, 0x0357}, // MPOW Wired Gamepad (ShenZhen ShanWan) {0x0F0D, 0x005E}, // Hori Fighting Commander 4 PS4 {0x0F0D, 0x00EE}, // Hori PS4 Mini (PS4-099U) + {0x0F0D, 0x008A}, // Hori Real Arcade Pro 4 / RAP4 Kai (PS4 mode) + {0x0F0D, 0x008B}, // Hori Real Arcade Pro 4 (PS4 mode alt) {0x1F4F, 0x1002}, // ASW GG Xrd controller {0x9886, 0x0025}, // Astro C40 TR PS4 {0x20D6, 0x792A}, // BDA PS4 Fightpad diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp index a7e9f831..a3e7b193 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.cpp @@ -80,30 +80,27 @@ bool PS3Host::local_bt_addr_is_nonzero(const uint8_t addr[6]) { return false; } -void PS3Host::bt_pair_complete_cb(tuh_xfer_s* xfer) { - auto* init_state = reinterpret_cast(xfer->user_data); - if (init_state == nullptr) { - return; +bool PS3Host::program_ds3_bt_host(uint8_t address) { + uni_bt_bd_addr_t addr{}; + uni_bt_get_local_bd_addr_safe(addr); + if (!local_bt_addr_is_nonzero(addr)) { + return false; } - init_state->stage = InitStage::DONE; - init_state->reports_enabled = true; - send_control_output_async(init_state->dev_addr, init_state->out_report); + bt_pair_buf_[0] = 0xF5; + bt_pair_buf_[1] = 0; + std::memcpy(bt_pair_buf_.data() + 2, addr, 6); + /* Sync transfer: PIO USB needs pio_usb_host_frame() while control completes. */ + (void)send_control_xfer_wait(address, &BT_MAC_FEATURE_REQUEST, bt_pair_buf_.data(), 150u); + return true; } void PS3Host::try_deferred_ds3_bt_pair(uint8_t address) { if (!ds3_bt_pair_deferred_) { return; } - uni_bt_bd_addr_t addr{}; - uni_bt_get_local_bd_addr_safe(addr); - if (!local_bt_addr_is_nonzero(addr)) { - return; + if (program_ds3_bt_host(address)) { + ds3_bt_pair_deferred_ = false; } - ds3_bt_pair_deferred_ = false; - bt_pair_buf_[0] = 0xF5; - bt_pair_buf_[1] = 0; - std::memcpy(bt_pair_buf_.data() + 2, addr, 6); - (void)send_control_xfer(address, &BT_MAC_FEATURE_REQUEST, bt_pair_buf_.data(), nullptr, 0); } #endif @@ -159,26 +156,6 @@ bool PS3Host::send_control_output_async(uint8_t address, PS3::OutReport* report) return send_control_xfer(address, &RUMBLE_REQUEST, reinterpret_cast(report), nullptr, 0); } -void PS3Host::send_init_get_report(InitState* init_state) -{ - if (init_state == nullptr) - { - return; - } - - tusb_control_request_t init_request = - { - .bmRequestType = 0xA1, - .bRequest = 0x01, // GET_REPORT - .wValue = (HID_REPORT_TYPE_FEATURE << 8) | 0xF2, - .wIndex = 0x0000, - .wLength = (init_state->stage == InitStage::RESP3) ? static_cast(8) : static_cast(17) - }; - - send_control_xfer(init_state->dev_addr, &init_request, init_state->init_buffer.data(), get_report_complete_cb, - reinterpret_cast(init_state)); -} - void PS3Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { (void)report_desc; @@ -187,13 +164,8 @@ void PS3Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, co gamepad.set_analog_host(true); init_host_out_report(out_report_, idx_); - - init_state_ = InitState{}; - init_state_.out_report = &out_report_; - init_state_.dev_addr = address; - init_state_.usb_instance = instance; + reports_enabled_ = false; #if defined(CONFIG_EN_BLUETOOTH) - init_state_.defer_bt_pair = &ds3_bt_pair_deferred_; ds3_bt_pair_deferred_ = false; #endif @@ -202,70 +174,18 @@ void PS3Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, co (void)send_control_xfer_wait(address, &ENABLE_USB_REQUEST, enable_usb_data, 150u); (void)send_control_output_sync(address, &out_report_); - init_state_.reports_enabled = true; - init_state_.stage = InitStage::DONE; - last_keepalive_ms_ = time_us_32() / 1000; - #if defined(CONFIG_EN_BLUETOOTH) - send_init_get_report(&init_state_); -#endif - - tuh_hid_receive_report(address, instance); -} - -void PS3Host::get_report_complete_cb(tuh_xfer_s *xfer) -{ - InitState* init_state = reinterpret_cast(xfer->user_data); - if (init_state == nullptr || init_state->stage == InitStage::DONE) - { - return; + /* Program master BD_ADDR so the pad can reconnect wirelessly after unplug (sixaxispairer). + * Must run here — the old GET 0xF2 async chain was skipped once wired init marked DONE. */ + if (!program_ds3_bt_host(address)) { + ds3_bt_pair_deferred_ = true; } +#endif - if (xfer->result != XFER_RESULT_SUCCESS) - { - if (init_state->init_retries < MAX_INIT_RETRIES) - { - ++init_state->init_retries; - send_init_get_report(init_state); - } - return; - } - init_state->init_retries = 0; + reports_enabled_ = true; + last_keepalive_ms_ = time_us_32() / 1000; - switch (init_state->stage) - { - case InitStage::RESP1: - init_state->stage = InitStage::RESP2; - send_init_get_report(init_state); - break; - case InitStage::RESP2: - init_state->stage = InitStage::RESP3; - send_init_get_report(init_state); - break; - case InitStage::RESP3: -#if defined(CONFIG_EN_BLUETOOTH) - { - uni_bt_bd_addr_t addr{}; - uni_bt_get_local_bd_addr_safe(addr); - if (local_bt_addr_is_nonzero(addr)) { - init_state->bt_pair_report[0] = 0xF5; - init_state->bt_pair_report[1] = 0; - std::memcpy(init_state->bt_pair_report.data() + 2, addr, 6); - send_control_xfer(init_state->dev_addr, &BT_MAC_FEATURE_REQUEST, init_state->bt_pair_report.data(), bt_pair_complete_cb, xfer->user_data); - break; - } - if (init_state->defer_bt_pair != nullptr) { - *init_state->defer_bt_pair = true; - } - } -#endif - init_state->stage = InitStage::DONE; - init_state->reports_enabled = true; - send_control_output_async(init_state->dev_addr, init_state->out_report); - break; - default: - break; - } + tuh_hid_receive_report(address, instance); } void PS3Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report, uint16_t len) @@ -329,7 +249,7 @@ bool PS3Host::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) { (void)instance; - if (!init_state_.reports_enabled) { + if (!reports_enabled_) { return false; } diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h index 9ea55218..3f88feb1 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS3/PS3.h @@ -20,41 +20,28 @@ class PS3Host : public HostDriver bool send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) override; private: - enum class InitStage { RESP1, RESP2, RESP3, DONE }; - - struct InitState - { - uint8_t dev_addr{0xFF}; - InitStage stage{InitStage::RESP1}; - uint8_t init_retries{0}; - std::array init_buffer; - std::array bt_pair_report{}; - PS3::OutReport* out_report{nullptr}; - uint8_t usb_instance{0}; - bool reports_enabled{false}; - /** If set, points to PS3Host::ds3_bt_pair_deferred_ — BT addr was not ready during init. */ - bool* defer_bt_pair{nullptr}; - }; - - static constexpr uint8_t MAX_INIT_RETRIES = 3; - - static void send_init_get_report(InitState* init_state); static void init_host_out_report(PS3::OutReport& out, uint8_t player_idx); static bool send_control_xfer_wait(uint8_t dev_addr, const tusb_control_request_t* req, uint8_t* buffer, uint32_t max_attempts_ms); static bool send_control_output_sync(uint8_t address, PS3::OutReport* report); static bool send_control_output_async(uint8_t address, PS3::OutReport* report); + static bool send_control_xfer(uint8_t dev_addr, const tusb_control_request_t* req, uint8_t* buffer, + tuh_xfer_cb_t complete_cb, uintptr_t user_data); static const tusb_control_request_t ENABLE_USB_REQUEST; static const tusb_control_request_t RUMBLE_REQUEST; #if defined(CONFIG_EN_BLUETOOTH) /** HID feature report: program DualShock 3 master Bluetooth address (see Bluepad32 sixaxispairer). */ static const tusb_control_request_t BT_MAC_FEATURE_REQUEST; + static bool local_bt_addr_is_nonzero(const uint8_t addr[6]); + /** SET feature 0xF5 with local BD_ADDR; returns false if address not ready yet. */ + bool program_ds3_bt_host(uint8_t address); + void try_deferred_ds3_bt_pair(uint8_t address); #endif PS3::InReport prev_in_report_; PS3::OutReport out_report_; - InitState init_state_; + bool reports_enabled_{false}; uint32_t last_keepalive_ms_{0}; #if defined(CONFIG_EN_USB_HOST) static constexpr uint32_t KEEPALIVE_MS = 1000u; @@ -62,18 +49,10 @@ class PS3Host : public HostDriver static constexpr uint32_t KEEPALIVE_MS = 0u; #endif #if defined(CONFIG_EN_BLUETOOTH) - /** Persistent buffer for async SET_REPORT (feature 0xF5). */ + /** Persistent buffer for SET_REPORT (feature 0xF5). */ std::array bt_pair_buf_{}; bool ds3_bt_pair_deferred_{false}; #endif - - static bool send_control_xfer(uint8_t dev_addr, const tusb_control_request_t* req, uint8_t* buffer, tuh_xfer_cb_t complete_cb, uintptr_t user_data); - static void get_report_complete_cb(tuh_xfer_s *xfer); -#if defined(CONFIG_EN_BLUETOOTH) - static void bt_pair_complete_cb(tuh_xfer_s* xfer); - static bool local_bt_addr_is_nonzero(const uint8_t addr[6]); - void try_deferred_ds3_bt_pair(uint8_t address); -#endif }; -#endif // _PS3_HOST_H_ \ No newline at end of file +#endif // _PS3_HOST_H_ diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp index 9d09d983..aecf3d29 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.cpp @@ -10,6 +10,7 @@ #endif #include "USBHost/HostDriver/PS4/PS4.h" +#include "Gamepad/MotionImu.h" void PS4Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { @@ -44,7 +45,13 @@ void PS4Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance { std::memcpy(&in_report_, report, std::min(static_cast(len), sizeof(PS4::InReport))); in_report_.buttons[2] &= static_cast(~PS4::COUNTER_MASK); - if (std::memcmp(reinterpret_cast(report), &prev_in_report_, sizeof(PS4::InReport)) == 0) + + bool imu_same = true; + if (len >= 25) { + imu_same = std::memcmp(&report[13], prev_imu_, sizeof(prev_imu_)) == 0; + } + if (std::memcmp(reinterpret_cast(report), &prev_in_report_, sizeof(PS4::InReport)) == 0 && + imu_same) { tuh_hid_receive_report(address, instance); return; @@ -101,10 +108,18 @@ void PS4Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report_.joystick_lx, in_report_.joystick_ly); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report_.joystick_rx, in_report_.joystick_ry); + if (len >= 25) { + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_DS4_USB; + MotionImu::fill_from_ds4_usb_report(gp_in.accel, gp_in.gyro, report); + } + gamepad.set_pad_in(gp_in); tuh_hid_receive_report(address, instance); std::memcpy(&prev_in_report_, &in_report_, sizeof(PS4::InReport)); + if (len >= 25) { + std::memcpy(prev_imu_, &report[13], sizeof(prev_imu_)); + } } bool PS4Host::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.h b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.h index f12547d2..81b61227 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS4/PS4.h @@ -19,6 +19,7 @@ class PS4Host : public HostDriver private: PS4::InReport in_report_{}; PS4::InReport prev_in_report_{}; + uint8_t prev_imu_[12]{}; PS4::OutReport out_report_{}; }; diff --git a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp index b646c007..2f0a27d6 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/PS5/PS5.cpp @@ -3,7 +3,11 @@ #include "host/usbh.h" #include "class/hid/hid_host.h" +#include "USBDevice/DeviceDriver/DeviceDriverTypes.h" +#include "USBDevice/DeviceDriver/Steam/SteamPassthrough.h" +#include "USBDevice/DeviceManager.h" #include "USBHost/HostDriver/PS5/PS5.h" +#include "Gamepad/MotionImu.h" void PS5Host::initialize(Gamepad& gamepad, uint8_t address, uint8_t instance, const uint8_t* report_desc, uint16_t desc_len) { @@ -81,11 +85,16 @@ void PS5Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance if (in_report->buttons[1] & PS5::Buttons1::SHARE) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; if (in_report->buttons[1] & PS5::Buttons1::OPTIONS) gp_in.buttons |= gamepad.MAP_BUTTON_START; if (in_report->buttons[2] & PS5::Buttons2::PS) gp_in.buttons |= gamepad.MAP_BUTTON_SYS; - if (in_report->buttons[2] & PS5::Buttons2::TP) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; // Touchpad press - if (in_report->buttons[2] & PS5::Buttons2::MUTE) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; // Mute button - // Touchpad finger touch (no click) – report has two points - if (in_report->points[0].touching || in_report->points[1].touching) + if (in_report->buttons[2] & PS5::Buttons2::MUTE) gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + + if (DeviceManager::get_instance().get_driver_type() == DeviceDriverType::STEAM) { + SteamPassthrough::input_has_touchpad = true; + SteamPassthrough::store(report, len); + } + + if (in_report->points[0].touching || in_report->points[1].touching) { gp_in.buttons |= gamepad.MAP_BUTTON_MISC; + } gp_in.trigger_l = gamepad.scale_trigger_l(in_report->trigger_l); gp_in.trigger_r = gamepad.scale_trigger_r(in_report->trigger_r); @@ -93,12 +102,9 @@ void PS5Host::process_report(Gamepad& gamepad, uint8_t address, uint8_t instance std::tie(gp_in.joystick_lx, gp_in.joystick_ly) = gamepad.scale_joystick_l(in_report->joystick_lx, in_report->joystick_ly); std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(in_report->joystick_rx, in_report->joystick_ry); - /* DualSense USB: map motion for PS3 gadget path (same int16 sensor layout as DS5 HID). */ + /* DualSense USB: normalize raw HID IMU to Bluepad DS4 units for PS3/PS4 gadget output. */ gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_DS5_USB; - for (int i = 0; i < 3; i++) { - gp_in.accel[i] = static_cast(static_cast(in_report->accel[i])); - gp_in.gyro[i] = static_cast(static_cast(in_report->gyro[i])); - } + MotionImu::fill_from_ds5_usb_raw(gp_in.accel, gp_in.gyro, in_report->accel, in_report->gyro); gamepad.set_pad_in(gp_in); diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp index e2244bbe..80147650 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.cpp @@ -7,6 +7,7 @@ #include "USBHost/HostDriver/SwitchPro/Switch2ProHost.h" #include "Board/ogxm_log.h" +#include "Gamepad/MotionImu.h" namespace { @@ -95,7 +96,8 @@ void Switch2ProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t i } const SwitchPro::InReport* in_report = reinterpret_cast(payload); - if (std::memcmp(&prev_in_report_.buttons, in_report->buttons, 9) == 0) + if (std::memcmp(&prev_in_report_.buttons, in_report->buttons, 9) == 0 && + MotionImu::switch_usb_imu_unchanged(prev_imu_, payload, payload_len)) { tuh_hid_receive_report(address, instance); return; @@ -123,14 +125,14 @@ void Switch2ProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t i if (br & (1U << 4)) gp_in.buttons |= gamepad.MAP_BUTTON_RB; - // Right byte: classic R / ZR are Start and stick R3 on this device. + // Right byte: classic R is Start; classic ZR bit is stick L3 on Switch 2 Pro (not R3). if (br & SwitchPro::Buttons0::R) gp_in.buttons |= gamepad.MAP_BUTTON_START; if (br & SwitchPro::Buttons0::ZR) - gp_in.buttons |= gamepad.MAP_BUTTON_R3; + gp_in.buttons |= gamepad.MAP_BUTTON_L3; // Bit 5 in misc byte: hardware ZL digital (capture: 00 20 00 vs released; classic CAPTURE bit). - // Bit 5 in first byte: hardware ZR / RT digital (capture: 20 00 00 vs released; classic ZR is bit 7 → R3). + // Bit 5 in first byte: hardware ZR / RT digital (capture: 20 00 00 vs released). // Analog travel may exist elsewhere in the 64-byte report; these are full-digital paths. const bool zl_on = (bm & (1U << 5)) != 0; const bool zr_on = (br & (1U << 5)) != 0; @@ -139,12 +141,12 @@ void Switch2ProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t i if (bm & (1U << 6)) gp_in.buttons |= gamepad.MAP_BUTTON_BACK; - // Bit 7 in misc byte: hardware L3 (capture: 00 80 00 vs released; not classic Buttons1::L3 bit 2). + // Bit 7 in misc byte: hardware R3 (was mapped to L3; swapped to match physical sticks). if (bm & (1U << 7)) - gp_in.buttons |= gamepad.MAP_BUTTON_L3; + gp_in.buttons |= gamepad.MAP_BUTTON_R3; // "Misc" byte: d-pad uses some classic − / + / L3 / R3 bit positions; L uses the Home bit. - // L3 here is d-pad left (capture: 00 04 00); stick L3 is bm bit 7 above. + // L3 here is d-pad left (capture: 00 04 00); stick R3 is bm bit 7 above. if (bm & SwitchPro::Buttons1::MINUS) gp_in.dpad |= gamepad.MAP_DPAD_DOWN; if (bm & SwitchPro::Buttons1::L3) @@ -177,8 +179,22 @@ void Switch2ProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t i std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(normalize_axis(joy_rx), normalize_axis(joy_ry), true); + if (payload_len >= 22) { + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_SWITCH_USB; + MotionImu::fill_from_switch_usb_payload(gp_in.accel, gp_in.gyro, payload, payload_len); + } + gamepad.set_pad_in(gp_in); std::memcpy(&prev_in_report_, in_report, sizeof(SwitchPro::InReport)); + if (payload_len >= 22) { + constexpr uint16_t kInReportSize = 10; + constexpr uint16_t kImuSampleSize = sizeof(MotionImu::SwitchImuSample); + uint16_t imu_off = kInReportSize; + if (payload_len >= kInReportSize + (3 * kImuSampleSize)) { + imu_off = static_cast(kInReportSize + (2 * kImuSampleSize)); + } + std::memcpy(prev_imu_, payload + imu_off, sizeof(prev_imu_)); + } tuh_hid_receive_report(address, instance); } diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h index 2eac2558..0197e25f 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/Switch2ProHost.h @@ -7,9 +7,8 @@ /** * Nintendo Switch 2 Pro Controller (USB PID 0x2069): same bulk bring-up + HID init as SwitchProHost. - * Decoding is **InReport only** (10-byte payload). Matching on bytes 10 / 16–17 (IMU + stick coupling) - * caused random presses and flicker on hardware — do not reintroduce without stable fields or debounce - * tuned on-device. + * Decoding is **InReport only** (10-byte payload) for buttons/sticks. IMU bytes after the + * 10-byte payload are parsed separately for PS3/PS4 motion output (no button coupling). */ class Switch2ProHost : public SwitchProHost { diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp index 46fe4250..9f11bcc4 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.cpp @@ -14,6 +14,7 @@ #include "USBHost/HostDriver/SwitchPro/SwitchPro.h" #include "USBHost/HostDriver/SwitchPro/Switch2UsbInitPackets.h" #include "USBHost/HostManager.h" +#include "Gamepad/MotionImu.h" namespace { @@ -90,6 +91,7 @@ void SwitchProHost::switch2_cancel_bringup() switch2_bringup_pending_retry_ = false; switch2_next_packet_ms_ = 0; switch2_pkt_idx_ = 0; + switch2_bulk_keepalive_busy_ = false; if (switch2_dev_addr_ != 0) { @@ -315,6 +317,49 @@ void SwitchProHost::switch2_in_cb(tuh_xfer_s* xfer) self->switch2_after_packet_round(); } +void SwitchProHost::switch2_keepalive_cb(tuh_xfer_s* xfer) +{ + const uint8_t daddr = xfer->daddr; + const uint8_t instance = static_cast(xfer->user_data >> 8); + SwitchProHost* self = switch2_lookup(daddr, instance); + if (self != nullptr) + { + self->switch2_bulk_keepalive_busy_ = false; + } + (void)daddr; + (void)instance; +} + +void SwitchProHost::switch2_send_bulk_keepalive() +{ + if (switch2_ep_out_ == 0 || switch2_bulk_keepalive_busy_) + { + return; + } + + static const uint8_t kKeepalive[] = {0x03, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00}; + if (sizeof(kKeepalive) > switch2_bulk_out_buf_.size()) + { + return; + } + + std::memcpy(switch2_bulk_out_buf_.data(), kKeepalive, sizeof(kKeepalive)); + + tuh_xfer_t xfer{}; + xfer.daddr = switch2_dev_addr_; + xfer.ep_addr = switch2_ep_out_; + xfer.buflen = static_cast(sizeof(kKeepalive)); + xfer.buffer = switch2_bulk_out_buf_.data(); + xfer.complete_cb = switch2_keepalive_cb; + xfer.user_data = switch2_make_cb_token(switch2_dev_addr_, hid_instance_); + + switch2_bulk_keepalive_busy_ = true; + if (!tuh_edpt_xfer(&xfer)) + { + switch2_bulk_keepalive_busy_ = false; + } +} + void SwitchProHost::switch2_submit_out_packet() { const Switch2UsbBulkPacket& pkt = SWITCH2_USB_BULK_PACKETS[switch2_pkt_idx_]; @@ -398,6 +443,9 @@ void SwitchProHost::switch2_finish_bringup() init_state_ = InitState::DONE; pending_usb_ack_ = 0; pending_subcmd_ack_ = 0; + send_usb_disable_timeout(switch2_dev_addr_, hid_instance_); + switch2_last_bulk_keepalive_ms_ = board_api::ms_since_boot(); + switch2_send_bulk_keepalive(); tuh_hid_receive_report(switch2_dev_addr_, hid_instance_); return; } @@ -460,9 +508,7 @@ void SwitchProHost::advance_after_usb_ack(Gamepad& gamepad, uint8_t address, uin void SwitchProHost::send_usb_disable_timeout_and_probe(uint8_t address, uint8_t instance) { - uint8_t usb_out[63] = {0}; - usb_out[0] = SwitchPro::CMD::USB_SUB_DISABLE_TIMEOUT; - (void)try_hid_out_id(address, instance, SwitchPro::REPORT_ID_USB_OUT, usb_out, sizeof(usb_out)); + send_usb_disable_timeout(address, instance); std::memset(&out_report_, 0, sizeof(out_report_)); fill_neutral_rumble(out_report_); @@ -475,6 +521,13 @@ void SwitchProHost::send_usb_disable_timeout_and_probe(uint8_t address, uint8_t init_step_retries_ = 0; } +void SwitchProHost::send_usb_disable_timeout(uint8_t address, uint8_t instance) +{ + uint8_t usb_out[63] = {0}; + usb_out[0] = SwitchPro::CMD::USB_SUB_DISABLE_TIMEOUT; + (void)try_hid_out_id(address, instance, SwitchPro::REPORT_ID_USB_OUT, usb_out, sizeof(usb_out)); +} + void SwitchProHost::init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t instance) { (void)gamepad; @@ -620,7 +673,8 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in } const SwitchPro::InReport* in_report = reinterpret_cast(payload); - if (std::memcmp(&prev_in_report_.buttons, in_report->buttons, 9) == 0) + if (std::memcmp(&prev_in_report_.buttons, in_report->buttons, 9) == 0 && + MotionImu::switch_usb_imu_unchanged(prev_imu_, payload, payload_len)) { tuh_hid_receive_report(address, instance); return; @@ -676,10 +730,24 @@ void SwitchProHost::process_report(Gamepad& gamepad, uint8_t address, uint8_t in std::tie(gp_in.joystick_rx, gp_in.joystick_ry) = gamepad.scale_joystick_r(normalize_axis(joy_rx), normalize_axis(joy_ry), true); + if (payload_len >= 22) { + gp_in.motion_source = Gamepad::PadIn::MOTION_SRC_SWITCH_USB; + MotionImu::fill_from_switch_usb_payload(gp_in.accel, gp_in.gyro, payload, payload_len); + } + gamepad.set_pad_in(gp_in); tuh_hid_receive_report(address, instance); std::memcpy(&prev_in_report_, in_report, sizeof(SwitchPro::InReport)); + if (payload_len >= 22) { + constexpr uint16_t kInReportSize = 10; + constexpr uint16_t kImuSampleSize = sizeof(MotionImu::SwitchImuSample); + uint16_t imu_off = kInReportSize; + if (payload_len >= kInReportSize + (3 * kImuSampleSize)) { + imu_off = static_cast(kInReportSize + (2 * kImuSampleSize)); + } + std::memcpy(prev_imu_, payload + imu_off, sizeof(prev_imu_)); + } } bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t instance) @@ -721,6 +789,16 @@ bool SwitchProHost::send_feedback(Gamepad& gamepad, uint8_t address, uint8_t ins return false; } + if (switch2_device) + { + const uint32_t now_ms = board_api::ms_since_boot(); + if (now_ms - switch2_last_bulk_keepalive_ms_ >= 2000U) + { + switch2_last_bulk_keepalive_ms_ = now_ms; + switch2_send_bulk_keepalive(); + } + } + std::memset(&out_report_, 0, sizeof(out_report_)); out_report_.command = SwitchPro::CMD::RUMBLE_ONLY; diff --git a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h index 032e778a..248fe4f9 100644 --- a/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h +++ b/Firmware/RP2040/src/USBHost/HostDriver/SwitchPro/SwitchPro.h @@ -46,6 +46,7 @@ class SwitchProHost : public HostDriver bool usb_timeout_sent_{false}; SwitchPro::InReport prev_in_report_{}; + uint8_t prev_imu_[12]{}; SwitchPro::OutReport out_report_{}; uint8_t hid_instance_{0}; @@ -60,6 +61,8 @@ class SwitchProHost : public HostDriver unsigned switch2_pkt_idx_{0}; uint32_t switch2_next_packet_ms_{0}; bool switch2_bringup_pending_retry_{false}; + uint32_t switch2_last_bulk_keepalive_ms_{0}; + bool switch2_bulk_keepalive_busy_{false}; void switch2_poll_bringup(); void switch2_start_bringup(); @@ -71,18 +74,21 @@ class SwitchProHost : public HostDriver bool switch2_parse_open_iface1(const uint8_t* desc_cfg, uint16_t buflen); void switch2_submit_out_packet(); void switch2_submit_in_read(); + void switch2_send_bulk_keepalive(); void switch2_after_packet_round(); void switch2_finish_bringup(); static void switch2_cfg_cb(tuh_xfer_s* xfer); static void switch2_out_cb(tuh_xfer_s* xfer); static void switch2_in_cb(tuh_xfer_s* xfer); + static void switch2_keepalive_cb(tuh_xfer_s* xfer); void init_switch_host(Gamepad& gamepad, uint8_t address, uint8_t instance); void start_usb_wired_init(uint8_t address, uint8_t instance); bool send_usb_wired_command(uint8_t address, uint8_t instance, uint8_t subcmd); void advance_after_usb_ack(Gamepad& gamepad, uint8_t address, uint8_t instance); void send_usb_disable_timeout_and_probe(uint8_t address, uint8_t instance); + void send_usb_disable_timeout(uint8_t address, uint8_t instance); void fill_neutral_rumble(SwitchPro::OutReport& out); uint8_t get_output_sequence_counter(); diff --git a/Firmware/RP2040/src/UserSettings/JoystickSettings.cpp b/Firmware/RP2040/src/UserSettings/JoystickSettings.cpp index e50321d6..3e6f90fd 100644 --- a/Firmware/RP2040/src/UserSettings/JoystickSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/JoystickSettings.cpp @@ -20,6 +20,27 @@ bool JoystickSettings::is_same(const JoystickSettingsRaw& raw) const invert_x == raw.invert_x; } +bool JoystickSettings::raw_has_customization(const JoystickSettingsRaw& raw) +{ + static const JoystickSettingsRaw defaults{}; + return raw.dz_inner != defaults.dz_inner || + raw.dz_outer != defaults.dz_outer || + raw.anti_dz_circle != defaults.anti_dz_circle || + raw.anti_dz_circle_y_scale != defaults.anti_dz_circle_y_scale || + raw.anti_dz_square != defaults.anti_dz_square || + raw.anti_dz_square_y_scale != defaults.anti_dz_square_y_scale || + raw.anti_dz_angular != defaults.anti_dz_angular || + raw.anti_dz_outer != defaults.anti_dz_outer || + raw.axis_restrict != defaults.axis_restrict || + raw.angle_restrict != defaults.angle_restrict || + raw.diag_scale_min != defaults.diag_scale_min || + raw.diag_scale_max != defaults.diag_scale_max || + raw.curve != defaults.curve || + raw.uncap_radius != defaults.uncap_radius || + raw.invert_y != defaults.invert_y || + raw.invert_x != defaults.invert_x; +} + void JoystickSettings::set_from_raw(const JoystickSettingsRaw& raw) { dz_inner = Fix16(raw.dz_inner); @@ -38,4 +59,16 @@ void JoystickSettings::set_from_raw(const JoystickSettingsRaw& raw) uncap_radius = raw.uncap_radius; invert_y = raw.invert_y; invert_x = raw.invert_x; +} + +void JoystickSettings::set_xbox360_stock_feel(bool right_stick) +{ + /* Reset to firmware defaults, then apply 360-like shaping. + * Keep remapped deadzone mild (not Microsoft's ~24% software filter) so console games + * that also apply deadzones are not double-dulled. Curve < 1 softens the center and + * steepens the outer third — closer to a stock 360 pad than a near-linear Series stick. */ + *this = JoystickSettings{}; + dz_inner = Fix16(right_stick ? 0.09f : 0.08f); + curve = Fix16(0.35f); + uncap_radius = false; } \ No newline at end of file diff --git a/Firmware/RP2040/src/UserSettings/JoystickSettings.h b/Firmware/RP2040/src/UserSettings/JoystickSettings.h index 2e7e06c1..11d5cd54 100644 --- a/Firmware/RP2040/src/UserSettings/JoystickSettings.h +++ b/Firmware/RP2040/src/UserSettings/JoystickSettings.h @@ -33,6 +33,13 @@ struct JoystickSettings bool is_same(const JoystickSettingsRaw& raw) const; void set_from_raw(const JoystickSettingsRaw& raw); + static bool raw_has_customization(const JoystickSettingsRaw& raw); + /** + * Xbox 360–like response for XInput mode when the WebApp has not customized sticks. + * Mild remapped inner deadzone + softer early / steeper outer curve + circular clamp. + * (@param right_stick slightly larger deadzone, matching Microsoft L/R asymmetry). + */ + void set_xbox360_stock_feel(bool right_stick = false); }; #pragma pack(push, 1) diff --git a/Firmware/RP2040/src/UserSettings/UserSettings.cpp b/Firmware/RP2040/src/UserSettings/UserSettings.cpp index f2c4cf8b..f8a78f4e 100644 --- a/Firmware/RP2040/src/UserSettings/UserSettings.cpp +++ b/Firmware/RP2040/src/UserSettings/UserSettings.cpp @@ -14,9 +14,20 @@ static constexpr uint32_t BUTTON_COMBO(const uint16_t& buttons, const uint8_t& d return (static_cast(buttons) << 16) | static_cast(dpad); } +/** Required buttons/dpad pressed (extra face buttons or triggers do not block the combo). */ +static bool combo_matches(uint32_t current, uint32_t expected) +{ + const uint16_t req_buttons = static_cast(expected >> 16); + const uint16_t cur_buttons = static_cast(current >> 16); + const uint8_t req_dpad = static_cast(expected & 0xFF); + const uint8_t cur_dpad = static_cast(current & 0xFF); + return ((cur_buttons & req_buttons) == req_buttons) && (cur_dpad == req_dpad); +} + namespace ButtonCombo { static constexpr uint32_t PS3 = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_LEFT); static constexpr uint32_t PS4 = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB, Gamepad::DPAD_LEFT); + static constexpr uint32_t STEAM = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_LB, Gamepad::DPAD_UP); static constexpr uint32_t DINPUT = BUTTON_COMBO(Gamepad::BUTTON_START | Gamepad::BUTTON_RB, Gamepad::DPAD_LEFT); static constexpr uint32_t XINPUT = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_UP); static constexpr uint32_t SWITCH = BUTTON_COMBO(Gamepad::BUTTON_START, Gamepad::DPAD_DOWN); @@ -40,6 +51,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::XINPUT, DeviceDriverType::PS3, DeviceDriverType::PS4, + DeviceDriverType::STEAM, DeviceDriverType::PSCLASSIC, DeviceDriverType::WIIU, DeviceDriverType::WII, @@ -65,6 +77,7 @@ static constexpr DeviceDriverType VALID_DRIVER_TYPES[] = { DeviceDriverType::WEBAPP, DeviceDriverType::PS3, DeviceDriverType::PS4, + DeviceDriverType::STEAM, DeviceDriverType::PSCLASSIC, DeviceDriverType::PS1PS2, DeviceDriverType::GAMECUBE, @@ -84,7 +97,7 @@ struct ComboMap { }; // GAMECUBE and N64 are build-only (fixed driver), not in combo map; use -DOGXM_FIXED_DRIVER=GAMECUBE or N64. -static constexpr std::array BUTTON_COMBO_MAP = {{ +static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::XBOXOG, DeviceDriverType::XBOXOG }, { ButtonCombo::XBOXOG_SB, DeviceDriverType::XBOXOG_SB }, { ButtonCombo::XBOXOG_XR, DeviceDriverType::XBOXOG_XR }, @@ -95,11 +108,34 @@ static constexpr std::array BUTTON_COMBO_MAP = {{ { ButtonCombo::XINPUT, DeviceDriverType::XINPUT }, { ButtonCombo::PS3, DeviceDriverType::PS3 }, { ButtonCombo::PS4, DeviceDriverType::PS4 }, + { ButtonCombo::STEAM, DeviceDriverType::STEAM }, { ButtonCombo::PSCLASSIC, DeviceDriverType::PSCLASSIC }, { ButtonCombo::PS1PS2, DeviceDriverType::PS1PS2 }, { ButtonCombo::DREAMCAST, DeviceDriverType::DREAMCAST }, }}; +/** Prefer the combo that requires the most buttons (e.g. STEAM over XInput when LB is held). */ +static uint32_t find_matching_combo(uint32_t current) +{ + uint32_t best = 0; + uint8_t best_button_count = 0; + for (const auto& entry : BUTTON_COMBO_MAP) { + if (!combo_matches(current, entry.combo)) { + continue; + } + const uint16_t req = static_cast(entry.combo >> 16); + uint8_t count = 0; + for (uint16_t bit = req; bit != 0; bit &= static_cast(bit - 1)) { + ++count; + } + if (count >= best_button_count) { + best_button_count = count; + best = entry.combo; + } + } + return best; +} + const std::string UserSettings::INIT_FLAG_KEY() { return std::string("init_flag"); @@ -147,15 +183,17 @@ bool UserSettings::check_for_driver_change(Gamepad& gamepad) return false; // Fixed output build: combos disabled #else Gamepad::PadIn gp_in = gamepad.get_pad_in(); - static uint32_t last_button_combo = BUTTON_COMBO(gp_in.buttons, gp_in.dpad); + static uint32_t last_button_combo = 0; static uint8_t call_count = 0; - uint32_t current_button_combo = BUTTON_COMBO(gp_in.buttons, gp_in.dpad); + const uint32_t current_button_combo = BUTTON_COMBO(gp_in.buttons, gp_in.dpad); + const uint32_t active_combo = find_matching_combo(current_button_combo); if (!(current_button_combo & (static_cast(Gamepad::BUTTON_START) << 16)) || - last_button_combo != current_button_combo) + active_combo == 0 || + last_button_combo != active_combo) { - last_button_combo = current_button_combo; + last_button_combo = active_combo; call_count = 0; return false; } @@ -173,7 +211,7 @@ bool UserSettings::check_for_driver_change(Gamepad& gamepad) for (const auto& combo_map : BUTTON_COMBO_MAP) { - if (combo_map.combo == current_button_combo && is_valid_driver(combo_map.driver)) + if (combo_map.combo == active_combo && is_valid_driver(combo_map.driver)) { new_driver = combo_map.driver; break; diff --git a/Firmware/RP2040/src/Wii/WiiReportConverter.cpp b/Firmware/RP2040/src/Wii/WiiReportConverter.cpp index 08b9a0a7..5266b50e 100644 --- a/Firmware/RP2040/src/Wii/WiiReportConverter.cpp +++ b/Firmware/RP2040/src/Wii/WiiReportConverter.cpp @@ -8,7 +8,7 @@ #include #include -#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) +#if defined(OGXM_BOARD_USES_PICO_W_FIRMWARE) && defined(CONFIG_EN_USB_HOST) #include "Board/board_api.h" #include "pico/time.h" diff --git a/Firmware/RP2040/src/Wii/WiiReportConverter.h b/Firmware/RP2040/src/Wii/WiiReportConverter.h index 91d7f42b..87ba8333 100644 --- a/Firmware/RP2040/src/Wii/WiiReportConverter.h +++ b/Firmware/RP2040/src/Wii/WiiReportConverter.h @@ -3,7 +3,7 @@ #include "Board/Config.h" -#if (OGXM_BOARD == PI_PICOW) && defined(CONFIG_EN_USB_HOST) +#if defined(OGXM_BOARD_USES_PICO_W_FIRMWARE) && defined(CONFIG_EN_USB_HOST) class Gamepad; diff --git a/Firmware/RP2040/src/btstack_config.h b/Firmware/RP2040/src/btstack_config.h index c4f404e5..6720c8f4 100644 --- a/Firmware/RP2040/src/btstack_config.h +++ b/Firmware/RP2040/src/btstack_config.h @@ -72,6 +72,9 @@ #define HCI_RESET_RESEND_TIMEOUT_MS 1000 #define ENABLE_SOFTWARE_AES128 +/* Steam Controller 2026 (and many modern BLE pads) reject legacy SMP with + * AUTH_REQUIREMENTS_MISMATCH unless LE Secure Connections is available. */ +#define ENABLE_LE_SECURE_CONNECTIONS #define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS #define HAVE_BTSTACK_STDIN diff --git a/Firmware/RP2040/src/tusb_config.h b/Firmware/RP2040/src/tusb_config.h index bc84dff9..f0fa0b0a 100644 --- a/Firmware/RP2040/src/tusb_config.h +++ b/Firmware/RP2040/src/tusb_config.h @@ -104,7 +104,8 @@ //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 -#define CFG_TUD_HID MAX_GAMEPADS +/* +1 HID interface for Steam mode composite mouse (unused by other output drivers). */ +#define CFG_TUD_HID (MAX_GAMEPADS + 1) #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 #define CFG_TUD_XID 1 diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index 6c8dc3ab..f1266794 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit 6c8dc3ab3dc4e8d36f9b62984d8f3b0563e39d63 +Subproject commit f12667945a4760de17fa688a1667444794853924 diff --git a/README.md b/README.md index d8e13fdf..8672bd16 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ --- -![OGX-Mini Boards](images/OGX-Mini-github.jpg "OGX-Mini Boards") +![OGX-Mini Boards](images/logo.png "OGX-Mini Boards") Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Pi Pico W, Pi Pico 2 W, Waveshare RP2040-Zero, Waveshare RP2350-USB-A, Waveshare RP2350-Zero, Seeed Studio XIAO RP2040, RP2354, Pico/ESP32 hybrid, and a 4-Channel RP2040-Zero setup. @@ -14,6 +14,10 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles [**Join the discord here!**](https://discord.gg/HhZuSaSc4) +[**Follow on TikTok!**](https://www.tiktok.com/@ogxmini2026) + +[**Subscribe on YouTube!**](https://www.youtube.com/@ogxmini2026) + ## Supported platforms - Original Xbox - Playstation 3 @@ -21,6 +25,8 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles - XInput (Xbox 360, UsbdSecPatch no longer required) - Playstation Classic - DInput +- **SteamOS / Bazzite** — Linux desktop / Steam Deck (desktop mode): **DualSense** USB gamepad + **touchpad → HID mouse** (see [SteamOS / Bazzite output mode](#steamos--bazzite-output-mode)) +- **PS3 / PS4 motion** — Sixaxis / accelerometer passthrough from DS4, DualSense, Switch Pro, and Wii Remote (see [Motion controls](#ps3--ps4-motion-controls)) - Wii U (GameCube Adapter) - **Wii (Wiimote)** — Pico W / Pico 2 W only; build with `-DOGXM_FIXED_DRIVER=WII`. See [Wii Mode Guide](Firmware/RP2040/docs/Wii_Mode_Guide.md). - **PlayStation 1 & 2** — GPIO output to console controller port (DualShock-style). @@ -28,7 +34,9 @@ Firmware for the RP2040, capable of emulating gamepads for several game consoles - **GameCube / Wii (GameCube ports)** — GPIO output over single-wire JoyBus. **Build-only (no combo):** use `-DOGXM_FIXED_DRIVER=GAMECUBE`; see below. - **Nintendo 64** — GPIO output over single-wire to controller port. **Build-only (no combo):** use `-DOGXM_FIXED_DRIVER=N64`; see below. -**RP2040 output modes:** **USB device:** XInput (Xbox 360 + XSM3), DInput, PS3, **Switch Pro** (Nintendo Switch Pro Controller emulation), Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. **GPIO (no USB device):** PS1/PS2, Dreamcast, GameCube, N64 — use any wired USB or (on Pico W / Pico 2 W) Bluetooth controller as input. **Wii, GameCube, and N64 are not in the combo list** — use a dedicated build for those modes (see below). +![Supported platforms](images/platform-list.png "Supported platforms") + +**RP2040 output modes:** **USB device:** XInput (Xbox 360 + XSM3), DInput, PS3, **PS4 (DualShock 4 USB)**, **STEAM (SteamOS / Bazzite — DualSense + touchpad mouse)**, **Switch Pro** (Nintendo Switch Pro Controller emulation), Wii U, **Wii (Wiimote, build-option only)**, Xbox OG (Gamepad / Steel Battalion / XRemote), PS Classic, Web App. **GPIO (no USB device):** PS1/PS2, Dreamcast, GameCube, N64 — use any wired USB or (on Pico W / Pico 2 W) Bluetooth controller as input. **Wii, GameCube, and N64 are not in the combo list** — use a dedicated build for those modes (see below). ## Changing platforms By default the OGX-Mini will emulate an OG Xbox controller, you must hold a button combo for 3 seconds to change which platform you want to play on. Your chosen mode will persist after powering off the device. @@ -47,6 +55,10 @@ Start = Plus (Switch) = Options (Dualsense/DS4) - Start + Dpad Down - PlayStation 3 - Start + Dpad Left +- PlayStation 4 (DualShock 4 USB) + - Start + Left Bumper + D-pad **Left** +- SteamOS / Bazzite (DualSense USB + touchpad mouse) + - Start + Left Bumper + D-pad **Up** - PlayStation Classic - Start + A (Cross for PlayStation and B for Switch gamepads) - PlayStation 1 / PlayStation 2 (GPIO output) @@ -70,13 +82,87 @@ Input for GPIO modes is Bluetooth or USB; no combo switching in these builds. After a new mode is stored, the RP2040 will reset itself so you don't need to unplug it. +## PS3 / PS4 motion controls + +**PS3** and **PS4 (DualShock 4 USB)** output modes can forward **tilt / motion** from compatible input controllers into the emulated report (Sixaxis on PS3, accelerometer on PS4). **Switch** output mode does **not** pass through motion for now. + +| | | +|--|--| +| **Select PS3 mode** | **Start + D-pad Left** (~3 s) | +| **Select PS4 mode** | **Start + Left Bumper + D-pad Left** (~3 s) | +| **Supported input (BT — Pico W / Pico 2 W)** | DualShock 4, DualSense, Switch Pro, **Wii Remote** (accelerometer) | +| **Supported input (wired USB host)** | DualShock 4, DualSense, Switch 1 Pro, Switch 2 Pro | +| **Wii Remote** | Point the **IR end at the TV**; motion is enabled automatically when motion output is active | +| **Play on a real PS3 or PS4** | OGX-Mini does **not** plug straight into the console for this — use a **USB adapter** between OGX-Mini and the console. **Tested with [Brook Wingman XE 2 Converter](https://www.brookaccessories.com/products/wingman-xe2).** Works on **PS3** (PS3 mode) and **PS4** (PS4 mode on OGX-Mini → Brook → PS4). | +| **PC testing (PS3/PS4)** | No Brook required — use PS3/PS4 mode on a PC/emulator to verify tilt | + +**Typical chain for a PS3 motion game (e.g. *Flower*):** + +```text +Wii Remote or DualSense (Bluetooth) → OGX-Mini (Pico W) → USB → Brook Wingman XE 2 → PS3 +``` + +Details: [IMPROVEMENTS.md — motion passthrough](Firmware/RP2040/docs/IMPROVEMENTS.md#ps3--ps4-output--motion-passthrough). + +## SteamOS / Bazzite output mode + +Use this mode on **SteamOS**, **Bazzite**, or other **Linux desktops** (including **Steam Deck** in desktop mode) when you want the host to see a **PS5 DualSense** gamepad **and** use the **touchpad as a USB mouse** (cursor movement + tap to click). Games and Steam Input see a normal DualSense; the desktop gets a separate **HID mouse** for navigating outside games. + +### Select mode + +| Method | Combo / option | +|--------|----------------| +| **Button combo** | Hold **Start + Left Bumper + D-pad Up** for ~3 seconds (saved to flash; device resets) | +| **Web app** | Output mode **SteamOS / Bazzite** | +| **Fixed build** | `-DOGXM_FIXED_DRIVER=STEAM` (also in `./scripts/build.sh` / `build.ps1` fixed-mode menu) | + +### DualSense USB emulation + +The adapter presents **two USB interfaces** to the PC: + +| Interface | Identity | Purpose | +|-----------|----------|---------| +| **Gamepad** | Sony **DualSense** `054c:0ce6`, 64-byte HID input report | Buttons, sticks, triggers, PS button — for Steam / Proton / desktop gamepad APIs | +| **Mouse** | Standard **relative HID mouse** (separate interface) | Cursor from **DualSense touchpad** only | + +**Input → USB behavior:** + +| Input controller | Gamepad report | Touchpad / mouse | +|------------------|----------------|------------------| +| **DualSense (PS5)** — Bluetooth or wired USB | **Passthrough** of the real DualSense report (sticks/triggers from host when wired) | Touchpad finger position → **relative mouse** movement; touchpad click (`TP`) → **left click** | +| **Other pads** (Xbox, DS4, Switch Pro, etc.) | **Synthesized** DualSense report — face buttons, shoulders, triggers, sticks, D-pad, **Share/Options**, **PS**, touchpad-click bit mapped from PadIn | No hardware touchpad — **no mouse** (gamepad only) | + +Face-button mapping to DualSense: **A→Cross**, **B→Circle**, **X→Square**, **Y→Triangle**; **LB/RB→L1/R1**; **Back/Start→Share/Options**; **SYS→PS**. Full table: [Controller_Mappings.md — STEAM mode](Firmware/RP2040/docs/Controller_Mappings.md#steamos--bazzite-steam-mode). + +After switching to STEAM mode, **unplug and replug** the adapter’s USB cable to the PC so Linux re-enumerates both interfaces. Verify with `lsusb -d 054c:0ce6` (two interfaces) and `evtest` on the mouse device. + +### Touchpad → mouse (DualSense input) + +When the **input** pad is a **DualSense** (Bluetooth on Pico W / Pico 2 W, or wired into the adapter’s USB host port): + +- **Drag** on the touchpad → **relative mouse** movement on the PC (second USB interface). +- **Tap / click** the touchpad → **left mouse button**. +- The touchpad data is also embedded in the DualSense gamepad report (offset compatible with Linux `hid-playstation`). + +Controllers **without** a DualSense touchpad still work as a DualSense gamepad; they do **not** drive the mouse interface. + +### Other notes + +- **On-screen keyboard:** Steam handles this — **Steam + X** on the controller (**PS + Square** on DualSense), same as Steam Deck desktop. +- **Input sources:** Most supported **USB** and **Bluetooth** controllers work as gamepad input; **touchpad → mouse** requires a **DualSense** (or other pad that reports touchpad data). + +Fixed-build example (Pico 2 W): +`cmake -DOGXM_BOARD=PI_PICO2W -DCMAKE_BUILD_TYPE=Release -DOGXM_FIXED_DRIVER=STEAM ..` then `ninja`. + +Technical detail: [IMPROVEMENTS.md — STEAM mode](Firmware/RP2040/docs/IMPROVEMENTS.md#steam-mode--steamos--bazzite-linux-desktop). + ## Disconnecting Controllers For most controllers pressing and holding Start+Select (+/-, etc) for the controller will disconnect it and restart pairing mode. For the OUYA controller there is no Start+Select, the disconnection combo has been set to L3+R3. ## Supported devices ### Wired controllers (USB input) -See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a full list by driver type. The following work when the adapter is outputting to any supported platform (Xbox, Switch, XInput, PS3, DInput, **PS1/PS2**, **Dreamcast**, **GameCube**, **N64**, etc.): +See [**Wired Controllers**](Firmware/RP2040/docs/Wired_Controllers.md) for a full list by driver type. The following work when the adapter is outputting to any supported platform (Xbox, Switch, XInput, PS3, DInput, **SteamOS / Bazzite**, **PS1/PS2**, **Dreamcast**, **GameCube**, **N64**, etc.): - Original Xbox Duke and S - Xbox 360, One, Series, and Elite - **Razer Atrox Arcade Stick** (Xbox One `1532:0a00`, Xbox 360 `24c6:5000`; wired USB host) @@ -100,7 +186,7 @@ Note: There are some third party controllers that can change their VID/PID, thes ### Wireless Bluetooth controllers (Pico W & ESP32) **Note:** Bluetooth functionality is in early testing; some controllers may have quirks. BT pads work as input in **any** USB output mode (OG Xbox, XInput, PS3, Switch, etc.) on Pico W / Pico 2 W, and also when outputting over **GPIO** to **PS1/PS2**, **Dreamcast**, **GameCube**, or **N64** (same as wired USB in those modes). -**DualShock 3 (PS3) — USB pairing to the adapter’s Bluetooth (Pico W / Pico 2 W):** The DS3 does not pair like a normal Bluetooth device. If you plug a **DualShock 3 into the adapter’s USB host port** while the firmware is running, it will **automatically program the controller with this Pico’s Bluetooth address** (same mechanism as the [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/) tool). Then **unplug the USB cable** and press the **PS** button to connect wirelessly. If the radio was not ready at the moment the pad enumerated, pairing is retried on the next input reports until the address is available. +**DualShock 3 (PS3) — USB pairing to the adapter’s Bluetooth (Pico W / Pico 2 W / RP2354):** The DS3 does not pair like a normal Bluetooth device. If you plug a **DualShock 3 into the adapter’s USB host port** while the firmware is running, it will **automatically program the controller with this adapter’s Bluetooth address** (HID feature **0xF5**, same mechanism as the [Bluepad32 sixaxispairer](https://bluepad32.readthedocs.io/en/latest/pair_ds3/) tool — restored in **v1.0.0.12a** as a sync SET after wired enable). Then **unplug the USB cable** and press the **PS** button to connect wirelessly. If the radio was not ready at the moment the pad enumerated, pairing is retried on the next input reports until the address is available. **Pico W / Pico 2 W — important for DualShock 4 (DS4):** DS4 uses **Classic Bluetooth (BR/EDR)**. The same CYW43 radio also runs **BLE advertising** for the **phone / web app**. Running both at once often **drops the DS4 link** seconds after connect (blue LED then off). Firmware therefore **pauses BLE advertising** while a **Classic BT** gamepad is connected (DS4, DS3 over BT, Xbox 360 wireless adapter style links). **DualSense** and **Xbox Series (BLE)** mostly use **LE** and are unaffected by that pause. @@ -113,13 +199,16 @@ Full technical detail: **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/ **Nintendo Switch 2 (Pico W / Pico 2 W):** **Switch 2 Pro** (PID **0x2069**) and **Joy-Con 2** Left (**0x2067**) / Right (**0x2066**) use a **custom BLE GATT protocol** (not standard gamepad HID). Put the controller in **pairing / SYNC** mode; the adapter discovers and connects automatically — **do not** pair it in your PC or phone Bluetooth settings first. **Joy-Con 2:** pair **Left** first, then **Right** while left stays connected — both merge into **player 1** like on a Switch. **Home** maps to **PS / Guide (SYS)** on PS3, XInput, OG Xbox, etc. Protocol credits: [Nadeflore/switch2-controllers](https://github.com/Nadeflore/switch2-controllers), [TommyWabg/switch2-controllers-windows10-gyro](https://github.com/TommyWabg/switch2-controllers-windows10-gyro), and [BlueRetro #1249](https://github.com/darthcloud/BlueRetro/issues/1249). Details: [IMPROVEMENTS — Switch 2 Bluetooth](Firmware/RP2040/docs/IMPROVEMENTS.md#nintendo-switch-2--bluetooth-pico-w--pico-2-w). +**Steam Controller 2026 / Triton (Pico W / Pico 2 W / RP2354 BT):** Hold **RB + B + Steam** for BLE pairing (`28de:1303`, HID-over-GATT). **Remove/disconnect it from PC or phone Bluetooth first** — only one host can own the link. Uses **LE Secure Connections**. **View → Start**, **Menu → Back/Select**, **Steam → Guide / SYS**. Details: [IMPROVEMENTS — Steam Controller 2026](Firmware/RP2040/docs/IMPROVEMENTS.md#steam-controller-2026-triton--bluetooth). + - Xbox Series, One, and Elite 2 - Dualshock 3 - Dualshock 4 - Dualsense - Switch Pro -- **Switch 2 Pro** and **Joy-Con 2 (L/R)** (BLE on Pico W / Pico 2 W; wired USB also supported) -- Steam +- **Switch 2 Pro** and **Joy-Con 2 (L/R)** (BLE on Pico W / Pico 2 W / RP2354; wired USB also supported) +- Steam (original SC) +- **Steam Controller 2026 (Triton)** — BLE on Pico W / Pico 2 W / RP2354 - Stadia - Wii U Pro - Wii Remote @@ -133,10 +222,26 @@ Please visit [**this page**](https://bluepad32.readthedocs.io/en/latest/supporte # Features new to this fork -Version history and release notes are in **[CHANGELOG.md](CHANGELOG.md)**. For detailed firmware improvements — **PS3**, **XInput / XSM3**, **OG Xbox**, **PS2/OPL**, **latency**, **Pico W Bluetooth (DS4 Classic BT, BLE coexistence, Xbox Series BLE, Switch 2 Pro + Joy-Con 2 BLE)**, **Pico W / Pico 2 W PIO USB wired unplug detection**, etc. — see **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)**. +Version history and release notes are in **[CHANGELOG.md](CHANGELOG.md)**. For detailed firmware improvements — **PS3**, **XInput / XSM3**, **OG Xbox**, **PS2/OPL**, **latency**, **SteamOS / Bazzite (STEAM mode)**, **PS3 / PS4 motion passthrough**, **Pico W Bluetooth (DS4 Classic BT, BLE coexistence, Xbox Series BLE, Switch 2 Pro + Joy-Con 2 BLE, Steam Controller 2026 / Triton, DualShock 3 USB→BT auto-pair)**, **Pico W / Pico 2 W PIO USB wired unplug detection**, etc. — see **[Firmware/RP2040/docs/IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md)**. Highlights: +- **Steam Controller 2026 (Triton) over Bluetooth** — Pair with **RB + B + Steam** on Pico W / Pico 2 W / RP2354 (**`28de:1303`**). Requires LE Secure Connections; disconnect from any PC/phone first. **View → Start**, **Menu → Back**, **Steam → Guide**. Details: [IMPROVEMENTS — Steam Controller 2026](Firmware/RP2040/docs/IMPROVEMENTS.md#steam-controller-2026-triton--bluetooth). + +- **DualShock 3 — USB → Bluetooth auto-pair (restored in v1.0.0.12a)** — Plug a DS3 into the adapter’s USB host port to program it with this unit’s BD_ADDR (**feature `0xF5`**), then unplug and press **PS**. Details: [Wireless Bluetooth](#wireless-bluetooth-controllers-pico-w--esp32), [IMPROVEMENTS — DS3 USB pairing](Firmware/RP2040/docs/IMPROVEMENTS.md#dualshock-3--automatic-usb-programming-for-bluetooth-pairing). + +- **XInput / Xbox 360 — stock stick feel (#38)** — In **XInput mode**, default (non–WebApp-customized) sticks get a milder 360-like deadzone/curve so Series pads are less twitchy. Details: [IMPROVEMENTS — stock stick feel](Firmware/RP2040/docs/IMPROVEMENTS.md#xinput--xbox-360--stock-stick-feel). + +- **Switch mode — HD rumble to input pads** — Console HD rumble is decoded and forwarded to Bluetooth/USB input pads (DualSense, Xbox, etc.). Details: [IMPROVEMENTS — Switch HD rumble](Firmware/RP2040/docs/IMPROVEMENTS.md#switch-mode--hd-rumble-passthrough). + +- **Pico W / Pico 2 W / RP2354 — USB resume restores BT pairing** — After console USB standby, scans restart without unplugging the dongle. Details: [IMPROVEMENTS — USB resume pairing](Firmware/RP2040/docs/IMPROVEMENTS.md#pico-w--pico-2-w--rp2354-bt--usb-resume-restores-pairing-scans). + +- **Two adapters on one console** — **Not supported yet** as two independent players: units share the same USB identity (VID/PID / serial / XSM3 on 360). Use **one OGX + a native or other-brand pad**, or a **multi-port** host. See [IMPROVEMENTS — Summary](Firmware/RP2040/docs/IMPROVEMENTS.md#summary). + +- **PS3 / PS4 motion (tilt / IMU passthrough)** — **PS3** and **PS4** output modes forward accelerometer (and gyro where available) from **DualShock 4**, **DualSense**, **Switch Pro**, and **Wii Remote** (BT/USB where supported). **Switch** output does not pass through motion for now. For **real PS3/PS4 consoles**, use a **USB adapter** between OGX-Mini and the console — **tested with [Brook Wingman XE 2 Converter](https://www.brookaccessories.com/products/wingman-xe2)** (works on **PS3** and **PS4**). Details: [Motion controls](#ps3--ps4-motion-controls), [IMPROVEMENTS.md — motion passthrough](Firmware/RP2040/docs/IMPROVEMENTS.md#ps3--ps4-output--motion-passthrough). + +- **SteamOS / Bazzite (STEAM output mode)** — **Start + Left Bumper + D-pad Up** (~3 s), **web app**, or `-DOGXM_FIXED_DRIVER=STEAM` / build-script fixed mode. USB enumerates as **Sony DualSense** (`054c:0ce6`) **plus** a separate **HID mouse** interface. **DualSense emulation:** passthrough of the real PS5 report when input is DualSense (BT or wired USB); other controllers get a **synthesized** DualSense report (Cross/Circle/Square/Triangle, L1/R2, Share/Options, PS). **Touchpad → mouse:** DualSense touchpad drag moves the desktop cursor; tap = left click. Controllers without a touchpad are gamepad-only. Works with **Bluetooth** (Pico W / Pico 2 W) or **wired USB** input. Details: [SteamOS / Bazzite output mode](#steamos--bazzite-output-mode), [IMPROVEMENTS.md — STEAM mode](Firmware/RP2040/docs/IMPROVEMENTS.md#steam-mode--steamos--bazzite-linux-desktop), [Controller_Mappings.md — STEAM](Firmware/RP2040/docs/Controller_Mappings.md#steamos--bazzite-steam-mode). + - **Pico W / Pico 2 W — PIO USB wired unplug:** When you unplug the gamepad from the adapter’s USB host port, the firmware now **detects disconnect reliably** even though PIO USB owns D+/D− (GPIO line state often never shows a true “disconnected” idle). Detection uses **debounced** hints: **HCD port connect status**, **no TinyUSB configured device** (all `tuh_mounted` addresses), and **no host input reports** for a few seconds — so the TinyUSB/PIO host can **tear down**, **GPIO line IRQ monitoring** can resume, and **Bluetooth pairing** can work again without power-cycling or “shorting” the port. Details: [IMPROVEMENTS.md — Pico W PIO USB unplug](Firmware/RP2040/docs/IMPROVEMENTS.md#pico-w--pico-2-w--pio-usb-wired-controller-unplug-detection). *Note: Many features were added and tested on Pico W / Pico 2 W; other boards may not have been tested for every change.* @@ -164,8 +269,8 @@ Highlights: - Genesis - Master System - Sega Saturn - - PS4/ PS5 - - Xbox One + - ~~PS4/PS5~~ (needs an authentication dongle to work) + - ~~Xbox One~~ (needs an authentication dongle to work) - Atari - PS2 MultiTap - PS1 MultiTap @@ -185,13 +290,11 @@ If your controller isn’t working but a similar one (e.g. same brand or protoco **VID/PID alone is not always enough.** Many pads need the correct **USB mode** (XInput vs DInput vs Switch), matching **report layout**, or **driver-specific** handling. Dropping IDs into the list may do nothing or behave wrong if the device doesn’t match an existing parser. -**What to do first:** run the **[controller capture tool](Tools/controller_capture/README.md)** on your PC, save the capture, and attach it when you ask for support (see that README for steps). Captures give us descriptors and traffic so we can see what the pad is really doing. - -**If a capture still isn’t enough to add support remotely:** **[donations via Ko-fi](https://ko-fi.com/megacadedev)** may be used toward **buying the same controller** so it can be tested and supported **when time and stock allow**—this is not a guaranteed timeline or commitment for every request. +**Getting support added:** I have a **PO box** — we can **schedule borrowing** your controller so support can be developed and tested, then returned. Otherwise, **[donations via Ko-fi](https://ko-fi.com/megacadedev)** will be needed toward **buying that controller** so it can be tested and supported **when time and stock allow**—this is not a guaranteed timeline or commitment for every request. Reach out (e.g. Discord or GitHub) to arrange either option. -**What we prioritize for support (disclaimer):** Maintainer effort focuses on **OEM and name‑brand** controllers (first‑party console pads and established third‑party brands with stable USB identities). **Knock‑offs, unbranded clones, and “compatible” pads** that reuse random VID/PIDs or change behavior by batch are often **not practical to support**: we may be unable to source the **exact same** unit, and fixes may not transfer to other clones. You can still open an issue or share a capture; just expect clone/no‑name hardware to be **lower priority or declined**. +**What we prioritize for support (disclaimer):** Maintainer effort focuses on **OEM and name‑brand** controllers (first‑party console pads and established third‑party brands with stable USB identities). **Knock‑offs, unbranded clones, and “compatible” pads** that reuse random VID/PIDs or change behavior by batch are often **not practical to support**: we may be unable to source the **exact same** unit, and fixes may not transfer to other clones. You can still open an issue; just expect clone/no‑name hardware to be **lower priority or declined**. -When you write in, include **VID**, **PID**, controller **name/model**, and (if possible) a **capture** from the tool above. If the controller has multiple modes (XInput / DInput / Switch), say which mode you used. +When you write in, include **VID**, **PID**, and controller **name/model**. If the controller has multiple modes (XInput / DInput / Switch), say which mode you used. ### How to get VID and PID @@ -236,13 +339,13 @@ Use one of these values for **`OGXM_BOARD`** in a manual build, or pick the same - ```RP2350_USB_A``` (Waveshare RP2350-USB-A) - ```RP2350_ZERO``` (Waveshare RP2350-Zero) - ```RP2040_XIAO``` (Seeed Studio XIAO RP2040) -- ```RP2354``` +- ```RP2354``` (RP2350 + **Pi Radio Module 2** / CYW43439 — **Bluetooth** wireless controllers like **Pico 2 W**, plus PIO USB host on **GP0/GP1**, LED **GP25**) - ```ADAFRUIT_FEATHER``` use the board’s **USB Type-A** port for the controller; 5V enable is GPIO 18, D+/D− are GPIO 16/17. If the controller is not detected, plug it in **after** the board has booted and ensure the green 5V LED next to the USB-A port is on.) - ```ESP32_BLUEPAD32_I2C``` - ```ESP32_BLUERETRO_I2C``` - ```EXTERNAL_4CH_I2C``` -You can also set ```MAX_GAMEPADS``` (if > 1, only DInput/PS3 and Switch Pro are supported). **Optional:** ```OGXM_FIXED_DRIVER``` to lock output mode (e.g. ```XINPUT```, ```PS3```); ```OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON``` to keep combos when fixed. ```MAIN_LOOP_DELAY_US``` (default ```0```) sets main-loop delay for lower CPU use (e.g. ```250```). +You can also set ```MAX_GAMEPADS``` (if > 1, only DInput/PS3 and Switch Pro are supported). **Optional:** ```OGXM_FIXED_DRIVER``` to lock output mode (e.g. ```XINPUT```, ```PS3```, ```STEAM```, ```PS4```); ```OGXM_FIXED_DRIVER_ALLOW_COMBOS=ON``` to keep combos when fixed. ```MAIN_LOOP_DELAY_US``` (default ```0```) sets main-loop delay for lower CPU use (e.g. ```250```). You'll need git, python3, CMake, Ninja and the GCC ARM toolchain installed. CMake scripts will patch some files in Bluepad32 and BTStack and also make sure all git submodules (plus their submodules and dependencies) are downloaded. @@ -258,8 +361,8 @@ We provide interactive build scripts so you can build firmware without memorizin The script will: 1. **Check prerequisites** — Verifies that `git`, `python3` (or `python`), `cmake`, `ninja`, and `arm-none-eabi-gcc` are installed. If something is missing, it prints install hints (e.g. `apt install` on Debian/Ubuntu, `brew install` on macOS, Chocolatey on Windows). -2. **Ask for your board** — Choose from a numbered list (Pi Pico, Pi Pico W, Pi Pico 2 W, RP2040-Zero, XIAO, Adafruit Feather, 4CH I2C, ESP32 hybrid, etc.). -3. **Ask for build type** — **Default** (all output modes available via button combos) or **Fixed output mode** (e.g. Wii, GameCube, N64 — one mode only, no combo switching). +2. **Ask for your board** — Choose from a numbered list (Pi Pico, Pi Pico W, Pi Pico 2 W, RP2040-Zero, RP2350-Zero, RP2350-USB-A, XIAO, **RP2354**, Adafruit Feather, 4CH I2C, ESP32 hybrid, etc.). +3. **Ask for build type** — **Default** (all output modes available via button combos) or **Fixed output mode** (e.g. Wii, GameCube, N64, **STEAM**, PS4 — one mode only, no combo switching). 4. **Ask for configuration** — **Release** (smaller, faster) or **Debug** (UART logging for troubleshooting). Build output (`.uf2`, `.elf`, etc.) is written to **`scripts/build/`**. To flash the board, copy the `.uf2` file from that folder to the Pico’s USB drive. If the build fails, the script can save a log to `scripts/build_log.txt` for debugging. @@ -280,9 +383,11 @@ Outputs (`.elf`, `.uf2`, etc.) are in the build directory; flash the `.uf2` to t ### Firmware documentation | Document | Description | |---------|-------------| +| [**Controller_Mappings.md**](Firmware/RP2040/docs/Controller_Mappings.md) | **Button/stick mappings** for all input controllers and USB/GPIO output modes (PadIn reference). | | [Wii_Mode_Guide.md](Firmware/RP2040/docs/Wii_Mode_Guide.md) | Wii mode (build-option only): No Extension / Nunchuk / Classic, USB host, sync and auto-connect, button mapping. | | [PICO2W_WII_USB_SETUP.md](Firmware/RP2040/docs/PICO2W_WII_USB_SETUP.md) | Pico 2 W / Pico W: USB host wiring (PIO USB), pins, build, troubleshooting for Wii mode. | -| [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, latency, XInput/360, Pico W Bluetooth, **Switch 2 Pro + Joy-Con 2 BLE**, **Pico W PIO USB wired unplug detection**. | +| [GPIO_Output_Pinout_and_Mappings.md](Firmware/RP2040/docs/GPIO_Output_Pinout_and_Mappings.md) | GPIO pin-outs and mappings for PS1/PS2, Dreamcast, GameCube, N64. | +| [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) | Firmware improvements: PS3 fixes, **PS3/PS4 motion passthrough**, latency, XInput/360, Pico W Bluetooth, **Switch 2 Pro + Joy-Con 2 BLE**, **Steam Controller 2026 (Triton) BLE**, **DS3 USB→BT auto-pair**, **Pico W PIO USB wired unplug detection**. | ### ESP32 Please see the Hardware directory for a diagram showing how to hookup the ESP32 to your RP2040. @@ -298,13 +403,14 @@ When you build with ESP-IDF, Cmake will run a python script that copies the nece - **[Sakura-Research-Lab/OGX-Mini-2026-Testing](https://github.com/Sakura-Research-Lab/OGX-Mini-2026-Testing)** — OG Xbox Guide button (tap/hold IGR/shutdown), board support for RP2350_ZERO, RP2040_XIAO, RP2354, and 8BitDo XInput (Xbox 360) LED keepalive fix. - **[Joypad OS](https://github.com/joypad-ai/joypad-os)** — Reference for Xbox 360 (XSM3) authentication with retail consoles; XInput mode on 360 follows the same approach. Descriptors and XSM3 flow are aligned with joypad-os; single config, full XSM3 security string, init/verify in main loop; USB is initialized before Core1 so the 360 can enumerate while BT loads. -- **[Bluepad32](https://github.com/ricardoquesada/bluepad32)** — Bluetooth controller support (Pico W / Pico 2 W). +- **[Bluepad32](https://github.com/ricardoquesada/bluepad32)** — Bluetooth controller support (Pico W / Pico 2 W / RP2354). - **[faithvoid](https://github.com/faithvoid)** — Xbox 360 controller vibration/rumble fix (host-side rumble handling, including wireless RUMBLE_ENABLE sequence). - **[PicoGamepadConverter](https://github.com/wiredopposite/PicoGamepadConverter)** — Wii (Wiimote) output mode: approach of USB gamepad on PIO USB with Bluetooth reserved for the Wiimote link, and button/stick mappings for No Extension, Nunchuk, and Classic Controller report modes. - **[retro-pico-switch](https://github.com/DavidPagels/retro-pico-switch)** — Reference for Nintendo Switch Pro Controller protocol and report layout (N64/GameCube → Raspberry Pi Pico → Switch via USB or Bluetooth). Used to align OGX-Mini’s Switch mode with correct Pro Controller button byte layout and emulation behavior. - **[Nadeflore/switch2-controllers](https://github.com/Nadeflore/switch2-controllers)** — Foundational **Switch 2** BLE discovery, pairing, and GATT protocol work used to implement wireless **Switch 2 Pro** support on Pico W / Pico 2 W. - **[TommyWabg/switch2-controllers-windows10-gyro](https://github.com/TommyWabg/switch2-controllers-windows10-gyro)** — Extended Switch 2 fork: **63-byte composed input report**, button bitfield, init/feature commands, and **Pro Controller** rumble packet format (fork of Nadeflore’s project). - **[BlueRetro #1249](https://github.com/darthcloud/BlueRetro/issues/1249)** (darthcloud) — Community reverse engineering of Switch 2 **63-byte BLE reports** and GATT notify handles. +- **[SDL3 `SDL_hidapi_steam_triton`](https://github.com/libsdl-org/SDL/blob/main/src/joystick/hidapi/SDL_hidapi_steam_triton.c)** / [`controller_structs.h`](https://github.com/libsdl-org/SDL/blob/main/src/joystick/hidapi/steam/controller_structs.h) — Steam Controller 2026 (Triton) BLE report IDs, button bits, lizard mode, and rumble layout used for OGX Bluepad32 support. ## Licenses and third-party code diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0e894adfcf1cf7eef5b57e887867fec81d7caf35 GIT binary patch literal 988528 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≀n0-U#M5jI{NW6>3DaUdv@RTyvS?6(2R|$` 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�@O6s6!UC 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≻=$DDbRS_H&ZmUcjBEnTh{~$5TMQ=l=`0+{MB(v+5RnvBU#WJOthL4xKM;55@kKcB8H2sAZvzq zyw0(_FaXd##PFgP}#PE$k?MN$d=g*p{I?Cnz-ty&i@KZ2$1Azp%#V@Hj948flqF=Dn5Ai zj6Ez&KuB0NXps66oN1ft6xh)?M5KbQ(y9;txoqhAlacom3GJgI#05~lM^(+75di~2 zKm{r=X)Q!E>I4js3H2B<07^&K>3E-pbJvgL;&mDBfeK17cwhu}SB%vPGN7!0Au6Q_ zVE6fL+P-PJ3AYd?208&u>*eCqZ9j>9e9+{CAYw;N6jt>11a%ZkJ)$W!ekVB5{ha)B z@@g(?XKH?g*U3k>+;6(UZBKZ8#1G!&>cRBH@4kiCpZS>e4Y@2r%}+N1h+@VX+%L?>Z7+gx;s)CgdL>@L^E-^5WorY4TQL!ZeC>EnUdP|dfi(o`gLasT&Sn}j&I0cGG zdoBL0> z63sX;$IKwCVR9(E0GmL{U8*FLZ?r}F+`yRvIkgis}M{t`KAv76~K7oFdLqL}IG@Y}D1@kalO@K#f+2(&-Mu%(=zk znFxy{NGFg7^r*4db;P0#i#atXoZwv$80>>Ik9~Q;Z~s1EiF1WQIqox^-Y@R zBi*W-NYo}weR;|6zFs1?{#>X>OMK$6BHJnwbOL6_M3lG&%?DAo94W>AJzXFRc|1$o z^#f)&MFn9(0k#k#u`!0E5Nbg{yPHzZp?zs|Lj*{tf;%x1yby$MjT`KS;sg8k!UQ_d z&f*Lqw{1L7KNk<0c!w%>sTg~X`T%9Pmxu?Kee=qgmM|Eutb(3)Yf3$0Bai>lwRc-gs zM+KA=8)i#)W(##cE+)`S6Eo{QT@)^m-`DZHkFTx{h=`m-hcX-;AFsyYhyME?`ZHhp z#e3KHc6N3U*$E=lS^=!a@!$ROFTeUVuO^|p@44^FYUDqii(Ku;a2UZkn{8@Yrmq80C;Xfg-x}TD7|5X5bm1duce#ZaEq#?z=-RoraNGI zp@XcC+?=Y$>ubIV{Qa@T>#Cp&on*^SDo-y5U0cvuS;hjUEcE-Brud}a6ujcnpS0pCcu zxOLc>5f-2!fMV-l@0h#FNIjQZo}jAAX^uOJeXedDQc??94?uSNZ+pprwqhjv&1T!O z)(dgx`;!)mbE$D*MzpU%J8>Q`Xhk*_l;T#unod`Y-m#<2e&MtyD$;Pw*V<%BW4ER* z=h)p$-8hR^QZPNjT+3usZdNoJKyUB{+`_1FnhC?*!!ZqXZih!+t}Ozd0wRO}l0a?0 z@8nBSq6kb;dm|B<`;yaBXr4&nsOE%xkJeDT4R0ILBZU=j3S5{5v zbpu-Phr+Qjyfd?hA>1=ao0eK!!lC36v?F+*fbl|er-J~Qffg7tf=MwMEE6p;J3y&w z_KtDGnb|cEvbL7|749L2x*>Me8~#HBvJ0Ew+z``1p6$@onPzw?LWoQBXhXPWrW%fP z$4jvTDr2uBMF&@MmI4u&l!%y=hzoHcKUkG*$Dn3FoETgpkHkTl@oT>ov3(-H&EH-? z1SR))K>*w9sJ+Dqjbk9xg4s%JREq9CH zho%u?-u+xObs197#>1L{s<=sGM5i}xk)tF7Rk2P16y!}2eMr&>36>b>W}z_WBz!r= z0($n6uDmNGv7?@rLt4zJvs&UvdI}10yCJL~Yl@p*Yh-ANJ79KE*EDy<65XQEuFxY< zmeEITyE6g?L?sQvyi1$z4$P|n(jAK!A4o0vocBT{5UcTSQLWvPNIC7SQ4)3BDMX+Z zP-snA1_()o{ZA*<30k2OFssgx8B|q{bvg#9&NOXMfB_(2bPh*h@L*!6fSq}r<}}4y zihA|VVX1t=PRJwE0FEv0Nm{l-j_Rw9(h>Z%V1b~ijzdg0rMAldh4kv;BPXs@HOs=_ zFg1bg8RRoJa6Fr>q^I7j`A`4Q;;W{MPh2b%^$F znhlx?%ayc;^Z|&Ua1)x{h9@GzFbs8`>pXwgcYfD5eakoP@9z!6;07U+h=^1I*6a1_ ze(N`1^XgYaaL+TJe(BQVJFD@wbLZdj&Ud`?9d94XpaiLPNfNoOqMKDfDHaz^NNxdg zUDDlv!zWfGzwkF87lcJUEj8Lq7cRQq$gVK96gQsn+Vn@b`VpsP|mr*MVlR)k#f>S zt)_bh_R?ans%Xw?hnJvLFA@thG|r^lRm(PrbW~(=B${R$RY&T<&8kIF!$~O>{zA97 zB|kPZ$0h-@_>4-!7@{!f<8<}p0w}udbRsdeodco4g}JpmqR7Po$$iTj0oZBpsibmz z@|3m4_yIJE*6XqORtBk^9(6Wvc_*)8pa6TM>3xB1R(;uaBU-qzwGdqqfG{(uz z0?mJL%FxBZu(6fS0p*MwAWI>i;A!DMn@Un_r(BX6Evgw*;kh3-I^CQ@@@NFJ6VYDp zkTg(`C{6|9$u#nOCM=MHHi|n=9SKo^yO-qm`<)#rI(RKdYR`$My8|-j0pxlev$=OS z$DuTx`eOnV*dl2PKqN$Lh0H zNS;Iux=6PyE3pWPdVfzVR`0e1p>3+S5!ygaIa35y(ncjGfu>Ddl2Kc90v~8}Xx^!7 zn?z0beg8%$yr{Tvh^8x*IorJ_oaEF+_6e2uO&{trZn<-3<^bv@)@>5_APx z0kf(qtw{$1w!(L>ApFfaLRS*bJfhlN18xno@f)S;YxH3o*=(y$Y~L`Vl2GxTjnM>| z**mF09BJF)4&7wpnZ>W6R%~W{_XT`Ru9J-Wgm-SK=9}DqE4O_F*Y>DS78D=JtRi%J zVknP#F8u=61|eJw=W!c_Zr7k)CZ)my5g#5Me9`BA{@?!YS8q1Q!!UAbc?o0D_0G;4 z|KJZ^{hHV8U*Es)>Cd?M_~W~))otg_zwK>rd*?geJ`Mv2ZC@Ee*g2e(7BW8nhYpB( z^F%*F$lV0)-JH>6YZI)XCWgYKh^$)N<<@Ex``J?RM|6q}S-587L;!zl%5K<1wZ7ld ze2g|%O||3U%3ha+McCzAQpu3doXE{X4PX(_F>eB$nVC5hmganjVohXES{QqKSqlfL zGf2=TP2Eak0giSxm{SkQB+kx2AeZSrJ&w#z3j?Z#3iA^8u*i^cWn1n7m>k(@<}^%W z9-M$ivz^Fc=Rl87q|q$UNAF|ZJ}HHH!ePnev$l(voH00@Pqt$fBWcBqCCPPj>wNpZ z>_2hr3ubQHR2w!iWqgB`TPi9STl>OvG6P zVpDPnpn){f5V|3hLj!659k3Lk86VO}b|i@=zLNSpA?fGVB)-`*TKPR&9+e!gQSGT5 zS!+*=nHVlm?#wS2yy{r)^2~NW5B^e9L&?`B`h-iw>~Y`@V7Sq4$7L)+7i1yRfT4J z(eI>CpV>75M8w3}V(0{b3zuQo+q?dWpYY5d{K5b3whLzukB)ZMYZHnRyY*J9_1oY1 zj=%Fg-}~VYeCWB)f5FAa9^F~5&z?K?j(5EMfp@=i97j>jXfZh(Caa&av?WwJJ06`~ zwN=SUE!A^_E8a&vky85+L4ri2y`6{b4NE4-YjS1-$(Dz!Mg zilEEXEyiyiMF47{4ncle8NwE`U$+SZT{goN*$L=TNR<33buVk|B?Q4X4sJct0VLyL zk=V44Alq*gg}?BIQm%7Tx5lVpn?(nM4tf3_W|HnW*-XfVQI|XxXl;N=EoF1@O|9g6 zlN;G|NNHhlA`+1tts^b!RY8`B4!rHL`u%MFFfaNdn|hqK~R^SfE^B4l93T@%v{3d(Nx^+KL4`I zlS}Zq#cEw*AeaG>opUl{_BN~w(M@S~#WFqIO2OC65(h9ccN;O_+}@T+NWYPS&B@Za zDk+5;r-#JQ<}LUzcHo49eD5Vu?#6c5Z&`zemJF>qnv!ienZLD3B?_~<;WSNuBaSd# zGnuA9);8M&y7MiQX4Cqy0evq^iF;zRvH(hP=ASLcw1j57!toMq8bhbRpGmnMLj9D{PPb&D`;Gs;G-Fy88;}rDK!oBOy+-kA zK)(AqDBni!Fqje{V5rMV4fIwn0k+LOUEy%v!;&!9lq@oy`!mtO+?m;4%?(!eDx#nS z#8g|r&LK*PJFiR#Pdl~;+YR=8+hA#=-sR-;Tx&$o+gU?F6#b!0^l2l5Hn$FRO5Q4_ zWgsj7WbcaV69QBS1%O)TIZ7T0?(+`DqB0W~pML51dr_akPzDu2IlHQN>|zZNs1ODS z10(2o7EF~&l6R&NI$;;a91+>ku_z1?52B@A)<5VIQUa?A$SMRf>CKC|dPu%28VcI( zKc4E-p2{$^_&I_;szdMNZLuBQV60OvU3@%cQa63*iT&G~j@|&%bpI{QJV)BP`9{wY z5GGigbSk1ALD>E)ZSfn<%LR^ihdD8dE0L_sFf!8|**ytZTTx{m4)zbnVR+4}U-N07 z@rrBLuB}!psFqShWY$?kc6N3ieeALC``+(+>z};+g)e^5rHhZR#^LPQb8maw+a7%2 z-NP`5h&p?A%p9(WHtLiUt8x1;U8yY`(KfN24i+K~Pbteb09fBn?G#$dVz+&KC*&d! z-w}@2d67svgD2+c9TzOnZX775d7-_BmR`%k@r&hiWY`R0wsBS(ihbrvng_9WFFV2f z-IaU!3=#1nkXbw-A$l__?K<*w%pyd~Y+}jJ8tZOO{o%t#&9y54T9!TrufS&ImJC{D zHTS(z6(F@Ugkv(!0{v#iEZqb&PEq%9ER~^ZuWR;1dwhw1Le{sS$E-E=RW}XdNB15{ zR4ME&_pFxaFcfns7WsDDmlp|N@*W08LtRr6C#qI#9O%$SKh(8H1)4)1feCgKr=@B8 z%TnY#=$-;P+>aKku-f=A>9zTv%?nk3y)h6Mx2P>XCB2}guE4%; zz?NIcqbdbn66R+(dtOmp7jSrGRt%r^3KJ_3<@C1Z5Gu@S6x*C^kT1u~X@kFmiUw%if!IUCKTHJtsOl1j5u)JEzn-cEVJwD zA(n{`$Av}TJRg|TGwf6#^HqUF}Y?%RFU{bCOJR3sl0;g^HgR)buSEMNuk3 z<=n2`ea_j-wzEQM1oozi<4OZV<`5k*#q%MFYyz8)Un~(@%Pus)x z%yiiW4Fc-D153dq)!z6b$4EyHr+Q0W$KV?b^8_zC?b%y;WIK<0i?6z&*GC>rZ=&c{ zuTFTL_^WZ#wvE>0`-0|ii_1WhGK=R$LfXSAFwe z`Ic|lKiD6~5gBbp}^LwDCyU8Fm}lyu=Ero9)8fw#2ylj_jrjWZ&wdS^W$5FY(ak`o3QLt zvoSOIS?tD2&=$dH+(EH=<8agQv;cK@>}EW2JNB8nxLXDn+?gRDV`u^p*w0J~GIP@@ zMN&T_O*#~b7z%aA3$+cC9v@^61R9PlXW=2eXnV#bHt-8c?mKO`>#b8SkMU&@Pz4OO zwrB_gzsbE~j6(@gRZ-to06z=_-U8DFPwobU$IEP)5%mjDFf7PqM^71Sn23stGI*=} zu+@mjnid$zF)>I)RcqiV!q2{drk>J_2o0rKs-G-Ptr9f-fQ~nbBQ4{SEO;~UOL@3! z==FR&l#4$|;Uc#CdGSZ}n1f&{u+q(0uL zK=qN`Eu^4d(FOs-n}m-oYSPLjYE|<19=zYRm@5;WBxxCiR;qO2EI;)eCa4gVaC`;0 za#(RN(FmDm!2YLzK&s=>4|_76RuA{2cugH>i)a=ZIZ5UY^AJzzdw7tJ5+c1w=}5OZ ztqlQNj6us!TRfB3a6=F91`nKmo#e{=<@7q`x6R&Qj1|GfkSWQ`irC}PZt-+sXxFZpDjn?az4Rq7`JV6jp5x;q zCSI*ps!$c{4?GM*Ddivizy8rr|J48XvQK{b;r@PMK6mcId*1u-1MhmrFpL`c)f5x9 z_E?oiik}E&E%?@M)a`8?-PPad_zaz^u`2}G=fc6@M=5r12w84H_7J)0c(_y&mE0xe zM!ATR$J6bRY;EOIUzI?`5-)%qZ((E+<`)Q{0ZRYx0nbER4n<)`i>lT8L50-{{~Tlx57Ss|&jcC=c_m9&ezhuP zw#U{LrSuB8)vMaOVd0pGE#0l66w!H-4M$=ysVNdlJ~y=31d`+=4h1A)D?&B^85p8{ z3{rQvfloxRV?h_2E|}O8VWgy-vGs2MBoxZTVo?ybXo6YpY3!silXV+Si1t@|b(gN~ zShdMT3Uu^&U8u&fEAgk}3n{pK0FJ{B!`ex)M(mkYCd;h(ba`MVYK@mXlckn4Q^Sj9 z9@K}jN~qGxIkOsB4ZMajwd#PZN$x$XTpCf~sLeLS5vfRxWdaIM`9%Q2wt7d?DNm6Q zm`DT`3+v>&vzPepvd~oIsg9Hk;Y}G8khWv=oNAOLHLPv+HF?hL(!h2=Yd`bEv^i#Q zdUaDC#uhG$$upz=6qh2Rs$%ej2M8!)D$Xg?dFf*3q!AS}5>;)3t45_x;lU&chhvE- zcJP^7RvB)j0W2a)U{J}og6tlPcQD7{j^scKBak@I>H^j!0D`kn9EPMo;l4Q&k+N98 zmm&#hRV46iaHAx#!g4PZG^1Z7&cjIdP&Wx&lz5#U0ZIf?(cG$PJ4=~~2FJe%O6}S* zlc^dT1bP~Zqnnb0sWWjojGUBBDI7Q} zLN(H2nKD&ZhjyE!pWw+NmoQ%a*c-ysi82j+i!fJm>e`uy)ZN~jWvN}Lf3{nFFIwBk z%>inri-fMER{TWqHV34J@xOdDZ5TAOvAt9iPg~jMZqN)<1c)@_o*bPZ*z`1a24^>=z=CSAJe=Y{nhwT`)@R`x4gT*h8z9@pC6s_z7y9Cer`s|i7!vOJCxNj zAJKJFpYWr-^yHtB5x>c8{dEH@^bT1krNSpOPK7EM&9(?TwcE(n`ZbNiaCmrl=FIMY z``>=|bDr~w*REYVbLNcMeAA>NwUkmy`GtS?i?98$AG`lWFRb%i>wL$Zcf9ZYAAI|t zyk!^$xE_d9QWhF^OSnNK;-k7wf+&58&~5CVR~q%9JD9qSrxq!X1}$M@`X&lBe=0Su zYc>)$N+^HQ%x;;YZ+jlmlD8>Q^VIcgkkH(Uu>B47lrCdH!48u_h{sf{9A1y1;e>ZTbFfVR(N?*6mxe^j&6|!ZA*Qai|q4HlTZ?2~mYW+KLF? zUeFb`!<;fs;=l;jaD+9?^rYg8?CSh|b-rZE)i&`RdduBz3d+_F?4gz&eqPb7*;Njz z#D0OO7~qJ+n;+UbT@|aUs6ZAZWd4+;f6&q0FXODcr5l5dMwCdMP+6 zS;PfN$44%;wwSsn3k~ATjmBt~Z830jmKT6h(t@%u>djpZ+;CHc2ul-I79K@1Ap;E> zR`X0@{6>v}gMWc1M|ajHyF693u4#gW{0SOr=mco60(B59AVp!Yd#7uGb(c_$9sY(0 z0)a{nOHkFq(1g8Mc#_Qjj78DWd}T>;GXlid%#}xnX1yxsFwxrdjE{g zEL0)K-q=YiP~BOzT(ckjLDzV&*2?drAjx8Hu{%C$fIgEy5j2uP(;Z~C;Er>wu# z0Kus@waEGQ&ARw2Y)uoF{(iu9kgF03mxGFx3#yPUl?yZ3zr?ZS9e_n$si7~#SvTEo z;S{A}qRPav2Q^vROm}k>V|}7#Xi0dAT?ET_L)i&y@V75~1r8$@5nd1hQTC?zGwt(oRH~piHvl*a&TK)s87dBuzVMaIp|roCB}U zWkHr+muRMt1-`7rz}6My;cD0Y5s;|lxh^h{d{aZXy~JK$MiK4-ERC$9=^P|%5ec!l z(U%v`EpCYgtJw0#l;V|XuJkgDqEQVkzw|gpH_p~4 z>Ymy%jT#}OHdqSPW|4P`1a%rJpW6CH+kYsm{DnwvcE2VeY5#KrtRbu6lv{W-9;eom zESv=@CaaiiGxq=<0rG?Bh>=lg(yl-tB%dmXRK#-TL~#TZyjDNlw$Po)3ReFb>e5Gb zo>34`yCY;YM05NHpi?ZNAc~H(a=z{;wm#UlBB@qTt0Jhgb)SrGlG=u~F|9nrEDh^+ z>GcZ*fNC`cQwW$kPd*}L%u1}x)*_yGAYKv1VU7DQ;7;Jf3J?o{q^=5o=o;Sro*7D2 zCY>iSe^qAKnX$IJmEecU5&(wQM2>HvXhdq2(&14jfjiusiZleSQEzC_9-eN^1;bEJ ze?6_A{Bn!>!$5ZOzG;>fOS-?ol?Lvqx1Ro`MoG_q^y^kU+grSrHd-gf@?G6GTQ{TW z^!~FUm^;!(&+{Rws99?;GXbjLp_DRQzjo#M&wkFUU-O!2+7v3K7@t_(6cY^>FJ1hR zAO7LJYkSXm{_`Hc_}KaLw{MQ;-~atLG7)i+I>ThhGS;wd!+xaKO{t{=Si_TxpiaW0 zv$IStDHkrK6fO!?(OIfWo#v_v38UcSdQsCoi^YBXXngS+BB=KTftvzhtaiFePLTdG z7=B9^x1s=zfuH!_{x4I5ZqkK7-C9={Mp&4pH-dzFQSA<&Aw}t6vVGV6crhX^zrTem z%=lY=pgl?4oIFEWQy`0YN;f-iOjJr4hGDf{tygPen&&!grnyehnZl!4T?#SZ7#&t& z<0odqCf?@qPFDG!_J~HYlfnV*byw&k1!=E@X7Y|;cDSyek81H`Aex+!A00x>T*@#E zWf+RNsiHbf^YPK)W|~w*s*q<~X(a9~{taAuGpB%wH-d7|pz~22M1}&&G_)%Zq*0VH zFtvJzfT^ldBw?vlG*j4MY4m!w#Mb9=1jkL*fOx73YQ?J+z$XPY z@JM9&Y$IUZ9xd+)R?AkX5Maf-=aflh0*2r@K?{HxJe@c~$+&9FaQ|t>T0-emB1hxJ zZR)=ff0?y*(tJAYyIZ@AWQ`!Y_xJAw(Ht=+)!uf*j0d!&0dpXzNqR_~{UZp@S9D$7}E zM{-87w4^#C>0MsmmfLL*p)^l1reDXd$|)sMp43HQ)ELZ5AtEp3*5AQPb~+-vpuhZ>837X!1?rljd% z#)yPCR2Tth5Skw_n_j5)6s6nsypD8r+I+(F-i?1>e%&2%lhXgjHrQ#=ohMS8HyCZ} zEvE~QCu0wudS@n-KTcOOUwV!>AVMS>EMr3eP|C15 zI$DpbZ~Kn_>LoAzr0dtO@9gZPFcWAYsrq;+2bMc6Nth^?R>> z!{NcfxLVCMIKO3!aby<_4!3}yHy$p8U;qo+eWtkJIZah9rIf;4c%J5i!=t3n zaU9Q{J#+s2`Q4o}<9bA-VG%~DMa|5tRNs3Pv!W0gM#WP5~i3Z={FZLm8d5K_kN3GcjwDl(PnQNT?p5JUu;>GZ&+Tg$PQs+-O6_3PL7uJ6rt2C!P~?CkDxp=q8_ zRYVEdQQ2M~nOw4jp@?{QsPJzAgo&_7Z7dakuxxxs&HDF;B8{~8HJxV>p@6=Ro<0On zvM!W)9Ea6vMPQM7ba-%lyqTwoOIfeiXU?9zaOa)3ojtQ&jfDrb=&^{ZQA{8@{Ri@u zYHZ~oPx6N}5b*>%ska(Z-|=Ws6-#cHp+FSGBGoC^aqp>k;}4A_ECW@9qBjrxjifzv z)9ebTI>d~+2@#Y6zzYo!U44U$O`_NuMO0KosH z3)DNsr${rA%%w1wQoMxQpz7kuvfo;@IwfeNLeh^7LYJr{HVJ3{$DDGAoLZU~^r<%S zD$VzCt}+OO>zm1_Ov@u88XEg5tX4KD)TFsen6!i-A!lDrv#*MVj3V1a3x_>>Cm|lk z)i{&~-}CVP-a#ovWRBi-4&YFoi<}0?_6$fi3`0HAGk4wf(oZQmVwPbnOen-)rlBwo zjH0U0T3w4MlvG7U)JaT&15J#w%H)JZ#U;Pipv|Jq)^`Ipalj>IX?1s+2~~t(~ z*up#ql*pP$o4oENTYu?^&nf-Va`%lt-Q7wNmdOXh1aS6RI#2C;`|}2t()I-U@3o(p zS70RBcW#OLu~0~pEDRL_MOB!>S_CURJ?NH*1^7ro#O&#lVI*L_eg)-@+h6$dGiT2b zP^USBIEzeRfjPGz;sVqBsvzszt_pA&V8kgEAfm!Ufg%pdVt{OOxRNtzwAEFmICjyZ zQ3_(zDhko+r->35w(Stsu#;4+dBK23)2Wi{T( zBz#C}?Wj@JPMz0WDQ6?%g;DRuK$i&UD{oFQ|8LD%TVz>J-oIovgdl57e=APRlkj!o zbtlEiM{-d|J3081n#!%d$cDb9dz+=$9$1vUx@2j}%Qtsv?u&CJ6G!v`W>G2R`1tTE zzTzvt^;^GfZ|^$0sZDURj8*mD|NDRcPyg9Jd;a||yng-Kz;y21xi|mOTONJ%!|UC% z^E{bs^Lh1P?jZMwJSIh_H9Ia1#a6jALtgqtue z5iz}PN=u}w2oobZ)|65}erPW<5p&@JLSa%r=ELUV87T90&G2GxdE{8CQdL!}mB)nF z>MaY%Di}4Y839!B85Yh35;NOgMX1feO3TCz(Vzfxq$G|lAcBaPn@Sv&)#eYVS_+Pt z1zL!u^G~E!Dx}eRKmn;zn8Z~$n5l{-e3S@MwG`VioLhpWnBHX;MJWsgGtIREn%)S3 zq>6@@VqUDw6%47uaWaXhdsfV>PGG`?jTow#m!dE~hgC(vZuLqPYv6RSzxSaJedvAf zegA{+dElXkAAZN%-gV{5MP@#G_BJhLnx;6>C2eds$|+oYH+<8~A{UgJy9mACw5G*# z3hTPl5!s8hqbMB%jTlWZc|`Low9~H@B?_Ej$xZDh$

    rAl=Sxim3I z!b%=UGeO>LmaO{*gROp~`NQTki;9TUDorScO&;=&*bb`kD)dOy!o6uxp-A1r%w%uf z=B_R�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

    GbH^+x_46 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

  1. RW%{m7f>F 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

    {yISjNJDWWcK&?`C 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 z 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%0AStET^G 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�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 z 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 za©ju^Ifq{2EqV-`Uu;okr&!`8s3r?#dTr%EX?1OLFcnlDt#f)(s$hOxs2SDqt zK@viD_P+Tf2`?oslWJc4tQaXeoa+5BhZn<F zN3vr&{UdCwz`DsCSHz9O5~WO5zoPZF8=_O1LrcdXNSC~0BLmS$;}^IhqKMF7@T;$i zWm1S6a%c=K_5K*l?<=)df*SSQQ4u9Hq*Ee+49r|;?JC(rS4v_jD4ev42%WnX1k}E^ zYcdv`L8TUQt)#;*4cv8=0Lxj@vRAa|d`aMep!$%TsVPcQ)(rHdTcU_cICp@OmRcg` zcCjdxV)`Tq5jk<{nG7o7#-^?%%Eyj97lz_p=N^t>gMky!=@u}4vVvrIZDg|W_=lM3vi{<2+ z-tkS3JiGu~7s(=kl3p`J0Z{kGQ7N5*oRP4HXnL)~LCw}%QevZW$hrtX>f3OxS79Kt z9!aVs+AM@(>FJ_MT{Yu*FpRzAM%nb9;)_=-$VE~yl?mm)DHtitXYb)N{ry!LKv^!A zc042-(DOMDO10NzybpSRQWC^7iCr+N7cmCr;@wHt*yDMv13Ri@(klSa`7uvC$B}P$ z%>n?+@~dsPjnX+rA1WDa2*{{rqH`HAbKwxW%R|C<;qY@i!9+U;r7c=!x=P3-fs3xU^6CoWX!k$WyrjtCP?= zYv*=rJ1y&7D2?w#oyi+U88yeGvZRc~`UPX;G9fs-(63ecssq^S(1tJb2r?EzYdmyz zaEx?FdzZL2Poe^ccmt?Xqc1Bam!%_9&J`puK~VIRmyrQ_yfbKS6Antpt=(30kTOEz zp=-3P{>citj{?&4RkfV4tQckk1T{}-{NKZD%~69MRkVFNtYpuVH*X`_2bxL39B-{s zbpo@VYuvgv`sDhNyM2~f!#Nu6he0Y)uK7H04hnta(D47mqJ&<~IxXvSbx5{ezw(oq zcXl4?*O==v7Gr?SYHHy;Y;q26lMHqwNQezSuQj^^`--ZLWY(|Yx-ky(cw9n}$V&p4)s2=HlnuiT8e^h4`yXgSPLMjWt z&M}7*f7;qm%wx)-iKqDFGD2FGZ4}^~GE!)1?4p^2-KhF_$j*%n@#B}IkwjOL4ZXBb z&@Lt6a^`AC`&9;rt#m5$R31IG+_oTC0t_CaQK{qZt}`2-;+UDj?_pz9AWi|hmjZzs z=W{1E2~L{_T=NJu?F68UGzIfOpu33Da4KRM`sz~F(B)VrNrWuT?=^9YagKnB0bB(6 z5S6a^T1H%otUwcDJuc@6pr8ku48_HAtm~K1bAOr?B~&_eAoSy5>5lCQUi;5Zf2HFg zcBbtGLPV^R^L)s~ec1;Ewb&4U)d?)2efdy46Vut%c0xu=gxkgln)Ny0 zvMte%km;Y%|LZn~0IShf4Ds1CJWkOoK`6>ZWU+|dxLzKD{4oEFSRxlDNPYrWsh1o< z=J-bMld`>Mv@SbX&IS+e)*1|B^lD)k;@pdPlCn&UaPl~f8IPk^KDOt%z{7sn|Efd* zy8lE@-B=fbl*p`uV9)p*A@@BxE)0R^QLfUe6jGuDx-m)_Opro@M}tD~;Mk@((Mv+YK^RzM$; zDCU+itBBSPTk|8>`8Vg(AkE(tetehn4T_ySMnCjObR%B_Hr$ok?0j4=Rar4NK|1YpLe42}z#x-6XqpPV=` zu)M}aqB2%CKpq(bDXCP1QbtfMpqd%uU7?{gg-1amz9fgVq7{f3w~r+k1xkx@M$_Z3 zLXd&iq5uH1ElET{RIw?W2KHtVor`eWW2ytK51CNB+d8&&yq&uCZLYCF&G64iCjY2K zx@hl!mYcE%LYtVJnP0}1Qtlj3RFuP%VBNgZJPdCw|MWG7-u!)}?Tzx=Cb|Al z2h1mUx|gKB>B>!?6`MX5W|LqS^UbrPlxn`FXU~b~B*v_XUgmzXAO%6l|63dejXCd@ z>?y;tRN0mpFrIcM?tR#iIB{cT*k5(iP9PlxjK;0?>rp%hcv8Ye8Bj1TI}k~DLjbJ) z$%=acKo?3(tIJdLkC9(vJ=Wo%46e^oje4HIy?^GP`1X-+fyRZOAfhA)PUgs<7n%a*>cEV@CNn;MT$nW$x6Van#&__vjxvLo zEKfhi(@#DAHDmyd1p3>^Xj>xABW@OCsE*VvAbZq;T8s21moXG|{*mLL?LiYxUfsFj zM7jYeu$1BP}sF}Q8+B1Fo#T96BUWvNTNb?74--1 ze+fkOua)uGjf*M&^+Dmy-;Ndjw+QYGJVg|r5$#T?Q$X&@hI%@NQf8p99Mdy=hL7@i zfztdecgB{vcB+zw$`g0tV5{u+Ng6Q5UcLFkVMa0pDQ2rh$VHvP;`kt9zzM;1=T}G+ zJQnT&MYe3$HLl`@2})Tp%TufBez)K1PUIw5$IEBVielEL!!k{OC+Uz9^Z$z4$06yY zqz+3J(L9NkDQ_7SQKl&P%2*$KzvkKWoh@fE5w7kY;#dp<@-~gL02NC$fZtuf!=VW`JkMl9mG$h8bfB#hhf5To`R=eH=iv_~I(dlmgG5 zfyN9e-Vjs7F46)#t=4omZ9CLYsAR8^8<@})KKwom&Jc?iKLH`-SDRwg)fp1?Ndn4B zmW`)i^o~d|n>4YoIVib}+dgZI0VS1W@F%ps8jD)#>p*)Rq{V?Nr5B01B^K0YdqE!a9fO+t?&oHHDj+x$09EwSo{4e#0!NP_B8Pk_ip=-i8b0Jy$veeW7 zi8YG{EW_n!3yL@)XpfTDccn_g^-H9qM=7j?Xa!^bkqrTz8ClYKB7%S*1_L5V;btad zb3JqjboQR1{@FE8s9X(WBn0Ya2u=URejgyyJg^<@0V0K^ZUe@eopxzMwjEJIR*9sR zpx?`q7?|}kY_BedA{|eXu9kU4@cZmo3BeUtJHyhnSW@MRfZsP|Q~ACN;h7L^ceTio8T#-s+E{CIzh% zxfShkboiD4nxC}ZG5HI>=fK}6-xM%@&4{hI*zjF0!Wa5D5qcgkVz9f?fkN8r8@O8y zkj0qK1x}i|O#iAvM5~aggfU2INJ8Zt1%stL4#W373>hqX#jddMSv6iflSdspri`pH za|eV?6voIU?ZQbimP#}a1L;O0{cFlfXI3kqg3{R_p-s6mO1}Lfq|*jUTTzI}fbwh7 z^@L$6fhu9`Eg|d}NBMDA?3AY%B?S@1U$s|gTglj{5*`lde~nLjfgqa=8IWNkfv2TL zNqUpLhM%7?(+1FtOmn2i=sAxJ=tP-bQhbUIsEkO;9$uzT=LDbiYnKZLAIt1Z6v2>+ zBT7eBaJ8c;WfhuqA}aIIb;&?PFdd;}XUU(U&fjwgiH zs5oRmDL_|}zA~xmT2>iXLnUe+XW3BChy=>*pk{qgJo7GuFN@T2aszt{L48PI*_x^m z1?79LO_0R-9$rHODk57!Wnc)S3YSOis~bVcrlrkv&tgsEGKPovE4|DR@R}vMX&uLt zmAdPjBTg&V$7)FLX2@8f9`{ag{ReMiFjMA#zO|oQF$uOwT(U%}f**M>8q|>|;*oW* z`%ie7x}3YN)OI!@3V@?G%4TmN zU>Q}htK0x=&M9@$A=T4Brmp?aGeGG4-3RvOWVBk6 zO<*r%sTkB+8RZqzEuAJ~{l;>Pkc5m#W`W>m&>8{1$4O^o(hdfBGXZLolmME@@#c)td8Y|rvs@(jw zERXG!I(g_5GJaye8cTq0unhGj7afv6JPaJzwnCVEBu#0z7>8AcsIl$QACD~-K8SW7V?2aXZbJHvflN*ZQ%G-oU((gnzl6skd)QyfeHgLncU5yv^`lWtW z9JAgc7X?RTJxhvw%s3EtcjU}82k(a%=s%$xA%y*PEM<$rL&eEzSt>c}fr5=HH&Cu}5wglxlZ~<}xEj`Iq zF}RqzX?cj1QpPa@Fs-<^WeA|Or3mwsUQBFV8Wg#4CJ9B?Wb__OO-Stu{J{KQ`{!M* zp6kc(g#%>%%+tfPRh%~DTC-?rZe64xdI1Uro0CaY{xHIUX)4;3yCO_HvY&L+ZhzZm zSXc?All?pwBMByxmb$UcS|Q1Zg;a)#U#bH|Vw|GI!h$EDEQ>O&hB3D&W(&&QXf0Lb`LsyO& z*drLjlLTpIar&h@cIIJV>Sg<=MqO2VV{|17t}@w@R%HDOPn0cDGJS^_ zMHc?xR}zL&S%U;l3`#`8=7k^R?P&`BfsHS_vs&^kO+hrg)yBw=kxd<7B!kv)X-}Xv zcq{@KkS_eeCwUk`g+~y8p`decfyZJma_1YdShLUSXyziz1M&?E!ycu!V%qx>B-ypux2vz@K+y`Ty<6h|Rp= z+0&CP)g4D)x3Fy!WeJBWM_E1@pjc{Lc5fLM+S|R>58KLF>e2@_%bqV3$w&sV5q!dY zo{S>)u$_8!I7DOlQL{K+c)+lALW5%ZP^&SA-m~`;TeKYDVC_T+GZ*|VFJ(&KY?LHHd zb~RC{;d9^@edSn;%AVNKNsCq5L&4w0T?JIkQspOtpW7z|gp29A*1>~KF0#U@hOMXJ zsq>~DJ&T!Nu&#jLK2>`_K$C!E@kjp86xQ;8^fP}zoJ4Yp|JLrqpft@48r#A+1R^e zM2M(j_Xax^b94Y=n9@2ZyrCDR6lFEFIi9Lk^+qmu%<`gA~{1CYAIMMeLAN_+Uvks5$?{se)Uv`^uJbg;k_!#&6^B zWD0m$w22Vfk}8q9pXL&f7ci|(QDLPZ%XZ_3LqV&Hxmfa^0?ojmJ1*$w#9eebAZRHk z7?(&r75L82R&x;t(+_hzD~MkE3CoaLPO{Q+hLYqni$dKdUEt8O{&+b}2(IsJ$zJQW z$zxj{7@1IxltagpqNiTTBW%cIl!;U>-HiArNI_7uEbX7N_g5i0poz9yVF;;v05DPt z;usM9_GO0;mheKFINxkj4k|&BpMh_SpS74>f zI>!Bi7BO#c4ABN=-DPQ(4BOR#1ONs!+`q5WBTllGvzYO$_*kO9wmh|Nj2 z79vO#3{3wefIe)L4i{TQw8q<%k$#i|zNcQBf&SgUe3&gKx~fJdFao3=C^w1?4+myc zA0BU@HrD?ts-#Y%b7fE;6)4#wLwFe2KS_0ysC0~_b5>$Nw8SJ*8?jr?2MSwWlSz0B zp&8yl$3tQo6=g2aISCSV^O-~-9m1`nEC1kk4V#h@to*dCH(Sd?q}x-~7QO7SZnpEd zJ!#3}eiyn0LP_c>k*Ix}k+ZC2NX)N6tt1cGGWs(6WK9IEVXr3UtLIxUgku<}FUh9) zmrI%mqnnpxqHbF{%Nocw?YuNI*f3IHwPz91&I2?hOe50Nq7W+X`%IiPKzO~5=yqaI zfeBvKOgZ!fWq}a1NDcjFbdwsbk<}@5d9G`bfLR_;BJt|@rlJSz^M5=eh27Sd9!L)p z75ldcm>IRAG|CW(gnqyzDd?eu6fj`2f0C&VWgt^Zg0;73YB<4`ftdL9ib~aD&KZ#~ zV!o@($0QP_)G6o3D);7q01#n*bw5^7|IB3Zx#Jvck1I2gWba%v^ z1FAT&x1($a=C$Ldt`M$>IQsG=@MfSa4e>;87Sgif^%I zuD$_;{+1F+NVC>~ToGN$pv(2d!)yO*pHtw}uFC~wA?%oQw~kA^4aOH-XXmM?pG-p@Im*AuCc8P;avt0!iV` zuIu57j4@1(5Sz)yEP~`-9Gc81n^AGP;sUKvqj{+Jvv<`Y^N_@AR`@x6#60)omjPoF z%*(=P3Nx+5xft>ZMsmv54s65F-6AVLR97#bZIuzXAN$Z;IQ7))7WyfwWmtq*$)063+qkW!j6#9PB1i15E zL@YkWj7pR#PaycNFJiJuvOW*20q*j~A)svmL;0~@C=voxhHl7ALsAk)!QSq~BgNAW zPcHg8gI%6bh&LN^DrlUz*86_KreYq=Uxip>3r;m(D}3XUN_wD$HhkG)pifU1iER$P z@M0JYVK3awZk~tMkW^&$=OH+^Be=XFXDOpY#xULjz7Gjd{wG$9IQcVHHEDM^>-CeK zkX{fjVk{CFxhn(pU|ABW2A;1L5s%|AG@TI76ec7Zh`|vuDJU*^#e&Y7@{6Tk(xM#| zky0}z%L|tjy40bJBZPi-Wlt+e8m~O*-`-F{y`XV-RW~$NjK(CY`##WJ-Q_X1;+i-I z5HP4A%po6%4HY?2o--yCMSfL_*T1GIse)Fy@Y*U-fZ*SjK+Wn#G>|zP9&TDc*#+h? zR@DGb0=WXp#Wbo!KU#U+VfWdM*)Fe$D*$0Yp1W=%vxQQjPiMm#ThBPtWKFL<$p(8CA^kk@3@ zp6uQJq_baY;+0C=$5EeUDj2lkNO;`6n{0U7?+fY zB*_%sU$N)_VDbhUIlN5_%sB_6RPfab>!RR)IU^YXN;BzYqQ$l?=t5=0ZiWh{A@?-V zbw@hK*c0$kS8qO-O%NV0bTj0h--z#xsiy7{ctWIUn`Ony}n`lKkATygNMo(WQ9_asxEqSiU4b*Oe4 z-EM>e6GZX#gWLXTikFw{wQjG4^(0M`c`%GZ4LV@(zcA2&0q8saOKHq$JRFsj_7Po!szs z&{y5rjdV?3iVYG5QwGXt;31HT*~c(#6+l$F(OTv8U;TxXMq$`^CC^Y-yWGXHL5K|+ z54Rimu7L6hK)9k4mGiTYsIM@|3&Dhg^^xU3wKl0J`}Ugdv5N1>ToUnw;n}CGqZrO(gc;rlJ4Xjts{Ew1qpjSFslSxtf#Dy zJ7;kC&Pa7}#xhkPa)!gVScg>)0PEJ0!QQ@&nVAL3w8F7@#N!pQR`3@`Ww(@A&y#eN zN^1Fz(-3!PAPk(igM?QYG4k6oA&FeJWJQcoWg|CUhi-KG#>FXWwh4Kgg0yk;r2VrZ zUXw&&;bPWjx=O=XX;(z4*shwBTnR7|KC(C&Sy=NJV=>0iGE1VPlvLOx=eEV&JaT;$ zX?NL9=ZOm2Fley^7`VUcsFGM=j49-d=oF!%qDA4)n`H)s(#MuTbiIqhiV=D)Ob@zc zS}ZLVbBgnsUd2~B;=)nFV`Q@7p;vz^G|&mNhgfv@+(FN02bD;e!2N5qVi<;pveJ43 z&8dOp5NY5lX-Zg^$Y2p+^v#r1?DkHAQyLv;X=E~#PX>fH(~^=qyd=skokUbVhpsG` zD{Qbp__>^JRJzWBiAYZD6N8{HV^`wIC|12$(A||w=Q8NrIqwzP*7;tu*~dB zW2WSC@BeKZI4~I9DGD1%qfL$EC7W#3qyEoFU0wH6A;|=FJRF?elR=bJF-sDh&--0g zQlNC037EDgISeSqbfmtG!aB{v2Aoz}%JCJG2(x;_ea=3}TrVmyV|vLDJVzDjah9@I zz>9^4o+%#&DiPEd=4fFcG-S9{iiGH9hcGL!fdcOkt+U)iV(9!xsK(E`dYO&x{Er88 z6`iy_lFWqno43YxI3HL9nDXCJ5bnd}cU^%DfTa4)!X6Cz#zN5uBinnkTYDY(4R|3>5h$9pO$9#Fe$w@|47?4!ykQ z!g)qtN2uOkV&E~JW9+Mqr#MIjWkhfg9K-1xRtW(mK1Z@l`Yk!N7`(1j(%OV$e_oHxjz9frc19ScWqKfDF4CF6<&lXQpL~UFoQj`9x#vzf3M37T$h}TN%@U(b}NA}zphU?G3D2E-eFc3=Hrh(Sm(vcCUT(G(|-2xz*yvniW(Wec*IANq*6^ zVvq@@E*_qi^UmX)g9No&{DNW!iQuoVyUL;ZI2AdA_071Syf+ZorZG$f!+xj`JdR=55#(b)piV(ki;K=@>9^;-nsFV6kc2 z7ju%cxFxcrx$EI|I0ka$-6jNLLK9<6R`EzTqzwy9U26n zy$9I4wieQ#da%%T+R_g^Q%u`ImkiN8Mk+#&XX^aPbsQO$f5W*#SO2&llCQikH-TL- z2wF8d7sR3&?HZ`Mw+ygbH43usQ!A)m`J)tC<}!dTaVavnoT$PjyIJO$@(C1&bzjn? z@M$Eo@Mt5NJv#J?$^B2p=_{N~j z&)zJqjqr_@{t!#rkK}CTu;a&;d?JE^6aaWLD5r^2@M17Ektv^*Pv|p1>?)3YLNVQZ zMvPN<pOy5sF0-(w$brmSRCM^4lA( z#9&WhXBqdsGR9(&YnPdv2x8!5o2(TnRq|$Kxa;(>rdr+uXT=yMHvui`<0d|(M81Y_ zg`$gzy`4#ps!j)8aTI4GL-IWo?WyXVyhDW3ARWM;H+D&r3#`H@=yK&&jWK!p;3)IF znmQM64zk!4K{OmGNaPSP?HMuHz^tHYw6LVba;KRZ2TKZyj8}MD1K|!L<`MoP^T9pP zXpUo6OjIXCn{>>@5VJlwi7{1z0RR|1N61Lw)VCKjd(=9sRSc5+RU4S`h53t)43hZ3 zzABJ}7CYjS^gK>2x8gu5+3GqEXyn9fTuR(Jz+&$y;Dj-zt6A&E(A{Zh@DMyeo(JKsW9C?UftWEL=X|SdprFzWGnJH) zZh*4>npI*%^^GSQl+szYJPaDQA)3zeBb>s@%B?2OcoBW3I1tjxFbMUMRBrLa;89;q z>nED5PmOgeRZ2>Yw~uTF{y+;TjYIuk1oW-{BnR6~-GAiRho4K@z#TSXw}4eLLF7~p z6S<|7#$Ye`t0Cxb3)FlcvE+u@D7wI=%d)0q9GKCUeFR43AkYu$ZNwDr5@v)SgZf3d ztC{{P2fMOq%uz5WU$`}j7jK=R@^j_7XrOxxAR`yH;5qr0(w-JX6AT!JR1t4VBQ&Tg zpSfi({0czPK(h`$^-HM|fGl?1mGq|!G2ep<_&LS<*R+44g# zP*`q@;MzvgLz_YFiev1Vr-L*3%CUo*_0Gl&W{h}tapBtrUG9a>+Snrbc96A_S#ar6 zJDgZyDH71(EbSoK+QXG3n2vW@5IDv{TT2tb=`k!}_BfNeY0;OY(gb`n!ky994GPSP0;FVc;e`;rh}jf^O4Hmw8@lb42Sw8aj?QvqKrj;#kjyz+wSZ4^y!p6 z0Ug#(ZiX;@#GMNwdVF=t&U5rhHuwZ)yrpE&mK0?rO`q&>w4>=JOnJwZR)x?P#O1Ph zE@Y1Igm%0WHKYfFd$*Qo{(*a!wM@4aNf{W-j6+|IsToMStQ<)B(+q%Zi}<|(sYgjE z{Tm6O5@w7M6!bA^1UZrew}bZ;9ii7^;Y3GM%J0fVTlv^(yIf_58!owB4|}+yjdKgHyHq6_v(ONsF_2NI{V*{SLd(&-E{ib0P_*H!7)G?qm~D@ zwit0YL3?FP}D`PyDXOAowC{>r?e76J09w@8)QGfqLco~w*Zkz{8w8F#G5zQST8-s&G4--pUOiRJ= zU_p|45$hvq!CelFs*#ca^-s>e2^$6x{N2)`=x|qSI-qLi}&bF;!tp*dr3v=czU@r0Tl37^(3Cq}st`(sL?if{ao7VH@mm zr%gk(KnnW>H8#D9kwmxUeI1fX^1T`*y2Y>mV|d*B)5TywRw1>2Jj+D%Nf8JzX+G~W zHiz<3sx3t_1{27Ue+_i0X@%x-lK7&y?DdE!z}YJc-QIQ~M)wy#5(AG@ew;eFh>S%o z)y$NBe;&1|IfrO7rLMEnlH@;`I+4R%guQX-DoGg^qlh~(n3svTwt>#`)XW^z*xehH z5!LZ+cP}LXHs{U__X4dWL^cdL>0&C@FuOP1Xy9lFJ&JFKvI8Qx;8?Lcvi27@58iX0J&v&@$YcOr(K9JNAEio09 zMzRDQFbL$b!I+z3Kq!i&yAzMl6g16?LsWXpQv?7j7!e>J64xaOnj4blQ5=`Hpi8_6 zn4F*}PVo59>xFX_r?2@Wbyvh>38IGqiJfS580&vZv*HMA^j03qpioC^w!&bUS6ozq z&E~^pb5ik3wEkZ~*e%&q3NWBQOt75Oc}`N6xysEXA_Xkr`lX=|WI5U%bKWyoHR1~% zvSMjtfG=VY2qd_}+lBZk0+E;zx!==f9R-PXT>w-0WZexZr351b&oaa^p8x}KUa<&T zITU6HA&6>RQ7@gHo75|mSGkNO9{d`Hti}^r;$|Po_+$EimI%J#AIV<@JL)PQ=0bQ3 z3+|k$co1VD*wQeh6^^=FY7G>Qkh!rlu+$qt+a#z2mOCg;Qx5zORoK!{Lkz5ZN@jc} zCGQexW!7^eORtmq(-u3zIk^i;$LcQF@2ql?E-a|!#OVn5H_A!Iy86{D6KVC~CT3(H7m z1~E7UgaHjv8Ei5}@B@Gy{S`#VralBpT}XhAPwq`}7%;8E7{cnMD?^ZKQ`eb067g+7 z3ZK4TDS*0;+tR3c8Tm=32*JCoMx+h^K)LWQ>28uzVC)k(WmVZLc47dCO`5C3uT!)ZFef zx(z`s2JY?mJQ>ZH%R>~}7J@Swfm%0e1_Y=sWgbPEMrFN8a`*nIXCK)lnvJ~#z7GTLPx`xs(sJTbv`q%&?6OkG2cl50l+6S!2AoST+zKL~#ZS1T`Or0&w!vBn zP>>B5B43YD1|?92v5booz4VYQ%-duGEewGOToV7hu(;4_G}sO{qZ782u_CltUT}vF zU22LD4@>gc7$>P*2=kPD-Z?SnuOm;A0$?Um6~P%qg#aZkXXyzQtj@GQTL}qGE9X}@ zpD^ReaJ`}2-kOOjCW^6$F3uU93=@)ec7M`SE?ewr9C&gxqK0uKpPN?{u&vhHgw z3Qjf(58_WmoV$j43l--&JjIl_cRvJU_Zm9&RUyKqE|{^lCpzV(P0VuqIHyvt}J=kg!<&|0g(JF(;V61!80(XxQ?<*n`63rACQ^m>9dok0R z6G>r_&WUIGyOkjTjJa}!^|R#6s{-_n4f_{>-q&gdFwoZsrDTv}8iZwl=AeZz(D7K< zx*GrkJ?}Hy0^|ao7lAo~i);k3C@yu9+ntmKP&OgK`|IFaaPok1X4-h@yT!_=gP{Ez z1%ixZ90&I{pFT9Xcawm{u%sU7zzjmAhJ)W$kd2FPty#$=V@Zme2mUWelT@ZO*TmaL zicBuzCZ{=2!-%TX2UWLl1^$h}Rk$2!ei)bbrE4ue;)Ig%MVY=jlz<_+MPN|=Irtn` z*+i9wyNdI9FvV{8RWWW=9I2vDF5OxyryPR6>Yqm%%(ggnY>V8)A|rw86K1Z}E`47DXaSDxol1b%WJkaOh%dz5un4opbgGEc7LO z%p`?yiLo!IzKHJS`V1N(^cZN}?$Q&kK21NgFfJr$%3kM0661qoGe*Q(@)I3jdTxdN zC3`!oV2cMWoY;%BGs82FPkM)h%lQ88gLt$(KeqHF-7WXWDT275ksb+^X$JSRzu6HfvCOGV*Sm4>ypygV6&=y)*B^|4z3 zV*j01SotrpJk7Neg~=KDB*)LgM1FFgvH(;0^sm_g3?6;2tO`QS`ury0*U`A_=`v$8 z(+U4ydr!A5Im)W^n)iQY&qbm^{y|e!{hem@%uXc=hzN+r7-GN9%~Gb^Ic8-1h|}wL z)_Dd+RXZQ=FQxIMY}LDx&<0@??feXkKtGl3dyt!}y%= z7s4OqF%qY>$E>{)N81*u5I*Hdzc4|F$Uk)aQb+%HNJh{lp>Lz@*Jns-=FRK%H}Z%d z@*?&M)gErQ31W6C7wV-72VZMsh0dE=i~3D6J8SK1X(Cm<0Ge^JF=v%(@4b*$!rvPL zjEU0*4O3Tt=YT3k5zSu!fc_sZpM|~NNW;Cv5!NpI{eK4Pi;-tRblH)0?+ZRKsV=~6 zn?IG-SqQsR8qvG`rW|W<&A*oh^|3H>65?NmQvr-$7SRY~$8K<1MVLvo-eu`6dy~W) zE1p1_+wk+kShNw_nk*QVOrF9*y#>Bd)tpdpg6h0N?GlbnB<7yv@_xB^MN$$5d0v+{ z-$Z*~@Q4KW!PG)V?AS>%0QWIYkMA*zn0@JNH=r88_oERg{Mz!}lTkj?fqJ{fLk_F?*unrzOh1i+0l*i%EL z?>|DVtC`7xNtGwiz_lW@*5e{ASfn!4JmWEgENLt#_ajgk0tMrCS(V;;>j&&GLG8}) zqnOGvych`IZ;=kYLQmZkFXum@M`um6d}3dyW-L4NG-Xs+{WlrfJfO;gn2^=%)#~tP zoJW(8xFW98dq@g}5kVM}k6#iwtj60KlV$&PARe1BSOD)wNB2rAC?Y<1JrbuwGQgRl zC1=F6NH7cbk#Z5JeB{P}BZ4W<{tf8ab*QCs>bA{BsG5)hIR-F!i11<+cp=LY3D<&9 z*)#M;iwf(X%FAhHC7<)NZ4)v$mkB;fWebk7azuLeNr0c>VSo^Bi4@_vRN2Te28!hY z^QQt@CzB!ZnmIiTM|4&->^k<%Eo9sPX`~FN(^vm^*j^c`k}~^q#&i@yLQb;Tv+HHQ z45GcLrvJ9365JNrnm?j*8?cs|2dGEOY(gyTO+&dKN!H-L`IEa6Ty-@Zc|Vb)^C*8B z{^PTDXWB3mFk@zgMHW|0Bh(NI_j#eBca!Ke(Kzvn85aPw4jEoPz|5=(Dtn#HPqEaj zvye23B%8vN0f=k234yg*%^e!;-Ly^W=yBj zU1bdQ90z5~YvI z$ab9$%KGw0_%Ux@`yx2kNq)#s{x4TMfYB}Nww2yH9tO|#a)cYX=S9%pioqG(G$XQt zM|WDIHDjFCu4D=r6r9*b)KTM-v2^ z70VFC^&N8O-3kbuw1O0A(1wd!Mk8$@(oTU=3p(5%_AHA_uedz9z7H(Mj%u|4LymbF zIdL9=Jd9zowJG5kL{G#s+M5Eq3wVC;h%Z3KRZ1!39S*hzTL0cN8fot(0y&SdJc03l zBRU#GRu7}r@`0NoO>I7W92^<}&4>*4`4UjMNger@=jM)xX5y~_9;;^jC;Yj;O8psrLqphV>C-;6fwBZ9!7RLv-|izb;+e?#Ex<;h#Lm^5^0cEb<81WjFXSam=iL% zimXo}`=A$s#ks&kFCB69^&(O=k-Q+-^$55CMQgmJ8GwvM2&=YjWp-EC-rxaivQ~v9 z*nshug+#qAzWUO=eT(5SxA1Yw^-~}%^+f(*kYl;w9!C+Uu4~*rnPKl#5)c%A+{5*f4JqeK2pBk5nwLJ8LO6^+F`csL;9oR0$MX9Yhr=* zpG_nV+Q|AHu-hB@c)}QBwpOcS)992JB*niCLs)Q!Fk|@^()@RV%M(a~raMpTWWPw= zF|QM7%)uK*RU>`?e9MDA#|=>c1<6M{n6hlj&ym&g4NQM3yWj>MwG06AvOe&x#MBL+>-E! z_3D`u^-D$fBW>lBdnXNlb%`}Ct2eaQSk!oho(0xa@N-=FR_c^g>;)zJEi(n-FM^>* zJ%6yB+&dpu)bAxx@Z^DTQIWxQE<+vIs`2lDGP>e@x2$n>{KqQ%nLQ5C^SWb)D1~HF zoOr!h+7*Ezr9P+~=^72m*D^X8(Cl+%XHbc{h4AX5Yk5DgQs@lBUs@Yf;2RuBGM(J}3n(l4wYCPQ+`;>!g6ZqWHpd#%J&)OV-_3Ff~a)ER(K1i|c_*A_2 zfT0%8Zjq|W94?p_>NgpqceJ{=jDl9(kFH_kq|4nq13g1S3h&bFFjlThBz7QpjZq}X zYy2Ckn;KT~@kLU_6o+#Fo^o(;o8aL2%zm8JFp=$8@e{Tz3JMac)uNsRI=#+V&~$G* znliwuowf(DIV=pr;}9CclC*>4TF^A9kK-MBME|pBHQVc&;;@u1(lXH-LttzWa-b-p z$l(YMXAMaXbCP*P_Fjufv>igIgP==U z>u3$vZI@gg)w|1R^cEL?VOxl47~D>;sj(dItt>_YKT={@WxY~0&RKtFGU^N~t)$m7 z@sWoPapkFKs*IB2{cG`|qXgL8;MC@YhZB^4ef`H#^vH>g9;8w$aiLKvr!zRm?PDm( zbh;HU=CxRJWGzY{cEY zFh&lJ^KdGEoZ7C|`y>7>Nx;PR36M8uMoiOF1L#z<>D%!bg!`_t|xy84C5 zp++16WuC&>1+=wi)pXQ322AoL>++TWPd|Fih-6erBV`C2xT-Gs zmoaZ#CnZw$_N10Qvq#Pr{uQwm5_a_?H!~b*N{))LsUb>Ch)|`jriC)%?b4~ePg~4s zV3wFWwTx`jrBx)kX%T7}tn>u_sqA+W6>FWGm@cP}xAQgSUh0U`2Z;x`DTvEK76}fK z6hQY)Ei)^*%mTkj?%&?j#jJ1fnh0%EeXAwYj|C5j+hl~#EiOE{$>8Q>1c;=2pD+bx zey}f(8E;9e=7V8$w64FOlCk5TR(^u9-m#mAAj$G0SU+ej|Ah;!^yO$$=}}RUBh`~0 zaJLL^)S@tQl}JunrhU>lJ$x~h0V=pjIxPqPF;I*jwgn+aX470+F zLr@QcQ#ekr#Risb@E@lp2}~BE;<;UB5*{I3@~I;A`Dv@8lfHWVG-m1erAak#Cjz}F zZhg+86AIqE?$5<*tw3saToX_CvP!+veL0dI7H6zWHEF!1k?3H|!ForxjzJWiVasQy zM!MFCAcNeX@@^Gc;DhtjHF7QgC~(45={n zBXEFudo}Ye5^X`z#OL8a*4r}$YW7)qFsE?%ra$NN;J8R9gZoPd7l!NxS0Pgn4}7ao zO9s6JK`+$Ti~RI4*W~mPLl{;@N>l5S}>OC-SPjCN9!U zm}i+@yF<6P9sxk>t;0A~V6Uxqr##%EqYMayKHa^N>#Fjng_9WU0CV={F12Ah>lY@3 z7~#9_ZKS$5evPUh3t!|;k#3feYp4pw!67$v$!OFBVg_Xc8({A#1FiM6K0~_?lph+i z_%nlng3Bw&S##0L08x%T)DA{6@^Lvgu|$cnT45?Mi$d$I&BLjUx~R&o!H-UFDS0-Te6moFGAQ(2hG{^}}OAuDkwz-u?&ac?yO#?_xgN{%L^5 z)02{B5_v|)A-$Pt2rTt)pC-W$gRuVyxLREN60VR~TjT%RKiZ{9cJxT~0taOGI}!?m8)w5-{S< zr6fvZ_T}DEz7Mbje;6Adx_V zAUYsVMI>!J|CNsAQnHuNmAIcL5fcP8L1o}*6|%(CJN^|TV7ih)<-jh#i{cKJKv;=K zoK-x?hV4M1J!1eDb62JK{pfsEw^J##w9Va^CbWiLcYAIkhaTMdXbGn<^!Tf~K_-}V z;vF>62xw#U4YYC42(I@9XXpYCc*JN#VBmficDelrzbOd-y{}6(#N6~}XNX{k#`doQ zII0CBSc;vuuCW02W2JmVCr~#2`ID0biZk%P9FACcqvtN5sy|lax_%XTJ`Zwj}x7;poZla zrTYfFg!Ui^atQPjOnb#T9*-$nOY+mpzuxC?KG^%`w;FcJA+!b>%NgSF!FZ%eMmG5= zuze&3cZfR(cN8O7F|L7{HNQ2v!f4Mbe~QSd0~BPZ#6K@2mmuDTrw15SDvU{7RK!P56)=s38{Y`|uzHaCR)SiWb5Q zcTW|w)+qM0-Krs)LbFO_Fe?^zxeFyBL;waHL%49Oe0h&BAYq6%bxKCmHyMlBV0j>9 z>}XEyOY)bEMR=a`HefX%_y2a#nwCQn=_$zwU<{hcws|uuW?@GN`wWP7W411WAIyKB zftV(2Qwa;Ch+opEvtqPW`o}Fxio1B>)Q5##R9XF}2I`QO2F({Qd_R)CH?3IU?XLh$ zCEVT-$FE!P4TA}uVq0}tJ%hcS&^Mv0H3}IY?M^WOR*|0A#;hTb$EL|2v`k9-!qxAJ zz2z6^2)4PP+pYswR%`$_P4Osyk@EAc; zi(%+D|8i}N7DlSex93OKljP&edt2`O$CkWS7X?igvAL z7)`dB4|a5G%Pv-?4U0tXQZSy`2RI>0y*IM!5mCqE)NKe^Q=&^u z>RDXvz`<2f7&fP2n`UpMCv|7LqKY*3JB_Zve|p!Cw~2^d+Pss4oBCh^(2mpYwUK|jds{ojVs9s21nv94-fr7 z;nnZN5snaPwe8GE@-mzQAnrlm`9r*X+E__Uw%DLdbuCx$f!Af|}TQoB_2JV&NAe$(FxLkzTn!#MW=vG0Pf0nD+QNgC6>O-qANcyaNr zisp1LR!m5F@H>T#Eg&N=afCRjAUsI_je0lKBPyh-AtYn+KYztZM~0YJMzySs*riAX zTugddU_J^UFd-$TSw-O{j$`TN)0<&JJ4d#mAi35ymJyBuc9$A_lFdmA3Ol;>0kS|K zQ&xtqT)VX@L_gUv{~IBc3F4gn<6Kah-!&3iwrG$1 zGzb{E#8F_GQ3obqb6w$h7Gq}h`g6xgML21nfZSmfk&s(WcHD{F;nFNE63xcSC|@r; z_0z){py_9#EwT0XS@*8P*MK}3$9rIFLEuF4aZT$2K0-=eWgWwV+-#zx^8E00X20>b zEDcve$MUx)V5D`I#apdRd(_#nRPBHeD4O}(!0(~8&L7$Z&^DnAzY|_q&RJ8w*++4O z)Bj~R%Lrc$y*SLTl^A})n@L{k#4=TVmG_Db;pJyUi5W?-iD4N z12ig#!bwW(n3v`qS4=u1ONV9+^PWYt1W&SS3)S6AYfp~OC@34SAId)0g>7|}^$3U) zVsVc+dJ68hI+ppWPKd(^6C{wLXg9;|$me(8bnMlf%sU3sq-S_#knY$`>*mi=`+9@U zHQwO-GjQq^#0A0*q*^tA*=rRjLzvxh@uAiuA=XH1!$5J8BbmW z;EuyB>{K4Ng82m zt&MLeX%aB=o$Yl08ZQ{Lp}O4WTNl7w{7JBM;WrtI^l~Z#{gTy9EnObhw-mg$%KECi zY^&VpQcU$DE;tgfLL!H;`iQXHXzX2aElv~Bisrh&`g10Q$y-Yzk8GVYf(%^oxHkS& zz~+MHVFCYP?TIvyMk80nmqkOP{qfuCFX{XRp^!JxAZ)z4ip96{Tnhg%nBjmL$qe)A zDr+_|&W}Nrms6xZ=vR^r%qR+;!XosYoCK|@zE%@D^m&y;T$0ORzQ1wOA)mkyVUdrC zu%`My@g~xgJj*DWIfek=nqQ&-oUxDI+vyHqm7|*gOJ1- zPi;gvNxg4|IA}1UB39(+pt?q>xt?V_jHb6!Fupjf0S;y6w?_EB@++dOu|PSJ=Bs2) zz^8;PhS;w`NJ$mgMenT%`#f%iCim93`uajZ0zi5tzwtW@?8KDhb9*Jw;$6`k`<%CQ`I}yK zyJU}}+nkrN+l1f2YIEEB(}O8bx&+Va2g=R^r4pg)jY?<@!Yi?HvJd|3cu+=E+28JT zO>tweFvU9uMtjoPDaE%5T^8%b;I6_5hzGkfV<)${+~xkhg*d7^&i>3~HALX%4t45%FG*JuO2Lch!gAxRYaV^O|wqfV9pR$LmLE$6$a&}9&1Z4>CA6< zBtP3w5D}?@GZC9QNxrkv!XGQ*cp}9N2{+{tMyytpC%S9cU=pgw3C{Dx;!o&7VOZwq z-49{Rn((q%h)$Oa1DdY}XIjn*@COtB8YQTX7l+)yC`7qRJ~XSq50V}jmW;6o@Unc? z>UyfTPGJaxV3C#|{zoM%b9Dt$RsXBgAyi|VyY%|zOf`mOS!+how3}F8e;UP~R=P{Y;x?G^c^LK*0=zp0FR}L4T*ilyA}5&W zSVwmbM?oiY1hdZp<47vc#mlL`;<)tHGs_rVfF;yfNrZyL$|mIpxAGES?>*C+PM)6(8RYFj2ag+lPl?I zBTr5A!vIf?0z0n=QG2grK~$)DV!s0Fh?zR6ks<^q{^#e&(KMuW9YrRr>Af{DI@R^; zuDw*Wms^%`qtgq6;&L2DRnPAQ(qLJgR!92??tVd={%GjYTAR}RC%L1S`u zv=|$_vWp&dSi~Zw_VcIs1$M0kOr4a+wn87lVlduiJ?RQELfvd|}+qgSO#}Z;# zJD$AvibrehPwf-9+`ecf-%A;lG0VL6kfwBLn@)t28n=;7znxf&z|JlsnL@W7?!cW8 z4NkH-N5R_#jBpRiQ_IV4qTwANNg6XvBUPqN-(&QQFgMh@Ms58arG1di;LO1;v%?Iu zGowI+GGiJ?BEmIo^&v=k^p}*{&On+B+?A5G%vr z%6`LVAB;!^_V)*`LWCI#XZEOA#l~*8eUZQea_)I4>CrpDkb=s>>}@x-NmwID!Rn4> zV+X9OTs0XE9XmEeggCNP@w<=}=CnVjsGGl|b#=`*p2)6HRCxR|AhA#Mut6i*rvVMt zP#I=HE4dE>9`qK$(?QkOVK#RRN(jXOLYcA>=dw;&sWv7X_<_JcELo<@o1YEga8O~? zT72Bl94q)aEzBUoh36At{6RCm#fImXARV|m(geIo{AebTV%`Vy#ql^099*69rC)% z8or{sN0!MWjMd<~)}DA`!^I8=i6Y%7amPpmi?*xm2b`z|V$5V0Fi`z)LoGNsqU0Df zESIiaN2>=;>;FspsOA}OZ-uQ2v?gvkVI@BR*s=aizsGW#-l&qgA0%p^x?kA|P}p>HHo~1UDJZ|4 z^xucy1D2!hD>;WOtjn4&+TWB?y5OGn}6JQ zhfi7XiO1@=X7vSmPfWH}o&Exiq=rG$EsEclyp5?f{F=!k=lF*C1UCVoX%Pi8>a15n zy*YyXPasGNOlrjyc&9C#Xc^mMK!$zxpI1n;^CIE4m^QhrKqAT9MElCW2tfE>a4WnF*sCsUN zSa|)3?SR6a12lSB>oQ-HOB$Ti$5q{&D#mhtv?UO6f-r+Aw%yi zI@w99w?TiUlKP=L3#t3UvL1zv_aM{pUxkmdGz<3E4Gy#&TF8}Xat#DpKA5RkPHcIb^p8DiO(eBg}+WNM;Ugf@ni?4?kP?`9ZzG-9|bb5ZRgQjzl^~q&7^%0t>R?W zRu$VJiVCom^ul!mjeG(sWo0PNi>%D2Gv@nQl8H&&NPITz;65MR3o z+#afE<7Bs{CUF&thN7fgddh0QQKroU@wGijy^q_UMwp{k$nhkwQiHBmmD_>$hb z;}3XOF|K@0MkKqtTUrb2uSXF>k52!y9dwwblo1L)<=3)4e|BR+7B+3S)0^w?9HHz= zMIKfbE1KPSZLZo{YhBX5=}1Btv0B1YIq2F)NkVwa7txhzvwRLGX9EzddpjdlKVj3k&| zGZ?!|OyNqylkPoJXay}&*1-X~TK97w-jW)Lf{bX{%Rs&kDLYU4RP;62koKlJTxx1w z+bY}&$|E_W$f&{hpQrvF3!9mnyb;oOe5;51RB)>~w@=VIP)LQy*lk z25Y*7|Fc$dc(h~F{zPjQIKonvzg@(38B0=0LIwj(o-{f*BNTV?BC@4cFhY!6H-0LW z2OF3|q@MghxVI*?gA(h?^@9iIR5*m>*MJAg^8LsV6V3n8#_tTk93gWj*`YS6Xl(qw zq`fsrIk2vbm$O}_VJpm6F??!}7CYUCKv$Kw)D)evZcI*6=S2xUoxG2^pVy52Z8&26 zgKRD%i9eM{2fH}rL|CC>)28})RJ;7mjxZ0vE~>Dz=PekU3DwLxafAilgBB?}U*#Yg z2A3$gE)U%9nUV2u`D#Uo8rR)qH}GBIHeKFhLagY0QmeO>?cQ}opw_(0G$-k64&OXq z_^@J@xibR$8aSBK-#&e^q_GsKfM5J=?z89VI*i1a^9ZYsN<~qtW@GK?XQKH^#)HVD zkZNttvYX26+&N6^N(eP6iD7h?3UDM3XQ-UEfhHmiI>&o4M=4ULoa6Nn${JA3hvm-= zvigPFMbViQ}bSXeJO=XGo-I}*(p$)0Jk@u5N`?c zt!A<0;_8DuuLgK5pYitz+O0Jt%-DP8Z*cMJx+p==2n)U-;_|#=d`x~Fi#Spu%>Z;I1@U^{;$PNMs2&jGXs=0FB_gQl zlCObF(|I&c#?>84t$cJOKyvX!`6LO_O?F)XLg3RtIq%P3A_1k1Ajxd}&U{(xS(DLg z92~{X&H^f1p@OXeuRnX>#Hj)#P>SSHZyn?=63F5~FkN`+Q&r!3hnx=pr|VfQUtJ;) zXnjFMw?j{TA`k9~M@Pm4W5g>7?Ip`MrF_3&GKnAijN;V<+a@^fINWxS#_Peh5FqnI z!l$6X4B+;|$+#bc^{Alr5SS73ry-d`qv<1^Fe9`xns;oN6FC{xq?n3aMjDlxtooa= zmC)$18~eH+ei3xjwKzu%Jj1(R5{ajtgKDo94pm*tutJ>=^Y{T;!@sas5++W1FuK7h z+{Z6PeBp@X`P_h%$<2Trst%ru)NqgWbq#U;!|yk31g@o7-F_f`1-Qf^^HxFb%c`3{ zCuK=Wx1uWR?FMOe_OuGnct>f)B;lHvh_UYL(^*RFb8Sd1p0JM>$`#Lt??ui-uz?_q z9MSwV)@h@qzj2Od`o>*_G-uI=fV}f8PVx45;0qeg>m1wgq$ry?2^)sHwTrm@*R)Sr2>1s&-ALVXls#WXd9=B4 zLp*Fu2-kL?z6hk?P~k{1W0o&<0KYev`wmPV%yTK)iE)l*t&F%581>#8-3+d=MmwB~ z1?~~yAewdi_|X-%BLGbq8=F&~H$mfT2xQJOr7{^YJ+`io?O`uNHoQx9`m6jKb}x)V z8Dm%edv9-&fH?Ma9c$@9_LX5ogM*mO@9Gcn#&-bFK`lKvgKBPPQ`I`&*mYZ4`h@>r zj-xMs)H0Skc4-WbL{~+E@Atrtvg9h=FN0yH5dn33-oXjUToWwy2Nix!Re2S7gtNsV z`x->Zw0AVbP#E0F(=Z4`y>}Ep)GwX3)gYboEP?w$@Pl4+46Ab1PIp_QK~kB|>1OWi z&-@*Sh-hZ&tGuZu1-*yjO~7^vEdILJ%*9PAlax>cN5c536!A|IZ&7Nk;T8EapwZUe zd%XXz3O>SK=O}RWaK}}(L0ldB&%omi@N5B6%X;U;1Bi!~vdLdVlF+mFVTVsC!9i|W zgVEKIY5#;r24@-h7W=}=K`bb@-o@3Wx9eHWpIViDedb0!EBwwbZXV)qbDSG}8d34S zZm#F!^+GN9XhmG|rmra0wZoEBW<(6gf*AT;d}~yYP(*C9HXiTy!yOKn3Zm?s?bGPd zhdsz-Or9r%H;yJKmTJ`?WIFh8o_~g9c5L$80i1HU6!yFVSE}9vCvKeq5S6Q@=a;3$ zo}wf3E8;Y!zUhpx=n<~l05&a)6|pe8$$C(I`(U#B(OA@uj6cMKO~~ z7%yCKz;U*1Tbts9VJ;fA<1fzXY$y&Wesi=jqU}2cf};Su4m}7bElG5$3{$abtFill z8{sSV;j^K_zMBZ!6Ty+Ci~}ZT)dOnxCT;4fSfLytPI$U4laEKn2=w6-pud_9ktOYt%gxAq9N0R8_2_?YNQO1NT-`l+TEuj!I` z9eH{Z_(gcDiSEY<+WXoIM+0)5y3L=|Mdjyozi*SI5L22Jlx?+f^DYx0(4f-7|l#@PPO z&jPt@D_nbK*MkS10vV`H4uMVZ+A1&EE#12$5Zmm|hXH240yOs0jH^amdPbFksBN{; zXpKW;y4X!?$$>)b&~eknLs%kQEqwB?S)j-Jsfx&iO6#4bKh>yg8XCL$>>X$8w7<7n zJu`sEDr5kF^mQLC=!^uTA@R;Y!!r$}X__d?{S_&H)`;z6BOknpH#zmr+rEn(P9g31 zZGAiFODuCSY@!zJFZy;nY+AH@D1cz|bymwbgQYLEarVVYou##+O^*b?qafE9inLm5 zow3aWn5Wkimxs%|t$rVa1n1aU>z3*s9As?!Zv=)QsH=tUh{rh^e&o1lVO85DF^2NO z!Qk-PyJ{ZLV2zp$#lFUoMR=B6C0}-ezQrCd|19*{J*#T5-v6YdNx`zp+PjESzNA+H)U&gjcDPtQ449$mu+&6jJse1|she{s|5BD-$@BM0(z1C0{9l`_vE|wW6n_ zdT+fWo5D!-{`@}zn#8(rB|P4jUT?W=PGu_OqKrq!0C#`b3cbMtX@$fLT_WnphutM~ zQI{=aAI|E?Xo8LYDjL--=uJ8*FbMnut@p@|A&j>-A(&X0L5_X1MZFsya`U&d`~$i=`O( z7Z=}|B;V%uK$54YgMj5UUdUKQ;QX7b`S*Fu*^qkk&cTU$ zb28Tc6u^8-P-{Ls#p+bd5nT&^P5Yp53uCH^p!3rGW-7DkDq1p#;n2%vSsu=P+1V`B z#iTwjW)~SxAty}=a`RWS+gG5H*XX>iO!s8>8e8Tf( z@{ren_1}srL7Rthx2`iB8djSV%#1T1*a#xE1BybCt9Qaskg*{;6phIY2XNgbr2yWE znR2stF~*IPivSIY936l~mqfoiMoNUWLIftL@q#cd54#4JPY7q037xtxp|D0B;O7t_ zJ;+%U%tmfovmG`F&SevyTBZAt|wgEqJpbWk}#(12B=;Yz=aza_lIhVj5A1 zl7m`B#)9p+UWJ0)`>w)Ii5*7!TB|-Ou8`eZ9KBWiKJE(W&1I3`W!JeG0~`l3PU8XU z$3V!1)$oW>0fbDPYdM9vz{aTNR{jlDiR$?(ICYivMhWSeI{M68kR$V9SWx=1=N4Lw z{QKkEg%d0;9q1;qJkUh#>IYw%Hk47k4}mgI;e0rCBIOLNHT(3Ed%)&b5jk|_IsvE0 zfS4~#gByR(r|fZLH(i*xg|;T}eI4WT)fV3O5ha0Arm;aJ>+*x;FNLG0%cN$lDdQE= zOtb{|{4tJe6YlFZjZR8A&u?{B!2F{JU8L-WmUnZVav>13eP=c5heU^h+ zGNyScB6-CU-2*1Ck#3Yz3LsU91INmk%O}0KL=G)q1oK{ighn61b8%$Y*Ca1$j$HC+ zCW)wus60=CE!eh?WEa1idCfPG%FoCxib?LZK#n?`R-5DSa5n7P!R1Y~F+`ewI_SXN z$Kf*&kbiJsX?NmgKd(7n0g*B7t5nkV90PNlNeH(8_h6sp{gM3v;~;g8W9S4F3FH+x zBFP^#wpsbOaUhODXBCm|uffHqCJ+=Wx_C?a4zMK3qzKXi zj3rp|d2^k=TGrQ#?J?oMRie~tv5MK_0cyZ?ytUSPEOo4ipf=(C!6+2ig+tzk1N{*?br*CP#3OB zgPL4?7QSw#(s`U0FxbEy>=hj)M!FqJCHdj-TfzKkNXaK2<2@r!jAJuIC%oDZeT4Gj z#-)TZ_Ipp6{ItfL1g=`<2GMUp@8dfa(zA}{UB%G425H4$S%d$Igh#08_New8%;)!( zUiR>!I@*wyGugLg?#7Vk#6}e(8W{ZcJ8y%&&CpR6t*=%5=BdK#_<1@^i4ciBz034F zRX=T6*$_Okiktp0Ee$7`O3{5RL|5xk;fsKq(Am$08+H=?eg7N}9HAKJb;S-m0*2Pd zXB|#CV^Aw9YYOcC`;EuLhlnVs_M$kFv~WEJ`;A^Ydtg@ zVhS;$2@!@OZoQAQYIf95Qz1xwpz*4*!A1zxda%=R|NAZ&-%|;+Dkz81hqYy_g07C+h;8FZN!aC9`|0jji~l5#c*9-b_&4`pP=oqojHtI*`D zT68~i4ZnqPK_=oakaGr?-V0hqysh+zYFQY<((<`xWkB9y2}XS$8fdwj%BcZhN!1&BsKXXRua~MHpf1= z;tiOQ5Cc*v`6enkVBg4^ep zvHl+YR?-Jn3cRM0HM%(1t7;Km?w_Z#F7cpQ&cx$uDaEE$bcudp4J$T*uR*Ojc&ET| z2t`*z?eNXt-!A0tx50%peY-Z&RE2L2tLLH0>70(*=-$*>i-tQ`b`)M9C*M3UJFy*{ zX7r5Km3KX$ZBR1$m#l%ilgMtY_Q@p*&{|XT+5+av_gW3|Y3Sa!c2l})KP`Cm_hu-m zg{;rOku*fVjrkWcV6e9^9>M>GcJYaeNAhcG`{z7qd|YGq^0v4%QFns z6QYzMyZkAbFA0fc#%1%)@kjXF_j=l>tZ8+*qKk96W1CaM>zzBUGTuzPi{>ip%LyfY zzWSt9?RQ734651MH5GhsL<+p_MOreszM|*8!Ky*@zAz{CM+mvR!^#rQF_nqZo6?T| zuVg&!*UTa;ooCxi{gi=?2}&xxR(#G9TckHcd}(h_Ce(i;plxkPxFUek2S`%RRb3;Z zR#u+MAkY(1H2xO2c~9pw32;#lXbyoH5fj9%N+xK_Okx~-B*1x_luElwyt}Gwis1NU@x!GFzPHBRO zut~CNj&j1H4$9do1rF^Y1M8^R7eB05tgoR>u}rnlj=j;XiaVolIqb0!cNWA!)RdM+ zdO4B=NfBjrSNs8ERUbYcLqW`ojzuXyRctCSZ2ol^T#ky4Hq7Vp^QU$m8Zg+F^>8UU zE()PcO&Fw8BFdu$64^nqW5g8BR!4>y<#a{gN9&Gy#?)XAnkyEtqb!+g#XwDNMILrX zlX1Y0Uv-ak9_KVWt+n~8Mauhca!c_HwfT$>jo9ahlTjL*OJ_t&2od!Q!x%An|6-Az zGq--&AgF$SEmnvj_eY{FLlL3VM+2{ccG7yd&VhOrHA4pG-r#6Qv_HXJ^ok-Fo zQl?z7(2y*Nr*NR?P!Dw= zE#6LJ6A|*Z*D!x|7gz{f6X%;jZRjcHOTeG72#%gxRnKiU&e_0~U00a6WR~5{5x1I3 zy-*O_Y2AN&EQ!)PXvD6GmvBFRQ^zd2+7Cc^OeG_MFPPE@!Q(#e0K%lD6UVz+Jz&)f zKrsZFc>#j*p8-#_clWHa)R7XLcY7@$2>7&C+)JjxCGswG<9~(vD3V$46{t5labCmu}4D@-58tSl3coFu?nJ7G8B(HvZ&?f zs3v}|elEojqU~GTBYo{+=+vG?UdKs5Z;4ScKfOjU*i+NbkBG8xUK&IP!Cp+6|3&$V zg!qs_r~)~4$1g416pM<1>^4LOX0}Qh$|h8VZ~OKrWDV@PukjPGxok-w&bS_ctiM5d zRD+4-2?D$oUc4psVM3Zl4%2n5>_3mmW`o2sGywaCp9<4(;(eD9bwZ80xt}*G-AQ)v zdfP!sk68E-4dU{HNH|siYfBQ=x%B?A{P)ucU2Th0>N{83ouJ1N1zVMN8lD`5)JJbP z&5xU3YS&Vm{pQudeVdB}uDEI-mj{Ts*KU-G<;|Mf7Tz!9PQ2qHyOe(xjG-rpsPG9# zXpMXm{Q6v-*eQ!?e{PlyRI8fYlqr~2r85tL{Z?y^mXIPZ>eU#A25wRRVfk|dcf(~@ zWmnwsfcwmBdWZLz2R3YqsU=h2maaE7CysNJA)-AdcG-qgYSg~G=(1zBOdEQZJ6tix zZ6+bg>F&dmdd6u$Rdkg_$;T z2BLNc$5QGziAp5b#h;S%2mHfdr7}{~8mt)3F0L16K*@@ZYsrzk=dxe&#l7u%pjTC~ zxBHV(KdSILTQwsPsRZEw!@=y%_xMwu;xaJEXr(DW#lJq2bDt&Z7Gu&)p0b+$&segU zHggKecqtD;w(M_iq z=nbWI!>3HSXd6p*K2MQ|KOkm#putFW!d<4ZPM^ZLp3R-}*H44<*=w-@B9P{&ObquB z%c}0#TyjBI=DvuKRFu4aEq(H)j6DDzn1;A1kvIISJ2@V>?2+$iK zb{W4p??7uUv!3vbbbaWhbam_l1kudU@dBtVbJp$cYYT$iG-Be!^+qk06GMViVcT=Q zQRZ+X4F{=wJW$cd_jMpG8arNsyII)2|Q^o)JuYs+Sib>Dftv;GoY(%!2q(b{CT{x=)pZQ$fx$mmRDXu>y+Nt48s@Ot% zW02M$t}XK*1iLVhYkNEf=zeS&yatdcaH*rldp#`Hg0+>KeEr8MMhJ^#O%L=~l zW8j7h!6S>JOXVTkV4{%`(BGS*@)G5)F+C+G=JJ)e$H{Al+P?!}Ughdw=M>EVt9tjXs{0`L-cJn1gxz!NyY?QhSW3Z~L6 z#qFPbler<$>D$wQtN`P>r;KE1_>KkkEQmWY$VC<&HASrV@qba6FZHWB!*9OjF@Tuj zZ0*+CD;aswLE3Z*J~c?F;G4;uUVAFaZcL}{iJVCPh#!O_c-DM2C}{oEety0h=@+>c zsAU`-GmJfBXiKo+%0B;KZ4%j{wEn_A@5~fw3$ujb(YKGUvSP8k2X^1RLAelT zpJl_QpPqq8)s1oNFqZiqPh=oquHJwHo+2ON21g|>d=OSUtqfIJ+V0iw&_s4cN^4T3*knTV(GeDo`7<^^v~u zc{z=Zpt8n^?l13SiZ$2o9KTeUMe{1PsW`0_NP3-2`JoF~uJ9*|NYL+c5^LmqM#J;{fiGYzcC!yc0g_a1KzjP26`O6~jNvuzI1NZRv!AKCal< zgTD5H{MJPWpY4=k6pBObK=sW!ukW2ef8k!&eyl6M~nC0)F<`vp&CKdqaSAvOaap}eZ9jDE{9op!L_j0rpC-i*FAE6_q^T_ zk=T6`cjO2P5zq2dS2b|}_q(-i-Qjy;^O%I{QoM(ArR^Na4okp!7)(eSJ1WIr`UmY0 zsn!CjE8gTvxDQttMhU@5jz@orQAL zGTA;hNCA55O&Jlm@DnU4C-8-ml0(SG=+1V8DopXb!@X_>U7HQQXz zGTz6xR$2!_3k7qf53#BoPrlqFNPaDRsF)C!NfoV7v-G_d7S^^V1SG=EV=&^?IQnnR z5GBXU)XIy7)rS;ZuHaGrJqdK-avuWUoi2WN{22g){UTgLp|#d^wgvP4!~<$2{;YG0(0lJ4(5Zk5 zIwANY{r`L+$veQ!g}7oB-vDrGEW3oqco8@d8zebwyjU3xt-3a-1ofO-Ernn0dL2#W+ar)pq+*{6ffF@cklox;Qz>dM? zb^Q*r@dTzHom~{*(!#!mr=JczSvS|DcNXp#?w!dnhLnku=S96;DUOH^OXlSO>=shZXP4{HK?4X27b)PpZBoEbInl?`#!gEJ?0s2 zRAJ@R=uT2bbi{8C@;Uee%A3PWCY!c|K_O;4CHoK*)`O9aICWl=AF! zEH(N<*{Mael(6C0+57Dxc7Obl=1d=gTW>E8QEy#WvV>P7WWAe|SB%I6Rh*O5ltIj- zno8^WLp?P+MH*$8a;48DByYE)P`&rd5KvLi18?r1>Zu`=!*lS==T}oT^MC|2O^)YSR-_@95&)pm`gF@5@#3irj4>P~Ff1S)Y4a_g zqn)Lcjd6?7uudh&fYMEu*p-=rqzs~l0LUn2C@AXW=Rr>e{53GUOL?SJ@tT@aV_6T! zm^aLbc2`u+1P>cF`<2^D7pO1 z8$flK>s;-3_tSjIT&ile@o_N4p0vlHdR@Y*CzVMP~GVD=l@wvoToQ*cO4l zrh?;0YV+$ZG1{-4qC=JtAkg{Fj?+6c>LYM0ACcQ%+jAxHkS&KhCzx&5Vv8EQG|+zB z2u5a)4oG{9Tcdk%Q!I_EknlK>5p|&zy7;VhbD!S!(n+~4shASJmLU!?1Fb{DA7V1r zvHONA*$3kt9&OJO#c+_D6}u*`AesVWz%H!9dZ9xJ{bpIC-nE4TVIH+O_;e)iF#JX5 zT7v3AO$buL$hw15l77S5bp5Tu)%S!E2CDeV83Z|fWe3D=i6Z#!;D!DhTW!u`{spi^ zT5I(>fpX!Kf+blkz`yQYe)%|bw05Z~juJR=`iOi!haRj%(YDqkh8r{x)@{a5KH+vGxP?etkw6SHPmvVCD-7G!w;;Uw;|}}2PxUT3O+&=-{xVcCsHH-@H12*q z$)E)cksb$Vt@&0fr91$0Rx_mg;m^5JhAi&mehpV?fx;iKX`g{;gxPL=(tBHVRo2O% zdtP-D1MX|UtE|^dq&Qz~vg!L*E*E-QzmszdeWtMQbFS#mPo zoi^^JSZ-q~W{UKXB8!gUoBC68$6}cs-=&!P)dt479W*GJA8l#r6V=U;)U<0 zxWa^B^#{$MF0h!;nwqv?r{B{wE9aW@`B$lVb)U9k^Wjio$9aA z5r~ZL0`63mUx@9p45xY4hfKijO}a%%l?7~9tgzG3=)V8I>3L%y*@}+-Uw}7w*33nU z2QYsw)dO9a9U610+WHTS?ZAB1ELA1@?RI|wVlTPMdyc-F*6`+E*R%gnkxI78n*u!; zQDhS(GpA6{T8D+xrP!hM)p@-HE*@6WDs8^X+3RBAWFw|j#8ohnPkz5o8JZmmhL|{& zU=DnUK$gZHY$WY^ff=KUJ-ZkRe3!INgtC#0IYetz@^#rNHLa~>nS?MN;}RX4iwBfR zm0EZnJJ;KDl);kEd(zW7RlM0flSkZ-v@eMXxzhDwb2MR_CYtZw`}Im;d@nACEUQBH zM8`ml)-;%Xd91CkiMqV+aYVRVF&a}|7$*~NvCOl%_G~N6vHz`*=*g;sz+qhdZ2pPG zNQFD6G%7Ltht2gu+(1;(#b1n??lMRf(e_fb`FQe0&{C+x+Jvee<7nMKUx%rj5iNz) zY+24zx|y4qGY&1r^7!|CsO^}7m=gx-UJZJ-OB^w72j*5L8g0#f@Lmu%oO4_Ks4n@qgJOvAX`c!amv>wy&C+g} zv@ihGA4%29lm_K`7iwo#9U9=L9hHDzYZ||wRg7SnWf)f9!rJjZN8r>uPEp$x6I5#8 z&nj7XT)-jx6&}{ZY;3cmDf}A{_Hb8WF`fxgS&rD0niFB<}4V*4?YtA{>DxD--W)Y?~8N8bu(}8aO#0dF=Bxi(9ZG{)QR9(m|K5wfr|3H3t;E3+n)lsIkiW|N4*%0|CeV~SxNw#x z&Wf#TLN{0uj8+a||L{k&sT}iEvH> z?Tsz1dz4KHGhWuSf{3Q|$Qt3O8Y?_SR7O;%IuHbFB-3C+Hg40;PH1P&*cKP7{6j>V<5(&TRW2e z{;g&!`rE&jld*LXJmn1F2LjyH`%5^ z^ex4q+lfIygXY>IEJUC27K!-f{ZZ>lFUtAmgXp8(oVR<%8t+goycR{ud5D9dy1+-S zUMzLibZS$XILr_3s^SPWqrc_ecKT>^y43rNgenq_^|FH`N%SDV@<;wM!GyS$iUuKf z)YIccAC#JxEaeOnpJA|>6hEuuarIUPAfiixWVMpeMz|%kaeqWdgbiSQJt#-CH5U(c zg>c=RF=qqw2tyfX;P5p!7jR^XI&q$acun^V~%GPJo3g;oT$8 zzkAaxr416|wIbVBDI?Eqbh64R&p_rD2s0L9WgEb$EhAH6Cy+(SB@`njB^yH-Y`VA; zvlz505NNWvT{8|TVZ!FN+9V)tRH+u&$##LjQl3gmD?s@t)O~-ul+)>=MauWf$JDA| z+#H+i57Nr37N-P)cPyv&yk2hc)s6v^$_FhCA}X4j4YQ|pde--enDJ(5vt%Z!Ib=|% zO@ldmFK)g*7?udUokIO4q?n95paOm`OjRl!kn&+|--#r(KmyjE7LxFasLI2}pxBJ1 zDYn7MpU69GGIz02qjvZM(3&x!O* zPpQIK5GU+3B^>0a?*wYj56JV}U|@y(&lX%9hee)R9OJwlpZq+ubnr$ zP6=b7f1993g{W5V!N@EKyan!@BzV&Xn19L2TOQR@cYC{(EmynKwJFEFFXku1z)~jo z(Z0Al#x#8jHq{LfK4uZ`8o}Ql12n+jBH_@L;9jGn9`@4<_{mVxhyn9hwC};30D!sC zFD=o&jy_nOMT$vIJG5M8Mn{|TpI{jvzja8s^?WR6_)w4@-@#^TlZbrN*w;UJ6PS}b zE^XdKZ^v-r;y%ia(RIKmRo|vDQHBf2y9NUv-UMWkZ{eNd$WV_!^|*YVD6QOFl;Zf!cagX1xZ181jCoekTq)EulHuBvOI zyDP2|A()kJuW$8idiDtv<9o^)v?SZPtwfm->sSmuSqH84q-jWrkuY{HqlQQX)IcLj z5`9__^Wj*(iS|@0$xOr%k8}CZMOAb;Yf`$CV5h}rE9|Q5+NW?&GIPNx%l6oo6)88- z7(TC}Eikg&J%mf6Qsz-7O6fvf3CL)QY)p+}Mpt*X{=%HWP~u`_@G|e$T;NB)rnWO- zf@pJz6>_;O?BtKYI;E%w4_6r6m53;T2Mv#{coqHeKZi`CQIWCxBDB4K)JdqHRT#$G zq9M|**2MtLs;tUDV*LsqDQw z39uJl&E>-bO{s66iM)a? zb@ZUiWt_V20F0eMJJmNK+rOeBotm$vwwWy~eRZAuJ<>lH14tmK#CnSdk#87tD6B-` z>aXe#N=&3o&CascOCGa=^$;g-G^w{UeJ{mG6|@~49D4*@k)4W=C(QY3qKaL1Z)~UH ztH-VGzrrpi=LpGtp~qKQX&xzZxQ>fD&rAr9neB)qmQww=pAXa1`3~lTD{MCGcTG8+ zRv@ibnXA2>ZeqcnwbM#h+H|hA7Q36;i*Opx&0mT(>XY#w3?`Pgj0u`@A{5QhUa%nG zR&j*vWW@ozQ$yY!DfU{*y}hg7;cZZNBI`4%#}(sk_z)Dbh~CVnkfqF0Dznd0yi-Gd38ih2l)6YKG7vk%MW9#gg>?&0%`k zjWEoq^YL=fs!YYWe+s+Ck#IcA;4Xs$+iMUuN{(3Nz%>w1orp2opyHP?*4coH9pW40 zs7g$6tO3wwV{a=u^duJ@F$?Sl7;l3i4Qm$+Tju3R3~kh;hwN1YTbG`amOURsoASqb z1EsaBQFjlDagVahZvx2&M`qu#6f(@W;~|FD$H?%|w+c%K2=QZ;L|Q_f{dRf$g7jtA zx8bFv<|(XF_GP)e|CQ;93Q^{*#)333$(t0yaM&1YVso)D%@=T%DnAaQl(eRS))%5J zis=lu90&Wc?bWSO7e}0kfwdgsCT_DPr(H86>u;U5k zVp+Tf#Rxy9zU>UU?9+puUB)kkGzE&JmWCv(S<=(jLXKjSs{ufUM5v6re~tN$1lz_~ zIM^xNyVWWdFzkRF5t)i1%1n$!#Rx>FXoY7r-fH$-WXv+BE9;rAhd&yJbb@Qfrs1e; zAU-qfmFXcv4$6I80Ggs%EBMQ@h&fRujiygN0dvKOJdcg1@4#6n^15$E57vb*zwS~X zZ;vVv@rR|}-N`;4c{K=*W;jDm8Ke^kf(PCh^9Vywq63ciA}M?-j5hGx;kvT( zB*lQy(pp1kZ??*~08{anlCd2`A)@0VF1mQ(g9t&{Dkkzjal-Rk?G9QPp(@DJ265E1 zIF;L3iDNp)Mvkt5D6&uK74%{S0Jg`BK-t74xIp|w_V@Y-+5S&;^Vlfgn*27(v9326 zs8qSL8`Qi*?huj12ur*2LR;ZwqASMZmaqUcY-p`1rc9_?au(lhF9EF!Kytpkuoz`& zj;6>TRu~<#OB6Y>XOnpohKpPo^8P}UVYKcMJ%KqP`YELoKr_hfx4duqq{{69n}(pD zr|lg8{E-n#6JDEc?hWK^VFUZ&V(jeQzW@aX>zEBE@Va1SC0EJuk|7gDE@Lc+6;ka6 z^XDdL?e1m|c^Si9>Ul&?K5PrObhALIP^GUS(LVBsz^kcVM#o%W=lld)x(`t*#?eyW z0Pwn|oIokUQP01R>j*aynGixouJdOBwpANEmx^v%WYi643a;-0b}^@%V2JLg2xTE2 zT6g8UUuT-OVsY$bsoT1{PI{M9?t|0R@?7zZ5?<50ADPUx)=Ytwb*7L_cnO?f^)!?7 z-B-fI^=!SFNb0w?o~Y?%9(7Ek9M49uoP&U|mWP1rf6CgkRZ)@~!uiCqT5_e(zp%Q~ z5C$sNYdJ{~mENl0`rcgUG;E;u;L0xX>~$(3_r<)M%_p=)ymaXxwk-A_X&0tMBP%Je zKpm~s5po9>+0b4II|^sZDa$}y^M-<8)nR*WT!}fAkc}c6URL?W4C$>b}zrq2;%RKzkF6BOQmB(DD?N5rYr_KCqbQB+*2!Bv}xB_9=$SkUc0 z!%f%K!v4J!Y<7gOp0oNLBGNPKT`L0^e;J8962;ZgWRHX+Qf|SPW(FP#mx!*o*+bN^xpan8O};AuNnu4RqZTGZQ z@L!9&rPktwM~%()+#BkzrKF!)?w6sDa|rAis+30KqRM6pbJE$6wPD zR>i55P>Z~f5d&qusy?CQb^>b+C4d+mViP(#y=}025$HE0n zYgWlX0HOH9_MUl#u@Rks_*IFWry#;gj^Glf}H zduddQedqY8!RWoZXpw{T+RM10UA&mI{b)c)X&HrE8y{SGxEikrtNT*W2@XN-O? zeDG=QF=1SI(;7QU6^nh@LIKe#2wL4SaEp_OYdDvq!6Pa{Eo+yJ0kdX8U6H++P>c_m z&&JvLfHXh6p$BsCTJ!3HbE zj192jmgu#%@*FY!arnRxb4he|5y4vQ25r~b3Mu6Fp!roJ##6;+vu}B?CH#@L{NkeM z>)ZI(^{Ek7z;kqPhlwh8cbIW)Ca~*|HC@yM56awqqem~ou?=!bC<*T~z?LT*Mz`X- zWp=y+efhJ}c$T%LiVAhQFszq}KuUebTp?5E1l-M0qnQAP2SF6XPI>7_#kMRto|o?@ zdkmPA9FZ0JCWKe5v!8b;P%gfg^YYg&zX-)5Gb^^98@hQq}!6EjV1-@lr_KgP6U8!r`s}*eyAX{(?yrFm61-j)7xu* zw-zuig_Ny>P{}e}(4(nns*nV&L?xXJb#i_yqsIl6f-z>FHp=_}4NL4nP35Pw@NAOO zuqQN^d~|=rksc&+i>}6)Uuc*Zk-9fPzx$-^EDg!0yJ>o^mCpe>BkiV=%-v_Z<={wM zyU&*gNH#_gIMa%VZ9?0mpW;ZlNVmI;(Y1@*MdmLDOZcAL(4sCg2yLM0h4{L6*RjE527Z zIUg`ltwyuiHmA`{zc#>jJy1aU>HOSPKI0DFTM+vNIOr-ay=kc53d83K&#Igm=KjO; zRTZuf98FM;b2R(np=nXkmLc*)4?%5QC+fhJ`KB{utNcpj4JA5aX>}l13_GQ88YDz)IF9@BLZh ziKJ&xUiqpzGGC}}bR@2Y#nWZ9NqKx2Vk)zb+I`|Shz-XTIS*9r^6#}7-)kLF{ko$AX~t|>If>Y{ z?!J1jRaRU{3_IC$>*cy}A?l&?(%p)}z~9Zz+EUJy&&{LS4#IxZ4759#pEaoQXL`Ts zOUiFMr+ZmBn`cHibC76gTPs?~Ags~K4@|un3|ZZr8M$s+aa;uQQM=yrlTg^0^K91$ ze8y&0%Bvgxbl!#H`tvobbv#Z`o{f(;2X-K$zGzJe=5c9^!xEvc$2-2&!|jyWmwzPS znNP2`+2Jv(Mn+{llxO_$UTu&iai0o=pX>zC&jw?JF^JIUY-gs#&d7}ze> zx55+8^(VILXZ^jZ3mFWX9O6)t^QL4woFh2m>J%|zjJP!7&c!Lm=Sa2-s06a7XB3eM z(o0jvBT(?#qKevrwNhj2-8t>d9h{1Gl8Xk4Gn@jAmwhLA7D~&B2R6tHFNl@$4xfae ze$@tV%2Ae~{;lbN<=+a5GFIg!o7|YMGeTkGpe)C-;iPF{gKu-9IGwI^M5s6XHE-pU zHVe7NpG}`6K4LJjnHz&e)J!mY^VK%woknPs@)5W+y71OBS)>gC1j|N+2+xJGt-#wE z3-e#N5es^X&d1VuMkgalU}gG67XThD5-U2``=fFR6JyLUFCtACRzuUqxT1;`--EBbUK75pLCLbFgVje%0Q1J+q)DiT)5DOd6rcP>6 z#7iOp(ux$BTj8)@Pt>=|dfNB|41{ajg!-Z2J7Aj#x3O9++qOrnoMXy1?BwKO{dsrY zj`_8p2EE~th~ixrsf3+7*wit8boLSC^D1VovIY|t`<(ZlIv?Q+aBk^i*r6IN!|Mns(UqF^&6gta~j7>5C5hmZ>%yq=Z zL9_PxR1hk*S6f4S9`r5Khp9rQLCd(v$N}$v;;6JcapW(mPw<2B7J@z4ApglNlJ|-w z+YO;C6=oLoc}*kG$Nq8@Ueta0aTisU(&g-vBHqv?vR^S?m_Kt{{0Wh0lGmEnTi>&p zH6R->Z*80&IWMX2F2LIQ?r`Oe*@#{lv(}U&lbFzG9^2RO+w+VqIJh5VsjkdP?yZi8 zAkOES@e)s3vNsZ3ioR_i%isCcIJrF`tOf?*o>R%*)&^9M(HKcQB+|#V^rg&XYFm2b z-CDzg>~s-POfq!`bc)4%WE0(IsSGpM>Tdm?5ZPD4C)Mk3Nz*cbwM#n{K+$wsePfUf zY_&7-ivw#^9~Wib*^a6{4!t+tiKaZPapyWWSdXH0)aHrnsaP~-QlmyYSReCg2b`|j z8~T=lm#o1f;ng%rC6yBdhkbTAOvP%Wf_5Pe%n+4G1 zRvQJbq0pz41|BkjF!;^V2()Ns^J>=xBXT+DeZZu|26X#zdYmLM2b?k_7;~`CW z5aRbON1Mg7!F*H*c&odDHZ_5#QS17JIpY{kH5$Y!(McE!?x78~Ba>A07D0ClkDHL} zaq$?`VBLoLv7lXnAwvbWsPy{ql$pW^cLol$_8&ow5%u1|v+S3eVc%9uv=sa+CZx^% zo-*vw;NjhdEIKwHcOcdEeAJ?++BMTs-QmG#dh%!LBAX2zc zjCHgwh76$y4AQ9xfQ2YFoKoRvIMs*kMFvW9TUon@K{G0%6`Yf30|WkfY_t+w zYaAH|H*D*u_tg~hNcWS9!Q8q96`D)aTY%1JZU29r!yu=It z4uq`h!6rf4oCOtCDAn1f$CR@O&c)P3qC;;>^9 zn%os#ud-C-`gPs_U^ZwGONzzkTTZmzHQj4_(fLXWnamZf+(~vCO8NBPLtu4^s@+Fx z_x2J5VXZZqQELhzkt=+Yiak&!Fk@df{ZI_%{#ed{QW98CKJVIDj@CRJf8e=AoRufO z@7js{gf0hSmRIXyjT8L(qLJU#3ZyLHrj?5WnKtb2*0yP7k-Y6#=SF&GlgKK9*r*ij z$)qZJ-Uupptce(o^c{xPhy`|k!1$c>U1c#%&!){L@M`nVzTr_!wXbWf0Jci#P3HZT z8uhM`TzWz?HIliz>cY6MS{QS*FTP`SH$m^SB2#1-a7-?EeJEGSdJOR&^# zBoQMFt3+*GiaWkw0ULJXc69BJk$jxyGoXzr#=t%;;rOLuQsG1_atbt}sitL9P*iL2 zT*Rw&7WVbNK#?RuIxDbTrC3y|jCt%a{lXJtPOnQMg5GM9BiiC93tCw{pfEa$km=XU zfcaB^Pi&3o>}w7Kq|D$mdu}l;?Un{OnTRla-h_5FViJeJsN=G#w7e^be+b^3uNL5# zHE77FC9;tskpTZ=HV4oDx8V9dmWfDvN^E5zM-v5I zXk9xzjF~)vJ=0Gwz9Yb%Q4pGXP}LEi*^_t*d)cfk*NORR4#Mnf&h3}sD-LL3Kss4X z9AW#ye6c%fnFGLPp`_f#`oIK|2W>dxgbtV^Z&72Dw0vn(kJtc7q0isukpp!YtC8|* zfSDw_E6Q_ySYE8qRvSjk%2_~LVcguukxUgzCAUT-Ip2$0-yhC#HSlKhcJ}hVisVT? zFDuY+38K=zV@iI>mb-Fox;-?b+O6lx1_*%Dh%JcRe^5w zK=XvwxT|%+`pC^!psyD_-;ulueo@dxh}90iru)?D>wHzGDKfhI! zooBjt1-ojJf}4F6*Xd7S47BWmJe{6($+<-Iq{sVo zc7}xbmdkSA5QC`gx9qrcdI@-#x@yeOq8iE@$%qag)L>UpKy)6FF7E87IQis&=V?L} zX!BIbY>akQANj|RgKK)KfP8@@)HzQmQUAo0wQjgriv;he5q;*VkMxuXvd^R(OOwbB zDqxW2UMOh%XebgTZy5Kbo;m&1(ta?#_Qft2Zbwc)LXYRG4!6o1{|`+i%8$VDIbH7$ z!(blDw1#WT{p*>*7)N^%m78-#QGrNU5VbC#1t00i0KK=n|qg_Sf zX>M+e>~hR5GR#+%gEb;8nX-yl%cbJdL8~@HLm_ttDMl1-qs4zYwO|Xxn>>&U2fV;N z+chpQ|J9nVvA1{)1I4mA+^Pr;5;zMAw-D{ddlY9j81sNwwzM~Tl`cnx=YX9RPJvs+ zYON`?Teglq;~>Rj#RT3l_`C6^r>-7&-wjq>A+CbLLK(xXB&j7fU(FUUJ5O<-7g(%x z)EH*CA~x`M7qPJ&wDPcW72*(9#Te;bd61$S@6GFQ+?z^-xhphU-K;~bLBwaJ{hA5A z%{lxNG+*L{@q)8B`42@k*~3wHV76l2Mo|oXd|N;DFEW)v*M=#ROo-!huYsu(I7um#h z6<7IKH>DKAW-R5Gd7lPbty(|5)0a)I2Ihb$=I+qoyfNCMtE#9mMuqK%a7z}G@Madfl~S``}rwciL$sgg?#n~N1% z)8vX`F{cRi;3SHFCep{ZwqyM5;dP&iH8p^cl`B(8)`#`Is0AX1{j(c`ao%ZMSd(Vy zSt+Tp3m3)W{C-U!2x;QI_Kb;UJ^RqjpMLd&<9Y+rtJ#+vU!^Pz!9eq(9|GZHo<9VS z>A0MXQi|A_<8XcQ^oxS}b{FB+`}tA!5}qr$HH{)XeJ7Uiz+_vL!;eIk1YGsml&-d5 z!g=6yWdDwW%2OhZ;|hBJ+Mon>aSFPJ^Po7j@u=;iZr1H0zzC^7Ip~heS5@S%S^5-O zr*MHqaoFc8)p)t11G1z{r_eKHdKmCDe(se%g_A&M7jIBWz<7hTjH;72H2_;@?RzIu zIxUpgz?b)rXYS7wW=YU2)K+3@mTOI%Q0(}9LR8X7(baaM&4kTphCm^bX>by*s6p;A zOXd7`3gS8Jwn{)wD=O(IJ0Ov>dD zaCVg!b_X2WNVT99eo3z6da&}-L_WubHh~Hs1m-~8dyBE6K$~5X`s-_mQRNy$@3*4cQzh1<&TqB3Xj`|+VPUk6@~z)=>+jbhYTN` z{RGJ%STk~OZLLWeCUL$xHxde&4K^K3&CG8eVI+KM0?bE6&VAOt9)ZE;OrEi$wQY=- z?b;LYzjS6jrYI2|cf;x4V+)4-(=JDeiVI4)9N~j%)XG$gm#12ATyztnqmV7DwaY3y$ zZi=Ow!KYas8rpFpe)&nMMHW17o;qd`aS81S9a4>@MOoO;JP#fhRL!;m<~t^K+h!JcAjn-L8UqpLt%~=? zVD|B`3a&%L#+SwQCzC;T&l#Hn{CqMp@gBm(9L`1Wfwm_hdh>lLeK9K>+-dx4A@2gx zmJt|Fo-!=VQmXoJ(r3pI!J%`izUzrG3^Q0^=tIM$U)xG@@D&LQYK=JgnLfXv;C+By z#H$dv=|XNibyVdQdDbiut{%DIu`{e|A*2P zed_+es`X1oEFWgS4#aFn8cz01)k!lHMx6W^x1#L<1UUR|bIo!4#~*w}wGO72fN7*q zCiXc>S|#!w#jM@jYwgSdzmxs^UEsY_Lt-b}&Vr`ig|()SMeQQbhS~~`zOI*`4qo0m zcSL?tVG1D0-_oyR(*wmgstR9SVJ&Z$u$_yj;kHY9X=X(^3D96wEYU`CXTf&eB~@Z0 zBJ{cp2^sL6EWEL;>80&Cc;)szMcSOg?I2XBEIm}2YVI+B5f%2rywp<>I6@cnj*c`f z)LHB?6md)pK7x&rDzb z{05YTY4_Xo{+bv!L&g->kv3jCB6hf%uftJ05yp8;F|PGelro5n=zR%%7ar*wPtEFf z88Mb9blH2uAC`S#+WMjj`|k3i+x-GMEpBtV>m6rRLAc!J>k8{c7Q$WTj^(N&9w9pn z^Zf>p1@2(8$Mz~%f36Z9~k>iok=7-$973 z*?dwyS0jWrAS2(W6YzOR9pw3Z=9SAo{<3uN{g~TccS?9e2n2fGz<;k{PhF3YE<|>W? zOBO2B@p4}iIqN^iy&_+6J)!Xl+(cguaBB^V>^Zj@4s97}4W7^TeH^C$jek`tW4n&q z36D~&M|a;@Q%>tKJAM6H7&(M5z;#hqC-n=Gafr4pHZ!itSJV7zXO*UA?Tspr@}Sj- zlTpw(P_(u7yk@$-KxBKjx5nGdZ2eBk>c~5^9EWjqO#-vFk0rmi!69Tm`jNhRj}1}0 zb!@+pk##!`K-JPV2Whw=k+MG`nFxq%mTgz0h9B!2)r6b9#0P1sJ}D2dco!U8+vyR6-vK__yZ~%gz$+G!u|C(K5Aiup9r}Vz;RYi zt2)Qb-vwM!JX(!T|9<{dt-sytpM}WU!vBWAUR^*4G4MYApY18GNFT`G{SLevXmVTq zgCh9L!ARd^J6DKRf??9PE!aN%vW;r(&UVeMBIMu8l;xX(s{E=1H7R{7iYN@0SD7qk z1kiRu2p+%mJ8Ae3{%3c{IuyYO~5sYf$`EJMbMSZuI}Pbt?vc zdoTa({Qp0Px4Z9WM_xz&{|v3)fuA>u75MeJ$9b^gp;YIRpvX`Udh?54y*mV{-A`Wt zzS-e}iZ0TTcC!4g{5}TR<)~kPjnVtO7Q5T5X>I~;3F16Ywu&bW48vf&YwnW3N52@X z@38tsAp1N=W7|g$9{2#IC?u3Kg=oK}tLb@kvVv-xnXdp!7JlK(k6#el!UK%|edeWu zgPXl&8dQ?NgHcm45pb zJ`})b>0H`zEIcxZj*H`jd`)}5c^~fa!eLz-^0&lii#B)y>+acO|KP8HPbOLZ|D~M2 z17K{=`kw~#sHuPO5B_>MrQiRC$Uis^|8M=yKllg#f8dQU{y4%v|H8n3un*qh4gcU6 ztZS}LByq>VfBz8g-&kM$2mc@f2Zz_bJN`FBs_-Ez`FEvvA8!8{-+%BA{-@#J2>%EF z;2%8j7ey-n;2->hGW;)OiC%-hYtHr${=q-^2mjzl;Lktr@elsNKllg#AOzn!{SdS8 z`x^&-oV`zieCX$Qc=-qa;4grGqvId^0}-J89}7k(6KPTdtN;K207*qoM6N<$f`0KS AbN~PV literal 0 HcmV?d00001 diff --git a/images/platform-list.png b/images/platform-list.png new file mode 100644 index 0000000000000000000000000000000000000000..880529365d45a87be69dce317861bb28bd0624d3 GIT binary patch literal 1758961 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
    {AYv9b`aX~(5 zuSCX%v-SlKPEVbOIoZ+5EQL}$h}*;`|~P#`A&ft>nq?BHUoF5C{>4tS1WcvuEvVA)HNpkQP2QFO@H#Sjso zzf`&Nta$DQtrwg|W~}{J`~3!cuBDN9hDH#Y39i#91yeu~dzO8Q-yd89p^|`#n7j=Q z8-G)KBwV!+0s<0+HipXks0206%KDHmmV^IVPVEmY7E$|@s$lyM(XAwy4Y48S5DfRx zD_f}`I64eaCeXu+P(AjlV99^XV!faDGTGw{rW+8su%NK4!dB51pe|fz`DkQTI*_Ums7jK?%`SXn3qL!~Qknxt%oZ*D>!voW>FXMX)CT<>=J00S;EDX|(F z5D;TJldrzC@bmuJ-Pj1Lt_x1kVA04#WvR?3m!fk{-u@0%0m&5eIvkv;Uggt%G0e4; zRe_$|4OI;`8+;65)s2YlYYZMl3e-onoA#M1g_0!b3^Iv`i)RCF4<{ZTo(Ug#xKC(^ zguPT^UY-l4h89Y-C2E)*1H>bE8O}n7c-qRz?nV`A-EE1}C-88dVd4*J4>lPILK68O zTD>n2iBwx#EZF#tpGkj{z2NTgP5%9(s9N3}k>n}XETOnF8A1m-ta!U73pd#jdG2J26{^@Ym8;(*UtfG0t%kQ_#ctqk z;TCJsv$QF;tXAC~3Q>ti0Tpu=%D}~mmx!z9a_il*s_TJ(i@@EIT_KS~Rt-sGF!DgaCOz3@SRC{rO!0cB<(rsS>bKrK{VXy(22X%C zC^^9`@%TFkKs6FN8BJNQeQoD`+Q~0z2>yCJ=%?0dhgL@Kp=-h)OD9d#NAx|t6jzEI z1)m+4?mIH0^+4$x(5YwOC+vvobPHKfV~!?;ES(t~IXF09r?~V$O2OCSWpO9WjAY@d zi2*=YKj8!@iLem(?Q61qho;PeOismA@3$cv*+-ObCEJSccosGVu8-7n@awl0*2*0G zdUKPO;P2f2y_0`mGRNXTv4oKW>KHVmT%-m@;IM}vW0e6CLTp;hj|<2jF=*(TC;}RX z=(YHd>1zOLD^lhOuS*Qk>b&ymWr-^8=>EpUYLGj@H5?zXcQ|AiW;r-+NPa^lw`oM} z%qu{9c`~5Dga^q3<_to)$tW$&pXaarEGZa+95QSba73LEP)<7<8TZ)0ps>0gUjGDz_Ec2C7Cq$onw^udX#_v_)&@7283{3-N_U1 z=kSUr_rbdz<0%cxu6)m|PWUNz(a%$gV|8_*=+*Io2kp&W>-u!g6d0U3EPpzN1=uhd zv)cgY<0VTJzT7dmU)Vah;90QrkEMhT2<)8x{~<(=E`p81CkQ@{x&;~69EF=5XC5mq zR=XR=LtqqW+~Jv`fEQ3jBez=s2Fn$ZexPs+4Y2MsEACbAm=H;tl$P(>QV4yc&R-w*ii4EG55TK4bf zN|wWurqd5houl_r+@)F7Y^3IJLc-1C4N=br*Sc1D?Z=I&wHv(56H;10B;P$8W+j#Koh27UhP%N-%Nnq2<9= zno4YO!AfKO7Tb)TP2K?CM+zAa+A9XaNEw*V{OtW5+p0%AMT4X%H#xma!5?I_)>f0C z-pZ0U?L&ag%ZNb%#~qI-@6{dN-za*0!N?&!s?%Igs}++FqrxYi4t0(5jKex>^7E^$KiR&R z15DdQ0twfA{8xPbqw4`PE6mmP>A#Yg^VbF!J>!C-&MfvDE%*2Q6FAdg_@eWL`@w7( zUSaKNafv2Kr&XzfU}8`?rgH0RxT@N(tGOU;kBQY(GGoO8wKREOB95g}MKgeiNh%Jl zq(O)E8VLzwqoE^bgR_7tM+}G2XFO*3EQTcuu>e30rPgrq5^RhP#G|vF!3!uF((;Nm z5iw}7&Ombj2`wVh0|~Y!(mG{HzMMr1&Kw^W`9Ou^TsTkj&?}EKz_tm2`Os4T`BjyjD{jo$tm);P>7qbyzW{&v-%d3LePlK%gltUC zST@VprtkE zvA;<5<-+DV{n(;Ji=>TzcKUz+ItroFW6XstW+r}8?vyfV9o&l0C=hwF;Rh8gEhr+G zgh0eXLcxd@SYFH6DS~Q6VQ6M$#!*ar66in3EN##R z8JGWy5g*YDO3))`TgJM*25}||Uk9Gcs?%4>qQ-Yv z<3ge0+DuC2I3eeZg;F>UPHr4z*rMTVfp6Nt?wI;Jvhb%&5XU>aXyWayzdYY}h2MoF zGp-@vpG8AAP^~AsL033y+yh4qA}#9QA`xytNwIa;%cFQ;Gr+I&Nrv{HaIXGK@3zW` zq*Ka=--p><8`}Ff8Q+13gKZrS5!j&yALqy0^SAVS1f}txHcPv_-M86-<_wYzB#QXz zoPI$>+#C%LI_g;1^S)gWxZnux4qhG}%~XVPiS{JyE@zcA_5e*%uA=3ET@l!Nh|^wO_8pUd!pXwj?G*@Gw(G!Q9JeTiN@^ZO@CCcBl^Jy?l? zz-ydbQWGFLC3$ZyzjOLo8)5M4-zVnlkC}#FR{i$2mA};X)MzPS?Q{1j*OJ4MbijZB zWs6r2c`;ODdsW=9j!&{SoSeACY8v>A5P}#sGFB7Xb#Isf;N_%`>F!{frG>ck0Vjv5 z8bgKC2K15`9egMe{++G4-PZYOY}=`wO-&txms*3Nh%IjpM*}E!38YMkOo0~`$4^4AN0JcG^LIXDk#U-M+T;OjJ z2q64rfsGOhFBGK0o5AoK>jaI66L`2$$BbbhAgVUth#Jv1jmJR75P?v5F4wDcNcD@$ z`GseW{A=g^{HDKr8t>$+7;xtM2l>I%%X_Ei{?1+gTS03w?NIP&7W0SN+K=`%7`*&= z7c!y8oB*m#htUeqWMB$(pEJ+n%)i!}|8;zQQH6yMOhQo!8*NKuF)9a9&YRuNBg$7JRkrYT&0s&PxB?QNT|Q zhMJNZ8av#73*;xW!0dgq>-o9wugZVz*{K*`BED-Sy z;ng?FB}uf1nSp^#ylHeZ6h0TTJs)-?Tk+uAD~`+uLBb(@P~$G;?{%zF2HKoQB~*y3!iwBwq>UWXTbw9%hv{4VH*me zg4<&1He*4?4~07X0Vpz57T~sJB=fE?J(|oUB>5QMgep8Qq&{uok|T zOoTNQicCbL2nZcoPUUiLJ7CXM3c#3Y(#m2eN2ZtBrAHAJ)IEu#@9 z&sALWj*DhWW}@Jb3q|&g)pxsM#A<44VEzczZ;Z65eWLlUq*#LxRPsK`zEqsa<*9D} zUy9dN^{Cv;d~JLTAdX?#K&C}%9@F=Zj|@h(QtkQY29g7hDtFMu8evY4qC>#MmjCt5 z^Z%JX911GIqFGZb`*s=$BOVjGp$3617r=nDr)mO^_wmbUS%AI+Z4?=#ATt`p>VyMJ zm%k|mTD$bF@4-r;U;nP(!)f-@%vg|Fa&tT^-*;Kk4$pvL;~8n{ugR_?YIUPs7(e`(D&pp6knuUGF|J)Ejcos?w%(=yQ?xIRhCt zA(?%59Z^XsG=_?0SJUVaBn~qRsF_1Esh4POLx*z-UO&~Z_sGyf5;V=TE^OWeR{X=y zOf645mVOp)6243RF;4bQ-s^RDw%Od6RK0IlGMzoRBpBqU4a`jr4(-UP81Mc3J@4DE z#h0<1l?kI29%r%BarLF*Vw$6%r(vx>W8jKi2|u9or&`g!w56 zPzf=%G8o{e-)cvs+Z7{rL|miqb5Bzq8by?sl>;qLB7&}UpVzbj>&Ry)po+stVrezei-{NQSQ22Yd zJ^yz{!8L_8hsD+QrSj7acVZ`IzP?NtT)Z||^5)GNILeL|PkizBUSQr+}7f1jzgzXtl{481m5_%D{05u++@P!~_9} zsa@qX`1#ufeeJ$S1C#b%D|!cn7Eq;+?_?U#mtBW~CB>tlzSLw^$S}Ze^tt}CU4Zph%Ciz6^Tl^Y{VYKKr|%+OjX zB`1%u>eK-3n0lc@a>RjJtW8;S=QF6ck_2JRsO&e6T4~I#p8mb?^LW2LVzd}6IcAxjYQ&uKqcJarw zRlDHJnb=(6@06Xx^N%Bs$Ry$S22@NBHNN}e{!9P*b|1$6o~H*793T6#T{klE-MtC* z<9(Blp15CmK4HjjKe({@{49?%Q!qF>IgoQzGGN=8p63B)rpssV^gKBhJF74i@IFB( z<*k5vVrmr_7_+Br)P$&t7it;uEd4 z_>9$_jHLq3V!<0`q~BY}8xQVA!L&zr@~Wgmx&PxWf-f?Hs%C&nR($4FPS*8Xq}Ul) zGk+zBdf*?M&o8(Pd~F^4RSBA|^h412%?1w61{?jPc+HP`flhVv$F+K|wYFE~HO(PY z3PDrw5O#t#MIprQElf;K?dS`huEUg=eD9dOe;m}Na;8f3k@6|gzua&;`wQ|tk zcdlo0BQp*LI%;m_QI64^l*teii58>8$5vA)U-l96HWaq>TnORs@Jl=7v(4$WxoOOi zW1oW#l@-2Wx(E0N6|BX#uM~oWtNpQNf2N#lJO(!GkfV}Me`NElB7 zruRfyNX5=7N>UT_{35M51mAD?;_T!zYb~5>Piz*WJyZoBAp$i`y3wqc3Zzc(v;-Ym zJU_wpgSPNO6GjUEzixxMfjiIF!!zF&Xq0Q?7b~ueemeKuGtb2-OLP310ii6+DnL!N7b8hQmjzd_7vNgh$Ly?J|EEpJ(Us+GuQ+^K*i;@CuOi z8t90VQ&-`Ey14c;%&|-<<5$H2SjRY3_o54d0%z>8)SvTpmCh97%q{=HbHdLEY zd|!SNTqyv3rla)7tyfx_{h@3^LE1QiC4dHnP~FxO|?|&`9!6C#8hCi`++Mr&7QkV-k7MA>_54Q#1!2@X(y3B70wRPuikiI1Vg1otU5zAy)s>nkLOklkwm7z_ zhSp!fUHvWEBR?;%9FAKZS6o?$6Wodekz~fqmq^3EO8c}ORaHF-X;Ke=rB zZD5z*cuVS3`Rvv=MkDUe?oCdPbPrw@%tM1BnD34mDFJ!uR9*C|&wm&FX&z2e2k$=` zTz)!@reJbl9i|zuBQ|i|;leXT=K+da4o}`&a44vCDChPOU5z) zLZUfy&F=~adV7{`LI=zbZs!YQtXB#h*XA8P_j@Yxmg2QmI{X5%{GcdYD>quL7);Z2 zP3}CytUDuU%N2~i3GVh=tC9&Bge|Le$bwt&lwT0fuX3WSeByY}zw6hyGJ>C{F9m;} z*R$ut<}wX}+^2<68H?UVi@}3_{{ANcsYGUx@^HXp1VXMhzd+MWjur;-799aI!&C6v zm}5Kq_EJWZm4AD7ukMLs?ifGSU~M=qh?@aVZf#OgFcTQk7#YOx4z@fPpga=#gj*vLpf_mxZG=?n02qC)L04L#FwM zl`OM+Mtd+s@^BBp9bps&;l(%|5n%1?E@PWwYAFa+?sSFFf8(iR5j~V|M_nJqHh<^%EQ(u9Kpcu8y81IoQm=zG1Cbjb`j!oTcY>S!g1ha?n+Oj2%upM^Zy%u( z$Z$rDN)jOAJOBWAkWo}kk=4HQE?KubxV1ZEzN~^*w&!9Ldi(?fx<=woQ&xU>Y{?1W zFM_sH4ivVbv9)4bNen=kz=yNO7P>^x10Y#eoQDbxzfAvr9U)DuvK5zp&Gv+%&&>GN zd~J{8QLr!Xy5XHvwiX&${#(Lj*csBuke36v805${4C~aniyJin@QTq318=ZV5x@c@jrXZkv5i5)N5Mt@Dm~ zIn&K->)~AqvG13rm4=UQzbCeT{{~gH2USG*lSE=uRPmD?$;Vo3tsi;{N1^!4UHud% z1oaX3>CV{)Vek6o?(U~szgwn!eT6Aagj5~ z?Rz`=P*<fv42p*h|1EKqo4D?w+C&Ty2#>|U zHU;=KIFLwm0)Cg%p!6!;`f<-cD?gxJ2F$^9;50vYFn95_ z*4u^NiK(|EcSJIGLHe{XhrjknX8DQM;*E)1&ce$$X3ZG0DJiHcE2MX&a&RSBpcm9X z-l=AlQ8}uZ{&TTAAnnXrW85OwT3Bcu@UA;Bj1TnLr5AClc}9Xxqm>%1rFgyTg6@Me zU+fYik7o#aGUi8&gd-WtXEWxN6n}<*1ZDEysAljPK$L+r4YcH3;D5$5;4F+!?P+)A z_xnu48}_1gGW+S%r(j%soT>BWi(|}X1=)+q;B+;{g2#0O7GOa1FmOP_F%pJ2r-x}c?Ii93TP43BiCLO- z(D2;N8VXJp3uOaNC(${jnW0mVc!i(lw>ssuY89U9&a*Y8DK(8M$z10ax#c+Ql~M6d z4sUfi26iYOkz7ypD6J@3%2YENdTAZ_@MtlNLWzi7BZVji+ivkxiSjNF&hx5l^{@Nz z8sNl3LOlUOS7VssS%q(+Xt6ff-dfpz(5_`oIK8%zQ#PF#9&id4x%R54cvcH$*M;{B z7vlUs`3XPpjUdFbWGp@KZI85pUG%N1SCYXM3F~2P*#5?W0ji#rk0O|jwWS9)zX^(d zbN$turJjtH8Yb zS6kSu9Hy8my=NEozhe-29g9*9t0uKPTe&pvFM|@7!=PYo(x&Wq|31|gTs|?f2ryK8 zD5jZ*#W6PKXxNIvSdM|YDe2)Oy?4jYX0Q6I1|$kgju7uLP<8fT6AOrY&}+j?2aUtg z?CY)rn=8DQdI5GtycVlsU9ER=I5}`o_ki00kHH(D)zYI1{4UR#kYS&UV`)cs28_C# zm0Gt&9JG1s0Go{sBkO zG9x9p901zGHDuPKaY<2b31p%Kcrkz#iD2OUK>h~~lm~9QSUT~+)We&n`xXz}+sYT- z_sc*XvkjfZiLaAnYttmcF*m5|Y7jsLq_PWt|E@n{Q$BP2Cs*&Aj9);j%+P(uh}`RT zchalVfyzs?YdrP{IeB>9W)h74akq)i*FJpQE2!eHas7v;M5jgBx5sZZy4T0srI<%u zz4(5qd~mP~fA}8$=6$No(i2e3SCZ=~c)BtQHZFj?twQPzqY+aLDJsnZQb-6+aGwh?2AY8_ zz!uojG!g=sT9he1RMu7;C61s>S^fy9u_QDkFx(d^#v)=$ufC_osN>vG$HjOpVSIF5 zz2=*~UtrI<>+sT)YMNYHP~g+B!!PJt5_8FoSv|H2)~c42$|i!a7H$)P0C!n!X%~EL z8fidf-QB!hQzkU>;P;P?^Dd4vL(I9Mj0H1AfsfJBCclh|u}|Z0@)j7)HZYgn6xTi~ z0)2bosoy{_f83)js97(hbEUFjC8$p=sLxu!jhj;3ajeOy!D=^rV=GU?KId z5JY6G=1i{&6_=_r{ImRmd47R${Kb6ujwfIcvE`#Q(uRa*V8L$Y1!_Km6i1}fs3sM zW9=b=Gr_{7;Ll@0je+G!3U5rGK4BN5rC~A*J3$RL<`_g&phO&VwEW|9Pm0Ft6jz43 z9hrjC0=`*j+O8@rs?iplj}Xa#Vf%Y{thBHFu=e7NblF^Vbv3UM1-rtf0iwg`!{9n- z&(M}3zP!ht)6ts0((Mq~A3WB6AC%8!Ij+t-TJG;Ur>hHYG-zCqdNd$8 zQWDRa2ahKOkI!FEOMX;XCvXO-HRN{bU(CIe26j)pIg1_iT1ODN4-#y{u?K)oX5faMg0KwDh2n-xOnfnPG_mMF*NJL(D^* zrLolFyUy_0g+rrd_SWv>$D4E4-sTENjF!V@6|~H4!t>P_fJG*PgHz`W9y9FNM4Sz> z1v)HC+jMu{OSO`P`-SGmq2H!sC}3Eb)d1FEbX(s-C;8FsP?Ja0e>+{6c0rhP0=EVfnCQb+2ZZm_`>S+p9#KWkFo`N~zU4XZzyE$)<%r(TL*^Rk zVJ9C|S!SKDn?1c9PsDt|C;?JdhYt3a?L9w|S7VG^-p0LP>j!L%D%A*B?w%d?%F0fV zzW*bZ42IGg0K!SLYN%+}_~KmX_~B`d>Of!%1H*cJVp~$>q(XIKRSkCcZZ-mhp`xu^ zdGZ$cFxk5*MZ4+XpI$wwHYjNDj}wUh}Q*bcHp{ zmDqdfC!Du~F3{c;cgFMqGn9=2r7OUIGZ4U5ga=qr#A7gUqF^AMCOjONilIG$XoX8I z(^hRl^@*&4%KP84w;zm!zxBWW*ttLGxAoS;U!t}fMun;6ubC`lG!BfE>(J94uot zKjXOab9)3Hdj*@5gz*;4rUAzS{+sQG(!)647N)M4vr%@gQ@$G|kDtbDLdCy|=AqQm1|~qvxS+^d~=;E`C8} zQgC~}pI`}UEbujG353(D15?kUWdgWi=RxTrwK!T&nd32I#MnNw(Co&=Prq9x@4?Lh@$&>7NLaQVTu6!=5H!?J||CmM89?MHF9 z#gQhW`X9T@C*R(pn#d!~s=6wZlam#ruQ&^Y@&UrML$3jIXf+}IS0-EvM(OQiZPF5E zlBuAQUS9SRjz$NT<<1_+U4dRZJ&w6LBHAWQcn&U1P8$Ta62mvY30m^yrsM0^3;vN>jA>u}lrwQixXCDBtwVUhDdh6da2B&(P0=Xi$B{$J%KVKB z%V+gsp01@3Ir3CqaMM6?%&4o?U)yKDDW-6K&K}Aw zT8JH7&~)f7dZ~oMLMaDaHZC4E!Zb#nHWAv!dSBP<{-L3d@c*Lj^9AQ}b{Ss?DEYo3 zoEzViWtCArHdUZ!?>FML`m6o((7&GtSJR$HD?GV`Nd%V-2!b#mO}*gc44VXg0Sa^) zW>v2^-(NXdXDczB+*H35c4A?zmJGU1mS;=Qp_Nj{#c%H0R7B$K8bA~dFWvP&kB%BU zert@bJZGM}`o1_VDi0Rg2D)i5q_pB$!H^m}AiAA^G^_VoO;j?DheYOTo8BsqiUp6H zZVxxKmDv9aCEeY6i}TamaWso7%L*Y2NugcmTnjclSOMja7>u^59sv+OX!PT;Oi{r! zc+vJaz@DzF@>M}j#x(~JGYs+_j3!npr^|Yidhd%IYl%6&1(ip@wgM6fs42nZR#h*O za6ORwcuv^SzIJ=pE@L^Z2mY6!r#A!p+bwZ3EKhN1ND-_eb52E_0|Vz@eujwq+Tt{K z*q(z2%^8W=KoQAl;SZsu3Ea#igF*BITsfI5)|;CE7XR8rNHQRtFqF z;Tduam_5R72IiuO6R4k{dBw9Z(pcSnu9nvZIdhdi1S)_aWQE^MxL#m=FkbnGX*kM> z%*Dg(lHx80YoQaCgEK4sDxoQ+v-TJuqzMSxEf1W{&w)PLFb3rmcJ#e^e4^oqf)dKq zG~LpaxZ8eZxzJc@I}v^}7NI*!IKebSRd@SvSH=w!6lxgmpK7EVGZf)eB=;{#3vk_^ zMT0dLM4RxvOCbMCXNF#TXv zH-d}+@CM>kps9pH2rev#Sk*N&Bs8WZqq?}Xg)2_Sz<>l(y*VCaZiq8Q_z{P&aJ4m^=dGtYYQTbg-p$IF%%y5H^l?XTrr%DH5fc3RG>_lv9#LUcy0R)d27P)V~N#9=YzP%yevNgFa=H%e# zvxCQLOMTqde!=KF@AVd%Ke4}Ei70{QNJ;i%WzvH?e6cj$}2XmPbp>a<1Xx%W#_W1RsIaPB$D zSgXre`zEvcL54HJfWE$upoqD;!kjx|wBY2m0*fNa+&Rg>$jI&i|9)#h zt+n8L?%Fc=;MSLajpi&4eLSUpS2N4o(EEpfce~L@!J*0d^DEbcQ(lVQe1Y=Lg)dsG zueHhw1KlYp2chW{28MiD**kS!zqmrzGJ!OE0(9#Bm(a>e>0zXFGn??Q6ZwC@(4Vo3-o?9vBN*&IN7Borp4kh zpp*4UE@=VlxKmg)z--XeV_0S7bfAzJ8YQ2-7y!eJv~L$xqQ>Zm(`+gOIUv&@Pxb#l;FXPis=EPr4gfJ@yJ8( zON*01zKa2+9|AfUF`(Ar-{ydvzYq3=yvk;S3X5heQDn{5X@3V-wiu1t2nTSniW%tR zTE$G!7*;;ec|dmvHjtQVap|Zi!az)i6NKo(1UP9cK@8TVzQ$S`_j)hN5E*nOgiw9? zJpWKsGTFQtq}Fhra}n5rQ9;%U4~}R6j?LNhftkxUN8yRKwZG-@V2DJcQiD8~H*BMT z@K!|6gx!2`UWfS2Py;5R337Y<_o7p#!Y>7>U_oHnUI$QUGP0%Kci3wCcJJ|aHVkgt zUorlDtJm>BQW>&(szIFID$r25X(ioM!GWau>ON~j7HW1bx3k}`Gs+~B3<7*O%Moli z=(r$+#;HXBMhlStZ;>0mopyYg+j@ei3?d0w2Eu2MjQ?@+ z@17l%SHJjhtTAT*$sg{L2jY6M;Sj+cS6=!?B^9%}o)4~TSVzMFpI2+cuc9^*ZMi$}zFA8(0nyeHaQGKko=ABp^x` zs4`e8SG)&KWTY_>rUc+(dmWp3?x4f)oebmqm+U_FD8qY&B1vQLs8BS<*fdb-~7hzyg;G{8z~H zxqQIb7x-kwC>XTiSXClsNX%g(*j6uZGXpI1VVaVGr*aRr#f8EzkR_5p@nI&SC`IhL zjqb_Z^r`;Oi-wDbWv(~93F^_i4hyY8-dcy&;xL32zche|_;YE1qIG2UUmGEBd-5sE zXtGQ2E-W^?^{N;wc`f&+?e`f~3;C6GXxYhVVUy94Q{`+KXXG>R)|mfBGUp&*Jlfj9 z=a-ZbU+T^dqpo%ZeqSJHAcgbYgMU~kd>;Hc?>L(?J$EN##yw-H%WG-NrJi|#LWoeI zvemBg^YP%h2GJ?oI+LyWSZn!4dte37U_~qIpj>_sKeq1XB>S94QDSFS&JwRdAV}dX zr35vu4{D4I`4q`{|EhAhRj>bQ2!FV1W+Y=yTT%B8%p@G%?$t#B{wlo{iy?*s1(gQf zHA0ZcLv@_>sF-LgyYzOvKFe_FWpr$SYxDF!>h0$^D(V~@KHA%=eI>O&k0@uKcWx%PIst~co0FKau`kowCVQ7 zwz>MYVVFXG?@V9bchdC+glYiv9Wmn?Dvp+dpX`Bxsm*gcf>-&_^M*sC+RdMJz#>T` zLz*cH9wyq-sx<$B(fqh|@ajkgt*pp3W&KGLt4@oGuNI2D{k{vU5!+saa)QfJ355{K z;={Bfw+i(r6ez-lUps_#IbAI+C(e@rRDeo&05&T}{~5=%)H zf_yj?e2!vl#d$!=)9oQv8PnKTg*6ems}Hr-Dge&MyTqw5c_A;BJ!1?k(gzArt+Q(B zM&3qYRQsWul#=n^%eT}3hiYpTk=zb1v5mZU!}J%ib^6sT#vasb@0Hw{pL)oM3HunD zN&_c83M&QC>PJNs}q!2001!T^AVa@UennEv`Ng?#D1P+nv7gQ=l*4)hV5bt3j% z+z7uc^e{Y=3*gCMWT`QDAcuRqy|13wgswVqmE83ksqsi<1}KJ68)>@Do{HZy(Sgp89&$3E=dwB>d z0jhxkPp|JXXl8alnRc@-o9}ADfQC`_w%nthe{vlJC2?!vISY<+b&gjG?JN3u6_bFR z<%?vSHDe(|3ijoNglAJbb{-tr`ex97WJB~4!^vsF%=-GTGr{k=E0t1_Us8QNv}f9GfJ-Gbh_;NymR3~{$hdA zTEWw&Vvwg0LNa5i?A3kH9HT-)l&Es;&H&VP!GeiA9^r*7B?T^lz_id^(u^3jVun_N zBnIlR&b!gBQN`7din)=ScLPD)$V^E|6f2qKa$r*)9EuP{1b!n=@?1d=)YQ`!-``rv zt!;BBIQDX`wg>am4?;4w+jJSfGI07}Ac)TU1Njg^cdfhMum4(in%_XcSejp7$k?P` zpEnRb`$ATBz~35nycrB=`0wX-_!+`m2XVgFqmukzUUjvo-3*veFdZ7eUrs>0zI9R^ zNH%LSa7HG(6O@ozDH4tdwJ-^q^;@^ZvmB>X9GAP9BYKYDZ}>G3IF;?Nu4*_LFr@GR z&;=7k6S{g)2;G1BsCv~-E2=#`NBlm$VxX^2_%K&^G3KyrynhHuLIb$Z@T5B0as!VFc%VJ4vNRgX(*nPF-K0FE+-{J!mEdWsUN^7!>WHw348!ARU zn;2lfI4reI2QqG1D0=v_KXi3{8glP?fE=mM+87N_3-dK?aLlc*I`uNv?1tqwFiTL4#fvHTBpSHe&im>9o18GvkHEVb_Yb^~>&Yvx-cEf0|_F;L~i%Vh2!W z5V=NCuq`$$0-Q`{#>PaA|NkL<^DAI(W?|&ciWQqVK{+N)h5s1puL^}25w}I82!OR) z9tuPBF=~QJ6b;8F8l|K28bv|@ksyW$CuWWOrsof;LPZ>tKl*OPPSXA@OJ^jHpGfd^ zwE#_Aar$CFp9dTx|w) z)Wk}%3B;>_+lIu0>}m+-fy+f?b;K=#tY%%%p&C_rYD zn8Gs--93o_ml7v!=)5}m&?98ck2y95&cT79$${n1j)LDCyqAB?eF`uZZ zi^?N~B4lu073ZT+V330G83`2MGBjzhwjG1{W;_~G-T@(3`>fpAd4N^~k4!c62NdAC zhEhSMz^Qggb{DA~8uItd-#@?feKfyG_BXnUkEH9JMT7CfrB|CqB?v;Aizzqrn3ls42Rd z|NEt^bPXVE#G7$0&#V&WhIc?yPTIbGYy+APIz9dLdu}@(q)~_%$#DJh*1gSIs1+?} z*`+smTiMzU$QnsOXOAGr2q&IFz`|bv5X72qZb%u+kFmlKEFyRw7XFszZ#@URjIqPPyzO9NDUotrK|E)cYSrxY-N7`XdB!QVbX+ks!+dr z!cPTSkPuG@nip1+JQ#fZTF0}?Ywkc8OuEj;Sk>5U>mA>1ubG5Mt1qN~E3gDSg`7jL zFMSzxU*YLFwH{NW?Nc@3Kq~OY%Yd0)>d35yTittlO;mk85Sr=PH_CDpSmSqji}K+` zN zR`&n?UqCw?SZQ2-L-DWUv;Odi$I9a%8XX_aDrkSQo@wp&^48~6Xs0FEA6Q;oH~Cdv zbJfI~U0qPHLL+;@8<=QRWC*DbfbQV&NdF6+o_luj@ZbKnU20g5VPhRAlrsNXj)Ik=8d$3++FDj&e8giiOqw*44y%gbX?Ajo`T~prM;c zuE#wLY7kq*)^r65%P!<#QfYwa2WTAB#Gs|eCS(;0ENuu%C!Rj8-|ldG)vC8{Wr3%c z#|4G`0kfC##a(cd1v;f@UL|K{aBMz#Y!a`&P?#g0%h{HrpIrah?jW=KJ4kW7v4vNi z0g}FeoZT1B6*~8XiL?4Y^bO?o{e(;GkolyR#m@_F;tP!K?P+n}0)KtTHTSM^exv{e zHdg4pn6o+u*Du$!EucRYoA+;9Q&?U;r_0{C$yNM^@74f*lj`fcrehD%>i0mf~1>z!r_OA1x~{3VtrY38L;JcLwm zg8AHi0s!U&v&rj<7A|VB1*<(hL6~9)-`e|jgCCOCosm!nm-L%Drl0XNpOYN+Y$ptn zxCsOc?*kbsgjU&_XY%fs4PMEBnxH4sJ8i2a5a;$pq#;&#U>0=s^nfHhdo@=y|H0`R zC3?0rF3xGcH4c-m`|DWFT)AjDMpW#g53Hj|k#H^A&Imq@!g_2B9B~A|jhuUFdsZP) zL4XCiGyvb>-U@|L_vO}YjhH(cF_F}H!a_dgP+rN0nkf$&M3|>^mLgk%uODI^YH-MJ zI7H@@)o`Ro$UqkZv9wwtUfd9NeUl9frG-G3N=lhnKmG;4F~Hjn9YjRcEzna2Lljbj zTjyQt&MIf^WDV66hAht8pcYBSzXd&p_Q`DO?k8CY4uSu=7)E27|Q&DfqV zU(*?CwoVAcw6W8)$Iq!qLt2jmM`2+#1f7ufdoc;(qNv}D9HAOQ*%rxAoJ?QW7HzYA zg>>?)W>wRnhPd56R&srcd2QwIaDc-tosOVo*G1jck?eiDpNr!p!Lk&-G~lG8pfM9p zIO+ERYO^KBa(|#O;J#9{0{&ism+YqJVSmp1-(8&u@k|3p2Eu0nT(Lp$wwPVn8R_Y@>j$0~XAKUY zJX&GAtv%hTP6iL}@&Ob@jZc=btuNwOLNE!CYzUZYNCYC(cAyC?sXahOfG*&WX`5(- zO|(r2;fmAYH-+ZMyX`%oo7F!;@p@|)d8A^Im$-;{J_hCMzS6}!*; z%i)x;4-eHNn)O^&Gy2Q=EOzb$-$wKHx%vEsmpgvuGCO?5l3{^^NeEn{bRrjZDqBFM zlEz-7h_04%VdrOt%UfIPDyrH|vMNH)mb*2ze3$sQm5o#_jP`c*6>eCGg4-jif4l$a z@M5iKX(VNNw(S)t=ylI3C!YaOR5CZ%?prmvx$1n_i^a?O^NW7@yeA2b_8P;dGuI|0 zwJlA%FMc}^zCzfLy!={G^54G5*ZU&B9gV63u{Gd%XaC!`@%fTB z`E$<$7S1Y9&HY=lLwTFKgg9IYJx~)w+(^8nRp+Ai0?Q^!@c#7Fq{9 zy)gtJ48>sT2hu59;`lRg4i&=EzUq5l_?f2&M8DDe)J&WfgYr0OgOZ+*Q8){GqlECW zignWe$&`sjfnx(8(x4de5gb%4;Am;FwBHZA_$e~SYXidmi&?d5m6R_HiRlAhjG*%( z5o233%2K2#l9EKr zwHDpN3gwM1eq;@{znfPooYcUG%+8<)$#zPQZyGtYKdXB4Om9H7`CHL5*@D(J&`u3d zHGo$WNVees*nySWMW4-&1tb)G=@zWsd^C-wUeCNOWr{;y4XReYGZXg-$(lw-I4tM| zv4SpH=%tTtU!~DpBf!EV3Z}!L4sq>H4G(zziAB&6uZou^8K6D4wx2711(yWiDDvP= z`0d2V-;cet^?!p7TNYvm+iI{5#)Lw@{c{4?)CV1ddlP~w(6#{8^B5cH3ur6ArK@F6 zG>2YR^Ex1KCL1_M>x|ACs!a}%iE{$dw4R1HoO;z$or*k3=|YTjK~DYeM6los!+h*4e+<1VihTJwywf8}In;7qEoO z*`G}}7Tlj$|5^f<2ppolEXn=0C(6?MNejnyr7RrA2vl4EXBvU82DxiFL@Ox$t8GP$ zcYmKdN{EG6sS3I5b1P{txZ*)A1!)oOiNdk3Z@~1-EfiQ~5dhvy9Eh^fOpgCqS{zLsgyX>d-^%jJg9Kdv>m{` z;i246+0$IvB3c{~Wt#?_TYsBX?F`;c=puz8V?fKR7}VR=NOQV~&>HM1Mo~_Pow#(6s{_XQ;}{ zXe*@}mzJjJ9UbD$Pw_5Im4+r%wDm23%Jc0+$hmO1dipKk4@SMe8Y#FcHTTSiSGFyf zFWy%a!HzTJ^DDc!n+tWrrw>MUfBszkw$SsjG6V2@Tblnn*S(uNH|IVc7BKx+!2DtL zg&;6D1*|g(n*8-NU_LEh8fjYGAe!oZeDh)L9wBSwSmy?{;mC<~krN@2;?l_W(x`Un zURq)3WA*3i2Id=`Oo92u7p8aH28gPzCZ2we3AO@9X&)EGNKZ;qC_-s8Q@OHMJ#9u< zcytUz5rGd&x8qupWz#{#t<-O)T~;+#HPJ+ZQ4JV>Z`%R0p8P1ZvNODQlST~GLL**Vixo%(vZv+b-){eT zMjXx@zdHDD352TIWma@Tn>GgyAZW^k0E#`4OJfnhnvzOescV(m_eHPoLC5owzx)cN zEq<`(lmD`d9Y^eC%xnhR)Zo7-j1y(V2{>51y;=en)tM5a;IuM)*e8%QsG4OZjS%;~ zhkbnjK%fV);J3D-+8JEMO5)QQ z(1-ypZv@Za+wJJT8y=-Xl*h`DJ>e)5NRFi4-qdi1O$Nsx+!T!+y|L0ZJAm~`^B}-cAs}f-TI%Lp zk4bj@{vQHcaCvWGXVvd9)#Pm5LSQ8VPz70Cq_@s+$J?ddEB7i{vMDmDN*IjN1Ff~@ zFSAUotIK)XieP{Oc!sAP6?)5Hn-220h8LgOW_dhKGpQ@WuCi|5+=9iGZ?ZnyDElnY zfwim8mRT0-C05%&(yp*j;}DCFvsGrrHvB0YgGlSIu;2}15D@t8z<<;Qk$gOch5%3< zv4XP?{OTAQOCHBCQgXhT%-9rvc_mIZ&C1Fu^^tYzU8@&`3bi{2KK!N-AING5+PT}b z$3hS?|GKGPf2v4d^5b^sFTctTzojm9Nu6F18Y&cJP!B<-)-38uKYX(CxVU&!j`yQk3hMC* z5r65cUdk&KQ5BAK-pWg=Q|LUddbp!~_GYf=()SZgZh4_(Qh&LKIn~LWyUG){HK=1S8unU-s<8<4eG+amoqO_qlQAFh8zGjST$%; zHTBKyXI)#Sc_c{wtqWD&X935UCtCbAHrJ;f_%(v+n)jDUL(1|bKp3`{tky}^ih(@| zF0*LZ0Bftm0{%SoyU9x(7oHrj2vG4gbS=b_!;ph!X;4x7Ihko+?d@Q-(Aiqr^XsOL zg}-NEK@t+9(7xS2z<+rlfBD0@stHy1<${L3sYK!Sp*z|LJC&YXh)r)i-R2&a!#rghpbZXA5C%MCFAAdqVbKyx8i#^k?3NM|w!~#sZ2Pg-Fg; zw=>m&^RdeI&4EdM2z2&Gt1+H*)6j>6or=j4ZLIc&Up-3j*cfTBfkdlV}| z3L`ET6ob2^EGH?kb#m2Pi{x$jmw|d1&8JOnfs`Jr5a5}Y?|ppV$gs;^xisH7mmz-b z_s0b06BZ1gf8$WQr_XdvuNSOr7SIi(dayj4{rv4(g?G!oA4REpF$~BU7A3JDzV+42 zw_QY-J|Xef6ik2t|Hh%ZNzN3LrtIkjr{o@{LazJ%XFeDdbhMKZn4jS2J7R4>30cOn zR_iQlsuG(pmvthEDVH2>mmd+>I@1{#u!8`41H?y`B?yTCNFqICM8Dp^b9B>ON&R1c z(Tll50mpMCuc^}c5Q#PvujUTpOg_%PS&Cf0XqGC(pylIyixtY=t3Q0ZckKAKVKf~9 z&p#x*3@EVkD9ho)&0W)g3fsC}S*xdADn%*txfZt*cyiTe&>AQK-4>vtZF`~A2n`!< z8uB|$Rwk8?kh~01QCbFA0+~jacV&vg|*slr;B{4}9hTn~{k23kwCq+tZ}l`jZo%R){8(L4^yLfff5o z{RN}b78AM$r6hq^xJ+4$ysRp@c>a8#_(TZrHC(SOOhK>H%sLEequ><`yG~Qzq zw{6%_uto!D(@UxWz!ZdQ*f>bm8>YPYJqPIs+@VoY?E<_F?7c*KDJ?Ba9$UYh**4e04DGRqm@won_kE44q6t%YAh9DxZQ-|5@3pews3uaLd9NGuBb(%_Md|wU0 zq|vtYUf=9XVagIrseX?b3WpcE8kmdwzTeDn%_z}t-=1X}R+E;+T@yX>LRmoOlQ>`P z8I&$q9YVhl0HZiKQ`@hT>>fUnUhLcE zzlG}JNG6az43Btbh-Q-9mx9zKK{?|}>aD}u(JPGB;?Tz)=}|QJFoqG@o}BWJ5X7i0 z-2vmw`#!gupSmav=vmQ1kvyRZH@z=2zYxYZB5;Ypaio* z)wmn?vMIwIll7`+Lkn+*PD~f9jP+Mx!$lS(V(4cgZ{2n(*b_FqX8nT)nJ$~8E=EnO z_kLCNe%a<1e)g0HpE%mCi6dhs%*HY z+P9DVk7kdTE>4Hn#;s(@=up}$ZMA8~mj~?Wu85!!9RFb6Gz76Oesjwj$Mvzg)w#F(O1#L$$l$=7mt(yzX6=s(Bg&l6)#c0SQ30fFNK? z#l|97tAM17X*+oz!qD*DTiH0#`I}6Wt@GOzHFtk>%gD70H+}HOGp*ga9C^|yyT)_r zDoq!TCpAmt#9MAp&3&mK$`5~78d?k7)uYVXPG+xPex*})5aMY zLjC1)`eK)Su}esASew42M*pmT0QDf3vHz6s_dEL;XBld08?K<8w@{1bl7(ZTzaFYD zOpC@#n6o;}@eQK+-qODL51tJnYgH41?l5H12W@n{#b089rjfrm+&2H>C-(IHW*< z1=|7{t|bhE15w=TfF-9&Q+TNiRd|^!;lyPb+6d4xc_l8*8%ld8?f`G+TsiEV@3wtU zZ^as9yS(*HfY;yd;6jB(6v!8~qS=q`x~>goYSA1ZHQQP_vLPIb05oeOV&Xn*n3C1% z({GUG1n)thg|ko@pa*!q9~}0Tfa@q{{nnJ1&oiFrZUY~I46cOES=6-!spBuuG@N?kzVp4&4Heo zo(h*;RYH*hlx2H*%9Eca^$&FTh}uMB67wGoQNQ*nDH)b%*R6|eT30!kQQ4$tEIJ<= zD!8=@1%?2?Xq2}AQWg&jB9lMQk5!7Rs#U8#SMY=tQOk;p^v(-3YoKmKD^c4{A_j;6 z`YyrFf<&VTEEs`pK`#Y1oIHs_KzxSkc1@615#{2)Lyh?Vq7nA=R3THg0P4s1pu4Ha zV|Om^vsc$dtA5>%j!r}YFNO@fvwEww^`U&7%N04*IaM+vL^L0lzK;K7cy_+i%Ueq3 z^_&1z5v3|m+lC5RUKK`5zg`dMEtp_h*7)|Z{(fN%mA|pF19RI*{0Dr09#-o-y#*A< zz{?j}RdX-f1Na;6(O{P0$jEfXj?K$NNb8yptLR{gawcOhy>@j?7ySA=D0nov-lgDUSLBQj_{i(my~J%A<+a3vgM;Qj;QzJHEiTb*PoFDgPL=AeO8PtTnBBZFmyzGtyK?Ve82PcQJ2wXQoj*%MxDXrEdXRQ0@cf|z zOsG!i37^S6%>Z0c{@j`T$)CK*XS~T1B8k+D*EZOm>-TY|z13g~qah_{b}nZQx^#XW zTxw~X`?oaWS!odZ1u*y-FM?j34=R0Dmu`zC3bprGowIE`UBGs*7GNnVS8Fb^jVz@h z4_bXs8>|GhHTXcBqie|H3M`3&O&A~)tH^)@j6py%&K%8wg|EeYVM=6udjJ?MYfgG5 zD}WiPHt^@Kr#bTgiV~zqK8Thj7V9(Ot+a_Sk)WI~R0`Pu>mfso-Y6&K_ME(MN4~3?=Zto5-f%HE4}gx+?0+E?|^tW$(pJWKy8M4VvbjbZ|>U%zxBc zgocF@lt`~-y6~w;*V-cJb{8abMnvNDRLi{_VV1_*OKEFT{NU{D% zG^A%JFges3z^+WwSV`{A+{ILm|sVK@!=bjjEV>LGy)-vJW8BJelDtDny*e_lGS z0S^lx(rg9?JD-a7yz%y!g-N(5QW|C=tV~oO1zX^?300 zh8;$$7M{CQ#JzV(;3yc;RXK3$K|u^i0L@|l)lYnAIud?$0p1eP`itOhkcgHlg`-u)9WMI| zdtHiQ4Hs*48=nYuY|!b|R&DBzEjUCDJl8sOD7@5A3C2+p21H;2vNG;Pc=rc!uEX3b-~4I^q8uC0eBW+04| z%XQCeZ7tjG!Uft6g60D)gblVG{?1+E45(DX(%}5DjoV&%Hp(nN3DL@KVxb7oI5t6Z z_~V`S=-e6uDpg>bz-hA9iRj;a$pDw=aG4F)T!S_kTpny1v90#ESOLkGSBK!N4U&nY zzq-m>-s(2-@R-hCL0mJSCuCs#ZK^0E{a1tKM?z}i@aNOKeWPIHsU|DelUmhZ53cj< zg(07esK_PC0{fnT(|Cw(zMjBLL=X+n>>C?tHk5LV7QksoeV;?7ot+qqf;>&C0TSnH zNaiD4a`EBk?ctJ8^J($i^g(TOE{Is@DTWQ5hM?I{yb6nU1O>)v;CB3umACujmYdKx zbXiS*%n}`A&#Fc~2+Es$-CAy+?H?8q_L8CjjsT}QiloK4u0goGKI5grfUDHlZ+qy6 zul2#KhgNwnygIgR2pXk+BN?_Yg}pqZ>11aZ>!i!kyM1+wxGB1>X$9}=9`~g>_hE@> z#KC>UTU~pys$y*MvHN^o&O&+4axrf{Vd}g7l^2DDJGsS?UtZ%6`5o~o-k`ZDBg3_} z;F;6t%c18DrUQn6y%|`XODH~Ok@)aY+^JS4Tiv*O8?9I)9;CGivYd-YD;z;+45ttvGI;o1fI46+pexr<*OFZv z!`E%yAnXb&Im)~R%!s4V)D+P)^t>{v(0Toa4Z}dWnR@P<*nU&bFW%`(&DmXHUtZ@% z&gVwdG(`TC-sYED-6g%Ql^^%4no&%;$SvI+Jpc9S+`p_mPaL*3w8}DKo}6qB39s8j!C;o67Tqx|15$)6+k6 zOH(Ct0A!0l8g=XFuFA-N9rUgdx?FA&NQqhXBzT~bDMFkMJZ~6wXYCrJ4^dS!xq7y) z^hAHYZ4DLY!7;2)HQ*|dg)CSRro~bio&>;+;DuJ3{9)juTT|7R#VO$*Jk>6M!$+7s zk!UZTN_X8>|E7fu{qIqey?y=uyr~SHLq=}hN-z0TFI9@yu|_Vfk%Y({cuP%tU-WYQ@CcD}1FVcqgiDE0#k zCW}v`3ujtO|Cf^b?_Bv!%v(xLs?m{D1xL_+w%&ld;NV&%{kix05+P4gk+(w#XmM?S z6NNhfoC>mt1^};OESpVe^Ge*ddMCGJYJ8vhxk?v1qqWeJEDeR!-)YXo^4o9bI-Xsc zgh|y*+}r-~ZaUZB3SmK7W(yn|hperUi$3!nr9F!fr;(&Ye9)4<)6Y_ifxKaV;M`pR zJaIRAs0P7vKw4?oe!;kB9JcGmQUlt2qRHrw3P++`&eLLEYwXwav2&jn zV_p718IT}-vxQxNN;IVN1>B&U06zeu+{o>yy4zL#CcFd(-HqFdHx^aHLk{LB@Js@; z5Qb1>Et(UCOxeTE42EjV;qs*&$D+Mu2aG%kAW6cVUMrgN;QF6E66@|`XCCi31yL5F z0BgVx)nAvx-;r;3KpxicrU{t(FI`^GN$m-N7PFnAl!IZ`KBB+@!zb5*{?f>Rpr>0^*9t9;EBMp+sRn>;`l<1x+Y&hcQXLqKF9eGN;LoR z(yxlLiZnauN=7hvdUPnj0WBLTP-~R1(6n{`0b-Tp=sguOaN6$;&OYk&7j%$AOS}v$lWR$fRjGM5eWMCShak_>p9X`mE7Kzb@izg`*RcWyTk%clKdtsdG z&;C+;*RXg^anTZ|Myu2|~ zTg#ihAzHqpxI8IZsI`cC)1Lj#WynX;)NcZ}pFM|5{B`KL);IYBMZZH~-oJkhb##N- z#vNp_SMvdj-4HmLg8c!**F|F^ZBy#aQ}H9zlIPF(AD*0UnLplYvWi*@=Rz_6x0_QXV%};wRp%@6j1nK`<@EP^lX!UVyz_?APTd)In zaQw%Q#n|B5o$~#0z2f54I*w;sz87~fm;uXx@qL>kGz&$zv{~1 zoz62{HRRWJeCp!Z_(c)mXU^45carlvhW45NRLWVj%emB+74p1uNUq}hW6tphTdCBP zKn`ZFgFM!Y$)E@7{a&EM9hzcdtG6=U|_1T@V)z`FH6p+GEiR9DW*G9#xmd8rMl-bM<*`g5FB!2OnJ8^SoW5n)xFRkc0XrQOB12GW ze)!G7*z5-!e;HD$yzlZSoU&5MGq485;W9R3Y&BpdkHM)*`4aw~iG}`&hTx*-Qw3We zXO_>jY_6=?Tsf%9o2ah`&%i+?t|hnJo}L(n$gunoqMvz=#pn1G-q>)Z5`g|d0lMr1 z)eyW6`1P)<*5w~d0J>vr&`1|o0T#fi?5%FE#wXMz?=}iWlG=V(KW?ixfdA@o8f*^1 z3R{qsE^SgxOHc1I%Hkp@peV92EA65!&yIMz4|tcBa+6mnZbWgF6hV-L!5gR;F@7V^ zzQ+8RuJq2OSg+tZC4Mu50&DX)U`PJvQZ)neFW@ypZv7W2?(J;7B*c1vKPO{B1p{GQ zG#|mnx4f>JxRL>CP}Hwli}BjDXMfrb{_zGYBS=Hc7lO^lrbRy#28xqTuixXb#Y-;H zpJPyuVAD54vsjumsWdnB9hm*1uV!#1iu!als-Q#jKHN~!~Hp`wiD|%wxwqrno zN|#b1@bUv;T_4(CE)}ZjcwtzHDCvagT7!jVBZG6kql;#?f0Nx14=qe$ro``g*ak?= zz>bgw!K#VlckzWu%;|@MWd(?`*5IaI!PZLk<>wu*&Tt?}e6rrrIIKdT z;R8vHPT?FGtreSPO{iHp!!8O^j!87M=W_!pt%5INZp&XhW^RCsX(@&w6ndyvKxQWv z@q}-J|0s^WBWObLI&AYPluYQj_-z;HT)<3KKm&)AJetd>D+z1}=#NL_Ksw}OQ83iP zlT8c!Z;*3hD+w;Y*lzN4BqL(*uaw&qKCq<#Uu1LK!}y|G)vGq+64Bh@nX@{(U8-3? z9j8GXOAboL7UFAkuvB5BWvpS;qj;QwZB2QLB=^*UN8f_0EiSu>O7B)`Pc<1Z{W-ED ztM*BY;if|b*{cd?Ltn2p(%rxBe2Zhjg$;RiLsfg0-WX5bPI)-|Uosmhd1BuYeNC5Z zNhMr7uv_=5TcpQb=dmys*WNGls_ru-?lVb!<7-3%7u-iY6sz#vl_6%5qs&1a>HBd= zx*8a*95V+;V*p@?FPs>0X->Q0N_D{5rFwN0t%jGyRp{EkU1jTt+wPE=o;_;wpIief z{r&v51#i@~x@enLpl7$1aPF>$v-rdgL7H{5`vR0T_jZO$awLN}a9oD^DI99VHiHn$ zVKf6p7x9!vblF+x7^L7j$Iu4g#a(bt69l#^u3lANLaEPJtIym&82RSNXqhD0W4(N& zXoN8a3{8K3#<2Q&^Zps%#Tn7ksA%bZ5aI<4#E?2h;Wnl8z>ugoo!5jq+2)H%(%@4uA zCJxUL!^f9-JA^3~ckhZEpfkr#F_#qp$07QvAetSjnp5TdkmGrUd&=Y{#Z?Wxe|p)0 zZQw{CN+Wo#D`CIalpcp;lyopQE3+xDFPROGsoS?gCA>=lC8ivhLNas?^p$c6Tu>CZ zVBk}qY2)QW#IA322E4I6tV&^W$=td(QY4y56t+R`v^hro{76Y>&-^df&S!siPS@97 z5@fbT{e;cl35Y>eO*U8APrF!NhV(H(`T@bUNFE^;1BNN-Z9ePtGxJNHY)DNqAkw$U z&>;qlsCsUxTUzRq+DAbRXFBK}_RD*m=Avbls*FXEXhdlnl>!KKu(db|bA^MTAh^D2uip{(W>{mwXD6!e zd*sY_r4P^j{Pzow6lXaao2)+FA%?}k%#^uU4&H%P^F8GWfQS-YJQ>p>0}rvpYO*Ie z%jtMo;KYHdUvf+1;;3bA#aJR(YFw$mwNbJ&La7P9(4Z~7wokl*@%X=j{+7+5p8LMv zUBfQq(*a}yK2!{rSnzOf=x=4;OO?E2rfP8L*L9*RDF(9Em#wMt==9ALdFVk&@^9Q$ z#~lCIvmmp{@OJul2!vB`wyZgau*vJ@r&OY2Y4C6&(V%73<{VvXT~KF04Tg3(Y%7|L zl#PB=iBaAw)eYzb?p+s)HJe@;J`qVUz^Xv)v=sIVO%7O<7!3R&(&lYFE5v5$ zgKEk<$zf!j-PyiwS2Qf4T?GDV70@U$a=@tLQSy!|aY~`xYj82hPb|C_K7oEm6%obc)6ZtcRn;)w4R-)UY1P^FcHs1y$n0iQH zQNh)PkT{{148lJwLvn#-_4%guyRG{IXRQrbeCid4dA)j>E8%5R`IW(DdQT7B+CQj^ zSYQ8Vqw?Q}&B8nfa$4@kfCo&U`0}osO^k;2W}+wK49zaThZ*&Jdu@m)$E6l zZjpC$THfO$L@OsY4Y5jt-oR^uzP^{|PxHK&x^kB1Twl$(n)c6_3~y255V#|8wyrem zM@Ke&-QND;%+ZYw?Jpq2^CH)5WR2VDF|gKu&1);W;8|r@g2(HCaYnU?ODOV(_&UHU z@Tz#B^g;{8&sa}8Tq4^a&v`U`X8NA%*|4e7sAoDBgLduPKR(~G)&%I|#}#3EUAO!t zVCiRo)QP>=wgj~~*@plARl5_WV9De|wFQA{z{@c4mpYH$zL8$hbZON0(khtb#{L8- zWSnz;N2gmzt4ZaQNo2oqlw?}9)0;B80stRUQM-JsqQPP=p84x4^Sm(cV0c?dc-sn# z+57wUU9DIrc3b-9Ht-QN(WM`d)BG^ud3E1D*CyYXQ{hwrW7^vb8+*``r7 z(!X>?)WkaGw@Q(?(tRG>v12*oioE$|-pp4Wvq1n-H2tTK7@g3P(Y1I1>qb zcXh#aiBOZu=RR`zy{u&L2mCtqaau}GXHKjOk1q`eX#I$2F-d*7P+ip3cTqdlA8%mW zNZ&&7kYO>j*nFG{oGNyt=K56V)U<50L3i1Z@Sum`RAP;ix*6uGxf2smv$Vtat?59W zdhkqkF(krE*_vw;y1IfxzLkm3!P<&Bw~u+;_+aR7TWHQTSX2#cipgxs1I)GC5rga0 zuip1gkhlKL&K3lEF7W*g))EmepA;6rWS&t_UirxBnzDwShDH;WyAkFg5@Tu$G+=At z+3?e@YWn-8=DUy2*$hm5BS{FTf^vIw3@Rqk-^wa|4nTlIfP=T8bCi|xN=8QVZo|bx z<;wk=pVAo=L{7!%2=t)QwYsP~_2U0C_;yLGN%BezazSIjZo>!$TsFvjXxNt10S_&8 z(voG5HVW>OF}N-&_5iGuRSqCH6)4jvc5ca8{E%zf-{Fhv!txR5U{R6NKpt({sOdsY z$xE9o&k^rZU#wP-5JiR@^n6ybQ_sVd$lb``Q|Vjmuy_cEY4pdDa!-f*B{Yh|mlfwf z14qgQo<$|vO@jmV-rS56`z^0M06^gwyw5Jx8b?kUn=ogN=j{OOD18f*wSqo@Feo%@ z`TnxtVL@laNaw2&ld6Xfx;1Z=xhM@8BM8~3s5X)1Aj^$|Yh*oC3PNLgo3{M(mvbYg zYkMe(_dKFe42ZKDkeX`B2INx zr9V1^;tOmcoGQZt%`x``Un@kiem_o)RzsfBG_WVwhNduQce^dOlLkU9w>g3rtI$&F zs+9+gS_bF{_@XS`YZ2o7+Lh6D!3H~%D_w4eNhGHvZ+dmrLGL!xn+F+yAJx0?X%f5JkOU0>9Cp|4+(t z5VOuTcu9X#@Hv8P6M}~!fFT!TAwwph4H~IO0Ts;9LZM}#@$L@>=XLPTOTYWN#dl>& zOzx!Zl<%&J?=l=SSJT$)T2|dE!IK#9r8)QRA!G#iz$(}2KbQ8qI?L;gE3MC-$USCR z^LLU#>T1MV*G8>4j2=egc0Kh|lMwUAUGk@(;14kMBQ^sSbHNOsX|huA$k7Fl2D9=3Vwj*zLP=TGJ$FSf|%Z zd!?5)x=(JDZoa^c|LhxLtI_or+X%%*ly@E-`smX|L-cYXvg;1*%q-)f#+wnEGCXH z=XIE&ohQV@ZashA?Hn^p!_DtkD|6I0>St$^ zq*Pk(^{FOS?t7biL_z&xE9*8XFf=S9Q?C+9&%v3v5Rv(`|8`Tr|r-&r-ab87%=H3R#T;Q83nE0@sHv@ z840oL0zEHz=SCLvK3;iYY)pmK zFw@WMUnuSHm%)MqhE1?)ghA-e>V{-#&-}trRmV_IA93+ zN|shgjm_OBLB4(qi+$zduzbb&Vhc&X%doDKsR(3z*y@@b)&-*JC zAa*hX>8}AWR!@S8V*Upg{o`ezu`OO16IYE*jff_)c5;+83zJ}sQ-Q|qL`sY$a01|U z!~YLLB#%Hhu>F&>3r{)+3a%4s>TT-b#3rDj=s8eu+L?c32{&Uvx6Qr*wdV+xChUJ| z(XzS9!qrR#2gr52Jz^Do%@DUyE%bfPgz?zbPCAnMT{}CY%)ay0TEA0d17N2@H(olh z+njEGdVfMbBv)8$%+mzO70rRePgE zB*~n{#BF8}fKUY&7c8Hpaos@sR8ucczTT9D^zefQrl0K2O1av=ECNm*t3Ta$fY%sp+FNvZ37%1O`ww1_z3)mML_|N0r<#aZMlL=9*3WGKUwS6o)yc zt|p!pj=c=&t*?64z~v?fxVt|Pq<7h7>MCit+SEI$#wgo*aM*@v-cUZM@EPHja>3e2 zQaTv+^N8B~e^=FneQNa@n(uXWHCgtz4>ikc8eWe!GE4OAypZ~S^yTP}@gE15ejId@ zGUVWnB?ctWf1kU6(3cLxp1Q=UzswgxE;2Z>Jr`^6&a}Y3Cf(OCp z&x%Yzd9iOk@AEuwDT4>N#>Fc)avi~_m03QJnDw@$mXja^c{ z2J!Bx`Uq}`v*52rz+9ctD~44gT$_|qY42b3fx(-Up0{pZD)uat*6bV+S`T*@h;di#Jl+UNEK>s;T;hKdpnN@ zw{|UzR-O+Us~IilEk3jes|bm>st%{^mW>6z~Vj*#S=>rg+KELzOi*A*GjL?jR&ZKC6 z8f375H!r}ZWAHR8&HyS-AgsgYlMU#=E@d!;V7^bqA$Z6{f-4D2!NajkVUQnq&4aVC z6J;k2!onxpZY2aqIeO|#|6Pq-R*YKKD>eNA2JEdTE<7oG9b5q1MX=bdDN5p_W4gDy z19dS|oKa301hA_eb zC{2NB4VF6eXw0GgNIqY-eRS6B6jX@%ZgX~&>8#So zJLw6^1QKltsu$}p+8HtHnK%BL&Ca5`fy<-KfsRaac=NyYeR{U*Jbl>O23Bk>Ylskn zG9U$~YZNG^jp7b}TUHl!F)A9w?z;c?L-X zZMG7fFtD9amBs>(pOPNku9x=o9JMxcOOs&Yx4`q(d`oF<; z9U^d(6v#Bh*$Dd{tBq5pbCeLW0hqfX76FsUm#8NvAy8pRBuA&bS}rw@_cZ~3DD0;+Lj$_fX)!yi8%dw=Yos~dam`DJHnqg>TXhz*YJ z%Wv|h&g9ShmcLk^zkEiKH)yYW{MA?=WQ%eZTEQyTU^a>uXIU7RJnblQZpp70O;p}h za=u%jfNSzN_L<=I<)o|K%DtGQ*04+TXMkIff2r zb1%)v!s0%bfYr!uvSlfdQCv&gnj*vJj~)AGS6j^V=Pb+Sgp16?Zr#H0x}y<;V3{~t zHj*rSaFeK@MPcc&@=6%^*<@EI1`1trh#@VQbkV~EFvsGjB|NjPj^K6?Xahv5!0Pj6HkE5 zw92T`CI8^r^(K)&e|0UqMWtN&s+GU%!hSuSN%7LS;_^@Z<%n><+KbjKSzB&<>!&MO z>8Eu-A6t3L$xlzC35k|U5Tm!GNBM-e+vi(u-_~pszMbjFS!zdL4Zd6lsjFO)ij|1?uRCKXHeR)tlsuw12|56c@lGhKM^eo&N#n5Sg+hUKWB>K|? zfCr$+3v7V231O;62)+xQQx#x-yI$Z=@c??P5U~~58r8EjD0pFg>e_@kgJk%z`wy-+ ziKJo^4k{}>3m%3S20@20DQ2@|w- zV8($J+6%r2Wb3tLp>)pBhCZqz>}i8akx-9BU=5K7NWIlXZ4CrU0*NH3p!Nin9?rn} zvv#^cfq~;-Ju&;#ahDv&VNg(5J6G3?jc7>gdv5Ve^ioA~^)R}4hK#_bNY6kj8rTW| z8KO~e9pVo#$!S3X05}oAT6|A6!ZOtOwrB$!L9pp{G09T{(r*wAc+WVyW%N})m$%q% zk%AMZHx-i#VkvTVsRh+su>ZMDheNV!zAD=yggdm*@f$=Hgf^^1Z+VznxtvEGMpl+& z)qA~x5(NwK0p2)jY&vS+khgA~BLV;zR@hnYwqjeFb%Yr3udcjr89bO>>&t_`TNw@P zvU_wr$ve@2e&7oV;9)y=FomU2wL?{X83L8ZkMguVg{gel0m;`uFjoN(b%|h9fYlCx zgr@lnbiK3@9Q}Rf%!HIFnt2%g$eaXkkg`v-oH&uymjd9&r$? z`Xc@+6N}z+QgzQHLsk~4!Rt1~`5LupdukBCy`V-P+E^KR<-qFSk+pafaV=IAk%3P! z>!jDGJ`uJ6xY8O3g|v z1e?fF9Rrqp4XpX1*{fIdNWw#p3LI?#MJsc+_v;bkVk6AjwQCWw2jHTJ2wl1HiSyNk zs&SJ|{xPvhD0wURH>dE)*&yFQh|oYgUDP5J(z$^{`NvzF_0Wp4~^43vh@mmW{@v@zBTs4=JjnJZ9xfmDHZ?>u29@xViK- zeaP+SpYC%z+@{y`{rW$S&IB&z{14;5na1o4#WccX(2T}iOl2!VQ=3d8#4ZX=x;7@{ zNJ%wmq9{geN!Pk+vFV@*>5z16rCm|et)h@hrTh9n^WWFLcGqjEX^!vrb3D)c!Fmk2 zIU#?g`S!G60M&iA$Y|`1>Dahwy-$0?*2)*%azjHDOJUm&*VMkVJF%D%p%+1v$iJPu zDcGFEoJCS6aXh2dL`k~hAQENeJ!g~{Rn7nD&jPEsLi_Rpp9aKGJUw>H!s;e(nTCvN zeKDl$`mW7SB0C&!RJf`Kk~S|>F0Ce9kM=G$?Y(2_HKs@tZ;gOYnK^jPMa+glT@CfR zQpZrZF2;MYHlL}Rl$>1dFqz%tm$GF2@VhUSQ3HdQwX!BWnkGDQK3~dp-Vifw`-dla z7E29IU!FhNmpgGu2@CSOxBKiThzJ_$8nCbO8BG`sP8biw6s`J9Ty<=@o0H8eWAFp~ zihshQxZbaN{r==6n>hdQYM*|Pj;wPEuq*=+Ib=;hbG`9a-JO+B6pG(sNUZf zv8w-IE}XQ(9T+GgDrBb8!SN{4zp73M(-Pjib-=pS-3VE_DABV%``9uA>w=zZMIO1e zE3*F?ocuiFQB{Z1RymQQHP&c4dB=49sWxfS`Smtizg#Qw%K2=a`#a)>0c-1qh~EF> zQ5Z#5c6CM0WnX%oQ62B~&%nDx&)7T;G*w-0h%#~pu#Uh`MN``|7_-Sd!w7FfNI`JO z&87?T<+>&EnN~~%ED(zNdWGpaZ-l@;qU#pUwvbT{`-MngV~y_woM{zOTj! zTwk%zl_F9hw~hymKYEBPPkWIpRb8nJgNjM2D^(>ET(lA%JTXw*Jc!n}uEU0bqOhbn zvV+V-Y^!zGJa{#cC@OfW96G~X;!zV>TxAn)+%pqM+HHO#JF&Nq#2>dJLOkceRw_UY zp$lAKFIg%gghF9pJe{5Ff1Zxc_O_!be#X=U0tBNP(z!e5_1oM=YJA39f&sVMRG!QlUa? zFf?H-D|g&p{a%J1F9=`>70?6gI7C=5g<8{f=(OkQK^KRvSy1hoc3sLDvUa8;KLHRd zD9l;>VwMw$iESIw!C>vfx?K(M-Y~9=U$Dg}oAi(u&YZ^9#4&{=<~)&;PHgit?-8wk zS27Wq#6#xVk`k(Rm_UdGQE8sw1BDyN6A%%)DmU7J9Hx-_1m`IowVA1F(|6>F1S}ow z(Qrx<+Q*(!N>x^lqi}`rK`0RjEz2IY-i&grU@_YEN|ldYm6{h3Y_;w}-)YYuLk#yI zbqP;Ka*RnXI^OHJk1TzO^%;2@Jue?cXXVAzmoyzxi~c2nqmju~@5O;;ZByxai@&6}j8eNsR~)yPHFxlubD!9d zoHu=$ee1i2g9&5nUq$(GwvD>Hk3K=hQHmFdV9LYuj(ncGzO7-M=`WORBWngGRp&w? zE@4QddSquudqa*iZ(s9N2pt_6SO-XV-Fg;op+_Z1h7=mbJi?hFd1+o;m|uMHw%rcz zxo1<`U#U?*Yxm@T3F|sFGanVX z&~;rOcchr^JanqG%1$0>b4?(Pb-tkii>~Ys8yCjPrw`lQNE6hqN6 zvD3z5V&BpF;c0SZsn(17>yNHygE_;0Tl|$lkutEFwJau^KdDN*e~NqS{?@+Xv8tr? z<2fhXwEBxLnD*b_R<}oNcmSLE@SW|2 z_s81K8+7-_caNWP7@wt#sQ7V9tLN4nL~hh)|M>U9y3Z?edrP}sbi{8mZM#|>`+T6F zWag#|Kl%FlW;PD|@SGd>V}It2RgZEfMslGl@WE;HG$Uj0T_x)mI^eA5kL=4v%3trZ zb)5=^FRPS{B(^ltbGr+UwRnteF;V8_CkNCj7A$pKQT;stVgkf5_3v;&u zQMRch?juIjUh;o$?-d-+9*I~rcKlBZ=frRiU=#`s+v@R*&u*Cmu(pki#^g_jD5a#sdK_yqy+%bs+#S2bCg~ZHjv(Q{G>{T07 zYEFF^293k33ET zmq*_`RRyF(qV29#wq03+jj+>P8UB(m5sfa;^Ip|$^U|uh&`*hQ^IRjT3c&={q(q2` zFufV5@ExB#eVL^7x+{cvZZ(rYH0exLs-vV#l3Ea#OAht0reQV-aio9+RP3>Zfoae3 z;k{tgeaq!yM;W9AP@hnK(6as*Kt?cM2Il zoibUQqk3cYw2u0nFU~NT(}fe+Va`);jQZD~_BTH;dT?H`WM;IRKCowqF;S&D<>5V8 zQcjt7pyh2hmz}!hoNT+qvlV!lj$?u6f~6!9s&ni)8KPefo8>j+23PZxFQ$+s4LP^= zc!9QM%U*cxv}3Jm{wujKl9S7=wjf=@1lpcih^^S3rF8`ZrPWu)bDHf<~T^NJ7J6b-pUc+{EQ6CW2`+4hD@ zr|i=D2VVVepFPg)v(FvM3K-f1_jx52-@n%w&S@xVWgj%LcU>%htZ8krZ4R8KIw0BI&#;|};qTioTVnXp3L$3vw#8qD&u)n6Fa31K*p|Z{YpPk_(x;?V` zP=-K3zy%I)VS$T2l`d1ZcC$I2rgi(Oj@LHU41a1G3I`?XbWKg;28gRpwY{@{@yY(| z``v#1RaKVH=~C>X?c~YH$x7WPCK?mT)&9xV>jEb75xtXnrqpOSO>6jS!fGG{a3ZT#tK5+=dJA2iZ%8^0-OI( zk>9sXS|&M<52TJu9ya3=9N(ndATESBIWY0nKv)NLKn7ajHq4 znPXA0Za8$?gN%2zRvZ#@H)|TsXh;v7bY!V|mJ&1Nt|xy_v0|}+S%?)c0neijDV?Aw zXilmuI2*0Gp`&y(<{W~A6$Pj(k(7&~xkc15%Dz8MIrp_Tw)L?Y7 zwesEjH$3=xdI)n71s7-yHM$h@TT}}yz9>m{RhmYywJ{Ku^RT^SkaaG(rC&`Y>8O}f z9j!$KR|-RiFkLrvMcCb{S_nA&M}g)>#Mdfb&si&>;+)t6aD<0BT^)^Gx{bZ@SzS+d z-F8mo5#J;lEWFbck&v(-q;u>Olddh<);a%MZbMzpxWm|c2Rb7n&qg~{93MjgfX&0r zav3`OS4L-F*+ZgjI(GF6I7ff&AgpMC<fJ~^uS5{80oM!vcJ#!jR3pU^QgX??L_YE&*| zA)neca*CDqQbyJmKuVlW*;t)(dDB&fIT@LtAHc+S4%|v8c(j|(I(C2J?cA(`8_}G6 z>qBkzK@B2MjqIe2##$greR)icAP)u4$yi)}>U z=fR0cKx4p)DW!<)owql~=l&U|4V#FjK&V(=gG8=_k6LH+2QP`R-h4sLJim~m12`2UUHy%7$Lp^}ev>~M zv`TmSFZ)Mzo5%|BeyI32#V#dy>t342RQH8x{bW4E9yo9z%G>14WSr{W&ub0Lv||>s zc9(6t{k3jV@vsiAL(nKxW~m^anHuUA0dOP9oXTKIHH1r5X?0{u@tb{Jt@qyzgW2)f z$mbGl2S(lv)!v_?;s%4or`LU=H=#uyFAA85%53ngIGzz({`~ddxy`kQ(|uSM45vqz z-=#36sju8OuD!SP`1!c|*U9rDE=u+54m~@NQsfG}2?l)GUs?eku5eH^+*lQHJy^(= zSshCZgIlM)ZE1lo|{%u7aK$HQ4H&e!MqU9f4EysXV_4ppOK;+%uGZUNI1~F2|zoXKxJ-z5wlqW+fdt!u8$`+flY`xnZv!R zJ@a+9#jl-Me6-iHsXwl%C){B&JYjT7!s*iT%-G!Su|xYZJs<2>b9V!_-UPcSA8+p; zr>{(2P*V0sD@`Y^0j_0lbSbXWDWhsj6mwy%LKVzcG#Oq(_bA)nIvfKg_uX$eyCEUb zlU1wpb*oX+P%A=~(U7;Fed9L%wqm>`IkVwrTNLOIIbYd1y$Bjn+tBihX>WVLa67!t z2gax64q5wmRQvah)r`jXK1s^S2gGL8MD41{ycuV^9VR;+5K3eiu3ISyzbkgvxk`mP zp3Q&-9x?P*=~pSJhk|ez`YeX@o2tpD@kJE)nC$a$*79m#W=Gz%BRj9npDNo*@i?^T zc9}9c>7Q2%M!pYMRek-iJwp_vhlF5f)#RT;a>p*^t~WORJnBDp)3PnKLPc93G>adc=WgSSq17%{*ECYm#Z}PScsT%cD!i zfo|w5d(vQ+HGIA!w-p1^SqHlAb!WFXzWvoP3`-$80~IGi(Wt3;l5nX(Fpm7^x#Ob& z-tDK)M2&WturHoW+__AwLS?6tf=E^@ncfU%lS&RU8Y{+rRE$L@jEDB8DXdU zF=mb@{?bW{ed_{xnh{)`q|6CKTHp~gba*VhKu85=@xlmhDlZR*6JIIn5|Hzt@lhB* z?fUt}7CY^8I19;4YpUkWIO820qQuK_x|>$Tu{o?IEH)zIDMCXyQLtoVpp<05>l?oj zk}E!v$_OScW@bvua}kVs;(NM*+%#@*G9}2#sG#7(Y3(x=()76USZF)>Z`uK~$$GzOlk$E@{ib6$;xNM28Qc;n1-Z(f4R5tgiygB`n}rM4dAR+rcUMYR?ehz!X75>_6y(b^B()+L7yv` zz8_yLxc%>OpC15CUdSEJ%I%Y)3HkQyQhDXUs)Tj&z1zBoR%08F<8sEzK%EPEqG_du z(bMl17u=1^uiG#&b7!;gZr)>p<$ zoo9L-v}Z1hmCwJ6fIW|p?T6pl85$W449>8NIg;Bizp&w>;}zffR=`oe@uV(m%o$$i z^wV^$Fbur;Gf#9g@%2HdL3`#L9UM5Cn~||5!-|Q4k3Jxn|94~no(aVZ21{Y7O6Q4E za(&R zk?#}hM3!pDKCsi8pIug(Gc@RbG`r)G$%f8rrk{{$ckMvSYlnPYj|w+~tj@0eQ2hWM zHhj%=Sot5LZ{jmfoN)3SDeGCf$lldeXv5Zy#Y%bwFPLZLZ29@achTV!IFJYLG~x{J zd>4AncQgtB?A&izIeoqdKD|HC37!4X@!3a_6gav&*c(sh$O5d*5SF@XGR!`~t1{eZ zq7z=Gqev{u{kkH%ez$+g?&+;x%T86pK9T)tli#~d;<9$6Fm;YpP}#rK62)@pB*Q>b zjzl~Il_v$p+fV}QlnQdf2pwmDIkCZ}aFA-bSowZ~NR&j)<17%;#DTn(k99&?tVicy z7g?KR`h|WlaOXZpAOtO=e>-`)$+sO#%cg9kjpRdMaq0T(d>er%h{0JoGm6f|7T-xg z+*qO7;$MgnKWKU`Jw%I74aR(s9hehjRs2HA3tS|StG61*t@RtZU-7gb@0C{)+XvX% z#f(Ome%o>=dDFvJrsI{SSl-MRD2Mq*(YphnM7gqhPw>ES#8rm2C-x;vPp(l*u8 z)G_`wlZwPUX>^T zsk}b0;zfPw*`~pXyn(b%lkOLfz4pr&TfwY`B+y{1Fvx84K(<|EXZ>=kk;CLQ)4@Ki z-axGv2WI#+WmX;EoD>tIDoOPrxP4Z+=R-&VenMb*bc3J^}+b;lq*md zZ<&haEuS0&hyaP|xZO33*Af~gB zjBzY)4Jn8~_g?>3OitUcdl!|s6jHZOwIT;@H8($(rlFaCUFTT$s%F0undBu)8^^6w zjj&wz6L#Q4TQm=F)_G-pPGGN51FxnEmOdTGaG$1smCwvCW*QdCWQ7a221$sT?Q^rX zIS-jQ6TpZF${ufJ=uZ$+X-A}{(M?2%u}gvc}}^Nsf}Yimi+ZwOjwX5$n@ z=n!GX1I$|E_xtDST#0lS2~{N$4enm1h!Q$?Z~d#0167k8@e*9(Fq^z6RwZV;lc#KG zDM@&#mb+zFeKD1+Qmg>fMU8rg5|nn!OmgfFuaY~*UuE$=1aZ*0sdsm#G(X?}_U-Qv z)b-63vch~cUaT;S)%o?~D?V1O_>?D-U{EAMQHL<`)H2>^c>b!d^6kUy}UB}Sm<#T zlOmro`_K6XPuuhw{g~S(Htd<(vxU5c72;HD+?6!GHSu5hku#^7`sX~E_U1oGx@WNo zZ7{c0X+hpL}=6=MTO$EwiNt`6s{e5^|mrhC{kL(_O5E75`P5JW)N z2O%~jf9W24;zn(?rzI~rVVGb?gPeue%ZO<>oxzjDF3ne$C*u@b)D6*YbpmDpt&m8HYD9Pl8meZSevVE zN-HCH`sFSd^(xOs%*UumpvB3>pBLqDAqH#5>gCD_=S;&EdLZ3=f%qC`=6LO{4H;7V}P_t4erF&0!{II){jL0eRxT)Ixz3S*FSQbCOdV+k#v(=}LSaPr=vdouIif0=Z zav;6nEKI!r-tNfLp7SX~=-=uq#>9VCEeB13=DBos>TIlTfE?3Gq$Z=yo7@ z$MH)t_r=?%lH3biFwp-csK9J~v#c(FwAcg~*OsYP^0Z&q?pm+Q4b^lxKhvmw`=5B} z!rix;UYW31c{(nXz$nBJSaCB~r@l`uDmgy~eC>NWUcF-$T|Pyk2NQ(a{7W4UD-(LJ zZHW?Hiknjz9rfY+x}AMH{li<0zW#7>RE|q#{inh~ENSeKuZHiAp78^ZHxIMmZyx(5 z?f$Ft9Xy{nuX+c4pE?Fm7)F@qw?WXaJ@dBUPl+UTYDB6u_Tt+4jeQ5ShHjfD;x_5o6*5JWa0}9j8KGOuN z9r^Ce{Bn31w??Eca*W0rE{rLxeCIm;?F-UI^}s)jIr6**`6(UGSH_|91$PB@LWc6# zziLJXuat=PGp< z>%umt1%02R{Dz|f5NTNg0s!|?&Dk~c_8A9oD{ZectM~afAOa@y{A~;I(W93CXY`F^ zG!32F^5uE>>$8VX^xZtX&C%{~bh+VTjbcs-$Ej}LY+FNz`fP?efL_L)Ulshny-p7r zwf9ww$5xnlodt}0;8ViHkEB0p$Lm*3!S(a-jj2^10!N366U>U7kJwFQ-R7*m>IhckDK&fIZZ*ZSr05m&ZA zREKdKr$i2&E4*h&46ufyGF{g*T5Ju*fHcpL<{7PO4wtP&PeLji2PTz|>rP*4kIMFxg1QAsOrjGxV?=k_d+w(xp83h<_9VJ`L(h zaT&Az*sFfi9s|=+<@~=@GR#VlT+ zI`V@f^ibtfgg5P=kXGW_{+%&etTi;z{gb5ZiAov5p5w1UdE-Qi@L7x;wL13|2iN~? z+FEHkzA2!kD00(^Qn-|yfRk21+53xV8D0&?tg17qxq~4W*7u$;ZGUXqUuin)BEviq zZ|1HgBw_k9bA8S<@IZn7ml1q(Xb)n&f305AI`UZAHi(J65|$%f z^XF8n+Kavc3n0>{c*RnoV9XnH!s6%jk_h$bs_t(&JR&gfgNFAx$$ReL#9V!r6Cx2j z_f|w#yEeqik6G*3VhF_G*b{|3W&jvAgVxyV>a9!Wl+_w8d z{&iydxl)QbE0Al(!Lh$)>&?}1K7~hH{4`il+)3X4+w{#~)qSo9vzZ?VtG6)BgU}}E zTdd_}_e_k3d^NyXR>Hm_LZ<(Eyx^L&fuk;)`i+`Tb-eSZ+Pm9JZB$?m#^n__#p`(Q z`_fUrUq-KPYm+xEJoCFqn~3>|sVF%2-;-a2#s~ci|9&=<`F90rpHAWu!(zX8jvRtQ zbC!Jf{?N}|a^QTI@tpYL=9PB7YkY2|Q+UhTdH0Q=+IWC=hjHUNB`|;2uF!MjS-ZCX zxiI~A)&I`-C_>9~M>|YMif4?ZCZPRkY^odYNf@dDO17z?v3^0-tJPZ<$F0dI@p9Gn z5U<;soUzRQa;3r!tRu-wcc=j6X-I}Nys+s)%Ea810sGtu`+&h2liLp~LwXVK7v1qF z*S|`4*X?I6I8(+dvfIG|V1qDnwk^rOEu(th;|0~`UrxH>ui9wcN+3tQl>hDOdN?`5 z^=xx~*YRf*h!h-#^Mm^k`8(LwW*L)M_4Z9^f=e~}E{fH&r(0#(R z14++~ryELknkYpF2i*F0`+VBH;Y3^5_r}J1ukO6+Kknj^d`i!u%4-m5n2XF-LCJdVfJWeBT_ngC~Euqb&ysGTF2n%z&92 z+MIAAJ2cawWmq+szG^gH>qkz?NcyVDgR3TPWTBDW+W6VyNY=Pq+{%A+=emCtG8WQH zwls$<43;k9B56R0?vxp*7h;A81r|*eh*d{)w@fsIz$el{@795(8D(z-A5t0$qU8lR z3NfJIXfV^4sb9G8(-m)p_HqAjGyMB9-<5Cq2eVs@TM+^mId4&Hry{LVDO&Sx`52nj z{rsT?Nq?s1iD1Nx0(fPPKv6>&afLLl04e1wA2TF;9JM@{dkMNuDoF*R2pt(kXilbM zuUo%Ox^T0QbmYtM-%xU}{kvxbbgyq5_gfija_M@FK;T;2wuXjR(n8~VVH*S*11U|% zOM@V1iMN~TFn9z-M1dMj;-M-M z&A99mBXnT}=Go{BzF$pbaqZE?lo zt|gBUg-%kTX#-)%Hopbu-ffrBiz!1F2fZs!=XN(f-oM+!$)wUyR0k!Lt%cP5mOx0Z ziT+ZxIL7_v0wh7^j$><=0;*AzZK9{Xf}nAUR0PF`kqXA8W)d@4`i_E-wbfTiW?!~*$>!7`@!WWkIo&F4UrqF=m1(I%_D?sDwNNF>fG!CMcN1Z4Q6%_x7jm5bNhnX+q_1tD<}{{GbLHg7J8q(2^esp3QC0nJF7 zxE{$@JUUPFSyrIYq;-qM`kQ|mgZ8JWDL&8MB1^xTELh0Uf9dt9E4O{{fEsldUj~ts zhOJ(6c~oD_xZLjgd+9>^j}#ju^pYYhXaW((@%FX85C?Di*%`DY%9jxe-B36ERbf2A zKJJPzLe)) ztLdY4jfb7p-iE1dQ}4Z$hliUH=Y+pY*BJJmHZ5=nFy^YZO|`N#7jhPE=c*b0cJj@6 z_T4+3WTC12TBrlX&#aqcc-4A8VzI3wc z?f$37ng{HU`u0S5r{TSu+fZA3Gtnv^Ju5{5zpj8rDulxs1t7DKWks!1R%ujw?%#|x zTTM(%l(f7aEa1+sn!LCw0KxCy4*Z*yQ<^1ruQ#dB?RaC7Xvj63-Pc;Z&%i+^{ZrSy zX#suEeBlq-=l0d*8pM>})_`g?{oZ=mOeqlr7ikC-Az?15WQCq+e}jmx7u89AwQdQ< zel1w0pWZM$)3mu|c$!v^p4M=G(?I{KVQ|g&Hw`y949s#kIZ~D}dSMfr{n*LgBr9q< znhgKR^^JWE3no5X7$3Vb{zJJu#1TGz@{dQk&4ttEyqWy5ZM+_vbffWMhsoE^8XhO5 ztoctrE;PFE{#N&S5gIJ$Y&DfDII%TZtR1LF6Obv9-YfA`5L8sF$ULUu6S+6S!)o0s z63{iNs^C9zl>;?W1cP}|#$$L1B~xaz!om@hSDas%&orLZ|F)|p(?90)&`YhM#-G-I zMikp{n0Ofj##ijuLfx1!t4m1AU-eOa}(9JKP;pghVt4b?IVk^c+QpTUVqxvjcT(Y>*u;LXbRjv3<$Z_vuU$!=W z(+%h?3i$EbVeEDH)4u7MuJ$zOt_X9yHDLeMgBo`)LH3OHo((yE$ecimWih@tw2Bfv zDz;pXIIh3BZ~oR=XYx3_rv2>196zOO#nVD?P)u0KNoKAaJ}1T~;TY{{SA5FiPB&Ny zZ4(#01p`r+9Xh7~st)5i)FG2kl1%$M8@u9gF>3Cwj-vfH?`m}N&j)C9cEPOtNLcE- zmN>utEpgW_je>Unu6D>KUJMMRId$}>TV$vq9u&d47#5iCp)vME=zT^@hqw9U*WG7d z@6LS^u!CC%0kSmDybzZf;6fY<6;pRI^!fz`uM^MiI6awMz0icVV>|a7<7;d%CHX%h zPGhO=%=dcjZ>eqpR3)+I!ZY)AF|cYeA*RHF2?itFz)binR{`#3#*(Up{Z;aM$#Kln zfBdDrcIS4pDT@wVT~Yhj`Sp1lB6jUFR2aYNG`&1SoyCU{AaAkR__FBu zZIPn?Qp%aRT&)Sw=o@4z<R ztFo(v@J0S%yX7xcHt>SJ-RL}4k;0!)QQz|~!2k`;V_W9ry-hwhW1jtLWkqe}oDse# z)OJsoY0r~*I_0)^Ih?1?nuf7lK3q_5Y4;f$X-hl=mV|y=4Tf?`5|0|0!ZB+r{$jLL zYv@#`ePhgt0Lvdw10lLWtE46oSlrU}Yj^1RoEfn@=a|Xq@#(bXG^P}Ph%Saqh9df< zb?jQn&tbN+!q;7-UE5=cHF%?tdBZJ2ZK|_Azy7;jkL}U+$C;z6a{n;iPWx5EBIMkI zUoC{ouP&&nZtyN|njAiwTW<2=)lt0T-`i!`9nEchq{P;a0frmxWM5Pyzgc*`Zgoag zVx)UrbaeEa`x%B?qmwftqYY6HM7yIXbgGLM-RVD*k)7?=GIT#-{24TfgWlD?@bG5D zkL)!HpZVL|N_l3c{{$9oJ7)O4%k(eGd{F^XV(88#b}{w(25~j|mC?~Q;O9rXn;00J zxOvl{GCtAj<-PGB>p7u(yVCx& z__J8tJ@lsg2aZ(xrMzzxOh1tx79{h4w6PAlW#y(qtYS&y;4(vM&Yj!+|BbvWx#rM! z$^oIOU$VM$++q{^kH7Cn&cyt>HS)By=;&>}Bb5{1DkjHP0o#!9<8D%{X~2P(Z3np< zU9tBJL}8@P4TKc8Yq%s~?EdaE8N1K)8TsLNl?^2$qo2kd||y# zdyzlJ9G8w?PI^S?q$#w5Rg+^~QgQ;XnXI8v#!qy$F!Mn{bXV$4wfx@Bzm@x7Fq2=ovU zJgXg>LutX=j|Ioc`RSc-=Pq`2Jb2W8v-V$Icwu>Do&UZMR0e z49AHgd3O7{t@YJ|;#V=*Juzqj&NeliZu-^SoRz2iFp0R!7A{<2_uI-Xk zF88IVo}m5pR}g72!Hy`ELgI%}x*?v2JjqoY>Jq?sL=3$Ca?B?Z;7%b?rkdQdl;k}< zCxBZ*Qb1Rm%e&z=m4A}MB2f%){KSZ|vi$ef^l1pTw zIZ6FCzC9GqEq2*)>JV+M{titxVCb?uI*k=pTXG2 z6>zYtCIXe%jr2e>h6ry2uU9N5&b`lDp+kX!iR0+joS50YpjXkeEmwO%Z)DZSC1+3Z?7sy5xq@t41}Aq2%w6xZ!Vf`@pN2WF%uE)k>CH4$&CU zLL8!w;5f&>HW%?ALDHrmpIo_Y07eFJUI3-Z3RHw-!io%pyA@8csU%z4#?bNcpg93Q z?o5xK{O{=G<>${D2(hEogJ3hmNY(_|BKh?im)_o0eaE}UC%XH;B84IbndVOx6gjR} zwW$+EXe_!5SPO1bHiIl>U^O9BJ`MqGFU>PpxvtBTc*KB`3CRZ;)=}I|6UoA z?e-qty}@6clmWSx;~uxi9*Fu;C##6q7=3|yjtmLBwj7EONuuNvrYaJ3s4vW6pul5b zi%mRKM6$afOYeF4Ri7IFyW9GHmM?VYNdaIt4BY`KC->iVf7psmW|E!j42{jBXMXN% z8jj1ISdn`$V_#S2e9K>B7K1W_Cl1Hl=1^4l6w%u+C)Yk+#LD}z|Ma(lo>iC@j6s@m zT*WqK@v^(A1_mBDAFvohE;TMQxb>uZ92IlZDL#+7o- z#z~vAaM$LmfbJ;VTerBajf=Kwi#AAVYG2>f-X8ENN;}`iejhhbZ?*(OTA*pMhT>8% ztfmIOG~QuG%D3FNn8pKiRm4ZD&ZOnh5v72^wUuZ=9*!D{2z>Iobx>p@I)TJ56vdlD zAdQun#P*!v1DT3A*An!-R447gJWlM>9&y{09UG_20$+^9R;9y_7gR9Irrw)$cROvf zt$-tT#v{lR5+UsegG#7$$;+`UE6naCVSEmvTRr!3a9pwQ5L!P@4J4VJdx>LMC?U5l zMTWHw0cb2+70Ti}%~VM$sDK23)(G4H@t~kjJ06z8mo&}18snaSJ_Y66@#`2p)||3E zkS-uZc!*SrIS$go&`rPFX1t!ogg+S)5ZK?IZTUcPBw~dUXFl>gc>R%($2r^6IGc(x zUNlyJ&(f+G(fqgL-iEqMm+Jd@|ID*6x})>ge%XF7Kb!9d4ArLe7AK6|O7Vq@$Okc= zRgbz4g@(A_^dE2w=z2NB=U;5etM>R?uG*SZBYh_U|`(0pV5W(*?h6dKe;H6TU@WU*8B9`1rL?hek3S z#$V5vkj%JcDTpb=umJf>g*I-ku5u-fS=U}(CO$8A_dMq9-8{C@&3EV*Ew5Hxqw&`X zlb@=p+Ki_s-;0aJZ$Iev+~u){iGf*PjVi&duGPH~d3134(a|9gw5QEE?KZCSSQD+2 z7#Jz4@+fd-=dpm?kmM=O%lMWNBpQk8*g`1+12a{-mn z6OG6|(LIrNqhiG7Vp*9u*~PUMKEhNVsDi+WdRk^EpF&%+c7Px)(g9gi7p9;UzFIwwzfVFEk(&}8byY!Xm z#ADM*+(s{Xs-&QowTt zde1r^s8%-Q95fy{ICT+7;RAgw0_**nNM}_HG*cJB5dghDU58>$F;~DHzz_!VxOePI zCmJV85jWZJ7*heQiNKL(j~!)ci^S9FsJ|RsIdf0?pVvc}mDfGy1}o=%2)fSs56rDg z4QKnxm)OMb(=oKxuwqJij(G~idyxdVBS<8~EpSoN@q%U2Ff&xEVQTs~Eb~}SaP&rK zFe99^GWMlJK|r0^Yiv-YWar7O`ngx z$+9=x-nqG0ZqTU_Nm`J?pvsfoWd%pg!*~euG`m{_YgM< zLr`4wqKn%*M{HY_T0#G@BLBbfzg*>FU0pW+ZaLJy1gbdHVSVBVvGOy2)jQI5bF$04 zqVm^i@Ygu3J<<8|E563Y+PelZon>vSB^uDDspE&ri;l+o&y}4Nnf&LaEZ?Jj1Kp`v zr@6PC=axo5gbTv08Gr+rW05dh7RyK!YFPO49jV@iJs`;HWXbXnYfsKYKmitH zTz;WMClw-5xtTI~5GaYV6Eisw>FLj82pOCS7YL=p0xfN1W0!Vq4<_(s5awF(@%$2D zyjG~}?}$en#;WB(giw6rSnD&oAY=}tgnGMaT&@!w!{-H4W-$<|HK!OM-b;8k>qs0V zn+FmaQUNi0)!IPz5e$n3*sIc{6oRaTMfBA32$o@2B%bFR?wy-b(ml*rIX2~M zPe?eyP!uCFQBAU4AR%Il^Cbpm93Dm#NC1S5a4!%8PB8!K1nN-*wm&Q*p5_C2>-9^K zcV|j_MQ&Jju0(CYc<9MF&xUsChx|#I`hMl#OYgrw67QS8Ghxiv0U^WSNB6kw*euMb zvOOGA2%X@767o4?{NF1ZKDlp;eSNn04||*B4EN2b^pDh}XH>n7*0n$U|3=#@vGNOM zoRUhJO~vd>m)ck5D3H?vae8fQ{P(-3y<;-Ze638VdcXICL81AdvE_#TEk*vl;|T9? z=vF&0Xt1Hx;7HDwwxFQ(e{Q|jS?~d0+THEU&BT+ghtb9h673I%Kv` zuEFDbT!T2oMdFfUSuEwj)opc=@x-vRTkCS`Q@~^}kYuhJXjwH7fyBkSy1Im3q$C_m z4LIpN^c4;Y42ezq5HQlJ^?jn-C_|q8Y}^bTa(DlN?sboL!wTl`0~)S}Nj3><*VZ;= zolHG2V@D}~3ug@L$@T6j?Gl8%+Q(5hCohz3Y|-*JF#Jg#b%o#d5Q@+ zgyTFemma!;N0$*G^zA}d$VpT7WEkXtJY#x-_qo`M2R|Bu;wSej1o z3W0)(a)7RWF@&}Z%eruvr1`c@r(%@fr-Wk#4Kuh&nkp|5Uv~xtd&8My|KBPr2YZ*I;KpRhGZhzt{}=Pj5okGy!y z(Cr+YpfVX5RM_R}J2YCNb&l1_rOCF^lg;^4IGgDuUWcO#-HE;U&LmMxDNryZuxu#B zIH?$h5`tg2a?$3{Es5^26?6PL?^G?#FC-LRYt=ZsjZy}aoEq*?uODY)U+ldh#^LEP zu9eju%rm4q(_oUv5+9u%cI;FLd_?RZ=~N&B<7f2D3uCjG+6XjMv6KKCK$GeO@dqEP z!K*~jVZTC#BY#q#D^Q}9h_YND`>Y6?b*SK0g>5$@LA281;2P^q?i-^mBvpyjsHu{19_5SiKE?oB$1RU5#A{q@$)d;8=Dpba8j?3z+O%Tz*#kWCvXuU{DZ@zt15vnT zi_)BmW(>^u<-b^wk$rq&^Q;3spK`~ua^RWkSihjJcvIu4?)8sr&d#f{plzx(J|`8% z=Mb0KV_2;Zi~#d+RHbRWazSP8S|ZUj~hXNQMxd{QE(2rVOIA7x^Cs{LVIbM*+j z(nlRD<8!}XPukFrq^?C1T}LPVfl&2HSLTrN^QnwN!(xm9R6&Lf9n}mYg;5HLwy9=h z7H8&NU{K;ZJ40ls4_2!=)zKv+OyDt45QFT@SZZ#gER$Z{>x5xY$(e6CoDC}XJL{ZX zt`nb78m^icTeTkPAP&j9*=%;}A-{q6(L_V5VfgqD9PN`I9sQaz@gPDONjm_BQ#F3~ z#NY3pX9mckO^QxiSXj7{7i!SHX>8U`JvJB2NbrTtZLC}LJ)>U&eKec4#%wmZ&XPbt zlUU{)mdBE&no;p`t474a))VF;pec>kj0)GVtB_g2#fOcm)gB3dHkl&7$H>1NQgb#f zGc#o=Z5f(qyqz}^hNzVc!lk-8_us8tnErF?r{3RvPW~Qm1qvIc(1sFNGwbmU5RH!D zz-x?_HNXt>F$Vg-X@s!)dMJq@IyTp6i|wDBAT<$Oq8vV1>0PAui1pL|D3-@fegD^@ z+b*?7-ed>)0hG*)Qf5}flq%W%d1Llan6)2NfkWjHhHDx-4(~oxa#D`0RwsSELWMp{ z8d$*k09ozj?NS0OV#A8Xh%m7-hi+UI$$=`f%`NCjaYsaaY%cO(rJ@0~$zT;sTLg7c zk505a=B{nWYPIC8bNM1P>U^qz%(H4)Qv*DQ*U0D3e6^|kiiLvz=X4*Wgv@z^u9cNn zGL45QQ9caeB*t!*ig~dz?A0iU;D@-Wvna|Amq8d#PA%ln^JJVns%qOaES^LJMFRRI z*@@^I(=>{Og9t%O5)VE;>*XARSvE~nOwnA#L9IhlRd#9w2_2tI@ggM5I|tfZQJBMWPAl6Cg_#q0@Wr)(F zP^YyDmsDqO^{c3e$r<;n@tyb8kt_q+g}^)e8H-6)#iIX?Azbn;m^wOu@I|7>KVdU#^=YIokq8 zl3$(q3m5yP;j^w;7D_Zy!jM(Mk1q*5Us{dFnvoZ@4b+hFwv@@j`KRkM4y4RMEM6nR zjYBa_`QRS`STuwqAfkz#!t^4ZCWIr$qd-LyO;8~;)PXNK*wW8tl66poD4_7ODwOa5 z>Icz+HHFH}GlUL=SW31xhb%dQug)d0%(-+7lBKHpDHAtS`mdRecKkH@Q^=M&dg#o+ z@bH;|x~Z!9v*qCg??T8@jIt$RV9DcSk~emmIfDnpuAJmH*Tm}L{yf`*L>&$DReJ^1 zNd=tPFf*>yoObiNy83b&oiW)VbY56Pbz8f2F=`AHD%03v!fe@&sS$!Pq>Ftii!^j6 ziNe&<5tg^o0Mb0}f?_$;;eZi?FvKRP?f9i4sm;YwZMg%$`_$_!dO^S8~hKdELB&ak8LHd1{sv- z*OcI6DGyIwVPUAa?=~Y)%A-IIsXYw=&LHv91so-Ttghq|kB8HwPA2y;<7qlgY=rlv zu2Atpz$M}HEia$8n6BFL4EHhaa79~_`BGpoQgI$ErUwzwkq~eLa7v&V2U`Q)aH#3X z$b-V#BxD7i(F<)Pz zcAgT*z==yClL)F*KuhgZpGpZ?norf?r{iaXPpM4ejO2L+-VR?mC`+A#B!t-q`qZx> zHj6L{db8c~?myyn>jul42IeDDd{y6#q8H-B*EB>gLuVE>b@(+-zS=MrlsjmWGdeA2 z=n}FS<^ZNO5~R#7@I_Bi|HqMeMdI=|7*iv~D*5N6${M@J4T-K3^$=ajd@9t=gf3RP0vMYZ|m=*DR^#0JA!nP}uifv;M2oxxzA&}EH zHd3-P>Aa^$P^BmfD@1fW)FU;K58wCxzRWjG5vyPKPD3x_3!JZqJ-&|CAlSMC+{uZ? zzq^av#mQ?L>g}vCx^_2te6KT-e%-l^<9~YfCK#i5_ z%^-8(hxw^Alev(P!oZHeHLm235kpXiGfAcd(!l2f4xw>nda@BNfiPkOE@C7*11+Fx?@EiVCl3K* zgi0Vbtya{sUINye(hx&`EnOktphzH`0QxLBXl~AjYsXz_xjr^QhxkBIhaJi&po|Cr z2XI|H-Y^2r;$mEL$ySFKOQjC+LAbnCLD(TFirU9JkNX+{N7u=o{6Dgq5@HYF1$@X* zbd;G!gqzsIdaA_Z8*^6$oU-9)lYwdIC zmjkH!g6;uk<*RecvkR&L!fs5J0bT-Ox|rV42k9qrA;E-><*Oza%gZ|~RdCnBAar0{ zoS4pn$?!D+#`NT25>y__l}HN-)Cp*K8udUjn`F!_3do{Z2q5iXs0nW^2eI$ywo>@` z2gvxD=$OSyBPm-%m=eiNyf)Le9_wz~wu12d-+%lo)hU(>_#B(sR1g)}bOlYqqp_>A z_-bu+fLs1=)9!kfyEn&&B-ho?i;N17w$UgsA<*aP$PG9dgttKwdA+^)?S4|7Ov+4K(Yx!zC@YXh?1~RIuSMA=Hd&uE^LnuTB zy@vJQ7LA2TX4kHDy;E;4TR1_O!k_h5L%HVZG z%G187E$`LU=GVbd$MveDKMd^|55m5AA`ay z_}}|uziYzs?vpzBUyXL%-%%!&e(qenVD@gs=kk_#qX)^!TWd_H>ZptUpPKs>b9!Sj zGxm7YVsB~jY09E1!3I4)PhXjf1>Z0H%${Pu;WD;!3s9`qLlAmT+CP5W2qeqy?RuBUIxrO|v2 z%&!g57n=cAftpBN>MY?Gg7Xi-3m2#cL+mg_heKwoa4>d|;5;ryvq{m?p$2vSzQ07N zTfB)y4+tkRaB>r<&{IU z01mQ<9K~LoZ9f_MDL-;Jf!&gYpcD@33qA!_TQfM3L)hqF1IJL|++hS&+O2Y=iaNPX zV@1-apc@IYCvyTE{lh_`$3d!fu+%AZp;EAHbwH(ysjiE1@-RMJtk8MKL-T}~9#s(b zdWn3bJ_Xh$ctHZYV?HuAJpYMNazacOJHQsRV__Cc$l-@kY_4fCwGJb68B``{I2lGr z#4hT$nyy1`}_cclq^5 z+|c)$hBTYPaTHT^gmg85Jl-%qI*Sg1E?Cad5bZWNG7v8a8RhvUpr*k|t0peP@KpJG zqqdRT+MjfHwmo{|$Qr$sz(PQ`$k4gCXwNHA)f`h(4u#qvpw=?q3YZ5A!|GS2f7?CK zzs)V}$(7I(p{>;W^$dy&2zC?y6Lzps3K%Sd=7U-5A-7OL^TmM0qanB9AUlES*BPGH zA%je`{#$eCcV8pjQ6AJ^!v^2Rtn0nG?j3kv+Xe^xV?yub1ed|8KE02G-oR7I*?TK# z-!1HWj<4Rl`t9H@b;6E~&e<1m<-;p&@s>YsyfE>q1rcYyPs#<2LT80(a?qFR%-*lJ z+TeIp5sM2%0gHis4w#Y7C)^;ax}P*F?q&AZDzAsFI`h z`2CSnDU(W88Dall2$1zJ5Ngh3Pm!Z=O;dkFM-*vqI`h|Vq4AE}uvRXPm&RC(D|th zIp{W15au~vKxAbC*o26ffRLWli&SnLLoNmkg#k`ZXBgfw4bWNRd{!AY&5-JW0FIC* zF;X$Yw4UQ(K}TW%BlUGS@c#7N2rKg$)t)>rEMeC$z#2(Hr-V)9#PSWI%Jni&uT)tz zqBNA_#Ml#)n1C9QSRaxj#7A zgzEx#WEn?==uH|jR&Bgf=M~D?RbqmSGoja3yTN+}DRhZg3<;=p(zH+<5`bD%@B;Ei zf2VID;AYt9(=f;vQ}v_NlNn@CCl@49EI>3kvgkyV0TGhhpvEZIH)j}gQBa`1t{guw z&c$=12b`WzjW@x#pK?GCNtDjASmFPHX%hs&H~NGY5m;$gjCMs*Gdu*LIYoAFh#kj#&kf>(gbp4 z07tb978VL*GplpcoIJ-9SW3L~YtNYt3vLSx8&B8Psp8V-I|!5a|ody zac6t``YrM1VlAdt_r71b`zd2)4>rX+Is32V1Qu7Nw!gnPr~6A@SMb{*!T-jm{!;T@ zO-O z?W;)&dR3JQ$GgWgN_DjqM#_E$JZpaG?yH@R=Uu1034FJHPX6|G$;-~<$XvMk>dCk& zXl4V#HPJKz=4d!{Q4)Brq0*#U5d7paoHP(+iy7^n<~PP1yy)=Za&l`?=1J(b@9jRe zbK`gso2aIvhSsZ<0928inF*@7r?CXZ@p%-61{S&H!>MLP*QLt9@iM4O!uYjZ8X@KA z%aHI;8)u_$gULfpB0sWBt)YPc#!=BoD@+-~Mg}4>_!Z(fu{j^17#hBpOv&fV7&3`c z%QC`bC8qyQ{=TPg-o(zWCRTu;uOlzQrWC-k(*%ihxT#@5LmRt|33~e|HG#_-7G;Yd zqU})7J6_Wy6m;Vyo;>*Na4B33I+L%KGAgWjyo!c5%}5SS4pQMtB;&LNgaoK};P{kg zu-}8WLZ5tB?F1tvq6WKhJVn63RWcMH*hn)Fi*Oq*3q?DPEtN>9D4eM>uD*uCqfq%# z8Wwe=n2HxA9L5z#_-0X{2M6ZHQew|mj&C2&Q-f-m5cx-`=%7hCz*OSJt4Zq)^2Yr4z&> zVghgGlEvh5g6inBn975SkDzGAu@7BrnLFoW-XNT=zO)TCln%SyO^-Y>!j3AIX2Syf zTG#&cu3yiAw#UCb0Z=fo9LWjm`k$kh|D5;c^W9%Z@~a&Y;;twkp+{qTSV{EeF~TKQ zAW51ZUI00j)j1p|Yx8p&n)*!Iu6=iUAG#^V*4FeOqr0W|>+NQU&4TBo+dG^ZIM$1;Z*Cx&wN0&iUi*J~kLkwIev}+_6Z5`L z#B3n%QRP5+W$KK8ioGjTo3Fl`o(-FdNweP<3|pC=*n8+uaJ}yZinJE7K^cZwhCUl@ zb(t1cOTNOK_hrb*m%-oTQ&+g^def+8pq$!Zs|XxQ2k~4C;)Oa^00RLsL56^L7wm?e zszu8=9VbSeez1SZ86T2m4cLjJbtx1j&44vc2I#AXbX?xJs`)x`S^xzIJSSzN>r-W9 z#S#ZMc*rcM7BCb+?^p;umY7YLR&yyJzf!?tVxZy2s7gu&H8z^h=Sqk~3CBdq$M*=T zhEwbx;N5Z1Y+E-Fk0U!VDODH1Qvl(8jw+(PFPRL?0tLX%7@09>Z6ywtOs&H-VBm|m z45)iqQbJ1QiSKgbaOn*tv2HtiyQsjSSPoPKOX@J9eH5NI3zRl7fki+}G*XH-zzY#j z77sxzAiLq$D$U2>r|Q5-xD`(wNMOH4iF1v$oPl0lpAylF)mMWnD2|}W!=fn&m{e(4 zWEl@V7y1nbRty20*D11 zAT%Hws4^%D1vFY1`B-j+@%z?Xh}ZF{c(^D@2IK9(p)Ooa2F9qkx{HhHa~ls@I{fc9 ziXve{fbvRTtyc3{Qcy+w!^Kz-2yf_}4X2TxqM{4l78$zZE{!d>PA@=bq;?`0CmdUi1DiNtK$I;x+8I6A|fg&VCkYeQ%`^>vyj2m zXR0N73=0%&l8DPktWz#zb>`I%%&YIIsP{+yOK0%x;GSP;{Wa^ZzI4Sjs~X`PZA)A0 zd%=Q#?>=y@Z7{X1_cs4~H?e&{3*O8n=M6j2p936Ue>#YwLYPaQki&E+X-=Vgc-~9MweQkZ(s`zDRFW9ek z^}XPyUn}+b&0w?b%g@it@(RmBK&tq*dDo4}DT}r~%y#c9-Zs!<8S=%_p?i~is+}n2 z=u!S?+hLVyvqE>?_|n^*a<3+30CT}dFPfS%*5;JIxByP>K^e)(#nVa_U%i=NPJ`wB z4TrsdE#LPXMlSh1SMuMydiC2wp1Gnn5juGaP{CqY2y1*Sn6PLm=46aE%0>`mIOsjl zjG#q9WueV3$fn7|K)yg_PKf0K4J}R!VZL82Az$4n z1R~846ec2e15<5)g|VQQ(q-9`sorWnngu@^Nd{ZZj&mZa6Zw>Ch9(pE1Yk;%rUA(@ zSH@n!2A@YI0X(5qY7-*Pe)x`XjP>z7_1&$G9w%#!tCI^g(Sx#cUS>WLs_xwDK4Yh>MjVooXdSF+C~@E{Z5R!U$5Xh~xqR zCya)hRQh0NBn;wc5xy|>E`IG!pm~s|J|O5?ZUzf>1&on=Z+NCSDd7XCWkf}*HM+RM z0Hb)bAn}7Q9=e4ZdXyS|eH6ul0)H8TA~c0z?M9rxC5{?Wh7r?dVEQCS?2sry$F8@P6RSr9hUX)O0YdM_xaz87iX%N?(&+f z#j93~o`8QH=B#{^JYw+8h=Id*#UcTws559wh#k%c4s3j8JhS`o%yzcTwYm0^Tva=N z*bS#KUM7ZWA}We|irD%`>y6uXZT)BO{_+(_PO;d{SRS z0IotQDUlHJsPNo{gb2~%IF)H!3S!ta1hxuq|72Z`Mc!-6Z*P}>cMoOx#jv(gHAW)B zh3-1t^2YG71GBnQ>L1pJ+Ma)?lMVI>&}R(-Abg@09dLWPrgFXUSpRQuFE2L>rswxA zI?+4Z#N1CTC%L&gfV>LC55zhYIiJ*)8Bl2)^ks|XRl=&z&jl&F{5JOvITRD}%wnJk z=t4F>a*E?O2zxfH`?(>s6IP~X`Q59xbsgQ-@$2F2_O^ir|8)Z!)^%eh=v6;ByMA5s znt}&gW4X1-L;os&v1;RmlLt3#zU(af?P)4C<3zHTLR;M8@u|4DY0aMcI{^w`&tdL+ zpDw+)>9AEtjRU!&ERgYxg+gw|l1zTes|NxDSj@I!26g1pCv18HoE6`zOd_u zp8lNs;JGfSv;5maL@5XTC$Cd%^Gkp6Zu8B%opAL4U$xP~i2=kIK}F zl4@L(3IOy5&{#tK3R@W1g|IjZeZrftP-jrIRG5^6At;k)?WZ7NJ|20QIVFZ?*p@aS z%M{afLk_4Bz1iNsD}Ufl=unkewoG+0&Jc?SW26Ovg%vXo zOz8Z)bR-VLm>R>T5KJEe!fgd``HS}h!VhGjfWxl^-9*@=vcbjA!%E7hP)B;XQkh{O zWw>$)vZ;W?3HH1+)5-@#37ASa(ZgX#OTmm#t{+8H`oI!@H6tv;2BIc zf(RzoIhIH+ZWQ7ODV?amF$9UabOkU;79jRgOlvSD!Mf-~;6bmkD%TV0XhR7M>v>p< z>2NE?;slXuk}QkD;)s!)2O%*Xv?T&P&ZkB(?#3~if zh>MYjj;3O3a)sL+p0|@Y_U|(u&Q4Av9|wG{To~GE9o0-hO2T!*U`3YS(nptqt=9&zVkol=aTJ+S&jf+ZjnC?` zr_w}8k*uK9hEY1)Wz+j+g?v5xZjqy1=%5B-(95}}SuTVeR6Bx#jnQDb2q z$yS`o<53_Ike(uT%{ZFgJ~Q3_rG4t|hQja=(dzV<4`cjt68H7?D*68k{@J##*spCM zwXOX#GAATZuBn09u+Jwfb|wp0 zBle0oOfan_N_DK{&zq}`zFW57^34U0rT|6ct0YDwg0sri`usD7waNL{A+@7p_E*nM z`~Lo-v$M%)NB_RIfq`vrzWTjE1nkydAg1?kdF*NLHrHyi?Ul~GoZ@|LcbflN*Yf+; z;GV1JO^GNRPdDUQiO#D{Bu0~OZt80M3d#NzaIxG^R5m9s($mUWg(w=BJTVozzYZdi zphy^D*c5nU#1TV;$k7~E11~OG<4SnX@eMdKFt$OgaVg{wJknxG%r2}JO5*r5Dj}=$2xRw#ir!i!hT`2j44e1!MT*~7^0Z9Ar_hmxz zD>QB!lunt-k_4VdOsx7Ti?*!;;WT{MhYoetK0}rJm}ak4gtKt z0*yeRG*YVhARC|`Vzk@fSIjBYB6}H1rifmqe|VsX1Q*0yg0G97+6C($6?+~(gQ5|$ zxO`+jv$zyIX(@qb2F%X2cu@p{m4xxca0wxaXr3Q25t#!1jKPCIi_CIny{c-Z9$K%(h=HFYCn*XpjbmDJV;6RySCQK?ixVF)? zZ&iJxz1^mYm6q?EU02;-l-%&g?BOvF&hFUZw$S+MlizS}$IHJhd;RytI6Th3nf|kf z?HfJ4G%sH_o-9o#Fm9=y_^hK5FNFlBr( zRm`QJpa)JUr0PyMe3)jM1&bG;LSimTP&EA%#$u&m`MX_?cGqrMhc<>iSs>(tk53y< zvwANwx>z=U(6jgYx`vp0$Ak|pKvqFhO{0jpDz2EIal^sP7oQfi#%+V^nJ6vQy?53h zzNgXO{@0A2$ZbHAYi7n)+DxeZQJXpabad6>O!{G+=0aAPxzS?>D@-IV`Wc z$2+F?&_fvIFM=0tOO<8Yz2-MBj`M4?D^v5@Zlj$I`1C7npe8NvLG9h{**W#SH+&uX zH@WZqK7aqSLv=r+W?dY0XVv*L5fLCYpGhD;o6L(l7eRm=R+aELLL-Tzozmo%Ki(O6 zKrr2yCuV41!{A|MetVVcRih`uhhCoPht8h0nB`mdj3#(of7oXR^ z;~xA8CL=IOf>CbF(4#{)KYMZ9M1Axqh}MhV{kSyW@zZ7eO7Z%$H<<#oROBp(k{vy6 z9y6--)h_gn`Ry0Xnu0^W_I2M&Nxq>A2XbcZYjae4934miNiuklgc3p!y3qHRPiZt zLS>^BM!k@% z87wz)2#ce^l7oO^u^gx_RM-+_hS~`PR63#?45+IymjRN^>rlXO3l6l`Cn~qrit0zIklaH&U(`Lo#J78b-bVv!2OZHBp0S zg3bX5RRyLmOmI^$^Z-o-Yb!-6MBfE*Geg#-2i2T1a1usqsTH^bCO}LUlF_7~roqIH zz+_$xH)|p87ld2`<<7d^?+5E;TZ_G})aYGxxpMxmKYt(j$UJGgVN#>EP`tp!MQXM9 z)S1PGn|-WDW}TSxXm@|K=cwFY`v`z?Jm!hgrim?vAv3q_-_$n2W%;T|(;blp8%lUI zCC`>cg2K8+QqYK*3w#Vm++?r3u<+&2Q`3Gd4K2Js!zV+F5k$m|f8FjDc6FbBlblzW z70YyyNU#^PpKVvqr7K1Piqo??Y~@ihZ>Z4%zKes)ocH5$`_rfIkK?D>MzBOKFIzf8 zBj@LfMwq|2`f}OX@T>%z&GS~8&pSXlWJ6&bju1;gnRAX{8CkLZDcXP9KK*`G{&E8p zn_Bh?3;`fnV8>BNeJV>yV`q^92DsjcIjGLL3@`;7XJEG?*CbVLn$L-ir(X_E$Zqbw zK2|r3@bKJ-fH2{7^Vjr8oga)tZ}ktjcg$b6pyiv|nBeikG#U*{3Md5*Es91}z&~Rj)yc)Vp zh$+($cD5mvLb#M5x*}0s062(;APcz(sGNa>OybECDA7=3B;lpSd!|rRY?w?lh*-c| z!*^j53B>omRSBrI1{K>`Y+pPXfeH+W7VOY5pTc<*hn^!2Ra7f&9Ip?>uuh3X3feWS)M5l;a{<}Np&XNdriX~l$lg*Q*iq=1 zbnq%|SS3!<9F_QO<+1$PiGmH&@(qzwXX zxa1WPM->RO-dor0a;|K3v>nHQ*U(#fZM%zO+m^8pZZV%<;>LfE&ptLrw4~RDifz`912Z{3%Fq@X}(&nRPtS&)3>_zXP434 zcEs^V@l=8paT%D8s>E5?Zg?vt5_4EZU0+iF@yOMip)JNw&M{u2j13&m^E8iS_r>f`>nG(!uhCv7*?)F48w1jW)qLB_F(8KKA~R{Hd#lz1)?4uF7uo#dQlU z$6S3EKdynkYM{rBZLbwOP(UcAU1BkZWoY~9y3`{gU2S?0>}%gH1s zexN&TpnC+2N{&7MDsvBcH5Rhp;F3f8PYEZruKToL#JF=F3#`sKTbV35bIG{?u+N-N zOJYFo3BGlyGl{ecem_6tS3!=$$KusnQKIehUE{7a;>^lacwan+@WXJ4N9!kr2&TXG zF^Tix?5?=l){99t)HU73cdx8*=3Maq(tQ1*WA~<|W_v2v&D{6%i{i<)tu_O1p(Fsi z*dn#B=px!eKiD2zU1Y?|%nyC`YG*@V`0~IH%lAHtPkr4Lyzx5Fm-p}@?*Ml}vp>%c3AG596%4G&aB)P|g@Qx#9JNguHPwFs&lXV92oH_J&tA&$BW!{p)sJghNr+ z&!4IA3K}!!+S<qzas@~8aU#bQsD-PngmQUJOmi_H0}{! zV~nt_Guuyq?~5Nw8f!2+0Z$I0D_-PPT#3O676ulsdf4_l#EY?V(AdM|VlKRCn^vM6 zqmo4#o|TshLnRfZT>a!XTWd>jj+6wQ**Yzr zxwGuy%jLh64>mu4@SfISqKu+Aof1FzTefKP-z#+0YN|6$k3VYhm$;Se8sP#nO;^yX zm`6G^Jr>t;@w!iDukNoqsV`f$Y`9Ten#BYP8%E%imhj5^brlA8fLMEkM~ zBaPXXZYMOF>HZRo4Ke$>U$HgUY5CgbBTt76bXKayBjCxDKzDdz-e$j3Z;D)tfRLZ2A+x{A)@@yFR54>wYeCNIJ}`h_*>w5lPqX}iE$Ntt zg*3gY3WWv4z`sN4NMikAI4XpG1Fblkbi3L)(Ae#@qV`5&q3!C8E=S7CqfYE-{&n<0 z`rwOggOBX`ANlQh9qUH}b{;c$dTfu%_jON{^~Jb(e<`xVw3~)3{$lc^GuT?!VNuoI z*`BZRrnsH0SU*Yu*Fp1b*EF$= zvURE9VmB32H+J_HTlh8kxFOe!Bpcuu%$Zi# z{q_kNHVs7>r9dRa22b9T%u_Q36-Y@Dlz?*3uAmFBLJF2MK({9hsA6HUCof79GzmGx zE^-uRJ~m+Bfo%&up_Ceh;Uh}8I2)iuh%wB>$rMI&Avk3-iTwZvQ^W-f(xGV7 zgK+@Z78YJ%PIQtO2uTAMA?!||G4cdl6%HgIZvmacB{MF;apXZQ2xNScu@ba9!Ez}Q z8SaBobDhts#)@c$Rz?T(WihdWf%HWeR8>f`!NgD>m4YEx4E;fq9+-SY-LHF|0c&QQ z5UTy2*|3eQ7P8_p0nhQIPRi2-&dP-c1W&S99tYT`oK}1;eK%>j)%FF|FQ#sLGN$ja z=W)zO=LQs*7og@e-E>S$NR;EAGMLP=Vn&k7CF?W8a}>D^qPNa;Y%J`S6HMK> z>zj1qBhy8Nszm_m@BiI`T_S@Acf-7}80m3Ussx@4^p(waz)e^b}?{>0H zX&m7y7mErDC5*pjJo(V0$rj4&JL1dTOJ}`zHnEsDL`6Ndvnc8#HY$dNxyB^?n9*#0 z>%Y-G)zdcb>*{gOPt4Hx@rkHt18#=SDzlGUFQ;{Esfr2J3GHr8Naj=o7zwfIWCHV2 z25qHwyk1tK^G7fDyte6RnF4n*4t*=em!&V z{!$Ms{x`=e10J39t_^-UdbF)w>({)B+Plw% z7P@WQ;Kx71Z``_>8L;1X%f2gZJqvv=R59Zuao9;fH=O?35iU(3w{n6~at2Dr_O`Gy zcPW~?U=mmVVa=QNgDG2kD%SN@*!whr{jD@7hBh&SqBcO|1?rdr(j#c145U;6 zDKUU`pbz0HY!a%RBqbtrKi+06A++{d4xzU3rZv@IG)+Kd$Oh4B;>U6v}*;ZWhF48;(WmQ^P_S+lDS zu|G(C&B@6r_PX1gy6^Yl`5IaY zIFdGTG!zh0E-OxrY%rb|oeCe;2XrTFOKCKXIq&EO663SAcszO6c z<=LQ0=D?I>b03U0W>{A~NcTt_!%P{oF`*0!u(lkP3#nX?u%8cxwuB<9XW zqj#POo0PoL{+R6KM~|t;bWd7285?nJh?Uu9Yfs$?t=}^+Y5|M^eU^^-xg?}|OVZq3 z$DjVT+VAp>KhG3O;?5qP^elYAr3J%(KXYd2=D)?m?Uy)5SaYS&xRh-4s{84BuPbRB zMQT+$lU!!y<6&~wL;U}WyX;)BBFIhzjLF#7b&?lt|D^32YZNdY^|E&mEH zqi+bya!Q^kx@7ju_LJ$Zl-rAHF4UfObPA0d;9p;Q{Nx!&8NM{>JlE`dEbVb`YRS70 z6PFAE#qG!_gO$!rQin?+?c3ZOe@*S{%vn4$=m1S6=AtcD5;ioYuEcXZmNcXXH_o`k z;!(rLnOx$Y=2F8=T&&c1_bx#fR`WQ|_hb1HqwvlNZnLXX_id|qF?VN~g}=pb$u#HY znP+Ry{dhHJjrT8ATleL*fgbmee>?Mo8@^qdc(N|B?1RPF?r-@$Dftx(F|>E=w|2kR z`J#4hW8b&kww8~bI#;gc6GsmIrBU2rzDKTa1y}*_Oi<6%}9^T-y zxvJqw!vp=K;!Z(I#qQm^n>v!sg#jyuy_<6M9WXbK*o896Ui4`P#ma zZ@nRc*33o!BrWNjk=7C9_~X9gx13Pq!1PZG4ftMk`FX}n|Hf+2Fef3rd)3v{pU*DN z`7}AEyB2!uAjcd-D;nEtmP8r-Uh~w=_kua~iO{#Bd-R^V?&`3I4j&U!K>bWz>A1xY z!^@HSJby=T4PW5GPC9R_nv8l#s|1kiW3WO_u!uxIFdvWkUXO~+2x?GA6~H?cGkDOj z%7?oEua`kE?xmhgNDw^;x0^sTi?GGx3M6u@XfOmpT?a;jO*obyg7gC83wB$9u~>#_ z`$%tnlEci;z)~>s!evTu{b&@W)hiNK4f`3hHNXF8U7c&ybnb$LRa-VLF!U*CU$U z<>+%uxda@sgmR4-U22I^P3Tm!K$_Oz1cT$7jvPUW$YS9^5>0T|a>KNDx0@<&mAg3D z=@Y7;F-;*&-H27|WrE#=Fh!`Ilgp1t3h(}j#F(H0gGSv9qsm1k4#Pk)n~~fLlm)@d zgL+LffI1xuH8v~CKOP>aGLSgLN5kf{95T@m#qA;fO}rU@9{-ye&k-!muuUDv>AOE7 z)|YbT(BXw5PP=-DLozkOqWetm@`mC0sV9vMB6TJ7jFvB97w@yRF5^#y-?pFA$#_vn z;qw0dZN%nEo9-iHn^M<3&@oM3e5yb%ojZBxQuZjm|D%|mDfNAg{}i~mcuk9Ud3(3b zjtBBJJA2AIr)>qX<3IoTF?0Ob?Jgl-@5aubCm@pkGXE|ciBByyj^ajqAk6hVRidPWm<6fLCclK#y6%i zr#QSdqT9=t&RzJZplWVVcl!Gx=Bo8tD@EKX{)p7VKs)LXf?nRQQ2kfO8Z@r7p`B8m za%{SND*6WV_-vu!;|nwA=baUNjn{eGFv<sXcRxs4>L=w**QpHg4E1vFuKu#?3%7OC_K&MfnEkR;0tDFvj5r z-F<)E{Ymnnz!!Jt{AlpYZT_~kE9LLmOBQi63b@Z^+|I0B|HZL?V*a4O>d60g zgtUn19FpI4Xo-)$#i_UD?DJP1e!bV5`ZBQM<=*&dA@@P;Ubhc+m7hZc``&>(Nj=d$ zBdsf_zH?1|drE$1itn{qyKc;!Sv@NkP7)vA3RTRk2Mi_qq(E|NkIcfjOlqzKf;fUSpNBRTW|e9Mg71F6b&)`=iGZD zh7D*w?08-|b86j=j*2^XlFse#dpC9v_WQ*Tv-b=g8neKdu@s^`=#qgU2JV_{k(PWN95MnS?`_Y7v^IYwt-OS zD1$)CiZX<~dk2q3_p-PK>M8D70J58wYM}~pg2;jjBhxVKVB|70kMzyV3IfjVqb{;X z<>&L&QU!tni%Nt+6d|gFe<~u;2m>LTG`%O?m{b(hYA{m5{Ef{~!!Qn0J!On&`G^YNzKCJvXY<==9L^p~3C`EEhRpF!JTSC5aCm+V46)=qGwhVC z#80MfZS_a>>ij>^-|6O1v^&gNnI0Ulp)4qn^W>I;dQ-#I#~T`SA;XNp)Y3B+Q>#^3 z(a#P&tL(YivhQBR#Q|c2&UhgYl{n^wc$*~XA!tgFa)E_Gz(WCLB`YdO#Pb0ZfC0_; zOHwX={Kwmtf7)goN|AlMZErX2>h9og{D~2IR0@}I=GD9jpK?;$yF$C8I?~$_u(>1j z`<~Fy#_GsTtFFDcZ-`~8a(34@;`8%QdqUf~)_vNr?z=zIOCKoOci8nd0=cP$8uek{ z2iS0;t=suBZ_n_}8<$E;Vm)^^zAybRt#feL-obUG zYi{d^(3a-0{g)p0y=fZ^nLf^Mt72_HMRJHpXH~ZUsEhtZ&ep#_O7xm)CcX1adk!h; zwI#`>3uc`deYt-KToKH!ts2JHk`*Li-Md=B~2qtr>MWVMkw4=9X(S zg1hRvvPJzL5G_%b_ob}=XWM|=%dXf+Vj8Q4y)v$K=c`2ivsG8lj~X+|p}pN5 zO!zrJA*=B>J2G!37~N5Vq?J^rf=^maj2lUlW*5-CL5);uG4lpVTw21hNnHe%a+IJl zsbV-ODV0^5R*qLIR+osN#70TOmg|7{2Z9v96#(hC$`g@@yg`Dir6=qYQjx~fp6l)4#rCJG>;8TRf3 zbb^#xBd{X)pt@*arW>~C07bB(8d`F8F;U_&Jk^NA@x^ zP$=pX6eWSxm%~K2Ou@oSP*MD`$m<0$BD6%TJ2n|w@P1I7kwk8F5WJa=O$3tvAC?Z~ zzPK9DJMOzX{sC-x=Xs8YJ1@X;9i?tWvln@X3;{|y^{*t1RZ(2Fk1EZzO) zaLKDSo&6=vJ7}UFR;TE?(V>i_)Tckc-O$cv*RY%)&d%xhkxsxk1*`^0RW!VU_>)5V z*gLV4jpUHZ&Z8xLUB7Fh5r@SwJ1`{AcnbwuHyfLoxt;FSy;Fy)pycC7ZL9(d4ZS;T z{JW-g7v7w6JL$wi$-D>gR`#R&Y>$;e{HLT);*j$V`#UVsuqiy6db^=>k^zSv5&wSG zxy;oEbaC*hVMuTxtxW7|06;=hB`^hF6A}Z=79$iEDRx!CPlrX<_a{4a&yO&4VA^>7 zM@xGUV3Y(B3QW{Ef+jtjR#4TQnU57+22)OvcC zoWqTtrw=B!bsw)B_~zJKn{Rf|`i#N-Wn1!E4yJs~{e1MrDrad{zh!9Oe7nK#b~!gQ zZ|%v*$qZwnqS_tw?#f=u4KHf2rgs=dEGB*QqCy80*VoM|ZC zY`DRN_I6?I`4ag>e(k3DO4~5%ownZox-jpDF=5#`*<-$E44M6dH;k9J>Kalwm@`Tf zKEU3ipsQ|=Xz8B1;7W_3Keyd$DMmQ?zBwt2Dy*W6TAZbEKCb5GPiNe`95d&->cXZ^ zy#uhgYeQsP{f-x1woBvuFg2>-iosR_Z^;5vG99@=9Ky*E#^!Cn7QvzF2rMn>G*kHQ zz?Q_q3*NaDm=_r`6#53$4AQq35(mQD2$Y|IaA?vs3PjsM1`p)~RueOwEV9zcn9LQ3 z7yup_W+;NeA!3H{y?GG4@mA{rLdLXRtuS+CKf0mj^J zLWc!t4UM#a<*2b~M)RSoLskGc^@x@L-Dnsb!-#4w0nZDX64N=Y3mf#MLI&RlhPVWa zF_%UIFUNva;^reg5tq4my;eiVOM}B0`oyokli~wS;SNJ-?1p3uMU=h;j4KzKR{Ch! zN^;T%!v;_dqJp>`1+kZzZEOw|d)<41-j6BIe_#$j4}VT7-7 zHG@SZ{e2`3j*UU3D+svTvAgWS`i32dma8)26!jPN8x%A8Zn!tMqzxNQ6GGgkvvWIB zTg?^OSXS*)~4xRlgYdA-Y$%V6=76P5-w-CSwOrs~MUE;Y7< zR&1Z>HOpVkCd@DkSgt-BXK^fLZJPDuYIOmTcw~B4^L91W>^DCB`^Of?@~Y5L!>8QW zjrxrz;BQKD}tm8umeqUtx@rD_D$jog20H(wa%%`Uf znW+H#jRg5sZ5RRgPK1&*O1CKp#t8-tF`cB8k*)aRbB86kE70(a^jLg8K?UN-MK(LX z%(%ZPup#^Ry1>@udm|kOj^w|3^CtB|Y0Jshs~saIZ4_~#Ud0qYudQ=!+pewo9X}`a zTq_zVXlUyjXagdBuk`+yfo}+we7YN9 z@ZS18ywRga{}qw5|MN6N4&C`{bE<)aC!@d;?ywb`kXiw+)TqrR@P!Q*$4NYh^9iCG zS6id!JM_fbbw0K8Z~8Iy-CpAMwYh4Ekx^l4#m1^BKwR{pBFRht_B}oD^VOW)YlcuU zK5EpnDC$?x;&N>yew(j6?-{r5)3~&sKQ2}_cYxGMgh9&*d6iUxiyl*S5P5ifQcO@x z6lPY0wH+up5P51XHI8^ud~JEknguL4$-p zyph;(N*H1AzL6;5d4cQ*(6QmWi<-k4BqRPgFp8`}wxsEmg3`@Zvm|jD!s|E3Z}Ro+ zEl;jOYUfpxuGhhp@u@!&&=vK*{kHh@wHK?7@Zo7Lg^c#J7svPdt@WRe&iZOT0S;Jn zL5Y%x%5cKy2Tcw-A~?l~K^<3tBn_>p7@1}L7+M8RqN>4BB--~!3?cbbDDp`}_q67) zk=~h8Vu?go7k@8Uc4q0$33+Fhwk$q0bJ-HHN=(6d;w7*`0Y&g88G{~&+X3U{k$(g1 zRiSG6-v@p|j?=9`H^EGq{89>R7{efZkU%lMR;&N}f+Q}HALKXw_Z{*c|98g{uyX(R z2>-8tksaRuz1#oqPRT*`f6tzG8n5_&-(;%L6pA6!cZcTCSw zo6};X2MJb1SPo1d5voH|X>8z;CKfBjm(K3=@%Fc{>o1McRjH|buD*SH?l$i>_a(Yq zihxL5Wi>B;{Ihe*_zQgS{Pc#;qb*qmj^tv{v9@2J%>KFMZntziPlxN{xp*-&_rXokxbD(p&}!zDOvdJ27-5g`0|Q_;i$~qusyvqIrMe+^u&TzC3UZ zu3uC&Ju&cK+Z@Z{*P(rrdtQ5wS?c$qi}isWhJbbKf?n3`2`-->@};fs z&9+pBknc|i&ac|CWf8k@6W7`H!?wYm^f_PdJHFSSGpN6=xpQsTuz|P3UVJ{S-fZhQ zu+*{Jt*vk9xCyzr;_=o8ibUpBCD{}+&AElk5*C<&1XJRs<7T#6{Y?10!ROkFF=L`Z zgS=67nV~8m9w~+emCW6Gr}eS_sO49lFHQaa{-MLq$%Egz1~c;V?2m>mvWiQ9?mzAv zPga6hvY|ZXi>$U@#G$vugp{AffWN$3|4#7Bn+vf!fx(*{OZubf(8UOoEQX$tbohqY zJ{kH-FN;!9r4P77VrXBhJvYLY6M5#*J{C-c8O*^Q;ti`Ygr$f95QHy4ey9VVx6lXe+eol%O(uakTh<|M{gPi6op4MEjHW!IZVN1TYe8izc zhu~=1Ruj;?{K{X8FQ0FlrLA@|V|B%=PiFH>mTq*cKW2Nhb@V?GhpYH_YEsC51cVDG zLo+#Iq7OPE4wg%0#S!gYh*uSmX82Ar?y@JiP@aRDqZ83QmumuOMjfuE>YNf&C{89; z36E(!R>Ty}v@EAExAK~ULZ(n|~dj+mU^gC&G%dStU4HXz+eOmdDN78ncbn{`fo zW#vbl9Y&zm7!-D#VORQ~_(&e%;xG+B5a|UtzM~NCK?@y*qyQfe8bc*81_X{=IX-os zoaR#E=>;bfgG+GsXw=g$57_Z4)r5N%$CCNw=#IZV2XF5!jY;VlGMNh4CrqHe)$vk` zR&!5CIbL6iGzaG0`VjoeHof8=tAyY<+n-#q?)!O17bVI_?zNzI zBHbx0hR%3iNq_GpJJXlt>pSR=B-``)5mM&>uNH-()w2 z>uTxXKxI&9Tz#e@H69=w0Wx5R&BmF0%VimxTwnbLo9AjJ1b*eii(%dadpEo(T<{eP zj={bpZ0@7%jqSpAqx!V^!IcjE50?xx)IqkQJ}^OMm=CDVC32$uOx$FQ6}s%Z>@fqU zN1ZlLE%oI2P*@ZSmr&5)0IZItYDH|9M4wN42CMDv^`_)EObhNBW+O6vELv3cqN%vu z`{5qD)>o#^j9(S&2BW)z+Pc;%Ugvq*y06*S_#|fkvvqx)>q08K2DD@(>OjHRz9rTT zH*}S+Pw*eQjmhtLJnPNd=r`XUto!od>;EC?T;Q4B|3CiS%-Td|B+_MAE+?|6r6{wc ziI6(oR3@a$q*5Yb%Y>qaBDti}^&CY?7s--DNTouQP&yJNNpkzY_WSp69*1t<^DBWxZoULO&)mr}R zj~uCw(1dQdFgjiX>Y8e#ALld3W_beRlrleUTz73MO#&t%#JGtdVdbqrYY8b-Ibw3i zh8N7C`H%yBsg#lz4O3^D8MZ2*MhjrqFeDg-GoZ&&IKs(vtPzDUxa4bLZo-CM5U4de z2krx*zC~@H^8BwA)nR;>bR#1im)MwsorHcmVYfztJ%t&1$W|H5kTE z%>-o&6$htwixLQxW|%sJT%=&ZqmU|^QnGo3^q~nw+a%|Z%GJw^sb5UTFIj53_V89i zmz#5^RcchlsakUBuE|Js(Z9=&Q-jV@uA|6V#h3-CBFI_rI)x0OzG9sPR9LDm#=rj) z0^+`h)d9yG#@_$mCP7J~#DW6@aITI<-13_+s)ZptO;t?Db#OXiPD>H?WmJP-+?!!0 zKZPV?NvL+8i{dlT+Kl(U#;IK*%u4<}DeW`s|Hpru2_={@W}vb%Y$~TJ@j>1kud2gS zj2tP{JnTN8rIwf1Xp_n0{=Jvd&cu$g_r(}&K6~%1!PEE~tSu*${aPE&iC#>tZ#xj^ z_3g3kn!H&R4MJ5F%MJXh8UB%zB${|1qq{aGub>DyG?urK*ZuTICHjAHT~WLU$E(T+ zn%kVHeUH*-?}6^h|M}mu-qn0r%@$=4w293?4!>ih_Lm*nnY?qcUtQ9u3u*xD!5{%9`xC3|yb^EyybPEr2$Saqj+pklm=#0-}Bf&S}{S!~~H0$Ksr zc-n>Ae^$J@{if*pm%o$^9Ktgl3C#k7InB~9;&_YQU6Mih9}&4R{fE>%m%#oT(8zVlw^%0-A_ufCZN96| z2{=!GCm$_J-Sz%p`*QWLvPb_rNq+aX2TZPehG-N7k#4i`+_Gi!#W&*h%cLTwSL;)& zUhlZy@sIxww~*3g?!0*yxAB1yC*n1jEIC)Z6bKH0d}kGy`|9zG>;Zd4TnG=dDFnzP z>XzQ5<5YOJROf#rV$_&84b3I91*I&Jj}lc87EdG0q$HsHXd*~c0Ih}fD2c^u`0taVo(Fx+jX_nPUb3#d zGRRYKWkqbZc+QOgmu0il_hJ1L98=Xl^Zt*2GMlDPAGkfn+xtvoo`B;j;<(bA2(DO_ zCa3B*kwx%mOF89yIKVUrTDpHCYD_GYRoezR02HN3LyRz+90ocVcQWPSL^!P>m(gO} z5zAQaF$YejonN^w+kC&VY10YbNm{wm+i7)+?&joHObn1K&Hs>?AuQ9ZeI>^+BgDp% ziYt&n+C6O5GGsVNNQ%P-Y9lD{3Lv*pqe3~MO(Cmd+f=5+hGVzSAc?~wBqT!~HsW{! z>+g;Z<sZ@+*k`%xI$!y#Tm|RQLh}fYtf6X;I5H%f){fsR`vm!t)A3f?| z!NUzkIAYO%@ec8Xd3X7AD#F&XoEQROhPA#v3Bi;k5^faun3`*W_V_^InaHj0@`GIO z7w(L3bA51RUhVU!1ZGNud+ebF=gu8c`774{Y23EW#fP-4ZlqBbXP2&OxN@(3U^pi5 za-R9B#H~9DHyx@U3rLx0&(OM4Lne1xKOV8ZXcbtc7WgyOs>% z=w+sty?HX7875p6XR>Es%36RiWug z67HPQpN)V{JtiHaxtzVXdvoo69i2Xy6*y?#@~7J~T`yqrC6V6IL2ySSpJeX;Vb%sx z&vmaKGrZc~c3r#s?LoougC7kyb@+LGQHSAkQE$6lPf^K0Snd0;z@YQ%TvL;`+$1K+!Dim?}Sq6US4jIYZ<#+Gi4Hfx+KHPQvOwEud=w{G3KNH-80cC3a8w3CRx9Cv&FCf6u{LesNZa+_cc7pSg>!iPK?Rp+$Dr1 zN#}NlyY;U1`j;-fS@1WVRZ#P1v=;vI_dVS$qubnyUKc{v1}X%K7o-^?zz9jZc$1hq zHfy4>btzb3%u42HW4#QmFjkAY zQklJN`khjtA)O;2vynMa<_B5^oq;VNB9O>(F(1ZQGNU1Q2OUYeU%!e1cJ7?e)!RJS z=N9^M<$(GG(b5&2S7iaBAUi}UQLO9I3O5>T&keV;xJ9k__i!�R`2^7WV9qT&Ud? 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

    o~^|m-*>6di>3gKjI(lzqyYaDC_ki8Xb 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 z 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 @cKegSB_Pk-5%uI7J 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 BY-MRCr<8$ggsRNyj*T7^i6P=hxXSM?@(J>k=Uw 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�XucmJs18ic{40^Iw&;Ll@`i)ZGZLJq-aDc4 z62PJeGeo@(tA3;|1|uJncO{M1m0f{P-QM|-wE&Mz2N_J4UeaeF3L6?ngv`11% z3O!3`eOhgrz5Qr?EoVR$RVIcVy_j&|EJhdH`lP?=XN1ZfDmxf5^?~xsg1^s9oH#L{ zd6+@GC3#jcd?dTs)p<7-hKCx8EqX*+#)%L=3wW@N8v( z%qY_G80BNdN;~o@Mdtc~;6bfim2Wi%sS{)_%EYqoKroz1BP_MXr#UTYBMmT5Wo6?QE5j3X_#swCGKD+-N`zmNUBM`}aG`4sgcp)UX=j z^d?F-{GNluORimXyJObKmd_d&*LE#RNvQRyUptU|et}g~IUAfqG`jR%&&67H#AA|T z^1_szs}-ZajACJ*vlxTnJyE!k&J$g^aN*8k|BX zX(2I#BNnSc&1iE;`F3%b*4-1ubRhykPv$hHz4P|C+^`4XjV{WV30zeb4rbp-9#wf3 z%I$9KLMAmv)&Qm*dw{t6QHv*~tyC^lqc-s4QGPNNFU1Aq(Ho9`M|R)O0^^#UZ>6I+ zzzJ0{Sd;zLqLs=$nb-GcAnab5N- z7h#?4Bg2FOtlk{lCa{SXpy^tk=D|cvWqolZiW)8Ww{XZ~n>8VjPiSBy)1RHr*Lxp` z;A(|3O|^xz*y@XEcNxX3l2_eUD~|rI(H5W?c&OGbV$~kklt(9*b++YxZQ(j6?F7*f zN4`r%n47p^iNQ&3!nK8QsBB!7%gQZ5!T|7^hPbjJoN!^{m5MUho~O2h5>+))X_jgr(&p+{D4$ay56jsq3dOHUNe zwJAGnT9A4M6Z!J0k;`eTu^mvKz%qo^nN+u}yiQl)${n>3_#el}AFcF-m+J-RuG*Xe zgoGCDPD?ltN+n3C{KBRvy)MkFsJ6y0+*fvN;?79TIH!eJ%$U~d6Z>(9nWr@(XXcj3x z0L3#n4cqS_&+^WTQk)Q7Ajp!Yiis5YntBwW=V9C_pi7~r@I!{ZK`wo zZyqK38c{yn3Tuhj5NRjLV4d3)R^ zJy|#G;OAkL56_$lT(Cn13K9xv(g-k)C&+`hsu?D@go8khEY+_bXD2C9fpk!Y{?$mZ zeA#p|0efB(bT+^mWCSKmN;OLXO$pt|dP~`Az=C2Ksn_Qw?S+M_OA2kiLoX*Vq)RVB z4S{$>5(sY;dMt_%iROml-H+reS^*p~%LvbaQg84om2yhPMzIN3C(_Bu-YRjGF)H5g zWK8(JjjcN z+6sJORKi7nJy@YJ@)(0(2$0e}g9tM8l!x?ZnugP=fUz%+faz z(gsVU?_CcZmms?IhnOs6I?{DncAt)24hq&_YQlULL(-z5d?`bQu@KU33#3M`65J04 zQcH-HF~doUVDUtAvqoThSmJo1>?JsO2uulWs}}=eu(B{PGPbQ2+gU_U6yI9Tlk& zDM7Oo`puVMZ?;pJ{5|9lwWXh2ptxoq%0XPzcAA=Q%(*d#0M8Ufl>X*(1l@E(VV3OT zGU%a&RPWju@Tp%1+MXGrE|8izJwN1lei$PYSyre!C}#>#`i%Guw=ud-)K`4 z%jORR%1bj*((^sI`lHdvNY80JppQhQ86MC1Z*V=h5zBGF-=t&lQxq{njd;SO;l*3l zv1Sag&cLCY*fN%dj@SmCH9YXbB>E-_kxs{L`0n38iEtZiUg%EQE z;POJ+sUFG>p!#ttp@|IiGZ6?KaeyY`YAur^ZMxAnv2SVL4|8GuFn3ld-!(t?%o?-- zNFiSe+Dd3>)%J{}d#0Zk*Xl!uxSh+W1z7H_PQ6drFP}A5TzJ{7wU6mKc$N3fsa|J} zIXPfK!rSLA;S;CTAofo1D#~hSM?@QnI73-K(1M`&W;PbZ{H(eU4_;kb73xzz=G?bW zf140wmf?nk1R`!B$P8j~_ghJX05dF*{zw#COne#of(*bQXqn?;Lf&N?R{N3+v^|7O z&cMk4v@9eE^*w+_4uhO*KN4O1tpk!)EMkq2_t_p9|3M3mpPbx76&#n5)VdD*;!MR|gy@c91l;QzA9(?<7{57za5 zxcT6U>sOL{29LL?{m+z`B;$Na@G`t;W7x{sC=KEn`LPhhKnpMp;eP)W&?p(b=z+J4 ztsbK&JDZPD+YmOo{}KcS!a)koz;N|*q_SoD2m=_A!3GoE_OKYXCO+<7A_KH7g3Gm# zN?aD(B8y%rG2>_T7+Q`f;2I)m&r60mJi;X-?uF?^$ zJp_XXvpC;cY$}FtR6Ia>83!}247HZW@p6?FHVL$tg+kTgEYp($aU9S~)+KB2`PH z2E34BJ z2$r5eeWY^mIZ$NEHP3F!k^Un$NInY&Jw@vPEmKH3;q$@K(&)y4P;$CSd@rYhrWhls zqbn*}7pR?S;#K!f4(mVp{8aa$cWSyCP-|}`YE{>V!!aNB- z^%a;=dFtb!st3Q*jcbT4VKcY>=E20(jFE~^rb5Ppm_*6J7I!0f9le9d2vr`Bsvt(% zSSr4G2(Ab{*53u>U+E)V+@oFL5ULo&F!@-J0RA;6EIKeKw6E*>6;ScQfc!)>_3iD;*#pab8!rkKlcgT{ zCX&`9I=_^ObInCKp;_YTi{%)GZR6ldRRLI|S;Z{GXUP~O9yETrv9$DorR)5+$Rx~e zT>MV|J2C&<8SZwu{yh27`LbXBXu7ob$3>I#dyeKUh)6jIzIhh}!8exQdpdLTOdpX5 zumB$gCL9#T$V$8!o*-A+bRY^0_~RXRqklw^Zoz3zcr{01C56ifc01FW9kq+=r-iAz zj7_#;hAC^-!=W8HNS>ZV8=Dhuk*VX-2n9zea=SQSd?Lk^_svLqp{br=HMjEEUc1Md z99TU7ANoVajSwh%4B`Q;oy4Qi5kR5Ai?KKu1TZ5GNKp=f2!$_l$qB>>aPbhIA6b1W zTtkq_92v)ru?lKxv@K?DM35x$I?m((jj-+5s}PiD!vO;5Qy`Inl9jck5W|q?MIvW8H;3OLhI&;3=b{geu0vbfF%OwsYgg@SE8euGD0gHkqk@2Kxf(g{=2u_Kdnpq z@ka9+a4nb&h_jb_EcdYasPz2p0bv0T*(FCIYin$L@MMy?wTuV!v%uF1)}Y8>6T#)? z=V$G03A>)n`hMfBMRg;*kP>U8VZm8`HShh|1Wn@z7q$e&4-;~jI(Sz>)+a5 zBniu?v*{|0LwxnTX12M&7yiASRG zRM^91B8yl7))c{jCLR~7MI%!&XDyMI5AUstp0+e%eBYyYrr7gw5;&dCww)nMuYFZi z1~}A{M}6HGUbQ?HD_9+ZgPG9UNFFfO4h>9)-3qvXNH}Iv!%M+uNZ8^So|2v@HEMl5 z_<-P+Y6rD^J-P!`IzuaSVfHM6pAd)mmT)l8-Bth@M}3ClTz+HDLbbV2_ppcM^vUQC z36lpQv=rk~(*aq@NIi=R?2d2NYj^R30sx>~a3zffU-p-)zs%2dE=uuHz}C3)it~H# zdy@bJa;fgpxqT;I8w0avolW8~aOlg3qVwiBfk~%SaNiog_=m>n)2nN8j$+<+tykT( z>fVIRtgs=FCVC&xRb0eSI6+vHd?nc<0Ie!vMod{82wg%AAxe;c4Rbk>2wX4%GGRKE zj8sWfp6&S!5x6EnAg+Xgq8@^F6%f*H;y0ENJqy0p&=jM0e6_(47qd-3ukt?2G5p33BglhpI*IaMfi?@1HCen@+04Pu~U0YDvTS)h$Z6~135vd2m8+dxM zTcH2|hM56$0l>>-4CG5$tIAIH|I{l&+(l2qpRHc8!Up@eg-ZU}S&>d`gz z-tof0V!FATUz7Cjnb?@T=a;Ky#{PBZ;M2LY=tK{SwxPk8kS1Q~$?PRYSO!qlzFu5t14@^35^ z#Vxz2O{ zYMKKTAQ=yO7nqsa%PxXrghVP;&tvaQ@(V+&s|AypZLTNr;4>TyCf_M=gyPwNG@LP} z6~90}ktL1;>rjD63@icT%$8Ad0HIp3NX=AmL_(9!7MJr)qQA;`x#8{0SJ39oTe7D* zZCj^Rn&VE&UUIF@vrw0r@qBUrI`)x>@xGJuottwKdD$lvfEr^&gFd2yZQUfJsZ6N zr!+Zp(t=YIsSDL(pkNnzsVX40{R9bpzCW9I2f$jCC*{XNS}SrB43oDM8Wyhx?@+PD zwl`w$nF&d{rMjiH?`0?(0!(=)_N^K^bSOMm`%YY4ItpbZ#vScB=piw@(#z07(ajl) zz2m_CM<<^yl}!J{|J>Czt{XRwJ-_t|uFu*JdS}f@1f8ROBqOlmLy{|&IEiLoSB@7r zHp_ZGY6pS285g6V1qUf6I!JF-1&(pB0g$B#SR5|`V;52tNK$U1)!s4)pjGyt%e4k0 zXNd_qcd`sUuZ2zorBN^;i8C5ikYi=;vIqoj!{tfO7tIJ0iIhGiCNY_O=vr@>d(w96 zgQNJq{H?8tN=43(U6|Nyu5ZlB4wd{?*SjfikCXf#=s~igp}daGap=r{nN&U1Afptj zpBH!B|M~Hi>QItKRHf4HiU(bnbCloM;)Zx&>d6!EB@j*RSnbOtFgFS0@v%QE&jQCY z(xnLn#MgLypQ(5Vr6vH}!*GEn`cfGaCBU~<4?~BncgVkbs|6W}Oy4LEUdO)7@@yZ5 zi4?JdADWZtP{;`kXMd{CFcEi53wVrOIknLysb z#3?%5xWM@6_sVrZe#%9a#&uKN3=#~Gvbcs~4RTH7cULQ2kkz6%(~eO9%w&5JP$HUG zza3>!2bObFs< zpbx+6J<;Bkw$njXltBOwjAmmCL(A)l@+9Rso)UmPDv{A-0`d)rh~{Qu!U$BE;Q)ab zn+TUaZ6#1&Y-_TQ(2R?Q0ZZ^+T7EGF1V2)iHvCLiPmiS+nhav)^`!LVh^o@v58Jn} zSH)V-ZX9_t;avT_#l_MZpm;s}Nrlx|b8jFC~~ zh~NL!k+)WUdg4y|nssf}UDrSFlqACV^YZkpfS275@4oSwhlnKXd!`fhs-J`+@?(Xh zbeCVtD0jNBcDC=P3jDUYX(7DGbX+0i5sCvAI3T(8$HN1}B!-u03+KaMp_41v++5c8 zU1Z}=1$UOzHfA!#U-7Nr2WkUFhWdIRU?X~)Plu)srzx;YpL-JBrx8wd^Om=LX3m_6 z9Ftv>);@b^jlOpD`uYDdX!4G53X4KLq*p93C`6wmbPR{v7R@w00__&Iz)TGZ4PRpavC^l zl)6*>A3lnGoik_c*_499k774CJD1@M5U$Odv-EEsXYPWLh-N+6n4>T< zLI_e{PcEq#U8=y|*ZTJWzth49&*t$OF}x3Ah-yGqV)q(tH3&?c#p)H0E2p((|f!fMZT?AN0?Vjv5fC_ zqeaN5+?OY)>7G!20oIeDXEAfXI3ak}bW_XAPxjWv-FaNHY%SySGaHOxWZk>c_`W%q z6a8L==6YGD6o@1x+s*N0!R1kF`Mv!p=|(~bPhfK>R9Y`zfobP=_tqRgye*Tu7* zC!qz+U3B@hwh+Q&VtmS2x2|GS z-Y2!AzF+yaN{CiL!-OtkNV4q6UVC1(4iynpOPy(O{Il1<)1*MssauYM^Lua<9edfv0M!w4e$KogLH5in#)|b-BaMx`=;u3 zxAxTW<09oJdz{F1cXRF$VnAEO%IY`{1Vaql4qKBzg76NSj7U3zTyWvhv91`~Ws7UtF&W7M z{nthXhH2oEm)JnnJhsn5i+!M#7ItL8+B|Ytu9B_}4G=jL3~PuG14>|63XiozX+=5M zmgSRms;OQpJ;bC6h#Ca~i;E&*Kxqzg09dnmU&Osoi~p+zxng2;o&Bn1SJ6^PHXqxtM)W6Gq^&Y-u z^9SN@*L*?|AvsZn-U>D>Kz9t2>GeE2>LfBOT8C?`4X_!@S6_@N&+`5K{~Y&Rx1q1A ztLN66^$|e*BRl+$WQL0K3S|^*sxV5Z zCBOM3$3hx{P`}y`+DLIj2nR^GvE*3ZwH&eTpX4;4dE?=Q7M{@1=7I0 z!s)?m8Dr4DovB#Z1ET$SJ&fzUsDT(SiiHgh+&mGOUH;nK+z-mX>=eU^9#>M0&I^Gi zHk|f*?R_kLdkcCM0Mmp^%C^<-wHB#UYl>MIb4Cn=qf)gu(NcO+hyX&|zF9kee}eYt z{X;VkO#I@^#F)Ilu4H`t&)G509&ffkov^(Va?^t>GS^DDsQH$3%re#DO$qW!VnpFgkV`^%Sa=9?5G{a>CX=UxqqM`7ZjTz2m zmDNKR)ueK$G-`*+P(TTd-msw>NQ?)2P^|?Z$uW96Vaoxv8t>hpTYoINeJ5s?%cJRBWINICF}m4`9(`~<-pNZYkyqDSpQG<`oHG9 z`TfhqFRK>w3ocyyqHo_T>%KSp$G-`eDdYs-a?ktP$N#2mcsld+KigujKL6j!qJZ}| zr>y-W<jQsNEAVq((Xj<|OIsttyJPmiU2NgK-FTLa1Nu`$)^3MVWoqIEj~ zvf+nHB9}7&t{9tCZl@C&_tF1G8Jqt54^e`_aLiE*(A?(de0uuX&7U6C0N!g~abo&| zrEk}OzkyaZod2w2uqF17iy?n2H*~*wvT9xL&Ix1qBQ6zfxg4sT{lEE#B;>sB_7hxm z-;is%tw^~#HeKIj*WGK`G9qNzMKRowwOX6$($wcSu0>6p=zC9c{bE@ym~gJa7yf6f zUNc94yM-5O6cyL+<@T(nHF!M5!Ymnsdb=@x%NgStPUf0btDZN%80@@~M&~E#d6byT zEKS}%Y}dS}U#BlyJnov@Y0be2)H5MzUI5JS#=uDkLORSWqV`%ZveFW$fu<&dx1@OI zfg()C{GcS?b6sNIym@Blq>XTz$iqKKn-;jD5kCRDjHqAeedGn3t*vSK?D(wozb{uM z;2|GQIU`Ag%Vsx9JT@qW@C*4QN7A8@P=Q;rfmWz8FjCo303kC;Ie`>4 z6o|E6xYbcF31$2e7QI;wgakaa7(KX{`X)9cTNW*5KE@q8NLVgQ1RseQCKIbfJj5e# z#D@awlERUp=0g;taKYTKH!?;om>XxnGWp8m-S58M=<#mo+^=Q$^>@5cqZSn5*U51P z#-E=xZsn*jvee#_WCiQJpR9{DLpi}2A_YRj0;U~JKwcu|wlMuj1!dvM`BbJId3fe~ zp>R`k_^KcQE_deb2^Jz-j-LWAtayD>GYGxnv4_y!2O3E+2K@@_7Dm0R_Mz$Yhd%(#$MO7i8U z$HN=Xw|%y7!@Z{^UFW|VX;079?Qys!)z>%OjWX;2{^wG-Vzw2t4s;^h2NFeZEIu&J z@EH@nau+H}CV&>)=ineRFx@1&0bBsB_k>1 zggZ3tM_MUdZ-97BxD;8?QjoOsS~L=s!=Y~=GF+dNLDV9 zu}2aNYjz$zO5DX|(E>q=X!lg1JQB9#(-ca8a~RTZxeulZM!Othpc&L63@fny1JxoP z13X8^vf90|8y>hWc71W{@U_6X0rE(%PRX!fN~REuRCsNUdHu+BYV*zBW4#YPSiNbz zarGQ=Yf-@W0txZ1>H3|zYEr{Y#r5DTg~qq4MPjz^h(ogr3heQHGWLx6LBuHPw978` z9NE+NSk>L|Rr3Dcu4%$^@BJ|SvDP;VzC@9->yVsaYTglCsdOFbZhs~j=HcD@bbjSO z3zpYr?inrFo{{zL?<-1q$#6bwd#07nso7iQJG&W$HU3k?=l<1s{;-#-d*sad<>+3$ zcg_&k8JP7Sh6izUCoK#u+#NHY;ls4#t&n`KY zR+k&LD8*X_0HrwSa?g4xWMEuH`Tg^p@PTlQ5J&+of5gzBVi~Tn9FqgKY>UT*C=n?2 zUaEA|(2~3Bqu5+{>4x|H> zOFL~^j!`>|Vz%L>wo>@0_aDt!S8!}$xbLoUeM(KW&Mkj^Xy2Y)GZQcaGZh|_myocS zrEDYhL>nYHS{^c-WljbQbZDtmx=H=;L=s2B5hHY|Y`(oKfTbBt!)_V_sRVHa^g}+F zUk>Ou7OMM0SOTmuNI@T4&f%iCPzuU(GPFOIN$u&?IunH^^ljz4K~e4{8D~~z ztz0z3{^P3c+siVNa=tu6u)A|4iMnRCo6G%=L8(L=mTxs2JuZg{gONsF76uQ<{S3JM zCB7Z!0sJ{2;Q#~J58)o{mQl`_kU%xC6=KN$ZpOykY1{B>)rLXWxu1~tc<%YQK6@Eb z$ksp1`1rGhZ|mBnsHcYB%)hTYws^w@_}R7uRt`K#-|+9Me>nvm&kI)dKRJPvHL9m9j0Ow^L4f+g}|n)AQ%ZHt9_Y-M+HrjmJ!ZoFd%Ztj7QYk$k}xla9!X74h^taMo-Ka^I;~xoZ4ZX^~RzFVBpY4H?4W zYKCwa8%;M~xlXn^rO$87dQ$2bA;756$H1z((397H>)X7kS=Zwyd9Q?71GEQ29!y=h zgW#cL=@7#QL}lEsdK=1zwr@(T(g)J*-W$LB4h0h^QntM%$5Gf*bwDUss2qf3|A}P+ zXnIc6^=983SaYMmf2Qc0y56XAZ%|e3dW)dg}kUbgAdr zhhrMcbjQ=|+WEQj%hS%cv$UJ{XVzWoT~QW#@ap7r23B^#Fc1kq(2#KWgxW!&LF5S( zyrT0Dr)Q?tz9l>&Ew+|fARNs7C?R}TLaO2b+BvuU-WB{Y8Nsp4t*+kzW*O>TOgZ)5 z!2OTO|2f~nq(7hx7&SU50$hEy5EOAEM*VQHVylf7_yth_&1KjtZiuPyN3iPPfQE_= zyHW%aJhU8`@0c*uh0<4#k9mODgzR^769qb;2v9F874!VBmOZ*$#Xko&Hk#(3ZvE10 zvk^W29%o}V=wa+U>oIxrCL5@BEll*h85qTTIc#I36Msw-o|7t@Rbw^69nU7bS6H3% zLseqLUL{hUF`gxO9T$qux8z6fvc3g@h8VL)3ZqK_*hmIw4b8FfOPjzsAFrJ~tc-<22}Y~cU3;S2T6&@e{Y?aqHaCV;x*E|z zDo`hhCA!nV zuPsdZqH*TbKj&?D8M5KV^(U9dzrH+t-TzIieEECG2QTZ#zxn0xlg~E%ee$%?jjk#P z8Q%Z8=KSMY`Z+-drYy>Txo1PcKewmU6u-Fp#M(Rm6w=wTP&n^baHvR3Mn$8}5}?nZ zi6t1GGNkQku;Brp67m=zN~pJ*1sSFY2|7&BEd~;!C=-e$n8Q1w;#HuZ5_T3uyYx|Z zV@?Sj)rh>XRyK)SNa0U_98w9N&?Yz*V2NR?BcGD=Qbe&ajKH}DAA!}>7TCGslvbb( zhkg^>3P920Mm#^#)SBwjEhRYVtan2p&G814>A~U*Vfj!dUNiPN8)auZ(~nTXmIM4s zLSd>xXnmv7XJwX0_`Cqi4Sx}b1%Z%@U7@kp9d10>IU!RD$Z*VWpB%sOfjuy1>3lfC zOh&tt=w8_K}=2go@-+R^ugFg#f81yypL)(o&BOd zW-`O!uq__%J9u@CpeB-*Gnn?b9IcoO!Yw~E8U`2!Z>$i3Ct(y5Eu#RKK!1u7i^PN! zx)d8}_-|I>RU)=UfO_cd;!`pe7QQDct1b#u(P7Lnj% zC9q}KvgUa3am_r?Esz4L9>K`7MzTdL%w5$G2Ev+K3m_Q7o3H`y6ks3 zJFH1la0J)r?w6LFI8`3ebMw%?@lyNBmHT}Yhy$QVY9DI7ZN(!dqW^mz_DCEFI%DGE ziY5IaIM|l>X(cFc;hrauQ3jSOBV*fnv_Kg65hW%TL(GIXw5*j#rFfie**h%ww1MCH zI$sRk@c3NGVpsxpCzYpcxNz;0Gmk(2_}|&PF78|RG-dT!PIuoQi=X|$LeA9&Lbkp+ zWc}sC|NJt3(W(odJI0=F9{Z;M(d(BX>;4MS=j|XI&9ICpo_}OM!Dg5yGSt=H%Wso1wP8VRVtK@(s36&86CrjG4!w9`IPhpoyQS+-Z+-R|d zAVjrCDNyOxEX&iv!d5jD_ATw;_jGX?pOm1Kd!LR>oEa`v8k@Rl_@;pG+4U>hU zf=9v3gQeg`yBy1gN4j?f}KF|I(BJf@H3+48%+efIK@PuCxq(MM^TiQB6(45*U-%~ z;q29uv!^0{)TogPg@P@HllO=c5^+(gH)!k*{_#WaE42XLbyABJMryDp>PqYT^U@{0 zMkox_W@u@RF2h(H6bL_kJtnNvaAOFCUT7Aie4x>g>>}oF&|fQ2aV?PfRPMwuqazEL zU!p=yZ!&;X<=K&=Aa!mZ43zAefl;+|6ZpM_K4@B1dKT9+{h_}*$C@ng92pQ%+I_i9 z)5_tBG9cPRK9)mTrg7-O(dp0#AGRcY^T%g?qA7hWPZ%ajsCz3m?rd*wKMH3Zvq=)K zI6!!PU1Zahj71zqB|_E#rpw9P*%TXpaNm6jOYN6 zu`v@TBFZo1qadwB))$BkY6nhI>39!V?+hl!H{)!Bldd2`v=|4bLyzd}*J%7NEN%Rv z?^?mr!>{%n4y)SmRm%FaQyv|AeQy2TklO=&w|hq6FhFvM+kNuMUxyz@IXAq1YXg(f zvGMFry(bvvduhMhK41ihkvhx~DkDY^8A4KRn;Jx$CbW-&iHjE}Lrn`SD=z>S_uXa1 zU>XA~0@cbG1^f(K2Gx$3;g~-Fag_apmF0K(&C`G&FZ0*Z4+3 zYgIF9^on1Di)V8yzGC@CVrt7|8SVGPH-`ZNYJT)s!lSo`-`$ zJW?T0qLOvQ&+s^?uNT!f0ohp~^L3R0P1b2Bk|h$V zm+TS?WUVZO3;v`+Pzd}Z=yd}onYKTqat8VvxQ75%AdLIjXRWPHDpY}L6qSF81HYeVc^=s!I)nth5|NfI8I0kb0TdZ7ayQ42)2;SRAIv!+=$m`X0 z6f}>hd>l1?u;IvyyI1Pxk4JX&n<=MXAzgRT-}ho)4_;f-cWvF{X=9!Y|Mzjr=GePx zWUIWwuuMGT^X+FQDWnWus}D(G=SpN*lj}*dMnM_Ll*hayMaz^x z#3Ppvj*4QYT%kfmqjX|x5(pqsL5%^%5)nm9uVH`<0egLM6BWo}g^GlMaN=$b!mFFva|t@aQqsyXfCGod#ZAei80Nts7JigiX*_8O z(hpg{&SV&Hw#Ju`SVgEKc+FCTowQ^IAZ|z@(KEyvhd^yG7h3uz82D%~3^oS^*Ioe@ zri$>C^;p5NXTYx;f43**{#f8LJ;tZU_7$7Z6zX7&w4(pik(q;gmVr>N5JBv#~If&+-hCIQ`Qq>Lxlx*$v`SbqZwv$8cEEk7f=TY-_ zXGiIQfji_*Sja$JY!BjU1M2{fi8Vqq9vp6!c#7+$>vj;iGs3x=aF!F&8{A-U)h0c= z8KA6ynCmJd3_6h*LfjJgLwE?$Z-}8trjhMJ41YR;B`K}2=Fw@zU^tJ#N87^W`URTI zk(AK}ewxKbj#LHW`SLgfRwLj5_|d}zV;doagncL->l?);RYV+P<*;7$son3q?SG}t z-W9IRPWWV4bq-9sU9ppXnE+4?^Xzw^0hR--22&P&tb^UH0M#8`D_nT7ETnhW!*H@a zGd>Efw*Mgf01d4yW*Z&p)^0&@ttZTQs=)A3Z*b2$ zwLf5k_yT-!Y_=oFFG~e9 zMUyM*;VlMyRA29{kEkrCC&u*gznTCY6T~tmg`Yw>MZwLEM>zSD_Sfy2x#8)q4Nof{ zJ>_R#TsT;?Ip(2j;NFJk&o}IQaQg3UrvvW#d|B{+Q&;U<_t^N(ljzvz`MpmYu1xk0 zWY=sZd?qD?0dE7T!OcNn;AR%bT$*F_);CdNt)+kn#LQm~ZG~!Zq1Zw&OTZfDm~l3# z%q$M=BE$qK8xs68+%M=1K~V6=AYBA+d_5-6j?}v!LEYuW5R+({slmh&z(SVQ!@x1KumB5z8_Nemu+tm|IxI9M)}d&1 z<(NTX@4``0&mug4G~u;Jve<@5G@i(l1``iv?V3R3Xt)@(3IdHEM$UwQsREHazwmf7 zdtjk?wQqhb$$31_T%{C(_5qReV0Oq#$6UiT2yvae(K zaFDRkU6!{$d|6l8aC!rQ>kI`fsxKL#z@0&YJSHZLpsp174&1<$PLGPZY-9R$$I`}I zuGAHciSrLuEnB7=6LIaHWZoJkMN_B#{3B*t3sWhO@$p3Ta1O^V zGvPQD!?Tu)X%qg4gH6UaL-)~!iquWvCAc_H7>zrEAV?p8Vj@qP^w&e;l@KJqBaQ)o z2aSW0>9MAuVn4#MnaMnB98Pz%20TH+T~I1`aR1g9I}~Dt3f`CmJ%kz25r7E_z-&zj zB4$VmT2kZj+sKc-Sn>Xd8S`^Xw8G2E_}pn>S1&ic`DTAK+oAU%?vgOBqcvYW9)pQ; z6^1$yCKOhwtw84`Y*zg4^MKi06b~n$WW2sU4mTU>2ckR?NMX;5l7irr#T0l#5p@lrYUad`5$UvK^-*xW{Li(A`vk!NS!(yud#CbM(LSE|E0t$sP9s^*8vyB{8nj&@I&eQ(myF59b9-}dsX-PJ2s6daA2eB*X( z>X-Jjbe>_<|?_0-$8v%n0c*G3X zRK}t*-4Tg83EpDeisl#D8(!>s^!n7JSG&)}{B>#ghDndlZTKhK_3z{1UkX1wcrNB; z{qtL&-(GU+?+dqIFugdoP5~>_3+zr~6Q!upHE`z&Bpz3j=N?UTPym5^V8jADAg`#N z<202yAI7|Dy8pK5DtDRB4hB`0AKO<*f2IVBPVN(ENeo48t510`2LIs@@Dm__?x3Cq z7Yfoe(CkqMz^Vk6yo1`Fj{thffQ#bX?9V2!YFeVVoJSm`03Zwe%;;^#!bt$oXDAZI z5nb4UlnAv^!&A{{uwY7)OONPr6A7>eyaEwyuTl8}V#ZlwBcW~}P;z%b|DYh)fvhM7 z7E>J*rCP_f7O04WzwXh5JVw- z77K!a5YtN_ZqEmf&4%eSP%0=aw20nqpYR^n@C}`!cXmnF)wJBxqpOXtr_J14Oz)XN zZTD#0IABOS2oB3hNL%e{7GL?~V#H+AGXjjEk}>eC=))7c1-LlQe$44&%JEC_ zVk+Otn5HMyxQE4{-`zcqcy<-`4dS{XhZ@4ByLm5S<>Ko%Z{F(0`dywiT~qx{Bg{-s z_TTMaA3#@1|!JU|FG5_#PnVX7!YAc>Z^YY}(XRXUxz6nXjOm-e9AU>WT7z0L0l% z%RL-1Z^4&Oj1$mFUo+6XVIqK&6;gS0G~|MyA98^+nbRksFOLOvL{`tcwCyZ>6d#~J(T+t@e*A(77@Ichf-?m^_& z-~RzK_PmFw*PfnPdT8Cg+Sz~AU#Jaz`uGzrTZq<*4-&M^M}Ibxfk_xv2kKMUf=Ds` zR-xKq%h)!UiCI{!Z1BmLeo&fl(_00&7vh?c46sn`#>dL*$f}&t5TQm4sx7W4+Xo)d zuK%!Y6Uk)Y+^2Oi0A&Kb7<3{c5M1Bgulx+81Pf9uL-9^qA^VvCg`xox*?gi1SlzkG zP!Ew#lmPG0l{#!S6%6EPfeDF<0mWY+mVvp@+li5F32j;chIgTZt%h$o5w5`@fxulB z9lYg(ODC4O8~#SEY}rEJNhHeuyH*n_Qw_|uv}3-e{kTF|6gtn)=#I*%8(uzXJL_~x zyt+rTju!16-vgKX(IMcXnBeP78bBL>WTF`=D@q$Eqj_s4Z%lDfC^C$uIK8es+i%mQ z>fTpp{_%d+eN>S-U`Ul@0>{~9<+}tHCnb5t$m=eTX zihxHFT_}@=Cb?6OF`59BRSQhsia{w+5-7+?hS*_e$=OC3J_Fj~ih^+$X2&Ajl|pd_ zp*0orRE8ZiEti60IiLW*?Et%O%we|)L`X-a?^g(ipw_Y=XhGD%>{jt`?K%{2RA7^3 zk$OTLE+Nu}=RP{JyW`ry|5Z1scftE??b^-vCe2%eRVow6S{rzF`m%3}*PDkhj1I(| zvdt*V+34e-t^uxP#(-B%s0l9o3;&CU$7Kvy1#8R+Avuo-7@~rwC7=zQ3gEf`mV#yo z*FK+Ujwb|xUbw26e$#^+BLDC4Z@-;-)xYk+TN?(R+WKEw>pN@To0gT8dr{jR)wd$6 zdau=`Jkf10jt&B9CXo4jv)mLgvKgXwxAbCrp1+*dWy5*oL?z;d6Hf15wJ0UG?Fm$Q zx4ZMRAHBc!`Ax_)A5C3#>+|PJSO303Q8YKTK_??p?|1BbeJ}P!XUduvDYl!RFZzDS z6nK11DE?MnRoZoZ0+&-L_7u8Tp7=v@sPBuHeLvEFcWDo*v^-|+OU@s+Xe3vV6#^R&cml~ul@O&H8*K$U(TF$h|Z-W zD`g7MrOX#zv)GEjt5@$dfz45xvhJ&tbv3Kjyn6KJ;v?&J_Q?w;x^qwWADmfw`_-A) zA#O-Lc0jM=z*Hazb%PM28C2RboZAEwg(mua4J2grP!GBnFPy{_zzsWTD+p#Ph*tf7 zVwU6kj-yp(v1KYHo7nQ!|C4ksa81|iAOG#*95QlD#nDQK%v)g$EYw69lmuy7);VIB zjyCmp8d{MFUSN~qB}Wc4kWlEVcFrjWDrR1os0aa3SqY+&mmu?ssEFMD?_d93|NlAF zK^WWb`+c70^L#GY)&coR3-KWj7FC3b6ML&88uV5bYmn3cpTFl)R6r)X`{0auqi{K( zdZiSUz?756*(I`wdaFC@x?G?t`r#FZR>;=}D<&JhCO{ei7*ZvNu$7~DS8;nD1R+D0 z3G`iwMxXVu7`q5DT#9BHH$=G|^e56?2P+L|S0*2@onBMLeFe^dc(}d0AO4GGAt?KD zYV(@bvK3|jKC`gJ=o*LTMv^wKW{4n_=%))xAA`$lmn$h_;qbET@(QdM4fHIMN^?k2 zCO(nkc6kJqe=XS_%*ijUw8 zYhw8YcgyMJHi*R@k+yguPY%ybGPtJD5CBbH>szom2az6%5Db6hc27>2zUkboiU=jv zWjtPvk&QTflFQK2SX<5;&PD6PtCQ=i8>l?}+gD=|$vew`MC)B{jHPh`_%?=}s84^b zJnVmG8cVPF&fJw;8FuFQfA$-mZBn`q7U!sVjX-ExhHRy(B7jT`3td4hU}QxEzjZYh zoFnKYeN^G%=WU~`H7dAXy?UbwO(n8fYDnSY&+j~@G6%KIV^66}DZsAD;_=(i8th*- ze%#4#=cgZQ&8Q}c_?5(_#GcO<)GpTPbepnCO4wExfMoO9;=PUkyVcc6%x2xty=l$M z_y6~m&+?=(((CWl;F$lqNJcmtk*lgKxH@BT%CkEf&+Z#G@R3JOE!ldcq-0{+r7OSv zw&(^b%QR2^q`EaKfLN6Y}K=JbgCNo#GLJDPjnIR5W@ zzxSU~b+vZgq`Bj0by^ph>K`tF8K{ryODM~iOR!~M-Y=acp?_-<~YYT}M@ zIl{Ch;|g_3XO{8bd4r4cn%k#D-Tu#>hyPyC^^XPj?}TF0uUH zmZIBdq8?0%QazLG3e&PI=AqTQuyZ$44H#*?LKO&_0C>wM)zU9~Lo30+tnZ<)4RG`$ zURGY3OlU$zF5Ru@Gb55ugjyLr?Ow$7^&_Z@3{^@M^RUwCr>t#9LWnwPv$ZnB$ipkqu`9_fae=#wlGSjfGeopxQ`wnKj4`Z8#76PBK%Z!r*hHNx%zFIW zWPD$Bj9I3jr*0i3>S0IuNPR*)Ipp+h5pJr)Wc0Z>bhc?VqrU^UBBAET5C-4A=TAX$PGdAFVGbz9fQCt)eII5^c9 z5)$+zKu#L3uNKuJNF|8#>H)?u20RicgvePsot4M9102u4W~u-kb7UJef;ehTLMROHMpVLdS$Bi9dzkO1B)eDiA&UL0F zCMF&?UUeYRoJR*GZa{aX*d z$zR!)|7^Og|H4IY>bwPI$v`W!#|(bLztk}J(|tQ`+`fH#$$<;$UE`N-F_lI4vnFb! zP&IK@HP`OlSo8A|9BhgPvKXw64Ht`tUUEqSh>0hN5&uh^6>+ZRJ+&`%h1sLcnC*-d zKWo^?liDH7&uYH;_=WUa=Q^XhGo#jS+gbf*eeb0`KNKJ8IJSB9l|9{mEt|BZc82WC z{8cyJ3~Rn{Rvxe^t$D?nqNzULzeftuhl|E8YVN{!s@?BQ#<^1&cl)oddSSJ<|1<9M ztiAj0ywTj#bN`Xh*{weyX0ikUw)-^;9CsjJrGp<^+g%Q9%MLL4h4}IuK zjAp{%%9+e6oWQ6z5=n(PJz~ahbu&;)Y$m(0Dy9sAvBcu0Wi|M?NSjTz7&m@Tt}s zJGS6i5}+W1%;`1D)KwFsl{y12l}6ZVte+OypNiL@aH_OHNli0pisNJKws*3uCy1#V zfGIJzk;yCxsDG0)8BG5=(nca6qK+8lWN!>{nj?c%8s)|(#r9Q{RZjN9A(&elTb=6g zd^+?boxq|-3C)T>M;d|0Pbuj5Em4B_G{rQ)6B^0)Yfu=H(B?b+V(o%YrV6IE;Tv^? z78?8ztSMzQ$k^4pP7Wz!Zoowy0~QvAex)i%D*yx_WKr?#w2|Ib#FDeB7Zo%0BgAwH zlu>n15_}8*`4!^3*hIr@4w9LDiKjplX!yg@BPYV2+l1+4GL9-4p?Uwq2l8hc{rC zc>MEUkzhaF_84#P+fpq%Qb7s4M_eEvL6h8ne3o2kjA&T*-pbNJo@#UkN9NsR?PtJp zFCQG=v?c-5LA6>tyzUa`6-x7TmMoc@>^Wo&Fe_EpcI5zORKNhFAv_3XPA!|!+?szV$ z?^=29)?HH`f3T&zyJp3jJsoM4<8PY!q0t2l_$fT<)~52iFCeQ~@W-$7FaGk?mi5)a>JD2=SPgk#O(5qvxk|5M5!#i10n@G&V<}B zkT`CTEopjLC0r+rJtaERVX%+s4H_hpAP`6yl%jqw24+g&F?6J(&{ zUkKI^lM=uUuARd_)MfQb2P=(LSenyz)El6%ZldJd4PFW={)ULVtIo|5ncAT6x-X2R zjm5IC45}s;P-91_lnf(R{e(GU`*C6kBM6mmr_1;|&JloK$R`c#<#)Y`~$+9?pX zrq8+>$#HBL|I*=(X#s)4m_Y@Hf z9B5*_JtFQcVN)8BPj5t(t+&#KOSD#oBpgoY#h==%jv2#fhBF})1U=qGnmj8DY}T+8 zcN#?j+Te7)og&laZl%L z{hPz^x&9u0NXH<%#Hr8bi%nHP@I{-Pemp6$>z=N_$4MGIP0qCd4#g36dxgq~hKLCJ z_+9T6o?W?oU-_90GcLBwh#RJV{`u(HWA)0H*ZMoX8$1T1)G9SOr14dXMj`h3uS%;I zJzCI0Y}f}eg9npXn}FNw+$X;Lek{wqanl65IFU#kY3a2Ke>l<7XmCV#Uu)o39FH}n zs0L9J+Xez(m^{n`@RSxH(h3bu<4@s3?wxBqbo7tH@<3C+>VVw~JMS&%{D*qL$=XSC z*WKwV@A+@!tJ@E?{!sj|ZL;JSU9JgvbLrP(%8GA)acauN_|3Aww*y`|wA7|>fR4gV z#Lpf)pP^P2S2mJR3c5-WQvQF+eP$$Vh$SVCgP7x=o7E6GTBkcv4tIA^P+{w$ z6dZPjzBq4`gaSl+&>vXZFyGjI7*;FP4?-BBL1yACsNrPk1eTJ}C(w4l;Mo+-!%@E( zbhTxY79ETh>l~OTw9epv?`=(a?u)VVOf;E@GmrZEJ^Al)1y^ zu!qGoQiwaOkI)3ni4(gLa>_RLM@CQ}`t}1Iuf;pNp!Imdxq4bcYZ0VlYCULzOv+L% z$cTa8^kNH-g>2UR4=$OOfG&`$~`6{|6; zV6o4TV&NeuJvmI#v;$ZIQ;~3@DU)lhIsmJUt#1am&9liwRR*U5ViWBY;2+NbpEd-~ zOmzfQf;wQJOt&A+KeFw%kV!mfB}yb#yGBCfRJo3giqbxYsR9sAfwEZxT` z4Z$I@@SyF4jPL>njWFpAae6S;mfjb$bB<*0qHK7Vp%)+d?!vIoUKvD^OgCvO^j|~T7W;7ph<%_vI(FWu6Dc`@?Wyqt^-zaM z*{V;)h9Ost~R>>Wzqn zbG%wSav-DmxY7jC8lRm=0Nw*$jBiEXUoR-LT^=9>i?ta7Q?kOujIVmDN&{*^drON8 z9YgPk=JQ~@(|LeFk|+C_GozI*o)o@bk5Lw?A0>J^yb#%y6Rxe~7%Nc*1Hw9UtS*cO zWM<%R89b;=TzxpM;@2ZmfYMX~h>On{P?=B_6KOXH79Ur%S;lP<(XqE~FQE*%sDT77 z=k|FngN2Dx^o+xilTCHju3Lj3wPvD3Z%~`*$(dgR z-ie}r9U>KiT=InXpSD^ukGa=*NF?$Jba-5XtWwzzm%xNL9>3^PD*WJvCDzLVhK6&L zzWp9i3l;00HajGl{u+f9NR=HOj|KLnJ#ziel}N7KZ=|&-5Io+>m|PEY_$E(U1a7KOr4{Vz zh~W+bFu*z0tCxs-EU!Yq{SDp#!&II~HAsC5d8LzxIj$tm7Ny(^E3g~OGHkg)8?=sv znFgB?cQzY4J+HzM9cQ-|O_PE`M#E`A0%?leLaRK8|04DiHzI^wc2edtMB@~1+ zV3sRwA~nz8rAvZ`*pCm%!-7)?YL8@)#97~H_t!F=IV9wx+o@5lBT(wWuVMixqOK=W zu*-q?DxoXN@!GQmt13W*PguxRm$|)ETtj03t9)85Kf=F;#f8`7A{C}^jPv2Yy&^4^ z;-WL=r9Gu^M<+Dsr<+Zc_GH>cyUmw@Pp}o$mC2=8oUyCI+%za9Dk+$M^=)xjoM0w( zk&-)Iv;+>ZqQemWR$vV9Wu#O%1iDb9A20==A?TaT-crGXkr>?q1^B#Gac4aN2-EOrEz86QG%8(E9+n$RYCPd2r_BP_vsQLa1$j7M{ z3An@T-^)Nqp_3F!ELB$;oxF{Kx)5xzC1Tp~xFk&Ww1JMWOIgrTxxVeDT&9%ZrpQfF zQ+Sf0f+AiCblcY5z_JO7LZ*9c9BXqn2+n>ELEYZg@-7SxwLZuj9xz}lWbnju^>C{U)lk;$rrGGFr9Sd- zs9I+FW9Qb_o*egNF3KO-#2}R>znY18et+*_NRjs2hI^vBZ+C z_xR5SK*vl_$V}#W$rRUabhiD#;ILVPi4%Fy-^3gI+lf=tw{)SomONaMuawn#nKBjyIVk)Hl9{Z1zqxILxTB4N^Wvt|5AT5MqGVEt$_`0&nH>Cs+cIqw z=2YeyJ+N8iaD`)Gpu7riW^veK4q*C@lQt=U7F<~j7Re4S(x8oastMx!0mGa$K=@~z zKA;y@7!zO>*E^51`19@2Jl>EfLnM`YRcRP0Ah@y7u^7#C;-*|lAdL-DUz7MLVcgab zz~2b5rP(6ELwt{U7(l`j%p!+Z;U>(Q@u4Ms=Akd60lDD_32Y|WVG|FeQOK2vW&mlE zStQQQP+%d-_+J^5P|0#VmV0B1&_2(ps^DP@PI_v*or|&{#8D!60PWRWK()CZeDEdo zhrDPRA0D!!Y;oaaw3k%xBU0G{&of-3aEsTuxaS2CGv-&92>>!WW@zDOr(kF@!?Rjc z6mM?d?phdR5wmPSD!{F?9nE;n$hYxd&WjX7{E#6W! z8$T&69pOhKlgN57ppt{hX`%ZsIK;!RVn52+r48Nf)jc{`Vzi3J8F0VCu%m}lH%;f7USrs}}dIWJvipWR^ zwlPA=%)koU7MB1@(iL*)HOw0Y3?k}brK2%XUkz8EbH$dLssocs%6Qn&&@vaXSmZzs z9VCp}h3uXKGgD{6DX?L=4%p|2h9;>sp`gn=Sc?g14CjaUU&mxf@P})h&V>x^Ndr6j zej53J_*gxQLxsL1=Q>-1*aSf-vc$(MoLd3GL*RXi;TydSjWSlMOTzceGt%Z6Y1GS^ zesk2?c!E_tIq3cYs38GRpei_7G&5jsIO<#ygB8U~JxVIKCrhv=)MnxlkJF!B;*ywn zjOyu*4Z%ikWh8U8H0oS>n2Q<8C;32+&-G#e zBQ;5bZ6*!{?KzeQQo$fvQZ+Ko^~0`%SV@~q07vm;(n)7ox`1~5A^cz85;`d1VnAQ!T_gUe81dbkjl*r7J+yM#NmdTOky@p%%E?Vv95KFr%s> z+~BpMO{wW2#!=u9W;DPuJu7==6SI!G+f^`BgtvtNmiSs3g+QYtCCtH{d(6y&ijO## zhyg{Q1=Du%pLM27jW|Px0lUC!7H=|cM;?Vh0l#!Crg&Wn0+4+&X+J<&WN}QUtlI<( zNJLJ9B1z!QtBsMGXmH^Q!XgZ$X`LG)56Ja%8nv1MMnFaa`e^EwQ2M-0EC z#oJ)EIsE0wdeoW#QJ01;T>_8pAn}VzdCa9ox?vcH*=$cDa#NRKk zxdPpRKg9w$%a$xvS#rB6mfu<219R-d>Z`Z4idrhs|JFf4O?@hy(ga{t{sH!Hk(+p- zKA4A`kZo+$&llRahtS|c9`U5TqUAlIWd>TIfU@C~X0o`aw-bdZEm`BuUWI2#K}F=y z;G}k2tW;*kCyVvbDDEs7SHLiy5dvE6Y=n7sWi9>Gq0fq5!{J1x_bc(Ib25fvc`ouw z%|+wJvk^Nf4ii-vOpK$4@F@fyqeu$?AK?PKRj5u-Z^N%9TIkQ@Xr{wkkC52C;`l*{;~(hntVNj=&q}FfdZ}Mbr3mqD$`-_q zuf3GX$B}kSWd|H?_!bqt_#mO6En1&8OkV${<*6+O9w)Cb6Fr;6Ox2OZ#R=R$Oi2!> z$D}tYr^o4KRpzG#<*D*Q9By@hQeFY>xXyV(fl-73j7L?eK)YwuhLG|tnlmP7bxm4f z)8M!O{3)eL9;dO)gEwVBfH_mb&Kox~4-hS3XeOz|Tq|pU*N%@C?t_x)N~U+4EFga_ zk645dU_Ko?`IWU{QlG5B3S(@n!dqFHd(3R*waH+u>YDh$MD%2qNF)l^j)oCK;^OQ; z<3G=g^CUZ?;|4ee$BohJP5NM6aH2wInOySH2ZJ}BE=x8FW0;og$#HQk=>$=}eknY7 zP;B0ehVarbuua1CSQnDM(_9`aTW1or`!Bs4`^&k6|@qsE=)9>q3}J{u&JQ+-{ZK z$UQQu>FZ}u+{h7)lpYhdVM{5CQ0OFjmtdLBal|AbUP^*oWm!qK#A4J28^t{mTQ3*2 zQrw-B%x*$BDyVS~aE}XedV%KIg?h4b#(5+NPX!($vnfUZR%3y$P@8J56sThKZkGfD zx`sTP5X=iRT;GQ@H8G|vEZ3xg+`dtcEp z$nAn$Q_8!?UWAfk3}*!qPEwu##Mq!!>D9c$lu`SZ86-Wo%@{Rk7c>+5G1kY79 zHBtdvKiisEA?lil<}fTCA(28q)s&I*Y++uN>62I+TQEiz6RNNSApRK3$8dCb0_c>& zAs1rjfoGXr67;cj=ly@MZGH9Gv@P{fA1?WF_QLI3cIZDF^MuCUuR#jV#Uf~4QixzN zDpas0thzuxN8z~vm#ZhelNB@|LTmbcpDfTgqGDY2+6eQP?l9-81AJh$3knX0r9d4k z6*4_P-xofi+zE2?=kDu@VX6;4aAsMZ_|Pa#6D5#dl7hW@puGAw#m;I#Alfu53|fso zNsWRYRhifpmYp1e%DE0$o9yOF5oEx+%ANcTOcW0%T&?#ABJgb`UB_Un5#5m3C9xd< z>HykwWkFhCRZ$m97XYD;tzI=7gwu%;F-e)x(<9NyKiP#>7`-+oIo~eT`6}DN81M zL4-Ka_xxU43Gs{_drCocsh?TG8qX;aiAUqHoUk$YDvkL*##lRV5?X5s*jPZlweU$f zI}buwF*&BErWq7+!$<&&7C8#}J|vutgQ7Dp$fT*SHVeVth)ZePx|si%f{A|>K!bQ0 zAZFpQ;@cwAyP_jQ$*0;RFIDR~D09E~y}(ss)2U!bBcSA+HlRPXpdaR@z*9{0|3_xC z5R7E~NROX}6yY)_*%Kv*+??Z_p3_n}BzRf@=n&Ypd5Pglo66WjAf;IJ162haw+PYV zwtdDU^R;+G!R>QPK#(|!1jAxGA@yqUK0w1_LZ2cqSFo@!_%iLtDk~NAgJi$@z)Q1< zq`;J@wvbr+$sqws@m|6gBZ; zHT;9oS=OABV|NK5Aud5@KM^0X-Q7@n%*2d%kdNC(?ksvD8)qI5DPk zu}J9EP7JAF!04g9F#`<})DSrVk~-c3P!s(0%!P)cP(Fq2w#AR)EmXa2=m{h#*g#KP z^o_cHIs%o#V}c&pV|&HM)1wmfqUA%ma|T)hLmMMCUAl{huGW;L&zA53lDWAGke-Wpxjsw=1Jr% zd1zL2PzlI+c4o^F(7?qZ=&VT(7))ne2nZH0f^ zU>(*d^vUe+0SA-Z;}2flpZ4{crOn-QA1LjY54Q}xntdVb>!NR-_~~+SUR39&M{jNZ z>^+4l29nds@pH98h(|()?S#fuV;8nxu@0Qq^~Cwf8QH_%`+W1L#|wY;tGxB_-|2n- zZ4)+TWo1XlXqL>@?fPeE-<{r^(`PesojGnlkU{O`t;rgl&UbWxL8-nPF?&xz#_wmY zMo)fWc;~tcJ&FDbRd|F_Ghz4M34NbjJoCinu5r_jh3A^gfgWS2Ueah^Xq*}8SpM** zXTJ;G{M7EdmAPKCYJgGclz3U+QK3bpN^!Jc7uzSQETcLpr%b{TF+u}{1DemddI~B_ zGx}*C@^tM;j-J|!8F-B~h*4dgfXop%Kn~0St5xs~V$hf8d9|K#1j$0L;3vjb1lZwa zCwY;QMrg>C)W$b#V~5Siu8GiBBQRnXmQee$g+{wX9OZ4nay!x(W-LAGJ$i<)xbRp? zQ*Mb@$tK>FojeRmB7+YRlL(#_ChDRTG(ieXbRtC*fw&~VZk`;g7i1HhO;G8R5(7%r zEN8h#?QF(z0-D}HX8>?3pn8I{3Y-qD&({mY6*#@2B2WBRb~&t@WA86w%^b%L)vK&c z5e3@<^rHT{q(lNh8H+2(w?&6yFjgsK@X{mzS|Lfnl8Q=w5`+7w>N2n1D$;9Ve#V!D zDQ)Zl;sww#C@eaxzw6%=30RgOnHHCJanqh7_HAamKyrz6)l8=%Q34ifqg9s)3Rsov z4Ul4BAyabn@l-Kam*t4`ErT&ukNE~G4g?l)3XnlZiP}70&%|EnCly0XZL&C`qdn~V zB`zE+lH3bbxyHOO#(k#65JgfjR!S;X0fS^_@_iT6Dw80=(U)p>M=n6p1$@?!z%U0( z6vcfTdrn4FB`Nh{!;0(A3^qd~#b&VYnGp+LUE$;CXFt&%Y@#*^u#RBDN@ArZyF{ia z1Vp35(^}vVQs=;L*(aw)Y#dr!DW!b-Kw0o=WukLxCa*N8s5*8^Xy4Iut8y|PNQ6a) z@8|#Z#)Yf}50>_|4Lnqrc71Yt<*lz~J(!m9(_0U_oB#7(z>n8Q4S9_v^^Dmui^ls` znI#P~2V2()>MvAJ2-=UQl(ubqxG`$y^cAiJw;ygV&ptW!$oKv8H}^LD^WuT>ZKJF} z&iyxjBqUGriy!iYd(1dO#IuCCjpntZCLBs~cy6!+Jyv$__c=QjJ#%Z`9nG@3TRmU@ zL)|dZ|BH=!@3DLY+5oJ_FfY60kn@R%4pOLPJpQ?4z(K%_ zX(_M6e1)OoRk?|DbQAs zIyd1C@&;EXd<38z2g`@4?^aSaoB**h^@jmS5yBc ziY7KezD5Oe`TJ{8MsWubbx(#fopGR~f`wi+gFw9%7!3?U7q8J{OajJoVhBD4LU@D} z!-zncmZ_7y6408T{a{R`-WQs$n;B6TZAuHCe_)X!c5(n1?Zf4op3p`!$8vQQagrHuj7 zOk%y^r!r&NabB+zfCK%+PMm`lGLx=?7@l_uIR5Nmq=l`qe;mY}pnkmsBq_uyFh1wU zR|w*z;UE$XN@Iu2MP^o$szy|s zc;l7udi_{qNw7ys6-41r*)cXCOBugB_*5LMty(&$eSMo|Pwnu&5y?Yyzs^6Mc=+p# z?zcMk*FWzVknv!BcioDQI(qz@AN-ZpdrK(&H1Nw65odD-jQr)}x2xwp_gvwOU`A`H zYR~|qVuJTIAy1#>xbxlc;{WXmO@DQruQYFcZ{4iABhw*F?&`UJ=CbVEb0aRUdvflE zVZSxLxagv1@8S=)O#D~tOS_d5b}b2hWXwK)g;Hv>&yd?)gC3@S+40rT;Rm`icbz%2 zdVSl#qeF^6|7WF-M)vrmQ!k{>3*GhJ<`;K<^!eBmkNNDm`h6^$6+|B8C941ck@nSq-J?txo>!9r z%k#jhPvqaX&w$eee~a!9B2Im@SwexrsEFdACY_jOUo^foKo+u-=a`U(vL3Bd40Hfv z1kHcPUVjEMG*w%o*{X!MOrml52HxW^uHzUpMP%kBN3E~u{floi`#NA-9GX6rgO+>J zhQWms)C`II`+}}XVTSy{=MVPLUZ-#}}o+UzpgQ|I#va#cLAm4G}!CQ5@+jcY2@BHRJsnF20?u_qa| zMx5*8;^@CcM>7OmP#uVe@x!(FAZH=VDlaw26%Z|bLY!hkbwTSwP#Kz(++_?HWiqXeh7nKmo8*8iRP2>PphT`@0z9Qv zAKKnck}45HyqO^cFC&RD!w@*JFo4rrD3MSd3_4it@b*X%qh{M_8em9C`QT`(#GWD= zNYVu>UrK`nkEfj-IS4I(61GyHRfg*bJPE(DY#J$aLSgngB7X!Ay{g2gu*Ru7bJ#FC zp!4VzwQ0HX7cKPAG{h{`B=ua#obNC zzwLbEaNw=mZ=_u--fgRI?!K|ewW_%-DXr;7)2;h~d)G(K{&I51*Tb(hrR$_83Jz>o z(f7r>$Cupy?ey@T?HTRUw|D(%2yOdM=UY*=Z#({cDJJ+vRA27>{3v<GjMxv1_;`%0N;Y3EIb2!u&C%}T-CIvx-EqM&G~?CYn}@#m!SKlo zG3wZ|^ss}oCLJ%# z2%6RX+`vg0X9kX$uzh|{<*l;f2XV7joH=#)Q1j(Yn^&)0(fvz$x3#Zv)`#W2(fS=%0aYAfW z!X-yYjUFFx0ULN>E=^TG%GxoessgzZg$^gjOpC~)F{eT4jZ@61f&*hTJNgBP1~kwf zG6f4BM&Uue5Frs~%9ZZy61kMh0r3r*l`NJ6#ETnJcFfK?*hdZ1saiX|g5ci zVJXahTcG4Ids^|KHy9P(1fi7cg5S;N_QEoiBU}!E^{r=_Dw;IEljY*@sWA)}=*Vkv zWfHfr@WPZx9l{lVuQStzjT#>YVI00I8~zeMy|F664E-{lG1QggEgP8>+}I*{FxR zk7?%6!(wQn$Ig~G?7!CnLXZbi+@-m&d9ghCTjt^8wvOia$#h4DqdK>VRlh3I9W4R} z-?+2b7_o6pfhfz}@oVHJHoN^aX51vcE%w4_y1AIQ421_AW2iV3T|p|TSMtW~4oCW%O%)Zhx!gS|XS&blGc#&70pXO>Sq?mbw3<%7gwb!!fkJiF{4;ifU4{B-m4^2S$B zUq5-^=$%7%24*bld}BfFZ^5m%x_|m_`rXjdHWO#askTE4#5 z7WGMa#s>%1Z7OeXU-?VnNA;aQT@9X}lbJZFJ@5SJ)h~5r78j>?&U)|qy1D}yeV<>O z`A0{_nC0v1iVhVkKk=?LRSrtinab;QH`X}#n|Krf+Ud8$L2N!phPds$_UUJl%&#v){df?C=slC>=ZrLk0zfJDWytSZt z&CAVySla!|uZON2RJ>|l@4123f}_@sK0l?ma`QX)mzfUVU3_BI;pM%z^9Qbo+JE@m zXoY~YEAs5%#puzDR-XPSvsum`kZRhkWr=zK^iQ0?aqV6WaCM(J&@Rl zJg31*1^`O(_~SDcV^$|9)iD85Pgb%iGD^(2gT?9evcPqV2s!3Bb78jmEB9`vl)z95|fAWt5meLf@NYiX`QIrYFx}{TC{oW2=JiQ!{-Qqc7|9HrNj*T zI7VE+a#vU`3|zA>&e?E~Gx3%RQ$W6@fjG8AZuZ6!#a0&)7Y_2J<#QPHzKu=1`k9 zu(EQF{BnCOknuTDtNZr6v*{vzI)?U5#VtL#dLF-Bs~8fgn; zI02hAv#}`_91@9HhxP}4}k&yId!?2PREPWzqNdrm)f;j6diR~+bj zr}xf+xArDxw2l5SqboVJ;`RFj|5!dhe?igs$JIYX^)_~2=#aI(n!Yi=bIsW`{TDo3 zntJk9_b2nO?@7Co*q+}!`$Er_Q&ByG(p!Rs0hmRsuv=+RIhoePV(-XpOT-4d}_PQCbrZuhDcC^*E zvu4l8DN}AP?sz{vf)6X2kvWr7=7g0`ftmN?%jC# z`^5B{cXj1gi&uvJ_+a1gOUwFP^}Q=&)FuC@y!F7av}>%<`1R0-8wTFpeAD=bE9oOr zl&-$j{6X0ZGcV`&uIXGi{NnPc|Mi^R^-kN-XVXvI)kU3b&hXXjJ(bsyo_~K!b6xS8 zAwS-H(Ad-cQ|kIzOBdYUE7R8XsS?p8 z#o=Nt#B9JL1qer%@Djx@HJZ|-40&ph0%lNA{NH282&5J`Wg>;h6=Zq_TYZ!L81AL+ zFnn404ps(-z10e6ZjOEsrg2NO!vIbarQe>kPno|&BM@VKU1XtOL@vxEzHv3T6WuBX z*>Y|8WjMb(vX&Au&8n|i`GSZ6Q^@KG5`U%i74#^PcSk+3&sp8UI&MnDQcoeAP* zg*FA&EtOQ!WXs^kW6dPWXh7-8(t>!N7yGw#LL$ad&&2N#3KNY>&LGGGLV@OF`Zi&$ zP@n|ycL~w%GF?Sw>{jpl(`EYjX#v`i4bUTOtcRQ`#u#s&HB$&-r>_)TCjHw=0Fs=y zgT_5GRAN45IJw_lHCVp^A8m|Phrc@_*cKlo+eqq>(l%cnW0tizYz7eyFxVt~1cV6l!WE(m6$TUp zl5w493L9%`dkkst}wA~0yl+)QDK$`#8gVvqOyA$q`R3-K;3O7QSQs2QMVBLECAD;cU5n_ zn_Dq+-7}l|eOw?JwV?0g&YwfCOzX5zO?Mi^;5nNN&RK|9~bS} zqu2c&*e87Wa=3BEx%(3%cfa@4prKE_;=6G4oQ zxnnnG`;GZe|I1RX>BqOixBaPXt7-n?;_R_|E5D!BGo*5J%a!M4Vf0nJ;hdFQ{U_AG^GJVYf$jHa}ye&Cz~;^zOvB&)2lOn#N8jTYvudWt}6Q zzV_YGm&V=d99eXDR)!}0)&p5f=+0B=|C+aA(B-M2_y4-_!=@_(4wUXM$hhDCO46LS z3afgeYBCy5A77BS;M&~nKLk|$V!0AD;mFD-bu0h;{NL&Sp8V~${zFq6GRa$5H2FU# zGx{?3?foU|9K1G%NPlh63(!KP-dr1~H8}6KeIJR&OBNtygwC*iY2MKPpwBkDy)g}D z1JWv;;Nu!;jEj-FJlT-S>cSO4nISNUP+kZIFByOizslHLBV6$CBvJY4CT$7WTg6V6 z=iBO)sAlmq#h6ob$&~zzeols-!B{>2d2w#`8PR7I>WCX85 zc$MSvpCdNZ?74E2)n!gN%&c$>I-8aGf=M<8rLQDTYlU>fM%7*d1V%<5d3yZ$6fkGn zZ913=0a8(>8qZb@p_cgN;8i5g6|63QluLmgktn{RHM1_G7V&^W*?4RpjfB_SG@UH?i# zk~1;k;tcmfr|OZP2R!M_T$kJ=kEqha5g@fp89gQhhPmK`QfvqcGTOs~!Y2MP%B7t4 zTu|2Ri3=0W8@&Sz1#dq(A&IvTHFq@Em`L!($J5PT*(P>JEC3{x+ZOLVID>h>YRc<} zyOLVmMi67zmWM&h|ALN~iByKrzCaAIAG(|3` zWRu1XYbW;y@(W+40}w$6+X(Z-p(Oo8u8%kSICBKY@pVtfLPYd9F{;I{T9kr?s1vFh zuw5cZU9Alw7)$|igzHLDiffgTp9?jwAl1GvnGXiOEE{~OWxhPuHTUML1OD2WV>{Zl zB=XODjj8II(a$|R6ZJ{Y_i-N#>>V<0Mn&DSuU7PF{%UyS{_Nx~zjrjPZhJ=Zq zR%{5^z3Y9u_wJn;VK01|emr0C{<6^(nz643zr16WUs!wQf|BIsKfgY`^1ae$^ULqF zr^Yz^OzS@KTAIuEf3x~T>sxIHFGf5b^6rJUKUZ7~j5>Zl_}tLE;IR7L&u9MUxZ`9+ zz^Mg0R&;4*CU;$uywKrE8J9n5p8ookxBXrmQuAZj?@KrB{&Ce>_43Mni@M}ZQxZqt zd1YDcrPpjTb5?b3-Sy~eE7#@xx#5wR_AST_--!y8#R2}2m03}t^kjQuv7k5EvA0$WrN}L-C*}lQH^n7E zAeZE3XL*uuF7_DWE6bwQ0pYO%ppnffF~%7N4AKWt-h4UZ7M(mdnzQLP2tL;Mrzeff z^i!z$iS;i*tW(GXgiD+xFLf6hAWUDF3y!qj@Il1Z0QIuS3h@X&O>F3JdGacJsv}w& z4Za48#hWV`6al-<7uHRLASywGVDygyjXu;HS!Jx!KpgMnWJxaD?I4w1RmNd6mO_T0 zV2unUBaL*aB+w0mN_qz~+f46nFnuWvFa5&(LD2e-PEQ;=?aSZgGOgjY z(*4_GNdr7-D2oer`Fzf6C))cXdCt?CuYTuN1cLT9CMD)&2DmGw-dO^5?TlkL=j~-I-qRlJ*}L^n7@I z>W(FUoaudk{?&zE`!CyLqUC`T3ls)*?aQGb2Y$YF_0P*5oSIs-JadVC&9?!0?oQ{a zYkxFXWIR}|YMuU%5sNSHoDdRvPjO@D)bme%c5NOyu9n0y;g=wDQtmgYo<;Bzhg~?e z`{x7qr!UB7+SvX3$j2=2k2efZ33cNx%J+0ue%IC3d-+z!Z}H!Ue1GmtdElOhANSr^ zUwU{}``a1Yjc>f8JNE36KXyGHz4c7`gyP)tzTi7$QHvt?oaudntoDCx%q*)Iv~>5{ z4c~wDQqlVojUj7_<@HPP{fAz1o*kI+&&eH=U%oiT(Re(``ucZYSFOv|;m#N61XE`Z zw8?pxP4mt<#J0U(RELY+L`?1)y`hH_H4pqXaW58gUgEB*u#)@!hP^Mc@$4>mk z>A%Dls0+gQjE!v)n^E=(+xokKo+N7g&J8w=jvkt!dVp!i)jgmIMx{3fV3KzPQYzQ zC3QzLJ770yB#WL(h$><2W6Qqlth`~Fyej{Z&wrb-JvnXPx#p(*BR(@U{IqlV^O1Ky z9aw(<;kDoXd-3L>TZg;8X?l7607KRD!Dm-aNwjUBl+x1u<&k%6dA8^55FLyy1>v)b zo?U+9>gidlDsLR0C^gIU&y~Hp>j%t;7ERllS9EsY)QPWueShOqFD_p@qUp7_I%bF7 z`+4y5zaofIKkAHptA45m|G0Hkb zEtL8AH_R@KY(AG>@fBi;`s6j&EJLS;LwbP3xrYy?H=&RnG@$koDFFt}7 zSl5B|{fB;*Xg|iX2aN)rs`=4cx`%fk^+9y#r$OfznPhO)Mhh;6hSMBkipL}6upFF-=ZW~Yju$siWBW_xM333HVQ8+7@653 zlcKYTXHolYt=WVBURhKu#@p^e2*iE_yZfJI03dkzQz$FO|c1diFF|?{q zw~MwYR~|05RK^I5wZ4HZ%Z3&k2vNtlB~9;xj}PX&Be36J(bw;%l=lBxrXBeG`mMGT zIzf9{H#cz3~+u=%~q6VA=}=EUyHp@Ww7E~%Yte)x50$iVXX%Wk)oHEsK$ z^7`_7pEiGyzh>dTTtj0%wQTNJ8?bo(sR>gWjw>r#p07__t!Xc8@{Ef3zHs%v4<9-B zKz_gP(|PAYH>WN9sV4aOj z=a%jxx9UpL4p*!yN!MhoNIZOU{pW8r{X04NYS{44UP$&F?*GN9!-fM>8fW#4tvnQT z`MdtF4)S^HZ1cTMM@Idzv#e~&<(y@EPT9I{rR#<~z59b5y6ER`9qN5;Xz9_G$)9}q zr}@(t4zD`=OQGa}``OtV&1}&jR0SuT{3QW5ZC!gvZmO_rN6W!@rH`yqAZ|p|B@{z! zgZxp)c0kCL=Ms*IN4LDfA@lXUJb0rdn2H{gYmir&bvB!@OU#>zkw%;B28ZEF_$8{VWwlt-1UW(wX8>bLgF?I! zq@4t*m2M}uWiALtsS&PX{=(^Q!W0z_bqraW22*$(wvs%YkBu-TP^%K2-d?~5a zJX;|~$rNJ;zhZv4Z`Q+Y&7C(EG@hHf^ReeHg>njTIp0T`wEoTBZo>9+;-EHEkn__~m9B zbH}|bHP=i`mgkM6p`(_;C$z(Okz@ZXQzSvib!HnYgbMpe2$;z*J22(WZ;aLCM@z>gv0_>*0ouUnloz|95Xg;+@&0B`;6tNc|%FuN~u5-xxh%tqnec zb3pqKn;yAczvjc5Gi@8oPo3`dzL1@ty0!23T?ubUzrB6x^no@1=zOsG^2zz<`)*&` zp1x#$+mItG(jR`fIcwwU7rW}pT?4y+>25l+Ao4-d<)^b-@Bfv3=8ONFihX9!!|&QI zm2WG*J7wh`2X5;kzgu&u|M+>{%eSW#KYHt7KU=S}_|6O4k1kw!W6u3KYX%DyivBO| z-g7%5?WWy#mUP2_e?}Y_ef!F)OW7B~`tH8f(^LFIevfBr-@vqU#XC}e`R~n_zTe+E z;le)aw%)rPm)^MW?1x7utgGC(rBf67)slrH|61dzKR*B2sa*%Uol*BvKRbHAW@h;v z-^iOoe{%hLzH`EXzjie5&DcL@cSifG>&qWzpFWeGez^YB3Cn_C4;|>LT^@OVM*6W` z(q9T97JukJ`Vkmbg5Db;=4~>7L1@BFuf_3m!AulF7;(!h^qCL?!Sw_mRw_uVqm>TK zGnk}M7hp3vKnBFG_0<{h9IhM@3+K%LbU3QiVz#F15tP=`1;wLO`C; z9D)d2g447KhjgjO;1vC)BocNx_-zDxD}CU0j&eE;PUT#w1*_VB?o>K$lS?Gi^(JJI z;*R>}XgoBY8ebJFn71#1h>3Py+)OD+J8pJ}~w2&&MvVzHrO7H0rOPHg|8G)w}P;jk?WU-`3Awx$3R1L*-qE z=3o41{>|&>5A^*wu#O07rG~xw;t*U-LW}+=`KiV)>RhE=L>3kABOh* z)qV2F(OVx5kLvw7v}^Y8dw*_zc1_(^9c!8gro6RyW^reAac_11s0TYIFU@!u+H+^w zkKL8a9##(TzBs&eVnm;P-~;3T(vLp);Z}Fc3U2wt$LBvhx!_^ejjz9+vu6L92PMP1 zF3!m~f2NDL)4hK#au-y_=p|L^g7=oUzj5JWa(eI3^sASStayL#!5#Lu-Tu}`5B>IV zLdLxn`5!(qVbR|4yJk*#_|xW|oLhZAtXNau-8Q_(=g)7ZtT|0gYJGF+>3iiph2{5k zjtj+arElDyNub(ZY!4EX^-j~gn8tz#l3BVitm20KB_w> zwCjUCINUwhvFHBTWw#$>q|UqRYx9vQ+Cm%(cu#wE@CG z5{h8+vaqsCSV3ZAY^rE!#8wb%dm6m?8a?_RD~jUQ=livX8XL6496={CL9w5zy3`qt zViXQzHX=V!PLDr&{Y&fCSxt7SBc>uIV2MNW>GSVvGaprcDu3zKC!UuhPl~7~k1;q& zkTb->31@{tV4wKRg@~!3I1&KM)A^qmvW`$MC6Ydfb>3Wd4zv!ReRrdMXw>n<@+sx_ zHynQO?V}?@dvh{=pVA#Zyz27>xpg1)waiKTzPanqZ?4{K9`ayCR8!6V`PUczvI7_J zXK$W8Q&YZZqVB=abazvFzAApvm(9JyihBFUN>g$cbk2;rw@m---50ulENtI4@Ym0m zEjr%&)1J$1%>y@jZy#82mRX|h=VgNiu563^_Ds~nA-y%j7cJjqXzK1h6t;Tj%*X0a z_5AfF31vO=Ea#8j-Twl7`k|(;aS_@fYhrCdOus;F#Tj@?9JZX zsJo?C23cdIJKH1GRYx}OWe);7t+4uXu z|Ec-*$+Vi|-~adMyG2tbtZAKdyCdqvKG%l3KSy=XU)fWyowefh`B{!<`fe}poR;CO zDepgF{;Bc9ZVi7BS=2q<9y)bw`jyFtpB-q=hWH79d0db2hdtU1YwG_vIuk&s^FEBv zj9cXD&?-ihZcrstE*Cz;|IIIXO#?wvch-h8n$;hMUJ znZG|4&tOZ?r#Q{qO3DiXChYAFbW zR%9=7e2=LY8LnD|pVas7oA}@88ZeE+E*pgLM$XHSHUcpW{61U-16&rVB&1L=Wn%n9`(GHx-Zp*G+!&Qp5z*} zIQjP6S8{d)@a(W;bI-|89T!Y0{Kjpw&d`Tce>!HtZi^7yx86zf8a|(6U z>!cv3Tvw*Q=K1N;G1XC|E0YqywP~Jt@qWi7_Siy3XEpP%P3pBLWp9j1M~Wh9Jt75h z3_+6Qx20^vMAm+!MC4f}Sy(nelYOC;bflIHo)HJCm38))b-2rhb=rqdaB{z<9r_k0 zInNSY4hicC5sjmEObLrmSsh$kzhlchWxRLIhKp8R-M*Yf>tEp&5FXAGv$<+>bZwlP zFK?yJ0KV^W*+eQ+;LMokxUKU~+V~2F#F@=+YyZ_&)?dv09m43hZU3R&F00Tf>wW9a z7)8%}#CR~ny(iI@@>7S|Q`A1Om?OGR8Qq~Xxq&k9F^SPy6!zG{VaTL?G>0>i?as6o zpp?v~hzuM?l-jv#C}Wng|E)LlZHdw~G;{v>{8XmLsWbh7&xN(^d^76Ba*{@z^_2L% zH4|dSk2vWdM^bQaEMFMMEEhA|r$&*{_l}*xDh5!LzYZ>0=7A)_mP33Cx(n7P4P0;e`hNYH+jM2Et=A#l$J5~kX&df#L5TAlVrCUfe zCDa8!RZ+#^3bHSBYIFk7qbUHFP;0w4VYLgrIetLI_8(Pk6M4jgQ`cX*hBcBdsk3O+ z{5Uz|6_+`it+uK|V{UR@lzl@+M2Y;tk>$F5l3I4VRiCstLsR>dZRI<*=n#2B!RF%f zpa@lx`KQONf?D?pn!3^T4_l+7l%Ee~@d`7x7|-)pGHxiM3FgsN2$IU-F82AljvZ1v znzn(v$Sqw^f4$=Q%S5s_N0=}9-HDZBz|6X_S-0|o$^(m=Vxfu&~k_NyPyUV}kHS&a2!u*gcR}NR)c(yiL59_*I z;{Wt-KGZHq)o7hR70Q0^SZ#8`!1c@}vzJeHew5PqVAd-a!pVzn)CEqfCja<7jgDe7 zmyo+S{mpKIwWF$!qKL&VFHxZ_FDDbC^{QZL$C@wMG!0BTBUieQ7A&I3Jj`39YdC{P zAof06>UDR^iqrn_sUyl7XGz=M&Axei#-DU`jB)fG9is^A2~h;kS1$T45FBDcLIf*? zu6%cf>aIYld(KMJ_&%G1o`~x?zSuMM`d6)}s|IST2p<=pf46*d`mPVo)1RBh5a2vT z&-NdgfnaD3?w}IsQ#=S5bSlP$P#O^Y6{Z6veT)*%z5^e{cG71C)^G5J z5~Bz$3Zw!(*&lVO*8A@6@l)4UW&3OQk5n`IEZPOyUg9Dvs!O&w9PPFM>L z7mhTC#;l1kQI@=+$%K9Xgmg9Ew8`O?41To@zfiRLN+>C%e%T(dbBLhM9#0r~GkUi>x4WNgCzr4ZKe!9{tf(u0K!B#0P&4mF* z0OuG%uNAHSbYFO-HceJQ{g(#5AN4GaGHg-EO>}X(z>DZp0ovLTPR2S$PTE9YbZ3KX@cM zL^_0+=2(+}&0_dgA6BvC*f6p;Mg={r0}t!-0c%Kq3mc-YdQ8~lDusQ0+l-6~oro3R zX4`z)=-9XO)U|ut|D2R*v0#cBK{;{W`Fq>9nw{SMXl>3_>cg>rmwlO`_el55eoYth zwSWIuu=&7MWff&2pgEX&DVT-PWX+9-Gk5xa*)nI|+U)hw2eSf{G+lOI*k+$hC0i|8 zt4!E-j=UiA)A;dgtIaes?;roSbYs@HZR<65B8=Vf4uRb8t1qg*$Li4PEW`P8^;>F` zx1HO$`(yBi-bZT+vUY8pv*6tCovT&uMV|o!AvS;jvO=O>6%g71aQ4Si$po{l`&$*9 z04Q-0`cPhoM89P4qjo!zk5cwn;~a=qQP@x6vH>fB@b<;;S~ccyoa|kYq?0Be&ydKt z@~^lnQ_{-1orgZmricKVDNM1*c9uQzHJ1+;f_Wim^)=rMcs;rg#Ly^Eearb({RM6GPOXVApM zAdSIw4nLIAN3XKOrM97wC8~I^^L7NjB7rWu^$xUHq-ZO|PuX8cc#ynaS^c3irEdGlhm8@qEMlN-Vugx^$$*>B7I<>S!ZbqvqczD>~FQ9`aIjLX$>y+pm@DHm4n6~G&;cW~ThU9e<7G7k9R?`M7SyU*g#%lg zjh98MkME0%ocKP6Uie!(u6A9e9WqHMKkp`udGWr`y8c9Pnuj>$dYsxWVKG}C$C0OTc4(acS}P3_-C{{vF^6pF-c@@x zD>0{QeT(N3Q|&6k<*D0acW$H?7P^<>LmbqRf4AK7_`)_jgIxr=ax?vEVa1K)!znp~ zL&ht2WD=ZfBVD;d26u1mNzb8AyY5&>q#S7_O?qZy{OQv%Zqx67wt12?v1C8{)8mrE zgME$Z6U(hCmbw0QkoT8AjBfs|&7d5s3fERZa-- zgNsk`)G9A%v?{GnEqm)1(P!Zx@z$yE(eCK|LL2|$AW?GoafQ;+MH6LuIU2v5eTgMs zt@t7Qqxxci5=*j?HFk?7>*J1X3DWTo3@9C|RjjJU+^&6^k*xSwtdVt&6P*eoZ5y9 z@2NZfXQfik?;8mCt3-|JZDCXOgHS$iv(0x*%v6mCcgd>}BB((aF`+`YRM=QWCzvT9 z-&l(&Y(am`#iAGY6-vOH(_Nyd`a63cvj^PDMlkC?L6fdvtvWh-z)LiT(rHHN<1@q_ z#v?V=mt$s!K76e)UqiP_qiTy?;$Z)leIcE%-^NjX&ov#WPn2abMynkp>nTzf5M z3c*qD{JiaJRn-3eBP%UuP(8=vNO=wJ3nL2~!|mqkJvjJ6kmw~Eq{%ZIq_-PFo7b5v zP5pA`#ENyQ(Ob#Uy7c=tFRtf=FvLaTRyLC~cy4>{(aZ76${RnXmUS3OM=j+8tz}<4 zokh2HSRhx3Gnm5YurQVlJO6w(`HU|BEK2%Sl3KuhqLE_cpKi&cqFJ_U#Jr~&VG`Kf z(80;+R@pAhr%3Z}jCq?(cq^WdYpdoK6pU;}hezpK=P+WL4FgEx0$}>~fyMUJHs;QFR-nqD4#Aonr+lO-6 zUwW)LAraV>R<=riCrN(9MbwBpcR8+Y{au_Pevu(UxB7H?xS$egX<6;Z8|!J3IW)>1tF41t=%Xr;r?j-u~R_Zs8TEo)9;^iIcN65$$Ob5LtbZXSYn=JE*L zLIYC5+vR|l1z!dX0XaYUd2bFlsY89Cnp}Ynh+M9Yxfky*IQQCL*V;gY0dF9cA2j|Aqcz@EeuZ}iSMEQ5>P=vc^ZqPH`Ipy-%`%`~@ ztY{bgQ?wqDbHd#NS!>2;*ifWbC}KWS9Af)Dw9!&Fmc-!mBl_*w{l(vpS8jflnd&^a zuJ7fI#Wn{ooOzx5#~r4e9~Sh%Qt~S3^fJU{m`2CWew6v)D@%Bo6*_pLN%}!Yw*Hdi z4J#F8x__(j*T;|MGzRvM{LRYYyU(=aCCAzSz1yTMvZ1uRD6*CRSIIxJG>&keywjc8 z-{ml5U@X?RRGa1dIdS`uZPN}6Zv5aSo9fjOLlIP#@xsgG>m0_E7}#q~c$N*>otu61 zCak5er*`h~_c1Pq*C@8)x`GZ*CD`o7SbGx~h&bDpT%k5sRl!>~BDp!erUqL@kcJSU z0DQw*f{mpv^uutEqeKMWme9Ehh}rxab-b)p7;x3gVdj0JTjQeYAG4GIgpe|c;M%F_ z+>}9K4)rj){idF3NeP2^WB5qf`y(rjCThzhwQDcrK0v0mY0EbgRKEn8d^1P#Fle+p zW8zQ-@%yQsSwW*tK@+Mh`P|39qBjyic7rAgwo9VF|Lb7T=HH%Mh@)ITib_Y<5{t+` zShJ~4h^C7nLRwWtxOoT!UBKc1jIq|x04JJ(qaDloZSx)7d~a9HOp9&8rF& z`fHp!r-*wcUo5F7 z=I*w^?o-{{#asF5QbZc>+^V}4D_3GJ{!|p%Ko-m(Kr04sm!tjGZ{SRNFEOBd6Nr#u zVIT#ecryrtMn2KFfRqX`KvNW@(9OL*u>I%ql5t!=;>a4c@1n7+l25hlca_G{{ir-x zg8P)=bvkHB9J+ldq?)6HhqQmJpFc2jnZ*W|s7p2TgGudNC62sXZH=U~T^@7T_DENs zX_5W!dd|RRug;G;DSQ7uPkrhb8@$)O|Nf!f2V%BQof`4aKPxjr3LaCp+z%#OT$`<7 zWMoEgBnnMUB+(q<8jf@nH(UP~{oS(`uUqntyw-)JM|RbpM~^t;aq5NQyU&r$;!Gm_ zvp?oc@Lm&2WOr)W;A3%Fc%yA(zehwtQ&_x5=ogmwC5zqBo$4@ZMlrN-Art9v*lPed+42u0trcnrpD!Sk@*K07dUPjz9^Fvh%93CCZ|DeNmp-%;BCfP z9?yZ-=yxIKP(i{Clxxi8g0}YY$n@b@CSm9~f60KqhE}cAW=Zhg8RqLZUZm=^?44X| zvncqFXm#cH{$1a0>L=5Se?5PHNM9X!SINY&GLvCqW?wz0Gsi^y$x>dE68e@O*}zZz zHWrq_dtuA@=Rzx?OO4sA#-2FBt_qUB4{ASNTiO0wyZz@cuc2RZ5lh~O0NNA9zk_F* zQaY|UOkDFCyvCG6qcRoqJum4BFP=7MI5A!Dyt2;#3 z7mA@APRBlmtcMX;*c{pv5{3^VohwOYiz*w0B@Hb%0)DQ%_URh=_KNjKo{eWQMOp0e z*3w^Gxr{6OsUy`IySX?GsuDfDyXw8A?b5W2vDj(~l88MHred63Q-$`6^>yJuNO($7 z_irbCE!^AO z92!JA(eW>D#nEKFo3se{l;pfOQjDwU2)c)h%LSVBSl<|^NZsfFPre>rp)I6g1`2M>gy3Cs~d zc;Aqzq+ByAp&D~!x``@_x0)qggT5@_a6V(?9ZRrry5&G%U{J~E!V*c7sohJ4Y$Hpe z87@|1%59U>0@+;?t$}Oas02tcT&A9n~IpDllI*~^pStnu_wx5VK(oLeWHOQU72m=y zYeX$28Hg5b=mdZ7sy{9M>?8^zU+9Y7P3#C z;FSzf62Deq4NPcWq<6E#ivV8K#@l~7myQr5`tAXYwRGsP$X3Xjn(Q^@o|mfZ4R?e6IOp?bw>A$ygiaSHXDdVd#>x9Alf9wAA!x+MV#^1~l{pltAMeE03 zwK+euy?VcR{W2;WI^xxxX~Oe18HwNMJe5vTi2@}PS@X@w(eX8h3JQYj`%AiyFvhYX zR&Uz&&$k*f*a}at&+mR{Cv^>yC|J2HZ7h$G@s}5`B;Brx~z~ZSYpYu zw&a~+$zQVg-&o>rEaATyvg{1O<)p~w;*y@Y$&c@EuiSpiW+vkYo~SHFU-cR(p5O+) zEcxriqsT(nZOM3N^#f);DIKb^4ZG4LAFvd?^Y6bA@bMFl!@|UYI`5gDsSblz9PXyp zr$y;9C#u={3B(k(P7Z2 zZ1l*71gndO{-AUlICRXRb!G;Y{d$-rtI?6hX9zwP!Qm*XWy^w3r0UyDGlaP$VJQ~x zXCP^Mz6pjI;Mw4Qp<^e3oGVvDstw%~UWF({LLuT60iK0LXA=goo-hg^gNL}tHyyGJ z)e%&Wkc_~o^xsMm&O__dJ^RyRh(42ImR<*U66an*Jx?FE?^D%o+#23(!Y@Mp~40+3@$01YDn zWGr$y6e!4+(WHdi!)KE0NWw%%hUk7vXPY&|KAl(L{RK zK`R?b>~%FaxI~jw7OcO6Pg(QmnY^Qpj;D#H_!mG7MvjdCl=W+)^|h)rz{Hy5>+5s- zWTi&8%F<3E=-J?2+b9`=sPz;?5~L-@RVbzi<}hd~ceX4_Cd4jn*pIjan3mqs&CMOp zy2XjhYs)^n9p6WRo^Or4z2G^JR4n;BR-EKflCZ{Zh*8yAHrQIwkz7|FCg-t-ceqEs z`)__@owZ^jv8iorI#cFHn|MQuZS^ee^>mQAGUdi-&@a5{v|tQWm&uNleP31DRLtf_ z_N0%bFh{C^+X#5VclQrqaCD>}u4IgbFrfy-U!~J2;vJOG#&ss$HtVN!ZSq1_FMh(6 zm9a$^C_)}ZBxPd=aH?jV@vVTJQ#6$6zP2B1BY8!o9jRq)Ea?!7BOCK0od0315v@xg zx&E8^;bEFjQ)!zg`!r`*-cZeS-&=(S2<4TYYE)+c;t=M{LBNsAY?xqq&+T zsSJ-S7Z)dHpFV$^DoVli7X<}QDhle75PDGmy0&y0~+v;me$ zTetXlyyK(0ri^GX$In~JkEQRzxKu-_Z^`XqUSSqRgQTV5pRw}e!;|7!A%Ebes%}44 zTTel8CVp)}`Bl{)7+Qd1+}WXXTkZWyzwff;DnC+A#iy(c>-(I6(K$uv>fX}ae5;`+ z^Rr@*T+F{{=QWf`I~CmXJor3LV}y;_Bd!Wrj;87J8||+^8~(;Viij7X!IcaqI_$QZ zKB#+eGZNwv!I2NQlD=Xa104oTI3$g8>J==>C@Vsi67j|Z+Y#naO2ikn$e+$-9iC;4 z8M0oQ6U8DmZt91J6PS~?(uOf;*~^lP&{CO15NjR`NtghqEpn+$W0Vv(gZIog`+H4Rgmz#rLd1BFHaIY z@?eZN$)UNuvf9)4V&mbKZy#>S$J}LO7aZi1+J7gu{|-RZZbMqBIHz4S*e;vZ{^`ZZ z`#&bTci- zX}|_T6RQN5mdn|pd3Z;PF{+| z?tvLfivA(G94Q{)(Z^uXtH_UOZAJ~KtV$$O)n}Lvr6}e(aBu5^60NUUj(|YASwi03 zjgqAB#3N4!33>@aIAg*o1n%o4660c?#t${N9F6%2`LK@s zhmP!blF2B3O4?dlpA^wh#2zv#>0MrMyXr|lQ-Gxloyl*ch=aYl-*`!8ae4=tzr|&P ze|mLkrvbEa@?KzMZV30-{5S94Yf$G9%<6(Kom00jt$JMY>V3QcWx|JIG4JV_`UCYg zHy`Qe|8|=n==97Z{F=vaKORMx&yL<%qoEF>v<)x@$SjLeajJ48kT6;Xt^|oO1mF%1 z0TNzNs$Zsy2ylSGfw5(nL-WA1{7DEq`irTi4e#PntFiXjAL zig6r8^4p~v83NaU+YW+t4nLMrc#W(VLu1Ynf@;YR2&eklBmF4J%ea>EPnNRJ_^s3! zKb*^cd6s;%W%d`z`&hE4hy85Tb)yzD&`{f%?&yuZJ0^JQHp@Z$Es?Sl}+EL?p5A*Eph%0-ql@*etB;#&2vLF<^KiE6pB5n1F z(K%k7OPOQNFhcbnt`G?^f8YwAcnAgVqS$JC(YEb*eb2v#_uGc2az$l9VWJ%O$hM}) z#_*vR`E@pJ4|g_Cvz~T++dQMp_ng5r&QKAvM~C}-@KE2hn>Qd_%1v`BG>RWv!4b@I zm&LI=T1Y2mZw?o%Gd3s)|8&J9>*b>jJ4D50JiB&5BIoyDdv`tSMeo_x^rQXDH$~bS zWgX2cXymtLUYK6SFJ_DHQzq7#@E*l|dAT(6&)Bdnu+YFc;*E-XcMbBcV1Ywwij89p zkeh}G7Xib;8ss+|i$I8#!!!>&=jEj?mjleL2-YC7Lc-YD;;)D@(Q+}2&I2(65Ncws zDH<;yT~L%UDl<<{MWzUvdL&Dcs8LiyB^;Sl5_LB~t`*ps)BUL~kQb11?``QCO_Kd= zxOX)rqBlj^YvdP=aqA&RUW(qHBVX6b8eYKi?Qtu4eZdIxY{~p7bVJo#WqMJJH0G!w zS(k2HPETEEt}(+(L4@|SA)A_OnC4=N;PSnJ!zFhKddjkYR6cZ-iWEsdl|i-1PmQKa?DG zbsyaUcq1Cs_Rg(qqct^kl{L*t=H|+ZiajAQar3QBp8$f!J*jSLZaP01xpG$I1cN_N zwO=vXl1tUs*G!&+sy=8bzWWX~8>L+oX@3ZlAHs|)V#bNz zxA6`J$)+hra^hf$IG@FP$&w$+7@g0R1%lm|F)^dyWc9^aMOjB@7MF?BxzdX%q46ow zcb4MI{D=(xi@_Q0%ye4m)E6lpN8J3%Q2-WJ*jw0n9szSATAS`;1-rYtF8JF3lEuOiVXn7L z^rneXZ`*dNKcL87P=Py%DHdi(=WJVTx0X71c)b(_WomU&VdP;V!UFqXG z3&!{AwKF-ZM$TZ@SNrSZk+QG-im~iqQKYyC1A)>Zn*0|n0*!mQkBL}+dILxLo;wye z-EuIpzbK+BwWQq$0}nhP$RKALXpmu;@-v3X z{18R=S?i>&O zIp!M63w!^5F(ej7I80YqNeD)sHcn1t)Ne-7gc)@Q<~EY4fWURHaseL?sT>3ir~rWX zpM?4dL%kRbS7Hf933&)nMF3j>RTU31GAvsh(bOi)IkEPl&-6#1h26V~niEU>I(+vrW=j`#Gs;(Zh`C;DM*YO4k%BL?k{?oWP zDdL((SSD8>Gl_Q9GlW(H$I1BxU0|mJf1&82|L*kbTt1O2gbW92@hw5N zOZZ8XFJ7FiW9^xC;*ML&64y6fV{kecQ^w3Vyw}xI=@E9f5hu7I;KMhORo03Ct-Byw zxP|^7`$+8oyg@Mn7`IG<&nzr{dD;a2amdx^;nJA3j!Ox)m3bo+@ zT%kipPD@l?m{+H!nHv!Go2H%XIS}@^gV2R!_u{8)64;HNv&Ug1*k^)nSrP8SvDa@Od z(ipak$DY05Lr9uqzHsK&_1T%Rw+j<100YuNez$$nhca_N|XHq4|`r>VvqP&Os0=;OvR z^6^Q1t!;bzSfz%BDphyh|FB`42aQKwMe<5hQ^kXI+2)b~0d^1t9uhsI;msa%Y+dmK zvA?PcS&)Wu%^|=2<$&Sia{!$cTzNk|f}uh(6624CCMItVg537pwz(tP#~ImYi2;W& z+CdgHjee@W!k24Hc(kkU)@S-z#SP zj%)9RUZAeGe_LdIQ|LIl>G|%0xN7J19DaFKiS3(P_0v29Zk;ENOTTw-#?mkvTSv?M z(ia77C-PZ>e_3IJP2pXWroY!bccZHJLfMangO?snj0vixr4NMNHgq=#WT~$@rfpZh zbDacRmVIixcWGJoOCwrO0j)ok%@ccDrJr58Ebr+4uAMedJ2pLAy}IPr^*DJ=QUnKw z-dJ9S0BfROu9+FFHr~o~+(cMc6Un|$5HMk#vIk#78%4SoSfZ&IVg=@y5{&$nZ}?py zLaFUVh`wEQ^4TFgKVdI$WbNvF+1PY@b=d00n=N~lYLYvR%0@g>oWoO7?W!+kNU&;; zu~^e_R41|~W)7q$aqaL3QA9oz(X%Xv19^F+`N0td_L8$fva{z#`&bhjn``AR9NG*J4-JWp}aCyVvfRxd8yT(bldhZsB5z*o_UFslZJ>%xCg9vIOTdM)qX< zdF0x@`$|s>;FjWtB{oHr>WJ>>Fw>gCr5W%lMJ6_#8Vq5?6{*~wc6bNLrm&)A@54D@ z+?m038*Gh`*I3WFWU9T1enX`Vq@2kCt%SnZ*rf{Z7%+zR$=b-!BmDQ=gQ%(NWM5Rb zex7Gxp|RS>*XHiet_K_|^sisl7Tk~~op_%F$7pFoF}w9bsi3w5j=%0;%6MbDY>@LZ zM+akR*`|+~X0vQuRu$CUewvwRU}57Fb!|p(M0F9fb|(6=N$k@H7kkcigmW}+P`UB) z*NLRb!{+WC+g4q!-(^$o$9-YDj6D!ck(yyZX)-n(N9puVk__tz&*=!t`R&D_9G2`; z5Ez=Ih{;Qt?SKpkNgyG6ev2AA!-i^ ziwlVuNeO*{ZM6rs(6V>7jLN34S6%WU6PZloG|rloQ@=dI3QQE0bC+#IW!xIcwxE%@ zAbxUq^+u_76j>wND$#kpYs{H2;%gK^*e+QkWY+1G6GlbW4R0=^dbjd0Gy)k)kzau> z+XKOkd3o6Xfqkl_S~nHjFc+v`$VRahFcm~>#cu;XH1^pbxA#DrWKl7$rrpL)F3|(?AN90 zGjI==lfi;krkevW1*4g|f3o(YOl^b}rnCTYjc_k3q;{7RY@z^ZGe_8@>Y}%*3A#>( z=8NDW){3gIu2Id+v$AQnxv|jKxB*>cyNu9~YV;tf`B)Z6{zbv(()eV3`` z;jLTs4(S_h-!yu43(vnQie#ia84?Z+6%x2u&<^_eV@jM%q!LN4*3{8WP8Cy;3R$!A z#j9N_6Q}8nKimI&mWDo{ov=@O^9ZUwM0`{(P|`wDT#kqc4hetN&jO4aA+&0ON^ zWv#5FAMxgv0BI2Qyq7s4L25QO|_nQ)SItk_}S!-|@Mt_vsey%MMDEbMhEJ*e~yo6U= zg4_JNVhFfqphE|jvh<~mw%%HEtNw5!@|w+!E8pI1dH8nXL>9|5l3&^rzk0KQZ%#p` z+4;;cicz(9@DZED1OA6ruH1cV=VH{~rqNV=y?IvJ^X5=@!*Z{;{q(E!_JPfuzy171 zCShX`m3FAriR3+r@OJyA$M@sb{JeyMm@;1Dyhc(<5#48V!^C;w zkx~zAlV!pTc}p$()xyX(9uXtOFf47lk`TRzlD{XXiQ4`7T8rUJetLeBS9oNObmU6) zoHf#~euie|8{>95_?7%35Erg#4+on^L@nsZYHFGpe8u9Vl-&%!>_mIfS zTl*m4a*k+@Bc)a+$v<*s@BJ86Su&}CF@G6F=F_;Gz!cgtr8vgT9*yO<^!@(r%=lT& z=?-WgdP5t16BRSQQEwlOxbEB8J)EGxB~^#^vOLb?HT6v>M_lSAdUPV5F~l4;e6U`7 zZs8&XI+~{=8U0DJFOP~O99VmOVi&he+pX@8U=~H(MuV@ejXt12K*Q|;uF5-R{}I2q zCGa>AuP?s5T!Tb zF~{{mo+3gpO8M5_2_p;2*g6i({BpkKZOUUt`l{1b>HrqzX`d*&F%Y;^NsWAAiebXX z0Z7%vCP%xpO(c0H<8Npa2Ovbv{(ZP9r%8>=ziYzRNeVC7>BZHi1^FED`HBr8&(-8| z@20H9vxc}{!Myt`j2}%HQeOo$H?JD;;tH2gCU#JQM+Vy3{&ys2tx7U-roCfc3jG%h z%xqn<@ZUs4Re}=Yg<~^021fQ)gmCKGkpAA%YERP#{K_ZY^?L)b2|&my zb*{pmW*R}?8UX-_0E;&xu`Unl_$pG&{HDN?CXdC;?hBDJlSgYNo7-PI;$><)+T0t& zxHbNSV3>{2kJdcaK=6iVNtWzh7cw0@)c5dBm`pU(HuDm-6j%6GC0l9w6C2|5m zSDonE^>jUexi;qN{-5d}4V1i@Zagj(NVykvrZm%&E0ES;9ev3Ppfp7S0MsAq|5@WT zlx);`g&b1qu#h?Wh1(Yh=pLRG@ux^&IJ1uXap2+V?u! zEiQZ?<;rpH8h&I|R;0+S?5A64ADW^VQWcdM6lNXY>$~M7$>#BwZzr==?&}9`YHZ#+ zdo5wd5mhT2t4;NV$VApR1a0o=i~n7O8JxDd|&mA zL?yf;TaAVaKB!UpQW)bs_?S{TTqVj+H8xk=b0Ozo)lp>)Ef>|?=NZc67)6*YvXQ`C zb9pt5U_A{KjVD$viW7riM67v!Kq-3ZH000K*fdXrrUyJjyzS+LO94{6!j~+0$1KI` zD3bdb!$&hlF&{Mwl3xsxU!h2MP(~{$Q=~Huvs4$^*b*y0?=3Wcx4hu%x5EXhHWvq@ zK0P~rWEFQ>c}MR0*;1?`USBAEecv3$qx|L?qRggM&(sf9X+OHe7zF=Qf$h{~qrC5Tnk6|Fc;!Wy{5& z!M}p*$9vwVmxhj9{&QgYD=f}Xc|tD&`a*Qrov(kO4RbrCD^!-@l;TwUay!Y6ynn>f=vPt_@pB^|f?$UYOvIgdH_seBNCZe}&K{2K~%uxOHZgxw({e4r_ zKV^)*ppAJl$1H*bPC@^)Y1=-@D&ak8W&BoS{B%tU|LgN+J7%9B!+ZaNzkPzQ?^yD3 z^%9RdQ5NTf`{bCNR%G1;#wkgsUf1f41aQQahgPIK3-F($6t!)yla=(lrKEEW|NBu+ z%Z0*kpZ%d&^3#{LXNuc@&f@UW+B zuOQ*BAkkT&!nmPV*vRAmf5vX=VKyBaRqD)RVCu* zl#opCACtV4UVa^;*H_qYVq1pOt56xg7@1KplP|Jr@a_7E1QbY(!e=8mY8AS=9CbFF=6HAlAzf%T=_G#@omNPYYL(VK!i-rv(glqWUxw_w3-^s;grOM^M zAIHIRz!GS(1gKd?ew0}@e*Sh9h)rGUUG1dEycE$jScMubwv;p#mo_BHUMD#ncXn1= z`DO8gWPRV%9(T-eaHaqxj4uctnfw-%0`(Y0D7d;rUpKFL(L@xx$nsKldR60ObFTBy zDR??zH61%zTPcMrg7rdNR!r%c#QtelHg1IGy=>Tn(Pg_Ny_le@O6k0-L)umQW##{D zy6rIZHET$tqy+N6hj3P2WR3sJ@^YJX-8o=U%fqJdm?qWqu~>_Zb$%DP;tDR;uPqBT zYedKNh>@m@W3l>TSFdV2&{z3AOBno;g&~-nn!Ho84T9C|pDvJjDRz3ZRx?;JlvXjZ4U1 zmD=nAWsP;iK}=bxHSh*V|0i0(8BMc^+DOS*rte($ge_Xgh68xiO_x01d;`1V zQDLIhuKRUNkuyV(#aOxd(eab{Z={P1c-3oUN0UwsEd2Rwdr{P;SaaY?m72GFR`^nC zl4SqfJGa^-^{9Da0&$(w+KV)4fkJL6{xjWm!}-9<=8tQH@$%uRv{BpU!lS1v>~~~r zyLO2BU~`+G7{Bi?uW{|k6BF5~>)ectEzVx%Ztj=Bf+CAET(!Jv!>-T-e7=EJ*_-qxs48dpF+YJ#F60%KIGosj&QoLW%t^#|;}P zb1OR3x{CM<#o9?%-_hPy17Y`6r|ZeNghj3da7(do;N4bkR?S5M754V${PKx00jGm>hEe{A}2=k8gxB8{jOJr)m%8m1b_H5QW3 zV}k!BF{UbSxT*pSDZf2!@YeJlZEICFd>=m6c&W8fe){`9Mtjy1w($PZZcap3CSR() zFT!5$Sd6k6A&jH8PWGc`at8lfWlGt%v1{DN^;?4Y*B-^0Qy=CWI&x#m_3ckxmd>AR ze?xEcc~!Gj-?S|@UZvl@_af)}uIJhFG`A@q*I~9T;|_Pco=GsfFr|5}(W-k_Ey|O` zWf9*ELf?d(UT>QG1_=;a*P+q#w6`#dsh^5EtJ~U)a6zn5Zdksh72shq0_l{ZUc9;v zt+Qcym8w!9q9!kCT{bWO%Uem^A4=c~!vvxhcKid|k}y8PCP*Sud`HS;FOSeLR~ zJ&7hC_u`qzI=C6KXMT5#1rWiEBqru~gn#i67jR^W^ONYJ>c~C&D2e;#?^XSTdq#l1>raLpYU3&bIK|F z9cmwE zyZY}dH2>?yzemEU7!ui9)!l6y+1SL!%JLgNYY444W6LN#%akeb=$vnyx7Yw{k>?qC zFJ9qFUIcCBx!O+}bOMj+7`3$U5;!=m*jBd|5|G&tplBOj8NO9Vyd06_t&3zjLbJN* zTSBu938`=xe2!^!GYY$*eRrc zVvkTfin3cS9<)19I92-nLE7AG-VKw57kp0S?U-h_l;Tvhu4rA`gDI_tqNA=CzI$%W zKWUk{aoG;1S}XW1v<+{%#N4TiPygN6^68NO9`M*sC+vTB`>AWu)cnEUMW5@pDSpMq zG0&x(j}gxK0rfV2z6xBKS3v;y3gr6Gxu%3gL>Cu)u>$;+u!+*b0h+3UR0b#ff%Y05 zJ@7qH#5f`<0}+)(-1pUJt)X&?3N6D@sT@ToSyyNM2E^+%8>AKBMP<9|qXwxSS%IH??BXhTgcKiJzB;Zw04sk{o*krUb-Olq+j2hm{$qT!(tE(f;Fnv4t& z&_;>P=z9@AHVK0XMV!tJ<|S0-_}-GJm|mpn(UVnF%hf?RSvBdGmXV)tL}*-VrvBlf zc%M~XhVOp?>wWh>^#CM4WD9yT^M;o<%Z5G|VQ z)uv_4_3eT?6SnRj3UtP^orT{yVnw8vuhoR z>)S>v){4d4Gm+7jvJ&Rc;PH-(+V^H9@=!wDbld8P+PLY#FAe|nUA^#D*VH`MeWCUZ z|0q99e`xon&tY`7^~RZj2ahV*H6434F?#5--s^*2a_gR<(hIVs$Eyp}Q5@ksK0%Ai0VcX|tC!v<}k|(xzHgJ9Fta)}~pq&T1O2?s5&v1-dqT?_Y&ouA9N1amDI%zSIi2cK})R-ZiSKahJx zta0E-K`L7g0uoM2u9rR2qt|xeAoZ1XgT7VS*CXur_f2@sUn(*~La|OSf`MuK;n?Kc zLKMi~m{MEjhBSzApmId6X_t@~@l}>9LE-4FSK`Pe`F;{My)R7$r4Qz}_C$81u)jhp;2hcPjEZc{ zP#osRTQcnRGO-+zwRtdwxS{+QuOjjyM{gM!^B=Iqk_PGi4JW$eB41ap>CQ`%CAf>O z>V!6g(2TWp!kX84Jg#&XB{XpCzK7pTVYD=e2HeGBY{U7?1|7$UKEFuW<5JNP$QT%J zy5t=iOi4JK^=U>-Vs_h$;vi;ENH~`(d>{%5MtmGS||H}H1zJaLuZ#mFTPcl@BGsn#|miTL`y#G4PS$VU)fNi zg!Xn02d2@OT1KpI>Gt&m3O zQbF)-qYQ+U29U>8WmVTsffEuGBtTjwP{HDSW1DZKxB`ljMyRbV*4Nou6fD}ROt4nu zr4)Xj!|#u0j|!CJocsR1T;J<^T|dyuHY3A%Z~&~5Wu`u_ry8v(Zo9=j81F!ReTqle zQoY8`ssxiC8U4~MJVlG`NXR1(G?s$8*v#@%U7A%Dj&Ym9GjyINgISV^H1Vq_<5{j-c^GE`O&9HIZc`Rt38cL^mT{cow& z(Amg7ydf)W@vG1JpQ>s%U`x;dup&e2(NcuoCgGUak+7_N>8W5asK0IWVMK^af^+df zl^h_~0rVyF1?t8GAgrfbi*Olj?3zOaEt`_XI_889WO^(zB6IDso}Avvx}mOX5Cax( z_rB^e`UVt~nW|IxuKEBcPPT;;9(71HPy!4g%%f_ius4CxJWeZM1lqJg6aR#{x}wnr zemmB5*Y$g*9IqeI|HF>upJk2s?ba#h?^a9KyztIf52BK@eBg_U(+~EaJk?Ua{pGZs zrAHq-dEw|Sy=zyV-ZRU)>zS9Q^tT)sJL>rpUw+2G9$KEJbok`qzR@+)5L84bEU9S5 ztr-%pNa*O04cZ;xz7QE}MVyc*Un@uKnVFcRV)b zC*Q?mZ|}MJ(wdX!FJ`TH`0TbRuWkI>>hiPyscC!s)S(~jN0UoN3?BKwNB1v(c==C% zU334&|LmN+{QQ58&U<>ecWBZ&(zL(k;xEHa*PnW?JM#F?Hw-`jj(e+p9e2o zRr7OXT*}pZE}C{u-f;K$mVHN`(|g8mKRDD!yMt=suo-z*NJ{7vgNSOWkGA`EVKXO% zhU!yD)-t&5%_-=rfRJ74|NP|1&YFuKyfN^^j^CO`oGD=NvvX$6O+{Z{d=e>>qi1hF zdU4Onb35-`@_gZU{~dix@3sR2j}1S+=1DX}FJAf2|DJ#G{ae1VA2|NlhG*N)F=klw z#kv1$ee;3kjX$mYdGyNj!&VNQ$-e6JeGi^_Z*mty{1+zwvU%HskAJdh$8UpYJ-+I? z1;4$tVBpQ2M|)46I`_cF@}DCQ9_Xo=)xT;y<@>G;RR zb4RD-t}4DoMoA?0%+uYcF2}kPQy%+r!pXYdkE%!9AX$3aI{wU4gID}~>*Rsd1Lme* zzr8_&-b|*wr;e;1apB^KlQ$h++;?ta<=CHM*KS*PX!Te38b!jd);6F6Rg4WbDzBzg zDP!x(p|H6JJ4L24ffB)s181OS1b8{Hu?T*6^S=XW2Ny3 z5KrEA_|&^6YBX7Z3r|Br-nQnp&jzOVKln=qysA_Eli%q3@{KRQxOg38z>V4-+{X_N zjJtm8T_2qP{`*_LK0fgEiFa1^oc{XQBX3Mv{iuk>Vqi?$g8zqz#CAFDc$2mcMd=hUC>#EgJJpMA1D>-BwY5ej z5!&#gSPU`w6o>xWu})MY%iIBihzREgq$UBNiK|FR#MX<10*fh-@7!GKtaT<{)XSn1 z!3&J1SOSE?)A=Yf1@?Mjoo3a>Ys)BbrOarllTO&Hk{yh%#uL@Sk(2J8_TifiS#5uMVd~TufA>=Kw)*Bf zbHDvQ^v|*=x|^89kJ}W})($Ln4BL@DnTtZVoiz2EHr&|dac#)$sLo6an`^R4cul&T-r+`nMfjtj>xzP_>h!Ikkn zmsY&?xX)YFfjD!Z}%TOefrat)o)*{8~AZg?U6U$`1#S^4@d01 z_}O2-`S7Ukj^VG4KU=c$=$76y3tsrM-|p-zpu}Ji(i9gROy`;u2bj9krS1}X)yeTc zQg`$6k{^b>a&yg#uP=j`(Vo@#Vs+3zxinmHzGt zpH?kd=RSJpGxMfz_$0i2$fB8lzvha^oTG0}n*DW-e=XNJzI!5=!t}yF@jl%RmaQ!#eO33|*>hKE=;m#Ru{lEQyC9~Q zVsJ8wi=@*@+7UpEVf?yTbZo92Rhv_rE`RdOsnCK;wbN$}OdshrZkHpN2HW(0cO$Ez z!htbk$g=b=V$Hb4c2zudf9b?%;{^0>WdA+$7SDJkP^B*pjd^QYePM9s3#GRm z4mrz@RS&AtYjPsbe^x&^$;w##gBdT~Rww`QFR^*1SVH-HUuoVq%~S2!HpybNp8oeA zggdU9=-TId_=aL_3wUP$%%0WX*U22qN=HqF{wDUD5oc z@2)Fr?!}6z{8HD>j~=O{ z_61wVuk?tOl?P6DZ?Bm6+^6GP?E7b|`0cU3biR>(%Yk3RM=qMa8#3j!|70UFye@lE z+r@pSZu#iF`5&+Be*pu6i=79YgUdfzaANG&Uk~KYoMN4o_tQp4=Bd+%?!9t@xboD` zKfV3x24$BB!k%k2h|)eaEF`ubvdYEE(Q> z#mZ}}Z|z(0(G}~Do?UdIp=U_Lp(&Y@PyBZN^P@*D{(Sb==z`)C-kz^p4)l(i|F!h5 zVUMk=_pj`KGMN%UIrfW3#_#;%@e!AfJ*ZUnziQ~dndQDAwk%0;F-a~ERrt!UX~`iM zE5V$QGcz?&U_CZt$w)8Q_YfaTQbRei>-F`O0)u&PvL0Pito{gUoi_fr6c^&M=O0bq zts1O9E^hzuV~^*F@BQN@v_JRf@8VC5{G@Qx$U8Q^TDyCaedY(|q2a{D&Uy0F3W7e|OXkaQg zPsmr`tJO&*B7%-^cs=&Ajo7}4Ay2(!Y<{YBs+{mIsxRIX8sahBYD_5CC2c!*jdH*6 z;ZSxAUV8e8?_-}2oix`jxjxQv1y>O(T-lxXoFBgUQTfI6`enP{vwpC~`qdL&&s~46 zUTRN$vhe?&n}mP1XX5P-K}62Pa?8z~R4JfXXJ2+Tb-YavmC=j_jKOR~f7ERdodCh< z?)ntrGvF^>g1K%GUN|%T;+ost1*l1N&55l}sIgt;S7yw{4XH_~*_0nZI$@EpV@7SD zJnK7>Q=5i(bI66sHIyIK-0s)3sF;jw-leBo#UYEEV)j*~)aQ1)i?R9}-7Ms|7g4pk zd?m`F4>G9n!7H32lgS_642zB{Z?z@re&>8qGU2vzu&>y1 ziGhzWyJa2oBR1G`+YTwQikVi=U`1!^^!WEbR1g47X9jP!ne^S~tV%+T=QMArNnWfN z-h1VD-;Dp`o*Q>=Td-&Bn6EsqJeKqD`@b_h-Syx00|!rkA-(n8BYnSxcdwkb=O3@1 zasB-5j_=!6{#y62lJ0McU+Dw14da^| zzPe`esLwtbGp*zq^TNN3b}~#idWVngAGWe|;G_G0{o5NoyWcx|?!ote)>ppUd-}@< zKA*dM;hq&cK0EeZ<@_Jg&&77ip?i1s8(x_@cG7Eq{OPg(woe^3`p?e{KX$NX=C})A z&AQw3!jsqhl6<4PBj=5?*`GeUGTFU;_@II7{hUvD@Tr3hJQ+f79tZ}uRI@!$kg?S%h(x+hq_ zSi|$MbXUB=I4e-5Yo-=%nUTYU-6b~XL;PtAa%Y;5>p3^uqJ((smPT9R!~cq)MI@0l zgXRLjkK5ATR+}UrdFaod-;*e^&HXU2YV*uB*Cst1;#a-=Qoj3;q4Rip^@Pu267BZ-pQ%$Zbv`xdWJIvVJVtdvoy43-YtGVtPOp8LusS zW-36IOjlFsRac`JnW-~wYuO%%u*6!NFp83z5kTgBTu#vQ3|&Brfd-d>pH$SyTMR_^ z`l?E?jPDxb43)&=3n;B>}IU$4bgLkgL@D{NUJ zQ?v0jvEl8^>c|MNciB1=8lJZBeRwF4k!_C6<&#rKTH-I}wpRt`8eD;?tGLtn%va|G zEg)B6_ylrJs^qE4x8Y*i1a{Btpu}sGlDNBAJw}Henfk%Xl7-mG$vR~?SGGdY(G0bw zW?>J@7kufPFTeQsvE`#u7oPcT{|VE(Yh{jw0Dt?`CH;sE2 zx{p2b>3x4*waXQ-h}5SWR`&ht;3*zMx7?JL~~8o+T9VFUN_d+DO>zka&=^O?k$^F zS-j6owV8_98bUkMaC2#vagxuv)Z0Di)=jy|nJr4~So12e&OAwf*AO<7n7%t&OvU;q z^kG73VCQz6d`P6tO3;gwK@QM~`s~b`&BTo2tnk=c+}jKsVU4W>6BHh_1+`Ti9qs75 zPpIzCym^QuGizccT?%9Yf@*DS@wyg$W5MQ6@eA6eOTEGq%`t`VREkT2siqbZP0lAx zans1?c27azjwUOmtRb_+k9V-c;(1XDmu4N;&sdlhDg7jn`Az)pkyE35RE^`$wno4! z{BA?BuF;1SIJVTdS=bIP!bdvIT@|CNG1R89h#zhMjjr3HPAQSNOOT>8O|F9WB9`fx0@#bS z<$@WqJsM57ncLxb!JE$!nIcrvESCT^D5=FduvBUjD{9UX^jo)-H0Z1W#0@h$mAOs) zG}dyd+|9@sv>nb{m!hWBi=Z%-KvJ?oAO{85EX+na8|Shq;e6D=u(;$aI0+VOhb7}_ zIU%NE-Xt2oXzO%`=~(`lerAX;Bv=N_G^=R@j&)KkE{I5|LS<3}>;;~k2%rXr5L$pI zq4XY!A)@P!1YL4m#HFZk;Lb#|1V&@xOqw+si!&2W1mFd(iZ+m8=7uSXq-jRvtnCR1 zsUUAW0*snH70*Mj#w60OrHFR1ZLwxJk1)frg3$Mo1Gl|9`oOW$#vjCu^Us|q@0hJz zAAR-)olTu_ow?%V+U;L@-*46hYd_pSwWeLMrUXRH>pyaC?vGQRxv@VnvH#b+@| z_nbR*X~T^bf4Hglrv<5Z40_FXhy2`!&#KSSv6;Qsy?XT{1vf7oxbei%OV6H7%xar; z>2Up}d!Bf2V)uo^Z!EoHW!kaeZ_0*S%r|cRc}>1SG5+HzeS3c7`=YO#ADwl};a{%2 zY5R~bzllA5=68YT-DAGrJJg>u{{P-S`_}_sULy<-$1duHtMkRdA5Iyn%_H&7hP%sY zM<59x0Co9rzTfD8C{2Z;Z=Y$8!p&Bq>%Gj4?55TMI#ZjN4vo-U6&)-2>vFq0qClV} zHJd8eOTi!-%^dqJrqrOGjS+TO_?mAytw)4Xh{QEjMqGz1tkk9Kb< z^ci|Z6&Xj@WGtyU)PC(Q^HTMO`d#2#*3Auu;)H>gmwdRW3IRrkXvR<8;T9CA*_U34|dmOrui0(}qGM&iqlP6`p08S)XVFM+&ZFrGF zKEVV4ae>Y}Rk${z-wlAS?GtUubg#2i-F{huUQxt zI&fv)HqDq1;SFpi1NJD~KNsjcE+}zHXEnI^{{kg;%#aIZR9D+YAR+v63Co~sm()qr zz}TN!xAtS|v!*8yQS@De zW!Y*hd6{ULtFV0=RR(#~gZ$N)-!0ATogr0bzvfh;V%rT%Cp83iK7A#>oE>(l`)JoJ znix9uw0BMa+MZjt_OIm=xDApjBD8aDixW#jt$kU1KeU6p_igRrq^f&!R&5%+_n{4* zbo+O?r>=hR*C)(rnbw!ej?Kx-_kDNWfu?=8&OctV^``$0`QpI*{qOIL8MAZjBKYL* zp8DY9Pk;Gs9afUtSDgC7w(-Rc^{q!QP5N-2uHl_o(?0iX{YU%n)SI&_({Ok#5e0ju zmi-vJsc*!}JBR0Vl}>s8$H(6v(fQP#bHV!gPjwvL{QS-?8}8__HsJ{vq=2Gw0*;{`&gHk2;s9oG8n?xaT2P&GECVPAu4RD6;nU znqN9!9rNJXLw`RJ`0&436-P&WTlvP|rEBiq7}(c+WWn=;&{_1fjT|@R%n+H=Wrmhl z4>2Nui;A{mW~wb6-8P-$QL`zHH)rG@4x@L!4VZ=Ur7zEH%Y5ncSG(`q@Fp_o&a3J_ zx$ViZ7VA`Ny;*qb*%g|%_^Ov*e0uX(i@fBS>q`D|!;@pT$FtK4w~G9t%Be5M?ob>O zMXJkPd8OUunHeex`HxRsI;v}s$rRPgF|T^(U008~_mfe-8~gdI-_D6)vExXvKShVd zT4pkEF(ui(diS#?t?UytRmuOqs4MD5uALfid4%(}F_mlI{N%R3Pc6G)%Dm{H$N%X%i;2Dd+3wOaX;L*VX6{oVC~*B_V>U4&)-W!ETlC> z@0>8U`QfW^PSEm#Ts^EYZ%X59QlKW1?(qjoSpHQjJiU(-?_q~@xmliF(IqjyoYJ=+ zFO1n+Tg<3u@&TPDm!^?rR#O5RL6JcfdE=2| zmAz;;fLV z6KRc;OX4X3a4Z55#yq5fvMHuG_M3jdFiU*`4WTrxXh<05Bw;^V5F%`p2HkS6l`4;X{A=-`^j${_gj-njaUO51(&1 zb??RRPdARf_{@RRedV8S{O=zwn75q#wYOy7%J~~FjXm=Gl$VdMtK4wam5u8by-F~LqMtpli(0g#&3Gwt&G>w>5F4Cl2 zMJQ@EMl{~8x!&uaw|Ka>uGA|#GV@ilHWX}KRJGn2;WjtQuQNE?ND)JmF+_sZSbR#vNO>L65=s9yn)nW;p{LVu@FhfSs~Hu zVd&Y4GWVKyY*>-5*}r7NmdwYZkXjVzHiY)cHOch+-9jWAr2_I z3+}5n)GOM<#v9s^tsnYIpXD>Lf|}Kqu=UtQ)+wHEExiL8P)sqHsR_}w(_T=1Is@g z|Hwo20~faZ(lh0Q36JhOGd^?t`IEa>be-Du))o4*5B;$7((jjC%4q%g?!Grxrat=o zo4sGW``&?p*Ur7zx%{`ntH-7L3=v71d2-)-EBl-^y>FMNtsVW}VHH14y7>M3`+g1j zzMX2{cl=K^zdZTssYQ<@CY(HW^1!IsdcRV<{hDjekGL33-MI4}U+^zy7IY6e)%EUy zGauiwy+3vMnVaVo?Vj8+<$~eBFGIKYPrt9?;jJq#JvQ&`WBLbX+`r?UEstFsG+0#U zo$K8`Fh+m;oeQUD{Sv$PKg}x#wq5vsN!if_%5#+%sNH|0zGvq}-K=xJ+k9r(#f@iQ zS@7K_w>^8dWkJu918cr}HopCDLk|qRfA;;!8wW=J`zkw{$#{p~E-=)R^;E~Gxp4O& zwrOVEh0k7h{VTd@T2lnW27t;$w;5+Sc_8MLSmE#LK!c_bPK^_kh*k!O$nWP`QEcgr ztg>i(+ZO&qF%CjLfeNz4Z>xpQ=#Z{OG1-fWmYh)c`glKHKqiy`sx%>1d=#~xr+S64 z_nMFwNoA*GbO2da>DP>5#@4l>$_WGSveP*}d)cP&+N*cJmiOf!jXBMI~T31-u+DV~P>w3ZphhF1Dzc9qPcNMJik;HZ{5XI)&SZjts*(YSl z3NJ#z%em&>g)u+cO=knvaqiyco~qJ=qkbhWfHsnQLm!W?zn0Ak{fyPPNEtAD)X&6aSgt-*U~E6(=Tq z{@_Hc1@4|RkNFcxF}$3zQY zffYLulN>||uSy3&z!y4CTlTWm`545q-(0pDFA0OI?GWltJoPYaOFe}~z)=zpW_8F3 z@xxnXx7#=D|9VSMNB}C$9*?#+sj#G<1N_7G82VF|Kw-N`79>rD_I%4n-him0t5`Co z$sc_Fsq3xRi+ld{+zm=%qT}gDufDalH+r?_f$~+pd-M-{s~;jHQzAB!DdJrZ)H~Ls zykx2R$y1zlN7q_UZ;1WKr?=)GGYnbt{T;`i$iHK;a88P^zrmK0KF@Jqn)t^mec^_Q z4Z`0PL>I7hS>mtz2Ro*Hxk?Cp{??2+SeA}uYK8>LfB*m!$djYJRTJj?@1JwaPfcDO zV#Ld{E38ZF9^?o{@->N;s_5aq5~xdhgO|f*wt+<;f-Y(ykF|58HzBT}Z&cG7jajjT z&52%4A*2Tc;{u6x%t&v|+qO&MWXoB?84ixyy=&RXsF`_!1k@L=?1&1Md>d_L zQ=|ab7LT$C>Ydl!yyVN1?||oqD`>1)idY7vuhD;GmKrS`$ArxTLQ*f0L5*3$(yp8w zU9-ul!@rv8dn})MkhXea3|mx9*FK^2&8Ry(l;@(2a5eoPvq!s+)Zm2y%9}Vb&s}H; z2}jUw0zYlX#jrkwnz!#7X4Fi}Bum?3JL0RL?TWX(YhPx9y+iUB{yO!55tu&GOUtQY z#ErXCEOIQ}rfYxP zK9kY0fAX>OvwKRXJpIPXo39UutDQ6bIK>)64-KUyrZa6r%7?3E%W-v`n_%Q=!nJKz z)7f`rj#MCufM0Q6q;QcKsO!~T@lw)0+7exo9<}Iuk5A9 z35mjX1mkGd6WmKK7L{SeifAnT!-8xuJ>D~eYsv(0Kal5n#U^u-vPq&2(AxDBZ*}3& z&f)2nc2`&&QCw4>OBi18&0c%`Adg3HeKA+IORD91DLi^pKtJdP-9zssM_&JL)o*`Z zB(rO!tNeF8cV+GE?^WIQ;M!1mRJqCE&>zy z+EF29o40!yD5mopK^bEe*>+?@W6?Cm`-NbP>sfoC;sdWQ)M`2SP7%-+|JE@SbdIbb z?U^aE9&CfxO+aSH1?)o(IbnzgARV|-3ez4VrlARcAY#V#(k8k6gdz?3)OidMXCx=J zIEQ>8ne2u2DVy`%m*rGnhj|2~q^^!7s2`1;LNga&p~e{6V?qmJU$VfR;Y0HTxCo-P zy31liFhr+tT?J9eNo80_?Krn87vqEcKm@vlX&Yo%y@AgaXZEP+vYPx^Gy^`N1kJ|G zRI|FecC2J=bJCVWf55^sP40xE@q{P5nm{uFS;6{BJtM*9fZf7={k|Qg94n-M+KqDr zm>O=Ll4c36E-Iwe(*_!_Bv@aHYPz);SGA$1CS#^m zzq}-8hbn33RFl+gFQ^+^TdAp_L}2o=OGa0iqZf_-Mpd*}>k(Ah2i}~JX)S3LB?u^j zR#9Z8#ulOZT60|`jV!rCb<(_IGHRu(m7KAljt8KGM@bmpL_{Gy`5bD8Ue0u0d_8bk zrfw$4Z*e@|7F!?FmST)0t!2+Wg9BUHl-_IftDLKP9Ik?`OC}5s#LJ8EET#F0cnKo- zX=r-oT^;D01DCV3m(;ozy$vu@ss|Bt`Q|xl3AEk&+BXY)k~AQl+JdUAK&~ERZma@5 zKG;Wi&fK2XT9)3nkm2GkK7nlU*z}5Uz|K$+tYj}or^J>9oUWNcX2sOjqpPkdu+>%T z!^$EHJi!z--F9O!qe+hwsAfVSs#m=MXRR>FpA7P11-afn(`?)+*`eqidm_3D)6SrD z-Dq3w5bKO==6^h^(KD}7oY--1|EKrZ)0cj|-?3)+XuL8Lww5ZwX@-r_gFC}&i@U5; zG#%9V!Wa*F4GI5Ws)opbVKay=SiH)K3>fQi6dN(4O&aWo!2%{!r3>Dmw5?}R!T=(e znsb?qEg5yTwd`}Js{$^R(l5s;66X0t1 z3e=QC3GGqM@Fe}VW>J?gnCsB2aL+EXLV(E(>bl(>o6TxY&7pdXZn6KEU0mn-kEy8%}&-UnZtm?1|dkPIn+G~g~puWi2{}QQR0O+4s(kO5vJ$@!&N0` z%{uA;9%Ug#d~YZz3?a>F+Ff96+p>4Yyv5s?>-xZSMN;EFw(f36ov>BMpim~@X{Bty zn+(LF>k;(QmP7Nwt91fa&F3a`?Q1u%+lSn6u~rAkU})e3 zjmk2laa9WLK~9J`jXvs1gHuE#29So5$Sz6WwE_*Me3nfPE^>DblK79rBxa~qn_j(B zkS80LI?YCVZN){ilCWqK{;Tfs2I7F|R3;RoiM(N*dE?pf!qylw$C7dPXLXckATW4A zO9k09SCQN{S}4f76yyBueBCyMN z2A@E2@g(TiX??moTCpJ83KheN_qd_=8cdxLM%dcZ!mo$-k#HZICkH5~AQ~_l->${A z5S|GW482~=3ICuphKWmhk=z^J`Q>I z>}^-LWC`+v6D?T`aaD_KF_`qKD2eKg{7Ed1$F%m1^7>g&DOK!Ms0eNJ=D-!u0+} zEq$BWcI&DJYG#JWU?5S8QFPj@nO3t0RYwFYY?+QZb>5;nk%>R+Kd6C_!S{4); z5=Nr1f#@a|+XYLpKE>(GBG=U%n)Fs0etA4^A#{*D=&7A+`0S$>ajU#YZ3m|Q^ZOx zgQY6b&M3yo=@xXO6&Ibf;~sKWT6<&n9C8rvq^Xhl5cBa2u&lH-Em5!h%==l~6HR>y zVglK+Jj3aK8_ka#5l+3!0o6 zyHevzYD*bCQ91___~Sa5@loTLB$Yl`?@qSc=m2y9?sF)?*=ZNHz8M9IH&B8X8U(p{ z*@fIj6ORqP3#=?eLV!fb-j*|)qF$em^opF3Mr6Z%zGj+|V6MQMlLZ_2K{O#W9058A zD8U%=A~CIPArGdtESH_4-I|Bh`UXA*dt9vVZU*U7g@sM2GPf!{G_u$0LAF}5_~nCr z@p5tfVB!PSg-`hNG_h$j^F;0|xSR}bX(lP<=V3*lu*bWsI+wl2D6MvCYhRU%dQt-r z+M4}Zo-U>dV5FJKk92@_cCV|xMeNE3|&15wI zYCD5{|FUYWx~8q)DDeejyh}@)QzD%L)x!hP z9360Niy?oI+=_ z3}%^t5lLT80qTJ$6mWW$ z)+$h~4)h0LTjt9NSzll*F(J8dg+)yxiHxFKtRGuQ9^RKzG1H^fJ>7#$0yv0|YI4aX z2{l(JooEI`h1OZ}v`lsw$sR&`W(jiM+#f#{ApvdYK?;o9Ex{iapnZ59prAJ-fCDE@ zaHf~)r^5j4;C3QGh*z-}nz0Aql_2M6ajQ=58tD{^NL?U{F5EQTtt5`jLW_?Pi%1pD z;R()rqk4EKly5^k0fbipkkl*;t-BdrsghQ(DK2amvd9+`20OLSNZ622?bDta9IAQv z%2TPVy`c)jRoIZ6i#BAY^AyoFy!X(uixTfSm0C_HEgcc6Cb>EdWFF7IQx| z6ONC3baikSkTg$5VCN-Sz;Lt{np2-`4{A$p7)-0J|a19RP)8kS}4}>cVj-$px zs~?+MiH{8I!28w9-mY_%t~OkK^5S@8cf0#SR*Ka&JeJB=#LDM)FIWhYBo0m>b`l+C zL)Hn^4DQ$;U?04GeF~!uBusi*C>MHXWORr13R%d}cLd3o0RW9NLr@wH6NY@31=Cq2 zk5HXpKdvO0x$B8sVSe(kr!8ALP{Hi3cIsE*;Ylfg6C&2E2ehPBkk*-|@eeHCE5S9Z-Y6AkMctd|-45gzw2e^*5&@Xb{?Pie81 z52g}B^~tq3JK31R?k3G_8>81o`%3Y+P30L`WOYE>Egi&Bfn^q5okgoM@HBGGd>vcR zZ7d$?+yS_Y5h{A=+hd$g-u(nd60{~bLKPpR=cbTwib7_yLI#wMTLilGeaNr|MI_e{ zU%eU@Gju|7KdK)Tzm`i@h*KQ~FYN%?(?+7z5NtlFDxm+Yqxx~H4UGmSLg+P^;b&|T z;Q0X!UNpoxp;~Te<7OtB0L$ZSMR9baQJI_{(AA~L9iV3T`smzlm5pJ*YN3tqRQ={k zuVyGT5{oT@aZ}zpXQ9%|DA`qC8xv;qv}xFL!0zW|bKTLJ)=CBH!#QRm<*r?oBH|QT z{0&qi(KJOuW0r|9)zc#4S+hYiY>WiGRp@v{N=bnw7NI!Ibtx=!AfQlI?M1YpQ1!|r zVjECEBnsKl={+)ww=Wf_V})L2;Ai(%#dBx3Gop%D%%@T0xtnSmy60#mU$+$1{z=Ud zk#r3ug&a^;E#g9NrDn~EL(+oRl2B_kg>gv{Iublw6Xfoh%tPT61|k;!-C0~SO%*y& zu{Hf2Fdpb4bkO(>ngN#e%qFKZtT&i#>_%@IYsnZ)eykOpdF#m7eKVkNL!;hAvJ3-p z+Ct_6mCpo<-Vzmk+e0mCiZ!6GmjF0yAzdIY!Cste#ub{jN*-?4B~;9{ z7%YgAk`g8gflegWdKU82%+#}?(0q$YSkwxM&X@}8@K84{C_pFc8bE||VGl7Iq@r^9 zsplKI-Gx-pMvHI1*FZzez4yRWqBa?7FjI8hu1dw2P`GTd+p}#Ejjl@WbC+D-HXY6- zFNhSMWQcq@79-_rh!S>WfhHFGB!-=Xout=B%`IYAqDX;X%WOu6KFQ^w=-yV|l%El4 zu9{Y4mFYSd*VLuKXX3IudqbF{aM^NP5M0@DjX<^4LqbqRmMcTyLXZQaCJPF>Wamp z4u99A%&3Kfo$zTLS7r&l94(a-MzhBj(c0P)up@$SGZS_M=GI9Jo-K_ShDHEao9zF6wHpn=VA- zh?(XXCAJ_kY#I%~R6B~XEysSa6Rl$PpstWr6_)T!5b+pct6ImWIT7mBT%{R$4d_CP zGb}MQShpk>LPoi#(~r1_gIcFVD=apTF{jHPXx(i~Wzs|WiNvTz z=CrazgKf~}MP@~(fbMVSrvj_FAv-#$wPA0=OW%>uTFnS_k;N9`DStcu3UuXTf$Q~P zv$gs3#3sA14=|nwhZ~5I>*4cgskK<>Jq8o-f6e$v`EZ$lP9~H?Aa#&bSVB=G*$!6INM}#h z+q@cj%pqWub$q_vuGuRH*l*K#!p;dT3$aJTg$2Pq3dg+KQP( zclv(9?;#?7;U-_sRtP1T5rV(pS#xCX!@ZMWtPw!6;kCJ{0RJJ`1<0pQ9b4tsqC z?HZ%8ZJ~M16;Plwjq~mfr+40BaCk0X>LLVdRh;WT(+9vgdx>BG% z<84b3KsA8*6V({-!~=#zP;P{KRWZ};IJtz8!|*0UG>XAM$b3xScVTT$HU*X^LY2hO zRc~yjrPmuvc-%3sOwr=h`|{!z#bMIA4q>4PGngo2s5p$Nq%J1|bV9nHzm0Z+OsVzQ zwCjdYmc{4is-h|sg;Za@!s!$ebN+xRq?2}HF7I^kW*DPu#Wj>38gKdt?MrnH$~0;B zS3|+~Cc#Y}=$cgB0{IyX#zc80Yh~jYejA~+Gf?6!vQgFn28bLpr%fQ@4tt0Ku`0^% zVM-dVh46|pkHb;R7({j!x&!uNa~)?fCLzou;31l+RRrTtol)mggWjS7R6tUZ3*pN+ zP#kR0)3SqdQqX9&EexccEI>wFMK+5uOP@>zYANyPmGvrt;d0UrcHnQ$(EGCSs9rAS z6X>+j14YlENJAs(FcGMAsjYo=Qrsz3g=!7~*0cxsiO$xc_53$WhLIYo&hWM06K#&Q0}aHBdGR&=8LiS}v2U63S5z*aAf5Q$nFbV>^IF--)@!*W{~aL0lAi>xigvieZV@_(e%o&~_CS+~w;_rnG?=mQb- z2RroKV?pV}!;O<<^o(9q5M`5&S_DUdf&ygg<~gV!=qmwP*9W`V&J=0?P*7IjlChOhjb#dZUgvGM`LDlv2J1unl~rl z^Fuu@tL7=Cp-kI3ubA(!Y;~?;sy#f^1N;T$6RB__0DnlxwTE>qUR`EB00RLtx{QE0 zMR_Xic^c(haROd6$b=gPm|o-Oxi9ZYaljLbrAy+V+MLK@^2PO3GuAB~cwg+Bf#f&y zG)N}-q&`9nQe_A&FcD@_KGvlrU9I%mruWyaUyoP>t$CZ12xKG-#`u2Qmei5=0jt`a zd|{J4LDUa}&pGHES9A?3AuwozyC{`nLeb6{8(P%FQh@kf9n=Jstwu@VHe?k?r0Ibi zO{76d*w$SE4(x6$sG@?;Z)|xT=mlf(ki*Iu-mXz$)RMxI{b`UxF$6b}RJf%i164RqW9h(y>KbMsf zz7+AFB?T)Z6RmwW##mJooeD;sS_w;8BC&@<2PC%jGu2DdjM(74@k^}O&dWa7H>#7p zTD3MG46ibdG6mAX`;tnrJt*i1_z!Y|s*;)XcoG6ISB1isIah`K5^H^a6YvyQ&cZ&Z zk?}lCd1{n16SgoZV-io$z@dkkm1GE4h>ijhOAeqf-9&VCd4?1KI0~SX1d+dbMo2(v zZ=+W-);tNr%Cl_B%|qgl@YVH0*c=Pf=FoYWM3_#fc{5`Lr+{XcE;BRnvW;q%2^DQ4 zsfmVr^RA%7f&l@FSWcY}{f`wm5yTj8qtwgHsV^kwj2nU|37#HQvuLSh!3@KjxezXp zUcnouJbUdhc#!C+8Cxfy+cY>BtGF{0xW|i-9(+N(hRBK}HEo;VGTMw2GiXc}V^qRU z-{Wigt6TJV2?tB4$MlK`pRPQo6rj>~fynSt5im@tEFaD;UhjSo>Y!J(s0~bPeS!&_ zMv5hOS1{>0IFwn@zUn0t$N-c84pKSaLa%DOhYILxdDslNBYS~V*5PHd1(M~g3-=dR zIi1dq3^dh^i3_PYd?;`xJy`XKNQKe|($5AW3-@;9y4DfhyU*37w>kM;T^-sI7{LL+ zjB<&3WkueoVK)4`H#ZqKRkx+;`w=_*Y!9h|F!gEe1qoAds{WK zr$j1;>Eoxst>il$=0h)z>~iw)2ee{m%`mUBwr3G8g{{IZXVu)Ew+>XwOVL9LmPrAA zg?`Hy;E}q(Sy((mc=z(muc{)S{je(w@c7v}Y$`3fP_=w45O*Ca>pX*lwEI45RXKki z6DdZ20Bc5Gj?=3UZ8MftSC+3JR0whW+jB0Fe0da>SIq$dDMh;VyL~3E69WNhG}Swl zxK#&%3hep?X4@0i8JEXW^t6ssQdZ?k%PWY$XlyVd{EGHenhv zZb*G@TQCCMhs`%-A>BC=-wGg5~&wWG*=)*ap`c; z(K2uC>WJkV=tI1ucUx3I7y!41l2p$mUxHc`WrI9uc5h}WOg7c-Yo(W9GYy_04ggiK zo$->Rnpg9+@TN*EaF$ungKbwLFs=~%u(a0^%|cnG1e{}a{oWlUX&G!d6v3%2!Qh5& zzFFZ`!nRk~nE{%;9e5O_V65gTKRHg2RuWLW*xv9Ok%r8G@g#hWvUZ~(v%nuhD2_XC z2uoQeGmUGe*8M`ofUm*a6$Yc0ADuWcVxUR6O+XB?1LdK@(pgneoCOCYD-+*~%jZGZ zixb@|WN1)VLW7|7AdQ$DJTtD6CeCJQds2YSLCT8e8*4cr`(~)*J}3d0i24~HmH)`1Da-l=;lk(4Qa!HNJ2Zt22)NauP&OVRU%-;)2tjsmhcY_&CqO$ z%{-Kly^zWui6J5_vjG{vDLhJmG-`(~*kRC-{elQB5$D6X{s0^iOr11=klDu2aJa@$ zsU}fc!G417pr;&8_3|~T8C3W_lEGo-bdbiJB|MY}(>B31t51RPE?FB%?^47fvkyi* zOSAIqkk&gw(++yxUd5|{DZ*$}WXR^m<_Vcnqrt+0aM_f9lPlnl5dfg;agdA&lgbX9 z;HT)_1**QCc9inS;MK5vN>N}M*=rLiYWYmrO!;zVH?O02yB>-fg(t~QqGJGL1QV0u z8sz}+qF4|+E%c!RQgFRg%fzgE9};_6A?{}s?mP>s7G(Q1EkaY zDAiKuVowH3QkPn}cLqa*Epv>;mPTO>@TavC8t{U`H_=EzLi1Uo>-~^S@(Zwy5;7%_NpH{|6ARh_L}@rp2X#fLRBvK; zshOh#*#)RSXfd*$4{sUr3tc@xh`A`BsYk%KiZHPRfscwNzoU2;~Uz^$Sah$=+HrIbxs+e79ZA<35d zd?X$C5`tnggrbfxIk=Tn$iO!meaakw0>wlzTc@ez2t;L^#SUG4zESfvWVn^Ch&X{7 zNHc*2m4sH$78a0-z^g_a2#5FF7eB)m&{Jf4Tm3 zVo)ej9T5G|`Ufc~;QTUXO7hZx4}-!2Q%zMseIbuZ#u&3jaK;>(GtML5mS{jpqplZx z-zElE4n2;?Kn~U-IhYFR)U^dXuPWaUd0Qemu=kWiqn!S8IET|o#+4*_I#Cxvv_*!n zh=lqchZ+P&8iK~kdt3(Zey@ix+i0{$$(W;^l_D?+0Y7X5Z6M9A2h42C2t*1oxmv}S^yTx z)#lY39Ae$D+ZY-(<&7YQXhl#lYi6t~5g3!&6u9K#B7?^4$s5r~);^rKlHpNPUOdi5 z6jT=4D-BR%;|9u)AY?+>=Qs{E#1d{u@d2VSM!vj4g{>=K9qkBi(|l{R){p9)zt|RK zPkb??n^Gx|N_ud?jt^XAE4i+=vci)Yj)5%kJ4bSI^VT7#6=T~G<+r4bBA9u0YEC%c zU``&H1rUk&!ND?O9aC9CMMfY3tfBcK}afmq7_Moia=s* zBjI%SKA&q$z(H+$uY1rst>Od&%dRbTXv!t612NV?%BuJJC_HH=bMz`up^I7whz9?R z2IiJ_$kCL7ki9wDc9Y9WJ2aS&BQgQDB|P75EM^a$d0>DSmae%;pt3^+$y6u6X8?cO zv=@Y$^}jxv1e=rBHXYqw$|SM@_>EThvzNUF=zxGjcB=sJt1#XT|!gI;wSXZSi3#}2O6bw zau%09Trm?91pbRKBs6_<*-o^{r>KS_K&?HayW`-Z#=I*WLK|aSxJE=E;sytda3wfD zDOANZgDGV*bi^*^51e9Z2<|xR<*rLs?I@C3_-ll|ds1}|2U>JhG=aQp$zr`0F0qT! zehxcMEA+5pi;w~|!h%!|A$A!IvOsuwg%YAQz(Ebu4p`kb*QI5ACLDYL z=(W!K;O-)$1A(J*Pv1QD$wEXH(k-DYXb#XmV$*v0TkPAx;3}+z5HQq}OJ3)e6;WH~ z-55U1orkH2i59pd8ptG3t5$R#hBd~5aYo^s^Z0c2Z#xFn6!B{SOzg3g%VCA zbVP@~Q58TED9*?f#!%pS(^<^K0@_%DISW5jNK87z68im6Co-5KY7hdg5U8rexP-B( zrow$@g3K&n-RFX z!Rws6pys0%N8zBdIXlmxL#@jN<7a_P$1erU02qpJ^liV4F=6T>j7$`SMitWR3%q>y zge{JRhzSxB`*++Pi4UWgM2k(b@|ZovsnqTQeH9!__{uaIrnyxFv=rl9W+_7pj1oUZ z3IJ+l)oS;RQzyxVD&r$67F4sxYRv{Sc2U4JS_pl=TH_8(ShJ)um#SVs9%0*nwE@YZ za0JE;;dF`3+$JI*3`|K)F%;&F&U7innL;^gY1C5vm=FpVM9owde~?R5`+(c&Xk`Bc(}%h%}VeQ76;JE;#yYkJ-XYT+9uGoTmo%y>PN`&p90Y@VlmIbb!r zHy=bE%j$uP%lpS`E}-%49jVN=)P%xQhU|xDi5XOP8}Zc?(W3?^9Im9nE0_^ix3CC9 zMq)ubgJi_Eul8V2*diHd0tLaE+bIql=qqH+C)(5h!=pBKD$7>Kcd^I_mXKHO+S;%swQ42unM;`j1hNYW}JZB z-xG8>Av@5atR0eF=Ot!^LLnFH*2G#7i{~nS59WBSA^j!-a+4-*%XCVw8w5 zN0($&HTh8J z2}ubuW}H@_ZDcs^Z6bz*Mtj;8vv633(gvOLvejd?pXi{IV(El8quY7~Ka0>)5(6DD zxFA?@VX5lCwP@MF_Plgf$i!&9gjUA}92zYevoLhsgpV58!=;NHzAT8LT`DJ!rIAoT zsp~>cHxXcVl%zLi?#19HQ(vU*!V6pxHF%j0pq5F5)}jQx2DT&CGjM^}T4zy9Eowe9 z8e*5En`u$Jwq_5a7K8BUx;xCV-2t?c&`hzkAgw7ad zjLp~OM{+eq2?VuV_3$F#N?UYD7`81Rcuoju44G%EeS79ZtKbU~^V}WXE1(UlS~JTz z()g-liB+76UT-~nzFCvFd>8gJcNlJZ?2t)a_cIyJe23Pj3&{nRE*~I~^3kd{}UPK}Li-=)3o4KO6L+PnQcodYjY9eX@s%Bt{J&N=TW?} zL*k*%kWocc8~ltS_#J@CrW8(%jz&H}>BLaH$Pk1{?#`t9QK2j{e&K*xCYDZ@X^kNS zhT=|^Q$z-A)?h6ETG+2YBXflHUuPNG$AHB8c0+u*8{nGjYIBI zcs(r662a+OA}oHscY|F`bP>Qev09+pe8a9^Z?a!FbWi8J3%cnjdc_c9p$2d<=Q-e(^5y9jkCN* zKm-h^Ae!B1L4zJsTdhE5eP|<%ep9|x#dcUBMOxBSei6=M$JJUPJ44u?>`tdMcgEQm zo88$MW8vA9;%aGsz}#mQS7LXlp&!S3Qylb2R+W^{{m_oFX%s0Lw$W|L*p|}0R@Ek) zU0Na-eUNVwLX0)B&eFodY2w(wCST2ZxIX5s*)+tL+Yyyn2(7k zw#OBeMb+DSRrW#Zq0JwYJLMuTP&- z6_rXzdBKc{?l|WrpW2DxrZmcM-ISf?E?IP{B1)@j9O3RC+V|+H;ak?u`M$bh_>+*K z-CqWgS~&PU8{YyyD@BQ9y>#r2~D&Wt}-`0VXQGOQsZ`9UsWg<^^I#-wenNH zAu)2;+(2AvwPEX_N#3aZ!q8OQab`o26r=TdS7k@WT-4;Zapg&IMx4do6eU=%;CSfv zna6LkrjGvKuv7|Z%&pz5gFjoy_tb@Jg+Oy>x0yk0-i! z(}o(q8aegMO9z%Dzw+9%gL~MFjhiYfPNh$NzE7LvtS!Y!vpya$Y~9RHwtP8h$BoJT zv*R3Q`;>(2uGO07)>cd^{pfhH!7M%0d-{c@M)UFNSypCs~wAe zX-|sugfQlQMvng8qR@0vf!IUp?TKlT8ZU8>aQtM*dxL42O4~GL`$*kW(Mu)M*c5em z+jy1n9}e_IboX2vQfbm{DzVx`RVcW;OQBu6YLi zoBQ&iIa}n2L6)n(tTliCP06?(ZMLSRB@&)dQ0X~5sUpf`h|5J!@rp^4NHY_Lm&YlZ zSkgAyj_$k^8r=BmNS(aFAHQU&DK8{%6seIQd3>grfbg`6GQrz9W})fD5URKcrS#&KDv~Y>|(3i4i`s3aRUrwd0W2Rr1jcMG2P^$_vmRkc!7b+)O(SDIyG%$ds~S99UqD z9)=r~qv(>WvEGAX0Kxv31O$p!Ch#<5P#zh~lyf$Y{Bimq77APj;^eEOO~6%F zhr!1Jc7zD)ACNX{Vh5eMRRKc*#lh4j%Y@3ObyKvC4W(^jcC*^3dS!AqX0<9#(F@ z*pOsl$l+G#n*L52lgTfqqX(%*V~PgHj`|3%g2cP?m=G0EP{t$WoBISu71F^O7*2bx z%T+7nZ)*t;S69>Yrz;^WjTC{>b63Qa;RuLD$b^`<0`MRBMUSo?Lv3ts-ds>XiFOyH ztjoGwh(TaAyByA2n1LU7<^)J*NT6hXOh>>qDH0kYauyUhtsc0-tg|c*{M)7VSN%^%j03sVrJXYL?D0{|u2lg$-nHvwa5D_NVpqUbzmXQ8MW5eMM z`8o6i#8$Csc`l9>RH8DWFNLcQk@2B+^d=!HrWXi!4;-A8Ve$Bd6-lnB1c*hXMx_hJ zB9WvpesZK1?F8kk*e7${sO-Arl4FAMU1^Nhd3qXoa%K%=T?6%ccwaYdDBdQdj?l>h zg|vFqgjVE9?jSoTt|$+=4Xq@^J4%q?LI`f~c7Ctr9GIvxTJa^Nl0zUlBJnW2rS zg@TC?iOnG@kb^#Bc{0RJ13rUzx{@4AGcUe_9D#=1jM&YKXT5Z8OvzPOP(vu1*f{VF zuy0{AtCBdSh~JyU60?FZTa;$2D#FdJ5Jbw_fQND^?Sfc@v4YP69Q1hbU44Z9Aw3ZdBlMPG1f}D{ema zUZ6NEyn1A_9cV657_p1f+F1>cb7MG+1p&%N4K+Y#%@HMW)q3^8c-|vKzAPK$uy0Yf5Jkl4RDWUYygzj5YvwW~VqMlvMlxXL|135jLJD(EAu9Rzdzf$1iI};@M`xmt+7_>Rll2 zC=zVFWLa``kfasv+>~;5^*lL3z>HJY4Kxa&5Gx%MQyY}aLMKAFDIPcl!WuqVQk7!y z@>3>V>6gEN>qp2#B$r9-4psZ`p@5We+qCp=f))eoff3Xq$HhFxIgRvrN;!Gp*tR$& zkPfS?oLMe!=#>Vzh-CcTyN8LwN{eI#@?bu$Ly2M=0iejqq3+&egJQMWxmd|S>~+}0 zq4l_Z)F5!IR@@cAR9Or}0qOS^N>=bIxHTeP6p;F{7{vic(3zE>d~YqB-DA}Tk0^-R zY2f&HWC?6O4oTmI(~P)Z?vI%5^#8SPBmls&wulEu29lCEK=A_WB!zN|Gly5BD#^ck zkj?F{_Q)6yMc5^3xvO1Zny6dETwePG13_YnfMCUh9%M&?uTr&)=W2;l%>?ZsRC#noekq{0ViPs5>iwmJFIH)YUCg^o5$G#Q_ReJGBt6oPWvk@VC1M8vO^PN@f$Y>E(r=J$KnY9T zaGbY*Az?ZUfCOv;XTemm9iog#V%sER zq#*)f74|-8Y?ZoNm9X8<7aWFDcNX0NOPZWJvxhTe4a04{dq4H;E9hAV@*kUEJtDG!s~ zUA@|5iv55O4oE8*_(Or@WTR>w!YA?2W=R?+R$}Z6W&;HnLnk~EzLBBsNE7Rfsn}L~ zr0{6aZ3HR4kwOc4fS~~PTz5i9J=iA$;i6^uNy@~>UoQBVj%6$zy&yZg6?zL9HDO3r zltryDO0~FSXo1)yo7tZmkd^5$jLKZCen`@Gz%!BgK_3AzUbjL#dryE+Q`5MpujjJ$ z$H-h8Rgek}$Gn|(h>;0q4*aG(^O~bJ;lfBBM~F}u#}UYOgL~b;IKlm4D{UocW(z|I z@3t9JuSs0DEDtb1k~0YyL0%K1AQiQ=AjbBj@Lhz}lqZuj(~lI$Zd7}i;7ffk2_n|O zA>2U5j+zyWg0fYFw-W0KeH-g&$<@c3M<1*o(&K# zS~PkZW_dv8)} zMXIH(;u5YwwHjj(vK890Wn5^y!~97wn1Hm}GS7#D!%G;XM%N z@Pr4&3?WKHu}bSECPIt$_VM^kG)5HYJf%6kVm!wV5EG^)nuKExwp_xnMvnEM0ng<| z+67Z4lF4~&yt0)g&PJ`3Q9ZF9T?LXUNPWR|`g_*1%dE+jC3p#(e?p$_d>>y4`GNk+a2a?(xZK#&1QsUW@+#*q++t@99ArAg0BvvFV8 zKzFY%s;p`XZ-lx_72T7Ek(x*8i7;&8%XXMyxngl>SA$%uRm^kVv))H4ieBprwW-`R z5i%TuSC@7r2Vpin$M({^JvK#BLpJ0R_UM%o3!?2pEYG)-OeBW0-Jyaq_^q0R1XIw? zOy_D$O$3c=E#@E|6hEaLLoYXi6nJiKcooUaV|BRJA%!9*e*rTQsz- zJa1|b4Mvxs%3AJng}H*|*rL3s`BWL8Y6%#mcds{b@l0Nw6zJ)t7OhAk<*s=ErHmc$ zFBeF^UMWaYMIZ|>S5=RnOe-Im$)X=CcH9EK2xX(aG|6KnQ-!>??6}-L>%m_5qAJ9+ zG?2Ieg*dT2WN?g3^O&k62CMBy?V$W1J_VAwB1)M-J~}H95sq-?1ZaF z;Y6hk&J7hiiQB3q=scaB5eaG!`b-r9!*v8U7bK1|$kfs*Zz)44$P=N9PxRtgTX)4On71f-sP2wEa21R6R7SsHZ*t)aqAZ{oWgH4YV&f>t!y*CABy;(mVPbYmgX^*I zjY_kF8&NAh4Q%tw;6Vt+n@Dk1-qnG$1yiQMgn~c{5%<^2R#41Q?&BG;(omJs%vFJm za9UY7Q4}OTpxe`# zO_^O-dzn1t(Wo=xSdQ!YkD6M+vwC@U>P+%(FiRJ&j=19>ka@8b~1?j~pJdo7mQ07yjQbmzl?NQg;Biyvs-rd7kZIVp-Os^fsIUD@y z4dQgcJlBRLT3IebAOnlURu2^|Y*cd@0>pb}n~YL#5CNv}wv>jc$Z zStKQLmQ!+}Pp2-!D}{563;_ut8?m}red|F}tQLu>CxoVzf}kS|4w4;(29~CQT-|yg zxm3gtG|FZb=A~YJY&D)7C4Wlv<2NKKj2E31ZK2rEuSwSs5(7NW#K;iJ1DhS-QsFPe zt#uPk{Lzq5N&v0Wa*mP@SO_5lnKc?So$LB&%oZK!Kf*u^QiMb%NFSqO@`@Z{H=*@s zw46_^NW_D1%1c!SDlIt~WN8^eZ&nr6jaq~4^a-*YN_8lIB>K7nskAfwB1Xtb$sWn4 zL&w3MET@vWI4qS@m^OvnBNFIV0-BqV+|xslBE&izrUHi1n3*oS?r5qV*biok4hP9d z6m1%to84_L7BdB$5=OM4njAo20r7Lr{cvbd>|);eHtn7ZttA`#7J?;t zaqAg*06NViVXLeJ21rJur1tP8-pwDd2MTYb#7;`LrIcJnsY7lqu1ui~ zYL*0tCaw`XEV(+M2aHO!N=i+9 zs3bl%U(ipqgwIFr8^{Wr!IjWxA6aV&x+PC@kkTWt1k!ajfP8j*63V!9IuW3s;_-_= zseCGwB~Xb*eh^>ULVf|5qv>zqp2E6II6mVMBq6WhegR-(w^+ko2nLKeVFXzUc+(Yn znw)7@8noo<0Q%8VmF}*>%Or*I0fByF4DeW}z!QTp>{7=bB+8VHa6DrRtf{FAAuHi= z1(k$Sqyc7D2oVcYiDu=Q(mj-k zK_NMrQjRCohzt%qj8of7ff$lXTwEpjB9S14d~PI-c0?|gOcm1#Fz%5~IEgipN{u3! z31h>8TB&f5t;UVnZd(&i$2i zCn(U(mb!^yN407_N52_BQinl7@te@2iC2ZPNW9tAANhEWLEU7xyFt~UXLd!H+GOZz z=t_T}qDBHeRSxyx;o@AOS0`Z3sv_`UH;M5flwAf8A&yKIt)f$05g}}G*bxc(;$@J& zYVp6IN{p;~UVxQ2%0FS$SAib#>&2 zsK_&r{5`GW0!opoK*5#T$BSOv6Us$y79|spgnA*mc8aI5kN;0o__F)dKC;578nwrq zsTF!?v%)wC_5{KiDSUw>B6&x7j_NakmyClHT`skDo310`jjWN@H0wz4 z!$LH0fNbAB9g0Qp)yQORj(<#MjIUa9~qc>=P<%E`^dyqHW8nXZH-SgTg!U-M+A^Vq^E zgplqeX_!l5@=-9%7?@jDDRIn;O9_n{BC*`f+E|j4@CkDQLJw4Hq{wm;TBNW9S7L;V z0VR?%AuJa6Bg+t96kRhgX@LlENijGRtxe>`n52S9QbHKMID=Y`C^*Vi9w`hpV&6`) zyYWCI$Vf?p0lboGEgLU7@yDKi5I<-+k}aj99y1yaqj}+AmCoK^ceon0W*ehC^r<#Y zLo(ZE4dr@n`m9N`ldhKH4qN5ejiM1b27n>|mSG$>jjnjQkUpA2b9$kc@Td z736qJY`?)wkINNI)dF&(;w6x&9cn-Z%8Q3IT9xPobi?-~;r>Ct@1g{Bp&Zo;gw2LJ z6KRvGpb~wfC}2<(Q^FyY5+^XEvONS8G-$vS0uo}xC6okFyJ67(cXYkQi>1fUp;w5GcLe#P)e~j!4(7S#$yeg zjhcd^40W)TF5_^Ea~-4vS8SYKK_(9&BFwvB+VEgeb|1bY#k|@i7_O2%$8Zs;;z~O= z#EiiQ5@Hwa0j4RSIxiF&?=Osp8W3BhQN^TA;2ti*c%wH(A?b)BA4?k!aISxlFPxuk zu2Rxf6y0X(Y)IYQxiJhD@g&)KTIwb;07MW8u>gc+kFRG=7bi~_jV4thNH*vX-&}$M zGQu22YcIg0vr z-fp%kv9jHqIU*#PI2EkE0aI}BLV`_M?j&saqS6@4=kz8?HL18psx$SiT{;!<4`~&7 z@CXtVG+oOO$muWv5o*lD#9(<{jpZpB@JvT`d`_5Kr{Vx1m`@xKiil2(K=1*6Xc9FU z-}vx=R*y|WEqZoTJ4lh8LJO|MoAV+E2>pXgI9=F4aXeXTJY{5JvyW(kxK7gRwFR6k zG0aLJjzg^=Yqy)&khlRz8=En!Ot%nK$A_Hv$wH!%j4?yq&7{MZF{)UzJ zbcq-x{Fm-SEoO{t9#d&hd2BgsZ9ObF49P8PTRIGD8a!ZSf$W4HX39mO;-f3Kc>P&j>vZT^?P9A~`@^B$7;JRf1VxlV)cv6)<&}Kvl>* zo@RRx8J6fkCrc)=S-8YN@sVwZ{PK)y$^E05n2b{af|W3OJP2+V3Rj|zYdl5jnhIZZ zg;eU#QH(8ak_l)02~h2AHT~$y>nQwwgQ*AOq z8m2HeqhCx7gTJ)zs#ILDh*|teYmOSApMq)iG_FM%W;5PcNEAVCwyI{l%kDj-#~({hzkn!=Q_xgaEQw6P;z#d)iUiU_@z zp{tOXv5gUUF^n8{5J5_+Xp=?ArbOgPjn~eUOz)f8Yd=F3Px4&&?~u66U~V> zVKj!`lT$~Tis^DBr^y|g0U{td!Bi%J7Hjc*)`%n@k!!OO4=gTkng}imiX!p}DJeh| zN35K=u=Ad0S8nWZq3^8YJI`!e@mlTeOYiURu;uoD79AV*PrkbHn1D4O~NqkP3&(reN|NLV%$(^_MQUdTRL61%7lJ)^L7 zxMX)5A&*}bay$moEpAzlTn7eV|2 z6>}tx5l$Gtm?I0!Pm0kj5@{Y+J+VklJQ4xZi1bXsWX~vO+$#={*ru^2$;Z_o2U%tH z`1xQe(@`zCVg=FlHNeO0$~cOdy+Q-aQ;zCHO#z_NrFwuYWnSLkjW#f^Hd4h0mhG}q zGG(Q8z`%0J5mDgc*e5uG!e+a9%qCy7X$++o0R6hduZrE55LPM^mu^lMg(HVn2YiG8 zx;QvG{yBXKE-@XWv3XX-F7qPC>wKhR%<{qw&f;s8J6B?|j;C-g&jGnmJ&|h+=n6t7 zf}Ds9gpP}}QJ4*396dV#7btxIEVW!COz}K)lHiAhjk!P|_DDlMQ&<^9BqEw~OfZ2H zwsdui-XqNp|18-8NfH^Lbg^T^5CyL!SM{x|v0ry5{3q*j%B}%d4!`-wM=P?|E;&18 z#P4%T=Xo!_wP$><70aLKz3sI%%a`}sc6#wwKmB0dek5zylq1a&y5*ltEtQ5gF2%Qz6FM0%&sMDorVZ#s_DTU! z6)?*qXs+ht!!6LFkw zT7;0;mUC>gRMhxw^~vC4;udo~`iaw9VsW#|gJQ-Sv2A+W$4}er?Cm5B>1&9%)>v&d zN-W(@o)$DC4aKCUwmPgj6~y3JNGOC-B1$|jay=4t+=Qe9Jh%NNtoLeki?BkKd^)Os!cd74i6doyj8F_#C9@g))s z9!5p1=_WjhDfX5`8^s%sid3p&lvxmdb4ZmT-QGy}0q#X`Ra0q7Ae&??6iemU0F46F zAF#|Ne5uy*p6eDT+3X2ogPJHo^Q6Hk7g5z|tPGC!yK{?Ngy^QySYd?X5vFQaQzyyA z+qM~pEV%LI;tMlt6FNOyvgV6P74Q9i@~QXEolnlVbnL2aVnuaLpUUfy3AZ5)y zDU7l-NJ7L)iQS@$T5$rP$~pp1^bDe)zd3~EpI8_jvs^S*5Qgm|Ka)4JOHiumB#3@BIbyo1)D1a^_rkYlxeeu5YTTW{RIJ)m$Ic59) z=0(>!{&TUU)4MIhpF97--vPV zjg9-~K5W{5_x$~WDd*N_b&$DSleY}#mE?UY5d41Lo9~40v*JH zgt^gpw1S(Cu1g$JDxtMYGq@PRMf96gEc!0KJZBlLL4<>d1>}BAu9X}u0}9Ga4xlv; z$AFaAc{@v=rh%hBvYZ5^b?J~Xu}rZ55>UDQaQmfX39->p{HAM&y>9J-AOgB(=PB*! z;6jB7aky8uqV_3`wns9MgGV{2N?;u#Zm`9Oa{%oWv=jtRkq^HtstXfx(im|d6`(|n z@RIa4U(}-Lvj#S#RZwQJp90I>>?-OlcH2aRp6#f26}dvq$4%06HkR|4r>YVuqjeCU zL7PFQzO{NxvF2_gt)EF=zwl&6hFS94bf&KcMnx_g8&@!CEaE)$n{+R}LXKj>G1!xs z*^9;=b+s7n!b4}5*f6AKcSWe8_EcWfpbUs`yEum8f(pb^ua!x5f6DGB%`phpIaG{N zTXAOd#l-CP0G&dpYmsvHZmYe!KG0xpyxoRJ=E0+n9rY@3=bVs}0xocKh)6 zq0jZ6UD4NZui=Btr*?k1Gs{--RP=_C`TBp&aL>B`%jvS2uXGQeG~(bluYbMf;Jvr@ zzxevsPpnveXLW6E?!k;}w|{tMTXM+@4U4dTg&NhPwQ3Z2og;-Lj2RPlv1f^|U3=i(R|g&~?mB+o^cNdH>o)5C=x>8rMHOu#;u8C%IZKnch2Bt(9;EJ&{n`-9 zBx-#)6_zv2iC1R9sZ*KQp}4>0z20zi0P%^1Pmi1|#q9_g90G@O@Bs6T$FK%2IQ~?B$ zCy$e;MJY8=8SAP5N}~)|V|0u=;_FRLCmBVNOgz1*koH9ql)kHZSim2}z!{gs3>rCI zjA~GYhPPE%yq?OwH++Zk+jJ$r#B2atKo+uA>vocdQ2ewDjiH7S&@~XN4CDf&q94+d znB$d2Zw~1;ALFtO$+}louVVwFNSFvd5K>R1pw6>lCcYdI0HUC@Cll}BfKF8i9e`}7padee_zIH|coDinxDzp73>9}l z5barYGIcz^O8*TtD4}fUG>QeR1L-KFQ~B4Rbfqc%|gms$;xj4SCJR1!_y+ge8?>{&Q-;?+g1F8uMol6T&(KYcpC zEa#nD_PZy(&8}WWS6?r?PwfZkvWi zxUA5G|A&xeIah0R$M-}(po__O$L0U#Ke=t&nG?}Jy}f-;bGr$DPny8rFSVQSa8jqg zOBcU6>&h|r>Bj7wcXuCHF#TcGo?$N?a$BzL-Tv;gCF9<%&YIGtesyx^c2oM!h&w%J zi*4EArm_|Df2=)luJ*eJjr(p--MR1T&-2#(xoPXe-`796Rp5RU}@c&xj=dF#YhdQaZy*}eKLr%qcsdm^9KNp zW9_8IIQ-$-xK=6(4G>}#Nt8xPLW)vR1%vj9=AOt!0@|tpH5yc~YMz29yAJNX1We36 zPRQ4ga_-=%))cotWPmkqkEQ}dO)L}z1q1l~Sk^u8X>Zh#=DNixv@ZbOxd@r01_gXk zjWPP_AU1|XA8{0M2phmVBh)IHrkQ#-&+4&4wvtaBwApOl(D?8ksog%)$+j9zV_3T7 zT+Jdq(mM2j>yF#|RZe=GPWNPEQOwm-y>?Za@5k`lAp+uk&Q8&zsLqXHrf%2NUGR z#EgLH6WsWp)f)5;f>jTu+R2Lsis z{(R}-3wJ-=_4~c~^QP3EnDP3p8*g@~Yh52b)%i+PY>+xduIwS`wxq5e=}gfq0y^e&*(ne(*MQv>zClgF3RrExO>93GuM9l;fG3d$DV6i z)&BJG;m?O11D>qjoK?Isz5giPhHh|^X_~M`f>?N(k`Td)fvhrF7FQLLv8z>>xO~{H zuQZs_y@f#d$;R9=pX^GMp=czHa8~Aw(8CW=`baT0rNhklFVn(1TP@vW*|y&oih{qVnE-@Etq-Pe0R{P?9e=N&Izl05w2rI|U+O${^FnuZKMbN9%K^>6iT z{Y2|q`)^&}eE$5eQ~MRPne$|6_S&o|lP9MR-uB=Qd(+CUBR+k8&(57c%|8F*misrq zeXql!2KSt%znaf{aC=P7jWh4xp0R)LNb!GZ!U~ta4|JH$wG=jia!m)ng(B*`iLIq3otwW?swh zD+KZ49|uM8s7Q}1H24si;R26aR=whs+3qN`IJp@o-jGTyHYSrN#nTg>yM_OKz}{#8 zV=*A41rH?eT~D1%1|4_Y0&(b zOh8cOfXu+=6oberB#ernRgav=5ge){TD3-60+Xr#$ZobCBS&6b`tKrBSp1AWzq{v- z9?|#cWPPJ4%a?-6AZRGfcC4+4t{akEk!?2Usx?6i6=UMjOnXVKFWPWa<4Y95(T|PB zi8Q?-^|n-<4U`FDLo(=nL5?e-kfAzLAxIs2XvauUK~%}@RCLk7QFD920|1T&F&1@c zh`HM)4RMQ3N`?Dn+>$o3Dkin6LI-n(QW}3P0~}p(I+0zqj#1heCD zqO~FpYT1-F3J5rWj)&1QpwbkehbINfm`#M8UF|V7Czj*kWO7DsQn+`MZg=6jz{lrj z-ZvS%gS!WcXMS9L`^VS5y8ZBvw{D&MIq$*2^SKB2|9bDO4y%hp zEaAEB!c#nLy?#~DqJ=c_i8ccIo4OF7BB-FUX6SiYN)@)|07G{H=&DeS)g;4ESnl>o z(~yZv6#~*AE+eSRR<&p0H;v)D+Ae&)QCD9d_1p6k9{g)UOZJ7E+a}!F`R3I{abI8C zJHNx}#rNmkJwNZAiPq>3pKJX2Y_FXipXyn+?uB^|&*eSH{qR4hPgj>Y8_&G4VEBc* zJ6DY)%#U1wZQEWucQrM~Tq#_!s$dc&Fl}cf8cY)hxTmu<6FOAjsZs-JpCotsX`{nRAzDdyRvIKR z<~3av<}{N(ms(At8+Myo$%aFzAP3^Zgp360ficQvmTH*5iG2{n*d-4OfWjb99Vx`4 zs|T#0A7CCWnY)suhWBS2H4#X19PVHmMs%oAdX>pb6_Tn7hW+uQ)swEn*iw{Ym&`IB zg}8f2A_2^Yp{U|fRD1mVjkJvo3)R+?c(wQWp?Tq6+q+BqO^SIi`Q0PV8C8>}y}td< zfa~)H9Qu5#{B`q_ngM5{^pWW!{1v4$nil1G4~2DU6PSV#)xDN+UJeG%Ob+78Vk2d! zXj-b>ToK(=E|pf+r0NDNE9=1^t_FZqM6|PJ<{_L&t&+l}L=XU>8KoN@GgA0MCWsn+ zi4?4cu$N%*bg+e~13Uo#k0%U3Kx>HVr{>2hx9pIuj6`0GEdUihQ(xflO?sJYLn-*SKbq0h~|&&~LK=)hb1P5^7oThnXo zyKn3&+xgS_0sk8M(a`RlOR|F%eTrwQuOD;kmoDixq;venSHH9yy?si~Cy$$4a`u@* z=i~}Y&odb(J;PUx-bfj7=Jtmxy6+4>nZ5J%omY-6YBy@{cHhY2ciisl?l<4NTo^s1 z%ea#2+cU>^>e>2E>oNDgUDK;$;@u}!JW-w1;Yek}^~onke5q_0={rmSx&y=3j<8tp z!4Tv)U7e+ymRw{k*dC&QIH3Rx@O&meiqEB`Dy<2Q{$=;}%?tis^TE+I^Y^TIarTY; zH~(sQ^WNek4{|?UGJ3D&|0eu*RPVnp5B%eWHxAT)`)+g9-#bp#`=TwIe>`4T_}#6= zj(s|j^BRz>WNPeT)xx);muo*=1+OMrEEpcv7KioT$stG@#c!l@4qm0c71i0GigD| zuKBgQ=6|*8gYREifA8r7cj5-#`F!B*){p*oH=*bE$3|s4U;08@dpxU3i%8Vz$1HQ0 z5Jx%T;YT7i)0d+(pMz~$ms@(grL$C^_M||l>Fb6sT2k{24kZ&do{2`Bd3YT?VQ;($~(qa;TdyL9oY7NVmyW2*+Q5C8hx}o=~p|A4! z7V3JW^$08+y~H}xmyt4L)W0^V(nf6@od0^y{Lg+Ioze3_>X+kw{qy+jS+9IP`_jHU zy7Iy&Hv zXhgC+NdS-VEyM*Xu#ChyIwBICRt0QI1Tzp9;2dI2{V;Okobz9{8rW31;{BTAtuHk6En8RLf56`RHzSV6J{z;F!MuD; zuL-YzJ*N1T=Wf0H=DguI<|Tf9`V-^Uwbe1WWGj;DEBfSFHbo-wXs+YUUEQSH`uz_PM2S-n?%YzjVLVORc_Yp8jk{ zV}rsu=tw|4k-VBZ8F+&%`YM7aHOMe3Ox;mb(aT9dH$jyXsey24viUS9CW6JRDrZ3o zAV+53BR}PK`m^+%hl{?RpSNZ~!}e?U4`2U$;PpW-UJn`QzV=IV>%Ts``$Enizr6WR z^ZEyW^!}%5&yMyR7q!)IUUmA(qt(@^H};-Cf4={%z1QrI{#W1ZT=D*o2bbS)XFR!R z#*|t&&A3N@eEo3p>yH|i z?f=W!@%C>otvLA2yx&JpUUs(UnQQwWTPwG&J@D7!t4*I= zdS^jkboW`K{q=okglw>St*O=Ckl3&u;jYMV;tdx{?R9BAYI^BD>b6ShF>0hP)Tekn zBem@|j_fh2`%gRn{b#TJLpQ_>?c8H?x2fG;RsHmz#Jw+0o|Wys{(`gr-hX#HICK21 zr{;cm=$T)>>GIOcpC9?x_T@A8Z|t1qcKV;HpIfyu**GJiWagjG{P5(oXHKQ=@@D<- z$I_!=FY`Rv>|O038Ije{#QAD>+MtQkZ7Pi`G1CvNxMtwQBTfA-5_cM2P z9FvirCXnAJLPrmli1Eq}A~1J1R%A;dH8@%Nw#o3Olt*FVi1n*qgB{UWEj1DYFBvn5 z=C>Bvg_jk&i%WfPW9Z@==b-%zgi)6EfQ!)jWwfSlNLD5%@ zlvKg2{@Kox)X6)KeyNEHd)gM*xN69m?yh4Epw`+qt+eR${k*z{9mN15qlZiA@Ycx)Jf9Hg+U;Aow?dKhD*R)^Ie1w+jX77hhy&wIu z;?bY&CN%##;rihTAH4I5pNQ0Lv;c8X+rt} zi4&tZq*#fty8r~5RdKSb2y`Zqj03ADt<-FA6$BMoDJYVCsKkM*3T1w|Ae6cGYT`1Y z5!Hqdb(5|Jqg;e5t0sFL@;M0ach}h|lJ#BE`AnCa(#x392naMkY*%>S(w&18h=1c#yWk z7hRv<*!A9n-_oN)_0P^M>^d`;(C<>%b7l{9vUK^Gu>3a9eOnaO6%IC`S06)HfEVyL z6*WjKakZ3zbQhjB$dx^^7)j!DMK)dk`d(S5nv(e)5Bzm>+UG;d1QMyNrMg4}AO%iI zmNAA1qNRvHcm=pMQdIzjx-Q+8IymL=2WAHHK@mZ~C-Y|Jf4C)Xz=_lp6_e?PXmxOm&7$+h2PJJ%MUaQEE0`qYnGPQRW}GOY2$Gb6TEGAETo0oKRI{NPk? zlsL#7htLj|rIh!igk=^I%EX`r35%?;*(%#DlH!`HC5!cI znAM(|)Dq3~4GU_XZM~o-s`dQ(o~`@u`Ec^|J=3TE`Dg!|pLThAY1{MrzL{J*=f#K3 z3uayUB<{rc_hwDrvh~+Xj&1*%_+*!(ORcK4p3af=_LV2v#(#Ww=QWq|N#iEn;8h*l ze^tAB(~iRIC%1M_@4nmina-azc=DhV?`CYxZ7j1O7Dbx-kExfhBoge7Io7-KL{&k9c(B!o!~ib$alH zt>1#1|D3LVZQ!*tmoNVLLDGf#`hC|<^k4VCzmB|#bk1EtL{H z&nV`AoG2NsiYZd-C@3rP`_kquSn%e_>WR%;-uWZ-?)mrb+*%nsv#W}WPr05%Y#OwU z9^8HD#?cGS-yibG5x!BXiqKR~blu`oIq^`t0LiF?9JpW{kl3Rbz!hod~vW;iHz>hL6~ZTN7EvDR+Zcz>dIWQy!ng$mWhUb%J>=9$`_{9&pC)W zUagTD^V{g3J2(B{@M**$n@t*bWPYI>A?y*oc7T~AK`(`9+-*^ci8u=6S(F*Gnr2+E z-u>bI^K~und=O~oGZrCnE4doq>{dM%j;0KF^Hqp(SQ8^2r8Lq>d8Wv}X(vpP^%aRI zamkIFLY@ki)|{9U%Y<1scAi<=uVG03M!%^+V)sakCJ--G3ariQPunp0?QO$*?iil^ z{p#YdZ-!kyrk=7TyK#g0wVLz`cejqXnYd#4v;(&*wqM)(T}Z#DhD_5WbO)Wp-S11W z2d%zM+V10e{P@#|H^z2+Dt-KW$J3)1x0<&zrftACwP@-P9A%sQzD*-PD=j0_GYMpe zOww_2)iVr7ZomKW>$O*gZEcfoKX>v}{gxTuXQlr>O2{fu0hLCj0k}1yCYi!OC2g<* zu?*5+x{L%)D}$7=K}%Q-bTJu773dup*GNUw{Es%4Lk_oXbiHy^6H+UQ+yj>YsYqlGbM* zn+(8vB%}Df^Bw9Y@3_4AL^}u5s2dfXR@WnMnx*9Uy~cG9|Gf6~w@FjayuRhBqzf-r zrOD5IedepRyYK!S@!Si)IX3q?`%IpD&zV_q7Sct9XPV$sW-Qsd1-OR z;C$`TIbH1Op5Vv23MqlPPeyMdiEfSBg6uGBV3Wge;?w>E*B}4+O7_q9et-GHvoAmR z@#Pnq9IfYldS+hk{hRxzeDZqQMeUI8!J9Xy^}O9~!p&b7{P)O#M_U&>Tr==d%Yi?# zUS6>AU;q8U+h^4f!{@4G!%4B@JWwN(FpCIEw^hW@YnrW(S+F4ZA#HsooW2MI#GS-Y zbf{a#m!l91DxPkkafoPS$WLGZga#7sO_?crY+$9rl47wi*AytpX178Dh3P7=_vHmW zKC}KaZFE(?ZG(URuY1bXU+z?2nSJJsSszT9GHceLw?3&x3v)hW&CUMv9#-AF`S8+& ziczCi<>W74;*L65?60z?Yl2H!(Mb>um@CPOpi3TW*pcp8(yCHxGWCd)AU!6=h0!{~ z!tiCxlFA$)Xf#D@guW&T&_#&A-97<#NPr`k{t~-XDs0BvFZ^=jcKI#yga6$RELQL4 zjBYtcTNthJc9yHlC1}G6#<~<(6$FpG?f+TrBdr@thlR^>s*U6YSxVN#$+p9zihLtK z^Qau2Lxt|$USoQ0ilVErY0ddjR7h#({^#nNS+9XrHe$a6kuHr+wMUkdPXK8wwOB15 z*Cx8+m`ctK;C|q*SkUs*{5>z9`D*^gNB^sx{<2J-FwhqUcpUL*c)WGVzzFG zi2YByq}4%o;+L)G)&&*rC+gH7MW>*i&jr>___f`HJ3pZ7Ie+)ud!+-$f4%t2ozyAE zPM>sb$xc2sqEWN8@KX!yc)sj^NX(m~BbOo-precXtOP1bMkx4QhyiF*wbliq%%&+$caqrx&4EHtxsj`hj2 z1#HHTx-HS>nX-OE+A|D3gkg0irqZR@>;==qgP-Z5 zi@F?{H0#a}1AjZa_=W3R`0L8zb?08(Gd^m{d%b_ox%Bf-^{;;a!FOe4{XYNkx4omM zc4>9L)wZ!4hi|(zx%0bs*7bk+jd{7pHb;D$)oI|YiBo%y>tVwcwIH2la*(LGuZGWx*{nVLr(?5S>`4e~V z+`W^Q-Knwu`HKC|zkXrP{ZqI0+?sa1urT)IFKfFDCeRP#?pWXy$;CsdBrxp79Mjt5 z^2f&$v=+$L)x!!TdvmyyAq1{HjhN0JMl&c^%#Q|qW~Km zy7CmlkO|@R6q#Xp7!buE0B~-d#;S6arYHn^sK%j;sit5Fu-keH)eG^q)J{7%`ni2M z`%b?!eBfUXagk5GFE|?L^rooG6ZjBxL_x^ZoTWf1Isz829~tzn1HIUV0vX z;cBFao5)|;AV-r^-IT1S=+T~_B|y3WQW0Pc7cG@RTv8VWN16zr<~uIRkZW)O-%Ih# zj}>Xdhi4cija5_oN-sS`5F?cWEszXSn|3J%UBx0Q$!87E=#}I>0?6yFxB7OAT3g&G zPU?NXbTntXpN-vq_S33tDrxuS4IA9mc*^mK=1^0g3B3aug9I``qO=>1+d+&VsQ~C` z7)eSe?w^x|f9EF~_|AO)_rHI?XAggUGR$?gx)JLPL=~PG-Ze({Aj8u1^~rpPHLFgY zs@<1r@WIx)$C)833UQDU0f`6#VIwruOnla@c4skO-ER`HL`aYgV}VlCo#C%L*ZMcT zIvLQA;{CWb3L`<-k+FwF#vLaXvrH=!d6B=7gYh-C7^G;*uJ3!$x*NZg5rA`n#T^+s zALR4AaNH(zjtXci`ZBe<^ry1p%z-Tizkc=R%zl~rm~OStSCCTie!c80hkf9Q{AITz z8!snBt*SEqueILew`&w-d+(0AeHR;-VwdF=oo3+MYr5_5<1g7Ot>SA<<*rgJmSeN( z%(!vx-t$7=!5sD$(<|XJGE6m!#d^Ejt1_F-Y;!}2H_H#N*OH?fHRhdy9vgL9QDt-U zkMH4ogyy-G_qL^a z*0-}vtSjDs-b!DEy<1!w@phP+89=?~=mHZjgrWohg)SoJ=5;Vbmx_2P@Q#a!ot{Ul z?}q9;xv4qv4%FQ-{y*n?_4{caeB%Hn)#ujjWR09UhCv^D0YitxfUjZzvAVjOrt1NzSlK!n;W`EMEElF zjjI!NOkaO`_3rM>`0)3|WwXMvNp9BvIcvwX zhksz4y})rMy=#8faNA<`V6oBN{ibi3UT=YLC&8J8sSae4*o>2*zF>(#$*l~`5(^fy zrJ9RK%Mq;FEw9+rJQu0tvxi!RS= zvAdUpO6OPI_K85EBE>ZL8aCt3pd>PbwK29p8c%Q-35y|&Q}OvA8KspXP7T+RFaneb zJV&tyq-2(iM5wb7X~BYJgq$ivL})h-GD7N*n7ovL`hUO71o*h|_hA%8L@WNpGb~nH z#I3-C1`!j1UAYK-8P4zBS62J%`_`8~caLsy9H!j3Bn|SLu?{PQM377%s@YSH7)a`2 zP$6I@a3L6}R*)b8;$$PMV}kLfNNx%Wi5vkLFx;IaiI11s{09a*$Lmm*_Vr({I-K#aLq+^U&qUX{gvH-zElIQ{nE%>Wj1?ll_Z=Lj#HK!`O-*dmZO}iHg+U}5 zVG%^K5d1~aNsoo+Kq|pxkwvTZL~i?-{o#QNTcvuYG&*O_m(DM|c*-~Xk1Ss02{{S7 zpzLdrVUf;ui0F8O)(_$jV4%XViUOk+F8iF|{jd~(YE6;C7~!}wY$|dR;J{|%iC(~j zMzBpn#C0^L6sOl(b^Q##>Hl9uhkw(~<+)K-#g`{gGAZ1|IDJ{Mwb%TQu#VfGA@LEYIXtC6?rEk@&I&QKzJ>qEuXSz7$_Gb0~BX{z}w(8_i zXS-Gjc5DuO8p|!!-}Hx@7ZeYd4&*xwuWrwh=a(BS5%#RmabiZ=gs}9LJ`Dy?Nf1HV1i88RV^ zP(-y6HyF6o<&ef<$juk^hUEsTBzQk$cEbl#!FDh1=Ji4$Ul6~<5MHt z5)Jy);6L2c^_sdDS=dnIFL@+q+`oUq{b}pos(f=lJ zv@g(aKsU8CFngg{`g>nf<7>R+=ev#*=-i+~5~VUo0q4tx!5QId=<`^@I4L>@a5t19 z7H~L9szZ1Wp`4SHxsH5DZSEU%4I~BtFw-C+P!*KlEGM2D8%caVV>%IdK2jmOGjCIv-9uy#-=R~ZXOc+TL34&^F{jtz3z`)9uq5i1G-lEow)x}$7Di@5aq(rYT*b3AD?fdKA70uLDqF%}1fDNJqHwX?-> z35YPAC}y!1mVYB+_TL$CO{;k9f5Tzu{%oIP?|O5+6Y54#vcc;F(>8=SItVwsvxtCc z8iT~X-FL`xAY>9@3t%J+=76=2Ej#L1uCrL|U!@6}vyIOjH^!Kx|G_<_{8WC>Vv>0AprCi*oI%-6&q@VSPC?CzTL)YZba+ZjA>H^-IJN1w%V zRk6Sov=X7^*|rMkL_s1PRTVB(4y_5v={!hrX$` zy+6EdS@8-@jhI6fTJ|r_xvd)g)hjqVPn_3_!VrPeRC{qwF0&R(C!YbeEs> zoonp$@3hx9)V6k5QgL>>ddp*{m3BM{=`ZgamGjr=d;Per+w%Ti!jr?-2PwhHYYy#v z^hJ=g7G|Brix($c-i?KR;$9oI{G_pbO!0-GS{iXeY9@pYC49Z?)&1-5>2b*(Z6QVrhfGb2G8{j$X#LVarv|+4@*jttn zUdf@+tA??^4?;ikbFkpyM&1Aq5M2Yo=FsB%q`Wz|krJIv9pq#sOsnoo)w5lqIUT-xjlRdpfO9Xr-L_b=wu+oFQsojhi#Q&M zoARn}t+s33_bbb%-SPa2hD8Nx?9n3upEsoXRBkDm)_MyI)*D>~HgZGT5}bt(oEz<1 zIs#hkHAl~CUY;C3JiHw&4R{ny{fcI77JSVmevGC<{HwI`bcnbp89gO@p=Ln@ATDU`kPrwu zArC4$d4_^BPOfXBJfP(!)gTIjcYB1csNPmhk&=kLC1J7UYvDFa+OqV6^e`?~GHgCioWhrb3WTCg5sQqL6|9loCIXlwh}dW_iT_f^;Aw@=O3*%p?Y#pQ6R!l2No zSZ(=i717bCj?GWf23!JgKnqlysgd-(;uut7(1&a%70@k_Ax_OU#?weRF={B*r`Pzs z?MeIbI@5s5_VZ&7yLat+l%F=%!Qs72YwgUoOfY{WtD$gkXU%=5txqm}$+mXQh>c?G ziVBarp84pv8%u?%)@$^`{%jL?9Eqve6xpQr^zcA!eAp_8-PHbfz*58ffF;(YSLF^o zh&73mS+Co4J-5wG=qwYr%xPKNdK;Ed&(1SR;CA~E)QKJ?woyGr%||$=Q(lbkX{i&& zSLi*t`S{-7bURPp(_!!E)x*7`C02d&z0c;I=2@qi&+P1IUOc8Hxh)RL9!@s$a1ux& zV+tM-Y`vgUMSHADlD*15g2k8ehzZQ>Xcoy4(6YTbrg%;9{w>?_*=E-zRbw`O3)NQIv;-Dx^Uleg`A@A11)lV2Myo;p9#wEXnA_JG?7q>ErSjn)qS!ot~~c4;HK17~*IMMMoe zEgt8&8uWA)592{78tF|swK4zwUqAnuoVnr9f1`6^w$pF8yYTadh&V;*!!Y>5gA3 zJNr{Qhh`=v_xXO!+E+HF5I9{hf2L}%;Mt++R{DoTSr8-f<%p!A%d1<%MJY3)9unRx z2`B6wCg5s?1=~y~P9ybAf)83d97S{^xX7q7I)`B&Hewk^ySM&6{8M@GSzvVLJaJ;N zGGNr;xyga9AyQ)jRLawEM$vP8O|{5@fmajOa2*0|Tr38(A(5{nFcXHzS*CS;4j<*% zD|vC$f5zoOzDzbBNM-^y1UYDf%n4A53>CnJ^2{|B!D|6o*VeoRAPfXT^gI9B&-X6; z8dYYgIZc|Y8Kz%o2egkQ4qm4*I0*1hiJU6L4FDh3RHIB@K%s(sf<)_J6=2zyFtQ0n zF))!S*(xXO9Q`WBRQGW^=Y9&SnwM?!J==HN-FnZ#q2bjApQ!sf+FD=sPBo1_T|D4% zQW|(Npg5_xo%jMKEG0oQ@)i^zJxvI6CaBXY!FS^S)QE{rn0;b+e(LkPcRxg}qSpapCe1SC-Ji7POf_CkfnQ2R)G{;HrE2|e1yW1(BdyW{N9$i zWy|=+)tz3#lz-iyZ7*qU&EEdBCI4}fU2acRbV}*a?XpRsYWPXOtrfM*;kO75A0v9o1ir zq@;NJRu#-f4^NerRNSY?WgFoWz}BmrDQAw{W1t+2$WC?ws1q=iK|)NNHWpTZ&>7)_ z1X~9!DAa%1vLewYHF&?wV#u?c(PY8Oy&SYfjA-Dq3L-eM#wHXH&*l@y zdfIqirs3?fx$e_x9zt$~kGRo(m$+rmRnoJyi04`Y%vX=CbB@HB!%_^7($2zJY`hylj3@6x{XlLY7E`L`N#I zlaxdVhWc>qs1qU5twA{mUdYZN;7UQgAMIj6jEVv>^8A1R-uhXK} z&=q2}$o!PK9vtZ6P<67CQVmsEzP@O>WAwmU45Q!T&re79_eCXzItC5%@AVaV( z!qFq3Dh$#FX+vN6>*lH$!ydJQ4^Qihp4(=@DrLBrZK{^efw*<;>Xg8lgVEg6_TCkn zX}PEJZ3~)BUY%f)Los!L4hUHFAg(yY4w>-TQGAvZj|5`yesPyoX0MJjlNwy6rx*I& z9A6P}bg<~l**4o#+|zZgx~@-ey3?;(#^*(0YzY++z$n;~N-)}(4FJ_)VUbkBu>#*F zKmKC#vxLW)hJ!q}+t#TDofEkp@YqSZxXcV_!f^!}8q89JYS?@Nb`-Z=>{T zuF#X}(Ry;(!=T+TFUmyrs*Srweys~FqB4P>Xi>qe=eW_dm~{QY*VdU_{hUE)(+*l{ z$K7iAyK(35f2&`b^p4g@)9c`&Z||Be+0mzKIHBV3LnUS~`AF8KvbmUzUFAx@p|C7q#F3W|K%vbFB6_ zk)hJhVR|FlAgxh!LXu&tIS6wi&}0ZnS*sdzNF+gm(9z(6)g^<@xQbrlNE{MAG)Qo{ z!>P?7&>f(Umv>4HDcple8$p(VLS8*K`vmZUpKDj$q|vH6|C8?gT-W(cdb%-9-iqW?*k^j|+vYcZEGas2|6!K^ijxqq zUOpMriE=#9?BG{N(DT79N*E!>hz^SbUVTiT#aJOxp+q)`52~At97_uKWeCG4P8KSY zTE(-+n*Q$mrQi7Gbby@788IRHNfF#%I%ok?K$i@~f)JWAXx@T=4n>a|@=cu7icgjz z-ntx1Kx|rY1Ym%M8DuqZ^sdP)b19a%8H-NB@)YshEJBMC%mwh6t|h@o@IrWvGuYaw zuVEGd3{pg5T~kfAVksjRZVy@AIa>xmJqaVlzTm)K<(lFEcm0($I zDeL;Hd!Ds~D0#uR!QrMF272Td2hRMeKksTyi(b4~`v9!{g=tX?aQE=F@JPX!4K1M| z67{&cSnIJ~j)S_(z}Qr@aClMwuaT6}w5&sqOG+wA9}Df0(&KC6|F9f%4OrW;cS~~N zXs10xKMeSd*N`Vh@L5K1DuY8bs)HNG#B{w%>UCpS9uz=40|A^QLY@%`*`fqCKs+$M zq^hZ`%vEe`eZbMzHWfFAr7m{$x^;eUk1ZMa@Z-#%+*)R#f&yiiMt;)yjweZVuDNgu zH^1r8pY?YrPQ2$H)qGaI%1J%}-K%`UK!w{%J0{!cu8rm3v~3YaR>rOMoc=sryP7@8 zi%b#QU2ZdI`T6gYh1(B*DB9ceJM&WV-uuzf%`3yM$KFXe-nVIwOqF%=$B*qRGd^S$ z>=-Kb8{T`X!IhRP9b!i|;hlgXLoNsa7#4iakWq_*uSIzZNZbnV+bz<(<5Uw-VNt*W zqzk+nOF6jmH{d#wq)6t9MrOO#>=?anc#*xs@MH0Vl|6cw%*5#aHPTBaU+??%y3)UA zso~(#p~9Z0ZYT9K>;1pF2J~_~U01GCyiRw*;(Sj61bvEOdu~q(Ue1nn)$1&8Nlsl` z_Kd^L%lvp__FH(!e_y{o^<#U~^}adSGZh!h1%I6*E(oggl+$~#N#*!TyQClXU1KR1 zf9<~b`TCBL>vJ>cP5s!OqYZOE8cx6L7ff7;nYg9dTfAbUsfO(HrPqU^?5*0mI?BeH zT@AVwmt5$-8StoUs-x@BAIW+~EU` z?YQq0F+C?h5#xYb`P**`U|N!7A-7RPSVB}6!1vGC1WD#d>s1$p2SonJLoeF1v7%>l z%+q7NnbB!_-Xk-UU&5X~+od8Skqz+xo6&X!IT=K@5@#YeahYhTd~&=5MmFvOkE>M)#v>6b(jGh8Ua1adV1`o*T;I*uv{z7ZKdMu@;iVGA=7 zLFq8ahc+ctB>Crm+$V2D8962{2)A)79;`ClJv^IL`fJn1S+PavRwW5%aRI`Iz>m2@ z#^6A-fPT|`6gvxCD5;t_;xOd{zBradvi{CqJ3{{-bBW8PgcGYW;M(FWPvcC7H?k>lo-rEOTx_kz+R~@P#=uQld@Ca*^;Dw0@l^DuP1(7()97zkv?006! zUahXJsJLHw{9^C>D`OXMy}y6e*_pj&y0ray6Uthr$S~}bwI{ASBNvYW4a&_n^XEC( zLfup#3GP13Kefs(86J5|L4+TV)b>TVy&XFlSgLK9$b@P;bH!&n>zKrz0T_J;ej!Z_UWeIqok3KVM1w> z7h~}s9_{eYS%2cgt>+)w1fNnSe$w`Rj6eRj>YBMb7rtJy3Y=}(Qc^z<-IrRFoaWJz z`y8`9$lNicN$PV_R?{thnyMc-l!K1Za2z7A%YicsRijg8u4nEDU=BM>oOkR4rl|JS zC;W2ie{7ebp`~}wrsmks+3TqzQrC7Sp&-9PULYsVva5!GHB_C3iHN*b99I#~B_AUa zj0&p>Gr3lzDeDA_;Orvg0~D)bWbD%=MJB@K9*I^|Dh9|5)rNK1c+D{WRym5?A_OnP zJBuU+JUWoyC#Z95euuR?`k|=bn`=Hjn$hCu=`zunE*yHX-SSaBYtL~7!Xh!@vpAm@ zmEvY`OtEcfx-|dgIXCZ|TNAl$@7F;;8kM5~amaecu67tuxlbxNrwri0QQ7)nG zjK>@h!((or9oX52XtoS0($l5MO4Z3SXmq^ zAta8uXw%vjEEN}uQ<4oMRITK3a}G{2DIjI&QiK@>xbj!}j$=FrRUZ1qM8rNvqBCcb zgGq{^TroK_z}MBOkqgMiayPzQ_iwnq^`i2Mx#Xvp#X+b=;G8&4W_a#t4<+~nU8IP6 ziDkr11-J_9P6(K{`jkXJ9cj$02!8!h!?M0kZ1}w|mgXE$pIWb-G?qk@3?AH**<^M% zBxI)!ba}NeQqj15tn9Gb;t)7Eo-^pQdCx(sqwsYY%OS;qYJ_-l0`CTrC!ML(Utlt(}3U^DX6INQw0av^K#~K}K?|bR)7d1}7vFRQ^~d>qs=J zIkWkq$jI_IF{&g)CvGcGc>$op)run@SVpR($S!(xBD!XF>{WWi#G`Z#m1rBwtXYn> zqq@sz)Fj8_TdP-B%G3Oa^>>(G^r9bsIf)qE(xSW38ULqf6l-FUqc zDZ5}mLNlz@ip$4@V&UIi75M&%=E9qT^pggT8@UJQO7*MsnYif0uf0b@( z@S@g4nV$Ff>7Xtl(M7cjThQD4(!r$mq;uWKlXG^x7pE8ZF z7bo-0%CATTVXBSnIZ!#wQ7R*s+c}mHZ&07~vfuXA~}S%-u|yYvJ%&LXPTl`v4t zA*5GVq$DRet#clY4|1263!?MNo32dBD5? ztGwvU3X;Nsk9C3sDM(C_Dh0WwK*9>aAULpa88al6Nj$(V>3D+}Y#Qy1rGUwkmIy*+ zr$8v?ZZFmEej?_%wYTrJS)h+0XO2=dfgKhjG(^>R*dFru#Q{SVggnZh-;?gE{- zNZo@nD!sXhf5Eu1-)gI8-5a;$RFCNt{T0lZGy`64?sjYLDnXu#f;hAFuRIkI8^Ku! zKCd=UBa{$L@d!jIX3JW$Z4x!C)ad%giZ~~@NI)Y)#|NV88#;%5o|wLn7Fdg$?aceaPegwlzH5z`hd zj--MZgtcg^DIAcdj960Ob%5{uvB7A)6br!JC3tor)`b}sbWG8Y0TCaGfD7S+#waiw zvqj{xN}B~;gRPXEEpk(a$cmFW&Qh&{L?%7n^1*(!{Bw8L^SButFYBf=dg_|?@^%^0 zSLMtpBbn?;W(Pil|F>~!bK3z{>S%)a=<{$?F-O^sJ)iw8Pq z+dqUiZXB%dm9*q(dq)qdGgn-`JRLaN68NIn&xx6K`V^kLohxw#hj2q>j}R0wjNtL= z&_b>e;!KH=kI1z|EK9>qY=kI;sd*gCEf{9Hq{3RE3#VA3D}r=)efIg)y25W{%Y}*- z!&YGgMS0h<h;Es!o9m|uuJ>ss)YaYezY!7@ z_32FVhEQpOB9wrzng%{C>zdn@NBO10%>$nvmwvWt>G?iT_A}|(_p8r-6+N5Yc5{53 zT<4;DC!MCzp_9|Zi+y+8ef)vy4!4yOb$t~lVOtGvRB;Lp7Ke#B4AG70dNmNF4C<v#Cq%zw^NAx~ z)sM2n2%z%rl)R59X|*dIOfsB#wM3!$aq&>0@P*gvD;8?zOYs;1+rojpxn~bMQ~BP& zwtpr^SGa5FS9#gGH@#o>9M3TtG6Zre2-l~if;pS?z~(B$f_GxW=SzFlw39TmBQJXt zO?2jZcLkhoxiL7HwZ*5SO>n1u>Pb{_&DZ%rBy3$nW!( zmm0pQ|FK@9wuH{KTL&frK3xW@Ii!stQV5>_&1n?P-{`7HlGWl}=0@#qLKfkqw(~0G zOhyxfb#&3Pv(<`{%55j3H<{`2tIHKHt8WEfPRhEt?bvc9B)B0-NJEuZxW^ofLPLOT zL|iBWYe<6SAQK{`15v%FE+sOXB#D5biwj6ByytL6(`1;Mi~hF;Qe2-k-HVbyfud1K zW@ZNPW>J%B5GR903QNkwOi8$@tM%^ysHW$IPrcFwPlkC+*8_jO-<0omn}48u{QZyb zXQ+jqoZR5nM>(L4V=GJuN@B# z$To~Jtv0vx^Yk3RsB01fm#NdUzmKb8el^OJ>x$`zN|iDr z$HtxjvYo|HB*lS7D8T{X1(B3YGL)ti5z>wZdmjcWP^ohWgysT}pfmAU1+kx6=7?XC z#?YI$fX)$LPC=F{F=E6NnO|AK3tHjObGowsg>--a)WGSBRo?ysHv`_>ymhvyuhfro zb3NVFlFa{IPTtBolR-ksro$D|ceUIIKkFm<^`fwFtE0LOjVzSU)<85Qzgj+d$ypgGsgNh0_`|%GHybDK*Oz4p4xuSHN7{ zmyl6Q=Cc*AVr^@^lE4lai z0|w^_A2WEpGm45~(kym1T0bKaKzvfL*}*ieXn~c5mbuPy5!f@b&?F&8Mub&`|I>(~ zj?@9bkwu9FPRfx`HmQUMi8GRsGH>@66hFv$mI2@5cO0mqq%ttYJj1TL=HPgRi}Pax zWcuRRwo53&SfO;fbf^|n>cols`l65!kmN3Gep2;C2Ev~f@4ssIxE_AXai!%rWL^65 z_18$&xgp1GACIZKN4THK(x9V{o(U@`%X`+ar6N)!#5NDwD37yy~2L_340`$~}3>Akd{EWi6K^x`ASNt!Oyf&m~>`=JZ#d z=}Lm8DE2(IE|-GsAq=W0+6WLf75Pl;Tgk_iY;SLn0xE{X5En(ig~%ZE5K13DT}0gD z$jHe@V)7+VRaBONEtJmTSkXg_d0~6o>#X&oNRT_TBrWh`LP(OuorJxIG)#i2@z%jy zDV7kV&wB}fi3fel)75R-YCSO0IMrA=N|#NCjQ=7tt*#Fe{pJQ&lq@^+eUIyZ|S#5mvZNSQC)w|vmE1$$&7-Ol$4mchcUCUOXjof)|?xK3F?3DeS7Zafn)%Os}T`I z1e22X?7kaXaOz_Jh3-ooy8_RBjdPE_+&A6RqHe8`;QcXudhXn0e3zG8zT?y5Uf*8l z=oR>RyxlTmaN{eCz35Ql6d6J&+Y%D**xYNr>Kvj_HPX>J+OcNxVHM~9URS@S)6>1f zFFy4q@y+>KQjf=`So172&?V6}MK&uUCLc9rrvCV>x_0#{q+dMQ+q5Za^r&G{UCbe? zduQ<-fOCB+&TnjU!?eAdvP1o&!Ds&khl)EulU_bO%e(Wr8$zE#Cd@rO*7jv=?(3-k-lyUrVji zLNgL{0_i|N&c%|n8Y-4U4}g4dG}(|WJeNkgy(kr$;8AIO7L5jjXy#7hIe8h+g5m^P zhg_U9^^qc)nq_fVBUvl3_q6wmv&DFKlglg2W96?;?7FCg=N|X}ZVD{yr4p53lu-nKXO%*G0DW*gy zfz;~4G!l3M@Vy(1E~hl_^ucA} zr32O}2HJ~zw5*}BuCo*BdAz&e(L`u^`jh$UI z(j99BZbdyj{g#UC+}y&Fk^o$J=X~-C^N(7(X=t-TV@(p(sIks=ibj-&`JoV8tko|q zDajqND;qsrM};?D5{B`^*jPy6I6DlEO(cSfAl!E{Vl8-1D26UDFGobW4D@}_Neh~zjey%rnm)h;1sB4^HHkmT7Mj1L%`%%-gO*3}|i zODxAi5xQp%ns|(FaE?V!8q*{X=DmpkmYNIm}Y zsd9G2X5ycl>T9}xRr-#dIipsUoU(1m>T>DCAz$u-o77m7w|OaT?eA?}F8!fYbn()% zyL&c>uXke?PbMTyXbw8Gm-zIIZRtD@+SW%eyTk78S@F+vj&M$$V%hRMRyBjl{O$)U zFp$k2iOe)C8E~)32zR^vwOKIUEU4_*{!Sqz>{SA?Wh~6i&E!MX-+aoGa&iK-N_%mn zwl&+lZIL*O#;^i53Un|MJyiNuANE+00Ef{-Id;dKLW%uUm4*tKc~PE8K@LYjz^Y5? zbx`)om1KjWNDJ;s*EH63{*3DUoYnPpZ$Ux9Q0YYJhYR*fmVXF?wC}_MmXw2#m*wV) zR6=qWRal|-G{OB!ROLOd|0$k%^y$Hg4L~!HR9S30GGpWQ7quDh&jPhPJ+wW--aWCd z7Xz&%*tD~t`<><&FP^`BYv)qXiOB$&pp4na5~Xwa?7)1IgGdCRbFnnU znZcqH)x8{d5D<5nD8(MIDscOA>EZP!=T`{Nb&Sf;8IRk`U=tx~)jN2=*<-a4V1 z(86V9VD34%;r76;`>_!=uY(L`82I0^zTV;n(CQSz=*$NCx%nT&ikLgGZ5 z5GiPI5z^7S^=P>SO@y523%QDw5fo=m_=b)`UiYF_BwbtzZx0mMm?e$OypVRaPVsMB z5%@k}B1PZ!S)^S}Le`0GtL0>5|JoyFZcP&kQZwFo)rc=%e3N_I^0lB@0ANmMm!Xe< z>%B_YSu|ecK2>VB@v!ydPzJJsgBM^rW=@!!XEevvcif--pIyt227^E6zAw}`<@3+X zuf$Wl14_%BPDUJ0+SC(!*{>SUG;&wR7x|i!xP8KA3Ao4u;c7 z0R0;0a^9_m#*co(ZI}dP4Msuy?ctmEQ79aq+P2}#_kY(9q7t)HGKmY7N^}!@z?I^y zw#jf;1Jh~vWm<|sX+T$7#8)PL0fkfzt4NS|kTep>Vo_{y#N}{GM&RdXO*e6J@(jBc zszK5*!z0hYfQ`2x2q+npG>Y*2;zU~r$0i*OL0opM^U18E_cxF~#ku^M2t3er&$BCS zOoGKt;Fvd}b70>sh_tyEsv$)4EK0ZY2t&@9wuGv@9Nr2Hto?QUE2Utx;( z?#I8t|I&Z_dbISwW8GJD8K%5kIgG7Q*R-jJ)aqXk%+3~%k2l!+bu4B|D82!v(OHWQ z=#dyjhQ|kb6pjTaxT5$yXsVHTJi!&J>b^>z)A_QaBAPt>= zHm%_fCHoWuARH1BK#PoRl6@x_*?sZ9%VobJ%6z;hj<07pD;Ob^$AU#uWFrs@lxxCV zD=N#^Mz;A*`RB&dEm7Bhe|I~RlW@4{g6*^a<=GBeKW;DkHgMxquJq*xzXj>!=0Dn7 zM}O4(yBgjTVb)O_-XH6gbV?jzWUnPwMX!FA?^oWFhWXa_Ma6!_0<7A2O^Nnd_$S4^ z?e4=xqu@t}q@)Zo_uiHFSZ}>bSUAYjCpa7|(c$Toqli-&VX|skhe9oHz!S(}XKECP zC-3#50Kq~Lr;7)1W4TC=;uF|>ArclpZv>E1#RP=81RVlP3{pVbl~9l*!B%62Hj|12 z57!XZYQ{m?;?}fBLG3U0bl-5CywN#{t*U_bv}B@lx_(EGNz3{CLyd6xQWzw2OuQmV z>QrH@+kywMo+S(Ruphtv^sccja!UboMN$&JRqpNQdxM(dK$oGJTbUsHBl{5wEFHUy zm}q!e7UvW{9XMH*gHg#xJzk0D;O3SGN3#x1U%q^K;lhEj3ndN(&9?5eBwFgnj6+36 zzb|7@AE*ff`Wo`5ha$qCdM&y5T?5k9n3M+B-Ip(mstANLRT+ZA7}$6{^@7{Hjl1$Y zt6gNB94ZPbC6Jn|fK_2QB~4Rd1TM$k2~#eF$dSdWDc|#KNZYg+h#!TLA1^Xe&EQ?c zAQkgxzJVrUgnJW1d4y z{Dn{D+qrt-?KFd|WnV7Q)_T+>y1Pbf9sm0MJDeLu!!s#oscPK5KZ+->uvMpz#>A^V zK=A4X-?{F9dSz@pi+@&mGxv$#W0+o1+SxdEzOb{*r(bCi@IMqxnwPT>6oa|R0_+&* z$R3tP`h*0GHp^RsMD$@k_H3e68{S>;flxMT-$aMq8xWx-p}7{7@Hn%zI`3CRiQv2SWb{bAKJSn zUvZXUaiDELBCv#3D=&)6j#QzBW;3o39GcKt$UJO*_di!%JMMEXAiZrIqDDeXUj5Gd z_V!q$Bn94;-o5*=RsM$GSG$oACnhHcT)z=!YC*uoprwvI!KY`7f+`8b%46_)cfWXp z5|ZiIG6GaEqJRQ%sM3>M;|ML5@k);V6;6*nEZ6pay+2`$S)H$!wZGZ{K>59O6tPwI;-31%^a#%rL2TbSlG+9JgwFbPq+=MzP%N>M2jj zUFy*q)*X!*%*8cE3b!-Vbh%3J&)b{I!)e;PjLuNtSjCB(n}+Un@v`^Eh_=hCYETqK z(`shJ-d-K=$f*ib{-75u(sim6v0>%&BdUMy6Z7?K90|ts41113Dn|>+Ia&JM%iR zDKj^J>_ULg89fNXM<=hReRsC7S)XUSUbRaqMtc^63ZW#m#5?8!Lwa-ky0iJkM(u*u-xwsS{rOZ?}J~>eD4ln(7{=3peeG z(m!1`__(Y$Vtz<7@WV0f`EQz&*ADwXx@pkvm@cs&fQ3~5uRnY7KXsjd9TT{Ak!afk z24am=P^B()3cT5v%NcECVX?~xX@bCHlsWa zY}`cZ*>yJV((i1OGTchmwC5%KS5%afb4%cHKJRwJRHc8ZpIhKW_uToGlpPnlf9U~5 zdMP}XYgC>9|En?m4=eS|Pc!M$YsP<%*mAMp@|vFu_FPM1*IeDokoEZ!im|z;bRX6qSz5B%`1^<5yFtVwSn{PkJraL zGq-xr&CJaicX?+vBolip{+xb&g>B@{&AFwvDe9oR+Wz&rVT{mNCGx68LW)8tH!1J3 z)3L0ox~wR>Q!j_=^))-s5Br{{dFi6g#)?S`kctDl@gLXRvE_wPR1dL;q8|Vf5@+evQ`S z&g>f>omjPIm2}1D1pEFiTbMi^kGUM1ikIi?cdJF8i#%w()J>RZ%}_HB)0RJa<%CnD z7Ryc`GNDA~9$$wa?jLv z*8Ggt(|z`y?1Eb-m^2~6;jiO(K?W}-f5R5(O!}2n6%P$No@{dt4rSbwEBgg_;kC6RPSexVHh|_q z2hg1eUg>L3SeIqYB>II;_}it_*p1 zHSa->sx>5zJ1m_uQi2Ba1~>8Si!bzd4^2)F*>N^zxS9TAlK9wZ_MgiJ6xBAqo(GvC zBL}Uf37s9XEPwA-jU~per~LnkK;gT+7X-a(=`CqRCLKm*VjkW%Ij_GjI_?06{2fA#wOcnlUK0Ks`7?>jAO9iF_m^jnHptHN;@X z{rWd}TyPhyLO?as#3VmzL*Gw)J)jtT;yTWqZ~$^?u4m1B==uZhnqupsjDV()l|U*q z4HtLhE_Z6GW^a{O^!CXsSbL6iN0fbLAIRI|Y6&iBVj>TkM)@U6ZuC<4>5ATb^ zO9Fpg4*b?RJ!F$;;e+}8;26xHd)8`*FFyD*b>^_*LZXBAzQ=}upYn_&+oD)vW)SHEANI3)J zn8FVV6DRXo5jDW3A#7OW5QU!=Hc7hHeqUw?K_HG+8L%So+rSbFeq|5~c@#YvRzlqa5eGjuJbXO@)YX8x&Tpm6RqU2^y06G?X6o&$5x&Ws9-zv zzt{91X!342%gF&bn+e#!8~N(mSeH?StDde6jzxJb6Jwv>^w_Lgt&!P$^=jSO{Dle5 z#0G{*kW6SfPmz1ZWl=J-m55tLzGwRIN%Mf?e4XLYaS3WdC^r(35jnBaEUbL#FkK?3 zCe|6Yp5;M`{N6+pSp@ot7Fgy4@{vhoXzBpHMHsP6P?*T?g+~lKb44R_^Ee~c?SGO= zD`_w52VOQ;O7;~$yn4%4-(Xw2Q2&L`NOy;KmuD5%d&jKXzOsS(;)YJ|PpN)GJGR;8 zYkNS`yMi`4`DEBN|6F>r-2bkIXTQmNC9t-`n{$MPQrGAKiJi>Ss-{bsnZc9EZDwyVwFUeb7wYkq5o0=I4D?U7MKdUm~t|J`uFE9G`cX|XkLp2wI@rWEb z_W#zw9DKK+sfm&Z6tiW)Umo4FPDu%aH6sCf`~NdZN+@bcC^*xg1WVm}Oi{7%kAe>y zN*dh_f%??*9_o}y+^8swnCyPE&-d-Slao52H}-8z)=U>2NU&o~F$tpS~l%uiw39I-|1cTvjK==Gcf|xfq+jUgW>o(9ugFw^oj)IGrZuCij zduV1r6WN7n-$J~VNY(@JBLWnNI74*h6-Yp8w*H=+SugT9= zUoR=D&3oY?($zw*t0S5oUT_k*+Y$TB_qa`NLwW9idv30%-Ege+iiuibDr>EL{Wu?Flz zq-4yU5u$P2(Gc(5>*aFcPKT^G0jAF^(ZQ#Ftt9y3?Hqt`I^Md~*a`%@@XyW; zQ+jop-wMJud_uqHsD{VZ?LMIIvwz*JQYjkxa{Ku3P88#fjJVixpmb(l%j_|=roDdJ zWh4tO3ovF*y6;8!KopgM0E-0z8I5F3V1JFo;FsMC`Xrd6dN_QyY32fAX*QC?7N_8w z)25k}Rt5hFisjFDDiG%aYb)1^sW;-iW)kFRSR4_R46Gki2+|EJw;}(dsGh{fVr92%Fd8ul8J@$D7Ct!%epD zi)RF5jFI2W*iBKjtFEfLcG~I+4%(h~@E2Ck&QINDDClgqS8V=Oygx}_w*9>SKvnC< zZw^0d3pYL&@3%u-qC`c;o>4pT^*ip>(4~&bx*-3`)<%byDNV~+Ughc$OZb+R8X4`7 zr~u!ngSVa4@fxDV3d|`}0xz zI0fGypU)(K^sHpP+Pmr+f@(d%fWCA>Z%xVrP&{F%e;Ha@nHcgPdVblki1kVNP#UB) zhC=t|om=<1Qd{YZo!_xfkT^J$CQDP%+>U&_5^!u~bwmnCxU{i>a9lzv6Vyfzf`wtE z3=n;JE^e@_a6|v2Aif?4s6zpg!Fxb2V}$hhA~Ks-!|EnhlKmKYWuJ`FjhBqAexwZB z9aOSw1y2X4Hnv#3Q@Vet=Sxwu31d8hPA-gG$SB;cka|%4Y;N*utRaA zWyK*yF?beeSN>-;ClYeml?M7ChYqkO*1s){y-wTdLkp9b!V@?m@n(91=4oZ)_3*{o z=XBFmtEfHRKu&l{r?kCpOXn75(|t@FpBPc!ilMKz`)t4P30+N5wbcxp7~g7CeAVR| z*kvI;VLKKvK?r)2`VLY+Oy*V%P-376&kiwmNg_}m=>w6PB7be!5Cx(Z1#->Ef z2bBT91z)uYWR{px0}7BLLGsNJlaf{yBOpn;1`#GeT$>6&X$7vrD1=L;beuw^t|JEX z!rx{ouL;2ByZIAqX7=s@HIXCa!tup~V~`WQf{J~he3GdwRlEmdKuur{q$76)3*SJGXm6KkOE=GZ1Dn2Li~p{PK!8{AYXu*DuU0D#r9X;{oJktUpIrXZ4!OAcA-4#=O-s{{FvDWPOtM?`{#3l z;wx%xtMCB%RY3Begz+@E#GZ*dvV1Q$Zhzo4h}~S&A@<1=b||=~Wm}$?{vM^aRLjUy@a69O;{_CgeEKou zJ{mAZ*(kXx6U5j+DUfgqt=rW)TE4rIJ{!Und%#}`Y5Cs;27&NJhZ;cWLpp$6etQyiw#&p3SzWeOhKdmo{}PwC+8t8!*vHR=B5>F2Hi{ zWo@JX{NVDky;V>5)vgP!k4V0@|HvkFzH${46T5@EQEyv^Pggp12nx@5n4NOJR*|Mc zCPZvBV7`zcb z6;eU_(AZ)UcCCW<@L@&!H~#Q;8~2?XtD6X%8w(l>f)U?%(8l6qXNQL;rl_~E;h~~% zbqgRrJ|DYM$(Iut`skEQ;0+pEWeNZ-WD%0gQ#h!6()nLwoZ*_cYFhh!cP!N=b%7dw z^-4ozRaJnLU@cMmjnKd3TW1S>B!G#jdBhn3`VkQhn9y&MZ9Rp;b-j?2a!uFfI!^ zi;isH*YM6i1xn!kC-j3B`evZdmT%#Hed+1@3N^WXSlu+26ieY)+sr;_>o#o#3P^GJJu!=w6+hDxPun)o{-Y2r(QP zg9YEV;PPJ2EN@*Oe&KPAS0R_oWTC?{vXY>YA5D-jmH@C@?!c@DO(UmIBv!$R#So>7 z2KJqRqchDTlP!b@@#}Nw5*f@04axRxQFE>~k>j&ByhQhBr zzx->SCriA$UwH?5!&+DEgZEW z=7+JfUyAP;{DM7~TVlrlK;bu8ltwj@D)3;whW1%kBys2wE*)d^mPp7eqZ->-_P90H zX3al)_U!!U&KrR>_e^%;RmZ}o+b5r7lvkt+SsK24)_7J->sOJvytVBe69^6H?bwLZlHa`?Cxok@){sXjq=I%ee1W6$2BjL{#({!QKSg&f!phU?$;KFce}96z<9x%oH#74S1Nb2XAk4rH=q%X=wHs+Cu{O52 z=!67xff?A?Ga%Cn^Q%?UbZ)j7fb>Z?uSh8oRmhGu5YblGMVf=luS(bOqQDhgG^>bm z1VpLoT6I#c65TX#wL>YLQ=JZr4=OhADXQ4WH?;Jug*K1VXsx%L828;rVVF3+{Y^$| z32KZQLHj`Ga0gcF=d@=-*UR>r3WI75QjT4elyA$K$LFYB%_@_?$R)R-<>3_1jnXy5 zA|M{m(Kc_H3F^RGk~fF}OSQDxSBH6bwxo(Dr?$eZy=+#?`tr#(8XEelW>@86kbqr+ zo-XV|m>LqsKs}4x%9E@TE=<5%EJBi17(SEf zQm9=lkmb5k2?f9#x4cIvF8dR3S}NYnOU)D0PM3P55sn;-HC5m&$Wj7s&PgXxNx)O% zVTJ*#WqB49+$Ka!;9Cs-X&xp~8$slM4u2Z(EO_9|$Z9Bw@!eRYW{1sZ7m$p=xW|I7 zoU7hqGPBV5;uCMqnP#RpW(TIk^uB`&FoMlF{=p*gbbD7sZ&%Z}SL=3-wbp!hP~8xo z&s$>TO~J%|{BV}v$oMrny`Xi$(YA@0m^XCsce|y3hdO?F3pr&Ak)1zI~ zkrywy-G}$v0*?bDWnyD#Jlq-Ex-%YTRT`i_?^&4BF9dEB!(@fFYcSi2Yl|ju7YSb{ zf40tr$T(}d3Zw*HyOyoLOU%gL2&BL9YYiOR*w|Q^)(}nNxegOunA0+cRTXx14;5j> z%v_|;up?*S4fw8dxXsbKaQQKZvku`ZK zbUEErkQTalm?lKcBG5?KQ$n1834t)pv`lK>ktAO&0aV->5_Z4^1E5g~TU+1=kx(q7 zr{L;CzZK!O`I9%~U|=(OAVIeOlndl0s9DfjiH2-00YhbeB-_|x_8l05 z*1XEK{FZVSgp-`(d%}QwGqLn3HDZMZ$z=G?QcbbsN3O;>9E_1-!4nR>sujqLcVxu#i^hAlnbV_6+jl-;-W z8ug2Mydj&RT5h7{^(!wHDnfd1l>Tn#Ow`nDnr_js<0PJ8(|g2RiSxQZNf)T=5VHr+ zRfyQsby#wMTqEWIFz&%-e+qF(02LFWod<)7B#8OwF?-vOJquz(P9?JQ38PQaY~dXx z0Zt82-lY>D1n(A$;AXpQA2wDSwYn)|tJ!Mhh15{N<=hvb9=~Yo_AE_Tl9rxlaQj%L zV0R9Y>?q2T4kY3yX&BvziM}~M8a&)#6mRQCx~W}A!vZwR@Ns$4mv+8s^CF>jnF_6y zUy6J8EE=YL{(Cn26xfRW`WoNbPHSqXay3pck|vbsw;yKd9B4%4JBN`f_UB{0Lq1+` z*yS&qKN5MsemLvM)gAT$we3Eg?V{n(GAs3nzQm4dhSIwm&pun5D5QsW-)&>NwGFhH zFP`4p2SOB&0%KW_2;CR(=D^Adak8>0 z-522hk}($n>{_+3l{RxpXI)2T>KTtwLNU){j=Cs$XkDRn-`aw$7>4T1q~WqVA|}M! zVCp)sYe>-um~XZr91-|I^OJnft5^;1CA{O5JQOWoDUF~#=f~pi$v!qeElmz2W`%{Z zXKx%9n)~fug0->g!rUr#eKkWlRtf9{sbe#ru9zg1m#$tP9++MIuisLXX?@c8AVzQ;9Y$3lNEi6A>NEYu|6zCZoY(@mTiLi2rbY(0X+}VNw4r zQNdxPc`YGc=UaIrT^jm21Vr~!Bd0?-H7i~%8w=yhW#iw9Bd3bt1{*IY6@SKNsJy{7 z|I>%w>dujDH4y@Y<(0wa{131oo`AO@Gr@!-q2c3#z{a_-$V%LfxVEtP z#eT0A>}})oo3k5ZbMWP~RP$f)>~wh%hl5S0C`7v*;rwViLMhUJ=`wrPOtx|_Ho*>T3-hiog zw?$6hPG`99uW#L6{V>veXk9>(I%0cmerN=|O3Ta3uvE-e z|6+-)!@5^rFAI2N?UrSk4_OQ%@(%P(LTexOxeeP#*|~}S<#mw)OBA5!U=84jYQ)BZ zg=JoUCBAs@TUGw_bZ81^G;~CqAPe|#2WAT~?QG!s_|1R_Q%|IBG(_ytF82Uqg=WPL z04oftb4bTzNYVq+3gIZqA?XZ^9+rnaP;cf)MnWH%HJbG<-@~ExB$Z(YheoyY=XdK1 zw{xMsH$4 zn4s>9x1RQ#^VK@OT#*%jcfmXOI{?zZ-~6BOD*W??Jqxg^_nSL4n&#G3?R4brP9FRi zh!T$uosJbd`zkf7XC}9GiPqYo(Oms^F9pmr!;u?ZI`ma-VHodXQL#J_$pt7K7ZZ<- zG-8Ih1eu+26}T0^J`sU|6gn{e1rRtStUBZik_5R}Q6~%fAOs{5hxi??(E~1R33H$u zK*R)}ib2MlVE_vXAqu5fdvBh(SZ_7w@JK%^X=TCK_r0>7&Pmo%Z|Ac-G~s+_Dnld} zm4ZkR^8{`57De+`AQb24kk4LB1i}@`*P7ssw+-vdDa$YOz&9QVr&!lhb#BG0rl21Vqxi$4)Tzgu>KR66c z4YHRPC3yN6%&#p(?S>hjFze`3wP(DU&?)5>QV?~N=yNrY_8$uvUZkH`TslE1`H07s z)*|?kuZClf9)jIqHC5imjo3mrDU*y7x+jpHm*YX>=a)8?qX>xLa7A&K^+mR~dgojI zuslv1*<7F4?wL_42?U4MiafOHghc?2!8*GI?aUBir(~fgmNJ;e#|MtwhXEBjS}6M6c`K;EKUKLAa!6zBO;7cvLFTa&o+3{rCKstg*g6 zhg>wac5g41Nh@Nwd66I!`6C>DY35Qxdr#VLyV}1l91wDSG;+IsWNfT?XE|)SX%$kk zO>^ZM^!lZF2)}pPL1sC~e?!*hLQz(v_5|gcJp5wL?hTzi3RXW-3?H=qpwO91Oj%nes2+x3B_UvqcxwRVVm?OI9^0yz%nO&2!7^p24tesnI;2fL3~&_NG>hZW) zuO0gFkFn~Y$f~eO$AyNmOD+9ZlF7HnE}nOhms4399UW~7_NdF;zA$mHRI&McMQgze z0jD}v0T4GkLPaoS@||DR8HgJrV;>+fx)2HlLzdqic%Q#D`1^c{$>Ncy#O%;kMg${% z+@B27q@B#_IiQh$ArfLRu^6b))8Nr10)nr+lFRyNz7Dm&O)}B7HA{SKx>sIg0qhe) z=vB4fmUj5{oBiZWvSMCq@Iu)@FhpC|zRBp!jBc%-`%pFA1%Tr^H?G_n&*m@>`r_7V zYSddn_v%RJD(0Yg*db~!MRh!Q>RtC%xVK+r)GZH&<@yC7wP)A*T+3 zM+2Thpz_E8+$OKfNlB$Cb)W%)5*%sdcoK?$K-c7SArK1R%r8+-AwfSnVt zR6p-GdrIc-W-dlDSz_gJyf)U;E|uKhz0mqyG!pUh-_kFh=ZFjC6ZIYD8_W| zQWCEglYHBj-E0ER@P27gbnnNHM=XnFa)LSlZeeYjX$W~{nhaCEI2z5?QKBm5jipLaW$03~y1b<^T1i9gtW}s6TN(^}BLK+E|YsgFC5U=}KuD$)n z^oG)5{WI!o!Eup86emfYeQlXUPRIO-dzmFAr_$x&d8u^hQGO1|JQg3DqK7JBee;L3 z)Z+0j;==)uHj{u_^JUVLKG?F9Pzhz&%9NX?MGL1#ha+b-3ikuW*Ar|CBPXaPb4N5* zGiWmGsbnSK$lmMo7<-YWz*FvLadpTti0Gbv!sAXxR*st`>8U&emdwGsgLihv3PVXN zeHs01aP~;nGLr}lB&MFwz}6BQ!#wJ3k14wCoqe&?*LQJvy#tQJ<#2-d?c%(#*G}0v zJYa7S_b%%{_^f;=hleH88o^OqRB6|E1G~z z!LtsvaF|XYq@~^(0%I3(l({SF-HVgw0v{{0tn^ym#Rgi?umE-D2Gvtl{wad1WhRk; z(SVgIr|x^Tv^zKq5ehXLOEoDxh9H^%HFCO?EL(gD8%qwPFrLl)7~SHc4pOeY)c;(r z5iv!91M)ohM7PTYJ#%_yZu|HgEK*k)<6#r|L1TUs%?xmVXjw%5AZItScLjMre0{Wc z7534U(ATEP{`q{>oqj!a!P@Pwwd%ey=i;FI4nh9&i(A!o`3ItQTmBC<1dSLW917Eh)zvpdkvu;1LS_9Bc@Pcf zKOQ1Hk2lWF6q$s5m32K+*t*-(vRK;k;g7QT$@`7Vp`(C^?Y0R2MW~yY?@j64-GsEh z`C_JQN2qO?6?;5;c0uSohehb%EQz#|Kh1P{_o+?SVhW>|fIwrF8#7qH^wl z_;zLd^ML)`J5U&n3SK)Y-f#_{Ocr|lG4vX5$H(=t?hKjVK9NdlU!h@m-!T5V#DhKzxmy)5ALU}?ExDqw(?*M*!jJe9!AEC+h$ z?F<=nsS_to*f#hxwpQmVT4%C`qcT)mH?lHI|hiidAUqe0*eE*Lf&xGyyBFKhVp;S+MbLk!Ii|GDtWwS0K#R#dj5{niVg z%?Z1`g#7$z8ylLs*_F*AhfT0vGzW}-*}^;DB>U|DvM`jOCGrSI^T0;Y3aqOT zj){NJ20%AMR3#5!y(N?Y!3(D^Bj_ygDI3^I>LRYd7s8F^0&sZZ90mar;h7jf7C}On z+p!>C7r~7F9%6&gdoDyJB9;H1O zsG>X?ww4l-OePDkC6g0|9tkP<)!K_ISV0X>)LZQnV^576-qXWzZe}KAzK}CP%aNmn=Gm^B)NhPr zxEG$;B{6m*ChlJ>_BVzBxo8`lVV}#+fJec7mRddcSLy$(7H&942G<-P3M z3dE;&s5$g{mI&zT$HhIgz7MVJtHS|FotjdMLWcbOIm1Plq7ep*U5)YMq$fCs{l_+ZY^QOr>-X4dDxnp=y$+$E!j{l44^hc%Ws;U$+RwV6= zfdEiKF&I8#I}u4EJ{O1)`VD_Rt&-f2?@*HGO?@$>oWheSP&?FlW8)+H#O73L#J3w& zpVsZ>{VQ#o7idx6i@18I;cRTIaF-Kh0e*w1(txn~jAz7IYS(~fu=CD4&x6Ni3+tai z^}8eWV~XNY`^>3+5lg)N+H+VL8IKT+B{=`rOJ;-WB|z`qj#{9Ab1aM#V5nq+%1ic7 z<6Amhc%#?ISZG;;-oj7EH>U~&wrnOb7bfwmefg?U)vDUoVsf~2WF=3{kmv9bk0| zG96f`QbKma-OsfSJ0C-`@k`_3n&WSvKO8_*QQ)|RyN1(e)rE-BkbteRT#>{J4*>94 zJ)z0|KfZ(vNEd?o!P4jlybe$AXqe z!9=|O3wEB)e$$&(@Z9z9s2#QqgBb(VZPHFJEz#|p&YF>*iS4|EXUd$#{^r2MH?#3u z0rOLtuZ9;|=;nE9Vppua2wKLL4^jw#`e4eGd-tBRsy`Sc^7Na&DoIhGU4Z9p>wZ$} zZZ71z7JS}#YjJmB>w*U8mKrySt_7WJ@=VM&Y^4RUZ=(VK3W=7q%h74NhSwy}QfU$r zaPDL(yInzq4xcN?3`)Qw0x%Vzn4-ceHV%Js*&TibolMeQ;HWM-SAEgiB6w;#etjJF z&+Ai)tICS2zZ9FRn{yUsQg_>eVh3#fJRgn#M)m&T(Y`aCfzk>gv}mL*hyhMlgXu_8N%vwjOqm#h59gkI1%f7PG+^yjW@EVD zKkR`r;36>~d~UaBtau{S%F1i_pYp5(rNejhUdIiZOa1BTU(H#ahKFH7Mf_fD$Ivli z{$sQew0GiitVg{2WGt37HzifM%CbwJ`LfDk0K04C$P$gLOfkw`OH3hKY@>DU zZK-PS-KYqiq67qdx$B|M(*cVIT3JO(=}M2%+2?{?K`%UBpZJu) z;}i#3vf1mfp=SjW1F!=ag4rC-mlG49w<%GO@c@iTX)x2N{*U{^%t0=@L(loGYc>bSX`$YO z3`|Gaynb-&m=o7O=r6~l4WYc1qphiVUQIKzKgRfqvetJ=-f>Evon}x1>Lg6dl;GFm zzvK?N4%Cs&twg!30y-vW`90Nq?AIwM;0tFCuaEM2z>7gI%dw^d=w-}>`lF}z0 z=fwt@L$!~51PdfaNwhup7K2V@>@LWb~9?oJF(D|c*O>Ssowtr&-4y)#c=Ot^z?v|Lr z>TY0vo%$t|LZxa~`7LgXdQ--!>VbF}sr_%f``?2i=Ys5)&e=!Q+k=q}p7m4jRuZOq zoth1R@0EgZ0>5b-0*3SgK%rx{0nj(jl{d7E-zHy(oKuYiRd>XP0M*eqVju@8PzzWj z(tNDqY*>ya&AGw}u%HjjLx2N5s>|e&pyOOvaWL=f#=RDWa4_p^Brtwg@UxMqRa@xk zfOstq!JY622Jd?(C5=xG<3IZd8X!GG0F~c=F9tbP8Aj3Z32Mvawu;Wds!rGfdEaGq z^TJMNQ(S*R^AW|EvZWKoFW)JdO~1jZ^LT_gFN|E$+U6&Gz#fj;vx>T#ICuikI4RSf zw);PWB0II_=#L0_A&J=$cYN`@kTZPp)JXaJX4OJN`Mpp^zQs8cz<44>1oSuop%NP+ zv5Ln*tBj(V)aM6Cel&swJQB>*w_4tzBH z4bvOS``z|tXAOYebM&t7YeAdAv*uU57S=0kYeN>_`TqR%^*yth1=e^t<$zsK1W5@z zPsm;BTp@Z#txbnT?Q!%BYH7RmM+r|KmR04iQCJEuQ9 z?17JP=<>}Q*tsfW0k@gGA^L&q;g>>S@Py;P0YYR&o=ukm#$bTj7@&{#y8eARE*&le z7^GtkJ76Oz5=ri_`L89ozeXCd#bRhU@W15bQH);Xd%RU6p8^G-8_k=o2R`H*WF3Z| z&PIn$y=__0eS#LauA*}5LV5s*-agl#FZh)e&uu4nB`%X_)>ASh21Q@MiKLJPCG>&^NzX@0*9bMQue7;XgM<+{Q?L76XLDd6rNsQG^IbzI8^DuR zk_JUjC0$u#&}hO}548(el@Or*2$9@$NLV>Z#-v@23!YXD&9}_FYM=llf18iWuC1R< zTHY1zcNaFdi#D~NHQRfo`X0zNBm}hlxE&?oB56d@l!1RXY$nwJsP1g?S|R3))qC(} zQV;?jv@DmCVr_hm8aXdkzIEqnA0)MWOR=X1q@JL)z+fRLBHJ99p7OVVFT*YJTK@MtR^Jf(IriwmerO_Oj^S%1# z0kc{0%edkf1mbT;ZL3C&3>;~95luc618mrVK8bQAbR{fn;rm~!p8?D&5f0{j37~GQ zIJBHp@&6QN%qA8UKu_b~;~qA>Snt>K<=;$8tWN@*>ZftzC0lv-& z-<=bpqDj3lO?Xq&$QV@I6M(LzeOdfarJ!u>`?o}-;O|$Yq{i+#UE{q#Oun302|{c) zFXun(u0!^I%TypOhfoW!>&%h=8THHn^yQ^lq9%POI}Et?o!L>;y=EZ0OcS9ZU1AaT zfm{fGTUhQw-#I5{3qGgZ0P$>H@ysg!)Rg&i-_E zU=XM%w|zzUJCyp}{B9}(c*WHQ#li+L8kk+gDZ~(%+bK|sAmC7p5qimoLmg$-9N^ss zZZ5!mvI@V3buCj61JVst@*Tcwj+H>nKt5zos|-0MdYMAK3=@W9zrNo(xKAr&(_E$> z4E5*ww5+`C^qbgTcQ}N{;{&U&b3p|x-|?}T;J-cV{)?Z_DehZV>_6{12q<%PpIh6B zcrUY7ZN0Poxp=oj@L-Z2-9j53v938D6f|Hr+RCaqzY=wOe>Xxjw+lj8ii~u{J?p5Q z;ntY;JoO0YdFOMyzJ(B>>=cBB!%7%}< zrm85$3DUx#3x_}vq<&$p=g!a8ErIEtjm$!@;Mjz&X=b#`CNLLE{37pu``fckf_czW zNnqy_U~^uDd=m>Q2I3TL5@Ncq+xv->(WYCsell8DYp^a>&lVOo`rRfNWkozh6z$4A zG6)#?Jj-|%CcplCxwJ%+Q;IfDv@|ASxyhs(kxM-8#&R8=aKuX%Fof^8Fe({|hh;h( z>nI|+HQ1p9a&FgP$neBri#=!&AJUNN>0WTxDBezS9s_RbeM>ncRXN@%=Tg|xVt(l! z*YtAp!esRIx{#+jW;c6>3^}-*CCm9pA{c-qC8y}!L(~2{EsK`7o?d}Q9{q$^rN!{@ z)+-COsFig6#B{2%igC{R9z=Z7?>aU4-@3Itby4@d$04kp)eAW=7I-QYW%)kDTd$@J z7uHX1d%;Ii>g_dQ zEW+Q#M^R|4W3)nzu+wkVXPW3wzyG`$aO>8exa!ErsWtOq#twVDhi4hd+#S2v%lf>M z5Q{n4O#-wR0ob%irc}Up1Sx#;xQvh^9?;+Qg$O`cvanr`yZ0t|zhLH8O?}Aih0R*N zTp9D!OYw8d^=0*h!iJJHyZJ_0*AEZSN?@*JfmWI`5`khiXQ9r-p^IXLf8#o(%z}cb zJx9W2IV50>0e{4?+64O(352uc>1t`1v%C(-rB$r|sCaE(0Rf7A(9tvNA2RzwdLf%p0}Ci25ND^=-7ix>mT7PnqrEz}(z`1EsOX$}`8>WK?A$DO-N-CRWxxzK@>19P-}T+&G)e-WcEW zWiqL`H;H~+r?#rL%AWVV@>goO*u9J{ixc4TZe+L7uqk50rAq>Z|2J4K@@}Uw_Evef zR68p4S+e{9dFlH?OI7{{4_=Nv^19k-jWg?|Y%duXKD--1g0_ zs-f5Qwe?k1>V*Rjfc<>;jMP*8OunlPWm%=qOf?$IwYTB_Ov#Zj->-w?<947XgG#dY zmYhYz2$`;SUK5ImJ>f%68;oK=9+VC(GflNXZ?qHJ{Tgqt7W8Ce@2na17+Z|*F{%WI zGdO=7W0}IIXdWq)vz+0jcSrhwtTm6uC|S*{KF-d<_x2xc&$Z}hI#&Ib4{yt1#k93^WHP;Qn3Oe`4GQkN#@^#O2M?J z^dE`SUB>!7cNOjk!G}le#Klan{^Jhv*pbYI8B5EOP6)EV79Id=IBaxEO1tf;M@v{J zXH&!dv@NQ&RmVezYs5BeM!fH5%HK(5g;tUE!mA0&OAU=KV-unH@f#y;j?_mD@z!;&R_PAGQktO7^H<*^pst>DUY4 z>l{lY(?Is8xHapuVGVOqGkot6V6qGi;EoNICNWQ#$FnT+0wuW8Fx{`)NJK(f6~@Ti z*+dEim`2Ju*5H_OF34z)KI6FTj!AZ{4>@jCOH&KjyI{OIYF9TFM#~5ayg%Tcl~=rH!-=wBaTLj~-p=raf2aB|`XO%o>ec|s*bgDC(*(0dy#owGwVM9fm(Rm4e{^NGk0q7U6(032hcVl&aH3#|}@^&;l4&Q9UlB4J1 zAe{w6uf9qZQ; zeUyP`$q>zrUNTj+09P#eEA^EPJ}>cOs1^)|x#kpq2e%vyQF3i;sJD;DV^ik+&tv|1 z|EHHWMd$q2%1q_lb;XT`T}^8yEzjZo%03WGQdw@=DKFMpKk7b^Z=+~M>mu5({NphB zDK&CYK~?MJ(3@M!O;VRf0JO>m#{npHA3fPU%SlUzT?*F2#7X06dHnzMHFx3uI5=In zDcZWf06P0pJDtPMnUy@RvKCqbH}p?k69JV@us0jrQb8mM_mMM9Za*g%2kN&!6LGAZ z7$7E~7WI|cSfK9?b0j!+@HrO1$`_{4a2bSw;`R5l>QthuJ54=uw$owiOf8A@)FQs@ zS*%InK8N^_a`C#ig6sR02ax7~J$S)T$MP1JZf5AjiPVE1ihHBHI}a_W)baD0Y9piS zGs#)K+uAwWOILL^QV+gcCEfTiFUcFW87t<$v^*aAh%F5D7`W@Zq|%nzQd9EUzZEOi z5TsFEwr}8?g4>v7aXD4^v-v%NbNXrkUa@cTANP>+{bf44r2?wHlb}h8<{Ri49RLd> z1eu@)4o_Rfqj2ogb&N@?L@4PBNx|b9aNiKOV8Q+d6L!c~AV7a{5{c3Png&uyf*Szz zD3|N7^V3B^V1TjOxqo|WwRIzGx*?zzFTWi*RH*6uYUs2I3`5d#41s5M&c#iRpWo2j zg6u!}w(}i4-#)0Bktq%31?NM;!`y9dhScEu?zLfop6j$?N|a`DlS}~j0f=x4I!(`` z5h7()#`(i3k$0=~;Dusj`1?i9qYny32Z_3l@WRM||Di6lT&_9B02wVO856T|yY_Hr zVn!Df0juijTI+&tZM3ZNkBn0*BcS>5ijKw3=Ga%nKbyIA>kTXI@N=}0Zrn&FNmou9 zSNjK5;G#Z9r?dFZ$7fCr^cIsVp^Y&xYJCs2)okGF=OQ7DgrG?Rn!-&l$R50b`yK-tq0l8Sxe5vb=cHlD#`O4K;9VuncD4~ z7C(UXK83MdI^6Ly4rYnFTU;G)S~k{lvLj2fZSnYVKYBAt-c%njVlGb3qLtjJJPuim zQ8Z%loy&Q`G={)}Ln%>!*##*4v_leYRGduzXr=G&c6sk|2x+1sd*}D+*A(rL#kKJ} zT$k976nhXG+eZBBFpfN6lXAu)ZD`0B zW0Knhu+c8yg}e@iF~BXM_=G$A;VGQ$ATOL9sAv#(1ucp;q_v$jTfKe&u1B|t)iIr) z(0EuUZ<(z23I1LdYRywtcDU4~I4`$knqkFG#w%6FZdd>Sw%`c75E@>}Z)tP)-A7;W6r@%oru2}aE z-cea@3ErPlIvxMacVROtBU0PMCM~177HdW#pEbyoT3@~XIdX2Z|C!icf)l_gFO*!o zk{9x;7k+fJ^t|EaFAhrqkq5kyqTDAAIgxeG3SN|YuP>Dx+yZAmL`<~hQ~jT&Ozi6Q zWCU#G@7!DcJ~pvFR?)gVBBQm^z1kUmoYbo?oNZ)?i%td=VMEJ7io-$Kk+7<+Q-nv> zxz_r!Q;XDUfM*ZIYkzA`4gGvlg{EYhj`;^IDj|j5;N7s9y>X_nPuRun1^5mTG3|yQ zfcc`1zW5G`B2~_=ziKqC?bMwB~DJ`Nv1T8puf-n@-o%1)VV~`vNQ5*$^n`-N85^;FE$k!6DvDxkydj40uyr z?YCDueDI@U??(pkiByL3JiN(g?_>t*Q@p9>1(XMId{|~BHCfNGpc5^>VruYOPaqo% z1V$pD3qc*?{4>E=PBsl7i(ur0ZOE*$6GX<|f`5q$rl?tv6aYa9kSJIIn5F5y)l`L6 zCaHg3HF9-0e{sp7;nw7Fp;8-#)aS{A?Lvd(!e4Rp{TOlY>7Q`>va)@$O>5ogfNkkj z2Zq_i)NHPJ4J9wNbmeBq+8RuPc%xR2&>MiathSiNq&5J^TH~~R(^|5-CJ#nwe`#X( zlQXFQc0bR1)GoSl(fC&yTMv3HLP>&2&R9CDbl!B_54`gn@4+Uo#L~NN0ETnG)0O!{ z(3?^gMZOmSNj;?Ufr|-gw=@?~cn|}y8;e@qMaQCm3n$?egTU}XAOmEE2qiR393(1Z zK2%d+g~bL3YEV1?Vv&`t5@6FHd1sYaG3{T`Qyu>a7Wy0R1%cr~LG(c&n(R;Bt_2FO z#B)BPo~4|$)OJgjCCS%wL6S_8uBos3K35GvRxt&yVY{d?2tG8Kk$?S^C0vC2R~#QB zL(fsv3Ht7a%2oiue`AV*S76K;wm}YTGy#7}e+0*Qv|AEmB!L&Tfy^0x%o4WCrl_x(U-MYupM2?@+ z-9W$RFXKdk!21hT{e0E%AB&Te>wxBh5IT2=nilAm;{%f`>pR7=;t=Z6~r6JRQTqnY_;jj6iao^!?vP^m7{-f3{TGx8fPNv27!|d?HY|XIcS3+>4 ztej`?oBm$e9$`I_TE-|SsWMe~y;Jui< zAo*dJGQWUZzr~pPanr|-cr(Y&ilAX53AzRpH?S4bnAb=kyiai&&E^0q0JtX{N-%#< zhq;QhF^AIMXWudx8*icef+#_-VIGUFJOrm@Kw|wua1=Q8dgu(%}JjJenYPKPw)(ARVm-?2%u2qZmO^TSp>)6ll=#3eWh! zP_)#tKyO)Ce)g=x(m3};Z{CZnd9aj+xzt*xPMMPo#z6Y<(h|=KXgyu#iPqYgkd`He08;?+_oJ+|a zZ=!D9f>DS5BxR!?e@6T-7Q^Ti7x_CFIMw7jJsetS?)}s7NpDsk!86^{>YlNiv2ihM zqG<3CLA62V(HI7f(JA?`MT2O$({*jl^AKnjbzAM^-TTR_$jjSr8}_0$OF_Cwq1&T9 z^csPHztNb2xb_<9EM^ECKR{_g4aw0aT@R9Ba1G^PJ@hx)^H22lz}_=?uV?hHTj;otufo<6QD{`2MMuDx|1o#l#1 zE^b|l!A1T$ouz?Ry6D00Pi6nDrV3K-%Fg?Hz0_V2-~Yw|Y+HoLTalX`TZOyj1C!VP zRG}#ze5*4|zlYI%%cemPMUPhU!w(5DMNN)_KU;!j3fcxJK3+%A&BUhg@nW1-3Fb2y^9Q=Kw7*?DB))5}py}!XQ=XVrqG*Zb5iq*b3?Gh0D`>(LDs{2*~-~%6q z`eyCQbbdLvezbapm!Zv10^V(+@A)+_d0>MMHVF=<@qMp5$~S7TVj zM83M8XINOH8F_MF4|>LDNPv9QhW0j#1O|yR0k@~4B&_9G4Zwbxl*W@|__rxd4m#H< zN{(PR5~g6&xnVDlhA$;e>AfK;4NO`bN@$u0*R`^tbS(CW-+-H4t8K+VL8ELc zvhjIjpXZcfVI7NJaQatM2rKnNW z$UZBrH78!04u$uQUi$x$bmrku@9iHSW6}`EkVJ|hC1siD3`Iy15v5MaIvQ~>Lze8z zIEIoXNi^9`3)*a9kStk7vYoOGV+kQyCi^~q_dLJr>W}BT&U2kp&G>#lpZk8lUoY7+ zqP{&nxvjZfftuQ<=1&X+^_)RT5P?5m3`iI_?P3l3RIJ_3-z;Ou}-r8?q1 zx@={0;H=x_^(z`WJ~qllB`yKCCr5gZl(cEE-o)Hay1g5L2L>Ntit86dA%>3t|AX;J zIrIwifSh0i()t|{LQocQ%!oJxuVH}xNPouu^G=Rc>^WWET-jox`XCu@F)Hee zLRRnDbE}Q}y+bVahTXYQ&B$8V{p@mpvxGK~$$@&6a_&DE?G9bp!9*YGj;st%Eej`lGE|A1JzZ&JS7LUKi$K%zX}^K3 z3;By*Waa@KD-H~xg$CqWf2H4$UwiM^{C{nEY&B&l|HLg!sBU&;ZjGH7i;$W7cg+yW z%d4kT8|fQ)$rcrPsBjuzPcA+z*QX8rqJ?ZuU_31OKHiw95JgH&KO zmm3v2c>0Hf#*A%$NJXjtXir$~_3cen&VA4~&A_=Vlha^dH91v1c|BxoBBZq^jHMAe zrBUu~B>D2P90E>1j!?r-(6i0W5`$M;C^&JouVlyk^18G5edp<)GMrh@*LnnAQHdRi zFrU8|{Xu76ybLRJNZ3Cg(h1eU^X%={=?e|hP~-4#?Fo(pM!S2t_J`sMH~C1CCqaY(;xZNjtn%XeiDXm)4MDI*;|z^z z4eFC}FOCwWH<&E=D2anScq9=4hsD^21&jn7 zjusG%HUj{XD<6urs)MU7?dHMD_iHFKEyZV&UzNn5^)Bps#pg`#Hj=_zzW*G3%gK!w z|L+lzzrxi!n6G>eUA+K@J-*oVhi&*0k|qzF&p?QfaTkGUzX<7KNIE>3sDpxz5fTHO zS4fzkQAnQ8aLvaEC<$Vl&^y|puACvv|0aP8+bR%gmnXszR~bH7=&FL+a$!GMco32i zf*I1w-|y;-7nT+~jD7$8`{(U)tNfi>MOpF@Kxv4+cPaOdw>NQr_L%E{)o#;{&Tlad zBcFsnxOjWJ?Q47yaW?XTvKchGWNE5j zRD54pC`3_H7fTd`aH<}90RebPDw+gJ2^5GOsR(Kz08#0O!n^AzH0AZsYZVqxy-RG; zbpmcyJu$zM$|&qir1kb&?LH#kgt5q0SAJcR#^6u#l~!rxKtx_@fwMWA_v;@RyWE2D zV;cA=_~bn!6Ueg)00qmshvQR%0>dXPkYx-3YJveTTLc1U3Hfa(fYbtY7;4Oiv&fGa zOa>Dt*g>jVt<>dow1#%y893p1wRLaNi@L58v0@MEC~0QjJwWnj^17(O^r*q4_?4zD ztMT#R83+ncA<-lv=7QL9Xf8*%=EbW>A2=|*zrv}i@a$`ss3nZ)79BEuh}bhoK?zBm zQ6d>*DJo$Mn^0Ja2qA%ICgBL7CKzGDS~#NM&|`}lX040EK_KLEA=04gW=P0#BkYEb z{A0IQzd;b#8QQb#!5~*2CG!68o`2 zKkX$C4YQB^-Ak(YKO)dXUIsMr4_=}O>OX%w(AhWq_3QdK+#hwb4V7`NYtTrzdclRJ z1|R%!{baJS1ToI(G#d{$;YwR$d9X6viW%GsffbTCqn z&sNMThj>UqWjdmxgz;(k)0+2${&B%6e2M4&obD)x7SiYmv(aL^{1=@mA&^DL?Frb@ z2r1Ig^&DA^+%?gjsjHjm2U(bbemm1EF-JrRQYTqSP~ZQxH1wn7!SY?m|L?pDGZwr3 z6?Rr2=@vMb;KFjekZq9E$0#&CYvB?4Ga|ooju8=2Ns{Qr>stxG@V1Bs9amcU_*3D~ z>J=!*{wV3m;Is~L2JY%k4@<>x;CeK=yrL2^B)t9amv^WHODr@XxHLbkEX0mc6ht@* zoeB{jaQ7XQRQL^N`m$XUD%v9tAAAH;qUy}-Kl&C_`Eyuw0jY)}7yn0!?NB9Wsxp2z zYoSUNp6(pr_Kj*@2tOceZRY%=Vb@+L#drk#R*s2l7|hyworRJhLLL>ekOb@6WI*5g zx{2&Sh&|25$6fq%v(Uf(h0I(M^!J#ZHFyCYBk&AK)JPBuMC99VTFbKZAq+()gSep? z&*UC#d8lOB8+u2gJb$jwiU@~I%WMwIY{Kn*2D-;qZdXzfphHC{p~zpx=6|Z|EbJZ{ zJ}^l1@USoOJ1pt~x*W*EAr|vOILdbeT`3P9DP^!TJ#e&BY zAwk7)GykLncxbe4)o+pb6V5;$3IV3pgRqx&e8|)^lH3&``wmefca|cmXK6%9XIda? z>0mE0W6=*OCR|B03g^KXV2!LlAJu>Fxx1DLga#%dO*=JGkOI4K2Z#e<5e~bcszQlF zENt>aLr#E2LBJ{lL<{vr{IHS2CUCcB0JNn9s6f6AE%gc#eD%DNpp$*bg9FMqd@8NH zlJX0B$@11&Z55oA?ce!cPn=@%k~9P6nJ4hZG)d9Km!1+<-L6RGK)E+) zR?FVR$2KnEylh=KO1m%VrLvX}_ zUU@~`NX>{40d6B|^ra^gKvl2zhIb{j2gE6Gpxp&aL++uU$2;;2B3e0iH$O`Pll9-Z z<7PSOB|ayGXeuRwg`oNI3%%cmM0v#I!Fp*(YAENtC5tW%Y4a$RQShXRM;u{oF$JhxYS z?X@{4(tfo|BV<(L<4Tn`)OMwaEQsa`Vgc$1P%a)UQca;aWd6h2roZA?6)RI)aA#_& z!bGFlj;h=2(`3tJeZ?+!ePI65`2~UZOF0yKoD0-L#vT_2xE@Jf59VlqrL=L1_$2UH zlz^iaLpHwRqrr9FC5hb<~N} zJ8!$zjm-nU)Jby+khvG%e{0&qkZ=%0z&lJd#n>X6lzU5h)-J74lzA#-^u7u!iRL~7 z+xvR+?H2RU*@;ljgWw@QZWIudJ**2ox10q|L)9w4f;f(QO)>{ z&TNPMeJ65z>c(%5k^!JY$NRyf5PEZl(Rr#OU;T=#-V~BY?_I(jx_lqLLRFQ8A^tv? zAKh~^t#0PGI{9A>qbiQpXdXN2H+p9a4`GBYX zP0i7s%pIJLv!D6P&hzviknogVsopfv^>7Q?NUfT&o_=m|*3wJBQ5JUpJfe7`SDm6+ zSUo7=>DBhPgDq`GE#ruJ+NrgTu;0#MTRmahU-FkPz=M2dc=+r5&sQbc=tzB8BoEL? zU*GeT@Kd#!Ue7Z)c}ly+y%!_$(0^a*>05_iby{37-e?C=Lpxy3XO?=}#=W(?0WN2K z7MTD>I;kcX0OIYDQx{3JvN95x+@J0FwY8`DuOo>lDkc$%6*f-2F1YU}n0!j%NoKOZ zPXa&)h~WV`bEdzYE{}+?%uQ*Gm#KhYZ|J;2=*URJE?}NJN$_dKkq#oj@G7sbDR~H4-)s)suK?h1A97oZ6bq{s0iBI+=1}WK_c$_K0 zV$g-?g@wD}D$37KY!Xm;#P3ERbJ1rNCbMcJIXW7(b+p%EiZdq(fj_9bEi&O4SKg%LZRqlvp6cD zwign}+an;IZs$xt0IKMbqNlWH4dBPwdM2|j0(%?XMWBCA0XVX8Zg->bAMrR}B$MfD z_5HhAI2mY1z&YoEL%^R4-)n6}Y|WIPs}9&WZEuFW?c$L7n@BHNo&Tt$TlTlR$O}S} zTM7V4@PNC?W#bvyI2?rL3k=I)VEV^pU_+~m0#Kj9rw44~!~)>%NMZ=)Zw`8#f}s4#MEq)iWEB#LpWT6NLl7y zhY7EMvXY{JsgBuKwgY{GR>~>Q3T`6}F1bDa;CV7B?w6t2;a_?h=X9;8oy6g1u=>@=$)vQz;%)=^7N>`-d@ZlrM%iM%g0-OS`^`$SRiyQID)fR)&4 z#eyu`WTM@6fA>`HM|-7lsZ^=0cRLxLUrdRz#2UU>h-d)RhsEUMfB)FZ1peyBCbhJ* zvJ9l2%3)wM30-pnivWU8IJJF#4{m1|oxyRcAg%^sNvOd~@E=r6C;#0ua69+N(01hz zi(4cJy$9_HKR>_7`+;+Q!&STd216%yhOTaeuva+$b!5yZJt3b`044)GS!`s9 zvkIQNQjjC(LD%!55Re8FftyV@0_b@>z>G!^^avQ(VSyC81umxuAdb!|c+-xfc?e(* zbwB`f2?4uGGr&F@#X{lnA6HT0CD@23CGXZFh_dJ%^iPC>TvKDZ5MNE3=^mwuCltgX zhX{D(vm~^8$3vm(?l?!{r^jK$)gTCoj6g9G2=FPuyda@K1P!iqBRC~Oun1?bTM5djWj*dxnF2*N+oepKsAbycJTN{DoQ}@Tyg`k~8lRXaJG#;LN#{h+ml;;%(X`vop z0fJcb9Su%ZB8D$Kjv9cUQ^gBmdD@qG@4}uF20bt0EB(P9ixThDT-iMwL|5@MP&ARGfAHF1Hf+mJEF-K+MA@f&M-nGT|FfmeC3g z_6|ChLQGd#e9LM(J^F1ae_kcE(JYiR0V&W-FDS7xg;UEWGAc}ZZkfoF#Lz?s*23B* z*aUU7nLEupG|fhFf_0jL@F2}C!NW5(Hn*fSsIfHF>X=9}X={+Z{Rwb@5a6D6gCf~! zsMOizUi%j#X@sQ8-G0@%uO#_MNm8uZNn0^nT6Zh$-&c=KjU~&(P2ODAce&J==b_x; z0!oTn{9$$H1an-dY_WE(c#G6{Xvd0fM7QwVAIb-a}2tKMo752 z(8&r2rYK<-fV1R@{Cc8vGAfbmNxO_@A(G|PU(_clzr3scGdX7{bc4Os#+HVnSEu{_ zoyN*S$!RoEeZmfbhl@qMAuEHW-qWj}hQCJd){;G_Z&`~4#0R{lq4=W*sT^2j0>?W1 zA)*P&YN&855`~nPYy$GL1P)H!FbKsKKrjXBUgI?CnM5IdB$h{>8@J`D6$eok3_R&% z>>+;1@WM|<`bS8;d?+Kzp#;D^)iN0_Qt-SbgGe1mc*IW;5RjLb+67z9G~YzVcsL1% zq(TL^@Dt$Ac%py}d{$^5JEsqD(rhLwLX;X~-RPD&2!OG=d7AG)exs zekFh=12yd^#IO+KJh6ZxVGwXopHj-h!Fr6!12*y+iQB0ks)BxXcvSmyZqC&0Rf#=Y z)WM|3K1)J8MafO^79?%d^_wDg43nOS<5czxr%J#GxLM);H)&TH)gajkV0GZ=z zsXO0;W>Gfdoao^h3*zxi)f5PD=A}##8+`$dHvH8>?ztBYGjf9@4S#V6I9x!U*OV9%(xwUA!36z^3 zIkF`5AT^C8N`Ge7iW-60>n(G+MEl?8?1OLL#!aoa z-~|uf28ngZGB`(0F&$F0B)4S)Cvt75~}Jdg&+GvdCSdvMTIE~pVHw98jbt0=G} z6?b!sLI}B{R_6sR_J=74;edN&1SCCLK`UTdYlN?j>w63j8k>&=6{oD)#Zw#2Gd?d3 zG*<#;M*4lwY_!a#to_na)orVxP36o`cBP-p{{7wVgV~pX3J5td<_*{WP}U5s*J~g2 z2pJCCSg7azM$e~K%`Ln3s($78AC32`P)o3v>ev^QsF%KP$=9`7oY9B;v4H>d)UX zK(m8H@ELoSSq=C!E30lpP3&&i^7*eG&Ui5dByH5tpoB@W&>smGgw<{Mae@QsU_nk7 zO~iKK^bp_y6{1PX?T5;{I)^XE<7+BkrLMlpF4| zJSs*zC$Fe3C#w3c99U5jkIBn~DIvF~LXCsD7!btJp1KP*kOZ)ST8Ds%Kn*$plA;`)%*8V?;`dq^ohj#k>m&u{u$DY5>R8j=*@ zIRb#F@c<@F{(G;XBN9*&0K~Sm1jrp39)tk+gZ~Fgwg7<=N8^m(@(G9;K#7AS62AI; z1^$2V%_-@_C;<#pI|MRfP$TDLDfeMMCmG|sJ0;q=&=bkm;w{>K6Goiq8sv@I{Pj1g zcc$w{*qjk#v5C$oPk7&@WiJKZ?(@Cwmb)jY+$Nr=<$2TD&6(vg>~LEC8eH^5Yb^m4 z&lHC~KOPCG7w%4*kRZ=W#I$F^dxGaP)>vO3FF08_|`bIQW>F)hJ~k!vqk|L?g^kC1UlC$Xg%2`dsCDoh``8IGYU% zE9qe`Gy)?Q_O^v|XoO910*Cwy3)iCZxB1x1ZET;-A8l^c%Wt=5*;}7nD}Q~UA^D|b zqgzNP2mCu)0hWAT2L^8^!#K4=TXmxweUB}swNF`PFTiZ=Kpr4G8x|%^6zS)T-VbEY zwa^}AQRUz`miJQZkETxzF%yqkNI*a&V3-JoI3+;{9-a&W)T_5pJ_F-zulvZ#;;9qt zz+Zs@Ro%VaO>QPh!~MOU64@@KD>HjVL|f5H2$B0#QP^!b28I;uzgCyjK}G%}dZb>x zm(KxW*rwVVb0k9sgYUe7!EaL3_mli!mKKFY89^3`zy(PJ-0wH}>-T-#Xz(M--X5L{ zt1h=p)A2q^OK#rtC@q7$II8*WeR5f`-(>P#9a7ctu)aqbn|vM|U)#ySiGjhHfx)Q| z-Jb__PUL(9*r1yA>m3n=S45szd;#_#FUHXgA)0KgNEOqUW}K0Yg*7l10WVKDVCd_m zdIbf!;io{Pc>a9zY(f9+*0Xe(;PJh%#0?v6Zwu*f44H3+y!!wrHYfjXVNze8JZyxF z`3e%!OWs!ORZZ6lvNw2lw>#TqKLgHeF7VitXzb25WwT{IF1uB?;qnT3OlN+zwfQP8 z-Le}#1fjz1#gWK?s?3YD#3UENM1-OM3|^>$@8z!EcZ__i{qF9mOpPNYCyrg%V{lcT zh*0ckLrK*Tq%eeCJ3>-K4EaQoBjeV4M@sBA{^I;@-;bEONc-!I4DV#?FnsetwxyEU-=`6}&LGZjx(z zeTvkbVzD=74O~0G6<3AmMeCg&0DB4Hrhj2s=uxPG z?T?!K8(QGk{RRU3lyAY`CjH5Zt-|ZxHV_CP9S-ud2p!o@IVfO&V`cey7=#7W@m^|~ zDVztT3hKRK{{lr({)l_U50j_H;xzhksmh_#=R-$8McOx&??Q7ID%dSZzXBRd3~tJK z6xScZwtWy%*l6e7S^`<&o$ynKWx+#nN_GA?2r_=(N*bOeA->15+9vDEH;5~M8j zFvbXf1cjxR>0`Cd{Sy~g$YU&uWdRG+^BhXx96=GequmkQO$e9|;Ly}t*4TpBII;pB zLZ1$2k=H0NxfJI%tMn5Q^416>6-N2sC5OT*at@^0B7muVMxlHc;Hib*+P%F-1WcKL zq#h+eS`^PjQ|kHoVE9i!;2@&|8B-V+9M<%kSj#!RChGfa{{fX3uh?I19+#R>myP`o z7dLvMO=G-~?k9iJTf)$kN+rQ6nkWmHKp^hG>IU|+#&q&7JtmsS1IaHk4{}%d8G_2A zGjz}xO-?&+1>;!*1G+)8n0oSt_*u$rD^Vuo1^~>g9ivAfnRi?@iN1#x`W7;wQmnW)Mn??s zJo(MNS6K#&B`Qv-AwxT!LZeuxdMYEvJcN;czq~-`GaZgx@U54HLoIw-QhM<9z+*)C zVFO`^#=$ZOMFE^DRHydn^GOor9TJ3)3;lwWGkoC)DU-**{xdA5&egRkg+9)SGWjYnmN$?fL8Mhl`_E zO}LQoMN!o`(dNo$7F^1~mUGzhUa-G}-q{}|KT#B?5zwI#z+MR~HL2JO{wl1X5japT z!ycr&d;CNev`b}qeOY~j{e!)djZH2)2{;KDNI+nrfK0^UQzRV|coL5L!_of1AJ>Cc z@=}8SgxFp;se1+{uP2lS=xS0&M{#W%<>jWnU@;VPR1+#P)5?i|VJS5F706e23rp~E zh7uPpqrRJBprM65YB{sbX?g30^1ghM1ay^o^q_P^&* zU4k=(kI$3b22xc;MGydHDi?trs5$oQHoTLsWw#HOX!lpYdhQi~t$JpAhIk^mx0Il4Lac)Q~+8p<>Bulv~S!iUf^UuQ!ax`1J6 zKb#^Muj8g1-jxLXj*$6SUFs2gI*x3W8|83{S+QE*sJmvq{av+f$a~m!aOME^>ZzPV z2&I3i`T{)3HT)0jG_9#tsmsZu!E6Xd&!JLuAq8q0c7fj1_^*Pru zL`6T-_l#;*)gG(zQM9GYALTZ?!NOF|&e!34M(r7;I$Wpn#zCxoF!}^ld8$ zic^(&n1=6pQulX{*2!>wZ?vUvf09}MI@1~lSBXFBush&>t)*Vxk}bw#+ryrnJ#b*Q z8l>>kowSb9)1#7q21c?pqY%dZ<^X+TA`{4PK9i*KL?DO&08oQE7Js;&#p}+0;I<5# z6&`M~Tc03}l><4%!IR383biggi9aw#7L)=Jnqq9~J3b_TQ=*u|&i|~=GKAoUeaJW* zD`as*j&vR?x|7d1@wpKiJ{d7tUYF+hs4PlS4J@bip{)B)*1aPlJP#R9PJlEMgH=Rc zf7fk@`$G<9bN9uVveU(~WOIao7{V+Ki&T7xK+&gfDo98v$;yVy9Z1AjIGT`*q>Y%s zBlwJkJC=lj#@Ri3$Y*-`wS2N*@4;LL&<=zMEnmsuQUKEo3Ri>#7CeMdL01QA5pc6> z;Qf<0J=Xx_V!G2(d=Q&Fn&j@=y$=G>qh->E!y(5%_JhmO+8DMN1DToBR6F_wDS@fNQW|UoiBakfe#$5k$>+S9RRbf`U z96Tta4B-6p4}$t1z!Q`o zA?Y0nuvAPU2C1fe%b<6#&q`^W=*C4R*mSF?sgoaEi6=VUJg7%^Riq8}G4Fo^AUK`? z7Y$K{C7;8=8tAeDY26Sh_nfQyJ~Ix2H=YDN2>{N^u>h)wV*o%4W=PO(MLj{iNPz3X zzot3qE=e@Mp*!s#Gj-P;9z5wQwmC2mv^;p^(DP~AQ^6IbA*sNKPuZ;0-K^8yD5}9}17-y75a^5EwO7Sp z5`4OdM0tQiWT(2r%{uUf%+_3{cIc*~V)zvY{_l(_5ALuN7fXOAfgm3L*^+^Ekcw^f zRs&$ief0cD!$O^AaZB!Q=k=;ohC_L^-|YgeRFCDDwKu-Dx>xMe;i(Hz5y$$=7EH9biku*~uL6M7kUUynJ;y@X{z4OU){z5`G+MBwJ}NZh+;fmDK`_`z62 zjXoa2*n}Dgx7F~;AFEHwve({xCTy$nAg#B{YpR32{sLBPDIv6!G(X$a^%q-@YmfZ( zJXtejyi;|nHb4E8=g5!OkK8**&Z8?~9ATM-SLZ!u(pF!ZZ?u$#-Bk!}g08S|Fngt% z6;#!j`msssQGh3V#I;g9$tuTX|6K=fZ*NQ3V|78c2`6~|?%UArbRExM^{;pTvlX#5 zs?{hDZ<3WFWyCkd4CDL7IS%NC)dFs$1Y1X@R==P;T;6X<&*lNVr3bV)o8f z`Y+$qn9A`Kdym*9X@X?&WnHmws@Q0&cqx(X0FSzhxsaY}^n}$A94B1@%Cx=5TcRH+ z^i2I_z+YHc;=kU(K4!~x!Q|-7O*W7H%IA!G*e~y~Ux)Z`@o_v>R!Ohc2pOGFD^MZw zXX91Hue)vU9zA1VbndGdxJjwgKSE*R6H(|Kay@3fwOpSs0`u>sXn6m?W33=HuVOep zsQt~=0uVi-Wr4H2TLhTZaH8OX-?8SSf`RCWr`DZ&g(13~kp1$mLe0_>;;oTg5`8YBX?q!`<7vgXZGgte6u~SqEi-{yvn@)N$8`kp*OHq=OVf zDH5p-*5M*r#})dRmrFq*FcogWL{2uZAdX7bgZY+(HC*iFzZun?@U;zTf$XVs7-u4E zb)y=}Ks|R#;zunn6e>HASTL3FrII|z57A^yXX^G)bL<2qFFEaVA<3z2S-Op)A1mcE>McJRu5x29`|9gH_+Q@64Mh)5ZBIPgF>+&d333Iny zA_mcN3S=wic;7yLK0&=J1}Hf>(sVuFS^emJPtvZ5KgXz_gZiqmM7Vd${%O9Wf2ySp zeCE?UuJ@b7Z?vbk_cpJd0IB1!`o3^IghXPq*kAgh3FOZxePqF&l3kJMP!doY>1|mM zE!tr#%!3V2@c&~Z93}qb7|?L37k7Xy16peQdT7820@4crl1Zb1m3Gp(VgffOn9B@C)JrHs71+En_^YG?Qn~PNrJR9ACG^-3 zcm%vv%UX~u7bus&-LeLYF=WyU$q8o|7fL~8i%-ow9W-1UIgmi7J-9mPSmD}qb)WQQIFE^~Nez}Qf*eW zcO;oT>(2I(RuL|e#7Sl$eD(M5m)809@PR)KXw1$Z*VH*9s+{ruwOtURmMS_o^TE`^ zT?tsD^deBJc3jC^UkuRYHl(QlQ*f`?qBjH=i4kMZA|Z3Sw=Hw~_k;C<%F4>2)$}2m zsApos^*5$Q?%162V~7p+wFL3u^1pCq%dCah8HpYRu9s zEUH%AXVRF1gPxO+EV}D?{@gYCHIs|e2HIEp9xL4$^tyEu(mxI%4r~j>TZ1bxYe0_B z@+5hu^$mN46x+xsr_e9`izM*gbAAMR5J3oymMh8K|L2%IP5`W?F=r5b@H|AP9s|+v?jCH@Q9u?-N%eGErAtQ*Z}#p|&PjFuFjo~c8`1@2 zs~2Mr^$9G%E#a?Q`rcIdQpIjhtD^fZDVhg-^9yNT`5!QAI_C89fx#tP>8+oQn*d$d zTnU-*s~nW78oWt_7FI9cE_ny(&zc=YH~fYwow>o3`V;ZW)^221AlX_;<-CSEExFw0 z^slFGCW^ht<8d9GfUBA;Bxh=dj?_n=uc|*7Hs>5R*`~!lT@^ACm73?#D+kC~s(Lzt z`n>qwyROUGy*5QR8m~zf`3z{rUam;9>V!+&nMC=>0(se!yQOkSX}82DyjOb_HV0$| zLMF6I#y(DYxe9>OfEFJ-|tle8UbZiZ%B8tuH_2{WEm53`Zzvbz5?K|N(kb= z&nXZ75He{Tv=7Q}vqHs9ScAD8^@ z-Z%}r?N{e@Hh(_1;h6Fp8*vLprE8g6nQ|!4ff+v9t zbR|(kJjh5WXXp?3KbsMZ{N>feFII@5ak9MWS(Io15-S6j`fab$mIL# zS<9by>drUVZD#q#&zN3;FR%{SlQt`WQr3J~1fA+>c~*PzjOrSc1xRjyZG-)Z-@wMI z0;en8Pdlr#>gxNrtQNcRJ$5s&Ce6%VwyxfCt6RrRM99oD;dUg>>h&Ux;!NNBwPyy+ zU&%}$zy9|44L-ia{o@z6$~>vP?Sm`A+rM+#&~sk-n;!rnl>B0By)<;;de7T~VzB0l zWZj;x|5J5MP4y1gLKJjoJvcyH(@(k{+@Qhi*TD-u`rG9^zq97_SKFSrx?zZk=ifX% z-e5PjTDbelxIJf$O`k+-`i^9S9P9GJ4Pi&K4(8|SbxvpW70AtODTJ*BS!nJqn`G<_ zYKf^_?Cwr}Ptac7pVR}l{|VxTCGfL|tgP^!zf>YJn|vWe#REq_<6^+7~O4NVIC6Q1I2kIJ`16i<|T^^2|(lOVH~6) z68=H_oqIqf)A&h$vQ@gEiH8S<*TQ@!e49XvC61(b>x zZ#8G7rdN7wU9aXyK`Qz|*k@(o(CC!V!kwpAlXo|oYja>Q|D$j>y!Rqz0mYlgo&kXJ zN042ENxQ&fZP^3J(;KPm?LnE<|AaZef$PEj>FYaI`R$mE-^@~PUt8O<7g%*F$+77y z>r^Ox=xAyOgW=tOprq%3ZotUT?|QOY?9-_+0X<8^B7J!Zitiy`4O69L z5UO1?my_waC4iBbY%z6q>YMBe3>m$sp>%ypcRgZAH;nU-Tz7NVq?@^iyGPz#&$R5H zqkV3GLh%O`ww-rf3Akp1f;K{iJZT*gN|-Fidln*buoLg-y!7m9m;QCH3l~awcoU%x zg{Q}=RRpX|`RR@pg)OJdo(}Re3~s-|nT@dD9Q!r+MM6JO?lX4LEC08J?m~05Xrkjm z5{80d(v|fP&w%pqUKxjmfDBIJ2fht7X(P>*n^!V7lYH``y8Lm5aZ`B}%TL|%%O_@o z+S5;Kr7i&k6d094d_*FV6hV&Q39q5(CFO0@4Q;>R(t!LRruQIl@t{Zf8soh7h%7vs zb^Vt6WwyU&LKSnfDVo^mUNx3&E$!1>(qju!nrsl-#J?Z|Nb$bDz&Yp{e<8t)sklXf zQ}@Vj{FeRu%%$BIBcF?YE0b0m=(}3cm)&ipg5S%f*5~(3srT3x1v#t;bG|>2nY(wl zy56K}mBXo0A|ZGrcHyWblSI_ZxQ7@C-b6TCwfOdRbi$u!-wT=5aJC2e!|eK0wr4Dw z*YKIoh44==$rUBtD=;1g9`VM)*zlXF^)auK^71Y#>-_6)y97kQ{|Fqgh9agBS`SWU zb0i2l)kyGz(nC-G8v2GlQdY#`6GaahUT}u1yLCiRQP^SeuOVM@g1^21M=uy6DKD6b zPgH+h$yls6-z)N#H8EVx%WO;sa6lCR&y$(%e-;m!sgMU8Gk zZpB3Y_`7`LPy2uNpI{ng&1}r{%w>p1_jpWd$Fp{waQ26u+RJ(rTaK z=L7p_Dk6Wa=7SRizEQeRZe_Vv|30C!epz*?+64xDc3QJQeyp`~V<#=oRxt~0 zsxkqH6Sk+V{|39FR%IbXch%9b+HDz{+t~!GIOqx1q)auObzj{+Wu| zA5BEt9%Dx)t~zFG1alNfA^tqQxhqzUYLENA9({w^iScRex*#I1TqUpL1bbLOnLx zVVuFB_5->hYDFcACUGr3hq0cz5ZR4APQWpfL2LjVHtG|<0nK+SZ9}Ky&xdGCji;VJ z52(Kw=e)|}l~1#mK4sauRJbd>&yvGUqFy3|>Ie!ck`E0Hd9bl}J@+xT1}eAmrZn*4 zTGmiV&OfbfWmi_FA;|kC3CTduDUGXz2LN^_34pl(U6qF!2!aPnnBj;5*n47oB`7K2 z7Gj+kNg_TyOrDQtZ_$R=?+2V!RnByK*hEk0 z!tKhynV!H_==}8z4(X;vdAjBrG_@qp)X$|uxO?igdEl>&%Iyt+aLe5~%=9&YzximZ z3qyX-a8>>eE8zE7AKGjkf^Ozk>!{4iYD(BzNeBOksB&$I(O!CLZ=n%=OM9l$bP*6z9NwQ zOOW5QBMbA)ie@3;e3Ys$^2bT4!Kng$`or4-`VuU0Lq@I`+q}7*GoxGO=O&&iJojl< zgVQgwxIz~WUP?)g`igjeu0HVe>BTb|$KG@x9aw~3XulQk$mx%)6$&Bvc>RNao|O*% z_4E;J)Kb(~q~lW`LP?{M3l#$K2Zm1iPBS|)IozpRrjGY19-<@*W^S=UunSbmXsQLR zwdcNx1rGTCCboZ@YwV3lb+6(?N#zCor>vnp{YhiSuD@bsx|~b!+A7lBZYF}L?89Uf zv?HHEVW*X(Q(at|If*uslNY%RsVZ&D8M}|GuNrl{JhmyP&C+yqtXtUSql4+`x%jM8 zuCGUNT~$AlXaTSWFOEKS<@P2FlL1iRWkO;x;T)@P1Opi0*HFl@`e2ZxkO@z->tXU2 zF5CN5yxOf*9TIFy55Z?Y#wb7>Y!$J5m=IH0< z7h{^S0!_u)_&;S;cB@eiL2?2C8x$}qQV>9hL2I4lY)hQ%1EeYyqfW_bjFF`&z( zhiziorl;HpTOQ#egIb+#6o8dpb09@SckwHGMOJ3RSY|tv#vlBBXIP&?@W}a@S!vUF zi#IOs+cH>>zBGnxD(H+wo3B<5Z3Lu=EEVZ292?vk7@8!MWT<{n%-Mf@_;v7qcSAn! z&fKJCu12#xzuk!e3Ytt%*7eZxg}uvD3{s^H-Jx&bw2hKe=9;Aa?Ue(i9B3V%L1|ex zn*6LSAJCeuBzv%LqVRC)EBEIR*n~TqKYR`7pQgS}y_hVqn^@AFu6nS!*}jHSyp*OB zGTN|f!!|c;t2AtvQD1-m?AzJ$h3Vn-pFasQjznJUE{qnd(NFb&@`G#UfqmqE8$U9e z(@qt6bE+yG(l=nB{pr6RcYI7<{?7BGLSsJwVdYozeCSA4zu(ZOft7)((y*FaIc+w6 z4t|Jy@ zXZF+H&`)itjfC)HAUgaAZfi6zfyj$o(Bs1# zDXYcm5h$kTs#-v`X86?}AQ>|Uq&r2Yx~#mM%yM%ZpS?@A?r;KxZc)}De!w#!<--e< zd!b?o?RQCUS{w$be$d22Fd@Ra3v%;R#!>|dMbNJgltVoWVpP_BLshJ zAtLr6j;}_-I}-O9=8m7$_^bh+4F+!@HX#EF2~Wl6K&Z~5ll!ouU%<2)rQ zpu`FJ8L$piE;fJcgb31ZYc~rRnDOx-7vy$RWP*f(~mc3d)V-zkAbhov+mKRUA zSbe$a=1n9%%#D=CqL7MWA{6Qc3gY1Oy#i(acmI7Fp67oM=GF6fW>jk<<&VtYs|uoh zI-V_>)~7lY_34Fr*a&|FQKcwu2cAMD^LQPxN>xd#&`{T)`??Oq_jTRK?;bB|(1hN* zP2vZa=e{q`TeqR~5>4}x&yN<@|9c;T%u>XNhw?ZV;X0h))PP9}pz51O8>M|ZN;Y;j z7wuiPiZ|E+RL>NIEcp8_VD+$&Z$?N#VGZ-YAtG!Nzocc~^Ixr#!NWaIUhD!B|Y#%GqkoA%u!R_o)1b<83>%}u$%eI{?5us z))64?84G5=x&#lV4{#fMm!H32mA{njF@M;1(07BZyHZrWIjXzqPtugdl^DSg_GMJqhCiuYi}An!DlRaH@j_)nYQs5N>kdFB}Yp1={@8o|FhnB%W~@ zHM80@16T0S!QRd3c8*P;fArq4CX4&&z8CIaO1dQU81u@=L0=qWPkv_!;<~@&Qy!MxYk?myW6)XdVAjmT9%sL5sBVI9FM-zxUt4?J*`*+ zvlHk+q6LqN7-4JF5VeLd$Cu#ux$R$85yXK6Qu#(+&>zANtegydirSVrgU{4G%I4Os zJt~*J|Ge$yc1*pnqcy=ytHXsw*Gr5X7dg zSpmG_p6jcDCrz(Z_|J_DZ7+{zdxE*ZpLS!&!=02Hf2}Bwy`DET%Pya)>Iy8EjuM4Y zEQgbIJvi&SJ1tx^0=n$AHnKc?EK$nwlwKRzbM(V55_j|1GCs`_uwmO?Hiy%VS%%IH zw{$Oy&oCLZ{0wR6=4^tS+eSQVwu}vLDx0uY&hW5T`3d@G)5kEqvG`o}b_Yry_NG9S zLO598gS;mVlH>QBMX(8nFamN|vju4Y;P>CU=A6<#mQH9D(6dsM>PgQ zdpgYR{pzNwKc#XJu)2Q3zq9OSADd@Z!BNcGe)@9$`WcyZ2fv}9*Kar501N{&>h`i+ z>A8f)kDv%IeQv`%Ff=zXxB*wrp7g2ffmuC)jeY@lS?;#3a8($E0n!lFWO z-(Cn8pEXNb+o&Acxi#Is`Jbkc2WOnUuBN(T0ftjh+hwpfM?3<5J>o29@2vcBH>{=6 zo;grC8RZ5mNV_q>%B@Umdj9HbU>GVcfg{tM3_SX+k{-MKBLnX?e&w&%R&T}V4l?@# zS~dJx8o`fB!J@qN4OC`D4W1Jg--I-D{?^HCUFXnqhVCB`Q7}&%?0<57QnB>(((msU z24vvQCmtMGm-2Ypx{iK5$*K*7<1Lk!%bqYeJTS$dxl478O&>@=wgX-MW_;ltPEpvSkz&S(g^&35{Cb>lo zjG^r=8FZV?MuJ~R{)$e}GM2bGm$~{Wb9;_`(sw@U!S)YT+E0j@&W1FB!zX=4J!t33 zQ6zQ8c=^2vc|A100}rsHBvAU;gEfRa3=`gikB$Nc>o7O~YAgx6aAqVNH;xDZf4H%s z3~R}6Li`r)X7d5?it z?Ze|($VI$NK=boR5Npg3Ifuk}m~U)T4F4`FlkRhm+4BQI< z$rl2Q2W;ZLr^M(T?vqDgI}Sg@Y}l0LTqJ4*%y-`DvG2H3)MAqxwd7hZea*m-M zqA0nw?UDhCmUL69hAOX5)f2JMlh7kbvh?cI@c&%8q1w0FUp|L%QAcEP!gIKTr*PkaidDU6?QK)7mS(JdFMqlTwMaG+PEnxXcJZUk{M9+R z<}Ho{QB=ru{4hKiA)1683z@TouUP)*_Txc9>d1bvWU0`&cD*2UyFk5m#aEL*Bw+NHXEvH%$+H zeOPYBGY!{4jLJ##gvdT^S=>F{2*G}(2P%Occ=N1A#sGj$ax|tU6UW9TdTx?TA`K{Y zeZ2;hblIDAEN@wzUTLN}%al~fS9Y8zD5PF>JjB&4XRuzO(-kyuH|_4TSU89@DD3Qz zgH5ckqq>sD_0)eSHZNDtPJHj;D@uLFemz0SUjr`M$h*38NB+fO_6>Y&oJn7fz)u2% zM4O)~F#~hVQH{QF=vc3HXq!)e%D&5>%v?ma!0Ea9Qy+`sRCspPz!0*!8rSDU;!H|U zhw!+WS=fQ2-)gELW%CPmTZ+zgGX%wp%YDjY8*$*Gbn|y|gXM3|b{r`uWXH0iq-kl} zRNB|qD0A#e@E_K5P-0V`6wUryDUG6Ewq6(%VMOazI$c$}%C9vrYFXp{E=9#->Py)P ziT^$&QYZ^Ui9&VvQ5oGk{=oz|qO2DhhZ1u|eQAnI<5zLD#Mh;%3&JAaZFuZBmZaz! z3R#$PFvqq;f<4pJ${3;}G#*>3!Cg{2SrvE8A zM*e8)gEPWqT9B@FP|T24V=PNpEuOYQ3q6B3w@iAE!&PI`^9Kx{e!Pq+s4qFjjOGP{ z-+p$9US;Ek;p#;5E+eo1VP0RC`{6 zqbF0tQc`;?q@7Y+{LidWS<-=D|G0$GZ)uvyDwZ4J{5 zL&$?{9XQ)vEcb2R0*5^u{iPzt@pD!OSZIJ62KI6L64;T!(la}N(K=E>J)LI4ti!2! zP+VUegT|=5u;+qUH=g>R>Cq&(l9k00P;wfl)!ehS}w2VlQk&`P)CdhKWs>4&sqNd<(7iNrqY+l~a(ph(22Qo|p?V`@>Rb*w`KKR7=8S zrvU{CR*>8_hRk*l_-jG@tW+SFaWvxui>q!{XXbYV7shtS_ilDw+=OLr*2mS6-MR(v zV&w~qtVcgXP1%BI=DJ8_Rq%Fe)FIao7R4!CP~QXfm5Nl9U^2i?;f)L0)YQl<SKZ4xRNefLh3ZUmyCGVQqaX z6CXBupzT&`qS5yGg3ra24i^osy!D0NijlTXZrqWxnr#0h)oRHcg7j+~Hf(StN{UYW2?mx&NSNn+XHKH0ieK}UN`_T_oUaunnafWp1$+G2lSn)RMQSNzg7WwZ#H zIQAPgyKc23knPR*nO)KNVIK$@KpXa(A2-wu-K5bL;hyk9*|MUd!e@E+{u^b7RSKmT zrh;soPORUM(U57qpx?^I$+-`t1wu%~b?q;fSWuH-uo&uM*U^fSqSY;C|2O#~pS;e@ zclp9?uB!G&KC-I((GAuOBAd8W=Yum+9c(g+i8*Q-q_LA}og+8k1|q!b>M`Bjp1r&2 z)v0jtf!Uc+)EGJR&kIFmWo4t2J2Ez)gu6`xV5;lOw zvNw~nH#j>qd%khye5Qu~%HN-5+D=L&BSYu{j{xC^i3D{w3ucJU4=+qY^duRCU0;kv zPKf{sZcXX3z8*8;xSf3ghkHgo1WgQKKHx#33{SXI%Cn}6pt;j-@*G1-kD=Vu1-o2j zeaUr5dH{qwIj)?q_e=~sl;1!GFg3!;ta&!+lh|{Y0$x@@J$oQs09XeAyvc%|tTH0& z#A8LlmbcorRvjf@(<%l78oU`L>wnzs8Yi91b(-`toBXdD(4`(TneKVHmlz)m&xPwAE}=X>YcM@o8*dgad=6N|%`G}3M1cgqu^c>^IWC|yuT5a=A zL82QRS>dFHx5GF5<5E6dC+x=WTx_WpdY9jwzOMYrB)Vp2Vuwp?>DUuA*zQW89L)h> zL(2v~4T<+hGchMHM%h=FQXwCz2BmlH=ut~gYRJOhw` z0KZto5wNvPdruKPbS&j~W;29URh1u%;RQBhn|5FE1SKj56LYP10pv*QUwGex6gp&& zkc28Z)K-|~(+>1XWk+Zl*=2XDp{CM5sawVxH`5ECd=LenR z1wb*S(l0cPynINQ^X$E+ z9qJ#A`i|ntVJ;zdNY$kn?uc*&3WPJPhK-$<2p~x%22CW2^~9s(aq-uPNW#=5aVZ&I zTm82tN*OW+Cr=e;Z+@^SZQ59aYls(B-O-RU4BVG!+66J~*Ws*(b4Yv2uDF&6Pz^8RFs$L%zb8_S1Ph1og0jeJ_ENevo`;^Wk zxgSD7=<`AJ9cq}G99@T`A%3K&$80Cbgo6TpS4DIue;=`@k{R78D~#h-`2f%S-GRbV z`Wv_X_sw|Wbb+LjQGYOP+-ukpyStS`mwD{yG6yTx%fLUI@XS1O<`RbF1Wbeeut*6h z{bZ>F9FTAlme;dq#`VuvX8AhQ6-&P}iIrmg`Q>wedQ3Nq5Q`ApUE|}U&=E=3!m@m! zkO3OjCr=egWe-GNeTIr0*`Zi&(EGFc;K(9D1n^m`f2rqqL1JU_fJJM^XkF= z{9aN6k z;zymxTe20mOi5&NPQHv{$3L9!Ok7;hXji$}RiOR5imDE+S3uXMg9fWJ$aqBCo{aB{ z5iie@HO{`We}6hwJ?1_Au+gj}0UdEoQ+v#VbV~E8q9Wuhx*%vF1CI{fXU|qg-cz>) z+Ku*QWjY$L-ifNH2edQgpUxDUHtcxtuqedpz<|LsIyw=si&9&LM7waTPR3{u(pvVS zPD#dO$asm4p^xnevLSnEO}opX z+qne^v}2;xUY(NG%d^k$E5ho(Coit+i+azUnp5?;xcV`Ju>seR^`_+k>60f#>)KqD z-F9k}{l65Adj`?Q#$)e~PmF$fDT}^<0K$&kOL;Nz57^;Wf83oVfx1T)C^BF1dFuokuUl94w8sYogBv{(Xe$c zV-k+yN*c*W;)!-5UeM}iwD#`xeJUbZkouLtIS$0^aM=OR=Qb{Zb0w;AJ86>D;qbw6xX^(pFxUh*Z=gVjTWNn9MqrA9#I11UA(m^phc7(^mirw-bF;E??1 zwvIs6b*R`daWaR$kUuJf;L_3pXs^d=cXeeZe~x;noKxqzeNg``9*q#RX~Is=gxAuT zVuG7>;GcmGr#EofUIU(J`NEF5s;g{^G!lRD)dXdXeaRpwGlOQMWF$6=L1W{g;? ztiKKXVoX>B%$Axsp2!eKgWboZ4k9@ z2^&OGM)VIjtabz4rN^~sW(9!M2jrEy5d& z_-M_u|5LQ+oNiAX>G$;UTiU%M_8x}XVJ@XjS8k2c#D{=~QBoby%Z=(6B7qG&)%?wP zU-6^#!O?%=6Of8PONs2?44Eb6At{MCkSF+s4!1xA8!NDE!~h(?DkP=J3>EpXW;W=O zETawdGMP;{(3x)}gxV*GJw58@;0_^5@}F$3%MIkeM!*m)c54+W}({>^uimxrInL3fhTZfKTYUHVi2ds#!AP zNeV)+1{?tc56HTY0&QYg&ZKLu!UGR}zY>c~6@SBG;palb5I8W5xm306zGu>z>4qL~ zHF7?o8_9g%CJ8Jbu+)Q!t>ht?&yVp+>FVklH_=Pj$?kMmHZ{&Qu4=clKm|ikOh-FX zD*G1P6czN2evaDrLojjh@tcVMmn*Wx;ht~E2XaP1j3@6rCbLiO^v2=CBI^e) zuKsGG#}w=?D>n?+HxUUP#esV($3u77$zD`z^7dyp`VVDvR^5DRaXh7)Jft&v4i63>-xrc#pBKhRPU_h0*{+;^IwY5Lq zWWjg37y^dv-%=hr+fnM%{1)x@R$yO7gBUK%?!>xYMcTR`T#K8gA<(?mPiinexzmnmT4AXHA`LIYPI~Yy(O4&v* z>Fe15urw}-Ns3kLz=4DBKQ1KQehXu}7-owwG^CoDl26)BMteduszA|eY;?3?vdhjW zb0p+TuJs>v@(#VM8jB2N9NT+4v)#huZ{I|GEDKlh9(u%T#eHiRABX*`nqA&MI+^u; zB{PCk_d?gDCuXxIXlsS00A?tyU21XLIehWV!v_@l5NJS^gDGhfSTZJAYQK56DcrcF znpwLsFyfWw8uHD~&7T;n^EkMMb_lg6K;HGS9w4y1)gE*2zcqjI41`fc?0;?xyWUMf zPd~(MF+|rmk3TXnUYG%n=jxT54Uf=`f~M|A1;%7|C~dqaHu?Ed`>xo@lr$~Rdi*B` z9Cli|9{UHFkO1@c7GR_JX%m6QvmcW_@SnDLIooc0vNtnfyXnw@Yn3YS6>k{yoYykIwh>Y`)Sbo3- zx;t@h!oJo6Fk@Ys2jst*aR_rZhbbT+8y&H4rUj!-`86^5up~^1>^R!-jLJ3m9le5g z1AU)o2ApN9);>SHen&z&O+!!O1MfE+H}dl>hf$&oAkysOvSP|HqWQ@Bt*+oTI;c*20831uj4Or{T>MX(0Rd>^Z)$c*;$ZlW>HTjNm~KJ+P*JL-T{G zx8FENqqeDuJb0MN-eDA%1uNqgB#u&vftGCZ8Ld1)eQ_O5eE=dxVi0jzY-m+Qj3z;> zjOl{mIlij9z@U-QY?BXAKP$-RlsIxpfR$M?4*u7|fmR;Q2URpSFb=@$)CQrCy9OFj ze=&fjF>#66LRG8-xC3AqLfAGZ=Xc3iBpwMLi?@n>f_VFCAxpA6zMTkNM zB&e!nKP16$PO7ft>C|rC_-*@qUK`=KSH9<+^8J;m+oLqg;>(z3=7*VY6q(%fPuqfY zuBQ@HfRWU6Mcz8jXCfmjQ1~dHTL=w_6;|X21)^B<4cO^%en58)4bAmV%nS_8&VQXP zEFlXGEjVQwPz++6prEpp*k48@KJfM`jBAU$CDv?@1X4>Jbj5)S4mCtUEiqDLxQCEy z(_G`TG4HlXPcOH<+doD)lUao{#q{|Oahn+Sm~ zNelW22(7P#+ z7Zg_QjLk&)z>mq5Sqs-uS7CU=1XFqFKa22vMW{b7cp4#Z7BX~R@D6}3YPwdp!UXmjaP@ijqwMCdQ=GQyqW< zvfDFC`)ZkCWZdaoiOz3n8$7Q5-y#^3b4{S=TGXZ-?qN{+>+c5>*H=URMuUrxMW&w; zhk~27>)Xdete3iw_4RH|J3qrldwaW$L|Fb zp9O!(Gdu>R$Tt~MjtTv5Z(9dMC3h(ttB7KKo#cG7c(kU6-h@{wetgCC6j_xxjjNZ# zQ%I=Y@{9g$rSz5QXX{~7_K!_pR#xCE@KseAk$>^PY zWu*oG6P2rGuyf-HTs{_vHgcM4f%wGu_`19t@~Gu7=nj{r8Lt7>XK zD@qbs?+|Df8{wFn&nrdllG=S?sYS5fjI!QeAO+06={Gf0l^tP2KeK1C;hk23>U!z$ zw5bSf6Rz}5b}kF8BdeW*o>k`OmC~NsmSv5g9UWY5>7>h;8rauWeX6=H-m0b3LpX8+ zFtDxP5c|H#kuQ&sVhC0BR01s4_sl|EOUX@&i6{kR11g7-mhK&tK62wlpy9h*MLiLmsdbN4G9p7z_AsBeC~ z;1=}ypOm$V#v|NLhuJ>?MIixCH@snTa)}DO^hQ!3eptF;bfHP7ns|cXTN7GljxAj| z;pVxrR+Y2jLCvl$`Zya79c)+~A((l?g!zSp5zFY=gVG3sT1HI{NavehIl`U@W_m9X z2w?yl5t!qm{Na$> zkW)7evth7Z$qjcam?}lF>OsGYNqBMS%?ExavHQ>>d&Nt*BZYt(VF5-s^M;Tivw>jq z4U^(FI2YQUG%?f_l;VY& z*-;|keV|qp=Fh~XtqlxIV7>vmGfj%5c5%O!h5(Ma=4SJ4H zLcEZz1;JBuV<9wX{*X*F4ksSQ7$yszb}r=0OHC3qBDJZ!ZDuZ0z`f{;kIUIC%qhNO zwF>6?*4kL!*!b=&0a8WDP+yLUe`_lz@R#A~ctThh?QWh7&Nugbu_LlsU@=D{Vs=Kv zgq!ukAnE`5LZ0wbWEJl9Dbi>oZetaxP@*d{TM_SJ4m01wZO%9%(HyPqjWGyhJr7u5 z@e8m9yM};rT_i%Dl_n~sxghEyH+zr; zUNSJtj7W+Ud;cJCb}c~YLz0v@fZ`)xv`%gXg)IO7hJYMAJ{&wQjoOki>QzQ=H&PuH zkLW))kzloVsGR)=H)IY3LXz0?KPpDhU2vo0+}0IQt6rh2)uH|Qh1M4)rn)C~^Q?D) zxJaEC?TwF$dj#m*a7?(=1*x)YXAF)PO#bS4xvCR7Kebe7T2Ru&cw@bjr+N`|m|z(& zk}XFY$eO@RPh_vA{glWee!#GCV1kh?^%AyNPIYtHfd(>m!a!e-zzD;_;Y7g$kyC@C z>lGrLg++A3hF`E)E^3&99?KVN`d90~E<4d;53{bFwv#;fI)_8?!~4qinYIW#Jj9w% zXO*hvp`^NC`>()tgP^;Z)sy zxaMkL(+&x>5rO(#Q3Vn40&v*Q6(jTBr2|MX;wiAmvs130Pc z4lK~}2Z1#^`?ID^!={xacJj)>(#_}KR)?Id)5%;xiDuTf_;Gc6RUIY(`wl@Ntx_$3 zKvuK!vYVbv4DwT62+Nu#(Lc5Aj+1wT$=!*kP^tZ29x>a+^>h54^z;GDgDXaKryRH@ z^fo*gdb3Ai6p?)CR5G_vit7_QQhUz?c4;^25Of@_yI9L*H_3m>FBZsnrrSA!PQ@|( zxCDrDRYgS!UgSZJS0!o8%!m(94!%|rlKvJZ1>nls96w|Pf|r>S5uT)Z_V(>_mIe29 zjvV0NJQV&25Rg!UKRD(YI5z?Wp9ThAWZ4%v8kaqD?0ebg;r z<=6Zw&C;(tEvU9#ZT9Qlh8u%Jf5j4uT2@3Y2gBeX*Xqv^>-js0{^|FE2ZvprkHxu;rpp>;yW)Xzjr3UFRfi*|oxpQwScjY-xN7V`u_?itF_S|A%J&tIaT0!k zU1Rso#Vv98B#%++f%dh;4)eD9T5A2r3Se;_aSw1@_%+m1Zu>Y;_t_j3ugjs_!EC|I zr#!a#mfv$5mMYAezAoLxw?Lb)8sybKwG_A%#(GJBtIHAo6Es+?M6A>Tsg^1j*SeX> zY|lo8op@_TVGezsT8eMWyKp{9}``ly14!@F*v;m(mm(+och?7cZHh6t|35-16^QE=4Mcu^Mjrk##V@b5FY6Y zdb0=Z;8@Cm$o)A2w0hV}TtKseMovoEu`@MY_H?t^!4cmxV*2l2h;A~dK65Zw@z}|N zT~PzYsTylJu7+D)E0{nU!FRUpXjRI3K-~K-sdwM=pW@4F%|zsO8ea~W_iQ(A9N_xQ z9d^Nv1oM{t`ml|(4Hq(jm)E2?PaC4+98&rmOz(czB`M|H=QBcAr#g|?U>O4f=m!qM zrq1`dCB^u(qML8<3t2F;5&<=pm5yV&B*6P=DA#6)7W*|wolExGkKrd$5YCHl#`UMW z7C$;8Ca%L5)<1HI(uK_EE~#Dmf>yAWeP&o6SY#XNQU3af&Pz<@XUO3r^j~*EnuDF+ zChjX8*h>1$@&LY=Iw*+-Yc(u4(FpjsctIz}&CK=9?14C-DOsMpi%*v|xYJ!;Wm_fE z{;ubtUE^jEY9}^uNh5HISU!8k)Fp<4Q$|ATAap-0em*s?;I`@XJ<*r<@pS24Kq=O* zOij(qa#YnkQF0D@>=;a?9$W>ucM-H<&wo>5LzlJm+zfl_QE~d(&Gh7lCXl0SJ|jV? zeAFo<3H4?1a;9b>`wNGTv#L}Ke2sa@Gcs{?=0=7&Zn6IG&R=(I)kKc0Lk2zJz1Qr( z4Jl1%14MRwVH1xiy9UQVu$2IcgoE`4$2(R@Im#(W?WPN;X3X_c|F^-$GMgT!ttW;C z(iD(BF4;)Q3BW5)9P%){9N%QLEHZ=_Y=2&oL9lS}+B?h}#HtHU_)c4 zz};n!n{Qm5Gaz3#h?;}p${|?W^Xff5LF!hX@E)dMEdwc#qQyeZCX*4Bv-LGCa4W5D zsm`U^7l*mx?dQH3SAbgQH1?aaXxPfgz8bvp`>$rJe!gSH5;)X5b05h}{$PtMmlAHq zW%0u(b6V+@iD97@-?=-VXMQkRx`)YrjImnl-6(5#`M8df)oXUL1Jf&CW3utou^RKC zMy;ez_lgt?dcE@ieyk|69IZb+vv#i=jj$*cIMwn1y1O{*7!Rz+RC{n0xEFGWIO!@cqM(Zu$kqpF3^i3H4# zGqAZqO>JW73{2?8mn}Qd|60?sH@|G8GzI=9O{f*$n+`DR`X3XEP41U)IOp>VU5fz` zM;x?Dz=?Y_?a|eKC^fr}I>q&;`(BN1NnL%*dO89sjXyBb!^;IeC>bq~I zhuu;dEwA3mFDy=LTy;tdL(y|pTb%fwo3Qq{Dt;`O1nwd>@)>z2ciFhkyYDMb=`S9#j;s-ROrfj=sizt?ZO z_|AX1qC4N{hV1pnurBv-37C^hr-t}{Mt_4OOEP6Blhc)t@A;7Vi+tM??N4D3pvZ@O zep|Mc4ej_)m>1dm6{%&z0^18fK7~WtK`BS^{71MpAwVJomijA^-7(YfT6J~A4Nfv3 zZZ4Wh#+TIx&OgRC_)ShUZNDTpEi4u2+g5)KIx7Ay^Tyk%4twNvpkg9Ilfx$tQOxg{Ma0j&%Em2{jhPeD|h@*(TtVM zokMIFggul0<5nJLt+nE=1`rIAnC@h^vn?#bZ<)4FXHymHFp^XCUmT@S>`Wk*+RkY4 zFM|abIn#6@AcU$MI;(HIn`^Er_Rrhf1D6y?(j}M%=sZ>%+zYiy|g*usbzBu;oBNKfer z2}dF#JS04#5WKHDp*g~3!z85n0Q9wwnQfEG;}IQ52@8Xn*$h{WG1O?lm!XV?En(=J z?OG=E+gWcbgaU9QaJ9{?j+$K&7#Jv=5nG@>b6k1Mv-?!_gil%h-sjSd&)BhmcDKDD zYU$n11-Ba4p>Bhew9r>+JKa#ojA&~M85)5LK^PjW0wf#pNN`-*aC9Iz>{;2+*Pfs` zZ|mvp$9g$zpV~4@FmoM@iqzs4({FuXE9a$`TqZ9>3S$D6`VF-t?xggpqVy~A6ewB# zNDS%9HO{#jJoT$53p=)z7P>ra+_b(i+a+^4TwMafZ>qh=Qqmq19aZ`?QyPt#{`CiNM@CS!7+uqHEEd_yod+i+P^Zpe;?g3rLHzq#SaVo>l0BD=SCl=t2E!1X_wUBR!5T}B`ZQfG(C!xU zh5M$nDZtviu;aeCTR!L_+pEvN%O?aY137&PBxlLYi|6dN&0Wezt77)9GJ24Wzqk!84 z_x8!f?GTNHXX_^hM&K1G6lw2B9z-#6QCCAJ7jG$(UynGfYP{Euthkk1-~oxHZ)haJ ziRJYBls-6+bwl9*l5z203FyYxy^iB(-{sw{uY@Ua9{+Cxo7T_dSoRp=<5h;b>Qwo*U ze?78VmqpEDLuc5heqX4tQ*InmRht?l+xW~k&QP!?#{+%mHs^I4`#M89bekCLK|_g) zdkg_DGu3Cxfpf$Dq+!1=wL44Q9;2^&ne60+m=SiG%m`aC(8OxCn%VH$FdgMb{MXeb zNQ6lTeAfWUqQJ=g1O}d`w4)|tj009ofr+KtFkpyZgODC$VnQAuE+a9X|7d&Y zJGx*_7K}7BZCz6?z8CSogdDXy^+q3y9wBqM+j#jvE5hHSRJ8s-YF%1D;jx`(5E)kv zr6?!ns0{UP51onZ=V-n}box%rm%w0L_dDi{-C9`h``VRzz$wM)u_alz<-=RwDr()= zhqxwG{=C82q@+*$0QoPY7_tY3wZ51yQ$VI0ofJP{lHx2(5)y9K5@VVQnF0vVGRz1i zUibbR33`pZU@Fojr(H5d2#==*u{EVyA_=zF{1+V(m2oVl5t#dsQiI>p$eVnthZfB=lSQ zb2g+@uVs+-5#z=4V_Sh#jX<~2bT(K2FS!POo)(D$h`Qw#9;Rv}1d56u_-=Rk_zbBA zwV%R@idgAYBaeqm{sU9(1k1p-DtnPr6mlSy@=@sKYgUonGF>r)$%()vgdme1^Zwpx zq@h#?JF(@h_ttw=pui}@LkMUw!Tk2KQaVq>#$IeC={79R1#MM>1$sLzWJR}Wwi9&* zVbU_5jM!vVjCKDnopff|um{&OqtKJDt@VkBir8=cyF z*|fPjC3G2$!309*#}fNzv*X567RnC~=r{6a6x*72ee5ssZ^|`%|NP@W@CySB(yQE4ho?!ATes=awbBX7? zVccR&L@*wtN-^CKf;TY>hcK&6Mkl)2>HI^pL|KwyQrG5hRdzACMfz0at(CxL3=;vN4=8PXy28`BkJEvpU zi5(%)3BnHWK5E_%R4g> zS&*K7%7ejFq?9BOzgcafQg=Gn1IB6e$;msoR9XECl8&8&H9_fV!Sl2L8rFz7F?OH3 zvmIPAG+&;2xr8h=oW=?B41&l1EG>(N+Y?UhgwgiGa`y79x7$#gZD}DRY1!C{nScZK zoiORT8ZuRrQCITmUgx?eMwfd%I27Ur(>W`Z%E5HyfRVJ2#jT1t!{YtL*g$8~*ISAH z@$1_k$r`mP9@|Up^mWC?Wz|Ho2NwHHXM0_>fngE+O%;aAi;f}FqIHdpV}@$KUWxil zPvqfqXNXU8I8lh-^hg z1BhJ$eANXzIacy=IEX&nNZSoI_TM$V_<*SH^Jf53>Z>2yPu8#YIPNYQ(|^6ES}(k^ znzXGR`zKfI{m1jR7DwkRs;wJrJ-X42k9AKx#f6gPOK12~_z^eszOhN#chMuYRP=pi2L5T6Av{@;8Or8Trx8VtR6lPJE`qjurkg>maNv z9`GFJRz6z;R^K_FJC0v(cG8jL#hv@zK3=nBR-#Ly@RdLwh70EDha>;$tX15rk zNz%pB0`auT$v*>^3-(F4F8(#==il)J{0bO^(dXKP=-(FFSn$SFR6Xdh$@6%PwO@sH zZN!8PYz||fKyUqs)$(O(T_E+R`)*PqeJzLHA$lq`4a#ZzsC#N=eth>9YRreER1yYc zmBvT2191O6Zqv0qU4T@^4z-<|fh=D2Rd_=BPJOYn+I?k3zid^{eM^x62^Hp#K06S; z?&uo)!N6n5r@`q10U-WPFKnVf;}JSrN_NyeFNI1tTLf zuWVE(c_fe;p=Z~M`~u8|Y`vW|yfrSoGazy>gP3C{f|AMv;hD(chP+RSiJ3H#AD2o`Qp0x%C=J*y5!+_Z5q-%!#H->~d?Auv^1~ z>(3IN*tT`gn%A@}y!Xnl81UykT|GvlZQM(64`Ys*JA;UWp=~o{ESbQyrkLK@^@u+V z1GpFYWJCsgark_WoGc<($6knQ>n|m?EiMomjfD@g)WGD6wA&2h43DLR%Yt9JNai-CSr2 z+9u4tw*a2b)+eem&LKm1H6C!d<;00mGjtd7XvIj-5H>3^&Z$b9qyG)%!>yPUSqex6 zg&boUV_#$83s}%NA>7FLvHcs8OVy%K_QH=A;V=Dr=XzKYnq(BgWE%l$kk5BGm_SfH zl^z#`dH35n4Ku1*Q&v?~1##!lrJnIvY}JFbONP>i(Pd0=&GR=U^=oV;?I3p#I73eH zt|RX42MJgltKNPRGpR*O(;>Ndz*!A^?*A=0-hZ#h z&;0)P)Yn*Jzt(98g*66xRBOlc$8KGaFc6IDt3*}-+%GlV_k@)Ga}FI&=uU_qXzdyF z92u>w4xM*0_Wy4Q3}R!!?Pw$_WaZ29G_V&?<+bIPt-Ic9=UZezZP(fNYQK>k8cx=5 zFo`nCzT!^~rtMEKr)!YR;~sOCf%WxO3-w=_|Jx`B#DRN1dLn*-iHW$hGoqO7K~lO^ zbyt&FD(XWLLSGN5t81t~{z=pq+YaWScaKaX<2CPiW{RvNSuE92vIV586_GSKtGN8! zw%ke1g*JL_ntyHD$0}osJ5N0por7uEz`1?c(M~a$K{1s!()cCLqw_(%L^tXmwK%(! zOF7*ILmP)Tau^>-4poh-q{ekwWlJn$H|p%EFd}*UJpEISn|FEnRh8Y&(wziddbfa^ znpfs@EZARjg8LJ{g8Aq?{y)P;qNM0m?u8jo{}62TExTlZoQ$9eM=r53!HvFIi(qqo z6t>>-h~&5^)^LG=d>M-yti|HMn}}>dN+`M%*B|SJFy^@XDmQJyhkCu#{|l8dNpM3ViROWJei1hr{dfE+JmtJ*&kC9l<1#qnw$ST_8ES;Bx!c)Q|{fN z6Nx7fsagl^naf&W>;B+Oq|}J3kv>QjT)OxE*0k?YP-+awWcq>O)F0-`Hvr71&UHQG zOj^>pRINJ(Lg7)07A`$EB{_it(33j9SkHiq{9k80qlda#g2&SZq>XW12%V0b`eDs% z@+zdBp^dHa@tvi5>OhBpG}PP~6RVvwmn^KzmvY{S7FBUQGSS94`BaX+b{o1M+6@%R zOto~`osbD1XzkUz4*AeQ6E9;N{HEVHXtcO`+?V}FY^0KmcwZ`~xK@|~u~?jmKN%6x zj0F5Thw$;(^Kr812!Tb9VkM*y%MG?wGzfN@#WK*zo%5yzEX~+4FKlOA*OWHl8=GAi zc_-Jpeig@4zdS44Ydsb^b1yVvIA~mX+|0X8#j4J4`Ag62*YQKZLL+mrg)CHuu4hfG z20LKh$ht!AZfCNqocbq^o=Z0@0s-kV-Foj-;Lb4&z^wOH+JjmPmMBZ86@`mCPB}XU z!3DFBc+crQDlAM--2KVpJ_4?ZCUcS0km&O(X z`+3)BcsyLCg;1**P-{M<;{T`arL-|u+n=eZ9p8(VaUahZ=hS*+dJ3(4>ByK^#cQZU z#n_&3Yux%Wr$M>6$A}57#Roe#mJ7AdH+s>Grp@p4$NbMdWdzEWq#7_?tU6L<@(jY! z@H%X})vu&Y*s8#?G5xTIYGBJ2I5(Vbk(5c=TEa8v~0J8Kwx z*R}lobsuuzT{vEZP$c*NVC@pQFR|zCZMo5^rpyGyCmRG%ToD^+Wc@P1)UnsPYu4K# z9}?(9Bu>!)u6mnw67qLSEjJftQV3`{qiUoAso&}{8<_K0aH*Y<|ia2e^Xrn7ida@eAeNK0;4F zDwO0Si}6MmNawodV)2Kt*&4yy+!MdM6YjFZKSxP79cKIlXSOx8D&Pw4R8OH$a`3bV zhNwlp>NP;KS{S zrobZxVIE|dKN9A`EH^;#$Xv$F!302kBz(MLWiSF})9mqZ+1YN_SUe44L|lgG#$WQ@ zOw)zZVb_}Zrz7Zzd+YS6F?Hj5KWbj?`ihfr5JA#W@M#YJhW3ZXlpdx;u$>eu6~m}#)HGwr)te|WMT=Yd`y)j48PiONXONy z)Xs*|*pW|>24tBhCVk)RUG6NjOiY3ZgVeBY;fmgX({_4)fufzW6HkduYB!3T{sCOY;U3r@R@IKg90URb!ALdy&&M_EUAjT!VAVqC3B9HMk&p8|7;z2B3>in5h>IVBp=Odie0);j zQJM%bN3Vq7;a7b*R~yyiT?!~&a*7q&DJEJkdZ0Hetv1O?4L^@X4v9Ub@gK?>}N{VMU`)0|Ir(kJSPX+Atr06*lQht6WVU3ltw zhRDjd^?*f(;9;yKrLIJ{-S)%{8GDxJh$Ub~nHxGhl)56@fjB7Bp9ec;^|1>pH1aVUi_4I@|5iL@r`l;W%bQj@>Ugje3V$Xb$S0-$RNS<8pT*PJ~_I*Zbhpa zUeFJF{TX->%U`V*%M*dI6*_q=6#P$%y+&DT!1s>XLR-~2t6GS_se6f%-Bd%uj(0XK zb~a3PHUhpG5H;~8=zXqW3-M`JWw#fvkgeu7W=ZiXfL%#2^F}*Xl*1j- zu<$bj0OQ-T#5RYnq%)8FKdZAU!9(-?b z&nl2P0D?Y9o;S`d6^w7kb#G0jTDXRMj}Y~yR5?1V)>1ss>BWz5PRW9NLSho1#QKR& zT<>q(M_&Mlik0Iy5dVJdCs;X%V-sl1a}JX4lej3fRMk*j$y#hN$+ao?4dI!_n)t$? z`<&v^bBWxDh?)5XqvE?5yp=1um%EzmzmaD(n@66-kO|X7!VvAU7SgFm`-98BSyb3*JOktY_yXQWm3nR$Bb>@6IChqnEG%z)$ol+8xto% zjR&5sTpvz(U)=h9(T8$bHEm;vHi0dr+>8XzkcIE{M`qc3YrwPWWjwi9KRL_JGwrv$ z+Y)kQWq!IHc+9kdpq2J))Q-2#tF__KWm3-0aZ#E_&gT7Kat;cska5JQJxBq}#PnGz zJ+&11d9#H|f0H4)`&~IGxB5ZJGkTlP*?)u3J5Xe#g$y}{cI50%mLmQayPr}?z)&v~ zG`KU=*!;Q-8@kG07C2Zca|!gUdp>uzh`qmO*t97?{ySqWU&-<_l^wMUanrv6kFgW} zI{{`-o%=+ViD|^qDpkeNetHT`?yQk-%fz19-rZlcy)~X-0fbWos}Qi;!k{Q_g zV>EDPJf*@H*?*UeVqhkwitjC~@8IVGgK4x-8hh}!XK;h3kH*-k>UIvoDnM45tl}R` zwsg$8Q+Hy-bHJ}`hpE(So7;*aj@sFwF}{h8)q6c$1$wyEnEK;ledhDOSi>=3Ityn) zMDV7?%(a1JLLNb2hLI=J)RqENceMx&w+X-z!u+Wda9epw-A$2ZbT7aBKa$Qo916Yt z|1(S)Wmim1Su&-?PD5E!iENb?Sw}>ev4&(nwhECPvR6W$vW2l_XC&Jx+l*;UC1e{} zC;RXA{hjOi>pa)h^*kB#`F!sC{eHdjo#^TfOEC>0?S++x)ybZt;YHSBg)4si*-O7_ zFXtydJ0mv)m$q8gMs@!Crz=QHSu=w@dE8$v?CV~Ot6%9W>A{EcUX3~AW`;FBG41({ zDLz*VfLUtU<>POzBc1bV-aeVi$+>F?I4#IRFZ^BEhyq5|YE)lKNo-<^%kh)$TgmPp zta$qzB6Ia5ek70#5$LY{%>-y1ac}~7mz49i!j+^!RaZ@yC&wR_w+@-3Ih7Lyt(9_R zQ9{pDfKaQxAKABX&%I8o>(B$d6cU31MqID4m1Elm=Cfg#N^$di5i-_EiBWiKz*Ga=g3ddZZv0J+SKi4(I|GpFE-w>#M7)Av6v(OOVo-%ebV{+zR7HsTO5u zT!Hau&&s%0#i6J#D=Nk&BCuZORZ8FI`*iesISz~H>vaU5i)C^0RVi-{y1wqCPTb@B zVzReVSrePNu)Yb{{cgbPP;|1aF69X(3fANs?zTSxCqy=fcG(ihwcLU}lh&hm%P%j; zufB}ddfzq0+-PIM>$>6L>=Tk8CQ{DkBh_ztc7#P@)lah;)}z~@v!NN{Ig~hS;llJ& z9eFVN?&IfEnt!9FFR-kKNvXNlV^J8+r&lC(CzpVQ#k*0D6GM?h(pD-3Z2D$X)TcXpeLGA2A`u7KDMnTIPXsEMQI z)*({K$z*SW&0LLdZr)~Y18%OWPBU zrJt?bs#a7}Bu+2aATsWV<*--yz*{sj z6?)Kjxg@`GaSCw>NE`?QwG==~U`ECfu8@oj+l7f0R@HbW+%h~Jh25vGfWxP70~1ss z;fTj&SXXWpfc1{)4o|NQ(@+(G4^6%}{681Q4peS-@2=Zc|2XVg*8xz8qpGUp%W>dD zV1htoYh-R?YU)qMYkh%TZStGn__d(DyfR=r5$EpzAMZ1_LSUd(!YpljOnZZoef#(x zg^HE7?8Pq)>y{1kk5U3@v_LVp^?(3B#(cl_-)`G8)LO$m4jMsyeu1MaD}$PT%+$H*Jvs8$B{xbdhE8aGKbakC&=#+G1 zS~O(x5=fy!qKPzzwD#*4QoH$9e0SW=^7ng#DubIQLMUF$selx?< z<=sG&OOQYt?cnjgM)vl1Rrz4A(vZn-!rLpo$nU^CS(M+%h|l`BXwc%FOVY4U;Z?`> ztc5oXZf9O`tU5KY&9eR3v+~Pc?jAE~%DLGc{`1W=>8)AuO@Pk}#UA(Ic(FU7QNkhX zq68SIkMT;tp~m^5Gs0i1Yp>4O9&YSBj5JfLn&INX!v%({MhaI1EPi>uUpSbbkw-Mk zq4FXht<$)Y2$G11^sq;uApwH}H+q+yLB;p1gpAwcM{$u#agBH?)Vi7g1EoxIxNpDYUnZf7sMkxHsX1*A- z$m>fkMc9Yq?mkSTK%Bf&w(|Yco1HCV^Uvv6x@D#2YSyfMy1pnV9msV)-MslXJMFA0 zyJu6C^X(2stt7j%$(MFVhy2;yu>LrE<3w%1di?ry10Z5I-hKRfYGcE6`%b|!bf?wZ z$@$JfEA@MyoUD$M^-LO$wB1x}hxs+$c6H2Vt!Evc?b(6M!5p`m@ibx6AeY;PyCXC7 z2s#9NaK%X2V2~zsE`?A@9*AX#=^)Gr5aNNcz9di&!_Hw)gz%&Koxx+bf^*^uXQeeJ z#f!8T|9DTx5woc^iz6}c47XM{t#b-`pu!w}ux2)=9xRi!#Bb`_Hzf|Ao{>MsOc(sL zT$Z{YEP^MG?GvI39VY~p)K;FglEoe_zZz**@wDhprbg-Lc+pDPZRfuJiw)IOT}EJO z*gq!6&#J^mv#qOqN)<^YwrHe4Ly*7fS8bfk!l}$^PaI)ZTA38YcyFDS?XV-GIrwqh%{I4qK{g zmkTcDiqUC+QE`rrbGMw(eEP>B_vQlhHuuX&sAwE8$MnQtoNRw!rT+wZKZJh znRf}&EL^*P1>(~w&J|WC`YpApyhd?Tfl9H zSP)i{r^hJ2jguQdUr_PC*oo&cJF#B?aAOoTl0Dt|6x2f?P!iY;3Qf`Aai?I4`{tl~ z-E=@5y^RqQvf3UpU(&7>SZ8zbZG|E~eWfFgG2nkPK4>*vZ0W`G{*QA{_cpBV-S%KT z4JQ`-r}osXC0D(-cYHIjzI0ggRt*A8qnxPrz4)Y{;<(ph|1qfk>wI{AiYQl>n#cXN z;t-vt_qhuaw;@%3tKjGgdC~1?nQjShc5UCEf9FTrRaHgG>Qjy!iSo26Oom1xP>g;+ z6c*YBdQL@Wf@Y{D{ZwtLY2|Ad>`Clug zSU}Pg(cMp3m!HUY)~ENO{^5Ep^Lj2q5yKhUNKJOYLf#A>2!zH@1O!&ve~(|~WvSu6Z+(a6;2&vMScQW46{wtx)K+B|c;TimeI`CbCy@+}TJ$)#aU znYlak$_><@_QtaKMvLvH){BWtf}z)0fc=2~(ljdc^;cC~TlNM^J`_R6r}FY}J^J5U zaGJr&$sj})c~Marq4y-%|NbBKhQCteSLZs6o=IT87jJ(TePF_7%>P|yJ<#aAzVGOD z0o_k;hjsTaoG@Km1euqqr=r)v!T%7E9tYv@&;fk91Sm{6Vxg*=Ac<5!VOO}p7vo5wB6z3P%kB6|4(79 zcg^t*csqgR?XK7lbU)VH*?7^Wcxx!Vl0A~)qx0&=mz^K_)bcAQy;@XO@V@z z0n{+~5Ly@QbSNBM%J50!LLIs2OwtGfDW(66;r3Ye23M9z29?Itv?^wMyG%>^@$(Pv z?sWUIyg2MGyAtnP=y~tm*ObE9HkZ1SSHH<{#~zjZ?B)OWZ1M7kxs8?L`Csjt%TLvN zVI!yw&xo_ZL@C&6R*2XQX2a@={@81rUgmvg z!nK}N9J0)x4JaG=tx8k>sSk%CSfK6YT03K-W@Sn`WMS*7A9dyJNlWji&AxkN6hcWz z34;$P00JlL-l@|#M6W6>J#9%eX;FKBOaDr&2k$=N<&bl6OKu4ZmVB{r!?0@1aff|yL|-oK-f z(18V;!(MJ20{5w4pIh~h`!8#Iva~fU{)xTSq7ZAwWRud49Kjm@=vuwA2zw8$kgabJ zAvSU{OTd#`Rg4lQ@$Z$MC@r3Vg~oW`v(Y~%oKdX}pF5%j8Bo?iKfu3vQSOPVCQnLWp$lCCTTF?}GTlGhR*ZdhAeskQ8U z75I3E;RFP`Vtf2y=E%sD=;lh#%?r?J`>{4%bU3OaP8o`DB=1OG{R<~9b&idU*c9G9 zB;1jzPey_Wr_`d5#4e-F`hA0avWiimao-Et%*mw5?!vb7;#>boYp@C~j{S)DZ_Q+X zgFD9RTifkO=K5IndWH8yZ`#Vr+(L4n3OAT`$Rztn^TJ#2%1#+TthaO)1xep0eVDyF zgie_QUxuq*km`nO>o(&<#zn=9cgLJIHMc#xDpdUUXYtCD&hVH$XL#{$G>UVYg`p4+ z%(RdI+(ct*D}Z;6;!*&9i!jG1@!h~0b>3KRuVA7s?iPr^GJI9%=t|ma_F6xJnC!Zd z@mVHBejomf-=fBAEF2ZntneIUzw#tA;xF}80|dLuZsl_EqF4NbRjiy%)#wJzTebf0 zpr!5hhlW+*_>cwL5za@+q~W@CLOqSmc3WaPK|MAuW%uoYfbD;hdKTQfV` zonT=oSH?@_lF7j15s6BfDvuvgzgZ<+!yTv??8#CO02WmF;0I%JDbbYlLD=lb+U*9o zD^Mto+S5ZVCoK$s@B*TF@_rZ6u(`~^VA!?TEqsyRdI2vlajUZ`)zuaLteMpTmj_^Q zi%SXW5LJiG>KDI(^OvGhNnN$SZ%#6NEaOSuu7=kRzK_a#)T(rbY_Hy~H7l%DQ$3c{ zLl$e-v*fogsCnSYHr-wj4_;K=B2a7PFN>E|r$<(G=|U9Yh12t@Y(yhhIIw~ZOnUMP zenbfi31NA-=+OEZrx~HX7;q5v!-+*DyrFGSthSps+Rq*PY)^z>O2PHm2t~czI|uYF z2?|e6a@VT$kz=4lbWQ@-k4)sHa9ot;Cc;VWaVG~AE}-`4pyYL8*p(ZTM`@3F4-|&Z zwo)gFf)}smB52f5gkh4LB;Y1geAp#5Rd23D^NXnz-Y^u>-eg3`JsNc_~~1y^dkLn8qvqTL0JT;%KBmc8{$L zAEe$C*~qfE7F-EQK_rxDNR>cM-s{<+<=#SDL{Z`iEgM)A`ba;4_)U10#cT<-NQE$fPdkT z$E%B$lB6u}dm=3TG{B|3hymm)hx9yXL{-}G#|JNkr|jOW^JA#KA7V@j`!R!9Y0A?3 zwW#U`qmhB#r}M#As?1Uk5&Ja=H#d>=vYZ^dds;rTlP!!K+UxVN?`}GVI<9)wr*=s?R<6d*1EiL>dff)GuXrQbQvY(UP1Pzy!h} zdZ2N#wTV+7{K3p)D)ER86z1X7HyPUdp)<@TOETUVF2)1lhgN&a5 z`UJ(fTDdcWPmZvK87yny#D~N^_oBy6pt|arv=Q+EKdfodX^BH4pdsX;*$z2qg z7bq6=W?&0|%kzD^Cu4cDboTjZe{ytm;t`HMNfLp)Q^C^U`;82rXm?qmeQ zejin$DB%GDX|9uwA78dp&8{x@`?FNro2QJs2zNZsgM&GuZdu2VLJy%}uT#Khv#djV z)RmphVuV^;j-n%hFWi*wqD<`*rRTd z{s#I08L2>7advq`B$@L|0!=@NomqiY@;*c%%3A83FmdV}g7*Jr4s*LNrglPnT`6AE zf8&=se8Fg}w27@gbpLx6!Ue^-CtpzVj$`Z*SggIeZsI;vrB5mg%t&-;RpyrKy-?N zkY#)gh4aiGKTk}|@P}k@cJ;VoZZeVAI}#N-tHQ-;)Tfs22lvlm_nFU?0O6U8)>^Pj zX8R418oQra6!WRZ%Z_Yt+VaO$YW-Mo0|oG0ZxJPD^?ktOlm-?n-$tXV-0ciwxi!C+ z+|yMldMSm^J+Req1|G)SGns8CbNh>?Z=4Ly_X}zN|B}e8?KtK}o%VWXgCe{E&ln4f zsF7kzUiIOy0A>HT@Z)OYJFHs<|AWJ6pc%8795l zTm}zCYS=i;_^4XdR#*G4WUUWQf2o>Y_hwr|3o5vQ?cbj6ezpv{>uRwR{I?!laixKe zo_0s9qWAbs0XNzF8FTvT_h5!Gjx#?N*=?Zf{C(pbjGziI+*a- zNQ6vQ2L`DYr@+-AENA`}LsK)u#P*qdIA9N1G82WH`fWl41U#)r%Z0gj7zcdVdp`5 z`*@wZYf%ZX$4UsUghrh*sn-=zGTs1Cg#iNvw1zrpA}3}q5y1&)5CJp--o%Lj9df|p zX!;nGgum3W-F+lerF^o(Gk!FWhD!Z;wj|F>LP zSEtDQy)vi%xhu{-W|3``wC{;$T2bBBUslsde$a3}Bd}8zVhQaGsF(H0s^0aQthYXK zee^fs_S%s%zk6&g+6!FQc3XSjXR*d2)d96UOh2qjp0E~WL^3Xkt5?efe}$rDoA~l4 zCbV5XqrxD$F2Er`m>TRlbx? z5OjJG<(Ju=`ij1$-nLRCP$CEO*m`8yJ1VcP&WFNj}Pa?>thP9USE5b zCux}NBt{Op?;J$$W2ps=Fa0!UJB4`v9kcaurmPij|31JzOw{^&Zm4VOXO=okeg41n zn$=RZ}HpX=f&=Cv{pFnc!JD!Ui_uEr{A9ny46X%`WglDuMgec3Cci5?9tGu zx_+54d?p#lho61*1$-|j9@2HV1zV#bSrK}l!u$4$vVsyZKDf`0hFyPyprJjr!( z;JiH0D8c<)_*a3j`cQ^OeZc(Bx(Rv5v}-yLry{UYCd>WZI5_pKB;g4!=|4O?BksRg z;Wy&9#VVVSl{~TU+WA7`mXfHh`;Wm>CYo*u8uKAmE+ei@&s+F&myqJq=g50B7u2!K z4xMLDS<`S-yz!hKxwt#`U5cFb zaNYd^<09))a~Z%Yr-LatNY?quq$>%o@hUvi_=>?aUBNHxi`RihD#kZ0Z5{a2r7lYz z-)-mw7PWs+TtMBY=n6HpEs9<)NHzY1CzL1>^6cIR-L|o+%&4gkS(~klFN{25mo}^t zS9n^1d}O%4rs(4r%a2e^*;=yQUbT&}c-?>N!N0dMqU`EmmUR}w8=-N;MzSK6fCYUU z6-|UT=_0WiBe3&1!|gIkZCO%s|3i^yKP>jSGw~OQ{w{qU!2F2!0n)@@U#>FRIBR5K(zKqv=1MlT zuJ!bACRKMmIq#=ERzG&tX8ph2y`nPmS+dt;73Zd8`RliY;a2TlGg*_bJvPZ7^!L2& z+_LSQ{Pu=?{miL`dDc3MK^y5HQbI}gqbjKfgg#*;IV4Zu1fL}Qy8l(5IMYQethn!Z zOfO2{ZN<$Gcb{jv^$?-UrIu+u=?Z+&Ax2?^rC6Z%i7_~=Gu?^hV<%lCTxLgRx<`I3 zrDj@!;<0Fsaqu;-@#HZ3ZoT3K+5f$XQzHHP+C4q8JVrav@u6`7iEs_)hO+{jkO0?o@6>bX@W^M8&j2MS0;C5nPI!6j!svzy zcc9ZdfiU2db_(*vIua-Z7g6k!fRZ^zri1zk&wh@G1sH>XghI*zEM%XmfE%hX9vtE?4 zhVq6YiJW+T91=aRLq;fII6>7AEXDgnfd91D51-$&o}(!LYi@kc7#? z?!ux|(2~E@$w_buP|oBqfLTyhx**KD9i${8Kn^6}jGKiKBvbv{w{JXc-GF&s`{m40 z%R8zN+c!8rTjrN-DaJdhCL5nz7Pr;B%E+{*w>-2e%yV^DtFAi}GHeEOy7=|zwmX6V zSPA@yO@HMw3E?Q&i?#S|C`R<9)Les67xm925vqw5!$*?Iy z^{f4t>W0t9cROY;Z#FEpTFQgXs2iXnv)7sccYiI&0hlhJ`}Pz=KH&Rt!oJ(%TEYDP`T6Mi+GQc=gHureYV{#woszx{gm%kChEx zyl3R4sd871vty6b0m{nB;!Ub(K(#XVebyGg-^Mpn?KAt$XdA1{`Vwor2qWD6;itf$ ztv|n;FY<2Y{vfyc@CPl$XpYCTs@8kA$GHnP@8&t(^<3zO!LI4Iz{NOKK=;R~W^q7~eTYK=pqX2TBm7fA_P>|3{;t&m^ny+Ee)}C2-uS(XY*83WjI;3mJp8Y7 znp@DCGRIv)A=P7WF>jvvIPdm{k+i;l<}bOXEZz(e4{ z(>^5IX}S@|e|+&eIBX1X`4%6ieb4NtMd}K3#-?UyV0p-t(#&SRTTa70`9IfJV7;RJ zX(danH^?VlFfaG{STnn87TJtiKj&VW%o$;B)U#AUq&_w28vLA7I&WMsDwG7gzP?ju zmyES_@lE)sCjjns)ms!1ZkLwloJR5d8T`bfvwk{z?M=ScDz~YB_fSY-zV>Lm*PTOO z4Zv@K!ODg39ee^@1~9lunz`eo|V78aKP?SwPW9xa=lZ0i_V;8(r9X5Y|r}5v1s|mqt_=ik9ALf zY?{uld%#MspQo?L&5($_HseQae{O334$@jw)?(#ouk=A(Z2h+Un}6P4J0f-d!x80K zm>x(x?!+MxTy{{(&7Zw*n17T9_vn77QOdryZY9aceMc|c4}xG|iQf>TJziWpXm&Du zvjwv1KyMc9nT3QM1XsL&Y_M{~H-9TT6;&@j4H#d%?MnOi19jy0&tD^~+*iDJUt>CS z5uc7-K7+SX+ltn%^ky@h;;kDVjzL{T6GN93EigmVcb64=~BDVi{^p zJZDa9Y7^Pts^2bh;Xi={jYk3@2}>!NSkeI@>C427p6iA$BqTlm0Y^0+egb=C!kP#P z-O4ls8HR5Y5(xrupW^sYg6jyCZNx{R8sS@0NGFU}k01lg4cHPNz3@*09Qs8ikhg?5 zuSO``kebY4#ERH!AKnD0bXh2J5D+-1Dxmj54)=iwHz)cW=;dTV`?eq7%*P!rfac~z zc6ck}h4>v1U1c-`-XyC7Dx)ux35c$}N09nD7YSLww}jU^l=Kx-fG(z#a)1b?)X+Gb zhhgtNLc&h6xE02>I|dLK8@`x03Li*F(!fgrHVFnW59-Br;Nkg><4nYbHKKXA;QvU( z75#wS(d}fi_Dqh}Pxw)ThqLG=7!lt!Y^}Nf9Upl3VmY(4(ZoQHL*Ww{g&|@&$-JS} zx@c~xXVsw3>YkWhe(3GAIB6P086S7lK4q!i&Z=1ih4SZyj7v|xM@-H>~G_>|+IBr}ET7c|k zRfxH+>|rQW-|jEE&$#0~GWF+9d~o$8?G4C5Og9V-1=s(+arqJ6_(<55unXlz6QO97 z;4?ip-CX&$3(wmn_va4&?-9NeEAG8X(Nz|&U#8c67T@TxW@jMqj5etDt(=m6|S=Tq!$Ebh0qTr#u~G+dQC*W^W{Q-I%TEZtEeE z?Th#CNaUmy)^Ik(!co25^e%b8B{u=}p^p&35$kIt@Lh-Q5b0rE2xjK4~%bjcmu0pu5%YQ8hAE8`C_daw(@c zPaX%6!QQU2+b_GiR31$nRnSK~a=N^WzjkbxVYm+Wdy_pGR6_n?L}Swzr6b3%_FjYX zEU+1bhlk(RE+aiBf4zF=V7nbg>drxFHbpJdgdW6vmsD8Di>ST3M>hiHa5iqXtNi4X zVK!+_|J8a=)@EwV|(p)K}?dH+boeJu1>BqPb#Re!_ZY|g)5A5s~t)8S^ug2@xiElN)ir@WJJ=+ z9Yv7Ss`E-3a3Hyee^iVkEXkmF^C)0ctIvt$bKA!{LvBmWIHy#x`AV&uITWEA2Gr}9 zcS_E)b90-+#aj!O4a;==Am5kUI=R;RVz3=KCL; z*=`#%mp{mF3AI<^du+cIR&Ws1p9zw~x-#;(&H07*>`V5Ph}a4KS~zw(Vq?3#g(A7^h~w6(Mf|sRi`J|TZmlvreGJlE zcrOeuwnbS5e-8-$%c9RcT(TEWJT_NpdtC|vG5}gqtWt! z$;5e;r!RK+aoyvo2Ttzc#+}fWM8Yx>-_tdoVbPf!Du57ab|b;rd#K%rzva>KSM}M( zE%(dMo|Q2U z*01=j-($90ZDLC=)8}fZb!RyY5=pU_9UkA6!}}E#*LD`R1!|>>|6_S49DN{TU*sb> zkH=OO_0!|@^z}=-Ro%b+g@Vosb0N<5)}0^sp>Ko+K(J0|BOFhb6v|^EZ0vKRO0LH+ z)SkYNRYv`2(L;Dc}e^Z)qs>2lBz$vP4OdrrVTIhNO%XemVCl(0X~ftHCd7NT+q z+L*})Ku%5orG&zxVT+Iu zkq{dTe=t`puaXFb!yc&zuo!zzTnc0hFo>`RTg2E`=h7hM*zK)=4@JWFnBa@uukWy= zb%0Y15&zyJU;{z|35Qsu@Mw1eQpH4gQA~j>+hH!!jBnNx!b^1E2~uG&DWWIBGL$Sp z1#FtwCk^rOV7&eZ-bbfoxEn=)!jA$XWiyvil6i4-(X{rIy_T1&(?m+hs;Hst8{63d zo8?(1t1x(}J=kl|FZ7(1qm*4N66g{6Bu-!z&^dT8VX1i^SGqc!iG6C_6J^qxTPJp$ zhZVVHXDnT5Px;Kg!UZZKsx(vGZ;n?r^EQh=Iv|?fUMX+=@&5fPjbN|*Ij8uCzof8R zAV;NdZss^TiMjUe+n*o*bda9T$P8JIrVnKe*RWcjLv7dotQAaLoZWry&;R+GI%=wB z5j^IuHF?y%etpQTf&G$KxpLJHna^0lsObiDwHXvleaV5A$ zkq<}#$k8C@5ga-k4!4t^$>^Krn`nDYQ0EQTMcp3$>4r5LbMX%Nwf|4lwR$UX4AL&s zKO#N?A&{VVqs`IXk3a6V)0At?wQ-(4@$C)f$b-$n^WrtD>kWTuD>d&nSeE;U6|z%h z@hR_utEc1r%cAQ?T-{c6zj>Iuo$+G|v+C`jJ>eJZh3PTKomLl2Pgg&>PqJ05BIBdQ z;k-WQMw4Gee~(Gxc)!o)_zJgR%fn1rLvFgPas(;i4Y5E6a{A(ji=vl_gOakh0KPS0 zVIn|KK<}VG!j1xr73P%BP-LV>&1twd`4R)X1MC$|M&Zz^D-U^uMeQ-r6Oe!kEb^0n zf-_bJa;m8lrr!^lW`RBPh31bA)7?gUyi;e55Z?i37&MvkfcTJRF}{Xd2jk` zrMrv>4B(km^RDqtl|1Rng3P)(Vp5GwF&MkJKO8<8B_SD$Y-P1E9+j9uz~{VUp5=vV z57q`{@Mm+IWH*EuV~|9wXbh3Yt8=Hk={V#-)`jJTD9F+ z1>TF{oXxjc7bodNVFikBUQ?n1MPKPrC!`JW)bgZRdW=GmH+^;H4${i&c# zC1?0oX}p-rP^c~DpT|^?z!N5HAM8O3WT!*tlqH;Sv zZq&Rs*vV<4D^HNXGPKyY0<_tS4PHOH=DkH(u%UUdtn6fBa^|ygL}ZhR zzg6!d zIV5Qu=On`3gaT@jpg=W&s0Lia6BUy^FMo)1;B3}NIA<)?5+@o;fMi!hW&0(S^)2WJLKm*ZS$Y=nRWQC~rVlS}6~QSuyu@ElZ| z-GKcww{kpyD-k3R1@JFA9R5M!;g4!9Gly4$2!QK8#6Bz8^)Eav6+{qRt$XbSdOI}I zO9c_on7ebx@&W>;lIO_JTKD7OITA+7YQv)u$YbX}kSrx3j|CzCZb?osGXumK03;CL z)Bqq1&b%=CmVeu=7u}*Eo1!89Gp(g=csi55UB_GvzofY!7<7wt3b%7Xhy|-DISyeT z+r(vnI5ulB4d5`o6+YduuWg1P;fd?5n(gr<=3bcnd|K7Ep;S>jptl-iVgnYv8E2}^ zyH?oux9Ve}cTX41^^61*WiQ7Ru0F)vnpUi-IeQj9b=|6tQD84WtX-kWYo?tpE>@^I zUix-aICv~tImfcg*QA%9pN}>iD{RSTc#`R~hih$Pz1y2jzZ?RBtIon&)>UrATNFdQc5Q41POMcg7RN3g4fqnZR>;l zD#d*vdHWALWF?ciayZ}AHe{;nG&UvTt`9fzU}ehXBTlA*- z_S#JG=IWQ+EtZs|IqORw$shDnCe+!S zIRFItS6!$hzl=)WbS3>m6aOtmFm$PF6A$=cb#2hoSr)Gyz@2S$5fN$C%@Vxxc!2E)K&G(t7CbxY|>Y z)shV#X8=6-=f5`NZD76EoRFI_k+uA)FCF*3LagE#Y^#@pv`qkziOfyzic*ZYCmX`% z-&UEa431IVfJg26=4QC(!H@~RkdTTrDDC?~1HrYpZX8^zZR6l6146SpjEDBstO7W& ze)U*O(~qr5U&oM;tGh3|jY^ z9p-4JW&rE^Z?pmh0lSC8vh8*rX&fS4eP5$HrEcf;8;bfd*9w_ymi5b)?jPr2$z%eK z&VR2dV}WT)Cp6+E3?xt-jR*>vm&;xNZNL$x5Mkj81-&&&@p>{lFy3#3!PspFj*-Sx zs_$84dQzWC*iegw&>jcK3@Y@VQ0}8px$JpD1qh88PAZ2&t8&(SY|KP&rdsL1a#_($ zgH*A6XH2xGrpzrUnVjYkmQ3G$#npdhq)fEOT8&(-Y1!Yh*&<{i#)nl8m*!iEADj;B zkF32_%PtgI?1t;s^q7iq%a;*5@4T|p_mYH?c}CS<%!qETmWgivVsCBSwPEFseDAhd zG_YN61wE&Da5jJ7T-zOdoEh1?=vMY>LH5>*cCGOgXra5;kB#%Mm+%?1j@w54Xq`B;3effRLJ5YH^#~+5T62M>!=f@Y{IzN=B zK36lkHf^H4k}JN5rw@<_FV|4cq^vKNsPbaDad(%!Cev zH%6htn=onq$Dm*hqVQN=2QVO>|`Mz${ z3q`~pMM%Qr2Z@G&=+E0bXNL~b4hh6Ro=An8FvR%6_i%9|Bo)v^6do@GxXecr?S#-|2Vk?D=YWMVS^&YZ_%T9&pmQD4 z>;i-=exPk}9N>gW8DvoX>v3|fBq6wxka0wug6=0SPzN|*5g<>KLgJ}=4ASy$8WvbX z;u{_tux(J}+8gOW#D)VoAsI#0N8lyk`;>af_Mv5~F*g{6Y$ zxpPN25^y+AZB8IQ@`Q$|q|mtbe!Z!G?@&Ihw60hU*WT~zR@Gj8Y+5~bPL;9nJw0nJ zDW6?|jrQ~@e+Z6cmk{>LioNQK-Ej0Xw_??AcHVtl*fxI1>iFhIOWC2^K~KikTJM%) z{ci`C$KCeno#FGpJt{P;d>9@Zt%EB!8>%bJpN?+jE{}I~w+!U=@oO!ch_lI9^|dd> zYh#w%D=W{{u?5$xRr^HcSX#d+(=L;F_^W&HXrzSQq6|l?w*Zyn-lPIsn2Q^W*jc1g z5ul@Klz<tVxdnN-RKFVoroqG3AuGG%JCpealq~s|M;4u!bIYn)OF>Q(TafhF*kpuM zufMe-CKcVV=*r)Us& z?Qol3UD2tsA2ZMA>Q*R`1PrC-E%o?Jm!p%3inGv%h$||Q=TIWaMt@;;Oj{>?dk^e!|KdJaT`aV0xCX`h@mY|m%9jAclHnGJ|LqW@s+)4?4EUi7}3`w+xx;jSp z+4psILBBjTt!nNU41SF1EWHpKX~^=GIPC7`|l6&Ey?us^xe_X zr(G6N4#yDWb7&f-@#h|U1YP4f65YC=qebN@$R!smf$>qdaH^sC{~XmDZO5OPNc1HV zIYIZ@)m2d8>2kW-}|!a21jE6IpP36IV$BZb~JE^a^oB8WPa3$p6));fGBOFaZu zCHRW_WTJ`v>wDzimaZ)cfW*~t_4nLPQti8(@Ufoq8{>D`^@g2wEiq2)UPh2W zR;HRi(cV>Yx!>P;=$DEyobl7kY9_+I*nBkK3O}oAlLedMzB!HAmBFQ3KnQ1Ns>32@ z&ZAl*#Itg`X8GaAlG^oT_tkN_y87Ij+uXUDrTJ0q6)D@l7i||#+iu^O+pZT^ct2RS z+NH-4Q7#q*!Qt+>ZcDNIhC^(@yN4*w2czv6AI?}`E&vQqQ9tm?(-;hfh3n&M`@-8d zH(M-XS}yIrq~2bcla$jUb-@*c-QE88ONNJO-FT*BZ9y?aN;pe#K}H9+1U`M#xH)xxLMU3Lv&SBi#g_cF&ww#71T^(8B*!7Cq%*QcP>kiBb<1;-1(*`Cvo zx0ec+^wj-{6Gqs>mC?JF`>E48FAM81y zI6zD~R&oxFL?a?#3BnWlKqP(QSk^@(67Fh<9nhixHG!(3%1KQSLhu397=hGRJ9iAB zpJi|ycMdJd9mYeD6Ncj{yi`X&;YvxB5lSf8Kwm#A{G5ikUT9O*vp6Ti42>8W;^R{& zbl0L2;w>hkF*LSqZ$3hy*O(BF4D%0uVU9!gM;;~sFi4|N==*B`73&wg*E zuJLd#KAvHA#(Uf;WXegoEJ+NmoUl^s?ZD#+Jea*aTs)HSQK7#Z_@7?&56ZNXf3tAb zpM>adUM;*s*_r`-)Y|)#U_XVZ{JWy!t5X0ajSUZPfgEeylxxFf`?Yu4YxEe=m9@B& z1xbmy7ZslN_4M4-o*uWvLWKKO6^qiRuC7j2T}vZrX!Xqt_qn*hM>e2u67F|B;`ci{ zc5BYm@`;qKmX5aPy@EE5XNAUDp9Ly-Xx}MKz=i_$)(J>%Y=i&>@#y}~3mjq9 zy3Ha=TqS}M2yOu~imMR;*@I9)#3%DmkAt7ji*E?EJe0kpoesasb(H7g+kV-J^X!`&Z0ZnpNf5LtjJ|AC_nva3jZ+p5w2DUD?-2(~oX` zZt%PiuGxzE%^2)nC%y0Yz0*KUHkh|K!Fn+~oXp*bxrWx^2*V*kn~fkko$T+09@Jvo zZPn>okD{B?-ViL8yH%KLAOPga$fIc7&TwYO7bkdxL>EE`!Oh51o8FwD7KcO$yfOl^ zn3afReovNWWx(Xuaf;rM5A2%N)zr`z9glFAI6DkiTzCwH@61g5QMLWM7W&g>ffhDM z@!V-NglzpJ4!T2nSRU^loSI_uaq8XD=0@}CB6PY*UaImq{XR7}H+Lv1ZVAQ*{^o`9 z$Iebg2qP1@@8!V5d)@le%m4Y51?Nm?+J>m+#3= zL}GEAv1XQqH%C>-$=1 znQ&t49nvifPYjsA>9qWx0tJJ>HR>lOO`H|C21rPB(IS zI1WGRy6;HN0MB&cl23)jV+4}J&>Y4k@D-&*;tWM{;uC=oK!9c4-rJs&Uym|+N;79i z+kJ_7o@rk2-JF(Zhshs|TK?~=20xbjyrX)EuX|l3OR7g}R<}Tr`F4VJwrYKHcgy7= zm_<@w@ON@YTP8iCQ7H47v&V0|?$^D1)K`8+Yn1Ht@e8(Y#CCIx$pJV3)>F$l4c`SS zvFy~z!n>}ccSgXx^RYE0WZ>36?p3Q?G5H$H&f**A#QzjB=V#{@k#p-6w(Gor;0SN` zj408J>s$E!`y7Apf2qntT@&7W^YfiK;=zR_8*TRqME0Epk}ieTs?#+^NxI&85Cw#$ zWMyUI6{@eRnPakrl4U<;CHflB&Srb80?y6@L!^bdox|8P^xGP+emC|dP%E2D`?sVj z0MJM&zC&;*X8JLf^W6XHoj7BluIv2#_T`spXNsav3%)rYd-97rWh=8~G-STbUF)|E zX=3JiP5xFl^DtCA`;CXPQ+p{jr6U1#w*tFN-41m+3yDz4pn;UqAs{>>;c*BXkAI(& z6!5?XK0w6E@KA&#>^adpv~_!Xpu8e5oDlSv5KOFUMng0qeZo-yW1oAd`4d4vq6j)| zc$flk@rekZ?7= z+yf}TN4u3C?N%@+v@R+&Qyw|NVxEcs$FttGgOWrYf)tXBlsW*EK-kF{HmF*>3D$bz9r+$RU580sPV~2v;F+^w7A>C!dy7 z;u;4B2Wjg)P)z!$2T{`e9!9{_U_KL+_B{o{(qC`8+&)}LCQqxxMemO89GmJd5H4E< z-mX98{iz`nCA@f9bcL;1&R^JC78L>A!~7}AYg~;L!bM|N^@mZv&G1L5xVHx7s$)=qx@%lXNGfHTDrSu z2i3mWYRw47pYiGL$On>A$TCE!fA$y5W)>dW1WoTR(#T|-&AN~6{CdMwfcQ?9b=0~3 z&+~?HV8hP!cRSTDrE5({@;_{azrOj9c_%;S-$&7hY|dJV^Ol)O%Zc%X%&VHxv}@Th z4fB`spOSbxXH>~v{~I0oQd_TEKYdDba;A?ZvpC8hd~f^vbWeRVrKeEaYyL6&gSSh4 zl`nb3+SK0iee&|xg{*e}5dV$2;IG=t*p~8{-jT9}e#f#numxz8J@`7Z_SCy?u%PY7 zkA5G^LWaHN2VP9Le*UbZ^TC>HIq%fM^(AIi@IqWT;*83NzGIeUngz#oFLg3%Fyw+$*r0PLA+Y_6!2u=&a|>J!%Dxv}=x z_JYCNg^?4bVsw(O^O*s{S4UoufeHRb2=Bi4qZzlU9m&IB-N11_6U z?n`Uh^EujJC@+nBZV8=2h>UDaU!D;^)U{ThJ+LU+!weYGgug{g{&&}=y5SKvr0EBE zi=dHcaF_YAnVNSkC{d%Ua=s{19cysUy~&o?cIP0&q@o5hc*klXHn zAi!d(=?Aj4%0^l&`ioj$p9|nv;fuiTbdSj90-+k3-GO*p`REKUS9{k|Msd_K!!K*L zMv1R;omE$SiV-gMaB*a$35HmsBj1;8aG2)xUb%^pq#^a`j27xmX zmMg5{2y(~#cTzL+HxuEQL)m_!W%PMj0TI&*-Z;~lrZKobh* zjsvT;ib=MBq-kViYhL@IP#Kh6aY>2I`*xZElwpaVNRT;nbi?5uVa3@9;u^LZyaad< zw|U8?SYq2Uw_iw%2KNg##b=x?DlhRXuoS$A2~3bNP1)kWY5;HmgD!v_(_6?1%E5~E z-HWe#C;H7d&;*(pG$BechJtLskj#COT^)|OtwABVlPx3sq;TOZnc zip5zemN59$H~Ft5{TpSHI}=<&N$LL(eFs0&69uG>KA4ji(zoo=ZcYzyii81I3j~?4 zKf0eM8p_GeX3IShx|cafnY{{JXpyTTDyL@R16Iysf~qM12d6n&sdr+j781g1ANYjH zs~}tMXqgP|UFy0bl|iwroZYJF4Nkr|vNYy8x*9gR3cyj__>d|4HNW`FYkHR_jCQBo zkMnc2YYso@eRFmCS$x$rbbponsE?WN-VN)`R$TteB+fOiUm>{B$FkhZ%Xj_vm-73q zTT32hpKwiqPOc}(J_`Sge&0V@?9(*4<<86=rth?W{oHS*sx?h^vk&rmH+Q_Kkt~+$ z+w?e^VWp~EC`V26n{)}7pCUqm@e}SIR+JTvyEej=^hw*}?OUvW4D-OkG}>t|s8533X%370E*0-G?ONa5k02@r_>G zA9`dBCL6=5LPqv5hvnYRUjPuHEEiRK8y@p72NVwlMQ-6&XYoO$)<8#0xAOY_IaKR~ z4%N4n{4<}9!6>|afg&b#=+Bl4b!J(7>7R>joOw_-G&1y+8fDT1x|>Sxbq--hUCr)( z{ALAyJr}Tjo$>}amjM{JF#nG9{Oi`>0h}bpKLogsZ+rC3G1xcQc8qP10GY{ThV*qh z%GH*hcfjM_iRMZ9dJ1f%Nq`Mo-k3NCIOV&S)k7xMs~DNIt)1#+ScuUDAT*;xko8jI zoRl}nV~H4(9Y_k#c+=c=wy>mxF$Sz`+{l7t&1?{UtbKIFKxp}cc1Df&;@Fr5nfsi` z@TM_@(yFPjA_8Sx5x}Ht@aykk7ME>3(O4U$E3Hxf(b-<6W`;cHRx`N<5ifWDDSM%v zeEN=?Q)i|rhXR#iXhA{Wb5gc&&AX)11UI~ysh{_w9@ir6moKolkPu*tPPJ4bMgE@oAfd zypbiz8hTI-7xqP-o%Y#bk7qa|m~3vO!=y>CB00ZeAq@g6F8wNUVn;o_ivuSnGfRnO z0btDoNp-s$E)f!8Q8I(_Cy=ZW;?HBi+?4Fg0Kn#goq%DMlF!0Wm$Q~@YTirZ2s?oY zQRL&CK2nLoslS|7w;P8cj$c>9tf;9dB37v?e^#-OFm&(#>0Ys#AJV6`eTxfXEPqAk zvb~LNV1@-PlzLg_|JpjzpAp#Ay&zyZ&BIj|Vp(x%wWv{W_Yap7Fb8sytJfkdFd-YB zL6h5qror#})h=0#EEXAk=RY2aUtd`^Qt|((H?+bV?@!4v^8cDrn?oqeN+>MVx78r9 zz`%+EBPTXURiP1fVYRlbXldT-DXq}DO9A^X>@#>!Yy?Co_nA7?XlO>;-kcCA2p5Mo z>#0XUc>kY-9}C*2MK! zIiy!iKfQrjF(7_7rys1 zrT}H$!6wbmA3c{}N5WBsG6{ZuP3rW&$mPX5I?E8USJpmHX}3206I~C}t>o zx$Jh`>VFwvIzZ89!dLA&tnGFq~y7B@A;0JG83y4EB6Z}QO5TRFIw|VPv z=mO$|1uTaI9vB^nXSTpI9Kk6f-FYUwX|dc@xX5d}oY^qlN4~C}-pR)go2KcWjx2RP zW_fA*Ogd!Evo2Rv4ORV7%GzF4XI7~*^69IayMJKj>f-)q>B}Pf7vEVyKm43R2*ZS4 z&bVKNhmKu()A6lYU(>ni;_uFPs|2#v`b$RE6HIaebj7jj;XR6D2&e}<>Uz1lkhMF~ zJu<(Far1Adt>$etJeaJ`b=zs~j5n$(YRjLkrY1-3SDGuX^f+fxGZffU?&c;Co&IG` zZ@?q*d#~b1 zN8ayS$M4OzeN#=q-OJ5rcZ+h3?RDAx^9PBr%jH4Hl6kLRM`@fbC^8t!r<33UP;xvt z&#lZn4+5eWP3P=h!RzF$h(=<9h7O`xH5$PJ(-_DgsiqU4vvmUQ+XL`g-aDl!g50{0 zM$^7LAqu+{xr_7G5T8R`ERyu^GRfRwcmIRnfPX?)xyo zQi7*_gif=w)h}w#gER;c8{nCx5{s`i1Akr>`fB|}qnnb08PGRr)ejTRnCt!BwU7<{ zPDa&NqVeyMY(1RIt*0{AKLq^VT&Qo1){fMM98&kf!h#~_$A@H^Uw%a4i{@fn?QJ$^ zVL<`n$JmA^JQSS-Gcs!6c&XA2CCX^c#tgsBFOUtxhOQrYAv>Fwthah0sFnsz2Owy= zwj1iEhHQ3chIF@=V1=n1ztZONVYXKTndYI**ZW5w6q|q7`tYKhSP03QDCkGfcSD8O zAtl+$wM}5uER@eNxDIn0VzDZRNQY!oQ#)P(K|ehQ6Jrm)0ovHuzbLS3z}rCwk#~uz z$_ESF>o9KPXG_`7%}tP&rR+7-kl<=Yb0Wy7Hky%|gdOYI@Ir^JKYxDyynk-Eq_EI) zd%e)UDGrCl>ge0McK0May>TwOeWPrv1HV-g%&4f^QVAa0U)fo365K0kqs*#ND1UFJ zx3{-DyX@bJoa_PxIwFWD@b;%Oxv`MzJO76w-f${BIX%XfCiB8UGp zYpXBK56=RO%Ix%E(@%qZ$J7?1jD|-mJjSaJ0tQfuxg@p4tG>?I{j;pjs1OGEv$6w8 z*XqNZqKa>PO}hzgXK8*hvUL$PW?D?ILo)`hrKZKgUx26 zji1HAf;t2QP|+|BgQw1!Nj8<|Y}|mKI0g&O)&~bpod5<;^Kps}>NF|95Lx^6o;a9~ z5#o1lzb-~_rtpz%Mb8PIL4<;)SMkbNmwdK2)z=qT`lm%%BN>r=)075~ULZ~Hkv_O%U{nRP(SDLm3M@0%C z*NDCV138Kg#6bDqVIi!Bu4U(}N4SM+K!_P!(QJrb0$7ZA0qhC46HKSUP$&EH1x#Ws zJliT9ZhUg?^>M)iAZMxI)fb?ezM`aw$Snt|2I-i?X({)uHmssp#zVdW+;=YYYY-f6?Ge0Ihq?W!p^r*gFTqiO?JCsu?)fATKZ1 z<@(3b5W=5{qtZc!eBs`L6BG{FpK1|mF%AF?jH21A zbZE@ezVvY*gZx1Nad=;<2pv!Z9j5YIX}%Vqd7sj5n8 z^yk*A98hykY`lZ2Q4TvA9P$KCokWf61U7aJNZ)ZIFgmud)Dh2bZcE~T;{HJmTPU!= z`oP((ie?xE@9Z~>%nFaD494evR|_6q9m28ce*9!f2av*AD|@01OjH0fWhrPiIBFx= z-#Y!>e}q9*N%t9{wmDgyIY+z5#h1Q(wDp}Geau53g7+UHm12g4ZiyT2;_>DDxh|!A z@~TUA{i2DA)u=nx4Imz;HU9x_G2X;dZpS%L@vXTC*BQ-Q6(_`IT8g4~gQ#N5N8v zQCW=lnE!SoF*bt?fNE$452g-$C4K}hmmS)iWOovtP=Jkq<2Fk{sZFasD*=cV8b}Zx z0@?ZsqS+9^hPWqqf zGu^r>wEepG!EnyU|CJBYY4l|C3({oFFD-o~8a&jk2IVqyI8p}XKljh|4q~{oQ7_Hk zzKD&D&B(||cdN83H2d5%ULDkV13}Isw&}N~cFXT=96evTm?~gq=B9s>=iHwdXRf@@ zt^So>^@EF9%hm2Qe7CT4En+8W|FG)Z_wnp^K?`aSP}n&>{JF>HL|@o@FoG>i!y4+a zl;952W@p$B-_78{F^{{i&SYohbu3(u!h9B5}+(qshYY4RFzag1#`X& z=Laa`8II*in?FH(*7h^ZI|12~PWd#7qSu3f*?qq`IoV;Cj)VihmvoBLjenqcemYg_H9{jIf%B~AqdHYQl9hlf;Yq)L z^AmC*sV zq^U>xIfp1_JV+F`nW$6w=>y_yhFB=rUp=(^iZj9+qjUb|%crkwb)38~(rEklXHlUX zndxO>&u4-B7+!kenFb+21|b3mPz2k}It06}rDJA`2qMM-v8;K5lf58;#VhqtGbP64 zlPChfSd_SgZpdhJCgRuBYlCh$dl}&-&nl>M?Gw339T@qp&u<^q_ccijtbcWd z_EbPj%=IQfMf;F$r1p7kTWJ5-Y5-jU_D^US2~rS`R;8=!_^WnQs;MeqtE(KJtJ;yk zZ%YgZbgC6qpA2Iu2*+h6L&4KBDHW-Ex~B_Xp)y-r`}=MDs^0evDjqh$OcwWk{`W5C zla=4v`~bG>vboddOyr1a++=r_?`+@N1iUtudL-0w=-U<+{Dv@B|5CA&#_v|S0|hhs zrg1#R(Zuz5MbQ4_i-K18ZXhXU-oIKgyWmA^OWGePI{5EfG9`_F%=j+R9EXiFnFFl< zB?!C)%np|fJ!F2S_cx$@9P_zFgqlIgX3Lr2n-gHop2~LvF(K>q*dGy^K=o)()yBGI z3{fq>+K5TVK~Egkbr&pz=IKV=vcNu#pk^)hBnJ(c?o5tWFk6iL2Uitr{FWQsD(Sj1 z)IVyo@g2fx%J{|Pij7PQh9Bc%p7vB@-Q%K9%-+0>Mp+`T+Hc*hbyKM14vNfnEt{1^2**$%G8=U(@Hr8{<)u06El538ko{JEC9 zF}d*ZUy0-};2sT^Tk8)hF=4MHmb%3i-D%>r_up0HYh?rU=!80urAYWWu zrZBx{62UNu4`GaKbh`gEK^di1 z%t0+y#qTgW7n}EzclVEBBsm{@3I>gnfMl@EGZ@{{G%}TjpJ6vcv&c9u4eB&HQ4bv`V)~yTWPp8_9#WYg@NDCo- z1(?PUs#8={%}Jsln)2P8ic)c_u}|aGQ9XR>t^gD?T|Q!-yn1j?m7@N$ygIABZ*Fyb zTvSZ%F{F8c#Ay^VaRh!|VPTnPXNF%%pJrf}iJO|LDiTPc8W^)Poi?QubN;?L?60SX z(7;g3J(fDq8%yoT7#*T0DqB|f=vA-V3#~TS0G1Y>Jlmga02cMC(+NoW;A5@h!hdUs zT=m$QZ}dznzf-lYzz0Jl5}f&mHe)QZR>CE+RKO#%@YwFsh)08u)Ecz1`rMhf`J>yn z7F4$E)t62w)U>K3^EOD|{qH(Nsw;*zOsdjh7#6m^%kFNSet^f15)Oerl|7+UU$Prc zu@Hy;|1E;-btIq}ZB1$+6Bh=o4SS7d3IfyFNVq~t)j{y;IIl6{4y9~Bfb^1Y6E6ik+80jfq?*M4{uk1PSIxF!DfA57UQuIezUto zL4k1?dWe#v6B7#y5aVN}&3$ptvwN(Qi_5LZ_a)A4Rr~h(Izl%q@Y3AY->#At|NHCh z%JKmDuKi`3dou$?vvEm!?*m3*4dzX1b55)6mWOoS@oT5Q*KOXvoc_{S6b_60)dT$a zNua5!R8CsdG+I>kf|$d|&#I=X=x^5mfW~<4Of)ifY8ip+_QD|y9HUKP_EtlOJsbio z6;*?0zMT?gHrH%+P?pKs>af`yfzX7($an@-QXvoa%>ZCZP_L$O+?o|TBnB)K#*zO* z$#NKRL+k}0Yq1eL#I87|*?)N*SzV2+JX0&^K%OsMV79ImXMO97{gS)C=Bt$IkKI2< zq>T?KJ!|p#l9z7X6~7fAtaj*8qu#Gu?r+>)#~OB@5geHS+^h;h=uW5`_c&tw#H0#g&4f!Sv^^TcwzQ$qolj>m!O~P?``bp zCp3X4g7sp~J@{Sc?G>T65Cpq|gG-5;vPl}2b{FL+a1BI;)*>ainSS6v_3iH+_$-xOTnJ82thk^$aH@(2hlf91atz)-PotG2)pm4%myC3U9m|2> zKrC-_AWm@%_K^HAqvIK)i}4}5@geZ4WOl35pbdS;y-&eCjZX!MN0b&h`Hb2=~n|m(Dt+VK<_8` z^(}mdnb9KBkV>Psly+iOMtB*&h8ap%tJb>oSxkSd)v$baF8rsKw?#J zJNw8Y&=&<9(*z6KakS_wF`?BD$u?j5gJ}xD99fQio@>}KTja&av=9;?V)7zS>6WNX zI>!h0ytCdsX0sU&60}1fpZXM6>|PyRb+zhmCz0rtv-7J91cNb* zb=8h){H*SIceah(F&^kcf1LeYF)NvQkfA#6E|poi@NJ~A_jB~g?uTi@G-8JRH04+O zJC%zUNx!ky$)ASplmn;ig$oOV|2bcn;zRVcGIa{Bp-^76J4H7NsL-ZAzcjx36xD{s zNJu_+7N;g^P(<%M)8dv@j&}Nze0}3^iAr&B zgIoCVpvsbqos*3h5~Ybp_b?KL2sTo!DhvvE_C_7Nz}3jqO-;>%u{um^S?pPkn;|`G zk^*Mc7z@GzmO&sqgqabPYAEW8szD3&d%xxnS-E}Bm*)o#y6+x#_gt)BfZ$AqdeAsr zs~J$DvGem|bnUn(-6M7N28`mc9Zp3d=3Jkqe^00}Jn!f<#pAM6118eCB|2YS4uHwk z#@&mJE@dMXvmuDt)aY7k{GUv%;wICvxm8u@|LN zqyBaYUOJN5wK@!2IEe0C_&(AY%@_&pziVGal&84meLM=(qMw)`MA-e*xm6E;e{{BE zeuQ1^8Qindxy^%oQbK}xLaP+*5x>r=Zux7HvyeI4Xfc|Wr4DtH+2OJ8jx*1@okvW= z+Q`N-z${`|5AYk|bKxGOQ7GM(}yZcpVWa1%; z;iL-cDB(U=i}!V;40e93lcTGWL3a=2>ylctzm3$52NGqk8D0ntutu^B@B#-(hk}Z! zg^V|V0Gk2rMu;hR27@9H?h#^m>g$^+&7?BuzN13nqmosJR2M-&lB)L1DI!=8!teWJG%aI)H*MxLMX7Czj7#D?WdiD zuh7!(Jsp9EzeoP(I3dX0;yIlUwz8i>aCgRsvz$O2O#h~fL~Fo$U%dW_+?P83;6yId zLFwL(3EgtXQ#)&40)88f$7t7hRnJ&Fi+s2xzppYRn(%LT)=WTuDp?)3VbsGwbR=ss9z&9$BX6{}v~@F-)S z#mjl=`Pb_BYnj_}hEGf?yZn|WzSQ0Rnxf;iAn3o8wUjQ5m}U7HP}n*4awIJFgj`Xf zEywPkzU^^|ji1gCevm=)@`|`k5HB0W2MCe^I}ccynlD+5rq}ESc%V2QeXCvc|MX=- zCbyI(FuKkzL{CJ<>}!erlI6a_k{wCU+Mw6Spw3Bl9hoLCt&I)~1xezWz7LzE##q|@ ziAIx2au2&F&4%M-g?4-cBe@*>I!CwH=9!WR_V1tYJ@dmhuG>Aw@Qh&Y_rKgGdexI7 zt1#3nPUIZY)MCxF&91<#)zhc@Sdg^{v_1w>feR9uy2s7xmPLU953g^XzZN9m`fDx1 zDv}u)fMJC;ZNPE%={ zCox3lSKoyDgzZWVCrORn^9iJl?7b+H5&MQ(Z+}!7STI?A^o{R@oX`K}q1L%Se zUM7K-DgY3bH8nM`ET76%%}e@9EW1CjP%(QUwLTS|`W9W%F`rfgWzv&nA(GPWSX9Lf z0~OI4bn6a1mqK*&Qor;=V z-q@xr!f}!=Fi*EBFI9>8^ltir8Z30Cr{2MCCYIL zzJ}7FQT4wzDddSa3f8+nlkp$&^4c4V&82e3*PMokev1>&cV@mw2?|uLv{v;A`l)A6 z-{=^)UP7@f?xhG!x}&;m=rVfHN1$JI)^sDQtJQi+$Rks=~qmVBv{AZICyh zX&io<^MLrpqQ_uoFasCow`1&_ykBDx8ffS$=zN9knuqIvYybut-%twEtQS2|aA;mo z03MDb!JPw>D%9N0SLGWKbFjHujnr;!_-~<0wBBWo?lN~q8ujT5G&)W2UYGeNtBuB}jSe8cw9u=H2TJ`-&%a8MB( z9UPh8G<<6OU7qB55*kL>env{eG*sb>?x;gx`OBsM-E%!{;V5_8(UG@q1|Emx>pf=R zl3P3cHT%(EFRZbg({5-DN)}xwDk&=ujtl?_3Tvb!C@9!|+$*=qj{AnOsQtAvTA!2Z z(vNt>JyJoR?g8entli!~bU+9;;qc-32s^WUxN!RpoS)KyWz@4X(&$4CrI1a}wq82j z|LNsTSDe|QUuQfgD2vaV;@zv-3TxJvYgB`FG!>#%fGqXP2v2_aLr|qKc$+d~Q8jG= z2tp-Q#T0XkyrfUP#yr`5XQ#((ckLiBpuSBTRh!_6*Rdc&v$gSn@z!_?1${@9rK(+DYN1n2`pfKVg*K60hoyZaK}d8n-d|yRPqdXkkY(n zFkI+#jCscSweSdnH4#DGue~4s@f&IXJO`E3LQugK7XI8CNtH|&&y@s3bDQ78e&B1K zGYZ+u*Cz+3CRZ=#SE$pMFVnY!`QkH_l?)`s*w~#0N!?o9iN>j^ph#^{glArnBoEI~ z&3}k6ASl|X%v#kX#m08~4o>x?b@QfzO`K24y7Wnk)J&p_X-t3QC)ZAZLi+`7Wo?yZ zsd&v#xmIs}s#Fq6XHbUadft7a{_CV+0`WV2;pQ}t=MZlP||Hh6Q>KGz5b+ZQL*U-3J(^!Ys_ zFw>%PXD()|qH5YsF<^qNEhX)rg4iqnz4!@;@W;4>IyB&-06m7_--muo_+?Gd%L~cSXa5dTgzjuD%sKD5Tu+Fp_4!Q7W8$h+B2$ zNITSc1d^9_&wYdzlnom!bSH(0a$*k1!_Kk>~z z82h|Nsq<>Q7xTQ=Ts-eFPQnS(5#gMltBG`46O$19q#MJnP-&g1I!&#OK#sjk_A98V zD_{?$v1X}zr!Jdk)pk}%WhQvI&M_N;X!GG%6~kYv)h%ECn17BdWg2;pI|~FQ2=5qI z_PBbk=x#6029>`~2oMQ_sC*s55Tg04wy=8gKfbKbYl^lrU2x(=LWrH9p@Tli53?D2 z{#pvqRKBt5BE$*Kl3ejgm%c}AhP^u#^ZqRI@ll@BPsPN<&xwU|pAIk8tS8|fgW_c+g>Kx%u>q)fDLh2+hn5O;ii5hG-Kf~MUxHlr?Hl@67lV>4lAWvmVg~3`g6x7n7H$<|clmJuJ zbN)hP;oK~Lx&=h*L4|pJeWGy~w)E40rx(g=>K&;o8=TG_4#G1`@yu-N@oWW~$-ggJ zQfg-NgLc>BcLIs3zkko?L|$G8)~H7rJrn*gEs(|=GMH`jDp|meJ^+LS6H8K}nh9Sh zFp1Vr>x-bYAT3~HVY zYe8Xu`@$2H?G;YM%VQzLqycPS+G*OdFRx*>zW&Z2{U%vz8E|4~2y zI<1m)sEm#A8GKrrMu8u{alKl&Sb`6v+LF``f$(-JegMcLUM;dWB_W=qZJ>4R`-#Tb!y<-tfcSP@NZh&2gn{3oe z#hujN$0L&kLM^P9mwn%A_IaL0e;1s9#60hh&hqxWYlgb_tIWA3&BWdwjne1u&jU_<~EbVI8=%A_<-kQxXogTTpH1p>pD5mS-BwN-UYI|^julyJ zhGM&p4t*w5Zz~Na9aMOX49Wsw1_eo05(_ulEWTkF62uHOhTFyCuqkQUL#q#d&b~LJ zn2*a+^4jFu83QaE*Y5isS;MlbvNEsjZ;El*M{}QDai(_YhhGr&2tR84?1GX9l0A&2 z#Wp4nC0@Xm$}1_?O-j~o4WgGhq1j)*_*zyNW#xM5w)CONLqP3h5nkEZ`>@!ws9~n> zuLz0{X|so|-F`v!YPHc+F||56B97=wgqS6@_nf6#2ncRTmA z9Jkxes-(g~ubGvRfgr8OuEP)m1i{w53!uHf`l#jlNp65JOKZMGN0Ap(h4G*8j4;tR ztXEPvcpu5Mkh71)2ksNv$XDG^Nw_(7_yC4YJafXVIA}N1CO}y3#I2c-LazRb5HWYg zorewdfL%`n=1B^xjv1Pbm;GO|KI1Yp&U{7gM*Q=uJ={QGQpWx1m{Cod`lf)YCpG@7 z^2F*$YMSM7skNj#{~p1&)NH;%tf)@=tzc}L6%}#cBhV^%d0H3S~xv?SOkNj2uck#rA?XQS;4B zou|++Gyd>G40x?1ntZb@KQ+OC_X80_)J1aCB8(wE!kWZ}?n=V3el29dh8999A5lvR ztES^uO+%LHyKD6L3`!a7XMkXGJUYN}&=6d)wxFceLb0Um_c+Ocy4LTf-TH37`p-IF z!|q~huI?V$Zc^QKUNR}+eFen-D2o}cU(|@!hyVA#uDgYbs(^(q1wloM)N$?obEsZ( zRhc#1QrBfy^8yAM7qHQg?=Ink#Bd{F$KK&Vf z{1^p=i?oH09d)*VW|aj3AW(@d`^-;5LPRvIR+Akt<*l%bni;@CR)`{k>dEPynMix? zB;@T({{v# z@&482(?9xv28Ds0&HY@T8m52TO7EM5N!aFU%J9RA*hwp+;3Xi-yw9-DJ$#tn`jKW; z>d~AhMVXeT=H`>Ha|RW z;F{K75(YmGbM1-BT$TQJ*Is6nLZOTd%)89WzhBIb4%#2I^{L?25;?k0|KlKhQ^XZ)<_T@`0S5wW}GA@^wz9Ku`2L?hRNCXT_Sf9Rq z@#rn_+!bhROu(X8LsN(BsKnWNa59+BH_LO&s%X$AsJ(@j*WRAd&I`TuGGZAq7<>Ni zCnDx>Ltt68_jux!HzAj^7)9-|8)W!;c>Im|oV;Oc!#jP}$)3R%d1XBw{|pHJuGsnW zXYaWqTMq*|dDy@aF~=HvavJYeR|K6a!r|P9z53M-{Lgc3ejy7Qh<~>4P}qwBsBD?v z7i~wh#Npf=^p4qy+ktZAd9Z2L(o`-SsJhL)&LGH!PIooF$s0ho&;^seyWP1x@lj5~ zvB>&=FywT1&C`-s&?Ok0Jbjw8L*5Z$K10DykmlU>HGiYY42e z{!*gA2dPY`|4SBdr_4IClDcPDzB$auo(MY)r%=0mX);h~5b#3~&D8z�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

    @kcF}L`k~@p%&4E-zW>qn^U=Mmjjd| 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 z zuK$64!{su&xK$aP)&^d&v-#*P;@lp}K(KEx+t}g37XR*h#{CBAp$xf&2`v6^4=6b} zhiB?$Iizn3Bkws-ma2GDJcK>-aY?mF^=I-eJD3U449+m+{W3f$ERS@l3jlC zCgICmA6>Tj0dLN4e(3t)KZfiW*-bBwUY>0Z2AyK*9}exWGSeE)WWazs;&@>f?Onb$ zD}g`cNE|#w95&!j8C**>RzSLkI9UthRYVD6lPg)Kh}IsHH?w%J?mOmDX)dLq?c0qW zWcmIQ68g1^irU*%6C!w|I)l3(g~_EPfh?`nPEh}-0u-aDc(|B&t3({sr%1UJ%!?5d z9WLbl+4wjNq>AFGVgaLt4$i7O%qm&PEgbY}6;#+_uj@c|N)!x1fDDHhlHgXRUWQCy zz_n8`d2aB~gvQ515ZY`c=Mh)t3gnxHs5%Z-p+pqaz|X2<%!+BTBtawHR>cF;PRu@$ zxv~s(X_>eNVzMmMwSJaaiLd|rQJVkc+~i~8vk)$`;PGbS9P7fWuQ@o-pkRW~!17;p z4G=sDqQZd9l)qaMI4T$0z?xWi*wFKwQW@gV9(`3+%NJtOV=CVOLVz~b5`&P9f>gp+ z&_4+aQa}@P)uBN`hVNd?cM!*CKovVC$dHwnLx+Q^9E_oGA&=wWF_%#Z8ZzB1ML{YF z6hjz`V?qlhdKqq0B9fn{-3W#T0z)YYV+UZr!O6$yN6^|}Kpq#g8j}-iGXv0@M6rWU z)oK+N%seom-TSxG*X@hK`rY65?g$zm@2Vz#ETXLJK=JL0zy^X6S_*j+Ih^&9h~7hM zB=q>rpPtHdbLP|j=6uhvu@s-5WK-vdCh-h71b8!^KO>|Pz1)6*ds6O+B6aUejf9G~ ztD6EC!Hf*$i`cpV5zcuVc>ABTf7u@xMfy4+PVgdq!$xvi1vCCuFdBYMdC-d=)9* z`N_ytOWFCD4E~*}rrgK9E9?rI?peT(Ies*(!gS&PBk5Y;V$9e7JD0{xO`4{Q$+)~z z(~U62P9obh$V3XeR+eSbkk&+GDVLh52~kY3NGX@xb{A7fNKMJ8-~W*JzA*p26U36M*0mm3kvjIi zIJUO#T;r$B0pl{Rtr6Vtd?P(`Bk|$4w;la7r6G_7@tsw~ivJNqM?G5n;X-3}6eeu(V`bh`297=u@w5My(y4uB;JuIG`ZVYD=h^rXG>xtd->ZES%ioOYeY^@Ewl8$;(9n9( z{IB4YTyFf*5D?$s8~ z;%X;#^S`qlUHs;g3ko4ca7t>t+CB4h=FtX>31uf<`G)5CU%C{xDItFO2n8s!rd3Zj zx1D|^{n+r=+6%`xI|t6&_vsTedSni0%)PbcA4ZmM=y*m%PfC9kvAI6xVqfR*-p=Pw zQ#}q=u#hiG=FNo7>05V%H_k&IwB^Jpp>~gV`t}q(xl$cg>OTDl3`?Ltysk-j4tINk zHzqx>8qF&gMp3xL_xEtrMqGI?6+ucgw2^Riv4xjg9hKCLtE!O47wGiX=ReNk(kL!_mD6>uY)`-!?`3iCHPUBWgewt7Wl&3sXR!04gM$8B*0tJ^X6GSlRMm||jIvFnIW6w#+wYdldU};g3 zoRD!W!3bdt;?wcbX~-ZkflNd&HE=OQ^bC?qC^jhpY#k#;Fen<>^C2gTC^quLO;orw zicDAhjSN-XX z?AC00R@Cf6nq+$FkMgM@63+b1f0)UeEN10SRnyJC}&uaYVB=3BpS}{k_b?m zsbXkg(Esw-Gtfaxc)8`y@|j?tEQz-m^~>(i=?Qy;s%0vv#CChOv&4MoLW3dD)-w86 zPEDV4Wm<5ar_94yCqMSeGB9W1aj)VU9V;!>J@|0!hf~`}v437(6mxS#bn_N>-$Q}) zS-)CWheUGMy$_Mw23~H`aZ{&cWd&n)r z;?HMXX09Pm+%laDR>E6NL)zO~a>Rdz&6TMlMjQx9pL}yj1tRHw%kR6Czi7wz&G!Rl z2vjoybw6M8d!IYq^QZ3|=6X7dg=beEpD=CLOsOg?CC-{vpf^r;7i>Rra&5uf%2Ay< zuc-J%f=(1VXXl$_sUs}alSPKXSpvQQ-K1&{;EkRsz!9WnD#Vd*R1 z;(#8%ymtrpIBA4@x^b_XM_0QLJZV!R-V>w{WW@w)Vqk8KIC&Rnvk?ccr|Dy4Y#P$T zNlqk0IxsJWEw^p$60~lXFasHdS85!#*-6pq=?EQL{uIF2fu~w1xr^t!VMId zuaR5)HVO)#Q8;ChP&l*DN+9J@hU5W-Ji=nHy@vDSEZNk#7dBjKnfv|1j?Q8I=8MZF zjG1|d6IK$~w8c)ychZfTjf5&}l9s?3@=~koqLE3@SAA|+b+=}Lz~&7r&6>m6QU&EB z6(v}wfW)u5h>-C4q@I8!ryQ=!G**PcOT|Uwh464ZhphyS#5P+3LRCEuIT)BTvNeI%E1qcI);qvzdBZCFKOgr3WxCfag0s23hlxPAlfv3mjQc2wg3$~#IY1$D&q<9Cz zuZxfSl~nzko)Xa2eRbc{_cJcNc+q=haY*O`OPHX8q{?FMrLJc#9p1gj?#T&cyQsxe zM;$Z!I11)#y#L+sq%Qb4HscN!8ew?+~1{&T} znZo%?xBO6~TEMnv|2}&9s(QcYp4I}35!?C4rr4*-WT8LY3>ut*w+8xxj11Yy4_WEl zVy30@1ikf?BgVZh8+3C*o2xX1nR6#h4J;~5)feo)86CFLj(%8wPE#S95JnTM{JKphBY38hhxFt@sYw%b&EGKA?j6s?ViD^ov<+_`<9;$Q>*Bv!Nv&K3ZwA$_4JVc(A z${iu;!8fDpXC9m4nT?1|V{=rJDJnMm$l!FHk-u}Gm5{bq!U6}*i9PieZGJW@#KT?u zd-lPSI&0n>`-w1<%uv|bde8F^^C|_qPy5}kBiwnsDWoSet8$%kV-dpB03_xBPGO6v zL>q8d_y|PEy|(@KzK+IM3%2C%L>JY$=7G9_$P_1Ft zN|BcloCfo7xw3O1yvV3PCafBesRYyZOhN|KC>u7qVnApJZ=xI-Z3&oK);c3tQv^p% zB~H^+A~oP-ZZ@4KwB(E8s9KuC2OJuTqoQM8ayh-_9xdj?vEaItIJgq zzU}5o{{XC0(IaqEUx=2bw6nuhOD11Svko4dZj`bk(<=y;5iuv}OX0IFV&dN6vn`le z@L#B8PqanC7#&^5f8LS^f24NO`+_0c$g5c>`Y*NENCfeVZZD-r!l1Q_&M|5dB6P^W z1n-Y1$}}V_as;;+2fL~6mKEqTL^w-JafXl%tRcK~G1OG`U-XbRA&|*J+Or#e`t(3P zMNx>}2PjG{U1YGW5=!RhVa0*{EhL880l<+j5k5*c>_0^lQ+W|e<+}cAq&0Cn2 z8pI_^ZScdwO&$S$sN3U(JdaxrMc&nEb~5mW2wy~FT7-)#arLCAqmD}iA&;f|Lv}D- z&`r?vI0w9wB;t9CXwXBNG!;_W66juZUJ(dqsL+$Jo99n+lVUP;KUHv;(8kPh9!2w+ zUN4}+MD&@NnH)df_|;8S8d|PK?HlE0OBzGf*bphqO?5g=mEO))0b`+KG_a>UVj`Cw zPc6*2Uu+CDYAk2V$jAr@EA?PIely6C2(t)v8nT!D*FE-vH2l;&Ev=3%(h?zSvc2h4 z=1ta3pA7F-OLw-6GFOU>M2uWfjC;Ysbq7Wwh5>}9DhEq_rlc0Fqn?FUj3t5!6M82; zZ|}@3+h4b<+qWmtz-J{c36^|zbHxCiGSeKee_`fUj z_UXOx<|DJpEk*AQ-WZRBd;nn_8e7r}R}hlJ_~Cdsu&%-9_0i&_&?A{3uOOfZTLR!9 zga{-Q>IBj0A@;ew4fDQydh~o~S!VvXO{4p4@6HA}1vEiA_1EAD@qAFyYZS=n5sC@5 zjz^F1ieT`SoCuy$D3L0~kuH%gfWNtXO@?YW;&3FSm=pZd{$x7cf{%1DbAh#^3Gbzs z3vxvH5o+IhjW{@qFuG;LL?TPQyefjma?yHeW1Iq$EBI!zSq zEH7juWO%8VsHTC@9KwaE8#>3be*Z{>7uk}t$TWlMCbI7JrrVlAS2@87R_fkNIVmT$ zRB2QZ9HXfkN!)xE!x04N3J;`fGxyR|dOf$`Qb=VGTejDh?WAIo5n3L-CJW9Oy4lW1 zp2Vw&l?qabvFJdHqc!N_hQwB_NTk_p`0~km)&JIxX&AB#H+3mVpW&lHv>J&lO*KkmS#85!yV+{>sHMW+*usnm!^k45}y3VhNrxle^9Tp*@=w!{%pK?JFz zB8>wWRCEW4H8{Fynt`Z?&>HD!WRY-X@E0D+H!X*uc zK?OFv7#beSi@gVVjd*c%_HKXa@h&5ogD4J$1qk63NDzDo)h#raLimXJ;iH>o zD1{0ym<&qjPEMG?t%wv3+y116sM#y7Lt|ir&q`&j)f9`tIgOjYB)y_qi8F^w6^De% z9EOts!9*g6iEjJ%$kLF2* z?`2_Kin$8RKC=RqT>{saO2_Wqqn?-?CJgQPdNrYY@%z42I}S{b3Inc%dX zfq@GV7KU;ukWm>lTtTGPwo(w6inj}nu(uYvIf*48%E(|PYo({y&uSBNE0_~?1hY60 zFAF&RgqVXRY7YKq4NVjYPPAlSFv~#Yp%zng5Xo9(sEI|z+FIM zBd*bmQVDsL8gGq-fSYDF*lBzXOSU8h9C7^n_8EXoPq<*va$?ajTJzxxVUi_h!qpI+ zQYC>u0U_)>8c9oo{Y93KbIWVD6*!h8DPc>=+Gjacztkpp^zc zVO)S{kq6)&3VcUJhQ@}_0iNlUE2Qvt1U(xk4+e~W>|1?kSae3htRQgRFUdm^Y!z;% zZBbe9mmpgGVCr)lnJ~AkqIk8}kh~d)_8pcnIr>0Sav>^yLO@qw>Ak3T6Bbu@Bziad z{mb=b^L)Z7n>8f8QRNXM;<7UsTd~je%8J23?hLVvq%sz?goH@5DEjZrkpxqYHEtFt zU*s$qTPwr$%5s;ALk;Rk391)dCrBe(!Cb2PH(kd7o}@#9jb>humjY3XwM zWMW|RxEcqf=?d^fltKi$hiFuhGL2p{jwEE1M_cU@g5tCW7OM5=7{M1yA$SlXCU6KS zkK?lIOO|xrd%-9>-S@wF?+Wq@KFoS!iv|X-tk&B`1q*vZj)e>p1;~F81Na}BUzlgN zU8C~8s~Gc%Z3FoG2TjLzCI#w+Kq8!y5#cnT67CCb{bHxl0WsBLDvCoux*f>`e;1^F zrHBcVuKy0)ZgRZdaJyc@BV|}Y!ZTlw5AThH5;z{Pk)3?;O<4 z?-rMe{%zYJ1<~*s^W?OSNRWz5(CnCmV{5j<$p&!=~BZ2yO|(W461W=iiC(l zo1rh%Ct$?~3NCsBJ=z1B3k~fC90%!t&3Ur7x8}r}`y1P1$|}m=IeFzPejy`e@cxSt z@h}ckz-6(vBp40t{aUO zK}V>U&Kf@rUK;AHKy;P5#=Na(K5pE|$awiV6X7JZQ1a7VwW;YeA%+NY z^bbo$?}m?o4($Wg0U=12+ICV92JU#ePR8SRpF`Y{bbr(jeCH4uNn>-x;|M2VdZ0-T zM*_*fM;O5)G~I}bTnZm`lw0_dBO#=Amj%9{z2KOm zedKV9jELA+}dNOuRNJ5B;HF+H^;1b3cNFM;Ev0BsJmeG$|gB7x^5 z;$f*LZAGI9Mk3%E3y==%W{0ZG4Cf29vTy|tp&o(P|2TPM34ACF6)t~uZgbyH>IzR+ zX)>7X9MD{72;o+D8l=ujhr^n}<9w5p8?2)xY+WehaOeb8)Ga@B3{F$DV1)%*}N(rd61N zOrAa?&k;S!XZ>qC6a7dOD4R)`Eo72I4!Aofn8`H5ZviHx$1} zA99F5VbhP205dgl((LL5T%}h^p)G`5AZpbtZS}EWbMQ~Vbj;EMBYl96lt|0Sj5)*0 z65A`tV1d_=pX9OGVrtycSt}(Np_PcJ1cx6K)@2JSp~FOY3H;vb(Zk?K6s3x-B4#Lv z2q!C!SY;){rV0`B(2~IpT3$rsc!@ak=@EIisf%A@A*V+~z+FU#>0e4U%_@!&@_huz z5@Lex!2a_Pmhhv;3UrW?!Y71}#wRsHXUn#b0wWhWi2^mV!udXs9np}_$Ld|{AoIANxdHx=?O8<+_qlmHO~;L#0JfQ5@z z#MG2JwzdL23V<)5z0@dH8BX1b8k+V}2w^S-XKsI6EqKdJq8hUzgOd)7jGbN;H`WF< z36fa`7JL;TGJ9jFzzYg_F-x0CAni{=chT}lHjh8TW0vcPKM=cm_vp^cv%Eaw2DfaF z-W8p{FjFfm{yn@}neHt>t|to^6#zzfgcCGu(4foHdb9Wz0^grg&Ret4^5D2*srh>p zW;tmJmxV}qZxtglXPl<6Ftf12)TBjlyV{Bd8Hx@!6q}>bZ_f!lFyir%g=a4xI=wl5 zkoEDJVau(3pTxS@@qL$%rwTTzBtrlQ2PL;Cex+18&#bYfi^X#k0zUus`Ag3CXhncw zcp9)lFgm2tfbyeA35iG=9ete@QAgcI8f%3QWk1oB2uK9G3^rl#BEWnWW7TFWppnoD zp5ft=rs)AY3YZ$Wi!qR*X9jK*ks`yK<&Omm=r1(1rqq`~=T^2N1(6DV4OHUu5s?r+ zkE)s7Dz!#>Eh~Zi*`2lPPf^3;C77(QWt|YUIZ&4$4OEfjQWGN7?bTZPxG9>4) z0muL683vXLg2|nP?)cecq~6twnT5^}>>v{afbbZC-vg98GA$7dO(x-k#3bq`gg1RU_?m*%0g6$+UB? zvVVE?@Z9BH?NX1HsXjI1(qNlsQeZwnfxsgM?r7AA(^K(LSm=U6*{WPUO!g{(Vnd%0 zX~a7|7YQ#^cVsHIepc`ue3CM5JD^jvA!QnZ5&qw2Gs09#FvE6b(A-DgALwVk;Pz#l zSk(R7x|QD-mKrv8H1^KD5_|FCw7h{%^IBxWYOVBc&>C{yd5*7-Xtj%-J1)RxtnGxb z?qgsWLnmr7p;%@N;48AkGxoj?$vIzmP^L}RX=Drc0^J1+OhG~}U?>Puz(7EfA$4Hf zWJP#DbdD&}3V^3eUT_hG1TLVz0=SG*Zoz7u}{dlPO{~ddWeY^h_PojLvojK~FpHN&eH+zAmwMb9}bVj_xma zdi%pVzXm_>`<0>tU_DB0X_b1zC~c}9d$coHxU??DlV;J#)!BxG(JZY0(K!amNyK53 z!~%f`BMZES(=r0(Pik>;=z%0tswcAS_mVQwNfD_cbVAfOq7n?e%%g9nsQ zAPfBQN1h&mj|%hYOuK9t(Mm%N_lgT^s?zuaz#Gq(k!Vh^FXc0{>=jdZqEy!(XNjgT z|Ckb}wVdra>9^xPM|1AR%v!&{qpCL~>HXnHWe+BAF-_W4-VoNaVzhtV)^5o!OBQC0 zJf2zXwlCf8e%|~)rWbJ}tn6`oxrwFA#3G4e{-L`;52Dn1i?hd9fP^Dr>>nWEJ7Cf7 zRmBi!tznNF4dYylvZ>yCjVywhrG~K)gVgHDg@62bIyqUIJZa!sU!bw}C(e8{H_aY1 zt>NEAQ9Z|}MNjO_DersvA|Q9(@iiaxAui3v^T(}2jy~Qt?J<0_?e5Ej{@?xl!;E_> zmjP{>X$NYy40y6UL#?_t(?@^+*_vR#XM5b2kFSXLVNJ95wEStowJE})jPtZT^Z&`x z@l3!Up1j*8T&a@pwi9w$k-*#Gi45cfL;33Lm|%Y!5DDiqNzm;{aB4^beSrmJ|M)MM zSTUw2B;rye(7#AnkdD)g<86zfT*V25f?S*yRg@5ll84FGNIA4oAQg!+h=r$KkHKG7 zNhrw3BN}z&4}XZi{WI^y>7+$ZyKi=_Ppba*E^?1tz^w$?#}d~Oh7%cI0D21KwU`9O z=$54awE*$bNUb$x>_!+#on)^ql@-b(pepx5^=26WW23vTb*3rkD4^+;S->?W>bweH^3>Ab>e2eEe3|8;eeqwe1VT3e>-OA0oxnT)xOBa~pA#j+X#1Ee8WW2NM#( zqnc5C76n*XKKTA+#gw>LN6q8{5mQNZX9`3SqAL{B97!6`X8k$cb^DHO`t1xA@7T%wyS42jU2y^W{gZXddmuNX#?SQ!pYMu1ch`iR z8W(wPz?GW00|)&@=$CRBN~;CDDJ9$3zyI;`%MlmuIXsek?jg4yo%Or%<609U$d^SYY)32EZ6;%F}(NS!S+)&9~;{Io}9R_Jp8(&xZuhDm@hp6w+8jg zy9T6`@x(eIfv1?j8 z$G&lHk-mt3rViF@yCg3<#ESJI*EH1SWfULn<>4M3e zuSt-C=0uE8{t&Kc3?n{LO(3DbEk_caFoG4k&@@aXJU~!MvW$n2L~E;L z6axoZq8H;XrznWT_zd7kEa2a+ zq6`{ni4h_q9Wh8sG2m%%7$6x(6A#(aFdr5e)LeAQA{Tjh5nZGrw1rDKUSfMCclty- zcccVw*~4V%{yJjtE@B&*0>tXc6wc{vPDZ=EO0>G#d$O;N`l`dj2q^MYc(!>Q~2|w$1Hzpfwxaqkibtc3V&@`D2>jdz>#DlSPQCIDr~;Fnivr^+hYRMLzb^aKZUyx^H{Ch z83PTC0_@v-=rRrS^owyXpLhJSxO=jxV}s4WJXv=07PKP!Z-xxkTGO?K*7#}}8VbIY z`6tly<&cu8u;SurGKo4?3Z_3enk1E!#G6WJ4TLJM2I!;=HdnYPM%at-g=N@bHR2^<@zK&Mo*2nRJdi>Fn8<0# zgy^tLZehW%#vpqrdBic7Wjpg8&mOcVa&3J~*OnQN%0I6!?cLG7+^_db9R*N|o|jGuT!rbWMwW7o6?gXX;JDI% zPJ|@&kA3nxI7m5=|`5D?8M{toV2z6&QDZfZcUsn64z_6 z-)OZI0v$xZsm&bwpmHWX>UiO-Y3;|7?>7hTZd>3!yf14^za^!$?szzteDp-;rv}{-_QHpEI zO$XoEt#eRTq!Z}Nq%VC)=+)^^c=C;%Fo@UK3=Y+ z*=fbNa6mjVLhcq^Y|&Z=KQbm?T4XC_VJf5uA$nrs+=&;vz8vkiJ!6wBVb`kV0bipR zeV>xZ0LY29ppulpII&V=gog!X5Njax2B6?lKDAwu)b0!9YYa$sG^gb_=*YhebO)Y~ zly&sT+Bn>!HrUM5cz>(vfm4U9bopaX=&=D2T9Tw;lcAbW9WppX<#InnseyYA=XTAx z{WtCL!qLGdj7rud%frp+V$gXS=|V5x$o+xOXtbhC)fq!BxQ_(Mu^oDh5t$Nu*}COG z+l*&b?aPEGJ?Bn7LPKf8z(yTRws|V|U6dPzx_gTdD<>L=-so~Qt zkeAsRLNlS~haq~#{b>4h*WDi5ZgDJDvK2*v2YN2FdQ3U?!9xMaA)@-0Ha9jo!OCPH_SM*Li&)Fx2HV5{UE_fYqL4yGkl8ctf$CBqbj&Ro;{-9LvF`s8fuT(J8 zVq|L^XM0!>ICkge;{nn!SAuw%N@TYwfdGMzGSCMoDFtYtI#Z9_!Lh}#CG_mqgv-wh zo7b1RzA63pR-REnaDc4};>xQuwvcV=s0mnvK_dGWxGXRm!qBhod;MUXqfoHY6N(f5+Q$E)CM(pg>Qp> z#jlrO%di>oWq0!vn*w?-{5u5d&RVewdlrp85XW6bh$M)xrY|sqqqwc@8l?VSfI)p~ z_o40@H8iSr`wswx7cYed_8s1s+0nOP7R9xUeMIgL#Y|aN>|o9;bF}9Xm-~JS+wEsw z>6V>a(|+$5(^GTi)z`#z>ZldcoS^}U>bMoJR(<>0VY6%J@#v+=9<~uYw3qP%5#!xt z8EGumSyOyJtd(X~!=4~?s;H&BXUn=*jaBuVSN1>c?o4ky^2x)9F0>GhCDsHw8j`47 zR|klUS==mdwvZz-g01y7ilIa&f!PpWhP3du%hS9!_qkViRgS+MzkPqgw|!q)@*Q@w z({t)de)28lM-7{q^kiRN#Se)G8_GotCyTv-Hk*Yjiw?a{oweS6K5T~q%OSNvLI>K(Gyn`V$^~T zn9jMDwy(M3Z0hdkgu~ZV#~T;E&rkYh*COHzIN)EAOjAL`oym=XC(d>U^cL9U55$>L zy!@cQ_;+DW7bl?Y)sp)!{dG z#=Z4?aOlT-L!P$9C4~(;Y*gwG?v4p9)verceSBg{aO2mlWgokr@!Ug7qF3);^!oH> zLz{cAc!=%6-~+$?d#vg1s+SWJ$8>y-6RCI_CZDf47@ZtB=0?imsqVvBt*-+<4^K>M zKgDM9S-wMijvpXdoxZiyYGQpzTeZv2)3070 zdb;DziEln{;EWy&lo&8C=tQ7g0Geab6dHgLK13D(Cx{Yjmw=W8gpsFY3Y?;LW~|w~ zc}MMmxA9w&nttK@IMH7uVS~uP1fB?%5KREuEtq{!IHEwx2uxN)C1mIj-Xx_Z5H(nQ zQma)Zp`~G0g`JF1p&X_Fk+$2e@<|xBHo6QPM#u(1vton2k4o&N4I}_Y0;I#LOQHbu zNXHV4O_TqJbbuTnGb`|agNejMHvys>kv)=0M#>Zdo(78aOhbuW9-(K_WqW6#HP|Mj zC6iq1f%6-7ZcqrKM~<7V3zU(P@ma^OuWtNw?taI?yH^sgCOy06pZ>sTt&Kfyhyj7! z2{yS4_{s(NU|0)Sn^<7xAe#dl+F2D(!f*#-a+63|A)zfy@bZ(HDKSiC+DIv zVSu~9FjJUtY1ggm(TQ*Fw_mJDBaAL@^o~kq9uhC$V=M{H)#Jcwz%I0q)-EvuxfZKr z<3Uz)KH&00miqAY2Q0sgI+n7h>f_n3f1LfacU502g2T`Dz8lc^;CS(s_3b++b__AC zUcbH@MoY&QeQ{Xa-udm_z9WMp85A1H>XgxWEd5d|7poa&F#vx77=oB_iQ-EkPikAW zw;bqHzkB;!^?w!4h9U|J2(TS}S`+Y}7Vx2}I)_Q8VcEHUkP-2vr`?F?F-5nTKQ;E>hA=$9|Lx0{?^-&4 z7}K+T%%qI_<3a_uT8|`|Q&v5G^0cJn%KA^Qzr+n1eO?-2H`f*bFVOC>_~gCFe21}E z?K17{K6Q)Z(!D)N`vczDU;T9B)#X7q%RdL2c6_+HoaH4pQ2DGz0U$FCenXay7D)~3 z5)-`nB+&3f&}GR`g0JmoTfgC2?Z@xj+b3Tz(>@D&uf6Gfuz2z|%~ef0ce`QI1) zw}p<+KH4?BDgVpQ!@hkS?-^)+;Db-czFqN7d+&uFtNBoH=?$m%t9wt=;t`f?Ix$(J zKb)4m_{G)uzoS2OuRSvTxcO%0;{Lhc9uCk?V+sx?{POhkpPR2mkJIeGz4q0BuY&?I z&XuP!epiV7a#vREefn}_@8z>0V=wj%y%JWmUE)Z&a^(^}K8JD^PdnSQ{mY<678yaf zh*ETcyAoHGf2uF?{Z}<>O8e{^r`x`ybvHE)w_WGf_i;nt*%wO}?HuL*-4R0%t=F`x zt8MZ2ZqK2o;yb&$R+Odub8c*;?&nD(Uk`oX(irt+EsyW05nFLoqvMJ`DxQAoihs8^ zvFBJ{bBA{KNHO=;$HBvoJ=);Z_jtkQX-_M3N1k7ZocOfq2fwjxVM$xszaN>_Tv{{j z(j5=O%jI+J2maK*yRpgU`;^Xhh2TeWH67#8<%%8UgKVy(1|*G2>|~_ZWSY}_`wnb+ zG4Dfjzb4@8Xs*|X3BxmU+~@Cnaol>}owXz0MJ2W7Z(MKMLC()}`(Mb}4^E{ICl>y4 z&}IL}jqg5}H{-dblwY%!Ox%##y`+t~;1Pa6da?VmT|0gIzs6UmwcqHc<#>z-2a>;U z>563)JCf|rcIV|Dm_If1!>Y3m1I0IrU}#jo3#UJBO~?IffrR z*l|OKP4$3-ExXDF4cFdXR$39&`pNB_DJZgG$kh6OqSp6)OsaT(m;fwpjl37Y%T1P6 zx4J|;6ND{Vi2`h~>Vo0FOfzQP=3RY~s#rybyoeCa?eH#*#N}rw%@e9Zd0r zgRzxB!;S_6AigSZH;urh2xcR-bAkWGw_oA+hQ$kr0U+5Bm1s#oo!t8$Sc?7TBJqFf zWFiuK4O}wRHrQW}oJ$jU`P5G*W4a9EW1 zg$gy(FOby6@{hX?o^^f87I**WnIQ^=I=3V(s4wO5(p+Z*hH9g zX;48Gi5h|?y+63=&5q6)!@~k5b4)brvk`K-VltI!3H&G14eofAW|NWv|2nOOT`=uiw;qz;vFd$4yZpG~ z_i@&*wtnAqSmP-{3#X%T2mrB;a>C3`(@(YZGVn!pX*wGEXDl9MmH1k;wsZ!G4-BJF zY}5LvFpMB2+?$lx7pa^GZ1vEqV|@i6k%@IF>3MEaOQ0|OZ%RKmbUzs?Tsq`o-Q!>X zUUO;ijn#20I)6R;^?w_CdfGZBUc7oC;cZ#Z&Vjq8&-3}=Vcog5r|&Wrt@@_?#({HV zeO_Yyv8ywpa}#cV7d86r_4|2WKkUA-Yn0=ToK=_m18pw1zgwR0yz=eS{)#mTFQ<$c zG1ruQ9^hz-k%u8qNNt-%k+MpS&YI5SOO*yyNPBct--7(soTr)dzD?=xz2X<2yCTdR z3}GrHr4ZDLVsDtjVgro+2)Cme7)209U2MdS1a>%DqWZfLuZMN^G-eEb>zVp?!|+Ly z*Hz#Cls510`lKQO;%s7W!^V&vgL@AW&@*5dME`*34@ zY3j{K?_Ld;$^DM`e%Y`%X?wsoTL0ImL+|vyt=5e*hIdZxf9%`(Bmf ~U1h->bAS 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

    )IP&r|oN1%uj77ff`(r^@U?Ag&S{3Z$ecH9+^ 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 z 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

    NQh&w9YkqISApCpn5TdZ|7Mj&WCg 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

    1j{yJVl%=j!E`{_2C5_U{LHX&=9z!xURmX-}M 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 BvDE+o literal 0 HcmV?d00001 diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 8cb9ed72..d919b53d 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -20,7 +20,7 @@ $Boards = @( @{ Id = "RP2350_ZERO"; Desc = "Waveshare RP2350-Zero" }, @{ Id = "RP2350_USB_A"; Desc = "Waveshare RP2350-USB-A" }, @{ Id = "RP2040_XIAO"; Desc = "Seeed Studio XIAO RP2040" }, - @{ Id = "RP2354"; Desc = "RP2354" }, + @{ Id = "RP2354"; Desc = "RP2354 (RP2350 + Pi Radio Module 2 — BT + PIO USB host GP0/GP1)" }, @{ Id = "ADAFRUIT_FEATHER"; Desc = "Adafruit Feather USB Host" }, @{ Id = "EXTERNAL_4CH_I2C"; Desc = "External 4CH I2C" }, @{ Id = "ESP32_BLUEPAD32_I2C"; Desc = "ESP32 Bluepad32 I2C" }, @@ -39,6 +39,8 @@ $FixedDrivers = @( @{ Id = "DREAMCAST"; Desc = "Dreamcast (GPIO)" }, @{ Id = "N64"; Desc = "Nintendo 64 (GPIO)" }, @{ Id = "DINPUT"; Desc = "DInput" }, + @{ Id = "PS4"; Desc = "PlayStation 4 (DualShock 4 USB)" }, + @{ Id = "STEAM"; Desc = "SteamOS / Bazzite (DualSense + touchpad mouse)" }, @{ Id = "PSCLASSIC"; Desc = "PlayStation Classic" }, @{ Id = "WEBAPP"; Desc = "Web App" } ) diff --git a/scripts/build.sh b/scripts/build.sh index f60bcb63..8ea18281 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -21,7 +21,7 @@ BOARDS=( "RP2350_ZERO:Waveshare RP2350-Zero" "RP2350_USB_A:Waveshare RP2350-USB-A" "RP2040_XIAO:Seeed Studio XIAO RP2040" - "RP2354:RP2354" + "RP2354:RP2354 (RP2350 + Pi Radio Module 2 — BT + PIO USB host GP0/GP1)" "ADAFRUIT_FEATHER:Adafruit Feather USB Host" "EXTERNAL_4CH_I2C:External 4CH I2C" "ESP32_BLUEPAD32_I2C:ESP32 Bluepad32 I2C" @@ -40,6 +40,8 @@ FIXED_DRIVERS=( "DREAMCAST:Dreamcast (GPIO)" "N64:Nintendo 64 (GPIO)" "DINPUT:DInput" + "PS4:PlayStation 4 (DualShock 4 USB)" + "STEAM:SteamOS / Bazzite (DualSense + touchpad mouse)" "PSCLASSIC:PlayStation Classic" "WEBAPP:Web App" ) From c74aa5052e8558ee161652d11c434ac3b015e7c7 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Sun, 19 Jul 2026 09:24:39 -0400 Subject: [PATCH 39/42] Point bluepad32 submodule at remote ogxm-mini-2026 tip. Co-authored-by: Cursor --- Firmware/external/bluepad32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index f1266794..d24917ff 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit f12667945a4760de17fa688a1667444794853924 +Subproject commit d24917ff23070e6ea847be91e4c34a5707ad4ddf From e41a4e6eba8950d32090cf88bfe74b05a7629792 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Sun, 19 Jul 2026 09:44:11 -0400 Subject: [PATCH 40/42] Fix BTstack v1.8 Pico W build: HIDS host rename and bluepad32 sync. Pico SDK 2.1 still referenced hids_client.c; point it at hids_host.c and hci_event_builder.c. Rename MAX_NR_HIDS_HOSTS and bump bluepad32 to the tip with DS5 touchpad + steam instance merge fixes. Co-authored-by: Cursor --- Firmware/RP2040/src/btstack_config.h | 2 +- Firmware/cmake/init_submodules.cmake | 2 +- Firmware/cmake/patch_libs.cmake | 22 +++++++++++ Firmware/external/bluepad32 | 2 +- .../external/patches/pico_sdk_hids_host.diff | 39 +++++++++++++++++++ 5 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 Firmware/external/patches/pico_sdk_hids_host.diff diff --git a/Firmware/RP2040/src/btstack_config.h b/Firmware/RP2040/src/btstack_config.h index 6720c8f4..24c6004e 100644 --- a/Firmware/RP2040/src/btstack_config.h +++ b/Firmware/RP2040/src/btstack_config.h @@ -27,7 +27,7 @@ #define MAX_NR_GATT_CLIENTS 4 #define MAX_NR_HCI_CONNECTIONS 4 #define MAX_NR_HID_HOST_CONNECTIONS 4 -#define MAX_NR_HIDS_CLIENTS 4 +#define MAX_NR_HIDS_HOSTS 4 #define MAX_NR_HFP_CONNECTIONS 1 #define MAX_NR_L2CAP_CHANNELS 6 #define MAX_NR_L2CAP_SERVICES 5 diff --git a/Firmware/cmake/init_submodules.cmake b/Firmware/cmake/init_submodules.cmake index d7ff9852..61300cb3 100644 --- a/Firmware/cmake/init_submodules.cmake +++ b/Firmware/cmake/init_submodules.cmake @@ -14,7 +14,7 @@ function(init_git_submodules EXTERNAL_DIR SUBMODULE_PATHS) if(INIT_SUBMODULE_RESULT EQUAL 0) message(STATUS "Submodules initialized successfully.") else() - message(FATAL_ERROR "Failed to initialize submodules: ${INIT_SUBMODULES_ERROR}") + message(FATAL_ERROR "Failed to initialize submodules: ${INIT_SUBMODULE_ERROR}") endif() endforeach() endfunction() \ No newline at end of file diff --git a/Firmware/cmake/patch_libs.cmake b/Firmware/cmake/patch_libs.cmake index 737a8713..368ddaf4 100644 --- a/Firmware/cmake/patch_libs.cmake +++ b/Firmware/cmake/patch_libs.cmake @@ -41,4 +41,26 @@ function(apply_lib_patches EXTERNAL_DIR) message(FATAL_ERROR "Failed to apply Bluepad32 patch: ${BLUEPAD32_PATCH_ERROR}") endif () + # Pico SDK 2.1.x still lists BTstack's old hids_client.c; Bluepad32's BTstack + # v1.8 renamed it to hids_host.c. Patch the SDK cmake when using that tree. + set(PICO_SDK_HIDS_PATCH "${EXTERNAL_DIR}/patches/pico_sdk_hids_host.diff") + set(PICO_SDK_PATH_LOCAL "${EXTERNAL_DIR}/pico-sdk") + if (EXISTS "${PICO_SDK_PATH_LOCAL}/src/rp2_common/pico_btstack/CMakeLists.txt") + message(STATUS "Applying Pico SDK HIDS host patch: ${PICO_SDK_HIDS_PATCH}") + execute_process( + COMMAND git apply --ignore-whitespace ${PICO_SDK_HIDS_PATCH} + WORKING_DIRECTORY ${PICO_SDK_PATH_LOCAL} + RESULT_VARIABLE PICO_SDK_HIDS_PATCH_RESULT + OUTPUT_VARIABLE PICO_SDK_HIDS_PATCH_OUTPUT + ERROR_VARIABLE PICO_SDK_HIDS_PATCH_ERROR + ) + if (PICO_SDK_HIDS_PATCH_RESULT EQUAL 0) + message(STATUS "Pico SDK HIDS host patch applied successfully.") + elseif (PICO_SDK_HIDS_PATCH_ERROR MATCHES "patch does not apply") + message(STATUS "Pico SDK HIDS host patch already applied.") + else () + message(FATAL_ERROR "Failed to apply Pico SDK HIDS host patch: ${PICO_SDK_HIDS_PATCH_ERROR}") + endif () + endif () + endfunction() \ No newline at end of file diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index d24917ff..039023e5 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit d24917ff23070e6ea847be91e4c34a5707ad4ddf +Subproject commit 039023e56bd176f64d9797bc9fe91d93f116f2e5 diff --git a/Firmware/external/patches/pico_sdk_hids_host.diff b/Firmware/external/patches/pico_sdk_hids_host.diff new file mode 100644 index 00000000..e26f248a --- /dev/null +++ b/Firmware/external/patches/pico_sdk_hids_host.diff @@ -0,0 +1,39 @@ +diff --git a/src/rp2_common/pico_btstack/CMakeLists.txt b/src/rp2_common/pico_btstack/CMakeLists.txt +index c622cac..2078825 100644 +--- a/src/rp2_common/pico_btstack/CMakeLists.txt ++++ b/src/rp2_common/pico_btstack/CMakeLists.txt +@@ -53,6 +53,7 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) + ${PICO_BTSTACK_PATH}/src/hci_cmd.c + ${PICO_BTSTACK_PATH}/src/hci_dump.c + ${PICO_BTSTACK_PATH}/src/hci_event.c ++ ${PICO_BTSTACK_PATH}/src/hci_event_builder.c + ${PICO_BTSTACK_PATH}/src/l2cap.c + ${PICO_BTSTACK_PATH}/src/l2cap_signaling.c + ${PICO_BTSTACK_PATH}/3rd-party/md5/md5.c +@@ -90,7 +91,7 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) + ${PICO_BTSTACK_PATH}/src/ble/gatt-service/device_information_service_server.c + ${PICO_BTSTACK_PATH}/src/ble/gatt-service/device_information_service_client.c + ${PICO_BTSTACK_PATH}/src/ble/gatt-service/heart_rate_service_server.c +- ${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_client.c ++ ${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_host.c + ${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_device.c + ${PICO_BTSTACK_PATH}/src/ble/gatt-service/nordic_spp_service_server.c + ${PICO_BTSTACK_PATH}/src/ble/gatt-service/ublox_spp_service_server.c +@@ -318,7 +319,7 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) + set_source_files_properties( + ${PICO_BTSTACK_PATH}/src/ble/att_server.c + ${PICO_BTSTACK_PATH}/src/ble/gatt-service/device_information_service_server.c +- ${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_client.c ++ ${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_host.c + ${PICO_BTSTACK_PATH}/src/btstack_util.c + ${PICO_BTSTACK_PATH}/src/btstack_crypto.c + ${PICO_BTSTACK_PATH}/src/classic/a2dp.c +@@ -381,7 +382,7 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) + COMPILE_OPTIONS "-Wno-unused-parameter;-Wno-sign-compare" + ) + set_source_files_properties( +- ${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_client.c ++ ${PICO_BTSTACK_PATH}/src/ble/gatt-service/hids_host.c + PROPERTIES + COMPILE_OPTIONS "-Wno-cast-qual;-Wno-null-dereference" + ) From 14c62be4b91fd0459ca6bbf327e361e62219de2b Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Sun, 19 Jul 2026 09:59:06 -0400 Subject: [PATCH 41/42] Bump bluepad32: continue GATT after BLE pairing for Steam Triton. Co-authored-by: Cursor --- Firmware/external/bluepad32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index 039023e5..affea982 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit 039023e56bd176f64d9797bc9fe91d93f116f2e5 +Subproject commit affea982ca2f564eece30bd53169e8dc00bddf6c From 66c24b42211a467c1c167ab4ea90bcdca1291a57 Mon Sep 17 00:00:00 2001 From: MegaCadeDev Date: Sun, 19 Jul 2026 10:25:19 -0400 Subject: [PATCH 42/42] v1.0.0.13a: Fix Steam Triton BLE pairing via Valve GATT. Skip HOGP for Triton, quiet CYW43 scans during BLE connect, and bump the firmware version after restoring input on Pico W. Co-authored-by: Cursor --- CHANGELOG.md | 6 +++ Firmware/FWDefines.cmake | 2 +- Firmware/RP2040/src/Bluepad32/Bluepad32.cpp | 41 ++++++++++++++++--- Firmware/cmake/patch_libs.cmake | 19 ++++++++- Firmware/external/bluepad32 | 2 +- .../patches/btstack_hids_num_reports.diff | 13 ++++++ 6 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 Firmware/external/patches/btstack_hids_num_reports.diff diff --git a/CHANGELOG.md b/CHANGELOG.md index 254a2b4f..0075052e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ Features and fixes added in this fork. For the latest firmware improvements (PS3 --- +### Version 1.0.0.13a + +- **Steam Controller 2026 (Triton) BLE — pair/input restored** — After DIS, Triton was stuck in HOGP (`hids_host_connect`) and never reached input. Match SDL/Android: skip standard HID-over-GATT and use Valve’s proprietary GATT service (`100F6C32-…`), enable notifications on input `0x45`/`0x47`, and resolve the connection handle from GATT packets (not the unused `channel` arg). Also quiet BR/LE scan during BLE connect and raise HID descriptor / HIDS report limits. **Files:** `uni_hid_parser_steam_triton.c`, `uni_bt_le.c`, `Bluepad32.cpp`, `uni_hid_device.h`, `btstack_hids_num_reports.diff`, `patch_libs.cmake`. + +--- + ### Version 1.0.0.12a - **DualShock 3 — USB → Bluetooth auto-pair restored** — Wiring a **DS3** into the adapter USB host again programs the pad with the Pico’s **BD_ADDR** (**HID feature `0xF5`**, same as sixaxispairer) so you can unplug and press **PS**. The PIO USB sync init path had marked init **DONE** before the old async **GET 0xF2** pair chain ran, so **`0xF5` never sent**. Fix: send **`0xF5` synchronously** right after **0xF4** + LED OUT (still deferred if the BT address is not ready yet). **Files:** `PS3.cpp` / `PS3.h` (USB host). See [IMPROVEMENTS.md](Firmware/RP2040/docs/IMPROVEMENTS.md) (*DualShock 3 — automatic USB programming for Bluetooth pairing*). diff --git a/Firmware/FWDefines.cmake b/Firmware/FWDefines.cmake index 4971ccb9..c8531f36 100644 --- a/Firmware/FWDefines.cmake +++ b/Firmware/FWDefines.cmake @@ -1,2 +1,2 @@ set(FW_NAME "OGX-Mini") -set(FW_VERSION "v1.0.0a11") \ No newline at end of file +set(FW_VERSION "v1.0.0.13a") diff --git a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp index 500e20f6..1bf47c40 100644 --- a/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp +++ b/Firmware/RP2040/src/Bluepad32/Bluepad32.cpp @@ -434,6 +434,19 @@ static void ogxm_resume_ble_ads_if_no_acl_pad(int disconnected_idx) { #endif } +/** CYW43: any active BLE gamepad link (HOGP or Triton Valve GATT) needs scans off. */ +static bool device_is_ble_hogp(const uni_hid_device_t* d) { + if (d == nullptr) + return false; + if (d->hids_cid != 0 && d->hids_cid != 0xffff) + return true; + /* Triton skips HIDS — still needs quiet radio while LE link is up. */ + if (uni_hid_parser_steam_triton_is_device(d) && d->conn.handle != UNI_BT_CONN_HANDLE_INVALID && + gap_get_connection_type(d->conn.handle) == GAP_CONNECTION_LE) + return true; + return false; +} + /** CYW43: periodic BR/EDR inquiry while a Classic ACL link is up can drop DS4/PS3 in ~1–2 s. */ static void maybe_restart_bredr_inquiry_after_disconnect(int disconnected_idx) { #if defined(CONFIG_TARGET_PICO_W) @@ -449,8 +462,8 @@ static void maybe_restart_bredr_inquiry_after_disconnect(int disconnected_idx) { continue; if (gap_get_connection_type(d->conn.handle) == GAP_CONNECTION_ACL) return; - /* Xbox Series BLE also stops BR inquiry (same radio contention). */ - if (d->controller_type == CONTROLLER_TYPE_XBoxOneController && d->hids_cid != 0) + /* Any BLE HOGP pad: keep BR inquiry off (same radio contention as Xbox). */ + if (device_is_ble_hogp(d)) return; } uni_bt_bredr_scan_start(); @@ -475,7 +488,7 @@ static void maybe_restart_ble_scan_after_disconnect(int disconnected_idx) { uni_hid_device_t* d = uni_hid_device_get_instance_for_idx(static_cast(i)); if (!d || uni_bt_conn_get_state(&d->conn) != UNI_BT_CONN_STATE_DEVICE_READY) continue; - if (d->controller_type == CONTROLLER_TYPE_XBoxOneController && d->hids_cid != 0) + if (device_is_ble_hogp(d)) return; /* Solo Switch Joy-Con keeps LE scan off while waiting for partner over Classic BT. */ if (uni_hid_parser_switch_solo_needs_partner(d)) @@ -502,11 +515,29 @@ static void bt_disconnect_reboot_cb(btstack_timer_source_t* ts) { static void restore_bt_pairing_mode(int disconnected_idx); #if defined(CONFIG_EN_BLUETOOTH) && defined(CONFIG_TARGET_PICO_W) +/** True while a BLE pad is connected but not yet DEVICE_READY (pairing / DIS / HIDS). */ +static bool any_ble_connect_in_progress() { + for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i) { + uni_hid_device_t* d = uni_hid_device_get_instance_for_idx(static_cast(i)); + if (!d || d->conn.handle == UNI_BT_CONN_HANDLE_INVALID) + continue; + if (uni_bt_conn_get_state(&d->conn) == UNI_BT_CONN_STATE_DEVICE_READY) + continue; + if (gap_get_connection_type(d->conn.handle) == GAP_CONNECTION_LE) + return true; + } + return false; +} + static bool is_pairing_idle() { #if defined(CONFIG_EN_USB_HOST) if (board_api::usb::host_any_pad_mounted()) return false; #endif + /* Mid HOGP discovery still looks "disconnected" to bt_devices_[], but scans + * must stay off or Triton's HIDS discovery never finishes. */ + if (any_ble_connect_in_progress()) + return false; return !any_connected(); } @@ -663,8 +694,8 @@ static uni_error_t device_ready_cb(uni_hid_device_t* device) { s_bt_any_connected_cached.store(true, std::memory_order_release); #endif #if defined(CONFIG_TARGET_PICO_W) - if (device->controller_type == CONTROLLER_TYPE_XBoxOneController && device->hids_cid != 0) { - /* CYW43439: BLE scan + BR inquiry during an active Xbox LE link causes supervision timeout. */ + if (device_is_ble_hogp(device)) { + /* CYW43439: BLE scan + BR inquiry during an active LE HOGP link stalls GATT / drops link. */ uni_bt_le_scan_stop(); uni_bt_bredr_scan_stop(); gap_advertisements_enable(0); diff --git a/Firmware/cmake/patch_libs.cmake b/Firmware/cmake/patch_libs.cmake index 368ddaf4..bd788691 100644 --- a/Firmware/cmake/patch_libs.cmake +++ b/Firmware/cmake/patch_libs.cmake @@ -20,6 +20,23 @@ function(apply_lib_patches EXTERNAL_DIR) message(FATAL_ERROR "Failed to apply BTStack patch: ${BTSTACK_PATCH_ERROR}") endif () + set(BTSTACK_HIDS_REPORTS_PATCH "${EXTERNAL_DIR}/patches/btstack_hids_num_reports.diff") + message(STATUS "Applying BTStack HIDS reports patch: ${BTSTACK_HIDS_REPORTS_PATCH}") + execute_process( + COMMAND git apply --ignore-whitespace ${BTSTACK_HIDS_REPORTS_PATCH} + WORKING_DIRECTORY ${BTSTACK_PATH} + RESULT_VARIABLE BTSTACK_HIDS_REPORTS_RESULT + OUTPUT_VARIABLE BTSTACK_HIDS_REPORTS_OUTPUT + ERROR_VARIABLE BTSTACK_HIDS_REPORTS_ERROR + ) + if (BTSTACK_HIDS_REPORTS_RESULT EQUAL 0) + message(STATUS "BTStack HIDS reports patch applied successfully.") + elseif (BTSTACK_HIDS_REPORTS_ERROR MATCHES "patch does not apply") + message(STATUS "BTStack HIDS reports patch already applied.") + else () + message(FATAL_ERROR "Failed to apply BTStack HIDS reports patch: ${BTSTACK_HIDS_REPORTS_ERROR}") + endif () + set(BLUEPAD32_PATCH "${EXTERNAL_DIR}/patches/bluepad32_uni.diff") set(BLUEPAD32_PATH "${EXTERNAL_DIR}/bluepad32") @@ -63,4 +80,4 @@ function(apply_lib_patches EXTERNAL_DIR) endif () endif () -endfunction() \ No newline at end of file +endfunction() diff --git a/Firmware/external/bluepad32 b/Firmware/external/bluepad32 index affea982..9c95e43a 160000 --- a/Firmware/external/bluepad32 +++ b/Firmware/external/bluepad32 @@ -1 +1 @@ -Subproject commit affea982ca2f564eece30bd53169e8dc00bddf6c +Subproject commit 9c95e43a87d3bd8a68565da0836d8a758bd8d8af diff --git a/Firmware/external/patches/btstack_hids_num_reports.diff b/Firmware/external/patches/btstack_hids_num_reports.diff new file mode 100644 index 00000000..6cc58d8b --- /dev/null +++ b/Firmware/external/patches/btstack_hids_num_reports.diff @@ -0,0 +1,13 @@ +diff --git a/src/ble/gatt-service/hids_host.h b/src/ble/gatt-service/hids_host.h +index de529831a..d02c067f1 100644 +--- a/src/ble/gatt-service/hids_host.h ++++ b/src/ble/gatt-service/hids_host.h +@@ -63,7 +63,7 @@ extern "C" { + #endif + #define HIDS_HOST_INVALID_REPORT_INDEX 0xFF + +-#define HIDS_HOST_NUM_REPORTS 15 ++#define HIDS_HOST_NUM_REPORTS 32 + + typedef enum { + HIDS_HOST_STATE_IDLE,