@@ -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+
3738static 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
4647static 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