A quick article to post the relevant power profile of ESP32-C6.
ESP32-C6 is a embedded micro-controller with a dual RISC-V cores running up to 160MHz and 20MHz. It's main selling point is that it's complete, it can talk Wifi (802.11ax), Bluetooth (BLE) and Zigbee (802.15.4). It's a direct competitor to ESP32-S3 (which is using a Tensilica Xtensa core running up to 240MHz) which doesn't do 802.15.14 networking.
The software is mainly open source (available in esp-idf repository except for the low level network stack that's distributed as pre-compiled libraries.
The documentation for these processors is plentiful, although it is lacking in some domains that I consider as very important. So let's sort it out:
The following section are specific to ESP32-C6. Unlike ESP32-S3, the power profile for the C6 is very different, so I'm focusing on those only.
In ESP32-C6, there are 2 RISC-V cores that can execute your binary. The high power (HP) core and the low power (LP) core. They both can execute the same binary since they support the same instruction set, however they are many limitations for the LP core (limited static RAM memory, access to peripherals, and so on). So the software stack is built to blend with the other ESP32 core, thus the LP core is specialized to run size limited program while the HP core is sleeping (that's the main documented usage, but you can also run the LP core and the HP core at the same time).
The HP core typically run software for communication (WIFI/BT/ZB) and is a huge power hog (WIFI can drain up to 350mA of current, cf page 63 of the datasheet).
However, the LP core is typically used to run an embedded (and simple) logic when the HP core is put to sleep, in order to save power. The main idea being: wake up the HP core when you need to communicate (or if you don't care about power consumption), else sleep it and let the LP core perform the monitoring work.
The HP core has 4 working mode:
The consumption number are from the datasheet, not from measures I've made.
The software stack is made to make it easy for you to automatically go from 1 to 3 (it's a configuration to enable in the menuconfig), but going to deep sleep is not automatic, since when entering deep sleep, everything is lost, it'll be amnesic when it wakes up (actually, it resets for waking up).
The ESP32-C6 also have interesting hardware features here, like STM32: it has few "deep sleep" surviving memories:
Low-power Always-on Register (LP_AON)
described at page 467 of the TRM). The software stack make use of them to provide interesting features, such as storing the boot time, storing a small wake up handler that can be run by the HP core before its main
functionThe always on registers are declared in esp-idf as:
* RTC store registers usage
* LP_AON_STORE0_REG Reserved
* LP_AON_STORE1_REG RTC_SLOW_CLK calibration value
* LP_AON_STORE2_REG Boot time, low word
* LP_AON_STORE3_REG Boot time, high word
* LP_AON_STORE4_REG External XTAL frequency
* LP_AON_STORE5_REG FAST_RTC_MEMORY_LENGTH
* LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY
* LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC
* LP_AON_STORE8_REG Store light sleep wake stub addr
* LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep)
The register 5/6 and 7 are used to store a fingerprint of the RTC
memory. If the memory at @entry
, with length @length
match the @CRC
, then the @wake_stub_address
is considered valid and the ESP32-C6's HP core will boot directly from this address in RTC
memory. This happens before the bootloader even run, allowing the HP core to directly execute some limited code and decide to continue or prevent the normal boot process.
Although the LP core is able to access almost all peripherals (exception is for some obscure debug registers), the default software stack doesn't provide any reference code for this.
The expected usage is either:
The software stack thus focus on the point 3 and provide the minimum library interface to monitor a GPIO from the LP core (with limitations), to start a I2C transaction (with limitations) or to sleep the LP core for some timer's elapsing.
Please notice that it's possible to actually run the LP core while the HP core is running, and it's possible to trigger an ADC reading from the LP core although, this implies keeping the SAR ADC peripheral powered on (which, as we'll see, doesn't actually save any power). Similarly, the other peripherals can still be used by the LP core is kept powered on, but again, without a real advantage.
There's only 8 GPIO that are controlable by the LP core (GPIO0-7
) and since the ADC capable pins are also located on these GPIO (GPIO0-6
) and they can't be used in low power mode, this is a very short sighting from Espressif since it means that any ADC need limits the already sparse low power GPIO.
Let's get straight to the information you can't find in the TRM or the datasheet.
Average WIFI consumption is around ~60 mA, with large variation
Talking about current consumption for the ESP32-C6 chip is often useless, because you can't operate such a chip alone on your board. You need a 3.3V voltage source, you need some peripherals (well, if you don't, it means that you probably missed the interest of this chip). And so on.
In the end, you should measure the consumption at the power source which will often by much larger than the actual consumption of this chip alone.
For example, if you have an I2C device on your board, this means that you have some 1 to 10 kΩ pull up resistors on two pins. When the chip is entering sleep, you can either isolate the GPIO (in that case, you'll get, at least, 100 nA current drain on this pins. You can also force hold the pin to VCC (in that case, you'll have a current drain that's equal to (VCC - Vds) / 10 kΩ
in each resistor, with Vds
being the voltage drop in the high level transistor. In the datasheet, this Vds
can be as high as 0.2 * VCC
which gives a leaking current of 66 µA).
If you enable a internal pull up or pull down for a peripheral, then you have an additional consumption for it (~76 µA for a typical pull up).
If you have an boot button (very likely), you typically have a capacitor in parallel to charge it, then there's its ESR resistance leakage to add.
Said differently, you can take the actual connected GPIO (which is maximum 23 on ESP32-C6) and multiply by 50 nA to get an ideal minimum consumption current. This alone can increase the deep sleep consumption by 1.15 µA.
Also you need to account for electrical oscillation. An isolated pin is just a pin where each connection to a lower circuit is opened by a transistor (the drain is disconnected from the source, showing the high impedance of the transistor). This means that if the pin captures some electrical field, its potential can increase and overcome the transistor's series diode, it'll pass some current. The voltage will then drop below the diode threshold, that will stop the current until the transistor parasitic capacitor charges and the cycle restarts. So an isolated pin can actually consume more than a fixed output pin if left floating.
I've tried to play with isolating pins myself or holding them at the appropriate level so they cannot oscillate, and I was able to drop the deep sleep consumption by ~ 0.7 µA.
You need to add the power drop inside the voltage regulator (depends on your schematic), the power drop in each peripheral's chip (for example, the I2C devices, the motor controller and so on).
By default, the software stack tries to be smart and will first try to isolate (disabling pull up/down, input buffer, ...) all pins that are unused while sleeping. Yet, it doesn't know your circuit and some device must keep some known electrical state to keep operating, and as such, it's not always possible to isolate all pins.