2 * This file is part of ATbetaflight.
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"
28 #include "drivers/dma.h"
30 #include "drivers/sensor.h"
31 #include "drivers/accgyro/accgyro.h"
36 #if !defined(ADC1_DMA_STREAM)
37 #define ADC1_DMA_STREAM DMA2_CHANNEL1
40 static adcDevice_t adcHardware
[ADCDEV_COUNT
] = {
41 { .ADCx
= ADC1
, .rccADC
= RCC_APB2(ADC1
), .rccDMA
= RCC_AHB1(DMA2
), .DMAy_Channelx
= ADC1_DMA_STREAM
, .dmaMuxid
= DMAMUX_DMAREQ_ID_ADC1
,.enabled
= false, .usedChannelCount
= 0 },
44 /* note these could be packed up for saving space */
45 const adcTagMap_t adcTagMap
[] = {
46 { DEFIO_TAG_E__PC0
, ADC_CHANNEL_10
},
47 { DEFIO_TAG_E__PC1
, ADC_CHANNEL_11
},
48 { DEFIO_TAG_E__PC2
, ADC_CHANNEL_12
},
49 { DEFIO_TAG_E__PC3
, ADC_CHANNEL_13
},
50 { DEFIO_TAG_E__PC4
, ADC_CHANNEL_14
},
51 { DEFIO_TAG_E__PC5
, ADC_CHANNEL_15
},
52 { DEFIO_TAG_E__PB0
, ADC_CHANNEL_8
},
53 { DEFIO_TAG_E__PB1
, ADC_CHANNEL_9
},
54 { DEFIO_TAG_E__PA0
, ADC_CHANNEL_0
},
55 { DEFIO_TAG_E__PA1
, ADC_CHANNEL_1
},
56 { DEFIO_TAG_E__PA2
, ADC_CHANNEL_2
},
57 { DEFIO_TAG_E__PA3
, ADC_CHANNEL_3
},
58 { DEFIO_TAG_E__PA4
, ADC_CHANNEL_4
},
59 { DEFIO_TAG_E__PA5
, ADC_CHANNEL_5
},
60 { DEFIO_TAG_E__PA6
, ADC_CHANNEL_6
},
61 { DEFIO_TAG_E__PA7
, ADC_CHANNEL_7
},
64 ADCDevice
adcDeviceByInstance(adc_type
*instance
)
69 if (instance == ADC2) // TODO add ADC2 and 3
76 * Init the Config of the adc common \dma \adc base ,use the regular ordinary to init the ADC instance ,eg.ADC1.
77 * @param adcDevice ADCdevice
80 static void adcInstanceInit(ADCDevice adcDevice
)
82 dma_init_type dma_init_struct
;
83 adcDevice_t
* adc
= &adcHardware
[adcDevice
];
84 // get dma channel, then assign the dma channel
85 DMA_t dmadac
= dmaGetByRef(adc
->DMAy_Channelx
);
90 // dmadac->dmaMuxref = adc->dmaMuxid;//this cause an error
91 dmaInit(dmadac
, OWNER_ADC
, adcDevice
);
93 dma_reset(dmadac
->ref
);
95 dma_default_para_init(&dma_init_struct
);
96 dma_init_struct
.peripheral_base_addr
= (uint32_t)&adc
->ADCx
->odt
;
97 // dma buffer_size= usedChannelCount*sanmple rate
98 dma_init_struct
.buffer_size
= adc
->usedChannelCount
* ADC_AVERAGE_N_SAMPLES
;
99 dma_init_struct
.peripheral_inc_enable
= FALSE
;
100 dma_init_struct
.memory_inc_enable
= ((adc
->usedChannelCount
> 1) || (ADC_AVERAGE_N_SAMPLES
> 1)) ? TRUE
: FALSE
;
101 dma_init_struct
.loop_mode_enable
= TRUE
;
102 dma_init_struct
.direction
= DMA_DIR_PERIPHERAL_TO_MEMORY
;
103 dma_init_struct
.memory_base_addr
= (uint32_t)adcValues
[adcDevice
];
104 dma_init_struct
.memory_data_width
= DMA_MEMORY_DATA_WIDTH_HALFWORD
;
105 dma_init_struct
.peripheral_data_width
= DMA_PERIPHERAL_DATA_WIDTH_HALFWORD
;
106 dma_init_struct
.priority
= DMA_PRIORITY_MEDIUM
;
107 dma_init(dmadac
->ref
, &dma_init_struct
);
108 //enable dma transfer and dma interrupt
109 dma_interrupt_enable(dmadac
->ref
, DMA_FDT_INT
, TRUE
);
111 dmaMuxEnable(dmadac
, adc
->dmaMuxid
);
112 dma_channel_enable(dmadac
->ref
,TRUE
);
115 adc_common_config_type adc_common_struct
;
116 adc_common_default_para_init(&adc_common_struct
);
117 adc_common_struct
.combine_mode
= ADC_INDEPENDENT_MODE
;
118 adc_common_struct
.div
= ADC_HCLK_DIV_4
;
119 adc_common_struct
.common_dma_mode
= ADC_COMMON_DMAMODE_DISABLE
;
120 adc_common_struct
.sampling_interval
= ADC_SAMPLING_INTERVAL_5CYCLES
;
121 adc_common_struct
.tempervintrv_state
= FALSE
;
122 adc_common_struct
.common_dma_request_repeat_state
= FALSE
;
123 adc_common_struct
.vbat_state
= FALSE
;
124 adc_common_config(&adc_common_struct
);
125 //enable adc RCC Clock
126 RCC_ClockCmd(adc
->rccADC
, ENABLE
);
128 adc_base_config_type adc_base_struct
;
129 adc_base_default_para_init(&adc_base_struct
);
130 adc_base_struct
.sequence_mode
= TRUE
;
131 adc_base_struct
.repeat_mode
= TRUE
;
132 adc_base_struct
.data_align
= ADC_RIGHT_ALIGNMENT
;
133 adc_base_struct
.ordinary_channel_length
= adc
->usedChannelCount
; //based on used channel count
134 adc_base_config(adc
->ADCx
, &adc_base_struct
);
135 adc_resolution_set(adc
->ADCx
, ADC_RESOLUTION_12B
);
138 for (int i
= ADC_CHN_1
; i
< ADC_CHN_COUNT
; i
++) {
139 if (!adcConfig
[i
].enabled
|| adcConfig
[i
].adcDevice
!= adcDevice
) {
142 adc_ordinary_channel_set(adc
->ADCx
, adcConfig
[i
].adcChannel
, rank
++, adcConfig
[i
].sampleTime
);
146 adc_dma_request_repeat_enable(adc
->ADCx
, TRUE
);
147 adc_dma_mode_enable(adc
->ADCx
, TRUE
);
149 //enable over flow interupt
150 adc_interrupt_enable(adc
->ADCx
, ADC_OCCO_INT
, TRUE
);
152 adc_enable(adc
->ADCx
,TRUE
);
154 // wait ready to start adc calibration
155 while(adc_flag_get(adc
->ADCx
, ADC_RDY_FLAG
) == RESET
);
157 adc_calibration_init(adc
->ADCx
);
158 while(adc_calibration_init_status_get(adc
->ADCx
));
159 adc_calibration_start(adc
->ADCx
);
160 while(adc_calibration_status_get(adc
->ADCx
));
162 adc_enable(adc
->ADCx
, TRUE
);
163 adc_ordinary_software_trigger_enable(adc
->ADCx
, TRUE
);
167 * ADC Hardware init ,config the GPIO Port and count the used ADC channel
170 void adcHardwareInit(drv_adc_config_t
*init
)
173 int configuredAdcChannels
= 0;
175 for (int i
= ADC_CHN_1
; i
< ADC_CHN_COUNT
; i
++) {
176 if (!adcConfig
[i
].tag
)
178 // only use adc1 for now
179 adcDevice_t
* adc
= &adcHardware
[adcConfig
[i
].adcDevice
];
180 // init adc gpio port
181 IOInit(IOGetByTag(adcConfig
[i
].tag
), OWNER_ADC
, RESOURCE_ADC_CH1
+ (i
- ADC_CHN_1
), 0);
182 IOConfigGPIO(IOGetByTag(adcConfig
[i
].tag
), IO_CONFIG(GPIO_MODE_ANALOG
, 0, 0, 0));
184 adcConfig
[i
].adcChannel
= adcChannelByTag(adcConfig
[i
].tag
);
185 adcConfig
[i
].dmaIndex
= adc
->usedChannelCount
++;
186 adcConfig
[i
].sampleTime
= ADC_SAMPLETIME_640_5
;
187 adcConfig
[i
].enabled
= true;
190 configuredAdcChannels
++;
193 if (configuredAdcChannels
== 0)
195 // config adc instance
196 for (int i
= 0; i
< ADCDEV_COUNT
; i
++) {
197 if (adcHardware
[i
].enabled
) {