Пример #1
0
/*
    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
Пример #2
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