mirror of
https://github.com/esphome/esphome.git
synced 2025-02-07 00:11:59 +01:00
Merge branch 'dev' into fix_rc5_recv
This commit is contained in:
commit
960def454b
@ -133,6 +133,7 @@ esphome/components/ens160_i2c/* @latonita
|
||||
esphome/components/ens160_spi/* @latonita
|
||||
esphome/components/ens210/* @itn3rd77
|
||||
esphome/components/es7210/* @kahrendt
|
||||
esphome/components/es7243e/* @kbx81
|
||||
esphome/components/es8156/* @kbx81
|
||||
esphome/components/es8311/* @kahrendt @kroimon
|
||||
esphome/components/esp32/* @esphome/core
|
||||
|
@ -9,8 +9,6 @@ static const char *const TAG = "ads1115";
|
||||
static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00;
|
||||
static const uint8_t ADS1115_REGISTER_CONFIG = 0x01;
|
||||
|
||||
static const uint8_t ADS1115_DATA_RATE_860_SPS = 0b111; // 3300_SPS for ADS1015
|
||||
|
||||
void ADS1115Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up ADS1115...");
|
||||
uint16_t value;
|
||||
@ -43,9 +41,9 @@ void ADS1115Component::setup() {
|
||||
config |= 0b0000000100000000;
|
||||
}
|
||||
|
||||
// Set data rate - 860 samples per second (we're in singleshot mode)
|
||||
// Set data rate - 860 samples per second
|
||||
// 0bxxxxxxxx100xxxxx
|
||||
config |= ADS1115_DATA_RATE_860_SPS << 5;
|
||||
config |= ADS1115_860SPS << 5;
|
||||
|
||||
// Set comparator mode - hysteresis
|
||||
// 0bxxxxxxxxxxx0xxxx
|
||||
@ -77,7 +75,7 @@ void ADS1115Component::dump_config() {
|
||||
}
|
||||
}
|
||||
float ADS1115Component::request_measurement(ADS1115Multiplexer multiplexer, ADS1115Gain gain,
|
||||
ADS1115Resolution resolution) {
|
||||
ADS1115Resolution resolution, ADS1115Samplerate samplerate) {
|
||||
uint16_t config = this->prev_config_;
|
||||
// Multiplexer
|
||||
// 0bxBBBxxxxxxxxxxxx
|
||||
@ -89,6 +87,11 @@ float ADS1115Component::request_measurement(ADS1115Multiplexer multiplexer, ADS1
|
||||
config &= 0b1111000111111111;
|
||||
config |= (gain & 0b111) << 9;
|
||||
|
||||
// Sample rate
|
||||
// 0bxxxxxxxxBBBxxxxx
|
||||
config &= 0b1111111100011111;
|
||||
config |= (samplerate & 0b111) << 5;
|
||||
|
||||
if (!this->continuous_mode_) {
|
||||
// Start conversion
|
||||
config |= 0b1000000000000000;
|
||||
@ -101,8 +104,54 @@ float ADS1115Component::request_measurement(ADS1115Multiplexer multiplexer, ADS1
|
||||
}
|
||||
this->prev_config_ = config;
|
||||
|
||||
// about 1.2 ms with 860 samples per second
|
||||
delay(2);
|
||||
// Delay calculated as: ceil((1000/SPS)+.5)
|
||||
if (resolution == ADS1015_12_BITS) {
|
||||
switch (samplerate) {
|
||||
case ADS1115_8SPS:
|
||||
delay(9);
|
||||
break;
|
||||
case ADS1115_16SPS:
|
||||
delay(5);
|
||||
break;
|
||||
case ADS1115_32SPS:
|
||||
delay(3);
|
||||
break;
|
||||
case ADS1115_64SPS:
|
||||
case ADS1115_128SPS:
|
||||
delay(2);
|
||||
break;
|
||||
default:
|
||||
delay(1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (samplerate) {
|
||||
case ADS1115_8SPS:
|
||||
delay(126); // NOLINT
|
||||
break;
|
||||
case ADS1115_16SPS:
|
||||
delay(63); // NOLINT
|
||||
break;
|
||||
case ADS1115_32SPS:
|
||||
delay(32);
|
||||
break;
|
||||
case ADS1115_64SPS:
|
||||
delay(17);
|
||||
break;
|
||||
case ADS1115_128SPS:
|
||||
delay(9);
|
||||
break;
|
||||
case ADS1115_250SPS:
|
||||
delay(5);
|
||||
break;
|
||||
case ADS1115_475SPS:
|
||||
delay(3);
|
||||
break;
|
||||
case ADS1115_860SPS:
|
||||
delay(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// in continuous mode, conversion will always be running, rely on the delay
|
||||
// to ensure conversion is taking place with the correct settings
|
||||
|
@ -33,6 +33,17 @@ enum ADS1115Resolution {
|
||||
ADS1015_12_BITS = 12,
|
||||
};
|
||||
|
||||
enum ADS1115Samplerate {
|
||||
ADS1115_8SPS = 0b000,
|
||||
ADS1115_16SPS = 0b001,
|
||||
ADS1115_32SPS = 0b010,
|
||||
ADS1115_64SPS = 0b011,
|
||||
ADS1115_128SPS = 0b100,
|
||||
ADS1115_250SPS = 0b101,
|
||||
ADS1115_475SPS = 0b110,
|
||||
ADS1115_860SPS = 0b111
|
||||
};
|
||||
|
||||
class ADS1115Component : public Component, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
@ -42,7 +53,8 @@ class ADS1115Component : public Component, public i2c::I2CDevice {
|
||||
void set_continuous_mode(bool continuous_mode) { continuous_mode_ = continuous_mode; }
|
||||
|
||||
/// Helper method to request a measurement from a sensor.
|
||||
float request_measurement(ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution);
|
||||
float request_measurement(ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution,
|
||||
ADS1115Samplerate samplerate);
|
||||
|
||||
protected:
|
||||
uint16_t prev_config_{0};
|
||||
|
@ -5,6 +5,7 @@ from esphome.const import (
|
||||
CONF_GAIN,
|
||||
CONF_MULTIPLEXER,
|
||||
CONF_RESOLUTION,
|
||||
CONF_SAMPLE_RATE,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_VOLT,
|
||||
@ -43,6 +44,17 @@ RESOLUTION = {
|
||||
"12_BITS": ADS1115Resolution.ADS1015_12_BITS,
|
||||
}
|
||||
|
||||
ADS1115Samplerate = ads1115_ns.enum("ADS1115Samplerate")
|
||||
SAMPLERATE = {
|
||||
"8": ADS1115Samplerate.ADS1115_8SPS,
|
||||
"16": ADS1115Samplerate.ADS1115_16SPS,
|
||||
"32": ADS1115Samplerate.ADS1115_32SPS,
|
||||
"64": ADS1115Samplerate.ADS1115_64SPS,
|
||||
"128": ADS1115Samplerate.ADS1115_128SPS,
|
||||
"250": ADS1115Samplerate.ADS1115_250SPS,
|
||||
"475": ADS1115Samplerate.ADS1115_475SPS,
|
||||
"860": ADS1115Samplerate.ADS1115_860SPS,
|
||||
}
|
||||
|
||||
ADS1115Sensor = ads1115_ns.class_(
|
||||
"ADS1115Sensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||
@ -64,6 +76,9 @@ CONFIG_SCHEMA = (
|
||||
cv.Optional(CONF_RESOLUTION, default="16_BITS"): cv.enum(
|
||||
RESOLUTION, upper=True, space="_"
|
||||
),
|
||||
cv.Optional(CONF_SAMPLE_RATE, default="860"): cv.enum(
|
||||
SAMPLERATE, string=True
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
@ -79,3 +94,4 @@ async def to_code(config):
|
||||
cg.add(var.set_multiplexer(config[CONF_MULTIPLEXER]))
|
||||
cg.add(var.set_gain(config[CONF_GAIN]))
|
||||
cg.add(var.set_resolution(config[CONF_RESOLUTION]))
|
||||
cg.add(var.set_samplerate(config[CONF_SAMPLE_RATE]))
|
||||
|
@ -8,7 +8,7 @@ namespace ads1115 {
|
||||
static const char *const TAG = "ads1115.sensor";
|
||||
|
||||
float ADS1115Sensor::sample() {
|
||||
return this->parent_->request_measurement(this->multiplexer_, this->gain_, this->resolution_);
|
||||
return this->parent_->request_measurement(this->multiplexer_, this->gain_, this->resolution_, this->samplerate_);
|
||||
}
|
||||
|
||||
void ADS1115Sensor::update() {
|
||||
@ -24,6 +24,7 @@ void ADS1115Sensor::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Multiplexer: %u", this->multiplexer_);
|
||||
ESP_LOGCONFIG(TAG, " Gain: %u", this->gain_);
|
||||
ESP_LOGCONFIG(TAG, " Resolution: %u", this->resolution_);
|
||||
ESP_LOGCONFIG(TAG, " Sample rate: %u", this->samplerate_);
|
||||
}
|
||||
|
||||
} // namespace ads1115
|
||||
|
@ -21,6 +21,7 @@ class ADS1115Sensor : public sensor::Sensor,
|
||||
void set_multiplexer(ADS1115Multiplexer multiplexer) { this->multiplexer_ = multiplexer; }
|
||||
void set_gain(ADS1115Gain gain) { this->gain_ = gain; }
|
||||
void set_resolution(ADS1115Resolution resolution) { this->resolution_ = resolution; }
|
||||
void set_samplerate(ADS1115Samplerate samplerate) { this->samplerate_ = samplerate; }
|
||||
float sample() override;
|
||||
|
||||
void dump_config() override;
|
||||
@ -29,6 +30,7 @@ class ADS1115Sensor : public sensor::Sensor,
|
||||
ADS1115Multiplexer multiplexer_;
|
||||
ADS1115Gain gain_;
|
||||
ADS1115Resolution resolution_;
|
||||
ADS1115Samplerate samplerate_;
|
||||
};
|
||||
|
||||
} // namespace ads1115
|
||||
|
@ -19,6 +19,7 @@ from .boards import BK72XX_BOARD_PINS, BK72XX_BOARDS
|
||||
|
||||
CODEOWNERS = ["@kuba2k2"]
|
||||
AUTO_LOAD = ["libretiny"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
COMPONENT_DATA = LibreTinyComponent(
|
||||
name=COMPONENT_BK72XX,
|
||||
|
@ -35,8 +35,8 @@ void DebugComponent::log_partition_info_() {
|
||||
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
while (it != NULL) {
|
||||
const esp_partition_t *partition = esp_partition_get(it);
|
||||
ESP_LOGCONFIG(TAG, " %-12s %-4d %-8d 0x%08X 0x%08X", partition->label, partition->type, partition->subtype,
|
||||
partition->address, partition->size);
|
||||
ESP_LOGCONFIG(TAG, " %-12s %-4d %-8d 0x%08" PRIX32 " 0x%08" PRIX32, partition->label, partition->type,
|
||||
partition->subtype, partition->address, partition->size);
|
||||
it = esp_partition_next(it);
|
||||
}
|
||||
esp_partition_iterator_release(it);
|
||||
|
0
esphome/components/es7243e/__init__.py
Normal file
0
esphome/components/es7243e/__init__.py
Normal file
34
esphome/components/es7243e/audio_adc.py
Normal file
34
esphome/components/es7243e/audio_adc.py
Normal file
@ -0,0 +1,34 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
from esphome.components.audio_adc import AudioAdc
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_MIC_GAIN
|
||||
|
||||
CODEOWNERS = ["@kbx81"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
es7243e_ns = cg.esphome_ns.namespace("es7243e")
|
||||
ES7243E = es7243e_ns.class_("ES7243E", AudioAdc, cg.Component, i2c.I2CDevice)
|
||||
|
||||
ES7243E_MIC_GAINS = [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 34.5, 36, 37.5]
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ES7243E),
|
||||
cv.Optional(CONF_MIC_GAIN, default="24db"): cv.All(
|
||||
cv.decibel, cv.one_of(*ES7243E_MIC_GAINS)
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x10))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
cg.add(var.set_mic_gain(config[CONF_MIC_GAIN]))
|
125
esphome/components/es7243e/es7243e.cpp
Normal file
125
esphome/components/es7243e/es7243e.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include "es7243e.h"
|
||||
#include "es7243e_const.h"
|
||||
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace es7243e {
|
||||
|
||||
static const char *const TAG = "es7243e";
|
||||
|
||||
// Mark the component as failed; use only in setup
|
||||
#define ES7243E_ERROR_FAILED(func) \
|
||||
if (!(func)) { \
|
||||
this->mark_failed(); \
|
||||
return; \
|
||||
}
|
||||
|
||||
// Return false; use outside of setup
|
||||
#define ES7243E_ERROR_CHECK(func) \
|
||||
if (!(func)) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
void ES7243E::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ES7243E audio ADC:");
|
||||
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, " Failed to initialize");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ES7243E::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up ES7243E...");
|
||||
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG01, 0x3A));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_RESET_REG00, 0x80));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_TEST_MODE_REGF9, 0x00));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG04, 0x02));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG04, 0x01));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_TEST_MODE_REGF9, 0x01));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_RESET_REG00, 0x1E));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG01, 0x00));
|
||||
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG02, 0x00));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG03, 0x20));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG04, 0x01));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ADC_CTRL_REG0D, 0x00));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG05, 0x00));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG06, 0x03)); // SCLK=MCLK/4
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG07, 0x00)); // LRCK=MCLK/256
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG08, 0xFF)); // LRCK=MCLK/256
|
||||
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG09, 0xCA));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_SDP_REG0A, 0x85));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_SDP_REG0B, 0x00));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ADC_CTRL_REG0E, 0xBF));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ADC_CTRL_REG0F, 0x80));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ADC_CTRL_REG14, 0x0C));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ADC_CTRL_REG15, 0x0C));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG17, 0x02));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG18, 0x26));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG19, 0x77));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG1A, 0xF4));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG1B, 0x66));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG1C, 0x44));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG1E, 0x00));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG1F, 0x0C));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG20, 0x1A)); // PGA gain +30dB
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG21, 0x1A));
|
||||
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_RESET_REG00, 0x80));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG01, 0x3A));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG16, 0x3F));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG16, 0x00));
|
||||
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_TEST_MODE_REGF9, 0x00));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG04, 0x01));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG17, 0x01));
|
||||
ES7243E_ERROR_FAILED(this->configure_mic_gain_());
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_RESET_REG00, 0x80));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_CLOCK_MGR_REG01, 0x3A));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG16, 0x3F));
|
||||
ES7243E_ERROR_FAILED(this->write_byte(ES7243E_ANALOG_REG16, 0x00));
|
||||
|
||||
this->setup_complete_ = true;
|
||||
}
|
||||
|
||||
bool ES7243E::set_mic_gain(float mic_gain) {
|
||||
this->mic_gain_ = clamp<float>(mic_gain, 0, 37.5);
|
||||
if (this->setup_complete_) {
|
||||
return this->configure_mic_gain_();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES7243E::configure_mic_gain_() {
|
||||
auto regv = this->es7243e_gain_reg_value_(this->mic_gain_);
|
||||
|
||||
ES7243E_ERROR_CHECK(this->write_byte(ES7243E_ANALOG_REG20, 0x10 | regv));
|
||||
ES7243E_ERROR_CHECK(this->write_byte(ES7243E_ANALOG_REG21, 0x10 | regv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t ES7243E::es7243e_gain_reg_value_(float mic_gain) {
|
||||
// reg: 12 - 34.5dB, 13 - 36dB, 14 - 37.5dB
|
||||
mic_gain += 0.5;
|
||||
if (mic_gain <= 33.0) {
|
||||
return (uint8_t) mic_gain / 3;
|
||||
}
|
||||
if (mic_gain < 36.0) {
|
||||
return 12;
|
||||
}
|
||||
if (mic_gain < 37.0) {
|
||||
return 13;
|
||||
}
|
||||
return 14;
|
||||
}
|
||||
|
||||
} // namespace es7243e
|
||||
} // namespace esphome
|
37
esphome/components/es7243e/es7243e.h
Normal file
37
esphome/components/es7243e/es7243e.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/audio_adc/audio_adc.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es7243e {
|
||||
|
||||
class ES7243E : public audio_adc::AudioAdc, public Component, public i2c::I2CDevice {
|
||||
/* Class for configuring an ES7243E ADC for microphone input.
|
||||
* Based on code from:
|
||||
* - https://github.com/espressif/esp-adf/ (accessed 20250116)
|
||||
*/
|
||||
public:
|
||||
void setup() override;
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
void dump_config() override;
|
||||
|
||||
bool set_mic_gain(float mic_gain) override;
|
||||
|
||||
float mic_gain() override { return this->mic_gain_; };
|
||||
|
||||
protected:
|
||||
/// @brief Convert floating point mic gain value to register value
|
||||
/// @param mic_gain Gain value to convert
|
||||
/// @return Corresponding register value for specified gain
|
||||
uint8_t es7243e_gain_reg_value_(float mic_gain);
|
||||
|
||||
bool configure_mic_gain_();
|
||||
|
||||
bool setup_complete_{false};
|
||||
float mic_gain_{0};
|
||||
};
|
||||
|
||||
} // namespace es7243e
|
||||
} // namespace esphome
|
54
esphome/components/es7243e/es7243e_const.h
Normal file
54
esphome/components/es7243e/es7243e_const.h
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace es7243e {
|
||||
|
||||
// ES7243E register addresses
|
||||
static const uint8_t ES7243E_RESET_REG00 = 0x00; // Reset control
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG01 = 0x01; // MCLK/BCLK/ADCCLK/Analog clocks on/off
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG02 = 0x02; // MCLK & BCLK configuration, source selection
|
||||
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG03 = 0x03; // ADC Over-sample rate control
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG04 = 0x04; // Pre-divide/Pre-multiplication
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG05 = 0x05; // CF/DSP clock divider
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG06 = 0x06; // BCLK divider at master mode
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG07 = 0x07; // BCLK/LRCK/SDOUT tri-state control/LRCK divider bit 11->8
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG08 = 0x08; // Master LRCK divider bit 7 to bit 0
|
||||
static const uint8_t ES7243E_CLOCK_MGR_REG09 = 0x09; // SEL S1/Timer for S1
|
||||
static const uint8_t ES7243E_SDP_REG0A = 0x0A; // SEL S3/Timer for S3
|
||||
static const uint8_t ES7243E_SDP_REG0B = 0x0B; // SDP out mute control/I2S/left-justify case/word length/format
|
||||
static const uint8_t ES7243E_SDP_REG0C = 0x0C; // NFS flag at slot0/LSB/TDM mode selection
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG0D = 0x0D; // data mux/pol. inv./ram clear on lrck/mclk active/gain scale up
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG0E = 0x0E; // volume control
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG0F = 0x0F; // offset freeze/auto level control/automute control/VC ramp rate
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG10 = 0x10; // automute noise gate/detection
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG11 = 0x11; // automute SDP control/out gain select
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG12 = 0x12; // controls for automute PDN_PGA/MOD/reset/digital circuit
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG13 = 0x13; // ALC rate selection/ALC target level
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG14 = 0x14; // ADCHPF stage1 coeff
|
||||
static const uint8_t ES7243E_ADC_CTRL_REG15 = 0x15; // ADCHPF stage2 coeff
|
||||
static const uint8_t ES7243E_ANALOG_REG16 = 0x16; // power-down/reset
|
||||
static const uint8_t ES7243E_ANALOG_REG17 = 0x17; // VMIDSEL
|
||||
static const uint8_t ES7243E_ANALOG_REG18 = 0x18; // ADC/ADCFL bias
|
||||
static const uint8_t ES7243E_ANALOG_REG19 = 0x19; // PGA1/PGA2 bias
|
||||
static const uint8_t ES7243E_ANALOG_REG1A = 0x1A; // ADCI1/ADCI23 bias
|
||||
static const uint8_t ES7243E_ANALOG_REG1B = 0x1B; // ADCSM/ADCCM bias
|
||||
static const uint8_t ES7243E_ANALOG_REG1C = 0x1C; // ADCVRP/ADCCPP bias
|
||||
static const uint8_t ES7243E_ANALOG_REG1D = 0x1D; // low power bits
|
||||
static const uint8_t ES7243E_ANALOG_REG1E = 0x1E; // low power bits
|
||||
static const uint8_t ES7243E_ANALOG_REG1F = 0x1F; // ADC_DMIC_ON/REFSEL/VX2OFF/VX1SEL/VMIDLVL
|
||||
static const uint8_t ES7243E_ANALOG_REG20 = 0x20; // select MIC1 as PGA1 input/PGA1 gain
|
||||
static const uint8_t ES7243E_ANALOG_REG21 = 0x21; // select MIC2 as PGA1 input/PGA2 gain
|
||||
static const uint8_t ES7243E_TEST_MODE_REGF7 = 0xF7;
|
||||
static const uint8_t ES7243E_TEST_MODE_REGF8 = 0xF8;
|
||||
static const uint8_t ES7243E_TEST_MODE_REGF9 = 0xF9;
|
||||
static const uint8_t ES7243E_I2C_CONF_REGFA = 0xFA; // I2C signals retime/reset registers to default
|
||||
static const uint8_t ES7243E_FLAG_REGFC = 0xFC; // CSM flag/ADC automute flag (RO)
|
||||
static const uint8_t ES7243E_CHIP_ID1_REGFD = 0xFD; // chip ID 1, reads 0x7A (RO)
|
||||
static const uint8_t ES7243E_CHIP_ID2_REGFE = 0xFE; // chip ID 2, reads 0x43 (RO)
|
||||
static const uint8_t ES7243E_CHIP_VERSION_REGFF = 0xFF; // chip version, reads 0x00 (RO)
|
||||
|
||||
} // namespace es7243e
|
||||
} // namespace esphome
|
@ -64,6 +64,7 @@ from .gpio import esp32_pin_to_code # noqa
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
AUTO_LOAD = ["preferences"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
CONF_RELEASE = "release"
|
||||
|
||||
|
@ -34,6 +34,7 @@ from .gpio import PinInitialState, add_pin_initial_states_array
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
AUTO_LOAD = ["preferences"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
|
@ -17,6 +17,7 @@ from .gpio import host_pin_to_code # noqa
|
||||
|
||||
CODEOWNERS = ["@esphome/core", "@clydebarrow"]
|
||||
AUTO_LOAD = ["network", "preferences"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
|
@ -47,6 +47,7 @@ from .const import (
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
CODEOWNERS = ["@kuba2k2"]
|
||||
AUTO_LOAD = ["preferences"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
|
||||
def _detect_variant(value):
|
||||
|
@ -186,6 +186,8 @@ CONFIG_SCHEMA = cv.All(
|
||||
esp32_s3_idf=USB_SERIAL_JTAG,
|
||||
esp32_c3_arduino=USB_CDC,
|
||||
esp32_c3_idf=USB_SERIAL_JTAG,
|
||||
esp32_c6_arduino=USB_CDC,
|
||||
esp32_c6_idf=USB_SERIAL_JTAG,
|
||||
rp2040=USB_CDC,
|
||||
bk72xx=DEFAULT,
|
||||
rtl87xx=DEFAULT,
|
||||
|
@ -72,9 +72,9 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
|
||||
// max_temp
|
||||
root[MQTT_MAX_TEMP] = traits.get_visual_max_temperature();
|
||||
// target_temp_step
|
||||
root[MQTT_TARGET_TEMPERATURE_STEP] = traits.get_visual_target_temperature_step();
|
||||
root[MQTT_TARGET_TEMPERATURE_STEP] = roundf(traits.get_visual_target_temperature_step() * 10) * 0.1;
|
||||
// current_temp_step
|
||||
root[MQTT_CURRENT_TEMPERATURE_STEP] = traits.get_visual_current_temperature_step();
|
||||
root[MQTT_CURRENT_TEMPERATURE_STEP] = roundf(traits.get_visual_current_temperature_step() * 10) * 0.1;
|
||||
// temperature units are always coerced to Celsius internally
|
||||
root[MQTT_TEMPERATURE_UNIT] = "C";
|
||||
|
||||
|
@ -52,6 +52,14 @@ class Format:
|
||||
pass
|
||||
|
||||
|
||||
class BMPFormat(Format):
|
||||
def __init__(self):
|
||||
super().__init__("BMP")
|
||||
|
||||
def actions(self):
|
||||
cg.add_define("USE_ONLINE_IMAGE_BMP_SUPPORT")
|
||||
|
||||
|
||||
class PNGFormat(Format):
|
||||
def __init__(self):
|
||||
super().__init__("PNG")
|
||||
@ -62,7 +70,13 @@ class PNGFormat(Format):
|
||||
|
||||
|
||||
# New formats can be added here.
|
||||
IMAGE_FORMATS = {x.image_type: x for x in (PNGFormat(),)}
|
||||
IMAGE_FORMATS = {
|
||||
x.image_type: x
|
||||
for x in (
|
||||
BMPFormat(),
|
||||
PNGFormat(),
|
||||
)
|
||||
}
|
||||
|
||||
OnlineImage = online_image_ns.class_("OnlineImage", cg.PollingComponent, Image_)
|
||||
|
||||
|
101
esphome/components/online_image/bmp_image.cpp
Normal file
101
esphome/components/online_image/bmp_image.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include "bmp_image.h"
|
||||
|
||||
#ifdef USE_ONLINE_IMAGE_BMP_SUPPORT
|
||||
|
||||
#include "esphome/components/display/display.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace online_image {
|
||||
|
||||
static const char *const TAG = "online_image.bmp";
|
||||
|
||||
int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) {
|
||||
size_t index = 0;
|
||||
if (this->current_index_ == 0 && index == 0 && size > 14) {
|
||||
/**
|
||||
* BMP file format:
|
||||
* 0-1: Signature (BM)
|
||||
* 2-5: File size
|
||||
* 6-9: Reserved
|
||||
* 10-13: Pixel data offset
|
||||
*
|
||||
* Integer values are stored in little-endian format.
|
||||
*/
|
||||
|
||||
// Check if the file is a BMP image
|
||||
if (buffer[0] != 'B' || buffer[1] != 'M') {
|
||||
ESP_LOGE(TAG, "Not a BMP file");
|
||||
return DECODE_ERROR_INVALID_TYPE;
|
||||
}
|
||||
|
||||
this->download_size_ = encode_uint32(buffer[5], buffer[4], buffer[3], buffer[2]);
|
||||
this->data_offset_ = encode_uint32(buffer[13], buffer[12], buffer[11], buffer[10]);
|
||||
|
||||
this->current_index_ = 14;
|
||||
index = 14;
|
||||
}
|
||||
if (this->current_index_ == 14 && index == 14 && size > this->data_offset_) {
|
||||
/**
|
||||
* BMP DIB header:
|
||||
* 14-17: DIB header size
|
||||
* 18-21: Image width
|
||||
* 22-25: Image height
|
||||
* 26-27: Number of color planes
|
||||
* 28-29: Bits per pixel
|
||||
* 30-33: Compression method
|
||||
* 34-37: Image data size
|
||||
* 38-41: Horizontal resolution
|
||||
* 42-45: Vertical resolution
|
||||
* 46-49: Number of colors in the color table
|
||||
*/
|
||||
|
||||
this->width_ = encode_uint32(buffer[21], buffer[20], buffer[19], buffer[18]);
|
||||
this->height_ = encode_uint32(buffer[25], buffer[24], buffer[23], buffer[22]);
|
||||
this->bits_per_pixel_ = encode_uint16(buffer[29], buffer[28]);
|
||||
this->compression_method_ = encode_uint32(buffer[33], buffer[32], buffer[31], buffer[30]);
|
||||
this->image_data_size_ = encode_uint32(buffer[37], buffer[36], buffer[35], buffer[34]);
|
||||
this->color_table_entries_ = encode_uint32(buffer[49], buffer[48], buffer[47], buffer[46]);
|
||||
|
||||
switch (this->bits_per_pixel_) {
|
||||
case 1:
|
||||
this->width_bytes_ = (this->width_ % 8 == 0) ? (this->width_ / 8) : (this->width_ / 8 + 1);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unsupported bits per pixel: %d", this->bits_per_pixel_);
|
||||
return DECODE_ERROR_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
|
||||
if (this->compression_method_ != 0) {
|
||||
ESP_LOGE(TAG, "Unsupported compression method: %d", this->compression_method_);
|
||||
return DECODE_ERROR_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
|
||||
if (!this->set_size(this->width_, this->height_)) {
|
||||
return DECODE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
this->current_index_ = this->data_offset_;
|
||||
index = this->data_offset_;
|
||||
}
|
||||
while (index < size) {
|
||||
size_t paint_index = this->current_index_ - this->data_offset_;
|
||||
|
||||
uint8_t current_byte = buffer[index];
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
size_t x = (paint_index * 8) % this->width_ + i;
|
||||
size_t y = (this->height_ - 1) - (paint_index / this->width_bytes_);
|
||||
Color c = (current_byte & (1 << (7 - i))) ? display::COLOR_ON : display::COLOR_OFF;
|
||||
this->draw(x, y, 1, 1, c);
|
||||
}
|
||||
this->current_index_++;
|
||||
index++;
|
||||
}
|
||||
this->decoded_bytes_ += size;
|
||||
return size;
|
||||
};
|
||||
|
||||
} // namespace online_image
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ONLINE_IMAGE_BMP_SUPPORT
|
40
esphome/components/online_image/bmp_image.h
Normal file
40
esphome/components/online_image/bmp_image.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
#ifdef USE_ONLINE_IMAGE_BMP_SUPPORT
|
||||
|
||||
#include "image_decoder.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace online_image {
|
||||
|
||||
/**
|
||||
* @brief Image decoder specialization for PNG images.
|
||||
*/
|
||||
class BmpDecoder : public ImageDecoder {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new BMP Decoder object.
|
||||
*
|
||||
* @param display The image to decode the stream into.
|
||||
*/
|
||||
BmpDecoder(OnlineImage *image) : ImageDecoder(image) {}
|
||||
|
||||
int HOT decode(uint8_t *buffer, size_t size) override;
|
||||
|
||||
protected:
|
||||
size_t current_index_{0};
|
||||
ssize_t width_{0};
|
||||
ssize_t height_{0};
|
||||
uint16_t bits_per_pixel_{0};
|
||||
uint32_t compression_method_{0};
|
||||
uint32_t image_data_size_{0};
|
||||
uint32_t color_table_entries_{0};
|
||||
size_t width_bytes_{0};
|
||||
size_t data_offset_{0};
|
||||
};
|
||||
|
||||
} // namespace online_image
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ONLINE_IMAGE_BMP_SUPPORT
|
@ -8,10 +8,11 @@ namespace online_image {
|
||||
|
||||
static const char *const TAG = "online_image.decoder";
|
||||
|
||||
void ImageDecoder::set_size(int width, int height) {
|
||||
this->image_->resize_(width, height);
|
||||
bool ImageDecoder::set_size(int width, int height) {
|
||||
bool resized = this->image_->resize_(width, height);
|
||||
this->x_scale_ = static_cast<double>(this->image_->buffer_width_) / width;
|
||||
this->y_scale_ = static_cast<double>(this->image_->buffer_height_) / height;
|
||||
return resized;
|
||||
}
|
||||
|
||||
void ImageDecoder::draw(int x, int y, int w, int h, const Color &color) {
|
||||
|
@ -4,6 +4,12 @@
|
||||
namespace esphome {
|
||||
namespace online_image {
|
||||
|
||||
enum DecodeError : int {
|
||||
DECODE_ERROR_INVALID_TYPE = -1,
|
||||
DECODE_ERROR_UNSUPPORTED_FORMAT = -2,
|
||||
DECODE_ERROR_OUT_OF_MEMORY = -3,
|
||||
};
|
||||
|
||||
class OnlineImage;
|
||||
|
||||
/**
|
||||
@ -24,7 +30,7 @@ class ImageDecoder {
|
||||
*
|
||||
* @param download_size The total number of bytes that need to be downloaded for the image.
|
||||
*/
|
||||
virtual void prepare(uint32_t download_size) { this->download_size_ = download_size; }
|
||||
virtual void prepare(size_t download_size) { this->download_size_ = download_size; }
|
||||
|
||||
/**
|
||||
* @brief Decode a part of the image. It will try reading from the buffer.
|
||||
@ -45,8 +51,9 @@ class ImageDecoder {
|
||||
*
|
||||
* @param width The image's width.
|
||||
* @param height The image's height.
|
||||
* @return true if the image was resized, false otherwise.
|
||||
*/
|
||||
void set_size(int width, int height);
|
||||
bool set_size(int width, int height);
|
||||
|
||||
/**
|
||||
* @brief Fill a rectangle on the display_buffer using the defined color.
|
||||
@ -68,8 +75,8 @@ class ImageDecoder {
|
||||
OnlineImage *image_;
|
||||
// Initializing to 1, to ensure it is distinguishable from initial "decoded_bytes_".
|
||||
// Will be overwritten anyway once the download size is known.
|
||||
uint32_t download_size_ = 1;
|
||||
uint32_t decoded_bytes_ = 0;
|
||||
size_t download_size_ = 1;
|
||||
size_t decoded_bytes_ = 0;
|
||||
double x_scale_ = 1.0;
|
||||
double y_scale_ = 1.0;
|
||||
};
|
||||
|
@ -6,6 +6,9 @@ static const char *const TAG = "online_image";
|
||||
|
||||
#include "image_decoder.h"
|
||||
|
||||
#ifdef USE_ONLINE_IMAGE_BMP_SUPPORT
|
||||
#include "bmp_image.h"
|
||||
#endif
|
||||
#ifdef USE_ONLINE_IMAGE_PNG_SUPPORT
|
||||
#include "png_image.h"
|
||||
#endif
|
||||
@ -118,9 +121,14 @@ void OnlineImage::update() {
|
||||
ESP_LOGD(TAG, "Starting download");
|
||||
size_t total_size = this->downloader_->content_length;
|
||||
|
||||
#ifdef USE_ONLINE_IMAGE_BMP_SUPPORT
|
||||
if (this->format_ == ImageFormat::BMP) {
|
||||
this->decoder_ = make_unique<BmpDecoder>(this);
|
||||
}
|
||||
#endif // ONLINE_IMAGE_BMP_SUPPORT
|
||||
#ifdef USE_ONLINE_IMAGE_PNG_SUPPORT
|
||||
if (this->format_ == ImageFormat::PNG) {
|
||||
this->decoder_ = esphome::make_unique<PngDecoder>(this);
|
||||
this->decoder_ = make_unique<PngDecoder>(this);
|
||||
}
|
||||
#endif // ONLINE_IMAGE_PNG_SUPPORT
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/http_request/http_request.h"
|
||||
#include "esphome/components/image/image.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/http_request/http_request.h"
|
||||
#include "esphome/components/image/image.h"
|
||||
|
||||
#include "image_decoder.h"
|
||||
|
||||
@ -27,6 +27,8 @@ enum ImageFormat {
|
||||
JPEG,
|
||||
/** PNG format. */
|
||||
PNG,
|
||||
/** BMP format. */
|
||||
BMP,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -146,7 +148,7 @@ class OnlineImage : public PollingComponent,
|
||||
*/
|
||||
int buffer_height_;
|
||||
|
||||
friend void ImageDecoder::set_size(int width, int height);
|
||||
friend bool ImageDecoder::set_size(int width, int height);
|
||||
friend void ImageDecoder::draw(int x, int y, int w, int h, const Color &color);
|
||||
};
|
||||
|
||||
|
@ -41,7 +41,7 @@ static void draw_callback(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, ui
|
||||
decoder->draw(x, y, w, h, color);
|
||||
}
|
||||
|
||||
void PngDecoder::prepare(uint32_t download_size) {
|
||||
void PngDecoder::prepare(size_t download_size) {
|
||||
ImageDecoder::prepare(download_size);
|
||||
pngle_set_user_data(this->pngle_, this);
|
||||
pngle_set_init_callback(this->pngle_, init_callback);
|
||||
@ -51,7 +51,7 @@ void PngDecoder::prepare(uint32_t download_size) {
|
||||
int HOT PngDecoder::decode(uint8_t *buffer, size_t size) {
|
||||
if (!this->pngle_) {
|
||||
ESP_LOGE(TAG, "PNG decoder engine not initialized!");
|
||||
return -1;
|
||||
return DECODE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (size < 256 && size < this->download_size_ - this->decoded_bytes_) {
|
||||
ESP_LOGD(TAG, "Waiting for data");
|
||||
|
@ -21,7 +21,7 @@ class PngDecoder : public ImageDecoder {
|
||||
PngDecoder(OnlineImage *image) : ImageDecoder(image), pngle_(pngle_new()) {}
|
||||
~PngDecoder() override { pngle_destroy(this->pngle_); }
|
||||
|
||||
void prepare(uint32_t download_size) override;
|
||||
void prepare(size_t download_size) override;
|
||||
int HOT decode(uint8_t *buffer, size_t size) override;
|
||||
|
||||
protected:
|
||||
|
@ -75,6 +75,8 @@ void PulseMeterSensor::loop() {
|
||||
case MeterState::RUNNING: {
|
||||
uint32_t delta_us = this->get_->last_detected_edge_us_ - this->last_processed_edge_us_;
|
||||
float pulse_width_us = delta_us / float(this->get_->count_);
|
||||
ESP_LOGV(TAG, "New pulse, delta: %" PRIu32 " µs, count: %" PRIu32 ", width: %.5f µs", delta_us,
|
||||
this->get_->count_, pulse_width_us);
|
||||
this->publish_state((60.0f * 1000000.0f) / pulse_width_us);
|
||||
} break;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ from .gpio import rp2040_pin_to_code # noqa
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
AUTO_LOAD = ["preferences"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
|
@ -19,6 +19,8 @@ from .boards import RTL87XX_BOARD_PINS, RTL87XX_BOARDS
|
||||
|
||||
CODEOWNERS = ["@kuba2k2"]
|
||||
AUTO_LOAD = ["libretiny"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
|
||||
COMPONENT_DATA = LibreTinyComponent(
|
||||
name=COMPONENT_RTL87XX,
|
||||
|
@ -88,7 +88,7 @@ void SPIDelegateBitBash::write(uint16_t data, size_t num_bits) { this->transfer_
|
||||
uint16_t SPIDelegateBitBash::transfer_(uint16_t data, size_t num_bits) {
|
||||
// Clock starts out at idle level
|
||||
this->clk_pin_->digital_write(clock_polarity_);
|
||||
uint8_t out_data = 0;
|
||||
uint16_t out_data = 0;
|
||||
|
||||
for (uint8_t i = 0; i != num_bits; i++) {
|
||||
uint8_t shift;
|
||||
|
@ -22,7 +22,6 @@ from esphome.const import (
|
||||
CONF_PACKAGES,
|
||||
CONF_PLATFORM,
|
||||
CONF_SUBSTITUTIONS,
|
||||
TARGET_PLATFORMS,
|
||||
)
|
||||
from esphome.core import CORE, DocumentRange, EsphomeError
|
||||
import esphome.core.config as core_config
|
||||
@ -833,7 +832,7 @@ def validate_config(
|
||||
result[CONF_ESPHOME] = config[CONF_ESPHOME]
|
||||
result.add_output_path([CONF_ESPHOME], CONF_ESPHOME)
|
||||
try:
|
||||
core_config.preload_core_config(config, result)
|
||||
target_platform = core_config.preload_core_config(config, result)
|
||||
except vol.Invalid as err:
|
||||
result.add_error(err)
|
||||
return result
|
||||
@ -845,9 +844,9 @@ def validate_config(
|
||||
cv.All(cv.version_number, cv.validate_esphome_version)(min_version)
|
||||
|
||||
# First run platform validation steps
|
||||
for key in TARGET_PLATFORMS:
|
||||
if key in config:
|
||||
result.add_validation_step(LoadValidationStep(key, config[key]))
|
||||
result.add_validation_step(
|
||||
LoadValidationStep(target_platform, config[target_platform])
|
||||
)
|
||||
result.run_validation_steps()
|
||||
|
||||
if result.errors:
|
||||
|
@ -15,15 +15,6 @@ PLATFORM_LIBRETINY_OLDSTYLE = "libretiny"
|
||||
PLATFORM_RP2040 = "rp2040"
|
||||
PLATFORM_RTL87XX = "rtl87xx"
|
||||
|
||||
TARGET_PLATFORMS = [
|
||||
PLATFORM_BK72XX,
|
||||
PLATFORM_ESP32,
|
||||
PLATFORM_ESP8266,
|
||||
PLATFORM_HOST,
|
||||
PLATFORM_LIBRETINY_OLDSTYLE,
|
||||
PLATFORM_RP2040,
|
||||
PLATFORM_RTL87XX,
|
||||
]
|
||||
|
||||
SOURCE_FILE_EXTENSIONS = {".cpp", ".hpp", ".h", ".c", ".tcc", ".ino"}
|
||||
HEADER_FILE_EXTENSIONS = {".h", ".hpp", ".tcc"}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import logging
|
||||
import multiprocessing
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from esphome import automation
|
||||
import esphome.codegen as cg
|
||||
@ -28,7 +29,6 @@ from esphome.const import (
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_VERSION,
|
||||
KEY_CORE,
|
||||
TARGET_PLATFORMS,
|
||||
__version__ as ESPHOME_VERSION,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
@ -174,7 +174,31 @@ PRELOAD_CONFIG_SCHEMA = cv.Schema(
|
||||
)
|
||||
|
||||
|
||||
def preload_core_config(config, result):
|
||||
def _is_target_platform(name):
|
||||
from esphome.loader import get_component
|
||||
|
||||
try:
|
||||
if get_component(name, True).is_target_platform:
|
||||
return True
|
||||
except KeyError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def _list_target_platforms():
|
||||
target_platforms = []
|
||||
root = Path(__file__).parents[1]
|
||||
for path in (root / "components").iterdir():
|
||||
if not path.is_dir():
|
||||
continue
|
||||
if not (path / "__init__.py").is_file():
|
||||
continue
|
||||
if _is_target_platform(path.name):
|
||||
target_platforms += [path.name]
|
||||
return target_platforms
|
||||
|
||||
|
||||
def preload_core_config(config, result) -> str:
|
||||
with cv.prepend_path(CONF_ESPHOME):
|
||||
conf = PRELOAD_CONFIG_SCHEMA(config[CONF_ESPHOME])
|
||||
|
||||
@ -187,12 +211,16 @@ def preload_core_config(config, result):
|
||||
conf[CONF_BUILD_PATH] = os.path.join(build_path, CORE.name)
|
||||
CORE.build_path = CORE.relative_internal_path(conf[CONF_BUILD_PATH])
|
||||
|
||||
target_platforms = [key for key in TARGET_PLATFORMS if key in config]
|
||||
target_platforms = []
|
||||
|
||||
for domain, _ in config.items():
|
||||
if _is_target_platform(domain):
|
||||
target_platforms += [domain]
|
||||
|
||||
if not target_platforms:
|
||||
raise cv.Invalid(
|
||||
"Platform missing. You must include one of the available platform keys: "
|
||||
+ ", ".join(TARGET_PLATFORMS),
|
||||
+ ", ".join(_list_target_platforms()),
|
||||
[CONF_ESPHOME],
|
||||
)
|
||||
if len(target_platforms) > 1:
|
||||
@ -202,6 +230,7 @@ def preload_core_config(config, result):
|
||||
)
|
||||
|
||||
config[CONF_ESPHOME] = conf
|
||||
return target_platforms[0]
|
||||
|
||||
|
||||
def include_file(path, basename):
|
||||
|
@ -60,6 +60,7 @@
|
||||
#define USE_NETWORK
|
||||
#define USE_NEXTION_TFT_UPLOAD
|
||||
#define USE_NUMBER
|
||||
#define USE_ONLINE_IMAGE_BMP_SUPPORT
|
||||
#define USE_ONLINE_IMAGE_PNG_SUPPORT
|
||||
#define USE_OTA
|
||||
#define USE_OTA_PASSWORD
|
||||
|
@ -52,6 +52,10 @@ class ComponentManifest:
|
||||
def is_platform_component(self) -> bool:
|
||||
return getattr(self.module, "IS_PLATFORM_COMPONENT", False)
|
||||
|
||||
@property
|
||||
def is_target_platform(self) -> bool:
|
||||
return getattr(self.module, "IS_TARGET_PLATFORM", False)
|
||||
|
||||
@property
|
||||
def config_schema(self) -> Optional[Any]:
|
||||
return getattr(self.module, "CONFIG_SCHEMA", None)
|
||||
@ -169,13 +173,15 @@ def install_custom_components_meta_finder():
|
||||
install_meta_finder(custom_components_dir)
|
||||
|
||||
|
||||
def _lookup_module(domain):
|
||||
def _lookup_module(domain, exception):
|
||||
if domain in _COMPONENT_CACHE:
|
||||
return _COMPONENT_CACHE[domain]
|
||||
|
||||
try:
|
||||
module = importlib.import_module(f"esphome.components.{domain}")
|
||||
except ImportError as e:
|
||||
if exception:
|
||||
raise
|
||||
if "No module named" in str(e):
|
||||
_LOGGER.info(
|
||||
"Unable to import component %s: %s", domain, str(e), exc_info=False
|
||||
@ -184,6 +190,8 @@ def _lookup_module(domain):
|
||||
_LOGGER.error("Unable to import component %s:", domain, exc_info=True)
|
||||
return None
|
||||
except Exception: # pylint: disable=broad-except
|
||||
if exception:
|
||||
raise
|
||||
_LOGGER.error("Unable to load component %s:", domain, exc_info=True)
|
||||
return None
|
||||
|
||||
@ -192,14 +200,14 @@ def _lookup_module(domain):
|
||||
return manif
|
||||
|
||||
|
||||
def get_component(domain):
|
||||
def get_component(domain, exception=False):
|
||||
assert "." not in domain
|
||||
return _lookup_module(domain)
|
||||
return _lookup_module(domain, exception)
|
||||
|
||||
|
||||
def get_platform(domain, platform):
|
||||
full = f"{platform}.{domain}"
|
||||
return _lookup_module(full)
|
||||
return _lookup_module(full, False)
|
||||
|
||||
|
||||
_COMPONENT_CACHE = {}
|
||||
|
@ -10,4 +10,5 @@ sensor:
|
||||
- platform: ads1115
|
||||
multiplexer: A0_A1
|
||||
gain: 1.024
|
||||
sample_rate: 128
|
||||
id: ads1115_sensor
|
||||
|
@ -10,4 +10,5 @@ sensor:
|
||||
- platform: ads1115
|
||||
multiplexer: A0_A1
|
||||
gain: 1.024
|
||||
sample_rate: 128
|
||||
id: ads1115_sensor
|
||||
|
@ -10,4 +10,5 @@ sensor:
|
||||
- platform: ads1115
|
||||
multiplexer: A0_A1
|
||||
gain: 1.024
|
||||
sample_rate: 128
|
||||
id: ads1115_sensor
|
||||
|
@ -10,4 +10,5 @@ sensor:
|
||||
- platform: ads1115
|
||||
multiplexer: A0_A1
|
||||
gain: 1.024
|
||||
sample_rate: 128
|
||||
id: ads1115_sensor
|
||||
|
@ -10,4 +10,5 @@ sensor:
|
||||
- platform: ads1115
|
||||
multiplexer: A0_A1
|
||||
gain: 1.024
|
||||
sample_rate: 128
|
||||
id: ads1115_sensor
|
||||
|
@ -10,4 +10,5 @@ sensor:
|
||||
- platform: ads1115
|
||||
multiplexer: A0_A1
|
||||
gain: 1.024
|
||||
sample_rate: 128
|
||||
id: ads1115_sensor
|
||||
|
14
tests/components/es7243e/common.yaml
Normal file
14
tests/components/es7243e/common.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- audio_adc.set_mic_gain: 0db
|
||||
- audio_adc.set_mic_gain: !lambda 'return 4;'
|
||||
|
||||
i2c:
|
||||
- id: i2c_es7243e
|
||||
scl: ${scl_pin}
|
||||
sda: ${sda_pin}
|
||||
|
||||
audio_adc:
|
||||
- platform: es7243e
|
||||
id: es7243e_adc
|
5
tests/components/es7243e/test.esp32-ard.yaml
Normal file
5
tests/components/es7243e/test.esp32-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es7243e/test.esp32-c3-ard.yaml
Normal file
5
tests/components/es7243e/test.esp32-c3-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es7243e/test.esp32-c3-idf.yaml
Normal file
5
tests/components/es7243e/test.esp32-c3-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es7243e/test.esp32-idf.yaml
Normal file
5
tests/components/es7243e/test.esp32-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
@ -26,6 +26,10 @@ online_image:
|
||||
format: PNG
|
||||
type: RGB
|
||||
transparency: chroma_key
|
||||
- id: online_binary_bmp
|
||||
url: https://samples-files.com/samples/images/bmp/480-360-sample.bmp
|
||||
format: BMP
|
||||
type: BINARY
|
||||
|
||||
# Check the set_url action
|
||||
esphome:
|
||||
|
Loading…
Reference in New Issue
Block a user