2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "build/build_config.h"
24 #include "build/debug.h"
25 #include "drivers/time.h"
26 #include "common/utils.h"
28 #include "drivers/adc.h"
29 #if defined(USE_ADC) && !defined(SITL_BUILD)
30 #include "drivers/io.h"
32 #include "drivers/adc_impl.h"
35 #define ADC_INSTANCE ADC1
38 #ifndef ADC_CHANNEL_1_INSTANCE
39 #define ADC_CHANNEL_1_INSTANCE ADC_INSTANCE
41 #ifndef ADC_CHANNEL_2_INSTANCE
42 #define ADC_CHANNEL_2_INSTANCE ADC_INSTANCE
44 #ifndef ADC_CHANNEL_3_INSTANCE
45 #define ADC_CHANNEL_3_INSTANCE ADC_INSTANCE
47 #ifndef ADC_CHANNEL_4_INSTANCE
48 #define ADC_CHANNEL_4_INSTANCE ADC_INSTANCE
50 #ifndef ADC_CHANNEL_5_INSTANCE
51 #define ADC_CHANNEL_5_INSTANCE ADC_INSTANCE
53 #ifndef ADC_CHANNEL_6_INSTANCE
54 #define ADC_CHANNEL_6_INSTANCE ADC_INSTANCE
60 #if defined(USE_ADC_AVERAGING)
61 static uint8_t activeChannelCount
[ADCDEV_COUNT
] = {0};
64 static int adcFunctionMap
[ADC_FUNCTION_COUNT
];
65 adc_config_t adcConfig
[ADC_CHN_COUNT
]; // index 0 is dummy for ADC_CHN_NONE
66 volatile ADC_VALUES_ALIGNMENT(uint16_t adcValues
[ADCDEV_COUNT
][ADC_CHN_COUNT
* ADC_AVERAGE_N_SAMPLES
]);
68 uint32_t adcChannelByTag(ioTag_t ioTag
)
70 for (uint8_t i
= 0; i
< ARRAYLEN(adcTagMap
); i
++) {
71 if (ioTag
== adcTagMap
[i
].tag
)
72 return adcTagMap
[i
].channel
;
77 int adcGetFunctionChannelAllocation(uint8_t function
)
79 return adcFunctionMap
[function
];
82 bool adcIsFunctionAssigned(uint8_t function
)
84 // Map function to ADC channel
85 return (adcFunctionMap
[function
] != ADC_CHN_NONE
);
88 uint16_t adcGetChannel(uint8_t function
)
90 int channel
= adcFunctionMap
[function
];
91 if (channel
== ADC_CHN_NONE
)
94 if (adcConfig
[channel
].adcDevice
!= ADCINVALID
&& adcConfig
[channel
].enabled
) {
95 #if !defined(USE_ADC_AVERAGING)
96 return adcValues
[adcConfig
[channel
].adcDevice
][adcConfig
[channel
].dmaIndex
];
99 for (int i
= 0; i
< ADC_AVERAGE_N_SAMPLES
; i
++) {
100 acc
+= adcValues
[adcConfig
[channel
].adcDevice
][adcConfig
[channel
].dmaIndex
+ i
* activeChannelCount
[adcConfig
[channel
].adcDevice
]];
102 return acc
/ ADC_AVERAGE_N_SAMPLES
;
109 #if defined(ADC_CHANNEL_1_PIN) || defined(ADC_CHANNEL_2_PIN) || defined(ADC_CHANNEL_3_PIN) || defined(ADC_CHANNEL_4_PIN) || defined(ADC_CHANNEL_5_PIN) || defined(ADC_CHANNEL_6_PIN)
110 static bool isChannelInUse(int channel
)
112 for (int i
= 0; i
< ADC_FUNCTION_COUNT
; i
++) {
113 if (adcFunctionMap
[i
] == channel
)
121 #if !defined(ADC_CHANNEL_1_PIN) || !defined(ADC_CHANNEL_2_PIN) || !defined(ADC_CHANNEL_3_PIN) || !defined(ADC_CHANNEL_4_PIN) || !defined(ADC_CHANNEL_5_PIN) || !defined(ADC_CHANNEL_6_PIN)
122 static void disableChannelMapping(int channel
)
124 for (int i
= 0; i
< ADC_FUNCTION_COUNT
; i
++) {
125 if (adcFunctionMap
[i
] == channel
) {
126 adcFunctionMap
[i
] = ADC_CHN_NONE
;
132 void adcInit(drv_adc_config_t
*init
)
134 memset(&adcConfig
, 0, sizeof(adcConfig
));
136 // Remember ADC function to ADC channel mapping
137 for (int i
= 0; i
< ADC_FUNCTION_COUNT
; i
++) {
138 if (init
->adcFunctionChannel
[i
] >= ADC_CHN_1
&& init
->adcFunctionChannel
[i
] <= ADC_CHN_MAX
) {
139 adcFunctionMap
[i
] = init
->adcFunctionChannel
[i
];
142 adcFunctionMap
[i
] = ADC_CHN_NONE
;
146 #ifdef ADC_CHANNEL_1_PIN
147 if (isChannelInUse(ADC_CHN_1
)) {
148 adcConfig
[ADC_CHN_1
].adcDevice
= adcDeviceByInstance(ADC_CHANNEL_1_INSTANCE
);
149 if (adcConfig
[ADC_CHN_1
].adcDevice
!= ADCINVALID
) {
150 adcConfig
[ADC_CHN_1
].tag
= IO_TAG(ADC_CHANNEL_1_PIN
);
151 #if defined(USE_ADC_AVERAGING)
152 activeChannelCount
[adcConfig
[ADC_CHN_1
].adcDevice
] += 1;
157 disableChannelMapping(ADC_CHN_1
);
160 #ifdef ADC_CHANNEL_2_PIN
161 if (isChannelInUse(ADC_CHN_2
)) {
162 adcConfig
[ADC_CHN_2
].adcDevice
= adcDeviceByInstance(ADC_CHANNEL_2_INSTANCE
);
163 if (adcConfig
[ADC_CHN_2
].adcDevice
!= ADCINVALID
) {
164 adcConfig
[ADC_CHN_2
].tag
= IO_TAG(ADC_CHANNEL_2_PIN
);
165 #if defined(USE_ADC_AVERAGING)
166 activeChannelCount
[adcConfig
[ADC_CHN_2
].adcDevice
] += 1;
171 disableChannelMapping(ADC_CHN_2
);
174 #ifdef ADC_CHANNEL_3_PIN
175 if (isChannelInUse(ADC_CHN_3
)) {
176 adcConfig
[ADC_CHN_3
].adcDevice
= adcDeviceByInstance(ADC_CHANNEL_3_INSTANCE
);
177 if (adcConfig
[ADC_CHN_3
].adcDevice
!= ADCINVALID
) {
178 adcConfig
[ADC_CHN_3
].tag
= IO_TAG(ADC_CHANNEL_3_PIN
);
179 #if defined(USE_ADC_AVERAGING)
180 activeChannelCount
[adcConfig
[ADC_CHN_3
].adcDevice
] += 1;
185 disableChannelMapping(ADC_CHN_3
);
188 #ifdef ADC_CHANNEL_4_PIN
189 if (isChannelInUse(ADC_CHN_4
)) {
190 adcConfig
[ADC_CHN_4
].adcDevice
= adcDeviceByInstance(ADC_CHANNEL_4_INSTANCE
);
191 if (adcConfig
[ADC_CHN_4
].adcDevice
!= ADCINVALID
) {
192 adcConfig
[ADC_CHN_4
].tag
= IO_TAG(ADC_CHANNEL_4_PIN
);
193 #if defined(USE_ADC_AVERAGING)
194 activeChannelCount
[adcConfig
[ADC_CHN_4
].adcDevice
] += 1;
199 disableChannelMapping(ADC_CHN_4
);
202 #ifdef ADC_CHANNEL_5_PIN
203 if (isChannelInUse(ADC_CHN_5
)) {
204 adcConfig
[ADC_CHN_5
].adcDevice
= adcDeviceByInstance(ADC_CHANNEL_5_INSTANCE
);
205 if (adcConfig
[ADC_CHN_5
].adcDevice
!= ADCINVALID
) {
206 adcConfig
[ADC_CHN_5
].tag
= IO_TAG(ADC_CHANNEL_5_PIN
);
207 #if defined(USE_ADC_AVERAGING)
208 activeChannelCount
[adcConfig
[ADC_CHN_5
].adcDevice
] += 1;
213 disableChannelMapping(ADC_CHN_5
);
216 #ifdef ADC_CHANNEL_6_PIN
217 if (isChannelInUse(ADC_CHN_6
)) {
218 adcConfig
[ADC_CHN_6
].adcDevice
= adcDeviceByInstance(ADC_CHANNEL_6_INSTANCE
);
219 if (adcConfig
[ADC_CHN_6
].adcDevice
!= ADCINVALID
) {
220 adcConfig
[ADC_CHN_6
].tag
= IO_TAG(ADC_CHANNEL_6_PIN
);
221 #if defined(USE_ADC_AVERAGING)
222 activeChannelCount
[adcConfig
[ADC_CHN_6
].adcDevice
] += 1;
227 disableChannelMapping(ADC_CHN_6
);
230 adcHardwareInit(init
);
235 uint16_t adcGetChannel(uint8_t channel
)
245 bool adcIsFunctionAssigned(uint8_t function
)
251 void adcInit(drv_adc_config_t
*init
)
256 uint16_t adcGetChannel(uint8_t channel
)