diff options
-rw-r--r-- | usb/descriptor.h | 210 |
1 files changed, 161 insertions, 49 deletions
diff --git a/usb/descriptor.h b/usb/descriptor.h index f806984..f889436 100644 --- a/usb/descriptor.h +++ b/usb/descriptor.h @@ -3,11 +3,23 @@ #include <stdint.h> +template <typename A, typename B> +struct X { + A a; + B b; +} __attribute__((packed)); + +template <typename A> +constexpr A pack(A a) { + return a; +} + +template <typename A, typename... R> +constexpr auto pack(A a, R... r) -> X<A, decltype(pack(r...))> { + return {a, pack(r...)}; +} + struct Device_desc { - enum { - SIZE = 18, - }; - uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdUSB; @@ -24,12 +36,40 @@ struct Device_desc { uint8_t bNumConfigurations; }; +constexpr Device_desc device_desc( + uint16_t bcdUSB, + uint8_t bDeviceClass, + uint8_t bDeviceSubClass, + uint8_t bDeviceProtocol, + uint8_t bMaxPacketSize0, + uint16_t idVendor, + uint16_t idProduct, + uint16_t bcdDevice, + uint8_t iManufacturer, + uint8_t iProduct, + uint8_t iSerialNumber, + uint8_t bNumConfigurations + ) { + + return { + sizeof(Device_desc), + 1, + bcdUSB, + bDeviceClass, + bDeviceSubClass, + bDeviceProtocol, + bMaxPacketSize0, + idVendor, + idProduct, + bcdDevice, + iManufacturer, + iProduct, + iSerialNumber, + bNumConfigurations + }; +} struct Configuration_desc { - enum { - SIZE = 9, - }; - uint8_t bLength; uint8_t bDescriptorType; uint16_t wTotalLength; @@ -40,11 +80,29 @@ struct Configuration_desc { uint8_t bMaxPower; } __attribute__((packed)); -struct Interface_desc { - enum { - SIZE = 9, - }; +template <typename... R> +constexpr auto configuration_desc( + uint8_t bNumInterfaces, + uint8_t bConfigurationvalue, + uint8_t iConfiguration, + uint8_t bmAttributes, + uint8_t bMaxPower, + R... r + ) -> decltype(pack(Configuration_desc(), r...)) { + return pack(Configuration_desc { + sizeof(Configuration_desc), + 2, + sizeof(pack(Configuration_desc(), r...)), + bNumInterfaces, + bConfigurationvalue, + iConfiguration, + bmAttributes, + bMaxPower + }, r...); +} + +struct Interface_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bInterfaceNumber; @@ -56,11 +114,32 @@ struct Interface_desc { uint8_t iInterface; } __attribute__((packed)); -struct Endpoint_desc { - enum { - SIZE = 7, - }; +template <typename... R> +constexpr auto interface_desc( + uint8_t bInterfaceNumber, + uint8_t bAlternateSetting, + uint8_t bNumEndpoints, + uint8_t bInterfaceClass, + uint8_t bInterfaceSubClass, + uint8_t bInterfaceProtocol, + uint8_t iInterface, + R... r + ) -> decltype(pack(Interface_desc(), r...)) { + return pack(Interface_desc { + sizeof(Interface_desc), + 4, + bInterfaceNumber, + bAlternateSetting, + bNumEndpoints, + bInterfaceClass, + bInterfaceSubClass, + bInterfaceProtocol, + iInterface + }, r...); +} + +struct Endpoint_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bEndpointAddress; @@ -69,22 +148,43 @@ struct Endpoint_desc { uint8_t bInterval; } __attribute__((packed)); -struct CDC_Header_desc { - enum { - SIZE = 5, - }; +constexpr Endpoint_desc endpoint_desc( + uint8_t bEndpointAddress, + uint8_t bmAttributes, + uint16_t wMaxPacketSize, + uint8_t bInterval + ) { + return { + sizeof(Endpoint_desc), + 5, + bEndpointAddress, + bmAttributes, + wMaxPacketSize, + bInterval + }; +} + +struct CDC_Header_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint16_t bcdCDC; } __attribute__((packed)); -struct CDC_Call_Management_desc { - enum { - SIZE = 5, - }; +constexpr CDC_Header_desc cdc_header_desc( + uint16_t bcdCDC + ) { + return { + sizeof(CDC_Header_desc), + 0x24, + 0x00, + bcdCDC + }; +} + +struct CDC_Call_Management_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; @@ -92,22 +192,40 @@ struct CDC_Call_Management_desc { uint8_t bDataInterface; } __attribute__((packed)); -struct CDC_ACM_desc { - enum { - SIZE = 4, - }; +constexpr CDC_Call_Management_desc cdc_call_management_desc( + uint8_t bmCapabilities, + uint8_t bDataInterface + ) { + return { + sizeof(CDC_Call_Management_desc), + 0x24, + 0x01, + bmCapabilities, + bDataInterface + }; +} + +struct CDC_ACM_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bmCapabilities; } __attribute__((packed)); -struct CDC_Union_desc { - enum { - SIZE = 5, - }; +constexpr CDC_ACM_desc cdc_acm_desc( + uint8_t bmCapabilities + ) { + return { + sizeof(CDC_ACM_desc), + 0x24, + 0x02, + bmCapabilities + }; +} + +struct CDC_Union_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; @@ -115,24 +233,18 @@ struct CDC_Union_desc { uint8_t bSubordinateInterface0; } __attribute__((packed)); -template <typename A, typename B> -struct X { - enum { - SIZE = A::SIZE + B::SIZE, - }; +constexpr CDC_Union_desc cdc_union_desc( + uint8_t bControlInterface, + uint8_t bSubordinateInterface0 + ) { - A a; - B b; -} __attribute__((packed)); - -template <typename A> -constexpr A pack(A a) { - return a; -} - -template <typename A, typename... R> -constexpr auto pack(A a, R... r) -> X<A, decltype(pack(r...))> { - return {a, pack(r...)}; + return { + sizeof(CDC_Union_desc), + 0x24, + 0x06, + bControlInterface, + bSubordinateInterface0 + }; } #endif |