Paparazzi UAS  v5.15_devel-230-gc96ce27
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 #else // !STM32F4
136 // ADC 3 not supported on STM32F1
137 #undef USE_AD3
138 #define USE_AD3 0
139 #endif
140 
141 #if USE_AD1
142 PRINT_CONFIG_MSG("Analog to Digital Coverter 1 active")
143 #endif
144 #if USE_AD2
145 PRINT_CONFIG_MSG("Analog to Digital Coverter 2 active")
146 #endif
147 #if USE_AD3
148 PRINT_CONFIG_MSG("Analog to Digital Coverter 3 active")
149 #endif
150 #if !USE_AD1 && !USE_AD2 && !USE_AD3 && !defined FBW
151 #warning ALL ADC CONVERTERS INACTIVE
152 #endif
153 
154 #ifndef ADC_TIMER_PERIOD
155 #define ADC_TIMER_PERIOD 10000
156 #endif
157 
163 #ifndef ADC_TIMER_FREQUENCY
164 #define ADC_TIMER_FREQUENCY 2000000
165 #endif
166 
167 /***************************************/
168 /*** STATIC FUNCTION PROTOTYPES ***/
169 /***************************************/
170 
171 static inline void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map);
172 
173 static inline void adc_push_sample(struct adc_buf *buf,
174  uint16_t sample);
175 
176 static inline void adc_init_rcc(void);
177 static inline void adc_init_irq(void);
178 
179 
180 /********************************/
181 /*** GLOBAL VARIABLES ***/
182 /********************************/
183 
184 /* Only 4 ADC channels may be enabled at the same time
185  * on each ADC, as there are only 4 injection registers.
186  * Currently, the enums adc1_channels and adc2_channels only
187  * serve to resolve the number of channels on each ADC.
188  * There are 3 separate buffer lists, each holds the addresses of the actual adc buffers
189  * for the particular adc converter.
190  */
191 
195 
196 #if USE_AD1 || USE_AD2 || USE_AD3
197 #define ADC_NUM_CHANNELS 4
198 #endif
199 
200 #if USE_AD1
201 static struct adc_buf *adc1_buffers[ADC_NUM_CHANNELS];
203 #endif
204 #if USE_AD2
205 static struct adc_buf *adc2_buffers[ADC_NUM_CHANNELS];
207 #endif
208 #if USE_AD3
209 static struct adc_buf *adc3_buffers[ADC_NUM_CHANNELS];
211 #endif
212 
213 #if USE_ADC_WATCHDOG
214 #include "mcu_periph/sys_time.h"
215 // watchdog structure with adc bank and callback
216 static struct {
217  uint32_t timeStamp;
218  uint32_t adc;
219  adc_watchdog_callback cb;
220 } adc_watchdog;
221 #endif
222 
223 /***************************************/
224 /*** PUBLIC FUNCTION DEFINITIONS ***/
225 /***************************************/
226 
227 void adc_init(void)
228 {
229 #if USE_AD1 || USE_AD2 || USE_AD3
230  uint8_t x = 0;
231 
232  // ADC channel mapping
234 #endif
235 
236  /* Init GPIO ports for ADC operation
237  */
238 #if USE_ADC_1
239  PRINT_CONFIG_MSG("Info: Using ADC_1")
241 #endif
242 #if USE_ADC_2
243  PRINT_CONFIG_MSG("Info: Using ADC_2")
245 #endif
246 #if USE_ADC_3
247  PRINT_CONFIG_MSG("Info: Using ADC_3")
249 #endif
250 #if USE_ADC_4
251  PRINT_CONFIG_MSG("Info: Using ADC_4")
253 #endif
254 #if USE_ADC_5
255  PRINT_CONFIG_MSG("Info: Using ADC_5")
257 #endif
258 #if USE_ADC_6
259  PRINT_CONFIG_MSG("Info: Using ADC_6")
261 #endif
262 #if USE_ADC_7
263  PRINT_CONFIG_MSG("Info: Using ADC_7")
265 #endif
266 #if USE_ADC_8
267  PRINT_CONFIG_MSG("Info: Using ADC_8")
268  gpio_setup_pin_analog(ADC_8_GPIO_PORT, ADC_8_GPIO_PIN);
269 #endif
270 #if USE_ADC_9
271  PRINT_CONFIG_MSG("Info: Using ADC_9")
273 #endif
274 
275  // Init clock and irq
276  adc_init_rcc();
277  adc_init_irq();
278 
279  /* If fewer than 4 channels are active, say 3, then they are placed in to
280  * injection slots 2,3 and 4 because the stm32 architecture converts injected
281  * slots 2,3 and 4 and skips slot 1 instead of logicaly converting slots 1,2
282  * and 3 and leave slot 4.
283  * EXAMPLE OF ADC EXECUTION ORDER WHEN WE HAVE SAY 2 ADC INPUTS USED on ADC1
284  * The first board adc channel ADC1_1 is mapped to injected channel 3 and ADC1_2
285  * to injected channel 4 and because the conversions start from the lowest
286  * injection channel used, 3 in our case, injected channel 3 data will be
287  * located at JDR1 and 4 to JDR2 so JDR1 = ADC1_1 and JDR2 = ADC1_2.
288  * That's why "adc_channel_map" has this descending order.
289  */
290 
291  nb_adc1_channels = 0;
292 #if USE_AD1
293 #ifdef AD1_1_CHANNEL
294  adc_channel_map[AD1_1] = AD1_1_CHANNEL;
295  nb_adc1_channels++;
296 #endif
297 #ifdef AD1_2_CHANNEL
298  adc_channel_map[AD1_2] = AD1_2_CHANNEL;
299  nb_adc1_channels++;
300 #endif
301 #ifdef AD1_3_CHANNEL
302  adc_channel_map[AD1_3] = AD1_3_CHANNEL;
303  nb_adc1_channels++;
304 #endif
305 #ifdef AD1_4_CHANNEL
306  adc_channel_map[AD1_4] = AD1_4_CHANNEL;
307  nb_adc1_channels++;
308 #endif
309  // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt
310  // handler, which is important as there are no buffers registered at the time the ADC trigger
311  // interrupt is enabled.
312  for (x = 0; x < 4; x++) { adc1_buffers[x] = NULL; }
313  adc_init_single(ADC1, nb_adc1_channels, adc_channel_map);
314 #endif // USE_AD1
315 
316 
317  nb_adc2_channels = 0;
318 #if USE_AD2
319 #ifdef AD2_1_CHANNEL
320  adc_channel_map[AD2_1 - nb_adc1_channels] = AD2_1_CHANNEL;
321  nb_adc2_channels++;
322 #endif
323 #ifdef AD2_2_CHANNEL
324  adc_channel_map[AD2_2 - nb_adc1_channels] = AD2_2_CHANNEL;
325  nb_adc2_channels++;
326 #endif
327 #ifdef AD2_3_CHANNEL
328  adc_channel_map[AD2_3 - nb_adc1_channels] = AD2_3_CHANNEL;
329  nb_adc2_channels++;
330 #endif
331 #ifdef AD2_4_CHANNEL
332  adc_channel_map[AD2_4 - nb_adc1_channels] = AD2_4_CHANNEL;
333  nb_adc2_channels++;
334 #endif
335  // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt
336  // handler, which is important as there are no buffers registered at the time the ADC trigger
337  // interrupt is enabled.
338  for (x = 0; x < 4; x++) { adc2_buffers[x] = NULL; }
339  adc_init_single(ADC2, nb_adc2_channels, adc_channel_map);
340 #endif // USE_AD2
341 
342 
343  nb_adc3_channels = 0;
344 #if USE_AD3
345 #ifdef AD3_1_CHANNEL
346  adc_channel_map[AD3_1 - nb_adc1_channels - nb_adc2_channels] = AD3_1_CHANNEL;
347  nb_adc3_channels++;
348 #endif
349 #ifdef AD3_2_CHANNEL
350  adc_channel_map[AD3_2 - nb_adc1_channels - nb_adc2_channels] = AD3_2_CHANNEL;
351  nb_adc3_channels++;
352 #endif
353 #ifdef AD3_3_CHANNEL
354  adc_channel_map[AD3_3 - nb_adc1_channels - nb_adc2_channels] = AD3_3_CHANNEL;
355  nb_adc3_channels++;
356 #endif
357 #ifdef AD3_4_CHANNEL
358  adc_channel_map[AD3_4 - nb_adc1_channels - nb_adc2_channels] = AD3_4_CHANNEL;
359  nb_adc3_channels++;
360 #endif
361  // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt
362  // handler, which is important as there are no buffers registered at the time the ADC trigger
363  // interrupt is enabled.
364  for (x = 0; x < 4; x++) { adc3_buffers[x] = NULL; }
365  adc_init_single(ADC3, nb_adc3_channels, adc_channel_map);
366 #endif // USE_AD3
367 
368 #if USE_ADC_WATCHDOG
369  adc_watchdog.cb = NULL;
370  adc_watchdog.timeStamp = 0;
371 #endif
372 
373 }
374 
375 void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
376 {
377  if (adc_channel < nb_adc1_channels) {
378 #if USE_AD1
379  adc1_buffers[adc_channel] = s;
380 #endif
381  } else if (adc_channel < (nb_adc1_channels + nb_adc2_channels)) {
382 #if USE_AD2
383  adc2_buffers[adc_channel - nb_adc1_channels] = s;
384 #endif
385  } else if (adc_channel < (nb_adc1_channels + nb_adc2_channels + nb_adc3_channels)) {
386 #if USE_AD3
387  adc3_buffers[adc_channel - (nb_adc1_channels + nb_adc2_channels)] = s;
388 #endif
389  }
390 
391  s->av_nb_sample = av_nb_sample;
392 
393 }
394 
395 #if USE_ADC_WATCHDOG
396 void register_adc_watchdog(uint32_t adc, uint8_t chan, uint16_t low, uint16_t high, adc_watchdog_callback cb)
397 {
398  adc_watchdog.adc = adc;
399  adc_watchdog.cb = cb;
400 
401  // activated adc watchdog of a single injected channel with interrupt
402  adc_set_watchdog_low_threshold(adc, low);
403  adc_set_watchdog_high_threshold(adc, high);
404  adc_enable_analog_watchdog_injected(adc);
405  adc_enable_analog_watchdog_on_selected_channel(adc, chan);
406  adc_enable_awd_interrupt(adc);
407 }
408 #endif
409 
410 /**************************************/
411 /*** PRIVATE FUNCTION DEFINITIONS ***/
412 /**************************************/
413 
414 #if defined(USE_AD_TIM4)
415 #define TIM_ADC TIM4
416 #define RCC_TIM_ADC RCC_TIM4
417 #elif defined(USE_AD_TIM1)
418 #define TIM_ADC TIM1
419 #define RCC_TIM_ADC RCC_TIM1
420 #else
421 #define TIM_ADC TIM2
422 #define RCC_TIM_ADC RCC_TIM2
423 #endif
424 
426 static inline void adc_init_rcc(void)
427 {
428 #if USE_AD1 || USE_AD2 || USE_AD3
429  /* Timer peripheral clock enable. */
430  rcc_periph_clock_enable(RCC_TIM_ADC);
431 #if defined(STM32F4)
432  adc_set_clk_prescale(ADC_CCR_ADCPRE_BY2);
433 #endif
434 
435  /* Enable ADC peripheral clocks. */
436 #if USE_AD1
437  rcc_periph_clock_enable(RCC_ADC1);
438 #endif
439 #if USE_AD2
440  rcc_periph_clock_enable(RCC_ADC2);
441 #endif
442 #if USE_AD3
443  rcc_periph_clock_enable(RCC_ADC3);
444 #endif
445 
446  /* Time Base configuration */
447  timer_reset(TIM_ADC);
448  timer_set_mode(TIM_ADC, TIM_CR1_CKD_CK_INT,
449  TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
450  /* timer counts with ADC_TIMER_FREQUENCY */
451  uint32_t timer_clk = timer_get_frequency(TIM_ADC);
452  timer_set_prescaler(TIM_ADC, (timer_clk / ADC_TIMER_FREQUENCY) - 1);
453 
454  timer_set_period(TIM_ADC, ADC_TIMER_PERIOD);
455  /* Generate TRGO on every update (when counter reaches period reload value) */
456  timer_set_master_mode(TIM_ADC, TIM_CR2_MMS_UPDATE);
457  timer_enable_counter(TIM_ADC);
458 
459 #endif // USE_AD1 || USE_AD2 || USE_AD3
460 }
461 
463 static inline void adc_init_irq(void)
464 {
465 #if defined(STM32F1)
466  nvic_set_priority(NVIC_ADC1_2_IRQ, NVIC_ADC_IRQ_PRIO);
467  nvic_enable_irq(NVIC_ADC1_2_IRQ);
468 #elif defined(STM32F4)
469  nvic_set_priority(NVIC_ADC_IRQ, NVIC_ADC_IRQ_PRIO);
470  nvic_enable_irq(NVIC_ADC_IRQ);
471 #endif
472 }
473 
474 
475 static inline void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map)
476 {
477  // Paranoia, must be down for 2+ ADC clock cycles before calibration
478  adc_power_off(adc);
479 
480  /* Configure ADC */
481  /* Explicitly setting most registers, reset/default values are correct for most */
482  /* Set CR1 register. */
483  /* Clear AWDEN */
484  adc_disable_analog_watchdog_regular(adc);
485  /* Clear JAWDEN */
486  adc_disable_analog_watchdog_injected(adc);
487  /* Clear DISCEN */
488  adc_disable_discontinuous_mode_regular(adc);
489  /* Clear JDISCEN */
490  adc_disable_discontinuous_mode_injected(adc);
491  /* Clear JAUTO */
492  adc_disable_automatic_injected_group_conversion(adc);
493  /* Set SCAN */
494  adc_enable_scan_mode(adc);
495  /* Enable ADC<X> JEOC interrupt (Set JEOCIE) */
496  adc_enable_eoc_interrupt_injected(adc);
497  /* Clear AWDIE */
498  adc_disable_awd_interrupt(adc);
499  /* Clear EOCIE */
500  adc_disable_eoc_interrupt(adc);
501 
502  /* Set CR2 register. */
503  /* Clear TSVREFE */
504  adc_disable_temperature_sensor();
505  /* Clear EXTTRIG */
506  adc_disable_external_trigger_regular(adc);
507  /* Clear ALIGN */
508  adc_set_right_aligned(adc);
509  /* Clear DMA */
510  adc_disable_dma(adc);
511  /* Clear CONT */
512  adc_set_single_conversion_mode(adc);
513 
514  //uint8_t x = 0;
515  //for (x = 0; x < nb_channels; x++) {
516  // adc_set_sample_time(adc, channel_map[x], ADC_SAMPLE_TIME);
517  //}
518  adc_set_sample_time_on_all_channels(adc, ADC_SAMPLE_TIME);
519 
520  adc_set_injected_sequence(adc, nb_channels, channel_map);
521 
522 #if USE_AD_TIM4
523  PRINT_CONFIG_MSG("Info: Using TIM4 for ADC")
524 #if defined(STM32F1)
525  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO);
526 #elif defined(STM32F4)
527  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
528 #endif
529 #elif USE_AD_TIM1
530  PRINT_CONFIG_MSG("Info: Using TIM1 for ADC")
531 #if defined(STM32F1)
532  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO);
533 #elif defined(STM32F4)
534  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
535 #endif
536 #else
537  PRINT_CONFIG_MSG("Info: Using default TIM2 for ADC")
538 #if defined(STM32F1)
539  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO);
540 #elif defined(STM32F4)
541  adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
542 #endif
543 #endif
544 
545  /* Enable ADC<X> */
546  adc_power_on(adc);
547 #if defined(STM32F1)
548  /* Rest ADC<X> calibaration register and wait until done */
549  adc_reset_calibration(adc);
550  /* Start ADC<X> calibaration and wait until done */
551  adc_calibrate(adc);
552 #endif
553 
554  return;
555 } // adc_init_single
556 
557 
558 static inline void adc_push_sample(struct adc_buf *buf, uint16_t value)
559 {
560  uint8_t new_head = buf->head + 1;
561 
562  if (new_head >= buf->av_nb_sample) {
563  new_head = 0;
564  }
565  buf->sum -= buf->values[new_head];
566  buf->values[new_head] = value;
567  buf->sum += value;
568  buf->head = new_head;
569 }
570 
571 /*********************************/
572 /*** ADC INTERRUPT HANDLER ***/
573 /*********************************/
574 
575 #if defined(STM32F1)
576 void adc1_2_isr(void)
577 #elif defined(STM32F4)
578 void adc_isr(void)
579 #endif
580 {
581 #if USE_AD1 || USE_AD2 || USE_AD3
582  uint8_t channel = 0;
583  uint16_t value = 0;
584  struct adc_buf *buf;
585 #endif
586 
587 #if USE_ADC_WATCHDOG
588  /*
589  We need adc sampling fast enough to detect battery plug out, but we did not
590  need to get actual actual value so fast. So timer fire adc conversion fast,
591  at least 500 hz, but we inject adc value in sampling buffer only at 50hz
592  */
593  const uint32_t timeStampDiff = get_sys_time_msec() - adc_watchdog.timeStamp;
594  const bool shouldAccumulateValue = timeStampDiff > 20;
595  if (shouldAccumulateValue) {
596  adc_watchdog.timeStamp = get_sys_time_msec();
597  }
598 
599  if (adc_watchdog.cb != NULL) {
600  if (adc_awd(adc_watchdog.adc)) {
601  ADC_SR(adc_watchdog.adc) &= ~ADC_SR_AWD; // clear int flag
602  adc_watchdog.cb();
603  }
604  }
605 #endif
606 
607 #if USE_AD1
608  // Clear Injected End Of Conversion
609  if (adc_eoc_injected(ADC1)) {
610  ADC_SR(ADC1) &= ~ADC_SR_JEOC;
611 #if USE_ADC_WATCHDOG
612  if (shouldAccumulateValue) {
613 #endif
614  for (channel = 0; channel < nb_adc1_channels; channel++) {
615  buf = adc1_buffers[channel];
616  if (buf) {
617  value = adc_read_injected(ADC1, channel + 1);
618  adc_push_sample(buf, value);
619  }
620  }
621 #if USE_ADC_WATCHDOG
622  }
623 #endif
624  }
625 #endif // USE_AD1
626 
627 #if USE_AD2
628  if (adc_eoc_injected(ADC2)) {
629  ADC_SR(ADC2) &= ~ADC_SR_JEOC;
630 #if USE_ADC_WATCHDOG
631  if (shouldAccumulateValue) {
632 #endif
633  for (channel = 0; channel < nb_adc2_channels; channel++) {
634  buf = adc2_buffers[channel];
635  if (buf) {
636  value = adc_read_injected(ADC2, channel + 1);
637  adc_push_sample(buf, value);
638  }
639  }
640 #if USE_ADC_WATCHDOG
641  }
642 #endif
643  }
644 #endif // USE_AD2
645 
646 #if USE_AD3
647  if (adc_eoc_injected(ADC3)) {
648  ADC_SR(ADC3) &= ~ADC_SR_JEOC;
649 #if USE_ADC_WATCHDOG
650  if (shouldAccumulateValue) {
651 #endif
652  for (channel = 0; channel < nb_adc3_channels; channel++) {
653  buf = adc3_buffers[channel];
654  if (buf) {
655  value = adc_read_injected(ADC3, channel + 1);
656  adc_push_sample(buf, value);
657  }
658  }
659 #if USE_ADC_WATCHDOG
660  }
661 #endif
662  }
663 #endif // USE_AD3
664 
665  return;
666 }
uint8_t av_nb_sample
Definition: adc.h:57
#define ADC1
Definition: LPC21xx.h:370
unsigned short uint16_t
Definition: types.h:16
static void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map)
Definition: adc_arch.c:475
static uint32_t s
#define ADC_7_GPIO_PIN
Definition: chimera.h:191
#define ADC_4_GPIO_PIN
Definition: board.h:195
#define AD3_2_CHANNEL
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
Definition: sys_time_arch.c:78
#define AD1_1_CHANNEL
Definition: cjmcu.h:62
Some architecture independent helper functions for GPIOs.
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:281
uint32_t sum
Definition: adc.h:54
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:263
#define ADC_6_GPIO_PIN
#define ADC_7_GPIO_PORT
Definition: chimera.h:190
#define ADC_9_GPIO_PIN
Definition: tawaki.h:135
uint8_t head
Definition: adc.h:56
arch independent ADC (Analog to Digital Converter) API
#define ADC_1_GPIO_PORT
Definition: cjmcu.h:64
static uint8_t nb_adc3_channels
Definition: adc_arch.c:194
#define ADC_3_GPIO_PIN
Definition: lisa_l_1.0.h:151
static struct adc_buf * adc1_buffers[ADC_NUM_CHANNELS]
Definition: adc_arch.c:149
Generic interface for all ADC hardware drivers, independent from microcontroller architecture.
Definition: adc.h:53
#define NVIC_ADC_IRQ_PRIO
Definition: adc_arch.c:104
static uint8_t nb_adc1_channels
Definition: adc_arch.c:192
static const uint8_t adc_channel_map[ADC_NUM_CHANNELS]
#endif
Definition: adc_arch.c:87
Architecture independent timing functions.
#define AD2_2_CHANNEL
#define ADC_5_GPIO_PIN
Definition: board.h:284
unsigned long uint32_t
Definition: types.h:18
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
void gpio_setup_pin_analog(ioportid_t port, uint16_t pin)
Setup a gpio for analog use.
Definition: gpio_arch.c:86
#define ADC_1_GPIO_PIN
Definition: cjmcu.h:65
#define ADC_5_GPIO_PORT
Definition: board.h:283
#define AD1_4_CHANNEL
Definition: board.h:192
#define ADC_TIMER_FREQUENCY
Timer frequency for ADC Timer will trigger an update event after reaching the period reload value...
Definition: adc_arch.c:164
static void adc_push_sample(struct adc_buf *buf, uint16_t sample)
Definition: adc_arch.c:558
#define ADC_9_GPIO_PORT
Definition: tawaki.h:134
#define ADC_TIMER_PERIOD
Definition: adc_arch.c:155
#define ADC_4_GPIO_PORT
Definition: board.h:194
uint16_t values[MAX_AV_NB_SAMPLE]
Definition: adc.h:55
#define ADC_3_GPIO_PORT
Definition: lisa_l_1.0.h:150
#define AD3_1_CHANNEL
unsigned char uint8_t
Definition: types.h:14
#define TIM_ADC
Definition: adc_arch.c:421
static void adc_init_irq(void)
Configure and enable ADC interrupt.
Definition: adc_arch.c:463
void adc_init(void)
Adc init.
Definition: adc_arch.c:304
#define AD2_1_CHANNEL
#define ADC_6_GPIO_PORT
static uint8_t nb_adc2_channels
Definition: adc_arch.c:193
static uint8_t channel
Definition: ADS8344.c:80
#define RCC_TIM_ADC
Definition: adc_arch.c:422
#define AD1_3_CHANNEL
Definition: lisa_l_1.0.h:148
#define ADC_NUM_CHANNELS
Definition: adc_arch.h:93
static void adc_init_rcc(void)
Configure and enable RCC for peripherals (ADC1, ADC2, Timer)
Definition: adc_arch.c:426