From fc307f79cff197b768139580bfcb94969de787bc Mon Sep 17 00:00:00 2001 From: kevin Date: Sun, 26 Apr 2026 23:04:23 +0800 Subject: [PATCH] Signed-off-by: kevin --- .workbuddy/expert-history.json | 17 -------- .workbuddy/memory/2026-04-26.md | 18 +++++++++ .workbuddy/memory/MEMORY.md | 29 +++++++++++++ PCB/Moonshine_travelers.eprj2 | Bin 5869568 -> 5869568 bytes .../src/input/TCA9535ButtonThread.cpp | 38 +++++++++++++----- .../src/input/TCA9535ButtonThread.h | 20 +++++---- .../esp32c3_moonshine_travelers_3/variant.h | 3 +- 7 files changed, 91 insertions(+), 34 deletions(-) delete mode 100644 .workbuddy/expert-history.json create mode 100644 .workbuddy/memory/2026-04-26.md diff --git a/.workbuddy/expert-history.json b/.workbuddy/expert-history.json deleted file mode 100644 index eba2273..0000000 --- a/.workbuddy/expert-history.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 2, - "sessions": { - "17e27f37a08d4079971bed834cd7a702": [ - { - "expertId": "EmbeddedFirmwareEngineer", - "name": "固件通", - "profession": "嵌入式固件工程师", - "avatarUrl": "https://acc-1258344699.cos.accelerate.myqcloud.com/workbuddy/experts/avatars/02-Engineering/EmbeddedFirmwareEngineer/EmbeddedFirmwareEngineer.png", - "promptUrl": "https://acc-1258344699.cos.accelerate.myqcloud.com/workbuddy/experts/experts/02-Engineering/EmbeddedFirmwareEngineer/EmbeddedFirmwareEngineer_zh.md", - "usedAt": 1776444279306, - "industryId": "all" - } - ] - }, - "lastUpdated": 1776444603959 -} \ No newline at end of file diff --git a/.workbuddy/memory/2026-04-26.md b/.workbuddy/memory/2026-04-26.md new file mode 100644 index 0000000..f1ebe88 --- /dev/null +++ b/.workbuddy/memory/2026-04-26.md @@ -0,0 +1,18 @@ +# 2026-04-26 工作日志 + +## 固件工程架构梳理 +- 工程路径:`code/firmware-2.7.15.567b8ea` +- 版本:Meshtastic v2.7.15,基于 PlatformIO 构建 +- 支持平台:ESP32 / nRF52 / RP2040 / RP2350 / Linux (Portduino) +- 路由层级:ReliableRouter → NextHopRouter → FloodingRouter → Router +- 定制点:TCA9535 I²C IO 扩展器用于代理 LoRa RST(P1.4)、GPS EN(P1.7)和 POWER_EN 引脚控制 +- 自定义文件:`src/input/TCA9535ButtonThread.cpp/.h`(I²C 按键驱动,约16KB+12KB) +- main.cpp 中有 TCA9535GpioHal 自定义 HAL 类,拦截虚拟引脚转发到 I²C + +## P1.6 振子震动功能实现 +- 变体:`variants/esp32c3/diy/esp32c3_moonshine_travelers_3` +- P1.6 原为 GPS RST,改为振子(VIBRATOR),高电平震动,低电平停止 +- 改动文件: + - `src/input/TCA9535ButtonThread.h`:`tca9535GpsReset()` → `tca9535Vibrate()`,添加 `_vibrateOn`/`_vibrateStartMs` 成员 + - `src/input/TCA9535ButtonThread.cpp`:init() 开机后触发 300ms 震动;runOnce() 关机时触发 300ms 震动;振子超时自动停止逻辑在 runOnce() 开头 + - `variants/.../variant.h`:注释更新 diff --git a/.workbuddy/memory/MEMORY.md b/.workbuddy/memory/MEMORY.md index e69de29..15a4abb 100644 --- a/.workbuddy/memory/MEMORY.md +++ b/.workbuddy/memory/MEMORY.md @@ -0,0 +1,29 @@ +# MEMORY.md - 项目长期记忆 + +## 当前固件工程 + +- **路径**:`code/firmware-2.7.15.567b8ea` +- **版本**:Meshtastic v2.7.15(PlatformIO 工程) +- **支持平台**:ESP32 / nRF52 / RP2040 / RP2350 / Linux(Portduino) +- **构建系统**:PlatformIO,默认目标 `tbeam`,variants/ 目录存放各板型配置 + +## 自定义硬件扩展(重要!) + +### TCA9535 I²C IO 扩展器 +用于代理几个不能直连 MCU GPIO 的关键引脚: +- **P1.4** → LoRa 模块 RST(通过 `TCA9535GpioHal` 自定义 HAL 拦截 RadioLib 调用) +- **P1.6** → 振子 VIBRATOR(高电平震动):开机/关机各震动 300ms(变体 esp32c3_moonshine_travelers_3) +- **P1.7** → GPS 使能引脚(`GpioTca9535GpsEnPin` 包装) +- **POWER_EN** → 上电保持(早期 boot 时即拉高,防止松开按键后 MOS 断电) + +### 自定义文件 +- `src/input/TCA9535ButtonThread.cpp` / `.h`:I²C 按键驱动(~16KB + ~12KB) +- `src/main.cpp`:含 TCA9535GpioHal 类定义、GPS EN 替换逻辑、TCA9535 按键线程初始化 + +## 工程架构要点 + +- **路由层级**:ReliableRouter → NextHopRouter → FloodingRouter → Router +- **Mesh 服务**:MeshService 连接射频收发、手机 API、GPS、模块系统 +- **模块系统**:setupModules() 统一初始化,各模块通过 MeshModule 订阅数据包端口 +- **线程调度**:基于 concurrency::OSThread + Periodic,loop() 中 mainController.runOrDelay() +- **消息协议**:Protobuf(protobufs/ 目录),生成代码在 src/mesh/generated/ diff --git a/PCB/Moonshine_travelers.eprj2 b/PCB/Moonshine_travelers.eprj2 index 51b960c1a57f21916dc13650dc8b11a0a662287f..079ac81865a0ffb7880cdadf23905fa91e2e7c00 100644 GIT binary patch delta 288 zcmWN=MOH!q06@|6F+s&ZEW%C@yTPIqyLI-Kf`d0!cEBdwl5=*T_ncdA{)X!RzY{^L zkt_zSPb83#v`M>kNT+m3w}d4kJ<=kNT+m3w}d4kJ<== TCA9535_POWER_BOOT_HOLD_MS) { LOG_WARN("TCA9535: Power button held %lu ms -> SHUTDOWN", held); _powerBtnPressStart = 0; + // 关机震动 300ms,震动结束后由振子超时逻辑触发 SHUTDOWN 事件 + if (!_vibrateOn) { + tca9535Vibrate(true); + _vibrateOn = true; + _vibrateStartMs = millis(); + LOG_DEBUG("TCA9535: Shutdown vibration started (300ms)"); + } dispatchEvent(INPUT_BROKER_SHUTDOWN); } } else if (!pressed && _powerBtnPressStart != 0) { @@ -188,6 +199,15 @@ int32_t TCA9535ButtonThread::runOnce() } } + // =================================================================== + // P1.6 振子超时停止:震动 300ms 后自动关闭 + // =================================================================== + if (_vibrateOn && millis() - _vibrateStartMs >= 300) { + _vibrateOn = false; + tca9535Vibrate(false); + LOG_DEBUG("TCA9535: Vibration stopped"); + } + // =================================================================== // P1.5 状态灯闪烁:500ms 亮 + 500ms 灭 = 1 秒周期 // =================================================================== diff --git a/code/firmware-2.7.15.567b8ea/src/input/TCA9535ButtonThread.h b/code/firmware-2.7.15.567b8ea/src/input/TCA9535ButtonThread.h index 20c3e3b..d87e63c 100644 --- a/code/firmware-2.7.15.567b8ea/src/input/TCA9535ButtonThread.h +++ b/code/firmware-2.7.15.567b8ea/src/input/TCA9535ButtonThread.h @@ -12,6 +12,7 @@ * - P1.3:电源开机按钮(POWER_BOOT),输入,低电平有效(按键按下接地) * - P1.4:LoRa RST 输出(通过 I²C 控制 RadioLib 复位序列) * - P1.5:状态指示灯,低电平点亮 + * - P1.6:振子(VIBRATOR),高电平震动,低电平停止 * P1 Config 寄存器 = 0x0A(P1.1、P1.3 为输入,其余为输出) * * 电源管理逻辑: @@ -88,7 +89,7 @@ #define TCA9535_BIT_P13 (1u << 3) // POWER_BOOT 输入 #define TCA9535_BIT_P14 (1u << 4) // LoRa RST 输出 #define TCA9535_BIT_P15 (1u << 5) // 状态指示灯输出(低电平点亮) -#define TCA9535_BIT_P16 (1u << 6) // GPS RST 输出 +#define TCA9535_BIT_P16 (1u << 6) // 振子输出(VIBRATOR,高电平震动) #define TCA9535_BIT_P17 (1u << 7) // GPS EN 输出(高电平有效) #ifdef TCA9535_CHARGE_DET_PIN @@ -240,10 +241,11 @@ static inline bool tca9535Backlight(bool on) } /** - * 通过 I²C 控制 TCA9535 P1.6 上的 GPS RST。 - * @param high true=释放复位(高电平),false=触发复位(低电平) + * 通过 I²C 控制 TCA9535 P1.6 上的振子(VIBRATOR)。 + * 高电平震动,低电平停止。 + * @param on true=震动(高电平),false=停止(低电平) */ -static inline bool tca9535GpsReset(bool high) +static inline bool tca9535Vibrate(bool on) { Wire.beginTransmission(TCA9535_I2C_ADDR); Wire.write(TCA9535_REG_OUTPUT_P1); @@ -253,10 +255,10 @@ static inline bool tca9535GpsReset(bool high) return false; uint8_t p1Out = Wire.read(); - if (high) - p1Out |= TCA9535_BIT_P16; // 拉高 = 释放复位 + if (on) + p1Out |= TCA9535_BIT_P16; // 拉高 = 震动 else - p1Out &= ~TCA9535_BIT_P16; // 拉低 = 触发复位 + p1Out &= ~TCA9535_BIT_P16; // 拉低 = 停止 Wire.beginTransmission(TCA9535_I2C_ADDR); Wire.write(TCA9535_REG_OUTPUT_P1); @@ -343,6 +345,10 @@ class TCA9535ButtonThread : public Observable, public concur bool _backlightOn = false; uint32_t _backlightLastMs = 0; + // P1.6 振子控制(开机/关机震动 300ms) + bool _vibrateOn = false; + uint32_t _vibrateStartMs = 0; // 震动开始时刻,0 = 未在震动 + // 写寄存器 bool writeReg(uint8_t reg, uint8_t val); diff --git a/code/firmware-2.7.15.567b8ea/variants/esp32c3/diy/esp32c3_moonshine_travelers_3/variant.h b/code/firmware-2.7.15.567b8ea/variants/esp32c3/diy/esp32c3_moonshine_travelers_3/variant.h index ec2fa35..6cecbf1 100644 --- a/code/firmware-2.7.15.567b8ea/variants/esp32c3/diy/esp32c3_moonshine_travelers_3/variant.h +++ b/code/firmware-2.7.15.567b8ea/variants/esp32c3/diy/esp32c3_moonshine_travelers_3/variant.h @@ -42,7 +42,8 @@ // 开机:持续按住 2 秒 → POWER_EN 拉高维持供电 // 关机:运行中持续按住 2 秒 → POWER_EN 拉低断电 // - P1.4 LoRa RST 输出(通过 I²C 控制 RadioLib 复位序列) -// - P1.6 GPS_RST 输出(通过 tca9535GpsReset() 控制,init 中释放) +// - P1.6 振子(VIBRATOR),高电平震动,低电平停止 +// 开机确认后震动 300ms,关机时震动 300ms // - P1.7 GPS_EN 输出(高电平有效,通过 enablePin 桥接到 TCA9535) // - P1.1 CHARGE_DET 输入(高电平=正在充电) // - 中断引脚 GPIO5,低电平有效,下降沿触发