ESP32-S3 RISC-V ULP termination
Posted: Wed Nov 06, 2024 4:02 pm
Hi,
New to ULP program, currently some doubt not so clear:
I'm implementing the ulp firmware as a state machine. For each state, it will decide how long the ULP CPU will sleep and execute the next state, some skeleton code as this:
So basically the ULP will execute init, sleep 100000 cycles, execute task1, sleep 200000 cycles, execute task2, then wake up the main processor. The main processor will later re-run ULP to have this loop happen again.
Question is:
1. If I don't wake up the main processor at TASK2 but only call ulp_riscv_timer_stop(), by my understanding the ULP should sleep forever. But in fact the whole ESP32S3 still consumes around 80uA current instead of the deep sleep period only consumes 10uA. (measured from DevKitC, with R24 removed and externally supply 3V3 using PPK2)
2. Looking at idf/components/ulp/ulp_riscv/ulp_core/start.S, ulp_riscv_halt() is called after main() returns, and ulp_riscv_halt() internally calls ulp_riscv_timer_stop() (ulp_riscv.c). Why call ulp_riscv_timer_stop() twice will stop timer but call only once won't stop timer?
TIA
Baoshi
New to ULP program, currently some doubt not so clear:
I'm implementing the ulp firmware as a state machine. For each state, it will decide how long the ULP CPU will sleep and execute the next state, some skeleton code as this:
Code: Select all
int main(void) {
switch (s_state) {
case ULP_STATE_INIT:
// do init
s_state = ULP_STATE_TASK1;
REG_SET_FIELD(RTC_CNTL_ULP_CP_TIMER_1_REG, RTC_CNTL_ULP_CP_TIMER_SLP_CYCLE, ((uint32_t)100000));
break;
case ULP_STATE_TASK1:
// do task1
s_state = ULP_STATE_TASK2;
REG_SET_FIELD(RTC_CNTL_ULP_CP_TIMER_1_REG, RTC_CNTL_ULP_CP_TIMER_SLP_CYCLE, ((uint32_t)200000));
break;
case ULP_STATE_TASK2:
// do task2
s_state = ULP_STATE_INIT;
ulp_riscv_wakeup_main_processor();
ulp_riscv_timer_stop();
break;
}
return 0;
}
Question is:
1. If I don't wake up the main processor at TASK2 but only call ulp_riscv_timer_stop(), by my understanding the ULP should sleep forever. But in fact the whole ESP32S3 still consumes around 80uA current instead of the deep sleep period only consumes 10uA. (measured from DevKitC, with R24 removed and externally supply 3V3 using PPK2)
2. Looking at idf/components/ulp/ulp_riscv/ulp_core/start.S, ulp_riscv_halt() is called after main() returns, and ulp_riscv_halt() internally calls ulp_riscv_timer_stop() (ulp_riscv.c). Why call ulp_riscv_timer_stop() twice will stop timer but call only once won't stop timer?
TIA
Baoshi