ESPHome  2025.2.0
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 
7 namespace esphome {
8 namespace es7210 {
9 
10 static const char *const TAG = "es7210";
11 
12 static 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 
38 void ES7210::setup() {
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 
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 
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 
220 bool 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 read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
ES7210BitsPerSample bits_per_sample_
Definition: es7210.h:57
bool is_failed() const
Definition: component.cpp:143
void dump_config() override
Definition: es7210.cpp:27
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
bool set_mic_gain(float mic_gain) override
Definition: es7210.cpp:91
void setup() override
Definition: es7210.cpp:38
bool configure_i2s_format_()
Definition: es7210.cpp:186
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:262
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
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
float mic_gain() override
Definition: es7210.h:35
uint32_t sample_rate_
Definition: es7210.h:58