3 #include "AudioConfig.h"
5 #if defined(ESP32) && defined(USE_ANALOG) && \
6 ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) || defined(DOXYGEN)
9 #ifndef perimanClearPinBus
10 #define perimanClearPinBus(p) perimanSetPinBus(p, ESP32_BUS_TYPE_INIT, NULL)
14 #include "AudioTools/CoreAudio/AudioAnalog/AnalogDriverBase.h"
15 #include "AudioTools/CoreAudio/AudioAnalog/AnalogConfigESP32V1.h"
16 #include "AudioTools/CoreAudio/AudioStreams.h"
17 #include "AudioTools/CoreAudio/AudioStreamsConverter.h"
28 class AnalogDriverESP32V1 :
public AnalogDriverBase {
45 switch (cfg.rx_tx_mode) {
47 if (!setup_tx())
return false;
49 if (!converter.begin(cfg, 16)) {
56 if (!setup_rx())
return false;
88 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
91 return converter.write(src, size_bytes);
96 size_t readBytes(uint8_t *dest,
size_t size_bytes)
override {
99 return io.readBytes(dest, size_bytes);
104 int available()
override {
105 return active_rx ? (uint32_t)(cfg.buffer_size *
sizeof(int16_t)) : 0;
110 adc_continuous_handle_t adc_handle =
nullptr;
111 adc_cali_handle_t adc_cali_handle =
nullptr;
112 AnalogConfigESP32V1 cfg;
114 bool active_tx =
false;
115 bool active_rx =
false;
116 ConverterAutoCenter auto_center;
118 dac_continuous_handle_t dac_handle =
nullptr;
124 class IO16Bit :
public AudioStream {
129 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
134 int16_t *data16 = (int16_t *)src;
135 uint8_t *data8 = (uint8_t *)src;
136 int samples = size_bytes / 2;
139 for (
int j = 0; j < samples; j++) {
140 data8[j] = (32768u + data16[j]) >> 8;
143 if (dac_continuous_write(self->dac_handle, data8, samples, &result, self->cfg.timeout) != ESP_OK) {
154 LOGD(
"readBytes: %d", (
int) size_bytes);
156 int channels =
self->cfg.channels;
157 assert(channels > 0);
158 sampleIndex.resize(channels);
159 for(
int ch=0;ch < channels;ch++){
162 uint16_t *result16 = (uint16_t *)dest;
163 int samples_requested = size_bytes /
sizeof(int16_t);
164 int samples_requested_per_channel = samples_requested / channels;
165 int buffer_size = samples_requested *
sizeof(adc_digi_output_data_t);
166 if (result_data.size() < buffer_size){
167 result_data.resize(buffer_size);
170 int read_size_bytes = buffer_size;
173 while (read_size_bytes > 0){
174 uint32_t bytes_read = 0;
175 if (adc_continuous_read(self->adc_handle, (uint8_t *)result_data.data(), (uint32_t)read_size_bytes, &bytes_read, (uint32_t)
self->cfg.timeout) == ESP_OK) {
176 int samples_read = bytes_read /
sizeof(adc_digi_output_data_t);
177 LOGD(
"adc_continuous_read -> %u bytes / %d samples of %d bytes requested", (
unsigned)bytes_read, samples_read, (
int)(samples_requested *
sizeof(adc_digi_output_data_t)));
180 for (
int i = 0; i < samples_read; i++) {
181 adc_digi_output_data_t *p = (adc_digi_output_data_t*) &result_data[i];
182 ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(p);
183 ADC_DATA_TYPE sample_value = AUDIO_ADC_GET_DATA(p);
184 int channel = getChannelIdx(chan_num);
187 if (channel >=0 && channel < channels){
188 int idx = channel + (sampleIndex[channel] * channels);
189 LOGI(
"idx for %d: %d", channel, idx);
190 if(idx < samples_requested){
192 if (self->cfg.adc_calibration_active) {
193 result16[idx] = getCalibratedValue(sample_value);
195 result16[idx] = sample_value;
198 sampleIndex[channel]++;
200 LOGE(
"Invalid idx: %d / max %d", idx, samples_requested);
203 LOGE(
"Invalid channel: %d", channel);
207 int samples_available = getMinSamplesForAllChannels(channels);
208 result = samples_available * channels *
sizeof(int16_t);
211 read_size_bytes = result - size_bytes;
212 if (read_size_bytes > 0)
213 LOGI(
"read missing samples: %d", samples_requested_per_channel - samples_available);
215 LOGE(
"adc_continuous_read error");
222 if (self->cfg.is_auto_center_read) {
223 self->auto_center.convert(dest, result);
234 int getChannelIdx(ADC_CHANNEL_TYPE chan_num){
235 for (
int j = 0; j <
self->cfg.channels; ++j) {
236 if (self->cfg.adc_channels[j] == chan_num) {
243 int16_t getCalibratedValue(ADC_DATA_TYPE sample_value){
244 int data_milliVolts = 0;
246 auto err = adc_cali_raw_to_voltage(self->adc_cali_handle, sample_value, &data_milliVolts);
248 result =
static_cast<int16_t
>(data_milliVolts);
250 LOGE(
"adc_cali_raw_to_voltage error: %d", err);
255 int getMinSamplesForAllChannels(
int channels) {
257 for (
int ch = 0; ch < channels; ch++){
258 if (sampleIndex[ch] < result){
259 result = sampleIndex[ch];
267 NumberFormatConverterStream converter{io};
273 dac_continuous_config_t cont_cfg = {
274 .chan_mask = cfg.channels == 1 ? cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL,
275 .desc_num = (uint32_t)cfg.buffer_count,
276 .buf_size = (
size_t)cfg.buffer_size,
277 .freq_hz = (uint32_t)cfg.sample_rate,
279 .clk_src = cfg.use_apll ? DAC_DIGI_CLK_SRC_APLL : DAC_DIGI_CLK_SRC_DEFAULT,
280 .chan_mode = DAC_CHANNEL_MODE_ALTER,
283 if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
284 LOGE(
"new_channels");
287 if (dac_continuous_enable(dac_handle) != ESP_OK) {
295 LOGE(
"DAC not supported");
303 adc_channel_t adc_channel;
313 if (adc_handle !=
nullptr) {
314 LOGE(
"adc unit %u continuous is already initialized. Please call end() first!", ADC_UNIT);
323 for (
int i = 0; i < cfg.channels; i++) {
324 adc_channel = cfg.adc_channels[i];
325 adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
326 if (!perimanClearPinBus(io_pin)) {
327 LOGE(
"perimanClearPinBus failed!");
335 uint32_t conv_frame_size = (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
336 #
if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
337 uint8_t calc_multiple = conv_frame_size % SOC_ADC_DIGI_DATA_BYTES_PER_CONV;
338 if (calc_multiple != 0) {
339 conv_frame_size = (uint32_t) (conv_frame_size + calc_multiple);
350 if (conv_frame_size > 4092) {
351 LOGE(
"buffer_size is too big. Please set lower buffer_size.");
354 LOGI(
"buffer_size: %u samples, conv_frame_size: %u bytes", cfg.buffer_size, (
unsigned)conv_frame_size);
358 adc_continuous_handle_cfg_t adc_config;
359 adc_config.max_store_buf_size = (uint32_t)conv_frame_size * 2;
360 adc_config.conv_frame_size = (uint32_t) conv_frame_size;
361 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
362 adc_config.flags.flush_pool =
true;
364 err = adc_continuous_new_handle(&adc_config, &adc_handle);
366 LOGE(
"adc_continuous_new_handle failed with error: %d", err);
369 LOGI(
"adc_continuous_new_handle successful");
373 adc_digi_pattern_config_t adc_pattern[cfg.channels] = {};
374 for (
int i = 0; i < cfg.channels; i++) {
375 uint8_t ch = cfg.adc_channels[i];
376 adc_pattern[i].atten = (uint8_t) cfg.adc_attenuation;
377 adc_pattern[i].channel = (uint8_t)ch;
378 adc_pattern[i].unit = (uint8_t) ADC_UNIT;
379 adc_pattern[i].bit_width = (uint8_t) cfg.adc_bit_width;
383 adc_continuous_config_t dig_cfg = {
384 .pattern_num = (uint32_t) cfg.channels,
385 .adc_pattern = adc_pattern,
386 .sample_freq_hz = (uint32_t)cfg.sample_rate * cfg.channels,
387 .conv_mode = (adc_digi_convert_mode_t) cfg.adc_conversion_mode,
388 .format = (adc_digi_output_format_t) cfg.adc_output_type,
392 LOGI(
"dig_cfg.sample_freq_hz: %u", (
unsigned)dig_cfg.sample_freq_hz);
393 LOGI(
"dig_cfg.conv_mode: %u (1: unit 1, 2: unit 2, 3: both)", dig_cfg.conv_mode);
394 LOGI(
"dig_cfg.format: %u (0 is type1: [12bit data, 4bit channel])", dig_cfg.format);
395 for (
int i = 0; i < cfg.channels; i++) {
396 LOGI(
"dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
397 LOGI(
"dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
398 LOGI(
"dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
399 LOGI(
"dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
403 err = adc_continuous_config(adc_handle, &dig_cfg);
405 LOGE(
"adc_continuous_config unsuccessful with error: %d", err);
408 LOGI(
"adc_continuous_config successful");
417 for (
int i = 0; i < cfg.channels; i++) {
418 adc_channel = cfg.adc_channels[i];
419 adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
421 if (!perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (
void *)(ADC_UNIT + 1), ADC_UNIT, adc_channel)) {
422 LOGE(
"perimanSetPinBus to Continuous an ADC Unit %u failed!", ADC_UNIT);
429 err = adc_continuous_start(adc_handle);
431 LOGE(
"adc_continuous_start unsuccessful with error: %d", err);
436 auto_center.begin(cfg.channels, cfg.bits_per_sample,
true);
438 LOGI(
"Setup ADC successful");
447 if (dac_handle==
nullptr)
return true;
448 if (dac_continuous_disable(dac_handle) != ESP_OK){
450 LOGE(
"dac_continuous_disable failed");
452 if (dac_continuous_del_channels(dac_handle) != ESP_OK){
454 LOGE(
"dac_continuous_del_channels failed");
456 dac_handle =
nullptr;
463 static bool adcDetachBus(
void *bus) {
464 LOGD(
"===> adcDetachBus: %d", (
int) bus);
471 if (adc_handle==
nullptr)
return true;
472 adc_continuous_stop(adc_handle);
473 adc_continuous_deinit(adc_handle);
474 if (cfg.adc_calibration_active) {
475 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
476 adc_cali_delete_scheme_curve_fitting(adc_cali_handle);
477 #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
478 adc_cali_delete_scheme_line_fitting(adc_cali_handle);
484 perimanSetBusDeinit(ESP32_BUS_TYPE_ADC_CONT, adcDetachBus);
485 for (
int i = 0; i < cfg.channels; i++) {
486 adc_channel_t adc_channel = cfg.adc_channels[i];
488 adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
489 if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
490 if (!perimanClearPinBus(io_pin)) {
491 LOGE(
"perimanClearPinBus failed!");
496 adc_handle =
nullptr;
502 if ((cfg.adc_bit_width < SOC_ADC_DIGI_MIN_BITWIDTH) ||
503 (cfg.adc_bit_width > SOC_ADC_DIGI_MAX_BITWIDTH)) {
504 LOGE(
"adc bit width: %u cannot be set, range: %u to %u", cfg.adc_bit_width,
505 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
508 LOGI(
"adc bit width: %u, range: %u to %u", cfg.adc_bit_width,
509 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
516 adc_channel_t adc_channel;
518 int max_channels =
sizeof(cfg.adc_channels) /
sizeof(adc_channel_t);
519 if (cfg.channels > max_channels) {
520 LOGE(
"number of channels: %d, max: %d", cfg.channels, max_channels);
523 LOGI(
"channels: %d, max: %d", cfg.channels, max_channels);
526 for (
int i = 0; i < cfg.channels; i++) {
527 adc_channel = cfg.adc_channels[i];
528 auto err = adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
530 LOGE(
"ADC channel %u is not available on ADC unit %u", adc_channel, ADC_UNIT);
533 LOGI(
"ADC channel %u is on pin %u", adc_channel, io_pin);
541 LOGI(
"sample rate (audio): %d", cfg.sample_rate);
542 int sample_rate = cfg.sample_rate * cfg.channels;
543 if ((sample_rate < SOC_ADC_SAMPLE_FREQ_THRES_LOW) ||
544 (sample_rate > SOC_ADC_SAMPLE_FREQ_THRES_HIGH)) {
545 LOGE(
"sample rate eff: %u can not be set, range: %u to %u", sample_rate,
546 SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
549 LOGI(
"sample rate eff: %u, range: %u to %u", sample_rate,
550 SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
557 int supported_bits = 16;
560 if (cfg.bits_per_sample == 0) {
561 cfg.bits_per_sample = supported_bits;
562 LOGI(
"bits per sample set to: %d", cfg.bits_per_sample);
566 if (cfg.bits_per_sample != supported_bits) {
567 LOGE(
"bits per sample: error. It should be: %d but is %d",
568 supported_bits, cfg.bits_per_sample);
571 LOGI(
"bits per sample: %d", cfg.bits_per_sample);
577 if (!cfg.adc_calibration_active)
584 if (adc_cali_handle == NULL) {
585 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
587 adc_cali_curve_fitting_config_t cali_config;
588 cali_config.unit_id = ADC_UNIT;
589 cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
590 cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
591 auto err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle);
592 #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
594 adc_cali_line_fitting_config_t cali_config;
595 cali_config.unit_id = ADC_UNIT;
596 cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
597 cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
598 auto err = adc_cali_create_scheme_line_fitting(&cali_config, &adc_cali_handle);
601 LOGE(
"creating calibration handle failed for ADC%d with atten %d and bitwidth %d",
602 ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);
605 LOGI(
"enabled calibration for ADC%d with atten %d and bitwidth %d",
606 ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);