LUFA Focus: Multi address space descriptors

I thought I’d take this opportunity between releases to show off some of the new features of the upcoming release. I’ve already posted on the new Device mode USB class driver framework which will make implementing the standard classes oh-so-easy, so here’s a run-down of a new feature (as of last night).

All device mode LUFA applications have several descriptors – special tables of values which are sent to the host upon request which indicate the device’s function, requirements, capabilities and other miscellaneous info. A typical device has a bunch of these, including a Device descriptor (giving the overall device class/subclass/protocol information, implemented USB specification, etc.) and a configuration descriptor (itself made up of a lot of sub-descriptors which describe implemented classes).

In the current release, these descriptors can be located in one of three memory address spaces; FLASH (the default, to save on RAM at the expense of having the descriptors be entirely read-only), EEPROM (to save on FLASH and allow the descriptors to be modified in a non-volatile manner) and RAM (for volatile manipulation of the descriptors). The descriptor memory space was set by a compile time constant, either by not defining any special token to indicate FLASH descriptors, or by defining the USE_EEPROM_DESCRIPTORS or USE_RAM_DESCRIPTORS for the other memory spaces.

However, this is not the level of granularity some people need. I’ve been asked by someone wanting to implement an EEPROM descriptor to hold the device’s serial number, while keeping all other descriptors in FLASH to save on EEPROM space – this simply isn’t possible without hacking up the low level library code. However, with the next release, there’s a solution.

The current user-application callback for the fetching of descriptors has the following signature:

uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress);

That is, the library indicates the descriptor being requested by the wValue and wIndex parameters (see USB specification), and the callback indicates the descriptor’s size and address if it exists by setting the DescriptorAddress parameter and returning the size. In the next release, this will remain by defining the new token USE_FLASH_DESCRIPTORS in the same manner as the other two tokens to fix all descriptors back into FLASH space.

If none of the USE_*_DESCRIPTORS tokens are used in an application, the function now takes on a slightly different signature:

uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress, uint8_t* MemoryAddressSpace);

That is, it gains a new MemoryAddressSpace parameter. This is similar to the USE_STATIC_OPTIONS compile time token which alters the function signature of the USB_Init() routine, so it shouldn’t be entirely alien to LUFA users.

The new parameter is a out parameter, and should be set to one of the values in the new USB_DescriptorMemorySpaces_t enum:

enum USB_DescriptorMemorySpaces_t
{
MEMSPACE_FLASH = 0,
MEMSPACE_EEPROM = 1,
MEMSPACE_RAM = 2,
};

Which indicates to the stack in what memory space the given descriptor lives. This gives a fine-grain control over each descriptor’s location for those who need it, allowing for the descriptors to live in different memory spaces according to the application’s needs.

 

Comments

No comments so far.

Leave a Reply

 
(will not be published)
 
 
Comment