1

I'm trying to put my AtTiny 13 to sleep and wake it up with interrupt. It does go to sleep but it never wakes up. The whole code:

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

#define RED (1<<PB4)
#define RED_HIGH PORTB |=RED
#define RED_LOW PORTB &= ~RED
#define RED_TOG PORTB ^= RED

#define BUTTON 1<<PB1

volatile static bool is_sleeping;

ISR(INT0_vect)
{
    RED_TOG;
    is_sleeping = true;
}

int main(void){

    GIMSK |= 1<<INT0;
    MCUCR |= 0<<ISC00 | 1<<ISC01;
    sei();

    DDRB |= RED;
    DDRB &= ~BUTTON;
    PORTB |= BUTTON;

    RED_HIGH;
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    while(1){
        if(is_sleeping){
            sleep_enable();
            sei();
            sleep_cpu();
            sleep_disable();
        }
    }
}

According to sleep.h data it should work. Any ideas?

Update: it does not have problems with waking up from IDLE mode;

Piotr Konopacki
  • 85
  • 1
  • 2
  • 7

1 Answers1

1

Assuming no hardware wiring issues your code is working as follow: after booting your LED is turned on and while-loop is idling since is_sleeping is initially set to zero. First INT0 interrupt toggles LED (turns it off) and sets is_sleeping flag so that while-loop will enter to guarded code in next turn. That code turns MCU to sleep on sleep_mcu() line. Once INT0 interrupt awaits MCU it continues from last place i.e. it goes back to sleep because is_sleeping is still set! (and in your code is never turned back to false). It means that right after MCU awakes it goes to sleep almost instantly and is off until next INT0 interrupt.

So to answer you question it never wakes up I would say: it does wake up but for really short moment. If you measure current (e.g. with scope and shunt resistor) you would observe spikes when it wakes and goes asleep immediatelly.

Regardless of you main problem pay attention to code quality. Embedded programming is far from forgiving and you may stuck for hours on trivial mistakes. For instance always be defensive with macro definitions. You defined BUTTON as 1<<PB1 without parens. Difference is that later on you get hit by operators precedence. For instance using DDRB &= ~BUTTON you do not have what you expect. Your right side expression unfolds to 11111100 (because ~1<<1 is 11111110 << 1) while you wanted 11111101 (because ~(1<<1) is ~ 00000010). If you use PB0 for something else you would expect unwanted behavior.

Also when copying sample code make sure you understand what it stands for. The sample in sleep.h relies on using both sei and cli complementary. In your code you only insist on re-enablig interrupts in loop, which is pointless here.

EDIT: Since you claim wake up works in "idle" mode, then your next issue is that you expect system to wake up on falling edge by setting pair (ISC00,ISC01) to (0,1) in MCUCR. See datasheet chapter 9.2 that says "Note that recognition of falling or rising edge interrupts on INT0 requires the presence of an I/O clock" while table in chapter 7.1 says that Clk_I/0 not present in power-down mode. Your only choice it to make INT0 external interrupt to trigger on low level by setting pair (ISC00,ISC01) to (0,0) in MCUCR.

andy
  • 757
  • 5
  • 13
  • You are right about code quality, thanks :) but if you'd be right about my problem, adding "is_sleeping = false" after "sleep_cpu" would solve the problem. It does not – Piotr Konopacki Nov 28 '17 at 05:26
  • Actually saying it works in "idle" mode paid my attention to clock presence, see my updated answer. – andy Nov 28 '17 at 06:52
  • You are genius. Thank you :) – Piotr Konopacki Nov 29 '17 at 05:32
  • You are welcome. Regarding attiny13 you may find my [glowing ping-pong project](http://amichalec.net/2012/04/rainbow-ping-pong) interesting ;) – andy Nov 29 '17 at 09:22
  • There is a confirmation, that datasheet are wrong on the part that only level interrupt can wake MCU from modes other than idle: http://gammon.com.au/interrupts I can confirm that falling edge mode can wake up at least attiny10, atmega328p in fact, no matter that datasheet claims. – NStorm May 23 '19 at 06:33