f62afff6f37cebb8e1d5069cfae47662dbafb0e0
"timeout mid-transfer (22 seen, 0 bad, 0 lapped, desc@+0=5 +1=17)". Reception now works -- 0 bad, 0 lapped, and the descriptor locator handles both offsets -- but 22 frames seen is almost exactly the sender's 20 retries of block 0. It never saw an ACK and gave up. send_ack() called bba_tx_bytes() and nothing else. That helper only streams bytes into the TXDATA FIFO: it does not write TWD (the frame length) and does not fire the NCRA ST trigger. So every ACK was written into the FIFO and never put on the wire. Entirely my bug -- t_tx(), which is proven on hardware, has done the full sequence all along and I did not follow it. send_ack() now matches t_tx(): clear IR, write TWD_LO/TWD_HI, stream the bytes, then write NCRA SR|ST0. TWD must come BEFORE the stream -- that is what queues the length so TXFrameDrain consumes concurrently with the EXI writes; without it the drain waits for a length that only arrives at the ST trigger and the whole frame must fit the 16-deep FIFO, which is the truncate-at-16-bytes bug. It then waits briefly for TI and counts failures as txto=N in the status line. TI is not proof the frame reached the wire, but its absence is a clear failure. Blocking here costs nothing: stop-and-wait means the host is idle until the ACK lands anyway. Also recorded: the descriptor offset is genuinely MIXED on hardware, +0 for 5 frames and +1 for 17 in one run. A race in the assembler, still unexplained, and not reproducible in simulation -- T2/T5 keep the descriptor at +0 with the write port free-running and stalled 1-in-3. The locator makes the transfer work regardless while the counts stay visible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
No description provided
Languages
Python
84.9%
C
12.4%
Shell
1.1%
Dockerfile
0.7%
Makefile
0.4%
Other
0.5%