whitequark / libfx2

Chip support package for Cypress EZ-USB FX2 series microcontrollers
BSD Zero Clause License
73 stars 26 forks source link

How to write a response in chunks (USB control read)? #6

Closed DurandA closed 3 years ago

DurandA commented 3 years ago

I am trying to write large responses to a USB control read. The data is read in chunks of 32 bytes from a i2c device and feeds EP0BUF.

I had a look at something similar in the Glasgow firmware and wrote this:

uint8_t USB_REQ_ATECC_READ = 0x20;

if((req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_VENDOR|USB_DIR_IN)) &&
   req->bRequest == USB_REQ_ATECC_READ) {
  uint8_t arg_slot = req->wValue;
  uint8_t arg_offset = req->wIndex;
  uint16_t arg_len = req->wLength;
  pending_setup = false;

  while(arg_len > 0) {
    uint8_t chunk_len = arg_len < 32 ? arg_len : 32;

    while(EP0CS & _BUSY);
    memset(EP0BUF, 0xFF, chunk_len); // whatever
    SETUP_EP0_BUF(chunk_len);

    arg_len  -= chunk_len;
    arg_offset += 1;
  }

  return;
}

I removed the i2c-related code so I just expect the FX2 to send garbage data. However, when I request more than 32 bytes (e.g. 33), I always receive 32 bytes:

data = await device.control_read(usb1.REQUEST_TYPE_VENDOR, REQ_ATECC_READ, 0, 0, 33)
print(len(data)) # == 32

In other cases, an usb1.USBErrorPipe: LIBUSB_ERROR_PIPE [-9] exception is thrown.

Sorry for opening an issue here as this is probably not an issue with the libfx2 implementation.

whitequark commented 3 years ago

I suggest using Wireshark to look at the requests and then comparing this with the information provided in the FX2 manual.

DurandA commented 3 years ago

Apparently only chunks of 64 bytes can be sent from EP0 if the data does not fit in a single packet. I tried with a few other values (32, 63) but this always results in an error.

I suggest using Wireshark to look at the requests

That was also my first idea. Unfortunately, the packets are captured by libusb which inserts its own errors before propagating to Wireshark.

and then comparing this with the information provided in the FX2 manual.

I think 64 bytes packets are expected with SDPAUTO=1. I did not try it yet but I believe smaller packets are possible by changing EP0BCL. Edit: SETUP_EP0_BUF already set EP0BCL so I guess only 64 bits chunks are possible in high speed mode.

Thanks @whitequark for your awesome projects. If you think that this behavior is expected, feel free to close the issue.

whitequark commented 3 years ago

I don't think this is a libfx2 issue and I don't really want to comb through FX2 manuals to find out the root cause.

DurandA commented 3 years ago

Of course. Thanks for your time and your open source projects.