Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
adc_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010-2013 The Paparazzi Team
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
41 /*
42  For better understanding of timer and GPIO settings:
43 
44  Table of GPIO pins available per ADC:
45 
46  ADC1/2: ADC3:
47  C0 -> PA0 C0 -> PA0
48  C1 -> PA1 C1 -> PA1
49  C2 -> PA2 C2 -> PA2
50  C3 -> PA3 C3 -> PA3
51  C4 -> PA4 C4 -> PF6
52  C5 -> PA5 C5 -> PF7
53  C6 -> PA6 C6 -> PF8
54  C7 -> PA7 C7 -> PF9
55  C8 -> PB0 C8 -> PF10
56  C9 -> PB1
57  C10 -> PC0 C10 -> PC0
58  C11 -> PC1 C11 -> PC1
59  C12 -> PC2 C12 -> PC2
60  C13 -> PC3 C13 -> PC3
61  C14 -> PC4
62  C15 -> PC5
63 
64  Table of timers available per ADC (from libstm/src/stm32_adc.c):
65 
66  T1_TRGO: Timer1 TRGO event (ADC1, ADC2 and ADC3)
67  T1_CC4: Timer1 capture compare4 (ADC1, ADC2 and ADC3)
68  T2_TRGO: Timer2 TRGO event (ADC1 and ADC2)
69  T2_CC1: Timer2 capture compare1 (ADC1 and ADC2)
70  T3_CC4: Timer3 capture compare4 (ADC1 and ADC2)
71  T4_TRGO: Timer4 TRGO event (ADC1 and ADC2)
72  TIM8_CC4: External interrupt line 15 or Timer8 capture compare4 event (ADC1 and ADC2)
73  T4_CC3: Timer4 capture compare3 (ADC3 only)
74  T8_CC2: Timer8 capture compare2 (ADC3 only)
75  T8_CC4: Timer8 capture compare4 (ADC3 only)
76  T5_TRGO: Timer5 TRGO event (ADC3 only)
77  T5_CC4: Timer5 capture compare4 (ADC3 only)
78 
79  By setting ADC_ExternalTrigInjecConv_None, injected conversion
80  is started by software instead of external trigger for any ADC.
81 
82  Table of APB per Timer (from libstm/src/stm32_tim.c):
83 
84  RCC_APB1: TIM2, TIM3, TIM4, TIM5, TIM7 (non-advanced timers)
85  RCC_APB2: TIM1, TIM8 (advanced timers)
86 
87 */
88 
89 #include "mcu_periph/adc.h"
90 
91 #include <libopencm3/stm32/rcc.h>
92 #include <libopencm3/stm32/gpio.h>
93 #include <libopencm3/stm32/adc.h>
94 #include <libopencm3/cm3/nvic.h>
95 #include <libopencm3/stm32/timer.h>
96 #include <string.h>
97 #include "mcu_periph/gpio.h"
98 #include "mcu_arch.h"
99 #include "std.h"
100 #include BOARD_CONFIG
101 
102 
103 #ifndef NVIC_ADC_IRQ_PRIO
104 #define NVIC_ADC_IRQ_PRIO 0
105 #endif
106 
107 #if defined(STM32F1)
108 #define ADC_SAMPLE_TIME ADC_SMPR_SMP_41DOT5CYC
109 #elif defined(STM32F4)
110 #define ADC_SAMPLE_TIME ADC_SMPR_SMP_56CYC
111 #endif
112 
113 // Macros to automatically enable the correct ADC
114 
115 #if defined(AD1_1_CHANNEL) || defined(AD1_2_CHANNEL) || defined(AD1_3_CHANNEL) || defined(AD1_4_CHANNEL)
116 #ifndef USE_AD1
117 #define USE_AD1 1
118 #endif
119 #endif
120 
121 #if defined(AD2_1_CHANNEL) || defined(AD2_2_CHANNEL) || defined(AD2_3_CHANNEL) || defined(AD2_4_CHANNEL)
122 #ifndef USE_AD2
123 #define USE_AD2 1
124 #endif
125 #endif
126 
127 #if defined(STM32F4)
128 
129 #if defined(AD3_1_CHANNEL) || defined(AD3_2_CHANNEL) || defined(AD3_3_CHANNEL) || defined(AD3_4_CHANNEL)
130 #ifndef USE_AD3
131 #define USE_AD3 1
132 #endif
133 #endif
134 
135 #define RST_ADC1 RST_ADC
136 #define RST_ADC2 RST_ADC
137 #define RST_ADC3 RST_ADC
138 
139 #else // !STM32F4
140 // ADC 3 not supported on STM32F1
141 #undef USE_AD3
142 #define USE_AD3 0
143 #endif
144 
145 #if USE_AD1
146 PRINT_CONFIG_MSG("Analog to Digital Coverter 1 active")
147 #endif
148 #if USE_AD2
149 PRINT_CONFIG_MSG("Analog to Digital Coverter 2 active")
150 #endif
151 #if USE_AD3
152 PRINT_CONFIG_MSG("Analog to Digital Coverter 3 active")
153 #endif
154 #if !USE_AD1 && !USE_AD2 && !USE_AD3 && !defined FBW
155 #warning ALL ADC CONVERTERS INACTIVE
156 #endif
157 
158 #ifndef ADC_TIMER_PERIOD
159 #define ADC_TIMER_PERIOD 10000
160 #endif
161 
167 #ifndef ADC_TIMER_FREQUENCY
168 #define ADC_TIMER_FREQUENCY 2000000
169 #endif
170 
171 /***************************************/
172 /*** STATIC FUNCTION PROTOTYPES ***/
173 /***************************************/
174 
175 static inline void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map);
176 
177 static inline void adc_push_sample(struct adc_buf *buf,
178  uint16_t sample);
179 
180 static inline void adc_init_rcc(void);
181 static inline void adc_init_irq(void);
182 
183 
184 /********************************/
185 /*** GLOBAL VARIABLES ***/
186 /********************************/
187 
188 /* Only 4 ADC channels may be enabled at the same time
189  * on each ADC, as there are only 4 injection registers.
190  * Currently, the enums adc1_channels and adc2_channels only
191  * serve to resolve the number of channels on each ADC.
192  * There are 3 separate buffer lists, each holds the addresses of the actual adc buffers
193  * for the particular adc converter.
194  */
195 
199 
200 #if USE_AD1 || USE_AD2 || USE_AD3
201 #define ADC_NUM_CHANNELS 4
202 #endif
203 
204 #if USE_AD1
206 static struct adc_buf *adc1_buffers[ADC_NUM_CHANNELS];
207 #endif
208 #if USE_AD2
210 static struct adc_buf *adc2_buffers[ADC_NUM_CHANNELS];
211 #endif
212 #if USE_AD3
214 static struct adc_buf *adc3_buffers[ADC_NUM_CHANNELS];
215 #endif
216 
217 #if USE_ADC_WATCHDOG
218 #include "mcu_periph/sys_time.h"
219 // watchdog structure with adc bank and callback
220 static struct {
221  uint32_t timeStamp;
222  uint32_t adc;
223  adc_watchdog_callback cb;
224 } adc_watchdog;
225 #endif
226 
227 /***************************************/
228 /*** PUBLIC FUNCTION DEFINITIONS ***/
229 /***************************************/
230 
231 void adc_init(void)
232 {
233 #if USE_AD1 || USE_AD2 || USE_AD3
234  uint8_t x = 0;
235 
236  // ADC channel mapping
238 #endif
239 
240  /* Init GPIO ports for ADC operation
241  */
242 #if USE_ADC_1
243  PRINT_CONFIG_MSG("Info: Using ADC_1")
245 #endif
246 #if USE_ADC_2
247  PRINT_CONFIG_MSG("Info: Using ADC_2")
249 #endif
250 #if USE_ADC_3
251  PRINT_CONFIG_MSG("Info: Using ADC_3")
253 #endif
254 #if USE_ADC_4
255  PRINT_CONFIG_MSG("Info: Using ADC_4")
257 #endif
258 #if USE_ADC_5
259  PRINT_CONFIG_MSG("Info: Using ADC_5")
261 #endif
262 #if USE_ADC_6
263  PRINT_CONFIG_MSG("Info: Using ADC_6")
264  gpio_setup_pin_analog(ADC_6_GPIO_PORT, ADC_6_GPIO_PIN);
265 #endif
266 #if USE_ADC_7
267  PRINT_CONFIG_MSG("Info: Using ADC_7")
269 #endif
270 #if USE_ADC_8
271  PRINT_CONFIG_MSG("Info: Using ADC_8")
272  gpio_setup_pin_analog(ADC_8_GPIO_PORT, ADC_8_GPIO_PIN);
273 #endif
274 #if USE_ADC_9
275  PRINT_CONFIG_MSG("Info: Using ADC_9")
277 #endif
278 
279  // Init clock and irq
280  adc_init_rcc();
281  adc_init_irq();
282 
283  /* If fewer than 4 channels are active, say 3, then they are placed in to
284  * injection slots 2,3 and 4 because the stm32 architecture converts injected
285  * slots 2,3 and 4 and skips slot 1 instead of logicaly converting slots 1,2
286  * and 3 and leave slot 4.
287  * EXAMPLE OF ADC EXECUTION ORDER WHEN WE HAVE SAY 2 ADC INPUTS USED on ADC1
288  * The first board adc channel ADC1_1 is mapped to injected channel 3 and ADC1_2
289  * to injected channel 4 and because the conversions start from the lowest
290  * injection channel used, 3 in our case, injected channel 3 data will be
291  * located at JDR1 and 4 to JDR2 so JDR1 = ADC1_1 and JDR2 = ADC1_2.
292  * That's why "adc_channel_map" has this descending order.
293  */
294 
295  nb_adc1_channels = 0;
296 #if USE_AD1
297 #ifdef AD1_1_CHANNEL
300 #endif
301 #ifdef AD1_2_CHANNEL
304 #endif
305 #ifdef AD1_3_CHANNEL
308 #endif
309 #ifdef AD1_4_CHANNEL
312 #endif
313  // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt
314  // handler, which is important as there are no buffers registered at the time the ADC trigger
315  // interrupt is enabled.
316  for (x = 0; x < 4; x++) { adc1_buffers[x] = NULL; }
318 #endif // USE_AD1
319 
320 
321  nb_adc2_channels = 0;
322 #if USE_AD2
323 #ifdef AD2_1_CHANNEL
324  adc_channel_map[AD2_1 - nb_adc1_channels] = AD2_1_CHANNEL;
326 #endif
327 #ifdef AD2_2_CHANNEL
328  adc_channel_map[AD2_2 - nb_adc1_channels] = AD2_2_CHANNEL;
330 #endif
331 #ifdef AD2_3_CHANNEL
332  adc_channel_map[AD2_3 - nb_adc1_channels] = AD2_3_CHANNEL;
334 #endif
335 #ifdef AD2_4_CHANNEL
336  adc_channel_map[AD2_4 - nb_adc1_channels] = AD2_4_CHANNEL;
338 #endif
339  // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt
340  // handler, which is important as there are no buffers registered at the time the ADC trigger
341  // interrupt is enabled.
342  for (x = 0; x < 4; x++) { adc2_buffers[x] = NULL; }
344 #endif // USE_AD2
345 
346 
347  nb_adc3_channels = 0;
348 #if USE_AD3
349 #ifdef AD3_1_CHANNEL
350  adc_channel_map[AD3_1 - nb_adc1_channels - nb_adc2_channels] = AD3_1_CHANNEL;
352 #endif
353 #ifdef AD3_2_CHANNEL
354  adc_channel_map[AD3_2 - nb_adc1_channels - nb_adc2_channels] = AD3_2_CHANNEL;
356 #endif
357 #ifdef AD3_3_CHANNEL
358  adc_channel_map[AD3_3 - nb_adc1_channels - nb_adc2_channels] = AD3_3_CHANNEL;
360 #endif
361 #ifdef AD3_4_CHANNEL
362  adc_channel_map[AD3_4 - nb_adc1_channels - nb_adc2_channels] = AD3_4_CHANNEL;
364 #endif
365  // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt
366  // handler, which is important as there are no buffers registered at the time the ADC trigger
367  // interrupt is enabled.
368  for (x = 0; x < 4; x++) { adc3_buffers[x] = NULL; }
370 #endif // USE_AD3
371 
372 #if USE_ADC_WATCHDOG
373  adc_watchdog.cb = NULL;
374  adc_watchdog.timeStamp = 0;
375 #endif
376 
377 }
378 
379 void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
380 {
381  if (adc_channel < nb_adc1_channels) {
382 #if USE_AD1
383  adc1_buffers[adc_channel] = s;
384 #endif
385  } else if (adc_channel < (nb_adc1_channels + nb_adc2_channels)) {
386 #if USE_AD2
387  adc2_buffers[adc_channel - nb_adc1_channels] = s;
388 #endif
389  } else if (adc_channel < (nb_adc1_channels + nb_adc2_channels + nb_adc3_channels)) {
390 #if USE_AD3
391  adc3_buffers[adc_channel - (nb_adc1_channels + nb_adc2_channels)] = s;
392 #endif
393  }
394 
395  s->av_nb_sample = av_nb_sample;
396 
397 }
398 
399 #if USE_ADC_WATCHDOG
400 void register_adc_watchdog(uint32_t adc, uint8_t chan, uint16_t low, uint16_t high, adc_watchdog_callback cb)
401 {
402  adc_watchdog.adc = adc;
403  adc_watchdog.cb = cb;
404 
405  // activated adc watchdog of a single injected channel with interrupt
406  adc_set_watchdog_low_threshold(adc, low);
407  adc_set_watchdog_high_threshold(adc, high);
408  adc_enable_analog_watchdog_injected(adc);
409  adc_enable_analog_watchdog_on_selected_channel(adc, chan);
410  adc_enable_awd_interrupt(adc);
411 }
412 #endif
413 
414 /**************************************/
415 /*** PRIVATE FUNCTION DEFINITIONS ***/
416 /**************************************/
417 
418 #if defined(USE_AD_TIM4)
419 #define TIM_ADC TIM4
420 #define RCC_TIM_ADC RCC_TIM4
421 #elif defined(USE_AD_TIM1)
422 #define TIM_ADC TIM1
423 #define RCC_TIM_ADC RCC_TIM1
424 #else
425 #define TIM_ADC TIM2
426 #define RCC_TIM_ADC RCC_TIM2
427 #endif
428 
430 static inline void adc_init_rcc(void)
431 {
432 #if USE_AD1 || USE_AD2 || USE_AD3
433  /* Timer peripheral clock enable. */
434  rcc_periph_clock_enable(RCC_TIM_ADC);
435 #if defined(STM32F4)
436  adc_set_clk_prescale(ADC_CCR_ADCPRE_BY2);
437 #endif
438 
439  /* Enable ADC peripheral clocks. */
440 #if USE_AD1
441  rcc_periph_clock_enable(RCC_ADC1);
442  rcc_periph_reset_pulse(RST_ADC1);
443 #endif
444 #if USE_AD2
445  rcc_periph_clock_enable(RCC_ADC2);
446  rcc_periph_reset_pulse(RST_ADC2);
447 #endif
448 #if USE_AD3
449  rcc_periph_clock_enable(RCC_ADC3);
450  rcc_periph_reset_pulse(RST_ADC3);
451 #endif
452 
453  /* Time Base configuration */
454  timer_set_mode(TIM_ADC, TIM_CR1_CKD_CK_INT,
455  TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
456  /* timer counts with ADC_TIMER_FREQUENCY */
457  uint32_t timer_clk = timer_get_frequency(TIM_ADC);
458  timer_set_prescaler(TIM_ADC, (timer_clk / ADC_TIMER_FREQUENCY) - 1);
459 
460  timer_set_period(TIM_ADC, ADC_TIMER_PERIOD);
461  /* Generate TRGO on every update (when counter reaches period reload value) */
462  timer_set_master_mode(TIM_ADC, TIM_CR2_MMS_UPDATE);
463  timer_enable_counter(TIM_ADC);
464 
465 #endif // USE_AD1 || USE_AD2 || USE_AD3
466 }
467 
469 static inline void adc_init_irq(void)
470 {
471 #if defined(STM32F1)
472  nvic_set_priority(NVIC_ADC1_2_IRQ, NVIC_ADC_IRQ_PRIO);
473  nvic_enable_irq(NVIC_ADC1_2_IRQ);
474 #elif defined(STM32F4)
475  nvic_set_priority(NVIC_ADC_IRQ, NVIC_ADC_IRQ_PRIO);
476  nvic_enable_irq(NVIC_ADC_IRQ);
477 #endif
478 }
479 
480 
481 static inline void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map)
482 {
483  // Paranoia, must be down for 2+ ADC clock cycles before calibration
484  adc_power_off(adc);
485 
486  /* Configure ADC */
487  /* Explicitly setting most registers, reset/default values are correct for most */
488  /* Set CR1 register. */
489  /* Clear AWDEN */
490  adc_disable_analog_watchdog_regular(adc);
491  /* Clear JAWDEN */
492  adc_disable_analog_watchdog_injected(adc);
493  /* Clear DISCEN */
494  adc_disable_discontinuous_mode_regular(adc);
495  /* Clear JDISCEN */
496  adc_disable_discontinuous_mode_injected(adc);
497  /* Clear JAUTO */
498  adc_disable_automatic_injected_group_conversion(adc);
499  /* Set SCAN */
500  adc_enable_scan_mode(adc);
501  /* Enable ADC<X> JEOC interrupt (Set JEOCIE) */
502  adc_enable_eoc_interrupt_injected(adc);
503  /* Clear AWDIE */
504  adc_disable_awd_interrupt(adc);
505  /* Clear EOCIE */
506  adc_disable_eoc_interrupt(adc);
507 
508  /* Set CR2 register. */
509  /* Clear TSVREFE */
510  adc_disable_temperature_sensor();
511  /* Clear EXTTRIG */
512  adc_disable_external_trigger_regular(adc);
513  /* Clear ALIGN */
514  adc_set_right_aligned(adc);
515  /* Clear DMA */
516  adc_disable_dma(adc);
517  /* Clear CONT */
518  adc_set_single_conversion_mode(adc);
519 
520  //uint8_t x = 0;
521  //for (x = 0; x < nb_channels; x++) {
522  // adc_set_sample_time(adc, channel_map[x], ADC_SAMPLE_TIME);
523  //}
524  adc_set_sample_time_on_all_channels(adc, ADC_SAMPLE_TIME);
525 
526  adc_set_injected_sequence(adc, nb_channels, channel_map);
527 
528 #if USE_AD_TIM4
529  PRINT_CONFIG_MSG("Info: Using TIM4 for ADC")
530 #if defined(STM32F1)
531  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO);
532 #elif defined(STM32F4)
533  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
534 #endif
535 #elif USE_AD_TIM1
536  PRINT_CONFIG_MSG("Info: Using TIM1 for ADC")
537 #if defined(STM32F1)
538  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO);
539 #elif defined(STM32F4)
540  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
541 #endif
542 #else
543  PRINT_CONFIG_MSG("Info: Using default TIM2 for ADC")
544 #if defined(STM32F1)
545  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO);
546 #elif defined(STM32F4)
547  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
548 #endif
549 #endif
550 
551  /* Enable ADC<X> */
552  adc_power_on(adc);
553 #if defined(STM32F1)
554  /* Rest ADC<X> calibaration register and wait until done */
555  adc_reset_calibration(adc);
556  /* Start ADC<X> calibaration and wait until done */
557  adc_calibrate(adc);
558 #endif
559 
560  return;
561 } // adc_init_single
562 
563 
564 static inline void adc_push_sample(struct adc_buf *buf, uint16_t value)
565 {
566  uint8_t new_head = buf->head + 1;
567 
568  if (new_head >= buf->av_nb_sample) {
569  new_head = 0;
570  }
571  buf->sum -= buf->values[new_head];
572  buf->values[new_head] = value;
573  buf->sum += value;
574  buf->head = new_head;
575 }
576 
577 /*********************************/
578 /*** ADC INTERRUPT HANDLER ***/
579 /*********************************/
580 
581 #if defined(STM32F1)
582 void adc1_2_isr(void)
583 #elif defined(STM32F4)
584 void adc_isr(void)
585 #endif
586 {
587 #if USE_AD1 || USE_AD2 || USE_AD3
588  uint8_t channel = 0;
589  uint16_t value = 0;
590  struct adc_buf *buf;
591 #endif
592 
593 #if USE_ADC_WATCHDOG
594  /*
595  We need adc sampling fast enough to detect battery plug out, but we did not
596  need to get actual actual value so fast. So timer fire adc conversion fast,
597  at least 500 hz, but we inject adc value in sampling buffer only at 50hz
598  */
599  const uint32_t timeStampDiff = get_sys_time_msec() - adc_watchdog.timeStamp;
600  const bool shouldAccumulateValue = timeStampDiff > 20;
601  if (shouldAccumulateValue) {
602  adc_watchdog.timeStamp = get_sys_time_msec();
603  }
604 
605  if (adc_watchdog.cb != NULL) {
606  if (adc_awd(adc_watchdog.adc)) {
607  ADC_SR(adc_watchdog.adc) &= ~ADC_SR_AWD; // clear int flag
608  adc_watchdog.cb();
609  }
610  }
611 #endif
612 
613 #if USE_AD1
614  // Clear Injected End Of Conversion
615  if (adc_eoc_injected(ADC1)) {
616  ADC_SR(ADC1) &= ~ADC_SR_JEOC;
617 #if USE_ADC_WATCHDOG
618  if (shouldAccumulateValue) {
619 #endif
620  for (channel = 0; channel < nb_adc1_channels; channel++) {
621  buf = adc1_buffers[channel];
622  if (buf) {
623  value = adc_read_injected(ADC1, channel + 1);
624  adc_push_sample(buf, value);
625  }
626  }
627 #if USE_ADC_WATCHDOG
628  }
629 #endif
630  }
631 #endif // USE_AD1
632 
633 #if USE_AD2
634  if (adc_eoc_injected(ADC2)) {
635  ADC_SR(ADC2) &= ~ADC_SR_JEOC;
636 #if USE_ADC_WATCHDOG
637  if (shouldAccumulateValue) {
638 #endif
639  for (channel = 0; channel < nb_adc2_channels; channel++) {
640  buf = adc2_buffers[channel];
641  if (buf) {
642  value = adc_read_injected(ADC2, channel + 1);
643  adc_push_sample(buf, value);
644  }
645  }
646 #if USE_ADC_WATCHDOG
647  }
648 #endif
649  }
650 #endif // USE_AD2
651 
652 #if USE_AD3
653  if (adc_eoc_injected(ADC3)) {
654  ADC_SR(ADC3) &= ~ADC_SR_JEOC;
655 #if USE_ADC_WATCHDOG
656  if (shouldAccumulateValue) {
657 #endif
658  for (channel = 0; channel < nb_adc3_channels; channel++) {
659  buf = adc3_buffers[channel];
660  if (buf) {
661  value = adc_read_injected(ADC3, channel + 1);
662  adc_push_sample(buf, value);
663  }
664  }
665 #if USE_ADC_WATCHDOG
666  }
667 #endif
668  }
669 #endif // USE_AD3
670 
671  return;
672 }
arch independent ADC (Analog to Digital Converter) API
uint32_t sum
Definition: adc.h:54
uint8_t head
Definition: adc.h:56
uint16_t values[MAX_AV_NB_SAMPLE]
Definition: adc.h:55
uint8_t av_nb_sample
Definition: adc.h:57
Generic interface for all ADC hardware drivers, independent from microcontroller architecture.
Definition: adc.h:53
#define ADC_4_GPIO_PORT
Definition: board.h:191
#define ADC_4_GPIO_PIN
Definition: board.h:192
#define AD1_4_CHANNEL
Definition: board.h:189
static struct adc_buf * adc1_buffers[ADC_NUM_CHANNELS]
Definition: adc_arch.c:144
void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
Link between ChibiOS ADC drivers and Paparazzi adc_buffers.
Definition: adc_arch.c:312
void adc_init(void)
Adc init.
Definition: adc_arch.c:332
static const uint8_t adc_channel_map[ADC_NUM_CHANNELS]
Definition: adc_arch.c:81
#define ADC_NUM_CHANNELS
Definition: adc_arch.h:93
void gpio_setup_pin_analog(ioportid_t port, uint16_t pin)
Setup a gpio for analog use.
Definition: gpio_arch.c:90
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
Definition: sys_time_arch.c:98
#define ADC_7_GPIO_PORT
Definition: chimera.h:190
#define ADC_7_GPIO_PIN
Definition: chimera.h:191
#define AD1_1_CHANNEL
Definition: cjmcu.h:62
#define ADC_1_GPIO_PORT
Definition: cjmcu.h:64
#define ADC_1_GPIO_PIN
Definition: cjmcu.h:65
#define AD1_2_CHANNEL
#define ADC_2_GPIO_PIN
#define ADC_2_GPIO_PORT
Some architecture independent helper functions for GPIOs.
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
#define ADC_5_GPIO_PORT
Definition: board.h:287
#define ADC_5_GPIO_PIN
Definition: board.h:288
static uint32_t s
#define AD1_3_CHANNEL
Definition: lisa_l_1.0.h:148
#define ADC_3_GPIO_PIN
Definition: lisa_l_1.0.h:151
#define ADC_3_GPIO_PORT
Definition: lisa_l_1.0.h:150
#define ADC_9_GPIO_PORT
#define ADC_9_GPIO_PIN
uint32_t timer_get_frequency(uint32_t timer_peripheral)
Get Timer clock frequency (before prescaling) Only valid if using the internal clock for the timer.
Definition: mcu_arch.c:311
#define NVIC_ADC_IRQ_PRIO
Definition: adc_arch.c:104
static uint8_t nb_adc3_channels
Definition: adc_arch.c:198
#define ADC_TIMER_FREQUENCY
Timer frequency for ADC Timer will trigger an update event after reaching the period reload value.
Definition: adc_arch.c:168
static void adc_init_irq(void)
Configure and enable ADC interrupt.
Definition: adc_arch.c:469
#define ADC_TIMER_PERIOD
Definition: adc_arch.c:159
static void adc_init_rcc(void)
Configure and enable RCC for peripherals (ADC1, ADC2, Timer)
Definition: adc_arch.c:430
#define TIM_ADC
Definition: adc_arch.c:425
static uint8_t nb_adc1_channels
Definition: adc_arch.c:196
static void adc_push_sample(struct adc_buf *buf, uint16_t sample)
Definition: adc_arch.c:564
#define RCC_TIM_ADC
Definition: adc_arch.c:426
static uint8_t nb_adc2_channels
Definition: adc_arch.c:197
static void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map)
Definition: adc_arch.c:481
Architecture independent timing functions.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98