5#if (defined(ESP32) && defined(USE_ANALOG) && !USE_LEGACY_I2S)
81 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
89 size_t readBytes(uint8_t *dest,
size_t size_bytes)
override {
92 return io.readBytes(dest, size_bytes);
112 FIFO() : size_(0), buffer_(nullptr), head_(0), tail_(0), count_(0) {}
122 if (count_ < size_) {
123 buffer_[tail_] = value;
125 tail_ = (tail_ + 1) % size_;
136 value = buffer_[head_];
138 head_ = (head_ + 1) % size_;
156 return count_ == size_;
184 dac_continuous_handle_t dac_handle =
nullptr;
202 if (fifo_size < min_samples) {
203 min_samples = fifo_size;
206 return (
int)min_samples;
216 size_t fallback = 8U;
217 if (SOC_ADC_DIGI_RESULT_BYTES == 0)
return fallback;
219 size_t frame_results = conv_frame_bytes / SOC_ADC_DIGI_RESULT_BYTES;
220 if (frame_results == 0)
return fallback;
222 size_t frame_results_per_channel = frame_results / (size_t)
cfg.
channels;
223 if (frame_results_per_channel == 0)
return fallback;
225 return frame_results_per_channel + 4U;
256 uint32_t chan_num = sample.type2.channel;
257#ifdef SOC_ADC_CHANNEL_NUM
258 if (chan_num >= SOC_ADC_CHANNEL_NUM(
cfg.
adc_unit)) {
259 LOGE(
"Invalid TYPE2 ADC channel: %u", (
unsigned)chan_num);
264#ifdef ADC_CONV_SINGLE_UNIT_1
266 sample.type2.unit != 0) {
267 LOGE(
"Invalid TYPE2 ADC unit for ADC1 mode: %u",
268 (
unsigned)sample.type2.unit);
272#ifdef ADC_CONV_SINGLE_UNIT_2
274 sample.type2.unit != 1) {
275 LOGE(
"Invalid TYPE2 ADC unit for ADC2 mode: %u",
276 (
unsigned)sample.type2.unit);
285 return static_cast<int16_t
>(data);
288 int data_milliVolts = 0;
292 LOGE(
"adc_cali_raw_to_voltage error: %d", err);
295 return static_cast<int16_t
>(data_milliVolts);
300 if (data ==
nullptr)
return false;
302 for (
int i = 0; i < samples_read; ++i) {
303 const adc_digi_output_data_t* sample = &data[i];
305 LOGE(
"ADC reorder resync on invalid TYPE2 record at sample %d", i);
310 ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(sample);
312 if (channel_idx < 0) {
313 LOGE(
"ADC reorder resync on invalid channel %u at sample %d",
314 (
unsigned)chan_num, i);
319 ADC_DATA_TYPE sample_value = AUDIO_ADC_GET_DATA(sample);
321 LOGE(
"ADC reorder FIFO overflow on channel index %d (channel %u)",
322 channel_idx, (
unsigned)chan_num);
331 if (dest ==
nullptr || max_frames <= 0 ||
cfg.
channels <= 0)
return 0;
335 (frames_available < max_frames) ? frames_available : max_frames;
336 int frames_emitted = 0;
338 for (
int frame = 0; frame < frames_to_emit; ++frame) {
339 ADC_DATA_TYPE frame_data[NUM_ADC_CHANNELS];
342 LOGE(
"ADC reorder pop failed on channel index %d", ch);
344 return frames_emitted;
355 return frames_emitted;
369#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
371#elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
379 void cleanupAttachedRxPins() {
380 perimanSetBusDeinit(ESP32_BUS_TYPE_ADC_CONT, adcDetachBus);
384 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
385 if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
386 if (!perimanClearPinBus(io_pin)) {
387 LOGE(
"perimanClearPinBus failed!");
403 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
408 int16_t *data16 = (int16_t *)src;
409 uint8_t *data8 = (uint8_t *)src;
410 int samples = size_bytes / 2;
413 for (
int j = 0; j < samples; j++) {
414 data8[j] = (32768u + data16[j]) >> 8;
417 if (dac_continuous_write(
self->dac_handle, data8, samples, &result,
self->
cfg.
timeout) != ESP_OK) {
451 LOGE(
"ADC RX scratch buffer is not initialized");
455 const size_t frame_size_bytes =
457 const size_t frames_requested = size_bytes / frame_size_bytes;
458 if (frames_requested == 0) {
462 int16_t* result16 =
reinterpret_cast<int16_t*
>(dest);
463 int frames_provided =
466 while (frames_provided < (
int)frames_requested) {
467 uint32_t bytes_read = 0;
468 esp_err_t err = adc_continuous_read(
474 if (err != ESP_ERR_TIMEOUT) {
475 LOGE(
"adc_continuous_read unsuccessful: %d", err);
480 int samples_read = bytes_read /
sizeof(adc_digi_output_data_t);
481 if (samples_read <= 0) {
492 (int)frames_requested - frames_provided);
495 size_t bytes_provided = (size_t)frames_provided * frame_size_bytes;
499 return bytes_provided;
513 dac_continuous_config_t cont_cfg = {
514 .chan_mask = (dac_channel_mask_t)(
cfg.
channels == 1 ?
cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL),
515 .desc_num = (uint32_t)
cfg.buffer_count,
516 .buf_size = (size_t)
cfg.buffer_size,
517 .freq_hz = (uint32_t)
cfg.sample_rate,
519 .clk_src =
cfg.use_apll ? DAC_DIGI_CLK_SRC_APLL : DAC_DIGI_CLK_SRC_DEFAULT,
520 .chan_mode =
cfg.channels == 1 ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER,
523 if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
524 LOGE(
"new_channels");
527 if (dac_continuous_enable(dac_handle) != ESP_OK) {
535 LOGE(
"DAC not supported");
543 adc_channel_t adc_channel;
554 LOGE(
"adc unit %u continuous is already initialized. Please call end() first!",
cfg.
adc_unit);
565 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
566 if (!perimanClearPinBus(io_pin)) {
567 LOGE(
"perimanClearPinBus failed!");
573 uint32_t conv_frame_size = (uint32_t)
cfg.
buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
574 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
575 conv_frame_size = adcContinuousAlignFrameSize(conv_frame_size);
578 uint32_t rx_max_conv_frame_bytes = adcContinuousMaxConvFrameBytes();
579 uint32_t max_samples_per_frame = adcContinuousMaxResultsPerFrame();
580 if (conv_frame_size > rx_max_conv_frame_bytes) {
582 "buffer_size is too big for one ADC DMA frame: %u samples = %u "
583 "bytes, max %u samples / %u bytes",
585 (
unsigned)max_samples_per_frame,
586 (
unsigned)rx_max_conv_frame_bytes);
590 "RX DMA frame: %u conversion results, %u bytes (max %u results / "
593 (
unsigned)max_samples_per_frame,
594 (
unsigned)rx_max_conv_frame_bytes);
598 adc_continuous_handle_cfg_t adc_config;
600 adc_config.max_store_buf_size = (uint32_t)conv_frame_size * rx_frame_count;
601 adc_config.conv_frame_size = (uint32_t) conv_frame_size;
602#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
603 adc_config.flags.flush_pool =
true;
605 LOGI(
"RX pool: %u frames, %u bytes", (
unsigned)rx_frame_count,
606 (
unsigned)adc_config.max_store_buf_size);
607 err = adc_continuous_new_handle(&adc_config, &
adc_handle);
609 LOGE(
"adc_continuous_new_handle failed with error: %d", err);
612 LOGI(
"adc_continuous_new_handle successful");
616 adc_digi_pattern_config_t adc_pattern[
cfg.
channels] = {};
620 adc_pattern[i].channel = (uint8_t)ch;
626 adc_continuous_config_t dig_cfg = {
628 .adc_pattern = adc_pattern,
635 LOGI(
"dig_cfg.sample_freq_hz: %u", (
unsigned)dig_cfg.sample_freq_hz);
636 LOGI(
"dig_cfg.conv_mode: %u (1: unit 1, 2: unit 2, 3: both)", dig_cfg.conv_mode);
639 LOGI(
"dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
640 LOGI(
"dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
641 LOGI(
"dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
642 LOGI(
"dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
646 err = adc_continuous_config(
adc_handle, &dig_cfg);
648 LOGE(
"adc_continuous_config unsuccessful with error: %d", err);
652 LOGI(
"adc_continuous_config successful");
664 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
666 if (!perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (
void *)(
cfg.
adc_unit + 1),
cfg.
adc_unit, adc_channel)) {
667 LOGE(
"perimanSetPinBus to Continuous an ADC Unit %u failed!",
cfg.
adc_unit);
678 LOGE(
"adc_continuous_start unsuccessful with error: %d", err);
693 LOGE(
"Failed to allocate ADC RX scratch buffer");
697 LOGI(
"ADC RX scratch buffer allocated for %u bytes / %u samples",
708 LOGI(
"%d FIFO buffers allocated of size %u from DMA frame %u bytes",
709 cfg.
channels, (
unsigned)fifo_size, (
unsigned)conv_frame_size);
711 LOGI(
"Setup ADC successful");
720 if (dac_handle==
nullptr)
return true;
721 if (dac_continuous_disable(dac_handle) != ESP_OK){
723 LOGE(
"dac_continuous_disable failed");
725 if (dac_continuous_del_channels(dac_handle) != ESP_OK){
727 LOGE(
"dac_continuous_del_channels failed");
729 dac_handle =
nullptr;
736 static bool adcDetachBus(
void *bus) {
737 LOGD(
"===> adcDetachBus: %d", (
int) bus);
746 if (adc_continuous_stop(
adc_handle) != ESP_OK) {
747 LOGE(
"adc_continuous_stop failed");
753 if (adc_continuous_deinit(
adc_handle) != ESP_OK) {
754 LOGE(
"adc_continuous_deinit failed");
765 cleanupAttachedRxPins();
775 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
779 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
786 adc_channel_t adc_channel;
798 auto err = adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
800 LOGE(
"ADC channel %u is not available on ADC unit %u", adc_channel,
cfg.
adc_unit);
803 LOGI(
"ADC channel %u is on pin %u", adc_channel, io_pin);
814 LOGE(
"sample rate eff: %u can not be set, range: %u to %u", sample_rate,
818 LOGI(
"sample rate eff: %u, range: %u to %u", sample_rate,
826 int supported_bits = 16;
836 LOGE(
"bits per sample: error. It should be: %d but is %d",
853 esp_err_t err = ESP_OK;
860 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
862 adc_cali_curve_fitting_config_t cali_config;
866 err = adc_cali_create_scheme_curve_fitting(&cali_config, &
adc_cali_handle);
867 #elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
869 adc_cali_line_fitting_config_t cali_config;
873 err = adc_cali_create_scheme_line_fitting(&cali_config, &
adc_cali_handle);
878 LOGE(
"creating calibration handle failed for ADC%d with atten %d and bitwidth %d",
883 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 TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26