Set blackbox file handler to NULL after closing file
[inav.git] / src / main / drivers / adc.c
blob679723e0a83535867933ef8ce8db4ef4c9276bc9
1 /*
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/>.
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <string.h>
22 #include "platform.h"
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"
34 #ifndef ADC_INSTANCE
35 #define ADC_INSTANCE ADC1
36 #endif
38 #ifndef ADC_CHANNEL_1_INSTANCE
39 #define ADC_CHANNEL_1_INSTANCE ADC_INSTANCE
40 #endif
41 #ifndef ADC_CHANNEL_2_INSTANCE
42 #define ADC_CHANNEL_2_INSTANCE ADC_INSTANCE
43 #endif
44 #ifndef ADC_CHANNEL_3_INSTANCE
45 #define ADC_CHANNEL_3_INSTANCE ADC_INSTANCE
46 #endif
47 #ifndef ADC_CHANNEL_4_INSTANCE
48 #define ADC_CHANNEL_4_INSTANCE ADC_INSTANCE
49 #endif
50 #ifndef ADC_CHANNEL_5_INSTANCE
51 #define ADC_CHANNEL_5_INSTANCE ADC_INSTANCE
52 #endif
53 #ifndef ADC_CHANNEL_6_INSTANCE
54 #define ADC_CHANNEL_6_INSTANCE ADC_INSTANCE
55 #endif
58 #ifdef USE_ADC
60 #if defined(USE_ADC_AVERAGING)
61 static uint8_t activeChannelCount[ADCDEV_COUNT] = {0};
62 #endif
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;
74 return 0;
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)
92 return 0;
94 if (adcConfig[channel].adcDevice != ADCINVALID && adcConfig[channel].enabled) {
95 #if !defined(USE_ADC_AVERAGING)
96 return adcValues[adcConfig[channel].adcDevice][adcConfig[channel].dmaIndex];
97 #else
98 uint32_t acc = 0;
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;
103 #endif
104 } else {
105 return 0;
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)
114 return true;
117 return false;
119 #endif
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;
130 #endif
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];
141 else {
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;
153 #endif
156 #else
157 disableChannelMapping(ADC_CHN_1);
158 #endif
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;
167 #endif
170 #else
171 disableChannelMapping(ADC_CHN_2);
172 #endif
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;
181 #endif
184 #else
185 disableChannelMapping(ADC_CHN_3);
186 #endif
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;
195 #endif
198 #else
199 disableChannelMapping(ADC_CHN_4);
200 #endif
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;
209 #endif
212 #else
213 disableChannelMapping(ADC_CHN_5);
214 #endif
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;
223 #endif
226 #else
227 disableChannelMapping(ADC_CHN_6);
228 #endif
230 adcHardwareInit(init);
233 #else
235 uint16_t adcGetChannel(uint8_t channel)
237 UNUSED(channel);
238 return 0;
241 #endif
243 #else // USE_ADC
245 bool adcIsFunctionAssigned(uint8_t function)
247 UNUSED(function);
248 return false;
251 void adcInit(drv_adc_config_t *init)
253 UNUSED(init);
256 uint16_t adcGetChannel(uint8_t channel)
258 UNUSED(channel);
259 return 0;
261 #endif