So I have updated to the current ESP-IDF 5.4 and started using Visual Studio Code. I have run the ULP ADC examples for both FSM and RISCV, also modifying each one with the previously discussed statements to disable the ADC from ULP. The result: In all cases the consumption is still around 50 µA (# 272023). It just seems to be like that.
That means that this chip is not suitable for ULP applications that need the ADC, which really limits its use. That is very disappointing.
The power consumption of 8 µA in the datatheet for "RTC memory and RTC peripherals are powered up" is at least misleading. And the large fluctuation of current consumtion with the ADC on between different batches (see my first post) does not cast a good light on process control, introducing a lot of risk into product development using this chip.
I want a statement by Espressif on this situation.
ESP32-S3 ULP power consumption
Re: ESP32-S3 ULP power consumption
Can you share your code and hardware schematic?
I want to rule out ULP duty cycle (in a previous post you had "WAIT 100000..." which will increase the ULP runtime and hence average power draw) and any external factors (eg. external pullup on the same pin where a RTC pulldown is being enabled).
I want to rule out ULP duty cycle (in a previous post you had "WAIT 100000..." which will increase the ULP runtime and hence average power draw) and any external factors (eg. external pullup on the same pin where a RTC pulldown is being enabled).
Re: ESP32-S3 ULP power consumption
Sure, this is the code for RISCV.
Main Processor:
ULP:
This is the code for FSM.
Main Processor:
ULP:
This is the schematic of the board I'm using: https://www.wemos.cc/en/latest/_static/ ... v1.0.0.pdf
I have removed the RGB-LED and I'm powering the 3.3 V directly, bypassing the regulator.
Since the current drops to about 9 µA when just the single line is commented where the ADC is enabled, I am fairly certain that the problem is not on the board. The differences between the chips are coming definitely from the chips themselves. I know that because I swapped chips between two boards (one at ~20 µA, one at ~50 µA) and the consumption stayed with the chip.
Main Processor:
Code: Select all
#include <stdio.h>
#include <inttypes.h>
#include "esp_sleep.h"
#include "ulp_riscv.h"
#include "ulp_adc.h"
#include "ulp_main.h"
#include "ulp/example_config.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
static void init_ulp_program(void);
void app_main(void)
{
vTaskDelay(pdMS_TO_TICKS(1000));
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
/* not a wakeup from ULP, load the firmware */
if ((cause != ESP_SLEEP_WAKEUP_ULP) && (cause != ESP_SLEEP_WAKEUP_TIMER)) {
printf("Not a ULP-RISC-V wakeup (cause = %d), initializing it! \n", cause);
init_ulp_program();
}
/* RTC peripheral power domain needs to be kept on to keep SAR ADC related configs during sleep */
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup());
esp_deep_sleep_start();
}
static void init_ulp_program(void)
{
ulp_adc_cfg_t cfg = {
.adc_n = EXAMPLE_ADC_UNIT,
.channel = EXAMPLE_ADC_CHANNEL,
.width = EXAMPLE_ADC_WIDTH,
.atten = EXAMPLE_ADC_ATTEN,
.ulp_mode = ADC_ULP_MODE_RISCV,
};
// Commenting out this line will drop the current consumption to ~9 µA
ESP_ERROR_CHECK(ulp_adc_init(&cfg));
esp_err_t err = ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
ESP_ERROR_CHECK(err);
/* The first argument is the period index, which is not used by the ULP-RISC-V timer
* The second argument is the period in microseconds, which gives a wakeup time period of: 2 s
*/
ulp_set_wakeup_period(0, 2000000);
/* Start the program */
err = ulp_riscv_run();
ESP_ERROR_CHECK(err);
}
Code: Select all
#include <stdint.h>
#include "ulp_riscv_utils.h"
#include "ulp_riscv_adc_ulp_core.h"
int main (void)
{
SENS.sar_peri_clk_gate_conf.saradc_clk_en = 0;
SENS.sar_power_xpd_sar.force_xpd_sar = 0x2;
return 0;
}
Main Processor:
Code: Select all
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "esp_sleep.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "ulp.h"
#include "ulp_main.h"
#include "esp_adc/adc_oneshot.h"
#include "ulp/example_config.h"
#include "ulp_adc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
/* This function is called once after power-on reset, to load ULP program into
* RTC memory and configure the ADC.
*/
static void init_ulp_program(void);
/* This function is called every time before going into deep sleep.
* It starts the ULP program and resets measurement counter.
*/
static void start_ulp_program(void);
void app_main(void)
{
/* If user is using USB-serial-jtag then idf monitor needs some time to
* re-connect to the USB port. We wait 1 sec here to allow for it to make the reconnection
* before we print anything. Otherwise the chip will go back to sleep again before the user
* has time to monitor any output.
*/
vTaskDelay(pdMS_TO_TICKS(1000));
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
if (cause != ESP_SLEEP_WAKEUP_ULP) {
printf("Not ULP wakeup\n");
init_ulp_program();
}
printf("Entering deep sleep\n\n");
start_ulp_program();
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
#if !CONFIG_IDF_TARGET_ESP32
/* RTC peripheral power domain needs to be kept on to keep SAR ADC related configs during sleep */
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
#endif
esp_deep_sleep_start();
}
static void init_ulp_program(void)
{
esp_err_t err = ulp_load_binary(0, ulp_main_bin_start,
(ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
ESP_ERROR_CHECK(err);
ulp_adc_cfg_t cfg = {
.adc_n = EXAMPLE_ADC_UNIT,
.channel = EXAMPLE_ADC_CHANNEL,
.width = EXAMPLE_ADC_WIDTH,
.atten = EXAMPLE_ADC_ATTEN,
.ulp_mode = ADC_ULP_MODE_FSM,
};
// Commenting out this line will drop the current consumption to ~9 µA
ESP_ERROR_CHECK(ulp_adc_init(&cfg));
/* Set ULP wake up period to 2 s */
ulp_set_wakeup_period(0, 2000000);
#if CONFIG_IDF_TARGET_ESP32
/* Disconnect GPIO12 and GPIO15 to remove current drain through
* pullup/pulldown resistors on modules which have these (e.g. ESP32-WROVER)
* GPIO12 may be pulled high to select flash voltage.
*/
rtc_gpio_isolate(GPIO_NUM_12);
rtc_gpio_isolate(GPIO_NUM_15);
#endif // CONFIG_IDF_TARGET_ESP32
esp_deep_sleep_disable_rom_logging(); // suppress boot messages
}
static void start_ulp_program(void)
{
/* Start the program */
esp_err_t err = ulp_run(&ulp_entry - RTC_SLOW_MEM);
ESP_ERROR_CHECK(err);
}
ULP:
Code: Select all
#include "soc/rtc_cntl_reg.h"
#include "soc/soc_ulp.h"
#include "soc/sens_reg.h"
#include "soc/rtc_io_reg.h"
/* Code goes into .text section */
.text
.global entry
entry:
// Disable the SAR ADC
WRITE_RTC_REG(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_SARADC_CLK_EN_S, 1, 0)
WRITE_RTC_REG(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN_S, 1, 0)
WRITE_RTC_REG(SENS_SAR_POWER_XPD_SAR_REG, SENS_SARCLK_EN_S, 1, 0)
WRITE_RTC_REG(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR_S, 2, 2)
WAIT 100000
jump wake_up
exit:
halt
.global wake_up
wake_up:
/* Check if the system can be woken up */
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP)
and r0, r0, 1
jump exit, eq
/* Wake up the SoC, end program */
wake
WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
halt
I have removed the RGB-LED and I'm powering the 3.3 V directly, bypassing the regulator.
Since the current drops to about 9 µA when just the single line is commented where the ADC is enabled, I am fairly certain that the problem is not on the board. The differences between the chips are coming definitely from the chips themselves. I know that because I swapped chips between two boards (one at ~20 µA, one at ~50 µA) and the consumption stayed with the chip.
Re: ESP32-S3 ULP power consumption
Any news on this?
Re: ESP32-S3 ULP power consumption
It stands to reason that if you undo all changes made as a result of the ADC initialisation then the sleep current will be as if it had never been initialised at all.
The registers you're altering look about right at first glance, but I'm not sure this code is helping with troubleshooting. There are all kinds of race conditions going on in there, and the two are doing different things.
If you still aren't seeing ~10uA then post your updated code and ESP-IDF version, and I'll have a look.
The registers you're altering look about right at first glance, but I'm not sure this code is helping with troubleshooting. There are all kinds of race conditions going on in there, and the two are doing different things.
If you still aren't seeing ~10uA then post your updated code and ESP-IDF version, and I'll have a look.
Re: ESP32-S3 ULP power consumption
Thank you, I appreciate any feedback. I'm not sure I quite understand. Could you be more specific about what you mean, what race conditions you see and what I should change in the example code? Should we maybe move forward with just one of the ULPs? FSM always had lower currents than RISCV, so I think that's the way to go.
Who is online
Users browsing this forum: Google Adsense [Bot] and 131 guests