Ejemplo n.º 1
0
void initAdc (ADC_t * adc) {
	ADC_CalibrationValues_Load (adc);
  	ADC_ConvMode_and_Resolution_Config (adc, ADC_ConvMode_Unsigned, ADC_RESOLUTION_8BIT_gc);
	ADC_Prescaler_Config (adc, ADC_PRESCALER_DIV16_gc); // Fadc = 250khz
	ADC_Reference_Config (adc, ADC_REFSEL_INT1V_gc); // vref = internal 1v
    
    /* Setup channel 0, 1, 2 and 3 to have single ended input and 1x gain. */
	ADC_Ch_InputMode_and_Gain_Config (&(adc->CH0),
	                                 ADC_CH_INPUTMODE_SINGLEENDED_gc,
	                                 ADC_CH_GAIN_1X_gc);

	ADC_Ch_InputMode_and_Gain_Config (&(adc->CH1),
	                                 ADC_CH_INPUTMODE_SINGLEENDED_gc,
	                                 ADC_CH_GAIN_1X_gc);

	ADC_Ch_InputMode_and_Gain_Config (&(adc->CH2),
	                                 ADC_CH_INPUTMODE_SINGLEENDED_gc,
	                                 ADC_CH_GAIN_1X_gc);

	ADC_Ch_InputMode_and_Gain_Config (&(adc->CH3),
	                                 ADC_CH_INPUTMODE_SINGLEENDED_gc,
	                                 ADC_CH_GAIN_1X_gc);

	/* Enable high level sample complete interrupt for channel 3 */
	ADC_Ch_Interrupts_Config (&(adc->CH0), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc);
	ADC_Ch_Interrupts_Config (&(adc->CH1), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc);
	ADC_Ch_Interrupts_Config (&(adc->CH2), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc);
	ADC_Ch_Interrupts_Config (&(adc->CH3), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc);

	PMIC.CTRL |= PMIC_HILVLEN_bm; // Enable low level interrupts
	ADC_Enable (adc); // Enable ADC A with free running mode
	ADC_Wait_32MHz (adc); // Wait until common mode voltage is stable
}
Ejemplo n.º 2
0
uint16_t readADC(){
    uint16_t ADC_result = 0;
    int8_t offset;
 	/* Move stored calibration values to ADC B */
	ADC_CalibrationValues_Load(&ADCA);
   
    /* Set up ADC B to have signed conversion mode and 12 bit resolution. */
  	ADC_ConvMode_and_Resolution_Config(&ADCA, true, ADC_RESOLUTION_12BIT_gc);

    // The ADC has different voltage reference options, controlled by the REFSEL bits in the
    // REFCTRL register. Here the internal reference is selected 
	ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc);

	// The clock into the ADC decide the maximum sample rate and the conversion time, and
    // this is controlled by the PRESCALER bits in the PRESCALER register. Here, the
    // Peripheral Clock is divided by 8 ( gives 250 KSPS with 2Mhz clock )
	ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV8_gc);

    // The used Virtual Channel (CH0) must be set in the correct mode
    // In this task we will use single ended input, so this mode is selected 
  
    /* Setup channel 0 to have single ended input. */
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,
	                                 ADC_CH_INPUTMODE_DIFF_gc,
                                     ADC_CH_GAIN_1X_gc);
     // Setting up the which pins to convert.
    // Note that the negative pin is internally connected to ground  
	ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN0_gc, ADC_CH_MUXNEG_PIN1_gc);
  

    // Before the ADC can be used it must be enabled 
	ADC_Enable(&ADCA);


    // Wait until the ADC is ready
    ADC_Wait_32MHz(&ADCA);

    // In the while(1) loop, a conversion is started on CH0 and the 8 MSB of the result is
    // ouput on the LEDPORT when the conversion is done   

	/* Get offset value for ADC B.  */
	offset = ADC_Offset_Get_Unsigned(&ADCA, &(ADCA.CH0), true);  
	
	for(int i = 0; i<5; i++){
	
         ADC_Ch_Conversion_Start(&ADCA.CH0);
           
         while(!ADC_Ch_Conversion_Complete(&ADCA.CH0));
                
            //ADCB.INTFLAGS = ADC_CH0IF_bm;     // Clear CH0IF by writing a one to it
         ADC_result += ADCA.CH0RES;// - offset;
    }
    
    return ADC_result/5;
}
Ejemplo n.º 3
0
/**
 * Name         : adc_init
 *
 * Synopsis     : void adc_init	(void)
 *
 * Description  : Initialize the main system clock
 * 
 */
