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 if (chan_num >= SOC_ADC_CHANNEL_NUM(
cfg.
adc_unit)) {
258 LOGE(
"Invalid TYPE2 ADC channel: %u", (
unsigned)chan_num);
262#ifdef ADC_CONV_SINGLE_UNIT_1
264 sample.type2.unit != 0) {
265 LOGE(
"Invalid TYPE2 ADC unit for ADC1 mode: %u",
266 (
unsigned)sample.type2.unit);
270#ifdef ADC_CONV_SINGLE_UNIT_2
272 sample.type2.unit != 1) {
273 LOGE(
"Invalid TYPE2 ADC unit for ADC2 mode: %u",
274 (
unsigned)sample.type2.unit);
283 return static_cast<int16_t
>(data);
286 int data_milliVolts = 0;
290 LOGE(
"adc_cali_raw_to_voltage error: %d", err);
293 return static_cast<int16_t
>(data_milliVolts);
298 if (data ==
nullptr)
return false;
300 for (
int i = 0; i < samples_read; ++i) {
301 const adc_digi_output_data_t* sample = &data[i];
303 LOGE(
"ADC reorder resync on invalid TYPE2 record at sample %d", i);
308 ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(sample);
310 if (channel_idx < 0) {
311 LOGE(
"ADC reorder resync on invalid channel %u at sample %d",
312 (
unsigned)chan_num, i);
317 ADC_DATA_TYPE sample_value = AUDIO_ADC_GET_DATA(sample);
319 LOGE(
"ADC reorder FIFO overflow on channel index %d (channel %u)",
320 channel_idx, (
unsigned)chan_num);
329 if (dest ==
nullptr || max_frames <= 0 ||
cfg.
channels <= 0)
return 0;
333 (frames_available < max_frames) ? frames_available : max_frames;
334 int frames_emitted = 0;
336 for (
int frame = 0; frame < frames_to_emit; ++frame) {
337 ADC_DATA_TYPE frame_data[NUM_ADC_CHANNELS];
340 LOGE(
"ADC reorder pop failed on channel index %d", ch);
342 return frames_emitted;
353 return frames_emitted;
367#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
369#elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
377 void cleanupAttachedRxPins() {
378 perimanSetBusDeinit(ESP32_BUS_TYPE_ADC_CONT, adcDetachBus);
382 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
383 if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
384 if (!perimanClearPinBus(io_pin)) {
385 LOGE(
"perimanClearPinBus failed!");
401 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
406 int16_t *data16 = (int16_t *)src;
407 uint8_t *data8 = (uint8_t *)src;
408 int samples = size_bytes / 2;
411 for (
int j = 0; j < samples; j++) {
412 data8[j] = (32768u + data16[j]) >> 8;
415 if (dac_continuous_write(
self->dac_handle, data8, samples, &result,
self->
cfg.
timeout) != ESP_OK) {
449 LOGE(
"ADC RX scratch buffer is not initialized");
453 const size_t frame_size_bytes =
455 const size_t frames_requested = size_bytes / frame_size_bytes;
456 if (frames_requested == 0) {
460 int16_t* result16 =
reinterpret_cast<int16_t*
>(dest);
461 int frames_provided =
464 while (frames_provided < (
int)frames_requested) {
465 uint32_t bytes_read = 0;
466 esp_err_t err = adc_continuous_read(
472 if (err != ESP_ERR_TIMEOUT) {
473 LOGE(
"adc_continuous_read unsuccessful: %d", err);
478 int samples_read = bytes_read /
sizeof(adc_digi_output_data_t);
479 if (samples_read <= 0) {
490 (int)frames_requested - frames_provided);
493 size_t bytes_provided = (size_t)frames_provided * frame_size_bytes;
497 return bytes_provided;
511 dac_continuous_config_t cont_cfg = {
512 .chan_mask =
cfg.
channels == 1 ?
cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL,
517 .clk_src =
cfg.use_apll ? DAC_DIGI_CLK_SRC_APLL : DAC_DIGI_CLK_SRC_DEFAULT,
518 .chan_mode =
cfg.channels == 1 ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER,
521 if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
522 LOGE(
"new_channels");
525 if (dac_continuous_enable(dac_handle) != ESP_OK) {
533 LOGE(
"DAC not supported");
541 adc_channel_t adc_channel;
552 LOGE(
"adc unit %u continuous is already initialized. Please call end() first!",
cfg.
adc_unit);
563 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
564 if (!perimanClearPinBus(io_pin)) {
565 LOGE(
"perimanClearPinBus failed!");
571 uint32_t conv_frame_size = (uint32_t)
cfg.
buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
572 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
573 conv_frame_size = adcContinuousAlignFrameSize(conv_frame_size);
576 uint32_t rx_max_conv_frame_bytes = adcContinuousMaxConvFrameBytes();
577 uint32_t max_samples_per_frame = adcContinuousMaxResultsPerFrame();
578 if (conv_frame_size > rx_max_conv_frame_bytes) {
580 "buffer_size is too big for one ADC DMA frame: %u samples = %u "
581 "bytes, max %u samples / %u bytes",
583 (
unsigned)max_samples_per_frame,
584 (
unsigned)rx_max_conv_frame_bytes);
588 "RX DMA frame: %u conversion results, %u bytes (max %u results / "
591 (
unsigned)max_samples_per_frame,
592 (
unsigned)rx_max_conv_frame_bytes);
596 adc_continuous_handle_cfg_t adc_config;
598 adc_config.max_store_buf_size = (uint32_t)conv_frame_size * rx_frame_count;
599 adc_config.conv_frame_size = (uint32_t) conv_frame_size;
600#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
601 adc_config.flags.flush_pool =
true;
603 LOGI(
"RX pool: %u frames, %u bytes", (
unsigned)rx_frame_count,
604 (
unsigned)adc_config.max_store_buf_size);
605 err = adc_continuous_new_handle(&adc_config, &
adc_handle);
607 LOGE(
"adc_continuous_new_handle failed with error: %d", err);
610 LOGI(
"adc_continuous_new_handle successful");
614 adc_digi_pattern_config_t adc_pattern[
cfg.
channels] = {};
618 adc_pattern[i].channel = (uint8_t)ch;
624 adc_continuous_config_t dig_cfg = {
626 .adc_pattern = adc_pattern,
633 LOGI(
"dig_cfg.sample_freq_hz: %u", (
unsigned)dig_cfg.sample_freq_hz);
634 LOGI(
"dig_cfg.conv_mode: %u (1: unit 1, 2: unit 2, 3: both)", dig_cfg.conv_mode);
637 LOGI(
"dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
638 LOGI(
"dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
639 LOGI(
"dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
640 LOGI(
"dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
644 err = adc_continuous_config(
adc_handle, &dig_cfg);
646 LOGE(
"adc_continuous_config unsuccessful with error: %d", err);
650 LOGI(
"adc_continuous_config successful");
662 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
664 if (!perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (
void *)(
cfg.
adc_unit + 1),
cfg.
adc_unit, adc_channel)) {
665 LOGE(
"perimanSetPinBus to Continuous an ADC Unit %u failed!",
cfg.
adc_unit);
676 LOGE(
"adc_continuous_start unsuccessful with error: %d", err);
691 LOGE(
"Failed to allocate ADC RX scratch buffer");
695 LOGI(
"ADC RX scratch buffer allocated for %u bytes / %u samples",
706 LOGI(
"%d FIFO buffers allocated of size %u from DMA frame %u bytes",
707 cfg.
channels, (
unsigned)fifo_size, (
unsigned)conv_frame_size);
709 LOGI(
"Setup ADC successful");
718 if (dac_handle==
nullptr)
return true;
719 if (dac_continuous_disable(dac_handle) != ESP_OK){
721 LOGE(
"dac_continuous_disable failed");
723 if (dac_continuous_del_channels(dac_handle) != ESP_OK){
725 LOGE(
"dac_continuous_del_channels failed");
727 dac_handle =
nullptr;
734 static bool adcDetachBus(
void *bus) {
735 LOGD(
"===> adcDetachBus: %d", (
int) bus);
744 if (adc_continuous_stop(
adc_handle) != ESP_OK) {
745 LOGE(
"adc_continuous_stop failed");
751 if (adc_continuous_deinit(
adc_handle) != ESP_OK) {
752 LOGE(
"adc_continuous_deinit failed");
763 cleanupAttachedRxPins();
773 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
777 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
784 adc_channel_t adc_channel;
796 auto err = adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
798 LOGE(
"ADC channel %u is not available on ADC unit %u", adc_channel,
cfg.
adc_unit);
801 LOGI(
"ADC channel %u is on pin %u", adc_channel, io_pin);
812 LOGE(
"sample rate eff: %u can not be set, range: %u to %u", sample_rate,
816 LOGI(
"sample rate eff: %u, range: %u to %u", sample_rate,
824 int supported_bits = 16;
834 LOGE(
"bits per sample: error. It should be: %d but is %d",
851 esp_err_t err = ESP_OK;
858 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
860 adc_cali_curve_fitting_config_t cali_config;
864 err = adc_cali_create_scheme_curve_fitting(&cali_config, &
adc_cali_handle);
865 #elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
867 adc_cali_line_fitting_config_t cali_config;
871 err = adc_cali_create_scheme_line_fitting(&cali_config, &
adc_cali_handle);
876 LOGE(
"creating calibration handle failed for ADC%d with atten %d and bitwidth %d",
881 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