Pages: [1]   Go Down
Author Topic: Reset flags in MCUSR not mutually exclusive?  (Read 1018 times)
0 Members and 1 Guest are viewing this topic.
Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4062
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
#include <avr/io.h>

int main(void)
{
    uint8_t mcusr = MCUSR;
    MCUSR = 0;
    DDRD = 0xFF;
    PORTD = mcusr;
    for (;;);
    return 0;
}
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12858
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


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.
Logged

Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4062
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1726
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
  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.
Logged

~Tom~

Pages: [1]   Go Up
Jump to: