feat(lp_adc): Added example to demonstrate LP ADC usage from LP Core

This commit adds an example which demonstrates how to configure and use
the LP ADC from the LP core while the main core is in deep sleep.
This commit is contained in:
Sudeep Mohanty 2024-08-28 17:33:33 +02:00
parent 594880dae4
commit 0b75e75f2c
8 changed files with 238 additions and 0 deletions

View File

@ -315,6 +315,12 @@ examples/system/ulp/lp_core/interrupt:
depends_components:
- ulp
examples/system/ulp/lp_core/lp_adc:
disable:
- if: (SOC_LP_ADC_SUPPORTED != 1)
depends_components:
- ulp, esp_adc
examples/system/ulp/lp_core/lp_i2c:
enable:
- if: SOC_LP_I2C_SUPPORTED == 1 and SOC_DEEP_SLEEP_SUPPORTED == 1

View File

@ -0,0 +1,8 @@
# 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)
list(APPEND SDKCONFIG_DEFAULTS "sdkconfig.defaults")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lp_core_adc)

View File

@ -0,0 +1,63 @@
| Supported Targets | ESP32-P4 |
| ----------------- | -------- |
# LP ADC Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrates how to use the LP ADC peripheral on the LP core. The example sets up the LP ADC from the HP core before putting it to sleep.
It then reads the configured LP ADC channels from the LP core and prints the raw and converted voltage values to the LP UART console.
## How to use example
### Hardware Required
* A development board with ESP SoC such as the ESP32-P4 which supports LP ADC.
* A USB cable for power supply and programming
* A USB to UART converter to monitor the LP core serial console
In this example, you need to connect a voltage source (e.g. a DC power supply) to the GPIO pins for the input ADC channels. The ADC channels to read can be configured from the menuconfig option for this example.
**Note:** The following pin assignments are used by default.
#### LP UART Pin Assignment:
| | UART Tx Pin |
| ----------------------- | ------------|
| ESP32-P4 | GPIO14 |
The UART Tx Pin must be connected to the UART Rx pin on the host machine.
#### LP ADC Pin Assignments:
| | LP ADC Channel Number | Pin |
| ----------------------- | --------------------------| ------ |
| ESP32-P4 | Channel 4 | GPIO20 |
| ESP32-P4 | Channel 5 | GPIO21 |
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
Use another serial monitor program/instance such as idf.py monitor, minicom or miniterm to send and receive data from the LP core.
The default baudrate used for the example is 115200. Care must be taken that the configuration matches on both the device and the serial terminal.
## Example Output
Running this example, you will see the following log output on the LP core serial monitor:
```
ESP-ROM-LP:esp32p4-20230811
Build:Aug 11 2023
rst:0x14 (SW_RST), wakeup:0x40000
entry:0x50108180
lpadc1 chan0 raw value = 0
lpadc1 chan0 converted value = 0 mV
lpadc1 chan1 raw value = 3894
lpadc1 chan1 converted value = 4167 mV
```

View File

@ -0,0 +1,25 @@
# Register the component
idf_component_register(SRCS "lp_adc_main.c"
INCLUDE_DIRS "."
REQUIRES ulp)
#
# ULP support additions to component CMakeLists.txt.
#
# 1. The LP Core app name must be unique (if multiple components use LP Core).
set(ulp_app_name lp_core_${COMPONENT_NAME})
#
# 2. Specify all C files.
# Files should be placed into a separate directory (in this case, lp_core/),
# which should not be added to COMPONENT_SRCS.
set(ulp_lp_core_sources "lp_core/main.c")
#
# 3. List all the component source files which include automatically
# generated LP Core export file, ${ulp_app_name}.h:
set(ulp_exp_dep_srcs "lp_adc_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_lp_core_sources}" "${ulp_exp_dep_srcs}")

View File

@ -0,0 +1,17 @@
menu "Example Configuration"
config EXAMPLE_LP_ADC1_CHANNEL_0_SELECT
int "LP ADC1 Channel 0 Select"
default 4
range 0 7
help
Select the channel to be used for LP ADC1 Channel 0
config EXAMPLE_LP_ADC1_CHANNEL_1_SELECT
int "LP ADC1 Channel 1 Select"
default 5
range 0 7
help
Select the channel to be used for LP ADC1 Channel 1
endmenu

View File

