mirror of
https://github.com/esphome/esphome.git
synced 2025-03-14 06:38:17 +00:00
136 lines
4.6 KiB
C++
136 lines
4.6 KiB
C++
#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
|