diff --git a/esphome/components/esp32_touch/__init__.py b/esphome/components/esp32_touch/__init__.py index cdf6aa3abd..b1bea345f1 100644 --- a/esphome/components/esp32_touch/__init__.py +++ b/esphome/components/esp32_touch/__init__.py @@ -11,6 +11,12 @@ from esphome.const import ( CONF_VOLTAGE_ATTENUATION, ) from esphome.core import TimePeriod +from esphome.components.esp32 import get_esp32_variant +from esphome.components.esp32.const import ( + VARIANT_ESP32, + VARIANT_ESP32S2, + VARIANT_ESP32S3, +) AUTO_LOAD = ["binary_sensor"] DEPENDENCIES = ["esp32"] @@ -50,30 +56,41 @@ VOLTAGE_ATTENUATION = { "0V": cg.global_ns.TOUCH_HVOLT_ATTEN_0V, } -CONFIG_SCHEMA = cv.Schema( - { - cv.GenerateID(): cv.declare_id(ESP32TouchComponent), - cv.Optional(CONF_SETUP_MODE, default=False): cv.boolean, - cv.Optional( - CONF_IIR_FILTER, default="0ms" - ): cv.positive_time_period_milliseconds, - cv.Optional(CONF_SLEEP_DURATION, default="27306us"): cv.All( - cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=436906)) - ), - cv.Optional(CONF_MEASUREMENT_DURATION, default="8192us"): cv.All( - cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=8192)) - ), - cv.Optional(CONF_LOW_VOLTAGE_REFERENCE, default="0.5V"): validate_voltage( - LOW_VOLTAGE_REFERENCE - ), - cv.Optional(CONF_HIGH_VOLTAGE_REFERENCE, default="2.7V"): validate_voltage( - HIGH_VOLTAGE_REFERENCE - ), - cv.Optional(CONF_VOLTAGE_ATTENUATION, default="0V"): validate_voltage( - VOLTAGE_ATTENUATION - ), - } -).extend(cv.COMPONENT_SCHEMA) + +def _validate_variant(value): + variant = get_esp32_variant() + if variant not in [VARIANT_ESP32, VARIANT_ESP32S2, VARIANT_ESP32S3]: + raise cv.Invalid(f"ESP32 variant {variant} does not support touch pads") + return value + + +CONFIG_SCHEMA = cv.All( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(ESP32TouchComponent), + cv.Optional(CONF_SETUP_MODE, default=False): cv.boolean, + cv.Optional( + CONF_IIR_FILTER, default="0ms" + ): cv.positive_time_period_milliseconds, + cv.Optional(CONF_SLEEP_DURATION, default="27306us"): cv.All( + cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=436906)) + ), + cv.Optional(CONF_MEASUREMENT_DURATION, default="8192us"): cv.All( + cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=8192)) + ), + cv.Optional(CONF_LOW_VOLTAGE_REFERENCE, default="0.5V"): validate_voltage( + LOW_VOLTAGE_REFERENCE + ), + cv.Optional(CONF_HIGH_VOLTAGE_REFERENCE, default="2.7V"): validate_voltage( + HIGH_VOLTAGE_REFERENCE + ), + cv.Optional(CONF_VOLTAGE_ATTENUATION, default="0V"): validate_voltage( + VOLTAGE_ATTENUATION + ), + } + ).extend(cv.COMPONENT_SCHEMA), + _validate_variant, +) async def to_code(config): diff --git a/esphome/components/esp32_touch/esp32_touch.cpp b/esphome/components/esp32_touch/esp32_touch.cpp index cb72820900..78d0bb9df2 100644 --- a/esphome/components/esp32_touch/esp32_touch.cpp +++ b/esphome/components/esp32_touch/esp32_touch.cpp @@ -1,6 +1,6 @@ -#ifdef USE_ESP32 - #include "esp32_touch.h" +#ifdef USE_ESP32_TOUCH_HAS_HARDWARE + #include "esphome/core/log.h" #include "esphome/core/hal.h" @@ -165,4 +165,4 @@ ESP32TouchBinarySensor::ESP32TouchBinarySensor(touch_pad_t touch_pad, uint16_t t } // namespace esp32_touch } // namespace esphome -#endif +#endif // USE_ESP32_TOUCH_HAS_HARDWARE diff --git a/esphome/components/esp32_touch/esp32_touch.h b/esphome/components/esp32_touch/esp32_touch.h index d49e4703a7..070f42bbb8 100644 --- a/esphome/components/esp32_touch/esp32_touch.h +++ b/esphome/components/esp32_touch/esp32_touch.h @@ -1,6 +1,10 @@ #pragma once -#ifdef USE_ESP32 +#if defined(USE_ESP32_VARIANT_ESP32) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#define USE_ESP32_TOUCH_HAS_HARDWARE +#endif + +#ifdef USE_ESP32_TOUCH_HAS_HARDWARE #include "esphome/core/component.h" #include "esphome/components/binary_sensor/binary_sensor.h" @@ -84,4 +88,4 @@ class ESP32TouchBinarySensor : public binary_sensor::BinarySensor { } // namespace esp32_touch } // namespace esphome -#endif +#endif // USE_ESP32_TOUCH_HAS_HARDWARE diff --git a/esphome/components/pulse_counter/pulse_counter_sensor.cpp b/esphome/components/pulse_counter/pulse_counter_sensor.cpp index f538a4c905..5696628310 100644 --- a/esphome/components/pulse_counter/pulse_counter_sensor.cpp +++ b/esphome/components/pulse_counter/pulse_counter_sensor.cpp @@ -8,7 +8,7 @@ static const char *const TAG = "pulse_counter"; const char *const EDGE_MODE_TO_STRING[] = {"DISABLE", "INCREMENT", "DECREMENT"}; -#ifdef USE_ESP8266 +#ifndef USE_PULSE_COUNTER_ESP32_PERIPH void IRAM_ATTR PulseCounterStorage::gpio_intr(PulseCounterStorage *arg) { const uint32_t now = micros(); const bool discard = now - arg->last_pulse < arg->filter_us; @@ -41,9 +41,9 @@ pulse_counter_t PulseCounterStorage::read_raw_value() { this->last_value = counter; return ret; } -#endif +#endif // !USE_PULSE_COUNTER_ESP32_PERIPH -#ifdef USE_ESP32 +#ifdef USE_PULSE_COUNTER_ESP32_PERIPH bool PulseCounterStorage::pulse_counter_setup(InternalGPIOPin *pin) { static pcnt_unit_t next_pcnt_unit = PCNT_UNIT_0; this->pin = pin; @@ -134,7 +134,7 @@ pulse_counter_t PulseCounterStorage::read_raw_value() { this->last_value = counter; return ret; } -#endif +#endif // USE_PULSE_COUNTER_ESP32_PERIPH void PulseCounterSensor::setup() { ESP_LOGCONFIG(TAG, "Setting up pulse counter '%s'...", this->name_.c_str()); diff --git a/esphome/components/pulse_counter/pulse_counter_sensor.h b/esphome/components/pulse_counter/pulse_counter_sensor.h index 94e37bc232..450a8c1ecb 100644 --- a/esphome/components/pulse_counter/pulse_counter_sensor.h +++ b/esphome/components/pulse_counter/pulse_counter_sensor.h @@ -4,7 +4,11 @@ #include "esphome/core/hal.h" #include "esphome/components/sensor/sensor.h" -#ifdef USE_ESP32 +#if defined(USE_ESP32_VARIANT_ESP32) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#define USE_PULSE_COUNTER_ESP32_PERIPH +#endif + +#ifdef USE_PULSE_COUNTER_ESP32_PERIPH #include #endif @@ -17,10 +21,9 @@ enum PulseCounterCountMode { PULSE_COUNTER_DECREMENT, }; -#ifdef USE_ESP32 +#ifdef USE_PULSE_COUNTER_ESP32_PERIPH using pulse_counter_t = int16_t; -#endif -#ifdef USE_ESP8266 +#else using pulse_counter_t = int32_t; #endif @@ -30,16 +33,15 @@ struct PulseCounterStorage { static void gpio_intr(PulseCounterStorage *arg); -#ifdef USE_ESP8266 +#ifndef USE_PULSE_COUNTER_ESP32_PERIPH volatile pulse_counter_t counter{0}; volatile uint32_t last_pulse{0}; #endif InternalGPIOPin *pin; -#ifdef USE_ESP32 +#ifdef USE_PULSE_COUNTER_ESP32_PERIPH pcnt_unit_t pcnt_unit; -#endif -#ifdef USE_ESP8266 +#else ISRInternalGPIOPin isr_pin; #endif PulseCounterCountMode rising_edge_mode{PULSE_COUNTER_INCREMENT}; diff --git a/esphome/components/pulse_counter/sensor.py b/esphome/components/pulse_counter/sensor.py index c7b89d41b0..c9b68d5e97 100644 --- a/esphome/components/pulse_counter/sensor.py +++ b/esphome/components/pulse_counter/sensor.py @@ -18,6 +18,12 @@ from esphome.const import ( UNIT_PULSES, ) from esphome.core import CORE +from esphome.components.esp32 import get_esp32_variant +from esphome.components.esp32.const import ( + VARIANT_ESP32, + VARIANT_ESP32S2, + VARIANT_ESP32S3, +) pulse_counter_ns = cg.esphome_ns.namespace("pulse_counter") PulseCounterCountMode = pulse_counter_ns.enum("PulseCounterCountMode") @@ -33,10 +39,12 @@ PulseCounterSensor = pulse_counter_ns.class_( "PulseCounterSensor", sensor.Sensor, cg.PollingComponent ) +ESP32_VARIANTS_WITH_PCNT = [VARIANT_ESP32, VARIANT_ESP32S2, VARIANT_ESP32S3] + def validate_internal_filter(value): value = cv.positive_time_period_microseconds(value) - if CORE.is_esp32: + if CORE.is_esp32 and ESP32_VARIANTS_WITH_PCNT in get_esp32_variant(): if value.total_microseconds > 13: raise cv.Invalid("Maximum internal filter value for ESP32 is 13us") return value diff --git a/platformio.ini b/platformio.ini index ee895ed882..15c2ebbabc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -131,12 +131,14 @@ extends = common:esp32-arduino build_flags = ${common:esp32-arduino.build_flags} ${runtime.build_flags} + -DUSE_ESP32_VARIANT_ESP32 [env:esp32-tidy] extends = common:esp32-arduino build_flags = ${common:esp32-arduino.build_flags} ${clangtidy.build_flags} + -DUSE_ESP32_VARIANT_ESP32 [env:esp32-idf] extends = common:esp32-idf @@ -144,6 +146,7 @@ board_build.esp-idf.sdkconfig_path = .temp/sdkconfig-esp32-idf build_flags = ${common:esp32-idf.build_flags} ${runtime.build_flags} + -DUSE_ESP32_VARIANT_ESP32 [env:esp32-idf-tidy] extends = common:esp32-idf @@ -151,3 +154,40 @@ board_build.esp-idf.sdkconfig_path = .temp/sdkconfig-esp32-idf-tidy build_flags = ${common:esp32-idf.build_flags} ${clangtidy.build_flags} + -DUSE_ESP32_VARIANT_ESP32 + +[env:esp32s2-idf] +extends = common:esp32-idf +board = esp32-s2-kaluga-1 +board_build.esp-idf.sdkconfig_path = .temp/sdkconfig-esp32s2-idf +build_flags = + ${common:esp32-idf.build_flags} + ${runtime.build_flags} + -DUSE_ESP32_VARIANT_ESP32S2 + +[env:esp32s2-idf-tidy] +extends = common:esp32-idf +board = esp32-s2-kaluga-1 +board_build.esp-idf.sdkconfig_path = .temp/sdkconfig-esp32s2-idf-tidy +build_flags = + ${common:esp32-idf.build_flags} + ${clangtidy.build_flags} + -DUSE_ESP32_VARIANT_ESP32S2 + +[env:esp32c3-idf] +extends = common:esp32-idf +board = esp32-c3-devkitm-1 +board_build.esp-idf.sdkconfig_path = .temp/sdkconfig-esp32c3-idf +build_flags = + ${common:esp32-idf.build_flags} + ${runtime.build_flags} + -DUSE_ESP32_VARIANT_ESP32C3 + +[env:esp32c3-idf-tidy] +extends = common:esp32-idf +board = esp32-c3-devkitm-1 +board_build.esp-idf.sdkconfig_path = .temp/sdkconfig-esp32c3-idf-tidy +build_flags = + ${common:esp32-idf.build_flags} + ${clangtidy.build_flags} + -DUSE_ESP32_VARIANT_ESP32C3 diff --git a/script/clang-tidy b/script/clang-tidy index 87ba1c84b5..44ad0a30db 100755 --- a/script/clang-tidy +++ b/script/clang-tidy @@ -20,7 +20,7 @@ from helpers import shlex_quote, get_output, filter_grep, \ build_all_include, temp_header_file, git_ls_files, filter_changed, load_idedata, basepath -def clang_options(idedata): +def clang_options(idedata, env_name: str): cmd = [ # target 32-bit arch (this prevents size mismatch errors on a 64-bit host) '-m32', @@ -42,31 +42,95 @@ def clang_options(idedata): # suppress warning about attribute cannot be applied to type # https://github.com/esp8266/Arduino/pull/8258 '-Ddeprecated(x)=', - # pretend we're an Xtensa compiler, which gates some features in the headers - '-D__XTENSA__', # allow to condition code on the presence of clang-tidy '-DCLANG_TIDY', - # (esp-idf) Disable this header because they use asm with registers clang-tidy doesn't know - '-D__XTENSA_API_H__', # (esp-idf) Fix __once_callable in some libstdc++ headers '-D_GLIBCXX_HAVE_TLS', ] + defines = idedata["defines"] + + if 'c3' not in env_name: + cmd += [ + # pretend we're an Xtensa compiler, which gates some features in the headers + '-D__XTENSA__', + # (esp-idf) Disable this header because they use asm with registers clang-tidy doesn't know + '-D__XTENSA_API_H__', + ] + else: + cmd += [ + "-D_GLIBCXX_GCC_GTHR_POSIX_H", + "-D__gthread_mutex_lock(a)=0", + "-D__gthread_recursive_mutex_unlock(a)=0", + "-D__gthread_recursive_mutex_trylock(a)=0", + "-D__gthread_recursive_mutex_destroy(a)=0", + "-D__gthread_recursive_mutex_lock(a)=0", + "-D__gthread_recursive_mutex_timedlock(a,b)=0", + "-D__gthread_recursive_mutex_t=int", + "-D__gthread_mutex_t=int", + "-D__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(a)=0", + "-D__GTHREAD_MUTEX_INIT_FUNCTION(a)=0", + "-D__gthread_mutex_destroy(a)=0", + "-D__gthread_mutex_trylock(a)=0", + "-D__gthread_mutex_unlock(a)=0", + "-D__gthread_mutex_timedlock(a,b)=0", + "-D__gthread_time_t=struct timespec", + "-D__gthread_once_t=int", + "-D__gthread_once(a,b)=0", + "-D__GTHREAD_ONCE_INIT=0", + ] + # copy compiler flags, except those clang doesn't understand. cmd.extend(flag for flag in idedata['cxx_flags'].split(' ') if flag not in ('-free', '-fipa-pta', '-fstrict-volatile-bitfields', '-mlongcalls', '-mtext-section-literals', - '-mfix-esp32-psram-cache-issue', '-mfix-esp32-psram-cache-strategy=memw')) + '-mfix-esp32-psram-cache-issue', '-mfix-esp32-psram-cache-strategy=memw', + '-march=rv32imc')) # defines - cmd.extend(f'-D{define}' for define in idedata['defines']) + cmd.extend(f'-D{define}' for define in defines) # add include directories, using -isystem for dependencies to suppress their errors - for directory in idedata['includes']['toolchain']: - if 'xtensa-esp32s2-elf' not in directory: - cmd.extend(['-isystem', directory]) + system_includes = idedata['includes']['toolchain'] + + # if esp32s2 or esp32c3 were installed on the computer at _any_ time + # the toolchain includes will contain the headers, even if the env + # is not based on those chips + variant_toolchains = { + "USE_ESP32_VARIANT_ESP32": "toolchain-xtensa32", + "USE_ESP32_VARIANT_ESP32S2": "toolchain-xtensa32s2", + "USE_ESP32_VARIANT_ESP32C3": "toolchain-riscv-esp", + } + for variant_define in variant_toolchains: + if variant_define not in defines: + continue + # Filter out the other toolchains + for var, toolchain in variant_toolchains.items(): + if var == variant_define: + continue + # Try to match directories like + # ~/.platformio/packages/toolchain-xtensa32@2.50200.97/... + # or ~/.platformio/packages/toolchain-xtensa32/... + # or with windows backslash paths + pattern = r".*[/\\]{}[/\\@].*".format(toolchain) + system_includes = [ + inc for inc in system_includes + if re.match(pattern, inc) is None + ] + + for inc in system_includes: + cmd.extend(['-isystem', inc]) + for directory in sorted(set(idedata['includes']['build'])): - dependency = "framework-arduino" in directory or "/libdeps/" in directory + dependency = any(x in directory for x in [ + "framework-arduino", + "framework-espidf", + "/libdeps/", + "\\libdeps\\", + # globally installed libs + "/.platformio/lib/", + "\\.platformio\\lib\\", + ]) or directory.endswith("config") cmd.extend(['-isystem' if dependency else '-I', directory]) return cmd @@ -155,7 +219,7 @@ def main(): return 1 idedata = load_idedata(args.environment) - options = clang_options(idedata) + options = clang_options(idedata, args.environment) files = [] for path in git_ls_files(['*.cpp']):