@@ -101,9 +101,28 @@ static bool _wait_for_callback(void) {
101
101
// we provided above. In other words, the callback isn't in an interrupt.
102
102
RUN_BACKGROUND_TASKS ;
103
103
}
104
+ if (mp_hal_is_interrupted ()) {
105
+ // Handle case of VM being interrupted by Ctrl-C or autoreload
106
+ return false;
107
+ }
108
+ // Handle callback result code from TinyUSB
104
109
xfer_result_t result = _xfer_result ;
105
110
_xfer_result = XFER_RESULT_INVALID ;
106
- return result == XFER_RESULT_SUCCESS ;
111
+ switch (result ) {
112
+ case XFER_RESULT_SUCCESS :
113
+ return true;
114
+ case XFER_RESULT_FAILED :
115
+ mp_raise_usb_core_USBError (NULL );
116
+ break ;
117
+ case XFER_RESULT_STALLED :
118
+ mp_raise_usb_core_USBError (MP_ERROR_TEXT ("Pipe error" ));
119
+ break ;
120
+ case XFER_RESULT_TIMEOUT :
121
+ case XFER_RESULT_INVALID :
122
+ mp_raise_usb_core_USBTimeoutError ();
123
+ break ;
124
+ }
125
+ return false;
107
126
}
108
127
109
128
static void _prepare_for_transfer (void ) {
@@ -173,41 +192,75 @@ static void _get_langid(usb_core_device_obj_t *self) {
173
192
}
174
193
// Two control bytes and one uint16_t language code.
175
194
uint16_t temp_buf [2 ];
176
- if (!tuh_descriptor_get_string (self -> device_address , 0 , 0 , temp_buf , sizeof (temp_buf ), _transfer_done_cb , 0 ) ||
177
- !_wait_for_callback ()) {
178
- return ;
195
+ _prepare_for_transfer ();
196
+ if (!tuh_descriptor_get_string (self -> device_address , 0 , 0 , temp_buf , sizeof (temp_buf ), _transfer_done_cb , 0 )) {
197
+ mp_raise_usb_core_USBError (NULL );
198
+ } else if (_wait_for_callback ()) {
199
+ self -> first_langid = temp_buf [1 ];
179
200
}
180
- self -> first_langid = temp_buf [1 ];
181
201
}
182
202
183
203
mp_obj_t common_hal_usb_core_device_get_serial_number (usb_core_device_obj_t * self ) {
184
204
uint16_t temp_buf [127 ];
185
- _get_langid (self );
186
- if (!tuh_descriptor_get_serial_string (self -> device_address , self -> first_langid , temp_buf , sizeof (temp_buf ), _transfer_done_cb , 0 ) ||
187
- !_wait_for_callback ()) {
205
+ tusb_desc_device_t descriptor ;
206
+ // First, be sure not to ask TinyUSB for a non-existent string (avoid error)
207
+ if (!tuh_descriptor_get_device_local (self -> device_address , & descriptor )) {
208
+ return mp_const_none ;
209
+ }
210
+ if (descriptor .iSerialNumber == 0 ) {
188
211
return mp_const_none ;
189
212
}
190
- return _get_string (temp_buf );
213
+ // Device does provide this string, so continue
214
+ _get_langid (self );
215
+ _prepare_for_transfer ();
216
+ if (!tuh_descriptor_get_serial_string (self -> device_address , self -> first_langid , temp_buf , sizeof (temp_buf ), _transfer_done_cb , 0 )) {
217
+ mp_raise_usb_core_USBError (NULL );
218
+ } else if (_wait_for_callback ()) {
219
+ return _get_string (temp_buf );
220
+ }
221
+ return mp_const_none ;
191
222
}
192
223
193
224
mp_obj_t common_hal_usb_core_device_get_product (usb_core_device_obj_t * self ) {
194
225
uint16_t temp_buf [127 ];
195
- _get_langid ( self ) ;
196
- if (! tuh_descriptor_get_product_string ( self -> device_address , self -> first_langid , temp_buf , sizeof ( temp_buf ), _transfer_done_cb , 0 ) ||
197
- ! _wait_for_callback ( )) {
226
+ tusb_desc_device_t descriptor ;
227
+ // First, be sure not to ask TinyUSB for a non-existent string (avoid error)
228
+ if (! tuh_descriptor_get_device_local ( self -> device_address , & descriptor )) {
198
229
return mp_const_none ;
199
230
}
200
- return _get_string (temp_buf );
231
+ if (descriptor .iProduct == 0 ) {
232
+ return mp_const_none ;
233
+ }
234
+ // Device does provide this string, so continue
235
+ _get_langid (self );
236
+ _prepare_for_transfer ();
237
+ if (!tuh_descriptor_get_product_string (self -> device_address , self -> first_langid , temp_buf , sizeof (temp_buf ), _transfer_done_cb , 0 )) {
238
+ mp_raise_usb_core_USBError (NULL );
239
+ } else if (_wait_for_callback ()) {
240
+ return _get_string (temp_buf );
241
+ }
242
+ return mp_const_none ;
201
243
}
202
244
203
245
mp_obj_t common_hal_usb_core_device_get_manufacturer (usb_core_device_obj_t * self ) {
204
246
uint16_t temp_buf [127 ];
205
- _get_langid ( self ) ;
206
- if (! tuh_descriptor_get_manufacturer_string ( self -> device_address , self -> first_langid , temp_buf , sizeof ( temp_buf ), _transfer_done_cb , 0 ) ||
207
- ! _wait_for_callback ( )) {
247
+ tusb_desc_device_t descriptor ;
248
+ // First, be sure not to ask TinyUSB for a non-existent string (avoid error)
249
+ if (! tuh_descriptor_get_device_local ( self -> device_address , & descriptor )) {
208
250
return mp_const_none ;
209
251
}
210
- return _get_string (temp_buf );
252
+ if (descriptor .iManufacturer == 0 ) {
253
+ return mp_const_none ;
254
+ }
255
+ // Device does provide this string, so continue
256
+ _get_langid (self );
257
+ _prepare_for_transfer ();
258
+ if (!tuh_descriptor_get_manufacturer_string (self -> device_address , self -> first_langid , temp_buf , sizeof (temp_buf ), _transfer_done_cb , 0 )) {
259
+ mp_raise_usb_core_USBError (NULL );
260
+ } else if (_wait_for_callback ()) {
261
+ return _get_string (temp_buf );
262
+ }
263
+ return mp_const_none ;
211
264
}
212
265
213
266
0 commit comments