2929#include  "esp32-hal.h" 
3030
3131#include  "esp32-hal-tinyusb.h" 
32- #include  "usb_persist.h" 
32+ #include  "esp32s2/rom/usb/ usb_persist.h" 
3333
3434typedef  char  tusb_str_t [127 ];
3535
@@ -309,6 +309,8 @@ __attribute__ ((weak)) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_
309309/* 
310310 * Private API 
311311 * */ 
312+ static  bool  usb_persist_enabled  =  false;
313+ static  restart_type_t  usb_persist_mode  =  RESTART_NO_PERSIST ;
312314
313315static  bool  tinyusb_reserve_in_endpoint (uint8_t  endpoint ){
314316 if (endpoint  >  6  ||  (tinyusb_endpoints .in  &  BIT (endpoint )) !=  0 ){
@@ -381,7 +383,7 @@ static bool tinyusb_load_enabled_interfaces(){
381383 };
382384 memcpy (tinyusb_config_descriptor , descriptor , TUD_CONFIG_DESC_LEN );
383385 if  ((tinyusb_loaded_interfaces_mask  ==  (BIT (USB_INTERFACE_CDC ) | BIT (USB_INTERFACE_DFU ))) ||  (tinyusb_loaded_interfaces_mask  ==  BIT (USB_INTERFACE_CDC ))) {
384-  usb_persist_set_enable ( true) ;
386+  usb_persist_enabled   =   true;
385387 log_d ("USB Persist enabled" );
386388 }
387389 log_d ("Load Done: if_num: %u, descr_len: %u, if_mask: 0x%x" , tinyusb_loaded_interfaces_num , tinyusb_config_descriptor_len , tinyusb_loaded_interfaces_mask );
@@ -451,6 +453,34 @@ static void tinyusb_apply_device_config(tinyusb_device_config_t *config){
451453 tinyusb_device_descriptor .bDeviceProtocol  =  config -> usb_protocol ;
452454}
453455
456+ static  void  IRAM_ATTR  usb_persist_shutdown_handler (void )
457+ {
458+  if (usb_persist_mode  !=  RESTART_NO_PERSIST ){
459+  if  (usb_persist_enabled ) {
460+  REG_SET_BIT (RTC_CNTL_USB_CONF_REG , RTC_CNTL_IO_MUX_RESET_DISABLE );
461+  REG_SET_BIT (RTC_CNTL_USB_CONF_REG , RTC_CNTL_USB_RESET_DISABLE );
462+  }
463+  if  (usb_persist_mode  ==  RESTART_BOOTLOADER ) {
464+  //USB CDC Download 
465+  if  (usb_persist_enabled ) {
466+  USB_WRAP .date .val  =  USBDC_PERSIST_ENA ;
467+  }
468+  REG_WRITE (RTC_CNTL_OPTION1_REG , RTC_CNTL_FORCE_DOWNLOAD_BOOT );
469+  periph_module_disable (PERIPH_TIMG1_MODULE );
470+  } else  if  (usb_persist_mode  ==  RESTART_BOOTLOADER_DFU ) {
471+  //DFU Download 
472+  USB_WRAP .date .val  =  USBDC_BOOT_DFU ;
473+  REG_WRITE (RTC_CNTL_OPTION1_REG , RTC_CNTL_FORCE_DOWNLOAD_BOOT );
474+  periph_module_disable (PERIPH_TIMG0_MODULE );
475+  periph_module_disable (PERIPH_TIMG1_MODULE );
476+  } else  if  (usb_persist_enabled ) {
477+  //USB Persist reboot 
478+  USB_WRAP .date .val  =  USBDC_PERSIST_ENA ;
479+  }
480+  SET_PERI_REG_MASK (RTC_CNTL_OPTIONS0_REG , RTC_CNTL_SW_PROCPU_RST );
481+  }
482+ }
483+ 
454484// USB Device Driver task 
455485// This top level thread processes all usb events and invokes callbacks 
456486static  void  usb_device_task (void  * param ) {
@@ -488,6 +518,24 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
488518 initialized  =  false;
489519 return  ESP_FAIL ;
490520 }
521+ 
522+  bool  usb_did_persist  =  (USB_WRAP .date .val  ==  USBDC_PERSIST_ENA );
523+ 
524+  if (usb_did_persist  &&  usb_persist_enabled ){
525+  // Enable USB/IO_MUX peripheral reset, if coming from persistent reboot 
526+  REG_CLR_BIT (RTC_CNTL_USB_CONF_REG , RTC_CNTL_IO_MUX_RESET_DISABLE );
527+  REG_CLR_BIT (RTC_CNTL_USB_CONF_REG , RTC_CNTL_USB_RESET_DISABLE );
528+  } else  {
529+  // Reset USB module 
530+  periph_module_reset (PERIPH_USB_MODULE );
531+  periph_module_enable (PERIPH_USB_MODULE );
532+  }
533+ 
534+  if  (usb_persist_enabled  &&  esp_register_shutdown_handler (usb_persist_shutdown_handler ) !=  ESP_OK ) {
535+  initialized  =  false;
536+  return  ESP_FAIL ;
537+  }
538+ 
491539 tinyusb_config_t  tusb_cfg  =  {
492540 .external_phy  =  false // In the most cases you need to use a `false` value 
493541 };
@@ -500,6 +548,16 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
500548 return  err ;
501549}
502550
551+ void  usb_persist_restart (restart_type_t  mode )
552+ {
553+  if  (usb_persist_enabled  &&  mode  <  RESTART_TYPE_MAX ) {
554+  usb_persist_mode  =  mode ;
555+  esp_restart ();
556+  } else  {
557+  log_e ("Persistence is not enabled" );
558+  }
559+ }
560+ 
503561uint8_t  tinyusb_add_string_descriptor (const  char  *  str ){
504562 if (str  ==  NULL  ||  tinyusb_string_descriptor_len  >= MAX_STRING_DESCRIPTORS ){
505563 return  0 ;
0 commit comments