diff --git a/docs/EEPROM-RECOVERY.md b/docs/EEPROM-RECOVERY.md index 92003cf..80f111e 100644 --- a/docs/EEPROM-RECOVERY.md +++ b/docs/EEPROM-RECOVERY.md @@ -12,10 +12,34 @@ corrupted firmware from EEPROM, preventing USB enumeration. ## Root Cause -The EEPROM (24C128 at I2C 0x51) likely has corrupted boot data. The -FX2LP boot ROM reads the EEPROM at power-up and hangs if the C2 image -has invalid load record lengths or addresses. The boot ROM occupies -the 8051 core, preventing USB control transfer processing. +The FX2LP boot ROM reads EEPROM (24C128 at I2C 0x51) at power-up. +The I2C bus is shared with the BCM3440 tuner and BCM4500 demod. Two +failure modes cause the hang: + +1. **I2C bus latch** (confirmed): The BCM4500 or BCM3440 holds SDA + LOW from a prior incomplete transaction. I2C is open-drain — any + device sinking SDA prevents all communication. The boot ROM loops + waiting for ACK from the EEPROM, which can never respond because + SDA is stuck. + +2. **Corrupted C2 image** (possible): If the EEPROM's C2 header is + intact but load records have invalid lengths or addresses, the boot + ROM hangs mid-load. + +Either way, the boot ROM occupies the 8051 core and never reaches +the USB enumeration handler. The D+ pull-up activates (hub sees the +device as "present") but descriptor reads time out. + +**Tested and failed (2025-02-19/20):** +- 100+ USB power cycles via uhubctl (varied off-times: 0.2s to 30s) +- Host-side I2C manipulation via 0xA0 vendor commands +- xHCI controller reset, port deauthorization +- Ultra-rapid cycling (0.2-1.0s off) +- Historically ~3-6% success rate on power cycles, now 0% + +The I2C bus state degrades with each failed attempt. Software-only +recovery is not viable. Physical intervention (Options A or B) is +required. ## Recovery Options (pick one) @@ -92,10 +116,10 @@ Most reliable but requires soldering skill. 4. Resolder pin 5 5. Use firmware to reprogram EEPROM with good C2 image -### Option D: Wait + Watch (Long Shot) +### Option D: Wait + Watch (Exhausted — Do Not Use) -If the boot ROM eventually times out on the I2C read, the device -will briefly enumerate as bare FX2. This might take several minutes. +Tested extensively (100+ attempts, 2025-02-19/20) with no success. +The I2C bus latch does not clear on its own. ```bash # Watch for bare FX2 enumeration @@ -135,6 +159,24 @@ Once the device enumerates (as bare FX2 or with loaded firmware): If you have a backup of the original EEPROM contents, flash that instead of the custom firmware. +## Firmware Fixes Pending Hardware Test + +The custom firmware at `firmware/build/skywalker1.ihx` (15,171 bytes) +includes three fixes discovered from stock firmware analysis: + +| Commit | Fix | Stock Reference | +|-----------|------------------------------|--------------------| +| `e9e5ab8` | Init block readback verify | 0x0DDD readback | +| `dffef75` | `bcm_wait_ready()` 3-check | 0x2000 pre-write | +| `0259950` | GPIF stop before boot | 0x1D6A GPIF abort | + +Load immediately after recovery: +```bash +python3 tools/fw_load.py load firmware/build/skywalker1.ihx +``` + +Then test: `BOOT_8PSK` (wValue=1), read signal, verify lock. + ## Prevention - Never send `BOOT_8PSK (0x89)` with mode 0x84 ("firmware load")