fernandoalves25/sf900-esp32-dongle
GitHub: fernandoalves25/sf900-esp32-dongle
该项目将ESP32-S3打造成适用于R36S等复古掌机的双模USB dongle,兼具SF900无线手柄接收器和USB Wi-Fi网卡功能。
Stars: 0 | Forks: 0
# SF900 ESP32 Dongle — R36S(及类似设备)的无线手柄接收器 + Wi-Fi dongle
将 **ESP32-S3** 变成适用于 R36S / R36H 等运行 ArkOS / dArkOS / ROCKNIX 的复古掌机的**双模式 USB dongle**:
- 🎮 **无线手柄接收器** — 接收 **Data Frog SF900 / SF2000** 2.4 GHz 控制器信号,并将其作为标准的 **USB-HID gamepad** 呈现给主机。
- 📶 **USB Wi-Fi dongle** — 作为 **USB RNDIS 网络适配器**呈现(支持在 R36S Linux 和 Windows 10 上使用),让没有 Wi-Fi 的掌机能够联网进行资料抓取、RetroAchievements、联机游戏和 ROM 传输。
- 🔁 **单板实现双重功能**,通过在手柄上长按 **L + R + SELECT**(约 1.5 秒)即可即时切换。上次使用的模式在重启后会被记住。
## 为什么会有这个项目
SF900 控制器和 SF2000 风格的掌机使用 **Panchip XN297L** 收发器(一种类似 nRF24 的芯片)通过专有的 2.4 GHz 链路进行通信。以前没有开源的接收器可以插到*其他*掌机上使用。同时,R36S 没有内置 Wi-Fi。这个项目用一个便宜的单块 ESP32-S3 解决了这两个问题。
其 RF 协议本身由 **[axgdev/UniFrog](https://github.com/axgdev/UniFrog)** 逆向工程得出 —— 本仓库在 ESP32 上重新实现了该协议,并增加了 USB-HID 和 Wi-Fi dongle 功能。
## 仓库结构
```
firmware/
esp32s3-gamepad/ SF900 receiver -> USB-HID gamepad (boots in OTA slot 0)
esp32s3-wifi-dongle/ USB RNDIS Wi-Fi dongle + mode-switch watcher (OTA slot 1)
xn297-selftest/ bring-up tools: SPI selftest, RSSI band scanner, SF900 receiver-to-serial
xn297-sniffer/ passive SPI-slave sniffer (for reverse-engineering other controllers)
docs/
PROTOCOL.md the SF900 / SF2000 RF protocol, fully documented
XN297-TRANSPLANT.md how the radio was cut from a dead SF2000 and validated
WIRING.md pinout / connections (ESP32-S3 <-> XN297L)
scripts/
flash-dual-mode.ps1 flash both firmwares into the two OTA slots (Windows)
flash-dual-mode.sh same, for Linux/macOS
```
## 硬件说明
- **ESP32-S3** 开发板(利用原生 USB 端口作为手柄/网络接口)。
- **XN297L / XN297LBW** 2.4 GHz 模块 + 16 MHz 晶振 + 天线。可以使用现成模块,或者从损坏的 SF2000 板上移植(请参阅移植指南)。
- 一个 **USB-C OTG 转接器**,用于将开发板的原生 USB 接口连接到掌机底部的端口。
接线(3-wire SPI,请参见 [docs/WIRING.md](docs/WIRING.md)):
| XN297L | ESP32-S3 | 功能 |
|--------|----------|------------------|
| CSN | GPIO10 | FSPICS0 |
| SCK | GPIO12 | FSPICLK |
| DATA | GPIO11 | FSPID (3-wire) |
| VDD | 3V3 | 仅限 2.3–3.3 V |
| VSS | GND | 接地 |
## 编译与烧录
需要安装 [PlatformIO](https://platformio.org/)(首次编译时会自动拉取 ESP-IDF 平台)。
```
# gamepad 固件
cd firmware/esp32s3-gamepad && pio run
# wifi dongle 固件
cd firmware/esp32s3-wifi-dongle && pio run
```
要获取**双模式**设置(两个 OTA 插槽中分别包含两个固件,默认先启动手柄固件),请分别编译两者,然后运行烧录脚本:
```
# Windows (PowerShell) — 在脚本内调整 COM 端口
scripts\flash-dual-mode.ps1 -Port COM19
```
```
# Linux / macOS
scripts/flash-dual-mode.sh /dev/ttyACM0
```
该脚本会写入:bootloader、分区表、`ota_0`=手柄固件、`ota_1`=Wi-Fi 固件,并擦除 `otadata`,从而使开发板优先启动手柄固件。
## 使用方法
1. 通过 USB-C OTG 转接器,将开发板的**原生 USB** 接口插入掌机。
2. **手柄模式(默认):** 打开 SF900 控制器即可开始游玩。掌机会将其识别为标准 HID gamepad(D-pad 映射在 hat switch 上,A/B/X/Y/L/R/SELECT/START 映射在按键 0–7 上)。
3. **切换至 Wi-Fi 模式:** 在控制器上长按 **L + R + SELECT** 约 1.5 秒。Dongle 将重启为 USB 网络适配器。通过其 USB-serial 控制台配置一次 Wi-Fi:`sta -s -p `(仅限 2.4 GHz)。凭据将被保存。
4. **切换回来:** 再次长按 **L + R + SELECT**。开发板会记住上一次使用的模式。
## 模式切换原理
USB 设备描述符在编译时是固定的,因此同一个二进制文件无法*同时*作为网络设备和 HID gamepad。相反,这两个固件分别存放在**两个 OTA app 插槽**中;长按组合键会调用 `esp_ota_set_boot_partition()` 并重启进入另一个插槽。每个固件都会监听控制器上的组合键(Wi-Fi 固件会运行一个微型的后台 XN297 监听器,不会干扰 Wi-Fi 运行)。
## 当前状态
这里的所有功能都**已在真实硬件上验证并正常工作**:SPI 自检通过;RSSI 扫描仪能在 4/29/49/79 信道上看到控制器;按键解码正确;USB-HID gamepad 被 Windows 和掌机成功识别;RNDIS Wi-Fi dongle 可以正常联网;并且双向模式切换均有效。
## 致谢
- **[axgdev/UniFrog](https://github.com/axgdev/UniFrog)** — 逆向工程了 SF900/SF2000 的 RF 协议。没有它就没有这个项目。
- **[Espressif esp-iot-solution](https://github.com/espressif/esp-iot-solution)** — Wi-Fi 端是基于其 `usb_dongle` 示例构建的。
- **Panchip** — XN297L 数据手册。
- R36S / ArkOS / dArkOS4Clone / ROCKNIX 社区。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。捆绑的第三方组件保留其各自的许可证(Apache-2.0 / MIT);署名信息请参见 LICENSE 文件。
标签:ESP32, 云资产清单, 客户端加密, 嵌入式开发, 游戏外设, 物联网硬件, 网络安全监控, 逆向工程, 驱动开发