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"
30 #include "drivers/sensor.h"
31 #include "drivers/accgyro/accgyro.h"
36 static adcDevice_t adcHardware
[ADCDEV_COUNT
] = {
37 { .ADCx
= ADC1
, .rccADC
= RCC_APB2(ADC1
), .rccDMA
= RCC_AHB1(DMA2
), .DMAy_Streamx
= DMA2_Stream0
, .channel
= DMA_CHANNEL_0
, .enabled
= false, .usedChannelCount
= 0 },
38 //{ .ADCx = ADC2, .rccADC = RCC_APB2(ADC2), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream1, .channel = DMA_Channel_0, .enabled = false, .usedChannelCount = 0 }
41 /* note these could be packed up for saving space */
42 const adcTagMap_t adcTagMap
[] = {
44 { DEFIO_TAG_E__PF3, ADC_Channel_9 },
45 { DEFIO_TAG_E__PF4, ADC_Channel_14 },
46 { DEFIO_TAG_E__PF5, ADC_Channel_15 },
47 { DEFIO_TAG_E__PF6, ADC_Channel_4 },
48 { DEFIO_TAG_E__PF7, ADC_Channel_5 },
49 { DEFIO_TAG_E__PF8, ADC_Channel_6 },
50 { DEFIO_TAG_E__PF9, ADC_Channel_7 },
51 { DEFIO_TAG_E__PF10, ADC_Channel_8 },
53 { DEFIO_TAG_E__PC0
, ADC_CHANNEL_10
},
54 { DEFIO_TAG_E__PC1
, ADC_CHANNEL_11
},
55 { DEFIO_TAG_E__PC2
, ADC_CHANNEL_12
},
56 { DEFIO_TAG_E__PC3
, ADC_CHANNEL_13
},
57 { DEFIO_TAG_E__PC4
, ADC_CHANNEL_14
},
58 { DEFIO_TAG_E__PC5
, ADC_CHANNEL_15
},
59 { DEFIO_TAG_E__PB0
, ADC_CHANNEL_8
},
60 { DEFIO_TAG_E__PB1
, ADC_CHANNEL_9
},
61 { DEFIO_TAG_E__PA0
, ADC_CHANNEL_0
},
62 { DEFIO_TAG_E__PA1
, ADC_CHANNEL_1
},
63 { DEFIO_TAG_E__PA2
, ADC_CHANNEL_2
},
64 { DEFIO_TAG_E__PA3
, ADC_CHANNEL_3
},
65 { DEFIO_TAG_E__PA4
, ADC_CHANNEL_4
},
66 { DEFIO_TAG_E__PA5
, ADC_CHANNEL_5
},
67 { DEFIO_TAG_E__PA6
, ADC_CHANNEL_6
},
68 { DEFIO_TAG_E__PA7
, ADC_CHANNEL_7
},
71 ADCDevice
adcDeviceByInstance(ADC_TypeDef
*instance
)
76 if (instance == ADC2) // TODO add ADC2 and 3
82 static void adcInstanceInit(ADCDevice adcDevice
)
84 adcDevice_t
* adc
= &adcHardware
[adcDevice
];
86 RCC_ClockCmd(adc
->rccDMA
, ENABLE
);
87 RCC_ClockCmd(adc
->rccADC
, ENABLE
);
89 adc
->ADCHandle
.Init
.ClockPrescaler
= ADC_CLOCK_SYNC_PCLK_DIV8
;
90 adc
->ADCHandle
.Init
.ContinuousConvMode
= ENABLE
;
91 adc
->ADCHandle
.Init
.Resolution
= ADC_RESOLUTION_12B
;
92 adc
->ADCHandle
.Init
.ExternalTrigConv
= ADC_EXTERNALTRIGCONV_T1_CC1
;
93 adc
->ADCHandle
.Init
.ExternalTrigConvEdge
= ADC_EXTERNALTRIGCONVEDGE_NONE
;
94 adc
->ADCHandle
.Init
.DataAlign
= ADC_DATAALIGN_RIGHT
;
95 adc
->ADCHandle
.Init
.NbrOfConversion
= adc
->usedChannelCount
;
96 adc
->ADCHandle
.Init
.ScanConvMode
= adc
->usedChannelCount
> 1 ? ENABLE
: DISABLE
; // 1=scan more that one channel in group
97 adc
->ADCHandle
.Init
.DiscontinuousConvMode
= DISABLE
;
98 adc
->ADCHandle
.Init
.NbrOfDiscConversion
= 0;
99 adc
->ADCHandle
.Init
.DMAContinuousRequests
= ENABLE
;
100 adc
->ADCHandle
.Init
.EOCSelection
= DISABLE
;
101 adc
->ADCHandle
.Instance
= adc
->ADCx
;
103 /*##-1- Configure the ADC peripheral #######################################*/
104 if (HAL_ADC_Init(&adc
->ADCHandle
) != HAL_OK
)
106 /* Initialization Error */
110 adc
->DmaHandle
.Init
.Channel
= adc
->channel
;
111 adc
->DmaHandle
.Init
.Direction
= DMA_PERIPH_TO_MEMORY
;
112 adc
->DmaHandle
.Init
.PeriphInc
= DMA_PINC_DISABLE
;
113 adc
->DmaHandle
.Init
.MemInc
= ((adc
->usedChannelCount
> 1) || (ADC_AVERAGE_N_SAMPLES
> 1)) ? DMA_MINC_ENABLE
: DMA_MINC_DISABLE
;
114 adc
->DmaHandle
.Init
.PeriphDataAlignment
= DMA_PDATAALIGN_HALFWORD
;
115 adc
->DmaHandle
.Init
.MemDataAlignment
= DMA_MDATAALIGN_HALFWORD
;
116 adc
->DmaHandle
.Init
.Mode
= DMA_CIRCULAR
;
117 adc
->DmaHandle
.Init
.Priority
= DMA_PRIORITY_HIGH
;
118 adc
->DmaHandle
.Init
.FIFOMode
= DMA_FIFOMODE_DISABLE
;
119 adc
->DmaHandle
.Init
.FIFOThreshold
= DMA_FIFO_THRESHOLD_FULL
;
120 adc
->DmaHandle
.Init
.MemBurst
= DMA_MBURST_SINGLE
;
121 adc
->DmaHandle
.Init
.PeriphBurst
= DMA_PBURST_SINGLE
;
122 adc
->DmaHandle
.Instance
= adc
->DMAy_Streamx
;
124 /*##-2- Initialize the DMA stream ##########################################*/
125 if (HAL_DMA_Init(&adc
->DmaHandle
) != HAL_OK
)
127 /* Initialization Error */
131 __HAL_LINKDMA(&adc
->ADCHandle
, DMA_Handle
, adc
->DmaHandle
);
134 for (int i
= ADC_CHN_1
; i
< ADC_CHN_COUNT
; i
++) {
135 if (!adcConfig
[i
].enabled
|| adcConfig
[i
].adcDevice
!= adcDevice
) {
139 ADC_ChannelConfTypeDef sConfig
;
140 sConfig
.Channel
= adcConfig
[i
].adcChannel
;
141 sConfig
.Rank
= rank
++;
142 sConfig
.SamplingTime
= adcConfig
[i
].sampleTime
;
145 /*##-3- Configure ADC regular channel ######################################*/
146 if (HAL_ADC_ConfigChannel(&adc
->ADCHandle
, &sConfig
) != HAL_OK
)
148 /* Channel Configuration Error */
153 //HAL_CLEANINVALIDATECACHE((uint32_t*)&adcValues[adcDevice], configuredAdcChannels);
154 /*##-4- Start the conversion process #######################################*/
155 if (HAL_ADC_Start_DMA(&adc
->ADCHandle
, (uint32_t*)&adcValues
[adcDevice
], adc
->usedChannelCount
* ADC_AVERAGE_N_SAMPLES
) != HAL_OK
)
157 /* Start Conversation Error */
161 void adcHardwareInit(drv_adc_config_t
*init
)
164 int configuredAdcChannels
= 0;
166 for (int i
= ADC_CHN_1
; i
< ADC_CHN_COUNT
; i
++) {
167 if (!adcConfig
[i
].tag
)
170 adcDevice_t
* adc
= &adcHardware
[adcConfig
[i
].adcDevice
];
172 IOInit(IOGetByTag(adcConfig
[i
].tag
), OWNER_ADC
, RESOURCE_ADC_CH1
+ (i
- ADC_CHN_1
), 0);
173 IOConfigGPIO(IOGetByTag(adcConfig
[i
].tag
), IO_CONFIG(GPIO_MODE_ANALOG
, 0, GPIO_NOPULL
));
175 adcConfig
[i
].adcChannel
= adcChannelByTag(adcConfig
[i
].tag
);
176 adcConfig
[i
].dmaIndex
= adc
->usedChannelCount
++;
177 adcConfig
[i
].sampleTime
= ADC_SAMPLETIME_480CYCLES
;
178 adcConfig
[i
].enabled
= true;
181 configuredAdcChannels
++;
184 if (configuredAdcChannels
== 0)
187 for (int i
= 0; i
< ADCDEV_COUNT
; i
++) {
188 if (adcHardware
[i
].enabled
) {