@ -0,0 +1,76 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_sleep.h"
#include "lp_core_main.h"
#include "ulp_lp_core.h"
#include "lp_core_uart.h"
#include "ulp_lp_core_lp_adc_shared.h"
/* LP ADC1 configuration */
#define EXAMPLE_LP_ADC1_CHAN0 CONFIG_EXAMPLE_LP_ADC1_CHANNEL_0_SELECT
#define EXAMPLE_LP_ADC1_CHAN1 CONFIG_EXAMPLE_LP_ADC1_CHANNEL_1_SELECT
#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12
/* LP core binary */
extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_main_bin_start");
extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_main_bin_end");
static void lp_uart_init(void)
{
lp_core_uart_cfg_t cfg = LP_CORE_UART_DEFAULT_CONFIG();
ESP_ERROR_CHECK(lp_core_uart_init(&cfg));
printf("LP UART initialized successfully\n");
}
static void lp_core_init(void)
{
/* Set LP core wakeup source as the HP CPU */
ulp_lp_core_cfg_t cfg = {
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER,
.lp_timer_sleep_duration_us = 1000000,
};
/* Load LP core firmware */
ESP_ERROR_CHECK(ulp_lp_core_load_binary(lp_core_main_bin_start, (lp_core_main_bin_end - lp_core_main_bin_start)));
/* Run LP core */
ESP_ERROR_CHECK(ulp_lp_core_run(&cfg));
printf("LP core loaded with firmware and running successfully\n");
}
void app_main(void)
{
/* LP ADC1 Init */
ESP_ERROR_CHECK(lp_core_lp_adc_init(ADC_UNIT_1));
/* LP ADC1 channel config */
const lp_core_lp_adc_chan_cfg_t config = {
.atten = EXAMPLE_ADC_ATTEN,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ESP_ERROR_CHECK(lp_core_lp_adc_config_channel(ADC_UNIT_1, EXAMPLE_LP_ADC1_CHAN0, &config));
ESP_ERROR_CHECK(lp_core_lp_adc_config_channel(ADC_UNIT_1, EXAMPLE_LP_ADC1_CHAN1, &config));
/* Initialize LP_UART to print the ADC values to the LP core console */
lp_uart_init();
/* Load LP Core binary and start the coprocessor */
lp_core_init();
/* Enable ULP wakeup */
ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());
/* Enter Deep Sleep */
printf("Entering deep sleep...\n");
esp_deep_sleep_start();
}

View File

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdint.h>
#include "sdkconfig.h"
#include "ulp_lp_core_print.h"
#include "ulp_lp_core_lp_adc_shared.h"
#define EXAMPLE_LP_ADC1_CHAN0 CONFIG_EXAMPLE_LP_ADC1_CHANNEL_0_SELECT
#define EXAMPLE_LP_ADC1_CHAN1 CONFIG_EXAMPLE_LP_ADC1_CHANNEL_1_SELECT
int main (void)
{
int adc_raw_value[2];
int adc_converted_value[2];
lp_core_lp_adc_read_channel_raw(ADC_UNIT_1, EXAMPLE_LP_ADC1_CHAN0, &adc_raw_value[0]);
lp_core_printf("lpadc1 chan0 raw value = %d\r\n", adc_raw_value[0]);
lp_core_lp_adc_read_channel_converted(ADC_UNIT_1, EXAMPLE_LP_ADC1_CHAN0, &adc_converted_value[0]);
lp_core_printf("lpadc1 chan0 converted value = %d mV\r\n", adc_converted_value[0]);
lp_core_lp_adc_read_channel_raw(ADC_UNIT_1, EXAMPLE_LP_ADC1_CHAN1, &adc_raw_value[1]);
lp_core_printf("lpadc1 chan1 raw value = %d\r\n", adc_raw_value[1]);
lp_core_lp_adc_read_channel_converted(ADC_UNIT_1, EXAMPLE_LP_ADC1_CHAN1, &adc_converted_value[1]);
lp_core_printf("lpadc1 chan1 converted value = %d mV\r\n", adc_converted_value[1]);
lp_core_printf("\n");
return 0;
}

View File

@ -0,0 +1,10 @@
# Enable LP Core
CONFIG_ULP_COPROC_ENABLED=y
CONFIG_ULP_COPROC_TYPE_LP_CORE=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