Skip to content

Commit 9bd88c0

Browse files
fix adc.begin() to correctly initialize channels according to selected pins
1 parent 9e610e2 commit 9bd88c0

File tree

1 file changed

+44
-17
lines changed

1 file changed

+44
-17
lines changed

src/AdvancedADC.cpp

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,19 @@ struct adc_descr_t {
2929
IRQn_Type dma_irqn;
3030
TIM_HandleTypeDef tim;
3131
uint32_t tim_trig;
32-
uint32_t pin_alt;
3332
DMABufferPool<Sample> *pool;
3433
DMABuffer<Sample> *dmabuf[2];
3534
};
3635

36+
static uint32_t pin_alt[3] = {0, ALT0, ALT1};
37+
3738
static adc_descr_t adc_descr_all[3] = {
3839
{{ADC1}, {DMA1_Stream1, {DMA_REQUEST_ADC1}}, DMA1_Stream1_IRQn, {TIM1}, ADC_EXTERNALTRIG_T1_TRGO,
39-
0, nullptr, {nullptr, nullptr}},
40+
nullptr, {nullptr, nullptr}},
4041
{{ADC2}, {DMA1_Stream2, {DMA_REQUEST_ADC2}}, DMA1_Stream2_IRQn, {TIM2}, ADC_EXTERNALTRIG_T2_TRGO,
41-
ALT0, nullptr, {nullptr, nullptr}},
42+
nullptr, {nullptr, nullptr}},
4243
{{ADC3}, {DMA1_Stream3, {DMA_REQUEST_ADC3}}, DMA1_Stream3_IRQn, {TIM3}, ADC_EXTERNALTRIG_T3_TRGO,
43-
ALT1, nullptr, {nullptr, nullptr}},
44+
nullptr, {nullptr, nullptr}},
4445
};
4546

4647
static uint32_t ADC_RES_LUT[] = {
@@ -121,13 +122,28 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
121122
return 0;
122123
}
123124

125+
// Clear ALTx pin.
126+
for (size_t i=0; i<n_channels; i++) {
127+
for (size_t j=0; j<AN_ARRAY_SIZE(pin_alt); j++) {
128+
adc_pins[i] = (PinName) (adc_pins[i] & ~(uint32_t)pin_alt[j]);
129+
}
130+
}
131+
124132
// Find an ADC that can be used with these set of pins/channels.
125-
for (size_t i=0; instance == ADC_NP && i<AN_ARRAY_SIZE(adc_descr_all); i++) {
126-
descr = &adc_descr_all[i];
127-
if (descr->pool == nullptr) {
128-
// Check if the first channel is connected to this ADC.
129-
PinName pin = (PinName) (adc_pins[0] | descr->pin_alt);
130-
instance = (ADCName) pinmap_peripheral(pin, PinMap_ADC);
133+
for (size_t i=0; instance == ADC_NP && i<AN_ARRAY_SIZE(pin_alt); i++) {
134+
// Calculate alternate function pin.
135+
PinName pin = (PinName) (adc_pins[0] | pin_alt[i]); // First pin decides the ADC.
136+
137+
// Check if pin is mapped.
138+
if (pinmap_find_peripheral(pin, PinMap_ADC) == NC) break;
139+
140+
// Find the first free ADC according to the available ADCs on pin.
141+
for (size_t j=0; instance == ADC_NP && j<AN_ARRAY_SIZE(adc_descr_all); j++) {
142+
descr = &adc_descr_all[j];
143+
if (descr->pool == nullptr && ((ADC_TypeDef*)pinmap_peripheral(pin, PinMap_ADC) == descr->adc.Instance)) {
144+
instance = (ADCName) pinmap_peripheral(pin, PinMap_ADC);
145+
adc_pins[0] = pin;
146+
}
131147
}
132148
}
133149

@@ -138,16 +154,27 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
138154
}
139155

140156
// Configure ADC pins.
141-
for (size_t i=0; i<n_channels; i++) {
142-
// Set the alternate pin names for this ADC instance.
143-
adc_pins[i] = (PinName) (adc_pins[i] | descr->pin_alt);
144-
// All channels must share the same instance; if not, bail out
145-
if (instance != pinmap_peripheral(adc_pins[i], PinMap_ADC)) {
146-
return 0;
157+
pinmap_pinout(adc_pins[0], PinMap_ADC);
158+
uint8_t ch_init = 1;
159+
for (size_t i=1; i<n_channels; i++) {
160+
for (size_t j=0; j<AN_ARRAY_SIZE(pin_alt); j++) {
161+
// Calculate alternate function pin.
162+
PinName pin = (PinName) (adc_pins[i] | pin_alt[j]);
163+
// Check if pin is mapped.
164+
if (pinmap_find_peripheral(pin, PinMap_ADC) == NC) break;
165+
// Check if pin is connected to the selected ADC.
166+
if (instance == pinmap_peripheral(pin, PinMap_ADC)) {
167+
pinmap_pinout(pin, PinMap_ADC);
168+
adc_pins[i] = pin;
169+
ch_init++;
170+
break;
171+
}
147172
}
148-
pinmap_pinout(adc_pins[i], PinMap_ADC);
149173
}
150174

175+
// All channels must share the same instance; if not, bail out.
176+
if (ch_init < n_channels) return 0;
177+
151178
// Allocate DMA buffer pool.
152179
descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
153180
if (descr->pool == nullptr) {

0 commit comments

Comments
 (0)