Skip to content

Commit df7d73d

Browse files
authored
Update AdvancedADC.cpp
Added modified begin() and new start() routine
1 parent 0312c3c commit df7d73d

File tree

1 file changed

+120
-33
lines changed

1 file changed

+120
-33
lines changed

src/AdvancedADC.cpp

+120-33
Original file line numberDiff line numberDiff line change
@@ -115,42 +115,74 @@ 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.
145+
146+
// Check if pin is mapped.
147+
if (pinmap_find_peripheral(pin, PinMap_ADC) == NC) {
148+
break;
149+
}
140150

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+
}
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]);
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
153183

184+
}
185+
154186
if (instance == ADC_NP) {
155187
// Couldn't find a free ADC/descriptor.
156188
descr = nullptr;
@@ -159,11 +191,40 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
159191

160192
// Configure ADC pins.
161193
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]);
167228
// Check if pin is mapped.
168229
if (pinmap_find_peripheral(pin, PinMap_ADC) == NC) {
169230
break;
@@ -173,21 +234,22 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
173234
pinmap_pinout(pin, PinMap_ADC);
174235
adc_pins[i] = pin;
175236
ch_init++;
176-
break;
177237
}
178238
}
239+
// All channels must share the same instance; if not, bail out.
240+
if (ch_init < n_channels) {
241+
return 0;
242+
}
179243
}
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+
186246
// Allocate DMA buffer pool.
187247
descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
188248
if (descr->pool == nullptr) {
189249
return 0;
190250
}
251+
252+
//Allocate two DMA buffers for double buffering
191253
descr->dmabuf[0] = descr->pool->allocate();
192254
descr->dmabuf[1] = descr->pool->allocate();
193255

@@ -201,23 +263,48 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
201263
return 0;
202264
}
203265

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+
204288
// Link DMA handle to ADC handle, and start the ADC.
205289
__HAL_LINKDMA(&descr->adc, DMA_Handle, descr->dma);
206290
if (HAL_ADC_Start_DMA(&descr->adc, (uint32_t *) descr->dmabuf[0]->data(), descr->dmabuf[0]->size()) != HAL_OK) {
207291
return 0;
208292
}
209293

210294
// Re/enable DMA double buffer mode.
211-
HAL_NVIC_DisableIRQ(descr->dma_irqn);
212295
hal_dma_enable_dbm(&descr->dma, descr->dmabuf[0]->data(), descr->dmabuf[1]->data());
213-
HAL_NVIC_EnableIRQ(descr->dma_irqn);
214296

215297
// Init, config and start the ADC timer.
216298
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
217304
if (HAL_TIM_Base_Start(&descr->tim) != HAL_OK) {
218305
return 0;
219306
}
220-
307+
221308
return 1;
222309
}
223310

0 commit comments

Comments
 (0)