ESP32-S3 Brownout Detector Bug (Issue 17718)
Overview
I recently found a bug in the ESP32-S3 brownout detector. It is officially logged as Issue 17718.
If you have enabled ESP_BROWNOUT_DET=y in your sdkconfig along with a corresponding brownout voltage level, the chip will automatically reset if the supply voltage dips below that value.
The brownout voltages you can select via menuconfig are approximations, not guarantees. You should empirically test the setting and understand that it may vary slighly from chip to chip.
When this happens, you would expect to see a reboot reason code of 0x0F but, instead, you will see a reason code of 0x3 in the serial logs. The good news is that esp_reset_reason already handles this issue properly and still gives you the correct code so your application logic should be unaffected.
Technical Details
According to the S3 Technical Reference Manual(TRM), Table 7.1-1, reset code 0x3 is a Core Reset. A brownout reset, code 0x0F is either a Chip Reset or System Reset according to the TRM.
Table 7.1-1 in the S3 Technical Reference Manual
This is a very important distinction because of how the TRM describes, in section 7.1.2, what the different resets do.
Figure 7.1-1 in the S3 Technical Reference Manual
Notice that a Core Reset does NOT reset the RTC memory but both a Chip and System Reset do. That means, according to the manual, when you get a reset code of 0x3 (Core Reset) you should be able to assume the RTC memory is still valid.
This is NOT the behavior the S3 exhibits in this scenario. If the chip browns out after having enabled the brownout detector in menuconfig, it will reset with reason code 0x3 but the RTC memory will, in fact, be reset.
Workaround
At the time of this writing, the bug is still under consideration from the IDF team and they have explained the cause as an issue with certain XMC flash chips that may or may not be used on ESP32 modules. To properly handle quirks in this specific flash chip, they handle the brownout in software instead of in hardware.
The good news here is that the reset hint reason is correct in this scenario so esp_reset_reason handles this and returns the correct reason to your application code. The main issue you will run into is if you have log parsing set up for device under test (DUT) scenarios or other general logging where you are trying to determine a cause of reset.
In these scenarios you should ignore the ROM reset reason listed at the top of the serial output and, instead, log the reason code directly returned from esp_reset_reason and use that instead.
