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