[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-libc-dev] [bug #44140] wdt_disable() macro clobbers prescaller bits
From: |
Pitchumani |
Subject: |
[avr-libc-dev] [bug #44140] wdt_disable() macro clobbers prescaller bits and can cause unexpected resets |
Date: |
Thu, 05 Mar 2015 11:35:38 +0000 |
User-agent: |
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36 OPR/27.0.1689.76 |
Update of bug #44140 (project avr-libc):
Status: None => In Progress
Assigned to: None => pitchumani
_______________________________________________________
Follow-up Comment #1:
Hi Josh,
Below is the modified wdt_disable function. I have included wdr instruction
before modifying watch dog. Also avoided overwriting prescaler bits.
static __inline__
__attribute__ ((__always_inline__))
void wdt_disable (void)
{
if (_SFR_IO_REG_P (_WD_CONTROL_REG))
{
uint8_t register temp_reg;
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__" "\n\t"
"cli" "\n\t"
"wdr" "\n\t"
"in %[TEMPREG],%[WDTREG]" "\n\t"
"ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
"out %[WDTREG],%[TEMPREG]" "\n\t"
"out %[WDTREG],__zero_reg__" "\n\t"
"out __SREG__,__tmp_reg__" "\n\t"
: [TEMPREG] "=r" (temp_reg)
: [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
[WDCE_WDE] "I" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
: "r0"
);
}
else
{
uint8_t register temp_reg;
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__" "\n\t"
"cli" "\n\t"
"wdr" "\n\t"
"lds %[TEMPREG],%[WDTREG]" "\n\t"
"ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
"sts %[WDTREG],%[TEMPREG]" "\n\t"
"sts %[WDTREG],__zero_reg__" "\n\t"
"out __SREG__,__tmp_reg__" "\n\t"
: [TEMPREG] "=r" (temp_reg)
: [WDTREG] "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
[WDCE_WDE] "I" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
: "r0"
);
}
}
Generated assembly for tiny84a it should be like:
in __tmp_reg__,__SREG__
cli
wdr ; watchdog reset
in r24,33 ; load wdt register value
ori r24,24 ; OR (WDCE | WDE)
out 33,r24 ; write back to wdt register
out 33,__zero_reg__ ; trun-off wdt
out __SREG__,__tmp_reg__
Is this change ok?
Manually verified the generated assembly for all devices that has wdt.
_______________________________________________________
Reply to this item at:
<http://savannah.nongnu.org/bugs/?44140>
_______________________________________________
Message sent via/by Savannah
http://savannah.nongnu.org/
- [avr-libc-dev] [bug #44140] wdt_disable() macro clobbers prescaller bits and can cause unexpected resets,
Pitchumani <=