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
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
197 static struct adc_buf *adc1_buffers[4];
201 static struct adc_buf *adc2_buffers[4];
205 static struct adc_buf *adc3_buffers[4];
215 adc_watchdog_callback cb;
286 nb_adc1_channels = 0;
307 for (x = 0; x < 4; x++) { adc1_buffers[x] = NULL; }
312 nb_adc2_channels = 0;
333 for (x = 0; x < 4; x++) { adc2_buffers[x] = NULL; }
338 nb_adc3_channels = 0;
349 adc_channel_map[AD3_3 - nb_adc1_channels -
nb_adc2_channels] = AD3_3_CHANNEL;
353 adc_channel_map[AD3_4 - nb_adc1_channels -
nb_adc2_channels] = AD3_4_CHANNEL;
359 for (x = 0; x < 4; x++) { adc3_buffers[x] = NULL; }
364 adc_watchdog.cb = NULL;
365 adc_watchdog.timeStamp = 0;
373 if (adc_channel < nb_adc1_channels) {
375 adc1_buffers[adc_channel] = s;
377 }
else if (adc_channel < (nb_adc1_channels + nb_adc2_channels)) {
381 }
else if (adc_channel < (nb_adc1_channels + nb_adc2_channels + nb_adc3_channels)) {
394 adc_watchdog.adc = adc;
395 adc_watchdog.cb = cb;
398 adc_set_watchdog_low_threshold(adc, low);
399 adc_set_watchdog_high_threshold(adc, high);
400 adc_enable_analog_watchdog_injected(adc);
401 adc_enable_analog_watchdog_on_selected_channel(adc, chan);
402 adc_enable_awd_interrupt(adc);
410 #if defined(USE_AD_TIM4)
412 #define RCC_TIM_ADC RCC_TIM4
413 #elif defined(USE_AD_TIM1)
415 #define RCC_TIM_ADC RCC_TIM1
418 #define RCC_TIM_ADC RCC_TIM2
424 #if USE_AD1 || USE_AD2 || USE_AD3
428 adc_set_clk_prescale(ADC_CCR_ADCPRE_BY2);
433 rcc_periph_clock_enable(RCC_ADC1);
436 rcc_periph_clock_enable(RCC_ADC2);
439 rcc_periph_clock_enable(RCC_ADC3);
444 timer_set_mode(
TIM_ADC, TIM_CR1_CKD_CK_INT,
445 TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
452 timer_set_master_mode(
TIM_ADC, TIM_CR2_MMS_UPDATE);
455 #endif // USE_AD1 || USE_AD2 || USE_AD3
463 nvic_enable_irq(NVIC_ADC1_2_IRQ);
464 #elif defined(STM32F4)
480 adc_disable_analog_watchdog_regular(adc);
482 adc_disable_analog_watchdog_injected(adc);
484 adc_disable_discontinuous_mode_regular(adc);
486 adc_disable_discontinuous_mode_injected(adc);
488 adc_disable_automatic_injected_group_conversion(adc);
490 adc_enable_scan_mode(adc);
492 adc_enable_eoc_interrupt_injected(adc);
494 adc_disable_awd_interrupt(adc);
496 adc_disable_eoc_interrupt(adc);
501 adc_disable_temperature_sensor(adc);
502 #elif defined(STM32F4)
503 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);
551 while ((ADC_CR2(adc) & ADC_CR2_RSTCAL) != 0);
553 adc_calibration(adc);
555 while ((ADC_CR2(adc) & ADC_CR2_CAL) != 0);
572 buf->
head = new_head;
580 void adc1_2_isr(
void)
581 #elif defined(STM32F4)
596 const bool_t shouldAccumulateValue = timeStampDiff > 20;
597 if (shouldAccumulateValue) {
601 if (adc_watchdog.cb != NULL) {
602 if (adc_awd(adc_watchdog.adc)) {
603 ADC_SR(adc_watchdog.adc) &= ~ADC_SR_AWD;
611 if (adc_eoc_injected(
ADC1)) {
612 ADC_SR(
ADC1) &= ~ADC_SR_JEOC;
614 if (shouldAccumulateValue) {
619 value = adc_read_injected(
ADC1, channel + 1);
630 if (adc_eoc_injected(ADC2)) {
631 ADC_SR(ADC2) &= ~ADC_SR_JEOC;
633 if (shouldAccumulateValue) {
638 value = adc_read_injected(ADC2, channel + 1);
649 if (adc_eoc_injected(ADC3)) {
650 ADC_SR(ADC3) &= ~ADC_SR_JEOC;
652 if (shouldAccumulateValue) {
657 value = adc_read_injected(ADC3, channel + 1);
static uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
void gpio_setup_pin_analog(uint32_t port, uint16_t pin)
Setup a gpio for analog use.
static void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t *channel_map)
Some architecture independent helper functions for GPIOs.
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
Generic interface for all ADC hardware drivers, independent from microcontroller architecture.
#define NVIC_ADC_IRQ_PRIO
static uint8_t nb_adc1_channels
Architecture independent timing functions.
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
#define ADC_TIMER_FREQUENCY
Timer frequency for ADC Timer will trigger an update event after reaching the period reload value...
void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
Registers a buffer to be used to store the specified converted channel Usage:
static void adc_push_sample(struct adc_buf *buf, uint16_t sample)
void adc_init(void)
Initialize the ADC.
uint16_t values[MAX_AV_NB_SAMPLE]
static void adc_init_irq(void)
Configure and enable ADC interrupt.
static uint8_t nb_adc2_channels
static void adc_init_rcc(void)
Configure and enable RCC for peripherals (ADC1, ADC2, Timer)