Exemple #1
0
void
adc_start (void)
{
  uint32_t config[4];

  get_adc_config (config);

  /* Use DMA channel 1.  */
  RCC->AHBENR |= RCC_AHBENR_DMA1EN;
  DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
  DMA1->IFCR = 0xffffffff;

  RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);

  ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
	       | ADC_CR1_SCAN);
  ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
	       | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
  ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
  ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
  ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
  ADC1->SQR2 = 0;
  ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;

  ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
	       | ADC_CR1_SCAN);
  ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
  ADC2->SMPR1 = config[0];
  ADC2->SMPR2 = config[1];
  ADC2->SQR1 = config[2];
  ADC2->SQR2 = 0;
  ADC2->SQR3 = config[3];

#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
  /*
   * We could just let ADC run continuously always and only enable DMA
   * to receive stable data from ADC.  But our purpose is not to get
   * correct data but noise.  In fact, we can get more noise when we
   * start/stop ADC each time.
   */
  ADC2->CR2 = 0;
  ADC1->CR2 = 0;
#else
  /* Start conversion.  */
  ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
  ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
	       | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
#endif
}
Exemple #2
0
static void
get_adc_config (uint32_t config[4])
{
  config[2] = ADC_SQR1_NUM_CH(2);
  switch (SYS_BOARD_ID)
    {
    case BOARD_ID_FST_01:
      config[0] = 0;
      config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
		| ADC_SMPR2_SMP_AN9(ADC_SAMPLE_1P5);
      config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)
		| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN9);
      break;

    case BOARD_ID_OLIMEX_STM32_H103:
    case BOARD_ID_STBEE:
      config[0] = ADC_SMPR1_SMP_AN10(ADC_SAMPLE_1P5)
		| ADC_SMPR1_SMP_AN11(ADC_SAMPLE_1P5);
      config[1] = 0;
      config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN10)
		| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN11);
      break;

    case BOARD_ID_STBEE_MINI:
      config[0] = 0;
      config[1] = ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
		| ADC_SMPR2_SMP_AN2(ADC_SAMPLE_1P5);
      config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN1)
		| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2);
      break;

    case BOARD_ID_CQ_STARM:
    case BOARD_ID_FST_01_00:
    case BOARD_ID_MAPLE_MINI:
    case BOARD_ID_STM32_PRIMER2:
    case BOARD_ID_STM8S_DISCOVERY:
    case BOARD_ID_ST_DONGLE:
    case BOARD_ID_ST_NUCLEO_F103:
    case BOARD_ID_NITROKEY_START:
    default:
      config[0] = 0;
      config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
		| ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5);
      config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)
		| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1);
      break;
    }
}
Exemple #3
0
/**
 * @brief   Starts an ADC conversion.
 *
 * @param[in] adcp      pointer to the @p ADCDriver object
 *
 * @notapi
 */
void adc_lld_start_conversion(ADCDriver *adcp) {
  uint32_t mode;
  uint32_t cr2;
  const ADCConversionGroup *grpp = adcp->grpp;

  /* DMA setup.*/
  mode = adcp->dmamode;
  if (grpp->circular) {
    mode |= STM32_DMA_CR_CIRC;
    if (adcp->depth > 1) {
      /* If circular buffer depth > 1, then the half transfer interrupt
         is enabled in order to allow streaming processing.*/
      mode |= STM32_DMA_CR_HTIE;
    }
  }
  dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
  dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
                                            (uint32_t)adcp->depth);
  dmaStreamSetMode(adcp->dmastp, mode);
  dmaStreamEnable(adcp->dmastp);

  /* ADC setup.*/
  adcp->adc->SR    = 0;
  adcp->adc->SMPR1 = grpp->smpr1;
  adcp->adc->SMPR2 = grpp->smpr2;
  adcp->adc->SQR1  = grpp->sqr1 | ADC_SQR1_NUM_CH(grpp->num_channels);
  adcp->adc->SQR2  = grpp->sqr2;
  adcp->adc->SQR3  = grpp->sqr3;

  /* ADC configuration and start.*/
  adcp->adc->CR1   = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN;

  /* Enforcing the mandatory bits in CR2.*/
  cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON;

  /* The start method is different dependign if HW or SW triggered, the
     start is performed using the method specified in the CR2 configuration.*/
  if ((cr2 & ADC_CR2_SWSTART) != 0) {
    /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/
    adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART;

    /* Finally enabling ADC_CR2_SWSTART.*/
    adcp->adc->CR2 = (cr2 | ADC_CR2_CONT);
  }
  else
    adcp->adc->CR2 = cr2;
}
Exemple #4
0
// From libopencm3
static void adc_regular_sequence(uint32_t *sqr1, uint32_t *sqr2, uint32_t *sqr3, uint8_t length, const uint8_t channel[])
{
  uint32_t first6 = 0;
  uint32_t second6 = 0;
  uint32_t third6 = ADC_SQR1_NUM_CH(length);
  uint8_t i = 0;

  for (i = 1; i <= length; i++) {
    if (i <= 6) {
      first6 |= (channel[i - 1] << ((i - 1) * 5));
    }
    if ((i > 6) & (i <= 12)) {
      second6 |= (channel[i - 1] << ((i - 6 - 1) * 5));
    }
    if ((i > 12) & (i <= 18)) {
      third6 |= (channel[i - 1] << ((i - 12 - 1) * 5));
    }
  }
  *sqr3 = first6;
  *sqr2 = second6;
  *sqr1 = third6;
}
      NULL,
      // error callback
      NULL,

      // Resent fields are stm32 specific. They contain ADC control registers data.
      // Please, refer to ST manual RM0008.pdf to understand what we do.
      // CR1 register content, set to zero for begin
      0,
      // CR2 register content, set to zero for begin
      0,
      // SMRP1 register content, channels 10, 11, 12, 13 to 71.5 cycles
      0xB6D,
      // SMRP2 register content, channels 0, 1, 2, 3 to 71.5 cycles
      0xB6D,
      // SQR1 register content. Set channel sequence length
      ADC_SQR1_NUM_CH(ADC_CH_NUM),
      // SQR2 register content, set to zero for begin
      (ADC_SQR2_SQ7_N(ADC_CHANNEL_IN10) |
       ADC_SQR2_SQ8_N(ADC_CHANNEL_IN11)),
      // SQR3 register content. First 6 channels
      (ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0 ) |
       ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1 ) |
       ADC_SQR3_SQ3_N(ADC_CHANNEL_IN2 ) |
       ADC_SQR3_SQ4_N(ADC_CHANNEL_IN3 ) |
       ADC_SQR3_SQ5_N(ADC_CHANNEL_IN12) |
       ADC_SQR3_SQ6_N(ADC_CHANNEL_IN13)),
};

