Skip to content

Commit

Permalink
Merge branch 'feature/ulp_fsm_adc_s3' into 'master'
Browse files Browse the repository at this point in the history
ulp-fsm: Update ulp-fsm ADC example with S3 support

Closes IDFGH-6299

See merge request espressif/esp-idf!19924
  • Loading branch information
ESP-Marius committed Sep 19, 2022
2 parents 29830f6 + 77ba84e commit cb48a7b
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 53 deletions.
4 changes: 2 additions & 2 deletions components/ulp/CMakeLists.txt
Expand Up @@ -6,7 +6,8 @@ set(includes "")
if(CONFIG_SOC_ULP_SUPPORTED OR CONFIG_SOC_RISCV_COPROC_SUPPORTED)

list(APPEND srcs
"ulp_common/ulp_common.c")
"ulp_common/ulp_common.c"
"ulp_common/ulp_adc.c")

list(APPEND includes
ulp_common/include
Expand All @@ -25,7 +26,6 @@ if(CONFIG_SOC_ULP_SUPPORTED OR CONFIG_SOC_RISCV_COPROC_SUPPORTED)
list(APPEND srcs
"ulp_riscv/ulp_riscv.c"
"ulp_riscv/ulp_riscv_lock.c"
"ulp_riscv/ulp_riscv_adc.c"
"ulp_riscv/ulp_riscv_i2c.c")

list(APPEND includes
Expand Down
34 changes: 34 additions & 0 deletions components/ulp/ulp_common/include/ulp_adc.h
@@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include "hal/adc_types.h"
#include "esp_err.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
adc_unit_t adc_n; // ADC Unit
adc_channel_t channel; // ADC channel
adc_atten_t atten; // ADC channel attenuation
adc_bitwidth_t width; // ADC bit width, only used for ADC unit 1
adc_ulp_mode_t ulp_mode; // ADC ULP Mode
} ulp_adc_cfg_t; // ULP FSM ADC configuration parameters

/**
* @brief Initialize and calibrate the ADC for use by ULP FSM
*
* @param cfg Configuration parameters
* @return esp_err_t ESP_OK for successful.
*/
esp_err_t ulp_adc_init(const ulp_adc_cfg_t *cfg);

#ifdef __cplusplus
}
#endif
Expand Up @@ -4,7 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include "ulp_riscv_adc.h"
#include "sdkconfig.h"
#include "ulp_adc.h"
#include "esp_err.h"
#include "esp_check.h"
#include "esp_log.h"
Expand All @@ -13,9 +14,9 @@
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/adc_share_hw_ctrl.h"

static const char *TAG = "ulp_riscv_adc";
static const char *TAG = "ulp_adc";

esp_err_t ulp_riscv_adc_init(const ulp_riscv_adc_cfg_t *cfg)
esp_err_t ulp_adc_init(const ulp_adc_cfg_t *cfg)
{
esp_err_t ret = ESP_OK;

Expand All @@ -24,10 +25,19 @@ esp_err_t ulp_riscv_adc_init(const ulp_riscv_adc_cfg_t *cfg)

//-------------ADC1 Init---------------//
adc_oneshot_unit_handle_t adc1_handle;

adc_oneshot_unit_init_cfg_t init_config1 = {
.unit_id = cfg->adc_n,
.ulp_mode = ADC_ULP_MODE_RISCV,
.ulp_mode = cfg->ulp_mode,
};

if (init_config1.ulp_mode == ADC_ULP_MODE_DISABLE) {
/* Default to RISCV for backward compatibility */
ESP_LOGI(TAG, "No ulp mode specified in cfg struct, default to riscv");
init_config1.ulp_mode = ADC_ULP_MODE_RISCV;
}


ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));

//-------------ADC1 Config---------------//
Expand All @@ -38,7 +48,10 @@ esp_err_t ulp_riscv_adc_init(const ulp_riscv_adc_cfg_t *cfg)
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, cfg->channel, &config));

//Calibrate the ADC
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
adc_set_hw_calibration_code(cfg->adc_n, cfg->atten);
#endif

esp_sleep_enable_adc_tsens_monitor(true);

err:
Expand Down
19 changes: 5 additions & 14 deletions components/ulp/ulp_riscv/include/ulp_riscv_adc.h
Expand Up @@ -9,24 +9,15 @@
#include "hal/adc_types.h"
#include "esp_err.h"

#include "ulp_adc.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
adc_unit_t adc_n; // ADC Unit
adc_channel_t channel; // ADC channel
adc_atten_t atten; // ADC channel attenuation
adc_bitwidth_t width; // ADC bit width, only used for ADC unit 1
} ulp_riscv_adc_cfg_t; // ULP Riscv ADC configuration parameters

/**
* @brief Initialize and calibrate the ADC for use by ULP RISCV
*
* @param cfg Configuration parameters
* @return esp_err_t ESP_OK for successful.
*/
esp_err_t ulp_riscv_adc_init(const ulp_riscv_adc_cfg_t *cfg);
/* Kept for backwards compatibilty */
#define ulp_riscv_adc_cfg_t ulp_adc_cfg_t
#define ulp_riscv_adc_init ulp_adc_init

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion examples/system/.build-test-rules.yml
Expand Up @@ -160,7 +160,7 @@ examples/system/ulp_fsm/ulp:

examples/system/ulp_fsm/ulp_adc:
enable:
- if: IDF_TARGET == "esp32"
- if: IDF_TARGET in ["esp32", "esp32s3"]
temporary: true
reason: the other targets are not tested yet

