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.)