The mechanisms used for Universal Serial Bus (USB) communication are data buffers called Endpoints. Endpoints exist on the Device and are typically implemented in CPU registers or dual-port memory.
Endpoints are unidirectional, i.e. each endpoint is designed to transmit data in one direction. OUT endpoints send data out of the Host to the Device. IN endpoints take data from the Device intended to go in to the Host. Endpoints exist in numbered pairs and each pair contains an OUT and an IN endpoint.
Endpoint 0 (EP0IN and EP0OUT) are reserved in every Device for control purposes. Control Endpoints are used during enumeration providing the Host the ability to read the Device Descriptor tables and to send control commands to the Device during normal application execution.
A USB device can have up to 32 endpoints (16 OUT and 16 IN). Since EP0IN and EP0OUT are set aside as control endpoints, the maximum number of endpoints available to transmit application data is 30.
Communication between the Host and the Device is asynchronous over USB. The Device is not informed when a Host-initiated transfer starts. A USB Device must proactively seek to see if a data-packet has been received from the Host. If the Device were to read or write to an endpoint while a Host transaction is accessing the endpoint, the result could corrupt the data.
Microchip’s USB software, combined with the dual-port implementation of the endpoints on PIC@ MCUs, prevents corruption of endpoint data. Microchip arbitrates between the Host and the Device resulting in exclusive access to the endpoint memory.