espressif / esptool-js

Javascript implementation of flasher tool for Espressif chips, running in web browser using WebSerial.
https://espressif.github.io/esptool-js/
Apache License 2.0
276 stars 108 forks source link

Is there any interest in supporting flashing of TinyUSB devices? #97

Open sblantipodi opened 1 year ago

sblantipodi commented 1 year ago

As title. Is there any plan in supporting the flash of TinyUSB devices that was flashed with a TinyUSB firmware previously?

sblantipodi commented 1 year ago

@igrr can you comment on the original question please? will Espressif support flashing S3 and S2 from the webtool when in TinyUSB mode?

thanks

igrr commented 1 year ago

@sblantipodi I will need to research a bit on what the "TinyUSB mode" is to answer this question. As far as this tool is concerned, the only thing that is necessary is that the application running on the ESP can be reset into ROM download mode over USB CDC using RTS/DTR signals.

My guess is the issue you are seeing may be due to the board not having correct eFuses burned, and therefore it uses USB_SERIAL_JTAG peripheral in download mode instead of the USB_OTG peripheral. From espefuse summary you have posted here I see that USB_PHY_SEL is not set, which means that the ROM code will use USB_SERIAL_JTAG peripheral, instead of the USB_OTG which the software (TinyUSB) uses.

TD-er commented 1 year ago

TinyUSB is the SW USB implementation layer. Since it is software implemented, it brings along a few side effects.

For example on Windows, the USB port will disappear from the device manager in Windows when the ESP32-S2 reboots. Thus it simply isn't the same serial device anymore, so any handle to that serial port isn't valid anymore.

It is possible to let the ESP32-S2 reboot into 'flash mode' via the web flasher, but then it will not be able to continue. You need to reload the web flasher page and start again for it to continue flashing.

The enumerated serial port in Windows does get the same com port nr. assigned and also the same USB PID (0x0002) but I don't think it is the same serial port as the one you initially granted permission for in the browser.

I have a version running here which is using some patches added by @Jason2866 to help the S2 to enter flash mode. It seems to work on his system, but it doesn't work on Windows.

So far I have no idea what is preventing this. Either you may need to enumerate a new serial device after switching it to flash mode, or maybe simply re-start (reinit?) the serial port.

I also noticed in the esptool.py some comments stating _setDTR would only be propagated when also calling _setRTS. If that's correct then there are some inconsistencies in the code where DTR is toggled for 100 msec, but not setting the RTS, even though it would then be the same logic state as it was set before.

sblantipodi commented 1 year ago

@TD-er correct me if I'm wrong please but as far as I know Tiny USB CDC is the hardware implementation, USB JTAG serial is the software emulation of the old school Serial used during flashing.

PlatformIO is able to flash those boards on both modes on my Windows PC.

The software USB mode: can be access via /COM port, PlatformIO calls it USB MODE=1 and this is how it looks in esp-web-tools image

the hardware native USB version: can be access via //./COM port, PlatformIO calls it USB MODE=0 and this is how it looks in esp-web-tools image

I have done some benchmarks that seems to confirm what I'm saying, TinyUSB CDC is 2 times faster than USB JTAG Serial, it doesn't causes microlag on the chip while printing to serial like the other mode, and it requires less memory.

The latest implementation from Jason2866 is the best I have tried so far.

It can flashes the S3 with a software emulated USB firmware (USB/JTAG) without the needs of pressing buttons on the microcontroller and it works with improv-wifi as well. It works well on S2 even if you need to put the S2 in flash mode by pressing the Boot+rst button before flashing, no need to keep pressing boot button with the Jason2866 version of the tool.

TD-er, please correct me if I said some inaccuracies.

igrr commented 1 year ago

If you see "USB Serial/JTAG debug unit" in device manager, that is the port provided by the hardware USB_SERIAL_JTAG peripheral. USB_SERIAL_JTAG is a fixed-function composite USB device which provides two classes: USB CDC, for serial port emulation, and a vendor-specific JTAG adapter device. (More information about USB_SERIAL_JTAG can be found in the ESP32-S3 technical reference manual)

TD-er commented 1 year ago

TD-er, please correct me if I said some inaccuracies.

As far as I understand it:

When using USBCDC, the serial port will be enumerated as "TinyUSB CDC" And those are solely software serial ports via USB. Still working OK as that code has callback functions to handle copying data to/from some buffers. Not sure if it even needs/uses DTR/RTS for this communication.

When using hardware JTAG, you probably see flow control in action, which will limit the actual throughput making it feel slightly more sluggish?

Jason2866 commented 1 year ago

@igrr Tried your fork / PR of esptool.js with the updated stubs. It does not solve the issues. In my tests the S3 connected via an USB serial chip on board runs always in "timeout" error. Seems the same issue as when trying to flash an S2 via CDC which always errors with "timeout". Tbh i have no idea why. Looked through the code and did not find something looking "fishy". Updated the Adafruit Web Flasher (supporting C6) and the reset sequence to get CDC devices in boot flash mode. This version is always working for flashing all esp variants?! Maybe you find the difference reason for this. My forked Adafruit version is here https://github.com/Jason2866/WebSerial_ESPTool

Jason2866 commented 1 year ago

@sblantipodi @igrr For supporting devices which are using Tinyusb mode (firmware) there is an "touch mode" query (special sequence) with 1200baud necessary. The device will switch and opens a new serial port. Connect to this port and flashing is possible (as with every other device). So yes, it is possible. It "just" needs to be implemented.

sblantipodi commented 1 year ago

thank you all for the answers and for the clarifications.

after some research I found that Espressif explains it well here: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/usb-serial-jtag-console.html

they say: For data sent in the direction of ESP32-S3 to PC Terminal (e.g. stdout, logs), the ESP32-S3 first writes to a small internal buffer. If this buffer becomes full (for example, if no PC Terminal is connected), the ESP32-S3 will do a one-time wait of 50ms hoping for the PC Terminal to request the data. This can appear as a very brief ‘pause’ in your application.

this is probably why I found TinyUSB much more responsive than the JTAG CDC method.

with TinyUSB I can drive 500 LEDs at 60FPS without flickering, with JTAG CDC I can drive the same amount of LEDs at a very reduced framerate with a lot of flickering.

@Jason2866 yes I know it, I can upload my tinyusb firmware using PlatformIO with this options:

board_upload.use_1200bps_touch = yes
board_upload.wait_for_upload_port = yes
board_upload.require_upload_port = yes

thanks for pointing it out and for the great job on your web tools...