示例#1
0
int main(void) {
  wdt_enable(WDTO_1S);                           /* enable 1s watchdog */
  WDTCSR &= ~(1 << WDE);                    /* don't reset on watchdog */
  sei();                                   /* enable global interrupts */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);           /* deepest sleep mode */
  power_all_disable();                     /* disable all peripherals. */
                           /* only matters during brief awake periods, */
                                       /* but we're saving power here. */
#if DEBUG_LED
  LED_DDR |= (1 << LED);                          /* enable LED output */
#endif
  while (1) {
    WDTCSR |= (1 << WDIE);             /* re-enable watchdog interrupt */
                              /* (it's disabled each time it wakes up) */
    sleep_mode();                                  /* then to go sleep */
#if DEBUG_LED
    LED_PORT ^= (1 << LED);         /* enable LED output for diagnosis */
#endif
    if (days == 30) {
      // execute something 30 days after this started running.
    }

  }                                                  /* End event loop */
  return (0);
}
示例#2
0
void Pendant::sleepNow() {
  disableLEDs();

  PCMSK0 |= _BV(PCINT0);  // Watch pin PB1
  GIFR   |= _BV(PCIE0);   // clear any outstanding interrupts

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  power_all_disable();  // power off ADC, Timer 0 and 1, serial interface
  sleep_enable();
  sleep_cpu();


  //
  // ... SLEEPING ...
  //


  // resumes here on wake
  sleep_disable();
  power_all_enable();    // power everything back on
  PCMSK0 &= ~_BV(PCINT0); // Turn off PB1 as interrupt pin

  sleepOnRelease = false;
  changeModeOnRelease = false;
  digitalWrite(PENDANT_LED_PWR_PIN, HIGH);
}
示例#3
0
int main (void) {

  //we re not in a power critical environment
  //but nevertheless switch off everything
  power_all_disable();
  //reset ports & pins
  DDRB = 0;
  PORTB = 0;
  DDRA = 0;
  PORTB = 0;

  //Start everything
  led_init();
  led_on();
  uint8_t result = accelerator_init();
  if (result==0) {
    led_off();
    led_start();
    //and let the games begin
    sei();
  }

  while (1) {
    led_calculate();
  }

}
示例#4
0
// enable low-power detection and disables microcontroller modules
void system_init(void) {
    system.initial_mcusr = MCUSR;  // save MCUSR
    MCUSR = 0;  // clear any watchdog timer flags
    wdt_enable(WDTO_8S);  // enable eight-second watchdog timer

    system.status &= ~SYSTEM_SLEEP;

    // enable pull-up resistors on unused pins to ensure a defined value
#ifndef VFD_ANODE_GRID_TO_SPEC
    PORTB |= _BV(PB4);
#endif  // ~VFD_ANODE_GRID_TO_SPEC
    // leave PC1 tri-stated in case clock is wired
    // for the depricated exteneded battery hack
#ifndef VFD_CATHODE_TO_SPEC
    PORTC |= _BV(PC2);
#endif  // ~VFD_CATHODE_TO_SPEC

    // use internal bandgap as reference for analog comparator
    // and enable analog comparator interrupt on falling edge
    // of AIN1 (interrupt triggers when adaptor power fails)
    ACSR = _BV(ACBG) | _BV(ACIE) | _BV(ACI);

    // disable digital input on analog comparator input, AIN1
    DIDR1 = _BV(AIN1D);

    // disable all features for power savings; individual features are enabled
    // one-by-one in appropriate submodules
    power_all_disable();
}
示例#5
0
文件: main.c 项目: jmesmon/avrbits
static inline void init(void)
{
	power_all_disable();
	debug_led_init();
	clock_prescale_set(clock_div_1);
	spi_io_init();
	adc_init();
	motor_init();
	sei();
}
示例#6
0
/*function to turn off all periferlas of the radian as well as to send uC into low power mode
in the event of a low battery condition
 */
