示例#1
0
/**
 * 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
示例#2
0
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