Watchdog question...

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On a 168P, this does not work, cpu reset after 1s:

void goto_sleep()
{
  cli();	// disable interrupt
  timer0_ovf=0;

  wdt_enable(WDTO_1S);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_bod_disable();
  sei();
  sleep_cpu();
  sleep_disable();
  wdt_disable();
}

I managed to get this to work:

void goto_sleep()
{
  cli();	// disable interrupt
  timer0_ovf=0;

  wdt_reset();
  MCUSR=0;
  WDTCSR = (1<<WDCE) | (1<<WDE);
  WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_bod_disable();
  sei();
  sleep_cpu();
  sleep_disable();
  wdt_disable();
}

both have a EMPTY_INTERRUPT(WDT_vect);

Why the wdt_enable makes the cpu reset after 1 second?

It's in a basic

while(1)
	{
		sprintf_P(str, PSTR("$u "), i++);
		lcd_print(str);
		goto_sleep();
	}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Watchdog runs on its own clk, so it doesn't sleep if enabled .

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using the watchdog as a 1s delay, but after taking a depper look, it's because I want to use interrupt mode and not reset mode, so I can not use wdt_enable() but I have to manipulate the bit myself...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For THAT I wrote a wdt_enable_ISR() in inline asm, using wdt.h as template, and put it in a my_wdt.h .

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I'm using the watchdog as a 1s delay,

I also use WDT interrupt as rough timekeeping in power-down sleep applications. (The usefulness of this depends on the app.)

IIRC there was some discussion of WDT interrupt and GCC-provided facilities. Try searching out the thread(s) in the GCC forum.

If you roll-your-own, take care about atomic operations and the 4-cycle limit.

Here is a fragment from one of my apps using the same AVR family:

WDTCSR = BIT_WDTCSR_WDCE | BIT_WDTCSR_WDE | WDT_8_SEC;
WDTCSR = BIT_WDTCSR_WDIE | WDT_8_SEC;

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

indianajones11 wrote:
For THAT I wrote a wdt_enable_ISR() in inline asm, using wdt.h as template, and put it in a my_wdt.h .
You are right Junior, I want WDIE and not WDE so I have to make my own.

theusch wrote:
WDTCSR = BIT_WDTCSR_WDCE | BIT_WDTCSR_WDE | WDT_8_SEC;
WDTCSR = BIT_WDTCSR_WDIE | WDT_8_SEC;
This is basically what I am doing now :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

This is basically what I am doing now Smile

IIRC I struggled a bit with WD and Mega88 family, getting the correct incantation. Also IIRC the double-set of the period needed to be done twice as in my example code. Now, that was some years ago...

Anyway, I did some of the searching for you, and following the link in this post may be of interest to you.
https://www.avrfreaks.net/index.p...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks you, nice alternate macro for the watchdog!