Sharing Endpoint Addresses?

An old “Internet Aquintance” pointed out to me today that my blog isn’t very visible from the main site, existing only as a small link in the bottom of the navigation pane. That’s a good point, so I’ve added an extra banner to the top each page to try to promote it somewhat. I’ll see how the traffic stats change in the next few days to see if it is effective. While I realise that most of my blog posts here are not exactly gripping to the regular folk, I like to think that at least a few people are tracking my development of my projects.

Also recently I’ve been emailed by two different people asking the same question; can two endpoints of opposite data directions share the same endpoint number? To answer this, let’s first take a look at USB endpoints.
Each endpoint in a USB device is a logical, rather than a physical entity – that is, they exist only as an abstraction on top of the physical data cable. This is shown in the figure below, taken from my unfinished book on USB:

Endpoints serve the purpose of logically separating several data channels in the device from one another, in a well defined (by the protocol) manner. Think of a USB Webcam; inside there are endpoints to handle both the video and the audio streams separately. In order for each stream to be differentiated from one another, they are referenced by an endpoint address, an 8-bit number.

Endpoint addresses are themselves composed of two elements; seven bits indicating the endpoint number, and a single bit indicating the endpoint data’s direction. Endpoints are (for the most part) half duplex in that data may only flow in one direction, thus the most significant bit indicates which direction a given endpoint “faces” in the device (a logic “1” for data IN to the host, or a logic “0” for data OUT of the host).

This gives an interesting edge case; while every endpoint in a device must have a completely unique endpoint address (the 8 bits of direction and endpoint number), two endpoints of opposite direction can share the same endpoint number. This is commonly used for associated data streams (although such an association cannot be inferred by the host – that is the job of the device descriptors) so that related streams (like audio in and audio out in a USB sound card) share the addresses of 0b1xxxxxxx and 0b0xxxxxxx. This is entirely allowed by the standard, and some device drivers are hard-wired to expect the device to use such a scheme, for vendor-specific devices (devices made by a manufacturer which uses a manufacturer supplied driver rather than a generic class driver).

However, just because something is allowed in the standard doesn’t mean that the hardware supports it. This is the case with the Atmel USB AVRs. As the USB AVRs only contain a small amount of USB DPRAM for endpoints, Atmel made the decision to simplify the silicon and the device firmware by only allowing 4-bit endpoint numbers — the upper 7 bits of the endpoint number are implicitly fixed to all logic “0”. While the endpoint direction is still set via the device descriptors as per normal USB devices, the controller-application interface distinguishes between endpoints by only the four bit endpoint number, and not the full endpoint address.

For this reason, the Atmel USB AVRs are unable to accommodate two endpoints of opposite direction sharing the same endpoint number; both endpoint address 0b1xxxyyyy and 0b0xxxyyyy will be seen by the application and controller (in the application side, not the host side) by the shortened endpoint address of 0byyyy. The upper bits and direction flag in the address are discarded, thus imposing a second limitation – endpoint numbers cannot exceed 15 for the current USB AVR models.

The former limitation could be avoided by the addition of a direction flag in the USB registers, but this would complicate the firmware slightly. As it stands, the USB AVR microcontrollers are great little devices, but for full, absolute USB endpoint functionality, the bigger USB supporting AVR32 32-bit AVR line needs to be used.

The above is entirely wrong — the Atmel devices do indeed support shared endpoint addresses by the changing of the endpoint token at runtime to the desired direction.

 

Comments: 1

Leave a reply »

 
 
 

Then let’s start working on AVR32 🙂 — I hope Matt from AVRopendous make a little board for AVR32, so we can start playing with it 😉

 

Leave a Reply

 
(will not be published)
 
 
Comment
 
 

 

Vital Stats

  • 35 Years Old
  • Australian
  • Lover of embedded systems
  • Firmware engineer
  • Self-Proclaimed Geek

Latest Blog Posts

RSS