I'm writing firmware for a USB 2.0 full speed device that communicates with a WinUSB host, with one Bulk Pipe in each direction. When should the device send a zero-length packet (ZLP) to terminate an IN transfer, and how does it know that it should?
Section 5.8.3 of the USB 2.0 spec says:
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 [ZLP]
I interpret this to mean that a ZLP should be sent when the transfer size is an integer multiple of the max packet size, and the "expected" size of the transfer is greater than the actual size (i.e. what is available to be sent). But how does the recipient know what's expected?
For instance, I'm using the WinUSBNet wrapper in C#. When I read from the pipe like this
int bytesRead;
buffer = new byte[128];
try
{
bytesRead = m_PipeIN.Read(buffer);
buffer = buffer.Take(bytesRead).ToArray();
}
the library calls WinUsb_ReadPipe() like this:
WinUsb_ReadPipe(InterfaceHandle(ifaceIndex),
pipeID,
pBuffer + offset,
(uint)bytesToRead,
out bytesRead,
IntPtr.Zero);
Suppose the device has exactly 128 bytes to send, and max packet size is 64 bytes. How does the device determine what the host is "expecting", thus whether it should send a ZLP to terminate the transfer?
(Similar to this question, but that one is about control pipes. I'm asking about bulk pipes.)
You may be wondering how to determine the "expected" amount of bytes since BULK transfers do not have a length like CTRL transfers do.
Yes, you've hit the nail on the head.This is determined entirely by the higher-level protocol...
Isn't this bad design on the part of USB-IF? In your ex 2, upon providing data for the IN transfer, the protocol/class layer either needs to [1] provide a boolean to the USB driver saying whether or not to include the ZLP, or [2] send the ZLP itself by sending a zero-length transaction when it gets the next data request. Munging layers... – Ursola