5#if (defined(ESP32) && defined(USE_ANALOG) && !USE_LEGACY_I2S)
8 #ifndef perimanClearPinBus
9 #define perimanClearPinBus(p) perimanSetPinBus(p, ESP32_BUS_TYPE_INIT, NULL)
87 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
95 size_t readBytes(uint8_t *dest,
size_t size_bytes)
override {
98 return io.readBytes(dest, size_bytes);
118 FIFO() : size_(0), buffer_(nullptr), head_(0), tail_(0), count_(0) {}
128 if (count_ < size_) {
129 buffer_[tail_] = value;
131 tail_ = (tail_ + 1) % size_;
142 value = buffer_[head_];
144 head_ = (head_ + 1) % size_;
162 return count_ == size_;
190 dac_continuous_handle_t dac_handle =
nullptr;
208 if (fifo_size < min_samples) {
209 min_samples = fifo_size;
212 return (
int)min_samples;
222 size_t fallback = 8U;
223 if (SOC_ADC_DIGI_RESULT_BYTES == 0)
return fallback;
225 size_t frame_results = conv_frame_bytes / SOC_ADC_DIGI_RESULT_BYTES;
226 if (frame_results == 0)
return fallback;
228 size_t frame_results_per_channel = frame_results / (size_t)
cfg.
channels;
229 if (frame_results_per_channel == 0)
return fallback;
231 return frame_results_per_channel + 4U;
262 uint32_t chan_num = sample.type2.channel;
263 if (chan_num >= SOC_ADC_CHANNEL_NUM(
cfg.
adc_unit)) {
264 LOGE(
"Invalid TYPE2 ADC channel: %u", (
unsigned)chan_num);
268#ifdef ADC_CONV_SINGLE_UNIT_1
270 sample.type2.unit != 0) {
271 LOGE(
"Invalid TYPE2 ADC unit for ADC1 mode: %u",
272 (
unsigned)sample.type2.unit);
276#ifdef ADC_CONV_SINGLE_UNIT_2
278 sample.type2.unit != 1) {
279 LOGE(
"Invalid TYPE2 ADC unit for ADC2 mode: %u",
280 (
unsigned)sample.type2.unit);
289 return static_cast<int16_t
>(data);
292 int data_milliVolts = 0;
296 LOGE(
"adc_cali_raw_to_voltage error: %d", err);
299 return static_cast<int16_t
>(data_milliVolts);
304 if (data ==
nullptr)
return false;
306 for (
int i = 0; i < samples_read; ++i) {
307 const adc_digi_output_data_t* sample = &data[i];
309 LOGE(
"ADC reorder resync on invalid TYPE2 record at sample %d", i);
314 ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(sample);
316 if (channel_idx < 0) {
317 LOGE(
"ADC reorder resync on invalid channel %u at sample %d",
318 (
unsigned)chan_num, i);
323 ADC_DATA_TYPE sample_value = AUDIO_ADC_GET_DATA(sample);
325 LOGE(
"ADC reorder FIFO overflow on channel index %d (channel %u)",
326 channel_idx, (
unsigned)chan_num);
335 if (dest ==
nullptr || max_frames <= 0 ||
cfg.
channels <= 0)
return 0;
339 (frames_available < max_frames) ? frames_available : max_frames;
340 int frames_emitted = 0;
342 for (
int frame = 0; frame < frames_to_emit; ++frame) {
343 ADC_DATA_TYPE frame_data[NUM_ADC_CHANNELS];
346 LOGE(
"ADC reorder pop failed on channel index %d", ch);
348 return frames_emitted;
359 return frames_emitted;
373#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
375#elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
383 void cleanupAttachedRxPins() {
384 perimanSetBusDeinit(ESP32_BUS_TYPE_ADC_CONT, adcDetachBus);
388 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
389 if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
390 if (!perimanClearPinBus(io_pin)) {
391 LOGE(
"perimanClearPinBus failed!");
407 size_t write(
const uint8_t *src,
size_t size_bytes)
override {
412 int16_t *data16 = (int16_t *)src;
413 uint8_t *data8 = (uint8_t *)src;
414 int samples = size_bytes / 2;
417 for (
int j = 0; j < samples; j++) {
418 data8[j] = (32768u + data16[j]) >> 8;
421 if (dac_continuous_write(
self->dac_handle, data8, samples, &result,
self->
cfg.
timeout) != ESP_OK) {
455 LOGE(
"ADC RX scratch buffer is not initialized");
459 const size_t frame_size_bytes =
461 const size_t frames_requested = size_bytes / frame_size_bytes;
462 if (frames_requested == 0) {
466 int16_t* result16 =
reinterpret_cast<int16_t*
>(dest);
467 int frames_provided =
470 while (frames_provided < (
int)frames_requested) {
471 uint32_t bytes_read = 0;
472 esp_err_t err = adc_continuous_read(
478 if (err != ESP_ERR_TIMEOUT) {
479 LOGE(
"adc_continuous_read unsuccessful: %d", err);
484 int samples_read = bytes_read /
sizeof(adc_digi_output_data_t);
485 if (samples_read <= 0) {
496 (int)frames_requested - frames_provided);
499 size_t bytes_provided = (size_t)frames_provided * frame_size_bytes;
503 return bytes_provided;
517 dac_continuous_config_t cont_cfg = {
518 .chan_mask =
cfg.
channels == 1 ?
cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL,
523 .clk_src =
cfg.use_apll ? DAC_DIGI_CLK_SRC_APLL : DAC_DIGI_CLK_SRC_DEFAULT,
524 .chan_mode =
cfg.channels == 1 ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER,
527 if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
528 LOGE(
"new_channels");
531 if (dac_continuous_enable(dac_handle) != ESP_OK) {
539 LOGE(
"DAC not supported");
547 adc_channel_t adc_channel;
558 LOGE(
"adc unit %u continuous is already initialized. Please call end() first!",
cfg.
adc_unit);
569 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
570 if (!perimanClearPinBus(io_pin)) {
571 LOGE(
"perimanClearPinBus failed!");
577 uint32_t conv_frame_size = (uint32_t)
cfg.
buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
578 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
579 conv_frame_size = adcContinuousAlignFrameSize(conv_frame_size);
582 uint32_t rx_max_conv_frame_bytes = adcContinuousMaxConvFrameBytes();
583 uint32_t max_samples_per_frame = adcContinuousMaxResultsPerFrame();
584 if (conv_frame_size > rx_max_conv_frame_bytes) {
586 "buffer_size is too big for one ADC DMA frame: %u samples = %u "
587 "bytes, max %u samples / %u bytes",
589 (
unsigned)max_samples_per_frame,
590 (
unsigned)rx_max_conv_frame_bytes);
594 "RX DMA frame: %u conversion results, %u bytes (max %u results / "
597 (
unsigned)max_samples_per_frame,
598 (
unsigned)rx_max_conv_frame_bytes);
602 adc_continuous_handle_cfg_t adc_config;
604 adc_config.max_store_buf_size = (uint32_t)conv_frame_size * rx_frame_count;
605 adc_config.conv_frame_size = (uint32_t) conv_frame_size;
606#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
607 adc_config.flags.flush_pool =
true;
609 LOGI(
"RX pool: %u frames, %u bytes", (
unsigned)rx_frame_count,
610 (
unsigned)adc_config.max_store_buf_size);
611 err = adc_continuous_new_handle(&adc_config, &
adc_handle);
613 LOGE(
"adc_continuous_new_handle failed with error: %d", err);
616 LOGI(
"adc_continuous_new_handle successful");
620 adc_digi_pattern_config_t adc_pattern[
cfg.
channels] = {};
624 adc_pattern[i].channel = (uint8_t)ch;
630 adc_continuous_config_t dig_cfg = {
632 .adc_pattern = adc_pattern,
639 LOGI(
"dig_cfg.sample_freq_hz: %u", (
unsigned)dig_cfg.sample_freq_hz);
640 LOGI(
"dig_cfg.conv_mode: %u (1: unit 1, 2: unit 2, 3: both)", dig_cfg.conv_mode);
643 LOGI(
"dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
644 LOGI(
"dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
645 LOGI(
"dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
646 LOGI(
"dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
650 err = adc_continuous_config(
adc_handle, &dig_cfg);
652 LOGE(
"adc_continuous_config unsuccessful with error: %d", err);
656 LOGI(
"adc_continuous_config successful");
668 adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
670 if (!perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (
void *)(
cfg.
adc_unit + 1),
cfg.
adc_unit, adc_channel)) {
671 LOGE(
"perimanSetPinBus to Continuous an ADC Unit %u failed!",
cfg.
adc_unit);
682 LOGE(
"adc_continuous_start unsuccessful with error: %d", err);
697 LOGE(
"Failed to allocate ADC RX scratch buffer");
701 LOGI(
"ADC RX scratch buffer allocated for %u bytes / %u samples",
712 LOGI(
"%d FIFO buffers allocated of size %u from DMA frame %u bytes",
713 cfg.
channels, (
unsigned)fifo_size, (
unsigned)conv_frame_size);
715 LOGI(
"Setup ADC successful");
724 if (dac_handle==
nullptr)
return true;
725 if (dac_continuous_disable(dac_handle) != ESP_OK){
727 LOGE(
"dac_continuous_disable failed");
729 if (dac_continuous_del_channels(dac_handle) != ESP_OK){
731 LOGE(
"dac_continuous_del_channels failed");
733 dac_handle =
nullptr;
740 static bool adcDetachBus(
void *bus) {
741 LOGD(
"===> adcDetachBus: %d", (
int) bus);
750 if (adc_continuous_stop(
adc_handle) != ESP_OK) {
751 LOGE(
"adc_continuous_stop failed");
757 if (adc_continuous_deinit(
adc_handle) != ESP_OK) {
758 LOGE(
"adc_continuous_deinit failed");
769 cleanupAttachedRxPins();
779 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
783 (
unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (
unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
790 adc_channel_t adc_channel;
802 auto err = adc_continuous_channel_to_io(
cfg.
adc_unit, adc_channel, &io_pin);
804 LOGE(
"ADC channel %u is not available on ADC unit %u", adc_channel,
cfg.
adc_unit);
807 LOGI(
"ADC channel %u is on pin %u", adc_channel, io_pin);
816 if ((sample_rate < SOC_ADC_SAMPLE_FREQ_THRES_LOW) ||
817 (sample_rate > SOC_ADC_SAMPLE_FREQ_THRES_HIGH)) {
818 LOGE(
"sample rate eff: %u can not be set, range: %u to %u", sample_rate,
819 SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
822 LOGI(
"sample rate eff: %u, range: %u to %u", sample_rate,
823 SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
830 int supported_bits = 16;
840 LOGE(
"bits per sample: error. It should be: %d but is %d",
857 esp_err_t err = ESP_OK;
864 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
866 adc_cali_curve_fitting_config_t cali_config;
870 err = adc_cali_create_scheme_curve_fitting(&cali_config, &
adc_cali_handle);
871 #elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
873 adc_cali_line_fitting_config_t cali_config;
877 err = adc_cali_create_scheme_line_fitting(&cali_config, &
adc_cali_handle);
882 LOGE(
"creating calibration handle failed for ADC%d with atten %d and bitwidth %d",
887 LOGI(
"enabled calibration for ADC%d with atten %d and bitwidth %d",
#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