Skip to content

Commit

Permalink
Merge branch 'feature/ulp_riscv_touch' into 'master'
Browse files Browse the repository at this point in the history
ulp-riscv: Added touch sensor support to ULP RISC-V

Closes IDFGH-9077

See merge request espressif/esp-idf!23859
  • Loading branch information
sudeep-mohanty committed Jun 9, 2023
2 parents 3d11043 + ba2daf3 commit 4b35e00
Show file tree
Hide file tree
Showing 10 changed files with 504 additions and 1 deletion.
3 changes: 2 additions & 1 deletion components/ulp/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ if(ULP_COCPU_IS_RISCV)
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_uart.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_print.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c")
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_touch.c")

target_link_options(${ULP_APP_NAME} PRIVATE "-nostartfiles")
target_link_options(${ULP_APP_NAME} PRIVATE -Wl,--gc-sections)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

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

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Read raw data of touch sensor on the ULP RISC-V core
* @note Refer `touch_pad_read_raw_data()` for more details
*
* @param touch_num Touch pad index
* @param raw_data Pointer to accept touch sensor value
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_read_raw_data(touch_pad_t touch_num, uint32_t *raw_data);

/**
* @brief Read benchmark of touch sensor on the ULP RISC-V core
* @note Refer `touch_pad_read_benchmark()` for more details
*
* @param touch_num Touch pad index
* @param benchmark Pointer to accept touch sensor benchmark value
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_read_benchmark(touch_pad_t touch_num, uint32_t *benchmark);

/**
* @brief Read the filtered (smoothened) touch sensor data on the ULP RISC-V core
* @note Refer `touch_pad_filter_read_smooth()` for more details
*
* @param touch_num Touch pad index
* @param smooth_data Pointer to accept smoothened touch sensor value
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_filter_read_smooth(touch_pad_t touch_num, uint32_t *smooth_data);

/**
* @brief Force reset benchmark to raw data of touch sensor.
* @note Refer `touch_pad_reset_benchmark()` for more details
*
* @param touch_num Touch pad index (TOUCH_PAD_MAX resets basaline of all channels)
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_reset_benchmark(touch_pad_t touch_num);

/**
* @brief Read raw data of touch sensor sleep channel on the ULP RISC-V core
* @note Refer `touch_pad_sleep_channel_read_data()` for more details
*
* @param touch_num Touch pad index (Only one touch sensor channel is supported in deep sleep)
* @param raw_data Pointer to accept touch sensor value
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_sleep_channel_read_data(touch_pad_t touch_num, uint32_t *raw_data);

/**
* @brief Read benchmark of touch sensor sleep channel on the ULP RISC-V core
* @note Refer `touch_pad_sleep_channel_read_benchmark()` for more details
*
* @param touch_num Touch pad index (Only one touch sensor channel is supported in deep sleep)
* @param benchmark Pointer to accept touch sensor benchmark value
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_sleep_channel_read_benchmark(touch_pad_t touch_num, uint32_t *benchmark);

/**
* @brief Read the filtered (smoothened) touch sensor sleep channel data on the ULP RISC-V core
* @note Refer `touch_pad_sleep_channel_read_smooth()` for more details
*
* @param touch_num Touch pad index (Only one touch sensor channel is supported in deep sleep)
* @param smooth_data Pointer to accept smoothened touch sensor value
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_sleep_channel_read_smooth(touch_pad_t touch_num, uint32_t *smooth_data);


/**
* @brief Reset benchmark of touch sensor sleep channel.
* @note Refer `touch_pad_sleep_channel_reset_benchmark()` for more details
*
* @return esp_err_t ESP_OK when successful
*/
esp_err_t ulp_riscv_touch_pad_sleep_channel_reset_benchmark(void);

#ifdef __cplusplus
}
#endif
125 changes: 125 additions & 0 deletions components/ulp/ulp_riscv/ulp_core/ulp_riscv_touch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "ulp_riscv_touch_ulp_core.h"
#include "soc/soc_caps.h"
#include "soc/touch_sensor_pins.h"
#include "hal/touch_sensor_hal.h"

/* Check Touch Channel correctness */
#define ULP_RISCV_TOUCH_CHANNEL_CHECK_AND_RETURN(channel) \
{ \
if (channel >= SOC_TOUCH_SENSOR_NUM || \
channel < 0 || \
channel == SOC_TOUCH_DENOISE_CHANNEL) { \
return ESP_ERR_INVALID_ARG; \
} \
} \

esp_err_t ulp_riscv_touch_pad_read_raw_data(touch_pad_t touch_num, uint32_t *raw_data)
{
/* Check Arguments */
if (!raw_data) {
return ESP_ERR_INVALID_ARG;
}
ULP_RISCV_TOUCH_CHANNEL_CHECK_AND_RETURN(touch_num);

/* Read raw touch data */
*raw_data = touch_hal_read_raw_data(touch_num);

return ESP_OK;
}

