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
196 #if USE_AD1 || USE_AD2 || USE_AD3
197 #define ADC_NUM_CHANNELS 4
219 adc_watchdog_callback cb;
229 #if USE_AD1 || USE_AD2 || USE_AD3
291 nb_adc1_channels = 0;
312 for (x = 0; x < 4; x++) { adc1_buffers[x] = NULL; }
317 nb_adc2_channels = 0;
338 for (x = 0; x < 4; x++) { adc2_buffers[x] = NULL; }
343 nb_adc3_channels = 0;
354 adc_channel_map[AD3_3 - nb_adc1_channels -
nb_adc2_channels] = AD3_3_CHANNEL;
358 adc_channel_map[AD3_4 - nb_adc1_channels -
nb_adc2_channels] = AD3_4_CHANNEL;
364 for (x = 0; x < 4; x++) { adc3_buffers[x] = NULL; }
369 adc_watchdog.cb = NULL;
370 adc_watchdog.timeStamp = 0;
377 if (adc_channel < nb_adc1_channels) {
379 adc1_buffers[adc_channel] =
s;
381 }
else if (adc_channel < (nb_adc1_channels + nb_adc2_channels)) {
385 }
else if (adc_channel < (nb_adc1_channels + nb_adc2_channels + nb_adc3_channels)) {
398 adc_watchdog.adc = adc;
399 adc_watchdog.cb = cb;
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);
414 #if defined(USE_AD_TIM4)
416 #define RCC_TIM_ADC RCC_TIM4
417 #elif defined(USE_AD_TIM1)
419 #define RCC_TIM_ADC RCC_TIM1
422 #define RCC_TIM_ADC RCC_TIM2
428 #if USE_AD1 || USE_AD2 || USE_AD3
432 adc_set_clk_prescale(ADC_CCR_ADCPRE_BY2);
437 rcc_periph_clock_enable(RCC_ADC1);
440 rcc_periph_clock_enable(RCC_ADC2);
443 rcc_periph_clock_enable(RCC_ADC3);
448 timer_set_mode(
TIM_ADC, TIM_CR1_CKD_CK_INT,
449 TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
456 timer_set_master_mode(
TIM_ADC, TIM_CR2_MMS_UPDATE);
459 #endif // USE_AD1 || USE_AD2 || USE_AD3
467 nvic_enable_irq(NVIC_ADC1_2_IRQ);
468 #elif defined(STM32F4)
470 nvic_enable_irq(NVIC_ADC_IRQ);
484 adc_disable_analog_watchdog_regular(adc);
486 adc_disable_analog_watchdog_injected(adc);
488 adc_disable_discontinuous_mode_regular(adc);
490 adc_disable_discontinuous_mode_injected(adc);
492 adc_disable_automatic_injected_group_conversion(adc);
494 adc_enable_scan_mode(adc);
496 adc_enable_eoc_interrupt_injected(adc);
498 adc_disable_awd_interrupt(adc);
500 adc_disable_eoc_interrupt(adc);
504 adc_disable_temperature_sensor();
506 adc_disable_external_trigger_regular(adc);
508 adc_set_right_aligned(adc);
510 adc_disable_dma(adc);
512 adc_set_single_conversion_mode(adc);
518 adc_set_sample_time_on_all_channels(adc, ADC_SAMPLE_TIME);
520 adc_set_injected_sequence(adc, nb_channels, channel_map);
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);
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);
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);
549 adc_reset_calibration(adc);
566 buf->
values[new_head] = value;
568 buf->
head = new_head;
576 void adc1_2_isr(
void)
577 #elif defined(STM32F4)
581 #if USE_AD1 || USE_AD2 || USE_AD3
594 const bool shouldAccumulateValue = timeStampDiff > 20;
595 if (shouldAccumulateValue) {
599 if (adc_watchdog.cb != NULL) {
600 if (adc_awd(adc_watchdog.adc)) {
601 ADC_SR(adc_watchdog.adc) &= ~ADC_SR_AWD;
609 if (adc_eoc_injected(
ADC1)) {
610 ADC_SR(
ADC1) &= ~ADC_SR_JEOC;
612 if (shouldAccumulateValue) {
617 value = adc_read_injected(
ADC1, channel + 1);
628 if (adc_eoc_injected(ADC2)) {
629 ADC_SR(ADC2) &= ~ADC_SR_JEOC;
631 if (shouldAccumulateValue) {
636 value = adc_read_injected(ADC2, channel + 1);
647 if (adc_eoc_injected(ADC3)) {
648 ADC_SR(ADC3) &= ~ADC_SR_JEOC;
650 if (shouldAccumulateValue) {
655 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)
Get the time in milliseconds since startup.
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)