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+
12+ int _adcToIndex (ADC_TypeDef *AdcHandle){
13+ if (AdcHandle == ADC1) return 0 ;
14+ #ifdef ADC2 // if ADC2 exists
15+ else if (AdcHandle == ADC2) return 1 ;
16+ #endif
17+ #ifdef ADC3 // if ADC3 exists
18+ else if (AdcHandle == ADC3) return 2 ;
19+ #endif
20+ #ifdef ADC4 // if ADC4 exists
21+ else if (AdcHandle == ADC4) return 3 ;
22+ #endif
23+ #ifdef ADC5 // if ADC5 exists
24+ else if (AdcHandle == ADC5) return 4 ;
25+ #endif
26+ return 0 ;
27+ }
28+ int _adcToIndex (ADC_HandleTypeDef *AdcHandle){
29+ return _adcToIndex (AdcHandle->Instance );
30+ }
31+
32+
33+ ADC_TypeDef* _indexToADC (uint8_t index){
34+ switch (index) {
35+ case 0 :
36+ return ADC1;
37+ break ;
38+ #ifdef ADC2 // if ADC2 exists
39+ case 1 :
40+ return ADC2;
41+ break ;
42+ #endif
43+ #ifdef ADC3 // if ADC3 exists
44+ case 2 :
45+ return ADC3;
46+ break ;
47+ #endif
48+ #ifdef ADC4 // if ADC4 exists
49+ case 3 :
50+ return ADC4;
51+ break ;
52+ #endif
53+ #ifdef ADC5 // if ADC5 exists
54+ case 4 :
55+ return ADC5;
56+ break ;
57+ #endif
58+ }
59+ return nullptr ;
60+ }
61+
62+ int _findIndexOfEntry (PinName pin) {
63+ // remove the ALT if it is there
64+ PinName pinName = (PinName)(pinName & ~ALTX_MASK);
65+ int i = 0 ;
66+ SIMPLEFOC_DEBUG (" STM32-CS: Looking for pin " );
67+ while (PinMap_ADC[i].pin !=NC) {
68+ if (pinName == PinMap_ADC[i].pin )
69+ return i;
70+ i++;
71+ SIMPLEFOC_DEBUG (" STM32-CS: Looking for pin " , i);
72+ }
73+ return -1 ;
74+ }
75+
76+ int _findIndexOfLastEntry (PinName pin) {
77+ // remove the ALT if it is there
78+ PinName pinName = (PinName)(pin & ~ALTX_MASK);
79+
80+ int i = 0 ;
81+ while (PinMap_ADC[i].pin !=NC) {
82+ if ( pinName == (PinMap_ADC[i].pin & ~ALTX_MASK)
83+ && pinName != (PinMap_ADC[i+1 ].pin & ~ALTX_MASK))
84+ return i;
85+ i++;
86+ }
87+ return -1 ;
88+ }
89+ int _findIndexOfFirstEntry (PinName pin) {
90+ // remove the ALT if it is there
91+ PinName pinName = (PinName)(pin & ~ALTX_MASK);
92+ int i = 0 ;
93+ while (PinMap_ADC[i].pin !=NC) {
94+ if (pinName == PinMap_ADC[i].pin )
95+ return i;
96+ i++;
97+ }
98+ return -1 ;
99+ }
100+
101+ // functions finding the index of the first pin entry in the PinMap_ADC
102+ // returns -1 if not found
103+ int _findIndexOfFirstPinMapADCEntry (int pin) {
104+ PinName pinName = digitalPinToPinName (pin);
105+ // remove the ALT if it is there
106+ return _findIndexOfFirstEntry (pinName);
107+ }
108+
109+ // functions finding the index of the last pin entry in the PinMap_ADC
110+ // returns -1 if not found
111+ int _findIndexOfLastPinMapADCEntry (int pin) {
112+ PinName pinName = digitalPinToPinName (pin);
113+ // remove the ALT if it is there
114+ return _findIndexOfLastEntry (pinName);
115+ }
116+
117+ // find the best ADC combination for the given pins
118+ // returns the index of the best ADC
119+ // each pin can be connected to multiple ADCs
120+ // the function will try to find a single ADC that can be used for all pins
121+ // if not possible it will return nullptr
122+ ADC_TypeDef* _findBestADCForPins (int numPins, int pins[]) {
123+
124+ // assuning that there is less than 8 ADCs
125+ uint8_t pins_at_adc[ADC_COUNT] = {0 };
126+
127+ // check how many pins are there and are not set
128+ int no_pins = 0 ;
129+ for (int i = 0 ; i < numPins; i++) {
130+ if (_isset (pins[i])) no_pins++;
131+ }
132+
133+ // loop over all elements and count the pins connected to each ADC
134+ for (int i = 0 ; i < numPins; i++) {
135+ int pin = pins[i];
136+ if (!_isset (pin)) continue ;
137+
138+ int index = _findIndexOfFirstPinMapADCEntry (pin);
139+ int last_index = _findIndexOfLastPinMapADCEntry (pin);
140+ if (index == -1 ) {
141+ return nullptr ;
142+ }
143+ for (int j = index; j <= last_index; j++) {
144+ if (PinMap_ADC[j].pin == NC) {
145+ break ;
146+ }
147+ int adcIndex = _adcToIndex ((ADC_TypeDef*)PinMap_ADC[j].peripheral );
148+ pins_at_adc[adcIndex]++;
149+ }
150+ }
151+
152+ for (int i = 0 ; i < ADC_COUNT; i++) {
153+ if (!pins_at_adc[i]) continue ;
154+ SimpleFOCDebug::print (" STM32-CS: ADC" );
155+ SimpleFOCDebug::print (i+1 );
156+ SimpleFOCDebug::print (" pins: " );
157+ SimpleFOCDebug::println (pins_at_adc[i]);
158+ }
159+
160+ // now take the first ADC that has all pins connected
161+ for (int i = 0 ; i < ADC_COUNT; i++) {
162+ if (pins_at_adc[i] == no_pins) {
163+ return _indexToADC (i);
164+ }
165+ }
166+ return nullptr ;
167+ }
168+
169+
170+
171+ /* *
172+ * @brief Return ADC HAL channel linked to a PinName
173+ * @param pin: PinName
174+ * @retval Valid HAL channel
175+ */
176+ uint32_t _getADCChannelFromPinMap (PinName pin)
177+ {
178+ uint32_t function = pinmap_function (pin, PinMap_ADC);
179+ uint32_t channel = 0 ;
180+ switch (STM_PIN_CHANNEL (function)) {
181+ #ifdef ADC_CHANNEL_0
182+ case 0 :
183+ channel = ADC_CHANNEL_0;
184+ break ;
185+ #endif
186+ case 1 :
187+ channel = ADC_CHANNEL_1;
188+ break ;
189+ case 2 :
190+ channel = ADC_CHANNEL_2;
191+ break ;
192+ case 3 :
193+ channel = ADC_CHANNEL_3;
194+ break ;
195+ case 4 :
196+ channel = ADC_CHANNEL_4;
197+ break ;
198+ case 5 :
199+ channel = ADC_CHANNEL_5;
200+ break ;
201+ case 6 :
202+ channel = ADC_CHANNEL_6;
203+ break ;
204+ case 7 :
205+ channel = ADC_CHANNEL_7;
206+ break ;
207+ case 8 :
208+ channel = ADC_CHANNEL_8;
209+ break ;
210+ case 9 :
211+ channel = ADC_CHANNEL_9;
212+ break ;
213+ case 10 :
214+ channel = ADC_CHANNEL_10;
215+ break ;
216+ case 11 :
217+ channel = ADC_CHANNEL_11;
218+ break ;
219+ case 12 :
220+ channel = ADC_CHANNEL_12;
221+ break ;
222+ case 13 :
223+ channel = ADC_CHANNEL_13;
224+ break ;
225+ case 14 :
226+ channel = ADC_CHANNEL_14;
227+ break ;
228+ case 15 :
229+ channel = ADC_CHANNEL_15;
230+ break ;
231+ #ifdef ADC_CHANNEL_16
232+ case 16 :
233+ channel = ADC_CHANNEL_16;
234+ break ;
235+ #endif
236+ case 17 :
237+ channel = ADC_CHANNEL_17;
238+ break ;
239+ #ifdef ADC_CHANNEL_18
240+ case 18 :
241+ channel = ADC_CHANNEL_18;
242+ break ;
243+ #endif
244+ #ifdef ADC_CHANNEL_19
245+ case 19 :
246+ channel = ADC_CHANNEL_19;
247+ break ;
248+ #endif
249+ #ifdef ADC_CHANNEL_20
250+ case 20 :
251+ channel = ADC_CHANNEL_20;
252+ break ;
253+ case 21 :
254+ channel = ADC_CHANNEL_21;
255+ break ;
256+ case 22 :
257+ channel = ADC_CHANNEL_22;
258+ break ;
259+ case 23 :
260+ channel = ADC_CHANNEL_23;
261+ break ;
262+ #ifdef ADC_CHANNEL_24
263+ case 24 :
264+ channel = ADC_CHANNEL_24;
265+ break ;
266+ case 25 :
267+ channel = ADC_CHANNEL_25;
268+ break ;
269+ case 26 :
270+ channel = ADC_CHANNEL_26;
271+ break ;
272+ #ifdef ADC_CHANNEL_27
273+ case 27 :
274+ channel = ADC_CHANNEL_27;
275+ break ;
276+ case 28 :
277+ channel = ADC_CHANNEL_28;
278+ break ;
279+ case 29 :
280+ channel = ADC_CHANNEL_29;
281+ break ;
282+ case 30 :
283+ channel = ADC_CHANNEL_30;
284+ break ;
285+ case 31 :
286+ channel = ADC_CHANNEL_31;
287+ break ;
288+ #endif
289+ #endif
290+ #endif
291+ default :
292+ _Error_Handler (" ADC: Unknown adc channel" , (int )(STM_PIN_CHANNEL (function)));
293+ break ;
294+ }
295+ return channel;
296+ }
297+
298+ /* *
299+ * @brief Return ADC HAL channel linked to a PinName and the ADC handle
300+ * @param pin: PinName
301+ * @param AdcHandle: ADC_HandleTypeDef a pointer to the ADC handle
302+ * @retval Valid HAL channel
303+ */
304+ uint32_t _getADCChannel (PinName pin, ADC_TypeDef *AdcHandle )
305+ {
306+ if (AdcHandle == NP) {
307+ return _getADCChannelFromPinMap (pin);
308+ }
309+ // find the PinName that corresponds to the ADC
310+ int first_ind = _findIndexOfFirstEntry (pin);
311+ int last_ind = _findIndexOfLastEntry (pin);
312+ if (first_ind == -1 || last_ind == -1 ) {
313+ _Error_Handler (" ADC: Pin not found in PinMap_ADC" , (int )pin);
314+ }
315+ // find the channel
316+ uint32_t channel = 0 ;
317+ for (int i = first_ind; i <= last_ind; i++) {
318+ if (PinMap_ADC[i].peripheral == AdcHandle) {
319+ channel =_getADCChannelFromPinMap (PinMap_ADC[i].pin );
320+ SIMPLEFOC_DEBUG (" STM32-CS: ADC channel: " , (int )STM_PIN_CHANNEL (pinmap_function (PinMap_ADC[i].pin , PinMap_ADC)));
321+ break ;
322+ }
323+ }
324+ return channel;
325+ }
326+
327+ uint32_t _getADCInjectedRank (uint8_t ind){
328+ switch (ind) {
329+ case 0 :
330+ return ADC_INJECTED_RANK_1;
331+ break ;
332+ case 1 :
333+ return ADC_INJECTED_RANK_2;
334+ break ;
335+ case 2 :
336+ return ADC_INJECTED_RANK_3;
337+ break ;
338+ case 3 :
339+ return ADC_INJECTED_RANK_4;
340+ break ;
341+ default :
342+ return 0 ;
343+ break ;
344+ }
345+ }
346+
347+ #endif
0 commit comments