Add hall sensor circuit design, NTAG5 config check tool, I2C bus docs
- Hall sensor + LP5562 EN wired-AND circuit design (DRV5032FB/FE, 1M pull-up, open-drain topology) with three interaction modes: boot-time recovery, tap-to-swap, hold-to-confirm recovery - NTAG5 config check tool (tools/ntag5_config_check.py) using uFCoder library for ISO15693 transparent mode via uFR Zero reader. Supports inventory + addressed mode for multi-tag fields. - Updated DEVELOPMENT_PLAN with I2C bus management notes for LP5562 (0x30) + NTAG5Link (0x54) shared bus - Updated README with wired-AND hardware diagram, hall sensor interaction section, and updated wiring table - Updated CLAUDE.md with LP5562 EN wired-AND topology docs - Updated STATUS.md with hall sensor decisions and hardware inventory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -80,6 +80,12 @@ This gives us real pattern data to inform the EEPROM storage format later (M5),
|
||||
|
||||
**Important**: The MCU accesses NTAG5Link as a standard I2C slave at address 0x54 — plain register read/write. This is NOT the NFC-side ISO15693 custom commands used by the Python ntag5sensor tooling.
|
||||
|
||||
**I2C bus management**: LP5562 (0x30) and NTAG5Link (0x54) share the same I2C bus (A4/A5). Both addresses are used simultaneously — the MCU talks to each device by its address. Key considerations:
|
||||
- Both are I2C slave devices with non-conflicting addresses
|
||||
- LP5562 engines run autonomously after programming — no ongoing I2C traffic needed
|
||||
- Pause LP5562 engines (set exec to Hold) before lengthy NTAG5 I2C transactions to avoid any bus contention edge cases
|
||||
- NTAG5Link's use_case must be set to `i2c_slave` (not `i2c_master`) so it doesn't drive the bus
|
||||
|
||||
**Tasks**:
|
||||
1. Write `src/ntag5/mod.rs` — `Ntag5Link<I2C>` struct, generic over `embedded_hal::i2c::I2c`
|
||||
2. Write `src/ntag5/registers.rs` — register map constants from `ntag5link.py`
|
||||
@@ -182,24 +188,37 @@ Typical 3-engine pattern: 16 + 3×34 + 4 = **122 bytes** (fits easily in 2048B E
|
||||
| LP5562 quiescent | ~0.5mA | ~0.5mA |
|
||||
| LP5562 LEDs (4ch @ 3mA) | ~12mA | ~12mA |
|
||||
| NTAG5Link | ~100µA | ~1µA |
|
||||
| Hall sensor (DRV5032) | ~1.6µA | ~1.6µA |
|
||||
| EN pull-up (1M @ 3V) | ~0 | ~0 (3µA only when EN low) |
|
||||
| **Total** | **~17mA** | **~12.5mA** |
|
||||
|
||||
Key insight: LED current dominates. MCU sleep saves ~4mA. Total must stay under EH max (~12.5mA), so LED current must be limited.
|
||||
|
||||
**Done when**: MCU sleeps after boot, LP5562 runs patterns, MCU wakes on NFC to accept new pattern.
|
||||
|
||||
### M8: Recovery Mode
|
||||
### M8: Recovery Mode + Pattern Swap
|
||||
|
||||
**Goal**: Hall sensor provides safe mode entry for post-implant recovery.
|
||||
**Goal**: Hall sensor provides pattern cycling (tap) and safe mode entry (hold + confirm).
|
||||
|
||||
**Circuit**: Wired-AND on LP5562 EN — hall sensor (open-drain) + MCU GPIO (open-drain) + pull-up resistor. Magnet presence forces EN low at hardware level, independent of MCU state. Hall output also connected to MCU EIC pin for interrupt/wake. See `docs/plans/2026-03-03-hall-en-design.md`.
|
||||
|
||||
**Interaction model**:
|
||||
- **Boot-time recovery**: Hall asserted at power-on → EN held low (hardware), MCU skips EEPROM, loads default pattern, stays awake
|
||||
- **Tap (<1s)**: LEDs off instantly (hardware EN drop) → magnet removed → MCU loads next pattern → LEDs back
|
||||
- **Hold (>3s + confirm)**: LEDs off (hardware) → magnet removed → MCU blinks warning (3x red) → 2s window for confirmation tap → if confirmed, enters recovery mode. No second tap → resumes normal operation
|
||||
- **MCU crashed + magnet**: Hall still kills EN (hardware safety)
|
||||
|
||||
**Tasks**:
|
||||
1. Wire hall sensor to EIC-capable GPIO pin
|
||||
2. Boot-time check: if hall sensor asserted → recovery mode
|
||||
3. Recovery behavior: load hardcoded solid white (low brightness), skip EEPROM, stay awake
|
||||
4. Set recovery flag in SRAM so phone app can detect it
|
||||
5. Add hall sensor as runtime EIC wake source (e.g., cycle patterns)
|
||||
1. Wire hall sensor: open-drain output to EN line (wired-AND) + separate wire to EIC pin
|
||||
2. Add pull-up resistor (100k-1M) on EN line
|
||||
3. Configure MCU GPIO (D0/A0) as open-drain for EN control
|
||||
4. Implement EIC interrupt handler for hall sensor pin
|
||||
5. Implement boot-time recovery: read hall GPIO at startup, if asserted → default pattern, skip EEPROM
|
||||
6. Implement runtime state machine: tap detection, hold timing, warning blink, recovery confirmation
|
||||
7. Recovery behavior: load hardcoded solid white (low brightness), skip EEPROM, stay awake
|
||||
8. Set recovery flag in SRAM so phone app can detect it
|
||||
|
||||
**Done when**: Holding magnet near hall sensor at boot triggers recovery mode with default LED pattern.
|
||||
**Done when**: Boot-time recovery works (magnet at power-on), tap cycles patterns at runtime, hold + confirm enters runtime recovery, hardware EN kill works even if MCU is unresponsive.
|
||||
|
||||
### M9: Power Characterization
|
||||
|
||||
@@ -272,7 +291,7 @@ Deferred until Groups A-D are solid.
|
||||
| Risk | Severity | Mitigation |
|
||||
|------|----------|------------|
|
||||
| Power budget too tight for 4ch LED | High | Limit current to 2-3mA/ch, use pulsed patterns, run fewer channels |
|
||||
| I2C bus contention (LP5562 + NTAG5) | Medium | Pause LP5562 engines before NTAG5 I2C access, resume after |
|
||||
| I2C bus contention (LP5562 + NTAG5) | Medium | Non-conflicting addresses (0x30 vs 0x54). Pause LP5562 engines during NTAG5 I2C bursts. Verify NTAG5 is in i2c_slave mode (not i2c_master) |
|
||||
| EEPROM write endurance (~100K cycles) | Low | SRAM for transient comms, EEPROM only for pattern persistence |
|
||||
| Boot time too slow | Low | Estimated ~15-20ms — appears instant to user |
|
||||
| NFC coupling distance too short | Medium | Optimize antenna, low field strength EH mode, accept 1-3cm |
|
||||
|
||||
@@ -131,6 +131,9 @@
|
||||
| Firmware update strategy | Deferred | UF2 for dev, NFC OTA evaluated later |
|
||||
| NTAG5Link I2C slave address | Assumed 0x54 | Verify in M4 with Click board |
|
||||
| Pattern binary format | Deferred to M5 | Design after M2-M3 engine experience |
|
||||
| Hall sensor + EN circuit | Designed | Wired-AND: hall + MCU open-drain on EN with 1M pull-up. See `docs/plans/2026-03-03-hall-en-design.md` |
|
||||
| Hall sensor part selection | Decided | DRV5032FB (SOT-23, 8.4mT, prototype) → DRV5032FE (X2SON 1x1mm, final PCB) |
|
||||
| EN pull-up value | Decided | 1M — zero steady-state draw, 3µA when EN low, ~10µs rise time |
|
||||
|
||||
## Hardware Inventory
|
||||
|
||||
@@ -140,6 +143,6 @@
|
||||
| LP5562EVM | Available | TI eval module, RGBW LEDs, I2C addr 0x30 |
|
||||
| Mini-USB cable | Not on hand | Needed to flash XIAO M0 |
|
||||
| NTAG5 Link Click | Available, partially wired | Missing I2C jumper to XIAO |
|
||||
| Hall effect sensor | Not available | Need to source |
|
||||
| Hall effect sensor | Not available | Need to source — TI DRV5032FB (SOT-23) for prototype |
|
||||
| ACR1552 PCSC reader | Available | For ntag5sensor Python tooling |
|
||||
| Multimeter | Available | For power budget measurements |
|
||||
|
||||
159
docs/plans/2026-03-03-hall-en-design.md
Normal file
159
docs/plans/2026-03-03-hall-en-design.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# Hall Sensor + LP5562 EN Wired-AND Circuit Design
|
||||
|
||||
**Date**: 2026-03-03
|
||||
**Status**: Design in progress
|
||||
|
||||
## Problem
|
||||
|
||||
The implant needs a hall sensor for three functions:
|
||||
1. **Pattern swap** — quick magnet tap cycles to the next stored pattern
|
||||
2. **Runtime recovery** — long hold + confirmation tap enters safe mode
|
||||
3. **Boot-time recovery** — magnet present at power-on skips EEPROM, loads default
|
||||
4. **Hardware safety** — LEDs forced off by magnet even if MCU firmware has crashed
|
||||
|
||||
These must work within extreme space and power constraints (energy-harvested implant).
|
||||
|
||||
## Circuit: Wired-AND on LP5562 EN
|
||||
|
||||
Zero extra active components. Hall sensor and MCU share the EN line via open-drain outputs.
|
||||
|
||||
```
|
||||
VCC (3.0V from NTAG5Link EH)
|
||||
|
|
||||
1M (pull-up resistor)
|
||||
|
|
||||
EN ------+------- MCU D0/A0 (open-drain)
|
||||
|
|
||||
+------- Hall sensor OUT (open-drain, active-low)
|
||||
|
|
||||
LP5562 EN pin
|
||||
|
||||
|
||||
Hall sensor OUT ---- MCU EIC pin (separate connection for interrupt/wake)
|
||||
```
|
||||
|
||||
### How it works
|
||||
|
||||
| State | MCU pin | Hall sensor | EN line | LP5562 |
|
||||
|-------|---------|-------------|---------|--------|
|
||||
| Normal operation | High-Z | High-Z (no magnet) | High (pull-up) | On |
|
||||
| Magnet present | High-Z | Driving low | Low | Off |
|
||||
| MCU disabling LP5562 | Driving low | High-Z | Low | Off |
|
||||
| Magnet + MCU low | Driving low | Driving low | Low | Off |
|
||||
|
||||
### Pull-up resistor: 1M
|
||||
|
||||
- Steady-state current: ~0 (both open-drains high-Z, no path to ground)
|
||||
- Current when EN low: 3V / 1M = 3 µA (only during magnet or MCU-driven low)
|
||||
- Rise time: ~10 µs (1M x ~10pF parasitic) — instant from human perspective
|
||||
- LP5562 EN input is high-impedance CMOS — no DC loading
|
||||
|
||||
## Hall Sensor: TI DRV5032
|
||||
|
||||
| Variant | Use | Iq | Threshold | Output | Package |
|
||||
|---------|-----|-----|-----------|--------|---------|
|
||||
| **DRV5032FB** | Prototype | 1.6 µA | 8.4 mT (omnipolar) | Open-drain | SOT-23 |
|
||||
| **DRV5032FE** | Final PCB | 0.55 µA | 4.5 mT (omnipolar) | Open-drain | X2SON (1x1mm) |
|
||||
|
||||
- **Omnipolar**: Triggers on either magnetic pole (user doesn't need to orient magnet)
|
||||
- **8.4 mT threshold (FB)**: Higher threshold = harder to accidentally trigger. Requires deliberate, close magnet interaction. Good for "don't accidentally enter recovery" requirement.
|
||||
- **Open-drain, active-low**: Required for wired-AND topology
|
||||
- **SOT-23 for prototyping**: Easy to hand-solder; X2SON for final implant PCB
|
||||
|
||||
## Interaction Model
|
||||
|
||||
### Pattern Swap (tap <1s)
|
||||
|
||||
1. Magnet near → hall pulls EN low → LEDs off instantly (hardware, zero MCU latency)
|
||||
2. MCU wakes via EIC interrupt on hall sensor pin, starts timer
|
||||
3. Magnet removed (hall goes high-Z, pull-up restores EN)
|
||||
4. MCU detects short press (<1s) → loads next stored pattern → LEDs back on
|
||||
|
||||
### Runtime Recovery (hold >3s + confirm)
|
||||
|
||||
1. Magnet near → EN low (hardware), MCU wakes via EIC
|
||||
2. MCU counts hold duration while hall stays asserted
|
||||
3. Magnet removed after >3s → MCU notes "long hold detected"
|
||||
4. MCU re-enables LP5562 → blinks warning pattern (3x red flash)
|
||||
5. MCU waits 2s for confirmation tap
|
||||
6. Confirmation tap received → enters recovery mode
|
||||
7. No confirmation → resumes normal operation (reloads previous pattern)
|
||||
|
||||
### Boot-time Recovery
|
||||
|
||||
1. NFC field arrives, VOUT powers system
|
||||
2. Hall sensor already active (magnet was present before power) → EN held low by hardware
|
||||
3. MCU boots, reads hall GPIO → asserted → boot-time recovery
|
||||
4. Loads hardcoded default pattern (solid white, low brightness)
|
||||
5. Skips EEPROM pattern data
|
||||
6. Sets recovery flag in SRAM for phone app detection
|
||||
7. When magnet removed, EN goes high, default pattern runs
|
||||
|
||||
### Hardware Safety (MCU crashed)
|
||||
|
||||
- Holding magnet forces EN low at circuit level regardless of MCU state
|
||||
- No firmware dependency — pure hardware path
|
||||
- Magnet removal restores EN via pull-up (LP5562 resumes last-programmed pattern)
|
||||
|
||||
## Firmware State Machine (M8)
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
power-on -->│ BOOT_CHECK │
|
||||
└──────┬──────┘
|
||||
hall low? │
|
||||
┌───yes─────┼────no───┐
|
||||
v │ v
|
||||
┌──────────┐ │ ┌─────────────┐
|
||||
│ RECOVERY │ │ │ RUNNING │<──────────────┐
|
||||
└──────────┘ │ └──────┬──────┘ │
|
||||
│ hall EIC │ │
|
||||
│ interrupt│ │
|
||||
│ v │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ HALL_ACTIVE │ │
|
||||
│ └──────┬──────┘ │
|
||||
│ hall released │
|
||||
│ │ │ │
|
||||
│ <1s >3s │
|
||||
│ │ │ │
|
||||
│ v v │
|
||||
│ ┌──────┐ ┌──────────────┐ │
|
||||
│ │ SWAP │ │ WARN_BLINK │ │
|
||||
│ └──┬───┘ └──────┬───────┘ │
|
||||
│ │ hall tap │ no tap │
|
||||
│ │ in 2s? │ │
|
||||
│ │ ┌──yes ┌──no │
|
||||
│ │ v v │
|
||||
│ │ ┌────────┐ │ │
|
||||
│ │ │RECOVERY│ │ │
|
||||
│ │ └────────┘ │ │
|
||||
│ └──────────────┴──────────┘
|
||||
```
|
||||
|
||||
States:
|
||||
- **BOOT_CHECK**: Read hall GPIO. If asserted → RECOVERY. Else → RUNNING.
|
||||
- **RUNNING**: LP5562 engines active, MCU in STANDBY sleep. Wakes on hall EIC.
|
||||
- **HALL_ACTIVE**: Magnet detected. Timer running. Waiting for release.
|
||||
- **SWAP**: Load next pattern, re-enable LP5562 → RUNNING.
|
||||
- **WARN_BLINK**: Blink 3x red. Wait 2s for confirmation tap.
|
||||
- **RECOVERY**: Default pattern, skip EEPROM, stay awake, set SRAM flag.
|
||||
|
||||
## Power Impact
|
||||
|
||||
| Component | Added draw | When |
|
||||
|-----------|-----------|------|
|
||||
| Hall sensor (DRV5032FB) | 1.6 µA | Always (quiescent) |
|
||||
| Pull-up resistor (1M) | 3 µA | Only when EN is low (magnet or MCU-driven) |
|
||||
| Pull-up resistor (1M) | ~0 | Steady state (EN high, no current path) |
|
||||
|
||||
Total added quiescent: **~1.6 µA** — negligible vs LP5562 LED current (~12 mA).
|
||||
|
||||
## Open Questions
|
||||
|
||||
| Question | Notes |
|
||||
|----------|-------|
|
||||
| Debounce needed? | Hall sensors are usually clean (no mechanical bounce), but verify with DRV5032 |
|
||||
| EIC pin selection on SAMD21E | Must be EIC-capable for wake from STANDBY. Check SAMD21E pinout. |
|
||||
| Magnet strength/distance | What N52 neodymium size triggers DRV5032FB at implant depth (~3-5mm subdermal)? |
|
||||
| Multiple stored patterns | How many patterns to cycle through? Currently TBD (depends on EEPROM format, M5) |
|
||||
90
docs/plans/2026-03-03-ntag5-config-check.md
Normal file
90
docs/plans/2026-03-03-ntag5-config-check.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# NTAG5Link Config Verification via uFR Zero
|
||||
|
||||
**Date**: 2026-03-03
|
||||
**Status**: Tool written, reader connection blocked
|
||||
|
||||
## Goal
|
||||
|
||||
Read-only verification that the NTAG5Link Click board's configuration matches xblink requirements, using the Digital Logic uFR Zero Multi-ISO reader.
|
||||
|
||||
## Tool
|
||||
|
||||
`tools/ntag5_config_check.py` — Python script using uFCoder library (ctypes) in ISO15693 transparent mode.
|
||||
|
||||
Features:
|
||||
- ISO15693 INVENTORY to discover all tags by UID
|
||||
- Addressed mode for all config reads (supports multiple tags in field)
|
||||
- Reads CONFIG block (0x37) and EH/ED CONFIG block (0x3D)
|
||||
- NXP system info for interface type verification
|
||||
- Checks against xblink expected config values
|
||||
|
||||
## Expected Config
|
||||
|
||||
| Setting | Expected | Config Location |
|
||||
|---------|----------|----------------|
|
||||
| EH mode | low_field_strength | CONFIG byte 0, bits 3:2 = 10 |
|
||||
| Use case | i2c_slave | CONFIG byte 1, bits 5:4 = 00 |
|
||||
| SRAM enabled | true | CONFIG byte 1, bit 1 = 1 |
|
||||
| Arbiter mode | sram_passthrough | CONFIG byte 1, bits 3:2 = 10 |
|
||||
| EH enable | true | EH_CONFIG byte 0, bit 0 = 1 |
|
||||
| EH voltage | 3.0V | EH_CONFIG byte 0, bits 2:1 = 10 |
|
||||
|
||||
## Reader Connection Issue
|
||||
|
||||
**Problem**: uFCoder library returns `UFR_TIMEOUT_ERR` (0x1002) for all `ReaderOpenEx` parameter combinations.
|
||||
|
||||
**USB device**: `10c4:ea60` — Silicon Labs CP2102 USB to UART Bridge Controller, iSerial "0001". Generic descriptor, no D-Logic branding in USB strings.
|
||||
|
||||
**Raw serial investigation**:
|
||||
- At 1 Mbps (expected uFR baud): responds with `00 80` (2 bytes) — not a valid uFR protocol frame (expected 6+ bytes with `0x55...0xAA` framing)
|
||||
- At 115200 bps: returns ASCII shell commands mentioning "systemctl", "proxmark3" paths
|
||||
- At 250 Kbps: returns structured but unrecognized data
|
||||
|
||||
**Possible causes**:
|
||||
1. Device may not be a uFR Zero — the CP210x bridge has generic descriptors
|
||||
2. Reader firmware may need updating
|
||||
3. Reader may be in a non-standard mode
|
||||
4. Different hardware variant requiring different protocol
|
||||
|
||||
**Next steps**:
|
||||
1. Physically verify the device is indeed the uFR Zero (check labels, LEDs)
|
||||
2. Try the D-Logic `ufr_online` Windows utility to confirm reader identity
|
||||
3. If confirmed as uFR Zero, check firmware version and update if needed
|
||||
4. Alternative: use the ACR1552 PCSC reader with ntag5sensor directly (requires porting the reader to share the field with NTAG5 Click)
|
||||
|
||||
## Fallback Plan: ntag5sensor + ACR1552
|
||||
|
||||
If the uFR Zero connection cannot be resolved, use the existing ntag5sensor Python tooling with the ACR1552 PCSC reader:
|
||||
|
||||
```python
|
||||
# From ntag5sensor — already has full config read/write support
|
||||
chip = NTAG5Link(reader)
|
||||
config = chip.get_config_info()
|
||||
eh_config = chip.get_eh_ed_config_info()
|
||||
```
|
||||
|
||||
The ACR1552 is already proven with ntag5sensor. Only change needed: physically position the ACR1552 over the NTAG5 Click board instead of the uFR Zero.
|
||||
|
||||
## Config Change Plan (if mismatches found)
|
||||
|
||||
Use ntag5sensor's write functions (via ACR1552 or adapted for uFR Zero):
|
||||
|
||||
```python
|
||||
# Set I2C slave mode + SRAM passthrough + SRAM enable
|
||||
chip.write_config1(
|
||||
sram_enable=True,
|
||||
arbiter_mode=NXP_CONFIG_1_ARBITER_MODE_SRAM_PASSTHROUGH,
|
||||
use_case=NXP_CONFIG_1_USE_CASE_CONF_I2C_SLAVE
|
||||
)
|
||||
|
||||
# Set EH: 3.0V, enabled, current limit TBD
|
||||
chip.write_eh_ed_config(
|
||||
enable=True,
|
||||
voltage=NXP_EH_CONFIG_EH_VOUT_V_SEL_3_0,
|
||||
current=NXP_EH_CONFIG_EH_VOUT_I_SEL_12_5, # max for testing
|
||||
ed_config=NXP_ED_CONFIG_NFC_FIELD_DETECT
|
||||
)
|
||||
|
||||
# Set EH mode in CONFIG byte 0
|
||||
chip.write_config0(eh_mode=NXP_CONFIG_0_EH_MODE_LOW_FIELD_STRENGTH)
|
||||
```
|
||||
Reference in New Issue
Block a user