(* 说明:全志A20的WatchDog底层操作封装类。单例。 作者:tjCFeng 邮箱:tjCFeng@163.com 更新日期:2014.12.06 *) unit WatchDog; {$mode objfpc}{$H+} interface uses SysUtils, A20, Clock; type TInterval = (S0_5, S1, S2, S3, S4, S5, S6, S8, S10, S12, S14, S16); TWDOG = class private class var FInstance: TWDOG; class function GetInstance: TWDOG; static; public class procedure Release; class property Instance: TWDOG read GetInstance; private FWDOG_BASE: ^LongWord; constructor Create; destructor Destroy; override; procedure SetInterval(Value: TInterval); function GetInterval: TInterval; procedure SetForceRestart(Value: Boolean); function GetForceRestart: Boolean; protected FWDOG_CTRL: TGROUP1_REG; FWDOG_MODE: TGROUP1_REG; public procedure Start; procedure Stop; procedure Reset; public property Interval: TInterval read GetInterval write SetInterval; property ForceRestart: Boolean read GetForceRestart write SetForceRestart; property WDOG_CTRL: TGROUP1_REG read FWDOG_CTRL; property WDOG_MODE: TGROUP1_REG read FWDOG_MODE; end; implementation const WDOG_BASE = $01C20C90; class function TWDOG.GetInstance: TWDOG; begin if FInstance = nil then FInstance:= TWDOG.Create; Result:= FInstance; end; class procedure TWDOG.Release; begin FreeAndNil(FInstance); end; constructor TWDOG.Create; var Base: LongWord; begin inherited Create; FWDOG_BASE:= TA20.Instance.GetMMap(WDOG_BASE); Base:= LongWord(FWDOG_BASE) + TA20.Instance.BaseOffset(WDOG_BASE); FWDOG_CTRL:= Pointer(Base + $00); FWDOG_MODE:= Pointer(Base + $04); end; destructor TWDOG.Destroy; begin TA20.Instance.FreeMMap(FWDOG_BASE); inherited Destroy; end; procedure TWDOG.SetInterval(Value: TInterval); begin FWDOG_MODE^:= FWDOG_MODE^ and not ($F shl 3); FWDOG_MODE^:= FWDOG_MODE^ or (Ord(Value) shl 3); end; function TWDOG.GetInterval: TInterval; var Value: Byte; begin Value:= (FWDOG_MODE^ and ($F shl 3)) shr 3; case Value of 0: Result:= S0_5; 1: Result:= S1; 2:Result:= S2; 3: Result:= S3; 4: Result:= S4; 5: Result:= S5; 6: Result:= S6; 7: Result:= S8; 8: Result:= S10; 9: Result:= S12; 10: Result:= S14; 11: Result:= S16; end; end; procedure TWDOG.SetForceRestart(Value: Boolean); begin case Value of False: FWDOG_MODE^:= FWDOG_MODE^ and not ($1 shl 1); True: FWDOG_MODE^:= FWDOG_MODE^ or ($1 shl 1); end; end; function TWDOG.GetForceRestart: Boolean; begin Result:= (FWDOG_MODE^ and ($1 shl 1)) > 0; end; procedure TWDOG.Start; begin FWDOG_MODE^:= FWDOG_MODE^ or ($1 shl 0); end; procedure TWDOG.Stop; begin FWDOG_MODE^:= FWDOG_MODE^ and not ($1 shl 0); end; procedure TWDOG.Reset; begin FWDOG_CTRL^:= 1; end; finalization TWDOG.Instance.Release; end.