/*-----------------------------------------------------------------------------*/
/** @brief      Initialize the ADC1 sub system                                 */
/*-----------------------------------------------------------------------------*/
static const ADCConversionGroup adcgrpcfg3 = {
  FALSE, //circular enable
  ADC_ADC3_NUM_CHANNELS, //num_channels
  adccallback, // end_conversion_cb
  adcerrorcallback, //error_cb
  0,                        /* CR1 */ 
  ADC_CR2_SWSTART,          /* CR2 */ 

  ADC_SMPR1_SMP_AN14(ADC_OVERSAMPLING) | ADC_SMPR1_SMP_AN15(ADC_OVERSAMPLING), // SMPR1

  ADC_SMPR2_SMP_AN4(ADC_OVERSAMPLING) | ADC_SMPR2_SMP_AN5(ADC_OVERSAMPLING) | /* SMPR2 */ 
  ADC_SMPR2_SMP_AN6(ADC_OVERSAMPLING) | ADC_SMPR2_SMP_AN7(ADC_OVERSAMPLING) | /* SMPR2 */ 
  ADC_SMPR2_SMP_AN9(ADC_OVERSAMPLING),  /* SMPR2 */ 

  ADC_SQR1_NUM_CH(ADC_ADC3_NUM_CHANNELS), // SQR1

  0,					  //SQR2
  ADC_SQR3_SQ1_N(GPIOF_ADC_CMD_TURRET_CHANNEL) |	//SQR3
  ADC_SQR3_SQ2_N(GPIOF_ADC_CMD_ELBOW_CHANNEL) |		//SQR3
  ADC_SQR3_SQ3_N(GPIOF_ADC_CMD_SHOULDER_CHANNEL)   | 	//SQR3
  ADC_SQR3_SQ4_N(GPIOF_ADC_CMD_WRIST_CHANNEL) | 	//SQR3
  ADC_SQR3_SQ5_N(GPIOF_ADC_CMD_CLAMP_CHANNEL)	        //SQR3
};

#ifndef __COVERITY__
_Static_assert(CMD_TURRET_ADC_IDX == 3, "ADC mismatch");
_Static_assert(CMD_SHOULDER_ADC_IDX == 3, "ADC mismatch");
_Static_assert(CMD_ELBOW_ADC_IDX == 3, "ADC mismatch");
_Static_assert(CMD_WRIST_ADC_IDX == 3, "ADC mismatch");
_Static_assert(CMD_CLAMP_ADC_IDX == 3, "ADC mismatch");
Exemple #7
0
//#define TS_CAL1_TMP     (25.0f)
//#define TS_AVG_SLOPE    (2.5f * (4096 / 3300))


