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?