static void adc_setup(void) { int i; rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); /* Make sure the ADC doesn't run during config. */ adc_off(ADC1); /* We configure everything for one single timer triggered injected conversion. */ adc_disable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); /* We can only use discontinuous mode on either the regular OR injected channels, not both */ adc_disable_discontinuous_mode_regular(ADC1); adc_enable_discontinuous_mode_injected(ADC1); /* We want to start the injected conversion with the TIM2 TRGO */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ __asm__("nop"); adc_reset_calibration(ADC1); while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0); adc_calibration(ADC1); while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0); }
static void adc_setup(void) { int i; rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); /* Make sure the ADC doesn't run during config. */ adc_off(ADC1); /* We configure everything for one single timer triggered injected conversion with interrupt generation. */ /* While not needed for a single channel, try out scan mode which does all channels in one sweep and * generates the interrupt/EOC/JEOC flags set at the end of all channels, not each one. */ adc_enable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); /* We want to start the injected conversion with the TIM2 TRGO */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); /* Generate the ADC1_2_IRQ */ adc_enable_eoc_interrupt_injected(ADC1); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ __asm__("nop"); adc_reset_calibration(ADC1); while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0); adc_calibration(ADC1); while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0); }
static void adc_setup(void) { int i; rcc_periph_clock_enable(RCC_ADC1); /* Make sure the ADC doesn't run during config. */ adc_power_off(ADC1); /* We configure everything for one single timer triggered injected conversion with interrupt generation. */ /* While not needed for a single channel, try out scan mode which does all channels in one sweep and * generates the interrupt/EOC/JEOC flags set at the end of all channels, not each one. */ adc_enable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); /* We want to start the injected conversion with the TIM2 TRGO */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); /* Generate the ADC1_2_IRQ */ adc_enable_eoc_interrupt_injected(ADC1); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(); adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); /* Select the channels we want to convert. * 16=temperature_sensor, 17=Vrefint, 13=ADC1, 10=ADC2 */ channel_array[0] = 16; channel_array[1] = 17; channel_array[2] = 13; channel_array[3] = 10; adc_set_injected_sequence(ADC1, 4, channel_array); adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ __asm__("nop"); adc_reset_calibration(ADC1); adc_calibrate(ADC1); }
/** * Enable selected channels on specified ADC. * Usage: * * adc_init_single(ADC1, 1, 1, 0, 0); * * ... would enable ADC1, enabling channels 1 and 2, * but not 3 and 4. */ static inline void adc_init_single(uint32_t adc, uint8_t chan1, uint8_t chan2, uint8_t chan3, uint8_t chan4) { uint8_t num_channels, rank; uint8_t channels[4]; // Paranoia, must be down for 2+ ADC clock cycles before calibration adc_off(adc); /* enable adc clock */ if (adc == ADC1) { #ifdef USE_AD1 num_channels = NB_ADC1_CHANNELS; ADC1_GPIO_INIT(); #endif } else if (adc == ADC2) { #ifdef USE_AD2 num_channels = NB_ADC2_CHANNELS; ADC2_GPIO_INIT(); #endif } /* Configure ADC */ /* Explicitly setting most registers, reset/default values are correct for most */ /* Set CR1 register. */ /* Clear AWDEN */ adc_disable_analog_watchdog_regular(adc); /* Clear JAWDEN */ adc_disable_analog_watchdog_injected(adc); /* Clear DISCEN */ adc_disable_discontinuous_mode_regular(adc); /* Clear JDISCEN */ adc_disable_discontinuous_mode_injected(adc); /* Clear JAUTO */ adc_disable_automatic_injected_group_conversion(adc); /* Set SCAN */ adc_enable_scan_mode(adc); /* Enable ADC<X> JEOC interrupt (Set JEOCIE) */ adc_enable_eoc_interrupt_injected(adc); /* Clear AWDIE */ adc_disable_awd_interrupt(adc); /* Clear EOCIE */ adc_disable_eoc_interrupt(adc); /* Set CR2 register. */ /* Clear TSVREFE */ adc_disable_temperature_sensor(adc); /* Clear EXTTRIG */ adc_disable_external_trigger_regular(adc); /* Clear ALIGN */ adc_set_right_aligned(adc); /* Clear DMA */ adc_disable_dma(adc); /* Clear CONT */ adc_set_single_conversion_mode(adc); rank = 0; if (chan1) { adc_set_sample_time(adc, adc_channel_map[0], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[0]; rank++; } if (chan2) { adc_set_sample_time(adc, adc_channel_map[1], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[1]; rank++; } if (chan3) { adc_set_sample_time(adc, adc_channel_map[2], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[2]; rank++; } if (chan4) { adc_set_sample_time(adc, adc_channel_map[3], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[3]; } adc_set_injected_sequence(adc, num_channels, channels); #if USE_AD_TIM4 #pragma message "Info: Using TIM4 for ADC" adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO); #elif USE_AD_TIM1 #pragma message "Info: Using TIM1 for ADC" adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO); #else #pragma message "Info: Using default TIM2 for ADC" adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO); #endif /* Enable ADC<X> */ adc_power_on(adc); /* Enable ADC<X> reset calibaration register */ adc_reset_calibration(adc); /* Check the end of ADC<X> reset calibration */ while ((ADC_CR2(adc) & ADC_CR2_RSTCAL) != 0); /* Start ADC<X> calibaration */ adc_calibration(adc); /* Check the end of ADC<X> calibration */ while ((ADC_CR2(adc) & ADC_CR2_CAL) != 0); } // adc_init_single
static inline void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t* channel_map) { // Paranoia, must be down for 2+ ADC clock cycles before calibration adc_off(adc); /* Configure ADC */ /* Explicitly setting most registers, reset/default values are correct for most */ /* Set CR1 register. */ /* Clear AWDEN */ adc_disable_analog_watchdog_regular(adc); /* Clear JAWDEN */ adc_disable_analog_watchdog_injected(adc); /* Clear DISCEN */ adc_disable_discontinuous_mode_regular(adc); /* Clear JDISCEN */ adc_disable_discontinuous_mode_injected(adc); /* Clear JAUTO */ adc_disable_automatic_injected_group_conversion(adc); /* Set SCAN */ adc_enable_scan_mode(adc); /* Enable ADC<X> JEOC interrupt (Set JEOCIE) */ adc_enable_eoc_interrupt_injected(adc); /* Clear AWDIE */ adc_disable_awd_interrupt(adc); /* Clear EOCIE */ adc_disable_eoc_interrupt(adc); /* Set CR2 register. */ /* Clear TSVREFE */ #if defined(STM32F1) adc_disable_temperature_sensor(adc); #elif defined(STM32F4) adc_disable_temperature_sensor(); #endif /* Clear EXTTRIG */ adc_disable_external_trigger_regular(adc); /* Clear ALIGN */ adc_set_right_aligned(adc); /* Clear DMA */ adc_disable_dma(adc); /* Clear CONT */ adc_set_single_conversion_mode(adc); //uint8_t x = 0; //for (x = 0; x < nb_channels; x++) { // adc_set_sample_time(adc, channel_map[x], ADC_SAMPLE_TIME); //} adc_set_sample_time_on_all_channels(adc, ADC_SAMPLE_TIME); adc_set_injected_sequence(adc, nb_channels, channel_map); #if USE_AD_TIM4 PRINT_CONFIG_MSG("Info: Using TIM4 for ADC") #if defined(STM32F1) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO); #elif defined(STM32F4) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES); #endif #elif USE_AD_TIM1 PRINT_CONFIG_MSG("Info: Using TIM1 for ADC") #if defined(STM32F1) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO); #elif defined(STM32F4) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES); #endif #else PRINT_CONFIG_MSG("Info: Using default TIM2 for ADC") #if defined(STM32F1) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO); #elif defined(STM32F4) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES); #endif #endif /* Enable ADC<X> */ adc_power_on(adc); #if defined(STM32F1) /* Enable ADC<X> reset calibaration register */ adc_reset_calibration(adc); /* Check the end of ADC<X> reset calibration */ while ((ADC_CR2(adc) & ADC_CR2_RSTCAL) != 0); /* Start ADC<X> calibaration */ adc_calibration(adc); /* Check the end of ADC<X> calibration */ while ((ADC_CR2(adc) & ADC_CR2_CAL) != 0); #endif return; } // adc_init_single
void accel_highg_init() { uint8_t channel_array[16]; gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0 | GPIO1 | GPIO2); adc_set_dual_mode(ADC_CR1_DUALMOD_RSM); /* ADC1 + ADC2 dual mode */ adc_set_dual_mode(ADC_CR1_DUALMOD_ISM); adc_enable_external_trigger_injected(ADC1, ADC_CR2_JEXTSEL_TIM1_TRGO); adc_enable_external_trigger_injected(ADC3, ADC_CR2_JEXTSEL_TIM1_TRGO); adc_enable_dma(ADC1); adc_enable_dma(ADC3); adc_power_on(ADC1); adc_power_on(ADC2); adc_power_on(ADC3); adc_stab_sleep(); adc_reset_calibration(ADC1); adc_reset_calibration(ADC2); adc_reset_calibration(ADC3); adc_calibration(ADC1); adc_calibration(ADC2); adc_calibration(ADC3); memset(channel_array, 0, sizeof(channel_array)); channel_array[0] = 10; adc_set_injected_sequence(ADC1, 1, channel_array); channel_array[0] = 11; adc_set_injected_sequence(ADC2, 1, channel_array); channel_array[0] = 12; adc_set_injected_sequence(ADC3, 1, channel_array); timer_reset(TIM1); timer_enable_irq(TIM1, TIM_DIER_UIE); timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); /* 500Hz */ timer_set_prescaler(TIM1, 64); timer_set_period(TIM1, 2250); /* Generate TRGO */ timer_set_master_mode(TIM1, TIM_CR2_MMS_UPDATE); dma_set_peripheral_address(DMA1, DMA_CHANNEL5, (uint32_t) &ADC1_DR); dma_set_read_from_memory(DMA1, DMA_CHANNEL5); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL5); dma_set_peripheral_size(DMA1, DMA_CHANNEL5, DMA_CCR_PSIZE_32BIT); dma_set_memory_size(DMA1, DMA_CHANNEL5, DMA_CCR_MSIZE_32BIT); dma_set_priority(DMA1, DMA_CHANNEL5, DMA_CCR_PL_HIGH); dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t) &ADC3_DR); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL6); dma_set_peripheral_size(DMA1, DMA_CHANNEL6, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL6, DMA_CCR_MSIZE_16BIT); dma_set_priority(DMA1, DMA_CHANNEL6, DMA_CCR_PL_HIGH); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL5); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL6); }