2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
29 #include "build/debug.h"
31 #include "drivers/dma_reqmap.h"
32 #include "drivers/io.h"
33 #include "drivers/io_impl.h"
34 #include "drivers/rcc.h"
35 #include "drivers/resource.h"
36 #include "drivers/dma.h"
38 #include "drivers/sensor.h"
40 #include "drivers/adc.h"
41 #include "drivers/adc_impl.h"
45 // XXX Instance and DMA stream defs will be gone in unified target
48 #define ADC1_INSTANCE NULL
51 #define ADC2_INSTANCE NULL
54 #define ADC3_INSTANCE NULL
56 #ifndef ADC1_DMA_STREAM
57 #define ADC1_DMA_STREAM NULL
59 #ifndef ADC2_DMA_STREAM
60 #define ADC2_DMA_STREAM NULL
62 #ifndef ADC3_DMA_STREAM
63 #define ADC3_DMA_STREAM NULL
66 const adcDevice_t adcHardware
[ADCDEV_COUNT
] = {
68 .ADCx
= ADC1_INSTANCE
,
69 .rccADC
= RCC_AHB1(ADC12
),
70 #if !defined(USE_DMA_SPEC)
71 .dmaResource
= (dmaResource_t
*)ADC1_DMA_STREAM
,
72 .channel
= DMA_REQUEST_ADC1
,
75 { .ADCx
= ADC2_INSTANCE
,
76 .rccADC
= RCC_AHB1(ADC12
),
77 #if !defined(USE_DMA_SPEC)
78 .dmaResource
= (dmaResource_t
*)ADC2_DMA_STREAM
,
79 .channel
= DMA_REQUEST_ADC2
,
83 // ADC3 is not available on all H7 MCUs, e.g. H7A3
84 // On H743 and H750, ADC3 can be serviced by BDMA also, but we settle for DMA1 or 2 (for now).
86 .ADCx
= ADC3_INSTANCE
,
87 .rccADC
= RCC_AHB4(ADC3
),
88 #if !defined(USE_DMA_SPEC)
89 .dmaResource
= (dmaResource_t
*)ADC3_DMA_STREAM
,
90 .channel
= DMA_REQUEST_ADC3
,
96 adcDevice_t adcDevice
[ADCDEV_COUNT
];
98 #if defined(STM32H743xx) || defined(STM32H750xx) || defined(STM32H723xx) || defined(STM32H725xx)
99 #define ADC_DEVICE_FOR_INTERNAL ADC_DEVICES_3
100 #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ)
101 #define ADC_DEVICE_FOR_INTERNAL ADC_DEVICES_2
106 /* note these could be packed up for saving space */
107 const adcTagMap_t adcTagMap
[] = {
108 #ifdef USE_ADC_INTERNAL
109 // Pseudo entries for internal sensor.
110 // Keep these at the beginning for easy indexing by ADC_TAG_MAP_{VREFINT,TEMPSENSOR}
111 #define ADC_TAG_MAP_VREFINT 0
112 #define ADC_TAG_MAP_TEMPSENSOR 1
114 #if defined(STM32H743xx) || defined(STM32H750xx) || defined(STM32H7A3xx) || defined(STM32H7A3xxQ)
115 { DEFIO_TAG_E__NONE
, ADC_DEVICE_FOR_INTERNAL
, ADC_CHANNEL_VREFINT
, 18 },
116 { DEFIO_TAG_E__NONE
, ADC_DEVICE_FOR_INTERNAL
, ADC_CHANNEL_TEMPSENSOR
, 17 },
117 #elif defined(STM32H723xx) || defined(STM32H725xx)
118 { DEFIO_TAG_E__NONE
, ADC_DEVICE_FOR_INTERNAL
, ADC_CHANNEL_VREFINT
, 18 },
119 { DEFIO_TAG_E__NONE
, ADC_DEVICE_FOR_INTERNAL
, ADC_CHANNEL_TEMPSENSOR
, 19 },
122 #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ)
123 // See DS13195 Rev 6 Page 51/52
124 { DEFIO_TAG_E__PC0
, ADC_DEVICES_12
, ADC_CHANNEL_10
, 10 },
125 { DEFIO_TAG_E__PC1
, ADC_DEVICES_12
, ADC_CHANNEL_11
, 11 },
126 { DEFIO_TAG_E__PC2
, ADC_DEVICES_12
, ADC_CHANNEL_12
, 0 },
127 { DEFIO_TAG_E__PC3
, ADC_DEVICES_12
, ADC_CHANNEL_13
, 1 },
129 { DEFIO_TAG_E__PC0
, ADC_DEVICES_123
, ADC_CHANNEL_10
, 10 },
130 { DEFIO_TAG_E__PC1
, ADC_DEVICES_123
, ADC_CHANNEL_11
, 11 },
131 { DEFIO_TAG_E__PC2
, ADC_DEVICES_3
, ADC_CHANNEL_0
, 0 },
132 { DEFIO_TAG_E__PC3
, ADC_DEVICES_3
, ADC_CHANNEL_1
, 1 },
134 { DEFIO_TAG_E__PC4
, ADC_DEVICES_12
, ADC_CHANNEL_4
, 4 },
135 { DEFIO_TAG_E__PC5
, ADC_DEVICES_12
, ADC_CHANNEL_8
, 8 },
136 { DEFIO_TAG_E__PB0
, ADC_DEVICES_12
, ADC_CHANNEL_9
, 9 },
137 { DEFIO_TAG_E__PB1
, ADC_DEVICES_12
, ADC_CHANNEL_5
, 5 },
138 { DEFIO_TAG_E__PA0
, ADC_DEVICES_1
, ADC_CHANNEL_16
, 16 },
139 { DEFIO_TAG_E__PA1
, ADC_DEVICES_1
, ADC_CHANNEL_17
, 17 },
140 { DEFIO_TAG_E__PA2
, ADC_DEVICES_12
, ADC_CHANNEL_14
, 14 },
141 { DEFIO_TAG_E__PA3
, ADC_DEVICES_12
, ADC_CHANNEL_15
, 15 },
142 { DEFIO_TAG_E__PA4
, ADC_DEVICES_12
, ADC_CHANNEL_18
, 18 },
143 { DEFIO_TAG_E__PA5
, ADC_DEVICES_12
, ADC_CHANNEL_19
, 19 },
144 { DEFIO_TAG_E__PA6
, ADC_DEVICES_12
, ADC_CHANNEL_3
, 3 },
145 { DEFIO_TAG_E__PA7
, ADC_DEVICES_12
, ADC_CHANNEL_7
, 7 },
148 // Inputs available for packages larger than LQFP144
149 { DEFIO_TAG_E__PF3
, ADC_DEVICES_3
, ADC_CHANNEL_5
, 5 },
150 { DEFIO_TAG_E__PF4
, ADC_DEVICES_3
, ADC_CHANNEL_9
, 9 },
151 { DEFIO_TAG_E__PF5
, ADC_DEVICES_3
, ADC_CHANNEL_4
, 4 },
152 { DEFIO_TAG_E__PF6
, ADC_DEVICES_3
, ADC_CHANNEL_8
, 8 },
153 { DEFIO_TAG_E__PF7
, ADC_DEVICES_3
, ADC_CHANNEL_3
, 3 },
154 { DEFIO_TAG_E__PF8
, ADC_DEVICES_3
, ADC_CHANNEL_7
, 7 },
155 { DEFIO_TAG_E__PF9
, ADC_DEVICES_3
, ADC_CHANNEL_2
, 2 },
156 { DEFIO_TAG_E__PF10
, ADC_DEVICES_3
, ADC_CHANNEL_6
, 6 },
157 { DEFIO_TAG_E__PF11
, ADC_DEVICES_1
, ADC_CHANNEL_2
, 2 },
158 { DEFIO_TAG_E__PF12
, ADC_DEVICES_1
, ADC_CHANNEL_6
, 6 },
159 { DEFIO_TAG_E__PF13
, ADC_DEVICES_2
, ADC_CHANNEL_2
, 2 },
160 { DEFIO_TAG_E__PF14
, ADC_DEVICES_2
, ADC_CHANNEL_6
, 6 },
164 // Translate rank number x to ADC_REGULAR_RANK_x (Note that array index is 0-origin)
166 #define RANK(n) ADC_REGULAR_RANK_ ## n
168 static uint32_t adcRegularRankMap
[] = {
189 static void errorHandler(void) { while (1) { } }
191 // Note on sampling time.
192 // Temperature sensor has minimum sample time of 9us.
193 // With prescaler = 4 at 200MHz (AHB1), fADC = 50MHz (tcycle = 0.02us), 9us = 450cycles < 810
195 void adcInitDevice(adcDevice_t
*adcdev
, int channelCount
)
197 ADC_HandleTypeDef
*hadc
= &adcdev
->ADCHandle
; // For clarity
199 hadc
->Instance
= adcdev
->ADCx
;
201 // DeInit is done in adcInit().
203 hadc
->Init
.ClockPrescaler
= ADC_CLOCK_SYNC_PCLK_DIV4
;
204 hadc
->Init
.Resolution
= ADC_RESOLUTION_12B
;
205 hadc
->Init
.ScanConvMode
= ENABLE
; // Works with single channel, too
206 hadc
->Init
.EOCSelection
= ADC_EOC_SINGLE_CONV
;
207 hadc
->Init
.LowPowerAutoWait
= DISABLE
;
208 hadc
->Init
.ContinuousConvMode
= ENABLE
;
209 hadc
->Init
.NbrOfConversion
= channelCount
;
210 hadc
->Init
.DiscontinuousConvMode
= DISABLE
;
211 hadc
->Init
.NbrOfDiscConversion
= 1; // Don't care
212 hadc
->Init
.ExternalTrigConv
= ADC_SOFTWARE_START
;
213 hadc
->Init
.ExternalTrigConvEdge
= ADC_EXTERNALTRIGCONVEDGE_NONE
; // Don't care
215 // Enable circular DMA.
216 // ADC3 of H72X and H73X has a special way of doing this.
217 #if defined(STM32H723xx) || defined(STM32H725xx)
218 if (adcdev
->ADCx
== ADC3
) {
219 hadc
->Init
.DMAContinuousRequests
= ENABLE
;
223 hadc
->Init
.ConversionDataManagement
= ADC_CONVERSIONDATA_DMA_CIRCULAR
;
227 hadc
->Init
.Overrun
= ADC_OVR_DATA_OVERWRITTEN
;
228 hadc
->Init
.OversamplingMode
= DISABLE
;
230 // Initialize this ADC peripheral
232 if (HAL_ADC_Init(hadc
) != HAL_OK
) {
236 // Execute calibration
238 if (HAL_ADCEx_Calibration_Start(hadc
, ADC_CALIB_OFFSET
, ADC_SINGLE_ENDED
) != HAL_OK
) {
243 int adcFindTagMapEntry(ioTag_t tag
)
245 for (int i
= 0; i
< ADC_TAG_MAP_COUNT
; i
++) {
246 if (adcTagMap
[i
].tag
== tag
) {
253 // H743, H750 and H7A3 seems to use 16-bit precision value,
254 // while H723 and H725 seems to use 12-bit precision value.
255 #if defined(STM32H743xx) || defined(STM32H750xx) || defined(STM32H7A3xx) || defined(STM32H7A3xxQ)
256 #define VREFINT_CAL_SHIFT 4
257 #elif defined(STM32H723xx) || defined(STM32H725xx)
258 #define VREFINT_CAL_SHIFT 0
263 void adcInitCalibrationValues(void)
265 adcVREFINTCAL
= *VREFINT_CAL_ADDR
>> VREFINT_CAL_SHIFT
;
266 adcTSCAL1
= *TEMPSENSOR_CAL1_ADDR
>> VREFINT_CAL_SHIFT
;
267 adcTSCAL2
= *TEMPSENSOR_CAL2_ADDR
>> VREFINT_CAL_SHIFT
;
268 adcTSSlopeK
= (TEMPSENSOR_CAL2_TEMP
- TEMPSENSOR_CAL1_TEMP
) * 1000 / (adcTSCAL2
- adcTSCAL1
);
271 // ADC conversion result DMA buffer
272 // Need this separate from the main adcValue[] array, because channels are numbered
273 // by ADC instance order that is different from ADC_xxx numbering.
275 static volatile DMA_RAM
uint16_t adcConversionBuffer
[ADC_CHANNEL_COUNT
] __attribute__((aligned(32)));
277 void adcInit(const adcConfig_t
*config
)
279 memset(adcOperatingConfig
, 0, sizeof(adcOperatingConfig
));
280 memcpy(adcDevice
, adcHardware
, sizeof(adcDevice
));
282 if (config
->vbat
.enabled
) {
283 adcOperatingConfig
[ADC_BATTERY
].tag
= config
->vbat
.ioTag
;
286 if (config
->rssi
.enabled
) {
287 adcOperatingConfig
[ADC_RSSI
].tag
= config
->rssi
.ioTag
; //RSSI_ADC_CHANNEL;
290 if (config
->external1
.enabled
) {
291 adcOperatingConfig
[ADC_EXTERNAL1
].tag
= config
->external1
.ioTag
; //EXTERNAL1_ADC_CHANNEL;
294 if (config
->current
.enabled
) {
295 adcOperatingConfig
[ADC_CURRENT
].tag
= config
->current
.ioTag
; //CURRENT_METER_ADC_CHANNEL;
298 #ifdef USE_ADC_INTERNAL
299 adcInitCalibrationValues();
302 for (int i
= 0; i
< ADC_CHANNEL_COUNT
; i
++) {
306 if (i
== ADC_TEMPSENSOR
) {
307 map
= ADC_TAG_MAP_TEMPSENSOR
;
308 dev
= ffs(adcTagMap
[map
].devices
) - 1;
309 } else if (i
== ADC_VREFINT
) {
310 map
= ADC_TAG_MAP_VREFINT
;
311 dev
= ffs(adcTagMap
[map
].devices
) - 1;
313 if (!adcOperatingConfig
[i
].tag
) {
317 map
= adcFindTagMapEntry(adcOperatingConfig
[i
].tag
);
322 // Found a tag map entry for this input pin
323 // Find an ADC device that can handle this input pin
325 for (dev
= 0; dev
< ADCDEV_COUNT
; dev
++) {
326 if (!adcDevice
[dev
].ADCx
328 || !adcDevice
[dev
].dmaResource
331 // Instance not activated
334 if (adcTagMap
[map
].devices
& (1 << dev
)) {
335 // Found an activated ADC instance for this input pin
340 if (dev
== ADCDEV_COUNT
) {
341 // No valid device found, go next channel.
346 // At this point, map is an entry for the input pin and dev is a valid ADCx for the pin for input i
348 adcOperatingConfig
[i
].adcDevice
= dev
;
349 adcOperatingConfig
[i
].adcChannel
= adcTagMap
[map
].channel
;
350 adcOperatingConfig
[i
].sampleTime
= ADC_SAMPLETIME_810CYCLES_5
;
351 adcOperatingConfig
[i
].enabled
= true;
353 adcDevice
[dev
].channelBits
|= (1 << adcTagMap
[map
].channelOrdinal
);
355 // Configure a pin for ADC
356 if (adcOperatingConfig
[i
].tag
) {
357 IOInit(IOGetByTag(adcOperatingConfig
[i
].tag
), OWNER_ADC_BATT
+ i
, 0);
358 IOConfigGPIO(IOGetByTag(adcOperatingConfig
[i
].tag
), IO_CONFIG(GPIO_MODE_ANALOG
, 0, GPIO_NOPULL
));
362 // DeInit ADCx with inputs
363 // We have to batch call DeInit() for all devices as DeInit() initializes ADCx_COMMON register.
365 for (int dev
= 0; dev
< ADCDEV_COUNT
; dev
++) {
366 adcDevice_t
*adc
= &adcDevice
[dev
];
368 if (!(adc
->ADCx
&& adc
->channelBits
)) {
372 adc
->ADCHandle
.Instance
= adc
->ADCx
;
374 if (HAL_ADC_DeInit(&adc
->ADCHandle
) != HAL_OK
) {
375 // ADC de-initialization Error
380 // Configure ADCx with inputs
382 int dmaBufferIndex
= 0;
384 for (int dev
= 0; dev
< ADCDEV_COUNT
; dev
++) {
385 adcDevice_t
*adc
= &adcDevice
[dev
];
387 if (!(adc
->ADCx
&& adc
->channelBits
)) {
391 RCC_ClockCmd(adc
->rccADC
, ENABLE
);
393 #ifdef USE_ADC3_DIRECT_HAL_INIT
394 // XXX (Only) ADC3 (sometimes) fails to self calibrate without these? Need to verify
396 // ADC Periph clock enable
397 __HAL_RCC_ADC3_CLK_ENABLE();
399 // ADC Periph interface clock configuration
400 __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP
);
403 int configuredAdcChannels
= BITCOUNT(adc
->channelBits
);
405 adcInitDevice(adc
, configuredAdcChannels
);
407 // Configure channels
411 for (int adcChan
= 0; adcChan
< ADC_CHANNEL_COUNT
; adcChan
++) {
413 if (!adcOperatingConfig
[adcChan
].enabled
) {
417 if (adcOperatingConfig
[adcChan
].adcDevice
!= dev
) {
421 adcOperatingConfig
[adcChan
].dmaIndex
= dmaBufferIndex
++;
423 ADC_ChannelConfTypeDef sConfig
;
425 sConfig
.Channel
= adcOperatingConfig
[adcChan
].adcChannel
; /* Sampled channel number */
426 sConfig
.Rank
= adcRegularRankMap
[rank
++]; /* Rank of sampled channel number ADCx_CHANNEL */
427 sConfig
.SamplingTime
= ADC_SAMPLETIME_387CYCLES_5
; /* Sampling time (number of clock cycles unit) */
428 sConfig
.SingleDiff
= ADC_SINGLE_ENDED
; /* Single-ended input channel */
429 sConfig
.OffsetNumber
= ADC_OFFSET_NONE
; /* No offset subtraction */
430 sConfig
.Offset
= 0; /* Parameter discarded because offset correction is disabled */
432 if (HAL_ADC_ConfigChannel(&adc
->ADCHandle
, &sConfig
) != HAL_OK
) {
437 // Configure DMA for this ADC peripheral
439 dmaIdentifier_e dmaIdentifier
;
441 const dmaChannelSpec_t
*dmaSpec
= dmaGetChannelSpecByPeripheral(DMA_PERIPH_ADC
, dev
, config
->dmaopt
[dev
]);
447 adc
->DmaHandle
.Instance
= dmaSpec
->ref
;
448 adc
->DmaHandle
.Init
.Request
= dmaSpec
->channel
;
449 dmaIdentifier
= dmaGetIdentifier(dmaSpec
->ref
);
451 dmaIdentifier
= dmaGetIdentifier(adc
->dmaResource
);
452 adc
->DmaHandle
.Instance
= (DMA_ARCH_TYPE
*)adc
->dmaResource
;
453 adc
->DmaHandle
.Init
.Request
= adc
->channel
;
455 adc
->DmaHandle
.Init
.Direction
= DMA_PERIPH_TO_MEMORY
;
456 adc
->DmaHandle
.Init
.PeriphInc
= DMA_PINC_DISABLE
;
457 adc
->DmaHandle
.Init
.MemInc
= DMA_MINC_ENABLE
;
458 adc
->DmaHandle
.Init
.PeriphDataAlignment
= DMA_PDATAALIGN_HALFWORD
;
459 adc
->DmaHandle
.Init
.MemDataAlignment
= DMA_MDATAALIGN_HALFWORD
;
460 adc
->DmaHandle
.Init
.Mode
= DMA_CIRCULAR
;
461 adc
->DmaHandle
.Init
.Priority
= DMA_PRIORITY_MEDIUM
;
463 // Deinitialize & Initialize the DMA for new transfer
465 // dmaInit must be called before calling HAL_DMA_Init,
466 // to enable clock for associated DMA if not already done so.
467 dmaInit(dmaIdentifier
, OWNER_ADC
, RESOURCE_INDEX(dev
));
469 HAL_DMA_DeInit(&adc
->DmaHandle
);
470 HAL_DMA_Init(&adc
->DmaHandle
);
472 // Associate the DMA handle
474 __HAL_LINKDMA(&adc
->ADCHandle
, DMA_Handle
, adc
->DmaHandle
);
476 #ifdef USE_ADC_INTERRUPT
477 // XXX No interrupt used, so we can skip this.
478 // If interrupt is needed in any case, use dmaXXX facility instead,
479 // using dmaIdentifier obtained above.
481 // NVIC configuration for DMA Input data interrupt
483 HAL_NVIC_SetPriority(DMA1_Stream1_IRQn
, 1, 0);
484 HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn
);
489 // This must be done after channel configuration is complete, as HAL_ADC_ConfigChannel
490 // throws an error when configuring internal channels if ADC1 or ADC2 are already enabled.
494 for (int dev
= 0; dev
< ADCDEV_COUNT
; dev
++) {
496 adcDevice_t
*adc
= &adcDevice
[dev
];
498 if (!(adc
->ADCx
&& adc
->channelBits
)) {
502 // Start conversion in DMA mode
504 if (HAL_ADC_Start_DMA(&adc
->ADCHandle
, (uint32_t *)&adcConversionBuffer
[dmaBufferIndex
], BITCOUNT(adc
->channelBits
)) != HAL_OK
) {
508 dmaBufferIndex
+= BITCOUNT(adc
->channelBits
);
512 void adcGetChannelValues(void)
514 // Transfer values in conversion buffer into adcValues[]
515 // Cache coherency should be maintained by MPU facility
517 for (int i
= 0; i
< ADC_CHANNEL_INTERNAL
; i
++) {
518 if (adcOperatingConfig
[i
].enabled
) {
519 adcValues
[adcOperatingConfig
[i
].dmaIndex
] = adcConversionBuffer
[adcOperatingConfig
[i
].dmaIndex
];
524 #ifdef USE_ADC_INTERNAL
526 bool adcInternalIsBusy(void)
531 void adcInternalStartConversion(void)
536 uint16_t adcInternalRead(int channel
)
538 int dmaIndex
= adcOperatingConfig
[channel
].dmaIndex
;
540 return adcConversionBuffer
[dmaIndex
];
543 uint16_t adcInternalReadVrefint(void)
545 uint16_t value
= adcInternalRead(ADC_VREFINT
);
549 uint16_t adcInternalReadTempsensor(void)
551 uint16_t value
= adcInternalRead(ADC_TEMPSENSOR
);
554 #endif // USE_ADC_INTERNAL