все очень хитро: есть два дефайна
#define WATCHDOG_DISABLE { __watchdog_reset(); MCU_REG &= ~(1 << WDRF); WDT_REG |= (1 << WDCE) | (1 << WDE); WDT_REG = 0; }
#define WATCHDOG_EN_250MS { __watchdog_reset(); MCU_REG &= ~(1 << WDRF); WDT_REG |= (1 << WDCE) | (1 << WDE); WDT_REG = (1 << WDP2) | (1 << WDE); }
если в проекте юзается только один из них, то все нормально, но когда два, то получается, что оптимизатор "начала" сделал общие, а "конец" разными
и после записи WDCE появляются лишние JMP, что в итоге анулирует весь смысл.
Тогда на телесисах, обсуждения привели к виду:
typedef enum {
wd_disable = 255,
wd_16ms = 0,
wd_32ms = (1 << WDP0),
wd_64ms = (1 << WDP1) ,
wd_125ms = (1 << WDP1) | (1 << WDP0),
wd_250ms = (1 << WDP2) ,
wd_500ms = (1 << WDP2) | (1 << WDP0),
wd_1sec = (1 << WDP2) | (1 << WDP1) ,
wd_2sec = (1 << WDP2) | (1 << WDP1) | (1 << WDP0),
#ifdef WDP3
wd_4sec = (1 << WDP3) ,
wd_8sec = (1 << WDP3) | (1 << WDP0),
#endif
}Ewd_modes;
void watchdog_cmd( Ewd_modes in_mode )
{
INTERRUPT_PUSH_AND_CLR;
WATCHDOG_RESET;
u8 temp = WDT_REG | (1 << WDCE) | (1 << WDE);
switch( in_mode )
{
case wd_disable:
MCU_REG &= ~(1 << WDRF);
WDT_REG = temp;
WDT_REG = 0;
break;
default: // временные переменные не дают оптимизатору вольностей, а при конфигурировании ватчдога это нужно успеть в четрые такта после записи бита WDCE
#ifdef WDP3
u8 t2 = ( WDT_REG & ~( (1 << WDP3) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0) ) ) | (1 << WDE) | (u8)in_mode;
#else
u8 t2 = ( WDT_REG & ~( (1 << WDP2) | (1 << WDP1) | (1 << WDP0) ) ) | (1 << WDE) | (u8)in_mode;
#endif
WDT_REG = temp;
WDT_REG = t2;
break;
}
INTERRUPT_POP;
}
Но смотрю в дизасме, и вычисления t2 происходят как раз между WDT_REG = temp; и WDT_REG = t2; !!!
Заколебался подстаиватся под оптимизатор, напишу на асме, он в этом случае более надежен !