//test reset routine for ATmega controller
//Author: Matjaz Marcina matjaz@marcina.net

#include SoftwareSerial.h

void wdt_init(void) __attribute__ ((section(".init3"), used, naked )) ; //must be executed imediately after reset

void wdt_init(void) {
     cli(); //disable interrupts
     unsigned int wdrf_mask = 1 << WDRF; //makes mask of MCUSR register's WDRF bit 00001000
     MCUSR &= ~wdrf_mask; //clears WDRF if set bitwise and of MCUSR register with 11110111 or negated 00001000 value in mask
     unsigned int wdce_mask = 1 << WDCE; //makes mask for WDTCSR register's WDCE bit 00010000
     unsigned int wde_mask = 1 << WDE; //makes mask for WDTCSR register's WDCE bit 00001000
     WDTCSR |= wdce_mask | wde_mask; //remains old prescaler settings by bitwise or with 00010000 or 00001000
     WDTCSR = 0x00; // turns off watchdog timer
     sei(); //enable interrupts
     }

unsigned long TimerStart = 0;
bool TimerRunning = false;
int led = 13;

void setup() {
  pinMode(led, OUTPUT);
  TimerStart = millis();
  TimerRunning = true;
  Serial.begin(9600);
  Serial.println("Start program!");
  Serial.println("Running.........");
  delay(5000);
  digitalWrite(led, HIGH);
}

void loop() {
  if (TimerRunning && (millis() - TimerStart) >= 60000){ //resets every minute
    Serial.println("Reset program");
    TimerRunning = false;
    do //infinite loop
     {
     cli(); //disable interrupts
     WDTCSR |= (1 << WDCE) | (1 << WDE); //starts timer sequence by setting WDCE and WDE bits uusing masks as explained before
     WDTCSR = (1 << WDE) | (1 << WDP2) | (1 << WDP1); //sets prescaler values to 1 second and WDTCSR to value 00001110
     sei(); //enable interrupts
     for(;;) {};
     } while(0); //infinite loop until reset
  }
}