diff --git a/CLAUDE.md b/CLAUDE.md index 8e74177..3748adb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -277,6 +277,22 @@ Pi over J4 with the board on 12 V — device ID `04 02 02 00`, NCRA reset self-clearing, PAR0–5, MAR0–7, ANALOG, NWAYC, IMR `0x86` readback, NCRA SR, and NWAYS `0x17`. See `hardware/re-bba-rb/exi_fullpath_rpi.py`. +✅ **BOTH DIRECTIONS PROVEN ON HARDWARE 2026-09-30 — the BBA data path works.** + +*GC → wire* (after the TWD fix below): a full **60-byte ARP request**, captured +on the PC byte-for-byte correct — broadcast dst, `00:09:bf:00:00:01` source, +ethertype 0806, sender 10.0.0.99, target 10.0.0.50, padded to 60. TI sets. + +*wire → GC*: a real **342-byte DHCP broadcast** from the PC was received by the +W5100 in MACRAW mode, assembled into the SPRAM ring by `RXFrameAssembler`, and +DMA-read back over EXI from 0x100. RI set. The ring descriptor read +`00 00 01 5A` = 346 = 342 + 4, and the frame's own IP total-length field (328) ++ 14 bytes of ethernet header = 342 — so the assembler's length is +independently confirmed correct, not just plausible. + +Together: EXI ↔ BBARegisterFile ↔ {tx_bytes→TXFrameDrain, SPRAM ring} ↔ +W5100ParallelMaster ↔ PHY, in both directions, on silicon. + ✅ **GC→wire TX REACHES THE WIRE — the full path is proven.** A frame written over EXI to TXDATA and triggered via the NCRA ST bits was captured on a PC: `ff ff ff ff ff ff | 00 09 bf 00 00 01 | 08 06 | 00 01` — broadcast dst, our diff --git a/hardware/re-bba-rb/exi_fullpath_rpi.py b/hardware/re-bba-rb/exi_fullpath_rpi.py index 5023ee0..560fe01 100644 --- a/hardware/re-bba-rb/exi_fullpath_rpi.py +++ b/hardware/re-bba-rb/exi_fullpath_rpi.py @@ -122,8 +122,15 @@ if got: print(f" SPRAM @0x100: {hx(data[:16])}") print(f" {hx(data[16:32])}") print(f" {hx(data[32:48])}") - if 0x08 in data and 0x06 in data: - print(" -> looks like an ARP frame came back. RX PATH WORKS.") + # Decode the ring descriptor instead of guessing from stray bytes: the + # first 4 bytes are the descriptor, whose length INCLUDES itself. + dlen = (data[2] << 8) | data[3] + etype = (data[16] << 8) | data[17] + print(f" descriptor length 0x{dlen:04X} = {dlen} -> {dlen-4} frame bytes") + print(f" dst {':'.join('%02x'%b for b in data[4:10])}" + f" src {':'.join('%02x'%b for b in data[10:16])} ethertype 0x{etype:04X}") + if 4 < dlen <= 1518: + print(" -> RX PATH WORKS: a real frame was assembled into the SPRAM ring.") else: print(f" no RX after 3s (RWP still {hx(read(0x16,2))}, IR {read(0x09,1)[0]:02x})") print(" TX may still have worked - check the capture.")