fix(w5100): wait 83ms after software reset, not 1ms
The init does MR=0x80 (software reset) then waits reset_cycles before writing NETLCKR/SHAR/SIPR/socket registers. That wait was 24_000 cycles = 1 ms at 24 MHz, but the W5100S needs the datasheet's 60.3 ms -- our own bus self-test needed ~85 ms before the chip answered at all. 1 ms is marginal rather than simply wrong, which is why this presented as intermittent: an NCRA reset sometimes left the chip still resetting while the init writes landed on it and were silently dropped, leaving it misconfigured and the bus master blocked. Symptom was a W5100 that wedged after an NCRA reset -- TX never completing and the UART shell's own 'udp unicast' hanging -- recoverable only by a 12 V power cycle. Note RST_N is never asserted by the gateware; only the software reset is used, so this wait is the only settle time the chip gets. Default is now 2_000_000 = 83 ms. Testbenches pass small values explicitly and are unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -48,7 +48,7 @@ class BBATop(Elaboratable):
|
|||||||
w5500_rst_n : W5500 hardware reset (output, active low)
|
w5500_rst_n : W5500 hardware reset (output, active low)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, eth="w5100", reset_cycles=24000,
|
def __init__(self, eth="w5100", reset_cycles=2_000_000,
|
||||||
status_panel=False, uart_console=False, uart_shell=False,
|
status_panel=False, uart_console=False, uart_shell=False,
|
||||||
udp_socket=3, udp_src_ip="192.168.1.123",
|
udp_socket=3, udp_src_ip="192.168.1.123",
|
||||||
udp_subnet="255.255.255.0", udp_gateway="192.168.1.1",
|
udp_subnet="255.255.255.0", udp_gateway="192.168.1.1",
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class W5100ParallelMaster(Elaboratable):
|
|||||||
Init / TX / RX interfaces are identical to W5500SPIMaster.
|
Init / TX / RX interfaces are identical to W5500SPIMaster.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, strobe_cycles=3, reset_cycles=24000,
|
def __init__(self, strobe_cycles=3, reset_cycles=2_000_000,
|
||||||
enable_udp_test=False, udp_socket=3,
|
enable_udp_test=False, udp_socket=3,
|
||||||
src_ip="192.168.1.123", subnet="255.255.255.0",
|
src_ip="192.168.1.123", subnet="255.255.255.0",
|
||||||
gateway="192.168.1.1", dst_ip="192.168.1.100",
|
gateway="192.168.1.1", dst_ip="192.168.1.100",
|
||||||
@@ -583,6 +583,18 @@ class W5100ParallelMaster(Elaboratable):
|
|||||||
m.next = "IDLE"
|
m.next = "IDLE"
|
||||||
|
|
||||||
# MR = 0x80 software reset (direct A=00), then settle.
|
# MR = 0x80 software reset (direct A=00), then settle.
|
||||||
|
#
|
||||||
|
# reset_cycles MUST cover the W5100S's post-reset dead time (the
|
||||||
|
# datasheet's 60.3 ms; our own bus self-test needed ~85 ms before
|
||||||
|
# the chip answered). The default 2_000_000 = 83 ms at the 24 MHz
|
||||||
|
# sync clock. It was 24_000 = 1 ms, which is MARGINAL: the chip
|
||||||
|
# sometimes answered and sometimes did not, so every init write
|
||||||
|
# after this point (NETLCKR, SHAR, SIPR, socket regs) could land on
|
||||||
|
# a still-resetting chip and be silently dropped. The symptom was
|
||||||
|
# a W5100 that wedged after an NCRA reset -- TX never completing
|
||||||
|
# and the UART shell's own `udp unicast` hanging -- recoverable
|
||||||
|
# only by a 12 V power cycle. Do NOT shrink this for the synthesis
|
||||||
|
# build; the testbenches pass a small value explicitly.
|
||||||
write_reg("MR_RST", _MR, [_MR_RST], "MR_WAIT", direct=True)
|
write_reg("MR_RST", _MR, [_MR_RST], "MR_WAIT", direct=True)
|
||||||
with m.State("MR_WAIT"):
|
with m.State("MR_WAIT"):
|
||||||
with m.If(wait_ctr == self._reset_cycles):
|
with m.If(wait_ctr == self._reset_cycles):
|
||||||
|
|||||||
Reference in New Issue
Block a user