int main(void) { facilitatePowersaving(); // Pull-ups and PR Registers initHardware(); // Switches, LEDs, Sleep, Interrupt sei(); // Enable global interrupts /* === Initialization of TWI Module === */ // Enable internal pull-up on PD0, PD1 for correct TWI operation PORTCFG.MPCMASK = 0x03; TWIPORT.PIN0CTRL = (TWIPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; /* Initialize TWI master. */ TWI_MasterInit(&twiMaster, &TWI, TWI_MASTER_INTLVL_LO_gc, TWI_BAUDSETTING); /* Initialize TWI slave. */ TWI_SlaveInitializeDriver(&twiSlave, &TWI, TWI_SlaveProcessData); TWI_SlaveInitializeModule(&twiSlave, OWN_ADDRESS, TWI_SLAVE_INTLVL_LO_gc); /* === End Initialization === */ while (1) { // Try to sleep while we are waiting for button press while (READ_SWITCHES == 0x00){ //See board.h for READ_SWITCHES define. sleep(); } _delay_ms(5); // Debounce switch sendBuffer[0] = READ_SWITCHES; TWI_MasterWrite(&twiMaster, // Module OTHER_ADDRESS, // Which slave &sendBuffer[0], // What to send 1); // Send how much /* Wait until transaction is complete. Required TWI interrupts will be executed while waiting */ while (twiMaster.status != TWIM_STATUS_READY); // Wait for user to release button. while (READ_SWITCHES != 0x00); //See board.h for READ_SWITCHES define. } }
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; SWITCHPORT.DIRCLR = 0xff; // Set port as input // Set up interrupt on buttons SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc; SWITCHPORT.INT0MASK = 0x0F; // 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 = 0x02; // Set initial value // Enable low interrupt level in PMIC and enable global interrupts. PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); // Main loop. char pressed = 0; while (1) { // == Button 0 pressed if (((SWITCHPORT.IN & SW_ACTIVE) | pressed) == 0x00) { _delay_ms(5); // Debounce switch pressed = 1; // Used for toggling LEDPORT.OUTSET = SW_ACTIVE; // Toggle led SLEEP.CTRL &= ~SLEEP_SEN_bm; // Disable sleep // == Button 1 pressed } else if (((SWITCHPORT.IN & SW_IDLE) | pressed) == 0x00) { _delay_ms(5); // Debounce switch pressed = 1; // Used for toggling LEDPORT.OUT = SW_IDLE; // Toggle led SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_IDLE_gc; SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep, else SLEEP-instruction is ineffective. // == Button 2 pressed } else if (((SWITCHPORT.IN & SW_STBY) | pressed) == 0x00) { _delay_ms(5); // Debounce switch pressed = 1; // Used for toggling. LEDPORT.OUT = SW_STBY; // Toggle led SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_STDBY_gc; SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep // == Button 3 pressed } else if (((SWITCHPORT.IN & SW_PWDN) | pressed) == 0x00) { _delay_ms(5); // Debounce switch pressed = 1; // Used for toggling. LEDPORT.OUT = SW_PWDN; SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_PDOWN_gc; SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep // == Buttons released } else if ( (SWITCHPORT.IN & (SW_ACTIVE | SW_IDLE | SW_STBY | SW_PWDN)) == 0x0F) { pressed = 0; LEDPORT.OUT = 0x00; sleep(); } } }
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; } } }
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 // Set up interrupt on buttons SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc; SWITCHPORT.INT0MASK = 0x0F; // 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 = 0x01; // Set initial value // Set up RTC timer and overflow interrupt CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_TOSC_gc; // Choose 1kHz input from external 32kHz oscillator as RTC source as this is most power-efficient. CLK.RTCCTRL |= CLK_RTCEN_bm; // Enable RTC // Now we have 1024 ticks per second. // We set the period to 2048, resulting in 1Hz toggling of the LED. RTC.PER = 2048; RTC.CTRL = (RTC.CTRL & ~RTC_PRESCALER_gm) | RTC_PRESCALER_DIV1_gc; // Set RTC prescaler 1 RTC.INTCTRL = (RTC.INTCTRL & ~RTC_COMPINTLVL_gm) | RTC_COMPINTLVL_LO_gc; // Enable LO interrupt on compare match // Set up sleep registers SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_PDOWN_gc; SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep, else SLEEP-instruction is ineffective. // Enable low interrupt level in PMIC and enable global interrupts. PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); // Main loop. char pressed = 0; while (1) { // == Button 0 pressed if (((SWITCHPORT.IN & SW_TOSC) | pressed) == 0x00) { _delay_ms(5); // Debounce switch pressed = 1; // Used for toggling LEDPORT.OUTSET = SW_TOSC; // Toggle led CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_TOSC_gc; // == Button 1 pressed } else if (((SWITCHPORT.IN & SW_RCOSC) | pressed) == 0x00) { _delay_ms(5); // Debounce switch pressed = 1; // Used for toggling LEDPORT.OUT = SW_RCOSC; // Toggle led CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_RCOSC_gc; // == Button 2 pressed } else if (((SWITCHPORT.IN & SW_ULP) | pressed) == 0x00) { _delay_ms(5); // Debounce switch pressed = 1; // Used for toggling. LEDPORT.OUT = SW_ULP; // Toggle led CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_ULP_gc; // == Buttons released } else if ( (SWITCHPORT.IN & (SW_TOSC | SW_RCOSC | SW_ULP )) == 0x07) { pressed = 0; LEDPORT.OUTCLR = 0x0F; sleep(); } } }
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"); } }