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); }
/*! \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]; }
/* 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; }
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(); } }
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"); } }