esp_err_t ulp_riscv_touch_pad_read_benchmark(touch_pad_t touch_num, uint32_t *benchmark)
{
/* Check Arguments */
if (!benchmark) {
return ESP_ERR_INVALID_ARG;
}
ULP_RISCV_TOUCH_CHANNEL_CHECK_AND_RETURN(touch_num);

/* Read benchmark data */
touch_hal_read_benchmark(touch_num, benchmark);

return ESP_OK;
}

esp_err_t ulp_riscv_touch_pad_filter_read_smooth(touch_pad_t touch_num, uint32_t *smooth_data)
{
/* Check Arguments */
if (!smooth_data) {
return ESP_ERR_INVALID_ARG;
}
ULP_RISCV_TOUCH_CHANNEL_CHECK_AND_RETURN(touch_num);

/* Read smoothened touch sensor data */
touch_hal_filter_read_smooth(touch_num, smooth_data);

return ESP_OK;
}

esp_err_t ulp_riscv_touch_pad_reset_benchmark(touch_pad_t touch_num)
{
/* Check Arguments */
if (touch_num > TOUCH_PAD_MAX || touch_num < 0) {
return ESP_ERR_INVALID_ARG;
}

/* Reset benchmark */
touch_hal_reset_benchmark(touch_num);

return ESP_OK;
}

esp_err_t ulp_riscv_touch_pad_sleep_channel_read_data(touch_pad_t touch_num, uint32_t *raw_data)
{
/* Check Arguments */
if (!raw_data) {
return ESP_ERR_INVALID_ARG;
}
ULP_RISCV_TOUCH_CHANNEL_CHECK_AND_RETURN(touch_num);

/* Read raw touch data */
touch_hal_sleep_read_data(raw_data);

return ESP_OK;
}

esp_err_t ulp_riscv_touch_pad_sleep_channel_read_benchmark(touch_pad_t touch_num, uint32_t *benchmark)
{
/* Check Arguments */
if (!benchmark) {
return ESP_ERR_INVALID_ARG;
}
ULP_RISCV_TOUCH_CHANNEL_CHECK_AND_RETURN(touch_num);

/* Read benchmark data */
touch_hal_sleep_read_benchmark(benchmark);

return ESP_OK;
}

esp_err_t ulp_riscv_touch_pad_sleep_channel_read_smooth(touch_pad_t touch_num, uint32_t *smooth_data)
{
/* Check Arguments */
if (!smooth_data) {
return ESP_ERR_INVALID_ARG;
}
ULP_RISCV_TOUCH_CHANNEL_CHECK_AND_RETURN(touch_num);

/* Read smoothened touch sensor data */
touch_hal_sleep_read_smooth(smooth_data);

return ESP_OK;
}

esp_err_t ulp_riscv_touch_pad_sleep_channel_reset_benchmark(void)
{
/* Reset benchmark */
touch_hal_sleep_reset_benchmark();

return ESP_OK;
}
4 changes: 4 additions & 0 deletions examples/system/.build-test-rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ examples/system/ulp/ulp_riscv/i2c:
enable:
- if: SOC_RISCV_COPROC_SUPPORTED == 1

examples/system/ulp/ulp_riscv/touch:
enable:
- if: SOC_RISCV_COPROC_SUPPORTED == 1

examples/system/ulp/ulp_riscv/uart_print:
enable:
- if: SOC_RISCV_COPROC_SUPPORTED == 1
Expand Down
6 changes: 6 additions & 0 deletions examples/system/ulp/ulp_riscv/touch/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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_example)
48 changes: 48 additions & 0 deletions examples/system/ulp/ulp_riscv/touch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
| Supported Targets | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- |

# ULP-RISC-V Touch Sensor example:

This example demonstrates how to program the ULP RISC-V coprocessor to read touch pad sensors.

ULP program written in C can be found across `ulp/main.c`. The build system compiles and links this program, converts it into binary format, and embeds it into the .rodata section of the ESP-IDF application.

At runtime, the application running inside the main CPU loads ULP program into the `RTC_SLOW_MEM` memory region using `ulp_riscv_load_binary` function. The main code then configures the ULP wakeup period and starts the coprocessor by using `ulp_riscv_run`. Once the ULP program is started, it runs periodically, with the period set by the main program. The main program enables ULP wakeup source and puts the chip into deep sleep mode.

The ULP Program scans all touch pad sensors periodically. When the ULP program finds a touch pad is active (touched), it captures the touch pad number in a variable and wakes up the main CPU. The main CPU reports which touch pad sensor was touched.

## How to use the example

### Hardware Required

* A development board with ESP32-S2 or ESP32-S3

### Build and Flash

Build the project and flash it to the board, then run monitor tool to view serial output:

```
idf.py -p PORT flash monitor
```

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type ``Ctrl-]``.)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

## Example output

```
Not a ULP wakeup, initializing it!
Entering in deep sleep
...
ULP-RISC-V woke up the main CPU!
T3 touched
T4 touched
Entering in deep sleep
```
25 changes: 25 additions & 0 deletions examples/system/ulp/ulp_riscv/touch/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Register the component
idf_component_register(SRCS "ulp_riscv_touch_example_main.c"
INCLUDE_DIRS ""
REQUIRES ulp)

#
# 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_touch_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}")
Loading

0 comments on commit 4b35e00

Please sign in to comment.