5353// this will be persistent across a soft-reset
5454mp_uint_t pyb_usb_flags = 0 ;
5555
56+ typedef struct _usb_device_t {
57+ uint32_t enabled ;
58+ USBD_HandleTypeDef hUSBDDevice ;
59+ usbd_cdc_msc_hid_state_t usbd_cdc_msc_hid_state ;
60+ usbd_cdc_itf_t usbd_cdc_itf ;
61+ usbd_hid_itf_t usbd_hid_itf ;
62+ } usb_device_t ;
63+
5664#ifdef USE_DEVICE_MODE
57- STATIC USBD_HandleTypeDef hUSBDDevice ;
58- STATIC usbd_cdc_msc_hid_state_t usbd_cdc_msc_hid_state ;
59- STATIC usbd_cdc_itf_t usbd_cdc_itf ;
60- STATIC usbd_hid_itf_t usbd_hid_itf ;
65+ usb_device_t usb_device ;
6166pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE ;
6267#endif
6368
@@ -106,78 +111,80 @@ void pyb_usb_init0(void) {
106111
107112bool pyb_usb_dev_init (uint16_t vid , uint16_t pid , usb_device_mode_t mode , USBD_HID_ModeInfoTypeDef * hid_info ) {
108113#ifdef USE_DEVICE_MODE
109- if (!(pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED )) {
114+ usb_device_t * usb_dev = & usb_device ;
115+ if (!usb_dev -> enabled ) {
110116 // only init USB once in the device's power-lifetime
111117
112118 // configure the VID, PID and the USBD mode (interfaces it will expose)
113119 USBD_SetVIDPIDRelease (vid , pid , 0x0200 , mode == USBD_MODE_CDC );
114- if (USBD_SelectMode (& usbd_cdc_msc_hid_state , mode , hid_info ) != 0 ) {
120+ if (USBD_SelectMode (& usb_dev -> usbd_cdc_msc_hid_state , mode , hid_info ) != 0 ) {
115121 return false;
116122 }
117123
118124 // set up the USBD state
119- USBD_HandleTypeDef * usbd = & hUSBDDevice ;
125+ USBD_HandleTypeDef * usbd = & usb_dev -> hUSBDDevice ;
120126 usbd -> id = USB_PHY_ID ;
121127 usbd -> dev_state = USBD_STATE_DEFAULT ;
122128 usbd -> pDesc = (USBD_DescriptorsTypeDef * )& USBD_Descriptors ;
123129 usbd -> pClass = & USBD_CDC_MSC_HID ;
124- usbd_cdc_msc_hid_state .pdev = usbd ;
125- usbd_cdc_msc_hid_state .cdc = & usbd_cdc_itf ;
126- usbd_cdc_msc_hid_state .hid = & usbd_hid_itf ;
127- usbd -> pClassData = & usbd_cdc_msc_hid_state ;
130+ usb_dev -> usbd_cdc_msc_hid_state .pdev = usbd ;
131+ usb_dev -> usbd_cdc_msc_hid_state .cdc = & usb_dev -> usbd_cdc_itf ;
132+ usb_dev -> usbd_cdc_msc_hid_state .hid = & usb_dev -> usbd_hid_itf ;
133+ usbd -> pClassData = & usb_dev -> usbd_cdc_msc_hid_state ;
128134
129135 switch (pyb_usb_storage_medium ) {
130136#if MICROPY_HW_HAS_SDCARD
131137 case PYB_USB_STORAGE_MEDIUM_SDCARD :
132- USBD_MSC_RegisterStorage (& usbd_cdc_msc_hid_state , (USBD_StorageTypeDef * )& USBD_SDCARD_STORAGE_fops );
138+ USBD_MSC_RegisterStorage (& usb_dev -> usbd_cdc_msc_hid_state , (USBD_StorageTypeDef * )& USBD_SDCARD_STORAGE_fops );
133139 break ;
134140#endif
135141 default :
136- USBD_MSC_RegisterStorage (& usbd_cdc_msc_hid_state , (USBD_StorageTypeDef * )& USBD_FLASH_STORAGE_fops );
142+ USBD_MSC_RegisterStorage (& usb_dev -> usbd_cdc_msc_hid_state , (USBD_StorageTypeDef * )& USBD_FLASH_STORAGE_fops );
137143 break ;
138144 }
139145
140146 // start the USB device
141147 USBD_LL_Init (usbd );
142148 USBD_LL_Start (usbd );
149+ usb_dev -> enabled = true;
143150 }
144- pyb_usb_flags |= PYB_USB_FLAG_DEV_ENABLED ;
145151#endif
146152
147153 return true;
148154}
149155
150156void pyb_usb_dev_deinit (void ) {
151- if (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED ) {
152- USBD_Stop (& hUSBDDevice );
153- pyb_usb_flags &= ~PYB_USB_FLAG_DEV_ENABLED ;
157+ usb_device_t * usb_dev = & usb_device ;
158+ if (usb_dev -> enabled ) {
159+ USBD_Stop (& usb_dev -> hUSBDDevice );
160+ usb_dev -> enabled = false;
154161 }
155162}
156163
157164bool usb_vcp_is_enabled (void ) {
158- return ( pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED ) != 0 ;
165+ return usb_device . enabled ;
159166}
160167
161168int usb_vcp_recv_byte (uint8_t * c ) {
162- return usbd_cdc_rx (& usbd_cdc_itf , c , 1 , 0 );
169+ return usbd_cdc_rx (& usb_device . usbd_cdc_itf , c , 1 , 0 );
163170}
164171
165172void usb_vcp_send_strn (const char * str , int len ) {
166173#ifdef USE_DEVICE_MODE
167- if (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED ) {
168- usbd_cdc_tx_always (& usbd_cdc_itf , (const uint8_t * )str , len );
174+ if (usb_device . enabled ) {
175+ usbd_cdc_tx_always (& usb_device . usbd_cdc_itf , (const uint8_t * )str , len );
169176 }
170177#endif
171178}
172179
173180void usb_vcp_send_strn_cooked (const char * str , int len ) {
174181#ifdef USE_DEVICE_MODE
175- if (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED ) {
182+ if (usb_device . enabled ) {
176183 for (const char * top = str + len ; str < top ; str ++ ) {
177184 if (* str == '\n' ) {
178- usbd_cdc_tx_always (& usbd_cdc_itf , (const uint8_t * )"\r\n" , 2 );
185+ usbd_cdc_tx_always (& usb_device . usbd_cdc_itf , (const uint8_t * )"\r\n" , 2 );
179186 } else {
180- usbd_cdc_tx_always (& usbd_cdc_itf , (const uint8_t * )str , 1 );
187+ usbd_cdc_tx_always (& usb_device . usbd_cdc_itf , (const uint8_t * )str , 1 );
181188 }
182189 }
183190 }
@@ -226,7 +233,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
226233 #if defined(USE_HOST_MODE )
227234 return MP_OBJ_NEW_QSTR (MP_QSTR_host );
228235 #elif defined(USE_DEVICE_MODE )
229- uint8_t mode = USBD_GetMode (& usbd_cdc_msc_hid_state );
236+ uint8_t mode = USBD_GetMode (& usb_device . usbd_cdc_msc_hid_state );
230237 switch (mode ) {
231238 case USBD_MODE_CDC :
232239 return MP_OBJ_NEW_QSTR (MP_QSTR_VCP );
@@ -351,9 +358,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj, 0, pyb_usb_mode);
351358
352359typedef struct _pyb_usb_vcp_obj_t {
353360 mp_obj_base_t base ;
361+ usb_device_t * usb_dev ;
354362} pyb_usb_vcp_obj_t ;
355363
356- STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp_obj = {{& pyb_usb_vcp_type }};
364+ STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp_obj = {{& pyb_usb_vcp_type }, & usb_device };
357365
358366STATIC void pyb_usb_vcp_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
359367 mp_print_str (print , "USB_VCP()" );
@@ -378,7 +386,8 @@ STATIC mp_obj_t pyb_usb_vcp_setinterrupt(mp_obj_t self_in, mp_obj_t int_chr_in)
378386STATIC MP_DEFINE_CONST_FUN_OBJ_2 (pyb_usb_vcp_setinterrupt_obj , pyb_usb_vcp_setinterrupt );
379387
380388STATIC mp_obj_t pyb_usb_vcp_isconnected (mp_obj_t self_in ) {
381- return mp_obj_new_bool (usbd_cdc_is_connected (& usbd_cdc_itf ));
389+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (self_in );
390+ return mp_obj_new_bool (usbd_cdc_is_connected (& self -> usb_dev -> usbd_cdc_itf ));
382391}
383392STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pyb_usb_vcp_isconnected_obj , pyb_usb_vcp_isconnected );
384393
@@ -391,7 +400,8 @@ MP_DEFINE_CONST_FUN_OBJ_0(pyb_have_cdc_obj, pyb_have_cdc);
391400/// \method any()
392401/// Return `True` if any characters waiting, else `False`.
393402STATIC mp_obj_t pyb_usb_vcp_any (mp_obj_t self_in ) {
394- if (usbd_cdc_rx_num (& usbd_cdc_itf ) > 0 ) {
403+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (self_in );
404+ if (usbd_cdc_rx_num (& self -> usb_dev -> usbd_cdc_itf ) > 0 ) {
395405 return mp_const_true ;
396406 } else {
397407 return mp_const_false ;
@@ -414,6 +424,7 @@ STATIC const mp_arg_t pyb_usb_vcp_send_args[] = {
414424
415425STATIC mp_obj_t pyb_usb_vcp_send (size_t n_args , const mp_obj_t * args , mp_map_t * kw_args ) {
416426 // parse args
427+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
417428 mp_arg_val_t vals [PYB_USB_VCP_SEND_NUM_ARGS ];
418429 mp_arg_parse_all (n_args - 1 , args + 1 , kw_args , PYB_USB_VCP_SEND_NUM_ARGS , pyb_usb_vcp_send_args , vals );
419430
@@ -423,7 +434,7 @@ STATIC mp_obj_t pyb_usb_vcp_send(size_t n_args, const mp_obj_t *args, mp_map_t *
423434 pyb_buf_get_for_send (vals [0 ].u_obj , & bufinfo , data );
424435
425436 // send the data
426- int ret = usbd_cdc_tx (& usbd_cdc_itf , bufinfo .buf , bufinfo .len , vals [1 ].u_int );
437+ int ret = usbd_cdc_tx (& self -> usb_dev -> usbd_cdc_itf , bufinfo .buf , bufinfo .len , vals [1 ].u_int );
427438
428439 return mp_obj_new_int (ret );
429440}
@@ -441,6 +452,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_vcp_send_obj, 1, pyb_usb_vcp_send);
441452/// otherwise the number of bytes read into `data` is returned.
442453STATIC mp_obj_t pyb_usb_vcp_recv (size_t n_args , const mp_obj_t * args , mp_map_t * kw_args ) {
443454 // parse args
455+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
444456 mp_arg_val_t vals [PYB_USB_VCP_SEND_NUM_ARGS ];
445457 mp_arg_parse_all (n_args - 1 , args + 1 , kw_args , PYB_USB_VCP_SEND_NUM_ARGS , pyb_usb_vcp_send_args , vals );
446458
@@ -449,7 +461,7 @@ STATIC mp_obj_t pyb_usb_vcp_recv(size_t n_args, const mp_obj_t *args, mp_map_t *
449461 mp_obj_t o_ret = pyb_buf_get_for_recv (vals [0 ].u_obj , & vstr );
450462
451463 // receive the data
452- int ret = usbd_cdc_rx (& usbd_cdc_itf , (uint8_t * )vstr .buf , vstr .len , vals [1 ].u_int );
464+ int ret = usbd_cdc_rx (& self -> usb_dev -> usbd_cdc_itf , (uint8_t * )vstr .buf , vstr .len , vals [1 ].u_int );
453465
454466 // return the received data
455467 if (o_ret != MP_OBJ_NULL ) {
@@ -486,7 +498,8 @@ STATIC const mp_rom_map_elem_t pyb_usb_vcp_locals_dict_table[] = {
486498STATIC MP_DEFINE_CONST_DICT (pyb_usb_vcp_locals_dict , pyb_usb_vcp_locals_dict_table );
487499
488500STATIC mp_uint_t pyb_usb_vcp_read (mp_obj_t self_in , void * buf , mp_uint_t size , int * errcode ) {
489- int ret = usbd_cdc_rx (& usbd_cdc_itf , (byte * )buf , size , 0 );
501+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (self_in );
502+ int ret = usbd_cdc_rx (& self -> usb_dev -> usbd_cdc_itf , (byte * )buf , size , 0 );
490503 if (ret == 0 ) {
491504 // return EAGAIN error to indicate non-blocking
492505 * errcode = MP_EAGAIN ;
@@ -496,7 +509,8 @@ STATIC mp_uint_t pyb_usb_vcp_read(mp_obj_t self_in, void *buf, mp_uint_t size, i
496509}
497510
498511STATIC mp_uint_t pyb_usb_vcp_write (mp_obj_t self_in , const void * buf , mp_uint_t size , int * errcode ) {
499- int ret = usbd_cdc_tx (& usbd_cdc_itf , (const byte * )buf , size , 0 );
512+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (self_in );
513+ int ret = usbd_cdc_tx (& self -> usb_dev -> usbd_cdc_itf , (const byte * )buf , size , 0 );
500514 if (ret == 0 ) {
501515 // return EAGAIN error to indicate non-blocking
502516 * errcode = MP_EAGAIN ;
@@ -507,13 +521,14 @@ STATIC mp_uint_t pyb_usb_vcp_write(mp_obj_t self_in, const void *buf, mp_uint_t
507521
508522STATIC mp_uint_t pyb_usb_vcp_ioctl (mp_obj_t self_in , mp_uint_t request , mp_uint_t arg , int * errcode ) {
509523 mp_uint_t ret ;
524+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (self_in );
510525 if (request == MP_STREAM_POLL ) {
511526 mp_uint_t flags = arg ;
512527 ret = 0 ;
513- if ((flags & MP_STREAM_POLL_RD ) && usbd_cdc_rx_num (& usbd_cdc_itf ) > 0 ) {
528+ if ((flags & MP_STREAM_POLL_RD ) && usbd_cdc_rx_num (& self -> usb_dev -> usbd_cdc_itf ) > 0 ) {
514529 ret |= MP_STREAM_POLL_RD ;
515530 }
516- if ((flags & MP_STREAM_POLL_WR ) && usbd_cdc_tx_half_empty (& usbd_cdc_itf )) {
531+ if ((flags & MP_STREAM_POLL_WR ) && usbd_cdc_tx_half_empty (& self -> usb_dev -> usbd_cdc_itf )) {
517532 ret |= MP_STREAM_POLL_WR ;
518533 }
519534 } else {
@@ -545,9 +560,10 @@ const mp_obj_type_t pyb_usb_vcp_type = {
545560
546561typedef struct _pyb_usb_hid_obj_t {
547562 mp_obj_base_t base ;
563+ usb_device_t * usb_dev ;
548564} pyb_usb_hid_obj_t ;
549565
550- STATIC const pyb_usb_hid_obj_t pyb_usb_hid_obj = {{& pyb_usb_hid_type }};
566+ STATIC const pyb_usb_hid_obj_t pyb_usb_hid_obj = {{& pyb_usb_hid_type }, & usb_device };
551567
552568STATIC mp_obj_t pyb_usb_hid_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
553569 // check arguments
@@ -576,6 +592,7 @@ STATIC mp_obj_t pyb_usb_hid_recv(size_t n_args, const mp_obj_t *args, mp_map_t *
576592 };
577593
578594 // parse args
595+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
579596 mp_arg_val_t vals [MP_ARRAY_SIZE (allowed_args )];
580597 mp_arg_parse_all (n_args - 1 , args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , vals );
581598
@@ -584,7 +601,7 @@ STATIC mp_obj_t pyb_usb_hid_recv(size_t n_args, const mp_obj_t *args, mp_map_t *
584601 mp_obj_t o_ret = pyb_buf_get_for_recv (vals [0 ].u_obj , & vstr );
585602
586603 // receive the data
587- int ret = usbd_hid_rx (& usbd_hid_itf , vstr .len , (uint8_t * )vstr .buf , vals [1 ].u_int );
604+ int ret = usbd_hid_rx (& self -> usb_dev -> usbd_hid_itf , vstr .len , (uint8_t * )vstr .buf , vals [1 ].u_int );
588605
589606 // return the received data
590607 if (o_ret != MP_OBJ_NULL ) {
@@ -598,6 +615,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_hid_recv_obj, 1, pyb_usb_hid_recv);
598615
599616STATIC mp_obj_t pyb_usb_hid_send (mp_obj_t self_in , mp_obj_t report_in ) {
600617#ifdef USE_DEVICE_MODE
618+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (self_in );
601619 mp_buffer_info_t bufinfo ;
602620 byte temp_buf [8 ];
603621 // get the buffer to send from
@@ -615,7 +633,7 @@ STATIC mp_obj_t pyb_usb_hid_send(mp_obj_t self_in, mp_obj_t report_in) {
615633 }
616634
617635 // send the data
618- if (USBD_OK == USBD_HID_SendReport (& usbd_cdc_msc_hid_state , bufinfo .buf , bufinfo .len )) {
636+ if (USBD_OK == USBD_HID_SendReport (& self -> usb_dev -> usbd_cdc_msc_hid_state , bufinfo .buf , bufinfo .len )) {
619637 return mp_obj_new_int (bufinfo .len );
620638 } else {
621639 return mp_obj_new_int (0 );
@@ -628,7 +646,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_usb_hid_send_obj, pyb_usb_hid_send);
628646
629647// deprecated in favour of USB_HID.send
630648STATIC mp_obj_t pyb_hid_send_report (mp_obj_t arg ) {
631- return pyb_usb_hid_send (MP_OBJ_NULL , arg );
649+ return pyb_usb_hid_send (MP_OBJ_FROM_PTR ( & pyb_usb_hid_obj ) , arg );
632650}
633651MP_DEFINE_CONST_FUN_OBJ_1 (pyb_hid_send_report_obj , pyb_hid_send_report );
634652
@@ -640,14 +658,15 @@ STATIC const mp_rom_map_elem_t pyb_usb_hid_locals_dict_table[] = {
640658STATIC MP_DEFINE_CONST_DICT (pyb_usb_hid_locals_dict , pyb_usb_hid_locals_dict_table );
641659
642660STATIC mp_uint_t pyb_usb_hid_ioctl (mp_obj_t self_in , mp_uint_t request , mp_uint_t arg , int * errcode ) {
661+ pyb_usb_vcp_obj_t * self = MP_OBJ_TO_PTR (self_in );
643662 mp_uint_t ret ;
644663 if (request == MP_STREAM_POLL ) {
645664 mp_uint_t flags = arg ;
646665 ret = 0 ;
647- if ((flags & MP_STREAM_POLL_RD ) && usbd_hid_rx_num (& usbd_hid_itf ) > 0 ) {
666+ if ((flags & MP_STREAM_POLL_RD ) && usbd_hid_rx_num (& self -> usb_dev -> usbd_hid_itf ) > 0 ) {
648667 ret |= MP_STREAM_POLL_RD ;
649668 }
650- if ((flags & MP_STREAM_POLL_WR ) && USBD_HID_CanSendReport (& usbd_cdc_msc_hid_state )) {
669+ if ((flags & MP_STREAM_POLL_WR ) && USBD_HID_CanSendReport (& self -> usb_dev -> usbd_cdc_msc_hid_state )) {
651670 ret |= MP_STREAM_POLL_WR ;
652671 }
653672 } else {
0 commit comments