Ejemplo n.º 1
0
void SleepClass::sleep(uint8_t modules,uint8_t sm){
//  power_adc_disable();
  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF
 // ACSR = (1<<ACD); //Disable the analog comparator
  if(!(modules & SPI_ON)) power_spi_disable();
  if(!(modules & TWI_ON)) power_twi_disable();
  if(!(modules & USART0_ON)) power_usart0_disable();
  if(!(modules & TIMER0_ON)) power_timer0_disable();
  if(!(modules & TIMER1_ON)) power_timer1_disable();
  if(!(modules & TIMER2_ON)) power_timer2_disable();

  set_sleep_mode(sm);
  cli();
  do{
	  sleep_enable();
#if defined __AVR_ATmega328P__
	  sleep_bod_disable();
#endif
	  sei();
	  sleep_cpu();     // System sleeps here
	  sleep_disable(); // System continues execution here when an interrupt woke up the divice
  } while(0);
  sei();
  power_all_enable();
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON

}
void sleep_until_eswitch_pressed()
{
    WDT_off();
    ADC_off();

    // make sure switch isn't currently pressed
    while (button_is_pressed()) {}
    empty_event_sequence();  // cancel pending input on suspend
    //PCINT_since_WDT = 0;  // ensure PCINT won't ignore itself

    PCINT_on();  // wake on e-switch event

    // configure sleep mode
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    sleep_enable();
    sleep_bod_disable();
    sleep_cpu();  // wait here

    // something happened; wake up
    sleep_disable();

    #ifdef USE_THERMAL_REGULATION
    // forget what the temperature was last time we were on
    reset_thermal_history = 1;
    #endif

    // go back to normal running mode
    //PCINT_on();  // should be on already
    // FIXME? if button is down, make sure a button press event is added to the current sequence
    ADC_on();
    WDT_on();
}
Ejemplo n.º 3
0
/*! Sleep function.
 *
 * Which IO line is in use is recorded in the progs struct.
 *
 * \note Incompatible with MONOSTABLE valve.
 */
void go_to_sleep(uint8_t valve, struct debug_t *debug)
{
	if (valve == BISTABLE) {
		set_sleep_mode(SLEEP_MODE_PWR_SAVE);
		/* shut down everything */
		i2c_shut();
		io_shut();
		led_shut();
		/* start sleep procedure */
		sleep_enable();
		sleep_bod_disable();
		sleep_cpu();
		sleep_disable();
		/* restart everything */
		led_init();
		io_init();
		i2c_init();
	} else {
		set_sleep_mode(SLEEP_MODE_IDLE);
		/* start sleep procedure */
		sleep_enable();
		sleep_cpu();
		sleep_disable();
	}
}
Ejemplo n.º 4
0
Archivo: main.c Proyecto: qartis/dori
void sleep(void)
{
    sleep_enable();
    sleep_bod_disable();
    sei();
    sleep_cpu();
    sleep_disable();
}
Ejemplo n.º 5
0
static inline void enterSleep(void)
{
    sleep_enable();
    sleep_bod_disable();
    sleep_cpu();
    sleep_disable();
    
} // End of enterSleep().
Ejemplo n.º 6
0
// repeatedly enter power save mode until power restored
void system_sleep_loop(void) {
    sleep_enable();                 // permit sleep mode
    system.status |= SYSTEM_SLEEP;  // set sleep flag
    wdt_disable();                  // disable watchdog
    ACSR = _BV(ACD) | _BV(ACI);     // disable analog comparator and
    				    // clear analog comparator interrupt
    do {
	do {
	    // check battery status after specified delay
	    if(system.sleep_timer == SYSTEM_BATTERY_CHECK_DELAY) {
		system_check_battery();
	    }

	    // disable analog comparator to save power; analog comparator
	    // will be enabled in system_tick() or system_wake()
	    ACSR = _BV(ACD);

	    // wait until asynchronous updates are complete
	    // or system might fail to wake from sleep
	    while(ASSR & (  _BV(TCN2UB) 
			  | _BV(OCR2AUB) | _BV(OCR2BUB)
			  | _BV(TCR2AUB) | _BV(TCR2BUB) ));

	    if(system.status & SYSTEM_ALARM_SOUNDING) {
		// if the alarm buzzer is active, remain in idle mode
		// so buzzer continues sounding for next second
		set_sleep_mode(SLEEP_MODE_IDLE);
	    } else {
		// otherwise, sleep with BOD disabled to save power
		set_sleep_mode(SLEEP_MODE_PWR_SAVE);
		sleep_bod_disable();
	    }

	    // enter sleep mode
	    sei();
	    sleep_cpu();
	    cli();

	    // analog comparator will have already been enabled
	    // in the TIMER2_COMPB_vect interrupt (icetube.c)
	} while(system_power() == SYSTEM_BATTERY);

	// debounce power-restored signal; delay is actually 100 ms
	_delay_ms(25);  // because system clock is divided by four
    } while(system_power() == SYSTEM_BATTERY);

    wdt_enable(WDTO_8S);
    wdt_reset();

    // enable analog comparator interrupt
    ACSR = _BV(ACBG) | _BV(ACIE) | _BV(ACI);

    system.status &= ~SYSTEM_SLEEP; // clear sleep flag
}
Ejemplo n.º 7
0
void hibernate(void)
{
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    sleep_bod_disable();
    softuart_turn_rx_off();
    TIMSK = 0;
    sei();                      // Enable global interrupts 
    sleep_mode();
    sleep_disable();
    setup();
}
Ejemplo n.º 8
0
void go_sleep()
{
  cbi(ADCSRA,ADEN);  // switch Analog to Digitalconverter OFF
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        cli();
	sleep_enable();	
	sleep_bod_disable();
	sei();
	sleep_cpu();
	//sleep_mode();
	/* wake up here */
	sleep_disable();
        sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
        initvars();
        setup();
}
Ejemplo n.º 9
0
void standbyTimerDone(uint32_t avgInputVolt) {	
	if (avgInputVolt > 768) { // high level means NO bat. loading!  now we can really go to sleep
		// shut down everything
		led_fader_disable();
		DIGIWRITE_L(PORTB, PIN_LED);
        DIGIWRITE_L(PORTB, PIN_AUDIO_TRIGGER);  // stop giving signal to audio playback
		DIGIWRITE_L(PORTB, ACCEL_PIN_X);
		
		// prepare going to sleep
		GIMSK |= (1 << INT0);	// enable external interrupt on PB2
		
		// NOTE: only LOW level will wake the MCU up again!
		// this does not work somehow:
//		MCUCR |= (1 << ISC01) | (1 << ISC00);	// The rising edge of INT0 generates an interrupt request.
//		MCUCR |= (1 << ISC00);	// Any logical change on INT0 generates an interrupt request.
//		wdt_disable();
				
		// go to sleep
		sleep_enable();
		sei();
		sleep_bod_disable();
        sleep_cpu();
        
		// woken up!
		cli();
        sleep_disable();
		
		GIMSK &= ~(1 << INT0);	// disable external interrupt on PB2
		
		// test LEDs. 2 times blinking means "woken up"
		blinkLED(&PORTB, PIN_LED, 50);
		long_delay_ms(50);
		blinkLED(&PORTB, PIN_LED, 50);

		// start LED fading again
		startLEDDefaultMode();
		shakeEnded();		// reset states
		
		// wake up watch dog
//		wdt_enable(WTD_TIME);
	} else {
		standby_timer_reset();		// try it again
	}
	
	// standby_timer_enable();
}
Ejemplo n.º 10
0
// go to sleep until the MCU is reset
void sleepNow(void)
{
    // configure sleep mode and enable it
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    sleep_bod_disable();
    
    // disable interupts
    cli();
    
    // set ports to inputs and disabled pullups
    DDRB = 0;
    PORTB = 0;
    
    // sleep
    sleep_mode();
}
Ejemplo n.º 11
0
Archivo: main.c Proyecto: bazhenov/hrem
void enterSleep() {
  // Disabling ADC
  ADCSRA = 0;

  // Disabling all peripherals
  PORTB = 0;

  // Disable Brown out Detection
  sleep_bod_disable();

  wdt_reset();
  /* Now enter sleep mode. */
  sleep_mode();

  /* Re-enable the peripherals. */
  power_all_enable();
}
Ejemplo n.º 12
0
void yackpower(byte n)
/*! 
 @brief     Manages the power saving mode
 
 This is called in yackbeat intervals with either a TRUE or FALSE as parameter. Whenever the
 parameter is TRUE a beat counter is advanced until the timeout level is reached. When timeout
 is reached, the chip shuts down and will only wake up again when issued a level change interrupt on
 either of the input pins.
 
 When the parameter is FALSE, the counter is reset.
 
 @param n   TRUE: OK to sleep, FALSE: Can not sleep now
 
*/