static const ADCConversionGroup core_temp_conv_grp = {
    .circular = FALSE,
    .num_channels = 1,
    .end_cb = NULL,
    .error_cb = NULL,

    /* HW dependent part.*/
    .cr1   = 0, // 12-bit resolution
    .cr2   = ADC_CR2_SWSTART, // software triggered
    .smpr1 = ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_480),
    .smpr2 = 0,
    .sqr1  = ADC_SQR1_NUM_CH(1),
    .sqr2  = 0,
    .sqr3  = ADC_SQR3_SQ1_N(ADC_CHANNEL_SENSOR),
};


/**
 * @brief   PAL setup.
 * @details Digital I/O ports static configuration as defined in @p board.h.
 *          This variable is used by the HAL when initializing the PAL driver.
 */
#if HAL_USE_PAL || defined(__DOXYGEN__)
const PALConfig pal_default_config =
{
  {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH},
  {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH},
Exemple #8
0
void AdcDevice::init(void) {
	hwConfig->num_channels = size();
	hwConfig->sqr1 += ADC_SQR1_NUM_CH(size());
}
Exemple #9
0
}

/*
 * ADC conversion group.
 * Mode:        Linear buffer, 8 samples of 1 channel, SW triggered.
 * Channels:    IN10.
 */
static const ADCConversionGroup adcgrpcfg1 = {
  FALSE,
  ADC_GRP1_NUM_CHANNELS,
  NULL,
  adcerrorcallback,
  0, 0,                         /* CR1, CR2 */
  ADC_SMPR1_SMP_AN10(ADC_SAMPLE_1P5),
  0,                            /* SMPR2 */
  ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),
  0,                            /* SQR2 */
  ADC_SQR3_SQ1_N(ADC_CHANNEL_IN10)
};

/*
 * ADC conversion group.
 * Mode:        Continuous, 16 samples of 8 channels, SW triggered.
 * Channels:    IN10, IN11, IN10, IN11, IN10, IN11, Sensor, VRef.
 */
