276 lines
9.9 KiB
C
276 lines
9.9 KiB
C
#include "usb_device_config.h"
|
|
#include "usb.h"
|
|
#include "usb_device.h"
|
|
#include "include/usb/usb_device_class.h"
|
|
#include "include/usb/usb_device_hid.h"
|
|
#include "util.h"
|
|
#include "usb_device_descriptor.h"
|
|
#include "composite.h"
|
|
#include "hid_keyboard.h"
|
|
#include "hid_mouse.h"
|
|
|
|
uint8_t UsbDeviceDescriptor[USB_DESCRIPTOR_LENGTH_DEVICE] = {
|
|
USB_DESCRIPTOR_LENGTH_DEVICE,
|
|
USB_DESCRIPTOR_TYPE_DEVICE,
|
|
USB_SHORT_GET_LOW(USB_DEVICE_SPECIFICATION_BCD_VERSION),
|
|
USB_SHORT_GET_HIGH(USB_DEVICE_SPECIFICATION_BCD_VERSION),
|
|
USB_DEVICE_CLASS,
|
|
USB_DEVICE_SUBCLASS,
|
|
USB_DEVICE_PROTOCOL,
|
|
USB_CONTROL_MAX_PACKET_SIZE,
|
|
GET_LSB_OF_WORD(USB_VENDOR_ID),
|
|
GET_MSB_OF_WORD(USB_VENDOR_ID),
|
|
GET_LSB_OF_WORD(USB_PRODUCT_ID),
|
|
GET_MSB_OF_WORD(USB_PRODUCT_ID),
|
|
USB_SHORT_GET_LOW(USB_DEVICE_RELEASE_NUMBER),
|
|
USB_SHORT_GET_HIGH(USB_DEVICE_RELEASE_NUMBER),
|
|
USB_STRING_DESCRIPTOR_ID_MANUFACTURER,
|
|
USB_STRING_DESCRIPTOR_ID_PRODUCT,
|
|
USB_STRING_DESCRIPTOR_ID_SERIAL_NUMBER,
|
|
USB_DEVICE_CONFIGURATION_COUNT,
|
|
};
|
|
|
|
uint8_t UsbConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL] = {
|
|
|
|
// Configuration descriptor
|
|
|
|
USB_DESCRIPTOR_LENGTH_CONFIGURE,
|
|
USB_DESCRIPTOR_TYPE_CONFIGURE,
|
|
USB_SHORT_GET_LOW(USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL),
|
|
USB_SHORT_GET_HIGH(USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL), // Total length of data returned for this configuration.
|
|
USB_COMPOSITE_INTERFACE_COUNT,
|
|
USB_COMPOSITE_CONFIGURE_INDEX, // Value to use as an argument to the SetConfiguration() request to select this configuration
|
|
0x00U, // Index of string descriptor describing this configuration
|
|
|
|
// Configuration characteristics
|
|
// D7: Reserved (set to one)
|
|
// D6: Self-powered
|
|
// D5: Remote Wakeup
|
|
// D4...0: Reserved (reset to zero)
|
|
(USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) |
|
|
(USB_DEVICE_CONFIG_SELF_POWER << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT) |
|
|
(USB_DEVICE_CONFIG_REMOTE_WAKEUP << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT),
|
|
|
|
// Maximum power consumption of the USB device from the bus in this specific configuration
|
|
// when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA).
|
|
USB_DEVICE_MAX_POWER,
|
|
|
|
// Mouse interface descriptor
|
|
|
|
USB_DESCRIPTOR_LENGTH_INTERFACE,
|
|
USB_DESCRIPTOR_TYPE_INTERFACE,
|
|
USB_MOUSE_INTERFACE_INDEX,
|
|
0x00U, // Value used to select this alternate setting for the interface identified in the prior field
|
|
USB_MOUSE_ENDPOINT_COUNT,
|
|
USB_MOUSE_CLASS,
|
|
USB_MOUSE_SUBCLASS,
|
|
USB_MOUSE_PROTOCOL,
|
|
USB_STRING_DESCRIPTOR_ID_MOUSE,
|
|
|
|
// Mouse HID descriptor
|
|
|
|
USB_DESCRIPTOR_LENGTH_HID,
|
|
USB_DESCRIPTOR_TYPE_HID,
|
|
0x00U, 0x01U, // ID Class Specification release.
|
|
0x00U, // Country code of the localized hardware
|
|
0x01U, // Number of class descriptors (at least one report descriptor)
|
|
USB_DESCRIPTOR_TYPE_HID_REPORT,
|
|
USB_SHORT_GET_LOW(USB_MOUSE_REPORT_DESCRIPTOR_LENGTH),
|
|
USB_SHORT_GET_HIGH(USB_MOUSE_REPORT_DESCRIPTOR_LENGTH),
|
|
|
|
// Mouse endpoint descriptor
|
|
|
|
USB_DESCRIPTOR_LENGTH_ENDPOINT,
|
|
USB_DESCRIPTOR_TYPE_ENDPOINT,
|
|
// The address of the endpoint on the USB device described by this descriptor.
|
|
USB_MOUSE_ENDPOINT_IN | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
|
|
USB_ENDPOINT_INTERRUPT, // This field describes the endpoint's attributes
|
|
// Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected.
|
|
USB_SHORT_GET_LOW(USB_MOUSE_INTERRUPT_IN_PACKET_SIZE), USB_SHORT_GET_HIGH(USB_MOUSE_INTERRUPT_IN_PACKET_SIZE),
|
|
USB_MOUSE_INTERRUPT_IN_INTERVAL, // Interval for polling endpoint for data transfers.
|
|
|
|
// Keyboard interface descriptor
|
|
|
|
USB_DESCRIPTOR_LENGTH_INTERFACE,
|
|
USB_DESCRIPTOR_TYPE_INTERFACE,
|
|
USB_KEYBOARD_INTERFACE_INDEX,
|
|
0x00U, // Value used to select this alternate setting for the interface identified in the prior field
|
|
USB_KEYBOARD_ENDPOINT_COUNT,
|
|
USB_KEYBOARD_CLASS,
|
|
USB_KEYBOARD_SUBCLASS,
|
|
USB_KEYBOARD_PROTOCOL,
|
|
USB_STRING_DESCRIPTOR_ID_KEYBOARD,
|
|
|
|
// Keyboard HID descriptor
|
|
|
|
USB_DESCRIPTOR_LENGTH_HID,
|
|
USB_DESCRIPTOR_TYPE_HID,
|
|
0x00U, 0x01U, // HID Class Specification release
|
|
0x00U, // Country code of the localized hardware
|
|
0x01U, // Number of class descriptors (at least one report descriptor)
|
|
USB_DESCRIPTOR_TYPE_HID_REPORT,
|
|
USB_SHORT_GET_LOW(USB_KEYBOARD_REPORT_DESCRIPTOR_LENGTH),
|
|
USB_SHORT_GET_HIGH(USB_KEYBOARD_REPORT_DESCRIPTOR_LENGTH),
|
|
|
|
// Keyboard endpoint descriptor
|
|
|
|
USB_DESCRIPTOR_LENGTH_ENDPOINT,
|
|
USB_DESCRIPTOR_TYPE_ENDPOINT,
|
|
USB_KEYBOARD_ENDPOINT_IN | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
|
|
// The address of the endpoint on the USB device described by this descriptor.
|
|
USB_ENDPOINT_INTERRUPT, // This field describes the endpoint's attributes
|
|
USB_SHORT_GET_LOW(USB_KEYBOARD_INTERRUPT_IN_PACKET_SIZE),
|
|
USB_SHORT_GET_HIGH(USB_KEYBOARD_INTERRUPT_IN_PACKET_SIZE),
|
|
// Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected.
|
|
USB_KEYBOARD_INTERRUPT_IN_INTERVAL,
|
|
};
|
|
|
|
uint8_t g_UsbDeviceString0[USB_DESCRIPTOR_LENGTH_STRING0] = {
|
|
sizeof(g_UsbDeviceString0), USB_DESCRIPTOR_TYPE_STRING, 0x09U, 0x04U,
|
|
};
|
|
|
|
uint8_t g_UsbDeviceString1[USB_DESCRIPTOR_LENGTH_STRING1] = {
|
|
sizeof(g_UsbDeviceString1),
|
|
USB_DESCRIPTOR_TYPE_STRING,
|
|
'F', 0x00U,
|
|
'R', 0x00U,
|
|
'E', 0x00U,
|
|
'E', 0x00U,
|
|
'S', 0x00U,
|
|
'C', 0x00U,
|
|
'A', 0x00U,
|
|
'L', 0x00U,
|
|
'E', 0x00U,
|
|
' ', 0x00U,
|
|
'S', 0x00U,
|
|
'E', 0x00U,
|
|
'M', 0x00U,
|
|
'I', 0x00U,
|
|
'C', 0x00U,
|
|
'O', 0x00U,
|
|
'N', 0x00U,
|
|
'D', 0x00U,
|
|
'U', 0x00U,
|
|
'C', 0x00U,
|
|
'T', 0x00U,
|
|
'O', 0x00U,
|
|
'R', 0x00U,
|
|
' ', 0x00U,
|
|
'I', 0x00U,
|
|
'N', 0x00U,
|
|
'C', 0x00U,
|
|
'.', 0x00U,
|
|
};
|
|
|
|
uint8_t g_UsbDeviceString2[USB_DESCRIPTOR_LENGTH_STRING2] = {
|
|
sizeof(g_UsbDeviceString2),
|
|
USB_DESCRIPTOR_TYPE_STRING,
|
|
'C', 0x00U,
|
|
'O', 0x00U,
|
|
'M', 0x00U,
|
|
'P', 0x00U,
|
|
'O', 0x00U,
|
|
'S', 0x00U,
|
|
'I', 0x00U,
|
|
'T', 0x00U,
|
|
'E', 0x00U,
|
|
' ', 0x00U,
|
|
'D', 0x00U,
|
|
'E', 0x00U,
|
|
'V', 0x00U,
|
|
'I', 0x00U,
|
|
'C', 0x00U,
|
|
'E', 0x00U,
|
|
};
|
|
|
|
uint32_t g_UsbDeviceStringDescriptorLength[USB_DEVICE_STRING_COUNT] = {
|
|
sizeof(g_UsbDeviceString0), sizeof(g_UsbDeviceString1), sizeof(g_UsbDeviceString2),
|
|
sizeof(UsbMouseString), sizeof(UsbKeyboardString),
|
|
};
|
|
|
|
uint8_t *g_UsbDeviceStringDescriptorArray[USB_DEVICE_STRING_COUNT] = {
|
|
g_UsbDeviceString0, g_UsbDeviceString1, g_UsbDeviceString2, UsbMouseString, UsbKeyboardString,
|
|
};
|
|
|
|
usb_language_t g_UsbDeviceLanguage[USB_DEVICE_LANGUAGE_COUNT] = {{
|
|
g_UsbDeviceStringDescriptorArray, g_UsbDeviceStringDescriptorLength, (uint16_t)0x0409U,
|
|
}};
|
|
|
|
usb_language_list_t g_UsbDeviceLanguageList = {
|
|
g_UsbDeviceString0, sizeof(g_UsbDeviceString0), g_UsbDeviceLanguage, USB_DEVICE_LANGUAGE_COUNT,
|
|
};
|
|
|
|
usb_status_t USB_DeviceGetDeviceDescriptor(
|
|
usb_device_handle handle, usb_device_get_device_descriptor_struct_t *deviceDescriptor)
|
|
{
|
|
deviceDescriptor->buffer = UsbDeviceDescriptor;
|
|
deviceDescriptor->length = USB_DESCRIPTOR_LENGTH_DEVICE;
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
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 = UsbConfigurationDescriptor;
|
|
configurationDescriptor->length = USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL;
|
|
return kStatus_USB_Success;
|
|
}
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
usb_status_t USB_DeviceGetHidDescriptor(
|
|
usb_device_handle handle, usb_device_get_hid_descriptor_struct_t *hidDescriptor)
|
|
{
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
|
|
usb_status_t USB_DeviceGetHidReportDescriptor(
|
|
usb_device_handle handle, usb_device_get_hid_report_descriptor_struct_t *hidReportDescriptor)
|
|
{
|
|
if (USB_MOUSE_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) {
|
|
hidReportDescriptor->buffer = UsbMouseReportDescriptor;
|
|
hidReportDescriptor->length = USB_MOUSE_REPORT_DESCRIPTOR_LENGTH;
|
|
} else if (USB_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) {
|
|
hidReportDescriptor->buffer = UsbKeyboardReportDescriptor;
|
|
hidReportDescriptor->length = USB_KEYBOARD_REPORT_DESCRIPTOR_LENGTH;
|
|
} else {
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
usb_status_t USB_DeviceGetHidPhysicalDescriptor(
|
|
usb_device_handle handle, usb_device_get_hid_physical_descriptor_struct_t *hidPhysicalDescriptor)
|
|
{
|
|
return kStatus_USB_InvalidRequest;
|
|
}
|