Improved way of coding string descriptors in USBdsc.c

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
android
Posts: 345
Joined: 12 May 2010 10:35
Location: Sinny, Straya

Improved way of coding string descriptors in USBdsc.c

#1 Post by android » 25 Apr 2017 07:58

I've finally got around to fixing something that has been annoying me for a few years: having to count the bytes in USB string descriptors and set the length manually...then getting it wrong...then fixing it again...and experiencing the same pain for each new USB project :(

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. :D

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 *) ∏
}
The STRING_DESCRIPTOR macro that does the magic is:

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 */ \
  }
I've attached a zip of USBDsc.c and USBDsc.h showing a working example. It works for the HID report descriptor too.

Enjoy :)
Attachments
usbdsc.zip
(5.23 KiB) Downloaded 134 times
Regards, android
(User of MikroC Pro + mikroProg)

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Improved way of coding string descriptors in USBdsc.c

#2 Post by filip » 25 Apr 2017 16:17

Hi,

Thanks for sharing this. :)

Regards,
Filip.

diode_blade
Posts: 172
Joined: 24 Aug 2014 17:55
Location: Sheffield

Re: Improved way of coding string descriptors in USBdsc.c

#3 Post by diode_blade » 25 Apr 2017 21:26

Hi Android,
could you not have used "strlen" to get the size of each string, i havn't dabbled much with doing USB stuff (hardley any seems a bit daunting)so i might be being a bit naive here, or is it that you can't use the strlen function for what you are trying to do to return the size of the string, I am intrigued but like I said I take one look at reading about how to write and do usb stuff and I run a mile.... :lol:
Regards
diode

Haa just answered my own question by reading about sizeof.....shot miself in foot.... :D
"When the bugs strike it's no good bashing your head against a brick wall, you might damage the wall"

Post Reply

Return to “mikroC PRO for PIC General”