1+ #include " stm32_adc_utils.h"
2+
3+ #if defined(_STM32_DEF_)
4+
5+ // for searching the best ADCs, we need to know the number of ADCs
6+ // it might be better to use some HAL variable for example ADC_COUNT
7+ // here I've assumed the maximum number of ADCs is 5
8+ #define ADC_COUNT 5
9+
10+ /* *
11+ * @brief Return ADC HAL channel linked to a PinName
12+ * @param pin: PinName
13+ * @retval Valid HAL channel
14+ */
15+ uint32_t _getADCChannel (PinName pin)
16+ {
17+ uint32_t function = pinmap_function (pin, PinMap_ADC);
18+ uint32_t channel = 0 ;
19+ switch (STM_PIN_CHANNEL (function)) {
20+ #ifdef ADC_CHANNEL_0
21+ case 0 :
22+ channel = ADC_CHANNEL_0;
23+ break ;
24+ #endif
25+ case 1 :
26+ channel = ADC_CHANNEL_1;
27+ break ;
28+ case 2 :
29+ channel = ADC_CHANNEL_2;
30+ break ;
31+ case 3 :
32+ channel = ADC_CHANNEL_3;
33+ break ;
34+ case 4 :
35+ channel = ADC_CHANNEL_4;
36+ break ;
37+ case 5 :
38+ channel = ADC_CHANNEL_5;
39+ break ;
40+ case 6 :
41+ channel = ADC_CHANNEL_6;
42+ break ;
43+ case 7 :
44+ channel = ADC_CHANNEL_7;
45+ break ;
46+ case 8 :
47+ channel = ADC_CHANNEL_8;
48+ break ;
49+ case 9 :
50+ channel = ADC_CHANNEL_9;
51+ break ;
52+ case 10 :
53+ channel = ADC_CHANNEL_10;
54+ break ;
55+ case 11 :
56+ channel = ADC_CHANNEL_11;
57+ break ;
58+ case 12 :
59+ channel = ADC_CHANNEL_12;
60+ break ;
61+ case 13 :
62+ channel = ADC_CHANNEL_13;
63+ break ;
64+ case 14 :
65+ channel = ADC_CHANNEL_14;
66+ break ;
67+ case 15 :
68+ channel = ADC_CHANNEL_15;
69+ break ;
70+ #ifdef ADC_CHANNEL_16
71+ case 16 :
72+ channel = ADC_CHANNEL_16;
73+ break ;
74+ #endif
75+ case 17 :
76+ channel = ADC_CHANNEL_17;
77+ break ;
78+ #ifdef ADC_CHANNEL_18
79+ case 18 :
80+ channel = ADC_CHANNEL_18;
81+ break ;
82+ #endif
83+ #ifdef ADC_CHANNEL_19
84+ case 19 :
85+ channel = ADC_CHANNEL_19;
86+ break ;
87+ #endif
88+ #ifdef ADC_CHANNEL_20
89+ case 20 :
90+ channel = ADC_CHANNEL_20;
91+ break ;
92+ case 21 :
93+ channel = ADC_CHANNEL_21;
94+ break ;
95+ case 22 :
96+ channel = ADC_CHANNEL_22;
97+ break ;
98+ case 23 :
99+ channel = ADC_CHANNEL_23;
100+ break ;
101+ #ifdef ADC_CHANNEL_24
102+ case 24 :
103+ channel = ADC_CHANNEL_24;
104+ break ;
105+ case 25 :
106+ channel = ADC_CHANNEL_25;
107+ break ;
108+ case 26 :
109+ channel = ADC_CHANNEL_26;
110+ break ;
111+ #ifdef ADC_CHANNEL_27
112+ case 27 :
113+ channel = ADC_CHANNEL_27;
114+ break ;
115+ case 28 :
116+ channel = ADC_CHANNEL_28;
117+ break ;
118+ case 29 :
119+ channel = ADC_CHANNEL_29;
120+ break ;
121+ case 30 :
122+ channel = ADC_CHANNEL_30;
123+ break ;
124+ case 31 :
125+ channel = ADC_CHANNEL_31;
126+ break ;
127+ #endif
128+ #endif
129+ #endif
130+ default :
131+ _Error_Handler (" ADC: Unknown adc channel" , (int )(STM_PIN_CHANNEL (function)));
132+ break ;
133+ }
134+ return channel;
135+ }
136+
137+
138+ int _adcToIndex (ADC_TypeDef *AdcHandle){
139+ if (AdcHandle == ADC1) return 0 ;
140+ #ifdef ADC2 // if ADC2 exists
141+ else if (AdcHandle == ADC2) return 1 ;
142+ #endif
143+ #ifdef ADC3 // if ADC3 exists
144+ else if (AdcHandle == ADC3) return 2 ;
145+ #endif
146+ #ifdef ADC4 // if ADC4 exists
147+ else if (AdcHandle == ADC4) return 3 ;
148+ #endif
149+ #ifdef ADC5 // if ADC5 exists
150+ else if (AdcHandle == ADC5) return 4 ;
151+ #endif
152+ return 0 ;
153+ }
154+ int _adcToIndex (ADC_HandleTypeDef *AdcHandle){
155+ return _adcToIndex (AdcHandle->Instance );
156+ }
157+
158+
159+ ADC_TypeDef* _indexToADC (uint8_t index){
160+ switch (index) {
161+ case 0 :
162+ return ADC1;
163+ break ;
164+ #ifdef ADC2 // if ADC2 exists
165+ case 1 :
166+ return ADC2;
167+ break ;
168+ #endif
169+ #ifdef ADC3 // if ADC3 exists
170+ case 2 :
171+ return ADC3;
172+ break ;
173+ #endif
174+ #ifdef ADC4 // if ADC4 exists
175+ case 3 :
176+ return ADC4;
177+ break ;
178+ #endif
179+ #ifdef ADC5 // if ADC5 exists
180+ case 4 :
181+ return ADC5;
182+ break ;
183+ #endif
184+ }
185+ return nullptr ;
186+ }
187+
188+
189+ // functions finding the index of the first pin entry in the PinMap_ADC
190+ // returns -1 if not found
191+ int _findIndexOfFirstPinMapADCEntry (int pin) {
192+ PinName pinName = digitalPinToPinName (pin);
193+ int i = 0 ;
194+ while ((PinMap_ADC[i].pin & ~ALTX_MASK) !=NC) {
195+ if (pinName == (PinMap_ADC[i].pin & ~ALTX_MASK))
196+ return i;
197+ i++;
198+ }
199+ return -1 ;
200+ }
201+
202+ // functions finding the index of the last pin entry in the PinMap_ADC
203+ // returns -1 if not found
204+ int _findIndexOfLastPinMapADCEntry (int pin) {
205+ PinName pinName = digitalPinToPinName (pin);
206+ int i = 0 ;
207+ while (PinMap_ADC[i].pin !=NC) {
208+ if ( pinName == (PinMap_ADC[i].pin & ~ALTX_MASK)
209+ && pinName != (PinMap_ADC[i+1 ].pin & ~ALTX_MASK))
210+ return i;
211+ i++;
212+ }
213+ return -1 ;
214+ }
215+
216+ // find the best ADC combination for the given pins
217+ // returns the index of the best ADC
218+ // each pin can be connected to multiple ADCs
219+ // the function will try to find a single ADC that can be used for all pins
220+ // if not possible it will return nullptr
221+ ADC_TypeDef* _findBestADCForPins (int numPins, int pins[]) {
222+
223+ // assuning that there is less than 8 ADCs
224+ uint8_t pins_at_adc[ADC_COUNT] = {0 };
225+
226+ // check how many pins are there and are not set
227+ int no_pins = 0 ;
228+ for (int i = 0 ; i < numPins; i++) {
229+ if (_isset (pins[i])) no_pins++;
230+ }
231+
232+ // loop over all elements and count the pins connected to each ADC
233+ for (int i = 0 ; i < numPins; i++) {
234+ int pin = pins[i];
235+ if (!_isset (pin)) continue ;
236+
237+ int index = _findIndexOfFirstPinMapADCEntry (pin);
238+ int last_index = _findIndexOfLastPinMapADCEntry (pin);
239+ if (index == -1 ) {
240+ return nullptr ;
241+ }
242+ for (int j = index; j <= last_index; j++) {
243+ if (PinMap_ADC[j].pin == NC) {
244+ break ;
245+ }
246+ int adcIndex = _adcToIndex ((ADC_TypeDef*)PinMap_ADC[j].peripheral );
247+ pins_at_adc[adcIndex]++;
248+ }
249+ }
250+
251+ for (int i = 0 ; i < ADC_COUNT; i++) {
252+ if (!pins_at_adc[i]) continue ;
253+ SimpleFOCDebug::print (" STM32-CS: ADC" );
254+ SimpleFOCDebug::print (i+1 );
255+ SimpleFOCDebug::print (" pins: " );
256+ SimpleFOCDebug::println (pins_at_adc[i]);
257+ }
258+
259+ // now take the first ADC that has all pins connected
260+ for (int i = 0 ; i < ADC_COUNT; i++) {
261+ if (pins_at_adc[i] == no_pins) {
262+ return _indexToADC (i);
263+ }
264+ }
265+ return nullptr ;
266+ }
267+
268+ #endif
0 commit comments