simavr icon indicating copy to clipboard operation
simavr copied to clipboard

Timer keeps running after turning its power supply off

Open gergoerdi opened this issue 7 years ago • 7 comments

On a real ATMega328P, the following program strobes PORTB5 5 times, then stops:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/power.h>

int main ()
{
    DDRB |= _BV(DDB5);

    TCCR1B |= _BV(CS10);
    TCCR1B |= _BV(CS12);

    int count = 0;
    for (;;)
    {
        if (TCNT1 >= 4000)
        {
            PORTB ^= _BV(PB5);
            TCNT1 = 0;
            if (++count == 10)
                power_timer1_disable();
        }
    }
}

However, in SimAVR, I see that PORTB5 keeps changing even after the 5th on/off cycle. It seems that shutting off TIMER1's power is not simulated.

gergoerdi avatar Feb 18 '17 03:02 gergoerdi

Interesting, I'll have a look at that. We already had a test case for the timer16 like that, so perhaps there is a regression there..?

buserror avatar Feb 19 '17 18:02 buserror

This certainly related to PRR handling (power_timer1_disable() doing that). The avr_timer_t structure has a 'disabled' regbit, but its handling never been implemented yet, as far as I know. Or I miss something obvious?

hovercraft-github avatar Mar 01 '17 15:03 hovercraft-github

I think we need to start by using a AVR_IRQ_FLAG_FLOAT... And also add accessors to get/set the flags...

The idea would be to do.. if () avr_irq_set_flag(irq, AVR_IRQ_FLAG_FLOAT); else avr_irq_raise(irq, value...);

And/Or add an accessor that does avr_irq_raise_float(avr, value, input ? true : false);

The receiving handler would have to do a getflag and/or use a new avr_irq_floating(irq) to know if the value passed is valid, or not.

So the IRQ propagation code would be converted to avr_irq_raise_float to propagate the flag down the chain, wether it's true or false...

Doesn't look terribly complicated to do. See any problem with that?

buserror avatar Mar 01 '17 16:03 buserror

Your post just accidentally get into issue #202 (Timer keeps running after turning its power supply off)02.03.2017, 00:49, "Michel Pollet" [email protected]:I think we need to start by using a AVR_IRQ_FLAG_FLOAT... And also add accessors to get/set the flags... The idea would be to do.. if () avr_irq_set_flag(irq, AVR_IRQ_FLAG_FLOAT); else avr_irq_raise(irq, value...); And/Or add an accessor that does avr_irq_raise_float(avr, value, input ? true : false); The receiving handler would have to do a getflag and/or use a new avr_irq_floating(irq) to know if the value passed is valid, or not. So the IRQ propagation code would be converted to avr_irq_raise_float to propagate the flag down the chain, wether it's true or false... Doesn't look terribly complicated to do. See any problem with that?

—You are receiving this because you commented.Reply to this email directly, view it on GitHub, or mute the thread.

hovercraft-github avatar Mar 02 '17 01:03 hovercraft-github

@hovercraft-github: and now your comment is also on the wrong ticket :D

gergoerdi avatar Mar 02 '17 07:03 gergoerdi

Yeah well, it was probably my fault, I had loads of tabs open, must have typed it all in the wrong one! :-)

buserror avatar Mar 02 '17 11:03 buserror

I had a look and yes, the PRR register bit isn't handled at all, my assumption was that the PRR is good to save power, but is not an 'on off switch'. Seems the avr-libc has decided otherwise :-)

So let's keep this issue open, we might have to make a special driver for the PRR register and dispatch IOctl's around for corresponding bits, instead of implementing the on/off for each of the drivers that might be affected.

buserror avatar Mar 07 '17 08:03 buserror