@@ -132,13 +132,23 @@ mp_obj_t common_hal_usb_core_device_get_manufacturer(usb_core_device_obj_t *self
132132}
133133
134134void common_hal_usb_core_device_set_configuration (usb_core_device_obj_t * self , mp_int_t configuration ) {
135- if (configuration == 0x100 ) {
136- tusb_desc_configuration_t desc ;
137- if (!tuh_descriptor_get_configuration (self -> device_number , 0 , & desc , sizeof (desc ), _transfer_done_cb , 0 ) ||
138- !_wait_for_callback ()) {
139- return ;
140- }
141- configuration = desc .bConfigurationValue ;
135+ // We assume that the config index is one less than the value.
136+ uint8_t config_index = configuration - 1 ;
137+ // Get the configuration descriptor and cache it. We'll use it later to open
138+ // endpoints.
139+
140+ // Get only the config descriptor first.
141+ tusb_desc_configuration_t desc ;
142+ if (!tuh_descriptor_get_configuration (self -> device_number , config_index , & desc , sizeof (desc ), _transfer_done_cb , 0 ) ||
143+ !_wait_for_callback ()) {
144+ return ;
145+ }
146+
147+ // Get the config descriptor plus interfaces and endpoints.
148+ self -> configuration_descriptor = m_realloc (self -> configuration_descriptor , desc .wTotalLength );
149+ if (!tuh_descriptor_get_configuration (self -> device_number , config_index , self -> configuration_descriptor , desc .wTotalLength , _transfer_done_cb , 0 ) ||
150+ !_wait_for_callback ()) {
151+ return ;
142152 }
143153 tuh_configuration_set (self -> device_number , configuration , _transfer_done_cb , 0 );
144154 _wait_for_callback ();
@@ -159,6 +169,7 @@ STATIC size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) {
159169 RUN_BACKGROUND_TASKS ;
160170 }
161171 if (mp_hal_is_interrupted ()) {
172+ tuh_edpt_abort_xfer (xfer -> daddr , xfer -> ep_addr );
162173 return 0 ;
163174 }
164175 xfer_result_t result = _xfer_result ;
@@ -167,6 +178,7 @@ STATIC size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) {
167178 mp_raise_usb_core_USBError (translate ("Pipe error" ));
168179 }
169180 if (result == 0xff ) {
181+ tuh_edpt_abort_xfer (xfer -> daddr , xfer -> ep_addr );
170182 mp_raise_usb_core_USBTimeoutError ();
171183 }
172184 if (result == XFER_RESULT_SUCCESS ) {
@@ -191,17 +203,13 @@ STATIC bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) {
191203 return true;
192204 }
193205
194- // Fetch the full configuration descriptor and search for the endpoint's descriptor.
195- uint8_t desc_buf [128 ];
196- if (!tuh_descriptor_get_configuration (self -> device_number , self -> configuration_index , & desc_buf , sizeof (desc_buf ), _transfer_done_cb , 0 ) ||
197- !_wait_for_callback ()) {
198- return false;
206+ if (self -> configuration_descriptor == NULL ) {
207+ mp_raise_usb_core_USBError (translate ("No configuration set" ));
199208 }
200- tusb_desc_configuration_t * desc_cfg = (tusb_desc_configuration_t * )desc_buf ;
209+
210+ tusb_desc_configuration_t * desc_cfg = (tusb_desc_configuration_t * )self -> configuration_descriptor ;
201211
202212 uint32_t total_length = tu_le16toh (desc_cfg -> wTotalLength );
203- // Cap to the buffer size we requested.
204- total_length = MIN (total_length , sizeof (desc_buf ));
205213 uint8_t const * desc_end = ((uint8_t const * )desc_cfg ) + total_length ;
206214 uint8_t const * p_desc = tu_desc_next (desc_cfg );
207215
@@ -287,6 +295,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self,
287295 RUN_BACKGROUND_TASKS ;
288296 }
289297 if (mp_hal_is_interrupted ()) {
298+ tuh_edpt_abort_xfer (xfer .daddr , xfer .ep_addr );
290299 return 0 ;
291300 }
292301 xfer_result_t result = _xfer_result ;
@@ -295,6 +304,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self,
295304 mp_raise_usb_core_USBError (translate ("Pipe error" ));
296305 }
297306 if (result == 0xff ) {
307+ tuh_edpt_abort_xfer (xfer .daddr , xfer .ep_addr );
298308 mp_raise_usb_core_USBTimeoutError ();
299309 }
300310 if (result == XFER_RESULT_SUCCESS ) {
0 commit comments