A good example of my question is code from Nick Gammon's forum
#include <avr/sleep.h>
#include <avr/wdt.h>
const byte LED = 9;
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
} // end of WDT_vect
void setup () { }
void loop ()
{
pinMode (LED, OUTPUT);
digitalWrite (LED, HIGH);
delay (50);
digitalWrite (LED, LOW);
pinMode (LED, INPUT);
// disable ADC
ADCSRA = 0;
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset
WDTCSR = bit (WDCE) | bit (WDE);
// set interrupt mode and an interval
WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1); // set WDIE, and 1 second delay
wdt_reset(); // pat the dog
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // timed sequence follows
sleep_enable();
// turn off brown-out enable in software
MCUCR = bit (BODS) | bit (BODSE);
MCUCR = bit (BODS);
interrupts (); // guarantees next instruction executed
sleep_cpu ();
// cancel sleep as a precaution
sleep_disable();
} // end of loop
I believe that the reason for noInterrupts () before setting the BODS is because, according to the datasheet, the brownout disable only lasts for 3 clock cycles. So calling noInterrupts () guarantees that no cycles will be "wasted" on an interrupt before the CPU goes to sleep. You can then call interrupts () right before sleep since the ISR first calls the next instruction (which is sleep) before executing the interrupt, you are safe anyway.
Please correct me if I am wrong.
If that's the case, why don't I see anyone calling noInterrupts () before setting the WDT?
Since the datasheet also states that in order to set or change the WDT register you must first
WDTCSR = bit (WDCE) | bit (WDE);
and within 4 clock cycles, you must do your selection - bit (WDCE) only remains active for 4 cycles. Isn't noInterrupts () necessary for this as well?
Thanks