From 36da26d040c6f6fbed0521ff6f523f7f9af1d043 Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Wed, 28 May 2025 00:26:55 -0600 Subject: [PATCH] Added HID report descriptor for lamparray --- .gitignore | 1 + cfg/halconf.h | 2 +- source/usbcfg.c | 170 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 160 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 751ff5c..a09e0d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ compile_commands.json .dep/ +.cache/ build/ tools/firmware.bin diff --git a/cfg/halconf.h b/cfg/halconf.h index b035b4b..6cbc4cd 100644 --- a/cfg/halconf.h +++ b/cfg/halconf.h @@ -457,7 +457,7 @@ * buffers. */ #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_USB_BUFFERS_SIZE 256 +#define SERIAL_USB_BUFFERS_SIZE 512 #endif /** diff --git a/source/usbcfg.c b/source/usbcfg.c index 9d14069..fe5ed29 100644 --- a/source/usbcfg.c +++ b/source/usbcfg.c @@ -1,10 +1,11 @@ #include "hal.h" +#include "hal_usb.h" /* * USB Device Descriptor. */ static const uint8_t device_descriptor_data[18] = { - USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */ + USB_DESC_DEVICE (0x0200, /* bcdUSB (2.0). */ 0x00, /* bDeviceClass (Unknown). */ 0x00, /* bDeviceSubClass. */ 0x00, /* bDeviceProtocol. */ @@ -31,7 +32,7 @@ static const uint8_t configuration_descriptor_data[41] = { /* Configuration Descriptor.*/ USB_DESC_CONFIGURATION(41, /* wTotalLength. */ 0x01, /* bNumInterfaces. */ - 0x01, /* bConfigurationValue. */ + 0x00, /* bConfigurationValue. */ 0, /* iConfiguration. */ 0xC0, /* bmAttributes (self powered). */ 50), /* bMaxPower (100mA). */ @@ -46,16 +47,14 @@ static const uint8_t configuration_descriptor_data[41] = { /* HID Descriptor (HID Section 6.2.1).*/ - USB_DESC_BYTE (6), /* bLength. */ + USB_DESC_BYTE (0x09), /* bLength. */ USB_DESC_BYTE (0x21), /* bDescriptorType (HID). */ - USB_DESC_BCD (0x110), /* bcdHID(1.1) */ + USB_DESC_BCD (0x111), /* bcdHID(1.1) */ USB_DESC_BYTE (0x00), /* bCountryCode(None) */ USB_DESC_BYTE (0x01), /* bNumDescriptors */ - USB_DESC_BYTE (0x34), /* bDescriptorType */ - USB_DESC_WORD (0x00), /* wDescriptorLength */ + USB_DESC_BYTE (0x22), /* bDescriptorType */ + USB_DESC_WORD (292), /* wDescriptorLength */ - /* HID Report Descriptors */ - /* Endpoint Descriptors */ USB_DESC_ENDPOINT (0x81, /* bEndpointAddress */ 0x03, /* bmAttributes */ @@ -66,16 +65,161 @@ static const uint8_t configuration_descriptor_data[41] = { 0x03, /* bmAttributes */ 0x0020, /* wMaxPacketSize. */ 0xFF), /* bInterval. */ + }; -/* - * Configuration Descriptor wrapper. - */ static const USBDescriptor configuration_descriptor = { sizeof configuration_descriptor_data, configuration_descriptor_data }; +static const uint8_t hid_report_descriptor_data[292] = { + 0x05, 0x59, // UsagePage(Lighting And Illumination[0x0059]) + 0x09, 0x01, // UsageId(LampArray[0x0001]) + 0xA1, 0x01, // Collection(Application) + 0x85, 0x01, // ReportId(1) + 0x09, 0x02, // UsageId(LampArrayAttributesReport[0x0002]) + 0xA1, 0x02, // Collection(Logical) + 0x09, 0x03, // UsageId(LampCount[0x0003]) + 0x15, 0x00, // LogicalMinimum(0) + 0x27, 0xFF, 0xFF, 0x00, 0x00, // LogicalMaximum(65,535) + 0x95, 0x01, // ReportCount(1) + 0x75, 0x10, // ReportSize(16) + 0xB1, 0x03, // Feature(Constant, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x04, // UsageId(BoundingBoxWidthInMicrometers[0x0004]) + 0x09, 0x05, // UsageId(BoundingBoxHeightInMicrometers[0x0005]) + 0x09, 0x06, // UsageId(BoundingBoxDepthInMicrometers[0x0006]) + 0x09, 0x07, // UsageId(LampArrayKind[0x0007]) + 0x09, 0x08, // UsageId(MinUpdateIntervalInMicroseconds[0x0008]) + 0x27, 0xFF, 0xFF, 0xFF, 0x7F, // LogicalMaximum(2,147,483,647) + 0x95, 0x05, // ReportCount(5) + 0x75, 0x20, // ReportSize(32) + 0xB1, 0x03, // Feature(Constant, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0xC0, // EndCollection() + 0x85, 0x02, // ReportId(2) + 0x09, 0x20, // UsageId(LampAttributesRequestReport[0x0020]) + 0xA1, 0x02, // Collection(Logical) + 0x09, 0x21, // UsageId(LampId[0x0021]) + 0x27, 0xFF, 0xFF, 0x00, 0x00, // LogicalMaximum(65,535) + 0x95, 0x01, // ReportCount(1) + 0x75, 0x10, // ReportSize(16) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0xC0, // EndCollection() + 0x85, 0x03, // ReportId(3) + 0x09, 0x22, // UsageId(LampAttributesResponseReport[0x0022]) + 0xA1, 0x02, // Collection(Logical) + 0x09, 0x21, // UsageId(LampId[0x0021]) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x23, // UsageId(PositionXInMicrometers[0x0023]) + 0x09, 0x24, // UsageId(PositionYInMicrometers[0x0024]) + 0x09, 0x25, // UsageId(PositionZInMicrometers[0x0025]) + 0x09, 0x27, // UsageId(UpdateLatencyInMicroseconds[0x0027]) + 0x09, 0x26, // UsageId(LampPurposes[0x0026]) + 0x27, 0xFF, 0xFF, 0xFF, 0x7F, // LogicalMaximum(2,147,483,647) + 0x95, 0x05, // ReportCount(5) + 0x75, 0x20, // ReportSize(32) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x28, // UsageId(RedLevelCount[0x0028]) + 0x09, 0x29, // UsageId(GreenLevelCount[0x0029]) + 0x09, 0x2A, // UsageId(BlueLevelCount[0x002A]) + 0x09, 0x2B, // UsageId(IntensityLevelCount[0x002B]) + 0x09, 0x2C, // UsageId(IsProgrammable[0x002C]) + 0x09, 0x2D, // UsageId(InputBinding[0x002D]) + 0x26, 0xFF, 0x00, // LogicalMaximum(255) + 0x95, 0x06, // ReportCount(6) + 0x75, 0x08, // ReportSize(8) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0xC0, // EndCollection() + 0x85, 0x04, // ReportId(4) + 0x09, 0x50, // UsageId(LampMultiUpdateReport[0x0050]) + 0xA1, 0x02, // Collection(Logical) + 0x09, 0x03, // UsageId(LampCount[0x0003]) + 0x25, 0x08, // LogicalMaximum(8) + 0x95, 0x01, // ReportCount(1) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x55, // UsageId(LampUpdateFlags[0x0055]) + 0x25, 0x01, // LogicalMaximum(1) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x21, // UsageId(LampId[0x0021]) + 0x27, 0xFF, 0xFF, 0x00, 0x00, // LogicalMaximum(65,535) + 0x95, 0x08, // ReportCount(8) + 0x75, 0x10, // ReportSize(16) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x26, 0xFF, 0x00, // LogicalMaximum(255) + 0x95, 0x20, // ReportCount(32) + 0x75, 0x08, // ReportSize(8) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0xC0, // EndCollection() + 0x85, 0x05, // ReportId(5) + 0x09, 0x60, // UsageId(LampRangeUpdateReport[0x0060]) + 0xA1, 0x02, // Collection(Logical) + 0x09, 0x55, // UsageId(LampUpdateFlags[0x0055]) + 0x25, 0x01, // LogicalMaximum(1) + 0x95, 0x01, // ReportCount(1) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x61, // UsageId(LampIdStart[0x0061]) + 0x09, 0x62, // UsageId(LampIdEnd[0x0062]) + 0x27, 0xFF, 0xFF, 0x00, 0x00, // LogicalMaximum(65,535) + 0x95, 0x02, // ReportCount(2) + 0x75, 0x10, // ReportSize(16) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0x09, 0x51, // UsageId(RedUpdateChannel[0x0051]) + 0x09, 0x52, // UsageId(GreenUpdateChannel[0x0052]) + 0x09, 0x53, // UsageId(BlueUpdateChannel[0x0053]) + 0x09, 0x54, // UsageId(IntensityUpdateChannel[0x0054]) + 0x26, 0xFF, 0x00, // LogicalMaximum(255) + 0x95, 0x04, // ReportCount(4) + 0x75, 0x08, // ReportSize(8) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0xC0, // EndCollection() + 0x85, 0x06, // ReportId(6) + 0x09, 0x70, // UsageId(LampArrayControlReport[0x0070]) + 0xA1, 0x02, // Collection(Logical) + 0x09, 0x71, // UsageId(AutonomousMode[0x0071]) + 0x25, 0x01, // LogicalMaximum(1) + 0x95, 0x01, // ReportCount(1) + 0xB1, 0x02, // Feature(Data, Variable, Absolute, NoWrap, Linear, PreferredState, NoNullPosition, NonVolatile, BitField) + 0xC0, // EndCollection() + 0xC0, // EndCollection() +}; + +static const USBDescriptor hid_report_descriptor = { + sizeof hid_report_descriptor_data, + hid_report_descriptor_data +}; + /* * U.S. English language identifier. */ @@ -136,6 +280,8 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp, uint8_t dtype, uint8 case USB_DESCRIPTOR_STRING: if (dindex < 4) return &usb_strings[dindex]; + case 0x22: + return &hid_report_descriptor; } return NULL; } @@ -167,7 +313,7 @@ static void usb_event(USBDriver *usbp, usbevent_t event) { case USB_EVENT_CONFIGURED: chSysLockFromISR(); - usbInitEndpointI(usbp, 0x02, &ep1config); + usbInitEndpointI(usbp, 0x01, &ep1config); chSysUnlockFromISR(); return;