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"
33 #include "drivers/io.h"
38 #include "drivers/sensor.h"
45 // These are missing from STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_adc.h
47 #define ADC_Channel_TempSensor ADC_Channel_18
50 const adcDevice_t adcHardware
[] = {
53 .rccADC
= RCC_APB2(ADC1
),
54 #if !defined(USE_DMA_SPEC)
55 .dmaResource
= (dmaResource_t
*)ADC1_DMA_STREAM
,
56 .channel
= DMA_Channel_0
59 #if !defined(STM32F411xE)
62 .rccADC
= RCC_APB2(ADC2
),
63 #if !defined(USE_DMA_SPEC)
64 .dmaResource
= (dmaResource_t
*)ADC2_DMA_STREAM
,
65 .channel
= DMA_Channel_1
70 .rccADC
= RCC_APB2(ADC3
),
71 #if !defined(USE_DMA_SPEC)
72 .dmaResource
= (dmaResource_t
*)ADC3_DMA_STREAM
,
73 .channel
= DMA_Channel_2
79 /* note these could be packed up for saving space */
80 const adcTagMap_t adcTagMap
[] = {
82 { DEFIO_TAG_E__PF3, ADC_DEVICES_3, ADC_Channel_9 },
83 { DEFIO_TAG_E__PF4, ADC_DEVICES_3, ADC_Channel_14 },
84 { DEFIO_TAG_E__PF5, ADC_DEVICES_3, ADC_Channel_15 },
85 { DEFIO_TAG_E__PF6, ADC_DEVICES_3, ADC_Channel_4 },
86 { DEFIO_TAG_E__PF7, ADC_DEVICES_3, ADC_Channel_5 },
87 { DEFIO_TAG_E__PF8, ADC_DEVICES_3, ADC_Channel_6 },
88 { DEFIO_TAG_E__PF9, ADC_DEVICES_3, ADC_Channel_7 },
89 { DEFIO_TAG_E__PF10,ADC_DEVICES_3, ADC_Channel_8 },
91 #if defined(STM32F411xE)
92 { DEFIO_TAG_E__PC0
, ADC_DEVICES_1
, ADC_Channel_10
},
93 { DEFIO_TAG_E__PC1
, ADC_DEVICES_1
, ADC_Channel_11
},
94 { DEFIO_TAG_E__PC2
, ADC_DEVICES_1
, ADC_Channel_12
},
95 { DEFIO_TAG_E__PC3
, ADC_DEVICES_1
, ADC_Channel_13
},
96 { DEFIO_TAG_E__PC4
, ADC_DEVICES_1
, ADC_Channel_14
},
97 { DEFIO_TAG_E__PC5
, ADC_DEVICES_1
, ADC_Channel_15
},
98 { DEFIO_TAG_E__PB0
, ADC_DEVICES_1
, ADC_Channel_8
},
99 { DEFIO_TAG_E__PB1
, ADC_DEVICES_1
, ADC_Channel_9
},
100 { DEFIO_TAG_E__PA0
, ADC_DEVICES_1
, ADC_Channel_0
},
101 { DEFIO_TAG_E__PA1
, ADC_DEVICES_1
, ADC_Channel_1
},
102 { DEFIO_TAG_E__PA2
, ADC_DEVICES_1
, ADC_Channel_2
},
103 { DEFIO_TAG_E__PA3
, ADC_DEVICES_1
, ADC_Channel_3
},
104 { DEFIO_TAG_E__PA4
, ADC_DEVICES_1
, ADC_Channel_4
},
105 { DEFIO_TAG_E__PA5
, ADC_DEVICES_1
, ADC_Channel_5
},
106 { DEFIO_TAG_E__PA6
, ADC_DEVICES_1
, ADC_Channel_6
},
107 { DEFIO_TAG_E__PA7
, ADC_DEVICES_1
, ADC_Channel_7
},
109 { DEFIO_TAG_E__PC0
, ADC_DEVICES_123
, ADC_Channel_10
},
110 { DEFIO_TAG_E__PC1
, ADC_DEVICES_123
, ADC_Channel_11
},
111 { DEFIO_TAG_E__PC2
, ADC_DEVICES_123
, ADC_Channel_12
},
112 { DEFIO_TAG_E__PC3
, ADC_DEVICES_123
, ADC_Channel_13
},
113 { DEFIO_TAG_E__PC4
, ADC_DEVICES_12
, ADC_Channel_14
},
114 { DEFIO_TAG_E__PC5
, ADC_DEVICES_12
, ADC_Channel_15
},
115 { DEFIO_TAG_E__PB0
, ADC_DEVICES_12
, ADC_Channel_8
},
116 { DEFIO_TAG_E__PB1
, ADC_DEVICES_12
, ADC_Channel_9
},
117 { DEFIO_TAG_E__PA0
, ADC_DEVICES_123
, ADC_Channel_0
},
118 { DEFIO_TAG_E__PA1
, ADC_DEVICES_123
, ADC_Channel_1
},
119 { DEFIO_TAG_E__PA2
, ADC_DEVICES_123
, ADC_Channel_2
},
120 { DEFIO_TAG_E__PA3
, ADC_DEVICES_123
, ADC_Channel_3
},
121 { DEFIO_TAG_E__PA4
, ADC_DEVICES_12
, ADC_Channel_4
},
122 { DEFIO_TAG_E__PA5
, ADC_DEVICES_12
, ADC_Channel_5
},
123 { DEFIO_TAG_E__PA6
, ADC_DEVICES_12
, ADC_Channel_6
},
124 { DEFIO_TAG_E__PA7
, ADC_DEVICES_12
, ADC_Channel_7
},
128 #define VREFINT_CAL_ADDR 0x1FFF7A2A
129 #define TS_CAL1_ADDR 0x1FFF7A2C
130 #define TS_CAL2_ADDR 0x1FFF7A2E
132 void adcInitDevice(ADC_TypeDef
*adcdev
, int channelCount
)
134 ADC_InitTypeDef ADC_InitStructure
;
136 ADC_StructInit(&ADC_InitStructure
);
138 ADC_InitStructure
.ADC_ContinuousConvMode
= ENABLE
;
139 ADC_InitStructure
.ADC_Resolution
= ADC_Resolution_12b
;
140 ADC_InitStructure
.ADC_ExternalTrigConv
= ADC_ExternalTrigConv_T1_CC1
;
141 ADC_InitStructure
.ADC_ExternalTrigConvEdge
= ADC_ExternalTrigConvEdge_None
;
142 ADC_InitStructure
.ADC_DataAlign
= ADC_DataAlign_Right
;
143 ADC_InitStructure
.ADC_NbrOfConversion
= channelCount
;
145 // Multiple injected channel seems to require scan conversion mode to be
146 // enabled even if main (non-injected) channel count is 1.
147 #ifdef USE_ADC_INTERNAL
148 ADC_InitStructure
.ADC_ScanConvMode
= ENABLE
;
150 ADC_InitStructure
.ADC_ScanConvMode
= channelCount
> 1 ? ENABLE
: DISABLE
; // 1=scan more that one channel in group
152 ADC_Init(adcdev
, &ADC_InitStructure
);
155 #ifdef USE_ADC_INTERNAL
156 void adcInitInternalInjected(const adcConfig_t
*config
)
158 ADC_TempSensorVrefintCmd(ENABLE
);
159 ADC_InjectedDiscModeCmd(ADC1
, DISABLE
);
160 ADC_InjectedSequencerLengthConfig(ADC1
, 2);
161 ADC_InjectedChannelConfig(ADC1
, ADC_Channel_Vrefint
, 1, ADC_SampleTime_480Cycles
);
162 ADC_InjectedChannelConfig(ADC1
, ADC_Channel_TempSensor
, 2, ADC_SampleTime_480Cycles
);
164 adcVREFINTCAL
= config
->vrefIntCalibration
? config
->vrefIntCalibration
: *(uint16_t *)VREFINT_CAL_ADDR
;
165 adcTSCAL1
= config
->tempSensorCalibration1
? config
->tempSensorCalibration1
: *(uint16_t *)TS_CAL1_ADDR
;
166 adcTSCAL2
= config
->tempSensorCalibration2
? config
->tempSensorCalibration2
: *(uint16_t *)TS_CAL2_ADDR
;
168 adcTSSlopeK
= (110 - 30) * 1000 / (adcTSCAL2
- adcTSCAL1
);
171 // Note on sampling time for temperature sensor and vrefint:
172 // Both sources have minimum sample time of 10us.
173 // With prescaler = 8:
174 // 168MHz : fAPB2 = 84MHz, fADC = 10.5MHz, tcycle = 0.090us, 10us = 105cycle < 144cycle
175 // 240MHz : fAPB2 = 120MHz, fADC = 15.0MHz, tcycle = 0.067usk 10us = 150cycle < 480cycle
177 // 480cycles@15.0MHz = 32us
179 static bool adcInternalConversionInProgress
= false;
181 bool adcInternalIsBusy(void)
183 if (adcInternalConversionInProgress
) {
184 if (ADC_GetFlagStatus(ADC1
, ADC_FLAG_JEOC
) != RESET
) {
185 adcInternalConversionInProgress
= false;
189 return adcInternalConversionInProgress
;
192 void adcInternalStartConversion(void)
194 ADC_ClearFlag(ADC1
, ADC_FLAG_JEOC
);
195 ADC_SoftwareStartInjectedConv(ADC1
);
197 adcInternalConversionInProgress
= true;
200 uint16_t adcInternalReadVrefint(void)
202 return ADC_GetInjectedConversionValue(ADC1
, ADC_InjectedChannel_1
);
205 uint16_t adcInternalReadTempsensor(void)
207 return ADC_GetInjectedConversionValue(ADC1
, ADC_InjectedChannel_2
);
211 void adcInit(const adcConfig_t
*config
)
214 uint8_t configuredAdcChannels
= 0;
216 memset(&adcOperatingConfig
, 0, sizeof(adcOperatingConfig
));
218 if (config
->vbat
.enabled
) {
219 adcOperatingConfig
[ADC_BATTERY
].tag
= config
->vbat
.ioTag
;
222 if (config
->rssi
.enabled
) {
223 adcOperatingConfig
[ADC_RSSI
].tag
= config
->rssi
.ioTag
; //RSSI_ADC_CHANNEL;
226 if (config
->external1
.enabled
) {
227 adcOperatingConfig
[ADC_EXTERNAL1
].tag
= config
->external1
.ioTag
; //EXTERNAL1_ADC_CHANNEL;
230 if (config
->current
.enabled
) {
231 adcOperatingConfig
[ADC_CURRENT
].tag
= config
->current
.ioTag
; //CURRENT_METER_ADC_CHANNEL;
234 ADCDevice device
= ADC_CFG_TO_DEV(config
->device
);
236 if (device
== ADCINVALID
) {
240 adcDevice_t adc
= adcHardware
[device
];
242 bool adcActive
= false;
243 for (int i
= 0; i
< ADC_CHANNEL_COUNT
; i
++) {
244 if (!adcVerifyPin(adcOperatingConfig
[i
].tag
, device
)) {
249 IOInit(IOGetByTag(adcOperatingConfig
[i
].tag
), OWNER_ADC_BATT
+ i
, 0);
250 IOConfigGPIO(IOGetByTag(adcOperatingConfig
[i
].tag
), IO_CONFIG(GPIO_Mode_AN
, 0, GPIO_OType_OD
, GPIO_PuPd_NOPULL
));
251 adcOperatingConfig
[i
].adcChannel
= adcChannelByTag(adcOperatingConfig
[i
].tag
);
252 adcOperatingConfig
[i
].dmaIndex
= configuredAdcChannels
++;
253 adcOperatingConfig
[i
].sampleTime
= ADC_SampleTime_480Cycles
;
254 adcOperatingConfig
[i
].enabled
= true;
257 #ifndef USE_ADC_INTERNAL
263 RCC_ClockCmd(adc
.rccADC
, ENABLE
);
265 ADC_CommonInitTypeDef ADC_CommonInitStructure
;
267 ADC_CommonStructInit(&ADC_CommonInitStructure
);
268 ADC_CommonInitStructure
.ADC_Mode
= ADC_Mode_Independent
;
269 ADC_CommonInitStructure
.ADC_Prescaler
= ADC_Prescaler_Div8
;
270 ADC_CommonInitStructure
.ADC_DMAAccessMode
= ADC_DMAAccessMode_Disabled
;
271 ADC_CommonInitStructure
.ADC_TwoSamplingDelay
= ADC_TwoSamplingDelay_5Cycles
;
272 ADC_CommonInit(&ADC_CommonInitStructure
);
274 #ifdef USE_ADC_INTERNAL
275 // If device is not ADC1 or there's no active channel, then initialize ADC1 separately
276 if (device
!= ADCDEV_1
|| !adcActive
) {
277 RCC_ClockCmd(adcHardware
[ADCDEV_1
].rccADC
, ENABLE
);
278 adcInitDevice(ADC1
, 2);
279 ADC_Cmd(ADC1
, ENABLE
);
282 // Initialize for injected conversion
283 adcInitInternalInjected(config
);
290 adcInitDevice(adc
.ADCx
, configuredAdcChannels
);
293 for (i
= 0; i
< ADC_CHANNEL_COUNT
; i
++) {
294 if (!adcOperatingConfig
[i
].enabled
) {
297 ADC_RegularChannelConfig(adc
.ADCx
, adcOperatingConfig
[i
].adcChannel
, rank
++, adcOperatingConfig
[i
].sampleTime
);
299 ADC_DMARequestAfterLastTransferCmd(adc
.ADCx
, ENABLE
);
301 ADC_DMACmd(adc
.ADCx
, ENABLE
);
302 ADC_Cmd(adc
.ADCx
, ENABLE
);
305 const dmaChannelSpec_t
*dmaSpec
= dmaGetChannelSpecByPeripheral(DMA_PERIPH_ADC
, device
, config
->dmaopt
[device
]);
307 if (!dmaSpec
|| !dmaAllocate(dmaGetIdentifier(dmaSpec
->ref
), OWNER_ADC
, RESOURCE_INDEX(device
))) {
311 dmaEnable(dmaGetIdentifier(dmaSpec
->ref
));
313 xDMA_DeInit(dmaSpec
->ref
);
315 if (!dmaAllocate(dmaGetIdentifier(adc
.dmaResource
), OWNER_ADC
, 0)) {
319 dmaEnable(dmaGetIdentifier(adc
.dmaResource
));
321 xDMA_DeInit(adc
.dmaResource
);
324 DMA_InitTypeDef DMA_InitStructure
;
326 DMA_StructInit(&DMA_InitStructure
);
327 DMA_InitStructure
.DMA_PeripheralBaseAddr
= (uint32_t)&adc
.ADCx
->DR
;
330 DMA_InitStructure
.DMA_Channel
= dmaSpec
->channel
;
332 DMA_InitStructure
.DMA_Channel
= adc
.channel
;
335 DMA_InitStructure
.DMA_Memory0BaseAddr
= (uint32_t)adcValues
;
336 DMA_InitStructure
.DMA_DIR
= DMA_DIR_PeripheralToMemory
;
337 DMA_InitStructure
.DMA_BufferSize
= configuredAdcChannels
;
338 DMA_InitStructure
.DMA_PeripheralInc
= DMA_PeripheralInc_Disable
;
339 DMA_InitStructure
.DMA_MemoryInc
= configuredAdcChannels
> 1 ? DMA_MemoryInc_Enable
: DMA_MemoryInc_Disable
;
340 DMA_InitStructure
.DMA_PeripheralDataSize
= DMA_PeripheralDataSize_HalfWord
;
341 DMA_InitStructure
.DMA_MemoryDataSize
= DMA_MemoryDataSize_HalfWord
;
342 DMA_InitStructure
.DMA_Mode
= DMA_Mode_Circular
;
343 DMA_InitStructure
.DMA_Priority
= DMA_Priority_High
;
346 xDMA_Init(dmaSpec
->ref
, &DMA_InitStructure
);
347 xDMA_Cmd(dmaSpec
->ref
, ENABLE
);
349 xDMA_Init(adc
.dmaResource
, &DMA_InitStructure
);
350 xDMA_Cmd(adc
.dmaResource
, ENABLE
);
353 ADC_SoftwareStartConv(adc
.ADCx
);
356 void adcGetChannelValues(void)