analog.c (21789B)
1 /* Copyright 2019 Drew Mills 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "analog.h" 18 #include <ch.h> 19 #include <hal.h> 20 21 #if !HAL_USE_ADC 22 # error "You need to set HAL_USE_ADC to TRUE in your halconf.h to use the ADC." 23 #endif 24 25 #if !RP_ADC_USE_ADC1 && !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3 && !STM32_ADC_USE_ADC4 && !WB32_ADC_USE_ADC1 && !AT32_ADC_USE_ADC1 26 # error "You need to set one of the 'xxx_ADC_USE_ADCx' settings to TRUE in your mcuconf.h to use the ADC." 27 #endif 28 29 #if STM32_ADC_DUAL_MODE 30 # error "STM32 ADC Dual Mode is not supported at this time." 31 #endif 32 33 #if STM32_ADCV3_OVERSAMPLING 34 // Apparently all ADCV3 chips that support oversampling (STM32L4xx, STM32L4xx+, 35 // STM32G4xx, STM32WB[35]x) have errata like “Wrong ADC result if conversion 36 // done late after calibration or previous conversion”; the workaround is to 37 // perform a dummy conversion and discard its result. STM32G4xx chips also 38 // have the “ADC channel 0 converted instead of the required ADC channel” 39 // errata, one workaround for which is also to perform a dummy conversion. 40 # define ADC_DUMMY_CONVERSIONS_AT_START 1 41 #else 42 # define ADC_DUMMY_CONVERSIONS_AT_START 0 43 #endif 44 45 // Otherwise assume V3 46 #if defined(STM32F0XX) || defined(STM32L0XX) || defined(STM32G0XX) 47 # define USE_ADCV1 48 #elif defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(GD32VF103) || defined(WB32F3G71xx) || defined(WB32FQ95xx) || defined(AT32F415) 49 # define USE_ADCV2 50 #endif 51 52 // BODGE to make v2 look like v1,3 and 4 53 #if defined(USE_ADCV2) || defined(RP2040) 54 # if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_3) 55 # define ADC_SMPR_SMP_1P5 ADC_SAMPLE_3 56 # define ADC_SMPR_SMP_7P5 ADC_SAMPLE_15 57 # define ADC_SMPR_SMP_13P5 ADC_SAMPLE_28 58 # define ADC_SMPR_SMP_28P5 ADC_SAMPLE_56 59 # define ADC_SMPR_SMP_41P5 ADC_SAMPLE_84 60 # define ADC_SMPR_SMP_55P5 ADC_SAMPLE_112 61 # define ADC_SMPR_SMP_71P5 ADC_SAMPLE_144 62 # define ADC_SMPR_SMP_239P5 ADC_SAMPLE_480 63 # endif 64 65 # if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_1P5) 66 # define ADC_SMPR_SMP_1P5 ADC_SAMPLE_1P5 67 # define ADC_SMPR_SMP_7P5 ADC_SAMPLE_7P5 68 # define ADC_SMPR_SMP_13P5 ADC_SAMPLE_13P5 69 # define ADC_SMPR_SMP_28P5 ADC_SAMPLE_28P5 70 # define ADC_SMPR_SMP_41P5 ADC_SAMPLE_41P5 71 # define ADC_SMPR_SMP_55P5 ADC_SAMPLE_55P5 72 # define ADC_SMPR_SMP_71P5 ADC_SAMPLE_71P5 73 # define ADC_SMPR_SMP_239P5 ADC_SAMPLE_239P5 74 # endif 75 76 // we still sample at 12bit, but scale down to the requested bit range 77 # define ADC_CFGR1_RES_12BIT 12 78 # define ADC_CFGR1_RES_10BIT 10 79 # define ADC_CFGR1_RES_8BIT 8 80 # define ADC_CFGR1_RES_6BIT 6 81 #endif 82 83 /* User configurable ADC options */ 84 #ifndef ADC_COUNT 85 # if defined(RP2040) || defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F4XX) || defined(STM32G0XX) || defined(GD32VF103) || defined(WB32F3G71xx) || defined(WB32FQ95xx) || defined(AT32F415) 86 # define ADC_COUNT 1 87 # elif defined(STM32F3XX) || defined(STM32G4XX) 88 # define ADC_COUNT 4 89 # elif defined(STM32L4XX) 90 # define ADC_COUNT 3 91 # else 92 # error "ADC_COUNT has not been set for this ARM microcontroller." 93 # endif 94 #endif 95 96 #ifndef ADC_NUM_CHANNELS 97 # define ADC_NUM_CHANNELS 1 98 #elif ADC_NUM_CHANNELS != 1 99 # error "The ARM ADC implementation currently only supports reading one channel at a time." 100 #endif 101 102 // Add dummy conversions as extra channels (this would work only on chips that 103 // have multiple channel index fields instead of a channel mask, but all chips 104 // that need that workaround are like that). 105 #define ADC_TOTAL_CHANNELS (ADC_DUMMY_CONVERSIONS_AT_START + ADC_NUM_CHANNELS) 106 107 #ifndef ADC_BUFFER_DEPTH 108 # define ADC_BUFFER_DEPTH 1 109 #endif 110 111 // For more sampling rate options, look at hal_adc_lld.h in ChibiOS 112 #if !defined(ADC_SAMPLING_RATE) && !defined(RP2040) 113 # if defined(ADC_SMPR_SMP_1P5) 114 # define ADC_SAMPLING_RATE ADC_SMPR_SMP_1P5 115 # elif defined(ADC_SMPR_SMP_2P5) // STM32L4XX, STM32L4XXP, STM32G4XX, STM32WBXX 116 # define ADC_SAMPLING_RATE ADC_SMPR_SMP_2P5 117 # elif defined(ADC_SMPR_SMP1_1P5) // STM32G0XX 118 # define ADC_SAMPLING_RATE ADC_SMPR_SMP1_1P5 119 # else 120 # error "Cannot determine the default ADC_SAMPLING_RATE for this MCU." 121 # endif 122 #endif 123 124 // Options are 12, 10, 8, and 6 bit. 125 #ifndef ADC_RESOLUTION 126 # ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4 127 # define ADC_RESOLUTION ADC_CFGR_RES_10BITS 128 # else // ADCv1, ADCv5, or the bodge for ADCv2 above 129 # define ADC_RESOLUTION ADC_CFGR1_RES_10BIT 130 # endif 131 #endif 132 133 static ADCConfig adcCfg = {}; 134 static adcsample_t sampleBuffer[ADC_TOTAL_CHANNELS * ADC_BUFFER_DEPTH]; 135 136 // Initialize to max number of ADCs, set to empty object to initialize all to false. 137 static bool adcInitialized[ADC_COUNT] = {}; 138 139 // TODO: add back TR handling??? 140 static ADCConversionGroup adcConversionGroup = { 141 .circular = FALSE, 142 .num_channels = (uint16_t)(ADC_TOTAL_CHANNELS), 143 #if defined(USE_ADCV1) 144 .cfgr1 = ADC_CFGR1_CONT | ADC_RESOLUTION, 145 .smpr = ADC_SAMPLING_RATE, 146 #elif defined(USE_ADCV2) 147 # if !defined(STM32F1XX) && !defined(GD32VF103) && !defined(WB32F3G71xx) && !defined(WB32FQ95xx) && !defined(AT32F415) 148 .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without... 149 # endif 150 # if defined(AT32F415) 151 .spt2 = ADC_SPT2_CSPT_AN0(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN1(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN2(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN3(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN4(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN5(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN6(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN7(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN8(ADC_SAMPLING_RATE) | ADC_SPT2_CSPT_AN9(ADC_SAMPLING_RATE), 152 .spt1 = ADC_SPT1_CSPT_AN10(ADC_SAMPLING_RATE) | ADC_SPT1_CSPT_AN11(ADC_SAMPLING_RATE) | ADC_SPT1_CSPT_AN12(ADC_SAMPLING_RATE) | ADC_SPT1_CSPT_AN13(ADC_SAMPLING_RATE) | ADC_SPT1_CSPT_AN14(ADC_SAMPLING_RATE) | ADC_SPT1_CSPT_AN15(ADC_SAMPLING_RATE), 153 # else 154 .smpr2 = ADC_SMPR2_SMP_AN0(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN1(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN2(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN3(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN4(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN5(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN6(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN7(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN8(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN9(ADC_SAMPLING_RATE), 155 .smpr1 = ADC_SMPR1_SMP_AN10(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN11(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN12(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN13(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN14(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN15(ADC_SAMPLING_RATE), 156 # endif 157 #elif defined(RP2040) 158 // RP2040 does not have any extra config here 159 #else 160 .cfgr = ADC_CFGR_CONT | ADC_RESOLUTION, 161 .smpr = {ADC_SMPR1_SMP_AN0(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN1(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN2(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN3(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN4(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN5(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN6(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN7(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN8(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN9(ADC_SAMPLING_RATE), ADC_SMPR2_SMP_AN10(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN11(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN12(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN13(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN14(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN15(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN16(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN17(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN18(ADC_SAMPLING_RATE)}, 162 #endif 163 }; 164 165 // clang-format off 166 __attribute__((weak)) adc_mux pinToMux(pin_t pin) { 167 switch (pin) { 168 #if defined(STM32F0XX) 169 case A0: return TO_MUX( 0, 0 ); 170 case A1: return TO_MUX( 1, 0 ); 171 case A2: return TO_MUX( 2, 0 ); 172 case A3: return TO_MUX( 3, 0 ); 173 case A4: return TO_MUX( 4, 0 ); 174 case A5: return TO_MUX( 5, 0 ); 175 case A6: return TO_MUX( 6, 0 ); 176 case A7: return TO_MUX( 7, 0 ); 177 case B0: return TO_MUX( 8, 0 ); 178 case B1: return TO_MUX( 9, 0 ); 179 case C0: return TO_MUX( 10, 0 ); 180 case C1: return TO_MUX( 11, 0 ); 181 case C2: return TO_MUX( 12, 0 ); 182 case C3: return TO_MUX( 13, 0 ); 183 case C4: return TO_MUX( 14, 0 ); 184 case C5: return TO_MUX( 15, 0 ); 185 #elif defined(STM32F3XX) 186 case A0: return TO_MUX( ADC_CHANNEL_IN1, 0 ); 187 case A1: return TO_MUX( ADC_CHANNEL_IN2, 0 ); 188 case A2: return TO_MUX( ADC_CHANNEL_IN3, 0 ); 189 case A3: return TO_MUX( ADC_CHANNEL_IN4, 0 ); 190 case A4: return TO_MUX( ADC_CHANNEL_IN1, 1 ); 191 case A5: return TO_MUX( ADC_CHANNEL_IN2, 1 ); 192 case A6: return TO_MUX( ADC_CHANNEL_IN3, 1 ); 193 case A7: return TO_MUX( ADC_CHANNEL_IN4, 1 ); 194 case B0: return TO_MUX( ADC_CHANNEL_IN12, 2 ); 195 case B1: return TO_MUX( ADC_CHANNEL_IN1, 2 ); 196 case B2: return TO_MUX( ADC_CHANNEL_IN12, 1 ); 197 case B12: return TO_MUX( ADC_CHANNEL_IN3, 3 ); 198 case B13: return TO_MUX( ADC_CHANNEL_IN5, 2 ); 199 case B14: return TO_MUX( ADC_CHANNEL_IN4, 3 ); 200 case B15: return TO_MUX( ADC_CHANNEL_IN5, 3 ); 201 case C0: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2 202 case C1: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2 203 case C2: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2 204 case C3: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2 205 case C4: return TO_MUX( ADC_CHANNEL_IN5, 1 ); 206 case C5: return TO_MUX( ADC_CHANNEL_IN11, 1 ); 207 case D8: return TO_MUX( ADC_CHANNEL_IN12, 3 ); 208 case D9: return TO_MUX( ADC_CHANNEL_IN13, 3 ); 209 case D10: return TO_MUX( ADC_CHANNEL_IN7, 2 ); // Can also be ADC4 210 case D11: return TO_MUX( ADC_CHANNEL_IN8, 2 ); // Can also be ADC4 211 case D12: return TO_MUX( ADC_CHANNEL_IN9, 2 ); // Can also be ADC4 212 case D13: return TO_MUX( ADC_CHANNEL_IN10, 2 ); // Can also be ADC4 213 case D14: return TO_MUX( ADC_CHANNEL_IN11, 2 ); // Can also be ADC4 214 case E7: return TO_MUX( ADC_CHANNEL_IN13, 2 ); 215 case E8: return TO_MUX( ADC_CHANNEL_IN6, 2 ); // Can also be ADC4 216 case E9: return TO_MUX( ADC_CHANNEL_IN2, 2 ); 217 case E10: return TO_MUX( ADC_CHANNEL_IN14, 2 ); 218 case E11: return TO_MUX( ADC_CHANNEL_IN15, 2 ); 219 case E12: return TO_MUX( ADC_CHANNEL_IN16, 2 ); 220 case E13: return TO_MUX( ADC_CHANNEL_IN3, 2 ); 221 case E14: return TO_MUX( ADC_CHANNEL_IN1, 3 ); 222 case E15: return TO_MUX( ADC_CHANNEL_IN2, 3 ); 223 case F2: return TO_MUX( ADC_CHANNEL_IN10, 0 ); // Can also be ADC2 224 case F4: return TO_MUX( ADC_CHANNEL_IN5, 0 ); 225 #elif defined(STM32F4XX) 226 case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 ); 227 case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 ); 228 case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 ); 229 case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 ); 230 case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 ); 231 case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 ); 232 case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 ); 233 case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 ); 234 case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 ); 235 case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 ); 236 case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 ); 237 case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 ); 238 case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 ); 239 case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 ); 240 case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 ); 241 case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 ); 242 # if STM32_ADC_USE_ADC3 243 case F3: return TO_MUX( ADC_CHANNEL_IN9, 2 ); 244 case F4: return TO_MUX( ADC_CHANNEL_IN14, 2 ); 245 case F5: return TO_MUX( ADC_CHANNEL_IN15, 2 ); 246 case F6: return TO_MUX( ADC_CHANNEL_IN4, 2 ); 247 case F7: return TO_MUX( ADC_CHANNEL_IN5, 2 ); 248 case F8: return TO_MUX( ADC_CHANNEL_IN6, 2 ); 249 case F9: return TO_MUX( ADC_CHANNEL_IN7, 2 ); 250 case F10: return TO_MUX( ADC_CHANNEL_IN8, 2 ); 251 # endif 252 #elif defined(STM32F1XX) || defined(GD32VF103) || defined(WB32F3G71xx) || defined(WB32FQ95xx) || defined(AT32F415) 253 case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 ); 254 case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 ); 255 case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 ); 256 case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 ); 257 case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 ); 258 case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 ); 259 case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 ); 260 case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 ); 261 case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 ); 262 case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 ); 263 case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 ); 264 case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 ); 265 case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 ); 266 case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 ); 267 case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 ); 268 case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 ); 269 // STM32F103x[C-G] in 144-pin packages also have analog inputs on F6...F10, but they are on ADC3, and the 270 // ChibiOS ADC driver for STM32F1xx currently supports only ADC1, therefore these pins are not usable. 271 #elif defined(STM32L4XX) 272 case A0: return TO_MUX( ADC_CHANNEL_IN5, 0 ); // Can also be ADC2 in some cases 273 case A1: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2 in some cases 274 case A2: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2 275 case A3: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2 276 case A4: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2 277 case A5: return TO_MUX( ADC_CHANNEL_IN10, 0 ); // Can also be ADC2 278 case A6: return TO_MUX( ADC_CHANNEL_IN11, 0 ); // Can also be ADC2 279 case A7: return TO_MUX( ADC_CHANNEL_IN12, 0 ); // Can also be ADC2 280 case B0: return TO_MUX( ADC_CHANNEL_IN15, 0 ); // Can also be ADC2 281 case B1: return TO_MUX( ADC_CHANNEL_IN16, 0 ); // Can also be ADC2 282 case C0: return TO_MUX( ADC_CHANNEL_IN1, 0 ); // Can also be ADC2 or ADC3 283 case C1: return TO_MUX( ADC_CHANNEL_IN2, 0 ); // Can also be ADC2 or ADC3 284 case C2: return TO_MUX( ADC_CHANNEL_IN3, 0 ); // Can also be ADC2 or ADC3 285 case C3: return TO_MUX( ADC_CHANNEL_IN4, 0 ); // Can also be ADC2 or ADC3 286 case C4: return TO_MUX( ADC_CHANNEL_IN13, 0 ); // Can also be ADC2 287 case C5: return TO_MUX( ADC_CHANNEL_IN14, 0 ); // Can also be ADC2 288 # if STM32_HAS_GPIOF && STM32_ADC_USE_ADC3 289 case F3: return TO_MUX( ADC_CHANNEL_IN6, 2 ); 290 case F4: return TO_MUX( ADC_CHANNEL_IN7, 2 ); 291 case F5: return TO_MUX( ADC_CHANNEL_IN8, 2 ); 292 case F6: return TO_MUX( ADC_CHANNEL_IN9, 2 ); 293 case F7: return TO_MUX( ADC_CHANNEL_IN10, 2 ); 294 case F8: return TO_MUX( ADC_CHANNEL_IN11, 2 ); 295 case F9: return TO_MUX( ADC_CHANNEL_IN12, 2 ); 296 case F10: return TO_MUX( ADC_CHANNEL_IN13, 2 ); 297 # endif 298 #elif defined(STM32G0XX) 299 case A0: return TO_MUX( 0, 0 ); 300 case A1: return TO_MUX( 1, 0 ); 301 case A2: return TO_MUX( 2, 0 ); 302 case A3: return TO_MUX( 3, 0 ); 303 case A4: return TO_MUX( 4, 0 ); 304 case A5: return TO_MUX( 5, 0 ); 305 case A6: return TO_MUX( 6, 0 ); 306 case A7: return TO_MUX( 7, 0 ); 307 case B0: return TO_MUX( 8, 0 ); 308 case B1: return TO_MUX( 9, 0 ); 309 case B2: return TO_MUX( 10, 0 ); 310 case B10: return TO_MUX( 11, 0 ); 311 case B11: return TO_MUX( 15, 0 ); 312 case B12: return TO_MUX( 16, 0 ); 313 case C4: return TO_MUX( 17, 0 ); 314 case C5: return TO_MUX( 18, 0 ); 315 #elif defined(STM32G4XX) 316 case A0: return TO_MUX( ADC_CHANNEL_IN1, 0 ); // Can also be ADC2 317 case A1: return TO_MUX( ADC_CHANNEL_IN2, 0 ); // Can also be ADC2 318 case A2: return TO_MUX( ADC_CHANNEL_IN3, 0 ); 319 case A3: return TO_MUX( ADC_CHANNEL_IN4, 0 ); 320 case A4: return TO_MUX( ADC_CHANNEL_IN17, 1 ); 321 case A5: return TO_MUX( ADC_CHANNEL_IN13, 1 ); 322 case A6: return TO_MUX( ADC_CHANNEL_IN3, 1 ); 323 case A7: return TO_MUX( ADC_CHANNEL_IN4, 1 ); 324 case B0: return TO_MUX( ADC_CHANNEL_IN15, 0 ); // Can also be ADC3 325 case B1: return TO_MUX( ADC_CHANNEL_IN12, 0 ); // Can also be ADC3 326 case B2: return TO_MUX( ADC_CHANNEL_IN12, 1 ); 327 case B11: return TO_MUX( ADC_CHANNEL_IN14, 0 ); // Can also be ADC2 328 case B12: return TO_MUX( ADC_CHANNEL_IN11, 0 ); // Can also be ADC4 329 case B13: return TO_MUX( ADC_CHANNEL_IN5, 2 ); 330 case B14: return TO_MUX( ADC_CHANNEL_IN5, 0 ); // Can also be ADC4 331 case B15: return TO_MUX( ADC_CHANNEL_IN15, 1 ); // Can also be ADC4 332 case C0: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2 333 case C1: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2 334 case C2: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2 335 case C3: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2 336 case C4: return TO_MUX( ADC_CHANNEL_IN5, 1 ); 337 case C5: return TO_MUX( ADC_CHANNEL_IN11, 1 ); 338 case D8: return TO_MUX( ADC_CHANNEL_IN12, 3 ); 339 case D9: return TO_MUX( ADC_CHANNEL_IN13, 3 ); 340 case D10: return TO_MUX( ADC_CHANNEL_IN7, 2 ); // Can also be ADC4 341 case D11: return TO_MUX( ADC_CHANNEL_IN8, 2 ); // Can also be ADC4 342 case D12: return TO_MUX( ADC_CHANNEL_IN9, 2 ); // Can also be ADC4 343 case D13: return TO_MUX( ADC_CHANNEL_IN10, 2 ); // Can also be ADC4 344 case D14: return TO_MUX( ADC_CHANNEL_IN11, 2 ); // Can also be ADC4 345 case E5: return TO_MUX( ADC_CHANNEL_IN2, 3 ); 346 case E7: return TO_MUX( ADC_CHANNEL_IN4, 2 ); 347 case E8: return TO_MUX( ADC_CHANNEL_IN6, 2 ); // Can also be ADC4 348 case E9: return TO_MUX( ADC_CHANNEL_IN2, 2 ); 349 case E10: return TO_MUX( ADC_CHANNEL_IN14, 2 ); // Can also be ADC4 350 case E11: return TO_MUX( ADC_CHANNEL_IN15, 2 ); // Can also be ADC4 351 case E12: return TO_MUX( ADC_CHANNEL_IN16, 2 ); // Can also be ADC4 352 case E13: return TO_MUX( ADC_CHANNEL_IN3, 2 ); 353 case E14: return TO_MUX( ADC_CHANNEL_IN1, 3 ); 354 case F0: return TO_MUX( ADC_CHANNEL_IN10, 0 ); 355 case F1: return TO_MUX( ADC_CHANNEL_IN10, 1 ); 356 #elif defined(RP2040) 357 case 26U: return TO_MUX(0, 0); 358 case 27U: return TO_MUX(1, 0); 359 case 28U: return TO_MUX(2, 0); 360 case 29U: return TO_MUX(3, 0); 361 #endif 362 } 363 364 // return an adc that would never be used so intToADCDriver will bail out 365 return TO_MUX(0, 0xFF); 366 } 367 // clang-format on 368 369 static inline ADCDriver* intToADCDriver(uint8_t adcInt) { 370 switch (adcInt) { 371 #if RP_ADC_USE_ADC1 || STM32_ADC_USE_ADC1 || WB32_ADC_USE_ADC1 || AT32_ADC_USE_ADC1 372 case 0: 373 return &ADCD1; 374 #endif 375 #if STM32_ADC_USE_ADC2 376 case 1: 377 return &ADCD2; 378 #endif 379 #if STM32_ADC_USE_ADC3 380 case 2: 381 return &ADCD3; 382 #endif 383 #if STM32_ADC_USE_ADC4 384 case 3: 385 return &ADCD4; 386 #endif 387 } 388 389 return NULL; 390 } 391 392 static inline void manageAdcInitializationDriver(uint8_t adc, ADCDriver* adcDriver) { 393 if (!adcInitialized[adc]) { 394 adcStart(adcDriver, &adcCfg); 395 adcInitialized[adc] = true; 396 } 397 } 398 399 int16_t analogReadPin(pin_t pin) { 400 palSetLineMode(pin, PAL_MODE_INPUT_ANALOG); 401 402 return adc_read(pinToMux(pin)); 403 } 404 405 int16_t analogReadPinAdc(pin_t pin, uint8_t adc) { 406 palSetLineMode(pin, PAL_MODE_INPUT_ANALOG); 407 408 adc_mux target = pinToMux(pin); 409 target.adc = adc; 410 return adc_read(target); 411 } 412 413 int16_t adc_read(adc_mux mux) { 414 #if defined(USE_ADCV1) 415 // TODO: fix previous assumption of only 1 input... 416 adcConversionGroup.chselr = 1 << mux.input; /*no macro to convert N to ADC_CHSELR_CHSEL1*/ 417 #elif defined(USE_ADCV2) 418 # if defined(AT32F415) 419 adcConversionGroup.osq3 = ADC_OSQ3_OSN1_N(mux.input); 420 # else 421 adcConversionGroup.sqr3 = ADC_SQR3_SQ1_N(mux.input); 422 # endif 423 #elif defined(RP2040) 424 adcConversionGroup.channel_mask = 1 << mux.input; 425 #else 426 adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(mux.input) 427 # if ADC_DUMMY_CONVERSIONS_AT_START >= 1 428 | ADC_SQR1_SQ2_N(mux.input) 429 # endif 430 ; 431 #endif 432 433 ADCDriver* targetDriver = intToADCDriver(mux.adc); 434 if (!targetDriver) { 435 return 0; 436 } 437 438 manageAdcInitializationDriver(mux.adc, targetDriver); 439 if (adcConvert(targetDriver, &adcConversionGroup, &sampleBuffer[0], ADC_BUFFER_DEPTH) != MSG_OK) { 440 return 0; 441 } 442 443 #if defined(USE_ADCV2) || defined(RP2040) 444 // fake 12-bit -> N-bit scale 445 return (sampleBuffer[ADC_DUMMY_CONVERSIONS_AT_START]) >> (12 - ADC_RESOLUTION); 446 #else 447 // already handled as part of adcConvert 448 return sampleBuffer[ADC_DUMMY_CONVERSIONS_AT_START]; 449 #endif 450 }