Correct EEPROM soft-brick record: partial write on undersized U7 kills enumeration
Hardware bring-up correction (Dennis, 2026-08-22): writing the FT2232H product string to the undersized 93LC46B (U7) does NOT harmlessly fail — the partial, mirrored write lands a checksum-valid-but-garbage config, and the FT2232H then FAILS USB enumeration entirely (dead silent, no dmesg attach). It does NOT fall back to ROM defaults; only a blank/checksum-invalid EEPROM does. The earlier claim that "a bad EEPROM always falls back and still enumerates" was WRONG. Recovery (confirmed working): power on with U7 CLK shorted to GND so the FT2232H can't read a valid config -> forces ROM defaults -> enumerates -> then erase U7. Updated REVIEW.md, TODO.md, the flash-re-bba-rb skill (do-not-program warning + recovery, native-Linux troubleshooting), and flash_ftdi_eeprom.py comments/help to state the soft-brick reality. The script already refuses the write on mirroring detection; --force now documented as "reproduce the soft-brick". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -85,12 +85,23 @@ datasheet extraction, WebSearch/WebFetch for parts and reference designs.
|
||||
128-byte chip mirrors into the upper half (`has_mirroring=True`); a config
|
||||
write mirror-clobbers word 0x80→0x00 and **fails verify at word 0x02**; and
|
||||
`set_property` indexes past byte 128. **Consequence:** the "re-BBA-rb" product
|
||||
string CANNOT be stored on V1. **Not a functional defect** — with U7 left
|
||||
blank the FT2232H uses ROM defaults ("Dual RS232-HS", 0403:6010), and iceprog
|
||||
(bitstream flash — verified OK on this unit) + the channel-B UART work
|
||||
normally. **Fix for a future rev:** fit a 93LC56B at U7 (same SOIC-8, fixed
|
||||
16-bit org, pin-compatible). Tooling: `hardware/re-bba-rb/flash_ftdi_eeprom.py`
|
||||
detects the mirroring and refuses the write; `--erase` blanks U7.
|
||||
string CANNOT be stored on V1 — and worse, **attempting the write SOFT-BRICKS
|
||||
the FT2232H** (confirmed 2026-08-22): the partial/mirrored write leaves a
|
||||
checksum-valid-but-garbage config, and the FT2232H then **fails USB enumeration
|
||||
entirely** (dead silent — no `dmesg` attach at all). It does NOT cleanly fall
|
||||
back to ROM defaults; only a BLANK or checksum-INVALID EEPROM does that. (An
|
||||
earlier note here wrongly said a bad EEPROM always falls back and still
|
||||
enumerates — that is FALSE for a partial write; corrected.)
|
||||
**RECOVERY (done on this unit, works):** short U7's **CLK to GND while powering
|
||||
on** so the FT2232H can't read a valid EEPROM → forces ROM defaults →
|
||||
enumerates → then **erase U7** (`flash_ftdi_eeprom.py --erase --commit`, or
|
||||
FT_PROG). Classic FTDI EEPROM recovery. With U7 blank the board runs on ROM
|
||||
defaults ("Dual RS232-HS", 0403:6010); iceprog (bitstream flash — VERIFY OK on
|
||||
this unit) + the channel-B UART are unaffected.
|
||||
**DO NOT run the string write on this board.** `flash_ftdi_eeprom.py` now
|
||||
detects the mirroring and refuses (use --force only to deliberately re-soft-
|
||||
brick for testing; `--erase` blanks). **Fix for a future rev:** fit a 93LC56B
|
||||
at U7 (same SOIC-8, fixed 16-bit org, pin-compatible).
|
||||
- **EE_CS pull-down (R43, 10 kΩ) — ADDED 2026-07-31.** FT2232H DS Table 3.4
|
||||
states EECS/EECLK/EEDATA are all **"Tri-State during device reset"**, so CS
|
||||
floats while the FT2232H is in reset. The Microchip 93LC46B DS is explicit:
|
||||
|
||||
@@ -361,12 +361,17 @@ Major work this session:
|
||||
- [ ] **U7 EEPROM undersized — swap 93LC46B → 93LC56B for V2 (found at bring-up
|
||||
2026-08-22).** The 93LC46B is 128 B; the FT2232H needs ≥256 B (93LC56B /
|
||||
93LC66B) to hold its config, so the "re-BBA-rb" USB product string can't be
|
||||
programmed on V1 (write mirrors + fails verify — see REVIEW.md "U7 PART IS
|
||||
UNDERSIZED"). **Not a functional blocker:** V1 ships with U7 blank → FT2232H
|
||||
ROM defaults ("Dual RS232-HS", 0403:6010); iceprog bitstream flash (VERIFY
|
||||
OK on the repaired unit) and the channel-B UART are unaffected. 93LC56B is
|
||||
the same SOIC-8 / fixed-16-bit-org, pin-compatible drop-in. Pick a JLC part
|
||||
(e.g. 93LC56BT-I/SN) when respinning.
|
||||
programmed on V1. **⚠️ Worse than cosmetic: ATTEMPTING the write SOFT-BRICKS
|
||||
the FT2232H** — the partial/mirrored write leaves a checksum-valid-garbage
|
||||
config and the chip then fails USB enumeration entirely (dead silent, no
|
||||
dmesg). It does NOT fall back to ROM defaults; only a blank/invalid EEPROM
|
||||
does. **Recovery (done, works):** power on with U7 CLK shorted to GND →
|
||||
forces ROM defaults → enumerates → then erase U7. See REVIEW.md "U7 PART IS
|
||||
UNDERSIZED". **Do NOT run the string write on V1** (`flash_ftdi_eeprom.py`
|
||||
refuses via mirroring detection). Blank U7 is the correct state: iceprog
|
||||
bitstream flash (VERIFY OK on the repaired unit) + the channel-B UART work
|
||||
normally. 93LC56B is the same SOIC-8 / fixed-16-bit-org, pin-compatible
|
||||
drop-in (e.g. 93LC56BT-I/SN) for the respin.
|
||||
- [x] RSET_BG 12.4 k — ACCEPTED 2026-07-18 (closed, no change): datasheet
|
||||
says 12.3 kΩ, but that is an E192 value with no JLC Basic part —
|
||||
WIZnet's own reference synthesizes it as 12 k + 300 Ω. The 0.8 %
|
||||
|
||||
@@ -5,32 +5,35 @@ Uses pyftdi (libusb) — the in-container tool, since debian's libftdi1-2 ships
|
||||
only the runtime lib, not the `ftdi_eeprom` binary. The intended descriptor
|
||||
values mirror hardware/re-bba-rb/ftdi_eeprom.conf.
|
||||
|
||||
SAFE BY DESIGN:
|
||||
* Keeps the stock VID/PID 0403:6010 and the dual-channel config, so iceprog
|
||||
(MPSSE on channel A) and the channel-B UART keep working unchanged — only
|
||||
the descriptor STRINGS change.
|
||||
* DRY-RUN BY DEFAULT: prints the diff and writes a raw backup, but does NOT
|
||||
touch the EEPROM unless you pass --commit.
|
||||
* Always dumps the current EEPROM to a backup file first.
|
||||
DRY-RUN BY DEFAULT: prints the diff and writes a raw backup, but does NOT touch
|
||||
the EEPROM unless you pass --commit. Keeps the stock VID/PID 0403:6010.
|
||||
|
||||
Usage (inside the rebuilt devcontainer, FT2232H usbipd-attached):
|
||||
Usage (inside the devcontainer, FT2232H attached):
|
||||
sudo /opt/venv/bin/python hardware/re-bba-rb/flash_ftdi_eeprom.py # dry-run + backup
|
||||
sudo /opt/venv/bin/python hardware/re-bba-rb/flash_ftdi_eeprom.py --commit # write strings
|
||||
sudo /opt/venv/bin/python hardware/re-bba-rb/flash_ftdi_eeprom.py --erase --commit # blank U7
|
||||
|
||||
⚠️ re-bba-rb V1 HARDWARE LIMITATION: U7 is a 93LC46B (128-byte / 1 Kbit) EEPROM,
|
||||
which is TOO SMALL for the FT2232H — the H-series needs a 93LC56B (256 B) or
|
||||
93LC66B (the 93LC46 is for the FT232R / FT2232D). The FT2232H config mirrors in
|
||||
the 128-byte chip and the string write fails verify, so the "re-BBA-rb" product
|
||||
string CANNOT be programmed on V1. This script therefore REFUSES the write when
|
||||
it detects mirroring (use --force to override, --erase to blank U7). The board
|
||||
is fully functional without it: it enumerates on ROM defaults ("Dual RS232-HS",
|
||||
0403:6010) and iceprog + the channel-B UART work normally. Fix in a future rev
|
||||
by fitting a 93LC56B at U7.
|
||||
⚠️⚠️ re-bba-rb V1: DO NOT PROGRAM THE STRINGS — IT SOFT-BRICKS THE FT2232H. ⚠️⚠️
|
||||
U7 is a 93LC46B (128-byte / 1 Kbit) EEPROM, TOO SMALL for the FT2232H — the
|
||||
H-series needs a 93LC56B (256 B) or 93LC66B (the 93LC46 is for the FT232R /
|
||||
FT2232D). The FT2232H config mirrors in the 128-byte chip, so a string write
|
||||
lands a PARTIAL, checksum-valid-but-garbage config. The FT2232H then reads it at
|
||||
power-up and **FAILS USB ENUMERATION ENTIRELY** — dead silent, no dmesg attach.
|
||||
It does NOT fall back to ROM defaults (only a BLANK / checksum-INVALID EEPROM
|
||||
does that). This was confirmed on hardware 2026-08-22. The script therefore
|
||||
REFUSES the write when it detects mirroring; --force exists only to reproduce the
|
||||
soft-brick deliberately.
|
||||
|
||||
Flash the FPGA bitstream FIRST and confirm iceprog works — the string is purely
|
||||
cosmetic. Do NOT rely on reset_device(): it re-enumerates the FT2232H and drops
|
||||
the usbipd attachment on WSL2 — re-attach with usbipd instead.
|
||||
RECOVERY if U7 ever gets a bad config written (done on the V1 unit, works):
|
||||
1. Power the board on with U7's CLK pin shorted to GND — the FT2232H then can't
|
||||
read a valid EEPROM and enumerates on ROM defaults ("Dual RS232-HS",
|
||||
0403:6010).
|
||||
2. Release the short and immediately blank U7:
|
||||
sudo /opt/venv/bin/python hardware/re-bba-rb/flash_ftdi_eeprom.py --erase --commit
|
||||
(Classic FTDI EEPROM recovery.) With U7 blank the board is fully functional;
|
||||
iceprog + the channel-B UART work normally. Fix for a future rev: 93LC56B at U7.
|
||||
|
||||
reset_device() is intentionally NOT called — it re-enumerates the FT2232H and can
|
||||
drop a usbip attachment; re-plug / re-attach manually instead.
|
||||
"""
|
||||
import argparse
|
||||
import sys
|
||||
@@ -55,7 +58,8 @@ def main() -> int:
|
||||
help="blank U7 to 0xFF (FT2232H falls back to ROM defaults)")
|
||||
ap.add_argument("--force", action="store_true",
|
||||
help="attempt the string write even if U7 reports mirroring "
|
||||
"(undersized 93LC46B) — will likely fail/corrupt")
|
||||
"(undersized 93LC46B) — WILL SOFT-BRICK the FT2232H on "
|
||||
"V1 (fails USB enumeration; recover via CLK-to-GND + erase)")
|
||||
ap.add_argument("--url", default=URL, help=f"pyftdi device URL (default {URL})")
|
||||
args = ap.parse_args()
|
||||
|
||||
@@ -94,17 +98,19 @@ def main() -> int:
|
||||
# 128 bytes: pyftdi sees the 128-byte chip mirror into the upper half
|
||||
# (has_mirroring=True), the config write mirror-clobbers word 0x80->0x00,
|
||||
# and verify fails. FTDI specs a 93LC56B (256 B) / 93LC66B for the H-series
|
||||
# (the 93LC46 is for the FT232R / FT2232D). So the product string CANNOT be
|
||||
# stored on V1 — the board still works fine on ROM defaults ("Dual RS232-HS",
|
||||
# 0403:6010; iceprog + the UART are unaffected). Refuse rather than
|
||||
# half-write (which corrupts U7 and needs an --erase recovery).
|
||||
# (the 93LC46 is for the FT232R / FT2232D). Writing the strings leaves a
|
||||
# PARTIAL checksum-valid-but-garbage config that SOFT-BRICKS the FT2232H: it
|
||||
# then fails USB enumeration entirely (dead silent — does NOT fall back to
|
||||
# ROM defaults). Recovery: power on with U7 CLK shorted to GND, then --erase.
|
||||
# So REFUSE the write — do not half-brick the chip.
|
||||
# ------------------------------------------------------------------
|
||||
if eeprom.has_mirroring and not args.force:
|
||||
print("\nREFUSING: U7 reports EEPROM mirroring — it is a 128-byte chip "
|
||||
"(93LC46B), too small for the FT2232H's 256-byte config.\n"
|
||||
"The 're-BBA-rb' product string cannot be stored on this board "
|
||||
"(see the header comment / REVIEW.md). The board works fine on ROM "
|
||||
"defaults. Use --erase to (re)blank U7; --force to attempt anyway.",
|
||||
"Writing the 're-BBA-rb' strings SOFT-BRICKS the FT2232H on this "
|
||||
"board (partial config -> fails USB enumeration; recover by shorting "
|
||||
"U7 CLK to GND at boot then --erase; see header / REVIEW.md).\n"
|
||||
"Use --erase to blank U7; --force ONLY to reproduce the soft-brick.",
|
||||
file=sys.stderr)
|
||||
eeprom.close()
|
||||
return 3
|
||||
|
||||
Reference in New Issue
Block a user