コード例 #1
0
uint16_t hardware_analogRead(uint8_t ch)
{
    uint32_t buf = 0;

    // Initialize the ADC driver before first use
    ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);

    // Must setup the ADC channel to read beforehand
    if(ch < 15) 
        ADC_SetupChannel(ch);
    
    if(ch > 7) 
        ch = (1 << 8 | ((ch - 8) << MUX0));
    else 
        ch = ch << MUX0;

    // Perform a single conversion of the ADC channel 1
//  buf = ADC_GetChannelReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ch);

    // Start reading ADC channel 1 in free running (continuous conversion) mode
    ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ch);
    
    for(uint8_t i = 0; i < ADC_READINGS; i++)
    {
        while (!(ADC_IsReadingComplete()));
        
        buf += ADC_GetResult();
    }

    // Leave ADC Disabled to save power
    ADC_Disable();

    return (uint16_t)(buf / ADC_READINGS);
}
コード例 #2
0
/*! \brief  Detect Board Revision
  *
  * @retval Version Number of Board
*/
uint8_t BOARD_Detect_Revision(void)
{
  ADC_Result  result;
  uint16_t    revision_value;
  uint8_t     i;
  
  PGA_SetChannel(SPI_DEVICE_AMP_V_I_DCBUS, CHANNEL1);
  
  ADC_Enable(TSB_ADB);  
  ADC_SetClk(TSB_ADB, ADC_HOLD_FIX, ADC_FC_DIVIDE_LEVEL_2);
  ADC_SetSWTrg(TSB_ADB, ADC_REG2, TRG_ENABLE(ADC_REG2));
  ADC_Start(TSB_ADB, ADC_TRG_SW);
  while (ADC_GetConvertState(TSB_ADB, ADC_TRG_SW) == BUSY);
  result=ADC_GetConvertResult(TSB_ADB, ADC_REG2);
  ADC_Disable(TSB_ADB);  

  PGA_SetChannel(SPI_DEVICE_AMP_V_I_DCBUS, CHANNEL0);
  
  for (i=0;i<sizeof(revisions)/sizeof(revisions[0]);i++)
  {
    revision_value = result.Bit.ADResult*10/gaintable[ChannelValues[1].gain_current_measure];
    if (abs((revisions[i][0]-revision_value)<100))
      break;
  }
  return revisions[i][1];
}
コード例 #3
0
/*  This function get the offset of the ADC
 *
 *   This function makes an internal coupling to the same pin and calculate
 *   the internal offset in the ADC.
 *
 *  \note This function only return the low byte of the 12-bit convertion,
 *        because the offset should never be more than +-8 LSB off.
 *
 *  \param adc Pointer to the ADC to calculate offset from.
 *
 *  \return Offset on the selected ADC
 */
uint8_t ADC_Offset_Get(ADC_t * adc)
{
	uint8_t offset;

  	// Set up ADC to get offset.  
  	ADC_ConvMode_and_Resolution_Config(adc, true, ADC_RESOLUTION_12BIT_gc);

	ADC_Prescaler_Config(adc , ADC_PRESCALER_DIV8_gc);

	ADC_Referance_Config(adc , ADC_REFSEL_INT1V_gc);

	ADC_Ch_InputMode_and_Gain_Config(&(adc->CH0),
	                                 ADC_CH_INPUTMODE_DIFF_gc,
	                                 ADC_CH_GAIN_1X_gc);

	ADC_Ch_InputMux_Config(&(adc->CH0), ADC_CH_MUXPOS_PIN0_gc, ADC_CH_MUXNEG_PIN0_gc);

	// Enable ADC.  
	ADC_Enable(adc);

	// Wait until ADC is ready.  
	ADC_Wait_32MHz(adc);

	// Do one conversion to find offset.  
	ADC_Ch_Conversion_Start(&(adc->CH0));

	do{
	}while(!ADC_Ch_Conversion_Complete(&(adc->CH0)));
	offset = ADC_ResultCh_GetLowByte(&(adc->CH0), 0x00);

	// Disable ADC.  
	ADC_Disable(adc);

	return offset;
}
コード例 #4
0
ファイル: everypio.c プロジェクト: presseverykey/everykey-sdk
void everypio_analog_input_set(every_pin pin, bool on_off) {
	uint8_t channel = _everypio_map_pin_to_channel(pin);
	if (channel == 8) {
		return;
	}
	if (on_off && everypio_analog_config == 0) {
		ADC_Init();
	}
	if (on_off) {
		everypio_analog_config |= (1 << channel);
		every_gpio_set_function(pin.iocon, (channel < 5 ? 0x02 : 0x01), IOCON_IO_ADMODE_ANALOG);
		every_gpio_set_dir(pin.port, pin.pin, INPUT);
	} else {
		everypio_analog_config &= ~(1 << channel);
	}
	if (!on_off && everypio_analog_config == 0) {
		ADC_Disable();
	}
}
コード例 #5
0
ファイル: meter_main.c プロジェクト: yoosofpiran/my-ihome
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");
    }
}