USB descriptor functions
All USB device descriptor and functions are placed in the “usb_device_descriptor.c” file.
USB descriptor
The descriptors for each class can be obtained from the class-related examples and class specification. For the composite device, combine multiple class descriptors.
Note: The interface number in the configuration descriptor must be the correct interface number value. The endpoint number value in each endpoint descriptor must be consistent with the structures in usb_device_endpoint_struct_t.
Parent topic:USB descriptor functions
USB_DeviceGetDeviceDescriptor
This function is used to get the device descriptor. All devices must implement this function.
usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle,
usb_device_get_device_descriptor_struct_t *deviceDescriptor)
{
deviceDescriptor->buffer = g_UsbDeviceDescriptor;
deviceDescriptor->length = USB_DESCRIPTOR_LENGTH_DEVICE;
return kStatus_USB_Success;
}
Parent topic:USB descriptor functions
Parent topic:USB composite device descriptor examples
USB_DeviceGetConfigurationDescriptor
This function is used to get the configuration descriptor. All devices must implement this function.
/* Get device configuration descriptor request */
usb_status_t USB_DeviceGetConfigurationDescriptor(
usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor)
{
if (USB_COMPOSITE_CONFIGURE_INDEX > configurationDescriptor->configuration)
{
configurationDescriptor->buffer = g_UsbDeviceConfigurationDescriptor;
configurationDescriptor->length = USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL;
return kStatus_USB_Success;
}
return kStatus_USB_InvalidRequest;
}
Parent topic:USB descriptor functions
Parent topic:USB composite device descriptor examples
USB_DeviceGetStringDescriptor
This function is used to get the string descriptor. All devices must implement this function.
/* Get device string descriptor request */
usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle,
usb_device_get_string_descriptor_struct_t *stringDescriptor)
{
if (stringDescriptor->stringIndex == 0U)
{
stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageString;
stringDescriptor->length = g_UsbDeviceLanguageList.stringLength;
}
else
{
uint8_t languageId = 0U;
uint8_t languageIndex = USB_DEVICE_STRING_COUNT;
for (; languageId < USB_DEVICE_STRING_COUNT; languageId++)
{
if (stringDescriptor->languageId == g_UsbDeviceLanguageList.languageList[languageId].languageId)
{
if (stringDescriptor->stringIndex < USB_DEVICE_STRING_COUNT)
{
languageIndex = stringDescriptor->stringIndex;
}
break;
}
}
if (USB_DEVICE_STRING_COUNT == languageIndex)
{
return kStatus_USB_InvalidRequest;
}
stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageList[languageId].string[languageIndex];
stringDescriptor->length = g_UsbDeviceLanguageList.languageList[languageId].length[languageIndex];
}
return kStatus_USB_Success;
}
Parent topic:USB descriptor functions
Parent topic:USB composite device descriptor examples
USB_DeviceGetHidDescriptor
/* Get HID descriptor request */
usb_status_t USB_DeviceGetHidDescriptor(usb_device_handle handle,
usb_device_get_hid_descriptor_struct_t *hidDescriptor)
{
/* If this request is not supported, return the error code “kStatus_USB_InvalidRequest”. Otherwise, fill the hidDescriptor with the descriptor buffer address and length based on the interface number. */
return kStatus_USB_InvalidRequest;
}
Parent topic:USB descriptor functions
Parent topic:USB composite device descriptor examples
USB_DeviceGetHidReportDescriptor
/* Get the HID report descriptor request */
usb_status_t USB_DeviceGetHidReportDescriptor(usb_device_handle handle,
usb_device_get_hid_report_descriptor_struct_t *hidReportDescriptor)
{
if (USB_HID_GENERIC_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber)
{
hidReportDescriptor->buffer = g_UsbDeviceHidGenericReportDescriptor;
hidReportDescriptor->length = USB_DESCRIPTOR_LENGTH_HID_GENERIC_REPORT;
}
else if (USB_HID_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber)
{
hidReportDescriptor->buffer = g_UsbDeviceHidKeyboardReportDescriptor;
hidReportDescriptor->length = USB_DESCRIPTOR_LENGTH_HID_KEYBOARD_REPORT;
}
else
{
return kStatus_USB_InvalidRequest;
}
return kStatus_USB_Success;
}
Parent topic:USB descriptor functions
Parent topic:USB composite device descriptor examples
USB_DeviceGetHidPhysicalDescriptor
/* Get the HID physical descriptor request */
usb_status_t USB_DeviceGetHidPhysicalDescriptor(
usb_device_handle handle, usb_device_get_hid_physical_descriptor_struct_t *hidPhysicalDescriptor)
{
/* If this request is not supported, return the error code “kStatus_USB_InvalidRequest”. Otherwise, fill the hidPhysicalDescriptor with the descriptor buffer address and length based on the interface number and the physical index. */
return kStatus_USB_InvalidRequest;
}
Parent topic:USB descriptor functions
Parent topic:USB composite device descriptor examples
USB_DeviceSetSpeed
/* Because HS and FS descriptors are different, update the device descriptors and configurations to match the current speed.
* By default, the device descriptors and configurations are configured by using FS parameters for both EHCI and KHCI.
* When the EHCI is enabled, the application needs to call this function to update the device by using current speed.
* The updated information includes the endpoint max packet size, endpoint interval, and so on. */
usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed)
{
usb_descriptor_union_t *descriptorHead;
usb_descriptor_union_t *descriptorTail;
descriptorHead = (usb_descriptor_union_t *)&g_UsbDeviceConfigurationDescriptor[0];
descriptorTail = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL - 1U]);
while (descriptorHead < descriptorTail)
{
if (descriptorHead->common.bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT)
{
if (USB_SPEED_HIGH == speed)
{
if (USB_HID_KEYBOARD_ENDPOINT_IN == (descriptorHead->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))
{
descriptorHead->endpoint.bInterval = HS_HID_KEYBOARD_INTERRUPT_IN_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_HID_KEYBOARD_INTERRUPT_IN_PACKET_SIZE,
descriptorHead->endpoint.wMaxPacketSize);
}
else if (((descriptorHead->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
(USB_HID_GENERIC_ENDPOINT_IN == (descriptorHead->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
{
descriptorHead->endpoint.bInterval = HS_HID_GENERIC_INTERRUPT_IN_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_HID_GENERIC_INTERRUPT_IN_PACKET_SIZE,
descriptorHead->endpoint.wMaxPacketSize);
}
else if (((descriptorHead->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
(USB_HID_GENERIC_ENDPOINT_OUT == (descriptorHead->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
{
descriptorHead->endpoint.bInterval = HS_HID_GENERIC_INTERRUPT_OUT_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_HID_GENERIC_INTERRUPT_OUT_PACKET_SIZE,
descriptorHead->endpoint.wMaxPacketSize);
}
}
else
{
if (USB_HID_KEYBOARD_ENDPOINT_IN == (descriptorHead->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))
{
descriptorHead->endpoint.bInterval = FS_HID_KEYBOARD_INTERRUPT_IN_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_HID_KEYBOARD_INTERRUPT_IN_PACKET_SIZE,
descriptorHead->endpoint.wMaxPacketSize);
}
else if (((descriptorHead->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
(USB_HID_GENERIC_ENDPOINT_IN == (descriptorHead->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
{
descriptorHead->endpoint.bInterval = FS_HID_GENERIC_INTERRUPT_IN_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_HID_GENERIC_INTERRUPT_IN_PACKET_SIZE,
descriptorHead->endpoint.wMaxPacketSize);
}
else if (((descriptorHead->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
(USB_HID_GENERIC_ENDPOINT_OUT == (descriptorHead->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
{
descriptorHead->endpoint.bInterval = FS_HID_GENERIC_INTERRUPT_OUT_INTERVAL;
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_HID_GENERIC_INTERRUPT_OUT_PACKET_SIZE,
descriptorHead->endpoint.wMaxPacketSize);
}
}
}
descriptorHead = (usb_descriptor_union_t *)((uint8_t *)descriptorHead + descriptorHead->common.bLength);
}
for (int i = 0U; i < USB_HID_GENERIC_ENDPOINT_COUNT; i++)
{
if (USB_SPEED_HIGH == speed)
{
if (g_UsbDeviceHidGenericEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN)
{
g_UsbDeviceHidGenericEndpoints[i].maxPacketSize = HS_HID_GENERIC_INTERRUPT_IN_PACKET_SIZE;
}
else
{
g_UsbDeviceHidGenericEndpoints[i].maxPacketSize = HS_HID_GENERIC_INTERRUPT_OUT_PACKET_SIZE;
}
}
else
{
if (g_UsbDeviceHidGenericEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN)
{
g_UsbDeviceHidGenericEndpoints[i].maxPacketSize = HS_HID_GENERIC_INTERRUPT_OUT_PACKET_SIZE;
}
else
{
g_UsbDeviceHidGenericEndpoints[i].maxPacketSize = FS_HID_GENERIC_INTERRUPT_OUT_PACKET_SIZE;
}
}
}
if (USB_SPEED_HIGH == speed)
{
g_UsbDeviceHidKeyboardEndpoints[0].maxPacketSize = HS_HID_KEYBOARD_INTERRUPT_IN_PACKET_SIZE;
}
else
{
g_UsbDeviceHidKeyboardEndpoints[0].maxPacketSize = FS_HID_KEYBOARD_INTERRUPT_IN_PACKET_SIZE;
}
return kStatus_USB_Success;
}
Parent topic:USB descriptor functions
Parent topic:USB composite device descriptor examples