diff --git a/docs/hw_meeting_v28_v29_agenda.md b/docs/hw_meeting_v28_v29_agenda.md new file mode 100644 index 000000000..1596a3f3a --- /dev/null +++ b/docs/hw_meeting_v28_v29_agenda.md @@ -0,0 +1,173 @@ +# Hardware Meeting — v2.8 Fleet Mitigation & v2.9 Architecture +**Date:** 2026-05-18 +**Participants:** Fábio Cunha (FW Lead), [HW Engineer] +**Objective:** Align on (A) what we can do RIGHT NOW with the 40 existing v2.8 boards, and (B) what schematic changes are required for v2.9 to prevent these problems permanently. + +--- + +## PART A — The 40 Existing v2.8 Devices + +> These boards are bought and assembled. We cannot change the hardware. Everything here is about firmware workarounds and operational procedures. + +### A.1 — Problem: Devices Are Un-brickable Without Opening the Case + +**Root Cause:** +The 3.3V regulator `EN` is hardwired to `VSYS` (Always-On). The reed switch is on the IO Expander (P5), so it cannot pull `EN` LOW or trigger a hardware reset. If firmware crashes, the device stays powered with no way to force a reboot externally. + +**Firmware Workaround (already implemented in branch):** +We built a 3-layer software recovery chain: + +| Layer | Mechanism | Trigger | +|-------|-----------|---------| +| 1. Clean Reboot | `esp_restart()` | 5-second magnet hold | +| 2. Hardware Watchdog | ESP32-S3 TWDT forces reset | 10-second hold (firmware is deadlocked) | +| 3. Safe Mode | Boot into USB-flashable infinite loop | Magnet still held at boot time | + +**✅ This works.** Tested and validated. The technician holds a magnet for 15 seconds → device reboots into Safe Mode → USB cable connects → `idf.py flash` works. + +**⚠️ Limitation:** This relies on the reed switch polling task being alive. If a crash corrupts FreeRTOS itself (scheduler destroyed), the TWDT may not fire. This is an extremely rare edge case, but it exists. + +**🔴 Question for Afonso:** +> Can we bodge-wire any of the 40 existing boards to add a physical reset path? For example, solder a wire from the reed switch pad to `CHIP_PU` through a small RC delay circuit? Or is the board layout too tight? + +--- + +### A.2 — Problem: Flashing Requires Tweezers + +**Root Cause:** +No BOOT or RESET buttons on the PCB. To enter Download Mode, you must short CON header pins with tweezers: +- Hold Pin 5 (`IO0_LCD_RST`) → GND (Pin 6) +- Momentarily short Pin 2 (`EN`) → GND (Pin 6) + +**Workaround:** +The UART method with a USB-to-UART adapter + auto-reset circuit (DTR/RTS on `EN` and `IO0`) works reliably. This is the recommended method for factory production runs. + +**🔴 Question for Afonso:** +> For the 40 boards in production — should we buy UART adapters with auto-reset for the hotel technicians? Or do we rely entirely on the 15-second magnet recovery (FW-based)? + +--- + +### A.3 — Problem: FSM Gets Stuck in SLEEP State (15 Devices Affected) + +**Root Cause:** +In `fsm.c`, when `esp_light_sleep_start()` fails (PIR motion during sleep entry), the FSM never posts `FSM_EVENT_WAKEUP`. The device stays in SLEEP state but is physically awake — no telemetry, no logs, appears dead. + +**Impact:** 6 confirmed stuck, 9 suspected. These devices drain battery silently. + +**Fix:** 1-line code change (add `fsm_post_event(FSM_EVENT_WAKEUP)` to the failure branch). This is **FW-205** — ready to implement immediately. + +**🟡 Discussion point:** +> This is a firmware bug, not hardware. But it has fleet impact. We need to decide: do we OTA this fix to the 40 deployed devices, or wait for the next full firmware release? + +--- + +### A.4 — Problem: PIR Sensor Noise Causes "Insomnia" (Battery Drain) + +**Root Cause:** +GPIO44 PIR sensor triggers false positives every 3–5 seconds, preventing the device from entering sleep. Battery drains over 5+ days without any cloud notification. Eventually causes brownout → RTC corruption (year 2089 bug). + +**Current Status:** FW-198 is in TESTING. + +**🔴 Question for Afonso:** +> Is the PIR noise a hardware sensitivity issue (component tolerances, layout crosstalk, missing filtering capacitor)? Or is it purely a firmware debounce problem? Do we need a hardware filter (e.g., RC on the PIR output) for v2.9? + +--- + +## PART B — v2.9 Schematic Changes Required + +> These are the 4 architectural changes we need to discuss for the next PCB spin. + +### B.1 — Reed Switch → Dedicated RTC GPIO + +| Aspect | v2.7 | v2.8 | v2.9 Target | +|--------|------|------|-------------| +| **Pin** | GPIO43 (TX0) | IO Expander P5 | Dedicated RTC GPIO | +| **Deep Sleep Wake** | Yes (with UART conflict) | No | Yes (EXT1, no conflicts) | +| **Hardware Reset** | Could cut power | No | Via supervisor IC | + +**Action:** Move reed switch from PCAL9538A P5 to a non-strapping RTC GPIO. +**Constraint:** Must NOT be GPIO0, GPIO3, GPIO45, GPIO46 (strapping pins). + +**🔴 Decision needed:** +> Which RTC GPIO is available? Need Afonso to check the current pin allocation and suggest the best candidate. + +--- + +### B.2 — Hardware Hard-Reset (Supervisor IC) + +**Goal:** 10+ second magnet hold → pulls `CHIP_PU` LOW → unconditional hardware reset, regardless of firmware state. + +**Options to discuss:** + +| Option | IC | Cost | Package | Iq | JLCPCB? | +|--------|-----|------|---------|-----|---------| +| A | LTC2950 | ~$2.50 | DFN-6 | 6µA | ❓ Check | +| B | MAX16054 | ~$1.80 | SOT-23-6 | 1.5µA | ❓ Check | +| C | TPS3420 | ~$0.80 | SOT-23-5 | 0.5µA | ❓ Check | +| D | Passive RC + MOSFET | ~$0.15 | Discretes | <1µA | ✅ | + +**🔴 Decisions needed:** +> 1. IC vs passive RC — what does Afonso recommend for timing precision vs cost? +> 2. What's the target hold duration? (Currently proposed: 10 seconds) +> 3. Budget per unit for this sub-circuit? + +--- + +### B.3 — Soft-Latch Power Circuit (Replace Always-On) + +**Current v2.8:** `EN` hardwired to `VSYS` → board is always on. +**v2.9 target:** Soft-latch with P-MOSFET + N-MOSFET. Reed switch toggles latch ON, firmware holds it via a GPIO. Firmware can cut all power for true Zero-Power shutdown. + +``` + ┌─────────┐ + VSYS ───┤ P-FET ├───> 3.3V Regulator EN + └────┬────┘ + │ + POWER_HOLD GPIO ──── N-FET ──── GND + │ + Reed Switch ──── trigger path +``` + +**🔴 Decisions needed:** +> 1. Which GPIO for POWER_HOLD? Must be available immediately at boot (before I2C). +> 2. What about USB charging? If USB is plugged in with battery removed, should the regulator still turn on? (Probably yes — need a bypass Schottky from USB 5V.) +> 3. Sleep current target for the latch circuit in OFF state? (<1µA?) + +--- + +### B.4 — BOOT + RESET Tactile Buttons + +**Action:** Add two SMD tactile switches: +- **RESET:** `CHIP_PU` → GND (100nF debounce cap) +- **BOOT:** GPIO0 → GND (100nF debounce cap) + +**🔴 Questions for Afonso:** +> 1. Board space available for two 3×6mm or 4×4mm switches? +> 2. Should they be accessible through the enclosure (cutouts) or internal-only for development? +> 3. Any concerns about GPIO0 being shared with `LCD_RST`? + +--- + +## PART C — Action Items Checklist + +After this meeting, we should have clear answers on: + +- [ ] **RTC GPIO selection** — which pin for the reed switch in v2.9 +- [ ] **Supervisor IC vs RC** — chosen approach for the hard-reset circuit +- [ ] **POWER_HOLD GPIO selection** — which pin for soft-latch control +- [ ] **PIR noise verdict** — hardware filter needed for v2.9, or firmware-only? +- [ ] **Bodge-wire feasibility** — can we add hardware reset to any of the 40 existing v2.8 boards? +- [ ] **OTA strategy** — push FSM sleep fix (FW-205) to deployed fleet now or wait? +- [ ] **Button placement** — BOOT/RESET button locations on PCB layout +- [ ] **BOM budget** — per-unit cost increase acceptable for v2.9 additions +- [ ] **Timeline** — when can v2.9 schematic rev be ready for review? + +--- + +## Reference Documents + +- [v2.9 Mitigation Plan](./v2.9_mitigation_plan.md) +- [v2.8 Brick Recovery Analysis](../../aws-iot-core-poc/docs/v2.8_brick_recovery_analysis.md) +- [v2.8 Flashing Guide](../../aws-iot-core-poc/docs/flashing_guide_v28.md) +- **Jira HW issues:** HW-52, HW-55, HW-56, HW-57, HW-58 +- **Jira FW issues:** FW-200 → FW-207 diff --git a/docs/v2.8_hardware_analysis_and_fixes.md b/docs/v2.8_hardware_analysis_and_fixes.md new file mode 100644 index 000000000..8c5764c5c --- /dev/null +++ b/docs/v2.8_hardware_analysis_and_fixes.md @@ -0,0 +1,42 @@ +# PCB v2.8 Hardware Analysis & Fixes + +## 1. Analysis of v2.8 Hardware Bugs + +### The "Bricking" & Flashing Issue +In v2.8, the 3.3V regulator `EN` pin is hardwired to `VSYS`, meaning the board is "Always-On" as long as a battery is connected. Simultaneously, the reed switch was moved to the PCAL9538A IO Expander (Port P5). +This combination created two major problems: +1. **Unrecoverable Crashes:** If the firmware deadlocks, the device cannot be manually reset because the IO Expander cannot hard-reset the MCU, and power cannot be cut. +2. **Flashing Friction:** To enter Download Mode over Native USB, `GPIO0` must be pulled LOW during a reset. Because the reed switch is on the IO Expander, it cannot pull `GPIO0` LOW, forcing technicians to open the sealed box and use tweezers on the `CON` header to flash the device. + +### Loss of Deep Sleep Wake-Up (v2.7 Regression) +In v2.7, passing the magnet could wake the device or boot it cleanly. Because v2.8 routed the reed switch through an I2C IO Expander, the ESP32-S3 can no longer use the reed switch to wake from Deep Sleep (EXT0/EXT1 wakeups require direct RTC GPIOs). + +--- + +## 2. Immediate Fixes for Current v2.8 Boards (No New Components) + +To achieve the goal of controlling the device and flashing it via USB while sealed in its plastic box, we will use a **single bodge wire** to restore v2.7 functionality. + +### Hardware Modification (Bodge Wire) +1. **Cut the trace** connecting the Reed Switch to the IO Expander (P5). +2. **Solder a bodge wire** from the Reed Switch directly to **`GPIO0`** (accessible at Pin 5 of the `CON` header: `IO0_LCD_RST`). + +### How This Fixes All Problems: +* **Un-brickable Native USB Flashing:** If the device crashes or needs an update, plug in the USB and hold the magnet against the box. The ESP32-S3's hardware Task Watchdog Timer (TWDT) will reset the chip after 10 seconds of deadlock. When the chip reboots, the magnet is physically holding `GPIO0` LOW, forcing the ROM Bootloader to start. The device instantly enumerates over USB and can be flashed (`idf.py flash`) without opening the box. +* **Restored Deep Sleep Wake-up:** `GPIO0` is an RTC GPIO (`RTC_GPIO0`). The firmware can now be put into true Deep Sleep and instantly woken via `esp_sleep_enable_ext1_wakeup()` when the magnet is swiped, exactly like v2.7. +* **Software-Triggered Safe Boot:** If the firmware is healthy, holding the magnet for 5 seconds can trigger `esp_restart()` in software. Because the magnet holds `GPIO0` LOW during the restart, it drops cleanly into Download Mode. + +> [!WARNING] +> **Firmware Adjustment Needed for v2.8:** +> Because `GPIO0` is shared with the LCD Reset (`HW_LCD_RST`), applying the magnet will hardware-reset the display. The firmware must simply re-initialize the LCD (re-send the ST7701S SPI init sequence) whenever the magnet is released. + +--- + +## 3. Changes for Next Version (PCB v2.9) + +For the next PCB revision, we can permanently solve these issues at the schematic level without adding any new components (no supervisor ICs or MOSFETs needed, keeping the BOM cost identical). + +### Schematic Updates: +1. **Permanent Reed Switch Routing:** Route the Reed Switch directly to `GPIO0` (with standard pull-up). This permanently embeds the "Un-brickable USB Flashing" and "Deep Sleep Wake-up" functionality into the board. +2. **Swap LCD Reset to IO Expander:** To prevent the magnet from blanking the screen, move the LCD Reset trace from `GPIO0` to the IO Expander (e.g., Port P5, which is now free). The LCD reset is only needed during initial boot and is not time-critical, making the IO Expander the perfect place for it. +3. **Retain Always-On Power:** With the `GPIO0` + Watchdog recovery mechanism guaranteed to work, the "Always-On" power architecture (Regulator `EN` tied to `VSYS`) is now completely safe. We do not need to add complex soft-latch power circuits or MOSFETs. The ESP32-S3 simply manages power by entering Deep Sleep.