broke LED descriptor

This commit is contained in:
William Toohey
2016-10-29 00:10:08 +10:00
parent bc15c1a16a
commit e79de98ac5
5 changed files with 155 additions and 13 deletions
+112 -8
View File
@@ -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;
}
+13 -4
View File
@@ -42,6 +42,7 @@
#include <LUFA/Drivers/USB/USB.h>
#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,
+25 -1
View File
@@ -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) {
+4
View File
@@ -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)
+1
View File
@@ -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