Flipper Zero Wii 扩展控制器协议分析器(wii_ec_anal)完全指南:接线、i2c 协议、屏幕场景与校准体系
【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper
导读
本文围绕 Flipper Zero 上的Wii Extension Controller Protocol Analyser(wii_ec_anal)插件展开,全面讲解如何将任天堂 Wii 双节棍(Nunchuck)、经典手柄(Classic Controller)等扩展控制器接入 Flipper Zero,通过 i2c 总线完成协议解析、实时数据显示、原始数据转储与软件校准。读完本文你将掌握:扩展控制器 6 针脚接线规范、i2c 初始化握手与寄存器布局、插件各屏幕场景的操作逻辑、完整的模拟量校准流程,以及如何基于源码结构扩展支持新的控制器类型。
插件定位:一个完整的"测试 + 校准"协议分析系统
该插件(Flipper 应用 ID:wii_ec_anal,参见 application.fam)不是一个简单的"读数据"工具,而是一套全功能的 Wii 扩展控制器测试与校准系统:
- 实时解析:将原始 i2c 字节流解码为可读的摇杆、按钮、加速度计数据;
- 场景化显示:为 Nunchuck、Classic Controller 提供专属可视化界面(
SCENE_NUNCHUCK、SCENE_CLASSIC),未知设备则统一进入原始数据 DUMP 界面; - 软件校准:可在运行时对模拟量(摇杆、加速度计、扳机键)进行中心点与行程极值的重新校准;
- 调试支撑:内置 DEBUG 屏幕与串口日志系统,便于协议逆向与问题排查。
需要强调的是,原文档明确给出免责声明:使用本插件(尤其是将扩展控制器连接到 Flipper Zero)的风险完全由使用者自行承担。截至文档写作时,插件仅在官方任天堂 Nunchuck 与 Classic Controller 上验证过。
关联文档:README.md,本文所有实操细节均以此为主干,并结合仓库源码进行展开。
硬件接线:WAIT 屏幕与 6 针脚映射
插件启动后首先进入SPLASH 启动画面(可按键清除,或 3.5 秒后自动消失),随后进入WAIT 等待画面。WAIT 屏幕会直接绘制出 Flipper Zero 与 Wii 扩展控制器之间的接线示意:
对照扩展控制器插头(从暴露面观察、凹口朝下),引脚定义如下:
| EC 引脚 # | EC 位置 | EC 引脚标识 | 引脚功能 | FZ GPIO 名称 | FZ GPIO 编号 |
|---|---|---|---|---|---|
| 1 | 左上 | +3v3 | 电源 | 3v3 | 9 |
| 2 | 左下 | SCL | i2c 时钟 | C0 | 16 |
| 3 | 上中 | EN | 疑似"存在检测" | ||
| 4 | 下中 | -x- | 无连接 | ||
| 5 | 右上 | SDA | i2c 数据 | C1 | 15 |
| 6 | 右下 | Gnd | 电源地 | Gnd | 18 |
接线要点:
- 实际必须接线的只有 4 根:3v3、Gnd、SCL(C0)、SDA(C1);
- 上中引脚(EN)被作者推测为"存在检测"(presence detect)功能,但尚未验证,且本插件并不需要它——设备检测是通过 i2c 握手完成的,见下文"初始化握手"一节;
- 设备连接成功后会被立即识别。若识别失败,通常有两种原因:控制器未正确连接(可能只是断线),或控制器内部电路板损坏(超出本插件排查范围)。
WAIT 画面按键:
Left(左键)— 回到 SPLASH 启动画面;Back(返回键)— 退出插件。
适配器(WiiChuck / Nunchucky)与方向警示
对于大多数玩家,最省事的连接方式是使用WiiChuck或Nunchucky一类的转接板(将扩展控制器插头转为杜邦线排针)。但这两类适配器都没有防反插机制——一旦插反,会以错误的极性向控制器供电。
作者给出的经验法则(适用于见过的所有 WiiChuck):
- WiiChuck 一侧有 3 个连接器,另一侧有 2 个;
- 有 2 个连接器的一侧应对准控制器插头上带大凹槽的一侧;
- 插头示意图(注意缺失的引脚与凹槽):
+-------------+ | _________ | | | = = = | | | |_=_____=_| | <-- notice missing pin | ___ | | | | | <-- notice indent +----+ +----+作者同时强调:强烈建议在接线前自行核对适配器引脚定义,因为接反电压可能永久损坏控制器。上方的缺失引脚(即 EN 检测脚)在插头上并不连通。
i2c 协议基础:从寄存器布局到初始化握手
理解了接线后,我们来剖析插件底层真正的核心——wii_i2c.c中实现的 i2c 通信层(wii_i2c.c)。
总线参数与地址
- 总线:Flipper Zero 的外部 i2c 总线(
furi_hal_i2c_handle_external,见 wii_i2c.h); - 设备地址:
0x52,注意 FZ 的 read/write 函数需要传入(7bitAddress << 1),即实际调用时使用0x52 << 1; - 超时:
i2cTimeout = 3ms;读等待:i2cReadWait = 300µs(在写地址与读数据之间插入延时,部分设备对读请求响应较慢)。
寄存器映射
Wii 扩展控制器的寄存器布局(读取时寄存器地址自动递增):
| 寄存器段 | 长度 | 方向 | 含义 |
|---|---|---|---|
0x00..0x05 | 6 字节 | 读 | 控制器实时数据(摇杆/按钮/加速度原始值) |
0x20..0x2F | 16 字节 | 读 | 出厂校准数据 |
0x30..0x3F | 16 字节 | 读 | 出厂校准数据的副本 |
0x40..0x4F | 16 字节 | 写 | 加密密钥(PSK,2×8 字节) |
0xFA..0xFF | 6 字节 | 读 | 外设 ID(PID,用于识别设备类型) |
对应到源码中的常量(见 wii_ec.h):
#define ENC_LEN (2*8) // 加密密钥长度,寄存器 0x40..0x4F #define JOY_LEN (6) // 控制器状态数据,寄存器 0x00..0x05 #define CAL_LEN (16) // 校准数据,寄存器 0x20..0x2F #define PID_LEN (6) // 控制器 ID,寄存器 0xFA..0xFF初始化握手(encryption-bypass 策略)
ecInit()(wii_i2c.c)的完整流程为:
- 探测设备:
furi_hal_i2c_is_device_ready()检查0x52是否在线; - 发送两条初始化命令(这是让控制器进入"未加密直通模式"的关键):
static const uint8_t regInit1 = 0xF0; static const uint8_t regInit2 = 0xFB; static const uint8_t cmdInit1[] = {regInit1, 0x55}; // i2c_write(0xf0, 0x55) static const uint8_t cmdInit2[] = {regInit2, 0x00}; // i2c_write(0xfb, 0x00)即文档中所说的i2c_write(0xf0, 0x55); i2c_write(0xfb, 0x00)——这是本插件正常工作的前提;
- 读取 6 字节 PID(寄存器
0xFA),与已知设备表比对,确定控制器类型; - 读取 16 字节出厂校准数据(寄存器
0x20),并调用ecCalibrate(pec, CAL_RESET | CAL_FACTORY)加载工厂校准; - 初始化解码双缓冲并做首次读取,使新旧两份解码数据一致,便于后续"变化检测"。
加密(Encryption)的现状与限制
Wii 官方加密协议使用位于0x40..0x4F的 2×8 字节 PSK 密钥,解密算法为:
// decrypted_byte = (encrypted_byte XOR encKey[1][address%8]) + encKey[2][address%8] *p = (*p ^ encKey[(reg + (p - buf)) % 8]) + encKey[8 + ((reg + (p - buf)) % 8)];请务必注意:原文档明确声明——"本插件有部分加密处理代码,但未使用、未测试,且已知其中部分无法工作"。插件目前仅支持实现加密绕过策略(encryption-bypass)的扩展控制器。如果你确实需要加密通信支持,应通过 Issue 或 Pull Request 参与完善(源码中ecInit()的加密分支已标注多处//! this encryption code fails注释)。
设备识别:已知控制器表与 info.sh
设备识别基于ecId[]查找表(定义于 wii_ec.c,类型定义见 wii_ec.h)。每个条目由 6 字节 ID、可读名称、默认场景以及一组函数指针(init/decode/check/calib/show/keys)组成。
运行./info.sh(info.sh)可查看当前支持的控制器,输出如下:
[PID_UNKNOWN ] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "Unknown Perhipheral", SCENE_DUMP, [PID_NUNCHUCK ] = { {0x00, 0x00, 0xA4, 0x20, 0x00, 0x00}, "Nunchuck", SCENE_NUNCHUCK, [PID_CLASSIC ] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x01}, "Classic Controller", SCENE_CLASSIC, [PID_BALANCE ] = { {0x00, 0x00, 0xA4, 0x20, 0x04, 0x02}, "Balance Board", SCENE_DUMP, [PID_GH_GUITAR ] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x03}, "Guitar Hero Guitar", SCENE_DUMP, [PID_GH_DRUMS ] = { {0x01, 0x00, 0xA4, 0x20, 0x01, 0x03}, "Guitar Hero World Tour Drums", SCENE_DUMP, [PID_TURNTABLE ] = { {0x03, 0x00, 0xA4, 0x20, 0x01, 0x03}, "DJ Hero Turntable", SCENE_DUMP, [PID_TAIKO_DRUMS] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x11}, "Taiko Drum Controller)", SCENE_DUMP,结合源码可以看到,ecId[]实际包含的条目更多、也更完整:除上述设备外,还有PID_NUNCHUCK_R2(Nunchuck rev2,ID 首字节为0xFF)、PID_CLASSIC_PRO(Classic Controller Pro,ID 首字节为0x01)、PID_UDRAW(uDraw 平板,仅有udraw_init而无 decode/scene)、PID_ERROR(读错误)与PID_NULL(表尾哨兵)。设备类型枚举ecPid及场景枚举scene分别定义于 wii_ec.h 与 wii_anal.h。
识别结论:共 8 个已知 ID(PID_UNKNOWN为未知设备兜底;7 个具名设备中,只有 Nunchuck 与 Classic Controller 两个拥有专属场景SCENE_NUNCHUCK/SCENE_CLASSIC),其余设备统一落入SCENE_DUMP原始数据界面。匹配逻辑位于ecInit():从PID_FIRST遍历到PID_ERROR,memcmp比对 6 字节 ID,未命中则标记为PID_UNKNOWN。
屏幕场景体系与按键操作
插件采用多场景 GUI 架构,场景枚举scene_t(wii_anal.h)包含:SCENE_NONE、SCENE_SPLASH、SCENE_RIP、SCENE_WAIT、SCENE_DEBUG、SCENE_DUMP、SCENE_CLASSIC、SCENE_CLASSIC_N、SCENE_NUNCHUCK、SCENE_NUNCHUCK_ACC。
SPLASH 启动画面
插件启动时显示,按任意键清除,否则 3.5 秒后自动消失。
WAIT 等待画面
已在上文"硬件接线"一节详述,显示引脚映射并等待控制器接入。
NUNCHUCK 主界面
连接 Nunchuck 后进入,实时显示:
- 加速度计
Accelerometer{X,Y,Z}值; - 摇杆
Joystick{X,Y}值与摇杆位置图形; - 按钮
Button{C,Z}状态。
按键映射:
| 按键 | 功能 |
|---|---|
| Left | 进入 DUMP 原始数据界面 |
| Right | 进入 NUNCHUCK_ACC 加速度计界面 |
| Up / Down / OK | 参见下文"Peak Meters" |
| 短按 Back | 重置控制器 |
| 长按 Back | 退出插件 |
NUNCHUCK 加速度计界面(NUNCHUCK_ACC)
轴方向约定:
| 轴 | 运动方向 | 较低读数 | 较高读数 |
|---|---|---|---|
| X | 左 / 右 | 左 | 右 |
| Y | 前 / 后 | 前 | 后 |
| Z | 下 / 上 | 下 | 上 |
解读规则:
- 沿某轴平动 → 改变该轴读数;
- 绕某轴转动/倾斜 → 改变另外两轴的读数;
- 例:向左平移(沿 X 轴)只影响 X;向左转(绕 Y 轴旋转)则同时影响 X 与 Z。
按键映射:
| 按键 | 功能 |
|---|---|
| Left | 返回 NUNCHUCK 主界面 |
| Up | Auto-Pause 已禁用 → 启用;页面末尾暂停时 → 重启扫描;Auto-Pause 已启用时运行中 → 禁用 |
| Nunchuck-Z | 切换暂停(Pause) |
| Nunchuck-C | 切换自动暂停(Auto-Pause) |
| 长按 OK | 进入软件校准模式(加速度计界面下仅校准加速度计) |
| 短按 OK | 退出软件校准模式,并校准 CENTRE 中心位置 |
| 短按 Back | 重置控制器 |
| 长按 Back | 退出插件 |
说明:源码中确实存在屏幕滚动显示代码,但 LCD 刷新率过低、效果不佳,因此未启用(见 notes.txt 中的波形绘制代码注释)。
CLASSIC 经典手柄界面
连接 Classic Controller(Pro)后,屏幕绘制一个经典手柄图形,并随控制器事件实时动画。扫描率设定为 30fps,但受 LCD 延迟影响实际体验因人而异。
| 按键 | 功能 |
|---|---|
| Left | 进入 DUMP 界面 |
| Right | 显示模拟量读数(再次按 Left 隐藏) |
| Up / Down / OK | 参见"Peak Meters" |
| 短按 Back | 重置控制器 |
| 长按 Back | 退出插件 |
DUMP 原始数据界面
所有未知设备(以及无专属_decode()的设备)只能看到此界面。它展示:
- SID:String ID,设备可读名称(来自
ecId表); - PID:Peripheral ID,识别设备的 6 字节 ID;
- Cal:16 字节出厂校准数据;
- 底部六字节:控制器实时数据,每字节十六进制上方是对应的二进制位图形。例如连接 Nunchuck 时按下 Z 按钮,可观察最右侧位的变化(Z 按钮位于 joy[5] 的 bit0,见 wii_ec_nunchuck.c)。
按键:
| 按键 | 功能 |
|---|---|
| Right | 返回控制器专属界面(若存在) |
| 短按 Back | 重置控制器 |
| 长按 Back | 退出插件 |
Peak Meters:峰值/谷值视图
在任何带 Peak/Trough 菜单的控制器专属界面上:
| 按键 | 功能 |
|---|---|
| Up | 切换:仅显示峰值(peak) |
| Down | 切换:仅显示谷值(trough) |
| 长按 OK | 进入软件校准模式 |
| 短按 OK | 退出软件校准模式 / 校准 CENTRE 中心位置 |
校准体系:工厂校准与软件校准
为什么需要校准
- 数字按钮无需校准;
- 部分控制器带出厂校准数据(疑似存储于控制器 OTP 中),例如 Classic Controller有出厂校准,而 Classic Controller Pro没有;
- 不同设备对校准数据的解读方式不同:Nunchuck 是 1 摇杆 + 加速度计,Classic Controller 是 2 摇杆 + 2 模拟扳机;
- 作者实测发现出厂校准数据可能不准确("控制器用久了会漂移")。若工厂值限制了行程,可通过在运行时扩展来解决;但若工厂数据给出的行程超出摇杆物理可达范围,就必须对控制器做完整重校准。
推荐的校准方法
- 控制器静止、水平放置时采集读数作为基准;
- 将控制器推到所有方向极限,记录各轴的极值(peak/trough)。
背景知识(文档提及):任天堂据称会在控制器刚连接时采集"静止"读数,且在任何时刻同时按住 {A、B、+、-} 至少 3 秒可触发"重校准",但文档作者并未掌握其具体行为细节。
本工具的实际校准流程
- 设备首次识别时:使用工厂校准数据决定每个模拟控制的中心/中间位置与极值(如最左、最右);
- 长按 OK(FlipperZero 端)——进入软件校准模式,注意按下期间不要触碰任何模拟控制:
- 校准按钮开始闪烁;
- 取当前读数作为中心位置;
- 将范围极限设为"无范围";
- 现在需要在各控制的两个极限之间移动,让代码记录新的校准/范围/峰谷值;
- 完成后按短按 OK退出软件校准模式;
- 短按 OK(FlipperZero 端)——同样不要触碰模拟控制:
- 停止校准按钮闪烁;
- 校准所有模拟控制的中心位置(加速度计暂不支持中心校准)。
从源码看,校准策略由ecCalib枚举(wii_ec.h)驱动:
typedef enum ecCalib { CAL_FACTORY = 0x01, // (re)set to factory defaults CAL_TRACK = 0x02, // track maximum and minimum values seen CAL_RESET = 0x04, // initialise ready for software calibration CAL_RANGE = 0x08, // perform software calibration step CAL_CENTRE = 0x10, // reset centre point of joystick CAL_NOTJOY = 0x20, // do NOT calibrate the joystick } ecCalib_t;软件校准数据在每个设备中以 5 个槽位组织(0=最低见过值;1=min;2=mid;3=max;4=最高见过值,见 wii_ec.h 的ecCal联合体注释)。Nunchuck 的校准实现(wii_ec_nunchuck.c)在CAL_RESET时会将 LO 置为最大值(10bit 值上限)、HI 置为零,以便后续通过扫描逐步收敛到真实行程。
事件驱动架构:从轮询到消息队列
插件并非简单死循环读寄存器,而是由定时器驱动的事件驱动架构:
- 状态结构体
state_t(wii_anal.h)包含定时器(timer/timerHz/fps)、当前/前一场景、校准状态、暂停标志、通知队列(用于拍打背光看门狗)与wiiEC_t控制器状态; - 轮询核心是
ecPoll()(wii_ec.c):- 未初始化时尝试
ecInit(),成功后向消息队列投递WIIEC_CONN连接事件; - 已初始化时调用
ecRead(),根据返回值处理:2= 设备断开,投递WIIEC_DISCONN;0= 读取成功,调用设备专属check()函数;3= 瞬时读失败,直接忽略;其余为不应发生的 bug 分支;
- 未初始化时尝试
- 事件类型枚举
wiiEcEventType(wii_ec.h):WIIEC_NONE、WIIEC_CONN、WIIEC_DISCONN、WIIEC_PRESS、WIIEC_RELEASE、WIIEC_ANALOG(摇杆/扳机变化)、WIIEC_ACCEL(加速度变化); - Nunchuck 的
nunchuck_msg()通过宏BUTTON()/ANALOG()/ACCEL()将新老解码数据逐项比对,仅在变化时投递对应事件(wii_ec_nunchuck.c)。
Nunchuck 原始字节的解码逻辑(nunchuck_decode())很值得参考:6 字节中,joy[0]/joy[1]直接对应摇杆 XY,joy[5]的低 2 位是按钮 C/Z(取反,低电平有效),而加速度计的 10bit 精度由高 8 位字节与joy[5]中的高位拼接而来:
p->accX = ((uint16_t)joy[2] << 2) | ((joy[5] >> 2) & 0x03); // {10} p->accY = ((uint16_t)joy[3] << 2) | ((joy[5] >> 4) & 0x03); // {10} p->accZ = ((uint16_t)joy[4] << 2) | ((joy[5] >> 6) & 0x03); // {10}DEBUG 屏幕与日志系统
在除 SPLASH 外的任意屏幕长按 Down进入 Debug 模式:
- 进入后实时扫描停止;
Up— 尝试初始化已连接的控制器;OK— 从控制器读取一次数据;长按 Down— 重启实时扫描并返回 WAIT 屏幕。
日志查看方式:通过 USB 连接 Flipper Zero,使用串口终端(minicom、putty等)启动log功能即可看到调试消息。
日志级别可在编译期通过LOG_LEVEL限制(bc_logging.h),也可在运行期通过FZ -> Settings -> System -> LogLevel调整:
- FURI 日志共 6 级(1=None,2=Errors,3=Warnings,4=Information,5=Debug,6=Trace);
LOG_LEVEL < N时对应宏会被替换为空操作,从而减小插件体积(文档特别提示:自 FAP 支持引入后,编译期裁剪对体积的意义可能已经不大);- 源码默认
#define LOG_LEVEL 4,且注释警告:若同时将编译期与运行期日志都开到 TRACE(6),插件退出时可能导致 FZ 崩溃。
用
./info.sh可一键查看源码中所有LOG_LEVEL的使用点与 TODO 标记。
源码结构:从文件清单到"新增一款控制器"
仓库 wii_ec_anal 目录(开发笔记见 README.txt)组织如下:
| 文件 | 职责 |
|---|---|
README.md /_images/ | 用户手册正文与配图 |
| application.fam | FAP 清单:appid="wii_ec_anal",类别GPIO_Extra,图标WiiEC.png,源码通配wii_*.c+gfx/*.c,栈 2KB |
wii_anal.c /.h | 主应用:场景机、事件循环、状态管理 |
wii_anal_ec.c /.h | 扩展控制器相关动作 |
wii_anal_keys.c /.h | 按键处理 |
wii_anal_lcd.c /.h | LCD 绘制函数 |
wii_i2c.c /.h | i2c 通信层(初始化/读取/解密) |
wii_ec.c /.h | 扩展控制器通用函数与ecId[]设备表 |
wii_ec_nunchuck.c /.h | Nunchuck 专属场景 |
wii_ec_classic.c /.h | Classic Controller Pro 专属场景 |
wii_ec_udraw.c /.h | uDraw 场景(未完成) |
| i2c_workaround.h | FZ i2c 库 bug 的临时绕行方案 |
| bc_logging.h / err.h | 日志宏与错误定义 |
| info.sh | 从源码提取支持列表/日志级别/TODO |
为插件添加新的扩展控制器类型
开发笔记(README.txt)给出了标准扩展流程(以新增 "mydev" 为例):
- 新建
wii_ec_mydev.c与wii_ec_mydev.h,实现以下函数(含原型):bool mydev_init(wiiEC_t*)— 额外初始化代码;void mydev_decode(wiiEC_t*)— 解码控制器输入数据;void mydev_msg(wiiEC_t*, FuriMessageQueue*)— 向事件队列投递消息;void mydev_calib(wiiEC_t*, ecCalib_t)— 校准函数;void mydev_show(Canvas*, state_t*)— 场景 LCD 绘制;bool mydev_key(const eventMsg_t*, state_t*)— 场景按键处理;
- 在 wii_ec.h 中
#include "wii_ec_mydev.h",并在enum ecPid增加PID_MYDEV; - 在 wii_anal.h 的
enum scene中增加SCENE_MYDEV; - 在 wii_ec.c 的
ecId[]表中注册设备:
[PID_MYDEV] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "My Device", SCENE_MYDEV, mydev_init, mydev_decode, mydev_msg, mydev_calib, mydev_show, mydev_key },这就是ecId_t中那组函数指针(init/decode/check/calib/show/keys)的实际用法——插件正是通过这张"设备驱动表"实现了解码、消息、校准、绘制与按键的多态分发(顶层ecDecode()/ecCalibrate()先判断对应函数指针是否存在再调用,见 wii_ec.c)。
已知问题与限制(TODO)
原文档在 TODO 一节记录了一个重要问题,并在源码中留有对应证据:
- FZ i2c bug:写作当时 FlipperZero 固件的 i2c 库存在缺陷,本插件通过 i2c_workaround.h 提供临时绕行——所有 i2c 调用被包装为"acquire → 操作 → release"的形式(
furi_hal_Wi2c_is_device_ready/tx/rx/trx),并额外提供带读延时的furi_hal_i2c_trxd()。notes.txt中还保留了完整的修复参考代码与"region locking"的固件定位线索。
其余已知限制(文档与源码交叉确认):
- 加密功能未使用、未测试且部分不可用,仅支持 encryption-bypass 控制器;
- 仅官方 Nunchuck 与 Classic Controller 得到实际验证;uDraw 设备仅注册了
udraw_init,场景未编写; - LCD 滚动显示因刷新率不足被禁用;
- 加速度计暂不支持软件校准中心点(
CAL_CENTRE注释为 "accelerometers not supported (yet)")。
结语:一份可复用的 i2c 外设分析范本
wii_ec_anal 的价值不仅在于"能读双节棍数据":它的多场景 GUI + 事件驱动轮询 + 设备驱动表 + 双缓冲解码 + 工厂/软件双层校准设计,为在 Flipper Zero 上逆向与调试任何 i2c 外设提供了一个高完成度的参考范本。无论你是想直接用它测试手中的 Nunchuck/Classic 手柄,还是想照葫芦画瓢为自己的扩展控制器写一个专属场景,本文结合 README.md 与源码给出的接线表、寄存器映射、初始化握手与校准流程,都能作为你起步的地图。
【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考