Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix S3 cannot reset to bootrom with USB OTG due to new gpio deinit() #8880

Merged
merged 1 commit into from
Nov 17, 2023

Conversation

hathach
Copy link
Contributor

@hathach hathach commented Nov 13, 2023

Description of Change

This PR fixes an issue when GPIO19/20 (USB D+/D-) pull-up is not enabled for usb jtag when we switch from OTG to Jtag when reset to bootrom. Making uploading via USB OTG not possible.

  • usb_otg_deinit() return false cause the new periman abort the pinMode() and digitalWrite() on DP/DM which is required disconnect from USB bus and force PC host to re-enumerate USB OTG in bootrom.

pinMode(USBPHY_DM_NUM, OUTPUT_OPEN_DRAIN);
pinMode(USBPHY_DP_NUM, OUTPUT_OPEN_DRAIN);
digitalWrite(USBPHY_DM_NUM, LOW);
digitalWrite(USBPHY_DP_NUM, LOW);

  • without this fix, above pinMode()/digitalWrite() do nothing, device reset to bootrom but USB host won't re-enumerate USB OTG. This can be observed when enable verbose logging (I added pinMode(D-/D+) and digitalWrite(D-/D+) to make it easier to follow)
[  5332][I][esp32-hal-tinyusb.c:514] usb_persist_restart(): USB Persist Restart: 2                                                           
[  5342][I][esp32-hal-tinyusb.c:435] usb_switch_to_cdc_jtag(): pinMode D-                                                                    
[  5349][V][esp32-hal-periman.c:150] perimanSetBusDeinit(): Deinit function for type GPIO (1) successfully set to 0x4202b490                 
[  5360][E][esp32-hal-periman.c:107] perimanSetPinBus(): Deinit function for previous bus type USB (21) failed (pin 19)                      
[  5370][E][esp32-hal-gpio.c:114] __pinMode(): Deinit of previous bus failed                                                                 
[  5377][I][esp32-hal-tinyusb.c:437] usb_switch_to_cdc_jtag(): pinMode D+                                                                    
[  5383][V][esp32-hal-periman.c:150] perimanSetBusDeinit(): Deinit function for type GPIO (1) successfully set to 0x4202b490                 
[  5394][E][esp32-hal-periman.c:107] perimanSetPinBus(): Deinit function for previous bus type USB (21) failed (pin 20)                      
[  5405][E][esp32-hal-gpio.c:114] __pinMode(): Deinit of previous bus failed                                                                 
[  5412][I][esp32-hal-tinyusb.c:439] usb_switch_to_cdc_jtag(): digitalWrite D-                                                               
[  5419][E][esp32-hal-gpio.c:167] __digitalWrite(): Pin is not set as GPIO.                                                                  
[  5425][I][esp32-hal-tinyusb.c:441] usb_switch_to_cdc_jtag(): digitalWrite D+                                                               
[  5432][E][esp32-hal-gpio.c:167] __digitalWrite(): Pin is not set as GPIO.                                                                  
[  5439][I][esp32-hal-tinyusb.c:445] usb_switch_to_cdc_jtag(): Initialize Serial JTAG                                                        
[  5718][V][esp32-hal-rmt.c:298] _rmtWrite(): GPIO: 48 - Request: 24 RMT Symbols - Blocking - Timeout: -1                                    
[  5718][V][esp32-hal-rmt.c:299] _rmtWrite(): GPIO: 48 - Currently in Loop Mode: [NO] | Asked to Loop: NO, LoopCancel: NO                    
[  6447][E][esp32-hal-tinyusb.c:468] usb_switch_to_cdc_jtag(): reset_sem timeout                                                             

Notice usb_switch_to_cdc_jtag(): reset_sem timeout since bus reset never occurs. Device is clearing in bootrom (check with cp210x) but If you do lsusb it still show OTG USB with application VID/PID.

Tests scenarios

Tested with esp32s3-devkitc-1 with (literally any S3 board). Steps to reproduce

  • Open an Blink sketch/example
  • Select "ESP32S3 Dev Module" board
  • Select USB Mode to "USB-OTG (TinyUSB)"
  • Select USB CDC on Boot to "Enabled"
  • Select Upload Mode to "USB-OTG CDC (TinyUSB)"

Click upload, it will complain

A fatal error occurred: Could not open /dev/ttyACM0, the port doesn't exist
Failed uploading: uploading error: exit status 2

Related links

Reported by Adafruit user

@ladyada

@@ -61,7 +61,12 @@ typedef struct {

static bool usb_otg_deinit(void * busptr) {
// Once USB OTG is initialized, its GPIOs are assigned and it shall never be deinited
// except when S3 swithicng usb from cdc to jtag while resetting to bootrom
#if CONFIG_IDF_TARGET_ESP32S3
return true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better fix could be using if check usb_persist_mode==RESTART_BOOTLOADER in the function, though we will need to move the static restart_type_t usb_persist_mode before usb_otg_deinit(). I am sure you guys could figure a better way. This PR is just a quick hack/suggestion to prove the point

@me-no-dev me-no-dev merged commit 93909f7 into espressif:master Nov 17, 2023
@hathach hathach deleted the fix-s3-otg-touch1200-bootrom branch September 5, 2024 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants