@@ -115,42 +115,74 @@ 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.
145
+
146
+ // Check if pin is mapped.
147
+ if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
148
+ break ;
149
+ }
140
150
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;
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 ]);
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 ];// assumes adc_decr_all[0]==>ADC1
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
153
183
184
+ }
185
+
154
186
if (instance == ADC_NP) {
155
187
// Couldn't find a free ADC/descriptor.
156
188
descr = nullptr ;
@@ -159,11 +191,40 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
159
191
160
192
// Configure ADC pins.
161
193
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++) {
165
- // Calculate alternate function pin.
166
- PinName pin = (PinName) (adc_pins[i] | adc_pin_alt[j]);
194
+
195
+ // If ADC was not specified ensure the remaining channels are mappable to same ADC
196
+ if (adcNum==0 )
197
+ {
198
+ uint8_t ch_init = 1 ;
199
+ for (size_t i=1 ; i<n_channels; i++) {
200
+ for (size_t j=0 ; j<AN_ARRAY_SIZE (adc_pin_alt); j++) {
201
+ // Calculate alternate function pin.
202
+ PinName pin = (PinName) (adc_pins[i] | adc_pin_alt[j]);
203
+ // Check if pin is mapped.
204
+ if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
205
+ break ;
206
+ }
207
+ // Check if pin is connected to the selected ADC.
208
+ if (instance == pinmap_peripheral (pin, PinMap_ADC)) {
209
+ pinmap_pinout (pin, PinMap_ADC);
210
+ adc_pins[i] = pin;
211
+ ch_init++;
212
+ break ;
213
+ }
214
+ }
215
+ }
216
+ // All channels must share the same instance; if not, bail out.
217
+ if (ch_init < n_channels) {
218
+ return 0 ;
219
+ }
220
+ }
221
+ else if (adcNum>0 ) // If specific ADC was requested ensure all other channels map to that same ADC
222
+ {
223
+ uint8_t ch_init = 1 ;
224
+ for (size_t i=1 ; i<n_channels; i++) {
225
+
226
+ // Calculate alternate function pin.
227
+ PinName pin = (PinName) (adc_pins[i] | adc_pin_alt[adcNum-1 ]);
167
228
// Check if pin is mapped.
168
229
if (pinmap_find_peripheral (pin, PinMap_ADC) == NC) {
169
230
break ;
@@ -173,21 +234,22 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
173
234
pinmap_pinout (pin, PinMap_ADC);
174
235
adc_pins[i] = pin;
175
236
ch_init++;
176
- break ;
177
237
}
178
238
}
239
+ // All channels must share the same instance; if not, bail out.
240
+ if (ch_init < n_channels) {
241
+ return 0 ;
242
+ }
179
243
}
180
-
181
- // All channels must share the same instance; if not, bail out.
182
- if (ch_init < n_channels) {
183
- return 0 ;
184
- }
185
-
244
+
245
+
186
246
// Allocate DMA buffer pool.
187
247
descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
188
248
if (descr->pool == nullptr ) {
189
249
return 0 ;
190
250
}
251
+
252
+ // Allocate two DMA buffers for double buffering
191
253
descr->dmabuf [0 ] = descr->pool ->allocate ();
192
254
descr->dmabuf [1 ] = descr->pool ->allocate ();
193
255
@@ -201,23 +263,48 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
201
263
return 0 ;
202
264
}
203
265
266
+ // if start is set, proceed with starting ADC capture
267
+ if (do_start) {
268
+ return (start (sample_rate));
269
+ }
270
+ else if (adcNum==2 && dualMode) /* If dual mode has been enabled and this is ADC2, then we do DMA linking here*/
271
+ {
272
+ // Link DMA handle to ADC handle, and start the ADC.
273
+ __HAL_LINKDMA (&descr->adc , DMA_Handle, descr->dma );
274
+ if (HAL_ADC_Start_DMA (&descr->adc , (uint32_t *) descr->dmabuf [0 ]->data (), descr->dmabuf [0 ]->size ()) != HAL_OK) {
275
+ return 0 ;
276
+ }
277
+
278
+ // Re/enable DMA double buffer mode.
279
+ hal_dma_enable_dbm (&descr->dma , descr->dmabuf [0 ]->data (), descr->dmabuf [1 ]->data ());
280
+ }
281
+ return 1 ;
282
+ }
283
+
284
+ int AdvancedADC::start (uint32_t sample_rate){
285
+
286
+ // This routine links adc and dma already setup via the begin() function, and then starts ADC capture timer
287
+
204
288
// Link DMA handle to ADC handle, and start the ADC.
205
289
__HAL_LINKDMA (&descr->adc , DMA_Handle, descr->dma );
206
290
if (HAL_ADC_Start_DMA (&descr->adc , (uint32_t *) descr->dmabuf [0 ]->data (), descr->dmabuf [0 ]->size ()) != HAL_OK) {
207
291
return 0 ;
208
292
}
209
293
210
294
// Re/enable DMA double buffer mode.
211
- HAL_NVIC_DisableIRQ (descr->dma_irqn );
212
295
hal_dma_enable_dbm (&descr->dma , descr->dmabuf [0 ]->data (), descr->dmabuf [1 ]->data ());
213
- HAL_NVIC_EnableIRQ (descr->dma_irqn );
214
296
215
297
// Init, config and start the ADC timer.
216
298
hal_tim_config (&descr->tim , sample_rate);
299
+
300
+ if (dualMode) // If dual mode was pre-selected, enable it in HW
301
+ int result=enableDualMode ();
302
+
303
+ // Start Timer and ADC Capture. If Dual Mode was enabled, then this will also start ADC2
217
304
if (HAL_TIM_Base_Start (&descr->tim ) != HAL_OK) {
218
305
return 0 ;
219
306
}
220
-
307
+
221
308
return 1 ;
222
309
}
223
310
0 commit comments