I confirm the problem with light sleep for ESP32-S2 for very similar example. It looks like watchdog of timer group 1 has very short timeout, like 600 for first stage (interrupt) and 1200 for second (system reset). I tried to reset stage 0 timeout to default 26,000,000 but what suprized me, that after leaving light sleep these timeouts appear reset to named values. I use low level program (direct manipulation with registers, so this behaviour really stalls me. What is the reason? RTOS? Or ROM firmware?
Similar deep sleep example works just fine.
Log of failure (ULP timer=250) follows
Code: Select all
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x4
load:0x3ffe6104,len:0x1308
load:0x4004c000,len:0x1580
load:0x40050000,len:0x1fe8
entry 0x4004c2e0
MCU reset 0x01
Edge count: 0
Ready to sleep
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x8 (TG1WDT_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x400270d8
0x400270d8: _xt_panic at C:/Users/nvaranki/esp/esp-idf/components/esp_system/port/panic_handler_asm.S:28
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x4
load:0x3ffe6104,len:0x1308
load:0x4004c000,len:0x1580
load:0x40050000,len:0x1fe8
entry 0x4004c2e0
W (48) boot.esp32s2: PRO CPU has been reset by WDT.
W (48) boot.esp32s2: WDT reset info: PRO CPU PC=0x4004c613
ULP FSM wakeup on system reset
Edge count: 512 Wake count: 1
Cancelling FSM program...
Abnormal exit Xtensa program
Done
Log of lucky test (ULP timer=50) follows; disregard UART ruptures. That is what expected for timeout=250 too, but with more delay in between wake-ups.
Code: Select all
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x4
load:0x3ffe6104,len:0x1308
load:0x4004c000,len:0x1580
load:0x40050000,len:0x1fe8
entry 0x4004c2e0
MCU reset 0x01
Edge count: 0
Ready to sleep
Unexpected wakeup cause 00000000
Edge count: 257 Wake count: 1
Ready to sleep
�H��A�FSM wakeup from sleep
Edge count: 513 Wake count: 2
Ready to sleep
H��A�FSM wakeup from sleep
Edge count: 769 Wake count: 3
Ready to sleep
�H��A�FSM wakeup from sleep
Edge count: 1025 Wake count: 4
Ready to sleep
�H��A�FSM wakeup from sleep
Edge count: 1281 Wake count: 5
Ready to sleep
�H��A�FSM wakeup from sleep
Edge count: 1537 Wake count: 6
Cancelling FSM program...
Final exit Xtensa program
Done
Here's excerpt of C++ code. Note, this is not a native ESP API in use.
Code: Select all
extern "C"
void app_main( void )
{
MicroControllerUnit* const mcu = new MicroControllerUnit();
PowerManagementUnit* const pmu = mcu->getPowerManagementUnit();
SleepAndWakeupController* const swc = pmu->getSleepAndWakeupController();
CoprocessorULP* const ulp = mcu->getCoprocessorULP();
CoreFSM* const fsm = ulp->getCoreFSM();
TimerULP* const tmr = ulp->getTimerULP();
CoreLX7* cpu = mcu->getProcessor( 0 );
uint32_t cause = 0;
if( swc->wakeup.isCause( SleepAndWakeupController::Peripherals::FSM ) )
{
printf( "\nULP FSM wakeup on system reset\n" );
printf( "Edge count: %10d Wake count: %3d\n", ulp_edge_count, ulp_wake_count );
//if( ulp_wake_count >= 6 )
{
// Done. Stop both programs
printf("Cancelling FSM program...\n");
tmr->active->set( false );
fsm->clockOn->set( false );
printf("Abnormal exit Xtensa program\n");
return;
}
}
else if( ( cause = swc->wakeup.cause->getAll() ) == 0 )
{
printf( "\nMCU reset 0x%02x\n", (uint32_t) cpu->getResetCause() );
// cancel next timer run if any
tmr->active->off();
// load code
BinaryImageULP image( ulp_main_bin_start, ulp_main_bin_end - ulp_main_bin_start );
esp_err_t e = image.loadAt( RTC_SLOW_MEM );
if( e != ESP_OK ) ...
ulp->entry->set( &ulp_entry - RTC_SLOW_MEM );
// init shared vars, not earlier than the program has been loaded
ulp_edge_count = 0;
ulp_wake_count = 0;
printf( "Edge count: %10d\n", ulp_edge_count );
// select FSM to run
fsm->selectForExec();
fsm->selectForDone();
fsm->startOn->off(); // block software start of ULP
fsm->clockOn->on();
fsm->clockOff->off();
// allow auto PD for clocks only, see Table 195: Predefined Power Modes
pmu->ctrl.wifi.sleepDn->off();
pmu->ctrl.digital.sleepDn->off();
//TODO how clocks OFF?
pmu->ctrl.slowMemory.sleepDn->off();
pmu->ctrl.fastMemory.sleepDn->off();
pmu->ctrl.peripherals.sleepDn->off();
// ensure power ON for RTC slow memory where FSM program resides
pmu->ctrl.slowMemory.power->on->on();
pmu->ctrl.slowMemory.power->off->off();
pmu->ctrl.slowMemory.isolation->off->on();
// allow Xtensa wakeup by FSM
swc->wakeup.enable->setAll( false );
swc->wakeup.setEnabled( SleepAndWakeupController::Peripherals::FSM, true );
// start ULP timer
tmr->sleep->set( 50 ); // 75+: rst:0x8 (TG1WDT_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
tmr->active->on();
}
else
{
printf( "\nUnexpected wakeup cause %08x\n", cause );
}
while( ulp_wake_count < 6 )
{
// Get ready to sleep
printf( "Ready to sleep\n\n" );
fflush(stdout);
suspend_uart(CONFIG_ESP_CONSOLE_UART_NUM);
vTaskDelay( 20 );
// enter light sleep
swc->sleep.start->off(); //
swc->sleep.start->on(); // returns after wakeup from there
// wait here until wakeup
resume_uart(CONFIG_ESP_CONSOLE_UART_NUM);
// while (GET_PERI_REG_MASK(RTC_CNTL_INT_RAW_REG,
// RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) == 0) {
// ;
// }
if( swc->wakeup.isCause( SleepAndWakeupController::Peripherals::FSM ) )
{
printf( "\nULP FSM wakeup from sleep\n" );
printf( "Edge count: %10d Wake count: %3d\n", ulp_edge_count, ulp_wake_count );
}
else
{
printf( "\nUnexpected wakeup cause %08x\n", cause );
printf( "Edge count: %10d Wake count: %3d\n", ulp_edge_count, ulp_wake_count );
}
}
// Done. Stop both programs
printf("Cancelling FSM program...\n");
tmr->active->off();
fsm->clockOn->off();
printf("Final exit Xtensa program\n");
}
ESP-IDF code base: version 4.2