diff --git a/Firmware/PocketVoltex/Descriptors.c b/Firmware/PocketVoltex/Descriptors.c index 1d5bff8..b174f29 100644 --- a/Firmware/PocketVoltex/Descriptors.c +++ b/Firmware/PocketVoltex/Descriptors.c @@ -50,6 +50,47 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = HID_DESCRIPTOR_MOUSE(-128, 127, -128, 127, 1, false) }; + +const uint8_t PROGMEM MS_OS_Descriptor[] = +{ + MS_OS_DESCRIPTOR_SET + ( + MS_OS_CONFIG_SUBSET_HEADER + ( + 0x00, // Config 0 + MS_OS_FUNCTION_SUBSET_HEADER + ( + INTERFACE_ID_Config, // Interface ID + MS_OS_COMPAT_ID_WINUSB + ) + ) + ) +}; + +const uint8_t PROGMEM WebUSBAllowedOrigins[] = { + WEBUSB_ALLOWED_ORIGINS_HEADER + ( + 1, // 1 config header present + WEBUSB_CONFIG_SUBSET_HEADER + ( + 0x00, 1, // Config 0, 1 function header + // Config interface accessible from the web, 2 valid URLs + WEBUSB_FUNCTION_SUBSET_HEADER(INTERFACE_ID_Config, URL_ID_Config, URL_ID_Localhost) + ) + ) +}; + +const uint8_t PROGMEM BOSDescriptor[] = +{ + BOS_DESCRIPTOR + ( + 2, // 2 capability descriptors in use + WEBUSB_CAPABILITY_DESCRIPTOR(WEBUSB_ID, URL_ID_Config), // Vendor request ID, URL ID + // Required to force WinUSB driver for driverless WebUSB compatibility + MS_OS_20_CAPABILITY_DESCRIPTOR(MS_OS_ID, sizeof(MS_OS_Descriptor)) // Vendor request ID, Descriptor set length + ) +}; + const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = { .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, @@ -72,31 +113,6 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS }; -const uint8_t PROGMEM MS_OS_Descriptor[] = -{ - MS_OS_DESCRIPTOR_SET( - MS_OS_CONFIG_SUBSET_HEADER(0x00, // Config 0 - MS_OS_COMPAT_ID_WINUSB - ) - ) -}; - -const uint8_t PROGMEM WebUSBAllowedOrigins[] = { - WEBUSB_ALLOWED_ORIGINS_HEADER(0, // no config headers - // our two valid URLs - URL_ID_Config, URL_ID_Localhost - ) -}; - -const uint8_t PROGMEM BOSDescriptor[] = -{ - BOS_DESCRIPTOR(2, // 2 capability descriptors in use - WEBUSB_CAPABILITY_DESCRIPTOR(WEBUSB_ID, URL_ID_Config), // Vendor request ID, URL ID - // Required to force WinUSB driver for driverless WebUSB compatibility - MS_OS_20_CAPABILITY_DESCRIPTOR(MS_OS_ID, sizeof(MS_OS_Descriptor)) // Vendor request ID, Descriptor set length - ) -}; - const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = { .Config = @@ -104,7 +120,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), - .TotalInterfaces = 3, + .TotalInterfaces = 4, .ConfigurationNumber = 1, .ConfigurationStrIndex = STRING_ID_Product, @@ -224,6 +240,44 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = .EndpointSize = LED_EPSIZE, .PollingIntervalMS = 255 }, + + .Config_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = INTERFACE_ID_Config, + .AlternateSetting = 0, + + .TotalEndpoints = 2, + + .Class = 0xFF, + .SubClass = 0xFF, + .Protocol = 0xFF, + + .InterfaceStrIndex = STRING_ID_Config + }, + + .Config_DataInEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = CONFIG_IN_EPADDR, + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CONFIG_EPSIZE, + // ignored but required + .PollingIntervalMS = 0x05 + }, + + .Config_DataOutEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = CONFIG_OUT_EPADDR, + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CONFIG_EPSIZE, + // ignored but required + .PollingIntervalMS = 0x05 + } }; @@ -235,6 +289,7 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Pocket Voltex"); const USB_Descriptor_String_t PROGMEM LEDString = USB_STRING_DESCRIPTOR(L"Pocket Voltex LEDs"); const USB_Descriptor_String_t PROGMEM KnobString = USB_STRING_DESCRIPTOR(L"Pocket Voltex Knobs"); +const USB_Descriptor_String_t PROGMEM ConfigString = USB_STRING_DESCRIPTOR(L"Pocket Voltex Config"); // There may be a better way to do this const USB_Descriptor_String_t PROGMEM LEDString_indiv[] = { USB_STRING_DESCRIPTOR(L"L1-B"), @@ -277,6 +332,7 @@ void USB_Process_BOS(void) { USB_ControlRequest.bmRequestType != (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE)) { return; } + led_set_all(16,16,16); switch(USB_ControlRequest.bRequest) { case WEBUSB_ID: switch(USB_ControlRequest.wIndex) { @@ -370,6 +426,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, Address = &KnobString; Size = pgm_read_byte(&KnobString.Header.Size); break; + case STRING_ID_Config: + Address = &ConfigString; + Size = pgm_read_byte(&ConfigString.Header.Size); + break; default: if(DescriptorNumber >= STRING_ID_LED_Indiv) { Address = &(LEDString_indiv[STRING_ID_LED_Indiv - DescriptorNumber]); diff --git a/Firmware/PocketVoltex/Descriptors.h b/Firmware/PocketVoltex/Descriptors.h index 910c2a3..489bba0 100644 --- a/Firmware/PocketVoltex/Descriptors.h +++ b/Firmware/PocketVoltex/Descriptors.h @@ -67,6 +67,11 @@ USB_Descriptor_Interface_t HID3_Interface; USB_HID_Descriptor_HID_t HID3_LEDHID; USB_Descriptor_Endpoint_t HID3_ReportINEndpoint; + + // Config interface as we can't talk to composite directly + USB_Descriptor_Interface_t Config_Interface; + USB_Descriptor_Endpoint_t Config_DataInEndpoint; + USB_Descriptor_Endpoint_t Config_DataOutEndpoint; } USB_Descriptor_Configuration_t; /** Enum for the device interface descriptor IDs within the device. @@ -75,7 +80,8 @@ { INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */ INTERFACE_ID_Mouse = 1, /**< Mouse interface descriptor ID */ - INTERFACE_ID_LED = 2 /**< LED interface descriptor ID */ + INTERFACE_ID_LED = 2, /**< LED interface descriptor ID */ + INTERFACE_ID_Config = 3 /**< Config interface descriptor ID */ }; /** Enum for the device string descriptor IDs within the device. Each string descriptor should @@ -86,8 +92,9 @@ STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ STRING_ID_Product = 2, /**< Product string ID */ STRING_ID_Knobs = 3, - STRING_ID_LED = 4, /**< LED string ID */ - STRING_ID_LED_Indiv = 5, + STRING_ID_Config = 4, + STRING_ID_LED = 5, /**< LED string ID */ + STRING_ID_LED_Indiv = 6, }; enum URLDescriptors_t @@ -97,15 +104,19 @@ }; /* Macros: */ - #define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1) - - #define MOUSE_IN_EPADDR (ENDPOINT_DIR_IN | 2) - - #define LED_EPADDR (ENDPOINT_DIR_IN | 3) + #define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1) + #define MOUSE_IN_EPADDR (ENDPOINT_DIR_IN | 2) + #define LED_EPADDR (ENDPOINT_DIR_IN | 3) + #define CONFIG_IN_EPADDR (ENDPOINT_DIR_IN | 4) + #define CONFIG_OUT_EPADDR (ENDPOINT_DIR_OUT | 5) #define KEYBOARD_EPSIZE SWITCH_COUNT + 2 #define MOUSE_EPSIZE 8 #define LED_EPSIZE LED_TOTAL_COUNT + // MUST be 8, 16, 32 or 64 bytes + #define CONFIG_EPSIZE CONFIG_BYTES <= 8 ? 8 : \ + CONFIG_BYTES <= 16 ? 16 : \ + CONFIG_BYTES <= 32 ? 32 : 64 // if it's larger than 64 bytes, you're out of luck /* Function Prototypes: */ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, diff --git a/Firmware/PocketVoltex/PocketVoltex.c b/Firmware/PocketVoltex/PocketVoltex.c index 6bb2e76..8b05789 100644 --- a/Firmware/PocketVoltex/PocketVoltex.c +++ b/Firmware/PocketVoltex/PocketVoltex.c @@ -158,6 +158,19 @@ int main(void) HID_Device_USBTask(&Mouse_HID_Interface); HID_Device_USBTask(&LED_HID_Interface); USB_USBTask(); + + //uint8_t ReceivedData[VENDOR_IO_EPSIZE]; + //memset(ReceivedData, 0x00, sizeof(ReceivedData)); + // + Endpoint_SelectEndpoint(CONFIG_OUT_EPADDR); + if (Endpoint_IsOUTReceived()) { + // Endpoint_Read_Stream_LE(ReceivedData, VENDOR_IO_EPSIZE, NULL); + Endpoint_ClearOUT(); + // + // Endpoint_SelectEndpoint(VENDOR_IN_EPADDR); + // Endpoint_Write_Stream_LE(ReceivedData, VENDOR_IO_EPSIZE, NULL); + // Endpoint_ClearIN(); + } } } @@ -317,6 +330,8 @@ void EVENT_USB_Device_ConfigurationChanged(void) HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface); HID_Device_ConfigureEndpoints(&Mouse_HID_Interface); HID_Device_ConfigureEndpoints(&LED_HID_Interface); + Endpoint_ConfigureEndpoint(CONFIG_IN_EPADDR, EP_TYPE_BULK, CONFIG_EPSIZE, 1); + Endpoint_ConfigureEndpoint(CONFIG_OUT_EPADDR, EP_TYPE_BULK, CONFIG_EPSIZE, 1); USB_Device_EnableSOFEvents(); }