Browse over 10,000 Electronics Projects

USB HID device development on the STM32 F042

USB HID device development on the STM32 F042

USB strings

During the device enumeration phase you get the opportunity to supply some strings, in a language of your choice, that describe the facets of your device. My custom HID device driver requires that you supply manufacturer and product names, serial number and descriptions for your configuration and interface.

Here’s the strings I used in the example code.

/*
 * These are the USB device strings in the format required for a USB string descriptor.
 * To change these to suit your device you need only change the unicode string in the
 * last line of each definition to suit your device. Then count up the bytes required for
 * the complete descriptor and go back and insert that byte count in the array declaration
 * in the configuration class.
 */

const uint8_t UsbDeviceCustomHid::MyHidConfiguration::ManufacturerString[sizeof(UsbDeviceCustomHid::MyHidConfiguration::ManufacturerString)]={
  sizeof(UsbDeviceCustomHid::MyHidConfiguration::ManufacturerString),
  USB_DESC_TYPE_STRING,
  'A',0,'n',0,'d',0,'y',0,''',0,'s',0,' ',0,'W',0,'o',0,'r',0,'k',0,'s',0,'h',0,'o',0,'p',0
};

const uint8_t UsbDeviceCustomHid::MyHidConfiguration::ProductString[sizeof(UsbDeviceCustomHid::MyHidConfiguration::ProductString)]={
  sizeof(UsbDeviceCustomHid::MyHidConfiguration::ProductString),
  USB_DESC_TYPE_STRING,
  'C',0,'u',0,'s',0,'t',0,'o',0,'m',0,' ',0,'H',0,'I',0,'D',0
};

const uint8_t UsbDeviceCustomHid::MyHidConfiguration::SerialString[sizeof(UsbDeviceCustomHid::MyHidConfiguration::SerialString)]={
  sizeof(UsbDeviceCustomHid::MyHidConfiguration::SerialString),
  USB_DESC_TYPE_STRING,
  '1',0,'.',0,'0',0,'.',0,'0',0
};

const uint8_t UsbDeviceCustomHid::MyHidConfiguration::ConfigurationString[sizeof(UsbDeviceCustomHid::MyHidConfiguration::ConfigurationString)]={
  sizeof(UsbDeviceCustomHid::MyHidConfiguration::ConfigurationString),
  USB_DESC_TYPE_STRING,
  'c',0,'f',0,'g',0
};

const uint8_t UsbDeviceCustomHid::MyHidConfiguration::InterfaceString[sizeof(UsbDeviceCustomHid::MyHidConfiguration::InterfaceString)]={
  sizeof(UsbDeviceCustomHid::MyHidConfiguration::InterfaceString),
  USB_DESC_TYPE_STRING,
  'i',0,'t',0,'f',0
};

USB strings are made up of 16-bit Unicode characters without ‘C’-style null terminators. Handily for English-speaking westeners the lower Unicode code points map directly to the printable ASCII range so all we need to do is expand those characters to 16-bits to have a valid Unicode code point. The sample strings serve as a base for you to copy-paste into your own code.



Advertisement1


The manufacturer, product name and serial number should be obvious. Don’t expect these to be displayed by the Windows Device Manager though because it will use the generic USB Input Device name supplied by Microsoft’s universal HID driver.

The configuration and interface strings are less obvious and you can learn more about what they are by clicking on the links. The stm32plus driver provides one configuration and one interface. I’ve never seen Windows display these strings anywhere in the user interface.

Starting the device

OK so you’ve done all the prep work and you’re ready to tell the host that you exist. To do that you just need to call the start() method.

/*
 * Start the peripheral. This will pull up the DP line which is the trigger for the host
 * to start enumeration of this device
 */

usb.start();

This will enable the pull-up resistor on the D+ line that prompts the host to begin the enumeration process and enable your device. You will get control back immediately. Everything else from here is interrupt driven.

There’s an equivalent stop() that can be used to do a software disconnect of the device and this can be useful in testing to ensure that you handle the case where a user uses the safely remove hardware system tray option to disconnect your device without cutting the power.

Sending reports to the host

The method on the UsbCustomHid class that sends a report to the host is sendReport(), an example of which is shown here.

usb.sendReport("x01Hello World",12);

 

Note how the data being sent is prefixed with the single byte report identifier. Very important. Don’t forget this. If your report is smaller than the 64-byte maximum packet size for an interrupt transfer, and I recommend that they are, then your report will be copied into the USB peripheral’s internal memory before this method returns so you don’t have to keep the data in scope.

The peripheral will begin the process of sending the report data to the host and you will be notified when it’s complete via the TX complete event handler. You cannot send another report until the previous report has been sent and you cannot exceed the maximum bandwidth for interrupt transfers of 64-bytes per millisecond.

Pages: 1 2 3 4 5 6 7 8 9

 


Top