@@ -45,28 +45,62 @@ static const struct usb_device_descriptor dev = {
4545 .bNumConfigurations = 1 ,
4646};
4747
48- static const struct usb_interface_descriptor dfu_iface = {
49- .bLength = USB_DT_INTERFACE_SIZE ,
50- .bDescriptorType = USB_DT_INTERFACE ,
51- .bInterfaceNumber = INTF_DFU ,
52- .bAlternateSetting = 0 ,
53- .bNumEndpoints = 0 ,
54- .bInterfaceClass = 0xFE ,
55- .bInterfaceSubClass = 1 ,
56- .bInterfaceProtocol = 2 ,
57- .iInterface = 4 ,
58-
59- .endpoint = NULL ,
60-
61- .extra = & dfu_function ,
62- .extralen = sizeof (dfu_function ),
48+ // Macro to create a dummy (no-op) USB interface descriptor with the given alternate setting
49+ #define ALT_DUMMY (N ) { \
50+ .bLength = USB_DT_INTERFACE_SIZE, \
51+ .bDescriptorType = USB_DT_INTERFACE, \
52+ .bInterfaceNumber = INTF_DFU, \
53+ .bAlternateSetting = (N), \
54+ .bNumEndpoints = 0, \
55+ .bInterfaceClass = 0, \
56+ .bInterfaceSubClass = 0, \
57+ .bInterfaceProtocol = 0, \
58+ .iInterface = 0, \
59+ .endpoint = NULL, \
60+ .extra = NULL, \
61+ .extralen = 0, \
62+ },
63+
64+ // Functionality for creating repetitive ALT_DUMMY structs with an increasing count during compile time.
65+ // It doesn't look very nice, but C doesn't allow loops in preprocessor macros, so this needs to be hard-coded.
66+ #define ALT0
67+ #define ALT1 ALT_DUMMY(0)
68+ #define ALT2 ALT1 ALT_DUMMY(1)
69+ #define ALT3 ALT2 ALT_DUMMY(2)
70+ #define ALT4 ALT3 ALT_DUMMY(3)
71+ #define ALT5 ALT4 ALT_DUMMY(4)
72+ #define ALTW (n ) ALT##n // Wrapper macro for expansion
73+ #define ALTN (n ) ALTW(n)
74+
75+ static const struct usb_interface_descriptor altsettings [] = {
76+ ALTN (USB_DFU_ALTN ) // Prepend USB_DFU_ALTN dummy USB interface descriptors to "pad" the real one
77+ {
78+ .bLength = USB_DT_INTERFACE_SIZE ,
79+ .bDescriptorType = USB_DT_INTERFACE ,
80+ .bInterfaceNumber = INTF_DFU ,
81+ .bAlternateSetting = USB_DFU_ALTN ,
82+ .bNumEndpoints = 0 ,
83+ .bInterfaceClass = 0xFE ,
84+ .bInterfaceSubClass = 1 ,
85+ .bInterfaceProtocol = 2 ,
86+ .iInterface = 4 ,
87+
88+ .endpoint = NULL ,
89+
90+ .extra = & dfu_function ,
91+ .extralen = sizeof (dfu_function ),
92+ }
6393};
6494
95+ // Tracking this is mandatory if exposing multiple altsettings
96+ static uint8_t cur_altsetting = 0 ;
97+
6598static const struct usb_interface interfaces [] = {
6699 /* DFU interface */
67100 {
68- .num_altsetting = 1 ,
69- .altsetting = & dfu_iface ,
101+ .cur_altsetting = & cur_altsetting ,
102+ .num_altsetting = USB_DFU_ALTN + 1 ,
103+ .altsetting = (const struct usb_interface_descriptor * )& altsettings ,
70104 }
71105};
72106
0 commit comments