Basically, what I do now is assign the string to a macro called STRING, then use another macro called STRING_DESCRIPTOR to calculate the length of that STRING and build the string descriptor structure. This strategy only works if you allow the compiler to optimise away the temporary variable created to compute length, but...if there's a better way I'm happy to be enlightened.
Code: Select all
#undef STRING
#define STRING 0x0409
STRING_DESCRIPTOR(Language); // Build the language code string descriptor
#undef STRING
#define STRING 'L','i','t','e','-','O','n',' ','T','e','c','h','n','o','l','o','g','y',' ','C','o','r','p','.'
STRING_DESCRIPTOR(Manufacturer); // Build the manufacturer string descriptor
#undef STRING
#define STRING 'T','h','i','n','k','P','a','d',' ','U','S','B',' ','K','e','y','b','o','a','r','d',' ','w','i','t','h',' ','T','r','a','c','k','P','o','i','n','t'
STRING_DESCRIPTOR(Product); // Build the product string descriptor
const uint8_t * USB_config_dsc_ptr[1]; // Array of configuration descriptors
const uint8_t * USB_string_dsc_ptr[3]; // Array of string descriptors
void USB_Init_Desc()
{
USB_config_dsc_ptr[0] = &configDescriptor1;
USB_string_dsc_ptr[0] = (const uint8_t *) &Language; // Index 0 MUST be the language code array pointer
USB_string_dsc_ptr[STRING_INDEX_MANUFACTURER] = (const uint8_t *) &Manufacturer;
USB_string_dsc_ptr[STRING_INDEX_PRODUCT] = (const uint8_t *) ∏
}
Code: Select all
#define STRING_DESCRIPTOR(array) \
uint16_t t##array[] = {STRING}; /* This array will be optimised away because it is never referenced at execution time. */ \
/* It is used only to compute the length of the string specified by the STRING macro. */ \
const struct \
{ \
uint8_t bLength; \
uint8_t bDscType; \
uint16_t string[sizeof t##array / sizeof t##array[0]]; \
} array = \
{ \
2+sizeof t##array, /* bLength: Size of this structure in bytes (including bLength and bDscType fields) */ \
0x03, /* bDscType: 0x03 means this is a String descriptor */ \
{STRING} /* string: This is the array of 2-byte "characters" comprising the string */ \
}
Enjoy