The USBD peripheral implements seven pairs of bulk/interrupt endpoints.
The bulk/interrupt endpoints have a fixed USB endpoint number, summarized in the following table.
| Bulk endpoint # | USB IN endpoint | USB OUT endpoint |
|---|---|---|
| [1] | 0x81 | 0x01 |
| [2] | 0x82 | 0x02 |
| [3] | 0x83 | 0x03 |
| [4] | 0x84 | 0x04 |
| [5] | 0x85 | 0x05 |
| [6] | 0x86 | 0x06 |
| [7] | 0x87 | 0x07 |
A bulk/interrupt transaction consists of a single Data stage. Two consecutive, successful transactions are distinguished through alternating leading process ID (PID): DATA0 follows DATA1, DATA1 follows DATA0, etc. A repeated transaction is detected by re-using the same PID as previous transaction, i.e DATA0 follows DATA0, or DATA1 follows DATA1.
The USBD controller automatically toggles DATA0/DATA1 PIDs for every bulk/interrupt transaction.
If incoming data is corrupted (CRC does not match), USBD automatically prevents DATA0/DATA1 from toggling, to request the USB host to resend the data.
In some specific cases, the software may want to force a data toggle (usually reset) on a specific IN endpoint, or force the expected toggle on an OUT endpoint, for instance as a consequence of the USB host issuing ClearFeature, SetInterface, or selecting an alternate setting. Controlling the data toggle of data IN or OUT endpoint n (n=1..7) is done through register DTOGGLE.
The bulk/interrupt transaction in USB full-speed can be of any size up to 64 bytes. It must be a multiple of four bytes and 32-bit aligned in memory.
When the USB transaction has completed, an EPDATA event is generated. Until new data has been transferred by EasyDMA from memory to USBD (signalled by the ENDEPIN[n] event), the hardware will automatically respond with NAK to all incoming IN tokens. Software has to configure and start the EasyDMA transfer once it is ready to send more data.
Each IN or OUT data endpoint has to be explicitly enabled by software through register EPINEN or EPOUTEN, according to the configuration declared by the USB device and selected by the USB host through the SetConfig command.
A disabled data endpoint will not respond to any traffic from the USB host. An enabled data endpoint will normally respond NAK or ACK (depending on the readiness of the buffers), or STALL (if configured in register EPSTALL), in which case the endpoint is asked to halt. The Halted or NotHalted state of a given endpoint can be read back from register HALTED.EPIN[n] or HALTED.EPOUT[n]. The format of the returned 16-bit value can be copied as is, as a response to a GetStatusEndpoint request from the USB host.
Enabling or disabling an endpoint will not change its Halted state. However, a USB reset will disable and clear the Halted state of all data endpoints.
The control endpoint 0 IN and OUT can also be enabled and/or halted using the same mechanisms, but due to USB specification, receiving a SETUP will override its state.