@@ -109,18 +109,79 @@ enum
109109
110110#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MTP_DESC_LEN)
111111
112- uint8_t const desc_fs_configuration [] = {
112+ // full speed configuration
113+ const uint8_t desc_fs_configuration [] = {
113114 // Config number, interface count, string index, total length, attribute, power in mA
114115 TUD_CONFIG_DESCRIPTOR (1 , ITF_NUM_TOTAL , 0 , CONFIG_TOTAL_LEN , 0x00 , 100 ),
116+ // Interface number, string index, EP event, EP event size, EP event polling, EP Out & EP In address, EP size
115117 TUD_MTP_DESCRIPTOR (ITF_NUM_MTP , 4 , EPNUM_MTP_EVT , 64 , 1 , EPNUM_MTP_OUT , EPNUM_MTP_IN , 64 ),
116118};
117119
120+ #if TUD_OPT_HIGH_SPEED
121+ // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
122+
123+ // high speed configuration
124+ uint8_t const desc_hs_configuration [] = {
125+ // Config number, interface count, string index, total length, attribute, power in mA
126+ TUD_CONFIG_DESCRIPTOR (1 , ITF_NUM_TOTAL , 0 , CONFIG_TOTAL_LEN , 0x00 , 100 ),
127+ // Interface number, string index, EP event, EP event size, EP event polling, EP Out & EP In address, EP size
128+ TUD_MTP_DESCRIPTOR (ITF_NUM_MTP , 4 , EPNUM_MTP_EVT , 64 , 1 , EPNUM_MTP_OUT , EPNUM_MTP_IN , 512 ),
129+ };
130+
131+ // other speed configuration
132+ uint8_t desc_other_speed_config [CONFIG_TOTAL_LEN ];
133+
134+ // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
135+ tusb_desc_device_qualifier_t const desc_device_qualifier = {
136+ .bLength = sizeof (tusb_desc_device_qualifier_t ),
137+ .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER ,
138+ .bcdUSB = USB_BCD ,
139+
140+ .bDeviceClass = TUSB_CLASS_MISC ,
141+ .bDeviceSubClass = MISC_SUBCLASS_COMMON ,
142+ .bDeviceProtocol = MISC_PROTOCOL_IAD ,
143+
144+ .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE ,
145+ .bNumConfigurations = 0x01 ,
146+ .bReserved = 0x00
147+ };
148+
149+ // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request
150+ // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
151+ // device_qualifier descriptor describes information about a high-speed capable device that would
152+ // change if the device were operating at the other speed. If not highspeed capable stall this request.
153+ uint8_t const * tud_descriptor_device_qualifier_cb (void ) {
154+ return (uint8_t const * ) & desc_device_qualifier ;
155+ }
156+
157+ // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
158+ // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
159+ // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
160+ uint8_t const * tud_descriptor_other_speed_configuration_cb (uint8_t index ) {
161+ (void ) index ; // for multiple configurations
162+
163+ // if link speed is high return fullspeed config, and vice versa
164+ // Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG
165+ memcpy (desc_other_speed_config ,
166+ (tud_speed_get () == TUSB_SPEED_HIGH ) ? desc_fs_configuration : desc_hs_configuration ,
167+ CONFIG_TOTAL_LEN );
168+ desc_other_speed_config [1 ] = TUSB_DESC_OTHER_SPEED_CONFIG ;
169+ return desc_other_speed_config ;
170+ }
171+
172+ #endif // highspeed
173+
118174// Invoked when received GET CONFIGURATION DESCRIPTOR
119175// Application return pointer to descriptor
120176// Descriptor contents must exist long enough for transfer to complete
121- uint8_t const * tud_descriptor_configuration_cb (uint8_t index ) {
177+ const uint8_t * tud_descriptor_configuration_cb (uint8_t index ) {
122178 (void ) index ; // for multiple configurations
179+ #if TUD_OPT_HIGH_SPEED
180+ // Although we are highspeed, host may be fullspeed.
181+ return (tud_speed_get () == TUSB_SPEED_HIGH ) ? desc_hs_configuration : desc_fs_configuration ;
182+ #else
123183 return desc_fs_configuration ;
184+ #endif
124185}
125186
126187//--------------------------------------------------------------------+
@@ -173,11 +234,12 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
173234 }
174235
175236 const char * str = string_desc_arr [index ];
176-
177237 // Cap at max char
178238 chr_count = strlen (str );
179- size_t const max_count = sizeof (_desc_str ) / sizeof (_desc_str [0 ]) - 1 ; // -1 for string type
180- if ( chr_count > max_count ) chr_count = max_count ;
239+ const size_t max_count = sizeof (_desc_str ) / sizeof (_desc_str [0 ]) - 1 ; // -1 for string type
240+ if ( chr_count > max_count ) {
241+ chr_count = max_count ;
242+ }
181243
182244 // Convert ASCII string into UTF-16
183245 for ( size_t i = 0 ; i < chr_count ; i ++ ) {
0 commit comments