0
votes

I am using a modified Arduino board: Gizduino X with Atmega 1281 MCU chip on-board. The application is uploaded to MCU using Arduino IDE programmer. I attempted to use the Watchdog timer reset feature of the Atmega 1281 and used the library "wdt.h". The problem is that the micro appears to continuously loop on reset after the watchdog reset. I was aware of the datasheet specification that the watchdog must be disabled prior to setup(), since it is automatically enabled after reset so that included in my code is as follows:

#include <stdint.h>
#include <avr/wdt.h> //Watchdog Timer library
#define RST_PIN 38        //pin for MCU reset indicator

uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init3")));
void get_mcusr(void)
{
    mcusr_mirror = MCUSR;
    MCUSR = 0;
    wdt_disable();
}

char ch;
char pn = 0;
bool ledState = false;

#define wdtReset()  wdt_reset(); \
                digitalWrite(RST_PIN, LOW)

#define wdtBegin()  wdt_reset(); \
                wdt_enable(WDTO_500MS); \
                bitSet(WDTCSR, WDIE)
/******************************************/
void setup() {
  wdtBegin();
  Serial.begin(115200);

  // initialize digital pin 13 as an output.

  wdtReset();
  pinMode(13, OUTPUT);
  pinMdoe(RST_PIN, OUTPUT);
}
/******************************************/
// the loop function runs over and over again forever
void loop() {
  if(Serial.available()) {
    ch = Serial.read();
    if(ch == 'R' || ch == 'r') {
      ledState = !ledState;
      digitalWrite(13, ledState);
      while(true);
    }
  }
  if(pn >= 255) pn = 0;
  Serial.println(pn++);
  wdtReset();
}
/******************************************/
ISR(WDT_vect) {
  digitalWrite(RST_PIN, HIGH);
}

The purpose of the code is to isolate the watchdog problem and invoke watchdog reset as I please. The code runs well as the MCU is powered, but when I send a character to invoke watchdog reset ('r' or 'R'), the RST_PIN is set to HIGH (indicating that the interrupt fired) and then set to LOW after the reset, but the LED indicator on the board is ON. Once in this state, pressing the reset button does not reset the MCU anymore until I removed the power from the board. Additionally, if I press down the reset button continuously, the LED indicator on board appears to dim a little bit and begins to flicker when I accidentally touch one of the ICSP pins beside the reset button.

I also followed instructions on setting up the Watchdog from this link: http://donalmorrissey.blogspot.com/2011/09/using-watch-dog-on-atmega1281-as-lock.html

I uploaded the same code on an Atmega328 MCU but it works fine. I suppose that the problem exists to newer chips because the Watchdog is still enabled with default values after the system reset.

Am I missing something? Is the problem hardware specific?

1

1 Answers

-1
votes

That's because your Arduino bootloader runs before your main app. When bootloader start WDT is still enabled and set to minimal period 16ms. Datasheet says:

Note: If the Watchdog is accidentally enabled, for example by a runaway pointer or brown-out condition, the device will be reset and the Watchdog Timer will stay enabled. If the code is not set up to handle the Watchdog, this might lead to an eternal loop of time-out resets. To avoid this situation, the application software should always clear the Watchdog System Reset Flag (WDRF) and the WDE control bit in the initialization routine, even if the Watchdog is not in use.

You need to modify bootloader to disable Watchdog on reset or forget about Watchdog at your main app.

UPDATE To disable WDT at bootloader, execute this code ASAP:

MCUSR &= ~(1 << WDRF);
wdt_disable();