mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
ulp-riscv: add support for using ADC as well as an example show-casing it.
This commit is contained in:
parent
9fe854c4ca
commit
f8f93d936e
@ -83,8 +83,6 @@ void bootloader_random_disable(void)
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
|
||||
|
||||
//Stop SAR ADC clock
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_SARADC_CLK_EN);
|
||||
//Power off SAR ADC
|
||||
REG_SET_FIELD(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0);
|
||||
//return to ADC RTC controller
|
||||
|
@ -224,7 +224,7 @@ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num)
|
||||
#if SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
|
||||
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
static uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
|
||||
uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
|
||||
{
|
||||
adc_atten_t atten = adc_ll_get_atten(adc_n, chan);
|
||||
extern uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten);
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enables the use of ADC and temperature sensor in monitor (ULP) mode
|
||||
*
|
||||
* @note This state is kept in RTC memory and will keep its value after a deep sleep wakeup
|
||||
*
|
||||
*/
|
||||
void esp_sleep_enable_adc_tsens_monitor(bool enable);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -178,7 +178,7 @@ static bool s_light_sleep_wakeup = false;
|
||||
static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static const char *TAG = "sleep";
|
||||
static bool s_adc_tsen_enabled = false;
|
||||
static RTC_FAST_ATTR bool s_adc_tsen_enabled = false;
|
||||
//in this mode, 2uA is saved, but RTC memory can't use at high temperature, and RTCIO can't be used as INPUT.
|
||||
static bool s_ultra_low_enabled = false;
|
||||
|
||||
@ -1364,7 +1364,7 @@ void esp_deep_sleep_disable_rom_logging(void)
|
||||
rtc_suppress_rom_log();
|
||||
}
|
||||
|
||||
void rtc_sleep_enable_adc_tesn_monitor(bool enable)
|
||||
void esp_sleep_enable_adc_tsens_monitor(bool enable)
|
||||
{
|
||||
s_adc_tsen_enabled = enable;
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ This test app is to enter 7 different sub power modes we have, so that the power
|
||||
Currently there are 6 sub power modes, 3 for deepsleep and 3 for lightsleep. Show as below (priority from high to low).
|
||||
|
||||
## Deepsleep
|
||||
1. Mode for ADC/Temp Sensor in monitor mode (ULP). To enable this mode, call `rtc_sleep_enable_adc_tesn_monitor`.
|
||||
1. Mode for ADC/Temp Sensor in monitor mode (ULP). To enable this mode, call `esp_sleep_enable_adc_tsens_monitor`.
|
||||
2. Default mode.
|
||||
3. Ultra low power mode. To enable this mode, call `rtc_sleep_enable_ultra_low`. Note if mode 1 has higher priority than this.
|
||||
|
||||
## Lightsleep
|
||||
1. Mode for using 40 MHz XTAL in lightsleep. To enable this mode, call `esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON)`.
|
||||
2. Mode for using 8M clock by digital system (peripherals). To enable this mode, initialize LEDC with 8M clock source.
|
||||
3. Mode for ADC/Temp Sensor in monitor mode (ULP). To enable this mdoe, call `rtc_sleep_enable_adc_tesn_monitor`.
|
||||
3. Mode for ADC/Temp Sensor in monitor mode (ULP). To enable this mdoe, call `esp_sleep_enable_adc_tsens_monitor`.
|
||||
4. Default mode.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
|
||||
static const char TAG[] = "rtc_power";
|
||||
|
||||
@ -29,8 +30,7 @@ TEST_CASE("Power Test: Deepsleep (with ADC/TSEN in monitor)", "[pm]")
|
||||
{
|
||||
rtc_dig_clk8m_disable(); //This is workaround for bootloader not disable 8M as digital clock source
|
||||
|
||||
extern void rtc_sleep_enable_adc_tesn_monitor(bool);
|
||||
rtc_sleep_enable_adc_tesn_monitor(true);
|
||||
esp_sleep_enable_adc_tsens_monitor(true);
|
||||
test_deepsleep();
|
||||
}
|
||||
|
||||
@ -107,8 +107,8 @@ TEST_CASE("Power Test: Lightsleep (with ADC/TSEN in monitor)", "[pm]")
|
||||
{
|
||||
rtc_dig_clk8m_disable(); //This is workaround for bootloader not disable 8M as digital clock source
|
||||
|
||||
extern void rtc_sleep_enable_adc_tesn_monitor(bool);
|
||||
rtc_sleep_enable_adc_tesn_monitor(true);
|
||||
extern void esp_sleep_enable_adc_tsens_monitor(bool);
|
||||
esp_sleep_enable_adc_tsens_monitor(true);
|
||||
test_lightsleep();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,9 @@ extern void abort(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_HAL_DEFAULT_ASSERTION_LEVEL == 1 // silent
|
||||
#if IS_ULP_COCPU
|
||||
#define HAL_ASSERT(__e) ((void)(__e))
|
||||
#elif CONFIG_HAL_DEFAULT_ASSERTION_LEVEL == 1 // silent
|
||||
#define HAL_ASSERT(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : abort())
|
||||
#elif CONFIG_HAL_DEFAULT_ASSERTION_LEVEL == 2 // full assertion
|
||||
#define HAL_ASSERT(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : __assert_func(__FILE__, __LINE__, __ASSERT_FUNC, #__e))
|
||||
|
@ -5,7 +5,8 @@ if(NOT (IDF_TARGET STREQUAL "esp32c3") AND NOT (IDF_TARGET STREQUAL "esp32h2"))
|
||||
"ulp_macro.c")
|
||||
|
||||
if(CONFIG_ESP32S2_ULP_COPROC_RISCV OR CONFIG_ESP32S3_ULP_COPROC_RISCV)
|
||||
list(APPEND srcs "ulp_riscv.c")
|
||||
list(APPEND srcs "ulp_riscv.c"
|
||||
"ulp_riscv_adc.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
|
@ -68,11 +68,14 @@ add_custom_target(${ULP_APP_NAME}_ld_script
|
||||
DEPENDS ${ULP_LD_SCRIPT}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# To avoid warning "Manually-specified variables were not used by the project"
|
||||
set(bypassWarning "${IDF_TARGET}")
|
||||
if(ULP_COCPU_IS_RISCV)
|
||||
#risc-v ulp uses extra files for building:
|
||||
list(APPEND ULP_S_SOURCES
|
||||
"${IDF_PATH}/components/ulp/ulp_riscv/start.S"
|
||||
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_riscv_utils.c")
|
||||
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_riscv_utils.c"
|
||||
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_riscv_adc.c")
|
||||
|
||||
#dummy loop to force pre-processed linker file generation:
|
||||
foreach(ulp_s_source ${ULP_S_SOURCES})
|
||||
@ -96,6 +99,8 @@ if(ULP_COCPU_IS_RISCV)
|
||||
list(APPEND EXTRA_LINKER_ARGS "-Wl,-Map=\"${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map\"")
|
||||
#Makes the csr utillies for riscv visible:
|
||||
target_include_directories(${ULP_APP_NAME} PRIVATE "${IDF_PATH}/components/ulp/ulp_riscv/include")
|
||||
target_link_libraries(${ULP_APP_NAME} "-T \"${IDF_PATH}/components/ulp/ld/${IDF_TARGET}.periperals.ld\"")
|
||||
target_compile_definitions(${ULP_APP_NAME} PRIVATE IS_ULP_COCPU)
|
||||
|
||||
else()
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
COMPONENT_OBJEXCLUDE := ulp_riscv.o
|
||||
COMPONENT_OBJEXCLUDE := ulp_riscv.o \
|
||||
ulp_riscv_adc.o
|
||||
|
32
components/ulp/include/esp32s3/ulp_riscv_adc.h
Normal file
32
components/ulp/include/esp32s3/ulp_riscv_adc.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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_channel_t channel; // ADC channel
|
||||
adc_atten_t atten; // ADC channel attenuation
|
||||
adc_bits_width_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 ADC1 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
9
components/ulp/ld/esp32s2.periperals.ld
Normal file
9
components/ulp/ld/esp32s2.periperals.ld
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
PROVIDE ( RTCCNTL = 0x8000 );
|
||||
PROVIDE ( RTCIO = 0xA400 );
|
||||
PROVIDE ( SENS = 0xC800 );
|
9
components/ulp/ld/esp32s3.periperals.ld
Normal file
9
components/ulp/ld/esp32s3.periperals.ld
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
PROVIDE ( RTCCNTL = 0x8000 );
|
||||
PROVIDE ( RTCIO = 0xA400 );
|
||||
PROVIDE ( SENS = 0xC800 );
|
@ -58,6 +58,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
|
||||
-DULP_APP_NAME=${app_name}
|
||||
-DCOMPONENT_DIR=${COMPONENT_DIR}
|
||||
-DCOMPONENT_INCLUDES=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES>
|
||||
-DIDF_TARGET=${idf_target}
|
||||
-DIDF_PATH=${idf_path}
|
||||
-DIDF_TARGET=${idf_target}
|
||||
-DSDKCONFIG_HEADER=${SDKCONFIG_HEADER}
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/adc_ll.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Start an ADC conversion and get the converted value.
|
||||
*
|
||||
* @note Will block until the conversion is completed
|
||||
*
|
||||
* @note ADC should be initilized for ULP by main CPU by calling ulp_riscv_adc_init()
|
||||
* before calling this.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number.
|
||||
*
|
||||
* @return Converted value, -1 if conversion failed
|
||||
*/
|
||||
int32_t ulp_riscv_adc_read_channel(adc_unit_t adc_n, int channel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
20
components/ulp/ulp_riscv/ulp_riscv_adc.c
Normal file
20
components/ulp/ulp_riscv/ulp_riscv_adc.c
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "ulp_riscv/ulp_riscv_adc_ulp_core.h"
|
||||
#include "hal/adc_ll.h"
|
||||
|
||||
int32_t ulp_riscv_adc_read_channel(adc_unit_t adc_n, int channel)
|
||||
{
|
||||
adc_ll_rtc_enable_channel(adc_n, channel);
|
||||
|
||||
adc_ll_rtc_start_convert(adc_n, channel);
|
||||
while (adc_ll_rtc_convert_is_done(adc_n) != true) {
|
||||
;
|
||||
}
|
||||
int32_t out_raw = adc_ll_rtc_get_convert_value(adc_n);
|
||||
|
||||
return out_raw;
|
||||
}
|
40
components/ulp/ulp_riscv_adc.c
Normal file
40
components/ulp/ulp_riscv_adc.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp32s3/ulp_riscv_adc.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/adc.h"
|
||||
#include "hal/adc_hal.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
|
||||
|
||||
extern esp_err_t adc1_rtc_mode_acquire(void);
|
||||
extern uint32_t get_calibration_offset(adc_unit_t adc_n, adc_channel_t chan);
|
||||
|
||||
static const char *TAG = "ulp_riscv_adc";
|
||||
|
||||
esp_err_t ulp_riscv_adc_init(const ulp_riscv_adc_cfg_t *cfg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
ESP_GOTO_ON_FALSE(cfg, ESP_ERR_INVALID_ARG, err, TAG, "cfg == NULL");
|
||||
|
||||
adc1_config_channel_atten(cfg->channel, cfg->atten);
|
||||
adc1_config_width(cfg->width);
|
||||
|
||||
//Calibrate the ADC
|
||||
uint32_t cal_val = get_calibration_offset(ADC_UNIT_1, cfg->channel);
|
||||
adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
|
||||
|
||||
adc1_rtc_mode_acquire();
|
||||
|
||||
esp_sleep_enable_adc_tsens_monitor(true);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
6
examples/system/ulp_riscv/adc/CMakeLists.txt
Normal file
6
examples/system/ulp_riscv/adc/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ulp-riscv-adc-example)
|
32
examples/system/ulp_riscv/adc/README.md
Normal file
32
examples/system/ulp_riscv/adc/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
| Supported Targets | ESP32-S3 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# ULP-RISC-V ADC Example
|
||||
|
||||
This example demonstrates how to use the ULP-RISC-V coprocessor to poll the ADC in deep sleep.
|
||||
|
||||
The ULP program periodically measures the input voltage on EXAMPLE_ADC_CHANNEL (by default ADC1 channel 0, GPIO1 on both ESP32-S2 and ESP32-S3). The voltage is compared to an upper threshold. If the voltage is higher than the threshold, the ULP wakes up the system.
|
||||
|
||||
By default, the threshold is set to 1.75V, approximately.
|
||||
|
||||
In this example, you need to connect a voltage source (e.g. a DC power supply) to the GPIO pin corresponding to the ADC channel specified in `ulp/example_config.h` (see the macros defined on the top of the header file). Feel free to modify the channel setting.
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with a SOC which has a RISC-V ULP coprocessor (e.g., ESP32-S2 Saola)
|
||||
* A USB cable for power supply and programming
|
||||
|
||||
## Example output
|
||||
|
||||
Below is the output from this example.
|
||||
|
||||
```
|
||||
Not a ULP-RISC-V wakeup (cause = 0), initializing it!
|
||||
Entering in deep sleep
|
||||
|
||||
ULP-RISC-V woke up the main CPU
|
||||
Threshold: high = 2000
|
||||
Value = 4095 was above threshold
|
||||
Entering in deep sleep
|
||||
```
|
||||
|
25
examples/system/ulp_riscv/adc/main/CMakeLists.txt
Normal file
25
examples/system/ulp_riscv/adc/main/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
idf_component_register(SRCS "ulp_riscv_adc_example_main.c"
|
||||
INCLUDE_DIRS ""
|
||||
REQUIRES soc ulp esp_adc_cal)
|
||||
|
||||
|
||||
#
|
||||
# ULP support additions to component CMakeLists.txt.
|
||||
#
|
||||
# 1. The ULP app name must be unique (if multiple components use ULP).
|
||||
set(ulp_app_name ulp_${COMPONENT_NAME})
|
||||
#
|
||||
# 2. Specify all C and Assembly source files.
|
||||
# Files should be placed into a separate directory (in this case, ulp/),
|
||||
# which should not be added to COMPONENT_SRCS.
|
||||
set(ulp_riscv_sources "ulp/main.c")
|
||||
|
||||
#
|
||||
# 3. List all the component source files which include automatically
|
||||
# generated ULP export file, ${ulp_app_name}.h:
|
||||
set(ulp_exp_dep_srcs "ulp_riscv_adc_example_main.c")
|
||||
|
||||
#
|
||||
# 4. Call function to build ULP binary and embed in project using the argument
|
||||
# values above.
|
||||
ulp_embed_binary(${ulp_app_name} "${ulp_riscv_sources}" "${ulp_exp_dep_srcs}")
|
15
examples/system/ulp_riscv/adc/main/ulp/example_config.h
Normal file
15
examples/system/ulp_riscv/adc/main/ulp/example_config.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "hal/adc_types.h"
|
||||
|
||||
#define EXAMPLE_ADC_CHANNEL ADC_CHANNEL_0
|
||||
#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_11
|
||||
#define EXAMPLE_ADC_WIDTH ADC_WIDTH_BIT_12
|
||||
|
||||
/* Set high threshold, approx. 1.75V*/
|
||||
#define EXAMPLE_ADC_TRESHOLD 2000
|
37
examples/system/ulp_riscv/adc/main/ulp/main.c
Normal file
37
examples/system/ulp_riscv/adc/main/ulp/main.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/* ULP-RISC-V example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
This code runs on ULP-RISC-V coprocessor
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ulp_riscv/ulp_riscv.h"
|
||||
#include "ulp_riscv/ulp_riscv_utils.h"
|
||||
#include "ulp_riscv/ulp_riscv_adc_ulp_core.h"
|
||||
|
||||
#include "example_config.h"
|
||||
|
||||
uint32_t adc_threshold = EXAMPLE_ADC_TRESHOLD;
|
||||
int32_t wakeup_result;
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int32_t last_result = ulp_riscv_adc_read_channel(ADC_NUM_1, EXAMPLE_ADC_CHANNEL);
|
||||
|
||||
if (last_result > adc_threshold) {
|
||||
wakeup_result = last_result;
|
||||
ulp_riscv_wakeup_main_processor();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/* ULP riscv example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "esp_sleep.h"
|
||||
#include "esp32s3/ulp.h"
|
||||
#include "esp32s3/ulp_riscv.h"
|
||||
#include "esp32s3/ulp_riscv_adc.h"
|
||||
#include "ulp_main.h"
|
||||
#include "ulp/example_config.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)
|
||||
{
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/* ULP Risc-V read and detected a temperature above the limit */
|
||||
if (cause == ESP_SLEEP_WAKEUP_ULP) {
|
||||
printf("ULP-RISC-V woke up the main CPU\n");
|
||||
printf("Threshold: high = %d\n", ulp_adc_threshold);
|
||||
printf("Value = %d was above threshold\n", ulp_wakeup_result);
|
||||
}
|
||||
|
||||
/* Go back to sleep, only the ULP Risc-V will run */
|
||||
printf("Entering in deep sleep\n\n");
|
||||
|
||||
/* 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_riscv_adc_cfg_t cfg = {
|
||||
.channel = EXAMPLE_ADC_CHANNEL,
|
||||
.width = EXAMPLE_ADC_WIDTH,
|
||||
.atten = EXAMPLE_ADC_ATTEN,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(ulp_riscv_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: 20ms
|
||||
*/
|
||||
ulp_set_wakeup_period(0, 20000);
|
||||
|
||||
/* Start the program */
|
||||
err = ulp_riscv_run();
|
||||
ESP_ERROR_CHECK(err);
|
||||
}
|
5
examples/system/ulp_riscv/adc/sdkconfig.defaults
Normal file
5
examples/system/ulp_riscv/adc/sdkconfig.defaults
Normal file
@ -0,0 +1,5 @@
|
||||
# Set log level to Warning to produce clean output
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=2
|
||||
CONFIG_LOG_DEFAULT_LEVEL_WARN=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=2
|
4
examples/system/ulp_riscv/adc/sdkconfig.defaults.esp32s3
Normal file
4
examples/system/ulp_riscv/adc/sdkconfig.defaults.esp32s3
Normal file
@ -0,0 +1,4 @@
|
||||
# Enable ULP
|
||||
CONFIG_ESP32S3_ULP_COPROC_ENABLED=y
|
||||
CONFIG_ESP32S3_ULP_COPROC_RISCV=y
|
||||
CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=4096
|
Loading…
x
Reference in New Issue
Block a user