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

Safe Mode on esp32s2 #3389

Closed
microdev1 opened this issue Sep 10, 2020 · 3 comments · Fixed by #3808
Closed

Safe Mode on esp32s2 #3389

microdev1 opened this issue Sep 10, 2020 · 3 comments · Fixed by #3808
Labels
enhancement espressif applies to multiple Espressif chips

Comments

@microdev1
Copy link
Collaborator

microdev1 commented Sep 10, 2020

This is a follow-up to 9-9-20 (CPY Day) esp32s2 Deep Dive in which esp32s2 manual safe mode support was briefly discussed.

The esp32s2 posses a challenge for manual safe mode implementation as it lacks a dedicated reset pin instead the reset button is connected to CHIP_PU which when pulled low turns off the power to the chip thus causing a hard reset.

A solution to this problem as discussed during the deep dive is to use IO0 (boot button) and check its state during CPY startup in order to trigger a soft reboot keeping the ram alive.

I was able to boot into safe mode by pressing the boot button momentarily during 700ms loop which is indicated by a steady yellow color of the rgb led on startup.

As of now I am just returning MANUAL_SAFE_MODE instead of NO_SAFE_MODE in order to enter safe mode and haven't really figured how this will work alongside other CPY ports and how it will soft reboot with status stored in ram.

Code snippet from safe_mode.c .
Tested on microS2.

digitalio_digitalinout_obj_t boot_button;
common_hal_digitalio_digitalinout_construct(&boot_button, MICROPY_HW_BUTTON);  //#define MICROPY_HW_BUTTON (&pin_GPIO0) 
common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP);

uint64_t start_ticks = supervisor_ticks_ms64();
uint64_t diff = 0;

while (diff < 700) {
       #ifdef MICROPY_HW_LED_STATUS
       // Blink on for 100, off for 100, on for 100, off for 100 and on for 200
       common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4);
       #endif
        
       if (!common_hal_digitalio_digitalinout_get_value(&boot_button)) {
           return MANUAL_SAFE_MODE;
       }

       diff = supervisor_ticks_ms64() - start_ticks;
}  
@tannewt
Copy link
Member

tannewt commented Sep 10, 2020

Awesome! Thank you!

I think the easiest thing is to add a board define CIRCUITPY_BOOT_BUTTON that can be used to include the code you've added.

Want to make a PR? Thanks!

@dhalbert dhalbert added this to the 6.x.0 - Features milestone Sep 11, 2020
@microdev1 microdev1 changed the title Manual Safe Mode on esp32s2 Safe Mode on esp32s2 Sep 14, 2020
@microdev1
Copy link
Collaborator Author

@tannewt I'll leave this issue open until soft_reboot approach is also implemented.

@tannewt tannewt added enhancement espressif applies to multiple Espressif chips labels Sep 14, 2020
@tannewt
Copy link
Member

tannewt commented Sep 14, 2020

So we need to:

  • Figure out how to reset from software and save 4-bytes across the reset.
  • Detect brown outs and safe mode when it happens.
  • Intercept fatal error from the IDF and safe mode.

tannewt added a commit that referenced this issue Dec 9, 2020
Uses the IDF's reset reason. Does nothing before reset.

Fixes #3389
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement espressif applies to multiple Espressif chips
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants