Page 1 of 1

Problem with ADC on ULP RISC-V while deep-sleep

Posted: Sat Jun 21, 2025 1:06 pm
by gabika
Hi all,
I am trying to write a simple program for reading ADC1CH6 while in deep sleep using ULP RISC-V.
For some reason, the "adc read" function is hanging. Removing it, I can verify that everything works well (going to sleep, setting variable on ULP and waking the main CPU, accessing the variable from the main program).

This is the main CPU code:

Code: Select all

#include "config.h"
#include "esp_sleep.h"
#include "esp_timer.h"
#include <../include/driver/gpio.h>
#include "driver/rtc_io.h"
#include "esp_log.h"
#include "ulp_riscv.h"
#include "ulp_adc.h"
#include "esp_adc/adc_oneshot.h"
#include "ulp_main.h" // ULP program header (generated by esp-idf build system)

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");

int counter = 0;

ulp_adc_cfg_t adc_config = {
    .adc_n    = ADC_UNIT,
    .channel  = ADC_CHANNEL,
    .atten    = ADC_ATTEN_DB_12,
    .width    = ADC_BITWIDTH_12,
    .ulp_mode = ADC_ULP_MODE_RISCV,
};

void clear_ulp_adc_buffer() {
    ulp_adc_buffer = 0;
}

void init_ulp() {
    ESP_LOGI("MAIN", "First boot or other wakeup, initializing ULP");
    ESP_ERROR_CHECK(ulp_adc_init(&adc_config));

    ESP_ERROR_CHECK(ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start)));

    ESP_ERROR_CHECK(ulp_set_wakeup_period(0, 1000000));

    clear_ulp_adc_buffer();

    // Start ULP
    ESP_LOGI("MAIN", "Starting ULP");
    ESP_ERROR_CHECK(ulp_riscv_run());
}

extern "C" void app_main() {
    esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
    ESP_LOGI("MAIN", "Wakeup cause: %d", wakeup_reason);

    if (wakeup_reason == ESP_SLEEP_WAKEUP_UNDEFINED) init_ulp();
    else ESP_LOGI("Wake up from ULP");

    clear_ulp_adc_buffer();

    // Enable ULP as wakeup source
    ESP_LOGI("MAIN", "Enabling ULP as wakeup source and going to sleep");
    ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());
    esp_deep_sleep_start();
} 
This is my ulp_main.c:

Code: Select all

#include "../src/config.h"
#include "ulp_riscv_adc_ulp_core.h"
#include "ulp_riscv_utils.h"
volatile int adc_buffer;
int main(void) {
    adc_buffer = ulp_riscv_adc_read_channel(ADC_UNIT, ADC_CHANNEL);
    ulp_riscv_wakeup_main_processor();
    ulp_riscv_halt();
} 
This is the config.h:

Code: Select all

#define ADC_CHANNEL     ADC_CHANNEL_6
#define ADC_UNIT        ADC_UNIT_1
This is my sdkconfig.default:

Code: Select all

# Bootloader configuration
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y

# Additional power saving configurations
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y 

CONFIG_ULP_COPROC_ENABLED=y
CONFIG_ULP_COPROC_TYPE_RISCV=y
CONFIG_ULP_COPROC_RESERVE_MEM=4096
This is the output from the serial:
I (294) MAIN: Wakeup cause: 0
I (294) MAIN: First boot or other wakeup, initializing ULP
I (304) MAIN: Starting ULP
I (304) MAIN: Enabling ULP as wakeup source and going to sleep
What am I missing? Why is the ULP hang on reading ADC?

Re: Problem with ADC on ULP RISC-V while deep-sleep

Posted: Sun Jun 22, 2025 5:44 am
by MicroController
Check the example.

Re: Problem with ADC on ULP RISC-V while deep-sleep

Posted: Sun Jun 22, 2025 6:10 am
by gabika
Thanks @MicroController , I used the same example to build my program. Do you see anything I am missing on my end by any chance?

Re: Problem with ADC on ULP RISC-V while deep-sleep

Posted: Mon Jun 23, 2025 7:04 am
by MicroController
Maybe the call to esp_sleep_pd_config() "to keep SAR ADC related configs during sleep".

Re: Problem with ADC on ULP RISC-V while deep-sleep

Posted: Tue Jun 24, 2025 7:06 pm
by gabika
I am calling to `esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);` of course :)

Re: Problem with ADC on ULP RISC-V while deep-sleep

Posted: Fri Jun 27, 2025 5:48 pm
by gabika
After tons of debugging, I found the issue.
The issue lies in the initialization of the new ADC Unit code. The default is LP and not RISC-V.
This bug has been fixed in this PR: https://github.com/espressif/esp-idf/co ... a54297e272

Platformio is still pulling an older version (with the bug), so the ULP code is stuck.

I am guessing this is not the place to ask for an update to platformio framework, right?

Re: Problem with ADC on ULP RISC-V while deep-sleep

Posted: Sat Jun 28, 2025 5:53 am
by gabika
It will be fixed in the next framework-espressif update, I am opening a PR for platformio to have v5.4.2 soon.

Thanks