3 #include "AudioConfig.h"
4 #if defined(ESP32) && defined(USE_ANALOG) && \
5 ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) || \
9 # ifndef perimanClearPinBus
10 # define perimanClearPinBus(p) perimanSetPinBus(p, ESP32_BUS_TYPE_INIT, NULL)
14 #include "AudioAnalog/AnalogAudioBase.h"
15 #include "AudioAnalog/AnalogConfigESP32V1.h"
16 #include "AudioTools/AudioStreams.h"
17 #include "AudioTools/AudioStreamsConverter.h"
42 switch (cfg.rx_tx_mode) {
48 if (!converter.begin(cfg, 16)) {
74 dac_continuous_del_channels(dac_handle);
78 adc_continuous_stop(adc_handle);
80 adc_continuous_deinit(adc_handle);
82 if (cfg.adc_calibration_active) {
83 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
84 adc_cali_delete_scheme_curve_fitting(adc_cali_handle);
85 #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
86 adc_cali_delete_scheme_line_fitting(adc_cali_handle);
93 for(
int i = 0; i < cfg.
channels; i++){
97 adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
98 if(perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT){
99 if( !perimanClearPinBus(io_pin) ){
100 LOGE(
"perimanClearPinBus failed!");
114 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
117 return converter.write(src, size_bytes);
121 size_t readBytes(uint8_t *dest,
size_t size_bytes)
override {
125 return io.readBytes(dest, size_bytes);
129 int available()
override {
return active_rx ? DEFAULT_BUFFER_SIZE : 0; }
132 adc_continuous_handle_t adc_handle =
nullptr;
133 adc_cali_handle_t adc_cali_handle =
nullptr;
134 AnalogConfigESP32V1 cfg;
136 bool active_tx =
false;
137 bool active_rx =
false;
138 ConverterAutoCenter auto_center;
140 dac_continuous_handle_t dac_handle;
149 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
155 int16_t *data16 = (int16_t *)src;
156 uint8_t *data8 = (uint8_t *)src;
157 int samples = size_bytes / 2;
158 for (
int j = 0; j < samples; j++) {
159 data8[j] = (32768u + data16[j]) >> 8;
162 if (dac_continuous_write(self->dac_handle, data8, samples, &result,
163 self->cfg.timeout) != ESP_OK) {
173 size_t readBytes(uint8_t *dest,
size_t size_bytes)
override {
175 size_t total_bytes = 0;
177 int sample_count = size_bytes /
sizeof(int16_t);
178 adc_digi_output_data_t result_data[sample_count];
179 memset(&result_data, 0,
sizeof(result_data));
180 uint32_t result_cont;
181 if (adc_continuous_read(self->adc_handle, (uint8_t *)result_data,
182 sizeof(result_data), &result_cont,
183 self->cfg.timeout) == ESP_OK) {
185 uint16_t *result16 = (uint16_t *)dest;
186 uint16_t *end = (uint16_t *)(dest + size_bytes);
187 int result_count = result_cont /
sizeof(adc_digi_output_data_t);
188 LOGD(
"adc_continuous_read -> %u bytes / %d samples", (
unsigned) result_cont,
191 for (
int i = 0; i < result_count; i++) {
192 adc_digi_output_data_t *p = &result_data[i];
193 uint16_t chan_num = AUDIO_ADC_GET_CHANNEL(p);
194 uint32_t data = AUDIO_ADC_GET_DATA(p);
196 if (isValidADCChannel((adc_channel_t)chan_num)) {
197 LOGD(
"Idx: %d, channel: %d, data: %u", i, chan_num, (
unsigned) data);
199 assert(result16 < end);
200 if (self->cfg.adc_calibration_active) {
203 auto err = adc_cali_raw_to_voltage(self->adc_cali_handle, data,
206 int result_full_range = data_milliVolts;
207 *result16 = result_full_range;
208 assert(result_full_range ==
211 total_bytes +=
sizeof(uint16_t);
213 LOGE(
"adc_cali_raw_to_voltage: %d", err);
219 (uint32_t)*result16);
221 total_bytes +=
sizeof(uint16_t);
225 LOGD(
"invalid channel: %d, data: %u", chan_num, (
unsigned) data);
229 if (self->cfg.is_auto_center_read) {
230 self->auto_center.convert(dest, total_bytes);
234 LOGE(
"adc_continuous_read unsuccessful");
243 bool isValidADCChannel(adc_channel_t channel) {
244 for (
int j = 0; j <
self->cfg.channels; j++) {
258 dac_continuous_config_t cont_cfg = {
260 cfg.channels == 1 ? cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL,
261 .desc_num = (uint32_t)cfg.buffer_count,
262 .buf_size = (
size_t)cfg.buffer_size,
263 .freq_hz = (uint32_t)cfg.sample_rate,
267 ? DAC_DIGI_CLK_SRC_APLL
268 : DAC_DIGI_CLK_SRC_DEFAULT,
270 .chan_mode = DAC_CHANNEL_MODE_ALTER,
273 if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
274 LOGE(
"new_channels");
277 if (dac_continuous_enable(dac_handle) != ESP_OK) {
286 LOGE(
"DAC not supported");
293 adc_channel_t adc_channel;
297 if (!checkADCChannels())
299 if (!checkADCSampleRate())
301 if (!checkADCBitWidth())
303 if (!checkADCBitsPerSample())
306 if(adc_handle !=
nullptr){
307 LOGE(
"adc unit %u continuous is already initialized. Please call end() first!", ADC_UNIT);
316 for(
int i = 0; i < cfg.channels; i++){
318 adc_channel = cfg.adc_channels[i];
319 adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
320 if( !perimanClearPinBus(io_pin) ){
321 LOGE(
"perimanClearPinBus failed!");
329 uint32_t conv_frame_size =
330 (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
331 uint8_t calc_multiple_diff =
332 conv_frame_size % SOC_ADC_DIGI_DATA_BYTES_PER_CONV;
333 if (calc_multiple_diff != 0) {
334 conv_frame_size = (conv_frame_size + calc_multiple_diff);
338 if(conv_frame_size > 4092){
339 LOGE(
"buffer_size is too big. Please set lower buffer_size.");
342 LOGD(
"buffer_size %u, conv_frame_size: %u", cfg.buffer_size, (
unsigned) conv_frame_size);
345 adc_continuous_handle_cfg_t adc_config = {
346 .max_store_buf_size = (uint32_t)conv_frame_size * cfg.buffer_count,
347 .conv_frame_size = conv_frame_size,
351 err = adc_continuous_new_handle(&adc_config, &adc_handle);
353 LOGE(
"adc_continuous_new_handle failed with error: %d", err);
356 LOGD(
"adc_continuous_new_handle successful");
359 adc_digi_pattern_config_t adc_pattern[cfg.channels] = {};
361 for (
int i = 0; i < cfg.channels; i++) {
362 uint8_t ch = cfg.adc_channels[i] & 0x7;
363 adc_pattern[i].atten = cfg.adc_attenuation;
364 adc_pattern[i].channel = ch;
365 adc_pattern[i].unit = ADC_UNIT;
366 adc_pattern[i].bit_width = cfg.adc_bit_width;
370 adc_continuous_config_t dig_cfg = {
371 .pattern_num = cfg.channels,
372 .adc_pattern = adc_pattern,
373 .sample_freq_hz = (uint32_t)cfg.sample_rate * cfg.channels,
374 .conv_mode = cfg.adc_conversion_mode,
375 .format = cfg.adc_output_type,
379 LOGI(
"dig_cfg.sample_freq_hz: %u", (
unsigned)dig_cfg.sample_freq_hz);
380 LOGI(
"dig_cfg.conv_mode: %u", dig_cfg.conv_mode);
381 LOGI(
"dig_cfg.format: %u", dig_cfg.format);
382 for (
int i = 0; i < cfg.channels; i++) {
383 LOGI(
"dig_cfg.adc_pattern[%d].atten: %u", i,
384 dig_cfg.adc_pattern[i].atten);
385 LOGI(
"dig_cfg.adc_pattern[%d].channel: %u", i,
386 dig_cfg.adc_pattern[i].channel);
387 LOGI(
"dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
388 LOGI(
"dig_cfg.adc_pattern[%d].bit_width: %u", i,
389 dig_cfg.adc_pattern[i].bit_width);
393 err = adc_continuous_config(adc_handle, &dig_cfg);
395 LOGE(
"adc_continuous_config unsuccessful with error: %d", err);
398 LOGI(
"adc_continuous_config successful");
401 if (!setupADCCalibration()) {
407 for(
int i = 0; i < cfg.channels; i++){
408 adc_channel = cfg.adc_channels[i];
409 adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
411 if( !perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (
void *)(ADC_UNIT+1), ADC_UNIT, adc_channel) ) {
412 LOGE(
"perimanSetPinBus to Continuous an ADC Unit %u failed!", ADC_UNIT);
419 err = adc_continuous_start(adc_handle);
421 LOGE(
"adc_continuous_start unsuccessful with error: %d", err);
426 auto_center.begin(cfg.channels, cfg.bits_per_sample,
true);
428 LOGI(
"adc_continuous_start successful");
432 bool checkADCBitWidth() {
433 if ((cfg.adc_bit_width < SOC_ADC_DIGI_MIN_BITWIDTH) ||
434 (cfg.adc_bit_width > SOC_ADC_DIGI_MAX_BITWIDTH)) {
435 LOGE(
"adc bit width: %u cannot be set, range: %u to %u", cfg.adc_bit_width,
436 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
439 LOGI(
"adc bit width: %u, range: %u to %u", cfg.adc_bit_width,
440 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
444 bool checkADCChannels() {
446 adc_channel_t adc_channel;
448 int max_channels =
sizeof(cfg.adc_channels) /
sizeof(adc_channel_t);
449 if (cfg.channels > max_channels) {
450 LOGE(
"number of channels: %d, max: %d", cfg.channels, max_channels);
453 LOGI(
"channels: %d, max: %d", cfg.channels, max_channels);
456 for(
int i = 0; i < cfg.channels; i++){
457 adc_channel = cfg.adc_channels[i];
458 auto err = adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
460 LOGE(
"ADC channel %u is not available on ADC unit %u", adc_channel, ADC_UNIT);
463 LOGI(
"ADC channel %u is on pin %u", adc_channel, io_pin);
469 bool checkADCSampleRate() {
470 int sample_rate = cfg.sample_rate * cfg.channels;
471 if ((sample_rate < SOC_ADC_SAMPLE_FREQ_THRES_LOW) ||
472 (sample_rate > SOC_ADC_SAMPLE_FREQ_THRES_HIGH)) {
473 LOGE(
"sample rate eff: %u can not be set, range: %u to %u",sample_rate,
474 SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
477 LOGI(
"sample rate eff: %u, range: %u to %u", sample_rate,
478 SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
483 bool checkADCBitsPerSample() {
484 int supported_bits = 16;
487 if (cfg.bits_per_sample == 0) {
488 cfg.bits_per_sample = supported_bits;
489 LOGI(
"bits per sample set to: %d", cfg.bits_per_sample);
493 if (cfg.bits_per_sample != supported_bits) {
494 LOGE(
"bits per sample: error. It should be: %d but is %d",
495 supported_bits, cfg.bits_per_sample);
498 LOGI(
"bits per sample: %d", cfg.bits_per_sample);
502 bool setupADCCalibration() {
503 if (!cfg.adc_calibration_active)
510 if (adc_cali_handle == NULL) {
511 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
513 adc_cali_curve_fitting_config_t cali_config;
514 cali_config.unit_id = ADC_UNIT;
515 cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
516 cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
518 adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle);
519 #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
521 adc_cali_line_fitting_config_t cali_config;
522 cali_config.unit_id = ADC_UNIT;
523 cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
524 cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
526 adc_cali_create_scheme_line_fitting(&cali_config, &adc_cali_handle);
529 LOGE(
"creating cali handle failed for ADC%d with atten %d and bitwidth "
531 ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);
534 LOGI(
"created cali handle for ADC%d with atten %d and bitwidth %d",
535 ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);