Clearing WDE bit is impossible

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

I am trying to use watchdog as interrupt only source. I have been trying different sequences for setting the WDE bit but no luck. I also searched up numerous posts about that issue on this forum and tried their solutions - still no luck.

I am working on an Attiny13A. I am aware that MCUSR -> WDRF must be cleared before the WDE and that also WDCE must be set less than 4 clock cycles before trying to change WDE.

I was able to set the prescaler bits but that WDE bit has been torturing me for the last couple hours. Any help would be appreciated.

 

Things I have tried:

	MCUSR = 0;														//Watchdog settings
	WDTCR = (1<<WDCE)|(1<<WDE);
	WDTCR = (1<<WDTIE) | (1<<WDP3) | (1<<WDP0);
	
	///////////////////
	
	MCUSR = 0;
	WDTCR = (1<<WDCE)|(1<<WDE);
	WDTCR = (1<<WDTIF)|(1<<WDTIE)|(1<<WDP3)|(1<<WDP0);
	
	//////////////////
	
    WDTCR=(0<<WDIF) | (0<<WDIE) | (1<<WDP3) | (1<<WDCE) | (0<<WDE) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
    WDTCR=(1<<WDIF) | (1<<WDIE) | (1<<WDP3) | (0<<WDCE) | (0<<WDE) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
   
    //////////////////

    cli();
    MCUSR = 0;
    WDTCR = (1<<WDCE)|(1<<WDE);
    WDTCR = (1<<WDIE) | (1<<WDP3) | (1<<WDP0);
    sei();
        

 

This topic has a solution.

TO THE FINDER... THE ISLE OF KOHOLINT, IS BUT AN ILLUSION... HUMAN, MONSTER, SEA, SKY... A SCENE ON THE LID OF A SLEEPER'S EYE... AWAKE THE DREAMER, AND KOHOLINT WILL VANISH MUCH LIKE A BUBBLE ON A NEEDLE... CAST-AWAY, YOU SHOULD KNOW THE TRUTH!

Last Edited: Thu. Oct 14, 2021 - 10:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The simulator shows that the WDE bit is 0 after my code is executed but that is not what is happening with the chip.

The chip continues to have the WDE pin set after the code is executed.

TO THE FINDER... THE ISLE OF KOHOLINT, IS BUT AN ILLUSION... HUMAN, MONSTER, SEA, SKY... A SCENE ON THE LID OF A SLEEPER'S EYE... AWAKE THE DREAMER, AND KOHOLINT WILL VANISH MUCH LIKE A BUBBLE ON A NEEDLE... CAST-AWAY, YOU SHOULD KNOW THE TRUTH!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
WDTCR=(0<<WDIF) | (0<<WDIE).....(0<<WDE)

 

This (0<<xxxx) does NOTHING, there is a macro in existence with GCC to do it, I'll see if I can find it.

 

wdt_disable();      http://www.nongnu.org/avr-libc/u...

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Thu. Oct 14, 2021 - 04:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You must also set WDE in WDTCR = (1<<WDIE) | (1<<WDP3) | (1<<WDP0);

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

Setting WDE is easy if you follow Datasheets. Do read it, and you will understand that it is not just one bit, but much more.

 

Edit: from Datasheets

WDT_Prescaler_Change:
; Turn off global interrupt
    cli
; Reset Watchdog Timer
    wdr
; Start timed sequence
    in      r16, WDTCR
    ori     r16, (1<<WDCE) | (1<<WDE)
    out     WDTCR, r16
; -- Got four cycles to set the new values from here -
; Set new prescaler(time-out) value = 64K cycles (~0.5 s)
    ldi     r16, (1<<WDE) | (1<<WDP2) | (1<<WDP0)
    out     WDTCR, r16
; -- Finished setting new values, used 2 cycles -
; Turn on global interrupt
    sei
    ret

 

Last Edited: Thu. Oct 14, 2021 - 05:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

There is the code from my latest '13A project, w=r16. On interrupt WDTIE should be written again:

sQSGQI_Init:
    ldi     w, 1<<WDTIE      ; 16ms Interrupt mode
    out     WDTCR, w
    ret