Expand Down
6 changes: 3 additions & 3 deletions examples/system/ulp_fsm/ulp_adc/README.md
@@ -1,11 +1,11 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
| Supported Targets | ESP32 | ESP32-S3 |
| ----------------- | ----- | -------- |

# ULP ADC Example

This example demonstrates how to use the ULP coprocessor to poll ADC in deep sleep.

ULP program periodically measures the input voltage on GPIO34. The voltage is compared to two thresholds. If the voltage is less than the low threshold, or higher than the high threshold, ULP wakes up the system.
ULP program periodically measures the input voltage on ADC_CHANNEL_6 (GPIO34 on ESP32, GPIO7 on ESP32-S3). The voltage is compared to two thresholds. If the voltage is less than the low threshold, or higher than the high threshold, ULP wakes up the system.

By default, thresholds are set to 1.35V and 1.75V, approximately.

Expand Down
9 changes: 7 additions & 2 deletions examples/system/ulp_fsm/ulp_adc/main/ulp/adc.S
@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* ULP Example: using ADC in deep sleep
This example code is in the Public Domain (or CC0 licensed, at your option.)
Expand All @@ -22,9 +27,9 @@
*/
#include "soc/rtc_cntl_reg.h"
#include "soc/soc_ulp.h"
#include "example_config.h"

/* ADC1 channel 6, GPIO34 */
.set adc_channel, 6
.set adc_channel, EXAMPLE_ADC_CHANNEL

/* Configure the number of ADC samples to average on each measurement.
For convenience, make it a power of 2. */
Expand Down
16 changes: 16 additions & 0 deletions examples/system/ulp_fsm/ulp_adc/main/ulp/example_config.h
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once

/* Ints are used here to be able to include the file in assembly as well */
#define EXAMPLE_ADC_CHANNEL 6 // ADC_CHANNEL_6, GPIO34 on ESP32, GPIO7 on ESP32-S3
#define EXAMPLE_ADC_UNIT 0 // ADC_UNIT_1
#define EXAMPLE_ADC_ATTEN 3 // ADC_ATTEN_DB_11
#define EXAMPLE_ADC_WIDTH 0 // ADC_BITWIDTH_DEFAULT

/* Set low and high thresholds, approx. 1.35V - 1.75V*/
#define EXAMPLE_ADC_LOW_TRESHOLD 1500
#define EXAMPLE_ADC_HIGH_TRESHOLD 2000
44 changes: 24 additions & 20 deletions examples/system/ulp_fsm/ulp_adc/main/ulp_adc_example_main.c
Expand Up @@ -10,16 +10,18 @@
#include <stdio.h>
#include <string.h>
#include "esp_sleep.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "driver/dac.h"
#include "esp32/ulp.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");
Expand Down Expand Up @@ -51,6 +53,12 @@ void app_main(void)
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();
}

Expand All @@ -60,35 +68,31 @@ static void init_ulp_program(void)
(ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
ESP_ERROR_CHECK(err);

//-------------ADC1 Init---------------//
adc_oneshot_unit_handle_t adc1_handle;
adc_oneshot_unit_init_cfg_t init_config1 = {
.unit_id = ADC_UNIT_1,
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,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));

//-------------ADC1 Channel Config---------------//
// Note: when changing channel here, also change 'adc_channel' constant in adc.S
adc_oneshot_chan_cfg_t config = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = ADC_ATTEN_DB_11,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, ADC_CHANNEL_6, &config));
ESP_ERROR_CHECK(ulp_adc_init(&cfg));

/* Set low and high thresholds, approx. 1.35V - 1.75V*/
ulp_low_thr = 1500;
ulp_high_thr = 2000;
ulp_low_thr = EXAMPLE_ADC_LOW_TRESHOLD;
ulp_high_thr = EXAMPLE_ADC_HIGH_TRESHOLD;

/* Set ULP wake up period to 20ms */
ulp_set_wakeup_period(0, 20000);

#if CONFIG_IDF_TARGET_ESP32
/* Disconnect GPIO12 and GPIO15 to remove current drain through
* pullup/pulldown resistors.
* 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
}

Expand Down
1 change: 1 addition & 0 deletions examples/system/ulp_fsm/ulp_adc/pytest_ulp_fsm_adc.py
Expand Up @@ -8,6 +8,7 @@


@pytest.mark.esp32
@pytest.mark.esp32s3
@pytest.mark.generic
def test_ulp_fsm_adc(dut: Dut) -> None:

Expand Down
15 changes: 8 additions & 7 deletions examples/system/ulp_riscv/adc/main/ulp_riscv_adc_example_main.c
Expand Up @@ -15,7 +15,7 @@
#include <stdio.h>
#include "esp_sleep.h"
#include "ulp_riscv.h"
#include "ulp_riscv_adc.h"
#include "ulp_adc.h"
#include "ulp_main.h"
#include "ulp/example_config.h"

Expand Down Expand Up @@ -56,14 +56,15 @@ void app_main(void)

static void init_ulp_program(void)
{
ulp_riscv_adc_cfg_t cfg = {
.adc_n = EXAMPLE_ADC_UNIT,
.channel = EXAMPLE_ADC_CHANNEL,
.width = EXAMPLE_ADC_WIDTH,
.atten = EXAMPLE_ADC_ATTEN,
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,
};

ESP_ERROR_CHECK(ulp_riscv_adc_init(&cfg));
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);
Expand Down

0 comments on commit cb48a7b

Please sign in to comment.