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