def transaction_data_in(self, addr, ep, data, chunk_size=None): epnum = EndpointType.epnum(ep) datax = PID.DATA1 sent_data = 0 if chunk_size is None: chunk_size = self.max_packet_size for i, chunk in enumerate(grouper_tofit(chunk_size, data)): # Do we still have time? current = get_sim_time("us") if current > self.request_deadline: raise TestFailure("Failed to get all data in time") self.dut._log.debug("Expecting chunk {}".format(i)) self.packet_deadline = current + 5e2 # 500 ms sent_data = 1 self.dut._log.debug( "Actual data we're expecting: {}".format(chunk)) recv = cocotb.fork(self.host_recv(datax, addr, epnum, chunk)) yield recv.join() if datax == PID.DATA0: datax = PID.DATA1 else: datax = PID.DATA0 if not sent_data: recv = cocotb.fork(self.host_recv(datax, addr, epnum, [])) yield recv.join()
def transaction_data_out(self, addr, ep, data, chunk_size=64, expected=PID.ACK, datax=PID.DATA1): epnum = EndpointType.epnum(ep) # # Set it up so we ACK the final IN packet # yield self.write(self.csrs['usb_in_ctrl'], 0) for _i, chunk in enumerate(grouper_tofit(chunk_size, data)): self.dut._log.warning("Sending {} bytes to host".format( len(chunk))) self.packet_deadline = get_sim_time("us") + super().MAX_PACKET_TIME # Enable receiving data yield self.set_response(ep, EndpointResponse.ACK) xmit = cocotb.fork( self.host_send(datax, addr, epnum, chunk, expected)) yield self.expect_data(epnum, list(chunk), expected) yield xmit.join() if datax == PID.DATA0: datax = PID.DATA1 else: datax = PID.DATA0
def transaction_data_in(self, addr, ep, data, chunk_size=64, datax=PID.DATA1): epnum = EndpointType.epnum(ep) sent_data = 0 for i, chunk in enumerate(grouper_tofit(chunk_size, data)): # Do we still have time? current = get_sim_time("us") if current > self.request_deadline: raise TestFailure("Failed to get all data in time") self.dut._log.debug("Expecting chunk {}".format(i)) self.packet_deadline = current + 5e2 # 500 ms sent_data = 1 self.dut._log.debug( "Actual data we're expecting: {}".format(chunk)) for b in chunk: yield self.write(self.csrs['usb_in_data'], b) yield self.write(self.csrs['usb_in_ctrl'], epnum) recv = cocotb.fork(self.host_recv(datax, addr, epnum, chunk)) yield recv.join() if datax == PID.DATA0: datax = PID.DATA1 else: datax = PID.DATA0 if not sent_data: yield self.write(self.csrs['usb_in_ctrl'], epnum) recv = cocotb.fork(self.host_recv(datax, addr, epnum, [])) yield self.send_data(datax, epnum, data) yield recv.join()
def transaction_data_out(self, addr, ep, data, chunk_size=64, datax=PID.DATA0, expected=PID.ACK): for _i, chunk in enumerate(grouper_tofit(chunk_size, data)): self.dut._log.warning("Sending {} bytes to device".format( len(chunk))) self.packet_deadline = (get_sim_time("us") + self.MAX_DATA_PACKET_TIME) xmit = cocotb.fork(self.host_send(datax, addr, ep, chunk, expected)) yield xmit.join()
def test_control_transfer_in_large(dut): """Test that we can transfer data in without immediately draining it""" epaddr_out = EndpointType.epaddr(0, EndpointType.OUT) epaddr_in = EndpointType.epaddr(0, EndpointType.IN) harness = get_harness(dut) yield harness.reset() yield harness.connect() yield harness.write(harness.csrs['usb_address'], 0) # Set address to 11 yield harness.control_transfer_out( 0, # Set address (to 11) [0x00, 0x05, 11, 0x00, 0x00, 0x00, 0x00, 0x00], # 18 byte descriptor, max packet size 8 bytes None, ) yield harness.write(harness.csrs['usb_address'], 11) # Send a packet that's longer than 64 bytes string_data = [ 0x4e, 0x3, 0x46, 0x0, 0x6f, 0x0, 0x6d, 0x0, 0x75, 0x0, 0x20, 0x0, 0x44, 0x0, 0x46, 0x0, 0x55, 0x0, 0x20, 0x0, 0x42, 0x0, 0x6f, 0x0, 0x6f, 0x0, 0x74, 0x0, 0x6c, 0x0, 0x6f, 0x0, 0x61, 0x0, 0x64, 0x0, 0x65, 0x0, 0x72, 0x0, 0x20, 0x0, 0x76, 0x0, 0x31, 0x0, 0x2e, 0x0, 0x38, 0x0, 0x2e, 0x0, 0x37, 0x0, 0x2d, 0x0, 0x38, 0x0, 0x2d, 0x0, 0x67, 0x0, 0x31, 0x0, 0x36, 0x0, 0x36, 0x0, 0x34, 0x0, 0x66, 0x0, 0x33, 0x0, 0x35, 0x0, 0x0, 0x0 ] # Send a SETUP packet without draining it on the device side yield harness.host_send_token_packet(PID.SETUP, 11, epaddr_in) yield harness.host_send_data_packet( PID.DATA0, [0x80, 0x06, 0x02, 0x03, 0x09, 0x04, 0xFF, 0x00]) yield harness.host_expect_ack() yield harness.drain_setup() # Send a few packets while we "process" the data as a slow host for i in range(3): yield harness.host_send_token_packet(PID.IN, 11, 0) yield harness.host_expect_nak() datax = PID.DATA1 sent_data = 0 for i, chunk in enumerate(grouper_tofit(64, string_data)): sent_data = 1 harness.dut._log.debug("Actual data we're expecting: {}".format(chunk)) for b in chunk: yield harness.write(harness.csrs['usb_in_data'], b) yield harness.write(harness.csrs['usb_in_ctrl'], 0) recv = cocotb.fork(harness.host_recv(datax, 11, 0, chunk)) yield recv.join() # Send a few packets while we "process" the data as a slow host for i in range(3): yield harness.host_send_token_packet(PID.IN, 11, 0) yield harness.host_expect_nak() if datax == PID.DATA0: datax = PID.DATA1 else: datax = PID.DATA0 if not sent_data: yield harness.write(harness.csrs['usb_in_ctrl'], 0) recv = cocotb.fork(harness.host_recv(datax, 11, 0, [])) yield harness.send_data(datax, 0, string_data) yield recv.join() yield harness.set_response(epaddr_out, EndpointResponse.ACK) yield harness.host_send_token_packet(PID.OUT, 11, 0) yield harness.host_send_data_packet(PID.DATA0, []) yield harness.host_expect_ack()