4747
4848// USB class flags are defined in mp_usbd.h
4949
50- // Structure for combinable built-in USB driver configurations
50+ #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
51+ // Structure for the lightweight USBBuiltin object
5152typedef struct _mp_obj_usb_builtin_t {
5253 mp_obj_base_t base ;
5354 uint8_t flags ; // Combination of USB_BUILTIN_FLAG_* values
5455} mp_obj_usb_builtin_t ;
5556
56- const mp_obj_type_t machine_usb_device_type ;
57+ // Forward declaration for the USBBuiltin type
5758const mp_obj_type_t mp_type_usb_builtin ;
59+ #endif
5860
59- // Forward declaration for builtin config creation
60- static mp_obj_t mp_usbd_create_builtin_config (uint8_t flags );
61+ const mp_obj_type_t machine_usb_device_type ;
6162
6263// Return true if any built-in driver is enabled
6364bool mp_usb_device_builtin_enabled (const mp_obj_usb_device_t * usbd ) {
64- #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
6565 return usbd -> builtin_driver != USB_BUILTIN_FLAG_NONE ;
66- #else
67- // In static mode, builtin_driver is an object
68- if (mp_obj_is_type (usbd -> builtin_driver , & mp_type_usb_builtin )) {
69- mp_obj_usb_builtin_t * builtin = MP_OBJ_TO_PTR (usbd -> builtin_driver );
70- return builtin -> flags != USB_BUILTIN_FLAG_NONE ;
71- }
72- return false;
73- #endif
7466}
7567
7668static mp_obj_t usb_device_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
@@ -84,16 +76,8 @@ static mp_obj_t usb_device_make_new(const mp_obj_type_t *type, size_t n_args, si
8476 o -> base .type = & machine_usb_device_type ;
8577
8678 // Initialize fields common to both minimal and full modes
87- #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
88- // Runtime mode: read current class state to reflect default CDC configuration
8979 o -> builtin_driver = mp_usbd_class_state .flags ;
9080 o -> active = tud_inited ();
91- #else
92- // In static mode, USB is always initialized at boot
93- // Class state is set during early boot, create a USBBuiltin object from it
94- o -> builtin_driver = mp_usbd_create_builtin_config (mp_usbd_class_state .flags );
95- o -> active = tud_inited ();
96- #endif
9781
9882 #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
9983 // Initialize runtime-only fields
@@ -210,10 +194,7 @@ static mp_obj_t usb_device_active(size_t n_args, const mp_obj_t *args) {
210194 mp_usbd_init (); // Ensure TinyUSB has initialised by this point
211195
212196 // Update class state based on current builtin_driver
213- if (mp_obj_is_type (usbd -> builtin_driver , & mp_type_usb_builtin )) {
214- mp_obj_usb_builtin_t * builtin = MP_OBJ_TO_PTR (usbd -> builtin_driver );
215- mp_usbd_class_state .flags = builtin -> flags ;
216- }
197+ mp_usbd_class_state .flags = usbd -> builtin_driver ;
217198 } else {
218199 // Disable all classes when deactivating
219200 mp_usbd_class_state .flags = USB_BUILTIN_FLAG_NONE ;
@@ -304,65 +285,26 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(usb_device_config_obj, 1, usb_device_config);
304285// Device descriptor object (needed by bitfield builtin functions)
305286static const MP_DEFINE_BYTES_OBJ (builtin_default_desc_dev_obj ,
306287 & mp_usbd_builtin_desc_dev , sizeof (tusb_desc_device_t ));
307-
308- // Forward declarations for bitfield builtin functions
309- static uint8_t mp_usbd_get_itf_max (uint8_t flags );
310- static uint8_t mp_usbd_get_ep_max (uint8_t flags );
311- static uint8_t mp_usbd_get_str_max (uint8_t flags );
312- static const uint8_t * mp_usbd_get_builtin_desc_cfg (uint8_t flags );
313- static size_t mp_usbd_get_desc_cfg_len (uint8_t flags );
314-
315288#endif // MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
316289
290+ #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
317291// Create a new builtin configuration object with specified flags
318292static mp_obj_t mp_usbd_create_builtin_config (uint8_t flags ) {
319293 mp_obj_usb_builtin_t * builtin = mp_obj_malloc (mp_obj_usb_builtin_t , & mp_type_usb_builtin );
320294 builtin -> flags = flags ;
321295 return MP_OBJ_FROM_PTR (builtin );
322296}
323297
324- // Print method for USBBuiltin objects
325- static void builtin_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
326- mp_obj_usb_builtin_t * self = MP_OBJ_TO_PTR (self_in );
327- mp_printf (print , "USBBuiltin(0x%02x)" , self -> flags );
328- }
329-
330- // Binary operator for equality checks (implements == and !=)
331- static mp_obj_t builtin_binary_op (mp_binary_op_t op , mp_obj_t lhs_in , mp_obj_t rhs_in ) {
332- if (op == MP_BINARY_OP_EQUAL ) {
333- mp_obj_usb_builtin_t * lhs = MP_OBJ_TO_PTR (lhs_in );
334- uint8_t rhs_flags ;
335- if (mp_obj_is_type (rhs_in , & mp_type_usb_builtin )) {
336- rhs_flags = ((mp_obj_usb_builtin_t * )MP_OBJ_TO_PTR (rhs_in ))-> flags ;
337- } else if (mp_obj_is_int (rhs_in )) {
338- rhs_flags = mp_obj_get_int (rhs_in );
339- } else {
340- return mp_const_false ;
341- }
342- return mp_obj_new_bool (lhs -> flags == rhs_flags );
343- }
344- return MP_OBJ_NULL ;
345- }
346-
347- // Unary operator for int() and bool() conversions
348- static mp_obj_t builtin_unary_op (mp_unary_op_t op , mp_obj_t self_in ) {
349- mp_obj_usb_builtin_t * self = MP_OBJ_TO_PTR (self_in );
350- if (op == MP_UNARY_OP_INT_MAYBE || op == MP_UNARY_OP_BOOL ) {
351- return MP_OBJ_NEW_SMALL_INT (self -> flags );
352- }
353- return MP_OBJ_NULL ;
354- }
355-
356- #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
357- // Dynamic attribute access for builtin config objects (runtime mode only)
298+ // Dynamic attribute access for the lightweight USBBuiltin object
358299static void builtin_attr (mp_obj_t self_in , qstr attr , mp_obj_t * dest ) {
359300 mp_obj_usb_builtin_t * self = MP_OBJ_TO_PTR (self_in );
360301
361302 if (dest [0 ] == MP_OBJ_NULL ) {
362303 // Load attribute
363304 if (attr == MP_QSTR_desc_cfg ) {
364- size_t len = mp_usbd_get_desc_cfg_len (self -> flags );
365- dest [0 ] = mp_obj_new_bytes (mp_usbd_get_builtin_desc_cfg (self -> flags ), len );
305+ size_t len ;
306+ const uint8_t * desc = mp_usbd_get_builtin_desc_cfg (self -> flags , & len );
307+ dest [0 ] = mp_obj_new_bytes (desc , len );
366308 } else if (attr == MP_QSTR_itf_max ) {
367309 dest [0 ] = MP_OBJ_NEW_SMALL_INT (mp_usbd_get_itf_max (self -> flags ));
368310 } else if (attr == MP_QSTR_ep_max ) {
@@ -375,61 +317,14 @@ static void builtin_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
375317 }
376318}
377319
378- // Helper functions for dynamic property calculation (runtime mode only)
379- static uint8_t mp_usbd_get_itf_max (uint8_t flags ) {
380- uint8_t count = 0 ;
381- if ((flags & USB_BUILTIN_FLAG_CDC ) && MICROPY_HW_USB_CDC ) {
382- count += 2 ; // CDC uses 2 interfaces
383- }
384- if ((flags & USB_BUILTIN_FLAG_MSC ) && MICROPY_HW_USB_MSC ) {
385- count += 1 ;
386- }
387- return count ;
388- }
389-
390- static uint8_t mp_usbd_get_ep_max (uint8_t flags ) {
391- uint8_t ep_max = 1 ; // Endpoint 0 is always used
392- if ((flags & USB_BUILTIN_FLAG_CDC ) && MICROPY_HW_USB_CDC ) {
393- ep_max = 3 ; // CDC uses endpoints 1, 2, 3
394- }
395- if ((flags & USB_BUILTIN_FLAG_MSC ) && MICROPY_HW_USB_MSC ) {
396- ep_max = (ep_max > 2 ) ? ep_max : 2 ; // MSC uses endpoints 1, 2
397- }
398- return ep_max ;
399- }
400-
401- static uint8_t mp_usbd_get_str_max (uint8_t flags ) {
402- uint8_t str_max = 1 ; // String 0 is always used (language descriptor)
403- if ((flags & USB_BUILTIN_FLAG_CDC ) && MICROPY_HW_USB_CDC ) {
404- str_max = 4 ; // CDC uses strings 1, 2, 3, 4
405- }
406- if ((flags & USB_BUILTIN_FLAG_MSC ) && MICROPY_HW_USB_MSC ) {
407- str_max = (str_max > 2 ) ? str_max : 2 ; // MSC uses strings 1, 2
408- }
409- return str_max ;
410- }
411-
412- static const uint8_t * mp_usbd_get_builtin_desc_cfg (uint8_t flags ) {
413- return mp_usbd_generate_desc_cfg_unified (flags , mp_usbd_desc_cfg_buffer );
414- }
415-
416- static size_t mp_usbd_get_desc_cfg_len (uint8_t flags ) {
417- return mp_usbd_get_descriptor_cfg_len_from_flags (flags );
418- }
419- #endif // MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
420-
421- // Type definition for builtin config objects
320+ // Type definition for the lightweight USBBuiltin object
422321MP_DEFINE_CONST_OBJ_TYPE (
423322 mp_type_usb_builtin ,
424323 MP_QSTR_USBBuiltin ,
425- MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE ,
426- print , builtin_print ,
427- unary_op , builtin_unary_op ,
428- binary_op , builtin_binary_op
429- #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
430- , attr , builtin_attr
431- #endif
324+ MP_TYPE_FLAG_NONE ,
325+ attr , builtin_attr
432326 );
327+ #endif
433328
434329// Calculate BUILTIN_DEFAULT flags at compile time
435330#if MICROPY_HW_USB_CDC && MICROPY_HW_USB_MSC
@@ -487,11 +382,11 @@ static void usb_device_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
487382 // Load attribute.
488383 if (attr == MP_QSTR_builtin_driver ) {
489384 #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
490- // Runtime mode: create USBBuiltin object from flags
385+ // Runtime mode: create lightweight USBBuiltin object from flags
491386 dest [0 ] = mp_usbd_create_builtin_config (self -> builtin_driver );
492387 #else
493- // Static mode: return the stored object directly
494- dest [0 ] = self -> builtin_driver ;
388+ // Static mode: return integer flags
389+ dest [0 ] = mp_obj_new_int ( self -> builtin_driver ) ;
495390 #endif
496391 } else {
497392 // Continue lookup in locals_dict.
@@ -505,35 +400,22 @@ static void usb_device_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
505400 if (self -> active ) {
506401 mp_raise_OSError (MP_EINVAL ); // Need to deactivate first
507402 }
508- #else
509- // In static mode, allow changing builtin_driver when active
510- // This will update the class state and trigger re-enumeration
511403 #endif
512404
513- // Extract flags from input (integer or USBBuiltin object)
514- uint8_t flags ;
515- if (mp_obj_is_type (dest [1 ], & mp_type_usb_builtin )) {
516- // USBBuiltin object - extract flags
517- mp_obj_usb_builtin_t * builtin = MP_OBJ_TO_PTR (dest [1 ]);
518- flags = builtin -> flags ;
519- } else if (mp_obj_is_int (dest [1 ])) {
520- // Integer value - use directly
521- flags = mp_obj_get_int (dest [1 ]);
522- } else {
523- mp_raise_TypeError (MP_ERROR_TEXT ("builtin_driver must be int or USBBuiltin" ));
405+ // Extract flags from input (must be an integer)
406+ if (!mp_obj_is_int (dest [1 ])) {
407+ mp_raise_TypeError (MP_ERROR_TEXT ("builtin_driver must be an int" ));
524408 }
409+ uint8_t flags = mp_obj_get_int (dest [1 ]);
525410
526411 // Update the internal class state based on flags
527412 mp_usbd_class_state .flags = flags ;
528413
529- #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
530- // In runtime mode, store flags directly
414+ // Store the integer flags directly
531415 self -> builtin_driver = flags ;
532- #else
533- // In static mode, store as a USBBuiltin object
534- self -> builtin_driver = mp_usbd_create_builtin_config (flags );
535416
536- // If USB is active, trigger re-enumeration to update the host
417+ #if !MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
418+ // In static mode, if USB is active, trigger re-enumeration to update the host
537419 if (self -> active ) {
538420 #ifndef NO_QSTR
539421 // Disconnect and reconnect to trigger enumeration with new descriptors
0 commit comments