void adc_init	(void)
{
	/////////////////FROM XPLAINED 1505////////////////////////////////
	// Variable for use when we read the result from an ADC channel
	//PORTQ.PIN2CTRL = (PORTQ.PIN2CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLDOWN_gc; // This pin must be grounded to "enable" NTC-resistor
	/* Move stored calibration values to ADC B */
	ADC_CalibrationValues_Load(&ADCA);
	/* Set up ADC A to have signed conversion mode and 8 bit resolution. */
	ADC_ConvMode_and_Resolution_Config(&ADCA, true, ADC_RESOLUTION_12BIT_gc);
	// The ADC has different voltage reference options, controlled by the REFSEL bits in the
	// REFCTRL register. Here the internal reference is selected
	ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc);
	// The clock into the ADC decides the maximum sample rate and the conversion time, and
	// this is controlled by the PRESCALER bits in the PRESCALER register. Here, the
	// Peripheral Clock is divided by 8 ( gives 250 KSPS with 2Mhz clock )
	ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV8_gc);
	// The used Virtual Channel (CH0) must be set in the correct mode
	// In this task we will use single ended input, so this mode is selected
	/* Setup channel 0 to have single ended input. */
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,
	ADC_CH_INPUTMODE_SINGLEENDED_gc,
	ADC_CH_GAIN_1X_gc);
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1,
	ADC_CH_INPUTMODE_SINGLEENDED_gc,
	ADC_CH_GAIN_1X_gc);
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2,
	ADC_CH_INPUTMODE_SINGLEENDED_gc,
	ADC_CH_GAIN_1X_gc);
	
	// Setting up the which pins to convert.
	// Note that the negative pin is internally connected to ground
	//ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN9_gc, ADC_CH_MUXNEG_PIN1_gc);
	ADCA.CH0.MUXCTRL |= ADC_CH_MUXPOS_PIN0_gc;
	ADCA.CH1.MUXCTRL |= ADC_CH_MUXPOS_PIN1_gc;
	ADCA.CH2.MUXCTRL |= ADC_CH_MUXPOS_PIN2_gc;
	
	// Before the ADC can be used it must be enabled
	ADC_Enable(&ADCA);
	
	// Wait until the ADC is ready
	ADC_Wait_8MHz(&ADCA);
	// In the while(1) loop, a conversion is started on CH0 and the 8 MSB of the result is
	// output on the LEDPORT when the conversion is done
	/* Get offset value for ADC B. */
	adcx.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH0), true);
	adcy.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH1), true);
	adcz.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH2), true);
		
}
Ejemplo n.º 4
0
void adc_init(void)
{
	ADC_CalibrationValues_Load(&ADCA);
	ADC_ConvMode_and_Resolution_Config(&ADCA, 
		ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc);

	ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV16_gc);

	ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc);

	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,
	                                 ADC_CH_INPUTMODE_SINGLEENDED_gc,
                                     ADC_CH_GAIN_1X_gc);

	ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN7_gc, ADC_CH_MUXNEG_PIN0_gc);

	ADC_Enable(&ADCA);

	ADC_Wait_8MHz(&ADCA);
}
Ejemplo n.º 5
0
void adc_temp_init(void)
{
	// enable 1V reference and temperature modules
	ADC_BandgapReference_Enable(&ADCB);
	ADC_TempReference_Enable(&ADCB);

	// load calibration from signature bytes
	ADC_CalibrationValues_Load(&ADCB);

	// Conversion mode and resolution (12 bit right-aligned)
	ADC_ConvMode_and_Resolution_Config(&ADCB, 
		ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc);

	// prescaler from system clock (fastest)
	ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV4_gc);

	// internal 1V reference
	ADC_Reference_Config(&ADCB, ADC_REFSEL_INT1V_gc);

	// channel 0 for temperature
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0,
	                                 ADC_CH_INPUTMODE_INTERNAL_gc,
                                     ADC_CH_GAIN_1X_gc);

	ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXINT_TEMP_gc, ADC_CH_MUXNEG_PIN0_gc);

	// channel 1 for VCC/10
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH1,
	                                 ADC_CH_INPUTMODE_INTERNAL_gc,
                                     ADC_CH_GAIN_1X_gc);

	ADC_Ch_InputMux_Config(&ADCB.CH1, ADC_CH_MUXINT_SCALEDVCC_gc, ADC_CH_MUXNEG_PIN0_gc);

	ADC_Enable(&ADCB);

	ADC_Wait_8MHz(&ADCB);
}
int main(void)
{
	facilitatePowersaving();

	// Configure switches
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches

	SWITCHPORT.DIRCLR = 0xff; // Set port as input

	// Configure LEDs
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	LEDPORT.PIN0CTRL = PORT_INVEN_bm; // Invert input to turn the leds on when port output value is 1

	LEDPORT.DIRSET = 0xff; 	// Set port as output
	LEDPORT.OUT = 0x00;  // Set initial value


	// Set up ADCB0 on PB0 to read temp sensor. More of this can be achieved by using driver from appnote AVR1300
	PORTQ.PIN2CTRL = (PORTQ.PIN2CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLDOWN_gc;	// This pin must be grounded to "enable" NTC-resistor
	PORTB.DIRCLR = PIN0;
	PORTB.PIN0CTRL = (PORTB.PIN0CTRL & ~PORT_OPC_gm);

	ADC_CalibrationValues_Load(&ADCB);  // Load factory calibration data for ADC
	ADCB.CH0.CTRL = (ADCB.CH0.CTRL & ~ADC_CH_INPUTMODE_gm) | ADC_CH_INPUTMODE_SINGLEENDED_gc; // Single ended input
	ADCB.CH0.MUXCTRL = (ADCB.CH0.MUXCTRL & ~ADC_CH_MUXPOS_gm) | ADC_CH_MUXPOS_PIN0_gc; // Pin 0 is input	
	ADCB.REFCTRL = (ADCB.REFCTRL & ~ADC_REFSEL_gm) | ADC_REFSEL_VCC_gc;	// Internal AVCC/1.6 as reference

	ADCB.CTRLB |= ADC_FREERUN_bm; // Free running mode
	ADCB.PRESCALER = (ADCB.PRESCALER & ~ADC_PRESCALER_gm) | ADC_PRESCALER_DIV512_gc; // Divide clock by 1024.
	ADCB.CTRLB = (ADCB.CTRLB & ~ADC_RESOLUTION_gm) | ADC_RESOLUTION_8BIT_gc; // Set 8 bit resolution
	ADCB.CTRLA |= ADC_ENABLE_bm; // Enable ADC
	

	// Set up DMA CH0 to transfer from ADC to LEDS. We only read low byte.
	DMA_Enable();
	DMA_SetupBlock( 
                    &DMA.CH0,
			        (void const *) &(ADCB.CH0RES), 
                    DMA_CH_SRCRELOAD_NONE_gc, 
                    DMA_CH_SRCDIR_FIXED_gc,
			        (void const *) &(LEDPORT.OUT), 
                    DMA_CH_DESTRELOAD_NONE_gc, 
                    DMA_CH_DESTDIR_FIXED_gc,
			        1, 
                    DMA_CH_BURSTLEN_1BYTE_gc, 
                    0,
                    true
                );
    DMA_EnableSingleShot( &DMA.CH0 );
	DMA_SetTriggerSource( &DMA.CH0, DMA_CH_TRIGSRC_ADCB_CH0_gc ); // ADC Channel 0 is trigger source.
	


	// Set up interrupt on button 0, or else we can't come back from IDLE
	SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc;
	SWITCHPORT.INT0MASK = SWITCHMASK_ACTIVE;
	SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_FALLING_gc;


	// Enable low interrupt level in PMIC and enable global interrupts.
	PMIC.CTRL |= PMIC_LOLVLEN_bm;
	sei();

	// Main loop.
	while (1) {

		if ((SWITCHPORT.IN & SWITCHMASK_ACTIVE) == 0x00)
		{
		// Button 0 pressed. Enter ACTIVE mode again.
			DMA_DisableChannel( &DMA.CH0 );

			SLEEP.CTRL &= ~SLEEP_SEN_bm;	// Disable sleep. sleep() is now ineffective.

		} else if ((SWITCHPORT.IN & SWITCHMASK_IDLE) == 0x00)	
	    {	
		// Button 1 pressed. Enter Idle mode
			DMA_EnableChannel( &DMA.CH0 );			

			// Set and enable sleep.
			SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_IDLE_gc;
			SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep.

		} else if (SLEEP.CTRL & SLEEP_SEN_bm) {
			 	// We are in wanting-to-sleep mode, but were awake.
				sleep();
	
		} else { 
			// Do active sampling and transfer of ADC data.
			LEDPORT.OUT = ADCB.CH0RES & 0xFF;
		}

	}
	
}
Ejemplo n.º 7
0
int main(void)
{
  //! set the power reduction register to minimize current consumption
  init_power_reduction();
  //! set CPU clock to 32MHz and enables the DFLL32MHz
  clock_init();           
  //! initialize the LCD module
  init_lcd();
  //! display all the segments in LCD
  lcd_show_all();        
  //! initialize the GPIO pins
  init_ioport();
  //! initializes the UART
  init_UART();
  //! load the calibration data from flash
  ADC_CalibrationValues_Load(&ADCA);
  //! get the ADC offset value
  get_offset();
  //! initialize the ADC
  init_ADC();
  //! load the calibration value from eeprom
  init_eeprom();
  //! initilize RTC to external clock and 1 sec interrupt
  rtc_init();
  //! initilize the timer
  init_timer();  

  while(1)
    {
      //! rtc_flag is set
      if (rtc_flag == 1)
      {
        //! perform the calculation of metering paramters
        calculate();
        //for debugging
        if(cover_open_flag ==1)
        PORTD.OUTTGL = PIN3_bm;
        //TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc;
        TCC1.INTCTRLA = (TCC1.INTCTRLA & ~(TC1_OVFINTLVL_gm | TC1_ERRINTLVL_gm))|TC1_OVFINTLVL0_bm;
        //! if power on detected
        if(power_status_flag == POWER_ON_DETECTED) 
        {
          //! change the clock frequency to 32MHz
          CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );
          //! switch off the battery
          PORTD.PIN4CTRL	= PORT_OPC_WIREDANDPULL_gc;
          //PORTD.OUTSET	= PIN4_bm;
          //! initialize gpio pins
          init_ioport();
          //! change the sleep mode to ideal sleep
          SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm)| SLEEP_SMODE_IDLE_gc;
          //! enable ADC & Timer
          ADC_Enable(&ADCA);
          TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc;
          //! initialize lcd module
          init_lcd();
          //! update power status flag
          power_status_flag = POWERED_UP;
        }
        //! update the LCD display
        lcd_disp_key();
        tamper_check();
        if( active_power[0] > max_demand )
        {
          max_demand = active_power[0];
        }
        //! check for calibration flag and proceed and call the appropriate calibration funtion
        if(calibration_flag != 0)
        {
          //! checking the calibration flag for calibrating the date & time
          if (calibration_flag == 1)
          { calibrate_time_date();  }
          //! checking the calibration flag for calibrating the voltage
          else if (calibration_flag == 2)
          { calibrate_voltage();    }
          //! checking the calibration flag for calculating the offset value
          else if (calibration_flag == 3)
          { calibrate_no_load();    }
          //! checking the calibration flag for calculating the phase angle variation
          else if (calibration_flag == 4)
          { calibrate_phase();	    }
          //! checking the calibration flag for calculating watt varition
          else if (calibration_flag == 5)
          { calibrate_watt();       }
          else if (calibration_flag == 6)
          //! checking the calibration flag for calibrating the current            
          { calibrate_current();    }
        }
        rtc_flag = 0;
        __watchdog_reset();
      }
      //! checking the power_status, if power off is detected
      else if(power_status_flag == POWER_OFF_DETECTED)
      {
        //! switch on the battery
        PORTD.PIN4CTRL	= PORT_OPC_WIREDAND_gc;
        //PORTD.OUTCLR  = PIN4_bm;
        //! change the sleep mode to power save mode
        SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm)| SLEEP_SMODE_PSAVE_gc;  
        //! switch off the LCD
        lcd_command(LCD_COMMAND,0x02);
        //! change reset the gpio pin
        facilitatePowersaving();
        //! disable the ADC
        ADC_Disable(&ADCA);
        //! disable the timer
        TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_OFF_gc;
        //! clear all the varilable used in for energy calculation
        meter_flush();
        //! reduce the cpu clock frequency to minimize power consumption
        CLKSYS_Prescalers_Config( CLK_PSADIV_64_gc, CLK_PSBCDIV_1_1_gc );
        //! update power status flag
        power_status_flag = POWER_OFF;
        __watchdog_reset();
      }
      //! goes to sleep
      SLEEP.CTRL |=  SLEEP_SEN_bm;
      asm("sleep");
    }
}
Ejemplo n.º 8
0
//-----------------------------------------------------------------------------
// functions
//-----------------------------------------------------------------------------
void adc_init(void) {
/*
	Note: port_init() must be run before this function, so that the inputs are
	set correctly.
	
	We are using both ADCs. So everything will be set up for ADCA && ADCB.
*/

// Load the production calibration data into each ADC.
// This data was taken by Atmel and is stored in the micro.
// This function takes care of the whole process for you.
	ADC_CalibrationValues_Load(&ADCA);
	ADC_CalibrationValues_Load(&ADCB);
	
// Set the mode of operation for each ADC
// Signed operation mode is required for the differential configuration.
	ADC_ConvMode_and_Resolution_Config(&ADCA,signed_y,ADC_RESOLUTION_12BIT_gc);
	ADC_ConvMode_and_Resolution_Config(&ADCB,signed_y,ADC_RESOLUTION_12BIT_gc);
	
// Set ADC clocks
// 32MHz / 128 = 250KHz
// I currently have no explanation for this choice
// Atmel documentation states that you need to stay within the recommended
// ADC frequencies, but I cannot find the specific numbers.
	ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV128_gc);
	ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV128_gc);
	
