1

I read the datasheet and this question, but there's still something wrong here. Here my wdt init code:

cli();
MCUSR &= ~_BV(WDRF);
WDTCSR |= _BV(WDCE) | _BV(WDE);
WDTCSR = _BV(WDP2) | _BV(WDP1) | _BV(WDP0);
WDTCSR |= _BV(WDIF);
WDTCSR |= _BV(WDIE);

Leaving fire the wdt I expect it does nothing but set the WDIF bit, instead it resets the MCU. Is there something wrong in my approach?

Mark
  • 1,161
  • 6
  • 23
  • Do you have an interrupt handler? (or do you leave interrupts off?) – user253751 Sep 21 '20 at 18:51
  • @user253751, I don't have and I don't want an ISR (for this reason I don't enable the interrupts with `sei()`). I'm going to check the `WDIF` manually. – Mark Sep 21 '20 at 18:54
  • 1
    A watchdog blocked by SEI() wouldn't be much of a watchdog since it could be disabled by a trivial software bug or glitch. Typically resetting the processor is *exactly* what they do. – Chris Stratton Sep 21 '20 at 18:57
  • How is the WDTON fuse bit programmed? There is also no watchdog reset before configuring it. – Justme Sep 21 '20 at 19:10
  • @ChrisStratton, I know how to use a wdt "usually" :) this is a bootloader and I *need* to use the interrupt mode - as provided by this MCU – Mark Sep 21 '20 at 19:14
  • @Justme, it is programmed, otherwise no reset will occur at all. – Mark Sep 21 '20 at 19:15
  • And by "programmed" you mean set to "0"? – Justme Sep 21 '20 at 19:21

2 Answers2

1

If you program the WDTON fuse (ie, set it to the non-default value of 0), then according to the data sheet you are locked into System Reset rather than Interrupt mode; this would not appear to be what you want.

It would appear that what you do want is a combination of Interrupt and System Reset mode, where the first count expiration sets WDIF and triggers and interrupt, and the second causes a reset.

However, if you do that without an ISR, you're going to need to be sure to keep re-setting the WDIE bit after it is cleared on each counter expiration, as if the count expires when WDIE is already unset, a reset will occur.

Chris Stratton
  • 33,282
  • 3
  • 43
  • 89
1

The problem is because WDTON fuse bit is programmed, or '0', the WDE and WDIE bits are ignored and the only time out action from the watchdog is a system reset. Setting the WDTON fuse bit to unprogrammed, or '1', will enable the WDE and WDIE bit usage and thus interrupt action on time-out can be selected.

Justme
  • 127,425
  • 3
  • 97
  • 261
  • Right. Even after 15+ years of AVR programming, I still get confused by the 0|1 meaning of the fuses... – Mark Sep 21 '20 at 19:34
  • It's OK. I do have to confess that I have not touched AVRs for about 12 years now, so my AVR skills are not up to date either. – Justme Sep 21 '20 at 19:37