예제 #1
0
void configure_adc_temp(void)
{
	struct adc_config conf_adc;
	
	adc_get_config_defaults(&conf_adc);
	
	conf_adc.clock_source = GCLK_GENERATOR_1;
	conf_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV16;
	conf_adc.reference = ADC_REFERENCE_INT1V;
	conf_adc.positive_input = ADC_POSITIVE_INPUT_TEMP;
	conf_adc.negative_input = ADC_NEGATIVE_INPUT_GND;
	conf_adc.sample_length = ADC_TEMP_SAMPLE_LENGTH;
	
	adc_init(&adc_instance, ADC, &conf_adc);
	
	ADC->AVGCTRL.reg = ADC_AVGCTRL_ADJRES(2) | ADC_AVGCTRL_SAMPLENUM_4;
	
	adc_enable(&adc_instance);
}
예제 #2
0
/*=== internal functions =========================================================================*/
static void samr21_adc_init(sensor_type_t sensor)
{
    uint8_t refsel1, refsel2;

    refsel1 = ADC->REFCTRL.bit.REFSEL;
    // generic Clock selection ID.. 0x1E = GCLK_ADC (page103 - Datasheet)
    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_ADC | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_CLKEN;
    while (GCLK->STATUS.bit.SYNCBUSY);

     //Power Manager - enable ADC (Page 122 - Datasheet)
    PM->APBCMASK.reg |= PM_APBCMASK_ADC;

    ADC->CTRLA.reg = ADC_CTRLA_ENABLE;
    WAIT_ADC_SYNC();

    switch (sensor)
    {
        case TEMPERATURE:
            // 1 Volt Reference for Temperature Measurement
            ADC->REFCTRL.reg = ADC_REFCTRL_REFSEL_INT1V;
            // sync-asynchronicity of CLK_ADC_APB and GLK_ADC=>some registers need sync
            WAIT_ADC_SYNC();
            // case  Temperature-measurement - select Temp-sensor-Inputs
            ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND | ADC_INPUTCTRL_MUXPOS_TEMP;
            WAIT_ADC_SYNC();
            // Temperature Sensor Output in VREF-Register enable
            SYSCTRL->VREF.reg = (SYSCTRL->VREF.reg & ~0x03) | SYSCTRL_VREF_TSEN;
            WAIT_ADC_SYNC();
            break;
#if BOARD==SAMR21_XPLAINED_PRO
        case IO_SUPPLY:
            ADC->REFCTRL.reg = ADC_REFCTRL_REFSEL_INT1V;
            WAIT_ADC_SYNC();
            ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND | ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC;
            WAIT_ADC_SYNC();
            SYSCTRL->VREF.bit.BGOUTEN = 0;
            SYSCTRL->VREF.bit.TSEN = 0;
            WAIT_ADC_SYNC();
            break;

        case ANALOG_PIN:
            PORT->Group[0].DIRCLR.reg = PORT_PA07;
            PORT->Group[0].PINCFG[7].reg |= PORT_PINCFG_PMUXEN;
            PORT->Group[0].PMUX[7 / 2].bit.PMUXO |= PORT_PMUX_PMUXO_B_Val;
            ADC->REFCTRL.reg = ADC_REFCTRL_REFSEL_INTVCC1;
            WAIT_ADC_SYNC();
            ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_IOGND | ADC_INPUTCTRL_MUXPOS_PIN7;
            WAIT_ADC_SYNC();
            SYSCTRL->VREF.bit.BGOUTEN = 1;
            SYSCTRL->VREF.bit.TSEN = 0;
            break;
#endif
        default:
            /* Invalid sensor value */
            return;
    }

    // Pre scaler & Resolution Selection (8MHz / 8 = 1Mhz used at page 1071 for temp. meas.)
    ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV8 | ADC_CTRLB_RESSEL_12BIT;

    // adjusting Result + Average Control 1...1024 samples possible
    ADC->AVGCTRL.reg = ADC_AVGCTRL_ADJRES(4) | ADC_AVGCTRL_SAMPLENUM_32;
    WAIT_ADC_SYNC();

    // sampling Time length Control
    ADC->SAMPCTRL.reg = ADC_SAMPCTRL_SAMPLEN(4);
    WAIT_ADC_SYNC();

    // calibration values
    uint32_t lin0 = (*((uint32_t *)ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
    uint32_t lin1 = (*((uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos;
    uint32_t bias = (*((uint32_t *)ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos;
    ADC->CALIB.bit.LINEARITY_CAL = (lin1 << 5) | lin0;
    ADC->CALIB.bit.BIAS_CAL = bias;

    refsel2 = ADC->REFCTRL.bit.REFSEL;

    if (refsel1 != refsel2)
    {
        /*
         * refer to datasheet:
         *  30.6.2 Basic Operation
         *  30.6.2.1 Initialization
         *  Before enabling the ADC, the asynchronous clock source must be selected and enabled, and
         *  the ADC reference must be configured. The first conversion after the reference is changed
         * must not be used.
         */
        adc_get_value();
    }
}
예제 #3
0
/*
 * Arduino Zero board initialization
 *
 * Good to know:
 *   - At reset, ResetHandler did the system clock configuration. Core is running at 48MHz.
 *   - Watchdog is disabled by default, unless someone plays with NVM User page
 *   - During reset, all PORT lines are configured as inputs with input buffers, output buffers and pull disabled.
 */
void init( void )
{
  uint32_t ul ;

  // Set Systick to 1ms interval, common to all Cortex-M variants
  if ( SysTick_Config( SystemCoreClock / 1000 ) )
  {
    // Capture error
    while ( 1 ) ;
  }

  // Clock PORT for Digital I/O
//  PM->APBBMASK.reg |= PM_APBBMASK_PORT ;
//
//  // Clock EIC for I/O interrupts
//  PM->APBAMASK.reg |= PM_APBAMASK_EIC ;

  // Clock SERCOM for Serial
  PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ;

  // Clock TC/TCC for Pulse and Analog
  PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 ;

  // Clock ADC/DAC for Analog
  PM->APBCMASK.reg |= PM_APBCMASK_ADC ;//| PM_APBCMASK_DAC ;

  // Setup all pins (digital and analog) in INPUT mode (default is nothing)
  for ( ul = 0 ; ul < NUM_DIGITAL_PINS ; ul++ )
  {
    pinMode( ul, INPUT ) ;
  }

  // Initialize Analog Controller
  // Setting clock
  while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_ADC ) | // Generic Clock ADC
                      GCLK_CLKCTRL_GEN_GCLK0     | // Generic Clock Generator 0 is source
                      GCLK_CLKCTRL_CLKEN ;

  while( ADC->STATUS.bit.SYNCBUSY == 1 );          // Wait for synchronization of registers between the clock domains

  ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV512 |    // Divide Clock by 512.
                   ADC_CTRLB_RESSEL_10BIT;         // 10 bits resolution as default

  ADC->SAMPCTRL.reg = 0x3f;                        // Set max Sampling Time Length

  while( ADC->STATUS.bit.SYNCBUSY == 1 );          // Wait for synchronization of registers between the clock domains

  ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND;   // No Negative input (Internal Ground)

  // Averaging (see datasheet table in AVGCTRL register description)
  ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 |    // 1 sample only (no oversampling nor averaging)
                     ADC_AVGCTRL_ADJRES(0x0ul);   // Adjusting result by 0

  analogReference( AR_DEFAULT ) ; // Analog Reference is AREF pin (3.3v)

  // Initialize DAC
  // Setting clock
  // while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY );
  // GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_DAC ) | // Generic Clock ADC
  //                     GCLK_CLKCTRL_GEN_GCLK0     | // Generic Clock Generator 0 is source
  //                     GCLK_CLKCTRL_CLKEN ;

  // while ( DAC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains
  // DAC->CTRLB.reg = DAC_CTRLB_REFSEL_AVCC | // Using the 3.3V reference
  //                  DAC_CTRLB_EOEN ;        // External Output Enable (Vout)
}
예제 #4
0
/*
 * Arduino Zero board initialization
 *
 * Good to know:
 *   - At reset, ResetHandler did the system clock configuration. Core is running at 48MHz.
 *   - Watchdog is disabled by default, unless someone plays with NVM User page
 *   - During reset, all PORT lines are configured as inputs with input buffers, output buffers and pull disabled.
 */
void init( void )
{
#if 0    ////// 사용하지 않음
  uint32_t ul ;

  // Set Systick to 1ms interval, common to all Cortex-M variants
  if ( SysTick_Config( SystemCoreClock / 1000 ) )
  {
    // Capture error
    while ( 1 ) ;
  }

//  Clock PORT for Digital I/O
//	PM->APBBMASK.reg |= PM_APBBMASK_PORT ;
//
//  Clock EIC for I/O interrupts
//	PM->APBAMASK.reg |= PM_APBAMASK_EIC ;

  // Clock SERCOM for Serial
  PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ;

  // Clock TC/TCC for Pulse and Analog
  PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 | PM_APBCMASK_TC6 | PM_APBCMASK_TC7 ;

  // Clock ADC/DAC for Analog
  PM->APBCMASK.reg |= PM_APBCMASK_ADC | PM_APBCMASK_DAC ;

  // Setup all pins (digital and analog) in INPUT mode (default is nothing)
	for ( ul = 0 ; ul < NUM_DIGITAL_PINS ; ul++ )
  {
	  pinMode( ul, INPUT ) ;
  }

  // Initialize Analog Controller
  // Setting clock
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_ADC ) |  // Generic Clock ADC
                      GCLK_CLKCTRL_GEN_GCLK0 |      // Generic Clock Generator 0 is source
                      GCLK_CLKCTRL_CLKEN ;
  // Setting CTRLB
  ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV128 |     // Divide Clock by 128.
                   ADC_CTRLB_RESSEL_10BIT;          // Result on 10 bits
    ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND | // No Negative input (Internal Ground)
                         ADC_INPUTCTRL_GAIN_1X;     // Gain setted to 1
  // Averaging (see table 31-2 p.816 datasheet)
  ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_2 |      // 2 samples
                     ADC_AVGCTRL_ADJRES(0x01ul);    // Adjusting result by 1
  
  ADC->SAMPCTRL.reg = 0x3f;	
  ADC->REFCTRL.reg = ADC_REFCTRL_REFSEL_INTVCC1;    // Reference intvcc1 [default]
 
  ADC->CTRLA.bit.ENABLE = 1; // Enable ADC
  while( ADC->STATUS.bit.SYNCBUSY == 1 )
  {
    // Waiting for synchroinization
  }

  // Initialize DAC
  // Setting clock
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_DAC ) |  // Generic Clock ADC
                      GCLK_CLKCTRL_GEN_GCLK0 |      // Generic Clock Generator 0 is source
                      GCLK_CLKCTRL_CLKEN ;


  DAC->CTRLB.reg = DAC_CTRLB_REFSEL_AVCC |          // Using the 3.3V reference
                   DAC_CTRLB_EOEN;                  // External Output Enable (Vout)
  DAC->DATA.reg = 0x3FFul;
#endif    ////// 사용하지 않음
}