48 #if defined(PIOS_INCLUDE_ADC)
53 enum pios_adc_dev_magic {
54 PIOS_INTERNAL_ADC_DEV_MAGIC = 0x58375124,
57 struct pios_internal_adc_dev {
58 enum pios_adc_dev_magic
magic;
62 static struct pios_internal_adc_dev * pios_adc_dev;
66 static bool PIOS_INTERNAL_ADC_validate(
struct pios_internal_adc_dev *);
68 #if defined(PIOS_INCLUDE_ADC)
69 static void init_pins(
void);
70 static void init_dma(
void);
71 static void init_adc(
void);
73 static int32_t PIOS_INTERNAL_ADC_PinGet(uintptr_t internal_adc_id, uint32_t pin);
74 static uint8_t PIOS_INTERNAL_ADC_Number_of_Channels(uintptr_t internal_adc_id);
75 static float PIOS_INTERNAL_ADC_LSB_Voltage(uintptr_t internal_adc_id);
78 .
get_pin = PIOS_INTERNAL_ADC_PinGet,
79 .number_of_channels = PIOS_INTERNAL_ADC_Number_of_Channels,
80 .lsb_voltage = PIOS_INTERNAL_ADC_LSB_Voltage,
83 struct adc_accumulator {
84 volatile uint32_t accumulator,
count;
88 static struct adc_accumulator * accumulator;
89 static uint16_t * adc_raw_buffer_0;
90 static uint16_t * adc_raw_buffer_1;
93 static void init_pins(
void)
95 if (!PIOS_INTERNAL_ADC_validate(pios_adc_dev)) {
100 GPIO_InitTypeDef GPIO_InitStructure;
101 GPIO_StructInit(&GPIO_InitStructure);
102 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
103 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
105 for (int32_t
i = 0;
i < pios_adc_dev->cfg->adc_pin_count;
i++) {
106 if (pios_adc_dev->cfg->adc_pins[
i].port == NULL)
108 GPIO_InitStructure.GPIO_Pin = pios_adc_dev->cfg->adc_pins[
i].pin;
109 GPIO_Init(pios_adc_dev->cfg->adc_pins[
i].port, &GPIO_InitStructure);
113 static void init_dma(
void)
115 if (!PIOS_INTERNAL_ADC_validate(pios_adc_dev)) {
120 DMA_ITConfig(pios_adc_dev->cfg->dma.rx.channel, pios_adc_dev->cfg->dma.irq.flags, DISABLE);
123 DMA_DeInit(pios_adc_dev->cfg->dma.rx.channel);
124 DMA_InitTypeDef DMAInit = pios_adc_dev->cfg->dma.rx.init;
125 DMAInit.DMA_Memory0BaseAddr = (uint32_t)&adc_raw_buffer_0[0];
127 DMAInit.DMA_DIR = DMA_DIR_PeripheralToMemory;
128 DMAInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
129 DMAInit.DMA_MemoryInc = DMA_MemoryInc_Enable;
130 DMAInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
131 DMAInit.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
132 DMAInit.DMA_Mode = DMA_Mode_Circular;
133 DMAInit.DMA_Priority = DMA_Priority_Low;
134 DMAInit.DMA_FIFOMode = DMA_FIFOMode_Disable;
135 DMAInit.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
136 DMAInit.DMA_MemoryBurst = DMA_MemoryBurst_Single;
137 DMAInit.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
139 DMA_Init(pios_adc_dev->cfg->dma.rx.channel, &DMAInit);
142 DMA_DoubleBufferModeConfig(pios_adc_dev->cfg->dma.rx.channel, (uint32_t)&adc_raw_buffer_1[0], DMA_Memory_0);
143 DMA_DoubleBufferModeCmd(pios_adc_dev->cfg->dma.rx.channel, ENABLE);
144 DMA_ITConfig(pios_adc_dev->cfg->dma.rx.channel, DMA_IT_TC, ENABLE);
147 DMA_Cmd(pios_adc_dev->cfg->dma.rx.channel, ENABLE);
150 NVIC_InitTypeDef NVICInit = pios_adc_dev->cfg->dma.irq.init;
151 NVIC_Init(&NVICInit);
154 static void init_adc(
void)
156 if (!PIOS_INTERNAL_ADC_validate(pios_adc_dev)) {
160 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
165 ADC_TempSensorVrefintCmd(ENABLE);
168 ADC_CommonInitTypeDef ADC_CommonInitStructure;
169 ADC_CommonStructInit(&ADC_CommonInitStructure);
170 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
171 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
172 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
173 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
174 ADC_CommonInit(&ADC_CommonInitStructure);
176 ADC_InitTypeDef ADC_InitStructure;
177 ADC_StructInit(&ADC_InitStructure);
178 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
179 ADC_InitStructure.ADC_ScanConvMode = ENABLE;
180 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
181 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
182 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;
183 ADC_InitStructure.ADC_NbrOfConversion = pios_adc_dev->cfg->adc_pin_count;
184 ADC_Init(pios_adc_dev->cfg->adc_dev_master, &ADC_InitStructure);
187 ADC_DMACmd(pios_adc_dev->cfg->adc_dev_master, ENABLE);
190 for (int32_t
i = 0;
i < pios_adc_dev->cfg->adc_pin_count;
i++) {
191 ADC_RegularChannelConfig(pios_adc_dev->cfg->adc_dev_master,
192 pios_adc_dev->cfg->adc_pins[
i].adc_channel,
194 ADC_SampleTime_480Cycles);
198 ADC_DMARequestAfterLastTransferCmd(pios_adc_dev->cfg->adc_dev_master, ENABLE);
201 ADC_Cmd(pios_adc_dev->cfg->adc_dev_master, ENABLE);
202 ADC_ContinuousModeCmd(pios_adc_dev->cfg->adc_dev_master, ENABLE);
203 ADC_SoftwareStartConv(pios_adc_dev->cfg->adc_dev_master);
206 static bool PIOS_INTERNAL_ADC_validate(
struct pios_internal_adc_dev * dev)
211 return (dev->magic == PIOS_INTERNAL_ADC_DEV_MAGIC);
216 struct pios_internal_adc_dev * adc_dev;
230 if (!adc_raw_buffer_0) {
237 if (!adc_raw_buffer_1) {
244 adc_dev->magic = PIOS_INTERNAL_ADC_DEV_MAGIC;
253 pios_adc_dev = PIOS_INTERNAL_ADC_Allocate(cfg);
254 if (pios_adc_dev == NULL)
257 pios_adc_dev->cfg =
cfg;
259 #if defined(PIOS_INCLUDE_ADC)
264 *internal_adc_id = (uintptr_t)pios_adc_dev;
277 static int32_t PIOS_INTERNAL_ADC_PinGet(uintptr_t internal_adc_id, uint32_t pin)
279 #if defined(PIOS_INCLUDE_ADC)
282 if (!PIOS_INTERNAL_ADC_validate(pios_adc_dev)) {
287 if (pin >= pios_adc_dev->cfg->adc_pin_count) {
291 if (accumulator[pin].accumulator <= 0) {
296 result = accumulator[pin].accumulator /
297 (accumulator[pin].count ? accumulator[pin].count : 1);
298 accumulator[pin].accumulator = result;
299 accumulator[pin].count = 1;
309 static inline void accumulate(uint16_t *buffer, uint32_t
count)
311 #if defined(PIOS_INCLUDE_ADC)
312 uint16_t *sp = buffer;
313 if (!PIOS_INTERNAL_ADC_validate(pios_adc_dev)) {
321 for (
int i = 0;
i < pios_adc_dev->cfg->adc_pin_count;
i++) {
322 accumulator[
i].accumulator += *(sp++);
323 accumulator[
i].count++;
328 if (accumulator[
i].accumulator >= (1 << 31)) {
329 accumulator[
i].accumulator /= 2;
330 accumulator[
i].count /= 2;
347 if (!PIOS_INTERNAL_ADC_validate(pios_adc_dev))
350 #if defined(PIOS_INCLUDE_ADC)
352 if (DMA_GetITStatus(pios_adc_dev->cfg->dma.rx.channel, pios_adc_dev->cfg->full_flag)) {
353 DMA_ClearITPendingBit(pios_adc_dev->cfg->dma.rx.channel, pios_adc_dev->cfg->full_flag);
356 if (DMA_GetCurrentMemoryTarget(pios_adc_dev->cfg->dma.rx.channel) == 0) {
374 static uint8_t PIOS_INTERNAL_ADC_Number_of_Channels(uintptr_t internal_adc_id)
376 struct pios_internal_adc_dev * adc_dev = (
struct pios_internal_adc_dev *)internal_adc_id;
377 if(!PIOS_INTERNAL_ADC_validate(adc_dev))
379 return adc_dev->cfg->adc_pin_count;
385 static float PIOS_INTERNAL_ADC_LSB_Voltage(uintptr_t internal_adc_id)
387 struct pios_internal_adc_dev * adc_dev = (
struct pios_internal_adc_dev *) internal_adc_id;
388 if (!PIOS_INTERNAL_ADC_validate(adc_dev)) {
391 return VREF_PLUS / (((uint32_t)1 << 16) - 16);
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_INTERNAL_ADC_Init(uintptr_t *internal_adc_id, const struct pios_internal_adc_cfg *cfg)
#define PIOS_IRQ_Epilogue()
void * PIOS_malloc(size_t size)
void * PIOS_malloc_no_dma(size_t size)
void PIOS_INTERNAL_ADC_DMA_Handler()
static struct flyingpicmd_cfg_fa cfg
const struct pios_adc_driver pios_internal_adc_driver
void PIOS_free(void *buf)
#define PIOS_ADC_MAX_OVERSAMPLING
#define PIOS_IRQ_Prologue()
int32_t(* get_pin)(uintptr_t id, uint32_t pin)