diff options
Diffstat (limited to 'drivers/arm/analog.c')
| -rw-r--r-- | drivers/arm/analog.c | 313 |
1 files changed, 191 insertions, 122 deletions
diff --git a/drivers/arm/analog.c b/drivers/arm/analog.c index 427381f28..a7e6d2525 100644 --- a/drivers/arm/analog.c +++ b/drivers/arm/analog.c | |||
| @@ -14,12 +14,74 @@ | |||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include "analog.h" | ||
| 18 | #include "quantum.h" | 17 | #include "quantum.h" |
| 18 | #include "analog.h" | ||
| 19 | #include "ch.h" | ||
| 20 | #include <hal.h> | ||
| 21 | |||
| 22 | #if !HAL_USE_ADC | ||
| 23 | # error "You need to set HAL_USE_ADC to TRUE in your halconf.h to use the ADC." | ||
| 24 | #endif | ||
| 25 | |||
| 26 | #if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3 && !STM32_ADC_USE_ADC4 | ||
| 27 | # error "You need to set one of the 'STM32_ADC_USE_ADCx' settings to TRUE in your mcuconf.h to use the ADC." | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #if STM32_ADC_DUAL_MODE | ||
| 31 | # error "STM32 ADC Dual Mode is not supported at this time." | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #if STM32_ADCV3_OVERSAMPLING | ||
| 35 | # error "STM32 ADCV3 Oversampling is not supported at this time." | ||
| 36 | #endif | ||
| 37 | |||
| 38 | // Otherwise assume V3 | ||
| 39 | #if defined(STM32F0XX) || defined(STM32L0XX) | ||
| 40 | # define USE_ADCV1 | ||
| 41 | #elif defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) | ||
| 42 | # define USE_ADCV2 | ||
| 43 | #endif | ||
| 44 | |||
| 45 | // BODGE to make v2 look like v1,3 and 4 | ||
| 46 | #ifdef USE_ADCV2 | ||
| 47 | # if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_3) | ||
| 48 | # define ADC_SMPR_SMP_1P5 ADC_SAMPLE_3 | ||
| 49 | # define ADC_SMPR_SMP_7P5 ADC_SAMPLE_15 | ||
| 50 | # define ADC_SMPR_SMP_13P5 ADC_SAMPLE_28 | ||
| 51 | # define ADC_SMPR_SMP_28P5 ADC_SAMPLE_56 | ||
| 52 | # define ADC_SMPR_SMP_41P5 ADC_SAMPLE_84 | ||
| 53 | # define ADC_SMPR_SMP_55P5 ADC_SAMPLE_112 | ||
| 54 | # define ADC_SMPR_SMP_71P5 ADC_SAMPLE_144 | ||
| 55 | # define ADC_SMPR_SMP_239P5 ADC_SAMPLE_480 | ||
| 56 | # endif | ||
| 57 | |||
| 58 | # if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_1P5) | ||
| 59 | # define ADC_SMPR_SMP_1P5 ADC_SAMPLE_1P5 | ||
| 60 | # define ADC_SMPR_SMP_7P5 ADC_SAMPLE_7P5 | ||
| 61 | # define ADC_SMPR_SMP_13P5 ADC_SAMPLE_13P5 | ||
| 62 | # define ADC_SMPR_SMP_28P5 ADC_SAMPLE_28P5 | ||
| 63 | # define ADC_SMPR_SMP_41P5 ADC_SAMPLE_41P5 | ||
| 64 | # define ADC_SMPR_SMP_55P5 ADC_SAMPLE_55P5 | ||
| 65 | # define ADC_SMPR_SMP_71P5 ADC_SAMPLE_71P5 | ||
| 66 | # define ADC_SMPR_SMP_239P5 ADC_SAMPLE_239P5 | ||
| 67 | # endif | ||
| 68 | |||
| 69 | // we still sample at 12bit, but scale down to the requested bit range | ||
| 70 | # define ADC_CFGR1_RES_12BIT 12 | ||
| 71 | # define ADC_CFGR1_RES_10BIT 10 | ||
| 72 | # define ADC_CFGR1_RES_8BIT 8 | ||
| 73 | # define ADC_CFGR1_RES_6BIT 6 | ||
| 74 | #endif | ||
| 19 | 75 | ||
| 20 | /* User configurable ADC options */ | 76 | /* User configurable ADC options */ |
| 21 | #ifndef ADC_CIRCULAR_BUFFER | 77 | #ifndef ADC_COUNT |
| 22 | # define ADC_CIRCULAR_BUFFER FALSE | 78 | # if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F4XX) |
| 79 | # define ADC_COUNT 1 | ||
| 80 | # elif defined(STM32F3XX) | ||
| 81 | # define ADC_COUNT 4 | ||
| 82 | # else | ||
| 83 | # error "ADC_COUNT has not been set for this ARM microcontroller." | ||
| 84 | # endif | ||
| 23 | #endif | 85 | #endif |
| 24 | 86 | ||
| 25 | #ifndef ADC_NUM_CHANNELS | 87 | #ifndef ADC_NUM_CHANNELS |
| @@ -29,7 +91,7 @@ | |||
| 29 | #endif | 91 | #endif |
| 30 | 92 | ||
| 31 | #ifndef ADC_BUFFER_DEPTH | 93 | #ifndef ADC_BUFFER_DEPTH |
| 32 | # define ADC_BUFFER_DEPTH 2 | 94 | # define ADC_BUFFER_DEPTH 1 |
| 33 | #endif | 95 | #endif |
| 34 | 96 | ||
| 35 | // For more sampling rate options, look at hal_adc_lld.h in ChibiOS | 97 | // For more sampling rate options, look at hal_adc_lld.h in ChibiOS |
| @@ -39,68 +101,128 @@ | |||
| 39 | 101 | ||
| 40 | // Options are 12, 10, 8, and 6 bit. | 102 | // Options are 12, 10, 8, and 6 bit. |
| 41 | #ifndef ADC_RESOLUTION | 103 | #ifndef ADC_RESOLUTION |
| 42 | # define ADC_RESOLUTION ADC_CFGR1_RES_12BIT | 104 | # define ADC_RESOLUTION ADC_CFGR1_RES_10BIT |
| 43 | #endif | 105 | #endif |
| 44 | 106 | ||
| 45 | static ADCConfig adcCfg = {}; | 107 | static ADCConfig adcCfg = {}; |
| 46 | static adcsample_t sampleBuffer[ADC_NUM_CHANNELS * ADC_BUFFER_DEPTH]; | 108 | static adcsample_t sampleBuffer[ADC_NUM_CHANNELS * ADC_BUFFER_DEPTH]; |
| 47 | 109 | ||
| 48 | // Initialize to max number of ADCs, set to empty object to initialize all to false. | 110 | // Initialize to max number of ADCs, set to empty object to initialize all to false. |
| 49 | #if defined(STM32F0XX) | 111 | static bool adcInitialized[ADC_COUNT] = {}; |
| 50 | static bool adcInitialized[1] = {}; | 112 | |
| 51 | #elif defined(STM32F3XX) | 113 | // TODO: add back TR handling??? |
| 52 | static bool adcInitialized[4] = {}; | 114 | static ADCConversionGroup adcConversionGroup = { |
| 115 | .circular = FALSE, | ||
| 116 | .num_channels = (uint16_t)(ADC_NUM_CHANNELS), | ||
| 117 | #if defined(USE_ADCV1) | ||
| 118 | .cfgr1 = ADC_CFGR1_CONT | ADC_RESOLUTION, | ||
| 119 | .smpr = ADC_SAMPLING_RATE, | ||
| 120 | #elif defined(USE_ADCV2) | ||
| 121 | # if !defined(STM32F1XX) | ||
| 122 | .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without... | ||
| 123 | # endif | ||
| 124 | .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), | ||
| 125 | .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), | ||
| 53 | #else | 126 | #else |
| 54 | # error "adcInitialized has not been implemented for this ARM microcontroller." | 127 | .cfgr = ADC_CFGR_CONT | ADC_RESOLUTION, |
| 128 | .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)}, | ||
| 55 | #endif | 129 | #endif |
| 130 | }; | ||
| 56 | 131 | ||
| 57 | static ADCConversionGroup adcConversionGroup = { | 132 | // clang-format off |
| 58 | ADC_CIRCULAR_BUFFER, | 133 | __attribute__((weak)) adc_mux pinToMux(pin_t pin) { |
| 59 | (uint16_t)(ADC_NUM_CHANNELS), | 134 | switch (pin) { |
| 60 | NULL, // No end callback | ||
| 61 | NULL, // No error callback | ||
| 62 | #if defined(STM32F0XX) | 135 | #if defined(STM32F0XX) |
| 63 | ADC_CFGR1_CONT | ADC_RESOLUTION, | 136 | case A0: return TO_MUX( ADC_CHSELR_CHSEL0, 0 ); |
| 64 | ADC_TR(0, 0).ADC_SAMPLING_RATE, | 137 | case A1: return TO_MUX( ADC_CHSELR_CHSEL1, 0 ); |
| 65 | NULL, // Doesn't specify a default channel | 138 | case A2: return TO_MUX( ADC_CHSELR_CHSEL2, 0 ); |
| 139 | case A3: return TO_MUX( ADC_CHSELR_CHSEL3, 0 ); | ||
| 140 | case A4: return TO_MUX( ADC_CHSELR_CHSEL4, 0 ); | ||
| 141 | case A5: return TO_MUX( ADC_CHSELR_CHSEL5, 0 ); | ||
| 142 | case A6: return TO_MUX( ADC_CHSELR_CHSEL6, 0 ); | ||
| 143 | case A7: return TO_MUX( ADC_CHSELR_CHSEL7, 0 ); | ||
| 144 | case B0: return TO_MUX( ADC_CHSELR_CHSEL8, 0 ); | ||
| 145 | case B1: return TO_MUX( ADC_CHSELR_CHSEL9, 0 ); | ||
| 146 | case C0: return TO_MUX( ADC_CHSELR_CHSEL10, 0 ); | ||
| 147 | case C1: return TO_MUX( ADC_CHSELR_CHSEL11, 0 ); | ||
| 148 | case C2: return TO_MUX( ADC_CHSELR_CHSEL12, 0 ); | ||
| 149 | case C3: return TO_MUX( ADC_CHSELR_CHSEL13, 0 ); | ||
| 150 | case C4: return TO_MUX( ADC_CHSELR_CHSEL14, 0 ); | ||
| 151 | case C5: return TO_MUX( ADC_CHSELR_CHSEL15, 0 ); | ||
| 66 | #elif defined(STM32F3XX) | 152 | #elif defined(STM32F3XX) |
| 67 | ADC_CFGR_CONT | ADC_RESOLUTION, | 153 | case A0: return TO_MUX( ADC_CHANNEL_IN1, 0 ); |
| 68 | ADC_TR(0, 4095), | 154 | case A1: return TO_MUX( ADC_CHANNEL_IN2, 0 ); |
| 69 | { | 155 | case A2: return TO_MUX( ADC_CHANNEL_IN3, 0 ); |
| 70 | ADC_SAMPLING_RATE, | 156 | case A3: return TO_MUX( ADC_CHANNEL_IN4, 0 ); |
| 71 | ADC_SAMPLING_RATE, | 157 | case A4: return TO_MUX( ADC_CHANNEL_IN1, 1 ); |
| 72 | }, | 158 | case A5: return TO_MUX( ADC_CHANNEL_IN2, 1 ); |
| 73 | { | 159 | case A6: return TO_MUX( ADC_CHANNEL_IN3, 1 ); |
| 74 | 0, // Doesn't specify a default channel | 160 | case A7: return TO_MUX( ADC_CHANNEL_IN4, 1 ); |
| 75 | 0, | 161 | case B0: return TO_MUX( ADC_CHANNEL_IN12, 2 ); |
| 76 | 0, | 162 | case B1: return TO_MUX( ADC_CHANNEL_IN1, 2 ); |
| 77 | 0, | 163 | case B2: return TO_MUX( ADC_CHANNEL_IN12, 1 ); |
| 78 | }, | 164 | case B12: return TO_MUX( ADC_CHANNEL_IN2, 3 ); |
| 165 | case B13: return TO_MUX( ADC_CHANNEL_IN3, 3 ); | ||
| 166 | case B14: return TO_MUX( ADC_CHANNEL_IN4, 3 ); | ||
| 167 | case B15: return TO_MUX( ADC_CHANNEL_IN5, 3 ); | ||
| 168 | case C0: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2 | ||
| 169 | case C1: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2 | ||
| 170 | case C2: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2 | ||
| 171 | case C3: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2 | ||
| 172 | case C4: return TO_MUX( ADC_CHANNEL_IN5, 1 ); | ||
| 173 | case C5: return TO_MUX( ADC_CHANNEL_IN11, 1 ); | ||
| 174 | case D8: return TO_MUX( ADC_CHANNEL_IN12, 3 ); | ||
| 175 | case D9: return TO_MUX( ADC_CHANNEL_IN13, 3 ); | ||
| 176 | case D10: return TO_MUX( ADC_CHANNEL_IN7, 2 ); // Can also be ADC4 | ||
| 177 | case D11: return TO_MUX( ADC_CHANNEL_IN8, 2 ); // Can also be ADC4 | ||
| 178 | case D12: return TO_MUX( ADC_CHANNEL_IN9, 2 ); // Can also be ADC4 | ||
| 179 | case D13: return TO_MUX( ADC_CHANNEL_IN10, 2 ); // Can also be ADC4 | ||
| 180 | case D14: return TO_MUX( ADC_CHANNEL_IN11, 2 ); // Can also be ADC4 | ||
| 181 | case E7: return TO_MUX( ADC_CHANNEL_IN13, 2 ); | ||
| 182 | case E8: return TO_MUX( ADC_CHANNEL_IN6, 2 ); // Can also be ADC4 | ||
| 183 | case E9: return TO_MUX( ADC_CHANNEL_IN2, 2 ); | ||
| 184 | case E10: return TO_MUX( ADC_CHANNEL_IN14, 2 ); | ||
| 185 | case E11: return TO_MUX( ADC_CHANNEL_IN15, 2 ); | ||
| 186 | case E12: return TO_MUX( ADC_CHANNEL_IN16, 2 ); | ||
| 187 | case E13: return TO_MUX( ADC_CHANNEL_IN3, 2 ); | ||
| 188 | case E14: return TO_MUX( ADC_CHANNEL_IN1, 3 ); | ||
| 189 | case E15: return TO_MUX( ADC_CHANNEL_IN2, 3 ); | ||
| 190 | case F2: return TO_MUX( ADC_CHANNEL_IN10, 0 ); // Can also be ADC2 | ||
| 191 | case F4: return TO_MUX( ADC_CHANNEL_IN5, 0 ); | ||
| 192 | #elif defined(STM32F4XX) // TODO: add all pins | ||
| 193 | case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 ); | ||
| 194 | //case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 ); | ||
| 195 | #elif defined(STM32F1XX) // TODO: add all pins | ||
| 196 | case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 ); | ||
| 79 | #endif | 197 | #endif |
| 80 | }; | 198 | } |
| 81 | 199 | ||
| 82 | static inline ADCDriver* intToADCDriver(uint8_t adcInt) { | 200 | // return an adc that would never be used so intToADCDriver will bail out |
| 83 | ADCDriver* target; | 201 | return TO_MUX(0, 0xFF); |
| 202 | } | ||
| 203 | // clang-format on | ||
| 84 | 204 | ||
| 205 | static inline ADCDriver* intToADCDriver(uint8_t adcInt) { | ||
| 85 | switch (adcInt) { | 206 | switch (adcInt) { |
| 86 | // clang-format off | ||
| 87 | #if STM32_ADC_USE_ADC1 | 207 | #if STM32_ADC_USE_ADC1 |
| 88 | case 0: target = &ADCD1; break; | 208 | case 0: |
| 209 | return &ADCD1; | ||
| 89 | #endif | 210 | #endif |
| 90 | #if STM32_ADC_USE_ADC2 | 211 | #if STM32_ADC_USE_ADC2 |
| 91 | case 1: target = &ADCD2; break; | 212 | case 1: |
| 213 | return &ADCD2; | ||
| 92 | #endif | 214 | #endif |
| 93 | #if STM32_ADC_USE_ADC3 | 215 | #if STM32_ADC_USE_ADC3 |
| 94 | case 2: target = &ADCD3; break; | 216 | case 2: |
| 217 | return &ADCD3; | ||
| 95 | #endif | 218 | #endif |
| 96 | #if STM32_ADC_USE_ADC4 | 219 | #if STM32_ADC_USE_ADC4 |
| 97 | case 3: target = &ADCD4; break; | 220 | case 3: |
| 221 | return &ADCD4; | ||
| 98 | #endif | 222 | #endif |
| 99 | default: target = NULL; break; | ||
| 100 | // clang-format on | ||
| 101 | } | 223 | } |
| 102 | 224 | ||
| 103 | return target; | 225 | return NULL; |
| 104 | } | 226 | } |
| 105 | 227 | ||
| 106 | static inline void manageAdcInitializationDriver(uint8_t adc, ADCDriver* adcDriver) { | 228 | static inline void manageAdcInitializationDriver(uint8_t adc, ADCDriver* adcDriver) { |
| @@ -110,98 +232,45 @@ static inline void manageAdcInitializationDriver(uint8_t adc, ADCDriver* adcDriv | |||
| 110 | } | 232 | } |
| 111 | } | 233 | } |
| 112 | 234 | ||
| 113 | static inline void manageAdcInitialization(uint8_t adc) { manageAdcInitializationDriver(adc, intToADCDriver(adc)); } | 235 | int16_t analogReadPin(pin_t pin) { |
| 236 | palSetLineMode(pin, PAL_MODE_INPUT_ANALOG); | ||
| 114 | 237 | ||
| 115 | pin_and_adc pinToMux(pin_t pin) { | 238 | return adc_read(pinToMux(pin)); |
| 116 | switch (pin) { | ||
| 117 | // clang-format off | ||
| 118 | #if defined(STM32F0XX) | ||
| 119 | case A0: return (pin_and_adc){ ADC_CHANNEL_IN0, 0 }; | ||
| 120 | case A1: return (pin_and_adc){ ADC_CHANNEL_IN1, 0 }; | ||
| 121 | case A2: return (pin_and_adc){ ADC_CHANNEL_IN2, 0 }; | ||
| 122 | case A3: return (pin_and_adc){ ADC_CHANNEL_IN3, 0 }; | ||
| 123 | case A4: return (pin_and_adc){ ADC_CHANNEL_IN4, 0 }; | ||
| 124 | case A5: return (pin_and_adc){ ADC_CHANNEL_IN5, 0 }; | ||
| 125 | case A6: return (pin_and_adc){ ADC_CHANNEL_IN6, 0 }; | ||
| 126 | case A7: return (pin_and_adc){ ADC_CHANNEL_IN7, 0 }; | ||
| 127 | case B0: return (pin_and_adc){ ADC_CHANNEL_IN8, 0 }; | ||
| 128 | case B1: return (pin_and_adc){ ADC_CHANNEL_IN9, 0 }; | ||
| 129 | case C0: return (pin_and_adc){ ADC_CHANNEL_IN10, 0 }; | ||
| 130 | case C1: return (pin_and_adc){ ADC_CHANNEL_IN11, 0 }; | ||
| 131 | case C2: return (pin_and_adc){ ADC_CHANNEL_IN12, 0 }; | ||
| 132 | case C3: return (pin_and_adc){ ADC_CHANNEL_IN13, 0 }; | ||
| 133 | case C4: return (pin_and_adc){ ADC_CHANNEL_IN14, 0 }; | ||
| 134 | case C5: return (pin_and_adc){ ADC_CHANNEL_IN15, 0 }; | ||
| 135 | #elif defined(STM32F3XX) | ||
| 136 | case A0: return (pin_and_adc){ ADC_CHANNEL_IN1, 0 }; | ||
| 137 | case A1: return (pin_and_adc){ ADC_CHANNEL_IN2, 0 }; | ||
| 138 | case A2: return (pin_and_adc){ ADC_CHANNEL_IN3, 0 }; | ||
| 139 | case A3: return (pin_and_adc){ ADC_CHANNEL_IN4, 0 }; | ||
| 140 | case A4: return (pin_and_adc){ ADC_CHANNEL_IN1, 1 }; | ||
| 141 | case A5: return (pin_and_adc){ ADC_CHANNEL_IN2, 1 }; | ||
| 142 | case A6: return (pin_and_adc){ ADC_CHANNEL_IN3, 1 }; | ||
| 143 | case A7: return (pin_and_adc){ ADC_CHANNEL_IN4, 1 }; | ||
| 144 | case B0: return (pin_and_adc){ ADC_CHANNEL_IN12, 2 }; | ||
| 145 | case B1: return (pin_and_adc){ ADC_CHANNEL_IN1, 2 }; | ||
| 146 | case B2: return (pin_and_adc){ ADC_CHANNEL_IN12, 1 }; | ||
| 147 | case B12: return (pin_and_adc){ ADC_CHANNEL_IN2, 3 }; | ||
| 148 | case B13: return (pin_and_adc){ ADC_CHANNEL_IN3, 3 }; | ||
| 149 | case B14: return (pin_and_adc){ ADC_CHANNEL_IN4, 3 }; | ||
| 150 | case B15: return (pin_and_adc){ ADC_CHANNEL_IN5, 3 }; | ||
| 151 | case C0: return (pin_and_adc){ ADC_CHANNEL_IN6, 0 }; // Can also be ADC2 | ||
| 152 | case C1: return (pin_and_adc){ ADC_CHANNEL_IN7, 0 }; // Can also be ADC2 | ||
| 153 | case C2: return (pin_and_adc){ ADC_CHANNEL_IN8, 0 }; // Can also be ADC2 | ||
| 154 | case C3: return (pin_and_adc){ ADC_CHANNEL_IN9, 0 }; // Can also be ADC2 | ||
| 155 | case C4: return (pin_and_adc){ ADC_CHANNEL_IN5, 1 }; | ||
| 156 | case C5: return (pin_and_adc){ ADC_CHANNEL_IN11, 1 }; | ||
| 157 | case D8: return (pin_and_adc){ ADC_CHANNEL_IN12, 3 }; | ||
| 158 | case D9: return (pin_and_adc){ ADC_CHANNEL_IN13, 3 }; | ||
| 159 | case D10: return (pin_and_adc){ ADC_CHANNEL_IN7, 2 }; // Can also be ADC4 | ||
| 160 | case D11: return (pin_and_adc){ ADC_CHANNEL_IN8, 2 }; // Can also be ADC4 | ||
| 161 | case D12: return (pin_and_adc){ ADC_CHANNEL_IN9, 2 }; // Can also be ADC4 | ||
| 162 | case D13: return (pin_and_adc){ ADC_CHANNEL_IN10, 2 }; // Can also be ADC4 | ||
| 163 | case D14: return (pin_and_adc){ ADC_CHANNEL_IN11, 2 }; // Can also be ADC4 | ||
| 164 | case E7: return (pin_and_adc){ ADC_CHANNEL_IN13, 2 }; | ||
| 165 | case E8: return (pin_and_adc){ ADC_CHANNEL_IN6, 2 }; // Can also be ADC4 | ||
| 166 | case E9: return (pin_and_adc){ ADC_CHANNEL_IN2, 2 }; | ||
| 167 | case E10: return (pin_and_adc){ ADC_CHANNEL_IN14, 2 }; | ||
| 168 | case E11: return (pin_and_adc){ ADC_CHANNEL_IN15, 2 }; | ||
| 169 | case E12: return (pin_and_adc){ ADC_CHANNEL_IN16, 2 }; | ||
| 170 | case E13: return (pin_and_adc){ ADC_CHANNEL_IN3, 2 }; | ||
| 171 | case E14: return (pin_and_adc){ ADC_CHANNEL_IN1, 3 }; | ||
| 172 | case E15: return (pin_and_adc){ ADC_CHANNEL_IN2, 3 }; | ||
| 173 | case F2: return (pin_and_adc){ ADC_CHANNEL_IN10, 0 }; // Can also be ADC2 | ||
| 174 | case F4: return (pin_and_adc){ ADC_CHANNEL_IN5, 0 }; | ||
| 175 | #else | ||
| 176 | #error "An ADC pin-to-mux configuration has not been specified for this microcontroller." | ||
| 177 | #endif | ||
| 178 | default: return (pin_and_adc){ 0, 0 }; | ||
| 179 | // clang-format on | ||
| 180 | } | ||
| 181 | } | 239 | } |
| 182 | 240 | ||
| 183 | adcsample_t analogReadPin(pin_t pin) { return adc_read(pinToMux(pin)); } | 241 | int16_t analogReadPinAdc(pin_t pin, uint8_t adc) { |
| 242 | palSetLineMode(pin, PAL_MODE_INPUT_ANALOG); | ||
| 184 | 243 | ||
| 185 | adcsample_t analogReadPinAdc(pin_t pin, uint8_t adc) { | 244 | adc_mux target = pinToMux(pin); |
| 186 | pin_and_adc target = pinToMux(pin); | 245 | target.adc = adc; |
| 187 | target.adc = adc; | ||
| 188 | return adc_read(target); | 246 | return adc_read(target); |
| 189 | } | 247 | } |
| 190 | 248 | ||
| 191 | adcsample_t adc_read(pin_and_adc mux) { | 249 | int16_t adc_read(adc_mux mux) { |
| 192 | #if defined(STM32F0XX) | 250 | #if defined(USE_ADCV1) |
| 193 | adcConversionGroup.sqr = ADC_CHSELR_CHSEL1; | 251 | // TODO: fix previous assumption of only 1 input... |
| 194 | #elif defined(STM32F3XX) | 252 | adcConversionGroup.chselr = 1 << mux.input; /*no macro to convert N to ADC_CHSELR_CHSEL1*/ |
| 195 | adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(mux.pin); | 253 | #elif defined(USE_ADCV2) |
| 254 | adcConversionGroup.sqr3 = ADC_SQR3_SQ1_N(mux.input); | ||
| 196 | #else | 255 | #else |
| 197 | # error "adc_read has not been updated to support this ARM microcontroller." | 256 | adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(mux.input); |
| 198 | #endif | 257 | #endif |
| 199 | 258 | ||
| 200 | ADCDriver* targetDriver = intToADCDriver(mux.adc); | 259 | ADCDriver* targetDriver = intToADCDriver(mux.adc); |
| 201 | manageAdcInitializationDriver(mux.adc, targetDriver); | 260 | if (!targetDriver) { |
| 261 | return 0; | ||
| 262 | } | ||
| 202 | 263 | ||
| 203 | adcConvert(targetDriver, &adcConversionGroup, &sampleBuffer[0], ADC_BUFFER_DEPTH); | 264 | manageAdcInitializationDriver(mux.adc, targetDriver); |
| 204 | adcsample_t* result = sampleBuffer; | 265 | if (adcConvert(targetDriver, &adcConversionGroup, &sampleBuffer[0], ADC_BUFFER_DEPTH) != MSG_OK) { |
| 266 | return 0; | ||
| 267 | } | ||
| 205 | 268 | ||
| 206 | return *result; | 269 | #ifdef USE_ADCV2 |
| 270 | // fake 12-bit -> N-bit scale | ||
| 271 | return (*sampleBuffer) >> (12 - ADC_RESOLUTION); | ||
| 272 | #else | ||
| 273 | // already handled as part of adcConvert | ||
| 274 | return *sampleBuffer; | ||
| 275 | #endif | ||
| 207 | } | 276 | } |
