Go Down

Topic: Reset flags in MCUSR not mutually exclusive? (Read 1 time) previous topic - next topic

Jack Christensen

The way I read the ATmega328 datasheet, I expected to find only one flag set:

Quote
• Bit 3 - WDRF: Watchdog System Reset Flag
This bit is set if a Watchdog System Reset occurs. The bit is reset by a Power-on Reset, or by writing a logic zero
to the flag.
• Bit 2 - BORF: Brown-out Reset Flag
This bit is set if a Brown-out Reset occurs. The bit is reset by a Power-on Reset, or by writing a logic zero to the
flag.
• Bit 1 - EXTRF: External Reset Flag
This bit is set if an External Reset occurs. The bit is reset by a Power-on Reset, or by writing a logic zero to the flag.
• Bit 0 - PORF: Power-on Reset Flag
This bit is set if a Power-on Reset occurs. The bit is reset only by writing a logic zero to the flag.
To make use of the Reset Flags to identify a reset condition, the user should read and then Reset the MCUSR as
early as possible in the program. If the register is cleared before another reset occurs, the source of the reset can
be found by examining the Reset Flags.


Instead I find that pressing the reset button sets only EXTRF, power on sets BORF and PORF, and if I hold the reset button down while powering on, all three are set.

My question then is how to interpret the flags to determine "the" source of the reset. I'm thinking right-to-left, e.g. if PORF is set, then assume a power-on reset, and disregard the other flags.

I'm testing with the following code, programming with an ICSP (no bootloader), I just have LEDs connected to PORTD.

Code: [Select]
void setup(void)
{
    uint8_t mcusr = MCUSR;
    MCUSR = 0;
    DDRD = 0xFF;
    PORTD = mcusr;
}

void loop(void)
{
}


I didn't think the Arduino core had any bearing on this, but just to verify, I tried the following with WinAVR, and indeed the results are identical.

Code: [Select]
#include <avr/io.h>

int main(void)
{
    uint8_t mcusr = MCUSR;
    MCUSR = 0;
    DDRD = 0xFF;
    PORTD = mcusr;
    for (;;);
    return 0;
}
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Coding Badly


Figure 11-1. Reset Logic sort of implies that simultaneous conditions result in multiple flags.

I suspect that the various bits are reset when the processor loses power (which is not quite the same as "reset by a Power-on Reset") but, while the processor is powering up, multiple conditions will result in multiple flags.

Quote
if PORF is set, then assume a power-on reset, and disregard the other flags


That's what I would do in the PORF case.

For the others, I think it depends on the application.

Jack Christensen

Thanks, that must be it, I guess the language about a POR resetting the other bits threw me. Maybe they get reset, but then set again. I suppose cycling the power by definition also includes a brown-out event.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Tom Carpenter

As an example, this is at the start of my modified optiboot:

Code: [Select]

  ch = MCUSR;
#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__)
  if (!(ch & (_BV(EXTRF) | _BV(PORF)))) appStart(); //Power on reset loads bootloader as well - allows bootloader even if reset pin is disabled //(1)
#else
  if (!(ch & _BV(EXTRF))) appStart(); //(2)
#endif


The normal optiboot just (2), which says that if the reset button was pressed, run the bootloader, otherwise skip the bootloader.
I added (1) which means that in the event of a power-on reset, the bootloader still runs - this is because I needed optiboot to work on an attiny with the reset pin disabled so EXTRF could never be set.
~Tom~

Go Up