Add ESP32 Joy-Con bridge serial reader

Adds app-side support for the ESP32-WROOM-32 Joy-Con bridge over USB
serial. The ESP32 pairs with the Joy-Con via Bluetooth Classic (using
Bluepad32), parses input reports, and streams an 11-byte wire protocol
frame at 60 Hz over the CP2102's USB-CDC serial connection.

ControllerManager now auto-detects known USB-serial chips (CP2102,
CH340, Espressif native USB) by VID/PID, opens the port at 115200 8N1
via usb-serial-for-android, and parses incoming frames into the same
dispatchButton / onAnalogEvent pipeline used by all other controller
paths. Frame format: [0xA5 sync] [seq] [btns_lo] [btns_hi] [dpad hat]
[lx] [ly] [rx] [ry] [flags] [XOR crc8].

Verified stable for 10+ minutes with zero disconnects on the Samsung
Fold 6 — the 8BitDo USB adapter wedged within 2 minutes on the same
phone. Full firmware control eliminates the OTG selective-suspend issue
that plagued the adapter path.
This commit is contained in:
2026-04-12 15:57:30 -04:00
parent 2154f7fd3c
commit 89f590480f
5 changed files with 275 additions and 1 deletions

View File

@@ -15,6 +15,7 @@ coroutines = "1.10.2"
windowSizeClass = "1.3.2"
datastorePrefs = "1.1.4"
coil = "2.7.0"
usbSerial = "3.9.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -51,6 +52,9 @@ datastore-prefs = { group = "androidx.datastore", name = "datastore-preferences"
# Coil (image loading)
coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" }
# USB serial (ESP32 Joy-Con bridge)
usb-serial = { group = "com.github.mik3y", name = "usb-serial-for-android", version.ref = "usbSerial" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }