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>
100 #include BOARD_CONFIG
103 #ifndef NVIC_ADC_IRQ_PRIO
104 #define NVIC_ADC_IRQ_PRIO 0
108 #define ADC_SAMPLE_TIME ADC_SMPR_SMP_41DOT5CYC
109 #elif defined(STM32F4)
110 #define ADC_SAMPLE_TIME ADC_SMPR_SMP_56CYC
115 #if defined(AD1_1_CHANNEL) || defined(AD1_2_CHANNEL) || defined(AD1_3_CHANNEL) || defined(AD1_4_CHANNEL)
121 #if defined(AD2_1_CHANNEL) || defined(AD2_2_CHANNEL) || defined(AD2_3_CHANNEL) || defined(AD2_4_CHANNEL)
129 #if defined(AD3_1_CHANNEL) || defined(AD3_2_CHANNEL) || defined(AD3_3_CHANNEL) || defined(AD3_4_CHANNEL)
150 #if !USE_AD1 && !USE_AD2 && !USE_AD3 && !defined FBW
151 #warning ALL ADC CONVERTERS INACTIVE
154 #ifndef ADC_TIMER_PERIOD
155 #define ADC_TIMER_PERIOD 10000
163 #ifndef ADC_TIMER_FREQUENCY
164 #define ADC_TIMER_FREQUENCY 2000000
201 static struct adc_buf *adc2_buffers[4];
205 static struct adc_buf *adc3_buffers[4];
215 adc_watchdog_callback cb;
225 #if USE_AD1 || USE_AD2 || USE_AD3
287 nb_adc1_channels = 0;
308 for (x = 0; x < 4; x++) { adc1_buffers[x] = NULL; }
313 nb_adc2_channels = 0;
334 for (x = 0; x < 4; x++) { adc2_buffers[x] = NULL; }
339 nb_adc3_channels = 0;
350 adc_channel_map[AD3_3 - nb_adc1_channels -
nb_adc2_channels] = AD3_3_CHANNEL;
354 adc_channel_map[AD3_4 - nb_adc1_channels -
nb_adc2_channels] = AD3_4_CHANNEL;
360 for (x = 0; x < 4; x++) { adc3_buffers[x] = NULL; }
365 adc_watchdog.cb = NULL;
366 adc_watchdog.timeStamp = 0;
374 if (adc_channel < nb_adc1_channels) {
376 adc1_buffers[adc_channel] = s;
378 }
else if (adc_channel < (nb_adc1_channels + nb_adc2_channels)) {
382 }
else if (adc_channel < (nb_adc1_channels + nb_adc2_channels + nb_adc3_channels)) {
395 adc_watchdog.adc = adc;
396 adc_watchdog.cb = cb;
399 adc_set_watchdog_low_threshold(adc, low);
400 adc_set_watchdog_high_threshold(adc, high);
401 adc_enable_analog_watchdog_injected(adc);
402 adc_enable_analog_watchdog_on_selected_channel(adc, chan);
403 adc_enable_awd_interrupt(adc);
411 #if defined(USE_AD_TIM4)
413 #define RCC_TIM_ADC RCC_TIM4
414 #elif defined(USE_AD_TIM1)
416 #define RCC_TIM_ADC RCC_TIM1
419 #define RCC_TIM_ADC RCC_TIM2
425 #if USE_AD1 || USE_AD2 || USE_AD3
429 adc_set_clk_prescale(ADC_CCR_ADCPRE_BY2);
434 rcc_periph_clock_enable(RCC_ADC1);
437 rcc_periph_clock_enable(RCC_ADC2);
440 rcc_periph_clock_enable(RCC_ADC3);
445 timer_set_mode(
TIM_ADC, TIM_CR1_CKD_CK_INT,
446 TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
453 timer_set_master_mode(
TIM_ADC, TIM_CR2_MMS_UPDATE);
456 #endif // USE_AD1 || USE_AD2 || USE_AD3
464 nvic_enable_irq(NVIC_ADC1_2_IRQ);
465 #elif defined(STM32F4)
467 nvic_enable_irq(NVIC_ADC_IRQ);
481 adc_disable_analog_watchdog_regular(adc);
483 adc_disable_analog_watchdog_injected(adc);
485 adc_disable_discontinuous_mode_regular(adc);
487 adc_disable_discontinuous_mode_injected(adc);
489 adc_disable_automatic_injected_group_conversion(adc);
491 adc_enable_scan_mode(adc);
493 adc_enable_eoc_interrupt_injected(adc);
495 adc_disable_awd_interrupt(adc);
497 adc_disable_eoc_interrupt(adc);
502 adc_disable_temperature_sensor(adc);
503 #elif defined(STM32F4)
504 adc_disable_temperature_sensor();
507 adc_disable_external_trigger_regular(adc);
509 adc_set_right_aligned(adc);
511 adc_disable_dma(adc);
513 adc_set_single_conversion_mode(adc);
519 adc_set_sample_time_on_all_channels(adc, ADC_SAMPLE_TIME);
521 adc_set_injected_sequence(adc, nb_channels, channel_map);
526 adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO);
527 #elif defined(STM32F4)
528 adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
533 adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO);
534 #elif defined(STM32F4)
535 adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
540 adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO);
541 #elif defined(STM32F4)
542 adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES);
550 adc_reset_calibration(adc);
552 while ((ADC_CR2(adc) & ADC_CR2_RSTCAL) != 0);
554 adc_calibration(adc);
556 while ((ADC_CR2(adc) & ADC_CR2_CAL) != 0);
571 buf->
values[new_head] = value;
573 buf->
head = new_head;
581 void adc1_2_isr(
void)
582 #elif defined(STM32F4)
586 #if USE_AD1 || USE_AD2 || USE_AD3
599 const bool shouldAccumulateValue = timeStampDiff > 20;
600 if (shouldAccumulateValue) {
604 if (adc_watchdog.cb != NULL) {
605 if (adc_awd(adc_watchdog.adc)) {
606 ADC_SR(adc_watchdog.adc) &= ~ADC_SR_AWD;
614 if (adc_eoc_injected(
ADC1)) {
615 ADC_SR(
ADC1) &= ~ADC_SR_JEOC;
617 if (shouldAccumulateValue) {
622 value = adc_read_injected(
ADC1, channel + 1);
633 if (adc_eoc_injected(ADC2)) {
634 ADC_SR(ADC2) &= ~ADC_SR_JEOC;
636 if (shouldAccumulateValue) {
641 value = adc_read_injected(ADC2, channel + 1);
652 if (adc_eoc_injected(ADC3)) {
653 ADC_SR(ADC3) &= ~ADC_SR_JEOC;
655 if (shouldAccumulateValue) {
660 value = adc_read_injected(ADC3, channel + 1);
static void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map)
uint32_t get_sys_time_msec(void)
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.
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...
arch independent ADC (Analog to Digital Converter) API
static uint8_t nb_adc3_channels
static struct adc_buf * adc1_buffers[ADC_NUM_CHANNELS]
Generic interface for all ADC hardware drivers, independent from microcontroller architecture.
#define NVIC_ADC_IRQ_PRIO
static uint8_t nb_adc1_channels
static const uint8_t adc_channel_map[ADC_NUM_CHANNELS]
#endif
Architecture independent timing functions.
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.
#define ADC_TIMER_FREQUENCY
Timer frequency for ADC Timer will trigger an update event after reaching the period reload value...
static void adc_push_sample(struct adc_buf *buf, uint16_t sample)
uint16_t values[MAX_AV_NB_SAMPLE]
static void adc_init_irq(void)
Configure and enable ADC interrupt.
void adc_init(void)
Adc init.
static uint8_t nb_adc2_channels
static void adc_init_rcc(void)
Configure and enable RCC for peripherals (ADC1, ADC2, Timer)