mirror of
https://github.com/esphome/esphome.git
synced 2024-11-21 11:37:27 +01:00
[es8311] Add es8311 dac component (#7693)
This commit is contained in:
parent
6afd004ec5
commit
765579dabb
@ -131,6 +131,7 @@ esphome/components/ens160_base/* @latonita @vincentscode
|
||||
esphome/components/ens160_i2c/* @latonita
|
||||
esphome/components/ens160_spi/* @latonita
|
||||
esphome/components/ens210/* @itn3rd77
|
||||
esphome/components/es8311/* @kahrendt @kroimon
|
||||
esphome/components/esp32/* @esphome/core
|
||||
esphome/components/esp32_ble/* @Rapsssito @jesserockz
|
||||
esphome/components/esp32_ble_client/* @jesserockz
|
||||
|
0
esphome/components/es8311/__init__.py
Normal file
0
esphome/components/es8311/__init__.py
Normal file
70
esphome/components/es8311/audio_dac.py
Normal file
70
esphome/components/es8311/audio_dac.py
Normal file
@ -0,0 +1,70 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
from esphome.components.audio_dac import AudioDac
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_BITS_PER_SAMPLE, CONF_ID, CONF_SAMPLE_RATE
|
||||
|
||||
CODEOWNERS = ["@kroimon", "@kahrendt"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
es8311_ns = cg.esphome_ns.namespace("es8311")
|
||||
ES8311 = es8311_ns.class_("ES8311", AudioDac, cg.Component, i2c.I2CDevice)
|
||||
|
||||
CONF_MIC_GAIN = "mic_gain"
|
||||
CONF_USE_MCLK = "use_mclk"
|
||||
CONF_USE_MICROPHONE = "use_microphone"
|
||||
|
||||
es8311_resolution = es8311_ns.enum("ES8311Resolution")
|
||||
ES8311_BITS_PER_SAMPLE_ENUM = {
|
||||
16: es8311_resolution.ES8311_RESOLUTION_16,
|
||||
24: es8311_resolution.ES8311_RESOLUTION_24,
|
||||
32: es8311_resolution.ES8311_RESOLUTION_32,
|
||||
}
|
||||
|
||||
es8311_mic_gain = es8311_ns.enum("ES8311MicGain")
|
||||
ES8311_MIC_GAIN_ENUM = {
|
||||
"MIN": es8311_mic_gain.ES8311_MIC_GAIN_MIN,
|
||||
"0DB": es8311_mic_gain.ES8311_MIC_GAIN_0DB,
|
||||
"6DB": es8311_mic_gain.ES8311_MIC_GAIN_6DB,
|
||||
"12DB": es8311_mic_gain.ES8311_MIC_GAIN_12DB,
|
||||
"18DB": es8311_mic_gain.ES8311_MIC_GAIN_18DB,
|
||||
"24DB": es8311_mic_gain.ES8311_MIC_GAIN_24DB,
|
||||
"30DB": es8311_mic_gain.ES8311_MIC_GAIN_30DB,
|
||||
"36DB": es8311_mic_gain.ES8311_MIC_GAIN_36DB,
|
||||
"42DB": es8311_mic_gain.ES8311_MIC_GAIN_42DB,
|
||||
"MAX": es8311_mic_gain.ES8311_MIC_GAIN_MAX,
|
||||
}
|
||||
|
||||
|
||||
_validate_bits = cv.float_with_unit("bits", "bit")
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ES8311),
|
||||
cv.Optional(CONF_BITS_PER_SAMPLE, default="16bit"): cv.All(
|
||||
_validate_bits, cv.enum(ES8311_BITS_PER_SAMPLE_ENUM)
|
||||
),
|
||||
cv.Optional(CONF_MIC_GAIN, default="42DB"): cv.enum(
|
||||
ES8311_MIC_GAIN_ENUM, upper=True
|
||||
),
|
||||
cv.Optional(CONF_SAMPLE_RATE, default=16000): cv.int_range(min=1),
|
||||
cv.Optional(CONF_USE_MCLK, default=True): cv.boolean,
|
||||
cv.Optional(CONF_USE_MICROPHONE, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x18))
|
||||
)
|
||||
|
||||
|
||||
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_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
|
||||
cg.add(var.set_mic_gain(config[CONF_MIC_GAIN]))
|
||||
cg.add(var.set_sample_frequency(config[CONF_SAMPLE_RATE]))
|
||||
cg.add(var.set_use_mclk(config[CONF_USE_MCLK]))
|
||||
cg.add(var.set_use_mic(config[CONF_USE_MICROPHONE]))
|
227
esphome/components/es8311/es8311.cpp
Normal file
227
esphome/components/es8311/es8311.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
#include "es8311.h"
|
||||
#include "es8311_const.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace es8311 {
|
||||
|
||||
static const char *const TAG = "es8311";
|
||||
|
||||
// Mark the component as failed; use only in setup
|
||||
#define ES8311_ERROR_FAILED(func) \
|
||||
if (!(func)) { \
|
||||
this->mark_failed(); \
|
||||
return; \
|
||||
}
|
||||
// Return false; use outside of setup
|
||||
#define ES8311_ERROR_CHECK(func) \
|
||||
if (!(func)) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
void ES8311::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up ES8311...");
|
||||
|
||||
// Reset
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG00_RESET, 0x1F));
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG00_RESET, 0x00));
|
||||
|
||||
ES8311_ERROR_FAILED(this->configure_clock_());
|
||||
ES8311_ERROR_FAILED(this->configure_format_());
|
||||
ES8311_ERROR_FAILED(this->configure_mic_());
|
||||
|
||||
// Set initial volume
|
||||
this->set_volume(0.75); // 0.75 = 0xBF = 0dB
|
||||
|
||||
// Power up analog circuitry
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG0D_SYSTEM, 0x01));
|
||||
// Enable analog PGA, enable ADC modulator
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG0E_SYSTEM, 0x02));
|
||||
// Power up DAC
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG12_SYSTEM, 0x00));
|
||||
// Enable output to HP drive
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG13_SYSTEM, 0x10));
|
||||
// ADC Equalizer bypass, cancel DC offset in digital domain
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG1C_ADC, 0x6A));
|
||||
// Bypass DAC equalizer
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG37_DAC, 0x08));
|
||||
// Power On
|
||||
ES8311_ERROR_FAILED(this->write_byte(ES8311_REG00_RESET, 0x80));
|
||||
}
|
||||
|
||||
void ES8311::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ES8311 Audio Codec:");
|
||||
ESP_LOGCONFIG(TAG, " Use MCLK: %s", YESNO(this->use_mclk_));
|
||||
ESP_LOGCONFIG(TAG, " Use Microphone: %s", YESNO(this->use_mic_));
|
||||
ESP_LOGCONFIG(TAG, " DAC Bits per Sample: %" PRIu8, this->resolution_out_);
|
||||
ESP_LOGCONFIG(TAG, " Sample Rate: %" PRIu32, this->sample_frequency_);
|
||||
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGCONFIG(TAG, " Failed to initialize!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool ES8311::set_volume(float volume) {
|
||||
volume = clamp(volume, 0.0f, 1.0f);
|
||||
uint8_t reg32 = remap<uint8_t, float>(volume, 0.0f, 1.0f, 0, 255);
|
||||
return this->write_byte(ES8311_REG32_DAC, reg32);
|
||||
}
|
||||
|
||||
float ES8311::volume() {
|
||||
uint8_t reg32;
|
||||
this->read_byte(ES8311_REG32_DAC, ®32);
|
||||
return remap<float, uint8_t>(reg32, 0, 255, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
uint8_t ES8311::calculate_resolution_value(ES8311Resolution resolution) {
|
||||
switch (resolution) {
|
||||
case ES8311_RESOLUTION_16:
|
||||
return (3 << 2);
|
||||
case ES8311_RESOLUTION_18:
|
||||
return (2 << 2);
|
||||
case ES8311_RESOLUTION_20:
|
||||
return (1 << 2);
|
||||
case ES8311_RESOLUTION_24:
|
||||
return (0 << 2);
|
||||
case ES8311_RESOLUTION_32:
|
||||
return (4 << 2);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const ES8311Coefficient *ES8311::get_coefficient(uint32_t mclk, uint32_t rate) {
|
||||
for (const auto &coefficient : ES8311_COEFFICIENTS) {
|
||||
if (coefficient.mclk == mclk && coefficient.rate == rate)
|
||||
return &coefficient;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ES8311::configure_clock_() {
|
||||
// Register 0x01: select clock source for internal MCLK and determine its frequency
|
||||
uint8_t reg01 = 0x3F; // Enable all clocks
|
||||
|
||||
uint32_t mclk_frequency = this->sample_frequency_ * this->mclk_multiple_;
|
||||
if (!this->use_mclk_) {
|
||||
reg01 |= BIT(7); // Use SCLK
|
||||
mclk_frequency = this->sample_frequency_ * (int) this->resolution_out_ * 2;
|
||||
}
|
||||
if (this->mclk_inverted_) {
|
||||
reg01 |= BIT(6); // Invert MCLK pin
|
||||
}
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG01_CLK_MANAGER, reg01));
|
||||
|
||||
// Get clock coefficients from coefficient table
|
||||
auto *coefficient = get_coefficient(mclk_frequency, this->sample_frequency_);
|
||||
if (coefficient == nullptr) {
|
||||
ESP_LOGE(TAG, "Unable to configure sample rate %" PRIu32 "Hz with %" PRIu32 "Hz MCLK", this->sample_frequency_,
|
||||
mclk_frequency);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register 0x02
|
||||
uint8_t reg02;
|
||||
ES8311_ERROR_CHECK(this->read_byte(ES8311_REG02_CLK_MANAGER, ®02));
|
||||
reg02 &= 0x07;
|
||||
reg02 |= (coefficient->pre_div - 1) << 5;
|
||||
reg02 |= coefficient->pre_mult << 3;
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG02_CLK_MANAGER, reg02));
|
||||
|
||||
// Register 0x03
|
||||
const uint8_t reg03 = (coefficient->fs_mode << 6) | coefficient->adc_osr;
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG03_CLK_MANAGER, reg03));
|
||||
|
||||
// Register 0x04
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG04_CLK_MANAGER, coefficient->dac_osr));
|
||||
|
||||
// Register 0x05
|
||||
const uint8_t reg05 = ((coefficient->adc_div - 1) << 4) | (coefficient->dac_div - 1);
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG05_CLK_MANAGER, reg05));
|
||||
|
||||
// Register 0x06
|
||||
uint8_t reg06;
|
||||
ES8311_ERROR_CHECK(this->read_byte(ES8311_REG06_CLK_MANAGER, ®06));
|
||||
if (this->sclk_inverted_) {
|
||||
reg06 |= BIT(5);
|
||||
} else {
|
||||
reg06 &= ~BIT(5);
|
||||
}
|
||||
reg06 &= 0xE0;
|
||||
if (coefficient->bclk_div < 19) {
|
||||
reg06 |= (coefficient->bclk_div - 1) << 0;
|
||||
} else {
|
||||
reg06 |= (coefficient->bclk_div) << 0;
|
||||
}
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG06_CLK_MANAGER, reg06));
|
||||
|
||||
// Register 0x07
|
||||
uint8_t reg07;
|
||||
ES8311_ERROR_CHECK(this->read_byte(ES8311_REG07_CLK_MANAGER, ®07));
|
||||
reg07 &= 0xC0;
|
||||
reg07 |= coefficient->lrck_h << 0;
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG07_CLK_MANAGER, reg07));
|
||||
|
||||
// Register 0x08
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG08_CLK_MANAGER, coefficient->lrck_l));
|
||||
|
||||
// Successfully configured the clock
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES8311::configure_format_() {
|
||||
// Configure I2S mode and format
|
||||
uint8_t reg00;
|
||||
ES8311_ERROR_CHECK(this->read_byte(ES8311_REG00_RESET, ®00));
|
||||
reg00 &= 0xBF;
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG00_RESET, reg00));
|
||||
|
||||
// Configure SDP in resolution
|
||||
uint8_t reg09 = calculate_resolution_value(this->resolution_in_);
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG09_SDPIN, reg09));
|
||||
|
||||
// Configure SDP out resolution
|
||||
uint8_t reg0a = calculate_resolution_value(this->resolution_out_);
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG0A_SDPOUT, reg0a));
|
||||
|
||||
// Successfully configured the format
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES8311::configure_mic_() {
|
||||
uint8_t reg14 = 0x1A; // Enable analog MIC and max PGA gain
|
||||
if (this->use_mic_) {
|
||||
reg14 |= BIT(6); // Enable PDM digital microphone
|
||||
}
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG14_SYSTEM, reg14));
|
||||
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG16_ADC, this->mic_gain_)); // ADC gain scale up
|
||||
ES8311_ERROR_CHECK(this->write_byte(ES8311_REG17_ADC, 0xC8)); // Set ADC gain
|
||||
|
||||
// Successfully configured the microphones
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES8311::set_mute_state_(bool mute_state) {
|
||||
uint8_t reg31;
|
||||
|
||||
this->is_muted_ = mute_state;
|
||||
|
||||
if (!this->read_byte(ES8311_REG31_DAC, ®31)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mute_state) {
|
||||
reg31 |= BIT(6) | BIT(5);
|
||||
} else {
|
||||
reg31 &= ~(BIT(6) | BIT(5));
|
||||
}
|
||||
|
||||
return this->write_byte(ES8311_REG31_DAC, reg31);
|
||||
}
|
||||
|
||||
} // namespace es8311
|
||||
} // namespace esphome
|
135
esphome/components/es8311/es8311.h
Normal file
135
esphome/components/es8311/es8311.h
Normal file
@ -0,0 +1,135 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/audio_dac/audio_dac.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es8311 {
|
||||
|
||||
enum ES8311MicGain {
|
||||
ES8311_MIC_GAIN_MIN = -1,
|
||||
ES8311_MIC_GAIN_0DB,
|
||||
ES8311_MIC_GAIN_6DB,
|
||||
ES8311_MIC_GAIN_12DB,
|
||||
ES8311_MIC_GAIN_18DB,
|
||||
ES8311_MIC_GAIN_24DB,
|
||||
ES8311_MIC_GAIN_30DB,
|
||||
ES8311_MIC_GAIN_36DB,
|
||||
ES8311_MIC_GAIN_42DB,
|
||||
ES8311_MIC_GAIN_MAX
|
||||
};
|
||||
|
||||
enum ES8311Resolution : uint8_t {
|
||||
ES8311_RESOLUTION_16 = 16,
|
||||
ES8311_RESOLUTION_18 = 18,
|
||||
ES8311_RESOLUTION_20 = 20,
|
||||
ES8311_RESOLUTION_24 = 24,
|
||||
ES8311_RESOLUTION_32 = 32
|
||||
};
|
||||
|
||||
struct ES8311Coefficient {
|
||||
uint32_t mclk; // mclk frequency
|
||||
uint32_t rate; // sample rate
|
||||
uint8_t pre_div; // the pre divider with range from 1 to 8
|
||||
uint8_t pre_mult; // the pre multiplier with x1, x2, x4 and x8 selection
|
||||
uint8_t adc_div; // adcclk divider
|
||||
uint8_t dac_div; // dacclk divider
|
||||
uint8_t fs_mode; // single speed (0) or double speed (1)
|
||||
uint8_t lrck_h; // adc lrck divider and dac lrck divider
|
||||
uint8_t lrck_l; //
|
||||
uint8_t bclk_div; // sclk divider
|
||||
uint8_t adc_osr; // adc osr
|
||||
uint8_t dac_osr; // dac osr
|
||||
};
|
||||
|
||||
class ES8311 : public audio_dac::AudioDac, public Component, public i2c::I2CDevice {
|
||||
public:
|
||||
/////////////////////////
|
||||
// Component overrides //
|
||||
/////////////////////////
|
||||
|
||||
void setup() override;
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
void dump_config() override;
|
||||
|
||||
////////////////////////
|
||||
// AudioDac overrides //
|
||||
////////////////////////
|
||||
|
||||
/// @brief Writes the volume out to the DAC
|
||||
/// @param volume floating point between 0.0 and 1.0
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_volume(float volume) override;
|
||||
|
||||
/// @brief Gets the current volume out from the DAC
|
||||
/// @return floating point between 0.0 and 1.0
|
||||
float volume() override;
|
||||
|
||||
/// @brief Disables mute for audio out
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_mute_off() override { return this->set_mute_state_(false); }
|
||||
|
||||
/// @brief Enables mute for audio out
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_mute_on() override { return this->set_mute_state_(true); }
|
||||
|
||||
bool is_muted() override { return this->is_muted_; }
|
||||
|
||||
//////////////////////////////////
|
||||
// ES8311 configuration setters //
|
||||
//////////////////////////////////
|
||||
|
||||
void set_use_mclk(bool use_mclk) { this->use_mclk_ = use_mclk; }
|
||||
void set_bits_per_sample(ES8311Resolution resolution) {
|
||||
this->resolution_in_ = resolution;
|
||||
this->resolution_out_ = resolution;
|
||||
}
|
||||
void set_sample_frequency(uint32_t sample_frequency) { this->sample_frequency_ = sample_frequency; }
|
||||
void set_use_mic(bool use_mic) { this->use_mic_ = use_mic; }
|
||||
void set_mic_gain(ES8311MicGain mic_gain) { this->mic_gain_ = mic_gain; }
|
||||
|
||||
protected:
|
||||
/// @brief Computes the register value for the configured resolution (bits per sample)
|
||||
/// @param resolution bits per sample enum for both audio in and audio out
|
||||
/// @return register value
|
||||
static uint8_t calculate_resolution_value(ES8311Resolution resolution);
|
||||
|
||||
/// @brief Retrieves the appropriate registers values for the configured mclk and rate
|
||||
/// @param mclk mlck frequency in Hz
|
||||
/// @param rate sample rate frequency in Hz
|
||||
/// @return ES8311Coeffecient containing appropriate register values to configure the ES8311 or nullptr if impossible
|
||||
static const ES8311Coefficient *get_coefficient(uint32_t mclk, uint32_t rate);
|
||||
|
||||
/// @brief Configures the ES8311 registers for the chosen sample rate
|
||||
/// @return True if successful and false otherwise
|
||||
bool configure_clock_();
|
||||
|
||||
/// @brief Configures the ES8311 registers for the chosen bits per sample
|
||||
/// @return True if successful and false otherwise
|
||||
bool configure_format_();
|
||||
|
||||
/// @brief Configures the ES8311 microphone registers
|
||||
/// @return True if successful and false otherwise
|
||||
bool configure_mic_();
|
||||
|
||||
/// @brief Mutes or unmute the DAC audio out
|
||||
/// @param mute_state True to mute, false to unmute
|
||||
/// @return
|
||||
bool set_mute_state_(bool mute_state);
|
||||
|
||||
bool use_mic_;
|
||||
ES8311MicGain mic_gain_;
|
||||
|
||||
bool use_mclk_; // true = use dedicated MCLK pin, false = use SCLK
|
||||
bool sclk_inverted_{false}; // SCLK is inverted
|
||||
bool mclk_inverted_{false}; // MCLK is inverted (ignored if use_mclk_ == false)
|
||||
uint32_t mclk_multiple_{256}; // MCLK frequency is sample rate * mclk_multiple_ (ignored if use_mclk_ == false)
|
||||
|
||||
uint32_t sample_frequency_; // in Hz
|
||||
ES8311Resolution resolution_in_;
|
||||
ES8311Resolution resolution_out_;
|
||||
};
|
||||
|
||||
} // namespace es8311
|
||||
} // namespace esphome
|
195
esphome/components/es8311/es8311_const.h
Normal file
195
esphome/components/es8311/es8311_const.h
Normal file
@ -0,0 +1,195 @@
|
||||
#pragma once
|
||||
|
||||
#include "es8311.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es8311 {
|
||||
|
||||
// ES8311 register addresses
|
||||
static const uint8_t ES8311_REG00_RESET = 0x00; // Reset
|
||||
static const uint8_t ES8311_REG01_CLK_MANAGER = 0x01; // Clock Manager: select clk src for mclk, enable clock for codec
|
||||
static const uint8_t ES8311_REG02_CLK_MANAGER = 0x02; // Clock Manager: clk divider and clk multiplier
|
||||
static const uint8_t ES8311_REG03_CLK_MANAGER = 0x03; // Clock Manager: adc fsmode and osr
|
||||
static const uint8_t ES8311_REG04_CLK_MANAGER = 0x04; // Clock Manager: dac osr
|
||||
static const uint8_t ES8311_REG05_CLK_MANAGER = 0x05; // Clock Manager: clk divider for adc and dac
|
||||
static const uint8_t ES8311_REG06_CLK_MANAGER = 0x06; // Clock Manager: bclk inverter BIT(5) and divider
|
||||
static const uint8_t ES8311_REG07_CLK_MANAGER = 0x07; // Clock Manager: tri-state, lrck divider
|
||||
static const uint8_t ES8311_REG08_CLK_MANAGER = 0x08; // Clock Manager: lrck divider
|
||||
static const uint8_t ES8311_REG09_SDPIN = 0x09; // Serial Digital Port: DAC
|
||||
static const uint8_t ES8311_REG0A_SDPOUT = 0x0A; // Serial Digital Port: ADC
|
||||
static const uint8_t ES8311_REG0B_SYSTEM = 0x0B; // System
|
||||
static const uint8_t ES8311_REG0C_SYSTEM = 0x0C; // System
|
||||
static const uint8_t ES8311_REG0D_SYSTEM = 0x0D; // System: power up/down
|
||||
static const uint8_t ES8311_REG0E_SYSTEM = 0x0E; // System: power up/down
|
||||
static const uint8_t ES8311_REG0F_SYSTEM = 0x0F; // System: low power
|
||||
static const uint8_t ES8311_REG10_SYSTEM = 0x10; // System
|
||||
static const uint8_t ES8311_REG11_SYSTEM = 0x11; // System
|
||||
static const uint8_t ES8311_REG12_SYSTEM = 0x12; // System: Enable DAC
|
||||
static const uint8_t ES8311_REG13_SYSTEM = 0x13; // System
|
||||
static const uint8_t ES8311_REG14_SYSTEM = 0x14; // System: select DMIC, select analog pga gain
|
||||
static const uint8_t ES8311_REG15_ADC = 0x15; // ADC: adc ramp rate, dmic sense
|
||||
static const uint8_t ES8311_REG16_ADC = 0x16; // ADC
|
||||
static const uint8_t ES8311_REG17_ADC = 0x17; // ADC: volume
|
||||
static const uint8_t ES8311_REG18_ADC = 0x18; // ADC: alc enable and winsize
|
||||
static const uint8_t ES8311_REG19_ADC = 0x19; // ADC: alc maxlevel
|
||||
static const uint8_t ES8311_REG1A_ADC = 0x1A; // ADC: alc automute
|
||||
static const uint8_t ES8311_REG1B_ADC = 0x1B; // ADC: alc automute, adc hpf s1
|
||||
static const uint8_t ES8311_REG1C_ADC = 0x1C; // ADC: equalizer, hpf s2
|
||||
static const uint8_t ES8311_REG1D_ADCEQ = 0x1D; // ADCEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG1E_ADCEQ = 0x1E; // ADCEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG1F_ADCEQ = 0x1F; // ADCEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG20_ADCEQ = 0x20; // ADCEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG21_ADCEQ = 0x21; // ADCEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG22_ADCEQ = 0x22; // ADCEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG23_ADCEQ = 0x23; // ADCEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG24_ADCEQ = 0x24; // ADCEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG25_ADCEQ = 0x25; // ADCEQ: equalizer A2
|
||||
static const uint8_t ES8311_REG26_ADCEQ = 0x26; // ADCEQ: equalizer A2
|
||||
static const uint8_t ES8311_REG27_ADCEQ = 0x27; // ADCEQ: equalizer A2
|
||||
static const uint8_t ES8311_REG28_ADCEQ = 0x28; // ADCEQ: equalizer A2
|
||||
static const uint8_t ES8311_REG29_ADCEQ = 0x29; // ADCEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG2A_ADCEQ = 0x2A; // ADCEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG2B_ADCEQ = 0x2B; // ADCEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG2C_ADCEQ = 0x2C; // ADCEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG2D_ADCEQ = 0x2D; // ADCEQ: equalizer B2
|
||||
static const uint8_t ES8311_REG2E_ADCEQ = 0x2E; // ADCEQ: equalizer B2
|
||||
static const uint8_t ES8311_REG2F_ADCEQ = 0x2F; // ADCEQ: equalizer B2
|
||||
static const uint8_t ES8311_REG30_ADCEQ = 0x30; // ADCEQ: equalizer B2
|
||||
static const uint8_t ES8311_REG31_DAC = 0x31; // DAC: mute
|
||||
static const uint8_t ES8311_REG32_DAC = 0x32; // DAC: volume
|
||||
static const uint8_t ES8311_REG33_DAC = 0x33; // DAC: offset
|
||||
static const uint8_t ES8311_REG34_DAC = 0x34; // DAC: drc enable, drc winsize
|
||||
static const uint8_t ES8311_REG35_DAC = 0x35; // DAC: drc maxlevel, minilevel
|
||||
static const uint8_t ES8311_REG36_DAC = 0x36; // DAC
|
||||
static const uint8_t ES8311_REG37_DAC = 0x37; // DAC: ramprate
|
||||
static const uint8_t ES8311_REG38_DACEQ = 0x38; // DACEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG39_DACEQ = 0x39; // DACEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG3A_DACEQ = 0x3A; // DACEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG3B_DACEQ = 0x3B; // DACEQ: equalizer B0
|
||||
static const uint8_t ES8311_REG3C_DACEQ = 0x3C; // DACEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG3D_DACEQ = 0x3D; // DACEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG3E_DACEQ = 0x3E; // DACEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG3F_DACEQ = 0x3F; // DACEQ: equalizer B1
|
||||
static const uint8_t ES8311_REG40_DACEQ = 0x40; // DACEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG41_DACEQ = 0x41; // DACEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG42_DACEQ = 0x42; // DACEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG43_DACEQ = 0x43; // DACEQ: equalizer A1
|
||||
static const uint8_t ES8311_REG44_GPIO = 0x44; // GPIO: dac2adc for test
|
||||
static const uint8_t ES8311_REG45_GP = 0x45; // GPIO: GP control
|
||||
static const uint8_t ES8311_REGFA_I2C = 0xFA; // I2C: reset registers
|
||||
static const uint8_t ES8311_REGFC_FLAG = 0xFC; // Flag
|
||||
static const uint8_t ES8311_REGFD_CHD1 = 0xFD; // Chip: ID1
|
||||
static const uint8_t ES8311_REGFE_CHD2 = 0xFE; // Chip: ID2
|
||||
static const uint8_t ES8311_REGFF_CHVER = 0xFF; // Chip: Version
|
||||
|
||||
// ES8311 clock divider coefficients
|
||||
static const ES8311Coefficient ES8311_COEFFICIENTS[] = {
|
||||
// clang-format off
|
||||
|
||||
// mclk, rate, pre_ pre_ adc_ dac_ fs_ lrck lrck bclk_ adc_ dac_
|
||||
// div, mult, div, div, mode, _h, _l, div, osr, osr
|
||||
|
||||
// 8k
|
||||
{12288000, 8000, 0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{18432000, 8000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x05, 0xff, 0x18, 0x10, 0x20},
|
||||
{16384000, 8000, 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 8192000, 8000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 6144000, 8000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 4096000, 8000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 3072000, 8000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 2048000, 8000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 1536000, 8000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 1024000, 8000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
// 11.025k
|
||||
{11289600, 11025, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 5644800, 11025, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 2822400, 11025, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 1411200, 11025, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
// 12k
|
||||
{12288000, 12000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 6144000, 12000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 3072000, 12000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 1536000, 12000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
// 16k
|
||||
{12288000, 16000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{18432000, 16000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x20},
|
||||
{16384000, 16000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 8192000, 16000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 6144000, 16000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 4096000, 16000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 3072000, 16000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 2048000, 16000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 1536000, 16000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{ 1024000, 16000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
// 22.05k
|
||||
{11289600, 22050, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 5644800, 22050, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 2822400, 22050, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1411200, 22050, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
// 24k
|
||||
{12288000, 24000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 24000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 6144000, 24000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 3072000, 24000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1536000, 24000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
// 32k
|
||||
{12288000, 32000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 32000, 0x03, 0x04, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10},
|
||||
{16384000, 32000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 8192000, 32000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 6144000, 32000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 4096000, 32000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 3072000, 32000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 2048000, 32000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1536000, 32000, 0x03, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
{ 1024000, 32000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
// 44.1k
|
||||
{11289600, 44100, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 5644800, 44100, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 2822400, 44100, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1411200, 44100, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
// 48k
|
||||
{12288000, 48000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 48000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 6144000, 48000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 3072000, 48000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1536000, 48000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
// 64k
|
||||
{12288000, 64000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 64000, 0x03, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
|
||||
{16384000, 64000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 8192000, 64000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 6144000, 64000, 0x01, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
|
||||
{ 4096000, 64000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 3072000, 64000, 0x01, 0x08, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
|
||||
{ 2048000, 64000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1536000, 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0xbf, 0x03, 0x18, 0x18},
|
||||
{ 1024000, 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
|
||||
// 88.2k
|
||||
{11289600, 88200, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 5644800, 88200, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 2822400, 88200, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1411200, 88200, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
|
||||
// 96k
|
||||
{12288000, 96000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 96000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 6144000, 96000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 3072000, 96000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{ 1536000, 96000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
} // namespace es8311
|
||||
} // namespace esphome
|
@ -8,7 +8,7 @@ from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32S3,
|
||||
)
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_CHANNEL, CONF_ID, CONF_SAMPLE_RATE
|
||||
from esphome.const import CONF_BITS_PER_SAMPLE, CONF_CHANNEL, CONF_ID, CONF_SAMPLE_RATE
|
||||
from esphome.cpp_generator import MockObjClass
|
||||
import esphome.final_validate as fv
|
||||
|
||||
@ -25,13 +25,11 @@ CONF_I2S_LRCLK_PIN = "i2s_lrclk_pin"
|
||||
CONF_I2S_AUDIO = "i2s_audio"
|
||||
CONF_I2S_AUDIO_ID = "i2s_audio_id"
|
||||
|
||||
CONF_BITS_PER_SAMPLE = "bits_per_sample"
|
||||
CONF_I2S_MODE = "i2s_mode"
|
||||
CONF_PRIMARY = "primary"
|
||||
CONF_SECONDARY = "secondary"
|
||||
|
||||
CONF_USE_APLL = "use_apll"
|
||||
CONF_BITS_PER_SAMPLE = "bits_per_sample"
|
||||
CONF_BITS_PER_CHANNEL = "bits_per_channel"
|
||||
CONF_MONO = "mono"
|
||||
CONF_LEFT = "left"
|
||||
|
@ -92,6 +92,7 @@ CONF_BINARY_SENSORS = "binary_sensors"
|
||||
CONF_BINDKEY = "bindkey"
|
||||
CONF_BIRTH_MESSAGE = "birth_message"
|
||||
CONF_BIT_DEPTH = "bit_depth"
|
||||
CONF_BITS_PER_SAMPLE = "bits_per_sample"
|
||||
CONF_BLOCK = "block"
|
||||
CONF_BLUE = "blue"
|
||||
CONF_BOARD = "board"
|
||||
|
15
tests/components/es8311/common.yaml
Normal file
15
tests/components/es8311/common.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- audio_dac.mute_off:
|
||||
- audio_dac.mute_on:
|
||||
- audio_dac.set_volume:
|
||||
volume: 50%
|
||||
|
||||
i2c:
|
||||
- id: i2c_aic3204
|
||||
scl: ${scl_pin}
|
||||
sda: ${sda_pin}
|
||||
|
||||
audio_dac:
|
||||
- platform: es8311
|
5
tests/components/es8311/test.esp32-ard.yaml
Normal file
5
tests/components/es8311/test.esp32-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8311/test.esp32-c3-ard.yaml
Normal file
5
tests/components/es8311/test.esp32-c3-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8311/test.esp32-c3-idf.yaml
Normal file
5
tests/components/es8311/test.esp32-c3-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8311/test.esp32-idf.yaml
Normal file
5
tests/components/es8311/test.esp32-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8311/test.esp8266-ard.yaml
Normal file
5
tests/components/es8311/test.esp8266-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
Loading…
Reference in New Issue
Block a user