You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
14 KiB

Update ADC driver for STM32F1xx, STM32F3xx, STM32F4xx (#12403) * Fix default ADC_RESOLUTION for ADCv3 (and ADCv4) Recent ChibiOS update removed ADC_CFGR1_RES_10BIT from the ADCv3 headers (that macro should not have been there, because ADCv3 has CFGR instead of CFGR1). Fix the default value for ADC_RESOLUTION to use ADC_CFGR_RES_10BITS if it is defined (that name is used for ADCv3 and ADCv4). * Update ADC docs to match the actually used resolution ADC driver for ChibiOS actually uses the 10-bit resolution by default (probably to match AVR); fix the documentation accordingly. Also add both ADC_CFGR_RES_10BITS and ADC_CFGR1_RES_10BIT constants (these names differ according to the ADC implementation in the particular MCU). * Fix pinToMux() for B12 and B13 on STM32F3xx Testing on STM32F303CCT6 revealed that the ADC mux values for B12 and B13 pins were wrong. * Add support for all possible analog pins on STM32F1xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 on STM32F1xx (they are the same at least for STM32F103x8 and larger F103 devices, and also F102, F105, F107 families). Actually tested on STM32F103C8T6 (therefore pins C0...C5 were not tested). Pins F6...F10, which are present on STM32F103x[C-G] in 144-pin packages, cannot be supported at the moment, because those pins are connected only to ADC3, but the ChibiOS ADC driver for STM32F1xx supports only ADC1. * Add support for all possible analog pins on STM32F4xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 and optionally F3...F10 (if STM32_ADC_USE_ADC3 is enabled). These mux values are apparently the same for all F4xx devices, except some smaller devices may not have ADC3. Actually tested on STM32F401CCU6, STM32F401CEU6, STM32F411CEU6 (using various WeAct “Blackpill” boards); only pins A0...A7, B0, B1 were tested. Pins F3...F10 are inside `#if STM32_ADC_USE_ADC3` because some devices which don't have ADC3 also don't have the GPIOF port, therefore the code which refers to Fx pins does not compile. * Fix STM32F3xx ADC mux table in documentation The ADC driver documentation had some errors in the mux table for STM32F3xx. Fix this table to match the datasheet and the actual code (mux settings for B12 and B13 were also tested on a real STM32F303CCT6 chip). * Add STM32F1xx ADC pins to the documentation * Add STM32F4xx ADC pins to the documentation
3 years ago
Update ADC driver for STM32F1xx, STM32F3xx, STM32F4xx (#12403) * Fix default ADC_RESOLUTION for ADCv3 (and ADCv4) Recent ChibiOS update removed ADC_CFGR1_RES_10BIT from the ADCv3 headers (that macro should not have been there, because ADCv3 has CFGR instead of CFGR1). Fix the default value for ADC_RESOLUTION to use ADC_CFGR_RES_10BITS if it is defined (that name is used for ADCv3 and ADCv4). * Update ADC docs to match the actually used resolution ADC driver for ChibiOS actually uses the 10-bit resolution by default (probably to match AVR); fix the documentation accordingly. Also add both ADC_CFGR_RES_10BITS and ADC_CFGR1_RES_10BIT constants (these names differ according to the ADC implementation in the particular MCU). * Fix pinToMux() for B12 and B13 on STM32F3xx Testing on STM32F303CCT6 revealed that the ADC mux values for B12 and B13 pins were wrong. * Add support for all possible analog pins on STM32F1xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 on STM32F1xx (they are the same at least for STM32F103x8 and larger F103 devices, and also F102, F105, F107 families). Actually tested on STM32F103C8T6 (therefore pins C0...C5 were not tested). Pins F6...F10, which are present on STM32F103x[C-G] in 144-pin packages, cannot be supported at the moment, because those pins are connected only to ADC3, but the ChibiOS ADC driver for STM32F1xx supports only ADC1. * Add support for all possible analog pins on STM32F4xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 and optionally F3...F10 (if STM32_ADC_USE_ADC3 is enabled). These mux values are apparently the same for all F4xx devices, except some smaller devices may not have ADC3. Actually tested on STM32F401CCU6, STM32F401CEU6, STM32F411CEU6 (using various WeAct “Blackpill” boards); only pins A0...A7, B0, B1 were tested. Pins F3...F10 are inside `#if STM32_ADC_USE_ADC3` because some devices which don't have ADC3 also don't have the GPIOF port, therefore the code which refers to Fx pins does not compile. * Fix STM32F3xx ADC mux table in documentation The ADC driver documentation had some errors in the mux table for STM32F3xx. Fix this table to match the datasheet and the actual code (mux settings for B12 and B13 were also tested on a real STM32F303CCT6 chip). * Add STM32F1xx ADC pins to the documentation * Add STM32F4xx ADC pins to the documentation
3 years ago
Update ADC driver for STM32F1xx, STM32F3xx, STM32F4xx (#12403) * Fix default ADC_RESOLUTION for ADCv3 (and ADCv4) Recent ChibiOS update removed ADC_CFGR1_RES_10BIT from the ADCv3 headers (that macro should not have been there, because ADCv3 has CFGR instead of CFGR1). Fix the default value for ADC_RESOLUTION to use ADC_CFGR_RES_10BITS if it is defined (that name is used for ADCv3 and ADCv4). * Update ADC docs to match the actually used resolution ADC driver for ChibiOS actually uses the 10-bit resolution by default (probably to match AVR); fix the documentation accordingly. Also add both ADC_CFGR_RES_10BITS and ADC_CFGR1_RES_10BIT constants (these names differ according to the ADC implementation in the particular MCU). * Fix pinToMux() for B12 and B13 on STM32F3xx Testing on STM32F303CCT6 revealed that the ADC mux values for B12 and B13 pins were wrong. * Add support for all possible analog pins on STM32F1xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 on STM32F1xx (they are the same at least for STM32F103x8 and larger F103 devices, and also F102, F105, F107 families). Actually tested on STM32F103C8T6 (therefore pins C0...C5 were not tested). Pins F6...F10, which are present on STM32F103x[C-G] in 144-pin packages, cannot be supported at the moment, because those pins are connected only to ADC3, but the ChibiOS ADC driver for STM32F1xx supports only ADC1. * Add support for all possible analog pins on STM32F4xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 and optionally F3...F10 (if STM32_ADC_USE_ADC3 is enabled). These mux values are apparently the same for all F4xx devices, except some smaller devices may not have ADC3. Actually tested on STM32F401CCU6, STM32F401CEU6, STM32F411CEU6 (using various WeAct “Blackpill” boards); only pins A0...A7, B0, B1 were tested. Pins F3...F10 are inside `#if STM32_ADC_USE_ADC3` because some devices which don't have ADC3 also don't have the GPIOF port, therefore the code which refers to Fx pins does not compile. * Fix STM32F3xx ADC mux table in documentation The ADC driver documentation had some errors in the mux table for STM32F3xx. Fix this table to match the datasheet and the actual code (mux settings for B12 and B13 were also tested on a real STM32F303CCT6 chip). * Add STM32F1xx ADC pins to the documentation * Add STM32F4xx ADC pins to the documentation
3 years ago
Update ADC driver for STM32F1xx, STM32F3xx, STM32F4xx (#12403) * Fix default ADC_RESOLUTION for ADCv3 (and ADCv4) Recent ChibiOS update removed ADC_CFGR1_RES_10BIT from the ADCv3 headers (that macro should not have been there, because ADCv3 has CFGR instead of CFGR1). Fix the default value for ADC_RESOLUTION to use ADC_CFGR_RES_10BITS if it is defined (that name is used for ADCv3 and ADCv4). * Update ADC docs to match the actually used resolution ADC driver for ChibiOS actually uses the 10-bit resolution by default (probably to match AVR); fix the documentation accordingly. Also add both ADC_CFGR_RES_10BITS and ADC_CFGR1_RES_10BIT constants (these names differ according to the ADC implementation in the particular MCU). * Fix pinToMux() for B12 and B13 on STM32F3xx Testing on STM32F303CCT6 revealed that the ADC mux values for B12 and B13 pins were wrong. * Add support for all possible analog pins on STM32F1xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 on STM32F1xx (they are the same at least for STM32F103x8 and larger F103 devices, and also F102, F105, F107 families). Actually tested on STM32F103C8T6 (therefore pins C0...C5 were not tested). Pins F6...F10, which are present on STM32F103x[C-G] in 144-pin packages, cannot be supported at the moment, because those pins are connected only to ADC3, but the ChibiOS ADC driver for STM32F1xx supports only ADC1. * Add support for all possible analog pins on STM32F4xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 and optionally F3...F10 (if STM32_ADC_USE_ADC3 is enabled). These mux values are apparently the same for all F4xx devices, except some smaller devices may not have ADC3. Actually tested on STM32F401CCU6, STM32F401CEU6, STM32F411CEU6 (using various WeAct “Blackpill” boards); only pins A0...A7, B0, B1 were tested. Pins F3...F10 are inside `#if STM32_ADC_USE_ADC3` because some devices which don't have ADC3 also don't have the GPIOF port, therefore the code which refers to Fx pins does not compile. * Fix STM32F3xx ADC mux table in documentation The ADC driver documentation had some errors in the mux table for STM32F3xx. Fix this table to match the datasheet and the actual code (mux settings for B12 and B13 were also tested on a real STM32F303CCT6 chip). * Add STM32F1xx ADC pins to the documentation * Add STM32F4xx ADC pins to the documentation
3 years ago
Update ADC driver for STM32F1xx, STM32F3xx, STM32F4xx (#12403) * Fix default ADC_RESOLUTION for ADCv3 (and ADCv4) Recent ChibiOS update removed ADC_CFGR1_RES_10BIT from the ADCv3 headers (that macro should not have been there, because ADCv3 has CFGR instead of CFGR1). Fix the default value for ADC_RESOLUTION to use ADC_CFGR_RES_10BITS if it is defined (that name is used for ADCv3 and ADCv4). * Update ADC docs to match the actually used resolution ADC driver for ChibiOS actually uses the 10-bit resolution by default (probably to match AVR); fix the documentation accordingly. Also add both ADC_CFGR_RES_10BITS and ADC_CFGR1_RES_10BIT constants (these names differ according to the ADC implementation in the particular MCU). * Fix pinToMux() for B12 and B13 on STM32F3xx Testing on STM32F303CCT6 revealed that the ADC mux values for B12 and B13 pins were wrong. * Add support for all possible analog pins on STM32F1xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 on STM32F1xx (they are the same at least for STM32F103x8 and larger F103 devices, and also F102, F105, F107 families). Actually tested on STM32F103C8T6 (therefore pins C0...C5 were not tested). Pins F6...F10, which are present on STM32F103x[C-G] in 144-pin packages, cannot be supported at the moment, because those pins are connected only to ADC3, but the ChibiOS ADC driver for STM32F1xx supports only ADC1. * Add support for all possible analog pins on STM32F4xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 and optionally F3...F10 (if STM32_ADC_USE_ADC3 is enabled). These mux values are apparently the same for all F4xx devices, except some smaller devices may not have ADC3. Actually tested on STM32F401CCU6, STM32F401CEU6, STM32F411CEU6 (using various WeAct “Blackpill” boards); only pins A0...A7, B0, B1 were tested. Pins F3...F10 are inside `#if STM32_ADC_USE_ADC3` because some devices which don't have ADC3 also don't have the GPIOF port, therefore the code which refers to Fx pins does not compile. * Fix STM32F3xx ADC mux table in documentation The ADC driver documentation had some errors in the mux table for STM32F3xx. Fix this table to match the datasheet and the actual code (mux settings for B12 and B13 were also tested on a real STM32F303CCT6 chip). * Add STM32F1xx ADC pins to the documentation * Add STM32F4xx ADC pins to the documentation
3 years ago
  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. #include "quantum.h"
  17. #include "analog.h"
  18. #include <ch.h>
  19. #include <hal.h>
  20. #if !HAL_USE_ADC
  21. # error "You need to set HAL_USE_ADC to TRUE in your halconf.h to use the ADC."
  22. #endif
  23. #if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3 && !STM32_ADC_USE_ADC4
  24. # error "You need to set one of the 'STM32_ADC_USE_ADCx' settings to TRUE in your mcuconf.h to use the ADC."
  25. #endif
  26. #if STM32_ADC_DUAL_MODE
  27. # error "STM32 ADC Dual Mode is not supported at this time."
  28. #endif
  29. #if STM32_ADCV3_OVERSAMPLING
  30. # error "STM32 ADCV3 Oversampling is not supported at this time."
  31. #endif
  32. // Otherwise assume V3
  33. #if defined(STM32F0XX) || defined(STM32L0XX)
  34. # define USE_ADCV1
  35. #elif defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(GD32VF103)
  36. # define USE_ADCV2
  37. #endif
  38. // BODGE to make v2 look like v1,3 and 4
  39. #ifdef USE_ADCV2
  40. # if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_3)
  41. # define ADC_SMPR_SMP_1P5 ADC_SAMPLE_3
  42. # define ADC_SMPR_SMP_7P5 ADC_SAMPLE_15
  43. # define ADC_SMPR_SMP_13P5 ADC_SAMPLE_28
  44. # define ADC_SMPR_SMP_28P5 ADC_SAMPLE_56
  45. # define ADC_SMPR_SMP_41P5 ADC_SAMPLE_84
  46. # define ADC_SMPR_SMP_55P5 ADC_SAMPLE_112
  47. # define ADC_SMPR_SMP_71P5 ADC_SAMPLE_144
  48. # define ADC_SMPR_SMP_239P5 ADC_SAMPLE_480
  49. # endif
  50. # if !defined(ADC_SMPR_SMP_1P5) && defined(ADC_SAMPLE_1P5)
  51. # define ADC_SMPR_SMP_1P5 ADC_SAMPLE_1P5
  52. # define ADC_SMPR_SMP_7P5 ADC_SAMPLE_7P5
  53. # define ADC_SMPR_SMP_13P5 ADC_SAMPLE_13P5
  54. # define ADC_SMPR_SMP_28P5 ADC_SAMPLE_28P5
  55. # define ADC_SMPR_SMP_41P5 ADC_SAMPLE_41P5
  56. # define ADC_SMPR_SMP_55P5 ADC_SAMPLE_55P5
  57. # define ADC_SMPR_SMP_71P5 ADC_SAMPLE_71P5
  58. # define ADC_SMPR_SMP_239P5 ADC_SAMPLE_239P5
  59. # endif
  60. // we still sample at 12bit, but scale down to the requested bit range
  61. # define ADC_CFGR1_RES_12BIT 12
  62. # define ADC_CFGR1_RES_10BIT 10
  63. # define ADC_CFGR1_RES_8BIT 8
  64. # define ADC_CFGR1_RES_6BIT 6
  65. #endif
  66. /* User configurable ADC options */
  67. #ifndef ADC_COUNT
  68. # if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F4XX) || defined(GD32VF103)
  69. # define ADC_COUNT 1
  70. # elif defined(STM32F3XX)
  71. # define ADC_COUNT 4
  72. # else
  73. # error "ADC_COUNT has not been set for this ARM microcontroller."
  74. # endif
  75. #endif
  76. #ifndef ADC_NUM_CHANNELS
  77. # define ADC_NUM_CHANNELS 1
  78. #elif ADC_NUM_CHANNELS != 1
  79. # error "The ARM ADC implementation currently only supports reading one channel at a time."
  80. #endif
  81. #ifndef ADC_BUFFER_DEPTH
  82. # define ADC_BUFFER_DEPTH 1
  83. #endif
  84. // For more sampling rate options, look at hal_adc_lld.h in ChibiOS
  85. #ifndef ADC_SAMPLING_RATE
  86. # define ADC_SAMPLING_RATE ADC_SMPR_SMP_1P5
  87. #endif
  88. // Options are 12, 10, 8, and 6 bit.
  89. #ifndef ADC_RESOLUTION
  90. # ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4
  91. # define ADC_RESOLUTION ADC_CFGR_RES_10BITS
  92. # else // ADCv1, ADCv5, or the bodge for ADCv2 above
  93. # define ADC_RESOLUTION ADC_CFGR1_RES_10BIT
  94. # endif
  95. #endif
  96. static ADCConfig adcCfg = {};
  97. static adcsample_t sampleBuffer[ADC_NUM_CHANNELS * ADC_BUFFER_DEPTH];
  98. // Initialize to max number of ADCs, set to empty object to initialize all to false.
  99. static bool adcInitialized[ADC_COUNT] = {};
  100. // TODO: add back TR handling???
  101. static ADCConversionGroup adcConversionGroup = {
  102. .circular = FALSE,
  103. .num_channels = (uint16_t)(ADC_NUM_CHANNELS),
  104. #if defined(USE_ADCV1)
  105. .cfgr1 = ADC_CFGR1_CONT | ADC_RESOLUTION,
  106. .smpr = ADC_SAMPLING_RATE,
  107. #elif defined(USE_ADCV2)
  108. # if !defined(STM32F1XX) && !defined(GD32VF103)
  109. .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without...
  110. # endif
  111. .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),
  112. .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),
  113. #else
  114. .cfgr = ADC_CFGR_CONT | ADC_RESOLUTION,
  115. .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)},
  116. #endif
  117. };
  118. // clang-format off
  119. __attribute__((weak)) adc_mux pinToMux(pin_t pin) {
  120. switch (pin) {
  121. #if defined(STM32F0XX)
  122. case A0: return TO_MUX( ADC_CHSELR_CHSEL0, 0 );
  123. case A1: return TO_MUX( ADC_CHSELR_CHSEL1, 0 );
  124. case A2: return TO_MUX( ADC_CHSELR_CHSEL2, 0 );
  125. case A3: return TO_MUX( ADC_CHSELR_CHSEL3, 0 );
  126. case A4: return TO_MUX( ADC_CHSELR_CHSEL4, 0 );
  127. case A5: return TO_MUX( ADC_CHSELR_CHSEL5, 0 );
  128. case A6: return TO_MUX( ADC_CHSELR_CHSEL6, 0 );
  129. case A7: return TO_MUX( ADC_CHSELR_CHSEL7, 0 );
  130. case B0: return TO_MUX( ADC_CHSELR_CHSEL8, 0 );
  131. case B1: return TO_MUX( ADC_CHSELR_CHSEL9, 0 );
  132. case C0: return TO_MUX( ADC_CHSELR_CHSEL10, 0 );
  133. case C1: return TO_MUX( ADC_CHSELR_CHSEL11, 0 );
  134. case C2: return TO_MUX( ADC_CHSELR_CHSEL12, 0 );
  135. case C3: return TO_MUX( ADC_CHSELR_CHSEL13, 0 );
  136. case C4: return TO_MUX( ADC_CHSELR_CHSEL14, 0 );
  137. case C5: return TO_MUX( ADC_CHSELR_CHSEL15, 0 );
  138. #elif defined(STM32F3XX)
  139. case A0: return TO_MUX( ADC_CHANNEL_IN1, 0 );
  140. case A1: return TO_MUX( ADC_CHANNEL_IN2, 0 );
  141. case A2: return TO_MUX( ADC_CHANNEL_IN3, 0 );
  142. case A3: return TO_MUX( ADC_CHANNEL_IN4, 0 );
  143. case A4: return TO_MUX( ADC_CHANNEL_IN1, 1 );
  144. case A5: return TO_MUX( ADC_CHANNEL_IN2, 1 );
  145. case A6: return TO_MUX( ADC_CHANNEL_IN3, 1 );
  146. case A7: return TO_MUX( ADC_CHANNEL_IN4, 1 );
  147. case B0: return TO_MUX( ADC_CHANNEL_IN12, 2 );
  148. case B1: return TO_MUX( ADC_CHANNEL_IN1, 2 );
  149. case B2: return TO_MUX( ADC_CHANNEL_IN12, 1 );
  150. case B12: return TO_MUX( ADC_CHANNEL_IN3, 3 );
  151. case B13: return TO_MUX( ADC_CHANNEL_IN5, 2 );
  152. case B14: return TO_MUX( ADC_CHANNEL_IN4, 3 );
  153. case B15: return TO_MUX( ADC_CHANNEL_IN5, 3 );
  154. case C0: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2
  155. case C1: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2
  156. case C2: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2
  157. case C3: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2
  158. case C4: return TO_MUX( ADC_CHANNEL_IN5, 1 );
  159. case C5: return TO_MUX( ADC_CHANNEL_IN11, 1 );
  160. case D8: return TO_MUX( ADC_CHANNEL_IN12, 3 );
  161. case D9: return TO_MUX( ADC_CHANNEL_IN13, 3 );
  162. case D10: return TO_MUX( ADC_CHANNEL_IN7, 2 ); // Can also be ADC4
  163. case D11: return TO_MUX( ADC_CHANNEL_IN8, 2 ); // Can also be ADC4
  164. case D12: return TO_MUX( ADC_CHANNEL_IN9, 2 ); // Can also be ADC4
  165. case D13: return TO_MUX( ADC_CHANNEL_IN10, 2 ); // Can also be ADC4
  166. case D14: return TO_MUX( ADC_CHANNEL_IN11, 2 ); // Can also be ADC4
  167. case E7: return TO_MUX( ADC_CHANNEL_IN13, 2 );
  168. case E8: return TO_MUX( ADC_CHANNEL_IN6, 2 ); // Can also be ADC4
  169. case E9: return TO_MUX( ADC_CHANNEL_IN2, 2 );
  170. case E10: return TO_MUX( ADC_CHANNEL_IN14, 2 );
  171. case E11: return TO_MUX( ADC_CHANNEL_IN15, 2 );
  172. case E12: return TO_MUX( ADC_CHANNEL_IN16, 2 );
  173. case E13: return TO_MUX( ADC_CHANNEL_IN3, 2 );
  174. case E14: return TO_MUX( ADC_CHANNEL_IN1, 3 );
  175. case E15: return TO_MUX( ADC_CHANNEL_IN2, 3 );
  176. case F2: return TO_MUX( ADC_CHANNEL_IN10, 0 ); // Can also be ADC2
  177. case F4: return TO_MUX( ADC_CHANNEL_IN5, 0 );
  178. #elif defined(STM32F4XX)
  179. case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 );
  180. case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 );
  181. case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 );
  182. case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 );
  183. case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 );
  184. case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 );
  185. case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 );
  186. case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 );
  187. case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 );
  188. case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 );
  189. case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 );
  190. case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 );
  191. case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 );
  192. case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 );
  193. case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 );
  194. case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 );
  195. # if STM32_ADC_USE_ADC3
  196. case F3: return TO_MUX( ADC_CHANNEL_IN9, 2 );
  197. case F4: return TO_MUX( ADC_CHANNEL_IN14, 2 );
  198. case F5: return TO_MUX( ADC_CHANNEL_IN15, 2 );
  199. case F6: return TO_MUX( ADC_CHANNEL_IN4, 2 );
  200. case F7: return TO_MUX( ADC_CHANNEL_IN5, 2 );
  201. case F8: return TO_MUX( ADC_CHANNEL_IN6, 2 );
  202. case F9: return TO_MUX( ADC_CHANNEL_IN7, 2 );
  203. case F10: return TO_MUX( ADC_CHANNEL_IN8, 2 );
  204. # endif
  205. #elif defined(STM32F1XX) || defined(GD32VF103)
  206. case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 );
  207. case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 );
  208. case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 );
  209. case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 );
  210. case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 );
  211. case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 );
  212. case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 );
  213. case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 );
  214. case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 );
  215. case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 );
  216. case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 );
  217. case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 );
  218. case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 );
  219. case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 );
  220. case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 );
  221. case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 );
  222. // STM32F103x[C-G] in 144-pin packages also have analog inputs on F6...F10, but they are on ADC3, and the
  223. // ChibiOS ADC driver for STM32F1xx currently supports only ADC1, therefore these pins are not usable.
  224. #endif
  225. }
  226. // return an adc that would never be used so intToADCDriver will bail out
  227. return TO_MUX(0, 0xFF);
  228. }
  229. // clang-format on
  230. static inline ADCDriver* intToADCDriver(uint8_t adcInt) {
  231. switch (adcInt) {
  232. #if STM32_ADC_USE_ADC1
  233. case 0:
  234. return &ADCD1;
  235. #endif
  236. #if STM32_ADC_USE_ADC2
  237. case 1:
  238. return &ADCD2;
  239. #endif
  240. #if STM32_ADC_USE_ADC3
  241. case 2:
  242. return &ADCD3;
  243. #endif
  244. #if STM32_ADC_USE_ADC4
  245. case 3:
  246. return &ADCD4;
  247. #endif
  248. }
  249. return NULL;
  250. }
  251. static inline void manageAdcInitializationDriver(uint8_t adc, ADCDriver* adcDriver) {
  252. if (!adcInitialized[adc]) {
  253. adcStart(adcDriver, &adcCfg);
  254. adcInitialized[adc] = true;
  255. }
  256. }
  257. int16_t analogReadPin(pin_t pin) {
  258. palSetLineMode(pin, PAL_MODE_INPUT_ANALOG);
  259. return adc_read(pinToMux(pin));
  260. }
  261. int16_t analogReadPinAdc(pin_t pin, uint8_t adc) {
  262. palSetLineMode(pin, PAL_MODE_INPUT_ANALOG);
  263. adc_mux target = pinToMux(pin);
  264. target.adc = adc;
  265. return adc_read(target);
  266. }
  267. int16_t adc_read(adc_mux mux) {
  268. #if defined(USE_ADCV1)
  269. // TODO: fix previous assumption of only 1 input...
  270. adcConversionGroup.chselr = 1 << mux.input; /*no macro to convert N to ADC_CHSELR_CHSEL1*/
  271. #elif defined(USE_ADCV2)
  272. adcConversionGroup.sqr3 = ADC_SQR3_SQ1_N(mux.input);
  273. #else
  274. adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(mux.input);
  275. #endif
  276. ADCDriver* targetDriver = intToADCDriver(mux.adc);
  277. if (!targetDriver) {
  278. return 0;
  279. }
  280. manageAdcInitializationDriver(mux.adc, targetDriver);
  281. if (adcConvert(targetDriver, &adcConversionGroup, &sampleBuffer[0], ADC_BUFFER_DEPTH) != MSG_OK) {
  282. return 0;
  283. }
  284. #ifdef USE_ADCV2
  285. // fake 12-bit -> N-bit scale
  286. return (*sampleBuffer) >> (12 - ADC_RESOLUTION);
  287. #else
  288. // already handled as part of adcConvert
  289. return *sampleBuffer;
  290. #endif
  291. }