static const ADCConversionGroup adcgrpcfg2 = {
  TRUE,
  ADC_GRP2_NUM_CHANNELS,
  adccallback,
  adcerrorcallback,
  0, ADC_CR2_TSVREFE,           /* CR1, CR2 */
//The ADC2 configuration for the pressure monitoring
/*
 * ADC conversion group.
 * Mode:        Linear buffer, 1 sample of 1 channel, SW triggered.
 * Channels:    IN11.
 */
static const ADCConversionGroup adcgrpcfg1 = {
  FALSE,
  PRESSURE_ADC_NUM_CHANNELS,
  NULL,
  adcerrorcallback,
  0,                        /* CR1 */
  ADC_CR2_SWSTART,          /* CR2 */
  ADC_SMPR1_SMP_AN14(ADC_SAMPLE_480),
  0,                        /* SMPR2 */
  ADC_SQR1_NUM_CH(PRESSURE_ADC_NUM_CHANNELS),
  0,                        /* SQR2 */
  ADC_SQR3_SQ1_N(ADC_PRESSURE_CHANNEL)
};

//The PWM configuration for the solenoid control
static PWMConfig PWM_Config_Solenoid = {
  1000000,                                  			/* 1MHz PWM clock frequency. */
  250,                                  			/* Initial PWM period 4KHz. */
  NULL,								/* No cyclic callback */
  {
   {PWM_OUTPUT_ACTIVE_HIGH, NULL},				/* Have to define the channel to enable here - channel 1=solenoid*/
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL}
  },
Exemple #11
0
/*
 * ADC conversion group.
 * Mode:        Linear buffer, 1 sample of 1 channel, SW triggered.
 * Channels:    IN1.
 */
static const ADCConversionGroup adcZeroSense = {
  FALSE,
  1,
  &cbAdcZeroSense,
  NULL,
  0,                        /* CR1 */
  ADC_CR2_SWSTART,          /* CR2 */
  0,
  ADC_SMPR2_SMP_AN1(ADC_SAMPLE_15),                        /* SMPR2 */
  ADC_SQR1_NUM_CH(1),
  0,                        /* SQR2 */
  ADC_SQR3_SQ1_N(ADC_CHANNEL_IN1)
};


/*
 * PWM Scheme:  High PWM, Lo ON
 * Time0 Time1
 */
static uint8_t pwmScheme[6][3] = {{PWM_UP|PWM_VN, PWM_VN, !PWM_EXPECT_ZERO},    //UP PWM, VN ON
                                  {PWM_UP|PWM_WN, PWM_WN, PWM_EXPECT_ZERO},     //UP PWM, WN ON
                                  {PWM_VP|PWM_WN, PWM_WN, !PWM_EXPECT_ZERO},    //VP PWM, WN ON
                                  {PWM_VP|PWM_UN, PWM_UN, PWM_EXPECT_ZERO},     //VP PWM, UN ON
                                  {PWM_WP|PWM_UN, PWM_UN, !PWM_EXPECT_ZERO},    //WP PWM, UN ON
                                  {PWM_WP|PWM_VN, PWM_VN, PWM_EXPECT_ZERO}      //WP PWM, VN ON
Exemple #12
0
     0                  // DIER
};

/* Instrument conversion group */
static const ADCConversionGroup adc_con_group_1 = {
    TRUE, /* circular mode */
    1, /* number of channels in this con_group */
    adc_inst_callback,
    adc_error_callback,
    0, /* ADC_CR1 */
    /* cr2: Clock the ADC to timer 8 TRGO event*/
    ADC_CR2_EXTSEL_SRC(14) | ADC_CR2_EXTEN_0,
    /* smpr1+2: set all channels to 40 cycles per conversion (28+12) */
    ADC_SMPR1_SMP_AN11(2)| ADC_SMPR1_SMP_AN12(2)| ADC_SMPR1_SMP_AN13(2),
    ADC_SMPR2_SMP_AN0(2) | ADC_SMPR2_SMP_AN1(2) | ADC_SMPR2_SMP_AN2(2),
    ADC_SQR1_NUM_CH(1), /* sqr1: set 1 channel in the group */
    0, /* sqr2: no higher channels being sampled */
    /* sqr3: set the two channels to sample */
    ADC_SQR3_SQ1_N(INST_IN_CHN)
};

/* FX inputs conversion group */
static const ADCConversionGroup adc_con_group_2 = {
    TRUE, /* circular mode */
    3, /* number of channels in this con group */
    adc_fx_callback,
    adc_error_callback,
    0, /* cr1 */
    /* cr2: Clock the ADC to timer 3 TRGO event*/
    ADC_CR2_EXTSEL_SRC(8) | ADC_CR2_EXTEN_0,
    /* smpr1+2: set all channels to 40 cycles per conversion (28+12) */
Exemple #13
0
 * ADC conversion group.
 * Mode:     Continuous, circular, 32 samples of 2 channels.
 * Channels: IN12, IN13.
 */
static const ADCConversionGroup adcgrpcfg = {
  TRUE,                 /* Circular buffer mode enabled.    */
  ADC_GRP_NUM_CHANNELS, /* Number of channels in the group. */
  adccb,                /* Callback function of the group.  */
  NULL,                 /* Error callback function.         */
  /* STM32F1xx dependent part: */
  0,                                      /* CR1.   */
  0,                                      /* CR2.   */
  ADC_SMPR1_SMP_AN12(ADC_SAMPLE_239P5) |
  ADC_SMPR1_SMP_AN13(ADC_SAMPLE_239P5),   /* SMPR1. */
  0,                                      /* SMPR2. */
  ADC_SQR1_NUM_CH(ADC_GRP_NUM_CHANNELS),  /* SQR1.  */
  0,                                      /* SQR2.  */
  ADC_SQR3_SQ2_N(ADC_CHANNEL_IN13) |
  ADC_SQR3_SQ1_N(ADC_CHANNEL_IN12)        /* SQR3.  */
};

/**
 * Input capture configuration for ICU2 driver.
 *
 * @note ICU drivers used in the firmware are modified ChibiOS
 *       drivers for extended input capture functionality.
 */
static const ICUConfig icucfg2 = {
  ICU_INPUT_TYPE_PWM,       /* Driver input type (EDGE, PULSE, PWM).  */
  1000000,                  /* 1MHz ICU clock frequency.              */
  {                         /* ICU channel configuration.             */
#include "m3pyro_continuity.h"
#include "m3pyro_status.h"

static const ADCConversionGroup adc_grp = {
    .circular = false,
    .num_channels = 5,
    .end_cb = NULL,
    .error_cb = NULL,
    .cr1 = 0,
    .cr2 = ADC_CR2_SWSTART,
    .smpr1 = ADC_SMPR1_SMP_AN11(ADC_SAMPLE_480) |
             ADC_SMPR1_SMP_AN13(ADC_SAMPLE_480),
    .smpr2 = ADC_SMPR2_SMP_AN1(ADC_SAMPLE_480) |
             ADC_SMPR2_SMP_AN2(ADC_SAMPLE_480) |
             ADC_SMPR2_SMP_AN8(ADC_SAMPLE_480),
    .sqr1 = ADC_SQR1_NUM_CH(5),
    .sqr2 = 0,
    .sqr3 = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN2)  |
            ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)  |
            ADC_SQR3_SQ3_N(ADC_CHANNEL_IN11) |
            ADC_SQR3_SQ4_N(ADC_CHANNEL_IN13) |
            ADC_SQR3_SQ5_N(ADC_CHANNEL_IN8),
};

/* 12bit ADC reading of PYRO_CONTINUITY into 2ohm/LSB uint8t */
static uint8_t adc_to_resistance(adcsample_t reading) {
    float r = 0.5 * (1000.0f * (float)reading) / (4096.0f - (float)reading);
    if(r >= 255.0f) {
        return 255;
    } else {
        return (uint8_t)r;
Exemple #15
0
/*
 * ADC conversion group.
 * Mode:        Continuous, 16 samples of 2 channels, HS triggered by
 *              GPT4-TRGO.
 * Channels:    Sensor, VRef.
 */
static const ADCConversionGroup adcgrpcfg1 = {
    true,
    ADC_GRP1_NUM_CHANNELS,
    adccallback,
    adcerrorcallback,
    0,                                                    /* CR1 */
    ADC_CR2_EXTEN_RISING | ADC_CR2_EXTSEL_SRC(12),        /* CR2 */
    ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_144) | ADC_SMPR1_SMP_VREF(ADC_SAMPLE_144),
    0,                                                    /* SMPR2 */
    ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),               /* SQR1 */
    0,                                                    /* SQR1 */
    ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR) | ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT)
};

