5#if defined(ESP32) && defined(USE_ANALOG) && !USE_LEGACY_I2S
8 #ifndef perimanClearPinBus
9 #define perimanClearPinBus(p) perimanSetPinBus(p, ESP32_BUS_TYPE_INIT, NULL)
89 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
97 size_t readBytes(uint8_t *dest,
size_t size_bytes)
override {
100 return io.readBytes(dest, size_bytes);
122 dac_continuous_handle_t dac_handle =
nullptr;
131#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
133#elif !defined(CONFIG_IDF_TARGET_ESP32H2)
141 void cleanupAttachedRxPins() {
142 perimanSetBusDeinit(ESP32_BUS_TYPE_ADC_CONT, adcDetachBus);
146 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
147 if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
148 if (!perimanClearPinBus(io_pin)) {
149 LOGE(
"perimanClearPinBus failed!");
165 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
170 int16_t *data16 = (int16_t *)src;
171 uint8_t *data8 = (uint8_t *)src;
172 int samples = size_bytes / 2;
175 for (
int j = 0; j < samples; j++) {
176 data8[j] = (32768u + data16[j]) >> 8;
179 if (dac_continuous_write(
self->dac_handle, data8, samples, &result,
self->
cfg.
timeout) != ESP_OK) {
190 LOGD(
"readBytes: %d", (
int) size_bytes);
195 for(
int ch=0;ch < channels;ch++){
198 uint16_t *result16 = (uint16_t *)dest;
199 int samples_requested = size_bytes /
sizeof(int16_t);
200 int samples_requested_per_channel = samples_requested / channels;
201 int buffer_size = samples_requested *
sizeof(adc_digi_output_data_t);
206 int read_size_bytes = buffer_size;
209 while (read_size_bytes > 0){
210 uint32_t bytes_read = 0;
212 int samples_read = bytes_read /
sizeof(adc_digi_output_data_t);
213 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)));
216 for (
int i = 0; i < samples_read; i++) {
217 adc_digi_output_data_t *p = (adc_digi_output_data_t*) &
result_data[i];
218 ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(p);
219 ADC_DATA_TYPE sample_value = AUDIO_ADC_GET_DATA(p);
223 if (channel >=0 && channel < channels){
224 int idx = channel + (
sampleIndex[channel] * channels);
225 LOGI(
"idx for %d: %d", channel, idx);
226 if(idx < samples_requested){
231 result16[idx] = sample_value;
236 LOGE(
"Invalid idx: %d / max %d", idx, samples_requested);
239 LOGE(
"Invalid channel: %d", channel);
244 result = samples_available * channels *
sizeof(int16_t);
247 read_size_bytes = result - size_bytes;
248 if (read_size_bytes > 0)
249 LOGI(
"read missing samples: %d", samples_requested_per_channel - samples_available);
251 LOGE(
"adc_continuous_read error");
286 int data_milliVolts = 0;
290 result =
static_cast<int16_t
>(data_milliVolts);
292 LOGE(
"adc_cali_raw_to_voltage error: %d", err);
299 for (
int ch = 0; ch < channels; ch++){
315 dac_continuous_config_t cont_cfg = {
316 .chan_mask = (dac_channel_mask_t)(
cfg.
channels == 1 ?
cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL),
317 .desc_num = (uint32_t)
cfg.buffer_count,
318 .buf_size = (size_t)
cfg.buffer_size,
319 .freq_hz = (uint32_t)
cfg.sample_rate,
321 .clk_src =
cfg.use_apll ? DAC_DIGI_CLK_SRC_APLL : DAC_DIGI_CLK_SRC_DEFAULT,
322 .chan_mode =
cfg.channels == 1 ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER,
325 if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
326 LOGE(
"new_channels");
329 if (dac_continuous_enable(dac_handle) != ESP_OK) {
337 LOGE(
"DAC not supported");
345 adc_channel_t adc_channel;
356 LOGE(
"adc unit %u continuous is already initialized. Please call end() first!",
cfg.
adc_unit);
367 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
368 if (!perimanClearPinBus(io_pin)) {
369 LOGE(
"perimanClearPinBus failed!");
375 uint32_t conv_frame_size = (uint32_t)
cfg.
buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
376 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
377 conv_frame_size = adcContinuousAlignFrameSize(conv_frame_size);
380 uint32_t rx_max_conv_frame_bytes = adcContinuousMaxConvFrameBytes();
381 uint32_t max_samples_per_frame = adcContinuousMaxResultsPerFrame();
382 if (conv_frame_size > rx_max_conv_frame_bytes) {
384 "buffer_size is too big for one ADC DMA frame: %u samples = %u "
385 "bytes, max %u samples / %u bytes",
387 (
unsigned)max_samples_per_frame,
388 (
unsigned)rx_max_conv_frame_bytes);
392 "RX DMA frame: %u conversion results, %u bytes (max %u results / "
395 (
unsigned)max_samples_per_frame,
396 (
unsigned)rx_max_conv_frame_bytes);
400 adc_continuous_handle_cfg_t adc_config;
402 adc_config.max_store_buf_size = (uint32_t)conv_frame_size * rx_frame_count;
403 adc_config.conv_frame_size = (uint32_t) conv_frame_size;
404#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
405 adc_config.flags.flush_pool =
true;
407 LOGI(
"RX pool: %u frames, %u bytes", (
unsigned)rx_frame_count,
408 (
unsigned)adc_config.max_store_buf_size);
409 err = adc_continuous_new_handle(&adc_config, &
adc_handle);
411 LOGE(
"adc_continuous_new_handle failed with error: %d", err);
414 LOGI(
"adc_continuous_new_handle successful");
418 adc_digi_pattern_config_t adc_pattern[
cfg.
channels] = {};
422 adc_pattern[i].channel = (uint8_t)ch;
428 adc_continuous_config_t dig_cfg = {
430 .adc_pattern = adc_pattern,
437 LOGI(
"dig_cfg.sample_freq_hz: %u", (
unsigned)dig_cfg.sample_freq_hz);
438 LOGI(
"dig_cfg.conv_mode: %u (1: unit 1, 2: unit 2, 3: both)", dig_cfg.conv_mode);
439 LOGI(
"dig_cfg.format: %u (0 is type1: [12bit data, 4bit channel])", dig_cfg.format);
441 LOGI(
"dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
442 LOGI(
"dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
443 LOGI(
"dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
444 LOGI(
"dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
448 err = adc_continuous_config(
adc_handle, &dig_cfg);
450 LOGE(
"adc_continuous_config unsuccessful with error: %d", err);
454 LOGI(
"adc_continuous_config successful");
466 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
468 if (!perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (
void *)(
cfg.
adc_unit + 1),
cfg.
adc_unit, adc_channel)) {
469 LOGE(
"perimanSetPinBus to Continuous an ADC Unit %u failed!",
cfg.
adc_unit);
480 LOGE(
"adc_continuous_start unsuccessful with error: %d", err);
489 LOGW(
"is_scale_to_16bit ignored: calibrated values are in mV");
492 LOGI(
"Setup ADC successful");
501 if (dac_handle==
nullptr)
return true;
502 if (dac_continuous_disable(dac_handle) != ESP_OK){
504 LOGE(
"dac_continuous_disable failed");
506 if (dac_continuous_del_channels(dac_handle) != ESP_OK){
508 LOGE(
"dac_continuous_del_channels failed");
510 dac_handle =
nullptr;
517 static bool adcDetachBus(
void *bus) {
518 LOGD(
"===> adcDetachBus: %d", (
int) bus);
527 if (adc_continuous_stop(
adc_handle) != ESP_OK) {
528 LOGE(
"adc_continuous_stop failed");
534 if (adc_continuous_deinit(
adc_handle) != ESP_OK) {
535 LOGE(
"adc_continuous_deinit failed");
544 cleanupAttachedRxPins();
554 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
558 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
565 adc_channel_t adc_channel;
577 auto err = adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
579 LOGE(
"ADC channel %u is not available on ADC unit %u", adc_channel,
cfg.
adc_unit);
582 LOGI(
"ADC channel %u is on pin %u", adc_channel, io_pin);
594 LOGE(
"sample rate eff: %u can not be set, range: %u to %u", sample_rate,
598 LOGI(
"sample rate eff: %u, range: %u to %u", sample_rate,
606 int supported_bits = 16;
616 LOGE(
"bits per sample: error. It should be: %d but is %d",
638 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
640 adc_cali_curve_fitting_config_t cali_config;
644 auto err = adc_cali_create_scheme_curve_fitting(&cali_config, &
adc_cali_handle);
645 #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
647 adc_cali_line_fitting_config_t cali_config;
651 auto err = adc_cali_create_scheme_line_fitting(&cali_config, &
adc_cali_handle);
656 LOGE(
"creating calibration handle failed for ADC%d with atten %d and bitwidth %d",
661 LOGI(
"enabled calibration for ADC%d with atten %d and bitwidth %d",
#define SOC_ADC_SAMPLE_FREQ_THRES_LOW
Definition AnalogConfigESP32V1.h:18
#define SOC_ADC_SAMPLE_FREQ_THRES_HIGH
Definition AnalogConfigESP32V1.h:15
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define assert(T)
Definition avr.h:10
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26