2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "drivers/time.h"
25 #include "drivers/io.h"
29 #include "drivers/sensor.h"
30 #include "drivers/accgyro/accgyro.h"
35 #if !defined(ADC1_DMA_STREAM)
36 #define ADC1_DMA_STREAM DMA2_Stream0
39 static adcDevice_t adcHardware
[ADCDEV_COUNT
] = {
40 { .ADCx
= ADC1
, .rccADC
= RCC_APB2(ADC1
), .rccDMA
= RCC_AHB1(DMA2
), .DMAy_Streamx
= ADC1_DMA_STREAM
, .channel
= DMA_Channel_0
, .enabled
= false, .usedChannelCount
= 0 },
41 //{ .ADCx = ADC2, .rccADC = RCC_APB2(ADC2), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream1, .channel = DMA_Channel_0, .enabled = false, .usedChannelCount = 0 }
44 /* note these could be packed up for saving space */
45 const adcTagMap_t adcTagMap
[] = {
47 { DEFIO_TAG_E__PF3, ADC_Channel_9 },
48 { DEFIO_TAG_E__PF4, ADC_Channel_14 },
49 { DEFIO_TAG_E__PF5, ADC_Channel_15 },
50 { DEFIO_TAG_E__PF6, ADC_Channel_4 },
51 { DEFIO_TAG_E__PF7, ADC_Channel_5 },
52 { DEFIO_TAG_E__PF8, ADC_Channel_6 },
53 { DEFIO_TAG_E__PF9, ADC_Channel_7 },
54 { DEFIO_TAG_E__PF10, ADC_Channel_8 },
56 { DEFIO_TAG_E__PC0
, ADC_Channel_10
},
57 { DEFIO_TAG_E__PC1
, ADC_Channel_11
},
58 { DEFIO_TAG_E__PC2
, ADC_Channel_12
},
59 { DEFIO_TAG_E__PC3
, ADC_Channel_13
},
60 { DEFIO_TAG_E__PC4
, ADC_Channel_14
},
61 { DEFIO_TAG_E__PC5
, ADC_Channel_15
},
62 { DEFIO_TAG_E__PB0
, ADC_Channel_8
},
63 { DEFIO_TAG_E__PB1
, ADC_Channel_9
},
64 { DEFIO_TAG_E__PA0
, ADC_Channel_0
},
65 { DEFIO_TAG_E__PA1
, ADC_Channel_1
},
66 { DEFIO_TAG_E__PA2
, ADC_Channel_2
},
67 { DEFIO_TAG_E__PA3
, ADC_Channel_3
},
68 { DEFIO_TAG_E__PA4
, ADC_Channel_4
},
69 { DEFIO_TAG_E__PA5
, ADC_Channel_5
},
70 { DEFIO_TAG_E__PA6
, ADC_Channel_6
},
71 { DEFIO_TAG_E__PA7
, ADC_Channel_7
},
74 ADCDevice
adcDeviceByInstance(ADC_TypeDef
*instance
)
79 if (instance == ADC2) // TODO add ADC2 and 3
84 static void adcInstanceInit(ADCDevice adcDevice
)
86 ADC_InitTypeDef ADC_InitStructure
;
87 DMA_InitTypeDef DMA_InitStructure
;
88 ADC_CommonInitTypeDef ADC_CommonInitStructure
;
90 adcDevice_t
* adc
= &adcHardware
[adcDevice
];
92 RCC_ClockCmd(adc
->rccDMA
, ENABLE
);
93 RCC_ClockCmd(adc
->rccADC
, ENABLE
);
95 DMA_DeInit(adc
->DMAy_Streamx
);
97 DMA_StructInit(&DMA_InitStructure
);
98 DMA_InitStructure
.DMA_PeripheralBaseAddr
= (uint32_t)&adc
->ADCx
->DR
;
99 DMA_InitStructure
.DMA_Channel
= adc
->channel
;
100 DMA_InitStructure
.DMA_Memory0BaseAddr
= (uint32_t)adcValues
[adcDevice
];
101 DMA_InitStructure
.DMA_DIR
= DMA_DIR_PeripheralToMemory
;
102 DMA_InitStructure
.DMA_BufferSize
= adc
->usedChannelCount
* ADC_AVERAGE_N_SAMPLES
;
103 DMA_InitStructure
.DMA_PeripheralInc
= DMA_PeripheralInc_Disable
;
104 DMA_InitStructure
.DMA_MemoryInc
= ((adc
->usedChannelCount
> 1) || (ADC_AVERAGE_N_SAMPLES
> 1)) ? DMA_MemoryInc_Enable
: DMA_MemoryInc_Disable
;
105 DMA_InitStructure
.DMA_PeripheralDataSize
= DMA_PeripheralDataSize_HalfWord
;
106 DMA_InitStructure
.DMA_MemoryDataSize
= DMA_MemoryDataSize_HalfWord
;
107 DMA_InitStructure
.DMA_Mode
= DMA_Mode_Circular
;
108 DMA_InitStructure
.DMA_Priority
= DMA_Priority_High
;
109 DMA_Init(adc
->DMAy_Streamx
, &DMA_InitStructure
);
111 DMA_Cmd(adc
->DMAy_Streamx
, ENABLE
);
113 ADC_CommonStructInit(&ADC_CommonInitStructure
);
114 ADC_CommonInitStructure
.ADC_Mode
= ADC_Mode_Independent
;
115 ADC_CommonInitStructure
.ADC_Prescaler
= ADC_Prescaler_Div8
;
116 ADC_CommonInitStructure
.ADC_DMAAccessMode
= ADC_DMAAccessMode_Disabled
;
117 ADC_CommonInitStructure
.ADC_TwoSamplingDelay
= ADC_TwoSamplingDelay_5Cycles
;
118 ADC_CommonInit(&ADC_CommonInitStructure
);
120 ADC_StructInit(&ADC_InitStructure
);
122 ADC_InitStructure
.ADC_ContinuousConvMode
= ENABLE
;
123 ADC_InitStructure
.ADC_Resolution
= ADC_Resolution_12b
;
124 ADC_InitStructure
.ADC_ExternalTrigConv
= ADC_ExternalTrigConv_T1_CC1
;
125 ADC_InitStructure
.ADC_ExternalTrigConvEdge
= ADC_ExternalTrigConvEdge_None
;
126 ADC_InitStructure
.ADC_DataAlign
= ADC_DataAlign_Right
;
127 ADC_InitStructure
.ADC_NbrOfConversion
= adc
->usedChannelCount
;
128 ADC_InitStructure
.ADC_ScanConvMode
= adc
->usedChannelCount
> 1 ? ENABLE
: DISABLE
; // 1=scan more that one channel in group
130 ADC_Init(adc
->ADCx
, &ADC_InitStructure
);
133 for (int i
= ADC_CHN_1
; i
< ADC_CHN_COUNT
; i
++) {
134 if (!adcConfig
[i
].enabled
|| adcConfig
[i
].adcDevice
!= adcDevice
) {
138 ADC_RegularChannelConfig(adc
->ADCx
, adcConfig
[i
].adcChannel
, rank
++, adcConfig
[i
].sampleTime
);
141 ADC_DMARequestAfterLastTransferCmd(adc
->ADCx
, ENABLE
);
143 ADC_DMACmd(adc
->ADCx
, ENABLE
);
144 ADC_Cmd(adc
->ADCx
, ENABLE
);
146 ADC_SoftwareStartConv(adc
->ADCx
);
149 void adcHardwareInit(drv_adc_config_t
*init
)
152 int configuredAdcChannels
= 0;
154 for (int i
= ADC_CHN_1
; i
< ADC_CHN_COUNT
; i
++) {
155 if (!adcConfig
[i
].tag
)
158 adcDevice_t
* adc
= &adcHardware
[adcConfig
[i
].adcDevice
];
160 IOInit(IOGetByTag(adcConfig
[i
].tag
), OWNER_ADC
, RESOURCE_ADC_CH1
+ (i
- ADC_CHN_1
), 0);
161 IOConfigGPIO(IOGetByTag(adcConfig
[i
].tag
), IO_CONFIG(GPIO_Mode_AN
, 0, GPIO_OType_OD
, GPIO_PuPd_NOPULL
));
163 adcConfig
[i
].adcChannel
= adcChannelByTag(adcConfig
[i
].tag
);
164 adcConfig
[i
].dmaIndex
= adc
->usedChannelCount
++;
165 adcConfig
[i
].sampleTime
= ADC_SampleTime_480Cycles
;
166 adcConfig
[i
].enabled
= true;
169 configuredAdcChannels
++;
172 if (configuredAdcChannels
== 0)
175 //RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div256); // 72 MHz divided by 256 = 281.25 kHz
177 for (int i
= 0; i
< ADCDEV_COUNT
; i
++) {
178 if (adcHardware
[i
].enabled
) {