Skip to content

Commit 7fb56df

Browse files
authored
Update AdvancedADC.cpp
Revised change based on feedback. Added new class AdvancedADCDual. Modified AdvancedADC.begin() to accept optional start and fixed ADC number to allow Dual Mode to be called from AdvancedADCDual.
1 parent 372b127 commit 7fb56df

File tree

1 file changed

+163
-31
lines changed

1 file changed

+163
-31
lines changed

src/AdvancedADC.cpp

+163-31
Original file line numberDiff line numberDiff line change
@@ -115,42 +115,73 @@ DMABuffer<Sample> &AdvancedADC::read() {
115115
return NULLBUF;
116116
}
117117

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+
119120
ADCName instance = ADC_NP;
120-
121121
// Sanity checks.
122122
if (resolution >= AN_ARRAY_SIZE(ADC_RES_LUT) || (descr && descr->pool)) {
123123
return 0;
124124
}
125125

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+
126133
// Clear ALTx pin.
127134
for (size_t i=0; i<n_channels; i++) {
128135
adc_pins[i] = (PinName) (adc_pins[i] & ~(ADC_PIN_ALT_MASK));
129136
}
130137

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.
135138

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.
140145

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+
}
149161
}
150162
}
151163
}
152164
}
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]);
153168

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+
154185
if (instance == ADC_NP) {
155186
// Couldn't find a free ADC/descriptor.
156187
descr = nullptr;
@@ -159,11 +190,40 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
159190

160191
// Configure ADC pins.
161192
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+
165225
// 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]);
167227
// Check if pin is mapped.
168228
if (pinmap_find_peripheral(pin, PinMap_ADC) == NC) {
169229
break;
@@ -173,21 +233,22 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
173233
pinmap_pinout(pin, PinMap_ADC);
174234
adc_pins[i] = pin;
175235
ch_init++;
176-
break;
177236
}
178237
}
238+
// All channels must share the same instance; if not, bail out.
239+
if (ch_init < n_channels) {
240+
return 0;
241+
}
179242
}
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+
186245
// Allocate DMA buffer pool.
187246
descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
188247
if (descr->pool == nullptr) {
189248
return 0;
190249
}
250+
251+
//Allocate two DMA buffers for double buffering
191252
descr->dmabuf[0] = descr->pool->allocate();
192253
descr->dmabuf[1] = descr->pool->allocate();
193254

@@ -202,7 +263,7 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
202263
}
203264

204265
// 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);
206267
if (HAL_ADC_Start_DMA(&descr->adc, (uint32_t *) descr->dmabuf[0]->data(), descr->dmabuf[0]->size()) != HAL_OK) {
207268
return 0;
208269
}
@@ -212,12 +273,24 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
212273
hal_dma_enable_dbm(&descr->dma, descr->dmabuf[0]->data(), descr->dmabuf[1]->data());
213274
HAL_NVIC_EnableIRQ(descr->dma_irqn);
214275

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+
{
215286
// Init, config and start the ADC timer.
216287
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
217290
if (HAL_TIM_Base_Start(&descr->tim) != HAL_OK) {
218291
return 0;
219292
}
220-
293+
221294
return 1;
222295
}
223296

@@ -227,11 +300,70 @@ int AdvancedADC::stop()
227300
return 1;
228301
}
229302

303+
void AdvancedADC::clear()
304+
{
305+
descr->pool->flush();
306+
}
307+
230308
AdvancedADC::~AdvancedADC()
231309
{
232310
dac_descr_deinit(descr, true);
233311
}
234312

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+
235367
extern "C" {
236368
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *adc) {
237369
adc_descr_t *descr = adc_descr_get(adc->Instance);

0 commit comments

Comments
 (0)