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.

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