This section explains the operation of the host and function (peripheral device) under various transfers. Bulk, Interrupt, and Isochronous transfers use either In or Out transfers.
On the other hand, Control transfers use a combination of Setup, In, and Out transfers. Each Control transfer is structured from 3 stages: the Setup stage for sending a USB request via a Setup transfer, the Data stage for exchanging data via In or Out transfers, and the Status stage for reporting the result of the transfer in the direction opposite to the Data stage. According to the combination of these stages, Control transfers are classified into 3 groups: Control Write transfers that write from host to function, Control Read transfers for reporting from function to host, and No Data Stage transfers without a Data stage, used to write from host to function as a result of either Control Write or Control Read.
Control Write Transfer
Control Read Transfer
No Data Stage Transfer
Setup transfers are transfer sequences used during the Setup Stage of Control transfers. The host issues the Token and Data, and the function issues the Handshake. The function must respond to Setup transfers with an ACK.
In transfers are transfer sequences used during the Data Stage or Setup Stage of Control transfers, or during Bulk In and Interrupt In transfers. The host issues the Token and Handshake, and the function issues the Data. Handshakes are not used for Isochronous transfers.
Out transfers are transfer sequences used during the Data Stage or Setup Stage of Control transfers, or during Bulk Out and Interrupt Out transfers. The host issues the Token and Data, and the function issues the Handshake. Handshakes are not used for Isochronous transfers.
While Handshake packets allow us to determine whether a data transfer was successful, there is also a risk of receiving the same data twice when the Handshake packet itself becomes corrupt. The data received in duplication is unwanted data, and must not be processed. USB uses 2 PIDs for Data packets, DATA0 (C3h) and DATA1 (4Bh), which are used alternately to allow identification of repeated data transmissions. Both hosts and functions have a "sequence bit" for each Endpoint. The sequence bits are used for comparison of the received DATA PIDs.
If the function is currently engaged in another process and is unable to accept a transfer, it responds with a NAK and maintains the sequence bit. The host will also maintain the sequence bit since it has not received an ACK, so the sequence bit remains synchronized even when the transfer is retried.
Upon successfully receiving data, the receiving end will confirm the matching of the sequence bit, and then respond with an ACK after reversing the sequence bit. If the ACK response from the receiving end is not received by the transmitting end, the transmitting end will retry the transfer with the same sequence bit.
This will then result in unsynchronized sequence bits. Given the mismatch of sequence bits, the receiving end will interpret the transfer as a retry, and will respond with an ACK while maintaining the sequence bit, and then discard the data received in duplication. The transmitting end will reverse the sequence bit after receiving an ACK, thus restoring the sequence bits to a synchronized state.
For Bulk and Interrupt transfers, transfers can only be supported in 1 direction for each endpoint. Hence, if a function fails to receive an ACK for an In transfer, the above recovery process will take place upon receiving the next In Token, thus restoring the sequence bits to a synchronized state. The final In transfer during the Data stage of a Control Read transfer is a special case. Regardless of whether an ACK is properly received, there is no further In transfer, and Out transfers for the Status stage will begin. For this reason, in the event that an Out Token is received before receiving an ACK for the last In transfer, the Control Read transfer must assume successful reception of the last In transfer and proceed to the next sequence.
Unlike Control, Bulk, and Interrupt transfers, Isochronous transfers do not use Handshakes for 2 reasons: Isochronous transfers are less likely to experience problems such as CRC errors, and there is also no time for a retry even if there was an error. Isochronous transfers are also unique in its synchronization method. There are 3 synchronization methods for Isochronous transfers: Async, Sync, and Adaptive. Async refers to a case in which the peripheral device has a fixed sampling frequency and cannot be synchronized with the system clock. If the receiving end is Async, rate matching must be performed by the transmitting end, meaning that the operating frequency must be fed back to the transmitting end. Sync devices are capable of sampling at a clock rate synchronized with the SOF. Adaptive devices have rate matching capability, and can matching the sampling frequency to the other end (i.e. a Source can synchronize with a Sink, and a Sink can synchronize with a Source).