// Select reference to be external reference on PIN0 for A and B
	ADC_Reference_Config(&ADCA, ADC_REFSEL_AREFA_gc);
	ADC_Reference_Config(&ADCB, ADC_REFSEL_AREFB_gc);

// Setup all channels to have differential input and 1X gain
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // V1
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // V2
	ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // reference
									  
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // I1
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH1,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // I2
	ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH2,ADC_CH_INPUTMODE_DIFF_gc,
	                                  ADC_CH_GAIN_1X_gc); // reference								  									 								  

// Select the input pins for each ADC.
/*
	See AnodV2.1.sch eagle file:
	V1 - A1
	V2 - A2
	I1 - B1
	I2 - B2
	Ref - A0,A3,B0,B3
*/
	ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN1_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // V1
	ADC_Ch_InputMux_Config(&ADCA.CH1, ADC_CH_MUXPOS_PIN2_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // V2
	ADC_Ch_InputMux_Config(&ADCA.CH2, ADC_CH_MUXPOS_PIN3_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // Offset calib
			
	ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN1_gc, \
									  ADC_CH_MUXNEG_PIN3_gc); // V1
	ADC_Ch_InputMux_Config(&ADCB.CH1, ADC_CH_MUXPOS_PIN2_gc, 
									  ADC_CH_MUXNEG_PIN3_gc); // V2
	ADC_Ch_InputMux_Config(&ADCB.CH2, ADC_CH_MUXPOS_PIN3_gc,
									  ADC_CH_MUXNEG_PIN3_gc); // Offset calib

// Configure the ADCA.CH2 interrupt.
// This will trip once a reading on channel 2 has been completely resolved.
// I am assuming the chan 0 and 1 of both ADCs will have their results completed
// when chan 2 is done. This is based from the Xmega A manual (sect 25)									  
	ADC_Ch_Interrupts_Config(&ADCA.CH1, ADC_CH_INTMODE_COMPLETE_gc, \
									    ADC_CH_INTLVL_LO_gc);

//Enable ADCs
	ADC_Enable(&ADCA);
	ADC_Enable(&ADCB);								

// Wait until common mode voltage is stable so tha bypass transients are not passed.
// What is the difference between the 32 and 8 MHz versions, 
// and which one do I want?
	ADC_Wait_32MHz(&ADCA);
	ADC_Wait_32MHz(&ADCB);									  

// The TCD0 timer will periodically trigger an event that will  create an event
// on channel 0. (Xmega A manual sect 6)
	eflags.setEventSource = EVSYS_SetEventSource(0, EVSYS_CHMUX_TCD0_OVF_gc);
	TC0_ConfigClockSource(&TCD0, TC_CLKSEL_DIV8_gc);
	TCD0.PER = 200; // 1/f = 1/(32MHz/DIVx/PER) --- 200---50us---20KHz

// This is moved to the adc_test() fun. May want to enable it here later.
	// enable timer overflow int and set priority to low.
	//TCD0.INTCTRLA = TC_OVFINTLVL_LO_gc; 

// An event on eventChan 0 will trigger a sweep of chan 0,1 in ADCA && ADCB.
// I do not know what would happen if an event happened on eventChan 1,2,3.
	ADC_Events_Config(&ADCA, ADC_EVSEL_0123_gc, ADC_EVACT_SWEEP_gc);	
	ADC_Events_Config(&ADCB, ADC_EVSEL_0123_gc, ADC_EVACT_SWEEP_gc);
	ADC_SweepChannels_Config(&ADCA, ADC_SWEEP_01_gc);
	ADC_SweepChannels_Config(&ADCB, ADC_SWEEP_01_gc);
	
	
// Calibration routine for the ADCs
// Find offset with two pins shorted together.
// Steve also found the offset for the current with 0 current flowing into them,
// but did not do an equivalent for voltage. I will leave this out for now.
	offset_A = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH2), true);
	offset_B = ADC_Offset_Get_Signed(&ADCB, &(ADCB.CH2), true);
}