ESPHome 2025.6.3
Loading...
Searching...
No Matches
es7210.cpp
Go to the documentation of this file.
1#include "es7210.h"
2#include "es7210_const.h"
3#include "esphome/core/hal.h"
4#include "esphome/core/log.h"
5#include <cinttypes>
6
7namespace esphome {
8namespace es7210 {
9
10static const char *const TAG = "es7210";
11
12static const size_t MCLK_DIV_FRE = 256;
13
14// Mark the component as failed; use only in setup
15#define ES7210_ERROR_FAILED(func) \
16 if (!(func)) { \
17 this->mark_failed(); \
18 return; \
19 }
20
21// Return false; use outside of setup
22#define ES7210_ERROR_CHECK(func) \
23 if (!(func)) { \
24 return false; \
25 }
26
28 ESP_LOGCONFIG(TAG,
29 "ES7210 audio ADC:\n"
30 " Bits Per Sample: %" PRIu8 "\n"
31 " Sample Rate: %" PRIu32,
32 this->bits_per_sample_, this->sample_rate_);
33
34 if (this->is_failed()) {
35 ESP_LOGE(TAG, " Failed to initialize");
36 return;
37 }
38}
39
41 ESP_LOGCONFIG(TAG, "Running setup");
42
43 // Software reset
44 ES7210_ERROR_FAILED(this->write_byte(ES7210_RESET_REG00, 0xff));
45 ES7210_ERROR_FAILED(this->write_byte(ES7210_RESET_REG00, 0x32));
46 ES7210_ERROR_FAILED(this->write_byte(ES7210_CLOCK_OFF_REG01, 0x3f));
47
48 // Set initialization time when device powers up
49 ES7210_ERROR_FAILED(this->write_byte(ES7210_TIME_CONTROL0_REG09, 0x30));
50 ES7210_ERROR_FAILED(this->write_byte(ES7210_TIME_CONTROL1_REG0A, 0x30));
51
52 // Configure HFP for all ADC channels
53 ES7210_ERROR_FAILED(this->write_byte(ES7210_ADC12_HPF2_REG23, 0x2a));
54 ES7210_ERROR_FAILED(this->write_byte(ES7210_ADC12_HPF1_REG22, 0x0a));
55 ES7210_ERROR_FAILED(this->write_byte(ES7210_ADC34_HPF2_REG20, 0x0a));
56 ES7210_ERROR_FAILED(this->write_byte(ES7210_ADC34_HPF1_REG21, 0x2a));
57
58 // Secondary I2S mode settings
59 ES7210_ERROR_FAILED(this->es7210_update_reg_bit_(ES7210_MODE_CONFIG_REG08, 0x01, 0x00));
60
61 // Configure analog power
62 ES7210_ERROR_FAILED(this->write_byte(ES7210_ANALOG_REG40, 0xC3));
63
64 // Set mic bias
65 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC12_BIAS_REG41, 0x70));
66 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC34_BIAS_REG42, 0x70));
67
68 // Configure I2S settings, sample rate, and microphone gains
69 ES7210_ERROR_FAILED(this->configure_i2s_format_());
70 ES7210_ERROR_FAILED(this->configure_sample_rate_());
71 ES7210_ERROR_FAILED(this->configure_mic_gain_());
72
73 // Power on mics 1 through 4
74 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC1_POWER_REG47, 0x08));
75 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC2_POWER_REG48, 0x08));
76 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC3_POWER_REG49, 0x08));
77 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC4_POWER_REG4A, 0x08));
78
79 // Power down DLL
80 ES7210_ERROR_FAILED(this->write_byte(ES7210_POWER_DOWN_REG06, 0x04));
81
82 // Power on MIC1-4 bias & ADC1-4 & PGA1-4 Power
83 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC12_POWER_REG4B, 0x0F));
84 ES7210_ERROR_FAILED(this->write_byte(ES7210_MIC34_POWER_REG4C, 0x0F));
85
86 // Enable device
87 ES7210_ERROR_FAILED(this->write_byte(ES7210_RESET_REG00, 0x71));
88 ES7210_ERROR_FAILED(this->write_byte(ES7210_RESET_REG00, 0x41));
89
90 this->setup_complete_ = true;
91}
92
93bool ES7210::set_mic_gain(float mic_gain) {
94 this->mic_gain_ = clamp<float>(mic_gain, ES7210_MIC_GAIN_MIN, ES7210_MIC_GAIN_MAX);
95 if (this->setup_complete_) {
96 return this->configure_mic_gain_();
97 }
98 return true;
99}
100
102 int mclk_fre = this->sample_rate_ * MCLK_DIV_FRE;
103 int coeff = -1;
104
105 for (int i = 0; i < (sizeof(ES7210_COEFFICIENTS) / sizeof(ES7210_COEFFICIENTS[0])); ++i) {
106 if (ES7210_COEFFICIENTS[i].lrclk == this->sample_rate_ && ES7210_COEFFICIENTS[i].mclk == mclk_fre)
107 coeff = i;
108 }
109
110 if (coeff >= 0) {
111 // Set adc_div & doubler & dll
112 uint8_t regv;
113 ES7210_ERROR_CHECK(this->read_byte(ES7210_MAINCLK_REG02, &regv));
114 regv = regv & 0x00;
115 regv |= ES7210_COEFFICIENTS[coeff].adc_div;
116 regv |= ES7210_COEFFICIENTS[coeff].doubler << 6;
117 regv |= ES7210_COEFFICIENTS[coeff].dll << 7;
118
119 ES7210_ERROR_CHECK(this->write_byte(ES7210_MAINCLK_REG02, regv));
120
121 // Set osr
122 regv = ES7210_COEFFICIENTS[coeff].osr;
123 ES7210_ERROR_CHECK(this->write_byte(ES7210_OSR_REG07, regv));
124 // Set lrck
125 regv = ES7210_COEFFICIENTS[coeff].lrck_h;
126 ES7210_ERROR_CHECK(this->write_byte(ES7210_LRCK_DIVH_REG04, regv));
127 regv = ES7210_COEFFICIENTS[coeff].lrck_l;
128 ES7210_ERROR_CHECK(this->write_byte(ES7210_LRCK_DIVL_REG05, regv));
129 } else {
130 // Invalid sample frequency
131 ESP_LOGE(TAG, "Invalid sample rate");
132 return false;
133 }
134
135 return true;
136}
137
139 auto regv = this->es7210_gain_reg_value_(this->mic_gain_);
140 for (uint8_t i = 0; i < 4; ++i) {
141 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43 + i, 0x10, 0x00));
142 }
143 ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC12_POWER_REG4B, 0xff));
144 ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC34_POWER_REG4C, 0xff));
145
146 // Configure mic 1
147 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
148 ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC12_POWER_REG4B, 0x00));
149 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43, 0x10, 0x10));
150 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43, 0x0f, regv));
151
152 // Configure mic 2
153 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
154 ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC12_POWER_REG4B, 0x00));
155 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC2_GAIN_REG44, 0x10, 0x10));
156 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC2_GAIN_REG44, 0x0f, regv));
157
158 // Configure mic 3
159 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
160 ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC34_POWER_REG4C, 0x00));
161 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC3_GAIN_REG45, 0x10, 0x10));
162 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC3_GAIN_REG45, 0x0f, regv));
163
164 // Configure mic 4
165 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
166 ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC34_POWER_REG4C, 0x00));
167 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC4_GAIN_REG46, 0x10, 0x10));
168 ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC4_GAIN_REG46, 0x0f, regv));
169
170 return true;
171}
172
173uint8_t ES7210::es7210_gain_reg_value_(float mic_gain) {
174 // reg: 12 - 34.5dB, 13 - 36dB, 14 - 37.5dB
175 mic_gain += 0.5;
176 if (mic_gain <= 33.0) {
177 return (uint8_t) mic_gain / 3;
178 }
179 if (mic_gain < 36.0) {
180 return 12;
181 }
182 if (mic_gain < 37.0) {
183 return 13;
184 }
185 return 14;
186}
187
189 // Configure bits per sample
190 uint8_t reg_val = 0;
191 switch (this->bits_per_sample_) {
193 reg_val = 0x60;
194 break;
196 reg_val = 0x40;
197 break;
199 reg_val = 0x20;
200 break;
202 reg_val = 0x00;
203 break;
205 reg_val = 0x80;
206 break;
207 default:
208 return false;
209 }
210 ES7210_ERROR_CHECK(this->write_byte(ES7210_SDP_INTERFACE1_REG11, reg_val));
211
212 if (this->enable_tdm_) {
213 ES7210_ERROR_CHECK(this->write_byte(ES7210_SDP_INTERFACE2_REG12, 0x02));
214 } else {
215 // Microphones 1 and 2 output on SDOUT1, microphones 3 and 4 output on SDOUT2
216 ES7210_ERROR_CHECK(this->write_byte(ES7210_SDP_INTERFACE2_REG12, 0x00));
217 }
218
219 return true;
220}
221
222bool ES7210::es7210_update_reg_bit_(uint8_t reg_addr, uint8_t update_bits, uint8_t data) {
223 uint8_t regv;
224 ES7210_ERROR_CHECK(this->read_byte(reg_addr, &regv));
225 regv = (regv & (~update_bits)) | (update_bits & data);
226 return this->write_byte(reg_addr, regv);
227}
228
229} // namespace es7210
230} // namespace esphome
bool is_failed() const
uint8_t es7210_gain_reg_value_(float mic_gain)
Convert floating point mic gain value to register value.
Definition es7210.cpp:173
float mic_gain() override
Definition es7210.h:35
bool es7210_update_reg_bit_(uint8_t reg_addr, uint8_t update_bits, uint8_t data)
Updates an I2C registry address by modifying the current state.
Definition es7210.cpp:222
void setup() override
Definition es7210.cpp:40
void dump_config() override
Definition es7210.cpp:27
uint32_t sample_rate_
Definition es7210.h:58
bool set_mic_gain(float mic_gain) override
Definition es7210.cpp:93
ES7210BitsPerSample bits_per_sample_
Definition es7210.h:57
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition i2c.h:266
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition i2c.h:239
@ ES7210_BITS_PER_SAMPLE_20
Definition es7210.h:15
@ ES7210_BITS_PER_SAMPLE_18
Definition es7210.h:14
@ ES7210_BITS_PER_SAMPLE_16
Definition es7210.h:13
@ ES7210_BITS_PER_SAMPLE_32
Definition es7210.h:17
@ ES7210_BITS_PER_SAMPLE_24
Definition es7210.h:16
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition helpers.h:102