mirror of
https://github.com/esphome/esphome.git
synced 2026-05-27 03:36:19 +08:00
[esp32_rmt] Handle ESP32 variants without RMT hardware (#14001)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,30 @@
|
|||||||
from esphome.components import esp32
|
from esphome.components import esp32
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
CODEOWNERS = ["@jesserockz"]
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
|
||||||
|
VARIANTS_NO_RMT = {esp32.VARIANT_ESP32C2, esp32.VARIANT_ESP32C61}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_rmt_not_supported(rmt_only_keys):
|
||||||
|
"""Validate that RMT-only config keys are not used on variants without RMT hardware."""
|
||||||
|
rmt_only_keys = set(rmt_only_keys)
|
||||||
|
|
||||||
|
def _validator(config):
|
||||||
|
if CORE.is_esp32:
|
||||||
|
variant = esp32.get_esp32_variant()
|
||||||
|
if variant in VARIANTS_NO_RMT:
|
||||||
|
unsupported = rmt_only_keys.intersection(config)
|
||||||
|
if unsupported:
|
||||||
|
keys = ", ".join(sorted(f"'{k}'" for k in unsupported))
|
||||||
|
raise cv.Invalid(
|
||||||
|
f"{keys} not available on {variant} (no RMT hardware)"
|
||||||
|
)
|
||||||
|
return config
|
||||||
|
|
||||||
|
return _validator
|
||||||
|
|
||||||
|
|
||||||
def validate_clock_resolution():
|
def validate_clock_resolution():
|
||||||
def _validator(value):
|
def _validator(value):
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import logging
|
|||||||
|
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import esp32, light
|
from esphome.components import esp32, esp32_rmt, light
|
||||||
from esphome.components.const import CONF_USE_PSRAM
|
from esphome.components.const import CONF_USE_PSRAM
|
||||||
from esphome.components.esp32 import include_builtin_idf_component
|
from esphome.components.esp32 import include_builtin_idf_component
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
@@ -71,6 +71,10 @@ CONF_RESET_LOW = "reset_low"
|
|||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
|
esp32.only_on_variant(
|
||||||
|
unsupported=list(esp32_rmt.VARIANTS_NO_RMT),
|
||||||
|
msg_prefix="ESP32 RMT LED strip",
|
||||||
|
),
|
||||||
light.ADDRESSABLE_LIGHT_SCHEMA.extend(
|
light.ADDRESSABLE_LIGHT_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(ESP32RMTLEDStripLightOutput),
|
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(ESP32RMTLEDStripLightOutput),
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ class RemoteComponentBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
#include <soc/soc_caps.h>
|
||||||
|
#if SOC_RMT_SUPPORTED
|
||||||
class RemoteRMTChannel {
|
class RemoteRMTChannel {
|
||||||
public:
|
public:
|
||||||
void set_clock_resolution(uint32_t clock_resolution) { this->clock_resolution_ = clock_resolution; }
|
void set_clock_resolution(uint32_t clock_resolution) { this->clock_resolution_ = clock_resolution; }
|
||||||
@@ -137,7 +139,8 @@ class RemoteRMTChannel {
|
|||||||
uint32_t clock_resolution_{1000000};
|
uint32_t clock_resolution_{1000000};
|
||||||
uint32_t rmt_symbols_;
|
uint32_t rmt_symbols_;
|
||||||
};
|
};
|
||||||
#endif
|
#endif // SOC_RMT_SUPPORTED
|
||||||
|
#endif // USE_ESP32
|
||||||
|
|
||||||
class RemoteTransmitterBase : public RemoteComponentBase {
|
class RemoteTransmitterBase : public RemoteComponentBase {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ RemoteReceiverComponent = remote_receiver_ns.class_(
|
|||||||
def validate_config(config):
|
def validate_config(config):
|
||||||
if CORE.is_esp32:
|
if CORE.is_esp32:
|
||||||
variant = esp32.get_esp32_variant()
|
variant = esp32.get_esp32_variant()
|
||||||
|
if variant in esp32_rmt.VARIANTS_NO_RMT:
|
||||||
|
return config
|
||||||
if variant in (esp32.VARIANT_ESP32, esp32.VARIANT_ESP32S2):
|
if variant in (esp32.VARIANT_ESP32, esp32.VARIANT_ESP32S2):
|
||||||
max_idle = 65535
|
max_idle = 65535
|
||||||
else:
|
else:
|
||||||
@@ -110,6 +112,8 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
|||||||
cv.SplitDefault(
|
cv.SplitDefault(
|
||||||
CONF_BUFFER_SIZE,
|
CONF_BUFFER_SIZE,
|
||||||
esp32="10000b",
|
esp32="10000b",
|
||||||
|
esp32_c2="1000b",
|
||||||
|
esp32_c61="1000b",
|
||||||
esp8266="1000b",
|
esp8266="1000b",
|
||||||
bk72xx="1000b",
|
bk72xx="1000b",
|
||||||
ln882x="1000b",
|
ln882x="1000b",
|
||||||
@@ -131,9 +135,11 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
|||||||
cv.SplitDefault(
|
cv.SplitDefault(
|
||||||
CONF_RMT_SYMBOLS,
|
CONF_RMT_SYMBOLS,
|
||||||
esp32=192,
|
esp32=192,
|
||||||
|
esp32_c2=cv.UNDEFINED,
|
||||||
esp32_c3=96,
|
esp32_c3=96,
|
||||||
esp32_c5=96,
|
esp32_c5=96,
|
||||||
esp32_c6=96,
|
esp32_c6=96,
|
||||||
|
esp32_c61=cv.UNDEFINED,
|
||||||
esp32_h2=96,
|
esp32_h2=96,
|
||||||
esp32_p4=192,
|
esp32_p4=192,
|
||||||
esp32_s2=192,
|
esp32_s2=192,
|
||||||
@@ -145,6 +151,8 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
|||||||
cv.SplitDefault(
|
cv.SplitDefault(
|
||||||
CONF_RECEIVE_SYMBOLS,
|
CONF_RECEIVE_SYMBOLS,
|
||||||
esp32=192,
|
esp32=192,
|
||||||
|
esp32_c2=cv.UNDEFINED,
|
||||||
|
esp32_c61=cv.UNDEFINED,
|
||||||
): cv.All(cv.only_on_esp32, cv.int_range(min=2)),
|
): cv.All(cv.only_on_esp32, cv.int_range(min=2)),
|
||||||
cv.Optional(CONF_USE_DMA): cv.All(
|
cv.Optional(CONF_USE_DMA): cv.All(
|
||||||
esp32.only_on_variant(
|
esp32.only_on_variant(
|
||||||
@@ -152,24 +160,45 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
|||||||
),
|
),
|
||||||
cv.boolean,
|
cv.boolean,
|
||||||
),
|
),
|
||||||
cv.SplitDefault(CONF_CARRIER_DUTY_PERCENT, esp32=100): cv.All(
|
cv.SplitDefault(
|
||||||
|
CONF_CARRIER_DUTY_PERCENT,
|
||||||
|
esp32=100,
|
||||||
|
esp32_c2=cv.UNDEFINED,
|
||||||
|
esp32_c61=cv.UNDEFINED,
|
||||||
|
): cv.All(
|
||||||
cv.only_on_esp32,
|
cv.only_on_esp32,
|
||||||
cv.percentage_int,
|
cv.percentage_int,
|
||||||
cv.Range(min=1, max=100),
|
cv.Range(min=1, max=100),
|
||||||
),
|
),
|
||||||
cv.SplitDefault(CONF_CARRIER_FREQUENCY, esp32="0Hz"): cv.All(
|
cv.SplitDefault(
|
||||||
cv.only_on_esp32, cv.frequency, cv.int_
|
CONF_CARRIER_FREQUENCY,
|
||||||
),
|
esp32="0Hz",
|
||||||
|
esp32_c2=cv.UNDEFINED,
|
||||||
|
esp32_c61=cv.UNDEFINED,
|
||||||
|
): cv.All(cv.only_on_esp32, cv.frequency, cv.int_),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.COMPONENT_SCHEMA)
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.add_extra(
|
||||||
|
esp32_rmt.validate_rmt_not_supported(
|
||||||
|
[
|
||||||
|
CONF_CLOCK_RESOLUTION,
|
||||||
|
CONF_USE_DMA,
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
|
CONF_FILTER_SYMBOLS,
|
||||||
|
CONF_RECEIVE_SYMBOLS,
|
||||||
|
CONF_CARRIER_DUTY_PERCENT,
|
||||||
|
CONF_CARRIER_FREQUENCY,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
.add_extra(validate_config)
|
.add_extra(validate_config)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||||
if CORE.is_esp32:
|
if CORE.is_esp32 and esp32.get_esp32_variant() not in esp32_rmt.VARIANTS_NO_RMT:
|
||||||
# Re-enable ESP-IDF's RMT driver (excluded by default to save compile time)
|
# Re-enable ESP-IDF's RMT driver (excluded by default to save compile time)
|
||||||
esp32.include_builtin_idf_component("esp_driver_rmt")
|
esp32.include_builtin_idf_component("esp_driver_rmt")
|
||||||
|
|
||||||
@@ -213,6 +242,8 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
|||||||
PlatformFramework.ESP32_IDF,
|
PlatformFramework.ESP32_IDF,
|
||||||
},
|
},
|
||||||
"remote_receiver.cpp": {
|
"remote_receiver.cpp": {
|
||||||
|
PlatformFramework.ESP32_ARDUINO,
|
||||||
|
PlatformFramework.ESP32_IDF,
|
||||||
PlatformFramework.ESP8266_ARDUINO,
|
PlatformFramework.ESP8266_ARDUINO,
|
||||||
PlatformFramework.BK72XX_ARDUINO,
|
PlatformFramework.BK72XX_ARDUINO,
|
||||||
PlatformFramework.RTL87XX_ARDUINO,
|
PlatformFramework.RTL87XX_ARDUINO,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#if defined(USE_LIBRETINY) || defined(USE_ESP8266) || defined(USE_RP2040)
|
#if defined(USE_LIBRETINY) || defined(USE_ESP8266) || defined(USE_RP2040) || (defined(USE_ESP32) && !SOC_RMT_SUPPORTED)
|
||||||
|
|
||||||
namespace esphome::remote_receiver {
|
namespace esphome::remote_receiver {
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,15 @@
|
|||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
|
||||||
#if defined(USE_ESP32)
|
#if defined(USE_ESP32)
|
||||||
|
#include <soc/soc_caps.h>
|
||||||
|
#if SOC_RMT_SUPPORTED
|
||||||
#include <driver/rmt_rx.h>
|
#include <driver/rmt_rx.h>
|
||||||
#endif
|
#endif // SOC_RMT_SUPPORTED
|
||||||
|
#endif // USE_ESP32
|
||||||
|
|
||||||
namespace esphome::remote_receiver {
|
namespace esphome::remote_receiver {
|
||||||
|
|
||||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY) || defined(USE_RP2040)
|
#if defined(USE_ESP8266) || defined(USE_LIBRETINY) || defined(USE_RP2040) || (defined(USE_ESP32) && !SOC_RMT_SUPPORTED)
|
||||||
struct RemoteReceiverComponentStore {
|
struct RemoteReceiverComponentStore {
|
||||||
static void gpio_intr(RemoteReceiverComponentStore *arg);
|
static void gpio_intr(RemoteReceiverComponentStore *arg);
|
||||||
|
|
||||||
@@ -35,7 +38,7 @@ struct RemoteReceiverComponentStore {
|
|||||||
volatile bool prev_level{false};
|
volatile bool prev_level{false};
|
||||||
volatile bool overflow{false};
|
volatile bool overflow{false};
|
||||||
};
|
};
|
||||||
#elif defined(USE_ESP32)
|
#elif defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
struct RemoteReceiverComponentStore {
|
struct RemoteReceiverComponentStore {
|
||||||
/// Stores RMT symbols and rx done event data
|
/// Stores RMT symbols and rx done event data
|
||||||
volatile uint8_t *buffer{nullptr};
|
volatile uint8_t *buffer{nullptr};
|
||||||
@@ -54,7 +57,7 @@ struct RemoteReceiverComponentStore {
|
|||||||
|
|
||||||
class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
||||||
public Component
|
public Component
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
,
|
,
|
||||||
public remote_base::RemoteRMTChannel
|
public remote_base::RemoteRMTChannel
|
||||||
#endif
|
#endif
|
||||||
@@ -66,7 +69,7 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
|||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
void set_filter_symbols(uint32_t filter_symbols) { this->filter_symbols_ = filter_symbols; }
|
void set_filter_symbols(uint32_t filter_symbols) { this->filter_symbols_ = filter_symbols; }
|
||||||
void set_receive_symbols(uint32_t receive_symbols) { this->receive_symbols_ = receive_symbols; }
|
void set_receive_symbols(uint32_t receive_symbols) { this->receive_symbols_ = receive_symbols; }
|
||||||
void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; }
|
void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; }
|
||||||
@@ -78,7 +81,7 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
|||||||
void set_idle_us(uint32_t idle_us) { this->idle_us_ = idle_us; }
|
void set_idle_us(uint32_t idle_us) { this->idle_us_ = idle_us; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
void decode_rmt_(rmt_symbol_word_t *item, size_t item_count);
|
void decode_rmt_(rmt_symbol_word_t *item, size_t item_count);
|
||||||
rmt_channel_handle_t channel_{NULL};
|
rmt_channel_handle_t channel_{NULL};
|
||||||
uint32_t filter_symbols_{0};
|
uint32_t filter_symbols_{0};
|
||||||
@@ -94,7 +97,7 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
|||||||
RemoteReceiverComponentStore store_;
|
RemoteReceiverComponentStore store_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY) || defined(USE_RP2040)
|
#if defined(USE_ESP8266) || defined(USE_LIBRETINY) || defined(USE_RP2040) || (defined(USE_ESP32) && !SOC_RMT_SUPPORTED)
|
||||||
HighFrequencyLoopRequester high_freq_;
|
HighFrequencyLoopRequester high_freq_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
#include <soc/soc_caps.h>
|
||||||
|
#if SOC_RMT_SUPPORTED
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_clk_tree.h>
|
#include <esp_clk_tree.h>
|
||||||
|
|
||||||
@@ -248,4 +250,5 @@ void RemoteReceiverComponent::decode_rmt_(rmt_symbol_word_t *item, size_t item_c
|
|||||||
|
|
||||||
} // namespace esphome::remote_receiver
|
} // namespace esphome::remote_receiver
|
||||||
|
|
||||||
#endif
|
#endif // SOC_RMT_SUPPORTED
|
||||||
|
#endif // USE_ESP32
|
||||||
|
|||||||
@@ -40,45 +40,66 @@ DigitalWriteAction = remote_transmitter_ns.class_(
|
|||||||
cg.Parented.template(RemoteTransmitterComponent),
|
cg.Parented.template(RemoteTransmitterComponent),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
MULTI_CONF = True
|
MULTI_CONF = True
|
||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = (
|
||||||
{
|
cv.Schema(
|
||||||
cv.GenerateID(): cv.declare_id(RemoteTransmitterComponent),
|
{
|
||||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
cv.GenerateID(): cv.declare_id(RemoteTransmitterComponent),
|
||||||
cv.Required(CONF_CARRIER_DUTY_PERCENT): cv.All(
|
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||||
cv.percentage_int, cv.Range(min=1, max=100)
|
cv.Required(CONF_CARRIER_DUTY_PERCENT): cv.All(
|
||||||
),
|
cv.percentage_int, cv.Range(min=1, max=100)
|
||||||
cv.Optional(CONF_CLOCK_RESOLUTION): cv.All(
|
|
||||||
cv.only_on_esp32,
|
|
||||||
esp32_rmt.validate_clock_resolution(),
|
|
||||||
),
|
|
||||||
cv.Optional(CONF_EOT_LEVEL): cv.All(cv.only_on_esp32, cv.boolean),
|
|
||||||
cv.Optional(CONF_USE_DMA): cv.All(
|
|
||||||
esp32.only_on_variant(
|
|
||||||
supported=[esp32.VARIANT_ESP32P4, esp32.VARIANT_ESP32S3]
|
|
||||||
),
|
),
|
||||||
cv.boolean,
|
cv.Optional(CONF_CLOCK_RESOLUTION): cv.All(
|
||||||
),
|
cv.only_on_esp32,
|
||||||
cv.SplitDefault(
|
esp32_rmt.validate_clock_resolution(),
|
||||||
CONF_RMT_SYMBOLS,
|
),
|
||||||
esp32=64,
|
cv.Optional(CONF_EOT_LEVEL): cv.All(cv.only_on_esp32, cv.boolean),
|
||||||
esp32_c3=48,
|
cv.Optional(CONF_USE_DMA): cv.All(
|
||||||
esp32_c5=48,
|
esp32.only_on_variant(
|
||||||
esp32_c6=48,
|
supported=[esp32.VARIANT_ESP32P4, esp32.VARIANT_ESP32S3]
|
||||||
esp32_h2=48,
|
),
|
||||||
esp32_p4=48,
|
cv.boolean,
|
||||||
esp32_s2=64,
|
),
|
||||||
esp32_s3=48,
|
cv.SplitDefault(
|
||||||
): cv.All(cv.only_on_esp32, cv.int_range(min=2)),
|
CONF_RMT_SYMBOLS,
|
||||||
cv.Optional(CONF_NON_BLOCKING): cv.All(cv.only_on_esp32, cv.boolean),
|
esp32=64,
|
||||||
cv.Optional(CONF_ON_TRANSMIT): automation.validate_automation(single=True),
|
esp32_c2=cv.UNDEFINED,
|
||||||
cv.Optional(CONF_ON_COMPLETE): automation.validate_automation(single=True),
|
esp32_c3=48,
|
||||||
}
|
esp32_c5=48,
|
||||||
).extend(cv.COMPONENT_SCHEMA)
|
esp32_c6=48,
|
||||||
|
esp32_c61=cv.UNDEFINED,
|
||||||
|
esp32_h2=48,
|
||||||
|
esp32_p4=48,
|
||||||
|
esp32_s2=64,
|
||||||
|
esp32_s3=48,
|
||||||
|
): cv.All(cv.only_on_esp32, cv.int_range(min=2)),
|
||||||
|
cv.Optional(CONF_NON_BLOCKING): cv.All(cv.only_on_esp32, cv.boolean),
|
||||||
|
cv.Optional(CONF_ON_TRANSMIT): automation.validate_automation(single=True),
|
||||||
|
cv.Optional(CONF_ON_COMPLETE): automation.validate_automation(single=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.add_extra(
|
||||||
|
esp32_rmt.validate_rmt_not_supported(
|
||||||
|
[
|
||||||
|
CONF_CLOCK_RESOLUTION,
|
||||||
|
CONF_EOT_LEVEL,
|
||||||
|
CONF_USE_DMA,
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
|
CONF_NON_BLOCKING,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _validate_non_blocking(config):
|
def _validate_non_blocking(config):
|
||||||
if CORE.is_esp32 and CONF_NON_BLOCKING not in config:
|
if (
|
||||||
|
CORE.is_esp32
|
||||||
|
and esp32.get_esp32_variant() not in esp32_rmt.VARIANTS_NO_RMT
|
||||||
|
and CONF_NON_BLOCKING not in config
|
||||||
|
):
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"'non_blocking' is not set for 'remote_transmitter' and will default to 'true'.\n"
|
"'non_blocking' is not set for 'remote_transmitter' and will default to 'true'.\n"
|
||||||
"The default behavior changed in 2025.11.0; previously blocking mode was used.\n"
|
"The default behavior changed in 2025.11.0; previously blocking mode was used.\n"
|
||||||
@@ -111,7 +132,7 @@ async def digital_write_action_to_code(config, action_id, template_arg, args):
|
|||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||||
if CORE.is_esp32:
|
if CORE.is_esp32 and esp32.get_esp32_variant() not in esp32_rmt.VARIANTS_NO_RMT:
|
||||||
# Re-enable ESP-IDF's RMT driver (excluded by default to save compile time)
|
# Re-enable ESP-IDF's RMT driver (excluded by default to save compile time)
|
||||||
esp32.include_builtin_idf_component("esp_driver_rmt")
|
esp32.include_builtin_idf_component("esp_driver_rmt")
|
||||||
|
|
||||||
@@ -155,6 +176,8 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
|||||||
PlatformFramework.ESP32_IDF,
|
PlatformFramework.ESP32_IDF,
|
||||||
},
|
},
|
||||||
"remote_transmitter.cpp": {
|
"remote_transmitter.cpp": {
|
||||||
|
PlatformFramework.ESP32_ARDUINO,
|
||||||
|
PlatformFramework.ESP32_IDF,
|
||||||
PlatformFramework.ESP8266_ARDUINO,
|
PlatformFramework.ESP8266_ARDUINO,
|
||||||
PlatformFramework.BK72XX_ARDUINO,
|
PlatformFramework.BK72XX_ARDUINO,
|
||||||
PlatformFramework.RTL87XX_ARDUINO,
|
PlatformFramework.RTL87XX_ARDUINO,
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome::remote_transmitter {
|
||||||
namespace remote_transmitter {
|
|
||||||
|
|
||||||
template<typename... Ts> class DigitalWriteAction : public Action<Ts...>, public Parented<RemoteTransmitterComponent> {
|
template<typename... Ts> class DigitalWriteAction : public Action<Ts...>, public Parented<RemoteTransmitterComponent> {
|
||||||
public:
|
public:
|
||||||
@@ -14,5 +13,4 @@ template<typename... Ts> class DigitalWriteAction : public Action<Ts...>, public
|
|||||||
void play(const Ts &...x) override { this->parent_->digital_write(this->value_.value(x...)); }
|
void play(const Ts &...x) override { this->parent_->digital_write(this->value_.value(x...)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace remote_transmitter
|
} // namespace esphome::remote_transmitter
|
||||||
} // namespace esphome
|
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
|
|
||||||
#if defined(USE_LIBRETINY) || defined(USE_ESP8266) || defined(USE_RP2040)
|
#if defined(USE_LIBRETINY) || defined(USE_ESP8266) || defined(USE_RP2040) || (defined(USE_ESP32) && !SOC_RMT_SUPPORTED)
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome::remote_transmitter {
|
||||||
namespace remote_transmitter {
|
|
||||||
|
|
||||||
static const char *const TAG = "remote_transmitter";
|
static const char *const TAG = "remote_transmitter";
|
||||||
|
|
||||||
@@ -105,7 +104,6 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
|
|||||||
this->complete_trigger_.trigger();
|
this->complete_trigger_.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace remote_transmitter
|
} // namespace esphome::remote_transmitter
|
||||||
} // namespace esphome
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,13 +6,15 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(USE_ESP32)
|
#if defined(USE_ESP32)
|
||||||
|
#include <soc/soc_caps.h>
|
||||||
|
#if SOC_RMT_SUPPORTED
|
||||||
#include <driver/rmt_tx.h>
|
#include <driver/rmt_tx.h>
|
||||||
#endif
|
#endif // SOC_RMT_SUPPORTED
|
||||||
|
#endif // USE_ESP32
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome::remote_transmitter {
|
||||||
namespace remote_transmitter {
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 1)
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 1)
|
||||||
// IDF version 5.5.1 and above is required because of a bug in
|
// IDF version 5.5.1 and above is required because of a bug in
|
||||||
// the RMT encoder: https://github.com/espressif/esp-idf/issues/17244
|
// the RMT encoder: https://github.com/espressif/esp-idf/issues/17244
|
||||||
@@ -33,7 +35,7 @@ struct RemoteTransmitterComponentStore {
|
|||||||
|
|
||||||
class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
||||||
public Component
|
public Component
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
,
|
,
|
||||||
public remote_base::RemoteRMTChannel
|
public remote_base::RemoteRMTChannel
|
||||||
#endif
|
#endif
|
||||||
@@ -51,7 +53,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
|||||||
|
|
||||||
void digital_write(bool value);
|
void digital_write(bool value);
|
||||||
|
|
||||||
#if defined(USE_ESP32)
|
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; }
|
void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; }
|
||||||
void set_eot_level(bool eot_level) { this->eot_level_ = eot_level; }
|
void set_eot_level(bool eot_level) { this->eot_level_ = eot_level; }
|
||||||
void set_non_blocking(bool non_blocking) { this->non_blocking_ = non_blocking; }
|
void set_non_blocking(bool non_blocking) { this->non_blocking_ = non_blocking; }
|
||||||
@@ -62,7 +64,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void send_internal(uint32_t send_times, uint32_t send_wait) override;
|
void send_internal(uint32_t send_times, uint32_t send_wait) override;
|
||||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY) || defined(USE_RP2040)
|
#if defined(USE_ESP8266) || defined(USE_LIBRETINY) || defined(USE_RP2040) || (defined(USE_ESP32) && !SOC_RMT_SUPPORTED)
|
||||||
void calculate_on_off_time_(uint32_t carrier_frequency, uint32_t *on_time_period, uint32_t *off_time_period);
|
void calculate_on_off_time_(uint32_t carrier_frequency, uint32_t *on_time_period, uint32_t *off_time_period);
|
||||||
|
|
||||||
void mark_(uint32_t on_time, uint32_t off_time, uint32_t usec);
|
void mark_(uint32_t on_time, uint32_t off_time, uint32_t usec);
|
||||||
@@ -73,7 +75,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
|||||||
uint32_t target_time_;
|
uint32_t target_time_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED
|
||||||
void configure_rmt_();
|
void configure_rmt_();
|
||||||
void wait_for_rmt_();
|
void wait_for_rmt_();
|
||||||
|
|
||||||
@@ -100,5 +102,4 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
|||||||
Trigger<> complete_trigger_;
|
Trigger<> complete_trigger_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace remote_transmitter
|
} // namespace esphome::remote_transmitter
|
||||||
} // namespace esphome
|
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
#include <soc/soc_caps.h>
|
||||||
|
#if SOC_RMT_SUPPORTED
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome::remote_transmitter {
|
||||||
namespace remote_transmitter {
|
|
||||||
|
|
||||||
static const char *const TAG = "remote_transmitter";
|
static const char *const TAG = "remote_transmitter";
|
||||||
|
|
||||||
@@ -358,7 +359,7 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace remote_transmitter
|
} // namespace esphome::remote_transmitter
|
||||||
} // namespace esphome
|
|
||||||
|
|
||||||
#endif
|
#endif // SOC_RMT_SUPPORTED
|
||||||
|
#endif // USE_ESP32
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
remote_receiver:
|
||||||
|
id: rcvr
|
||||||
|
pin: GPIO2
|
||||||
|
dump: all
|
||||||
|
<<: !include common-actions.yaml
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: remote_receiver
|
||||||
|
name: Panasonic Remote Input
|
||||||
|
panasonic:
|
||||||
|
address: 0x4004
|
||||||
|
command: 0x100BCBD
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
remote_transmitter:
|
||||||
|
id: xmitr
|
||||||
|
pin: GPIO2
|
||||||
|
carrier_duty_percent: 50%
|
||||||
|
|
||||||
|
packages:
|
||||||
|
buttons: !include common-buttons.yaml
|
||||||
Reference in New Issue
Block a user