#include "usbd_core.h" #include "usbd_desc.h" #include "usbd_conf.h" #define XINPUT_VID 0x1209U #define XINPUT_PID 0xE668U #define XINPUT_LANGID 0x0409U #define XINPUT_MANUFACTURER_STRING "ERTOtech" #define XINPUT_PRODUCT_STRING "Refleks Lite XInput" #define XINPUT_CONFIGURATION_STRING "XInput Config" #define XINPUT_INTERFACE_STRING "XInput Interface" static uint8_t *XInput_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); static uint8_t *XInput_LangIdDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); static uint8_t *XInput_ManufacturerDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); static uint8_t *XInput_ProductDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); static uint8_t *XInput_SerialDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); static uint8_t *XInput_ConfigurationDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); static uint8_t *XInput_InterfaceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); static void XInput_UpdateSerial(void); static void XInput_IntToUnicode(uint32_t value, uint8_t *buffer, uint8_t length); USBD_DescriptorsTypeDef FS_Desc = { XInput_DeviceDescriptor, XInput_LangIdDescriptor, XInput_ManufacturerDescriptor, XInput_ProductDescriptor, XInput_SerialDescriptor, XInput_ConfigurationDescriptor, XInput_InterfaceDescriptor, }; __ALIGN_BEGIN static uint8_t xinputDeviceDescriptor[USB_LEN_DEV_DESC] __ALIGN_END = { USB_LEN_DEV_DESC, USB_DESC_TYPE_DEVICE, 0x00, 0x02, /* USB 2.00 */ 0x00, 0x00, 0x00, /* Class is defined by the interface */ USB_MAX_EP0_SIZE, LOBYTE(XINPUT_VID), HIBYTE(XINPUT_VID), LOBYTE(XINPUT_PID), HIBYTE(XINPUT_PID), 0x01, 0x01, /* Device release 1.01 */ USBD_IDX_MFC_STR, USBD_IDX_PRODUCT_STR, USBD_IDX_SERIAL_STR, 0x01, }; __ALIGN_BEGIN static uint8_t xinputLangIdDescriptor[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(XINPUT_LANGID), HIBYTE(XINPUT_LANGID), }; __ALIGN_BEGIN static uint8_t xinputStringDescriptor[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; __ALIGN_BEGIN static uint8_t xinputSerialDescriptor[USB_SIZ_STRING_SERIAL] __ALIGN_END = { USB_SIZ_STRING_SERIAL, USB_DESC_TYPE_STRING, }; static uint8_t *XInput_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); *length = sizeof(xinputDeviceDescriptor); return xinputDeviceDescriptor; } static uint8_t *XInput_LangIdDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); *length = sizeof(xinputLangIdDescriptor); return xinputLangIdDescriptor; } static uint8_t *XInput_ManufacturerDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); USBD_GetString((uint8_t *)XINPUT_MANUFACTURER_STRING, xinputStringDescriptor, length); return xinputStringDescriptor; } static uint8_t *XInput_ProductDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); USBD_GetString((uint8_t *)XINPUT_PRODUCT_STRING, xinputStringDescriptor, length); return xinputStringDescriptor; } static uint8_t *XInput_SerialDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); XInput_UpdateSerial(); *length = sizeof(xinputSerialDescriptor); return xinputSerialDescriptor; } static uint8_t *XInput_ConfigurationDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); USBD_GetString((uint8_t *)XINPUT_CONFIGURATION_STRING, xinputStringDescriptor, length); return xinputStringDescriptor; } static uint8_t *XInput_InterfaceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { UNUSED(speed); USBD_GetString((uint8_t *)XINPUT_INTERFACE_STRING, xinputStringDescriptor, length); return xinputStringDescriptor; } static void XInput_UpdateSerial(void) { uint32_t serial0 = *(uint32_t *)DEVICE_ID1; uint32_t serial1 = *(uint32_t *)DEVICE_ID2; uint32_t serial2 = *(uint32_t *)DEVICE_ID3; serial0 += serial2; if (serial0 != 0U) { XInput_IntToUnicode(serial0, &xinputSerialDescriptor[2], 8U); XInput_IntToUnicode(serial1, &xinputSerialDescriptor[18], 4U); } } static void XInput_IntToUnicode(uint32_t value, uint8_t *buffer, uint8_t length) { uint8_t index; for (index = 0U; index < length; index++) { uint8_t digit = (uint8_t)(value >> 28); buffer[2U * index] = (digit < 10U) ? (uint8_t)(digit + '0') : (uint8_t)(digit - 10U + 'A'); buffer[(2U * index) + 1U] = 0U; value <<= 4; } }