@@ -375,60 +375,92 @@ extern "C" void CoreUsbDeviceTask(void* param) noexcept
375
375
376
376
while (true )
377
377
{
378
- auto tusb_init = isHostMode ? tuh_init : tud_init;
379
- auto tusb_int_enable = isHostMode ? hcd_int_enable : dcd_int_enable;
380
- auto tusb_task = isHostMode ? tuh_task_ext : tud_task_ext;
381
-
382
378
digitalWrite (UsbVbusOn, isHostMode);
383
- tusb_init (0 );
379
+
380
+ auto tusb_init = isHostMode ? tuh_init : tud_init;
384
381
if (changingMode)
385
382
{
386
- if (isHostMode)
383
+ auto tusb_inited = isHostMode ? tuh_inited : tud_inited;
384
+ if (tusb_inited ())
387
385
{
388
- if (tuh_inited ())
386
+ // TinyUSB class drivers already inited previously, just call
387
+ // the functions to initialize the USB peripheral.
388
+ if (isHostMode)
389
389
{
390
390
hcd_init (0 );
391
+ hcd_int_enable (0 );
392
+ }
393
+ else
394
+ {
395
+ dcd_init (0 );
396
+ dcd_int_enable (0 );
391
397
}
392
398
}
393
399
else
394
400
{
395
- tud_connect ( );
401
+ tusb_init ( 0 );
396
402
}
397
403
}
398
- tusb_int_enable (0 );
404
+ else
405
+ {
406
+ tusb_init (0 );
407
+ }
408
+
409
+ auto tusb_task = isHostMode ? tuh_task_ext : tud_task_ext;
399
410
400
411
changingMode = false ;
401
412
while (!changingMode)
402
413
{
403
414
tusb_task (100 , false );
404
415
}
405
416
406
- // Deinit current tinyUSB context.
407
- if (isHostMode)
408
- {
409
- hcd_event_device_remove (0 , false );
410
- }
411
- else
412
- {
413
- tud_disconnect ();
414
- }
415
- tusb_task (100 , false );
416
-
417
- // Reset USB hardware.
418
- USBHS->USBHS_CTRL &= ~USBHS_CTRL_USBE;
417
+ // Disable pipes, deallocate DPRAM
419
418
for (int i = 9 ; i >= 0 ; i--)
420
419
{
421
420
if (isHostMode)
422
421
{
422
+ USBHS->USBHS_HSTPIP &= ~(USBHS_HSTPIP_PEN0 << i);
423
423
USBHS->USBHS_HSTPIPCFG [i] &= ~(USBHS_HSTPIPCFG_ALLOC);
424
424
}
425
425
else
426
426
{
427
+ USBHS->USBHS_DEVEPT &= ~(USBHS_DEVEPT_EPEN0 << i);
427
428
USBHS->USBHS_DEVEPTCFG [i] &= ~(USBHS_DEVEPTCFG_ALLOC);
428
429
}
429
430
}
430
431
431
- // Complete the mode change.
432
+ // Reset DMA registers
433
+ for (int i = 0 ; i < 7 ; i++)
434
+ {
435
+ if (isHostMode)
436
+ {
437
+ USBHS->USBHS_HSTDMA [i].USBHS_HSTDMAADDRESS = 0 ;
438
+ USBHS->USBHS_HSTDMA [i].USBHS_HSTDMACONTROL = 0 ;
439
+ USBHS->USBHS_HSTDMA [i].USBHS_HSTDMASTATUS = 0 ;
440
+ }
441
+ else
442
+ {
443
+ USBHS->USBHS_DEVDMA [i].USBHS_DEVDMAADDRESS = 0 ;
444
+ USBHS->USBHS_DEVDMA [i].USBHS_DEVDMACONTROL = 0 ;
445
+ USBHS->USBHS_DEVDMA [i].USBHS_DEVDMASTATUS = 0 ;
446
+ }
447
+ }
448
+
449
+ // Deinit current tinyUSB host context. Not needed for device
450
+ // since changing mode requires the board to not be connected
451
+ // to a host, so if we are changing mode then the DCD_EVENT_UNPLUGGED
452
+ // must have been handled in the past already.
453
+ if (isHostMode)
454
+ {
455
+ hcd_event_device_remove (0 , false );
456
+ tusb_task (100 , false );
457
+ }
458
+
459
+ // Reset USB hardware
460
+ USBHS->USBHS_CTRL &= ~(USBHS_CTRL_USBE | USBHS_CTRL_UIMOD);
461
+ USBHS->USBHS_CTRL |= USBHS_CTRL_FRZCLK;
462
+
463
+ // Toggle mode for next loop
432
464
isHostMode = !isHostMode;
433
465
}
434
466
}
0 commit comments