Is it possible to use ULP to wake up ESP-WROOM32? Contemplating alternatives

Viewed 90

I bought some boards that have modules labeled ESP-WROOM32. esptool reports the version as:

Chip is ESP32D0WDQ6 (revision (unknown 0xa))
Chip ID: 0xbc78e36d10fd

which seems old.

I wrote a few ULP test programs and everything works as expected except for the WAKE instruction, which doesn't seem to work at all. I have a feeling it might be an old hardware limitation, but I'm not sure.

Before calling machine.deepsleep(0) I made sure that the wake-up source was enabled:

mem32[ 0x3ff48038 ] = 0x200 << 10

that didn't help. I also tried enabling ULP wakeup from the ULP itself:

WRITE_RTC_REG(RTC_CNTL_WAKEUP_STATE_REG, 21, 11, 0x200);

which also didn't work. Searching around, it seems like this chip might be from before the ULP wakeup was stable. Based on that, I am thinking this module doesn't support wake on ULP, and I have to wire an output from the ULP back to the reset pin to get the main CPU to wake up. This will still let me use the ULP to do a more complicated wake-up. What I'm really looking for is to wake up on a GPIO pin transition, after a suitable software debounce time, or after a certain amount of time has elapsed. The use case is an input where I want to report a change of state immediately, but if there is no state change, I still want to wake up every once in a while to let the receiver know I'm still alive.

Wiring a pin back to reset doesn't seem too bad, but before I do it, does anyone have a better idea? For example, (in micropython) machine.deepsleep(1000) works, and by default uses timer 0. Would it work to just have the ULP program keep pushing that timer back until it wants the CPU to wake up?

1 Answers

I made this work. The main issue was on the micropython side - I was using v1.19.1 but the changes I needed were actually made in the last 5 days. Before this update I think that something would wipe out the ULP flag in RTC_CNTL_WAKEUP_STATE_REG after I set it. I wasn't able to figure out why; I traced the source code up to some ESP-IDF code with this comment:

// TODO: move timer wakeup configuration into a similar function
// once rtc_sleep is opensourced.

With the latest micropython nightly, though, you can just call:

esp32.wake_on_ulp(True)

and everything works as expected. Now, after a WAKE instruction in the ULP, I get a reset with the right flag set:

rst:0x5 (DEEPSLEEP_RESET)

This opens up a lot of interesting, very low power possibilities even within the micropython world.

I wasn't sure I was going to be able to figure this out, but the micropython team figured it out for me. Kudos to them.

Related