sQSGQI_WDT:
    in      rSREG, SREG
    sbr     rGF, 1<<rGF_16ms
    push    w
    ldi     w, 1<<WDTIE      ; 16ms Interrupt mode
    out     WDTCR, w
    pop     w
    out     SREG, rSREG
    reti

Edit: You do not need WDE

 

 

 

Last Edited: Thu. Oct 14, 2021 - 07:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

grohote wrote:
Setting WDE is easy if you follow Datasheets. Do read it, and you will understand that it is not just one bit, but much more.

+1

 

In particular:

grohote wrote:

; Start  timed sequence 

A couple of recent threads where people have been caught out by the Timed Sequence:

 

https://www.avrfreaks.net/commen...

 

https://www.avrfreaks.net/forum/...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I am trying to clear the WDE bit.

I can tell that the WDE is written to 1 from the beginning of execution on the chip because I use this line to light some LEDS at the start of main, after the setup function:

if (WDTCR & (1 << WDE))rampUP();

So, re-writting the WDTIE bit in the watchdog ISR is not the problem here, right?

I am sure that the prescaler is set since the LEDS are ramped up from 0 volts once every 8sec.

TO THE FINDER... THE ISLE OF KOHOLINT, IS BUT AN ILLUSION... HUMAN, MONSTER, SEA, SKY... A SCENE ON THE LID OF A SLEEPER'S EYE... AWAKE THE DREAMER, AND KOHOLINT WILL VANISH MUCH LIKE A BUBBLE ON A NEEDLE... CAST-AWAY, YOU SHOULD KNOW THE TRUTH!

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

grohote wrote:

    in      r16, WDTCR
    ori     r16, (1<<WDCE) | (1<<WDE)
    out     WDTCR, r16
; -- Got four cycles to set the new values from here -
; Set new prescaler(time-out) value = 64K cycles (~0.5 s)
    ldi     r16, (1<<WDE) | (1<<WDP2) | (1<<WDP0)
    out     WDTCR, r16

Why are you doing the LDI in the middle of this? Surely you can preload a register with the value to be written in the second OUT long before the time senesitive sequence (OK I know the LDI "fits" in the cycles available but why get even close to the limit?)

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

tellSlater wrote:
Yes, I am trying to clear the WDE bit.

 

Once again, do read datasheets, to understand what is going on.

The code from Datasheets that removes WDT and you should follow is:

WDT_off:
; Turn off global interrupt
    cli
; Reset Watchdog Timer
    wdr
; Clear WDRF in MCUSR
    in      r16, MCUSR
    andi    r16, (0xff - (1<<WDRF))
    out     MCUSR, r16
; Write logical one to WDCE and WDE
; Keep old prescaler setting to prevent unintentional time-out
    in      r16, WDTCR
    ori     r16, (1<<WDCE) | (1<<WDE)
    out     WDTCR, r16
; Turn off WDT
    ldi     r16, (0<<WDE)
    out     WDTCR, r16
; Turn on global interrupt
    sei
    ret

 

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

clawson wrote:
Why are you doing the LDI in the middle of this?

 

That is why the WDE is tricky- all that for a change of prescallers.

The code is from a datasheets. 

 

Edit: I am using ASM examples, and the C-one is available, too.

 

 

Last Edited: Thu. Oct 14, 2021 - 10:17 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok I am dump:

I thought the WDTON bit in the low fuse was meant to be 1 for using the watchdog timer.

After reading the Watchdog timer section on the datasheet line by line I realized my mistake.

Writing the WDTON bit to logic 0 solved the problem.

TO THE FINDER... THE ISLE OF KOHOLINT, IS BUT AN ILLUSION... HUMAN, MONSTER, SEA, SKY... A SCENE ON THE LID OF A SLEEPER'S EYE... AWAKE THE DREAMER, AND KOHOLINT WILL VANISH MUCH LIKE A BUBBLE ON A NEEDLE... CAST-AWAY, YOU SHOULD KNOW THE TRUTH!

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

tellSlater wrote:
Ok I am dump

 

Ok I am dumb- no, you are not, and programming Tiny13 or other AVR will never become, for sure.