diff --git a/_analog_driver_e_s_p32_v1_8h_source.html b/_analog_driver_e_s_p32_v1_8h_source.html index 8a3444a30..902e44cc3 100644 --- a/_analog_driver_e_s_p32_v1_8h_source.html +++ b/_analog_driver_e_s_p32_v1_8h_source.html @@ -98,7 +98,7 @@
36  }
37 
40  bool begin(AnalogConfigESP32V1 cfg) {
-
41  // TRACEI();
+
41  TRACEI();
42  bool result = true;
43  this->cfg = cfg;
44 
@@ -126,714 +126,727 @@
66  }
67 
70  void end() override {
-
71  // TRACEI();
-
72  #ifdef HAS_ESP32_DAC
-
73  if (active_tx) {
-
74  dac_continuous_del_channels(dac_handle);
-
75  }
-
76  #endif
-
77  if (active_rx) {
-
78  cleanup_rx();
-
79  }
+
71  TRACEI();
+
72  if (active_tx) {
+
73  cleanup_tx();
+
74  }
+
75  if (active_rx) {
+
76  cleanup_rx();
+
77  }
+
78 
+
79  converter.end();
80 
-
81  converter.end();
-
82 
-
83  active_tx = false;
-
84  active_rx = false;
-
85  active = false;
-
86  }
-
87 
-
88  // Writes the data to the Digital to Analog Converter
-
89  // ----------------------------------------------------------
-
90  size_t write(const uint8_t *src, size_t size_bytes) override {
-
91  // TRACED();
-
92  // convert any format to int16_t
-
93  return converter.write(src, size_bytes);
-
94  }
-
95 
-
96  // Reads data from DMA buffer of the Analog to Digital Converter
-
97  // ----------------------------------------------------------
-
98  size_t readBytes(uint8_t *dest, size_t size_bytes) override {
-
99  // TRACED();
-
100  // Use the IO16Bit class for reading
-
101  return io.readBytes(dest, size_bytes);
-
102  }
-
103 
-
104  // How much data will there be available after reading ADC buffer
-
105  // ----------------------------------------------------------
-
106  int available() override {
-
107  return active_rx ? (uint32_t)(cfg.buffer_size * sizeof(int16_t)) : 0;
-
108  }
+
81  active_tx = false;
+
82  active_rx = false;
+
83  active = false;
+
84  }
+
85 
+
86  // Writes the data to the Digital to Analog Converter
+
87  // ----------------------------------------------------------
+
88  size_t write(const uint8_t *src, size_t size_bytes) override {
+
89  // TRACED();
+
90  // convert any format to int16_t
+
91  return converter.write(src, size_bytes);
+
92  }
+
93 
+
94  // Reads data from DMA buffer of the Analog to Digital Converter
+
95  // ----------------------------------------------------------
+
96  size_t readBytes(uint8_t *dest, size_t size_bytes) override {
+
97  // TRACED();
+
98  // Use the IO16Bit class for reading
+
99  return io.readBytes(dest, size_bytes);
+
100  }
+
101 
+
102  // How much data will there be available after reading ADC buffer
+
103  // ----------------------------------------------------------
+
104  int available() override {
+
105  return active_rx ? (uint32_t)(cfg.buffer_size * sizeof(int16_t)) : 0;
+
106  }
+
107 
+
108 protected:
109 
-
110 protected:
-
111 
-
115  template<typename T>
-
116  class FIFO {
-
117  public:
-
118 
-
119  FIFO() : size_(0), buffer_(nullptr), head_(0), tail_(0), count_(0) {}
+
113  template<typename T>
+
114  class FIFO {
+
115  public:
+
116 
+
117  FIFO() : size_(0), buffer_(nullptr), head_(0), tail_(0), count_(0) {}
+
118 
+
119  FIFO(size_t size) : size_(size), buffer_(new T[size]), head_(0), tail_(0), count_(0) {}
120 
-
121  FIFO(size_t size) : size_(size), buffer_(new T[size]), head_(0), tail_(0), count_(0) {}
-
122 
-
123  ~FIFO() {
-
124  delete[] buffer_;
-
125  //LOGD("FIFO destroyed: size: %d, count: %d", size_, count_);
-
126  }
-
127 
-
128  bool push(const T& value) {
-
129  if (count_ < size_) {
-
130  buffer_[tail_] = value;
-
131  //LOGD("FIFO push - Value: %d at location: %d", value, tail_);
-
132  tail_ = (tail_ + 1) % size_;
-
133  count_++;
-
134  //LOGD("FIFO push updated tail: %d, count: %d", tail_, count_);
-
135  return true;
-
136  }
-
137  //LOGD("FIFO push failed - count %d > size %d", value, count_, size_);
-
138  return false; // Buffer full
-
139  }
-
140 
-
141  bool pop(T& value) {
-
142  if (count_ > 0) {
-
143  value = buffer_[head_];
-
144  //LOGD("FIFO pop - Value: %d at location: %d", value, head_);
-
145  head_ = (head_ + 1) % size_;
-
146  count_--;
-
147  //LOGD("FIFO pop updated head: %d, count: %d", head_, count_);
-
148  return true;
-
149  }
-
150  //LOGD("FIFO pop failed - count %d == 0", count_);
-
151  return false; // Buffer empty
-
152  }
-
153 
-
154  size_t size() const {
-
155  return count_;
-
156  }
-
157 
-
158  bool empty() const {
-
159  return count_ == 0;
-
160  }
-
161 
-
162  bool full() const {
-
163  return count_ == size_;
-
164  }
-
165 
-
166  void clear() const {
-
167  head_ = 0;
-
168  tail_ = 0;
-
169  count_ = 0;
-
170  }
-
171 
-
172  private:
-
173  size_t size_;
-
174  T* buffer_;
-
175  size_t head_;
-
176  size_t tail_;
-
177  size_t count_;
-
178  };
-
179 
-
180  adc_continuous_handle_t adc_handle = nullptr;
-
181  adc_cali_handle_t adc_cali_handle = nullptr;
-
182  AnalogConfigESP32V1 cfg;
-
183  bool active = false;
-
184  bool active_tx = false;
-
185  bool active_rx = false;
-
186  ConverterAutoCenter auto_center;
-
187  #ifdef HAS_ESP32_DAC
-
188  dac_continuous_handle_t dac_handle;
-
189  #endif
-
190 
-
191  // create array of FIFO buffers, one for each channel
-
192  FIFO<ADC_DATA_TYPE>** fifo_buffers;
-
193 
-
194  // 16Bit Audiostream for ESP32
-
195  // ----------------------------------------------------------
-
196  class IO16Bit : public AudioStream {
-
197  public:
-
198  IO16Bit(AnalogDriverESP32V1 *driver) { self = driver; }
-
199 
-
200  // Write int16_t data to the Digital to Analog Converter
-
201  // ----------------------------------------------------------
-
202  size_t write(const uint8_t *src, size_t size_bytes) override {
-
203  // TRACED();
-
204  #ifdef HAS_ESP32_DAC
-
205  size_t result = 0;
-
206  // Convert signed 16-bit to unsigned 8-bit
-
207  int16_t *data16 = (int16_t *)src;
-
208  uint8_t *data8 = (uint8_t *)src;
-
209  int samples = size_bytes / 2;
-
210 
-
211  // Process data in batches to reduce the number of conversions and writes
-
212  for (int j = 0; j < samples; j++) {
-
213  data8[j] = (32768u + data16[j]) >> 8;
-
214  }
-
215 
-
216  if (dac_continuous_write(self->dac_handle, data8, samples, &result, self->cfg.timeout) != ESP_OK) {
-
217  result = 0;
-
218  }
-
219  return result * 2;
-
220  #else
-
221  return 0;
-
222  #endif
-
223  }
-
224 
-
225  // Read int16_t data from Analog to Digital Converter
-
226  // ----------------------------------------------------------
-
227  // FYI
-
228  // typedef struct {
-
229  // union {
-
230  // struct {
-
231  // uint16_t data: 12; /*!<ADC real output data info. Resolution: 12 bit. */
-
232  // uint16_t channel: 4; /*!<ADC channel index info. */
-
233  // } type1; /*!<ADC type1 */
-
234  // struct {
-
235  // uint16_t data: 11; /*!<ADC real output data info. Resolution: 11 bit. */
-
236  // uint16_t channel: 4; /*!<ADC channel index info. For ESP32-S2:
-
237  // If (channel < ADC_CHANNEL_MAX), The data is valid.
-
238  // If (channel > ADC_CHANNEL_MAX), The data is invalid. */
-
239  // uint16_t unit: 1; /*!<ADC unit index info. 0: ADC1; 1: ADC2. */
-
240  // } type2; /*!<When the configured output format is 11bit.*/
-
241  // uint16_t val; /*!<Raw data value */
-
242  // };
-
243  // } adc_digi_output_data_t;
-
244 
-
245  size_t readBytes(uint8_t *dest, size_t size_bytes) {
-
246  // TRACED();
-
247 
-
248  size_t total_bytes = 0;
-
249  size_t bytes_provided = 0;
-
250  int min_samples_in_fifo_per_channel = 0;
-
251  int max_samples_in_fifo_per_channel = 0;
-
252  int samples_read =0;
-
253  int fifo_size = 0;
-
254  int idx = -1;
-
255  int samples_provided_per_channel = 0;
-
256  int data_milliVolts = 0;
-
257 
-
258  int samples_requested = size_bytes / sizeof(int16_t);
-
259  int samples_requested_per_channel = samples_requested/self->cfg.channels;
-
260  // for the adc_continuous_read function
-
261  adc_digi_output_data_t* result_data = (adc_digi_output_data_t*)malloc(samples_requested * sizeof(adc_digi_output_data_t));
-
262  if (result_data == NULL) {
-
263  LOGE("Failed to allocate memory for result_data");
-
264  return 0; // Handle memory allocation failure
-
265  }
-
266  memset(result_data, 0, samples_requested * sizeof(adc_digi_output_data_t));
-
267  uint32_t bytes_read; // bytes from ADC buffer read
-
268 
-
269  // for output buffer
-
270  uint16_t *result16 = (uint16_t *)dest; // pointer to the destination buffer
-
271  uint16_t *end = (uint16_t *)(dest + size_bytes); // pointer to the end of the destination buffer
+
121  ~FIFO() {
+
122  delete[] buffer_;
+
123  //LOGD("FIFO destroyed: size: %d, count: %d", size_, count_);
+
124  }
+
125 
+
126  bool push(const T& value) {
+
127  if (count_ < size_) {
+
128  buffer_[tail_] = value;
+
129  //LOGD("FIFO push - Value: %d at location: %d", value, tail_);
+
130  tail_ = (tail_ + 1) % size_;
+
131  count_++;
+
132  //LOGD("FIFO push updated tail: %d, count: %d", tail_, count_);
+
133  return true;
+
134  }
+
135  //LOGD("FIFO push failed - count %d > size %d", value, count_, size_);
+
136  return false; // Buffer full
+
137  }
+
138 
+
139  bool pop(T& value) {
+
140  if (count_ > 0) {
+
141  value = buffer_[head_];
+
142  //LOGD("FIFO pop - Value: %d at location: %d", value, head_);
+
143  head_ = (head_ + 1) % size_;
+
144  count_--;
+
145  //LOGD("FIFO pop updated head: %d, count: %d", head_, count_);
+
146  return true;
+
147  }
+
148  //LOGD("FIFO pop failed - count %d == 0", count_);
+
149  return false; // Buffer empty
+
150  }
+
151 
+
152  size_t size() const {
+
153  return count_;
+
154  }
+
155 
+
156  bool empty() const {
+
157  return count_ == 0;
+
158  }
+
159 
+
160  bool full() const {
+
161  return count_ == size_;
+
162  }
+
163 
+
164  void clear() const {
+
165  head_ = 0;
+
166  tail_ = 0;
+
167  count_ = 0;
+
168  }
+
169 
+
170  private:
+
171  size_t size_;
+
172  T* buffer_;
+
173  size_t head_;
+
174  size_t tail_;
+
175  size_t count_;
+
176  };
+
177 
+
178  adc_continuous_handle_t adc_handle = nullptr;
+
179  adc_cali_handle_t adc_cali_handle = nullptr;
+
180  AnalogConfigESP32V1 cfg;
+
181  bool active = false;
+
182  bool active_tx = false;
+
183  bool active_rx = false;
+
184  ConverterAutoCenter auto_center;
+
185  #ifdef HAS_ESP32_DAC
+
186  dac_continuous_handle_t dac_handle;
+
187  #endif
+
188 
+
189  // create array of FIFO buffers, one for each channel
+
190  FIFO<ADC_DATA_TYPE>** fifo_buffers;
+
191 
+
192  // 16Bit Audiostream for ESP32
+
193  // ----------------------------------------------------------
+
194  class IO16Bit : public AudioStream {
+
195  public:
+
196  IO16Bit(AnalogDriverESP32V1 *driver) { self = driver; }
+
197 
+
198  // Write int16_t data to the Digital to Analog Converter
+
199  // ----------------------------------------------------------
+
200  size_t write(const uint8_t *src, size_t size_bytes) override {
+
201  // TRACED();
+
202  #ifdef HAS_ESP32_DAC
+
203  size_t result = 0;
+
204  // Convert signed 16-bit to unsigned 8-bit
+
205  int16_t *data16 = (int16_t *)src;
+
206  uint8_t *data8 = (uint8_t *)src;
+
207  int samples = size_bytes / 2;
+
208 
+
209  // Process data in batches to reduce the number of conversions and writes
+
210  for (int j = 0; j < samples; j++) {
+
211  data8[j] = (32768u + data16[j]) >> 8;
+
212  }
+
213 
+
214  if (dac_continuous_write(self->dac_handle, data8, samples, &result, self->cfg.timeout) != ESP_OK) {
+
215  result = 0;
+
216  }
+
217  return result * 2;
+
218  #else
+
219  return 0;
+
220  #endif
+
221  }
+
222 
+
223  // Read int16_t data from Analog to Digital Converter
+
224  // ----------------------------------------------------------
+
225  // FYI
+
226  // typedef struct {
+
227  // union {
+
228  // struct {
+
229  // uint16_t data: 12; /*!<ADC real output data info. Resolution: 12 bit. */
+
230  // uint16_t channel: 4; /*!<ADC channel index info. */
+
231  // } type1; /*!<ADC type1 */
+
232  // struct {
+
233  // uint16_t data: 11; /*!<ADC real output data info. Resolution: 11 bit. */
+
234  // uint16_t channel: 4; /*!<ADC channel index info. For ESP32-S2:
+
235  // If (channel < ADC_CHANNEL_MAX), The data is valid.
+
236  // If (channel > ADC_CHANNEL_MAX), The data is invalid. */
+
237  // uint16_t unit: 1; /*!<ADC unit index info. 0: ADC1; 1: ADC2. */
+
238  // } type2; /*!<When the configured output format is 11bit.*/
+
239  // uint16_t val; /*!<Raw data value */
+
240  // };
+
241  // } adc_digi_output_data_t;
+
242 
+
243  size_t readBytes(uint8_t *dest, size_t size_bytes) {
+
244  // TRACED();
+
245 
+
246  size_t total_bytes = 0;
+
247  size_t bytes_provided = 0;
+
248  int min_samples_in_fifo_per_channel = 0;
+
249  int max_samples_in_fifo_per_channel = 0;
+
250  int samples_read =0;
+
251  int fifo_size = 0;
+
252  int idx = -1;
+
253  int samples_provided_per_channel = 0;
+
254  int data_milliVolts = 0;
+
255 
+
256  int samples_requested = size_bytes / sizeof(int16_t);
+
257  int samples_requested_per_channel = samples_requested/self->cfg.channels;
+
258  // for the adc_continuous_read function
+
259  adc_digi_output_data_t* result_data = (adc_digi_output_data_t*)malloc(samples_requested * sizeof(adc_digi_output_data_t));
+
260  if (result_data == NULL) {
+
261  LOGE("Failed to allocate memory for result_data");
+
262  return 0; // Handle memory allocation failure
+
263  }
+
264  memset(result_data, 0, samples_requested * sizeof(adc_digi_output_data_t));
+
265  uint32_t bytes_read; // bytes from ADC buffer read
+
266 
+
267  // for output buffer
+
268  uint16_t *result16 = (uint16_t *)dest; // pointer to the destination buffer
+
269  uint16_t *end = (uint16_t *)(dest + size_bytes); // pointer to the end of the destination buffer
+
270 
+
271 
272 
-
273 
-
274 
-
275  // 1) read the requested bytes from the buffer
-
276  // LOGI("adc_continuous_read request:%d samples %d bytes requested", samples_requested, (uint32_t)(samples_requested * sizeof(adc_digi_output_data_t)));
-
277  if (adc_continuous_read(self->adc_handle, (uint8_t *)result_data, (uint32_t)(samples_requested * sizeof(adc_digi_output_data_t)), &bytes_read, (uint32_t)self->cfg.timeout) == ESP_OK) {
-
278  samples_read = bytes_read / sizeof(adc_digi_output_data_t);
-
279  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)));
-
280 
-
281  // Parse and store data in FIFO buffers
-
282  for (int i = 0; i < samples_read; i++) {
-
283  adc_digi_output_data_t *p = &result_data[i];
-
284  ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(p);
-
285  ADC_DATA_TYPE data = AUDIO_ADC_GET_DATA(p);
-
286 
-
287  // Find the index of the channel in the configured channels
-
288  idx = -1;
-
289  for (int j = 0; j < self->cfg.channels; ++j) {
-
290  if (self->cfg.adc_channels[j] == chan_num) {
-
291  idx = j;
-
292  break;
-
293  }
-
294  }
-
295  // Push the data to the corresponding FIFO buffer
-
296  if (idx >= 0) {
-
297  if (self->fifo_buffers[idx]->push(data)) {
-
298  LOGD("Sample %d, FIFO %d, ch %u, d %u", i, idx, chan_num, data);
-
299  } else {
-
300  LOGE("Sample %d, FIFO buffer is full, ch %u, d %u", i, (unsigned)chan_num, data);
-
301  }
-
302  } else {
-
303  LOGE("Sample %d, ch %u not found in configuration, d: %u", i, (unsigned)chan_num, data);
-
304  for (int k = 0; k < self->cfg.channels; ++k) {
-
305  LOGE("Available config ch: %u", self->cfg.adc_channels[k]);
-
306  }
-
307  }
+
273  // 1) read the requested bytes from the buffer
+
274  // LOGI("adc_continuous_read request:%d samples %d bytes requested", samples_requested, (uint32_t)(samples_requested * sizeof(adc_digi_output_data_t)));
+
275  if (adc_continuous_read(self->adc_handle, (uint8_t *)result_data, (uint32_t)(samples_requested * sizeof(adc_digi_output_data_t)), &bytes_read, (uint32_t)self->cfg.timeout) == ESP_OK) {
+
276  samples_read = bytes_read / sizeof(adc_digi_output_data_t);
+
277  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)));
+
278 
+
279  // Parse and store data in FIFO buffers
+
280  for (int i = 0; i < samples_read; i++) {
+
281  adc_digi_output_data_t *p = &result_data[i];
+
282  ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(p);
+
283  ADC_DATA_TYPE data = AUDIO_ADC_GET_DATA(p);
+
284 
+
285  // Find the index of the channel in the configured channels
+
286  idx = -1;
+
287  for (int j = 0; j < self->cfg.channels; ++j) {
+
288  if (self->cfg.adc_channels[j] == chan_num) {
+
289  idx = j;
+
290  break;
+
291  }
+
292  }
+
293  // Push the data to the corresponding FIFO buffer
+
294  if (idx >= 0) {
+
295  if (self->fifo_buffers[idx]->push(data)) {
+
296  LOGD("Sample %d, FIFO %d, ch %u, d %u", i, idx, chan_num, data);
+
297  } else {
+
298  LOGE("Sample %d, FIFO buffer is full, ch %u, d %u", i, (unsigned)chan_num, data);
+
299  }
+
300  } else {
+
301  LOGE("Sample %d, ch %u not found in configuration, d: %u", i, (unsigned)chan_num, data);
+
302  for (int k = 0; k < self->cfg.channels; ++k) {
+
303  LOGE("Available config ch: %u", self->cfg.adc_channels[k]);
+
304  }
+
305  }
+
306 
+
307  }
308 
-
309  }
-
310 
-
311  // Determine min number of samples from all FIFO buffers
-
312  min_samples_in_fifo_per_channel = self->fifo_buffers[0]->size();
-
313  for (int i = 1; i < self->cfg.channels; i++) {
-
314  fifo_size = self->fifo_buffers[i]->size();
-
315  if (fifo_size < min_samples_in_fifo_per_channel) {
-
316  min_samples_in_fifo_per_channel = fifo_size;
-
317  }
-
318  }
-
319 
-
320  // 2) If necessary, top off the FIFO buffers to return the requested number of bytes
-
321  while (samples_requested_per_channel > min_samples_in_fifo_per_channel) {
-
322 
-
323  // obtain two extra sets of data (2 because number of bytes requested from ADC buffer needs to be divisible by 4)
-
324  // LOGI("adc_continuous_read request:%d samples %d bytes requested", samples_requested, (uint32_t)(samples_requested * sizeof(adc_digi_output_data_t)));
-
325  if (adc_continuous_read(self->adc_handle, (uint8_t *)result_data, (uint32_t)(2*self->cfg.channels * sizeof(adc_digi_output_data_t)), &bytes_read, (uint32_t)self->cfg.timeout) != ESP_OK) {
-
326  LOGE("Top off, adc_continuous_read unsuccessful");
-
327  break;
-
328  }
-
329 
-
330  // Parse the additional data
-
331  samples_read = bytes_read / sizeof(adc_digi_output_data_t);
-
332  LOGD("Top Off: Requested %d samples per Channel, Min samples in FIFO: %d, Read additional %d bytes / %d samples", samples_requested_per_channel, min_samples_in_fifo_per_channel, (unsigned)bytes_read, samples_read);
-
333 
-
334  for (int i = 0; i < samples_read; i++) {
-
335  adc_digi_output_data_t *p = &result_data[i];
-
336  ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(p);
-
337  ADC_DATA_TYPE data = AUDIO_ADC_GET_DATA(p);
-
338 
-
339  // Find the index of the channel in the configured channels
-
340  idx = -1;
-
341  for (int j = 0; j < self->cfg.channels; ++j) {
-
342  if (self->cfg.adc_channels[j] == chan_num) {
-
343  idx = j;
-
344  break;
-
345  }
-
346  }
-
347  // Push the data to the corresponding FIFO buffer
-
348  if (idx >= 0) {
-
349  if (self->fifo_buffers[idx]->push(data)) {
-
350  LOGD("Top Off Sample %d, FIFO %d, ch %u, d %u", i, idx, chan_num, data);
-
351  } else {
-
352  LOGE("Top Off Sample %d, FIFO buffer is full, ch %u, d %u", i, chan_num, data);
-
353  }
-
354  } else {
-
355  LOGE("Top Off Sample %d, ch %u not found in configuration, d %u", i, chan_num, data);
-
356  for (int k = 0; k < self->cfg.channels; ++k) {
-
357  LOGE("Available config ch: %u", self->cfg.adc_channels[k]);
-
358  }
-
359  }
-
360  }
-
361 
-
362  // Determine the updated minimal number of samples in FIFO buffers
-
363  min_samples_in_fifo_per_channel = self->fifo_buffers[0]->size();
-
364  max_samples_in_fifo_per_channel = self->fifo_buffers[0]->size();
-
365  for (int i = 1; i < self->cfg.channels; i++) {
-
366  fifo_size = self->fifo_buffers[i]->size();
-
367  if (fifo_size < min_samples_in_fifo_per_channel) {
-
368  min_samples_in_fifo_per_channel = fifo_size;
-
369  }
-
370  if (fifo_size > max_samples_in_fifo_per_channel) {
-
371  max_samples_in_fifo_per_channel = fifo_size;
-
372  }
-
373  }
-
374  LOGD("Min # of samples in FIFO: %d, Max # of samples in FIFO: %d", min_samples_in_fifo_per_channel, max_samples_in_fifo_per_channel);
-
375  }
-
376 
-
377  // 3) Calibrate and copy data to the output buffer
-
378  if (samples_requested_per_channel <= min_samples_in_fifo_per_channel) {
-
379  LOGD("Going to copying %d samples of %d samples/channel to output buffer", samples_requested, samples_requested_per_channel);
-
380  samples_provided_per_channel = samples_requested_per_channel;
-
381  } else {
-
382  // This should not happen as we topped off the FIFO buffers in step 2)
-
383  LOGE("Only %d samples per channel available for output buffer", min_samples_in_fifo_per_channel);
-
384  samples_provided_per_channel = min_samples_in_fifo_per_channel;
-
385  }
-
386 
-
387  for (int i = 0; i < samples_provided_per_channel; i++) {
-
388  for (int j = 0; j < self->cfg.channels; j++) {
-
389  ADC_DATA_TYPE data;
-
390  self->fifo_buffers[j]->pop(data);
-
391  if (result16 < end) {
-
392  if (self->cfg.adc_calibration_active) {
-
393  // Provide result in millivolts
-
394  auto err = adc_cali_raw_to_voltage(self->adc_cali_handle, (int)data, &data_milliVolts);
-
395  if (err == ESP_OK) {
-
396  *result16 = static_cast<int16_t>(data_milliVolts);
-
397  } else {
-
398  LOGE("adc_cali_raw_to_voltage error: %d", err);
-
399  *result16 = 0;
-
400  }
-
401  } else {
-
402  *result16 = data;
-
403  }
-
404  result16++;
-
405  } else {
-
406  LOGE("Buffer write overflow, skipping data");
-
407  }
-
408  }
-
409  }
+
309  // Determine min number of samples from all FIFO buffers
+
310  min_samples_in_fifo_per_channel = self->fifo_buffers[0]->size();
+
311  for (int i = 1; i < self->cfg.channels; i++) {
+
312  fifo_size = self->fifo_buffers[i]->size();
+
313  if (fifo_size < min_samples_in_fifo_per_channel) {
+
314  min_samples_in_fifo_per_channel = fifo_size;
+
315  }
+
316  }
+
317 
+
318  // 2) If necessary, top off the FIFO buffers to return the requested number of bytes
+
319  while (samples_requested_per_channel > min_samples_in_fifo_per_channel) {
+
320 
+
321  // obtain two extra sets of data (2 because number of bytes requested from ADC buffer needs to be divisible by 4)
+
322  // LOGI("adc_continuous_read request:%d samples %d bytes requested", samples_requested, (uint32_t)(samples_requested * sizeof(adc_digi_output_data_t)));
+
323  if (adc_continuous_read(self->adc_handle, (uint8_t *)result_data, (uint32_t)(2*self->cfg.channels * sizeof(adc_digi_output_data_t)), &bytes_read, (uint32_t)self->cfg.timeout) != ESP_OK) {
+
324  LOGE("Top off, adc_continuous_read unsuccessful");
+
325  break;
+
326  }
+
327 
+
328  // Parse the additional data
+
329  samples_read = bytes_read / sizeof(adc_digi_output_data_t);
+
330  LOGD("Top Off: Requested %d samples per Channel, Min samples in FIFO: %d, Read additional %d bytes / %d samples", samples_requested_per_channel, min_samples_in_fifo_per_channel, (unsigned)bytes_read, samples_read);
+
331 
+
332  for (int i = 0; i < samples_read; i++) {
+
333  adc_digi_output_data_t *p = &result_data[i];
+
334  ADC_CHANNEL_TYPE chan_num = AUDIO_ADC_GET_CHANNEL(p);
+
335  ADC_DATA_TYPE data = AUDIO_ADC_GET_DATA(p);
+
336 
+
337  // Find the index of the channel in the configured channels
+
338  idx = -1;
+
339  for (int j = 0; j < self->cfg.channels; ++j) {
+
340  if (self->cfg.adc_channels[j] == chan_num) {
+
341  idx = j;
+
342  break;
+
343  }
+
344  }
+
345  // Push the data to the corresponding FIFO buffer
+
346  if (idx >= 0) {
+
347  if (self->fifo_buffers[idx]->push(data)) {
+
348  LOGD("Top Off Sample %d, FIFO %d, ch %u, d %u", i, idx, chan_num, data);
+
349  } else {
+
350  LOGE("Top Off Sample %d, FIFO buffer is full, ch %u, d %u", i, chan_num, data);
+
351  }
+
352  } else {
+
353  LOGE("Top Off Sample %d, ch %u not found in configuration, d %u", i, chan_num, data);
+
354  for (int k = 0; k < self->cfg.channels; ++k) {
+
355  LOGE("Available config ch: %u", self->cfg.adc_channels[k]);
+
356  }
+
357  }
+
358  }
+
359 
+
360  // Determine the updated minimal number of samples in FIFO buffers
+
361  min_samples_in_fifo_per_channel = self->fifo_buffers[0]->size();
+
362  max_samples_in_fifo_per_channel = self->fifo_buffers[0]->size();
+
363  for (int i = 1; i < self->cfg.channels; i++) {
+
364  fifo_size = self->fifo_buffers[i]->size();
+
365  if (fifo_size < min_samples_in_fifo_per_channel) {
+
366  min_samples_in_fifo_per_channel = fifo_size;
+
367  }
+
368  if (fifo_size > max_samples_in_fifo_per_channel) {
+
369  max_samples_in_fifo_per_channel = fifo_size;
+
370  }
+
371  }
+
372  LOGD("Min # of samples in FIFO: %d, Max # of samples in FIFO: %d", min_samples_in_fifo_per_channel, max_samples_in_fifo_per_channel);
+
373  }
+
374 
+
375  // 3) Calibrate and copy data to the output buffer
+
376  if (samples_requested_per_channel <= min_samples_in_fifo_per_channel) {
+
377  LOGD("Going to copying %d samples of %d samples/channel to output buffer", samples_requested, samples_requested_per_channel);
+
378  samples_provided_per_channel = samples_requested_per_channel;
+
379  } else {
+
380  // This should not happen as we topped off the FIFO buffers in step 2)
+
381  LOGE("Only %d samples per channel available for output buffer", min_samples_in_fifo_per_channel);
+
382  samples_provided_per_channel = min_samples_in_fifo_per_channel;
+
383  }
+
384 
+
385  for (int i = 0; i < samples_provided_per_channel; i++) {
+
386  for (int j = 0; j < self->cfg.channels; j++) {
+
387  ADC_DATA_TYPE data;
+
388  self->fifo_buffers[j]->pop(data);
+
389  if (result16 < end) {
+
390  if (self->cfg.adc_calibration_active) {
+
391  // Provide result in millivolts
+
392  auto err = adc_cali_raw_to_voltage(self->adc_cali_handle, (int)data, &data_milliVolts);
+
393  if (err == ESP_OK) {
+
394  *result16 = static_cast<int16_t>(data_milliVolts);
+
395  } else {
+
396  LOGE("adc_cali_raw_to_voltage error: %d", err);
+
397  *result16 = 0;
+
398  }
+
399  } else {
+
400  *result16 = data;
+
401  }
+
402  result16++;
+
403  } else {
+
404  LOGE("Buffer write overflow, skipping data");
+
405  }
+
406  }
+
407  }
+
408 
+
409  bytes_provided = samples_provided_per_channel * self->cfg.channels * sizeof(int16_t);
410 
-
411  bytes_provided = samples_provided_per_channel * self->cfg.channels * sizeof(int16_t);
-
412 
-
413  // 4) Engage centering if enabled
-
414  if (self->cfg.is_auto_center_read) {
-
415  self->auto_center.convert(dest, bytes_provided);
-
416  }
-
417 
-
418  } else {
-
419  LOGE("adc_continuous_read unsuccessful");
-
420  bytes_provided = 0;
-
421  }
-
422  free(result_data);
-
423  return bytes_provided;
-
424  }
-
425 
-
426  protected:
-
427  AnalogDriverESP32V1 *self;
+
411  // 4) Engage centering if enabled
+
412  if (self->cfg.is_auto_center_read) {
+
413  self->auto_center.convert(dest, bytes_provided);
+
414  }
+
415 
+
416  } else {
+
417  LOGE("adc_continuous_read unsuccessful");
+
418  bytes_provided = 0;
+
419  }
+
420  free(result_data);
+
421  return bytes_provided;
+
422  }
+
423 
+
424  protected:
+
425  AnalogDriverESP32V1 *self;
+
426 
+
427  } io{this};
428 
-
429  } io{this};
+
429  NumberFormatConverterStream converter{io};
430 
-
431  NumberFormatConverterStream converter{io};
-
432 
-
433  // Setup Digital to Analog
-
434  // ----------------------------------------------------------
-
435  #ifdef HAS_ESP32_DAC
-
436  bool setup_tx() {
-
437  dac_continuous_config_t cont_cfg = {
-
438  .chan_mask = cfg.channels == 1 ? cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL,
-
439  .desc_num = (uint32_t)cfg.buffer_count,
-
440  .buf_size = (size_t)cfg.buffer_size,
-
441  .freq_hz = (uint32_t)cfg.sample_rate,
-
442  .offset = 0,
-
443  .clk_src = cfg.use_apll ? DAC_DIGI_CLK_SRC_APLL : DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range
-
444  .chan_mode = DAC_CHANNEL_MODE_ALTER,
-
445  };
-
446  // Allocate continuous channels
-
447  if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
-
448  LOGE("new_channels");
-
449  return false;
-
450  }
-
451  if (dac_continuous_enable(dac_handle) != ESP_OK) {
-
452  LOGE("enable");
-
453  return false;
-
454  }
-
455  return true;
-
456  }
-
457  #else
-
458  bool setup_tx() {
-
459  LOGE("DAC not supported");
-
460  return false;
-
461  }
-
462  #endif
-
463 
-
464  // Setup Analog to Digital Converter
-
465  // ----------------------------------------------------------
-
466  bool setup_rx() {
-
467  adc_channel_t adc_channel;
-
468  int io_pin;
-
469  esp_err_t err;
-
470 
-
471  // Check the configuration
-
472  if (!checkADCChannels()) return false;
-
473  if (!checkADCSampleRate()) return false;
-
474  if (!checkADCBitWidth()) return false;
-
475  if (!checkADCBitsPerSample()) return false;
-
476 
-
477  if (adc_handle != nullptr) {
-
478  LOGE("adc unit %u continuous is already initialized. Please call end() first!", ADC_UNIT);
-
479  return false;
-
480  }
-
481 
-
482  #ifdef ARDUINO
-
483  // Set periman deinit callback
-
484  // TODO, currently handled in end() method
-
485 
-
486  // Set the pins/channels to INIT state
-
487  for (int i = 0; i < cfg.channels; i++) {
-
488  adc_channel = cfg.adc_channels[i];
-
489  adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
-
490  if (!perimanClearPinBus(io_pin)) {
-
491  LOGE("perimanClearPinBus failed!");
-
492  return false;
-
493  }
-
494  }
-
495  #endif
-
496 
-
497  // Determine conv_frame_size which must be multiple of SOC_ADC_DIGI_DATA_BYTES_PER_CONV
-
498  // Old Code
-
499  uint32_t conv_frame_size = (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
-
500  #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
-
501  uint8_t calc_multiple = conv_frame_size % SOC_ADC_DIGI_DATA_BYTES_PER_CONV;
-
502  if (calc_multiple != 0) {
-
503  conv_frame_size = (uint32_t) (conv_frame_size + calc_multiple);
-
504  }
-
505  #endif
-
506 
-
507  // Proposed new Code
-
508  // uint32_t conv_frame_size = (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
-
509  // #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
-
510  // uint32_t conv_frame_size = (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_DATA_BYTES_PER_CONV
-
511  // #endif
-
512 
-
513  // Conversion frame size buffer can't be bigger than 4092 bytes
-
514  if (conv_frame_size > 4092) {
-
515  LOGE("buffer_size is too big. Please set lower buffer_size.");
-
516  return false;
-
517  } else {
-
518  LOGI("buffer_size: %u samples, conv_frame_size: %u bytes", cfg.buffer_size, (unsigned)conv_frame_size);
-
519  }
-
520 
-
521  // Create adc_continuous handle
-
522  adc_continuous_handle_cfg_t adc_config;
-
523  adc_config.max_store_buf_size = (uint32_t)conv_frame_size * 2;
-
524  adc_config.conv_frame_size = (uint32_t) conv_frame_size;
-
525 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
-
526  adc_config.flags.flush_pool = true;
-
527 #endif
-
528  err = adc_continuous_new_handle(&adc_config, &adc_handle);
-
529  if (err != ESP_OK) {
-
530  LOGE("adc_continuous_new_handle failed with error: %d", err);
-
531  return false;
-
532  } else {
-
533  LOGI("adc_continuous_new_handle successful");
-
534  }
-
535 
-
536  // Configure the ADC patterns
-
537  adc_digi_pattern_config_t adc_pattern[cfg.channels] = {};
-
538  for (int i = 0; i < cfg.channels; i++) {
-
539  uint8_t ch = cfg.adc_channels[i];
-
540  adc_pattern[i].atten = (uint8_t) cfg.adc_attenuation;
-
541  adc_pattern[i].channel = (uint8_t)ch;
-
542  adc_pattern[i].unit = (uint8_t) ADC_UNIT;
-
543  adc_pattern[i].bit_width = (uint8_t) cfg.adc_bit_width;
-
544  }
-
545 
-
546  // Configure the ADC
-
547  adc_continuous_config_t dig_cfg = {
-
548  .pattern_num = (uint32_t) cfg.channels,
-
549  .adc_pattern = adc_pattern,
-
550  .sample_freq_hz = (uint32_t)cfg.sample_rate * cfg.channels,
-
551  .conv_mode = (adc_digi_convert_mode_t) cfg.adc_conversion_mode,
-
552  .format = (adc_digi_output_format_t) cfg.adc_output_type,
-
553  };
-
554 
-
555  // Log the configuration
-
556  LOGI("dig_cfg.sample_freq_hz: %u", (unsigned)dig_cfg.sample_freq_hz);
-
557  LOGI("dig_cfg.conv_mode: %u (1: unit 1, 2: unit 2, 3: both)", dig_cfg.conv_mode);
-
558  LOGI("dig_cfg.format: %u (0 is type1: [12bit data, 4bit channel])", dig_cfg.format);
-
559  for (int i = 0; i < cfg.channels; i++) {
-
560  LOGI("dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
-
561  LOGI("dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
-
562  LOGI("dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
-
563  LOGI("dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
-
564  }
-
565 
-
566  // Initialize ADC
-
567  err = adc_continuous_config(adc_handle, &dig_cfg);
-
568  if (err != ESP_OK) {
-
569  LOGE("adc_continuous_config unsuccessful with error: %d", err);
-
570  return false;
-
571  }
-
572  LOGI("adc_continuous_config successful");
-
573 
-
574  // Set up optional calibration
-
575  if (!setupADCCalibration()) {
-
576  return false;
-
577  }
-
578 
-
579  // Attach the pins to the ADC unit
-
580  #ifdef ARDUINO
-
581  for (int i = 0; i < cfg.channels; i++) {
-
582  adc_channel = cfg.adc_channels[i];
-
583  adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
-
584  // perimanSetPinBus: uint8_t pin, peripheral_bus_type_t type, void * bus, int8_t bus_num, int8_t bus_channel
-
585  if (!perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (void *)(ADC_UNIT + 1), ADC_UNIT, adc_channel)) {
-
586  LOGE("perimanSetPinBus to Continuous an ADC Unit %u failed!", ADC_UNIT);
-
587  return false;
-
588  }
-
589  }
-
590  #endif
-
591 
-
592  // Start ADC
-
593  err = adc_continuous_start(adc_handle);
-
594  if (err != ESP_OK) {
-
595  LOGE("adc_continuous_start unsuccessful with error: %d", err);
-
596  return false;
-
597  }
-
598 
-
599  // Setup up optimal auto center which puts the avg at 0
-
600  auto_center.begin(cfg.channels, cfg.bits_per_sample, true);
-
601 
-
602  // Initialize the FIFO buffers
-
603  size_t fifo_size = (cfg.buffer_size / cfg.channels) + 8; // Add a few extra elements
-
604  fifo_buffers = new FIFO<ADC_DATA_TYPE>*[cfg.channels]; // Allocate an array of FIFO objects
-
605  for (int i = 0; i < cfg.channels; ++i) {
-
606  fifo_buffers[i] = new FIFO<ADC_DATA_TYPE>(fifo_size);
-
607  }
-
608  LOGI("%d FIFO buffers allocated of size %d", cfg.channels, fifo_size);
-
609 
-
610  LOGI("Setup ADC successful");
-
611 
-
612  return true;
-
613  }
-
614 
-
615  // Cleanup Analog to Digital Converter
-
616  // ----------------------------------------------------------
-
617  bool cleanup_rx() {
-
618 
-
619  adc_continuous_stop(adc_handle);
-
620  adc_continuous_deinit(adc_handle);
-
621  if (cfg.adc_calibration_active) {
-
622  #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
-
623  adc_cali_delete_scheme_curve_fitting(adc_cali_handle);
-
624  #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
-
625  adc_cali_delete_scheme_line_fitting(adc_cali_handle);
-
626  #endif
-
627  }
+
431  // Setup Digital to Analog
+
432  // ----------------------------------------------------------
+
433  #ifdef HAS_ESP32_DAC
+
434  bool setup_tx() {
+
435  dac_continuous_config_t cont_cfg = {
+
436  .chan_mask = cfg.channels == 1 ? cfg.dac_mono_channel : DAC_CHANNEL_MASK_ALL,
+
437  .desc_num = (uint32_t)cfg.buffer_count,
+
438  .buf_size = (size_t)cfg.buffer_size,
+
439  .freq_hz = (uint32_t)cfg.sample_rate,
+
440  .offset = 0,
+
441  .clk_src = cfg.use_apll ? DAC_DIGI_CLK_SRC_APLL : DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range
+
442  .chan_mode = DAC_CHANNEL_MODE_ALTER,
+
443  };
+
444  // Allocate continuous channels
+
445  if (dac_continuous_new_channels(&cont_cfg, &dac_handle) != ESP_OK) {
+
446  LOGE("new_channels");
+
447  return false;
+
448  }
+
449  if (dac_continuous_enable(dac_handle) != ESP_OK) {
+
450  LOGE("enable");
+
451  return false;
+
452  }
+
453  return true;
+
454  }
+
455  #else
+
456  bool setup_tx() {
+
457  LOGE("DAC not supported");
+
458  return false;
+
459  }
+
460  #endif
+
461 
+
462  // Setup Analog to Digital Converter
+
463  // ----------------------------------------------------------
+
464  bool setup_rx() {
+
465  adc_channel_t adc_channel;
+
466  int io_pin;
+
467  esp_err_t err;
+
468 
+
469  // Check the configuration
+
470  if (!checkADCChannels()) return false;
+
471  if (!checkADCSampleRate()) return false;
+
472  if (!checkADCBitWidth()) return false;
+
473  if (!checkADCBitsPerSample()) return false;
+
474 
+
475  if (adc_handle != nullptr) {
+
476  LOGE("adc unit %u continuous is already initialized. Please call end() first!", ADC_UNIT);
+
477  return false;
+
478  }
+
479 
+
480  #ifdef ARDUINO
+
481  // Set periman deinit callback
+
482  // TODO, currently handled in end() method
+
483 
+
484  // Set the pins/channels to INIT state
+
485  for (int i = 0; i < cfg.channels; i++) {
+
486  adc_channel = cfg.adc_channels[i];
+
487  adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
+
488  if (!perimanClearPinBus(io_pin)) {
+
489  LOGE("perimanClearPinBus failed!");
+
490  return false;
+
491  }
+
492  }
+
493  #endif
+
494 
+
495  // Determine conv_frame_size which must be multiple of SOC_ADC_DIGI_DATA_BYTES_PER_CONV
+
496  // Old Code
+
497  uint32_t conv_frame_size = (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
+
498  #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
+
499  uint8_t calc_multiple = conv_frame_size % SOC_ADC_DIGI_DATA_BYTES_PER_CONV;
+
500  if (calc_multiple != 0) {
+
501  conv_frame_size = (uint32_t) (conv_frame_size + calc_multiple);
+
502  }
+
503  #endif
+
504 
+
505  // Proposed new Code
+
506  // uint32_t conv_frame_size = (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_RESULT_BYTES;
+
507  // #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
+
508  // uint32_t conv_frame_size = (uint32_t)cfg.buffer_size * SOC_ADC_DIGI_DATA_BYTES_PER_CONV
+
509  // #endif
+
510 
+
511  // Conversion frame size buffer can't be bigger than 4092 bytes
+
512  if (conv_frame_size > 4092) {
+
513  LOGE("buffer_size is too big. Please set lower buffer_size.");
+
514  return false;
+
515  } else {
+
516  LOGI("buffer_size: %u samples, conv_frame_size: %u bytes", cfg.buffer_size, (unsigned)conv_frame_size);
+
517  }
+
518 
+
519  // Create adc_continuous handle
+
520  adc_continuous_handle_cfg_t adc_config;
+
521  adc_config.max_store_buf_size = (uint32_t)conv_frame_size * 2;
+
522  adc_config.conv_frame_size = (uint32_t) conv_frame_size;
+
523 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
+
524  adc_config.flags.flush_pool = true;
+
525 #endif
+
526  err = adc_continuous_new_handle(&adc_config, &adc_handle);
+
527  if (err != ESP_OK) {
+
528  LOGE("adc_continuous_new_handle failed with error: %d", err);
+
529  return false;
+
530  } else {
+
531  LOGI("adc_continuous_new_handle successful");
+
532  }
+
533 
+
534  // Configure the ADC patterns
+
535  adc_digi_pattern_config_t adc_pattern[cfg.channels] = {};
+
536  for (int i = 0; i < cfg.channels; i++) {
+
537  uint8_t ch = cfg.adc_channels[i];
+
538  adc_pattern[i].atten = (uint8_t) cfg.adc_attenuation;
+
539  adc_pattern[i].channel = (uint8_t)ch;
+
540  adc_pattern[i].unit = (uint8_t) ADC_UNIT;
+
541  adc_pattern[i].bit_width = (uint8_t) cfg.adc_bit_width;
+
542  }
+
543 
+
544  // Configure the ADC
+
545  adc_continuous_config_t dig_cfg = {
+
546  .pattern_num = (uint32_t) cfg.channels,
+
547  .adc_pattern = adc_pattern,
+
548  .sample_freq_hz = (uint32_t)cfg.sample_rate * cfg.channels,
+
549  .conv_mode = (adc_digi_convert_mode_t) cfg.adc_conversion_mode,
+
550  .format = (adc_digi_output_format_t) cfg.adc_output_type,
+
551  };
+
552 
+
553  // Log the configuration
+
554  LOGI("dig_cfg.sample_freq_hz: %u", (unsigned)dig_cfg.sample_freq_hz);
+
555  LOGI("dig_cfg.conv_mode: %u (1: unit 1, 2: unit 2, 3: both)", dig_cfg.conv_mode);
+
556  LOGI("dig_cfg.format: %u (0 is type1: [12bit data, 4bit channel])", dig_cfg.format);
+
557  for (int i = 0; i < cfg.channels; i++) {
+
558  LOGI("dig_cfg.adc_pattern[%d].atten: %u", i, dig_cfg.adc_pattern[i].atten);
+
559  LOGI("dig_cfg.adc_pattern[%d].channel: %u", i, dig_cfg.adc_pattern[i].channel);
+
560  LOGI("dig_cfg.adc_pattern[%d].unit: %u", i, dig_cfg.adc_pattern[i].unit);
+
561  LOGI("dig_cfg.adc_pattern[%d].bit_width: %u", i, dig_cfg.adc_pattern[i].bit_width);
+
562  }
+
563 
+
564  // Initialize ADC
+
565  err = adc_continuous_config(adc_handle, &dig_cfg);
+
566  if (err != ESP_OK) {
+
567  LOGE("adc_continuous_config unsuccessful with error: %d", err);
+
568  return false;
+
569  }
+
570  LOGI("adc_continuous_config successful");
+
571 
+
572  // Set up optional calibration
+
573  if (!setupADCCalibration()) {
+
574  return false;
+
575  }
+
576 
+
577  // Attach the pins to the ADC unit
+
578  #ifdef ARDUINO
+
579  for (int i = 0; i < cfg.channels; i++) {
+
580  adc_channel = cfg.adc_channels[i];
+
581  adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
+
582  // perimanSetPinBus: uint8_t pin, peripheral_bus_type_t type, void * bus, int8_t bus_num, int8_t bus_channel
+
583  if (!perimanSetPinBus(io_pin, ESP32_BUS_TYPE_ADC_CONT, (void *)(ADC_UNIT + 1), ADC_UNIT, adc_channel)) {
+
584  LOGE("perimanSetPinBus to Continuous an ADC Unit %u failed!", ADC_UNIT);
+
585  return false;
+
586  }
+
587  }
+
588  #endif
+
589 
+
590  // Start ADC
+
591  err = adc_continuous_start(adc_handle);
+
592  if (err != ESP_OK) {
+
593  LOGE("adc_continuous_start unsuccessful with error: %d", err);
+
594  return false;
+
595  }
+
596 
+
597  // Setup up optimal auto center which puts the avg at 0
+
598  auto_center.begin(cfg.channels, cfg.bits_per_sample, true);
+
599 
+
600  // Initialize the FIFO buffers
+
601  size_t fifo_size = (cfg.buffer_size / cfg.channels) + 8; // Add a few extra elements
+
602  fifo_buffers = new FIFO<ADC_DATA_TYPE>*[cfg.channels]; // Allocate an array of FIFO objects
+
603  for (int i = 0; i < cfg.channels; ++i) {
+
604  fifo_buffers[i] = new FIFO<ADC_DATA_TYPE>(fifo_size);
+
605  }
+
606  LOGI("%d FIFO buffers allocated of size %d", cfg.channels, fifo_size);
+
607 
+
608  LOGI("Setup ADC successful");
+
609 
+
610  return true;
+
611  }
+
612 
+
614  bool cleanup_tx() {
+
615  bool ok = true;
+
616 #ifdef HAS_ESP32_DAC
+
617  if (dac_continuous_disable(dac_handle) != ESP_OK){
+
618  ok = false;
+
619  LOGE("dac_continuous_disable failed");
+
620  }
+
621  if (dac_continuous_del_channels(dac_handle) != ESP_OK){
+
622  ok = false;
+
623  LOGE("dac_continuous_del_channels failed");
+
624  }
+
625 #endif
+
626  return ok;
+
627  }
628 
-
629  // Clean up the FIFO buffers
-
630  if (fifo_buffers != nullptr) {
-
631  for (int i = 0; i < cfg.channels; ++i) {
-
632  delete fifo_buffers[i];
-
633  }
-
634  delete[] fifo_buffers;
-
635  fifo_buffers = nullptr;
-
636  }
-
637 
-
638  #ifdef ARDUINO
-
639  // Set all used pins/channels to INIT state
-
640  for (int i = 0; i < cfg.channels; i++) {
-
641  adc_channel_t adc_channel = cfg.adc_channels[i];
-
642  int io_pin;
-
643  adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
-
644  if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
-
645  if (!perimanClearPinBus(io_pin)) {
-
646  LOGE("perimanClearPinBus failed!");
-
647  }
-
648  }
+
630  bool cleanup_rx() {
+
631 
+
632  adc_continuous_stop(adc_handle);
+
633  adc_continuous_deinit(adc_handle);
+
634  if (cfg.adc_calibration_active) {
+
635  #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
+
636  adc_cali_delete_scheme_curve_fitting(adc_cali_handle);
+
637  #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
+
638  adc_cali_delete_scheme_line_fitting(adc_cali_handle);
+
639  #endif
+
640  }
+
641 
+
642  // Clean up the FIFO buffers
+
643  if (fifo_buffers != nullptr) {
+
644  for (int i = 0; i < cfg.channels; ++i) {
+
645  delete fifo_buffers[i];
+
646  }
+
647  delete[] fifo_buffers;
+
648  fifo_buffers = nullptr;
649  }
-
650  #endif
-
651 
-
652  return true; // Return true to indicate successful cleanup
-
653  }
-
654 
-
656  bool checkADCBitWidth() {
-
657  if ((cfg.adc_bit_width < SOC_ADC_DIGI_MIN_BITWIDTH) ||
-
658  (cfg.adc_bit_width > SOC_ADC_DIGI_MAX_BITWIDTH)) {
-
659  LOGE("adc bit width: %u cannot be set, range: %u to %u", cfg.adc_bit_width,
-
660  (unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
-
661  return false;
+
650 
+
651  #ifdef ARDUINO
+
652  // Set all used pins/channels to INIT state
+
653  for (int i = 0; i < cfg.channels; i++) {
+
654  adc_channel_t adc_channel = cfg.adc_channels[i];
+
655  int io_pin;
+
656  adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
+
657  if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
+
658  if (!perimanClearPinBus(io_pin)) {
+
659  LOGE("perimanClearPinBus failed!");
+
660  }
+
661  }
662  }
-
663  LOGI("adc bit width: %u, range: %u to %u", cfg.adc_bit_width,
-
664  (unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
-
665  return true;
+
663  #endif
+
664 
+
665  return true; // Return true to indicate successful cleanup
666  }
667 
-
669  bool checkADCChannels() {
-
670  int io_pin;
-
671  adc_channel_t adc_channel;
-
672 
-
673  int max_channels = sizeof(cfg.adc_channels) / sizeof(adc_channel_t);
-
674  if (cfg.channels > max_channels) {
-
675  LOGE("number of channels: %d, max: %d", cfg.channels, max_channels);
-
676  return false;
-
677  }
-
678  LOGI("channels: %d, max: %d", cfg.channels, max_channels);
-
679 
-
680  // Lets make sure the adc channels are available
-
681  for (int i = 0; i < cfg.channels; i++) {
-
682  adc_channel = cfg.adc_channels[i];
-
683  auto err = adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
-
684  if (err != ESP_OK) {
-
685  LOGE("ADC channel %u is not available on ADC unit %u", adc_channel, ADC_UNIT);
-
686  return false;
-
687  } else {
-
688  LOGI("ADC channel %u is on pin %u", adc_channel, io_pin);
-
689  }
+
669  bool checkADCBitWidth() {
+
670  if ((cfg.adc_bit_width < SOC_ADC_DIGI_MIN_BITWIDTH) ||
+
671  (cfg.adc_bit_width > SOC_ADC_DIGI_MAX_BITWIDTH)) {
+
672  LOGE("adc bit width: %u cannot be set, range: %u to %u", cfg.adc_bit_width,
+
673  (unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
+
674  return false;
+
675  }
+
676  LOGI("adc bit width: %u, range: %u to %u", cfg.adc_bit_width,
+
677  (unsigned)SOC_ADC_DIGI_MIN_BITWIDTH, (unsigned)SOC_ADC_DIGI_MAX_BITWIDTH);
+
678  return true;
+
679  }
+
680 
+
682  bool checkADCChannels() {
+
683  int io_pin;
+
684  adc_channel_t adc_channel;
+
685 
+
686  int max_channels = sizeof(cfg.adc_channels) / sizeof(adc_channel_t);
+
687  if (cfg.channels > max_channels) {
+
688  LOGE("number of channels: %d, max: %d", cfg.channels, max_channels);
+
689  return false;
690  }
-
691  return true;
-
692  }
-
693 
-
695  bool checkADCSampleRate() {
-
696  int sample_rate = cfg.sample_rate * cfg.channels;
-
697  if ((sample_rate < SOC_ADC_SAMPLE_FREQ_THRES_LOW) ||
-
698  (sample_rate > SOC_ADC_SAMPLE_FREQ_THRES_HIGH)) {
-
699  LOGE("sample rate eff: %u can not be set, range: %u to %u", sample_rate,
-
700  SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
-
701  return false;
-
702  }
-
703  LOGI("sample rate eff: %u, range: %u to %u", sample_rate,
-
704  SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
-
705 
-
706  return true;
-
707  }
-
708 
-
710  bool checkADCBitsPerSample() {
-
711  int supported_bits = 16; // for the time being we support only 16 bits!
-
712 
-
713  // calculated default value if nothing is specified
-
714  if (cfg.bits_per_sample == 0) {
-
715  cfg.bits_per_sample = supported_bits;
-
716  LOGI("bits per sample set to: %d", cfg.bits_per_sample);
-
717  }
+
691  LOGI("channels: %d, max: %d", cfg.channels, max_channels);
+
692 
+
693  // Lets make sure the adc channels are available
+
694  for (int i = 0; i < cfg.channels; i++) {
+
695  adc_channel = cfg.adc_channels[i];
+
696  auto err = adc_continuous_channel_to_io(ADC_UNIT, adc_channel, &io_pin);
+
697  if (err != ESP_OK) {
+
698  LOGE("ADC channel %u is not available on ADC unit %u", adc_channel, ADC_UNIT);
+
699  return false;
+
700  } else {
+
701  LOGI("ADC channel %u is on pin %u", adc_channel, io_pin);
+
702  }
+
703  }
+
704  return true;
+
705  }
+
706 
+
708  bool checkADCSampleRate() {
+
709  int sample_rate = cfg.sample_rate * cfg.channels;
+
710  if ((sample_rate < SOC_ADC_SAMPLE_FREQ_THRES_LOW) ||
+
711  (sample_rate > SOC_ADC_SAMPLE_FREQ_THRES_HIGH)) {
+
712  LOGE("sample rate eff: %u can not be set, range: %u to %u", sample_rate,
+
713  SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
+
714  return false;
+
715  }
+
716  LOGI("sample rate eff: %u, range: %u to %u", sample_rate,
+
717  SOC_ADC_SAMPLE_FREQ_THRES_LOW, SOC_ADC_SAMPLE_FREQ_THRES_HIGH);
718 
-
719  // check bits_per_sample
-
720  if (cfg.bits_per_sample != supported_bits) {
-
721  LOGE("bits per sample: error. It should be: %d but is %d",
-
722  supported_bits, cfg.bits_per_sample);
-
723  return false;
-
724  }
-
725  LOGI("bits per sample: %d", cfg.bits_per_sample);
-
726  return true;
-
727  }
-
728 
-
730  bool setupADCCalibration() {
-
731  if (!cfg.adc_calibration_active)
-
732  return true;
-
733 
-
734  // Initialize ADC calibration handle
-
735  // Calibration is applied to an ADC unit (not per channel).
-
736 
-
737  // setup calibration only when requested
-
738  if (adc_cali_handle == NULL) {
-
739  #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
-
740  // curve fitting is preferred
-
741  adc_cali_curve_fitting_config_t cali_config;
-
742  cali_config.unit_id = ADC_UNIT;
-
743  cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
-
744  cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
-
745  auto err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle);
-
746  #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
-
747  // line fitting is the alternative
-
748  adc_cali_line_fitting_config_t cali_config;
-
749  cali_config.unit_id = ADC_UNIT;
-
750  cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
-
751  cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
-
752  auto err = adc_cali_create_scheme_line_fitting(&cali_config, &adc_cali_handle);
-
753  #endif
-
754  if (err != ESP_OK) {
-
755  LOGE("creating calibration handle failed for ADC%d with atten %d and bitwidth %d",
-
756  ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);
-
757  return false;
-
758  } else {
-
759  LOGI("enabled calibration for ADC%d with atten %d and bitwidth %d",
-
760  ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);
-
761  }
-
762  }
-
763  return true;
-
764  }
-
765 
-
766 };
-
767 
-
769 using AnalogDriver = AnalogDriverESP32V1;
-
770 
-
771 } // namespace audio_tools
-
772 
-
773 #endif
+
719  return true;
+
720  }
+
721 
+
723  bool checkADCBitsPerSample() {
+
724  int supported_bits = 16; // for the time being we support only 16 bits!
+
725 
+
726  // calculated default value if nothing is specified
+
727  if (cfg.bits_per_sample == 0) {
+
728  cfg.bits_per_sample = supported_bits;
+
729  LOGI("bits per sample set to: %d", cfg.bits_per_sample);
+
730  }
+
731 
+
732  // check bits_per_sample
+
733  if (cfg.bits_per_sample != supported_bits) {
+
734  LOGE("bits per sample: error. It should be: %d but is %d",
+
735  supported_bits, cfg.bits_per_sample);
+
736  return false;
+
737  }
+
738  LOGI("bits per sample: %d", cfg.bits_per_sample);
+
739  return true;
+
740  }
+
741 
+
743  bool setupADCCalibration() {
+
744  if (!cfg.adc_calibration_active)
+
745  return true;
+
746 
+
747  // Initialize ADC calibration handle
+
748  // Calibration is applied to an ADC unit (not per channel).
+
749 
+
750  // setup calibration only when requested
+
751  if (adc_cali_handle == NULL) {
+
752  #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
+
753  // curve fitting is preferred
+
754  adc_cali_curve_fitting_config_t cali_config;
+
755  cali_config.unit_id = ADC_UNIT;
+
756  cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
+
757  cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
+
758  auto err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle);
+
759  #elif !defined(CONFIG_IDF_TARGET_ESP32H2)
+
760  // line fitting is the alternative
+
761  adc_cali_line_fitting_config_t cali_config;
+
762  cali_config.unit_id = ADC_UNIT;
+
763  cali_config.atten = (adc_atten_t)cfg.adc_attenuation;
+
764  cali_config.bitwidth = (adc_bitwidth_t)cfg.adc_bit_width;
+
765  auto err = adc_cali_create_scheme_line_fitting(&cali_config, &adc_cali_handle);
+
766  #endif
+
767  if (err != ESP_OK) {
+
768  LOGE("creating calibration handle failed for ADC%d with atten %d and bitwidth %d",
+
769  ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);
+
770  return false;
+
771  } else {
+
772  LOGI("enabled calibration for ADC%d with atten %d and bitwidth %d",
+
773  ADC_UNIT, cfg.adc_attenuation, cfg.adc_bit_width);
+
774  }
+
775  }
+
776  return true;
+
777  }
+
778 
+
779 };
+
780 
+
782 using AnalogDriver = AnalogDriverESP32V1;
+
783 
+
784 } // namespace audio_tools
+
785 
+
786 #endif
audio_tools::AnalogConfigESP32V1
ESP32 specific configuration for i2s input via adc using the adc_continuous API.
Definition: AnalogConfigESP32V1.h:100
audio_tools::AnalogDriverBase
Definition: AnalogDriverBase.h:13
-
audio_tools::AnalogDriverESP32V1::FIFO
Custom FIFO class.
Definition: AnalogDriverESP32V1.h:116
-
audio_tools::AnalogDriverESP32V1::IO16Bit
Definition: AnalogDriverESP32V1.h:196
+
audio_tools::AnalogDriverESP32V1::FIFO
Custom FIFO class.
Definition: AnalogDriverESP32V1.h:114
+
audio_tools::AnalogDriverESP32V1::IO16Bit
Definition: AnalogDriverESP32V1.h:194
audio_tools::AnalogDriverESP32V1
AnalogAudioStream: A very fast DAC using DMA using the new dac_continuous API.
Definition: AnalogDriverESP32V1.h:28
-
audio_tools::AnalogDriverESP32V1::checkADCBitWidth
bool checkADCBitWidth()
Definition: AnalogDriverESP32V1.h:656
+
audio_tools::AnalogDriverESP32V1::checkADCBitWidth
bool checkADCBitWidth()
Definition: AnalogDriverESP32V1.h:669
audio_tools::AnalogDriverESP32V1::~AnalogDriverESP32V1
virtual ~AnalogDriverESP32V1()
Destructor.
Definition: AnalogDriverESP32V1.h:34
-
audio_tools::AnalogDriverESP32V1::checkADCChannels
bool checkADCChannels()
Definition: AnalogDriverESP32V1.h:669
+
audio_tools::AnalogDriverESP32V1::checkADCChannels
bool checkADCChannels()
Definition: AnalogDriverESP32V1.h:682
audio_tools::AnalogDriverESP32V1::end
void end() override
Definition: AnalogDriverESP32V1.h:70
+
audio_tools::AnalogDriverESP32V1::cleanup_tx
bool cleanup_tx()
Cleanup dac.
Definition: AnalogDriverESP32V1.h:614
+
audio_tools::AnalogDriverESP32V1::cleanup_rx
bool cleanup_rx()
Cleanup Analog to Digital Converter.
Definition: AnalogDriverESP32V1.h:630
audio_tools::AnalogDriverESP32V1::begin
bool begin(AnalogConfigESP32V1 cfg)
Definition: AnalogDriverESP32V1.h:40
audio_tools::AnalogDriverESP32V1::AnalogDriverESP32V1
AnalogDriverESP32V1()
Default constructor.
Definition: AnalogDriverESP32V1.h:31
-
audio_tools::AnalogDriverESP32V1::setupADCCalibration
bool setupADCCalibration()
Definition: AnalogDriverESP32V1.h:730
-
audio_tools::AnalogDriverESP32V1::checkADCSampleRate
bool checkADCSampleRate()
Definition: AnalogDriverESP32V1.h:695
-
audio_tools::AnalogDriverESP32V1::checkADCBitsPerSample
bool checkADCBitsPerSample()
Definition: AnalogDriverESP32V1.h:710
+
audio_tools::AnalogDriverESP32V1::setupADCCalibration
bool setupADCCalibration()
Definition: AnalogDriverESP32V1.h:743
+
audio_tools::AnalogDriverESP32V1::checkADCSampleRate
bool checkADCSampleRate()
Definition: AnalogDriverESP32V1.h:708
+
audio_tools::AnalogDriverESP32V1::checkADCBitsPerSample
bool checkADCBitsPerSample()
Definition: AnalogDriverESP32V1.h:723
audio_tools::AudioStream
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition: BaseStream.h:109
audio_tools::ConverterAutoCenter
Makes sure that the avg of the signal is set to 0.
Definition: BaseConverter.h:185
audio_tools::NumberFormatConverterStream
Converter which converts between bits_per_sample and 16 bits. The templated NumberFormatConverterStre...
Definition: AudioStreamsConverter.h:449
diff --git a/classaudio__tools_1_1_analog_driver_e_s_p32_v1-members.html b/classaudio__tools_1_1_analog_driver_e_s_p32_v1-members.html index c7add0cee..7e78380de 100644 --- a/classaudio__tools_1_1_analog_driver_e_s_p32_v1-members.html +++ b/classaudio__tools_1_1_analog_driver_e_s_p32_v1-members.html @@ -88,17 +88,18 @@ checkADCBitWidth()AnalogDriverESP32V1inlineprotected checkADCChannels()AnalogDriverESP32V1inlineprotected checkADCSampleRate()AnalogDriverESP32V1inlineprotected - cleanup_rx() (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlineprotected - converter (defined in AnalogDriverESP32V1)AnalogDriverESP32V1protected - end() overrideAnalogDriverESP32V1inlinevirtual - fifo_buffers (defined in AnalogDriverESP32V1)AnalogDriverESP32V1protected - readBytes(uint8_t *dest, size_t size_bytes) override (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlinevirtual - setup_rx() (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlineprotected - setup_tx() (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlineprotected - setupADCCalibration()AnalogDriverESP32V1inlineprotected - this (defined in AnalogDriverESP32V1)AnalogDriverESP32V1protected - write(const uint8_t *src, size_t size_bytes) override (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlinevirtual - ~AnalogDriverESP32V1()AnalogDriverESP32V1inlinevirtual + cleanup_rx()AnalogDriverESP32V1inlineprotected + cleanup_tx()AnalogDriverESP32V1inlineprotected + converter (defined in AnalogDriverESP32V1)AnalogDriverESP32V1protected + end() overrideAnalogDriverESP32V1inlinevirtual + fifo_buffers (defined in AnalogDriverESP32V1)AnalogDriverESP32V1protected + readBytes(uint8_t *dest, size_t size_bytes) override (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlinevirtual + setup_rx() (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlineprotected + setup_tx() (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlineprotected + setupADCCalibration()AnalogDriverESP32V1inlineprotected + this (defined in AnalogDriverESP32V1)AnalogDriverESP32V1protected + write(const uint8_t *src, size_t size_bytes) override (defined in AnalogDriverESP32V1)AnalogDriverESP32V1inlinevirtual + ~AnalogDriverESP32V1()AnalogDriverESP32V1inlinevirtual