void ArduboyPlaytune::initChannel(byte pin)
{
  byte timer_num;

  // we are all out of timers
  if (_tune_num_chans == AVAILABLE_TIMERS)
    return;

  timer_num = pgm_read_byte(tune_pin_to_timer_PGM + _tune_num_chans);
  _tune_pins[_tune_num_chans] = pin;
  _tune_num_chans++;
  pinMode(pin, OUTPUT);
  switch (timer_num) {
    case 1: // 16 bit timer
      power_timer1_enable();
      TCCR1A = 0;
      TCCR1B = 0;
      bitWrite(TCCR1B, WGM12, 1);
      bitWrite(TCCR1B, CS10, 1);
      _tunes_timer1_pin_port = portOutputRegister(digitalPinToPort(pin));
      _tunes_timer1_pin_mask = digitalPinToBitMask(pin);
      break;
    case 3: // 16 bit timer
      power_timer3_enable();
      TCCR3A = 0;
      TCCR3B = 0;
      bitWrite(TCCR3B, WGM32, 1);
      bitWrite(TCCR3B, CS30, 1);
      _tunes_timer3_pin_port = portOutputRegister(digitalPinToPort(pin));
      _tunes_timer3_pin_mask = digitalPinToBitMask(pin);
      playNote(0, 60);  /* start and stop channel 0 (timer 3) on middle C so wait/delay works */
      stopNote(0);
      break;
  }
}
Example #2
0
//---------------------------------------------------------------------------
void SndInit(void)
{
	_Memset(&Snd, 0x00, sizeof(ST_SND));

	pinMode(SND_PIN1, OUTPUT);
	Snd.ch[0].pPinPort = portOutputRegister(digitalPinToPort(SND_PIN1));
	Snd.ch[0].pinMask  = digitalPinToBitMask(SND_PIN1);

#if defined(ARDUBOY_10)

	pinMode(SND_PIN2, OUTPUT);
	Snd.ch[1].pPinPort = portOutputRegister(digitalPinToPort(SND_PIN2));
	Snd.ch[1].pinMask  = digitalPinToBitMask(SND_PIN2);

#endif


	TCCR3A = 0;
	TCCR3B = 0;
	TCCR1A = 0;
	TCCR1B = 0;

	bitWrite(TCCR3B, WGM32, 1);
	bitWrite(TCCR3B, CS30,  1);
	bitWrite(TCCR1B, WGM12, 1);
	bitWrite(TCCR1B, CS10,  1);

	power_timer3_enable();
	power_timer1_enable();
}
Example #3
0
void	LowPowerClass::idle(period_t period, adc_t adc, 
							            timer1_t timer1, timer0_t timer0)
{
	if (adc == ADC_OFF)	
	{
		ADCSRA &= ~(1 << ADEN);
		power_adc_disable();
	}

	if (timer1 == TIMER1_OFF)	power_timer1_disable();	
	if (timer0 == TIMER0_OFF)	power_timer0_disable();	
	
	if (period != SLEEP_FOREVER)
	{
		wdt_enable(period);
		WDTCR |= (1 << WDIE);	
	}
	
	lowPowerBodOn(SLEEP_MODE_IDLE);
	
	if (adc == ADC_OFF)
	{
		power_adc_enable();
		ADCSRA |= (1 << ADEN);
	}

	if (timer1 == TIMER1_OFF)	power_timer1_enable();	
	if (timer0 == TIMER0_OFF)	power_timer0_enable();	
}
Example #4
0
void cube_start(uint8_t unused)
{
	// Set sleep mode to lighter
	mode = old_mode;

	power_adc_enable();
	power_spi_enable();
	power_timer0_enable();
	power_timer1_enable();

	// Enable BLANK timer interrupt (starts SPI)
	TIMSK0 |= (1 << OCIE0A);
}
Example #5
0
/*********************************************************************************************************
** Function name:           wakeUp
** Descriptions:            wakeUp
*********************************************************************************************************/
void xadow::wakeUp()
{
#if defined(__AVR_ATmega32U4__)
    power_adc_enable();
    power_usart0_enable();
    power_spi_enable();
    power_twi_enable();
    power_timer1_enable();
    power_timer2_enable();
    power_timer3_enable();
    power_usart1_enable();
    power_usb_enable();
#endif
}
Example #6
0
void	Low_Power::idle(Period_t period, ADC_t adc,
                        Timer4_t timer4, Timer3_t timer3,
                        Timer1_t timer1, Timer0_t timer0,
                        SPI_t spi, USART1_t usart1,	TWI_t twi, usb_t usb)
{
    if (adc == ADC_OFF)
    {
        ADCSRA &= ~(1 << ADEN);
        power_adc_disable();
    }

    if (timer4 == TIMER4_OFF)	power_timer4_disable();
    if (timer3 == TIMER3_OFF)	power_timer3_disable();
    if (timer1 == TIMER1_OFF)	power_timer1_disable();
    if (timer0 == TIMER0_OFF)	power_timer0_disable();
    if (spi == SPI_OFF)				power_spi_disable();
    if (usart1 == USART1_OFF)	power_usart1_disable();
    if (twi == TWI_OFF)				power_twi_disable();
    if (usb == USB_OFF)				power_usb_disable();

    if (period != SLEEP_FOREVER)
    {
        wdt_enable(period);
        WDTCSR |= (1 << WDIE);
    }

    lowPowerBodOn(SLEEP_MODE_IDLE);

    if (adc == ADC_OFF)
    {
        power_adc_enable();
        ADCSRA |= (1 << ADEN);
    }

    if (timer4 == TIMER4_OFF)	power_timer4_enable();
    if (timer3 == TIMER3_OFF)	power_timer3_enable();
    if (timer1 == TIMER1_OFF)	power_timer1_enable();
    if (timer0 == TIMER0_OFF)	power_timer0_enable();
    if (spi == SPI_OFF)				power_spi_enable();
    if (usart1 == USART1_OFF)	power_usart1_enable();
    if (twi == TWI_OFF)				power_twi_enable();
    if (usb == USB_OFF)				power_usb_enable();
}
Example #7
0
void	Low_Power::idle(Period_t period, ADC_t adc, Timer5_t timer5,
                        Timer4_t timer4, Timer3_t timer3, Timer2_t timer2,
                        Timer1_t timer1, Timer0_t timer0, SPI_t spi,
                        USART3_t usart3, USART2_t usart2, USART1_t usart1,
                        USART0_t usart0, TWI_t twi)
{
    // Temporary clock source variable
    unsigned char clockSource = 0;

    if (timer2 == TIMER2_OFF)
    {
        if (TCCR2B & CS22) clockSource |= (1 << CS22);
        if (TCCR2B & CS21) clockSource |= (1 << CS21);
        if (TCCR2B & CS20) clockSource |= (1 << CS20);

        // Remove the clock source to shutdown Timer2
        TCCR2B &= ~(1 << CS22);
        TCCR2B &= ~(1 << CS21);
        TCCR2B &= ~(1 << CS20);

        power_timer2_disable();
    }

    if (adc == ADC_OFF)
    {
        ADCSRA &= ~(1 << ADEN);
        power_adc_disable();
    }

    if (timer5 == TIMER5_OFF)	power_timer5_disable();
    if (timer4 == TIMER4_OFF)	power_timer4_disable();
    if (timer3 == TIMER3_OFF)	power_timer3_disable();
    if (timer1 == TIMER1_OFF)	power_timer1_disable();
    if (timer0 == TIMER0_OFF)	power_timer0_disable();
    if (spi == SPI_OFF)			  power_spi_disable();
    if (usart3 == USART3_OFF)	power_usart3_disable();
    if (usart2 == USART2_OFF)	power_usart2_disable();
    if (usart1 == USART1_OFF)	power_usart1_disable();
    if (usart0 == USART0_OFF)	power_usart0_disable();
    if (twi == TWI_OFF)			  power_twi_disable();

    if (period != SLEEP_FOREVER)
    {
        wdt_enable(period);
        WDTCSR |= (1 << WDIE);
    }

    lowPowerBodOn(SLEEP_MODE_IDLE);

    if (adc == ADC_OFF)
    {
        power_adc_enable();
        ADCSRA |= (1 << ADEN);
    }

    if (timer2 == TIMER2_OFF)
    {
        if (clockSource & CS22) TCCR2B |= (1 << CS22);
        if (clockSource & CS21) TCCR2B |= (1 << CS21);
        if (clockSource & CS20) TCCR2B |= (1 << CS20);

        power_timer2_enable();
    }

    if (timer5 == TIMER5_OFF)	power_timer5_enable();
    if (timer4 == TIMER4_OFF)	power_timer4_enable();
    if (timer3 == TIMER3_OFF)	power_timer3_enable();
    if (timer1 == TIMER1_OFF)	power_timer1_enable();
    if (timer0 == TIMER0_OFF)	power_timer0_enable();
    if (spi == SPI_OFF)			  power_spi_enable();
    if (usart3 == USART3_OFF)	power_usart3_enable();
    if (usart2 == USART2_OFF)	power_usart2_enable();
    if (usart1 == USART1_OFF)	power_usart1_enable();
    if (usart0 == USART0_OFF)	power_usart0_enable();
    if (twi == TWI_OFF)			  power_twi_enable();
}
Example #8
0
void ArduboyAudio::on()
{
  power_timer1_enable();
  power_timer3_enable();
  audio_enabled = true;
}
Example #9
0
/*******************************************************************************
* Name: idle
* Description: Putting microcontroller into idle state. Please make sure you 
*			   understand the implication and result of disabling module.
*
* Argument  	Description
* =========  	===========
* 1. period     Duration of low power mode. Use SLEEP_FOREVER to use other wake
*				up resource:
*				(a) SLEEP_15MS - 15 ms sleep
*				(b) SLEEP_30MS - 30 ms sleep
*				(c) SLEEP_60MS - 60 ms sleep
*				(d) SLEEP_120MS - 120 ms sleep
*				(e) SLEEP_250MS - 250 ms sleep
*				(f) SLEEP_500MS - 500 ms sleep
*				(g) SLEEP_1S - 1 s sleep
*				(h) SLEEP_2S - 2 s sleep
*				(i) SLEEP_4S - 4 s sleep
*				(j) SLEEP_8S - 8 s sleep
*				(k) SLEEP_FOREVER - Sleep without waking up through WDT
*
* 2. adc		ADC module disable control:
*				(a) ADC_OFF - Turn off ADC module
*				(b) ADC_ON - Leave ADC module in its default state
*
* 3. timer2		Timer 2 module disable control:
*				(a) TIMER2_OFF - Turn off Timer 2 module
*				(b) TIMER2_ON - Leave Timer 2 module in its default state
*
* 4. timer1		Timer 1 module disable control:
*				(a) TIMER1_OFF - Turn off Timer 1 module
*				(b) TIMER1_ON - Leave Timer 1 module in its default state
*
* 5. timer0		Timer 0 module disable control:
*				(a) TIMER0_OFF - Turn off Timer 0 module
*				(b) TIMER0_ON - Leave Timer 0 module in its default state
*
* 6. spi		SPI module disable control:
*				(a) ADC_OFF - Turn off ADC module
*				(b) ADC_ON - Leave ADC module in its default state
*
* 7. usart0		USART0 module disable control:
*				(a) USART0_OFF - Turn off USART0  module
*				(b) USART0_ON - Leave USART0 module in its default state
*
* 8. twi		TWI module disable control:
*				(a) TWI_OFF - Turn off TWI module
*				(b) TWI_ON - Leave TWI module in its default state
*
*******************************************************************************/
void	LowPowerClass::idle(period_t period, adc_t adc, timer2_t timer2, 
							timer1_t timer1, timer0_t timer0,
							spi_t spi, usart0_t usart0,	twi_t twi)
{
	// Temporary clock source variable 
	unsigned char clockSource = 0;
	
	if (timer2 == TIMER2_OFF)
	{
		if (TCCR2B & CS22) clockSource |= (1 << CS22);
		if (TCCR2B & CS21) clockSource |= (1 << CS21);
		if (TCCR2B & CS20) clockSource |= (1 << CS20);
	
		// Remove the clock source to shutdown Timer2
		TCCR2B &= ~(1 << CS22);
		TCCR2B &= ~(1 << CS21);
		TCCR2B &= ~(1 << CS20);
		
		power_timer2_disable();
	}
	
	if (adc == ADC_OFF)	
	{
		ADCSRA &= ~(1 << ADEN);
		power_adc_disable();
	}
	
	if (timer1 == TIMER1_OFF)	power_timer1_disable();	
	if (timer0 == TIMER0_OFF)	power_timer0_disable();	
	if (spi == SPI_OFF)			power_spi_disable();
	if (usart0 == USART0_OFF)	power_usart0_disable();
	if (twi == TWI_OFF)			power_twi_disable();
	
	if (period != SLEEP_FOREVER)
	{
		wdt_enable(period);
		WDTCSR |= (1 << WDIE);	
	}
	
	lowPowerBodOn(SLEEP_MODE_IDLE);
	
	if (adc == ADC_OFF)
	{
		power_adc_enable();
		ADCSRA |= (1 << ADEN);
	}
	
	if (timer2 == TIMER2_OFF)
	{
		if (clockSource & CS22) TCCR2B |= (1 << CS22);
		if (clockSource & CS21) TCCR2B |= (1 << CS21);
		if (clockSource & CS20) TCCR2B |= (1 << CS20);
		
		power_timer2_enable();
	}
	
	if (timer1 == TIMER1_OFF)	power_timer1_enable();	
	if (timer0 == TIMER0_OFF)	power_timer0_enable();	
	if (spi == SPI_OFF)			power_spi_enable();
	if (usart0 == USART0_OFF)	power_usart0_enable();
	if (twi == TWI_OFF)			power_twi_enable();
}
Example #10
0
int main(void)
{
	// set clock prescaler for 8MHz
	CLKPR = 0x80;
	CLKPR = 0x01;

	cli();

	power_all_disable();
	power_spi_enable();
	power_timer1_enable();
	set_sleep_mode(SLEEP_MODE_IDLE);

	pins_init();

	delay_ms(345); // arbitrary

	uint8_t dpi = 0x0f; // default to 800
	if (!(PIND & (1<<0))) // if left is pressed at boot
		dpi = 0xff; // set to 12800

	pmw3366_init(dpi);
	nrf24_init();

	// button stuff
	// previous debounced state
	uint8_t btn_prev = ~(PIND);
	// time (in 125us) button has been unpressed.
	// consider button to be released if this time exceeds DEBOUNCE_TIME.
	uint8_t btn_time[3] = {0, 0, 0};

	// absolute positions. relies on integer overflow
	union motion_data x = {0}, y = {0};

	// wheel stuff
	uint8_t whl_prev_same = 0; // what A was the last time A == B
	uint8_t whl_prev_diff = 0; // what A was the last time A != B
	// absolute scroll position. relies on integer overflow
	int8_t whl = 0;

	// begin burst mode for 3366
	spi_set3366mode();
	SS_3366_LOW;
	spi_3366_write(0x50, 0x00);
	SS_3366_HIGH;

	// set up timer1 to set OCF0A in TIFR0 every 1ms
	TCCR1A = 0x00;
	TCCR1B = 0x09; // CTC, 8MHz
	OCR1A = 7999; // main loop nominal period (7999 + 1) / 8MHz = 1ms
	OCR1B = 320; // timing of when to read burst mode data from sensor
	OCR1C = 800; // timing of when to load nrf24l01+ with data

	// let receiver know if it's the first time sending data, so that it
	// can reset the reference for absolute position and that there's no
	// jump when rebooting the mouse
	// uint8_t first = 0x80; // transmitted as MSB with button data below.

	// when sync reaches 0, always send a packet with bit 6 in btn set, to
	// tell the receiver to calculate the timing offset.
	// when sync reaches 1, always send a packet requesting ACK to load the
	// timing offset
	// i.e. when it overflows, so 256ms periodicity.

	// when sync reaches 0, afk increments.
	// afk is cleared by any motion or button press.
	// when afk reaches AFK_TIMEOUT, go into powerdown mode.
	for (uint8_t first = 0x80, sync = 0, afk = 0; ; first = 0, sync++) {
		// sync to 1ms intervals using timer1
	//	if (TIFR1 & (1<<OCF1A)) PORTD |= (1<<6);
		TIMSK1 |= (1<<OCIE1A);
		sei(); sleep_mode(); cli();
		TIMSK1 &= ~(1<<OCIE1A);
		TIFR1 |= (1<<OCF1A); TIFR1 |= (1<<OCF1B); TIFR1 |= (1<<OCF1C);

		// begin burst mode read
		spi_set3366mode();
		SS_3366_LOW;
		spi_send(0x50);
		// do stuff here instead of busy waiting for 35us

		// read wheel
		int8_t dwhl = 0;
		const uint8_t whl_a = WHL_A_IS_HIGH;
		const uint8_t whl_b = WHL_B_IS_HIGH;
	//	if (whl_a == whl_b) {
	//		if (whl_a != whl_prev_same) {
	//			dwhl = 2 * (whl_a ^ whl_prev_diff) - 1;
	//			whl += dwhl;
	//			whl_prev_same = whl_a;
	//		}
	//	} else
	//		whl_prev_diff = whl_a;
		if (whl_a != whl_b)
			whl_prev_diff = whl_a;
		else if (whl_a != whl_prev_same) {
			dwhl = 2 * (whl_a ^ whl_prev_diff) - 1;
			whl += dwhl;
			whl_prev_same = whl_a;
		}

		// read buttons
		/*
		PIND 0 EIFR 0: low, no edges -> is low
		PIND 0 EIFR 1: low, edge -> is low
		PIND 1 EIFR 0: high, no edges -> always high during last 1ms
		PIND 1 EIFR 1: high, edge -> low at some point in the last 1ms
		*/
		const uint8_t btn_unpressed = PIND & ~(EIFR);
		EIFR = 0b00000111; // clear EIFR
		// manual loop debouncing for every button
		uint8_t btn_dbncd = 0x00;
		#define DEBOUNCE(index) \
		if ((btn_prev & (1<<index)) && (btn_unpressed & (1<<index))) { \
			btn_time[index]++; \
			if (btn_time[index] < DEBOUNCE_TIME) \
				btn_dbncd |= (1<<index); \
		} else { \
			btn_time[index] = 0; \
			btn_dbncd |= (~btn_unpressed) & (1<<index); \
		}

		DEBOUNCE(0);
		DEBOUNCE(1);
		DEBOUNCE(2);
		#undef DEBOUNCE

		// wait until 35us have elapsed since spi_send(0x50)
	//	if (TIFR1 & (1<<OCF1B)) PORTD |= (1<<6);
		TIMSK1 |= (1<<OCIE1B);
		sei(); sleep_mode(); cli();
		TIMSK1 &= ~(1<<OCIE1B);

		union motion_data dx, dy;
		spi_send(0x00); // motion, not used
		spi_send(0x00); // observation, not used
		dx.lo = spi_recv();
		dx.hi = spi_recv();
		dy.lo = spi_recv();
		dy.hi = spi_recv();
		SS_3366_HIGH;

		x.all += dx.all;
		y.all += dy.all;

		if (sync == 0) afk++;
		const uint8_t changed = (btn_dbncd != btn_prev) || dx.all || dy.all || dwhl;
		if (changed) afk = 0;

		if (changed || (sync <= 1)) {
			btn_prev = btn_dbncd;
			// W_TX_PAYLOAD if sync == 1, W_TX_PAYLOAD_NOACK otherwise
			const uint8_t mode = (sync == 1) ? 0b10100000 : 0b10110000;
			// send miscellaneous info using top bits of btn byte
			uint8_t btn_send = btn_dbncd | first; // first is either 0x80 or 0
			if (sync == 0) btn_send |= 0x40;

			// try to transmit at the same time every frame
	//		if (TIFR1 & (1<<OCF1C)) {PORTD |= (1<<6);}
			TIMSK1 |= (1<<OCIE1C);
			sei(); sleep_mode(); cli();
			TIMSK1 &= ~(1<<OCIE1C);

			spi_setnrf24mode();
			SS_NRF24_LOW;
			spi_send(0x20 | 0x07); // STATUS
			spi_send(0b01110000); // clear IRQ
			SS_NRF24_HIGH;
			SS_NRF24_LOW;
			spi_send(0b11100001); // flush tx
			SS_NRF24_HIGH;
			SS_NRF24_LOW;
			spi_send(0b11100010); // flush rx
			SS_NRF24_HIGH;

			SS_NRF24_LOW;
			spi_send(mode);
			spi_send(btn_send);
			spi_send(x.lo);
			spi_send(x.hi);
			spi_send(y.lo);
			spi_send(y.hi);
			spi_send(whl);
			SS_NRF24_HIGH;

			// pulse CE to transmit
			CE_HIGH;
			delay_us(12);
			CE_LOW;

			if (sync == 1) { // get ack payload of timing offset
				delay_us(400);
				if (IRQ_IS_LOW) {
					// recycle motion_data union for timing
					union motion_data offset;
					SS_NRF24_LOW;
					spi_send(0b01100001);
					offset.lo = spi_recv();
					offset.hi = spi_recv();
					SS_NRF24_HIGH;
					// shift TCNT1 by the offset, plus a
					// little more because of the time it
					// takes to add stuff to TCNT1.
					TCNT1 += offset.all + 11;
				}
			}
		}

		// power down if afk
		if (afk > AFK_TIMEOUT) {
			// enable external interrupts on INT0/1/2/3, PCINT0
			EIMSK = 0b00000111;
			PCICR = 0x01;
			// go power down mode; wake up on interrupt
			set_sleep_mode(SLEEP_MODE_PWR_DOWN);
			sei(); sleep_mode(); cli();
			// disable external interrupts
			PCICR = 0;
			EIMSK = 0;
			// restore state
			set_sleep_mode(SLEEP_MODE_IDLE);
			sync = 0;
			afk = 0;
		}
	}
}
Example #11
0
// Shutdown
void bg_pwr_down()
{
  // execute sleep routine
  if (bg_pwr_exec_sleep_routine_flag)
  {
    if (bg_pwr_on_sleep != NULL)
      bg_pwr_on_sleep();
    // the flag is needed because we want to execute sleep
    // routine only when we go from pwr up to pwr down
    bg_pwr_exec_sleep_routine_flag = 0;
  }

  //Shut off ADC, TWI, SPI, Timer0, Timer1, Timer2

  ADCSRA &= ~(1<<ADEN); //Disable ADC
  ACSR |= (1<<ACD); //Disable the analog comparator
  DIDR0 = 0xFF; //Disable digital input buffers on all ADC0-ADC5 pins
  DIDR1 = (1<<AIN1D)|(1<<AIN0D); //Disable digital input buffer on AIN1/0

  power_twi_disable();
  power_spi_disable();
  power_usart0_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();
#if defined(__AVR_ATmega1284P__)
  power_timer3_disable();
#endif

  //Power down various bits of hardware to lower power usage  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();

  /*********/
  /* SLEEP */
  /*********/

  // The processor wakes up back here after interrupt

  //Turn on ADC, TWI, SPI, Timer0, Timer1, Timer2
  ADCSRA |= (1<<ADEN); // Enable ADC
  ACSR &= ~(1<<ACD);   // Enable the analog comparator

  // this should be set to reflect real usage of analog pins
  DIDR0 = 0x00;   // Enable digital input buffers on all ADC0-ADC5 pins
  DIDR1 &= ~(1<<AIN1D)|(1<<AIN0D); // Enable digital input buffer on AIN1/0

  power_twi_enable();
  power_spi_enable();
  power_usart0_enable();
  power_timer0_enable();
  power_timer1_enable();
  power_timer2_enable();
#if defined(__AVR_ATmega1284P__)
  power_timer3_enable();
#endif

  // check button press time and handle state
  unsigned long start = millis();
  while ( (ellapsed_millis(start) < BG_PWR_BUTTON_TIME) && (digitalRead(bg_pwr_switch_pin) == HIGH) );
  // if the button is pressed continuously for 2 seconds, swap to on state
  if (ellapsed_millis(start) >= BG_PWR_BUTTON_TIME)
    bg_pwr_state = BG_STATE_PWR_UP;

  // lower the button flag
  bg_pwr_button_pressed_flag = 0;

  // execute wake up routine only if we really woke up
  if (bg_pwr_state == BG_STATE_PWR_UP || sd_reader_interrupted)
  {
    // execute wake up routine if any is defined
    if (bg_pwr_on_wakeup != NULL)
      bg_pwr_on_wakeup();
    // next time we sleep execute sleep routine
    bg_pwr_exec_sleep_routine_flag = 1; 
  }
}
Example #12
0
/*this mode turns off everything not needed during the time in which only the main counter is running
 The only things needed during simple sleep are the operation of basic pins and the timer1 interrupt
 */
