| diff --git a/luna/gateware/stream/generator.py b/luna/gateware/stream/generator.py
index 81a99e0..ee14345 100644
--- a/luna/gateware/stream/generator.py
+++ b/luna/gateware/stream/generator.py
@@ -177,6 +177,9 @@ class ConstantStreamGenerator(Elaboratable):
(position_in_stream == (data_length - 1)) | \
(bytes_sent + bytes_per_word >= self.max_length)
+ on_packet_end = position_in_stream[:6] == 63
+ on_packet_start = position_in_stream[:6] == 0
+
#
# Output length field.
@@ -211,6 +214,14 @@ class ConstantStreamGenerator(Elaboratable):
m.next = 'STREAMING'
+ # WAITING -- we've finished one packet and are waiting to send the next.
+ with m.State('WAITING'):
+
+ # Once the user requests that we start, move to our stream being valid.
+ with m.If(self.start & (self.max_length > 0)):
+ m.next = 'STREAMING'
+
+
# STREAMING -- we're actively transmitting data
with m.State('STREAMING'):
m.d.comb += [
@@ -219,8 +230,8 @@ class ConstantStreamGenerator(Elaboratable):
self.stream.payload .eq(rom_read_port.data),
## ... and base First and Last based on our current position in the stream.
- self.stream.first .eq(on_first_packet),
- self.stream.last .eq(on_last_packet)
+ self.stream.first .eq(on_first_packet | on_packet_start),
+ self.stream.last .eq(on_last_packet | on_packet_end)
]
# Our ``valid`` flag requires a bunch of special handling, since it could be
@@ -295,6 +306,9 @@ class ConstantStreamGenerator(Elaboratable):
# If the current data byte is accepted, move past it.
with m.If(self.stream.ready):
+ with m.If(on_packet_end):
+ m.next = 'WAITING'
+
# If there's still data left to transmit, move forward.
with m.If(~on_last_packet):
m.d.sync += position_in_stream.eq(position_in_stream + 1)
diff --git a/luna/gateware/usb/usb2/control.py b/luna/gateware/usb/usb2/control.py
index 9fcb67b..956a89f 100644
--- a/luna/gateware/usb/usb2/control.py
+++ b/luna/gateware/usb/usb2/control.py
@@ -200,7 +200,7 @@ class USBControlEndpoint(Elaboratable):
# Fix our data PIDs to DATA1, for now, as we don't support multi-packet responses, yet.
# Per [USB2.0: 8.5.3], the first packet of the DATA or STATUS phase always carries a DATA1 PID.
- interface.tx_pid_toggle.eq(1)
+ #interface.tx_pid_toggle.eq(1)
]
@@ -218,6 +218,8 @@ class USBControlEndpoint(Elaboratable):
# We won't do anything until we receive a SETUP token.
with m.If(setup_decoder.packet.received & endpoint_targeted):
+ m.d.usb += interface.tx_pid_toggle.eq(1)
+
# If our SETUP packet indicates we'll have a data stage (wLength > 0)
# move to the DATA stage. Otherwise, move directly to the status stage [8.5.3].
with m.If(setup_decoder.packet.length):
@@ -245,6 +247,9 @@ class USBControlEndpoint(Elaboratable):
# Notify the request handler to prepare a response.
m.d.comb += request_handler.data_requested.eq(1)
+ with m.If(request_handler.tx.valid & request_handler.tx.ready & request_handler.tx.last):
+ m.d.usb += interface.tx_pid_toggle[0].eq(~interface.tx_pid_toggle[0])
+
# Once we get an OUT token, we should move on to the STATUS stage. [USB2, 8.5.3]
with m.If(endpoint_targeted & interface.tokenizer.new_token & interface.tokenizer.is_out):
m.next = 'STATUS_OUT'
|