@@ -136,13 +136,23 @@ mp_obj_t common_hal_usb_core_device_get_manufacturer(usb_core_device_obj_t *self
136136}
137137
138138void common_hal_usb_core_device_set_configuration (usb_core_device_obj_t * self , mp_int_t configuration ) {
139- if (configuration == 0x100 ) {
140- tusb_desc_configuration_t desc ;
141- if (!tuh_descriptor_get_configuration (self -> device_number , 0 , & desc , sizeof (desc ), _transfer_done_cb , 0 ) ||
142- !_wait_for_callback ()) {
143- return ;
144- }
145- configuration = desc .bConfigurationValue ;
139+ // We assume that the config index is one less than the value.
140+ uint8_t config_index = configuration - 1 ;
141+ // Get the configuration descriptor and cache it. We'll use it later to open
142+ // endpoints.
143+
144+ // Get only the config descriptor first.
145+ tusb_desc_configuration_t desc ;
146+ if (!tuh_descriptor_get_configuration (self -> device_number , config_index , & desc , sizeof (desc ), _transfer_done_cb , 0 ) ||
147+ !_wait_for_callback ()) {
148+ return ;
149+ }
150+
151+ // Get the config descriptor plus interfaces and endpoints.
152+ self -> configuration_descriptor = m_realloc (self -> configuration_descriptor , desc .wTotalLength );
153+ if (!tuh_descriptor_get_configuration (self -> device_number , config_index , self -> configuration_descriptor , desc .wTotalLength , _transfer_done_cb , 0 ) ||
154+ !_wait_for_callback ()) {
155+ return ;
146156 }
147157 tuh_configuration_set (self -> device_number , configuration , _transfer_done_cb , 0 );
148158 _wait_for_callback ();
@@ -163,6 +173,7 @@ STATIC size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) {
163173 RUN_BACKGROUND_TASKS ;
164174 }
165175 if (mp_hal_is_interrupted ()) {
176+ tuh_edpt_abort_xfer (xfer -> daddr , xfer -> ep_addr );
166177 return 0 ;
167178 }
168179 xfer_result_t result = _xfer_result ;
@@ -171,6 +182,7 @@ STATIC size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) {
171182 mp_raise_usb_core_USBError (translate ("Pipe error" ));
172183 }
173184 if (result == 0xff ) {
185+ tuh_edpt_abort_xfer (xfer -> daddr , xfer -> ep_addr );
174186 mp_raise_usb_core_USBTimeoutError ();
175187 }
176188 if (result == XFER_RESULT_SUCCESS ) {
@@ -195,17 +207,13 @@ STATIC bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) {
195207 return true;
196208 }
197209
198- // Fetch the full configuration descriptor and search for the endpoint's descriptor.
199- uint8_t desc_buf [128 ];
200- if (!tuh_descriptor_get_configuration (self -> device_number , self -> configuration_index , & desc_buf , sizeof (desc_buf ), _transfer_done_cb , 0 ) ||
201- !_wait_for_callback ()) {
202- return false;
210+ if (self -> configuration_descriptor == NULL ) {
211+ mp_raise_usb_core_USBError (translate ("No configuration set" ));
203212 }
204- tusb_desc_configuration_t * desc_cfg = (tusb_desc_configuration_t * )desc_buf ;
213+
214+ tusb_desc_configuration_t * desc_cfg = (tusb_desc_configuration_t * )self -> configuration_descriptor ;
205215
206216 uint32_t total_length = tu_le16toh (desc_cfg -> wTotalLength );
207- // Cap to the buffer size we requested.
208- total_length = MIN (total_length , sizeof (desc_buf ));
209217 uint8_t const * desc_end = ((uint8_t const * )desc_cfg ) + total_length ;
210218 uint8_t const * p_desc = tu_desc_next (desc_cfg );
211219
@@ -291,6 +299,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self,
291299 RUN_BACKGROUND_TASKS ;
292300 }
293301 if (mp_hal_is_interrupted ()) {
302+ tuh_edpt_abort_xfer (xfer .daddr , xfer .ep_addr );
294303 return 0 ;
295304 }
296305 xfer_result_t result = _xfer_result ;
@@ -299,6 +308,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self,
299308 mp_raise_usb_core_USBError (translate ("Pipe error" ));
300309 }
301310 if (result == 0xff ) {
311+ tuh_edpt_abort_xfer (xfer .daddr , xfer .ep_addr );
302312 mp_raise_usb_core_USBTimeoutError ();
303313 }
304314 if (result == XFER_RESULT_SUCCESS ) {
0 commit comments