@@ -115,42 +115,73 @@ DMABuffer<Sample> &AdvancedADC::read() {
115
115
return NULLBUF;
116
116
}
117
117
118
- int AdvancedADC::begin (uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers) {
118
+ int AdvancedADC::begin (uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers,bool do_start,uint8_t adcNum) {
119
+
119
120
ADCName instance = ADC_NP;
120
-
121
121
// Sanity checks.
122
122
if (resolution >= AN_ARRAY_SIZE (ADC_RES_LUT) || (descr && descr->pool )) {
123
123
return 0 ;
124
124
}
125
125
126
+ // if ADC specified is more than the number of available ADC bail out
127
+ if (adcNum>AN_ARRAY_SIZE (adc_pin_alt))
128
+ {
129
+ descr = nullptr ;
130
+ return 0 ;
131
+ }
132
+
126
133
// Clear ALTx pin.
127
134
for (size_t i=0 ; i<n_channels; i++) {
128
135
adc_pins[i] = (PinName) (adc_pins[i] & ~(ADC_PIN_ALT_MASK));
129
136
}
130
137
131
- // Find an ADC that can be used with these set of pins/channels.
132
- for (size_t i=0 ; instance == ADC_NP && i<AN_ARRAY_SIZE (adc_pin_alt); i++) {
133
- // Calculate alternate function pin.
134
- PinName pin = (PinName) (adc_pins[0 ] | adc_pin_alt[i]); // First pin decides the ADC.
135
138
136
- // Check if pin is mapped.
137
- if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
138
- break ;
139
- }
139
+ // If ADC not specified find an ADC that can be used with these set of pins/channels.
140
+ if (adcNum==0 )
141
+ {
142
+ for (size_t i=0 ; instance == ADC_NP && i<AN_ARRAY_SIZE (adc_pin_alt); i++) {
143
+ // Calculate alternate function pin.
144
+ PinName pin = (PinName) (adc_pins[0 ] | adc_pin_alt[i]); // First pin decides the ADC.
140
145
141
- // Find the first free ADC according to the available ADCs on pin.
142
- for (size_t j=0 ; instance == ADC_NP && j<AN_ARRAY_SIZE (adc_descr_all); j++) {
143
- descr = &adc_descr_all[j];
144
- if (descr->pool == nullptr ) {
145
- ADCName tmp_instance = (ADCName) pinmap_peripheral (pin, PinMap_ADC);
146
- if (descr->adc .Instance == ((ADC_TypeDef*) tmp_instance)) {
147
- instance = tmp_instance;
148
- adc_pins[0 ] = pin;
146
+ // Check if pin is mapped.
147
+ if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
148
+ break ;
149
+ }
150
+
151
+ // Find the first free ADC according to the available ADCs on pin.
152
+ for (size_t j=0 ; instance == ADC_NP && j<AN_ARRAY_SIZE (adc_descr_all); j++) {
153
+ descr = &adc_descr_all[j];
154
+ if (descr->pool == nullptr ) {
155
+ ADCName tmp_instance = (ADCName) pinmap_peripheral (pin, PinMap_ADC);
156
+ if (descr->adc .Instance == ((ADC_TypeDef*) tmp_instance)) {
157
+ instance = tmp_instance;
158
+ adc_pins[0 ] = pin;
159
+ selectedADC=j;
160
+ }
149
161
}
150
162
}
151
163
}
152
164
}
165
+ else if (adcNum>0 ) // if ADC specified use that ADC to try to map first channel
166
+ {
167
+ PinName pin = (PinName) (adc_pins[0 ] | adc_pin_alt[adcNum-1 ]);
153
168
169
+ // Check if pin is mapped.
170
+ if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
171
+ return 0 ;
172
+ }
173
+
174
+ descr = &adc_descr_all[adcNum-1 ];
175
+ if (descr->pool == nullptr ) {
176
+ ADCName tmp_instance = (ADCName) pinmap_peripheral (pin, PinMap_ADC);
177
+ if (descr->adc .Instance == ((ADC_TypeDef*) tmp_instance)) {
178
+ instance = tmp_instance;
179
+ adc_pins[0 ] = pin;
180
+ }
181
+ }
182
+ selectedADC=adcNum; // Store selected number
183
+ }
184
+
154
185
if (instance == ADC_NP) {
155
186
// Couldn't find a free ADC/descriptor.
156
187
descr = nullptr ;
@@ -159,11 +190,40 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
159
190
160
191
// Configure ADC pins.
161
192
pinmap_pinout (adc_pins[0 ], PinMap_ADC);
162
- uint8_t ch_init = 1 ;
163
- for (size_t i=1 ; i<n_channels; i++) {
164
- for (size_t j=0 ; j<AN_ARRAY_SIZE (adc_pin_alt); j++) {
193
+
194
+ // If ADC was not specified ensure the remaining channels are mappable to same ADC
195
+ if (adcNum==0 )
196
+ {
197
+ uint8_t ch_init = 1 ;
198
+ for (size_t i=1 ; i<n_channels; i++) {
199
+ for (size_t j=0 ; j<AN_ARRAY_SIZE (adc_pin_alt); j++) {
200
+ // Calculate alternate function pin.
201
+ PinName pin = (PinName) (adc_pins[i] | adc_pin_alt[j]);
202
+ // Check if pin is mapped.
203
+ if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
204
+ break ;
205
+ }
206
+ // Check if pin is connected to the selected ADC.
207
+ if (instance == pinmap_peripheral (pin, PinMap_ADC)) {
208
+ pinmap_pinout (pin, PinMap_ADC);
209
+ adc_pins[i] = pin;
210
+ ch_init++;
211
+ break ;
212
+ }
213
+ }
214
+ }
215
+ // All channels must share the same instance; if not, bail out.
216
+ if (ch_init < n_channels) {
217
+ return 0 ;
218
+ }
219
+ }
220
+ else if (adcNum>0 ) // If specific ADC was requested ensure all other channels map to that same ADC
221
+ {
222
+ uint8_t ch_init = 1 ;
223
+ for (size_t i=1 ; i<n_channels; i++) {
224
+
165
225
// Calculate alternate function pin.
166
- PinName pin = (PinName) (adc_pins[i] | adc_pin_alt[j ]);
226
+ PinName pin = (PinName) (adc_pins[i] | adc_pin_alt[adcNum- 1 ]);
167
227
// Check if pin is mapped.
168
228
if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
169
229
break ;
@@ -173,21 +233,22 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
173
233
pinmap_pinout (pin, PinMap_ADC);
174
234
adc_pins[i] = pin;
175
235
ch_init++;
176
- break ;
177
236
}
178
237
}
238
+ // All channels must share the same instance; if not, bail out.
239
+ if (ch_init < n_channels) {
240
+ return 0 ;
241
+ }
179
242
}
180
-
181
- // All channels must share the same instance; if not, bail out.
182
- if (ch_init < n_channels) {
183
- return 0 ;
184
- }
185
-
243
+
244
+
186
245
// Allocate DMA buffer pool.
187
246
descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
188
247
if (descr->pool == nullptr ) {
189
248
return 0 ;
190
249
}
250
+
251
+ // Allocate two DMA buffers for double buffering
191
252
descr->dmabuf [0 ] = descr->pool ->allocate ();
192
253
descr->dmabuf [1 ] = descr->pool ->allocate ();
193
254
@@ -202,7 +263,7 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
202
263
}
203
264
204
265
// Link DMA handle to ADC handle, and start the ADC.
205
- __HAL_LINKDMA (&descr->adc , DMA_Handle, descr->dma );
266
+ __HAL_LINKDMA (&descr->adc , DMA_Handle, descr->dma );
206
267
if (HAL_ADC_Start_DMA (&descr->adc , (uint32_t *) descr->dmabuf [0 ]->data (), descr->dmabuf [0 ]->size ()) != HAL_OK) {
207
268
return 0 ;
208
269
}
@@ -212,12 +273,24 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
212
273
hal_dma_enable_dbm (&descr->dma , descr->dmabuf [0 ]->data (), descr->dmabuf [1 ]->data ());
213
274
HAL_NVIC_EnableIRQ (descr->dma_irqn );
214
275
276
+ if (do_start)
277
+ {
278
+ return (start (sample_rate));
279
+ }
280
+
281
+ return 1 ;
282
+ }
283
+
284
+ int AdvancedADC::start (uint32_t sample_rate)
285
+ {
215
286
// Init, config and start the ADC timer.
216
287
hal_tim_config (&descr->tim , sample_rate);
288
+
289
+ // Start Timer and ADC Capture. If Dual Mode was enabled, then this will also start ADC2
217
290
if (HAL_TIM_Base_Start (&descr->tim ) != HAL_OK) {
218
291
return 0 ;
219
292
}
220
-
293
+
221
294
return 1 ;
222
295
}
223
296
@@ -227,11 +300,70 @@ int AdvancedADC::stop()
227
300
return 1 ;
228
301
}
229
302
303
+ void AdvancedADC::clear ()
304
+ {
305
+ descr->pool ->flush ();
306
+ }
307
+
230
308
AdvancedADC::~AdvancedADC ()
231
309
{
232
310
dac_descr_deinit (descr, true );
233
311
}
234
312
313
+ int AdvancedADCDual::begin (AdvancedADC *in1, AdvancedADC *in2,uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers)
314
+ {
315
+ adcIN1=in1;
316
+ adcIN2=in2;
317
+
318
+ int result=0 ;
319
+
320
+ // Configure first pin on ADC1
321
+ result=adcIN1->begin (resolution,sample_rate,n_samples,n_buffers,1 ,&(adc_pins_unmapped[0 ]),false ,1 );
322
+ if (result!=1 )
323
+ {
324
+ return (0 );
325
+ }
326
+ // Configure all other pins on ADC2
327
+ result=adcIN2->begin (resolution,sample_rate,n_samples,n_buffers,n_channels-1 ,&(adc_pins_unmapped[1 ]),false ,2 );
328
+ if (result!=1 )
329
+ {
330
+ return (0 );
331
+ }
332
+
333
+ result=hal_enable_dual_mode ();
334
+
335
+ result=adcIN1->start (sample_rate);
336
+
337
+ if (result!=1 )
338
+ {
339
+ return (0 );
340
+ }
341
+
342
+ return (1 );
343
+
344
+ }
345
+
346
+ int AdvancedADCDual:: stop()
347
+ {
348
+ if (adcIN1!=nullptr )
349
+ {
350
+ adcIN1->stop ();
351
+ }
352
+ if (adcIN2!=nullptr )
353
+ {
354
+ adcIN2->stop ();
355
+ }
356
+ // Always disable dual mode when stopped
357
+ int result=hal_disable_dual_mode ();
358
+ return (1 );
359
+
360
+ }
361
+
362
+ AdvancedADCDual::~AdvancedADCDual ()
363
+ {
364
+ int result=stop ();
365
+ }
366
+
235
367
extern " C" {
236
368
void HAL_ADC_ConvCpltCallback (ADC_HandleTypeDef *adc) {
237
369
adc_descr_t *descr = adc_descr_get (adc->Instance );
0 commit comments