From e79de98ac56c99cfc8f77a6f3247ad00de71fdde Mon Sep 17 00:00:00 2001 From: William Toohey Date: Sat, 29 Oct 2016 00:10:08 +1000 Subject: [PATCH] broke LED descriptor --- Firmware/Keyboard/Descriptors.c | 120 +++++++++++++++++++++++++++++--- Firmware/Keyboard/Descriptors.h | 17 +++-- Firmware/Keyboard/Keyboard.c | 26 ++++++- Firmware/Keyboard/LED.c | 4 ++ Firmware/Keyboard/LED.h | 1 + 5 files changed, 155 insertions(+), 13 deletions(-) diff --git a/Firmware/Keyboard/Descriptors.c b/Firmware/Keyboard/Descriptors.c index 315e5ad..085cc1d 100644 --- a/Firmware/Keyboard/Descriptors.c +++ b/Firmware/Keyboard/Descriptors.c @@ -34,6 +34,63 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] = HID_RI_END_COLLECTION(0), }; +const USB_Descriptor_HIDReport_Datatype_t PROGMEM LEDReport[] = +{ + HID_RI_USAGE_PAGE(16, 0xFFDE), /* Vendor Page 0xDC */ + HID_RI_USAGE(8, 0xFE), /* Vendor Usage 0xFB */ + HID_RI_COLLECTION(8, 0x03), /* Vendor Usage 1 */ + HID_RI_USAGE(8, 0x04), /* Vendor Usage 2 */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0xFF), + HID_RI_REPORT_SIZE(8, 8), + HID_RI_REPORT_COUNT(8, CONFIG_BYTES), + HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + + HID_RI_USAGE(8, 0x04), /* Vendor Usage 2 */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0xFF), + HID_RI_REPORT_SIZE(8, 8), + HID_RI_REPORT_COUNT(8, CONFIG_BYTES), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + HID_RI_END_COLLECTION(0), + //HID_RI_USAGE_PAGE(16, 0xFF00), + // HID_RI_USAGE(8, 0x01), + // HID_RI_COLLECTION(8, 0x01), + // HID_RI_USAGE(8, 0x02), + // HID_RI_LOGICAL_MINIMUM(8, 0), + // HID_RI_LOGICAL_MAXIMUM(8, 64), + // HID_RI_REPORT_SIZE(8, 8), + // HID_RI_REPORT_COUNT(8, 1), + // HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + // + // HID_RI_USAGE(8, 0x02), + // HID_RI_LOGICAL_MINIMUM(8, 0), + // HID_RI_LOGICAL_MAXIMUM(8, 64), + // HID_RI_REPORT_SIZE(8, 8), + // HID_RI_REPORT_COUNT(8, 1), + // HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + // HID_RI_END_COLLECTION(0) + //HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ + //HID_RI_USAGE(8, 0x4b), /* Generic indicator */ + //HID_RI_COLLECTION(8, 0x01), /* Application */ + // // Lights aren't the full 256 shades + // HID_RI_USAGE(8, 0x4B), /* Generic indicator 1 */ + // HID_RI_LOGICAL_MINIMUM(8, 0), + // HID_RI_LOGICAL_MAXIMUM(8, 64), + // HID_RI_USAGE_PAGE(8, 0x0A), /* Ordinals */ + // + // HID_RI_USAGE(8, 1), /* Instance 1 */ + // HID_RI_COLLECTION(8, 0x02), /* Logical */ + // HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ + // + // HID_RI_REPORT_SIZE(8, 8), + // HID_RI_REPORT_COUNT(8, 8), + // HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + // HID_RI_END_COLLECTION(0), + // + //HID_RI_END_COLLECTION(0), +}; + /** HID class report descriptor. This is a special descriptor constructed with values from the * USBIF HID class specification to describe the reports and capabilities of the HID device. This * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) @@ -107,14 +164,14 @@ 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 = NO_DESCRIPTOR, + .ConfigurationStrIndex = STRING_ID_Product, .ConfigAttributes = USB_CONFIG_ATTR_RESERVED, - .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + .MaxPowerConsumption = USB_CONFIG_POWER_MA(500) }, .HID1_Interface = @@ -130,7 +187,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = .SubClass = HID_CSCP_NonBootSubclass, .Protocol = HID_CSCP_NonBootProtocol, - .InterfaceStrIndex = STRING_ID_Product + .InterfaceStrIndex = NO_DESCRIPTOR }, .HID1_KeyboardHID = @@ -167,7 +224,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = .SubClass = HID_CSCP_BootSubclass, .Protocol = HID_CSCP_MouseBootProtocol, - .InterfaceStrIndex = STRING_ID_Product + .InterfaceStrIndex = NO_DESCRIPTOR }, .HID2_MouseHID = @@ -227,6 +284,43 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = .EndpointSize = GENERIC_EPSIZE, .PollingIntervalMS = 255 }, + + .HID4_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = INTERFACE_ID_LED, + .AlternateSetting = 0x00, + + .TotalEndpoints = 1, + + .Class = HID_CSCP_HIDClass, + .SubClass = HID_CSCP_NonBootSubclass, + .Protocol = HID_CSCP_NonBootProtocol, + + .InterfaceStrIndex = STRING_ID_LED + }, + + .HID4_LEDHID = + { + .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, + + .HIDSpec = VERSION_BCD(1,1,1), + .CountryCode = 0x00, + .TotalReportDescriptors = 1, + .HIDReportType = HID_DTYPE_Report, + .HIDReportLength = sizeof(LEDReport) + }, + + .HID4_ReportOUTEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = LED_EPADDR, + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = LED_EPSIZE, + .PollingIntervalMS = 15 + }, }; /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests @@ -246,9 +340,8 @@ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR * Descriptor. */ const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"Pocket Voltex"); - - -const USB_Descriptor_String_t PROGMEM ConfigString = USB_STRING_DESCRIPTOR(L"SDVX Config"); +const USB_Descriptor_String_t PROGMEM ConfigString = USB_STRING_DESCRIPTOR(L"Pocket Voltex Config"); +const USB_Descriptor_String_t PROGMEM LEDString = USB_STRING_DESCRIPTOR(L"Pocket Voltex LEDs"); /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" * documentation) by the application code so that the address and size of a requested descriptor can be given @@ -295,6 +388,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, Address = &ConfigString; Size = pgm_read_byte(&ConfigString.Header.Size); break; + case STRING_ID_LED: + Address = &LEDString; + Size = pgm_read_byte(&LEDString.Header.Size); + break; } break; @@ -310,6 +407,9 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, case INTERFACE_ID_Generic: Address = &ConfigurationDescriptor.HID3_VendorHID; break; + case INTERFACE_ID_LED: + Address = &ConfigurationDescriptor.HID4_LEDHID; + break; } break; case HID_DTYPE_Report: @@ -326,6 +426,10 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, Address = &GenericReport; Size = sizeof(GenericReport); break; + case INTERFACE_ID_LED: + Address = &LEDReport; + Size = sizeof(LEDReport); + break; } break; } diff --git a/Firmware/Keyboard/Descriptors.h b/Firmware/Keyboard/Descriptors.h index 99c94d6..84f2e03 100644 --- a/Firmware/Keyboard/Descriptors.h +++ b/Firmware/Keyboard/Descriptors.h @@ -42,6 +42,7 @@ #include #include "Config.h" + #include "LED.h" /* Type Defines: */ /** Type define for the device configuration descriptor structure. This must be defined in the @@ -66,6 +67,11 @@ USB_Descriptor_Interface_t HID3_Interface; USB_HID_Descriptor_HID_t HID3_VendorHID; USB_Descriptor_Endpoint_t HID3_ReportINEndpoint; + + // LED HID Interface for pretty lights + USB_Descriptor_Interface_t HID4_Interface; + USB_HID_Descriptor_HID_t HID4_LEDHID; + USB_Descriptor_Endpoint_t HID4_ReportOUTEndpoint; } USB_Descriptor_Configuration_t; /** Enum for the device interface descriptor IDs within the device. Each interface descriptor @@ -76,7 +82,8 @@ { INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */ INTERFACE_ID_Mouse = 1, /**< Mouse interface descriptor ID */ - INTERFACE_ID_Generic = 2 /**< Generic interface descriptor ID */ + INTERFACE_ID_Generic = 2, /**< Generic interface descriptor ID */ + INTERFACE_ID_LED = 3 /**< LED interface descriptor ID */ }; /** Enum for the device string descriptor IDs within the device. Each string descriptor should @@ -88,21 +95,23 @@ STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ STRING_ID_Product = 2, /**< Product string ID */ - STRING_ID_Config = 3 /**< Config string ID */ + STRING_ID_Config = 3, /**< Config string ID */ + STRING_ID_LED = 4 /**< LED string ID */ }; /* Macros: */ - /** Endpoint address of the Keyboard HID reporting IN endpoint. */ #define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1) #define MOUSE_IN_EPADDR (ENDPOINT_DIR_IN | 2) #define GENERIC_EPADDR (ENDPOINT_DIR_IN | 3) + + #define LED_EPADDR (ENDPOINT_DIR_OUT | 4) - /** Size in bytes of the Keyboard HID reporting IN endpoint. */ #define KEYBOARD_EPSIZE 8 #define MOUSE_EPSIZE 8 #define GENERIC_EPSIZE CONFIG_BYTES + #define LED_EPSIZE LED_COUNT /* Function Prototypes: */ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, diff --git a/Firmware/Keyboard/Keyboard.c b/Firmware/Keyboard/Keyboard.c index e7e78a6..3c8264a 100644 --- a/Firmware/Keyboard/Keyboard.c +++ b/Firmware/Keyboard/Keyboard.c @@ -16,6 +16,7 @@ typedef struct static uint8_t PrevKeyboardHIDReportBuffer[sizeof(Keyboard_Report_t)]; static uint8_t PrevMouseHIDReportBuffer[sizeof(USB_MouseReport_Data_t)]; static uint8_t PrevGenericHIDReportBuffer[CONFIG_BYTES]; +static uint8_t PrevLEDHIDReportBuffer[LED_COUNT]; /** LUFA HID Class driver interface configuration and state information. This structure is * passed to all HID Class driver functions, so that multiple instances of the same class @@ -74,6 +75,22 @@ USB_ClassInfo_HID_Device_t Generic_HID_Interface = }, }; +USB_ClassInfo_HID_Device_t LED_HID_Interface = +{ + .Config = + { + .InterfaceNumber = INTERFACE_ID_LED, + .ReportINEndpoint = + { + .Address = LED_EPADDR, + .Size = LED_EPSIZE, + .Banks = 1, + }, + .PrevReportINBuffer = PrevLEDHIDReportBuffer, + .PrevReportINBufferSize = sizeof(PrevLEDHIDReportBuffer), + }, +}; + // NOTE: atemga16u2 does not have a PORTA typedef enum { B = 0, @@ -157,7 +174,7 @@ int main(void) // Blink to show we're not in bootloader for(uint8_t i = 0; i < LED_COUNT; i++) { led_set(i, 32, 0, 0); - _delay_ms(1000); + _delay_ms(100); led_set(i, 0, 0, 0); } @@ -169,6 +186,7 @@ int main(void) HID_Device_USBTask(&Keyboard_HID_Interface); HID_Device_USBTask(&Mouse_HID_Interface); HID_Device_USBTask(&Generic_HID_Interface); + HID_Device_USBTask(&LED_HID_Interface); USB_USBTask(); } } @@ -289,6 +307,9 @@ void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDI RebootToBootloader(); } SetConfig(ConfigReport); + } else if(HIDInterfaceInfo == &LED_HID_Interface && ReportType == HID_REPORT_ITEM_Out) { + uint8_t* LEDReport = (uint8_t*)ReportData; + led_set_indiv(0, LEDReport[0]); } } @@ -311,6 +332,7 @@ void EVENT_USB_Device_ConfigurationChanged(void) HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface); HID_Device_ConfigureEndpoints(&Mouse_HID_Interface); HID_Device_ConfigureEndpoints(&Generic_HID_Interface); + HID_Device_ConfigureEndpoints(&LED_HID_Interface); USB_Device_EnableSOFEvents(); } @@ -321,6 +343,7 @@ void EVENT_USB_Device_ControlRequest(void) HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); HID_Device_ProcessControlRequest(&Mouse_HID_Interface); HID_Device_ProcessControlRequest(&Generic_HID_Interface); + HID_Device_ProcessControlRequest(&LED_HID_Interface); } /** Event handler for the USB device Start Of Frame event. */ @@ -329,6 +352,7 @@ void EVENT_USB_Device_StartOfFrame(void) HID_Device_MillisecondElapsed(&Keyboard_HID_Interface); HID_Device_MillisecondElapsed(&Mouse_HID_Interface); HID_Device_MillisecondElapsed(&Generic_HID_Interface); + HID_Device_MillisecondElapsed(&LED_HID_Interface); for(int i = 0; i < SWITCH_COUNT; i++) { if(switches[i].debounce) { diff --git a/Firmware/Keyboard/LED.c b/Firmware/Keyboard/LED.c index 16a9a00..3bd1a03 100644 --- a/Firmware/Keyboard/LED.c +++ b/Firmware/Keyboard/LED.c @@ -60,6 +60,10 @@ void led_set(uint8_t num, uint8_t r, uint8_t g, uint8_t b) { leds[offset+B] = b; } +void led_set_indiv(uint8_t num, uint8_t val) { + leds[num] = val; +} + /* Straight voodoo magic, consult the Inline Assembler Cookbook Equivalent to: if(*led++ > brightness) diff --git a/Firmware/Keyboard/LED.h b/Firmware/Keyboard/LED.h index 2fe24a8..346b8fc 100644 --- a/Firmware/Keyboard/LED.h +++ b/Firmware/Keyboard/LED.h @@ -9,5 +9,6 @@ void led_init(void); void led_set(uint8_t num, uint8_t r, uint8_t g, uint8_t b); +void led_set_indiv(uint8_t num, uint8_t val); #endif