mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 04:59:55 +00:00 
			
		
		
		
	ulp-riscv: add support for using ADC as well as an example show-casing it.
This commit is contained in:
		| @@ -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_ENT_RTC_ADDR, 0); | ||||||
|     REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_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 |     //Power off SAR ADC | ||||||
|     REG_SET_FIELD(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0); |     REG_SET_FIELD(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0); | ||||||
|     //return to ADC RTC controller |     //return to ADC RTC controller | ||||||
|   | |||||||
| @@ -225,7 +225,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_RTC_CTRL_SUPPORTED | ||||||
|  |  | ||||||
| #if SOC_ADC_CALIBRATION_V1_SUPPORTED | #if SOC_ADC_CALIBRATION_V1_SUPPORTED | ||||||
| static uint32_t get_calibration_offset(adc_unit_t adc_n, adc_channel_t chan) | uint32_t get_calibration_offset(adc_unit_t adc_n, adc_channel_t chan) | ||||||
| { | { | ||||||
|     adc_atten_t atten = adc_ll_get_atten(adc_n, chan); |     adc_atten_t atten = adc_ll_get_atten(adc_n, chan); | ||||||
|     extern uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_atten_t atten); |     extern uint32_t adc_get_calibration_offset(adc_unit_t adc_n, 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 | ||||||
| @@ -182,7 +182,7 @@ static bool s_light_sleep_wakeup = false; | |||||||
| static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED; | static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED; | ||||||
|  |  | ||||||
| static const char *TAG = "sleep"; | 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. | //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; | static bool s_ultra_low_enabled = false; | ||||||
|  |  | ||||||
| @@ -1386,7 +1386,7 @@ void esp_deep_sleep_disable_rom_logging(void) | |||||||
|     rtc_suppress_rom_log(); |     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; |     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). | Currently there are 6 sub power modes, 3 for deepsleep and 3 for lightsleep. Show as below (priority from high to low). | ||||||
|  |  | ||||||
| ## Deepsleep | ## 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. | 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. | 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 | ## 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)`. | 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. | 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. | 4. Default mode. | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| #include "soc/soc_caps.h" | #include "soc/soc_caps.h" | ||||||
| #include "driver/ledc.h" | #include "driver/ledc.h" | ||||||
| #include "soc/rtc.h" | #include "soc/rtc.h" | ||||||
|  | #include "esp_private/esp_sleep_internal.h" | ||||||
|  |  | ||||||
| static const char TAG[] = "rtc_power"; | static const char TAG[] = "rtc_power"; | ||||||
|  |  | ||||||
| @@ -30,8 +31,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 |     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); |     esp_sleep_enable_adc_tsens_monitor(true); | ||||||
|     rtc_sleep_enable_adc_tesn_monitor(true); |  | ||||||
|     test_deepsleep(); |     test_deepsleep(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -108,8 +108,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 |     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); |     extern void esp_sleep_enable_adc_tsens_monitor(bool); | ||||||
|     rtc_sleep_enable_adc_tesn_monitor(true); |     esp_sleep_enable_adc_tsens_monitor(true); | ||||||
|     test_lightsleep(); |     test_lightsleep(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,7 +31,9 @@ extern void abort(void); | |||||||
| #endif | #endif | ||||||
| #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()) | #define HAL_ASSERT(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : abort()) | ||||||
| #elif CONFIG_HAL_DEFAULT_ASSERTION_LEVEL == 2 // full assertion | #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)) | #define HAL_ASSERT(__e) (__builtin_expect(!!(__e), 1) ? (void)0 : __assert_func(__FILE__, __LINE__, __ASSERT_FUNC, #__e)) | ||||||
|   | |||||||
| @@ -23,7 +23,8 @@ if(CONFIG_SOC_ULP_SUPPORTED OR CONFIG_SOC_RISCV_COPROC_SUPPORTED) | |||||||
|  |  | ||||||
|     elseif(CONFIG_ULP_COPROC_TYPE_RISCV) |     elseif(CONFIG_ULP_COPROC_TYPE_RISCV) | ||||||
|         list(APPEND srcs |         list(APPEND srcs | ||||||
|             "ulp_riscv/ulp_riscv.c") |             "ulp_riscv/ulp_riscv.c" | ||||||
|  |             "ulp_riscv/ulp_riscv_adc.c") | ||||||
|  |  | ||||||
|         list(APPEND includes |         list(APPEND includes | ||||||
|             ulp_riscv/include) |             ulp_riscv/include) | ||||||
| @@ -31,4 +32,5 @@ if(CONFIG_SOC_ULP_SUPPORTED OR CONFIG_SOC_RISCV_COPROC_SUPPORTED) | |||||||
| endif() | endif() | ||||||
|  |  | ||||||
| idf_component_register(SRCS ${srcs} | idf_component_register(SRCS ${srcs} | ||||||
|                        INCLUDE_DIRS ${includes}) |                        INCLUDE_DIRS ${includes} | ||||||
|  |                        REQUIRES driver) | ||||||
|   | |||||||
| @@ -71,8 +71,9 @@ add_custom_target(${ULP_APP_NAME}_ld_script | |||||||
| if(ULP_COCPU_IS_RISCV) | if(ULP_COCPU_IS_RISCV) | ||||||
|     #risc-v ulp uses extra files for building: |     #risc-v ulp uses extra files for building: | ||||||
|     list(APPEND ULP_S_SOURCES |     list(APPEND ULP_S_SOURCES | ||||||
|         "${IDF_PATH}/components/ulp/ulp_riscv/start.S" |         "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/start.S" | ||||||
|         "${IDF_PATH}/components/ulp/ulp_riscv/ulp_riscv_utils.c") |         "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_adc.c" | ||||||
|  |         "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c") | ||||||
|  |  | ||||||
|     #dummy loop to force pre-processed linker file generation: |     #dummy loop to force pre-processed linker file generation: | ||||||
|     foreach(ulp_s_source ${ULP_S_SOURCES}) |     foreach(ulp_s_source ${ULP_S_SOURCES}) | ||||||
| @@ -95,7 +96,9 @@ if(ULP_COCPU_IS_RISCV) | |||||||
|     list(APPEND EXTRA_LINKER_ARGS "-Wl,--gc-sections") |     list(APPEND EXTRA_LINKER_ARGS "-Wl,--gc-sections") | ||||||
|     list(APPEND EXTRA_LINKER_ARGS "-Wl,-Map=\"${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map\"") |     list(APPEND EXTRA_LINKER_ARGS "-Wl,-Map=\"${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map\"") | ||||||
|     #Makes the csr utillies for riscv visible: |     #Makes the csr utillies for riscv visible: | ||||||
|     target_include_directories(${ULP_APP_NAME} PRIVATE "${IDF_PATH}/components/ulp/ulp_riscv/include") |     target_include_directories(${ULP_APP_NAME} PRIVATE "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/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() | else() | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										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} |                             -DULP_APP_NAME=${app_name} | ||||||
|                             -DCOMPONENT_DIR=${COMPONENT_DIR} |                             -DCOMPONENT_DIR=${COMPONENT_DIR} | ||||||
|                             -DCOMPONENT_INCLUDES=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES> |                             -DCOMPONENT_INCLUDES=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES> | ||||||
|  |                             -DIDF_TARGET=${idf_target} | ||||||
|                             -DIDF_PATH=${idf_path} |                             -DIDF_PATH=${idf_path} | ||||||
|                             -DSDKCONFIG_HEADER=${SDKCONFIG_HEADER} |                             -DSDKCONFIG_HEADER=${SDKCONFIG_HEADER} | ||||||
|                             -DPYTHON=${python} |                             -DPYTHON=${python} | ||||||
|   | |||||||
| @@ -1,8 +1,3 @@ | |||||||
| if(IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET STREQUAL "esp32s3") |  | ||||||
|     #Disabled for now due to RTC bug IDF-4801 |  | ||||||
|     return() |  | ||||||
| endif() |  | ||||||
|  |  | ||||||
| if(NOT CONFIG_ULP_COPROC_TYPE_FSM AND NOT CONFIG_ULP_COPROC_TYPE_RISCV) | if(NOT CONFIG_ULP_COPROC_TYPE_FSM AND NOT CONFIG_ULP_COPROC_TYPE_RISCV) | ||||||
|     # Nothing to test if no co-processor enabled |     # Nothing to test if no co-processor enabled | ||||||
|     return() |     return() | ||||||
|   | |||||||
| @@ -6,4 +6,4 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #warning Contents of ulp_riscv/ulp_riscv.h have been deprecated. Please include the header which contains the actual definitions you are trying to use, e.g. "ulp_riscv_register_ops.h". | #warning Contents of ulp_riscv/ulp_riscv.h have been deprecated. Please include the header which contains the actual definitions you are trying to use, e.g. "ulp_riscv_register_ops.h". | ||||||
| #include "../ulp_riscv_register_ops.h" | #include "../../ulp_core/include/ulp_riscv_register_ops.h" | ||||||
|   | |||||||
| @@ -6,5 +6,5 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #warning "ulp_riscv_gpio.h has been moved one level up. Please include the file without the ulp_riscv prefix." | #warning "ulp_riscv_gpio.h has been moved. Please include the file without the ulp_riscv prefix." | ||||||
| #include "../ulp_riscv_gpio.h" | #include "../../ulp_core/include/ulp_riscv_gpio.h" | ||||||
|   | |||||||
| @@ -5,5 +5,5 @@ | |||||||
|  */ |  */ | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #warning ulp_riscv_register_ops.h has been moved one level up. Please include the file without the ulp_riscv prefix. | #warning ulp_riscv_register_ops.h has been moved. Please include the file without the ulp_riscv prefix. | ||||||
| #include "../ulp_riscv_register_ops.h" | #include "../../ulp_core/include/ulp_riscv_register_ops.h" | ||||||
|   | |||||||
| @@ -5,5 +5,5 @@ | |||||||
|  */ |  */ | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #warning ulp_riscv_utils.h has been moved one level up. Please include the file without the ulp_riscv prefix. | #warning ulp_riscv_utils.h has been moved. Please include the file without the ulp_riscv prefix. | ||||||
| #include "../ulp_riscv_utils.h" | #include "../../ulp_core/include/ulp_riscv_utils.h" | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								components/ulp/ulp_riscv/include/ulp_riscv_adc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								components/ulp/ulp_riscv/include/ulp_riscv_adc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | /* | ||||||
|  |  * 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_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 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); | ||||||
| @@ -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 | ||||||
| @@ -1,3 +1,8 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
| 	.section .text.vectors | 	.section .text.vectors | ||||||
| 	.global irq_vector
 | 	.global irq_vector
 | ||||||
| 	.global reset_vector
 | 	.global reset_vector
 | ||||||
							
								
								
									
										30
									
								
								components/ulp/ulp_riscv/ulp_core/ulp_riscv_adc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								components/ulp/ulp_riscv/ulp_core/ulp_riscv_adc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  | #include "ulp_riscv_adc.h" | ||||||
|  | #include "hal/adc_ll.h" | ||||||
|  |  | ||||||
|  | int32_t ulp_riscv_adc_read_channel(adc_unit_t adc_n, int channel) | ||||||
|  | { | ||||||
|  |     uint32_t event = (adc_n == ADC_UNIT_1) ? ADC_LL_EVENT_ADC1_ONESHOT_DONE : ADC_LL_EVENT_ADC2_ONESHOT_DONE; | ||||||
|  |     adc_oneshot_ll_clear_event(event); | ||||||
|  |     adc_oneshot_ll_disable_all_unit(); | ||||||
|  |     adc_oneshot_ll_enable(adc_n); | ||||||
|  |     adc_oneshot_ll_set_channel(adc_n, channel); | ||||||
|  |  | ||||||
|  |     adc_oneshot_ll_start(adc_n); | ||||||
|  |     while (adc_oneshot_ll_get_event(event) != true) { | ||||||
|  |         ; | ||||||
|  |     } | ||||||
|  |     int32_t out_raw = adc_oneshot_ll_get_raw_result(adc_n); | ||||||
|  |     if (adc_oneshot_ll_raw_check_valid(adc_n, out_raw) == false) { | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     //HW workaround: when enabling periph clock, this should be false | ||||||
|  |     adc_oneshot_ll_disable_all_unit(); | ||||||
|  |  | ||||||
|  |     return out_raw; | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								components/ulp/ulp_riscv/ulp_riscv_adc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								components/ulp/ulp_riscv/ulp_riscv_adc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "ulp_riscv_adc.h" | ||||||
|  | #include "esp_err.h" | ||||||
|  | #include "esp_check.h" | ||||||
|  | #include "esp_log.h" | ||||||
|  | #include "driver/adc.h" | ||||||
|  | #include "hal/adc_hal_common.h" | ||||||
|  | #include "esp_private/esp_sleep_internal.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Will be refactored when ADC NG is merged, TODO IDF-5513 */ | ||||||
|  | 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"); | ||||||
|  |     ESP_GOTO_ON_FALSE(cfg->adc_n == ADC_UNIT_1, ESP_ERR_INVALID_ARG, err, TAG, "Only ADC_UNIT_1 is supported for now"); | ||||||
|  |  | ||||||
|  |     adc1_config_channel_atten(cfg->channel, cfg->atten); | ||||||
|  |     adc1_config_width(cfg->width); | ||||||
|  |  | ||||||
|  |     //Calibrate the ADC | ||||||
|  |     uint32_t cal_val = get_calibration_offset(cfg->adc_n, cfg->channel); | ||||||
|  |     adc_hal_set_calibration_param(cfg->adc_n, 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.16) | ||||||
|  |  | ||||||
|  | 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}") | ||||||
							
								
								
									
										16
									
								
								examples/system/ulp_riscv/adc/main/ulp/example_config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								examples/system/ulp_riscv/adc/main/ulp/example_config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | /* | ||||||
|  |  * 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_UNIT        ADC_UNIT_1 | ||||||
|  | #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 | ||||||
							
								
								
									
										36
									
								
								examples/system/ulp_riscv/adc/main/ulp/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								examples/system/ulp_riscv/adc/main/ulp/main.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | /* | ||||||
|  |  * 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_utils.h" | ||||||
|  | #include "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(EXAMPLE_ADC_UNIT, 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 "ulp_riscv.h" | ||||||
|  | #include "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 = { | ||||||
|  |         .adc_n   = EXAMPLE_ADC_UNIT, | ||||||
|  |         .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); | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								examples/system/ulp_riscv/adc/sdkconfig.defaults
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								examples/system/ulp_riscv/adc/sdkconfig.defaults
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | # Enable ULP | ||||||
|  | CONFIG_ULP_COPROC_ENABLED=y | ||||||
|  | CONFIG_ULP_COPROC_RISCV=y | ||||||
|  | CONFIG_ULP_COPROC_RESERVE_MEM=4096 | ||||||
|  | # 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 | ||||||
		Reference in New Issue
	
	Block a user
	 Marius Vikhammer
					Marius Vikhammer