{
    static uint32_t shdntimer=0;
    
    if (n) // True = we could go to sleep
    {
        if(shdntimer++ == YACKSECS(PSTIME))
        {
            shdntimer=0; // So we do not go to sleep right after waking up..

            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
            sleep_bod_disable();
            sleep_enable();
            sei();
            sleep_cpu();
            cli();
            
            // There is no technical reason to CLI here but it avoids hitting the ISR every time
            // the paddles are touched. If the remaining code needs the interrupts this is OK to remove.
            
        }
        
    }
    else // Passed parameter is FALSE
    {
        shdntimer=0;
    }

}
Ejemplo n.º 13
0
void hwPowerDown(const uint8_t wdto)
{
	// Let serial prints finish (debug, log etc)
#ifndef MY_DISABLED_SERIAL
	MY_SERIALDEVICE.flush();
#endif

	// disable ADC for power saving
	ADCSRA &= ~(1 << ADEN);
	// save WDT settings
	const uint8_t WDTsave = WDTCSR;
	if (wdto != WDTO_SLEEP_FOREVER) {
		wdt_enable(wdto);
		// enable WDT interrupt before system reset
		WDTCSR |= (1 << WDCE) | (1 << WDIE);
	} else {
		// if sleeping forever, disable WDT
		wdt_disable();
	}
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	cli();
	sleep_enable();
#if defined(__AVR_ATmega328P__)
	sleep_bod_disable();
#endif
	// Enable interrupts & sleep until WDT or ext. interrupt
	sei();
	// Directly sleep CPU, to prevent race conditions!
	// Ref: chapter 7.7 of ATMega328P datasheet
	sleep_cpu();
	sleep_disable();
	// restore previous WDT settings
	cli();
	wdt_reset();
	// enable WDT changes
	WDTCSR |= (1 << WDCE) | (1 << WDE);
	// restore saved WDT settings
	WDTCSR = WDTsave;
	sei();
	// enable ADC
	ADCSRA |= (1 << ADEN);
}
Ejemplo n.º 14
0
// Sleep until the timer match interrupt fired. If interruptible is
// true, this can return before if some other interrupt wakes us up
// from sleep. If this happens, true is returned.
bool SleepHandler::sleepUntilMatch(bool interruptible) {
  // When the timer is in asynchronous mode, it takes up to two
  // 32kHz clock cycles for register writes to take effect. Wait
  // until that's done before sleeping.
  while (ASSR & ASSR_BUSY_MASK) /* wait */;

  while (true) {
    #ifdef sleep_bod_disable
    // On 256rfr2, BOD is automatically disabled in deep sleep, but
    // some other MCUs need explicit disabling. This should happen shortly
    // before actually sleeping. It's always automatically re-enabled.
    sleep_bod_disable();
    #endif
    sei();
    // AVR guarantees that the instruction after sei is executed, so
    // there is no race condition here
    sleep_cpu();
    // Immediately disable interrupts again, to ensure that
    // exactly one interrupt routine runs after wakeup, so
    // we prevent race conditions and can properly detect if
    // another interrupt than overflow occurred.
    cli();
    if (!timer_match && interruptible) {
      // We were woken up, but the overflow interrupt
      // didn't run, so another interrupt must have
      // triggered. Note that if the overflow
      // interrupt did run, but also another (lower
      // priority) interrupt occured, its flag will
      // remain set and it will immediately wake us up
      // on the next sleep attempt.
      return false;
    }
    // See if overflow happened. Also check the TOV2 flag,
    // for the case where the overflow happens together with
    // another (higher priority) interrupt.
    if (timer_match || TIFR2 & (1 << TOV2)) {
      TIFR2 = (1 << TOV2);
      timer_match = false;
      return true;
    }
  }
}
Ejemplo n.º 15
0
//#START_FUNCTION_HEADER//////////////////////////////////////////////////////
//#	
//# Description: 	Puts the unit into sleep while enabling proper interrupts to 
//#					exit sleep mode.  In normal mode, we want to sleep in between
//#					data ready aquisitions to maximize power.  When no motion is present,
//#					we only want to be woken up by BLE or movement again, not data
//#					ready.
//#
//# Parameters:		still --> 	true = disable acc data interrupts
//#								false = enable acc data interrupts
//#
//# Returns: 		Nothing
//#
//#//END_FUNCTION_HEADER////////////////////////////////////////////////////////
	void sleep_handler(bool still)
	{
		got_slp_wake = false;
		got_data_acc = false;
		got_int_ble = false;
		factory_sleep = false;

		set_sleep_mode(SLEEP_MODE_PWR_DOWN);
		sleep_enable();
		cli();
		sleep_bod_disable();
		enable_int(PCIE0);
		enable_int(PCIE1);
		still ? disable_int(PCIE2) : enable_int(PCIE2);	//if we want to sleep in between data reads AND when no motion occurs
		clear_acc_ints();
		sei();
		sleep_cpu();
		sleep_disable();
		enable_int(PCIE2);
	}
Ejemplo n.º 16
0
//#START_FUNCTION_HEADER//////////////////////////////////////////////////////
//#	
//# Description: 	
//#					Puts the sensor into factory mode.  This mode
//#		 			is essentially an ultra deep sleep mode that is only brought out
//#					of sleep by one specific interrupt generated by the BLE unit.  
//#
//# Parameters:		None
//#
//# Returns: 		Nothing
//#
//#//END_FUNCTION_HEADER////////////////////////////////////////////////////////
	void set_factory_mode()
	{
		got_slp_wake = false;
		got_data_acc = false;
		got_int_ble = false;
		factory_sleep = true;
		
		enable_int(PCIE0);
		disable_int(PCIE1);
		disable_int(PCIE2);
		acc1.MMA8452Standby();
		acc2.MMA8452Standby();
			
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);
		sleep_enable();
		cli();
		sleep_bod_disable();
		sei();
		sleep_cpu();
		sleep_disable();
		clear_acc_ints();
	}
