/* 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(ADC_TypeDef * adc_t, uint8_t chan1, uint8_t chan2, uint8_t chan3, uint8_t chan4) { GPIO_InitTypeDef gpio; ADC_InitTypeDef adc; uint8_t num_channels, rank; // Paranoia, must be down for 2+ ADC clock cycles before calibration ADC_Cmd(adc_t, DISABLE); /* enable adc_t clock */ if (adc_t == ADC1) { #ifdef USE_AD1 num_channels = NB_ADC1_CHANNELS; ADC1_GPIO_INIT(gpio); #endif } else if (adc_t == ADC2) { #ifdef USE_AD2 num_channels = NB_ADC2_CHANNELS; ADC2_GPIO_INIT(gpio); #endif } /* Configure ADC */ adc.ADC_Mode = ADC_Mode_Independent; adc.ADC_ScanConvMode = ENABLE; adc.ADC_ContinuousConvMode = DISABLE; adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; adc.ADC_DataAlign = ADC_DataAlign_Right; adc.ADC_NbrOfChannel = 0; // No. of channels in regular mode ADC_Init(adc_t, &adc); ADC_InjectedSequencerLengthConfig(adc_t, num_channels); rank = 1; if (chan1) { ADC_InjectedChannelConfig(adc_t, adc_channel_map[0], rank, ADC_SampleTime_41Cycles5); rank++; } if (chan2) { ADC_InjectedChannelConfig(adc_t, adc_channel_map[1], rank, ADC_SampleTime_41Cycles5); rank++; } if (chan3) { ADC_InjectedChannelConfig(adc_t, adc_channel_map[2], rank, ADC_SampleTime_41Cycles5); rank++; } if (chan4) { ADC_InjectedChannelConfig(adc_t, adc_channel_map[3], rank, ADC_SampleTime_41Cycles5); } ADC_ExternalTrigInjectedConvCmd(adc_t, ENABLE); #if defined(USE_AD_TIM4) ADC_ExternalTrigInjectedConvConfig(adc_t, ADC_ExternalTrigInjecConv_T4_TRGO); #elif defined(USE_AD_TIM1) ADC_ExternalTrigInjectedConvConfig(adc_t, ADC_ExternalTrigInjecConv_T1_TRGO); #else ADC_ExternalTrigInjectedConvConfig(adc_t, ADC_ExternalTrigInjecConv_T2_TRGO); #endif /* Enable ADC<X> JEOC interrupt */ ADC_ITConfig(adc_t, ADC_IT_JEOC, ENABLE); /* Enable ADC<X> */ ADC_Cmd(adc_t, ENABLE); /* Enable ADC<X> reset calibaration register */ ADC_ResetCalibration(adc_t); /* Check the end of ADC<X> reset calibration */ while (ADC_GetResetCalibrationStatus(adc_t)) ; /* Start ADC<X> calibaration */ ADC_StartCalibration(adc_t); /* Check the end of ADC<X> calibration */ while (ADC_GetCalibrationStatus(adc_t)) ; } // adc_init_single
/** * 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