Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / adc_at32f43x.c
blobe2ed2f57b15a15de0ccd7dd163a4549e3114ded7
1 /*
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/>.
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <string.h>
22 #include "platform.h"
23 #include "drivers/time.h"
25 #include "drivers/io.h"
26 #include "io_impl.h"
27 #include "rcc.h"
28 #include "drivers/dma.h"
30 #include "drivers/sensor.h"
31 #include "drivers/accgyro/accgyro.h"
33 #include "adc.h"
34 #include "adc_impl.h"
36 #if !defined(ADC1_DMA_STREAM)
37 #define ADC1_DMA_STREAM DMA2_CHANNEL1
38 #endif
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)
66 if (instance == ADC1)
67 return ADCDEV_1;
69 if (instance == ADC2) // TODO add ADC2 and 3
70 return ADCDEV_2;
72 return ADCINVALID;
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);
86 if(!dmadac)
88 return;
90 // dmadac->dmaMuxref = adc->dmaMuxid;//this cause an error
91 dmaInit(dmadac, OWNER_ADC, adcDevice);
92 // dma_channel_type
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);
110 //AT32 DMA MUX
111 dmaMuxEnable(dmadac, adc->dmaMuxid);
112 dma_channel_enable(dmadac->ref,TRUE);
113 //init adc common
114 adc_reset();
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);
127 //config adc base
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);
137 uint8_t rank = 1;
138 for (int i = ADC_CHN_1; i < ADC_CHN_COUNT; i++) {
139 if (!adcConfig[i].enabled || adcConfig[i].adcDevice != adcDevice) {
140 continue;
142 adc_ordinary_channel_set(adc->ADCx, adcConfig[i].adcChannel, rank++, adcConfig[i].sampleTime);
145 // config dma repeat
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);
156 //start calibration
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));
161 //start adc
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
168 *@parm init
170 void adcHardwareInit(drv_adc_config_t *init)
172 UNUSED(init);
173 int configuredAdcChannels = 0;
175 for (int i = ADC_CHN_1; i < ADC_CHN_COUNT; i++) {
176 if (!adcConfig[i].tag)
177 continue;
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;
189 adc->enabled = true;
190 configuredAdcChannels++;
193 if (configuredAdcChannels == 0)
194 return;
195 // config adc instance
196 for (int i = 0; i < ADCDEV_COUNT; i++) {
197 if (adcHardware[i].enabled) {
198 adcInstanceInit(i);