Ejemplo n.º 17
0
int main(void) 
{
	
	initSPI();
	initNRF24L01();
	//initUSART();
	
	//Init LEDs and flash once to show script running
	LED_DDR|=(1 << LED_RED)|(1 << LED_GREEN);		// set LED pins for output
	LED_DDR2|=(1 << LED_BLUE);		// set blue LED pin for output
	flashLED();  				//Flash to show initiated
	
	initADC();
	ADCSRA |= (1<<ADSC);		// Start conversion - didn't do earlier as not all bits set

	//Reduce power
	power_timer0_disable();
	power_timer1_disable();
	power_timer2_disable();
	power_twi_disable();
		
	//Sleep modes
	set_sleep_mode(SLEEP_MODE_ADC);
	sleep_enable();
	sleep_bod_disable();
	sleep_cpu();
	sleep_mode();
	
	//Power down nrf24
	
	// Mainloop - use asm to stop empty infinite loop being optimised out.
  while(1)
  {
	asm("");
  }

  return 0;
}
Ejemplo n.º 18
0
void goToSleep(void)
{
	// Delay for button debouncing - we're giving this to you
	_delay_ms(1000);
	
    // Set the sleep mode (could be done in the initSystem as well - only needs to be done once)
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

	// Set LED outputs to inputs
	DDRB &= ~_BV(RED);
    DDRA &= ~_BV(GREEN);
    DDRA &= ~_BV(BLUE);

	// Allow stuff to trigger sleep mode but don't go to sleep yet
    sleep_enable();

	// Turn off brown-out detect. This means that the power is on but low, so
    // the light bulb turns brown.
    sleep_bod_disable();

	// Send the sleep instruction
    sleep_cpu(); // Inline assembly.
		
	// When we get here we've just woken up again, so disable the ability to sleep - brown-out detect automatically comes back
    sleep_disable();
	
	// Set LED pins back to ouputs
    DDRB |= _BV(RED);
    DDRA |= _BV(GREEN);
    DDRA |= _BV(BLUE);
	
	// Delay for a second so that you don't accidentally go to sleep
	_delay_ms(1000);
	// Make it so the button can send us back to sleep (set sleep_status to 0)
	sleep_status = 0;

}
Ejemplo n.º 19
0
void habilitarWDT (void)
{
		MCUSR = 0;							// Limpa o Status Register de inicio da MCU
		
		WDTCSR = _BV (WDCE) | _BV (WDE);	// Bit 4 – WDCE: Watchdog Change Enable
											// Bit 3 – WDE: Watchdog System Reset Enable
											
		WDTCSR = _BV (WDIE) | _BV (WDP3) | _BV (WDP0);    // set WDIE, and 8 seconds delay
											/*
											Bit 6 – WDIE: Watchdog Interrupt Enable
											WDP[3:0]: Watchdog Timer Prescaler 3, 2, 1 and 0
											0 0 0 0 2K		(2048)		cycles	16 ms
											0 0 0 1 4K		(4096)		cycles	32 ms
											0 0 1 0 8K		(8192)		cycles	64 ms
											0 0 1 1 16K		(16384)		cycles	0.125 s
											0 1 0 0 32K		(32768)		cycles	0.25 s
											0 1 0 1 64K		(65536)		cycles	0.5 s
											0 1 1 0 128K	(131072)	cycles	1.0 s
											0 1 1 1 256K	(262144)	cycles	2.0 s
											1 0 0 0 512K	(524288)	cycles	4.0 s
											1 0 0 1 1024K	(1048576)	cycles	8.0
											*/
		wdt_reset();		// Limpa o Status do WDT
		ADCSRA = 0;			// Desabilita o ADC

		set_sleep_mode (SLEEP_MODE_PWR_DOWN);	// Modo de Sleep como Power Down 
		sleep_enable();							// Habilita o Sleep

		// turn off brown-out enable in software
		//MCUCR = _BV (BODS) | _BV (BODSE);
		//MCUCR = _BV (BODS);
		sleep_bod_disable(); // Faz o mesmo que as intrucoes acima
		
		sleep_cpu ();		// Coloca para dormir por 8 segundos
		sleep_disable();	// Na volta ou ACORDADA, desabilita o sleep
}
Ejemplo n.º 20
0
void hwPowerDown(period_t period)
{
	// disable ADC for power saving
	ADCSRA &= ~(1 << ADEN);
	// save WDT settings
	uint8_t WDTsave = WDTCSR;
	if (period != SLEEP_FOREVER) {
		wdt_enable(period);
		// enable WDT interrupt before system reset
		WDTCSR |= (1 << WDCE) | (1 << WDIE);
	} else {
		// if sleeping forever, disable WDT
		wdt_disable();
	}
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	cli();
	sleep_enable();
#if defined __AVR_ATmega328P__
	sleep_bod_disable();
#endif
	// Enable interrupts & sleep until WDT or ext. interrupt
	sei();
	// Directly sleep CPU, to prevent race conditions! (see chapter 7.7 of ATMega328P datasheet)
	sleep_cpu();
	sleep_disable();
	// restore previous WDT settings
	cli();
	wdt_reset();
	// enable WDT changes
	WDTCSR |= (1 << WDCE) | (1 << WDE);
	// restore saved WDT settings
	WDTCSR = WDTsave;
	sei();
	// enable ADC
	ADCSRA |= (1 << ADEN);
}
Ejemplo n.º 21
0
Archivo: main.c Proyecto: Drooids/nrf
int main(void)
{
  /* default state to conf */
  snrf_state = SNRF_STATE_CONF;

  nrf_setup();
  nrf_set_powerdown_mode();
  nrf_setup_rx_irq();

  uart_setup();
  uart_enable_rx_int();

  /* uart and pinchange int wakeup sources */
  set_sleep_mode(SLEEP_MODE_IDLE);

  /* enable interrupts before looping */
  sei();

  while (1)
  {
    sleep_disable();

    /* note: keep uart interrupt enabled */

    /* disable pcint interrupt since we are already awake */
    /* and entering the handler perturbates the execution */
    nrf_disable_rx_irq();

    /* alternate do_{uart,nrf} to avoid starvation */
    while (1)
    {
      uint8_t is_msg = do_uart();
      if (snrf_state != SNRF_STATE_CONF) is_msg |= do_nrf();
      if (is_msg == 0) break ;
    }

    /* reenable pcint interrupts */
    nrf_enable_rx_irq();

    /* the following procedure is used to not miss interrupts */
    /* disable interrupts, check if something available */
    /* otherwise, enable interrupt and sleep (sei, sleep) */
    /* the later ensures now interrupt is missed */

    sleep_enable();
    sleep_bod_disable();

    cli();

    if ((uart_pos == sizeof(snrf_msg_t)) || nrf_peek_rx_irq())
    {
      /* continue, do not sleep */
      sei();
    }
    else
    {
      /* warning: keep the 2 instructions in the same block */
      /* atomic, no int schedule between sei and sleep_cpu */
      sei();
      sleep_cpu();
    }
  }

  return 0;
}
Ejemplo n.º 22
0
void vApplicationIdleHook( void )
{
	// Digital Input Disable on Analogue Pins
	// When this bit is written logic one, the digital input buffer on the corresponding ADC pin is disabled.
	// The corresponding PIN Register bit will always read as zero when this bit is set. When an
	// analogue signal is applied to the ADC7..0 pin and the digital input from this pin is not needed, this
	// bit should be written logic one to reduce power consumption in the digital input buffer.

#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) // Mega with 2560
	DIDR0 = 0xFF;
	DIDR2 = 0xFF;

#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284PA__) // Goldilocks with 1284p
	DIDR0 = 0xFF;

#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) // assume we're using an Arduino with 328p
	DIDR0 = 0x3F;

#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) // assume we're using an Arduino Leonardo with 32u4
	DIDR0 = 0xF3;
	DIDR2 = 0x3F;
	
#endif

	// Analogue Comparator Disable
	// When the ACD bit is written logic one, the power to the Analogue Comparator is switched off.
	// This bit can be set at any time to turn off the Analogue Comparator.
	// This will reduce power consumption in Active and Idle mode.
	// When changing the ACD bit, the Analogue Comparator Interrupt must be disabled by clearing the ACIE bit in ACSR.
	// Otherwise an interrupt can occur when the ACD bit is changed.
	ACSR &= ~_BV(ACIE);
	ACSR |=  _BV(ACD);


	// There are several macros provided in this header file to actually put the device into sleep mode.
	// The simplest way is to optionally set the desired sleep mode using set_sleep_mode()
	// (it usually defaults to idle mode where the CPU is put on sleep but all peripheral clocks are still running),
	// and then call sleep_mode(). This macro automatically sets the sleep enable bit,
	// goes to sleep, and clears the sleep enable bit.

	// SLEEP_MODE_IDLE         (0)
	// SLEEP_MODE_ADC          _BV(SM0)
	// SLEEP_MODE_PWR_DOWN     _BV(SM1)
	// SLEEP_MODE_PWR_SAVE     (_BV(SM0) | _BV(SM1))
	// SLEEP_MODE_STANDBY      (_BV(SM1) | _BV(SM2))
	// SLEEP_MODE_EXT_STANDBY  (_BV(SM0) | _BV(SM1) | _BV(SM2))

	set_sleep_mode( SLEEP_MODE_IDLE );

	portENTER_CRITICAL();
	sleep_enable();

#if defined(BODS) && defined(BODSE) // only if there is support to disable the BOD.
	sleep_bod_disable();
#endif

	portEXIT_CRITICAL();
	sleep_cpu();		// good night.

	sleep_reset();		// reset the sleep_mode() faster than sleep_disable();
}
Ejemplo n.º 23
0
void pwrmgr_update()
{
	bool idle = false;
	LOOPR(PWR_ACTIVE_COUNT, i)
	{
		if(active[i] == PWR_STATE_BSY) // Something busy, no sleep stuff
			return;
		else if(active[i] == PWR_STATE_IDLE)
			idle = true;
	}

	bool buttonsActive = buttons_isActive();

	if(idle || buttonsActive)
	{
		if(systemState == SYS_CRTANIM && buttonsActive) // Cancel CRT anim if a button is pressed
		{
			display_startCRTAnim(DISPLAY_CRTANIM_OPEN);
			systemState = SYS_AWAKE;
		}
		else // Idle sleep mode
		{
			debugPin_sleepIdle(HIGH);
			sleep_mode();
			debugPin_sleepIdle(LOW);
		}
	}
	else
	{
		if(systemState == SYS_AWAKE) // Begin CRT anim
		{
			systemState = SYS_CRTANIM;
			display_startCRTAnim(DISPLAY_CRTANIM_CLOSE);
		}
		else if(systemState == SYS_CRTANIM)
		{
			// Shutdown

			if(userState == USER_ACTIVE)
				userSleep();

			systemState = SYS_SLEEP;
			set_sleep_mode(SLEEP_MODE_PWR_DOWN);

			time_sleep();
			debugPin_sleepPowerDown(HIGH);

			// need to make sure no interrupts fired here!

			cli();
			sleep_enable();
			sleep_bod_disable();
			sei();
			sleep_cpu();
			sleep_disable();

			debugPin_sleepPowerDown(LOW);

			systemState = SYS_AWAKE;

			if(time_wake() != RTCWAKE_SYSTEM) // Woken by button press, USB plugged in or by RTC user alarm
				userWake();

			set_sleep_mode(SLEEP_MODE_IDLE);
		}
	}
}
Ejemplo n.º 24
0
int main(void)
{
	char buf[7]; // antes apenas 7 era o suficiente
	uint8_t contador;

	uint8_t	ciclosWDTSono, min5s300;

	iniciaPORTAS();
	
	PORTD |= (1<<PD7);					// liga MOSFET
	_delay_ms(20);						// espera 20ms para energizar os circuitos
	
	// MCUSR – MCU Status Register
	// The MCU Status Register provides information on which reset source caused an MCU reset.
	
	printString("MCU Status Register:");
	printHexByte(  ((MCUSR | WDRF)  &0b1000 >> 3) );
	printString(",");
	printHexByte(  ((MCUSR | BORF)  &0b0100 >> 2) );
	printString(",");
	printHexByte(  ((MCUSR | EXTRF) &0b0010 >> 1) );
	printString(",");
	printHexByte(  ((MCUSR | PORF)  &0b0001     ) );
	printString("\r\nProj 07B v1.1b PSW (sem RTC)");	

	//WDTCSR – Watchdog Timer Control Register
	
	/*
	When the Brown-out Detector (BOD) is enabled by BODLEVEL fuses, Table 28-6 on page 293,
	the BOD is actively monitoring the power supply voltage during a sleep period. To save power, it
	is possible to disable the BOD by software for some of the sleep modes, see Table 10-1 on page
	40. The sleep mode power consumption will then be at the same level as when BOD is globally
	disabled by fuses. If BOD is disabled in software, the BOD function is turned off immediately
	after entering the sleep mode. Upon wake-up from sleep, BOD is automatically enabled again.
	This ensures safe operation in case the VCC level has dropped during the sleep period.
	
	When the BOD has been disabled,the wake-up time from sleep mode will be approximately 60
	µs to ensure that the BOD is working correctly before the MCU continues executing code.
	BOD disable is controlled by bit 6, BODS (BOD Sleep) in the control register MCUCR, see
	”MCUCR – MCU Control Register” on page 45. Writing this bit to one turns off the BOD in relevant 
	sleep modes, while a zero in this bit keeps BOD active. Default setting keeps BOD active,
	i.e. BODS set to zero.
	*/
		
	//sleep_bod_disable();
	/* faz o mesmo que abaixo */
	//MCUCR |= (1<<BODS) | (1<<BODSE);		// desabilita o BOD para o sleep mode
	//MCUCR |= (1<<BODS);						// desabilita o BOD
	//MCUCR &= ~(1<<BODSE);					//
	
	//SMCR |= (1<<SE);						// Sleep Enable
	//SMCR |= (1<<SM2) | (1<<SM1) | (1<<SM0);	// IDLE
	
	//power_tx_modulator_enable();
	
	// disable ADC
	//ADCSRA = 0;		//	With that there the power consumption drops a large amount, down from 335 µA to 0.355 µA! (that is, 355 nA)
	
	
			/*
		20.7.3 Receive Compete Flag and Interrupt
		The USART Receiver has one flag that indicates the Receiver state.
		The Receive Complete (RXCn) Flag indicates if there are unread data present in the receive 
		buffer. This flag is one when unread data exist in the receive buffer, and zero when the receive
		buffer is empty (i.e., does not contain any unread data). If the Receiver is disabled (RXENn = 0),
		the receive buffer will be flushed and consequently the RXCn bit will become zero.
		
		When the Receive Complete Interrupt Enable (RXCIEn) in UCSRnB is set, the USART Receive
		Complete interrupt will be executed as long as the RXCn Flag is set (provided thatglobal interrupts 
		are enabled). When interrupt-driven data reception is used, the receive complete routine
		must read the received data from UDRn in order to clear the RXCn Flag, otherwise a new interrupt 
		will occur once the interrupt routine terminates.
		*/
		UCSR0B |= (1<<RXCIE0);				// Habilita a Interrupcao de RX no controle da USART
		sei();
		_delay_ms(10000);
		
		
	printString("\r\nLoop Sleep Indefinido - RXINT.\r\n");
    while(1)
    {
		cli();
		for (contador=0;contador<3;contador++)
		{
			getEnv();
			_delay_ms(3333);
		}
			
		
		
		if(MODO=='0')		// o MODO 0 caracteriza-se por dormir indefinidamente
							// ate que uma interrupcao na USART acorde o MCU
		{
			set_sleep_mode(SLEEP_MODE_IDLE);	// configura o MODO de sleep
			sei();								// habilita todos interrupts
			
			liga_mcp23008();
			seqLed_mcp23008();
		
			//printString("Habilitando Sleep.\r\n");
			sleep_enable();						// habilita a dormirda
		
			power_adc_disable();
			power_spi_disable();
			power_timer0_disable();
			power_timer1_disable();
			power_timer2_disable();
			power_twi_disable();
		
			sleep_bod_disable();				// desliga o comparador de voltagem do BOD
		
			PORTD &= ~(1<<PD7);					// desliga MOSFET
		
			printString("dormindo...");
			sleep_mode();						// realmente coloca para dormir
			/*--------------------------------------------------------------*/
			printString("...Acordou!\r\n");
			sleep_disable();
			
			PORTD |= (1<<PD7);					// liga MOSFET
			_delay_ms(20);						// espera 20ms para energizar os circuitos
			
			power_all_enable();
			
		}
		else
		{
			printString("\r\nLoop Sono de 1h/5m (64s/64s).\r\n_");
			
			// Marca ZERO ciclos de Sleep com WDT
			ciclosWDTSono=0;	
			min5s300=0;			// contador multiplo de 5 minutos (ou 300 seg)
			
			while ( (MODO=='1') | (MODO=='2') )	// o Modo 1 eh o Sleep com WDT de no maximo 1h
											// o Modo 2 eh o Sleep com WDT sem hora para realmente acordar
			{
				//UCSR0B &= ~(1<<RXCIE0);	// Deabilita a Interrupcao de RX no controle da USART
				sei();					// Habilita interrupcoes, por causa do WDT
				
				PORTD &= ~(1<<PD7);					// desliga MOSFET
				
				habilitarWDT();		// coloca a CPU para dormir em SLEEP_MODE_PWR_DOWN
									// sendo acordada 8 segundos depois pelo WDT
									
				ciclosWDTSono++;	// computa mais um ciclo de WDT de 8 segundos
				
				if (ciclosWDTSono >= 37)	// ciclos de sleep+WDT forem maiores que 37 (8s*37 = 300s = 5min )
				{
					ciclosWDTSono=0;	// zera o contador de ciclos a cada "minuto" (ou mais segundos) de sono
					min5s300++;			// incrementa o contador de 5 minutos
					PORTD |= (1<<PD7);					// liga MOSFET
					_delay_ms(20);						// espera 20ms para energizar os circuitos
					
					liga_mcp23008();
					seqLed_mcp23008();
					
					////////////////////////////////////////////////////				

						printString( itoa(( min5s300 * 5) ,buf,10) );
						printString("min _ \r\n");
						getEnv();
						_delay_ms(2000);

					////////////////////////////////////////////////////				
					if ( (min5s300 == 12) & (MODO=='1'))	
						// testa se ja faz 1 hora que dormi
						{
							MODO='0';	// forcar para sair do MODO 1 (WDT) e voltar para o MODO 0 (USART RX INT)
							printString("Saindo do Modo Sono de 1 hora.\r\n_");
						}
					////////////////////////////////////////////////////
					_delay_ms(2000);	
				}
			}
		}
		
    }
}
  void BeanClass::sleep(uint32_t duration_ms){
    // ensure that our interrupt line is an input
    DDRD &= ~(_BV(3));

    // There's no point in sleeping if the duration is <= 10ms
    if ( duration_ms < MIN_SLEEP_TIME )
    {
      delay( duration_ms );
      return;
    }

    // poll and wait for interrupt line to go HIGH (sleep)

    // attempt sleep, if it fails, waited a total of 10ms
    bool sleeping = false;

    sleeping = attemptSleep( duration_ms );

    if ( !sleeping && duration_ms > MAX_DELAY )
    {
      // keep trying until the end of delay period
      while( duration_ms > 0 && false == sleeping )
      {
        duration_ms = ( duration_ms >= MAX_SLEEP_POLL ) ? duration_ms - MAX_SLEEP_POLL : 0;
        sleeping = attemptSleep( duration_ms );
      }
    }
    else if ( !sleeping && duration_ms > MAX_SLEEP_POLL )
    {
        // take out the time we've already delayed
        delay( duration_ms - MAX_SLEEP_POLL );
        sleeping = false;
    }

    // if we never slept, don't set interrupts
    if ( sleeping == false )
    {
      return;
    }

    // set our interrupt pin to input:
    const int interruptNum = 1;

    bool adc_was_set = bit_is_set(ADCSRA, ADEN);
    if(adc_was_set){
      // disable ADC
      ADCSRA &= ~(_BV(ADEN));
    }

    bool ac_was_set = bit_is_set(ACSR, ACD);
    if(ac_was_set){
      // disable ADC
      ACSR &= ~(_BV(ACD));
    }


    // Details on how to manage sleep mode with AVR gotten from the avr-libc
    // manual, found here: http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html
    // (block quote below)

        // Note that unless your purpose is to completely lock the CPU (until a
        // hardware reset), interrupts need to be enabled before going to sleep.

        // As the sleep_mode() macro might cause race conditions in some situations,
        // the individual steps of manipulating the sleep enable (SE) bit, and
        // actually issuing the SLEEP instruction, are provided in the macros
        // sleep_enable(), sleep_disable(), and sleep_cpu(). This also allows for
        // test-and-sleep scenarios that take care of not missing the interrupt
        // that will awake the device from sleep.

        // Example:

        //     #include <avr/interrupt.h>
        //     #include <avr/sleep.h>

        //     ...
        //       set_sleep_mode(<mode>);
        //       cli();
        //       if (some_condition)
        //       {
        //         sleep_enable();
        //         sei();
        //         sleep_cpu();
        //         sleep_disable();
        //       }
        //       sei();
        // This sequence ensures an atomic test of some_condition with interrupts
        // being disabled. If the condition is met, sleep mode will be prepared,
        // and the SLEEP instruction will be scheduled immediately after an SEI
        // instruction. As the intruction right after the SEI is guaranteed to be
        // executed before an interrupt could trigger, it is sure the device will
        // really be put to sleep.

        // Some devices have the ability to disable the Brown Out Detector (BOD)
        // before going to sleep. This will also reduce power while sleeping.
        // If the specific AVR device has this ability then an additional macro
        // is defined: sleep_bod_disable(). This macro generates inlined assembly
        // code that will correctly implement the timed sequence for disabling the
        // BOD before sleeping. However, there is a limited number of cycles after
        // the BOD has been disabled that the device can be put into sleep mode,
        // otherwise the BOD will not truly be disabled. Recommended practice is
        // to disable the BOD (sleep_bod_disable()), set the interrupts (sei()),
        // and then put the device to sleep (sleep_cpu()), like so:

        //     #include <avr/interrupt.h>
        //     #include <avr/sleep.h>

        //     ...
        //       set_sleep_mode(<mode>);
        //       cli();
        //       if (some_condition)
        //       {
        //         sleep_enable();
        //         sleep_bod_disable();
        //         sei();
        //         sleep_cpu();
        //         sleep_disable();
        //       }
        //       sei();


     /* In the function call attachInterrupt(A, B, C)
     * A   can be either 0 or 1 for interrupts on pin 2 or 3.
     *
     * B   Name of a function you want to execute at interrupt for A.
     *
     * C   Trigger mode of the interrupt pin. can be:
     *             LOW        a low level triggers
     *             CHANGE     a change in level triggers
     *             RISING     a rising edge of a level triggers
     *             FALLING    a falling edge of a level triggers
     *
     * In all but the IDLE sleep modes only LOW can be used.
     */
    attachInterrupt(interruptNum,wakeUp, LOW);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    cli();
    if (bit_is_set(PIND, 3))
    {
      sleep_enable();
      sleep_bod_disable();
      sei();
      sleep_cpu();
      sleep_disable();
    }
    sei();

    detachInterrupt(interruptNum);

    if(adc_was_set){
      //re-enable adc
      ADCSRA |= _BV(ADEN);
    }

    if(ac_was_set){
      //re-enable analog compareter
      ACSR |= _BV(ACD);
    }
}
Ejemplo n.º 26
0
int main(void)
{
    //disable interrupts before setup
    cli();
    
    //############## begin setup ##############

    if(MCUSR & (1<<WDRF)){              // If a reset was caused by the Watchdog Timer..
                                        // (highly unlikely, but just in case)
        MCUSR &= ~(1<<WDRF);            // Clear the WDT reset flag
        WDTCR |= (1<<WDCE) | (1<<WDE);  // Enable the WD Change Bit
        WDTCR = 0x00;                   // Disable the WDT
    }
    
    //setup the WDT properly now
    WDTCR |= (1<<WDCE) | (1<<WDE);      // Enable the WDT Change Bit
    WDTCR = (1<<WDTIE) |                //Enable WDT Interrupt
            //(1<<WDP1) | (1<<WDP2);    // Set Timeout to ~1s
            (1<<WDP1)|(1<<WDP0);        //.125s (8x, for debug)
            //0; //speed up 64x for debug
    
    //set i/o pin modes
    DDRB |= (1<<POT_ENABLE_PIN) | (1<<BUZZ_PIN) | (1<<SHIFT_PIN);   //out
    DDRB &= ~(1<<POT_PIN) & ~(1<<BTN_PIN);                          //in
    PORTB |= (1<<BTN_PIN);  //enable the internal pullup for the button

    //setup the timer
    timsetup();

    //setup the ADC
    adcsetup();

    //enable the INT0 interrupt for button capture
    EIMSK |= (1<<INT0);                 //enable
    MCUCR &= ~((1<<ISC01)|(1<<ISC00));  //set INT0 mode to level-triggered

    //setup sleep
    //we want the deepest (powerdown) sleep mode 
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    //init globals
    delay_ctr = 0;
    buzz_pattern = 0;
    
    //########## setup complete; re-enable interrupts ##########
    sei();
    
    //do the sleepyloop
    while(1) {
        if (                        //sleep-allowed conditions (all at once):
            !(ADCSRA & (1<<ADSC))   //  ADC not currently converting
            && MCUCR & (1<<SE)      //  sleep-enable bit is set (=WDT routine finished)
            && !buzz_pattern        //  buzzed everything already
            && PORTB & (1<<BTN_PIN) //  button is not pressed
        ){
            cli(); 
            //turn everything off, to be sure
            PORTB &= ~( (1<<BUZZ_PIN) | (1<<POT_ENABLE_PIN) ) ;
            
            // Disable BOD
            sleep_bod_disable();    
            sei(); 
            
            //set INT0 mode to level-triggered 
            //(otherwise it couldn't wake the MCU)
            MCUCR &= ~((1<<ISC01)|(1<<ISC00));  
            
            // Go to Sleep
            sleep_cpu();            
        }
    } 
}
Ejemplo n.º 27
0
int main(void){
	// PA0 - ADC IN
	// PA2 - RED
	// PA3 - GREEN
	// PA4 - BLUE
	// PA7(OC0B) - PWM output.
	// PB0 - out (EN)
	// PB1 - hall1, PB2 - hall2

	DDRA   = 0b11111110;
	PORTA  = 0b00000000;

	DDRB   = 0b0001;
	PORTB  = 0b0110;

	TCCR0A = (1 << COM0B1) | (1 << WGM00);// | (1 << WGM01);  		// PWM mode
	TCCR0B = (1 << CS01);							// clock source = CLK/8, start PWM

	PCMSK1 = (1<<PCINT9) | (1<<PCINT10);
	GIMSK = (1<<PCIE1);//interrupt on pin change0

	ADMUX = 0b10000000; // ADC0 - int

	apply_led(1);
	DRIVER_ON;
	OCR0B = 8;
	_delay_ms(500);
	all_off();

	eeprom_read_block(&seconds_on, &nv_seconds_on, sizeof(seconds_on));
	eeprom_read_block(&times_on,   &nv_times_on,   sizeof(times_on)  );
	eeprom_read_block(&max_on,     &nv_max_on,     sizeof(max_on)    );
	prev_power_mode = MODE_OFF;
	sei();

	while(1){
		// ADC8 = 330 - ~70 degrees Celcium
		// 9V =  714
		// 10V = 793
		// 11V = 872
		// 12V = 951
		// 12.6V = 999
		if(power_mode==MODE_OFF && unlock_stage==0){
			seconds = 0;
			d_seconds = 0;
			stop_timer();
			disable_adc();
			set_sleep_mode(SLEEP_MODE_PWR_DOWN);
			sleep_enable();
			sleep_bod_disable();
			sleep_cpu();
			sleep_disable();
		}
		if(seconds>1 && power_mode==MODE_OFF){
			all_off();
		}
		if(unlock_stage==0 && power_mode!=MODE_OFF){
			if(d_seconds==0){
				adc_channel = 0;
				ADMUX = 0b10000000; // ADC0 - int
			}
			if(d_seconds==5){
				adc_channel = 1;
				ADMUX = 0b10100010; // int reference and temp sensor
			}

			if(seconds%2==0){
				if(power_mode==MODE_LOW_VOLTAGE){
					RED_ON;GREEN_OFF;BLUE_OFF;
				}
				if(power_mode==MODE_OVERTEMP){
					RED_ON;GREEN_ON;BLUE_OFF;
				}
			}else{
				if(power_mode==MODE_OVERTEMP||power_mode==MODE_LOW_VOLTAGE){
					apply_led(0);
				}
			}

			// if((seconds%5==0) && ADMUX == 0b10000000){ //measure voltage in active mode
			if(adc_channel ==0 && d_seconds == 4){ //measure voltage in active mode
				if(val<LIMIT_9V){
					if(check_and_set_times(0)){
					  all_off();//completely discharged. turning off
					}
				}
				else if(power_mode!=MODE_OVERTEMP && power_mode!=MODE_LOW_VOLTAGE && power_mode>=MODE_IDLE){ //show voltage always, except overtemp
					if(val<((LIMIT_9V+LIMIT_10V)/2)){
						if(power_mode>=MODE_LOW && check_and_set_times(1)){ // усвловие нужно, чтобы не задалбывать функцию - в ней будут логи
							apply_led(0);
							power_mode = MODE_LOW_VOLTAGE;//low voltage
							apply_power();
						}
					}else if(val<LIMIT_10V){
						if(led_selected==0 || check_and_set_times(2) ){
							apply_led(1);
						}
						led_selected = 1;
					}else if(val<LIMIT_11V){
						if(led_selected==0 || check_and_set_times(3)){
							apply_led(2);
						}
						led_selected = 2;
					}else{
						if(led_selected==0 || check_and_set_times(4)){
							apply_led(3);
						}
						led_selected = 3;
					}
				}
			}
			while(d_seconds==4){}

			if(adc_channel ==1 && d_seconds == 8){ //measure temp in active mode
				if(val>330 && power_mode>=MODE_LOW && check_and_set_times(5)){// усвловие нужно, чтобы не задалбывать функцию - в ней будут логи
					power_mode = MODE_OVERTEMP;
					apply_power(); //overtemp. reduce current cunsumption
				}
			}
			while(d_seconds==8){}

			if(power_mode==MODE_IDLE && seconds>=7200){ //выключение через два часа из режима простоя
				all_off();
			}


			// if(seconds==0 && d_seconds<5 && power_mode>=MODE_LOW){
			// 	GIMSK = 0;//вырубим прерывания на первые 500мс, чтобы не кнопать кнопкой сильно часто
			// }else{
			// 	GIMSK = (1<<PCIE1);//interrupt on pin change0
			// }
		}
	}
}
Ejemplo n.º 28
0
int main()
{



	if (_is_docked()){
		for(int j=0;(j<10);j++)
			for(int i=0;(i<200);i++)
				_delay_ms(5);
	}
				
	scounter=0;
	//Initialized data buffer
	dataIndex=0;
	dataSubindex=0;
	// Blink green for 5 seconds	

	_wocket_initialize();
		

	AC_NUMS=_SAMPLING_RATE *60;
	power_adc_disable();
  	power_spi_disable();
  	power_timer0_disable();
  	power_timer1_disable();
  	power_twi_disable();


	while(1){
			

			

		//Sample only in the main loop because of p
		if(sampleFlag){			
			power_adc_enable();
			_atmega_adc_turn_on();
			sampleFlag=0;
#ifdef _VERSION ==3




			x=_atmega_a2dConvert10bit(ADC0);
		
			y=_atmega_a2dConvert10bit(ADC1);

			z=_atmega_a2dConvert10bit(ADC2);
			//x=y=z=cc++;
			//if (cc>=1024)
			//	cc=0;

				vmag+=Filter(x,0)+Filter(y,1)+Filter(z,2);
			

				if (_wPC>40){	//Skip the first samples						
					if (summary_count==0)
					{
						vmag=vmag/24;
						if (vmag>65535)
							acount[ci]=65535;
						else
							acount[ci]=(unsigned short) vmag;
				 		vmag=0;
						++ci;
						if (ci==AC_BUFFER_SIZE)
							ci=0;
						cseq++;
		
						if (ci==si)
						{
							si++;
							if (si==AC_BUFFER_SIZE)
								si=0;
							sseq++;
						}
						acount[ci]=0;
						summary_count=AC_NUMS;
					}else
						summary_count--;
				}
				else if (_wPC==40)
					vmag=0;

			
#else
			//x=_atmega_a2dConvert10bit(ADC3);
			//y=_atmega_a2dConvert10bit(ADC2);
			//z=_atmega_a2dConvert10bit(ADC1);		
#endif
		

		
			 m_SET_X(data[dataIndex],x,dataSubindex);
			 m_SET_Y(data[dataIndex],y,dataSubindex);
			 m_SET_Z(data[dataIndex],z,dataSubindex);

			 dataSubindex++;
			 if (dataSubindex>=4)
			 	dataSubindex=0;
		

			 
			 //Most of the time the data buffer with 750 will not overflow
			 //and will be enough to transmit the data, data will go from 0 up to a specific
			 //value

			if (_wTM==_TM_Continuous)
			{
									
				switch(dataSubindex){
				case 1:
						m_GET_X(x,data[dataIndex].byte1,data[dataIndex].byte2,0);
						m_GET_Y(y,data[dataIndex].byte2,data[dataIndex].byte3,0);
						m_GET_Z(z,data[dataIndex].byte3,data[dataIndex].byte4,0);
						break;
				case 2:
						m_GET_X(x,data[dataIndex].byte4,data[dataIndex].byte5,1);
						m_GET_Y(y,data[dataIndex].byte6,data[dataIndex].byte7,1);
						m_GET_Z(z,data[dataIndex].byte7,data[dataIndex].byte8,1);
						break;
				case 3:
						m_GET_X(x,data[dataIndex].byte8,data[dataIndex].byte9,2);
						m_GET_Y(y,data[dataIndex].byte9,data[dataIndex].byte10,2);
						m_GET_Z(z,data[dataIndex].byte11,data[dataIndex].byte12,2);
						break;
				case 0:
						m_GET_X(x,data[dataIndex].byte12,data[dataIndex].byte13,3);
						m_GET_Y(y,data[dataIndex].byte13,data[dataIndex].byte14,3);
						m_GET_Z(z,data[dataIndex].byte14,data[dataIndex].byte15,3);
						break;
				}
											
		
				if (justconnected==1)
				{
					_send_tm();
					justconnected=2;
				}		
				//_send_pdu(x,y,z);
				_send_uncompressed_pdu(x, y, z);

				
					//Send summary activity count
				/*	for (int i=0;(i<summaryindex);i++){
						_send_summary_count(acount[i]);
						acount[i]=0;
					}
					if (summaryindex<AC_BUFFER_SIZE){
						acount[0]=acount[summaryindex];
						summaryindex=0;
					}*/

			}
			else 
			{
				if ((dataSubindex==0) && (batch_counter<750))
					batch_counter++;
				if (connected){
					_greenled_turn_on();
						
					gotack=1;
					tester=0;

					if (_wTM==_TM_Continuous)
						continue;
						
					for (int ixz=0;(ixz<100);ixz++) {                                                                                      
       						_bluetooth_transmit_uart0_byte(0xff); 

							
						if (sampleFlag)
							{
								sampleFlag=0;

								x=_atmega_a2dConvert10bit(ADC0);
		
								y=_atmega_a2dConvert10bit(ADC1);

								z=_atmega_a2dConvert10bit(ADC2);


								vmag+=Filter(x,0)+Filter(y,1)+Filter(z,2);
			

								if (_wPC>40){	//Skip the first samples						
									if (summary_count==0)
									{
										vmag=vmag/24;
										if (vmag>65535)
											acount[ci]=65535;
										else
											acount[ci]=(unsigned short) vmag;
			 							vmag=0;
										++ci;
										if (ci==AC_BUFFER_SIZE)
											ci=0;
										cseq++;
	
										if (ci==si)
										{
											si++;
											if (si==AC_BUFFER_SIZE)
												si=0;
											sseq++;
										}
										acount[ci]=0;
										summary_count=AC_NUMS;
									}else
										summary_count--;
								}
								else if (_wPC==40)
									vmag=0;

			

		
			 					m_SET_X(data[dataIndex],x,dataSubindex);
			 					m_SET_Y(data[dataIndex],y,dataSubindex);
			 					m_SET_Z(data[dataIndex],z,dataSubindex);

			 					dataSubindex++;
			 					if (dataSubindex>=4)
			 					dataSubindex=0;
							}						
					}

					_send_fv();
					_send_sr();					 
					_send_tm();
					_send_batch_count((batch_counter-1)*4);																	
					_send_acs();
					//Send summary activity count
					/*for (int i=0;(i<summaryindex);i++){
						_send_summary_count(acount[i]);
						acount[i]=0;
					}
					if (summaryindex<AC_BUFFER_SIZE){
						acount[0]=acount[summaryindex];
						summaryindex=0;
					}*/

					
					if ((batch_counter>0) && (batch_counter<750)) // Go from 0 up to batch_counter
					{						
						for (int i=0;(i<(batch_counter-1));i++)
						{
							m_GET_X(x,data[i].byte1,data[i].byte2,0);
							m_GET_Y(y,data[i].byte2,data[i].byte3,0);
							m_GET_Z(z,data[i].byte3,data[i].byte4,0);							
							//_send_uncompressed_pdu(x, y, z);
							
							_send_pdu(x,y,z);

							m_GET_X(x,data[i].byte4,data[i].byte5,1);
							m_GET_Y(y,data[i].byte6,data[i].byte7,1);
							m_GET_Z(z,data[i].byte7,data[i].byte8,1);							
							//_send_uncompressed_pdu(x,y, z);
							
							_send_pdu(x,y,z);

							m_GET_X(x,data[i].byte8,data[i].byte9,2);
							m_GET_Y(y,data[i].byte9,data[i].byte10,2);
							m_GET_Z(z,data[i].byte11,data[i].byte12,2);
							//_send_uncompressed_pdu(x, y, z);
							
							_send_pdu(x,y,z);

							m_GET_X(x,data[i].byte12,data[i].byte13,3);
							m_GET_Y(y,data[i].byte13,data[i].byte14,3);
							m_GET_Z(z,data[i].byte14,data[i].byte15,3);							
							//_send_uncompressed_pdu(x, y, z);
							
							_send_pdu(x,y,z);

							_receive_data();


							if (sampleFlag)
							{
								sampleFlag=0;

								x=_atmega_a2dConvert10bit(ADC0);
		
								y=_atmega_a2dConvert10bit(ADC1);

								z=_atmega_a2dConvert10bit(ADC2);


								vmag+=Filter(x,0)+Filter(y,1)+Filter(z,2);
			

								if (_wPC>40){	//Skip the first samples						
									if (summary_count==0)
									{
										vmag=vmag/24;
										if (vmag>65535)
											acount[ci]=65535;
										else
											acount[ci]=(unsigned short) vmag;
			 							vmag=0;
										++ci;
										if (ci==AC_BUFFER_SIZE)
											ci=0;
										cseq++;
	
										if (ci==si)
										{
											si++;
											if (si==AC_BUFFER_SIZE)
												si=0;
											sseq++;
										}
										acount[ci]=0;
										summary_count=AC_NUMS;
									}else
										summary_count--;
								}
								else if (_wPC==40)
									vmag=0;

			

		
			 					m_SET_X(data[dataIndex],x,dataSubindex);
			 					m_SET_Y(data[dataIndex],y,dataSubindex);
			 					m_SET_Z(data[dataIndex],z,dataSubindex);

			 					dataSubindex++;
			 					if (dataSubindex>=4)
			 					dataSubindex=0;
							}
						}

						
						if (batch_counter>0){
						//copy end item into start
						data[0].byte1=data[batch_counter].byte1;
						data[0].byte2=data[batch_counter].byte2;
						data[0].byte3=data[batch_counter].byte3;
						data[0].byte4=data[batch_counter].byte4;
						data[0].byte5=data[batch_counter].byte5;
						data[0].byte6=data[batch_counter].byte6;
						data[0].byte7=data[batch_counter].byte7;
						data[0].byte8=data[batch_counter].byte8;
						data[0].byte9=data[batch_counter].byte9;
						data[0].byte10=data[batch_counter].byte10;
						data[0].byte11=data[batch_counter].byte11;
						data[0].byte12=data[batch_counter].byte12;
						data[0].byte13=data[batch_counter].byte13;
						data[0].byte14=data[batch_counter].byte14;
						data[0].byte15=data[batch_counter].byte15;
						}


					}else{

						int current=dataIndex+1;
						int end =dataIndex;
						if (current>=750)
							current=0;
						while(current!=end)
						{
							m_GET_X(x,data[current].byte1,data[current].byte2,0);
							m_GET_Y(y,data[current].byte2,data[current].byte3,0);
							m_GET_Z(z,data[current].byte3,data[current].byte4,0);							
							//_send_uncompressed_pdu(x, y, z);
							
							_send_pdu(x,y,z);

							m_GET_X(x,data[current].byte4,data[current].byte5,1);
							m_GET_Y(y,data[current].byte6,data[current].byte7,1);
							m_GET_Z(z,data[current].byte7,data[current].byte8,1);							
							//_send_uncompressed_pdu(x, y, z);
							
							_send_pdu(x,y,z);

							m_GET_X(x,data[current].byte8,data[current].byte9,2);
							m_GET_Y(y,data[current].byte9,data[current].byte10,2);
							m_GET_Z(z,data[current].byte11,data[current].byte12,2);
							//_send_uncompressed_pdu(x, y, z);
							
							_send_pdu(x,y,z);

							m_GET_X(x,data[current].byte12,data[current].byte13,3);
							m_GET_Y(y,data[current].byte13,data[current].byte14,3);
							m_GET_Z(z,data[current].byte14,data[current].byte15,3);							
							//_send_uncompressed_pdu(x,y, z);
							
							_send_pdu(x,y,z);

							current++;
							if (current==750)
								current=0;

							_receive_data();


							if (sampleFlag)
							{
								sampleFlag=0;

								x=_atmega_a2dConvert10bit(ADC0);
		
								y=_atmega_a2dConvert10bit(ADC1);

								z=_atmega_a2dConvert10bit(ADC2);


								vmag+=Filter(x,0)+Filter(y,1)+Filter(z,2);
			

								if (_wPC>40){	//Skip the first samples						
									if (summary_count==0)
									{
										vmag=vmag/24;
										if (vmag>65535)
											acount[ci]=65535;
										else
											acount[ci]=(unsigned short) vmag;
			 							vmag=0;
										++ci;
										if (ci==AC_BUFFER_SIZE)
											ci=0;
										cseq++;
	
										if (ci==si)
										{
											si++;
											if (si==AC_BUFFER_SIZE)
												si=0;
											sseq++;
										}
										acount[ci]=0;
										summary_count=AC_NUMS;
									}else
										summary_count--;
								}
								else if (_wPC==40)
									vmag=0;

			

		
			 					m_SET_X(data[dataIndex],x,dataSubindex);
			 					m_SET_Y(data[dataIndex],y,dataSubindex);
			 					m_SET_Z(data[dataIndex],z,dataSubindex);

			 					dataSubindex++;
			 					if (dataSubindex>=4)
			 					dataSubindex=0;
							}
							
						}

						//copy end item into start
						data[0].byte1=data[end].byte1;
						data[0].byte2=data[end].byte2;
						data[0].byte3=data[end].byte3;
						data[0].byte4=data[end].byte4;
						data[0].byte5=data[end].byte5;
						data[0].byte6=data[end].byte6;
						data[0].byte7=data[end].byte7;
						data[0].byte8=data[end].byte8;
						data[0].byte9=data[end].byte9;
						data[0].byte10=data[end].byte10;
						data[0].byte11=data[end].byte11;
						data[0].byte12=data[end].byte12;
						data[0].byte13=data[end].byte13;
						data[0].byte14=data[end].byte14;
						data[0].byte15=data[end].byte15;
					}


			

					
					batch_counter=0;
					dataIndex=0;
					seconds_passed=0;
					while (seconds_passed<400)
					{
						_delay_ms(5);
						seconds_passed++;
						_receive_data();

						if (sampleFlag)
							{
								sampleFlag=0;

								x=_atmega_a2dConvert10bit(ADC0);
		
								y=_atmega_a2dConvert10bit(ADC1);

								z=_atmega_a2dConvert10bit(ADC2);


								vmag+=Filter(x,0)+Filter(y,1)+Filter(z,2);
			

								if (_wPC>40){	//Skip the first samples						
									if (summary_count==0)
									{
										vmag=vmag/24;
										if (vmag>65535)
											acount[ci]=65535;
										else
											acount[ci]=(unsigned short) vmag;
			 							vmag=0;
										++ci;
										if (ci==AC_BUFFER_SIZE)
											ci=0;
										cseq++;
	
										if (ci==si)
										{
											si++;
											if (si==AC_BUFFER_SIZE)
												si=0;
											sseq++;
										}
										acount[ci]=0;
										summary_count=AC_NUMS;
									}else
										summary_count--;
								}
								else if (_wPC==40)
									vmag=0;

			

		
			 					m_SET_X(data[dataIndex],x,dataSubindex);
			 					m_SET_Y(data[dataIndex],y,dataSubindex);
			 					m_SET_Z(data[dataIndex],z,dataSubindex);

			 					dataSubindex++;
			 					if (dataSubindex>=4)
			 					dataSubindex=0;
							}						
					}						
					//connected=0;

					//Don't turn off the radio if a request to switch mode has been received
					if (_wTM==_TM_Continuous)
						_bluetooth_turn_on();	
					else
						_bluetooth_turn_off();		
					
					command_counter=0;
					seconds_disconnected=0;
					_greenled_turn_off();
				
				}
			}
			_atmega_adc_turn_off();
			power_adc_disable();

			if ((dataSubindex==0) && (!connected))
				dataIndex++;			
			if (dataIndex==750)
				dataIndex=0;
			connected=0;			
			
		}	
		
			cli();
			set_sleep_mode(SLEEP_MODE_IDLE);
			//set_sleep_mode(SLEEP_MODE_PWR_SAVE);
    		sleep_enable();
    		sleep_bod_disable(); 	
    		sei();
    		sleep_cpu();
    		sleep_disable();


	}

	return 0;
}