123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- MODULE PrivateTimer;
- (**
- Author: Alexey Morozov, HighDim GmbH, 2013
- Purpose: implementation of the driver for ARM Cortex-A9 MPCore private timer
- *)
- IMPORT
- SYSTEM;
- CONST
- (* register offsets *)
- LoadOffset = 00H;
- CounterRegOffset = 04H;
- ControlRegOffset = 08H;
- IsrRegOffset = 00CH;
- (* control register masks *)
- ControlEnableMask = {0};
- ControlAutoReloadMask = {1};
- ControlIrqEnableMask = {2};
- ControlPrescalerMask = SYSTEM.VAL(SET,00000FF00H);
- TYPE
-
- (**
- Timer descriptor
- *)
- Timer* = RECORD
- baseAddr-: ADDRESS; (** timer base address *)
- END;
- (**
- Initialize a timer given a private timer bas address
- *)
- PROCEDURE Init*(VAR timer: Timer; baseAddress: ADDRESS);
- BEGIN
- timer.baseAddr := baseAddress;
- END Init;
- (**
- Get private timer counter value
- Remarks:
- counter value changes decrementally from the initial value set by LoadTimer
- *)
- PROCEDURE GetCounterValue*(CONST timer: Timer): LONGINT;
- BEGIN
- RETURN SYSTEM.GET32(timer.baseAddr+CounterRegOffset);
- END GetCounterValue;
- (**
- Load timer with a given 32-bit initial counter value
- *)
- PROCEDURE LoadTimer*(VAR timer: Timer; value: LONGINT);
- BEGIN
- SYSTEM.PUT32(timer.baseAddr+LoadOffset,value);
- END LoadTimer;
- (** Start timer *)
- PROCEDURE Start*(VAR timer: Timer);
- BEGIN
- SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))+ControlEnableMask);
- END Start;
- (** Stop timer *)
- PROCEDURE Stop*(VAR timer: Timer);
- BEGIN
- SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))-ControlEnableMask);
- END Stop;
- (** Enable/Disable auto reload of the timer counter *)
- PROCEDURE EnableAutoReload*(VAR timer: Timer; enable: BOOLEAN);
- BEGIN
- IF enable THEN
- SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))+ControlAutoReloadMask);
- ELSE
- SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))-ControlAutoReloadMask);
- END;
- END EnableAutoReload;
- (**
- Set 8-bit timer clock prescaler value
- *)
- PROCEDURE SetPrescaler*(VAR timer: Timer; value: LONGINT);
- VAR reg: LONGINT;
- BEGIN
- reg := SYSTEM.GET32(timer.baseAddr+ControlRegOffset);
- (* clear all prescaler control bits and set the prescaler value *)
- SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,reg)-ControlPrescalerMask+SYSTEM.VAL(SET,LSH(value,8)));
- END SetPrescaler;
- (**
- Get 8-bit timer clock prescaler value
- *)
- PROCEDURE GetPrescaler*(CONST timer: Timer): LONGINT;
- BEGIN
- RETURN LSH(SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset)) * ControlPrescalerMask),-8);
- END GetPrescaler;
- (** Enable/disable timer interrupt *)
- PROCEDURE EnableInterrupt*(VAR timer: Timer; enable: BOOLEAN);
- BEGIN
- IF enable THEN
- SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))+ControlIrqEnableMask);
- ELSE
- SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))-ControlIrqEnableMask);
- END;
- END EnableInterrupt;
- (** Get timer interrupt status
- Remark:
- returned status value indicates the timer counter register has reached zero
- *)
- PROCEDURE GetInterruptStatus*(CONST timer: Timer): LONGINT;
- BEGIN
- RETURN SYSTEM.GET32(timer.baseAddr+IsrRegOffset);
- END GetInterruptStatus;
- (**
- Clear timer interrupt status
- *)
- PROCEDURE ClearInterruptStatus*(VAR timer: Timer);
- BEGIN
- SYSTEM.PUT32(timer.baseAddr+IsrRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+IsrRegOffset)) - {0});
- END ClearInterruptStatus;
- END PrivateTimer.
|