Debug - Initialise debug pins on startup, not as part of the dshot
[betaflight.git] / src / main / drivers / adc_stm32h7xx.c
blobfc4ecd5bf14e88a5891c9a46d26ab49a90aba0ea
1 /*
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)
8 * any later version.
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/>.
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <string.h>
25 #include "platform.h"
27 #ifdef USE_ADC
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"
43 #include "pg/adc.h"
45 // XXX Instance and DMA stream defs will be gone in unified target
47 #ifndef ADC1_INSTANCE
48 #define ADC1_INSTANCE NULL
49 #endif
50 #ifndef ADC2_INSTANCE
51 #define ADC2_INSTANCE NULL
52 #endif
53 #ifndef ADC3_INSTANCE
54 #define ADC3_INSTANCE NULL
55 #endif
56 #ifndef ADC1_DMA_STREAM
57 #define ADC1_DMA_STREAM NULL
58 #endif
59 #ifndef ADC2_DMA_STREAM
60 #define ADC2_DMA_STREAM NULL
61 #endif
62 #ifndef ADC3_DMA_STREAM
63 #define ADC3_DMA_STREAM NULL
64 #endif
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,
73 #endif
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,
80 #endif
82 #if defined(ADC3)
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,
91 #endif
93 #endif // 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
102 #else
103 #error Unknown MCU
104 #endif
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 },
120 #endif
121 #endif
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 },
128 #else
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 },
133 #endif
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 },
147 #if 0
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 },
161 #endif
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[] = {
169 RANK(1),
170 RANK(2),
171 RANK(3),
172 RANK(4),
173 RANK(5),
174 RANK(6),
175 RANK(7),
176 RANK(8),
177 RANK(9),
178 RANK(10),
179 RANK(11),
180 RANK(12),
181 RANK(13),
182 RANK(14),
183 RANK(15),
184 RANK(16),
187 #undef RANK
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;
220 } else
221 #else
223 hadc->Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
225 #endif
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) {
233 errorHandler();
236 // Execute calibration
238 if (HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK) {
239 errorHandler();
243 int adcFindTagMapEntry(ioTag_t tag)
245 for (int i = 0; i < ADC_TAG_MAP_COUNT; i++) {
246 if (adcTagMap[i].tag == tag) {
247 return i;
250 return -1;
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
259 #else
260 #error Unknown MCU
261 #endif
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();
300 #endif
302 for (int i = 0; i < ADC_CHANNEL_COUNT; i++) {
303 int map;
304 int dev;
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;
312 } else {
313 if (!adcOperatingConfig[i].tag) {
314 continue;
317 map = adcFindTagMapEntry(adcOperatingConfig[i].tag);
318 if (map < 0) {
319 continue;
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
327 #ifndef USE_DMA_SPEC
328 || !adcDevice[dev].dmaResource
329 #endif
331 // Instance not activated
332 continue;
334 if (adcTagMap[map].devices & (1 << dev)) {
335 // Found an activated ADC instance for this input pin
336 break;
340 if (dev == ADCDEV_COUNT) {
341 // No valid device found, go next channel.
342 continue;
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)) {
369 continue;
372 adc->ADCHandle.Instance = adc->ADCx;
374 if (HAL_ADC_DeInit(&adc->ADCHandle) != HAL_OK) {
375 // ADC de-initialization Error
376 errorHandler();
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)) {
388 continue;
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);
401 #endif
403 int configuredAdcChannels = BITCOUNT(adc->channelBits);
405 adcInitDevice(adc, configuredAdcChannels);
407 // Configure channels
409 int rank = 0;
411 for (int adcChan = 0; adcChan < ADC_CHANNEL_COUNT; adcChan++) {
413 if (!adcOperatingConfig[adcChan].enabled) {
414 continue;
417 if (adcOperatingConfig[adcChan].adcDevice != dev) {
418 continue;
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) {
433 errorHandler();
437 // Configure DMA for this ADC peripheral
439 dmaIdentifier_e dmaIdentifier;
440 #ifdef USE_DMA_SPEC
441 const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_ADC, dev, config->dmaopt[dev]);
443 if (!dmaSpec) {
444 return;
447 adc->DmaHandle.Instance = dmaSpec->ref;
448 adc->DmaHandle.Init.Request = dmaSpec->channel;
449 dmaIdentifier = dmaGetIdentifier(dmaSpec->ref);
450 #else
451 dmaIdentifier = dmaGetIdentifier(adc->dmaResource);
452 adc->DmaHandle.Instance = (DMA_ARCH_TYPE *)adc->dmaResource;
453 adc->DmaHandle.Init.Request = adc->channel;
454 #endif
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);
485 #endif
488 // Start channels.
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.
492 dmaBufferIndex = 0;
494 for (int dev = 0; dev < ADCDEV_COUNT; dev++) {
496 adcDevice_t *adc = &adcDevice[dev];
498 if (!(adc->ADCx && adc->channelBits)) {
499 continue;
502 // Start conversion in DMA mode
504 if (HAL_ADC_Start_DMA(&adc->ADCHandle, (uint32_t *)&adcConversionBuffer[dmaBufferIndex], BITCOUNT(adc->channelBits)) != HAL_OK) {
505 errorHandler();
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)
528 return false;
531 void adcInternalStartConversion(void)
533 return;
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);
546 return value;
549 uint16_t adcInternalReadTempsensor(void)
551 uint16_t value = adcInternalRead(ADC_TEMPSENSOR);
552 return value;
554 #endif // USE_ADC_INTERNAL
556 #endif // USE_ADC