void Radian_power_saver::EnterDeepSleepMode(){
    POWER_OFF;
    if(DEBUG) Serial.println("Entering Deep Sleep Mode");
    //Disable ADC and internal Vref
    digitalWrite(BOOST_EN, LOW);
    POWER_OFF;
    ADMUX &= ~( (1<<REFS1) | (1<<REFS0) );
    ADCSRA &= ~( (1<<ADEN) );
    
    //Disable AnalogComparator
    ACSR |= (1<<ACD); 
    
    DIDR0 = 0xFF;
    //  DIDR1 = 0xFF;
    DIDR2 = 0xFF;
    
    
    
    //disable watchdog timer
    cli();
    wdt_reset();
    // Clear WDRF in MCUSR 
    MCUSR &= ~(1<<WDRF);
    MCUCR |= (1<<JTD);//disable on chip debug system by writing 1 to JTD bit in MCUCR
    // Write logical one to WDCE and WDE 
    // Keep old prescaler setting to prevent unintentional time-out
     
    WDTCSR |= (1<<WDCE) | (1<<WDE);
    // Turn off WDT 
    WDTCSR = 0x00;
    
    //disable port pins by writing to digital input disable register DIDR1
    
    //disable USB
    PRR0 = 0xFF; //turn off all periferals in the power reduction registers
    PRR1 = 0xFF; 
    
    wdt_disable();
    //bod_disable();
    power_usart0_disable();
    power_usart1_disable();
    power_spi_disable();
    power_adc_disable();
    power_all_disable();
    POWER_OFF;
    cli(); //disable all interrupts
    SMCR = B00000101; //enable sleep mode (bit0 set) and set to POWER DOWN mode (lowest consumption)
    sleep_mode(); //go into sleep
    
    
    
}
示例#7
0
文件: compass.c 项目: iospace/compass
/* Configure the pins on the ATmega328p */
void InitDevice() {
    /* Disable all possible devices on the board */
    power_all_disable();

    /* LCD setup */
    /* All PORTB pins are data pins for the LCD screen */
    DDRB = (uint8_t)(-1);

    /* PDO, PD1, and PD3 are all used as control pins for the LCD screen.
     * PD0 is used as the R/S pin, which determines whether the LCD is getting a
     * command or a character
     * PD1 is the Enable pin, which signals the LCD to read the data pins
     * PD3 is the R/W Pin which is used to activate the Busy flag on the LCD and
     * is used for timing
     */
    DDRD |= (_BV(PD0) | _BV(PD1) | _BV(PD3));

    LcdInit();

    /* Display title screen */
    LcdWriteString(TITLE, LCD_LINE_ONE);
    LcdWriteString(NAME, LCD_LINE_TWO);
    _delay_ms(STARTUP_DELAY);

    LcdWriteString(BOOTUP, LCD_LINE_TWO);

    /* Calibration circuit */
    /* PD4 is used to determine if the calibration circuit is active or not */
    DDRD &= ~_BV(PD4); /* Configure PD4 as an input */
    PORTD |= _BV(PD4); /* Pullup PD4 */

    /* Configure the ADC */
    //Currently not implemented
    //power_adc_enable();

    /* Magnetometer set up */
    /* INT0 is attached to the DataReady pin on the magnometer, and will be used
     * to signal that data is ready to be read (obviously).  INT0 is set to go
     * off on a rising edge.
     */
    EIMSK |= _BV(INT0);
    EICRA |= _BV(ISC01) | _BV(ISC00);

    /* Configure TWI */
    power_twi_enable();
    TWCR = _BV(TWEN); /* Enable TWI */ //May not be needed here, but definitely elsewhere
    //Check to see if the magnetometer needs initialization from the ATmega
    //will need init
    //Display "Waiting on data" on line 2
}
示例#8
0
/*******************************************************************************
 * Power down processor
 * Don't forget to switch off the LED and the RF module for lowest consumption.
 * Board quiescent current budget:
 * charge circuit = 180 nA
 * ATmega328P deep sleep = 120 nA
 * regulators quiescent currents = 30 nA
 *******************************************************************************/
void TheAirBoard::powerDown() {
  byte br_high = UBRR0H, br_low = UBRR0L; // save baudrate register 
  Serial.end();
  digitalWrite(RX, LOW);           // reset internal pull-up serial link
  ADCSRA &= B01111111;             // disable ADC
  power_all_disable();
  /****************DON'T CHANGE************************************************/
  MCUCR = B01100000;               // BOD disable timed sequence
  MCUCR = B01000000;
  SMCR = B00000101;                // power down mode + sleep enable
  asm("sleep\n");
  sleep_disable();                 // first thing after wake up
  /****************************************************************************/
  power_all_enable();
  ADCSRA |= B10000000;             // enable ADC
  UBRR0H = br_high;                // set baud rate MSB
  UBRR0L = br_low;                 // set baud rate LSB
  UCSR0B |= (1<<RXCIE0)|(1<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0); // enable uart
}
示例#9
0
void
sleep()
{
    LINCR = 0;                  // stop the LIN block
    ms_delay(20);               // wait for any frame to complete (seems necessary to avoid hangs?)
    power_all_disable();        // turn off all of the peripherals we can

    // Put the board to sleep.
    //
    pinLINTX.set();         // make sure TX is 1
    pinLINCS.clear();       // make sure CS is 0
    pinLINCS.cfg_output();  // make sure CS is an output (will be low now)
    pinLINTX.cfg_output();  // make sure TX is an output (will be high now)
    pinLINTX.clear();       // drive TX low to turn off power
    for (;;) {
        // If we fail to power down, e.g. because LIN traffic causes the regulator to stay on,
        // the watchdog will pull us back out via the reset path after ~500ms.
    }
}
示例#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;
		}
	}
}