mirror of
https://github.com/esphome/esphome.git
synced 2024-12-19 12:04:54 +01:00
[esp32_rmt] Updates for IDF 5+ (#7770)
Some checks are pending
CI / Test split components (push) Blocked by required conditions
CI / Create common environment (push) Waiting to run
CI / Check black (push) Blocked by required conditions
CI / Check flake8 (push) Blocked by required conditions
CI / Check pylint (push) Blocked by required conditions
CI / Check pyupgrade (push) Blocked by required conditions
CI / Run script/ci-custom (push) Blocked by required conditions
CI / Run pytest (push) Blocked by required conditions
CI / Check clang-format (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 1/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 2/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 3/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 4/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 IDF (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP8266 (push) Blocked by required conditions
CI / list-components (push) Blocked by required conditions
CI / Component test (push) Blocked by required conditions
CI / Split components for testing into 20 groups maximum (push) Blocked by required conditions
CI / CI Status (push) Blocked by required conditions
YAML lint / yamllint (push) Waiting to run
Some checks are pending
CI / Test split components (push) Blocked by required conditions
CI / Create common environment (push) Waiting to run
CI / Check black (push) Blocked by required conditions
CI / Check flake8 (push) Blocked by required conditions
CI / Check pylint (push) Blocked by required conditions
CI / Check pyupgrade (push) Blocked by required conditions
CI / Run script/ci-custom (push) Blocked by required conditions
CI / Run pytest (push) Blocked by required conditions
CI / Check clang-format (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 1/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 2/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 3/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 Arduino 4/4 (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP32 IDF (push) Blocked by required conditions
CI / Run script/clang-tidy for ESP8266 (push) Blocked by required conditions
CI / list-components (push) Blocked by required conditions
CI / Component test (push) Blocked by required conditions
CI / Split components for testing into 20 groups maximum (push) Blocked by required conditions
CI / CI Status (push) Blocked by required conditions
YAML lint / yamllint (push) Waiting to run
Co-authored-by: Jonathan Swoboda <jonathan.swoboda> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
This commit is contained in:
parent
61499dbdd8
commit
265b6ec445
33 changed files with 817 additions and 379 deletions
|
@ -1,7 +1,8 @@
|
||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
|
||||||
from esphome.components import esp32
|
from esphome.components import esp32
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import KEY_CORE, KEY_FRAMEWORK_VERSION
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
CODEOWNERS = ["@jesserockz"]
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
|
||||||
|
@ -36,8 +37,32 @@ RMT_CHANNEL_ENUMS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def validate_rmt_channel(*, tx: bool):
|
def use_new_rmt_driver():
|
||||||
|
framework_version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
|
||||||
|
if CORE.using_esp_idf and framework_version >= cv.Version(5, 0, 0):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def validate_clock_resolution():
|
||||||
|
def _validator(value):
|
||||||
|
cv.only_on_esp32(value)
|
||||||
|
value = cv.int_(value)
|
||||||
|
variant = esp32.get_esp32_variant()
|
||||||
|
if variant == esp32.const.VARIANT_ESP32H2 and value > 32000000:
|
||||||
|
raise cv.Invalid(
|
||||||
|
f"ESP32 variant {variant} has a max clock_resolution of 32000000."
|
||||||
|
)
|
||||||
|
if value > 80000000:
|
||||||
|
raise cv.Invalid(
|
||||||
|
f"ESP32 variant {variant} has a max clock_resolution of 80000000."
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
||||||
|
return _validator
|
||||||
|
|
||||||
|
|
||||||
|
def validate_rmt_channel(*, tx: bool):
|
||||||
rmt_channels = RMT_TX_CHANNELS if tx else RMT_RX_CHANNELS
|
rmt_channels = RMT_TX_CHANNELS if tx else RMT_RX_CHANNELS
|
||||||
|
|
||||||
def _validator(value):
|
def _validator(value):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <cinttypes>
|
|
||||||
#include "led_strip.h"
|
#include "led_strip.h"
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
|
@ -13,9 +13,13 @@ namespace esp32_rmt_led_strip {
|
||||||
|
|
||||||
static const char *const TAG = "esp32_rmt_led_strip";
|
static const char *const TAG = "esp32_rmt_led_strip";
|
||||||
|
|
||||||
|
#ifdef USE_ESP32_VARIANT_ESP32H2
|
||||||
|
static const uint32_t RMT_CLK_FREQ = 32000000;
|
||||||
|
static const uint8_t RMT_CLK_DIV = 1;
|
||||||
|
#else
|
||||||
static const uint32_t RMT_CLK_FREQ = 80000000;
|
static const uint32_t RMT_CLK_FREQ = 80000000;
|
||||||
|
|
||||||
static const uint8_t RMT_CLK_DIV = 2;
|
static const uint8_t RMT_CLK_DIV = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
void ESP32RMTLEDStripLightOutput::setup() {
|
void ESP32RMTLEDStripLightOutput::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Setting up ESP32 LED Strip...");
|
ESP_LOGCONFIG(TAG, "Setting up ESP32 LED Strip...");
|
||||||
|
@ -37,9 +41,48 @@ void ESP32RMTLEDStripLightOutput::setup() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
RAMAllocator<rmt_symbol_word_t> rmt_allocator(this->use_psram_ ? 0 : RAMAllocator<rmt_symbol_word_t>::ALLOC_INTERNAL);
|
||||||
|
|
||||||
|
// 8 bits per byte, 1 rmt_symbol_word_t per bit + 1 rmt_symbol_word_t for reset
|
||||||
|
this->rmt_buf_ = rmt_allocator.allocate(buffer_size * 8 + 1);
|
||||||
|
|
||||||
|
rmt_tx_channel_config_t channel;
|
||||||
|
memset(&channel, 0, sizeof(channel));
|
||||||
|
channel.clk_src = RMT_CLK_SRC_DEFAULT;
|
||||||
|
channel.resolution_hz = RMT_CLK_FREQ / RMT_CLK_DIV;
|
||||||
|
channel.gpio_num = gpio_num_t(this->pin_);
|
||||||
|
channel.mem_block_symbols = this->rmt_symbols_;
|
||||||
|
channel.trans_queue_depth = 1;
|
||||||
|
channel.flags.io_loop_back = 0;
|
||||||
|
channel.flags.io_od_mode = 0;
|
||||||
|
channel.flags.invert_out = 0;
|
||||||
|
channel.flags.with_dma = 0;
|
||||||
|
channel.intr_priority = 0;
|
||||||
|
if (rmt_new_tx_channel(&channel, &this->channel_) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Channel creation failed");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmt_copy_encoder_config_t encoder;
|
||||||
|
memset(&encoder, 0, sizeof(encoder));
|
||||||
|
if (rmt_new_copy_encoder(&encoder, &this->encoder_) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Encoder creation failed");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rmt_enable(this->channel_) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Enabling channel failed");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
RAMAllocator<rmt_item32_t> rmt_allocator(this->use_psram_ ? 0 : RAMAllocator<rmt_item32_t>::ALLOC_INTERNAL);
|
RAMAllocator<rmt_item32_t> rmt_allocator(this->use_psram_ ? 0 : RAMAllocator<rmt_item32_t>::ALLOC_INTERNAL);
|
||||||
this->rmt_buf_ = rmt_allocator.allocate(buffer_size * 8 +
|
|
||||||
1); // 8 bits per byte, 1 rmt_item32_t per bit + 1 rmt_item32_t for reset
|
// 8 bits per byte, 1 rmt_item32_t per bit + 1 rmt_item32_t for reset
|
||||||
|
this->rmt_buf_ = rmt_allocator.allocate(buffer_size * 8 + 1);
|
||||||
|
|
||||||
rmt_config_t config;
|
rmt_config_t config;
|
||||||
memset(&config, 0, sizeof(config));
|
memset(&config, 0, sizeof(config));
|
||||||
|
@ -64,6 +107,7 @@ void ESP32RMTLEDStripLightOutput::setup() {
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP32RMTLEDStripLightOutput::set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high,
|
void ESP32RMTLEDStripLightOutput::set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high,
|
||||||
|
@ -100,7 +144,12 @@ void ESP32RMTLEDStripLightOutput::write_state(light::LightState *state) {
|
||||||
|
|
||||||
ESP_LOGVV(TAG, "Writing RGB values to bus...");
|
ESP_LOGVV(TAG, "Writing RGB values to bus...");
|
||||||
|
|
||||||
if (rmt_wait_tx_done(this->channel_, pdMS_TO_TICKS(1000)) != ESP_OK) {
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
esp_err_t error = rmt_tx_wait_all_done(this->channel_, 1000);
|
||||||
|
#else
|
||||||
|
esp_err_t error = rmt_wait_tx_done(this->channel_, pdMS_TO_TICKS(1000));
|
||||||
|
#endif
|
||||||
|
if (error != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "RMT TX timeout");
|
ESP_LOGE(TAG, "RMT TX timeout");
|
||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
return;
|
return;
|
||||||
|
@ -112,7 +161,11 @@ void ESP32RMTLEDStripLightOutput::write_state(light::LightState *state) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
uint8_t *psrc = this->buf_;
|
uint8_t *psrc = this->buf_;
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
rmt_symbol_word_t *pdest = this->rmt_buf_;
|
||||||
|
#else
|
||||||
rmt_item32_t *pdest = this->rmt_buf_;
|
rmt_item32_t *pdest = this->rmt_buf_;
|
||||||
|
#endif
|
||||||
while (size < buffer_size) {
|
while (size < buffer_size) {
|
||||||
uint8_t b = *psrc;
|
uint8_t b = *psrc;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
|
@ -130,7 +183,16 @@ void ESP32RMTLEDStripLightOutput::write_state(light::LightState *state) {
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmt_write_items(this->channel_, this->rmt_buf_, len, false) != ESP_OK) {
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
rmt_transmit_config_t config;
|
||||||
|
memset(&config, 0, sizeof(config));
|
||||||
|
config.loop_count = 0;
|
||||||
|
config.flags.eot_level = 0;
|
||||||
|
error = rmt_transmit(this->channel_, this->encoder_, this->rmt_buf_, len * sizeof(rmt_symbol_word_t), &config);
|
||||||
|
#else
|
||||||
|
error = rmt_write_items(this->channel_, this->rmt_buf_, len, false);
|
||||||
|
#endif
|
||||||
|
if (error != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "RMT TX error");
|
ESP_LOGE(TAG, "RMT TX error");
|
||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
return;
|
return;
|
||||||
|
@ -186,7 +248,11 @@ light::ESPColorView ESP32RMTLEDStripLightOutput::get_view_internal(int32_t index
|
||||||
void ESP32RMTLEDStripLightOutput::dump_config() {
|
void ESP32RMTLEDStripLightOutput::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "ESP32 RMT LED Strip:");
|
ESP_LOGCONFIG(TAG, "ESP32 RMT LED Strip:");
|
||||||
ESP_LOGCONFIG(TAG, " Pin: %u", this->pin_);
|
ESP_LOGCONFIG(TAG, " Pin: %u", this->pin_);
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
ESP_LOGCONFIG(TAG, " RMT Symbols: %" PRIu32, this->rmt_symbols_);
|
||||||
|
#else
|
||||||
ESP_LOGCONFIG(TAG, " Channel: %u", this->channel_);
|
ESP_LOGCONFIG(TAG, " Channel: %u", this->channel_);
|
||||||
|
#endif
|
||||||
const char *rgb_order;
|
const char *rgb_order;
|
||||||
switch (this->rgb_order_) {
|
switch (this->rgb_order_) {
|
||||||
case ORDER_RGB:
|
case ORDER_RGB:
|
||||||
|
|
|
@ -9,8 +9,14 @@
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <driver/rmt.h>
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
|
#include <esp_idf_version.h>
|
||||||
|
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
#include <driver/rmt_tx.h>
|
||||||
|
#else
|
||||||
|
#include <driver/rmt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace esp32_rmt_led_strip {
|
namespace esp32_rmt_led_strip {
|
||||||
|
@ -54,7 +60,11 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
|
||||||
uint32_t reset_time_high, uint32_t reset_time_low);
|
uint32_t reset_time_high, uint32_t reset_time_low);
|
||||||
|
|
||||||
void set_rgb_order(RGBOrder rgb_order) { this->rgb_order_ = rgb_order; }
|
void set_rgb_order(RGBOrder rgb_order) { this->rgb_order_ = rgb_order; }
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
void set_rmt_symbols(uint32_t rmt_symbols) { this->rmt_symbols_ = rmt_symbols; }
|
||||||
|
#else
|
||||||
void set_rmt_channel(rmt_channel_t channel) { this->channel_ = channel; }
|
void set_rmt_channel(rmt_channel_t channel) { this->channel_ = channel; }
|
||||||
|
#endif
|
||||||
|
|
||||||
void clear_effect_data() override {
|
void clear_effect_data() override {
|
||||||
for (int i = 0; i < this->size(); i++)
|
for (int i = 0; i < this->size(); i++)
|
||||||
|
@ -70,7 +80,17 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
|
||||||
|
|
||||||
uint8_t *buf_{nullptr};
|
uint8_t *buf_{nullptr};
|
||||||
uint8_t *effect_data_{nullptr};
|
uint8_t *effect_data_{nullptr};
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
rmt_channel_handle_t channel_{nullptr};
|
||||||
|
rmt_encoder_handle_t encoder_{nullptr};
|
||||||
|
rmt_symbol_word_t *rmt_buf_{nullptr};
|
||||||
|
rmt_symbol_word_t bit0_, bit1_, reset_;
|
||||||
|
uint32_t rmt_symbols_;
|
||||||
|
#else
|
||||||
rmt_item32_t *rmt_buf_{nullptr};
|
rmt_item32_t *rmt_buf_{nullptr};
|
||||||
|
rmt_item32_t bit0_, bit1_, reset_;
|
||||||
|
rmt_channel_t channel_{RMT_CHANNEL_0};
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t pin_;
|
uint8_t pin_;
|
||||||
uint16_t num_leds_;
|
uint16_t num_leds_;
|
||||||
|
@ -78,9 +98,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
|
||||||
bool is_wrgb_;
|
bool is_wrgb_;
|
||||||
bool use_psram_;
|
bool use_psram_;
|
||||||
|
|
||||||
rmt_item32_t bit0_, bit1_, reset_;
|
|
||||||
RGBOrder rgb_order_;
|
RGBOrder rgb_order_;
|
||||||
rmt_channel_t channel_;
|
|
||||||
|
|
||||||
uint32_t last_refresh_{0};
|
uint32_t last_refresh_{0};
|
||||||
optional<uint32_t> max_refresh_rate_{};
|
optional<uint32_t> max_refresh_rate_{};
|
||||||
|
|
|
@ -13,6 +13,7 @@ from esphome.const import (
|
||||||
CONF_PIN,
|
CONF_PIN,
|
||||||
CONF_RGB_ORDER,
|
CONF_RGB_ORDER,
|
||||||
CONF_RMT_CHANNEL,
|
CONF_RMT_CHANNEL,
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
)
|
)
|
||||||
|
|
||||||
CODEOWNERS = ["@jesserockz"]
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
@ -23,8 +24,6 @@ ESP32RMTLEDStripLightOutput = esp32_rmt_led_strip_ns.class_(
|
||||||
"ESP32RMTLEDStripLightOutput", light.AddressableLight
|
"ESP32RMTLEDStripLightOutput", light.AddressableLight
|
||||||
)
|
)
|
||||||
|
|
||||||
rmt_channel_t = cg.global_ns.enum("rmt_channel_t")
|
|
||||||
|
|
||||||
RGBOrder = esp32_rmt_led_strip_ns.enum("RGBOrder")
|
RGBOrder = esp32_rmt_led_strip_ns.enum("RGBOrder")
|
||||||
|
|
||||||
RGB_ORDERS = {
|
RGB_ORDERS = {
|
||||||
|
@ -65,6 +64,13 @@ CONF_RESET_HIGH = "reset_high"
|
||||||
CONF_RESET_LOW = "reset_low"
|
CONF_RESET_LOW = "reset_low"
|
||||||
|
|
||||||
|
|
||||||
|
def final_validation(config):
|
||||||
|
if not esp32_rmt.use_new_rmt_driver() and CONF_RMT_CHANNEL not in config:
|
||||||
|
raise cv.Invalid("rmt_channel is a required option.")
|
||||||
|
|
||||||
|
|
||||||
|
FINAL_VALIDATE_SCHEMA = final_validation
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
light.ADDRESSABLE_LIGHT_SCHEMA.extend(
|
light.ADDRESSABLE_LIGHT_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
|
@ -72,7 +78,18 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_number,
|
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_number,
|
||||||
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
||||||
cv.Required(CONF_RGB_ORDER): cv.enum(RGB_ORDERS, upper=True),
|
cv.Required(CONF_RGB_ORDER): cv.enum(RGB_ORDERS, upper=True),
|
||||||
cv.Required(CONF_RMT_CHANNEL): esp32_rmt.validate_rmt_channel(tx=True),
|
cv.Optional(CONF_RMT_CHANNEL): cv.All(
|
||||||
|
cv.only_with_arduino, esp32_rmt.validate_rmt_channel(tx=True)
|
||||||
|
),
|
||||||
|
cv.SplitDefault(
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
|
esp32_idf=64,
|
||||||
|
esp32_s2_idf=64,
|
||||||
|
esp32_s3_idf=48,
|
||||||
|
esp32_c3_idf=48,
|
||||||
|
esp32_c6_idf=48,
|
||||||
|
esp32_h2_idf=48,
|
||||||
|
): cv.All(cv.only_with_esp_idf, cv.int_range(min=2)),
|
||||||
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
||||||
cv.Optional(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
cv.Optional(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
||||||
cv.Optional(CONF_IS_RGBW, default=False): cv.boolean,
|
cv.Optional(CONF_IS_RGBW, default=False): cv.boolean,
|
||||||
|
@ -148,8 +165,12 @@ async def to_code(config):
|
||||||
cg.add(var.set_is_wrgb(config[CONF_IS_WRGB]))
|
cg.add(var.set_is_wrgb(config[CONF_IS_WRGB]))
|
||||||
cg.add(var.set_use_psram(config[CONF_USE_PSRAM]))
|
cg.add(var.set_use_psram(config[CONF_USE_PSRAM]))
|
||||||
|
|
||||||
cg.add(
|
if esp32_rmt.use_new_rmt_driver():
|
||||||
var.set_rmt_channel(
|
cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS]))
|
||||||
getattr(rmt_channel_t, f"RMT_CHANNEL_{config[CONF_RMT_CHANNEL]}")
|
else:
|
||||||
|
rmt_channel_t = cg.global_ns.enum("rmt_channel_t")
|
||||||
|
cg.add(
|
||||||
|
var.set_rmt_channel(
|
||||||
|
getattr(rmt_channel_t, f"RMT_CHANNEL_{config[CONF_RMT_CHANNEL]}")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace remote_base {
|
||||||
|
|
||||||
static const char *const TAG = "remote_base";
|
static const char *const TAG = "remote_base";
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5
|
||||||
RemoteRMTChannel::RemoteRMTChannel(uint8_t mem_block_num) : mem_block_num_(mem_block_num) {
|
RemoteRMTChannel::RemoteRMTChannel(uint8_t mem_block_num) : mem_block_num_(mem_block_num) {
|
||||||
static rmt_channel_t next_rmt_channel = RMT_CHANNEL_0;
|
static rmt_channel_t next_rmt_channel = RMT_CHANNEL_0;
|
||||||
this->channel_ = next_rmt_channel;
|
this->channel_ = next_rmt_channel;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5
|
||||||
#include <driver/rmt.h>
|
#include <driver/rmt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -112,25 +112,43 @@ class RemoteComponentBase {
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
class RemoteRMTChannel {
|
class RemoteRMTChannel {
|
||||||
public:
|
public:
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
void set_clock_resolution(uint32_t clock_resolution) { this->clock_resolution_ = clock_resolution; }
|
||||||
|
void set_rmt_symbols(uint32_t rmt_symbols) { this->rmt_symbols_ = rmt_symbols; }
|
||||||
|
#else
|
||||||
explicit RemoteRMTChannel(uint8_t mem_block_num = 1);
|
explicit RemoteRMTChannel(uint8_t mem_block_num = 1);
|
||||||
explicit RemoteRMTChannel(rmt_channel_t channel, uint8_t mem_block_num = 1);
|
explicit RemoteRMTChannel(rmt_channel_t channel, uint8_t mem_block_num = 1);
|
||||||
|
|
||||||
void config_rmt(rmt_config_t &rmt);
|
void config_rmt(rmt_config_t &rmt);
|
||||||
void set_clock_divider(uint8_t clock_divider) { this->clock_divider_ = clock_divider; }
|
void set_clock_divider(uint8_t clock_divider) { this->clock_divider_ = clock_divider; }
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t from_microseconds_(uint32_t us) {
|
uint32_t from_microseconds_(uint32_t us) {
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
const uint32_t ticks_per_ten_us = this->clock_resolution_ / 100000u;
|
||||||
|
#else
|
||||||
const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u;
|
const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u;
|
||||||
|
#endif
|
||||||
return us * ticks_per_ten_us / 10;
|
return us * ticks_per_ten_us / 10;
|
||||||
}
|
}
|
||||||
uint32_t to_microseconds_(uint32_t ticks) {
|
uint32_t to_microseconds_(uint32_t ticks) {
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
const uint32_t ticks_per_ten_us = this->clock_resolution_ / 100000u;
|
||||||
|
#else
|
||||||
const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u;
|
const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u;
|
||||||
|
#endif
|
||||||
return (ticks * 10) / ticks_per_ten_us;
|
return (ticks * 10) / ticks_per_ten_us;
|
||||||
}
|
}
|
||||||
RemoteComponentBase *remote_base_;
|
RemoteComponentBase *remote_base_;
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
uint32_t clock_resolution_{1000000};
|
||||||
|
uint32_t rmt_symbols_;
|
||||||
|
#else
|
||||||
rmt_channel_t channel_{RMT_CHANNEL_0};
|
rmt_channel_t channel_{RMT_CHANNEL_0};
|
||||||
uint8_t mem_block_num_;
|
uint8_t mem_block_num_;
|
||||||
uint8_t clock_divider_{80};
|
uint8_t clock_divider_{80};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import esp32_rmt, remote_base
|
from esphome.components import esp32, esp32_rmt, remote_base
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_BUFFER_SIZE,
|
CONF_BUFFER_SIZE,
|
||||||
CONF_CLOCK_DIVIDER,
|
CONF_CLOCK_DIVIDER,
|
||||||
|
CONF_CLOCK_RESOLUTION,
|
||||||
CONF_DUMP,
|
CONF_DUMP,
|
||||||
CONF_FILTER,
|
CONF_FILTER,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
|
@ -12,12 +13,17 @@ from esphome.const import (
|
||||||
CONF_MEMORY_BLOCKS,
|
CONF_MEMORY_BLOCKS,
|
||||||
CONF_PIN,
|
CONF_PIN,
|
||||||
CONF_RMT_CHANNEL,
|
CONF_RMT_CHANNEL,
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
CONF_TOLERANCE,
|
CONF_TOLERANCE,
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
|
CONF_USE_DMA,
|
||||||
CONF_VALUE,
|
CONF_VALUE,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, TimePeriod
|
from esphome.core import CORE, TimePeriod
|
||||||
|
|
||||||
|
CONF_FILTER_SYMBOLS = "filter_symbols"
|
||||||
|
CONF_RECEIVE_SYMBOLS = "receive_symbols"
|
||||||
|
|
||||||
AUTO_LOAD = ["remote_base"]
|
AUTO_LOAD = ["remote_base"]
|
||||||
remote_receiver_ns = cg.esphome_ns.namespace("remote_receiver")
|
remote_receiver_ns = cg.esphome_ns.namespace("remote_receiver")
|
||||||
remote_base_ns = cg.esphome_ns.namespace("remote_base")
|
remote_base_ns = cg.esphome_ns.namespace("remote_base")
|
||||||
|
@ -97,15 +103,43 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
||||||
cv.positive_time_period_microseconds,
|
cv.positive_time_period_microseconds,
|
||||||
cv.Range(max=TimePeriod(microseconds=4294967295)),
|
cv.Range(max=TimePeriod(microseconds=4294967295)),
|
||||||
),
|
),
|
||||||
cv.SplitDefault(CONF_CLOCK_DIVIDER, esp32=80): cv.All(
|
cv.SplitDefault(CONF_CLOCK_DIVIDER, esp32_arduino=80): cv.All(
|
||||||
cv.only_on_esp32, cv.Range(min=1, max=255)
|
cv.only_on_esp32,
|
||||||
|
cv.only_with_arduino,
|
||||||
|
cv.int_range(min=1, max=255),
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_CLOCK_RESOLUTION): cv.All(
|
||||||
|
cv.only_on_esp32,
|
||||||
|
cv.only_with_esp_idf,
|
||||||
|
esp32_rmt.validate_clock_resolution(),
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_IDLE, default="10ms"): cv.All(
|
cv.Optional(CONF_IDLE, default="10ms"): cv.All(
|
||||||
cv.positive_time_period_microseconds,
|
cv.positive_time_period_microseconds,
|
||||||
cv.Range(max=TimePeriod(microseconds=4294967295)),
|
cv.Range(max=TimePeriod(microseconds=4294967295)),
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_MEMORY_BLOCKS, default=3): cv.Range(min=1, max=8),
|
cv.SplitDefault(CONF_MEMORY_BLOCKS, esp32_arduino=3): cv.All(
|
||||||
cv.Optional(CONF_RMT_CHANNEL): esp32_rmt.validate_rmt_channel(tx=False),
|
cv.only_with_arduino, cv.int_range(min=1, max=8)
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_RMT_CHANNEL): cv.All(
|
||||||
|
cv.only_with_arduino, esp32_rmt.validate_rmt_channel(tx=False)
|
||||||
|
),
|
||||||
|
cv.SplitDefault(
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
|
esp32_idf=192,
|
||||||
|
esp32_s2_idf=192,
|
||||||
|
esp32_s3_idf=192,
|
||||||
|
esp32_c3_idf=96,
|
||||||
|
esp32_c6_idf=96,
|
||||||
|
esp32_h2_idf=96,
|
||||||
|
): cv.All(cv.only_with_esp_idf, cv.int_range(min=2)),
|
||||||
|
cv.Optional(CONF_FILTER_SYMBOLS): cv.All(
|
||||||
|
cv.only_with_esp_idf, cv.int_range(min=0)
|
||||||
|
),
|
||||||
|
cv.SplitDefault(
|
||||||
|
CONF_RECEIVE_SYMBOLS,
|
||||||
|
esp32_idf=192,
|
||||||
|
): cv.All(cv.only_with_esp_idf, cv.int_range(min=2)),
|
||||||
|
cv.Optional(CONF_USE_DMA): cv.All(cv.only_with_esp_idf, cv.boolean),
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA)
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
)
|
)
|
||||||
|
@ -114,13 +148,27 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
||||||
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:
|
||||||
if (rmt_channel := config.get(CONF_RMT_CHANNEL, None)) is not None:
|
if esp32_rmt.use_new_rmt_driver():
|
||||||
var = cg.new_Pvariable(
|
var = cg.new_Pvariable(config[CONF_ID], pin)
|
||||||
config[CONF_ID], pin, rmt_channel, config[CONF_MEMORY_BLOCKS]
|
cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS]))
|
||||||
)
|
cg.add(var.set_receive_symbols(config[CONF_RECEIVE_SYMBOLS]))
|
||||||
|
if CONF_USE_DMA in config:
|
||||||
|
cg.add(var.set_with_dma(config[CONF_USE_DMA]))
|
||||||
|
if CONF_CLOCK_RESOLUTION in config:
|
||||||
|
cg.add(var.set_clock_resolution(config[CONF_CLOCK_RESOLUTION]))
|
||||||
|
if CONF_FILTER_SYMBOLS in config:
|
||||||
|
cg.add(var.set_filter_symbols(config[CONF_FILTER_SYMBOLS]))
|
||||||
|
if CORE.using_esp_idf:
|
||||||
|
esp32.add_idf_sdkconfig_option("CONFIG_RMT_RECV_FUNC_IN_IRAM", True)
|
||||||
|
esp32.add_idf_sdkconfig_option("CONFIG_RMT_ISR_IRAM_SAFE", True)
|
||||||
else:
|
else:
|
||||||
var = cg.new_Pvariable(config[CONF_ID], pin, config[CONF_MEMORY_BLOCKS])
|
if (rmt_channel := config.get(CONF_RMT_CHANNEL, None)) is not None:
|
||||||
cg.add(var.set_clock_divider(config[CONF_CLOCK_DIVIDER]))
|
var = cg.new_Pvariable(
|
||||||
|
config[CONF_ID], pin, rmt_channel, config[CONF_MEMORY_BLOCKS]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], pin, config[CONF_MEMORY_BLOCKS])
|
||||||
|
cg.add(var.set_clock_divider(config[CONF_CLOCK_DIVIDER]))
|
||||||
else:
|
else:
|
||||||
var = cg.new_Pvariable(config[CONF_ID], pin)
|
var = cg.new_Pvariable(config[CONF_ID], pin)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
|
||||||
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
#include <driver/rmt_rx.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace remote_receiver {
|
namespace remote_receiver {
|
||||||
|
|
||||||
|
@ -25,6 +29,21 @@ struct RemoteReceiverComponentStore {
|
||||||
uint32_t filter_us{10};
|
uint32_t filter_us{10};
|
||||||
ISRInternalGPIOPin pin;
|
ISRInternalGPIOPin pin;
|
||||||
};
|
};
|
||||||
|
#elif defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
struct RemoteReceiverComponentStore {
|
||||||
|
/// Stores RMT symbols and rx done event data
|
||||||
|
volatile uint8_t *buffer{nullptr};
|
||||||
|
/// The position last written to
|
||||||
|
volatile uint32_t buffer_write{0};
|
||||||
|
/// The position last read from
|
||||||
|
volatile uint32_t buffer_read{0};
|
||||||
|
bool overflow{false};
|
||||||
|
uint32_t buffer_size{1000};
|
||||||
|
uint32_t receive_size{0};
|
||||||
|
uint32_t filter_symbols{0};
|
||||||
|
esp_err_t error{ESP_OK};
|
||||||
|
rmt_receive_config_t config;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
||||||
|
@ -33,9 +52,10 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
||||||
,
|
,
|
||||||
public remote_base::RemoteRMTChannel
|
public remote_base::RemoteRMTChannel
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5
|
||||||
RemoteReceiverComponent(InternalGPIOPin *pin, uint8_t mem_block_num = 1)
|
RemoteReceiverComponent(InternalGPIOPin *pin, uint8_t mem_block_num = 1)
|
||||||
: RemoteReceiverBase(pin), remote_base::RemoteRMTChannel(mem_block_num) {}
|
: RemoteReceiverBase(pin), remote_base::RemoteRMTChannel(mem_block_num) {}
|
||||||
|
|
||||||
|
@ -49,19 +69,32 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
||||||
void loop() override;
|
void loop() override;
|
||||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||||
|
|
||||||
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
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_with_dma(bool with_dma) { this->with_dma_ = with_dma; }
|
||||||
|
#endif
|
||||||
void set_buffer_size(uint32_t buffer_size) { this->buffer_size_ = buffer_size; }
|
void set_buffer_size(uint32_t buffer_size) { this->buffer_size_ = buffer_size; }
|
||||||
void set_filter_us(uint32_t filter_us) { this->filter_us_ = filter_us; }
|
void set_filter_us(uint32_t filter_us) { this->filter_us_ = filter_us; }
|
||||||
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
|
#ifdef USE_ESP32
|
||||||
void decode_rmt_(rmt_item32_t *item, size_t len);
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
void decode_rmt_(rmt_symbol_word_t *item, size_t item_count);
|
||||||
|
rmt_channel_handle_t channel_{NULL};
|
||||||
|
uint32_t filter_symbols_{0};
|
||||||
|
uint32_t receive_symbols_{0};
|
||||||
|
bool with_dma_{false};
|
||||||
|
#else
|
||||||
|
void decode_rmt_(rmt_item32_t *item, size_t item_count);
|
||||||
RingbufHandle_t ringbuf_;
|
RingbufHandle_t ringbuf_;
|
||||||
|
#endif
|
||||||
esp_err_t error_code_{ESP_OK};
|
esp_err_t error_code_{ESP_OK};
|
||||||
std::string error_string_{""};
|
std::string error_string_{""};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
|
#if defined(USE_ESP8266) || defined(USE_LIBRETINY) || (defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5)
|
||||||
RemoteReceiverComponentStore store_;
|
RemoteReceiverComponentStore store_;
|
||||||
HighFrequencyLoopRequester high_freq_;
|
HighFrequencyLoopRequester high_freq_;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,15 +2,104 @@
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
#include <driver/rmt.h>
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace remote_receiver {
|
namespace remote_receiver {
|
||||||
|
|
||||||
static const char *const TAG = "remote_receiver.esp32";
|
static const char *const TAG = "remote_receiver.esp32";
|
||||||
|
#ifdef USE_ESP32_VARIANT_ESP32H2
|
||||||
|
static const uint32_t RMT_CLK_FREQ = 32000000;
|
||||||
|
#else
|
||||||
|
static const uint32_t RMT_CLK_FREQ = 80000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
static bool IRAM_ATTR HOT rmt_callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *event, void *arg) {
|
||||||
|
RemoteReceiverComponentStore *store = (RemoteReceiverComponentStore *) arg;
|
||||||
|
rmt_rx_done_event_data_t *event_buffer = (rmt_rx_done_event_data_t *) (store->buffer + store->buffer_write);
|
||||||
|
uint32_t event_size = sizeof(rmt_rx_done_event_data_t);
|
||||||
|
uint32_t next_write = store->buffer_write + event_size + event->num_symbols * sizeof(rmt_symbol_word_t);
|
||||||
|
if (next_write + event_size + store->receive_size > store->buffer_size) {
|
||||||
|
next_write = 0;
|
||||||
|
}
|
||||||
|
if (store->buffer_read - next_write < event_size + store->receive_size) {
|
||||||
|
next_write = store->buffer_write;
|
||||||
|
store->overflow = true;
|
||||||
|
}
|
||||||
|
if (event->num_symbols <= store->filter_symbols) {
|
||||||
|
next_write = store->buffer_write;
|
||||||
|
}
|
||||||
|
store->error =
|
||||||
|
rmt_receive(channel, (uint8_t *) store->buffer + next_write + event_size, store->receive_size, &store->config);
|
||||||
|
event_buffer->num_symbols = event->num_symbols;
|
||||||
|
event_buffer->received_symbols = event->received_symbols;
|
||||||
|
store->buffer_write = next_write;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void RemoteReceiverComponent::setup() {
|
void RemoteReceiverComponent::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Setting up Remote Receiver...");
|
ESP_LOGCONFIG(TAG, "Setting up Remote Receiver...");
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
rmt_rx_channel_config_t channel;
|
||||||
|
memset(&channel, 0, sizeof(channel));
|
||||||
|
channel.clk_src = RMT_CLK_SRC_DEFAULT;
|
||||||
|
channel.resolution_hz = this->clock_resolution_;
|
||||||
|
channel.mem_block_symbols = rmt_symbols_;
|
||||||
|
channel.gpio_num = gpio_num_t(this->pin_->get_pin());
|
||||||
|
channel.intr_priority = 0;
|
||||||
|
channel.flags.invert_in = 0;
|
||||||
|
channel.flags.with_dma = this->with_dma_;
|
||||||
|
channel.flags.io_loop_back = 0;
|
||||||
|
esp_err_t error = rmt_new_rx_channel(&channel, &this->channel_);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
if (error == ESP_ERR_NOT_FOUND) {
|
||||||
|
this->error_string_ = "out of RMT symbol memory";
|
||||||
|
} else {
|
||||||
|
this->error_string_ = "in rmt_new_rx_channel";
|
||||||
|
}
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error = rmt_enable(this->channel_);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_enable";
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmt_rx_event_callbacks_t callbacks;
|
||||||
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
|
callbacks.on_recv_done = rmt_callback;
|
||||||
|
error = rmt_rx_register_event_callbacks(this->channel_, &callbacks, &this->store_);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_rx_register_event_callbacks";
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t event_size = sizeof(rmt_rx_done_event_data_t);
|
||||||
|
uint32_t max_filter_ns = 255u * 1000 / (RMT_CLK_FREQ / 1000000);
|
||||||
|
uint32_t max_idle_ns = 65535u * 1000;
|
||||||
|
memset(&this->store_.config, 0, sizeof(this->store_.config));
|
||||||
|
this->store_.config.signal_range_min_ns = std::min(this->filter_us_ * 1000, max_filter_ns);
|
||||||
|
this->store_.config.signal_range_max_ns = std::min(this->idle_us_ * 1000, max_idle_ns);
|
||||||
|
this->store_.filter_symbols = this->filter_symbols_;
|
||||||
|
this->store_.receive_size = this->receive_symbols_ * sizeof(rmt_symbol_word_t);
|
||||||
|
this->store_.buffer_size = std::max((event_size + this->store_.receive_size) * 2, this->buffer_size_);
|
||||||
|
this->store_.buffer = new uint8_t[this->buffer_size_];
|
||||||
|
error = rmt_receive(this->channel_, (uint8_t *) this->store_.buffer + event_size, this->store_.receive_size,
|
||||||
|
&this->store_.config);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_receive";
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
this->pin_->setup();
|
this->pin_->setup();
|
||||||
rmt_config_t rmt{};
|
rmt_config_t rmt{};
|
||||||
this->config_rmt(rmt);
|
this->config_rmt(rmt);
|
||||||
|
@ -59,7 +148,9 @@ void RemoteReceiverComponent::setup() {
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteReceiverComponent::dump_config() {
|
void RemoteReceiverComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "Remote Receiver:");
|
ESP_LOGCONFIG(TAG, "Remote Receiver:");
|
||||||
LOG_PIN(" Pin: ", this->pin_);
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
|
@ -67,9 +158,16 @@ void RemoteReceiverComponent::dump_config() {
|
||||||
ESP_LOGW(TAG, "Remote Receiver Signal starts with a HIGH value. Usually this means you have to "
|
ESP_LOGW(TAG, "Remote Receiver Signal starts with a HIGH value. Usually this means you have to "
|
||||||
"invert the signal using 'inverted: True' in the pin schema!");
|
"invert the signal using 'inverted: True' in the pin schema!");
|
||||||
}
|
}
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
ESP_LOGCONFIG(TAG, " Clock resolution: %" PRIu32 " hz", this->clock_resolution_);
|
||||||
|
ESP_LOGCONFIG(TAG, " RMT symbols: %" PRIu32, this->rmt_symbols_);
|
||||||
|
ESP_LOGCONFIG(TAG, " Filter symbols: %" PRIu32, this->filter_symbols_);
|
||||||
|
ESP_LOGCONFIG(TAG, " Receive symbols: %" PRIu32, this->receive_symbols_);
|
||||||
|
#else
|
||||||
ESP_LOGCONFIG(TAG, " Channel: %d", this->channel_);
|
ESP_LOGCONFIG(TAG, " Channel: %d", this->channel_);
|
||||||
ESP_LOGCONFIG(TAG, " RMT memory blocks: %d", this->mem_block_num_);
|
ESP_LOGCONFIG(TAG, " RMT memory blocks: %d", this->mem_block_num_);
|
||||||
ESP_LOGCONFIG(TAG, " Clock divider: %u", this->clock_divider_);
|
ESP_LOGCONFIG(TAG, " Clock divider: %u", this->clock_divider_);
|
||||||
|
#endif
|
||||||
ESP_LOGCONFIG(TAG, " Tolerance: %" PRIu32 "%s", this->tolerance_,
|
ESP_LOGCONFIG(TAG, " Tolerance: %" PRIu32 "%s", this->tolerance_,
|
||||||
(this->tolerance_mode_ == remote_base::TOLERANCE_MODE_TIME) ? " us" : "%");
|
(this->tolerance_mode_ == remote_base::TOLERANCE_MODE_TIME) ? " us" : "%");
|
||||||
ESP_LOGCONFIG(TAG, " Filter out pulses shorter than: %" PRIu32 " us", this->filter_us_);
|
ESP_LOGCONFIG(TAG, " Filter out pulses shorter than: %" PRIu32 " us", this->filter_us_);
|
||||||
|
@ -81,10 +179,38 @@ void RemoteReceiverComponent::dump_config() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteReceiverComponent::loop() {
|
void RemoteReceiverComponent::loop() {
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
if (this->store_.error != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Receive error");
|
||||||
|
this->error_code_ = this->store_.error;
|
||||||
|
this->error_string_ = "in rmt_callback";
|
||||||
|
this->mark_failed();
|
||||||
|
}
|
||||||
|
if (this->store_.overflow) {
|
||||||
|
ESP_LOGW(TAG, "Buffer overflow");
|
||||||
|
this->store_.overflow = false;
|
||||||
|
}
|
||||||
|
uint32_t buffer_write = this->store_.buffer_write;
|
||||||
|
while (this->store_.buffer_read != buffer_write) {
|
||||||
|
rmt_rx_done_event_data_t *event = (rmt_rx_done_event_data_t *) (this->store_.buffer + this->store_.buffer_read);
|
||||||
|
uint32_t event_size = sizeof(rmt_rx_done_event_data_t);
|
||||||
|
uint32_t next_read = this->store_.buffer_read + event_size + event->num_symbols * sizeof(rmt_symbol_word_t);
|
||||||
|
if (next_read + event_size + this->store_.receive_size > this->store_.buffer_size) {
|
||||||
|
next_read = 0;
|
||||||
|
}
|
||||||
|
this->decode_rmt_(event->received_symbols, event->num_symbols);
|
||||||
|
this->store_.buffer_read = next_read;
|
||||||
|
|
||||||
|
if (!this->temp_.empty()) {
|
||||||
|
this->temp_.push_back(-this->idle_us_);
|
||||||
|
this->call_listeners_dumpers_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
auto *item = (rmt_item32_t *) xRingbufferReceive(this->ringbuf_, &len, 0);
|
auto *item = (rmt_item32_t *) xRingbufferReceive(this->ringbuf_, &len, 0);
|
||||||
if (item != nullptr) {
|
if (item != nullptr) {
|
||||||
this->decode_rmt_(item, len);
|
this->decode_rmt_(item, len / sizeof(rmt_item32_t));
|
||||||
vRingbufferReturnItem(this->ringbuf_, item);
|
vRingbufferReturnItem(this->ringbuf_, item);
|
||||||
|
|
||||||
if (this->temp_.empty())
|
if (this->temp_.empty())
|
||||||
|
@ -93,13 +219,18 @@ void RemoteReceiverComponent::loop() {
|
||||||
this->temp_.push_back(-this->idle_us_);
|
this->temp_.push_back(-this->idle_us_);
|
||||||
this->call_listeners_dumpers_();
|
this->call_listeners_dumpers_();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void RemoteReceiverComponent::decode_rmt_(rmt_item32_t *item, size_t len) {
|
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
void RemoteReceiverComponent::decode_rmt_(rmt_symbol_word_t *item, size_t item_count) {
|
||||||
|
#else
|
||||||
|
void RemoteReceiverComponent::decode_rmt_(rmt_item32_t *item, size_t item_count) {
|
||||||
|
#endif
|
||||||
bool prev_level = false;
|
bool prev_level = false;
|
||||||
uint32_t prev_length = 0;
|
uint32_t prev_length = 0;
|
||||||
this->temp_.clear();
|
this->temp_.clear();
|
||||||
int32_t multiplier = this->pin_->is_inverted() ? -1 : 1;
|
int32_t multiplier = this->pin_->is_inverted() ? -1 : 1;
|
||||||
size_t item_count = len / sizeof(rmt_item32_t);
|
|
||||||
uint32_t filter_ticks = this->from_microseconds_(this->filter_us_);
|
uint32_t filter_ticks = this->from_microseconds_(this->filter_us_);
|
||||||
|
|
||||||
ESP_LOGVV(TAG, "START:");
|
ESP_LOGVV(TAG, "START:");
|
||||||
|
@ -124,7 +255,8 @@ void RemoteReceiverComponent::decode_rmt_(rmt_item32_t *item, size_t len) {
|
||||||
this->temp_.reserve(item_count * 2); // each RMT item has 2 pulses
|
this->temp_.reserve(item_count * 2); // each RMT item has 2 pulses
|
||||||
for (size_t i = 0; i < item_count; i++) {
|
for (size_t i = 0; i < item_count; i++) {
|
||||||
if (item[i].duration0 == 0u) {
|
if (item[i].duration0 == 0u) {
|
||||||
// Do nothing
|
// EOF, sometimes garbage follows, break early
|
||||||
|
break;
|
||||||
} else if ((bool(item[i].level0) == prev_level) || (item[i].duration0 < filter_ticks)) {
|
} else if ((bool(item[i].level0) == prev_level) || (item[i].duration0 < filter_ticks)) {
|
||||||
prev_length += item[i].duration0;
|
prev_length += item[i].duration0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,7 +272,8 @@ void RemoteReceiverComponent::decode_rmt_(rmt_item32_t *item, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item[i].duration1 == 0u) {
|
if (item[i].duration1 == 0u) {
|
||||||
// Do nothing
|
// EOF, sometimes garbage follows, break early
|
||||||
|
break;
|
||||||
} else if ((bool(item[i].level1) == prev_level) || (item[i].duration1 < filter_ticks)) {
|
} else if ((bool(item[i].level1) == prev_level) || (item[i].duration1 < filter_ticks)) {
|
||||||
prev_length += item[i].duration1;
|
prev_length += item[i].duration1;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,12 +2,23 @@ from esphome import automation, pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import esp32_rmt, remote_base
|
from esphome.components import esp32_rmt, remote_base
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_CARRIER_DUTY_PERCENT, CONF_ID, CONF_PIN, CONF_RMT_CHANNEL
|
from esphome.const import (
|
||||||
|
CONF_CARRIER_DUTY_PERCENT,
|
||||||
|
CONF_CLOCK_DIVIDER,
|
||||||
|
CONF_CLOCK_RESOLUTION,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_PIN,
|
||||||
|
CONF_RMT_CHANNEL,
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
|
CONF_USE_DMA,
|
||||||
|
)
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
AUTO_LOAD = ["remote_base"]
|
AUTO_LOAD = ["remote_base"]
|
||||||
|
|
||||||
CONF_ON_TRANSMIT = "on_transmit"
|
CONF_ON_TRANSMIT = "on_transmit"
|
||||||
CONF_ON_COMPLETE = "on_complete"
|
CONF_ON_COMPLETE = "on_complete"
|
||||||
|
CONF_ONE_WIRE = "one_wire"
|
||||||
|
|
||||||
remote_transmitter_ns = cg.esphome_ns.namespace("remote_transmitter")
|
remote_transmitter_ns = cg.esphome_ns.namespace("remote_transmitter")
|
||||||
RemoteTransmitterComponent = remote_transmitter_ns.class_(
|
RemoteTransmitterComponent = remote_transmitter_ns.class_(
|
||||||
|
@ -22,7 +33,28 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
cv.Required(CONF_CARRIER_DUTY_PERCENT): cv.All(
|
cv.Required(CONF_CARRIER_DUTY_PERCENT): cv.All(
|
||||||
cv.percentage_int, cv.Range(min=1, max=100)
|
cv.percentage_int, cv.Range(min=1, max=100)
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_RMT_CHANNEL): esp32_rmt.validate_rmt_channel(tx=True),
|
cv.Optional(CONF_CLOCK_RESOLUTION): cv.All(
|
||||||
|
cv.only_on_esp32,
|
||||||
|
cv.only_with_esp_idf,
|
||||||
|
esp32_rmt.validate_clock_resolution(),
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_CLOCK_DIVIDER): cv.All(
|
||||||
|
cv.only_on_esp32, cv.only_with_arduino, cv.int_range(min=1, max=255)
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ONE_WIRE): cv.All(cv.only_with_esp_idf, cv.boolean),
|
||||||
|
cv.Optional(CONF_USE_DMA): cv.All(cv.only_with_esp_idf, cv.boolean),
|
||||||
|
cv.SplitDefault(
|
||||||
|
CONF_RMT_SYMBOLS,
|
||||||
|
esp32_idf=64,
|
||||||
|
esp32_s2_idf=64,
|
||||||
|
esp32_s3_idf=48,
|
||||||
|
esp32_c3_idf=48,
|
||||||
|
esp32_c6_idf=48,
|
||||||
|
esp32_h2_idf=48,
|
||||||
|
): cv.All(cv.only_with_esp_idf, cv.int_range(min=2)),
|
||||||
|
cv.Optional(CONF_RMT_CHANNEL): cv.All(
|
||||||
|
cv.only_with_arduino, esp32_rmt.validate_rmt_channel(tx=True)
|
||||||
|
),
|
||||||
cv.Optional(CONF_ON_TRANSMIT): automation.validate_automation(single=True),
|
cv.Optional(CONF_ON_TRANSMIT): automation.validate_automation(single=True),
|
||||||
cv.Optional(CONF_ON_COMPLETE): automation.validate_automation(single=True),
|
cv.Optional(CONF_ON_COMPLETE): automation.validate_automation(single=True),
|
||||||
}
|
}
|
||||||
|
@ -31,8 +63,24 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
|
|
||||||
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 (rmt_channel := config.get(CONF_RMT_CHANNEL, None)) is not None:
|
if CORE.is_esp32:
|
||||||
var = cg.new_Pvariable(config[CONF_ID], pin, rmt_channel)
|
if esp32_rmt.use_new_rmt_driver():
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], pin)
|
||||||
|
cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS]))
|
||||||
|
if CONF_CLOCK_RESOLUTION in config:
|
||||||
|
cg.add(var.set_clock_resolution(config[CONF_CLOCK_RESOLUTION]))
|
||||||
|
if CONF_USE_DMA in config:
|
||||||
|
cg.add(var.set_with_dma(config[CONF_USE_DMA]))
|
||||||
|
if CONF_ONE_WIRE in config:
|
||||||
|
cg.add(var.set_one_wire(config[CONF_ONE_WIRE]))
|
||||||
|
else:
|
||||||
|
if (rmt_channel := config.get(CONF_RMT_CHANNEL, None)) is not None:
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], pin, rmt_channel)
|
||||||
|
else:
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], pin)
|
||||||
|
if CONF_CLOCK_DIVIDER in config:
|
||||||
|
cg.add(var.set_clock_divider(config[CONF_CLOCK_DIVIDER]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var = cg.new_Pvariable(config[CONF_ID], pin)
|
var = cg.new_Pvariable(config[CONF_ID], pin)
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
#include <driver/rmt_tx.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace remote_transmitter {
|
namespace remote_transmitter {
|
||||||
|
|
||||||
|
@ -16,7 +20,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef USE_ESP32
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 5
|
||||||
RemoteTransmitterComponent(InternalGPIOPin *pin, uint8_t mem_block_num = 1)
|
RemoteTransmitterComponent(InternalGPIOPin *pin, uint8_t mem_block_num = 1)
|
||||||
: remote_base::RemoteTransmitterBase(pin), remote_base::RemoteRMTChannel(mem_block_num) {}
|
: remote_base::RemoteTransmitterBase(pin), remote_base::RemoteRMTChannel(mem_block_num) {}
|
||||||
|
|
||||||
|
@ -29,10 +33,16 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
||||||
|
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
|
|
||||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
// transmitter setup must run after receiver setup to allow the same GPIO to be used by both
|
||||||
|
float get_setup_priority() const override { return setup_priority::DATA - 1; }
|
||||||
|
|
||||||
void set_carrier_duty_percent(uint8_t carrier_duty_percent) { this->carrier_duty_percent_ = carrier_duty_percent; }
|
void set_carrier_duty_percent(uint8_t carrier_duty_percent) { this->carrier_duty_percent_ = carrier_duty_percent; }
|
||||||
|
|
||||||
|
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; }
|
||||||
|
void set_one_wire(bool one_wire) { this->one_wire_ = one_wire; }
|
||||||
|
#endif
|
||||||
|
|
||||||
Trigger<> *get_transmit_trigger() const { return this->transmit_trigger_; };
|
Trigger<> *get_transmit_trigger() const { return this->transmit_trigger_; };
|
||||||
Trigger<> *get_complete_trigger() const { return this->complete_trigger_; };
|
Trigger<> *get_complete_trigger() const { return this->complete_trigger_; };
|
||||||
|
|
||||||
|
@ -54,7 +64,15 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
||||||
|
|
||||||
uint32_t current_carrier_frequency_{38000};
|
uint32_t current_carrier_frequency_{38000};
|
||||||
bool initialized_{false};
|
bool initialized_{false};
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
std::vector<rmt_symbol_word_t> rmt_temp_;
|
||||||
|
bool with_dma_{false};
|
||||||
|
bool one_wire_{false};
|
||||||
|
rmt_channel_handle_t channel_{NULL};
|
||||||
|
rmt_encoder_handle_t encoder_{NULL};
|
||||||
|
#else
|
||||||
std::vector<rmt_item32_t> rmt_temp_;
|
std::vector<rmt_item32_t> rmt_temp_;
|
||||||
|
#endif
|
||||||
esp_err_t error_code_{ESP_OK};
|
esp_err_t error_code_{ESP_OK};
|
||||||
std::string error_string_{""};
|
std::string error_string_{""};
|
||||||
bool inverted_{false};
|
bool inverted_{false};
|
||||||
|
|
|
@ -9,13 +9,22 @@ namespace remote_transmitter {
|
||||||
|
|
||||||
static const char *const TAG = "remote_transmitter";
|
static const char *const TAG = "remote_transmitter";
|
||||||
|
|
||||||
void RemoteTransmitterComponent::setup() { this->configure_rmt_(); }
|
void RemoteTransmitterComponent::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up Remote Transmitter...");
|
||||||
|
this->configure_rmt_();
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteTransmitterComponent::dump_config() {
|
void RemoteTransmitterComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "Remote Transmitter...");
|
ESP_LOGCONFIG(TAG, "Remote Transmitter:");
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
ESP_LOGCONFIG(TAG, " One wire: %s", this->one_wire_ ? "true" : "false");
|
||||||
|
ESP_LOGCONFIG(TAG, " Clock resolution: %" PRIu32 " hz", this->clock_resolution_);
|
||||||
|
ESP_LOGCONFIG(TAG, " RMT symbols: %" PRIu32, this->rmt_symbols_);
|
||||||
|
#else
|
||||||
ESP_LOGCONFIG(TAG, " Channel: %d", this->channel_);
|
ESP_LOGCONFIG(TAG, " Channel: %d", this->channel_);
|
||||||
ESP_LOGCONFIG(TAG, " RMT memory blocks: %d", this->mem_block_num_);
|
ESP_LOGCONFIG(TAG, " RMT memory blocks: %d", this->mem_block_num_);
|
||||||
ESP_LOGCONFIG(TAG, " Clock divider: %u", this->clock_divider_);
|
ESP_LOGCONFIG(TAG, " Clock divider: %u", this->clock_divider_);
|
||||||
|
#endif
|
||||||
LOG_PIN(" Pin: ", this->pin_);
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
|
|
||||||
if (this->current_carrier_frequency_ != 0 && this->carrier_duty_percent_ != 100) {
|
if (this->current_carrier_frequency_ != 0 && this->carrier_duty_percent_ != 100) {
|
||||||
|
@ -29,6 +38,72 @@ void RemoteTransmitterComponent::dump_config() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteTransmitterComponent::configure_rmt_() {
|
void RemoteTransmitterComponent::configure_rmt_() {
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
esp_err_t error;
|
||||||
|
|
||||||
|
if (!this->initialized_) {
|
||||||
|
rmt_tx_channel_config_t channel;
|
||||||
|
memset(&channel, 0, sizeof(channel));
|
||||||
|
channel.clk_src = RMT_CLK_SRC_DEFAULT;
|
||||||
|
channel.resolution_hz = this->clock_resolution_;
|
||||||
|
channel.gpio_num = gpio_num_t(this->pin_->get_pin());
|
||||||
|
channel.mem_block_symbols = this->rmt_symbols_;
|
||||||
|
channel.trans_queue_depth = 1;
|
||||||
|
channel.flags.io_loop_back = this->one_wire_;
|
||||||
|
channel.flags.io_od_mode = this->one_wire_;
|
||||||
|
channel.flags.invert_out = 0;
|
||||||
|
channel.flags.with_dma = this->with_dma_;
|
||||||
|
channel.intr_priority = 0;
|
||||||
|
error = rmt_new_tx_channel(&channel, &this->channel_);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
if (error == ESP_ERR_NOT_FOUND) {
|
||||||
|
this->error_string_ = "out of RMT symbol memory";
|
||||||
|
} else {
|
||||||
|
this->error_string_ = "in rmt_new_tx_channel";
|
||||||
|
}
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmt_copy_encoder_config_t encoder;
|
||||||
|
memset(&encoder, 0, sizeof(encoder));
|
||||||
|
error = rmt_new_copy_encoder(&encoder, &this->encoder_);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_new_copy_encoder";
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = rmt_enable(this->channel_);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_enable";
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->initialized_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->current_carrier_frequency_ == 0 || this->carrier_duty_percent_ == 100) {
|
||||||
|
error = rmt_apply_carrier(this->channel_, nullptr);
|
||||||
|
} else {
|
||||||
|
rmt_carrier_config_t carrier;
|
||||||
|
memset(&carrier, 0, sizeof(carrier));
|
||||||
|
carrier.frequency_hz = this->current_carrier_frequency_;
|
||||||
|
carrier.duty_cycle = (float) this->carrier_duty_percent_ / 100.0f;
|
||||||
|
carrier.flags.polarity_active_low = this->inverted_;
|
||||||
|
carrier.flags.always_on = 1;
|
||||||
|
error = rmt_apply_carrier(this->channel_, &carrier);
|
||||||
|
}
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_apply_carrier";
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
rmt_config_t c{};
|
rmt_config_t c{};
|
||||||
|
|
||||||
this->config_rmt(c);
|
this->config_rmt(c);
|
||||||
|
@ -76,6 +151,7 @@ void RemoteTransmitterComponent::configure_rmt_() {
|
||||||
}
|
}
|
||||||
this->initialized_ = true;
|
this->initialized_ = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t send_wait) {
|
void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t send_wait) {
|
||||||
|
@ -90,7 +166,11 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
|
||||||
this->rmt_temp_.clear();
|
this->rmt_temp_.clear();
|
||||||
this->rmt_temp_.reserve((this->temp_.get_data().size() + 1) / 2);
|
this->rmt_temp_.reserve((this->temp_.get_data().size() + 1) / 2);
|
||||||
uint32_t rmt_i = 0;
|
uint32_t rmt_i = 0;
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
rmt_symbol_word_t rmt_item;
|
||||||
|
#else
|
||||||
rmt_item32_t rmt_item;
|
rmt_item32_t rmt_item;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int32_t val : this->temp_.get_data()) {
|
for (int32_t val : this->temp_.get_data()) {
|
||||||
bool level = val >= 0;
|
bool level = val >= 0;
|
||||||
|
@ -125,6 +205,31 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->transmit_trigger_->trigger();
|
this->transmit_trigger_->trigger();
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
for (uint32_t i = 0; i < send_times; i++) {
|
||||||
|
rmt_transmit_config_t config;
|
||||||
|
memset(&config, 0, sizeof(config));
|
||||||
|
config.loop_count = 0;
|
||||||
|
config.flags.eot_level = this->inverted_;
|
||||||
|
esp_err_t error = rmt_transmit(this->channel_, this->encoder_, this->rmt_temp_.data(),
|
||||||
|
this->rmt_temp_.size() * sizeof(rmt_symbol_word_t), &config);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(TAG, "rmt_transmit failed: %s", esp_err_to_name(error));
|
||||||
|
this->status_set_warning();
|
||||||
|
} else {
|
||||||
|
this->status_clear_warning();
|
||||||
|
}
|
||||||
|
error = rmt_tx_wait_all_done(this->channel_, -1);
|
||||||
|
if (error != ESP_OK) {
|
||||||
|
ESP_LOGW(TAG, "rmt_tx_wait_all_done failed: %s", esp_err_to_name(error));
|
||||||
|
this->status_set_warning();
|
||||||
|
} else {
|
||||||
|
this->status_clear_warning();
|
||||||
|
}
|
||||||
|
if (i + 1 < send_times)
|
||||||
|
delayMicroseconds(send_wait);
|
||||||
|
}
|
||||||
|
#else
|
||||||
for (uint32_t i = 0; i < send_times; i++) {
|
for (uint32_t i = 0; i < send_times; i++) {
|
||||||
esp_err_t error = rmt_write_items(this->channel_, this->rmt_temp_.data(), this->rmt_temp_.size(), true);
|
esp_err_t error = rmt_write_items(this->channel_, this->rmt_temp_.data(), this->rmt_temp_.size(), true);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
|
@ -136,6 +241,7 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
|
||||||
if (i + 1 < send_times)
|
if (i + 1 < send_times)
|
||||||
delayMicroseconds(send_wait);
|
delayMicroseconds(send_wait);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
this->complete_trigger_->trigger();
|
this->complete_trigger_->trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,12 @@ light:
|
||||||
id: led_strip
|
id: led_strip
|
||||||
pin: 4
|
pin: 4
|
||||||
num_leds: 60
|
num_leds: 60
|
||||||
rmt_channel: 0
|
|
||||||
rgb_order: GRB
|
rgb_order: GRB
|
||||||
chipset: ws2812
|
chipset: ws2812
|
||||||
- platform: esp32_rmt_led_strip
|
- platform: esp32_rmt_led_strip
|
||||||
id: led_strip2
|
id: led_strip2
|
||||||
pin: 5
|
pin: 5
|
||||||
num_leds: 60
|
num_leds: 60
|
||||||
rmt_channel: 1
|
|
||||||
rgb_order: RGB
|
rgb_order: RGB
|
||||||
bit0_high: 100µs
|
bit0_high: 100µs
|
||||||
bit0_low: 100µs
|
bit0_low: 100µs
|
||||||
|
|
|
@ -3,14 +3,12 @@ light:
|
||||||
id: led_strip
|
id: led_strip
|
||||||
pin: 13
|
pin: 13
|
||||||
num_leds: 60
|
num_leds: 60
|
||||||
rmt_channel: 6
|
|
||||||
rgb_order: GRB
|
rgb_order: GRB
|
||||||
chipset: ws2812
|
chipset: ws2812
|
||||||
- platform: esp32_rmt_led_strip
|
- platform: esp32_rmt_led_strip
|
||||||
id: led_strip2
|
id: led_strip2
|
||||||
pin: 14
|
pin: 14
|
||||||
num_leds: 60
|
num_leds: 60
|
||||||
rmt_channel: 2
|
|
||||||
rgb_order: RGB
|
rgb_order: RGB
|
||||||
bit0_high: 100µs
|
bit0_high: 100µs
|
||||||
bit0_low: 100µs
|
bit0_low: 100µs
|
||||||
|
|
144
tests/components/remote_receiver/common-actions.yaml
Normal file
144
tests/components/remote_receiver/common-actions.yaml
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
on_abbwelcome:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_abbwelcome: %u"
|
||||||
|
args: ["x.data()[0]"]
|
||||||
|
on_aeha:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_aeha: %u %u"
|
||||||
|
args: ["x.address", "x.data.front()"]
|
||||||
|
on_byronsx:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_byronsx: %u %u"
|
||||||
|
args: ["x.address", "x.command"]
|
||||||
|
on_canalsat:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_canalsat: %u %u"
|
||||||
|
args: ["x.address", "x.command"]
|
||||||
|
# on_canalsatld:
|
||||||
|
# then:
|
||||||
|
# - logger.log:
|
||||||
|
# format: "on_canalsatld: %u %u"
|
||||||
|
# args: ["x.address", "x.command"]
|
||||||
|
on_coolix:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_coolix: %lu %lu"
|
||||||
|
args: ["long(x.first)", "long(x.second)"]
|
||||||
|
on_dish:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_dish: %u %u"
|
||||||
|
args: ["x.address", "x.command"]
|
||||||
|
on_dooya:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_dooya: %u %u %u"
|
||||||
|
args: ["x.channel", "x.button", "x.check"]
|
||||||
|
on_drayton:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_drayton: %u %u %u"
|
||||||
|
args: ["x.address", "x.channel", "x.command"]
|
||||||
|
on_jvc:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_jvc: %lu"
|
||||||
|
args: ["long(x.data)"]
|
||||||
|
on_keeloq:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_keeloq: %lu %lu %u"
|
||||||
|
args: ["long(x.encrypted)", "long(x.address)", "x.command"]
|
||||||
|
on_haier:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_haier: %u"
|
||||||
|
args: ["x.data.front()"]
|
||||||
|
on_lg:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_lg: %lu %u"
|
||||||
|
args: ["long(x.data)", "x.nbits"]
|
||||||
|
on_magiquest:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_magiquest: %u %lu"
|
||||||
|
args: ["x.magnitude", "long(x.wand_id)"]
|
||||||
|
on_midea:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_midea: %u %u"
|
||||||
|
args: ["x.size()", "x.data()[0]"]
|
||||||
|
on_nec:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_nec: %u %u"
|
||||||
|
args: ["x.address", "x.command"]
|
||||||
|
on_nexa:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_nexa: %lu %u %u %u %u"
|
||||||
|
args: ["long(x.device)", "x.group", "x.state", "x.channel", "x.level"]
|
||||||
|
on_panasonic:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_panasonic: %u %lu"
|
||||||
|
args: ["x.address", "long(x.command)"]
|
||||||
|
on_pioneer:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_pioneer: %u %u"
|
||||||
|
args: ["x.rc_code_1", "x.rc_code_2"]
|
||||||
|
on_pronto:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_pronto: %s"
|
||||||
|
args: ["x.data.c_str()"]
|
||||||
|
on_raw:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_raw: %lu"
|
||||||
|
args: ["long(x.front())"]
|
||||||
|
on_rc5:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_rc5: %u %u"
|
||||||
|
args: ["x.address", "x.command"]
|
||||||
|
on_rc6:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_rc6: %u %u"
|
||||||
|
args: ["x.address", "x.command"]
|
||||||
|
on_rc_switch:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_rc_switch: %llu %u"
|
||||||
|
args: ["x.code", "x.protocol"]
|
||||||
|
on_samsung:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_samsung: %llu %u"
|
||||||
|
args: ["x.data", "x.nbits"]
|
||||||
|
on_samsung36:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_samsung36: %u %lu"
|
||||||
|
args: ["x.address", "long(x.command)"]
|
||||||
|
on_sony:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_sony: %lu %u"
|
||||||
|
args: ["long(x.data)", "x.nbits"]
|
||||||
|
on_toshiba_ac:
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
format: "on_toshiba_ac: %llu %llu"
|
||||||
|
args: ["x.rc_code_1", "x.rc_code_2"]
|
||||||
|
on_mirage:
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.data).c_str());
|
14
tests/components/remote_receiver/esp32-common-ard.yaml
Normal file
14
tests/components/remote_receiver/esp32-common-ard.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
remote_receiver:
|
||||||
|
- id: rcvr
|
||||||
|
pin: ${pin}
|
||||||
|
rmt_channel: ${rmt_channel}
|
||||||
|
dump: all
|
||||||
|
tolerance: 25%
|
||||||
|
<<: !include common-actions.yaml
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: remote_receiver
|
||||||
|
name: Panasonic Remote Input
|
||||||
|
panasonic:
|
||||||
|
address: 0x4004
|
||||||
|
command: 0x100BCBD
|
18
tests/components/remote_receiver/esp32-common-idf.yaml
Normal file
18
tests/components/remote_receiver/esp32-common-idf.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
remote_receiver:
|
||||||
|
- id: rcvr
|
||||||
|
pin: ${pin}
|
||||||
|
dump: all
|
||||||
|
tolerance: 25%
|
||||||
|
clock_resolution: ${clock_resolution}
|
||||||
|
filter_symbols: ${filter_symbols}
|
||||||
|
receive_symbols: ${receive_symbols}
|
||||||
|
rmt_symbols: ${rmt_symbols}
|
||||||
|
use_dma: ${use_dma}
|
||||||
|
<<: !include common-actions.yaml
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: remote_receiver
|
||||||
|
name: Panasonic Remote Input
|
||||||
|
panasonic:
|
||||||
|
address: 0x4004
|
||||||
|
command: 0x100BCBD
|
|
@ -1,157 +0,0 @@
|
||||||
remote_receiver:
|
|
||||||
id: rcvr
|
|
||||||
pin: ${pin}
|
|
||||||
rmt_channel: ${rmt_channel}
|
|
||||||
dump: all
|
|
||||||
tolerance: 25%
|
|
||||||
on_abbwelcome:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_abbwelcome: %u"
|
|
||||||
args: ["x.data()[0]"]
|
|
||||||
on_aeha:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_aeha: %u %u"
|
|
||||||
args: ["x.address", "x.data.front()"]
|
|
||||||
on_byronsx:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_byronsx: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_canalsat:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_canalsat: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
# on_canalsatld:
|
|
||||||
# then:
|
|
||||||
# - logger.log:
|
|
||||||
# format: "on_canalsatld: %u %u"
|
|
||||||
# args: ["x.address", "x.command"]
|
|
||||||
on_coolix:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_coolix: %lu %lu"
|
|
||||||
args: ["long(x.first)", "long(x.second)"]
|
|
||||||
on_dish:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_dish: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_dooya:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_dooya: %u %u %u"
|
|
||||||
args: ["x.channel", "x.button", "x.check"]
|
|
||||||
on_drayton:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_drayton: %u %u %u"
|
|
||||||
args: ["x.address", "x.channel", "x.command"]
|
|
||||||
on_jvc:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_jvc: %lu"
|
|
||||||
args: ["long(x.data)"]
|
|
||||||
on_keeloq:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_keeloq: %lu %lu %u"
|
|
||||||
args: ["long(x.encrypted)", "long(x.address)", "x.command"]
|
|
||||||
on_haier:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_haier: %u"
|
|
||||||
args: ["x.data.front()"]
|
|
||||||
on_lg:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_lg: %lu %u"
|
|
||||||
args: ["long(x.data)", "x.nbits"]
|
|
||||||
on_magiquest:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_magiquest: %u %lu"
|
|
||||||
args: ["x.magnitude", "long(x.wand_id)"]
|
|
||||||
on_midea:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_midea: %u %u"
|
|
||||||
args: ["x.size()", "x.data()[0]"]
|
|
||||||
on_nec:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_nec: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_nexa:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_nexa: %lu %u %u %u %u"
|
|
||||||
args: ["long(x.device)", "x.group", "x.state", "x.channel", "x.level"]
|
|
||||||
on_panasonic:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_panasonic: %u %lu"
|
|
||||||
args: ["x.address", "long(x.command)"]
|
|
||||||
on_pioneer:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_pioneer: %u %u"
|
|
||||||
args: ["x.rc_code_1", "x.rc_code_2"]
|
|
||||||
on_pronto:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_pronto: %s"
|
|
||||||
args: ["x.data.c_str()"]
|
|
||||||
on_raw:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_raw: %lu"
|
|
||||||
args: ["long(x.front())"]
|
|
||||||
on_rc5:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_rc5: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_rc6:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_rc6: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_rc_switch:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_rc_switch: %llu %u"
|
|
||||||
args: ["x.code", "x.protocol"]
|
|
||||||
on_samsung:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_samsung: %llu %u"
|
|
||||||
args: ["x.data", "x.nbits"]
|
|
||||||
on_samsung36:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_samsung36: %u %lu"
|
|
||||||
args: ["x.address", "long(x.command)"]
|
|
||||||
on_sony:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_sony: %lu %u"
|
|
||||||
args: ["long(x.data)", "x.nbits"]
|
|
||||||
on_toshiba_ac:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_toshiba_ac: %llu %llu"
|
|
||||||
args: ["x.rc_code_1", "x.rc_code_2"]
|
|
||||||
on_mirage:
|
|
||||||
then:
|
|
||||||
- lambda: |-
|
|
||||||
ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.data).c_str());
|
|
||||||
|
|
||||||
binary_sensor:
|
|
||||||
- platform: remote_receiver
|
|
||||||
name: Panasonic Remote Input
|
|
||||||
panasonic:
|
|
||||||
address: 0x4004
|
|
||||||
command: 0x100BCBD
|
|
|
@ -3,4 +3,4 @@ substitutions:
|
||||||
rmt_channel: "2"
|
rmt_channel: "2"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-ard.yaml
|
||||||
|
|
|
@ -3,4 +3,4 @@ substitutions:
|
||||||
rmt_channel: "2"
|
rmt_channel: "2"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-ard.yaml
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
substitutions:
|
substitutions:
|
||||||
pin: GPIO2
|
pin: GPIO2
|
||||||
rmt_channel: "2"
|
clock_resolution: "2000000"
|
||||||
|
filter_symbols: "2"
|
||||||
|
receive_symbols: "4"
|
||||||
|
rmt_symbols: "64"
|
||||||
|
use_dma: "true"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-idf.yaml
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
substitutions:
|
substitutions:
|
||||||
pin: GPIO2
|
pin: GPIO2
|
||||||
rmt_channel: "2"
|
clock_resolution: "2000000"
|
||||||
|
filter_symbols: "2"
|
||||||
|
receive_symbols: "4"
|
||||||
|
rmt_symbols: "64"
|
||||||
|
use_dma: "true"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-idf.yaml
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
substitutions:
|
substitutions:
|
||||||
pin: GPIO38
|
pin: GPIO38
|
||||||
rmt_channel: "5"
|
clock_resolution: "2000000"
|
||||||
|
filter_symbols: "2"
|
||||||
|
receive_symbols: "4"
|
||||||
|
rmt_symbols: "64"
|
||||||
|
use_dma: "true"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-idf.yaml
|
||||||
|
|
|
@ -2,150 +2,7 @@ remote_receiver:
|
||||||
id: rcvr
|
id: rcvr
|
||||||
pin: GPIO5
|
pin: GPIO5
|
||||||
dump: all
|
dump: all
|
||||||
on_abbwelcome:
|
<<: !include common-actions.yaml
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_abbwelcome: %u"
|
|
||||||
args: ["x.data()[0]"]
|
|
||||||
on_aeha:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_aeha: %u %u"
|
|
||||||
args: ["x.address", "x.data.front()"]
|
|
||||||
on_byronsx:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_byronsx: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_canalsat:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_canalsat: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
# on_canalsatld:
|
|
||||||
# then:
|
|
||||||
# - logger.log:
|
|
||||||
# format: "on_canalsatld: %u %u"
|
|
||||||
# args: ["x.address", "x.command"]
|
|
||||||
on_coolix:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_coolix: %u %u"
|
|
||||||
args: ["x.first", "x.second"]
|
|
||||||
on_dish:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_dish: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_dooya:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_dooya: %u %u %u"
|
|
||||||
args: ["x.channel", "x.button", "x.check"]
|
|
||||||
on_drayton:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_drayton: %u %u %u"
|
|
||||||
args: ["x.address", "x.channel", "x.command"]
|
|
||||||
on_jvc:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_jvc: %u"
|
|
||||||
args: ["x.data"]
|
|
||||||
on_keeloq:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_keeloq: %u %u %u"
|
|
||||||
args: ["x.encrypted", "x.address", "x.command"]
|
|
||||||
on_haier:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_haier: %u"
|
|
||||||
args: ["x.data.front()"]
|
|
||||||
on_lg:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_lg: %u %u"
|
|
||||||
args: ["x.data", "x.nbits"]
|
|
||||||
on_magiquest:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_magiquest: %u %u"
|
|
||||||
args: ["x.magnitude", "x.wand_id"]
|
|
||||||
on_midea:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_midea: %u %u"
|
|
||||||
args: ["x.size()", "x.data()[0]"]
|
|
||||||
on_nec:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_nec: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_nexa:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_nexa: %u %u %u %u %u"
|
|
||||||
args: ["x.device", "x.group", "x.state", "x.channel", "x.level"]
|
|
||||||
on_panasonic:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_panasonic: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_pioneer:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_pioneer: %u %u"
|
|
||||||
args: ["x.rc_code_1", "x.rc_code_2"]
|
|
||||||
on_pronto:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_pronto: %s"
|
|
||||||
args: ["x.data.c_str()"]
|
|
||||||
on_raw:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_raw: %u"
|
|
||||||
args: ["x.front()"]
|
|
||||||
on_rc5:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_rc5: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_rc6:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_rc6: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_rc_switch:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_rc_switch: %llu %u"
|
|
||||||
args: ["x.code", "x.protocol"]
|
|
||||||
on_samsung:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_samsung: %llu %u"
|
|
||||||
args: ["x.data", "x.nbits"]
|
|
||||||
on_samsung36:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_samsung36: %u %u"
|
|
||||||
args: ["x.address", "x.command"]
|
|
||||||
on_sony:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_sony: %u %u"
|
|
||||||
args: ["x.data", "x.nbits"]
|
|
||||||
on_toshiba_ac:
|
|
||||||
then:
|
|
||||||
- logger.log:
|
|
||||||
format: "on_toshiba_ac: %llu %llu"
|
|
||||||
args: ["x.rc_code_1", "x.rc_code_2"]
|
|
||||||
on_mirage:
|
|
||||||
then:
|
|
||||||
- lambda: |-
|
|
||||||
ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.data).c_str());
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: remote_receiver
|
- platform: remote_receiver
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
remote_transmitter:
|
||||||
|
- id: xmitr
|
||||||
|
pin: ${pin}
|
||||||
|
rmt_channel: ${rmt_channel}
|
||||||
|
carrier_duty_percent: 50%
|
||||||
|
|
||||||
|
packages:
|
||||||
|
buttons: !include common-buttons.yaml
|
11
tests/components/remote_transmitter/esp32-common-idf.yaml
Normal file
11
tests/components/remote_transmitter/esp32-common-idf.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
remote_transmitter:
|
||||||
|
- id: xmitr
|
||||||
|
pin: ${pin}
|
||||||
|
carrier_duty_percent: 50%
|
||||||
|
clock_resolution: ${clock_resolution}
|
||||||
|
one_wire: ${one_wire}
|
||||||
|
rmt_symbols: ${rmt_symbols}
|
||||||
|
use_dma: ${use_dma}
|
||||||
|
|
||||||
|
packages:
|
||||||
|
buttons: !include common-buttons.yaml
|
|
@ -1,8 +0,0 @@
|
||||||
remote_transmitter:
|
|
||||||
id: rcvr
|
|
||||||
pin: ${pin}
|
|
||||||
rmt_channel: ${rmt_channel}
|
|
||||||
carrier_duty_percent: 50%
|
|
||||||
|
|
||||||
packages:
|
|
||||||
buttons: !include common-buttons.yaml
|
|
|
@ -3,4 +3,4 @@ substitutions:
|
||||||
rmt_channel: "2"
|
rmt_channel: "2"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-ard.yaml
|
||||||
|
|
|
@ -3,4 +3,4 @@ substitutions:
|
||||||
rmt_channel: "1"
|
rmt_channel: "1"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-ard.yaml
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
substitutions:
|
substitutions:
|
||||||
pin: GPIO2
|
pin: GPIO2
|
||||||
rmt_channel: "1"
|
clock_resolution: "2000000"
|
||||||
|
one_wire: "true"
|
||||||
|
rmt_symbols: "64"
|
||||||
|
use_dma: "true"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-idf.yaml
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
substitutions:
|
substitutions:
|
||||||
pin: GPIO2
|
pin: GPIO2
|
||||||
rmt_channel: "2"
|
clock_resolution: "2000000"
|
||||||
|
one_wire: "true"
|
||||||
|
rmt_symbols: "64"
|
||||||
|
use_dma: "true"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-idf.yaml
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
substitutions:
|
substitutions:
|
||||||
pin: GPIO38
|
pin: GPIO38
|
||||||
rmt_channel: "3"
|
clock_resolution: "2000000"
|
||||||
|
one_wire: "true"
|
||||||
|
rmt_symbols: "64"
|
||||||
|
use_dma: "true"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
common: !include esp32-common.yaml
|
common: !include esp32-common-idf.yaml
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
remote_transmitter:
|
remote_transmitter:
|
||||||
id: trns
|
id: xmitr
|
||||||
pin: GPIO5
|
pin: GPIO5
|
||||||
carrier_duty_percent: 50%
|
carrier_duty_percent: 50%
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue