adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.07k stars 1.2k forks source link

microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER) not working on S3 TFT #6765

Open dglaude opened 2 years ago

dglaude commented 2 years ago

CircuitPython version

Adafruit CircuitPython 8.0.0-alpha.1-139-g3fbddfde5 on 2022-08-15; Adafruit Feather ESP32-S3 TFT with ESP32S3

Code/REPL

>>> import microcontroller
>>> microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
>>> microcontroller.reset()

Behavior

The board reset due to the microcontroller.reset() but does not go into UF2 mode.

Description

Expectation is for the board to go in UF2 mode where you can drag and drop a new firmware. But this is not happening, it just seems to be "not implemented". It is however possible to go in UF2 mode by double clicking the reset button.

Additional information

I also tested with an ESP32-S3-USB-OTG_SUB v2.0 and it also fail... But that board is not Adafruit, and does not seems to go to UF2 mode when double clicking the reset button. My feeling is that all the ESP32-S3 are affected (maybe more) but I prefer to open this issue for an Adafruit board.

jepler commented 2 years ago

Please note that on esp32-s2 and esp32-s3, RunMode.BOOTLOADER should enter the kind of bootloader that works with esptool and arduino, while RunMode.UF2 is for accessing the UF2 bootloader. On many other boards that have just a single bootloader, the two behave identically.

I only have an ESP32-S3-EYE on hand so I tested with it. For me, RunMode.UF2 worked. RunMode.BOOTLOADER seems to just crash the device until it's re-plugged or the reset button is pressed.

dglaude commented 2 years ago

So it is not a bug... it just that I am used to RunMode.BOOTLOADER on other board and did not notice the difference.

With RunMode.UF2 it works perfectly on my Feather S3+TFT. => Problem solved, we can close this ticket.

Very long in the weed side note...

It still fail on my ESP32-S3-USB-OTG-N8 but I am not even sure that board accept UF2 or how to get it into that mode "manually" by double clicking. All my upgrade on that board have been done with esptool (AFAIR).

If I compare a few S3 board Adafruit board:

  1. https://circuitpython.org/board/adafruit_feather_esp32s3_tft/
  2. https://circuitpython.org/board/unexpectedmaker_feathers3/
  3. https://circuitpython.org/board/espressif_esp32s3_devkitm_1_n8/
  4. https://circuitpython.org/board/espressif_esp32s3_usb_otg_n8/

The 3 first one have an UF2 boot loader available from circuitpython.org (but those are also board one could acquire from adafruit shop) where the last one has no UF2 boot loader.

It could either be something missing on circuitpython.org, or I guess that mean that TinyUSB is not supported on the esp32s3_usb_otg_n8 but it is on the 3 other board (one from Adafuit, one from Unexpected Maker and one by Espressif themself).

The bizarre thing is that on the four pages, you can download both the .bin and the .uf2. Maybe this is to be ready when UF2 will be supported on it.

I hesitate to try to install the UF2 bootloader from another S3 board on my USB-OTG board... I am not sure if there is a lot that is hardware specific, but I don't want to brick it either (not sure it is possible to brick it).

jepler commented 2 years ago

If you need UF2 support on a non-Adafruit board (including ones that happen to be sold through the adafruit store), contact the original hardware maker and let them know your needs. Contributing a bootloader to tinyuf2 would be fine too.

tannewt commented 2 years ago

It still fail on my ESP32-S3-USB-OTG-N8 but I am not even sure that board accept UF2 or how to get it into that mode "manually" by double clicking. All my upgrade on that board have been done with esptool (AFAIR).

Double clicking reset requires the board to have a capacitor to hold one bit of state because reset actually wipes all mcu memory. The espressif boards probably don't have it. Instead, clicking reset and then boot is usually done to avoid actually resetting the device.

It could either be something missing on circuitpython.org, or I guess that mean that TinyUSB is not supported on the esp32s3_usb_otg_n8 but it is on the 3 other board (one from Adafuit, one from Unexpected Maker and one by Espressif themself).

TinyUF2 could be added for the usb_otg I think. Just no one has added it.

The bizarre thing is that on the four pages, you can download both the .bin and the .uf2. Maybe this is to be ready when UF2 will be supported on it.

This is just an oversight. Don't read too much into it.

I hesitate to try to install the UF2 bootloader from another S3 board on my USB-OTG board... I am not sure if there is a lot that is hardware specific, but I don't want to brick it either (not sure it is possible to brick it).

ESP boards can't really be bricked because they have a ROM bootloader. I think the only way would be to burn some fuses. UF2 won't do that though.

You could try another TinyUF2 build with the same amount of ram and flash.

DJDevon3 commented 1 year ago

Worth noting that I tried this NOT in REPL but in my script. Took about 2 hours to get out of it. You'd think that using python esptool to erase_flash would defeat it but it didn't. Only way out was to quickly load the QT Py S3 Factory Reset (even though I'm on a UM FeatherS3 because it's just too big to go through fast enough). Surprisingly the UM FeatherS3 is happy to live as a QT Py S3. Once the QT Py boot showed up I was able to reflash everything back as the UM FeatherS3 using a full install with CircuitPython.org online installer (worked great).

import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()

This was a horrible decision I immediately regretted. Inifinite bootloop haha! Oops. Don't do this.

import microcontroller
>>> microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
>>> microcontroller.reset()

REPL run once better idea, duh. :)