/*===========================================================================*/
/* Application code.                                                         */
/*===========================================================================*/

/*
 * This is a periodic thread that does absolutely nothing except flashing
 * a LED attached to TP1.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
Exemple #16
0
/**
 * @brief   Starts an ADC conversion.
 *
 * @param[in] adcp      pointer to the @p ADCDriver object
 *
 * @notapi
 */
void adc_lld_start_conversion(ADCDriver *adcp) {
  uint32_t dmamode, ccr, cfgr;
  const ADCConversionGroup *grpp = adcp->grpp;

  osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0),
                "odd number of channels in dual mode");

  /* Calculating control registers values.*/
  dmamode = adcp->dmamode;
  ccr     = grpp->ccr | (adcp->adcc->CCR & (ADC_CCR_CKMODE_MASK |
                                            ADC_CCR_MDMA_MASK));
  cfgr    = grpp->cfgr | ADC_CFGR_DMAEN;
  if (grpp->circular) {
    dmamode |= STM32_DMA_CR_CIRC;
#if STM32_ADC_DUAL_MODE
    ccr  |= ADC_CCR_DMACFG_CIRCULAR;
#else
    cfgr |= ADC_CFGR_DMACFG_CIRCULAR;
#endif
    if (adcp->depth > 1) {
      /* If circular buffer depth > 1, then the half transfer interrupt
         is enabled in order to allow streaming processing.*/
      dmamode |= STM32_DMA_CR_HTIE;
    }
  }

  /* DMA setup.*/
  dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
#if STM32_ADC_DUAL_MODE
  dmaStreamSetTransactionSize(adcp->dmastp, ((uint32_t)grpp->num_channels/2) *
                                            (uint32_t)adcp->depth);
#else
    dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
                                              (uint32_t)adcp->depth);
#endif
  dmaStreamSetMode(adcp->dmastp, dmamode);
  dmaStreamEnable(adcp->dmastp);

  /* Configuring the CCR register with the static settings ORed with
     the user-specified settings in the conversion group configuration
     structure.*/
  adcp->adcc->CCR   = ccr;

  /* ADC setup, if it is defined a callback for the analog watch dog then it
     is enabled.*/
  adcp->adcm->ISR   = adcp->adcm->ISR;
  adcp->adcm->IER   = ADC_IER_OVR | ADC_IER_AWD1;
  adcp->adcm->TR1   = grpp->tr1;
#if STM32_ADC_DUAL_MODE
  adcp->adcm->SMPR1 = grpp->smpr[0];
  adcp->adcm->SMPR2 = grpp->smpr[1];
  adcp->adcm->SQR1  = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
  adcp->adcm->SQR2  = grpp->sqr[1];
  adcp->adcm->SQR3  = grpp->sqr[2];
  adcp->adcm->SQR4  = grpp->sqr[3];
  adcp->adcs->SMPR1 = grpp->ssmpr[0];
  adcp->adcs->SMPR2 = grpp->ssmpr[1];
  adcp->adcs->SQR1  = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
  adcp->adcs->SQR2  = grpp->ssqr[1];
  adcp->adcs->SQR3  = grpp->ssqr[2];
  adcp->adcs->SQR4  = grpp->ssqr[3];

#else /* !STM32_ADC_DUAL_MODE */
  adcp->adcm->SMPR1 = grpp->smpr[0];
  adcp->adcm->SMPR2 = grpp->smpr[1];
  adcp->adcm->SQR1  = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels);
  adcp->adcm->SQR2  = grpp->sqr[1];
  adcp->adcm->SQR3  = grpp->sqr[2];
  adcp->adcm->SQR4  = grpp->sqr[3];
