espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.66k stars 7.41k forks source link

Brownout Support #10537

Open Kyklas opened 2 weeks ago

Kyklas commented 2 weeks ago

Board

XIAO ESP32C6

Device Description

Using a XIAO ESP32C6 with a battery. Using the brownout to generate a application interrupt to notify of low battery. Application will reduce consumption until user connect external power.

Hardware Configuration

XIAO ESP32C6 + LED and Battery Super Cap for testing.

Version

v3.0.5

IDE Name

vscode-arduino Community Edition

Operating System

Windows 10 x64

Flash frequency

80Mhz / 40MHz

PSRAM enabled

no

Upload speed

921600

Description

The brownout can be configured. I see the restart being triggered at different voltage level. However the interrupt for the brownout can't be registered.

esp_intr_alloc error 261 (ESP_ERR_NOT_FOUND)

Brownout support may be present for Arduino in future release ( Based on IDF v5.3.1+ ).

Testing with IDF only on V5.1.4 reports the following error

W (295) rtc_module: rtc_isr_deregister() has not been implemented yet
E (305) APP: APP_brownout_isr_handler alloc FAILED 261

Testing with IDF only on V5.3.1 reports interrupt configuration success

W (284) rtc_module: rtc_isr_deregister() has not been implemented yet
I (294) APP: APP_brownout_isr_handler alloc = 0

Sketch

#include "esp_private/rtc_ctrl.h"
#include "esp_intr_alloc.h"
#include "hal/brownout_hal.h"
#include "hal/brownout_ll.h"
#include <soc/periph_defs.h>

// #include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32C6
#elif CONFIG_IDF_TARGET_ESP32C3
#include <soc/rtc_cntl_reg.h>
#endif

#include <../../include/esp_system\port\include\private\esp_private\brownout.h>

IRAM_ATTR static void app_brownout_isr_handler(void *arg)
{
    /* Normally RTC ISR clears the interrupt flag after the application-supplied
     * handler returns. Since restart is called here, the flag needs to be
     * cleared manually.
     */
    brownout_ll_intr_clear();

    esp_rom_printf("App Brownout Triggered\r\n\r\n");

    brownout_ll_intr_enable(false);
    esp_brownout_disable();
}

void app_brownout_init(void)
{
    int ret;

    brownout_hal_config_t cfg = {
        .threshold = 3,
        .enabled = true,
        .reset_enabled = false,
        .flash_power_down = false,
        .rf_power_down = true,
    };

    brownout_hal_config(&cfg);
    brownout_ll_intr_clear();
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
    // TODO IDF-6606: LP_RTC_TIMER interrupt source is shared by lp_timer and brownout detector, but lp_timer interrupt
    // is not used now. An interrupt allocator is needed when lp_timer intr gets supported.
    ret = esp_intr_alloc(ETS_LP_RTC_TIMER_INTR_SOURCE, ESP_INTR_FLAG_IRAM, &app_brownout_isr_handler, NULL, NULL);

#else
    ret = rtc_isr_register(app_brownout_isr_handler, 0, RTC_CNTL_BROWN_OUT_INT_ENA_M, RTC_INTR_FLAG_IRAM);
#endif

    if (ret != ESP_OK)
    {
        esp_rom_printf("esp_intr_alloc error %d\n",ret);
    }

    brownout_ll_intr_enable(true);

}

#if CONFIG_IDF_TARGET_ESP32C6
#define PIN_GPIO 22
#elif CONFIG_IDF_TARGET_ESP32C3
#define PIN_GPIO 6
#endif

void setup() {

//  Serial.setTxBufferSize(2048);
    Serial.begin(115200);

    Serial.printf("ESP32 Brownout\n");

    esp_brownout_init();
    esp_brownout_disable();
    app_brownout_init();

    pinMode( PIN_GPIO, OUTPUT);

    digitalWrite(PIN_GPIO,0);

    esp_rom_printf("esp_rom_printf ? \r\n\r\n");

}

uint32_t loop_count = 0;

void loop() {

    Serial.printf("Loop %d\n",loop_count++);
    digitalWrite(PIN_GPIO,loop_count & 0x1);
    delay(500);
}

Debug Message

=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32-C6
  Package           : 1
  Revision          : 0.01
  Cores             : 1
  CPU Frequency     : 160 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000052
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : No
  BT Low Energy     : Yes
  IEEE 802.15.4     : Yes
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   482092 B ( 470.8 KB)
  Free Bytes        :   451080 B ( 440.5 KB)
  Allocated Bytes   :    24780 B (  24.2 KB)
  Minimum Free Bytes:   451036 B ( 440.5 KB)
  Largest Free Block:   434164 B ( 424.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  4194304 B (4 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 40 MHz
  Bus Mode          : QIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  1280.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00150000, size:  1280.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00290000, size:  1408.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Oct 28 2024 22:12:19
  Compile Host OS   : windows
  ESP-IDF Version   : v5.1.4-828-g33fbade6b8-dirty
  Arduino Version   : 3.0.5
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : XIAO_ESP32C6
  Arduino Variant   : XIAO_ESP32C6
  Arduino FQBN      : esp32:esp32:XIAO_ESP32C6:JTAGAdapter=default,CDCOnBoot=default,PartitionScheme=default,CPUFreq=160,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,DebugLevel=verbose,EraseFlash=none,ZigbeeMode=default
============ Before Setup End ============
[   557][V][esp32-hal-uart.c:408] uartBegin(): UART0 baud(115200) Mode(800001c) rxPin(17) txPin(16)
[   566][V][esp32-hal-uart.c:497] uartBegin(): UART0 not installed. Starting installation
[   574][V][esp32-hal-uart.c:560] uartBegin(): UART0 initialization done.
ESP32 Brownout
esp_intr_alloc error 261
[   581][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type GPIO (1) successfully set to 0x42000eda
[   596][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 22 successfully set to type GPIO (1) with bus 0x17
esp_rom_printf ?

=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   482092 B ( 470.8 KB)
  Free Bytes        :   454264 B ( 443.6 KB)
  Allocated Bytes   :    21388 B (  20.9 KB)
  Minimum Free Bytes:   450564 B ( 440.0 KB)
  Largest Free Block:   434164 B ( 424.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------
     3 : GPIO
    14 : GPIO
    16 : UART_TX[0]
    17 : UART_RX[0]
    22 : GPIO
============ After Setup End =============
Loop 0
Loop 1
Loop 2
Loop 3
Loop 4
Loop 5
Loop 6
Loop 7
Loop 8
Loop 9
Loop 10
Loop 11
Loop 12
Loop 13
Loop 14
Loop 15
Loop 16
Loop 17
Loop 18
Loop 19
Loop 20
Loop 21
Loop 22
Loop 23
Loop 24
Loop 25
Loop 26
Loop 27
Loop 28
Loop 29
Loop 30
Loop 31
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022

Other Steps to Reproduce

I have tested the same sketch with XIAO ESP32C3. The application interrupt is called.

I have checked existing issues, online documentation and the Troubleshooting Guide

VojtechBartoska commented 1 week ago

Hello @Kyklas, what exactly do you need to be added on Arduino side? I probably not get it fully from your issue report. Thanks a lot for clarification.