void Radian_power_saver::EnterSimpleSleep(unsigned int IdlePWM ){
    
  /*  
    
    //Disable ADC and internal Vref
    POWER_OFF;
    ADMUX &= ~( (1<<REFS1) | (1<<REFS0));
    ADCSRA &= ~( (1<<ADEN) );
    //Disable AnalogComparator
    ACSR |= (1<<ACD); 
    
    
    
    SMCR = 1; //go into idle mode
    sleep_mode();
    POWER_ON;
   
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
    sleep_enable();
    interrupts();
 //   attachInterrupt(0,sleepHandler, FALLING);
    sleep_mode();  //sleep now
    //--------------- ZZZZZZ sleeping here
    sleep_disable(); //fully awake now
    POWER_ON; //turn the power back on
   
  */
    
    
    if(DEBUG) Serial.println("Entering simple Sleep Mode");
    if(IdlePWM == 0) SetIdlePins(PAN);
    else SetIdlePins(TILT);
//    power_all_disable(); //turn off all modules
    
    //turn necessary idle ports back on
    power_usart0_enable();
    power_timer1_enable();
 //   power_timer4_enable(); //leave PWM module on, should make something smarter for future
    
    set_sleep_mode(SLEEP_MODE_IDLE);  
    sleep_enable();
    //  interrupts();
    //  attachInterrupt(0,sleepHandler, FALLING);
    
    sleep_mode();  //sleep now
    //--------------- ZZZZZZ sleeping here
    sleep_disable(); //fully awake now
   // Serial.println("Woke up");
    POWER_ON;
    power_all_enable();
    if(IdlePWM == 0) WakeUpPins(PAN);
    else WakeUpPins(TILT);

    
    /*power_adc_enable();
    power_timer0_enable();
    power_usart1_enable();
    power_useart0_enable();
     
     */
    
}