#endif /* !STM32_ADC_DUAL_MODE */

  /* ADC configuration.*/
  adcp->adcm->CFGR  = cfgr;

  /* Starting conversion.*/
  adcp->adcm->CR   |= ADC_CR_ADSTART;
}
Exemple #17
0
		ADC_SMPR1_SMP_AN11(MY_SAMPLING_SLOW) |
		ADC_SMPR1_SMP_AN12(MY_SAMPLING_SLOW) |
		ADC_SMPR1_SMP_AN13(MY_SAMPLING_SLOW), // sample times for channels 10...18
		ADC_SMPR2_SMP_AN0(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN1(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN3(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN4(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN5(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN6(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN7(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN8(MY_SAMPLING_SLOW) |
		ADC_SMPR2_SMP_AN9(MY_SAMPLING_SLOW)

		, // In this field must be specified the sample times for channels 0...9

		ADC_SQR1_NUM_CH(EFI_ADC_SLOW_CHANNELS_COUNT), // Conversion group sequence 13...16 + sequence length

		0
//		| ADC_SQR2_SQ7_N(ADC_CHANNEL_IN12) /* PC2 - green */
//				| ADC_SQR2_SQ8_N(ADC_CHANNEL_IN13) /* PC3 - yellow maf? */

		,// Conversion group sequence 7...12
		0
//		| ADC_SQR3_SQ1_N(ADC_CHANNEL_IN6) /* PA6 - white */
//		| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN7) /* PA7 - blue */
//				| ADC_SQR3_SQ3_N(ADC_CHANNEL_IN14) /* PC4 - green */
//				| ADC_SQR3_SQ4_N(ADC_CHANNEL_IN15) /* PC5 - yellow */
//				| ADC_SQR3_SQ5_N(ADC_CHANNEL_IN8) /* PB0 - blue */
//				| ADC_SQR3_SQ6_N(ADC_CHANNEL_IN9) /* PB1 - white */
// Conversion group sequence 1...6
		};
/**
 * @brief   Starts an ADC conversion.
 *
 * @param[in] adcp      pointer to the @p ADCDriver object
 *
 * @notapi
 */
void adc_lld_start_conversion(ADCDriver *adcp) {
  uint32_t mode;
  const ADCConversionGroup* grpp = adcp->grpp;

  /* DMA setup.*/
  mode = adcp->dmamode;
  if (grpp->circular) {
    mode |= STM32_DMA_CR_CIRC;
    if (adcp->depth > 1) {
      /* If circular buffer depth > 1, then the half transfer interrupt
         is enabled in order to allow streaming processing.*/
      mode |= STM32_DMA_CR_HTIE;
    }
  }
  dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
  dmaStreamSetTransactionSize(adcp->dmastp,
			      (uint32_t)grpp->num_channels * 
			      (uint32_t)adcp->depth);
  dmaStreamSetMode(adcp->dmastp, mode);
  dmaStreamEnable(adcp->dmastp);

#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
  if (adcp->adc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC
  {
    uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
    cr2 |= grpp->u.adc.cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
    if ((cr2 & ADC_CR2_SWSTART) != 0)
      cr2 |= ADC_CR2_CONT;
    adcp->adc->CR2   = cr2;

    /* ADC setup.*/
    adcp->adc->SR    = 0;
    adcp->adc->LTR   = grpp->u.adc.ltr;
    adcp->adc->HTR   = grpp->u.adc.htr;
    adcp->adc->SMPR1 = grpp->u.adc.smpr[0];
    adcp->adc->SMPR2 = grpp->u.adc.smpr[1];
    adcp->adc->SQR1  = grpp->u.adc.sqr[0] |
                       ADC_SQR1_NUM_CH(grpp->num_channels);
    adcp->adc->SQR2  = grpp->u.adc.sqr[1];
    adcp->adc->SQR3  = grpp->u.adc.sqr[2];

    /* ADC conversion start, the start is performed using the method
       specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/
    adcp->adc->CR1   = grpp->u.adc.cr1 | ADC_CR1_AWDIE | ADC_CR1_SCAN;
    adcp->adc->CR2   = adcp->adc->CR2;  /* Triggers the conversion start.*/
  }
#endif /* STM32_ADC_USE_ADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
  else if (adcp->sdadc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_SDADC
  {
    uint32_t cr2 = (grpp->u.sdadc.cr2 & ~SDADC_FORBIDDEN_CR2_FLAGS) |
                   SDADC_CR2_ADON;
    if ((grpp->u.sdadc.cr2 & SDADC_CR2_JSWSTART) != 0)
      cr2 |= SDADC_CR2_JCONT;

    /* Entering initialization mode.*/
    adcp->sdadc->CR1 |= SDADC_CR1_INIT;
    while ((adcp->sdadc->ISR & SDADC_ISR_INITRDY) == 0)
      ;

    /* SDADC setup.*/
    adcp->sdadc->JCHGR    = grpp->u.sdadc.jchgr;
    adcp->sdadc->CONFCHR1 = grpp->u.sdadc.confchr[0];
    adcp->sdadc->CONFCHR2 = grpp->u.sdadc.confchr[1];

    /* SDADC trigger modes, this write must be performed when
       SDADC_CR1_INIT=1.*/
    adcp->sdadc->CR2 = cr2;

    /* Leaving initialization mode.*/
    adcp->sdadc->CR1 &= ~SDADC_CR1_INIT;

    /* Special case, if SDADC_CR2_JSWSTART is specified it has to be
       written after SDADC_CR1_INIT has been set to zero. Just a write is
       performed, any other bit is ingore if not in initialization mode.*/
    adcp->sdadc->CR2 = cr2;
  }
#endif /* STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
  else {
    chDbgAssert(FALSE, "adc_lld_start_conversion(), #1", "invalid state");
  }
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
}
Exemple #19
0
static const ADCConversionGroup adcgrpcfg1 = {FALSE,      //circular buffer mode
    ADC_GRP1_NUM_CHANNELS,        //Number of the analog channels
    NULL,                         //Callback function (not needed here)
    0,             //Error callback
    0, /* CR1 */
    ADC_CR2_SWSTART, /* CR2 */
    ADC_SMPR1_SMP_AN10(ADC_SAMPLE_84) | ADC_SMPR1_SMP_AN11(ADC_SAMPLE_84)
        | ADC_SMPR1_SMP_AN12(ADC_SAMPLE_84) | ADC_SMPR1_SMP_AN13(ADC_SAMPLE_84)
        | ADC_SMPR1_SMP_AN14(ADC_SAMPLE_84) | ADC_SMPR1_SMP_AN15(ADC_SAMPLE_84), //sample times ch10-18
    ADC_SMPR2_SMP_AN0(ADC_SAMPLE_84) | ADC_SMPR2_SMP_AN1(ADC_SAMPLE_84)
        | ADC_SMPR2_SMP_AN2(ADC_SAMPLE_84) | ADC_SMPR2_SMP_AN3(ADC_SAMPLE_84)
        | ADC_SMPR2_SMP_AN4(ADC_SAMPLE_84) | ADC_SMPR2_SMP_AN5(ADC_SAMPLE_84)
        | ADC_SMPR2_SMP_AN6(ADC_SAMPLE_84) | ADC_SMPR2_SMP_AN7(ADC_SAMPLE_84)
        | ADC_SMPR2_SMP_AN8(ADC_SAMPLE_84) | ADC_SMPR2_SMP_AN9(ADC_SAMPLE_84), //sample times ch0-9
    ADC_SQR1_SQ13_N(ADC_CHANNEL_IN12) | ADC_SQR1_SQ14_N(ADC_CHANNEL_IN13)
        | ADC_SQR1_SQ15_N(ADC_CHANNEL_IN14) | ADC_SQR1_SQ16_N(ADC_CHANNEL_IN15)
        | ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS), //SQR1: Conversion group sequence 13...16 + sequence length
    ADC_SQR2_SQ7_N(ADC_CHANNEL_IN6) | ADC_SQR2_SQ8_N(ADC_CHANNEL_IN7)
        | ADC_SQR2_SQ9_N(ADC_CHANNEL_IN8) | ADC_SQR2_SQ10_N(ADC_CHANNEL_IN9)
        | ADC_SQR2_SQ11_N(ADC_CHANNEL_IN10) | ADC_SQR2_SQ12_N(ADC_CHANNEL_IN11), //SQR2: Conversion group sequence 7...12
    ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
        | ADC_SQR3_SQ3_N(ADC_CHANNEL_IN2) | ADC_SQR3_SQ4_N(ADC_CHANNEL_IN3)
        | ADC_SQR3_SQ5_N(ADC_CHANNEL_IN4) | ADC_SQR3_SQ6_N(ADC_CHANNEL_IN5) //SQR3: Conversion group sequence 1...6
};

void adc_convert(void) {
  adcStopConversion(&ADCD1);
  adcStartConversion(&ADCD1, &adcgrpcfg1, adcvalues, ADC_GRP1_BUF_DEPTH);
}

Exemple #20
0
 */
static const ADCConversionGroup adccg = {
  TRUE,
  ADC_NUM_CHANNELS,
  adccallback,
  adcerrorcallback,
  0,                        /* CR1 */
  ADC_CR2_SWSTART,          /* CR2 */
  ADC_SMPR1_SMP_AN10(ADC_SAMPLE_480) |
  ADC_SMPR1_SMP_AN11(ADC_SAMPLE_480) |
  ADC_SMPR1_SMP_AN12(ADC_SAMPLE_480) |
  ADC_SMPR1_SMP_AN13(ADC_SAMPLE_480) |
  ADC_SMPR1_SMP_AN14(ADC_SAMPLE_480) |
  ADC_SMPR1_SMP_AN15(ADC_SAMPLE_480),
  0,                        /* SMPR2 */
  ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
  0,
  (ADC_SQR3_SQ6_N(ADC_AN33_2)         | ADC_SQR3_SQ5_N(ADC_AN33_1) |
      ADC_SQR3_SQ4_N(ADC_AN33_0)      | ADC_SQR3_SQ3_N(ADC_6V_SUPPLY) |
      ADC_SQR3_SQ2_N(ADC_MAIN_SUPPLY) | ADC_SQR3_SQ1_N(ADC_CURRENT_SENS))
};

/*
 *******************************************************************************
 *******************************************************************************
 * LOCAL FUNCTIONS
 *******************************************************************************
 *******************************************************************************
 */

/* пересчет из условных единиц АЦП в mV */
namespace r2p {

/*===========================================================================*/
/* Motor calibration.                                                        */
/*===========================================================================*/

static int pwm = 0;

#define ADC_NUM_CHANNELS  1
#define ADC_BUF_DEPTH     1

static float meanLevel = 0.0f;

static adcsample_t adc_samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];

static void current_callback(ADCDriver *adcp, adcsample_t *buffer, size_t n);

/*
 * ADC conversion group.
 * Mode:        Circular buffer, 1 sample of 1 channel, triggered by pwm channel 3
 * Channels:    IN10.
 */
static const ADCConversionGroup adcgrpcfg = { TRUE, // circular
		ADC_NUM_CHANNELS, // num channels
		current_callback, // end callback
		NULL, // error callback
		0, // CR1
		ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL_1, // CR2
		0, // SMPR1
		ADC_SMPR2_SMP_AN3(ADC_SAMPLE_1P5)/*ADC_SMPR2_SMP_AN3(ADC_SAMPLE_239P5)*/, // SMPR2
		ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS), // SQR1
		0, // SQR2
		ADC_SQR3_SQ1_N(ADC_CHANNEL_IN3) // SQR3
		};

static void current_callback(ADCDriver *adcp, adcsample_t *buffer, size_t n) {

	(void) adcp;
	(void) n;

	palTogglePad(LED2_GPIO, LED2);

	chSysLockFromIsr()
	;

	meanLevel = buffer[0];

	if (tp_motor != NULL) {
		chSchReadyI(tp_motor);
		tp_motor = NULL;
	}

	chSysUnlockFromIsr();

}


static PWMConfig pwmcfg = { STM32_SYSCLK, // 72MHz PWM clock frequency.
		4096, // 12-bit PWM, 17KHz frequency.
		NULL, // pwm callback
		{
				{ PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH, NULL }, //
				{ PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH, NULL }, //
				{ PWM_OUTPUT_ACTIVE_LOW, NULL }, //
				{ PWM_OUTPUT_DISABLED, NULL } }, //
				0, //
#if STM32_PWM_USE_ADVANCED
		72, /* XXX 1uS deadtime insertion   */
#endif
		0 };

static calibration_pub_node_conf defaultPubConf = { "motor_calibration_node",
		"bits" };

msg_t motor_calibration_node(void * arg) {
	//Configure current node
	calibration_pub_node_conf* conf;
	if (arg != NULL)
		conf = (calibration_pub_node_conf *) arg;
	else
		conf = &defaultPubConf;

	Node node(conf->name);
	Publisher<FloatMsg> current_pub;
	FloatMsg * msgp;

	chRegSetThreadName(conf->name);

	node.advertise(current_pub, conf->topic);

	// Start the ADC driver and conversion
	adcStart(&ADC_DRIVER, NULL);
	adcStartConversion(&ADC_DRIVER, &adcgrpcfg, adc_samples, ADC_BUF_DEPTH);

	// Init motor driver
	palSetPad(DRIVER_GPIO, DRIVER_RESET);
	chThdSleepMilliseconds(500);
	pwmStart(&PWM_DRIVER, &pwmcfg);

	// wait some time
	chThdSleepMilliseconds(500);

	// start pwm
	float voltage = 24.0;

	const float pwm_res = 4096.0f / 24.0f;
	pwm = static_cast<int>(voltage * pwm_res);

	if (pwm > 0) {
		pwm_lld_enable_channel(&PWM_DRIVER, 1, pwm);
		pwm_lld_enable_channel(&PWM_DRIVER, 0, 0);

		pwm_lld_enable_channel(&PWM_DRIVER, 2, pwm/2);
	} else {
		pwm_lld_enable_channel(&PWM_DRIVER, 1, 0);
		pwm_lld_enable_channel(&PWM_DRIVER, 0, -pwm);

		pwm_lld_enable_channel(&PWM_DRIVER, 2, -pwm/2);
	}

	// Start publishing current measures
	for (;;) {
		// Wait for interrupt
		chSysLock()
		;
		tp_motor = chThdSelf();
		chSchGoSleepS(THD_STATE_SUSPENDED);
		chSysUnlock();

		// publish current
		if (current_pub.alloc(msgp)) {
			msgp->value = meanLevel;
			current_pub.publish(*msgp);
		}

	}

	return CH_SUCCESS;
}

}