[FLYWOOF411] add board documentation
[inav/snaewe.git] / src / main / drivers / adc.c
blob25fb015dab10a1cce502bc241163dc2aaf7c7c2c
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"
24 #include "build/build_config.h"
25 #include "build/debug.h"
27 #include "drivers/time.h"
29 #include "drivers/io.h"
30 #include "drivers/adc.h"
31 #include "drivers/adc_impl.h"
33 #include "common/utils.h"
35 #ifndef ADC_INSTANCE
36 #define ADC_INSTANCE ADC1
37 #endif
39 #ifndef ADC_CHANNEL_1_INSTANCE
40 #define ADC_CHANNEL_1_INSTANCE ADC_INSTANCE
41 #endif
42 #ifndef ADC_CHANNEL_2_INSTANCE
43 #define ADC_CHANNEL_2_INSTANCE ADC_INSTANCE
44 #endif
45 #ifndef ADC_CHANNEL_3_INSTANCE
46 #define ADC_CHANNEL_3_INSTANCE ADC_INSTANCE
47 #endif
48 #ifndef ADC_CHANNEL_4_INSTANCE
49 #define ADC_CHANNEL_4_INSTANCE ADC_INSTANCE
50 #endif
52 #ifdef USE_ADC
54 #if defined(USE_ADC_AVERAGING)
55 static uint8_t activeChannelCount[ADCDEV_COUNT] = {0};
56 #endif
58 static int adcFunctionMap[ADC_FUNCTION_COUNT];
59 adc_config_t adcConfig[ADC_CHN_COUNT]; // index 0 is dummy for ADC_CHN_NONE
60 volatile uint16_t adcValues[ADCDEV_COUNT][ADC_CHN_COUNT * ADC_AVERAGE_N_SAMPLES];
62 uint8_t adcChannelByTag(ioTag_t ioTag)
64 for (uint8_t i = 0; i < ARRAYLEN(adcTagMap); i++) {
65 if (ioTag == adcTagMap[i].tag)
66 return adcTagMap[i].channel;
68 return 0;
71 int adcGetFunctionChannelAllocation(uint8_t function)
73 return adcFunctionMap[function];
76 bool adcIsFunctionAssigned(uint8_t function)
78 // Map function to ADC channel
79 return (adcFunctionMap[function] != ADC_CHN_NONE);
82 uint16_t adcGetChannel(uint8_t function)
84 int channel = adcFunctionMap[function];
85 if (channel == ADC_CHN_NONE)
86 return 0;
88 if (adcConfig[channel].adcDevice != ADCINVALID && adcConfig[channel].enabled) {
89 #if !defined(USE_ADC_AVERAGING)
90 return adcValues[adcConfig[channel].adcDevice][adcConfig[channel].dmaIndex];
91 #else
92 uint32_t acc = 0;
93 for (int i = 0; i < ADC_AVERAGE_N_SAMPLES; i++) {
94 acc += adcValues[adcConfig[channel].adcDevice][adcConfig[channel].dmaIndex + i * activeChannelCount[adcConfig[channel].adcDevice]];
96 return acc / ADC_AVERAGE_N_SAMPLES;
97 #endif
98 } else {
99 return 0;
103 #if defined(ADC_CHANNEL_1_PIN) || defined(ADC_CHANNEL_2_PIN) || defined(ADC_CHANNEL_3_PIN) || defined(ADC_CHANNEL_4_PIN)
104 static bool isChannelInUse(int channel)
106 for (int i = 0; i < ADC_FUNCTION_COUNT; i++) {
107 if (adcFunctionMap[i] == channel)
108 return true;
111 return false;
113 #endif
115 #if !defined(ADC_CHANNEL_1_PIN) || !defined(ADC_CHANNEL_2_PIN) || !defined(ADC_CHANNEL_3_PIN) || !defined(ADC_CHANNEL_4_PIN)
116 static void disableChannelMapping(int channel)
118 for (int i = 0; i < ADC_FUNCTION_COUNT; i++) {
119 if (adcFunctionMap[i] == channel) {
120 adcFunctionMap[i] = ADC_CHN_NONE;
124 #endif
126 void adcInit(drv_adc_config_t *init)
128 memset(&adcConfig, 0, sizeof(adcConfig));
130 // Remember ADC function to ADC channel mapping
131 for (int i = 0; i < ADC_FUNCTION_COUNT; i++) {
132 if (init->adcFunctionChannel[i] >= ADC_CHN_1 && init->adcFunctionChannel[i] <= ADC_CHN_MAX) {
133 adcFunctionMap[i] = init->adcFunctionChannel[i];
135 else {
136 adcFunctionMap[i] = ADC_CHN_NONE;
140 #ifdef ADC_CHANNEL_1_PIN
141 if (isChannelInUse(ADC_CHN_1)) {
142 adcConfig[ADC_CHN_1].adcDevice = adcDeviceByInstance(ADC_CHANNEL_1_INSTANCE);
143 if (adcConfig[ADC_CHN_1].adcDevice != ADCINVALID) {
144 adcConfig[ADC_CHN_1].tag = IO_TAG(ADC_CHANNEL_1_PIN);
145 #if defined(USE_ADC_AVERAGING)
146 activeChannelCount[adcConfig[ADC_CHN_1].adcDevice] += 1;
147 #endif
150 #else
151 disableChannelMapping(ADC_CHN_1);
152 #endif
154 #ifdef ADC_CHANNEL_2_PIN
155 if (isChannelInUse(ADC_CHN_2)) {
156 adcConfig[ADC_CHN_2].adcDevice = adcDeviceByInstance(ADC_CHANNEL_2_INSTANCE);
157 if (adcConfig[ADC_CHN_2].adcDevice != ADCINVALID) {
158 adcConfig[ADC_CHN_2].tag = IO_TAG(ADC_CHANNEL_2_PIN);
159 #if defined(USE_ADC_AVERAGING)
160 activeChannelCount[adcConfig[ADC_CHN_2].adcDevice] += 1;
161 #endif
164 #else
165 disableChannelMapping(ADC_CHN_2);
166 #endif
168 #ifdef ADC_CHANNEL_3_PIN
169 if (isChannelInUse(ADC_CHN_3)) {
170 adcConfig[ADC_CHN_3].adcDevice = adcDeviceByInstance(ADC_CHANNEL_3_INSTANCE);
171 if (adcConfig[ADC_CHN_3].adcDevice != ADCINVALID) {
172 adcConfig[ADC_CHN_3].tag = IO_TAG(ADC_CHANNEL_3_PIN);
173 #if defined(USE_ADC_AVERAGING)
174 activeChannelCount[adcConfig[ADC_CHN_3].adcDevice] += 1;
175 #endif
178 #else
179 disableChannelMapping(ADC_CHN_3);
180 #endif
182 #ifdef ADC_CHANNEL_4_PIN
183 if (isChannelInUse(ADC_CHN_4)) {
184 adcConfig[ADC_CHN_4].adcDevice = adcDeviceByInstance(ADC_CHANNEL_4_INSTANCE);
185 if (adcConfig[ADC_CHN_4].adcDevice != ADCINVALID) {
186 adcConfig[ADC_CHN_4].tag = IO_TAG(ADC_CHANNEL_4_PIN);
187 #if defined(USE_ADC_AVERAGING)
188 activeChannelCount[adcConfig[ADC_CHN_4].adcDevice] += 1;
189 #endif
192 #else
193 disableChannelMapping(ADC_CHN_4);
194 #endif
197 adcHardwareInit(init);
200 #else
202 uint16_t adcGetChannel(uint8_t channel)
204 UNUSED(channel);
205 return 0;
208 #endif