mirror of
https://github.com/esphome/esphome.git
synced 2025-01-30 23:02:14 +01:00
[es8156] Add support for ES8156 audio DAC (#8085)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
0f4e274e52
commit
716a8b87e1
@ -133,6 +133,7 @@ esphome/components/ens160_i2c/* @latonita
|
||||
esphome/components/ens160_spi/* @latonita
|
||||
esphome/components/ens210/* @itn3rd77
|
||||
esphome/components/es7210/* @kahrendt
|
||||
esphome/components/es8156/* @kbx81
|
||||
esphome/components/es8311/* @kahrendt @kroimon
|
||||
esphome/components/esp32/* @esphome/core
|
||||
esphome/components/esp32_ble/* @Rapsssito @jesserockz
|
||||
|
0
esphome/components/es8156/__init__.py
Normal file
0
esphome/components/es8156/__init__.py
Normal file
27
esphome/components/es8156/audio_dac.py
Normal file
27
esphome/components/es8156/audio_dac.py
Normal file
@ -0,0 +1,27 @@
|
||||
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_ID
|
||||
|
||||
CODEOWNERS = ["@kbx81"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
es8156_ns = cg.esphome_ns.namespace("es8156")
|
||||
ES8156 = es8156_ns.class_("ES8156", AudioDac, cg.Component, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ES8156),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x08))
|
||||
)
|
||||
|
||||
|
||||
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)
|
87
esphome/components/es8156/es8156.cpp
Normal file
87
esphome/components/es8156/es8156.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "es8156.h"
|
||||
#include "es8156_const.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace es8156 {
|
||||
|
||||
static const char *const TAG = "es8156";
|
||||
|
||||
// Mark the component as failed; use only in setup
|
||||
#define ES8156_ERROR_FAILED(func) \
|
||||
if (!(func)) { \
|
||||
this->mark_failed(); \
|
||||
return; \
|
||||
}
|
||||
|
||||
void ES8156::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up ES8156...");
|
||||
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG02_SCLK_MODE, 0x04));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG20_ANALOG_SYS1, 0x2A));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG21_ANALOG_SYS2, 0x3C));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG22_ANALOG_SYS3, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG24_ANALOG_LP, 0x07));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG23_ANALOG_SYS4, 0x00));
|
||||
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0A_TIME_CONTROL1, 0x01));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0B_TIME_CONTROL2, 0x01));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG11_DAC_SDP, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG19_EQ_CONTROL1, 0x20));
|
||||
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0D_P2S_CONTROL, 0x14));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG09_MISC_CONTROL2, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG18_MISC_CONTROL3, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG08_CLOCK_ON_OFF, 0x3F));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG00_RESET, 0x02));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG00_RESET, 0x03));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG25_ANALOG_SYS5, 0x20));
|
||||
}
|
||||
|
||||
void ES8156::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ES8156 Audio Codec:");
|
||||
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGCONFIG(TAG, " Failed to initialize");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool ES8156::set_volume(float volume) {
|
||||
volume = clamp(volume, 0.0f, 1.0f);
|
||||
uint8_t reg = remap<uint8_t, float>(volume, 0.0f, 1.0f, 0, 255);
|
||||
ESP_LOGV(TAG, "Setting ES8156_REG14_VOLUME_CONTROL to %u (volume: %f)", reg, volume);
|
||||
return this->write_byte(ES8156_REG14_VOLUME_CONTROL, reg);
|
||||
}
|
||||
|
||||
float ES8156::volume() {
|
||||
uint8_t reg;
|
||||
this->read_byte(ES8156_REG14_VOLUME_CONTROL, ®);
|
||||
return remap<float, uint8_t>(reg, 0, 255, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
bool ES8156::set_mute_state_(bool mute_state) {
|
||||
uint8_t reg13;
|
||||
|
||||
this->is_muted_ = mute_state;
|
||||
|
||||
if (!this->read_byte(ES8156_REG13_DAC_MUTE, ®13)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Read ES8156_REG13_DAC_MUTE: %u", reg13);
|
||||
|
||||
if (mute_state) {
|
||||
reg13 |= BIT(1) | BIT(2);
|
||||
} else {
|
||||
reg13 &= ~(BIT(1) | BIT(2));
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Setting ES8156_REG13_DAC_MUTE to %u (muted: %s)", reg13, YESNO(mute_state));
|
||||
return this->write_byte(ES8156_REG13_DAC_MUTE, reg13);
|
||||
}
|
||||
|
||||
} // namespace es8156
|
||||
} // namespace esphome
|
51
esphome/components/es8156/es8156.h
Normal file
51
esphome/components/es8156/es8156.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/audio_dac/audio_dac.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es8156 {
|
||||
|
||||
class ES8156 : 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_; }
|
||||
|
||||
protected:
|
||||
/// @brief Mutes or unmutes the DAC audio out
|
||||
/// @param mute_state True to mute, false to unmute
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_mute_state_(bool mute_state);
|
||||
};
|
||||
|
||||
} // namespace es8156
|
||||
} // namespace esphome
|
68
esphome/components/es8156/es8156_const.h
Normal file
68
esphome/components/es8156/es8156_const.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "es8156.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es8156 {
|
||||
|
||||
/* ES8156 register addresses */
|
||||
/*
|
||||
* RESET Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG00_RESET = 0x00;
|
||||
/*
|
||||
* Clock Managerment
|
||||
*/
|
||||
static const uint8_t ES8156_REG01_MAINCLOCK_CTL = 0x01;
|
||||
static const uint8_t ES8156_REG02_SCLK_MODE = 0x02;
|
||||
static const uint8_t ES8156_REG03_LRCLK_DIV_H = 0x03;
|
||||
static const uint8_t ES8156_REG04_LRCLK_DIV_L = 0x04;
|
||||
static const uint8_t ES8156_REG05_SCLK_DIV = 0x05;
|
||||
static const uint8_t ES8156_REG06_NFS_CONFIG = 0x06;
|
||||
static const uint8_t ES8156_REG07_MISC_CONTROL1 = 0x07;
|
||||
static const uint8_t ES8156_REG08_CLOCK_ON_OFF = 0x08;
|
||||
static const uint8_t ES8156_REG09_MISC_CONTROL2 = 0x09;
|
||||
static const uint8_t ES8156_REG0A_TIME_CONTROL1 = 0x0a;
|
||||
static const uint8_t ES8156_REG0B_TIME_CONTROL2 = 0x0b;
|
||||
/*
|
||||
* System Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG0C_CHIP_STATUS = 0x0c;
|
||||
static const uint8_t ES8156_REG0D_P2S_CONTROL = 0x0d;
|
||||
static const uint8_t ES8156_REG10_DAC_OSR_COUNTER = 0x10;
|
||||
/*
|
||||
* SDP Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG11_DAC_SDP = 0x11;
|
||||
static const uint8_t ES8156_REG12_AUTOMUTE_SET = 0x12;
|
||||
static const uint8_t ES8156_REG13_DAC_MUTE = 0x13;
|
||||
static const uint8_t ES8156_REG14_VOLUME_CONTROL = 0x14;
|
||||
|
||||
/*
|
||||
* ALC Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG15_ALC_CONFIG1 = 0x15;
|
||||
static const uint8_t ES8156_REG16_ALC_CONFIG2 = 0x16;
|
||||
static const uint8_t ES8156_REG17_ALC_CONFIG3 = 0x17;
|
||||
static const uint8_t ES8156_REG18_MISC_CONTROL3 = 0x18;
|
||||
static const uint8_t ES8156_REG19_EQ_CONTROL1 = 0x19;
|
||||
static const uint8_t ES8156_REG1A_EQ_CONTROL2 = 0x1a;
|
||||
/*
|
||||
* Analog System Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG20_ANALOG_SYS1 = 0x20;
|
||||
static const uint8_t ES8156_REG21_ANALOG_SYS2 = 0x21;
|
||||
static const uint8_t ES8156_REG22_ANALOG_SYS3 = 0x22;
|
||||
static const uint8_t ES8156_REG23_ANALOG_SYS4 = 0x23;
|
||||
static const uint8_t ES8156_REG24_ANALOG_LP = 0x24;
|
||||
static const uint8_t ES8156_REG25_ANALOG_SYS5 = 0x25;
|
||||
/*
|
||||
* Chip Information
|
||||
*/
|
||||
static const uint8_t ES8156_REGFC_I2C_PAGESEL = 0xFC;
|
||||
static const uint8_t ES8156_REGFD_CHIPID1 = 0xFD;
|
||||
static const uint8_t ES8156_REGFE_CHIPID0 = 0xFE;
|
||||
static const uint8_t ES8156_REGFF_CHIP_VERSION = 0xFF;
|
||||
|
||||
} // namespace es8156
|
||||
} // namespace esphome
|
15
tests/components/es8156/common.yaml
Normal file
15
tests/components/es8156/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_es8156
|
||||
scl: ${scl_pin}
|
||||
sda: ${sda_pin}
|
||||
|
||||
audio_dac:
|
||||
- platform: es8156
|
5
tests/components/es8156/test.esp32-ard.yaml
Normal file
5
tests/components/es8156/test.esp32-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp32-c3-ard.yaml
Normal file
5
tests/components/es8156/test.esp32-c3-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp32-c3-idf.yaml
Normal file
5
tests/components/es8156/test.esp32-c3-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp32-idf.yaml
Normal file
5
tests/components/es8156/test.esp32-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp8266-ard.yaml
Normal file
5
tests/components/es8156/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