Hardware bring-up: first UDP packet transmitted and captured
The W5100S ethernet back-end now works end-to-end on real hardware: a complete, correctly-checksummed UDP datagram (10.0.0.99:40000 -> 10.0.0.50:6464, 32-byte payload) was transmitted by the FPGA-driven W5100S and captured on a PC, after a full bidirectional ARP handshake. Records the three W5100S-specific findings in CLAUDE.md (NETLCKR unlock, the 15-bit IDM address space putting the buffers at 0x4000/0x6000, and the 60.3 ms reset-to-ready time), and notes that UDP unicast is the reliable bring-up path while a 255.255.255.255 send sets SEND_OK without appearing on the wire. w5100_udptest.py is the self-contained configure+send+readback probe that isolated all of this. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,27 +30,45 @@ _MR_IND, _MR_AI, _MR_RST = 0x01, 0x02, 0x80
|
||||
|
||||
_SOCK = 3
|
||||
_SBASE = 0x0400 + _SOCK * 0x0100 # socket-3 register block = 0x0700
|
||||
_TXBUF = 0x8000 + _SOCK * 0x0800 # socket-3 TX buffer (W5100S) = 0x9800
|
||||
_TXBUF = 0x4000 + _SOCK * 0x0800 # socket-3 TX buffer (IDM 15-bit) = 0x5800
|
||||
_PAYLEN = 32 # >= 18 so the frame clears 64B minimum
|
||||
|
||||
# ── address-aliasing probe: distinct value to each candidate address ────────
|
||||
# ── phase 1: unlock + network config + open socket 3 as UDP ──────────────────
|
||||
_CFG1 = [
|
||||
(0x4000, 0x11), (0x6000, 0x22), (0x8000, 0x33),
|
||||
(0x9800, 0x44), (0xC000, 0x55),
|
||||
(0x0071, 0x3A), # NETLCKR unlock
|
||||
(0x0009, 0x00), (0x000A, 0x09), (0x000B, 0xBF), # SHAR 00:09:BF:00:00:01
|
||||
(0x000C, 0x00), (0x000D, 0x00), (0x000E, 0x01),
|
||||
(0x0005, 0xFF), (0x0006, 0xFF), (0x0007, 0xFF), (0x0008, 0x00), # SUBR /24
|
||||
(0x000F, 10), (0x0010, 0), (0x0011, 0), (0x0012, 99), # SIPR 10.0.0.99
|
||||
(0x001A, 0x55), (0x001B, 0x55), # RMSR / TMSR
|
||||
(_SBASE + 0x00, 0x02), # Sn_MR = UDP
|
||||
(_SBASE + 0x04, 0x9C), (_SBASE + 0x05, 0x40), # Sn_PORT = 40000
|
||||
(_SBASE + 0x01, 0x01), # Sn_CR = OPEN
|
||||
]
|
||||
|
||||
# ── phase 2: destination + payload + length + SEND ───────────────────────────
|
||||
_CFG2 = [
|
||||
(_SBASE + 0x0C, 10), (_SBASE + 0x0D, 0), # DIPR 10.0.0.50 (PC)
|
||||
(_SBASE + 0x0E, 0), (_SBASE + 0x0F, 50),
|
||||
(_SBASE + 0x10, 0x19), (_SBASE + 0x11, 0x40), # DPORT = 6464
|
||||
] + [(_TXBUF + i, 0x41 + (i % 26)) for i in range(_PAYLEN)] + [
|
||||
(_SBASE + 0x24, (_PAYLEN >> 8) & 0xFF), # Sn_TX_WR = len
|
||||
(_SBASE + 0x25, _PAYLEN & 0xFF),
|
||||
(_SBASE + 0x01, 0x20), # Sn_CR = SEND
|
||||
]
|
||||
_CFG2 = [(0x0030, 0x66)]
|
||||
|
||||
_SCRIPT = _CFG1 + _CFG2
|
||||
_N1 = len(_CFG1)
|
||||
|
||||
# registers read back, in report order
|
||||
_READS = [("A40", 0x4000), ("A60", 0x6000), ("A80", 0x8000),
|
||||
("A98", 0x9800), ("AC0", 0xC000), ("A30", 0x0030)]
|
||||
_READS = [("B00", _TXBUF + 0), ("B01", _TXBUF + 1), ("B02", _TXBUF + 2),
|
||||
("C00", 0x4000), ("C01", 0x4001),
|
||||
("SIR", _SBASE + 0x02), ("TRl", _SBASE + 0x23)]
|
||||
|
||||
|
||||
class W5100UdpTest(Elaboratable):
|
||||
def __init__(self, *, strobe_cycles=3, rst_cycles=48_000,
|
||||
boot_cycles=2_040_000, settle_cycles=240_000):
|
||||
boot_cycles=2_040_000, settle_cycles=12_000_000):
|
||||
self._strobe = strobe_cycles
|
||||
self._rst = rst_cycles
|
||||
self._boot = boot_cycles # >= 60.3 ms W5100S init
|
||||
|
||||
Reference in New Issue
Block a user