20
20
21
21
#include "hal/usb_hal.h"
22
22
#include "hal/gpio_ll.h"
23
+ #include "hal/usb_serial_jtag_ll.h"
23
24
24
25
#include "freertos/FreeRTOS.h"
25
26
#include "freertos/task.h"
@@ -376,6 +377,120 @@ __attribute__ ((weak)) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_
376
377
static bool usb_persist_enabled = false;
377
378
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST ;
378
379
380
+ #if CONFIG_IDF_TARGET_ESP32S3
381
+
382
+ static void hw_cdc_reset_handler (void * arg ) {
383
+ portBASE_TYPE xTaskWoken = 0 ;
384
+ uint32_t usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask ();
385
+ usb_serial_jtag_ll_clr_intsts_mask (usbjtag_intr_status );
386
+
387
+ if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_BUS_RESET ) {
388
+ xSemaphoreGiveFromISR ((xSemaphoreHandle )arg , & xTaskWoken );
389
+ }
390
+
391
+ if (xTaskWoken == pdTRUE ) {
392
+ portYIELD_FROM_ISR ();
393
+ }
394
+ }
395
+
396
+ static void usb_switch_to_cdc_jtag (){
397
+ // Disable USB-OTG
398
+ periph_module_reset (PERIPH_USB_MODULE );
399
+ //periph_module_enable(PERIPH_USB_MODULE);
400
+ periph_module_disable (PERIPH_USB_MODULE );
401
+
402
+ // Switch to hardware CDC+JTAG
403
+ CLEAR_PERI_REG_MASK (RTC_CNTL_USB_CONF_REG , (RTC_CNTL_SW_HW_USB_PHY_SEL |RTC_CNTL_SW_USB_PHY_SEL |RTC_CNTL_USB_PAD_ENABLE ));
404
+
405
+ // Do not use external PHY
406
+ CLEAR_PERI_REG_MASK (USB_SERIAL_JTAG_CONF0_REG , USB_SERIAL_JTAG_PHY_SEL );
407
+
408
+ // Release GPIO pins from CDC+JTAG
409
+ CLEAR_PERI_REG_MASK (USB_SERIAL_JTAG_CONF0_REG , USB_SERIAL_JTAG_USB_PAD_ENABLE );
410
+
411
+ // Force the host to re-enumerate (BUS_RESET)
412
+ pinMode (USBPHY_DM_NUM , OUTPUT_OPEN_DRAIN );
413
+ pinMode (USBPHY_DP_NUM , OUTPUT_OPEN_DRAIN );
414
+ digitalWrite (USBPHY_DM_NUM , LOW );
415
+ digitalWrite (USBPHY_DP_NUM , LOW );
416
+
417
+ // Initialize CDC+JTAG ISR to listen for BUS_RESET
418
+ usb_serial_jtag_ll_disable_intr_mask (USB_SERIAL_JTAG_LL_INTR_MASK );
419
+ usb_serial_jtag_ll_clr_intsts_mask (USB_SERIAL_JTAG_LL_INTR_MASK );
420
+ usb_serial_jtag_ll_ena_intr_mask (USB_SERIAL_JTAG_INTR_BUS_RESET );
421
+ intr_handle_t intr_handle = NULL ;
422
+ xSemaphoreHandle reset_sem = xSemaphoreCreateBinary ();
423
+ if (reset_sem ){
424
+ if (esp_intr_alloc (ETS_USB_SERIAL_JTAG_INTR_SOURCE , 0 , hw_cdc_reset_handler , reset_sem , & intr_handle ) != ESP_OK ){
425
+ vSemaphoreDelete (reset_sem );
426
+ reset_sem = NULL ;
427
+ log_e ("HW USB CDC failed to init interrupts" );
428
+ }
429
+ } else {
430
+ log_e ("reset_sem init failed" );
431
+ }
432
+
433
+ // Connect GPIOs to integrated CDC+JTAG
434
+ SET_PERI_REG_MASK (USB_SERIAL_JTAG_CONF0_REG , USB_SERIAL_JTAG_USB_PAD_ENABLE );
435
+
436
+ // Wait for BUS_RESET to give us back the semaphore
437
+ if (reset_sem ){
438
+ if (xSemaphoreTake (reset_sem , 1000 / portTICK_PERIOD_MS ) != pdPASS ){
439
+ log_e ("reset_sem timeout" );
440
+ }
441
+ usb_serial_jtag_ll_disable_intr_mask (USB_SERIAL_JTAG_LL_INTR_MASK );
442
+ esp_intr_free (intr_handle );
443
+ vSemaphoreDelete (reset_sem );
444
+ }
445
+ }
446
+ #endif
447
+
448
+ static void IRAM_ATTR usb_persist_shutdown_handler (void )
449
+ {
450
+ if (usb_persist_mode != RESTART_NO_PERSIST ){
451
+ if (usb_persist_enabled ) {
452
+ usb_dc_prepare_persist ();
453
+ }
454
+ if (usb_persist_mode == RESTART_BOOTLOADER ) {
455
+ //USB CDC Download
456
+ if (usb_persist_enabled ) {
457
+ chip_usb_set_persist_flags (USBDC_PERSIST_ENA );
458
+ #if CONFIG_IDF_TARGET_ESP32S2
459
+ } else {
460
+ periph_module_reset (PERIPH_USB_MODULE );
461
+ periph_module_enable (PERIPH_USB_MODULE );
462
+ #endif
463
+ }
464
+ REG_WRITE (RTC_CNTL_OPTION1_REG , RTC_CNTL_FORCE_DOWNLOAD_BOOT );
465
+ } else if (usb_persist_mode == RESTART_BOOTLOADER_DFU ) {
466
+ //DFU Download
467
+ #if CONFIG_IDF_TARGET_ESP32S2
468
+ // Reset USB Core
469
+ USB0 .grstctl |= USB_CSFTRST ;
470
+ while ((USB0 .grstctl & USB_CSFTRST ) == USB_CSFTRST ){}
471
+ #endif
472
+ chip_usb_set_persist_flags (USBDC_BOOT_DFU );
473
+ REG_WRITE (RTC_CNTL_OPTION1_REG , RTC_CNTL_FORCE_DOWNLOAD_BOOT );
474
+ } else if (usb_persist_enabled ) {
475
+ //USB Persist reboot
476
+ chip_usb_set_persist_flags (USBDC_PERSIST_ENA );
477
+ }
478
+ }
479
+ }
480
+
481
+ void usb_persist_restart (restart_type_t mode )
482
+ {
483
+ if (mode < RESTART_TYPE_MAX && esp_register_shutdown_handler (usb_persist_shutdown_handler ) == ESP_OK ) {
484
+ usb_persist_mode = mode ;
485
+ #if CONFIG_IDF_TARGET_ESP32S3
486
+ if (mode == RESTART_BOOTLOADER ) {
487
+ usb_switch_to_cdc_jtag ();
488
+ }
489
+ #endif
490
+ esp_restart ();
491
+ }
492
+ }
493
+
379
494
static bool tinyusb_reserve_in_endpoint (uint8_t endpoint ){
380
495
if (endpoint > 6 || (tinyusb_endpoints .in & BIT (endpoint )) != 0 ){
381
496
return false;
@@ -521,60 +636,6 @@ static void tinyusb_apply_device_config(tinyusb_device_config_t *config){
521
636
tinyusb_device_descriptor .bDeviceProtocol = config -> usb_protocol ;
522
637
}
523
638
524
- static void IRAM_ATTR usb_persist_shutdown_handler (void )
525
- {
526
- if (usb_persist_mode != RESTART_NO_PERSIST ){
527
- if (usb_persist_enabled ) {
528
- usb_dc_prepare_persist ();
529
- }
530
- if (usb_persist_mode == RESTART_BOOTLOADER ) {
531
- //USB CDC Download
532
- if (usb_persist_enabled ) {
533
- chip_usb_set_persist_flags (USBDC_PERSIST_ENA );
534
- } else {
535
- #if CONFIG_IDF_TARGET_ESP32S3
536
- /*
537
- * This currently does not work!
538
- * Integrated CDC+JTAG refuses to communicate, once into Download mode
539
- */
540
- // Disable USB-OTG
541
- periph_module_reset (PERIPH_USB_MODULE );
542
- //periph_module_enable(PERIPH_USB_MODULE);
543
- periph_module_disable (PERIPH_USB_MODULE );
544
- // Switch to hardware CDC+JTAG
545
- REG_CLR_BIT (RTC_CNTL_USB_CONF_REG , (RTC_CNTL_SW_HW_USB_PHY_SEL |RTC_CNTL_SW_USB_PHY_SEL ));
546
- // Release GPIO pins from CDC+JTAG
547
- CLEAR_PERI_REG_MASK (USB_SERIAL_JTAG_CONF0_REG , USB_SERIAL_JTAG_USB_PAD_ENABLE );
548
- // Force the host to re-enumerate (BUS_RESET)
549
- pinMode (USBPHY_DM_NUM , OUTPUT_OPEN_DRAIN );
550
- pinMode (USBPHY_DP_NUM , OUTPUT_OPEN_DRAIN );
551
- digitalWrite (USBPHY_DM_NUM , LOW );
552
- digitalWrite (USBPHY_DP_NUM , LOW );
553
- delay (20 );
554
- // Connect GPIOs to integrated CDC+JTAG
555
- SET_PERI_REG_MASK (USB_SERIAL_JTAG_CONF0_REG , USB_SERIAL_JTAG_USB_PAD_ENABLE );
556
- // Do not use external PHY
557
- CLEAR_PERI_REG_MASK (USB_SERIAL_JTAG_CONF0_REG , USB_SERIAL_JTAG_PHY_SEL );
558
- #else
559
- periph_module_reset (PERIPH_USB_MODULE );
560
- periph_module_enable (PERIPH_USB_MODULE );
561
- #endif
562
- }
563
- REG_WRITE (RTC_CNTL_OPTION1_REG , RTC_CNTL_FORCE_DOWNLOAD_BOOT );
564
- } else if (usb_persist_mode == RESTART_BOOTLOADER_DFU ) {
565
- //DFU Download
566
- // Reset USB Core
567
- USB0 .grstctl |= USB_CSFTRST ;
568
- while ((USB0 .grstctl & USB_CSFTRST ) == USB_CSFTRST ){}
569
- chip_usb_set_persist_flags (USBDC_BOOT_DFU );
570
- REG_WRITE (RTC_CNTL_OPTION1_REG , RTC_CNTL_FORCE_DOWNLOAD_BOOT );
571
- } else if (usb_persist_enabled ) {
572
- //USB Persist reboot
573
- chip_usb_set_persist_flags (USBDC_PERSIST_ENA );
574
- }
575
- }
576
- }
577
-
578
639
// USB Device Driver task
579
640
// This top level thread processes all usb events and invokes callbacks
580
641
static void usb_device_task (void * param ) {
@@ -638,11 +699,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
638
699
periph_module_enable (PERIPH_USB_MODULE );
639
700
}
640
701
641
- if (esp_register_shutdown_handler (usb_persist_shutdown_handler ) != ESP_OK ) {
642
- tinyusb_is_initialized = false;
643
- return ESP_FAIL ;
644
- }
645
-
646
702
tinyusb_config_t tusb_cfg = {
647
703
.external_phy = false // In the most cases you need to use a `false` value
648
704
};
@@ -655,14 +711,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
655
711
return err ;
656
712
}
657
713
658
- void usb_persist_restart (restart_type_t mode )
659
- {
660
- if (mode < RESTART_TYPE_MAX ) {
661
- usb_persist_mode = mode ;
662
- esp_restart ();
663
- }
664
- }
665
-
666
714
uint8_t tinyusb_add_string_descriptor (const char * str ){
667
715
if (str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS ){
668
716
return 0 ;
0 commit comments