unit watchdog;
{$mode ObjFPC}
{$macro on}
interface
const
WDTO_15MS = 0;
WDTO_30MS = 1;
WDTO_60MS = 2;
WDTO_120MS = 3;
WDTO_250MS = 4;
WDTO_500MS = 5;
WDTO_1S = 6;
WDTO_2S = 7;
WDTO_4S = 8;
WDTO_8S = 9;
procedure wdt_enable(const Timeout: byte);
procedure wdt_disable;
procedure wdt_reset;
implementation
const
WDP3 = 5;
{$define _WD_PS3_MASK := (1 << WDP3)}
{$define _WD_CONTROL_REG := WDTCSR}
{$define _WD_CHANGE_BIT := WDCE}
{$define _WD_WDE := (1 << WDE)}
{$define _WD_CHANGE_ENABLE := (1 << _WD_CHANGE_BIT) or (1 << WDE)}
var
WD_CONTROL_REG: byte absolute _WD_CONTROL_REG;
WD_PS3_MASK: byte absolute _WD_PS3_MASK;
WD_CHANGE_ENABLE: byte absolute _WD_CHANGE_ENABLE;
WD_WDE: byte absolute _WD_WDE;
procedure wdt_enable(const Timeout: byte); assembler;
asm
LDI r25, WD_CHANGE_ENABLE;
MOV r1, r24;
ANDI r24, 7;
ORI r24, WD_WDE;
SBRC r1, 3;
ORI r24, WD_PS3_MASK;
EOR r1, r1;
IN r0, 0x3F;
CLI;
WDR;
STS WD_CONTROL_REG, r25;
OUT 0x3F, r0;
STS WD_CONTROL_REG, r24;
end;
procedure wdt_disable; assembler; nostackframe;
asm
IN r0, 0x3F;
CLI;
WDR;
LDI r24, WD_CONTROL_REG;
ORI r24, WD_CHANGE_ENABLE;
STS WD_CONTROL_REG, r24;
STS WD_CONTROL_REG, r1;
OUT 0x3F, r0;
end;
procedure wdt_reset; assembler; nostackframe;
asm
WDR;
end;
end.