ESP32 enhancement: support automatic light-sleep / dynamic freq scaling
On the esp32 automatic light sleep / dynamic frequency scaling / power management puts the CPU to sleep when all tasks are idle thereby reducing the power consumption to about 1mA instead of around 40mA @ 160Mhz. The special feature of auto light sleep is that it can maintain a Wifi association by waking up at the appropriate times to receive AP beacons and respond to them. This ticket proposes to discuss how to enable auto light-sleep.
The first issue is that FREERTOS_USE_TICKLESS_IDLE needs to be enabled in sdkconfig.h and that machine.freq() must set pm.light_sleep_enable = true.
The next issue is that mp_hal_stdin_rx_chr and mp_hal_delay_ms in mphalport.h do not call vTaskDelay and instead call ulTaskNotifyTake which does not seem to enable auto light sleep (need to dig into this). Specifically, in the idle loop without wifi enabled ulTaskNotifyTake almost always returns after 100ms, which seems to be too little for light sleep to kick in.
The use of vTaskDelay got switched to ulTaskNotifyTake as part of https://github.com/micropython/micropython/commit/14ab81e87accedfb9ed231b206dd21f3a0143404 because it affects interrupt latency too much, see #3894.
Adding a call to vTaskDelay(4) in there for test purposes results in the expected power savings (a value of 4 is the minimum for light sleep to kick in). However, it messes up gpio: they all(?) go low, which is unexpected (I expected ESP-IDF to handle this appropriately). The gpio issue also affects the uart: the console no longer works unless one manages to get a char in while mp is polling. Mysteries...
Update: I had not understood the second parameter of ulTaskNotifyTake: setting that to 4 also causes light sleep to kick in.
ESP32: support dynamic freq scaling and wifi power save
This PR allows the power consumption of the esp32 to be tweaked. It enables:
- using dynamic frequency scaling allowing FreeRTOS to reduce the clock frequency when the processor is idle
- using listen interval on the WiFi STA interface to reduce the amount of time the radio is powered on
- using listen interval to keep the radio on permanently to reduce network latency
The punchline is that one can halve the power consumption for more battery life or double it for lower network latency.
These features are documented, see the PR files. I have not been able to preview the docs, however, so I assume there are issues. I need to figure out how to do that...
One caveat I'm just realizing is that I haven't tested with ESP-IDF v3....