mirror of
https://github.com/esphome/esphome.git
synced 2024-12-02 11:44:13 +01:00
pulse_counter: Add ULP sources from Platformio example
Source: https://github.com/platformio/platform-espressif32/tree/develop/examples/espidf-ulp-pulse
This commit is contained in:
parent
349dc506ce
commit
49b4169f51
4 changed files with 227 additions and 2 deletions
|
@ -1,3 +1,27 @@
|
||||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
|
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
|
||||||
|
|
||||||
idf_component_register(SRCS ${app_sources})
|
idf_component_register(SRCS ${app_sources}
|
||||||
|
INCLUDE_DIRS ""
|
||||||
|
REQUIRES driver soc nvs_flash 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_main)
|
||||||
|
##
|
||||||
|
## 2. Specify all assembly source files.
|
||||||
|
## Files should be placed into a separate directory (in this case, ulp/),
|
||||||
|
## which should not be added to COMPONENT_SRCS.
|
||||||
|
##TODO
|
||||||
|
set(ulp_s_sources "../ulp/pulse_cnt.S" "../ulp/wake_up.S")
|
||||||
|
##
|
||||||
|
## 3. List all the component source files which include automatically
|
||||||
|
## generated ULP export file, ${ulp_app_name}.h:
|
||||||
|
set(ulp_exp_dep_srcs "components/pulse_counter/pulse_counter_sensor.cpp")
|
||||||
|
##
|
||||||
|
## 4. Call function to build ULP binary and embed in project using the argument
|
||||||
|
## values above.
|
||||||
|
ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}")
|
||||||
|
#
|
||||||
|
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||||
|
|
|
@ -138,7 +138,16 @@ async def to_code(config):
|
||||||
"src/CMakeLists.txt",
|
"src/CMakeLists.txt",
|
||||||
os.path.join(os.path.dirname(__file__), "CMakeLists.txt"),
|
os.path.join(os.path.dirname(__file__), "CMakeLists.txt"),
|
||||||
)
|
)
|
||||||
var = await sensor.new_sensor(config, config.get(CONF_USE_PCNT))
|
esp32.add_extra_build_file(
|
||||||
|
"ulp/pulse_cnt.S",
|
||||||
|
os.path.join(os.path.dirname(__file__), "ulp/pulse_cnt.S"),
|
||||||
|
)
|
||||||
|
esp32.add_extra_build_file(
|
||||||
|
"ulp/wake_up.S", os.path.join(os.path.dirname(__file__), "ulp/wake_up.S")
|
||||||
|
)
|
||||||
|
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_ENABLED", True)
|
||||||
|
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_TYPE_FSM", True)
|
||||||
|
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_RESERVE_MEM", 1024)
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
|
||||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||||
|
|
161
esphome/components/pulse_counter/ulp/pulse_cnt.S
Normal file
161
esphome/components/pulse_counter/ulp/pulse_cnt.S
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
/* ULP Example: pulse counting
|
||||||
|
|
||||||
|
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 file contains assembly code which runs on the ULP.
|
||||||
|
|
||||||
|
ULP wakes up to run this code at a certain period, determined by the values
|
||||||
|
in SENS_ULP_CP_SLEEP_CYCx_REG registers. On each wake up, the program checks
|
||||||
|
the input on GPIO0. If the value is different from the previous one, the
|
||||||
|
program "debounces" the input: on the next debounce_max_count wake ups,
|
||||||
|
it expects to see the same value of input.
|
||||||
|
If this condition holds true, the program increments edge_count and starts
|
||||||
|
waiting for input signal polarity to change again.
|
||||||
|
When the edge counter reaches certain value (set by the main program),
|
||||||
|
this program running triggers a wake up from deep sleep.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ULP assembly files are passed through C preprocessor first, so include directives
|
||||||
|
and C macros may be used in these files
|
||||||
|
*/
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "soc/rtc_io_reg.h"
|
||||||
|
#include "soc/soc_ulp.h"
|
||||||
|
#include "soc/sens_reg.h"
|
||||||
|
|
||||||
|
/* Define variables, which go into .bss section (zero-initialized data) */
|
||||||
|
.bss
|
||||||
|
/* Next input signal edge expected: 0 (negative) or 1 (positive) */
|
||||||
|
.global next_edge
|
||||||
|
next_edge:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* Counter started when signal value changes.
|
||||||
|
Edge is "debounced" when the counter reaches zero. */
|
||||||
|
.global debounce_counter
|
||||||
|
debounce_counter:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* Value to which debounce_counter gets reset.
|
||||||
|
Set by the main program. */
|
||||||
|
.global debounce_max_count
|
||||||
|
debounce_max_count:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* Total number of signal edges acquired */
|
||||||
|
.global edge_count
|
||||||
|
edge_count:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* Number of edges to acquire before waking up the SoC.
|
||||||
|
Set by the main program. */
|
||||||
|
.global edge_count_to_wake_up
|
||||||
|
edge_count_to_wake_up:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* RTC IO number used to sample the input signal.
|
||||||
|
Set by main program. */
|
||||||
|
.global io_number
|
||||||
|
io_number:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
/* Code goes into .text section */
|
||||||
|
.text
|
||||||
|
.global entry
|
||||||
|
entry:
|
||||||
|
/* Load io_number */
|
||||||
|
move r3, io_number
|
||||||
|
ld r3, r3, 0
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
/* ESP32S2 powers down RTC periph when entering deep sleep and thus by association SENS_SAR_IO_MUX_CONF_REG */
|
||||||
|
WRITE_RTC_FIELD(SENS_SAR_IO_MUX_CONF_REG, SENS_IOMUX_CLK_GATE_EN, 1)
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
/* ESP32S3 powers down RTC periph when entering deep sleep and thus by association SENS_SAR_PERI_CLK_GATE_CONF_REG */
|
||||||
|
WRITE_RTC_FIELD(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Lower 16 IOs and higher need to be handled separately,
|
||||||
|
* because r0-r3 registers are 16 bit wide.
|
||||||
|
* Check which IO this is.
|
||||||
|
*/
|
||||||
|
move r0, r3
|
||||||
|
jumpr read_io_high, 16, ge
|
||||||
|
|
||||||
|
/* Read the value of lower 16 RTC IOs into R0 */
|
||||||
|
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S, 16)
|
||||||
|
rsh r0, r0, r3
|
||||||
|
jump read_done
|
||||||
|
|
||||||
|
/* Read the value of RTC IOs 16-17, into R0 */
|
||||||
|
read_io_high:
|
||||||
|
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 16, 2)
|
||||||
|
sub r3, r3, 16
|
||||||
|
rsh r0, r0, r3
|
||||||
|
|
||||||
|
read_done:
|
||||||
|
and r0, r0, 1
|
||||||
|
/* State of input changed? */
|
||||||
|
move r3, next_edge
|
||||||
|
ld r3, r3, 0
|
||||||
|
add r3, r0, r3
|
||||||
|
and r3, r3, 1
|
||||||
|
jump changed, eq
|
||||||
|
/* Not changed */
|
||||||
|
/* Reset debounce_counter to debounce_max_count */
|
||||||
|
move r3, debounce_max_count
|
||||||
|
move r2, debounce_counter
|
||||||
|
ld r3, r3, 0
|
||||||
|
st r3, r2, 0
|
||||||
|
/* End program */
|
||||||
|
halt
|
||||||
|
|
||||||
|
.global changed
|
||||||
|
changed:
|
||||||
|
/* Input state changed */
|
||||||
|
/* Has debounce_counter reached zero? */
|
||||||
|
move r3, debounce_counter
|
||||||
|
ld r2, r3, 0
|
||||||
|
add r2, r2, 0 /* dummy ADD to use "jump if ALU result is zero" */
|
||||||
|
jump edge_detected, eq
|
||||||
|
/* Not yet. Decrement debounce_counter */
|
||||||
|
sub r2, r2, 1
|
||||||
|
st r2, r3, 0
|
||||||
|
/* End program */
|
||||||
|
halt
|
||||||
|
|
||||||
|
.global edge_detected
|
||||||
|
edge_detected:
|
||||||
|
/* Reset debounce_counter to debounce_max_count */
|
||||||
|
move r3, debounce_max_count
|
||||||
|
move r2, debounce_counter
|
||||||
|
ld r3, r3, 0
|
||||||
|
st r3, r2, 0
|
||||||
|
/* Flip next_edge */
|
||||||
|
move r3, next_edge
|
||||||
|
ld r2, r3, 0
|
||||||
|
add r2, r2, 1
|
||||||
|
and r2, r2, 1
|
||||||
|
st r2, r3, 0
|
||||||
|
/* Increment edge_count */
|
||||||
|
move r3, edge_count
|
||||||
|
ld r2, r3, 0
|
||||||
|
add r2, r2, 1
|
||||||
|
st r2, r3, 0
|
||||||
|
/* Compare edge_count to edge_count_to_wake_up */
|
||||||
|
move r3, edge_count_to_wake_up
|
||||||
|
ld r3, r3, 0
|
||||||
|
sub r3, r3, r2
|
||||||
|
jump wake_up, eq
|
||||||
|
/* Not yet. End program */
|
||||||
|
halt
|
31
esphome/components/pulse_counter/ulp/wake_up.S
Normal file
31
esphome/components/pulse_counter/ulp/wake_up.S
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
/* ULP assembly files are passed through C preprocessor first, so include directives
|
||||||
|
and C macros may be used in these files
|
||||||
|
*/
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "soc/soc_ulp.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
.global wake_up
|
||||||
|
wake_up:
|
||||||
|
/* Check if the system is in sleep mode */
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
READ_RTC_REG(RTC_CNTL_LOW_POWER_ST_REG, 27, 1)
|
||||||
|
#else
|
||||||
|
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_MAIN_STATE_IN_IDLE)
|
||||||
|
#endif
|
||||||
|
move r1, r0
|
||||||
|
/* Check if the system can be woken up */
|
||||||
|
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP)
|
||||||
|
/* If the system is in normal mode or if the system is in sleep mode with ready for wakeup set, we can signal the main CPU to wakeup */
|
||||||
|
or r0, r0, r1
|
||||||
|
jump wake_up, eq
|
||||||
|
|
||||||
|
/* Wake up the SoC, end program */
|
||||||
|
wake
|
||||||
|
halt
|
||||||
|
|
Loading…
Reference in a new issue