int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) {
    // Disable interrupts until going to sleep, otherwise interrupts occurring between attachInterrupt()
    // and sleep might cause the ATMega to not wakeup from sleep as interrupt has already be handled!
	cli();
	// attach interrupts 
    _wakeUp1Interrupt  = interrupt1;
    _wakeUp2Interrupt  = interrupt2;
    if (interrupt1 != INVALID_INTERRUPT_NUM) attachInterrupt(interrupt1, wakeUp1, mode1);
	if (interrupt2 != INVALID_INTERRUPT_NUM) attachInterrupt(interrupt2, wakeUp2, mode2);
	
	if (ms>0) {
		// sleep for defined time
		hwInternalSleep(ms);
	} else {
		// sleep until ext interrupt triggered
    	hwPowerDown(SLEEP_FOREVER);
	}
    
    // Assure any interrupts attached, will get detached when they did not occur.
    if (interrupt1 != INVALID_INTERRUPT_NUM) detachInterrupt(interrupt1);
	if (interrupt2 != INVALID_INTERRUPT_NUM) detachInterrupt(interrupt2);

    // Return what woke the mcu.
    int8_t ret = MY_WAKE_UP_BY_TIMER;       // default: no interrupt triggered, timer wake up	
    if (interruptWakeUp()) ret = static_cast<int8_t>(_wokeUpByInterrupt);

    // Clear woke-up-by-interrupt flag, so next sleeps won't return immediately.
    _wokeUpByInterrupt = INVALID_INTERRUPT_NUM;

	return ret;
}
Beispiel #2
0
int8_t hwSleep(const uint8_t interrupt1, const uint8_t mode1, const uint8_t interrupt2,
               const uint8_t mode2,
               uint32_t ms)
{
	// ATMega328P supports following modes to wake from sleep: LOW, CHANGE, RISING, FALLING
	// Datasheet states only LOW can be used with INT0/1 to wake from sleep, which is incorrect.
	// Ref: http://gammon.com.au/interrupts

	// Disable interrupts until going to sleep, otherwise interrupts occurring between attachInterrupt()
	// and sleep might cause the ATMega to not wakeup from sleep as interrupt has already be handled!
	cli();
	// attach interrupts
	_wakeUp1Interrupt  = interrupt1;
	_wakeUp2Interrupt  = interrupt2;

	// Attach external interrupt handlers, and clear any pending interrupt flag
	// to prevent waking immediately again.
	// Ref: https://forum.arduino.cc/index.php?topic=59217.0
	if (interrupt1 != INVALID_INTERRUPT_NUM) {
		clearPendingInterrupt(interrupt1);
		attachInterrupt(interrupt1, wakeUp1, mode1);
	}
	if (interrupt2 != INVALID_INTERRUPT_NUM) {
		clearPendingInterrupt(interrupt2);
		attachInterrupt(interrupt2, wakeUp2, mode2);
	}

	if (ms > 0u) {
		// sleep for defined time
		hwInternalSleep(ms);
	} else {
		// sleep until ext interrupt triggered
		hwPowerDown(WDTO_SLEEP_FOREVER);
	}

	// Assure any interrupts attached, will get detached when they did not occur.
	if (interrupt1 != INVALID_INTERRUPT_NUM) {
		detachInterrupt(interrupt1);
	}
	if (interrupt2 != INVALID_INTERRUPT_NUM) {
		detachInterrupt(interrupt2);
	}

	// Return what woke the mcu.
	// Default: no interrupt triggered, timer wake up
	int8_t ret = MY_WAKE_UP_BY_TIMER;
	if (interruptWakeUp()) {
		ret = static_cast<int8_t>(_wokeUpByInterrupt);
	}
	// Clear woke-up-by-interrupt flag, so next sleeps won't return immediately.
	_wokeUpByInterrupt = INVALID_INTERRUPT_NUM;

	return ret;
}
Beispiel #3
0
int8_t hwSleep(uint32_t ms)
{
	// Return what woke the mcu.
	// Default: no interrupt triggered, timer wake up
	int8_t ret = MY_WAKE_UP_BY_TIMER;
	if (ms > 0u) {
		// sleep for defined time
		hwInternalSleep(ms);
	} else {
		// sleep until ext interrupt triggered
		hwPowerDown(WDTO_SLEEP_FOREVER);
	}
	if (interruptWakeUp()) {
		ret = static_cast<int8_t>(_wokeUpByInterrupt);
	}
	// Clear woke-up-by-interrupt flag, so next sleeps won't return immediately.
	_wokeUpByInterrupt = INVALID_INTERRUPT_NUM;

	return ret;
}
Beispiel #4
0
int8_t hwSleep(unsigned long ms)
{
	hwInternalSleep(ms);
	return MY_WAKE_UP_BY_TIMER;
}