Skip to content

Commit

Permalink
Merge pull request #212 from antoinevg/antoinevg/force-disconnect
Browse files Browse the repository at this point in the history
gateware.usb2: add disconnect signal to USBResetSequencer
  • Loading branch information
miek authored Jun 8, 2024
2 parents bf2f346 + c546c84 commit 664d5d1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
2 changes: 2 additions & 0 deletions luna/gateware/usb/usb2/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ def elaborate(self, platform):

reset_sequencer.vbus_connected .eq(~self.utmi.session_end),
reset_sequencer.line_state .eq(self.utmi.line_state),

reset_sequencer.disconnect .eq(~self.connect),
]


Expand Down
36 changes: 34 additions & 2 deletions luna/gateware/usb/usb2/reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class USBResetSequencer(Elaboratable):
be held in perpetual bus reset, and reset handshaking will be disabled.
line_state: Signal(2), input
The UTMI linestate signals; used to read the current state of the USB D+ and D- lines.
disconnect: Signal(), input
If set, the device will be switched into non-driving operating mode to force a host disconnect.
bus_reset: Signal(), output
Strobe; pulses high for one cycle when a bus reset is detected. This signal indicates that the
Expand Down Expand Up @@ -123,6 +125,8 @@ def __init__(self):
self.vbus_connected = Signal()
self.line_state = Signal(2)

self.disconnect = Signal()

self.bus_reset = Signal()
self.suspended = Signal()

Expand Down Expand Up @@ -166,7 +170,7 @@ def elaborate(self, platform):
with m.If(self.current_speed == USBSpeed.HIGH):
m.d.comb += bus_idle.eq(self.line_state == self._LINE_STATE_SQUELCH)

# Full and low-speed busses see a 'J' state when idle, due to the device pull-up restistors.
# Full and low-speed busses see a 'J' state when idle, due to the device pull-up resistors.
# (The line_state values for these are flipped between speeds.) [USB2.0: 7.1.7.4.1; USB2.0: Table 7-2].
with m.Elif(self.current_speed == USBSpeed.FULL):
m.d.comb += bus_idle.eq(self.line_state == self._LINE_STATE_FS_HS_J)
Expand Down Expand Up @@ -200,7 +204,9 @@ def elaborate(self, platform):
# potential reset. Keep our timer at zero.
with m.If(self.line_state != self._LINE_STATE_SE0):
m.d.usb += timer.eq(0)

# Enter forced disconnect when self.disconnect is high.
with m.If(self.disconnect):
m.next = "DISCONNECT"

# If VBUS isn't connected, don't go through the whole reset process;
# but also consider ourselves permanently in reset. This ensures we
Expand Down Expand Up @@ -242,6 +248,9 @@ def elaborate(self, platform):
# potential reset. Keep our timer at zero.
with m.If(self.line_state != self._LINE_STATE_SE0):
m.d.usb += timer.eq(0)
# Enter forced disconnect when self.disconnect is high.
with m.If(self.disconnect):
m.next = "DISCONNECT"

# If VBUS isn't connected, our device/host relationship is effectively
# a blank state. We'll want to present our detection pull-up to the host,
Expand Down Expand Up @@ -508,4 +517,27 @@ def elaborate(self, platform):
with m.Else():
m.next = 'START_HS_DETECTION'


# DISCONNECT -- our device has entered a forced USB disconnect; hold the device in
# NON_DRIVING operating mode for Tddis=0.25us and wait for self.disconnect to go low.
with m.State('DISCONNECT'):
m.d.usb += self.operating_mode.eq(UTMIOperatingMode.NON_DRIVING)

# A disconnect condition is indicated if the host or hub is not driving the data lines and an
# SE0 persists on a downstream facing port for more than Tddis.
# [USB2.0: 7.1.7.3].
tddis = Signal()
with m.If(timer == self._CYCLES_2P5_MICROSECONDS):
m.d.usb += tddis.eq(1)

# Exit DISCONNECT once the Tddis timer has expired and self.disconnect is low.
with m.If((~self.disconnect) & tddis):
m.d.usb += [
tddis.eq(0),
self.current_speed.eq(USBSpeed.FULL),
self.operating_mode.eq(UTMIOperatingMode.NORMAL),
self.termination_select.eq(1),
]
m.next = 'INITIALIZE'

return m

0 comments on commit 664d5d1

Please sign in to comment.