Skip to content

Commit

Permalink
Error handling, boundary check, type fixes, adc-serial (#1045)
Browse files Browse the repository at this point in the history
Merged my changes to data types in ESP32V1:
added more log information when setting up continuous ADC,
added setting of bits_per_sample based on adc_sample_width,
updated base-adc-serial.ino to include custom settings
  • Loading branch information
uutzinger authored Nov 9, 2023
1 parent 040eeb9 commit 2ac4a88
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 33 deletions.
29 changes: 25 additions & 4 deletions examples/examples-basic-api/base-adc-serial/base-adc-serial.ino
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,33 @@ ConverterScaler<int16_t> scaler(1.0, -26427, 32700 );

// Arduino Setup
void setup(void) {
delay(3000); // Give time to boot
Serial.begin(115200);
// Include logging to serial
AudioLogger::instance().begin(Serial, AudioLogger::Info); //Warning, Info
Serial.println("starting ADC...");
auto adcConfig = adc.defaultConfig(RX_MODE);
adcConfig.sample_rate = 44100;
// do not set bits_per_sample as that is configured based on adc_bit_with
adcConfig.adc_bit_width = 12; // this will result in 16 bits_per_sample
adc.begin(adcConfig);

// start i2s input with default configuration
Serial.println("starting I2S-ADC...");
adc.begin(adc.defaultConfig(RX_MODE));

// delay(100);
// if (adcConfig.rx_tx_mode == RX_MODE){
// Serial.println("Using RX Mode (ADC)");
// }
// else if (adcConfig.rx_tx_mode == TX_MODE) {
// Serial.println("Using TX Mode (DAC)");
// }
// Serial.printf("sample_rate is: %u\n", adcConfig.sample_rate);
// Serial.printf("bits_per_sample is: %u\n", adcConfig.bits_per_sample);
// Serial.printf("adc_attenuation is: %u\n", adcConfig.adc_attenuation);
// Serial.printf("adc_bit_width is: %u\n", adcConfig.adc_bit_width);
// Serial.printf("adc mode is: %u\n", adcConfig.adc_conversion_mode);
// Serial.printf("adc format is: %u\n", adcConfig.adc_output_type);
// for(int i=0; i<adcConfig.channels; i++) {
// Serial.printf("channel[%d] is on pin: %u\n", i, adcConfig.adc_channels[i]);
// }
}

// Arduino loop - repeated processing
Expand Down
76 changes: 61 additions & 15 deletions src/AudioAnalog/AnalogAudioESP32V1.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class AnalogDriverESP32V1 : public AnalogDriverBase {
return active;
}

/// stops the I2S and unistalls the driver
/// stops the I2S and uninstalls the driver
void end() override {
TRACEI();
#ifdef HAS_ESP32_DAC
Expand Down Expand Up @@ -194,24 +194,59 @@ class AnalogDriverESP32V1 : public AnalogDriverBase {
}
#endif


bool setup_rx(){
int max_channels = sizeof(cfg.adc_channels)/sizeof(adc_channel_t);
if (cfg.channels > max_channels ){
LOGE("channels: %d, max: %d", cfg.channels, max_channels);
return false;
}
} else {
LOGI("channels: %d, max: %d", cfg.channels, max_channels);

}
adc_continuous_handle_cfg_t adc_config = {
.max_store_buf_size = (uint32_t)cfg.buffer_size * cfg.buffer_count,
.conv_frame_size = (uint32_t)cfg.buffer_size / SOC_ADC_DIGI_DATA_BYTES_PER_CONV * SOC_ADC_DIGI_DATA_BYTES_PER_CONV,
};
adc_continuous_new_handle(&adc_config, &adc_handle);
esp_err_t err = adc_continuous_new_handle(&adc_config, &adc_handle);
if (err != ESP_OK){
LOGE("adc_continuous_new_handle failed with error: %d", err);
return false;
} else {
LOGI("adc_continuous_new_handle successful");
}

if ((cfg.sample_rate < SOC_ADC_SAMPLE_FREQ_THRES_LOW) || (cfg.sample_rate > SOC_ADC_SAMPLE_FREQ_THRES_HIGH)){
LOGE("sample rate: %u can not be set, range: %u to %u", SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
return false;
} else {
LOGI("sample rate: %u, range: %u to %u",cfg.sample_rate, SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
}

if ((cfg.adc_bit_width < SOC_ADC_DIGI_MIN_BITWIDTH) || (cfg.adc_bit_width > SOC_ADC_DIGI_MAX_BITWIDTH)){
LOGE("adc bit width: %u cannot be set, range: %u to %u", SOC_ADC_DIGI_MIN_BITWIDTH, SOC_ADC_DIGI_MAX_BITWIDTH);
return false;
} else {
LOGI("adc bit width: %u, range: %u to %u", cfg.adc_bit_width, SOC_ADC_DIGI_MIN_BITWIDTH, SOC_ADC_DIGI_MAX_BITWIDTH);
}

// adjust bits per sample based on adc bit width setting (multiple of 8)
if (cfg.adc_bit_width <= 8) {
cfg.bits_per_sample = 8;
} else if (cfg.adc_bit_width <= 16) {
cfg.bits_per_sample = 16;
} else if(cfg.adc_bit_width <= 24) {
cfg.bits_per_sample = 24;
} else if(cfg.adc_bit_width <= 32) {
cfg.bits_per_sample = 32;
} else {
cfg.bits_per_sample = 16;
}
LOGI("bits per sample: %d", cfg.bits_per_sample);

adc_continuous_config_t dig_cfg = {
.sample_freq_hz = (uint32_t)cfg.sample_rate,
.conv_mode = (adc_digi_convert_mode_t)cfg.adc_conversion_mode,
.format = (adc_digi_output_format_t)cfg.adc_output_type,
.sample_freq_hz = cfg.sample_rate,
.conv_mode = cfg.adc_conversion_mode,
.format = cfg.adc_output_type,
};
adc_digi_pattern_config_t adc_pattern[cfg.channels] = {0};
dig_cfg.pattern_num = cfg.channels;
Expand All @@ -222,22 +257,33 @@ class AnalogDriverESP32V1 : public AnalogDriverBase {
adc_pattern[i].channel = ch;
adc_pattern[i].unit = unit;
adc_pattern[i].bit_width = cfg.adc_bit_width;

LOGI("adc_pattern[%d].atten is :%x", i, adc_pattern[i].atten);
LOGI("adc_pattern[%d].channel is :%x", i, adc_pattern[i].channel);
LOGI("adc_pattern[%d].unit is :%x", i, adc_pattern[i].unit);
}
dig_cfg.adc_pattern = adc_pattern;
if (adc_continuous_config(adc_handle, &dig_cfg)!=ESP_OK){
LOGE("adc_continuous_config");

LOGI("dig_cfg.sample_freq_hz: %u", dig_cfg.sample_freq_hz);
LOGI("dig_cfg.conv_mode: %u", dig_cfg.conv_mode);
LOGI("dig_cfg.format: %u", dig_cfg.format);
for (int i = 0; i < cfg.channels; i++) {
LOGI("dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
LOGI("dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
LOGI("dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
LOGI("dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
}

err = adc_continuous_config(adc_handle, &dig_cfg);
if (err != ESP_OK){
LOGE("adc_continuous_config unsuccessful with error: %d", err);
return false;
}
LOGI("adc_continuous_config successful");

if (adc_continuous_start(adc_handle)!=ESP_OK){
LOGE("adc_continuous_start");
err = adc_continuous_start(adc_handle);
if(err != ESP_OK){
LOGE("adc_continuous_start unsuccessful with error: %d", err);
return false;
}

LOGI("adc_continuous_start successful");
return true;
}

Expand Down
18 changes: 11 additions & 7 deletions src/AudioAnalog/AnalogConfigESP32V1.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#define ADC_CHANNELS {ADC_CHANNEL_6, ADC_CHANNEL_7}
#define HAS_ESP32_DAC
#elif CONFIG_IDF_TARGET_ESP32S2
#define ADC_CONV_MODE ADC_CONV_BOTH_UNIT
#define ADC_CONV_MODE ADC_CONV_BOTH_UNIT // might only work with single unit
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
#define ADC_CHANNELS {ADC_CHANNEL_2, ADC_CHANNEL_3}
#define HAS_ESP32_DAC
Expand All @@ -20,7 +20,7 @@
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
#define ADC_CHANNELS {ADC_CHANNEL_2, ADC_CHANNEL_3}
#elif CONFIG_IDF_TARGET_ESP32S3
#define ADC_CONV_MODE ADC_CONV_BOTH_UNIT
#define ADC_CONV_MODE ADC_CONV_BOTH_UNIT // might only work with single unit
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
#define ADC_CHANNELS {ADC_CHANNEL_2, ADC_CHANNEL_3}
#endif
Expand Down Expand Up @@ -52,20 +52,24 @@ class AnalogConfigESP32V1 : public AudioInfo {
bool use_apll = false;

// public config parameters
int adc_conversion_mode = ADC_CONV_MODE;
int adc_output_type = ADC_OUTPUT_TYPE;
int adc_attenuation = ADC_ATTEN_DB_0;
int adc_bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
adc_digi_convert_mode_t adc_conversion_mode = ADC_CONV_MODE;
adc_digi_output_format_t adc_output_type = ADC_OUTPUT_TYPE;
uint8_t adc_attenuation = ADC_ATTEN_DB_0;
uint8_t adc_bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
uint32_t sample_rate = SOC_ADC_SAMPLE_FREQ_THRES_LOW;
/// ESP32: ADC_CHANNEL_6, ADC_CHANNEL_7; others ADC_CHANNEL_2, ADC_CHANNEL_3
adc_channel_t adc_channels[2] = ADC_CHANNELS;
uint32_t channels = 2;
int bits_per_sample = 16;

#ifdef HAS_ESP32_DAC
/// ESP32: DAC_CHANNEL_MASK_CH0 or DAC_CHANNEL_MASK_CH1
dac_channel_mask_t dac_mono_channel = DAC_CHANNEL_MASK_CH0;
#endif
/// Default constructor
AnalogConfigESP32V1(RxTxMode rxtxMode=TX_MODE) {
sample_rate = 44100;
bits_per_sample = 16;
adc_bit_width = 12;
channels = 2;
rx_tx_mode = rxtxMode;
if (rx_tx_mode == RX_MODE) {
Expand Down
15 changes: 8 additions & 7 deletions src/AudioTools/AudioTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ INLINE_VAR const char* TimeUnitStr[] {"MS","US","HZ"};
* @ingroup basic
*/
struct AudioInfo {

/// Sample Rate: e.g 44100
int sample_rate = DEFAULT_SAMPLE_RATE;
/// Number of channels: 2=stereo, 1=mono
int channels = DEFAULT_CHANNELS;
/// Number of bits per sample (int16_t = 16 bits)
int bits_per_sample = DEFAULT_BITS_PER_SAMPLE;

/// Default constructor
AudioInfo() = default;

Expand Down Expand Up @@ -100,13 +108,6 @@ struct AudioInfo {
//}
}

/// Sample Rate: e.g 44100
int sample_rate = DEFAULT_SAMPLE_RATE;
/// Number of channels: 2=stereo, 1=mono
int channels = DEFAULT_CHANNELS;
/// Number of bits per sample (int16_t = 16 bits)
int bits_per_sample = DEFAULT_BITS_PER_SAMPLE;

};

/**
Expand Down

0 comments on commit 2ac4a88

Please sign in to comment.