This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

USB bulk IN fails a 64 byte transfer

I am using the AM335x StarterWare 2.0.0.7 USB stack with a device modeled on the Bulk device example.  The device is set for Full Speed operation. 

If the response for an in endpoint (not EP0) IN request is exactly 64 bytes, the transaction never completes.  I see the 64 bytes being transferred, but I do not see the 0-byte packet mandated by the USB 2.0 spec.

Where in the USB stack/bulk device code should this be handled?  I could not find any logic to do this.

Gerry Belanger

  • Hello Gerard,

    USB spec mandates ZLP for USB traffic only on message pipes ( control transfers - EP0). Hence during a control transfer after a data stage you see a zero length packet being sent either by the host or by the device depending on the direction of the data transfer. 

    In you case , bulk transfers ( also called stream pipes) do not end with a zero length packet. Since you are using a bulk device example this is your flow:

    1 . Host sends Read10 SCSI ( CSW) command indicating the where ( Logical Block Address) and how many blocks to read (multiples of 512 bytes). - Done through the BULK OUT PIPE.

    2. Device sends 64 byte packets when the host sends the BULK IN . All transactions have a 64 byte payload  ( because it is an MSC device). 

    3. Device keeps sending as many bytes it was asked- (in our case - either using the CPPI DMA or through the PIO mode)

    4. Host Asks for SCSI status ( also called CSW) during which the device sends out a SCSI status to the host. - BULK IN


    Could you exactly tell me where the code is hanging ?


    Cheers!

    Vineeth 

  • Vineeth,

    Thank you for your response.

    Referring to section 5.8.3 Bulk Transfer Packet Size Constraints of the USB2.0 spec, is says:

    An endpoint must always transmit data payloads with a data field less than or equal to the endpoint’s
    reported wMaxPacketSize value. When a bulk IRP involves more data than can fit in one maximum-sized
    data payload, all data payloads are required to be maximum size except for the last data payload, which will
    contain the remaining data. A bulk transfer is complete when the endpoint does one of the following:
    • Has transferred exactly the amount of data expected
    • Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet

    In my case, since this is a bulk endpoint, the host does not know in advance how much data is coming, so the first completion condition is moot.

    Since my data is exactly 64 bytes (wMaxPacketSize for FULL speed), the zero-length packet is required on the IN request following the 64 byte packet.

    What I see on the USB analyzer is that after the 64 bytes is sent, the endpoint is NAKing subsequent DATA IN requests, never sending the zero length packet.

    In response to the IN request on the endpoint, the stack's Tx Endpoint handler should set TxPktRdy in the endpoint's TXCSRL register with no data in the FIFO.

    I cannot find where this is being handled in the stack.

    Gerry Belanger

  • Hi Gerry,

    I have added this fix to our code and will be a part of our next release. 

    Regards

    Vineeth