public Atmel91SystemTimer(Machine machine) { IRQ = new GPIO(); PeriodIntervalTimer = new LimitTimer(machine, 32768, int.MaxValue); // long.MaxValue couses crashes PeriodIntervalTimer.Value = 0x00000000; PeriodIntervalTimer.AutoUpdate = true; PeriodIntervalTimer.LimitReached += PeriodIntervalTimerAlarmHandler; WatchdogTimer = new LimitTimer(machine, 32768, int.MaxValue); WatchdogTimer.Value = 0x00020000; WatchdogTimer.AutoUpdate = true; WatchdogTimer.Divider = 128; WatchdogTimer.LimitReached += WatchdogTimerAlarmHandler; RealTimeTimer = new AT91_InterruptibleTimer(machine, 32768, BitHelper.Bits(20), Direction.Ascending); RealTimeTimer.Divider = 0x00008000; RealTimeTimer.OnUpdate += () => { lock (localLock) { if (RealtimeTimerIncrementInterruptMask) { RealTimeTimerIncrement = true; } } }; }
public AT91_InterruptibleTimer(Machine machine, long frequency, long limit = long.MaxValue, Direction direction = Direction.Descending, bool enabled = false) { timer = new LimitTimer(machine, frequency, limit, direction, enabled); timer.LimitReached += () => { if (OnUpdate != null) { OnUpdate(); } }; }
public void OnTimerLimitReached(LimitTimer timer) { if (timer == timer12 && interruptEnable12.Value) { interruptOccurred12.Value = true; Update(); } else if (timer == timer34 && interruptEnable34.Value) { interruptOccurred34.Value = true; Update(); } }
public NVIC(Machine machine, int systickFrequency = 50 * 0x800000) { priorities = new byte[IRQCount]; activeIRQs = new Stack<int>(); systick = new LimitTimer(machine, systickFrequency, limit: uint.MaxValue, direction: Direction.Descending, enabled: false); systick.EventEnabled = false; systick.AutoUpdate = true; irqs = new IRQState[IRQCount]; IRQ = new GPIO(); systick.LimitReached += () => { SetPendingIRQ(15); }; InitInterrupts(); Init(); }
public TexasInstrumentsTimer(Machine machine) { IRQ12 = new GPIO(); IRQ34 = new GPIO(); timer12 = new LimitTimer(machine, 24000000, direction: Direction.Ascending); // clocked from AUXCLK (default 24 MHz) timer34 = new LimitTimer(machine, 24000000, direction: Direction.Ascending); timer12.LimitReached += () => OnTimerLimitReached(timer12); timer34.LimitReached += () => OnTimerLimitReached(timer34); timer12.EventEnabled = true; timer34.EventEnabled = true; timerControlRegister = new DoubleWordRegister(this); timerGlobalControlRegister = new DoubleWordRegister(this, 3); timerInterruptControlAndStatusRegister = new DoubleWordRegister(this, 0x10001); // the driver expects interrupts to be enabled; inconsistent with timer user's guixde timerControlRegister.DefineEnumField<OperationMode>(6, 2, changeCallback: (oldValue, newValue) => OnEnableModeChanged(oldValue, newValue, timer12)); timerControlRegister.DefineEnumField<OperationMode>(22, 2, changeCallback: (oldValue, newValue) => OnEnableModeChanged(oldValue, newValue, timer34)); resetOnRead12 = timerControlRegister.DefineFlagField(10); resetOnRead34 = timerControlRegister.DefineFlagField(26); timerGlobalControlRegister.DefineFlagField(0, changeCallback: (oldValue, newValue) => { if(!newValue) { timer12.Reset(); } }); timerGlobalControlRegister.DefineFlagField(1, changeCallback: (oldValue, newValue) => { if(!newValue) { timer34.Reset(); } }); timerGlobalControlRegister.DefineEnumField<TimerMode>(2, 2, changeCallback: OnTimerModeChanged); timerGlobalControlRegister.DefineValueField(8, 4, changeCallback: (oldValue, newValue) => timer34.Divider = (int)newValue); interruptEnable12 = timerInterruptControlAndStatusRegister.DefineFlagField(0); interruptEnable34 = timerInterruptControlAndStatusRegister.DefineFlagField(16); interruptOccurred12 = timerInterruptControlAndStatusRegister.DefineFlagField(3); interruptOccurred34 = timerInterruptControlAndStatusRegister.DefineFlagField(19); Reset(); }
public TexasInstrumentsTimer(Machine machine) { IRQ12 = new GPIO(); IRQ34 = new GPIO(); timer12 = new LimitTimer(machine, 24000000, direction: Direction.Ascending); // clocked from AUXCLK (default 24 MHz) timer34 = new LimitTimer(machine, 24000000, direction: Direction.Ascending); timer12.LimitReached += () => OnTimerLimitReached(timer12); timer34.LimitReached += () => OnTimerLimitReached(timer34); timer12.EventEnabled = true; timer34.EventEnabled = true; timerControlRegister = new DoubleWordRegister(this); timerGlobalControlRegister = new DoubleWordRegister(this, 3); timerInterruptControlAndStatusRegister = new DoubleWordRegister(this, 0x10001); // the driver expects interrupts to be enabled; inconsistent with timer user's guixde timerControlRegister.DefineEnumField <OperationMode>(6, 2, changeCallback: (oldValue, newValue) => OnEnableModeChanged(oldValue, newValue, timer12)); timerControlRegister.DefineEnumField <OperationMode>(22, 2, changeCallback: (oldValue, newValue) => OnEnableModeChanged(oldValue, newValue, timer34)); resetOnRead12 = timerControlRegister.DefineFlagField(10); resetOnRead34 = timerControlRegister.DefineFlagField(26); timerGlobalControlRegister.DefineFlagField(0, changeCallback: (oldValue, newValue) => { if (!newValue) { timer12.Reset(); } }); timerGlobalControlRegister.DefineFlagField(1, changeCallback: (oldValue, newValue) => { if (!newValue) { timer34.Reset(); } }); timerGlobalControlRegister.DefineEnumField <TimerMode>(2, 2, changeCallback: OnTimerModeChanged); timerGlobalControlRegister.DefineValueField(8, 4, changeCallback: (oldValue, newValue) => timer34.Divider = (int)newValue); interruptEnable12 = timerInterruptControlAndStatusRegister.DefineFlagField(0); interruptEnable34 = timerInterruptControlAndStatusRegister.DefineFlagField(16); interruptOccurred12 = timerInterruptControlAndStatusRegister.DefineFlagField(3); interruptOccurred34 = timerInterruptControlAndStatusRegister.DefineFlagField(19); Reset(); }
public void ShouldBeDescending() { using(var machine = new Machine()) { var timer = new LimitTimer(machine, 100, 100000, Direction.Descending, true); var manualClockSource = new ManualClockSource(); machine.SetClockSource(manualClockSource); machine.Start(); var oldValue = timer.Limit; for(var i = 0; i < 100; i++) { manualClockSource.AdvanceBySeconds(1); var value = timer.Value; Assert.Less(value, oldValue, "Timer is not monotonic."); oldValue = value; } machine.Pause(); } }
public void ShouldNotExceedLimitAscending() { var limit = 100; using(var machine = new Machine()) { var timer = new LimitTimer(machine, 1, limit, Direction.Ascending, true); var manualClockSource = new ManualClockSource(); machine.SetClockSource(manualClockSource); machine.Start(); manualClockSource.AdvanceBySeconds(limit - 1); for(var i = 0; i < 3; ++i) { var value = timer.Value; Assert.LessOrEqual(value, limit, "Timer exceeded given limit."); Assert.GreaterOrEqual(value, 0, "Timer returned negative value."); manualClockSource.AdvanceBySeconds(1); } Thread.Sleep(7); machine.Pause(); } }
private void OnEnableModeChanged(OperationMode oldValue, OperationMode newValue, LimitTimer timer) { switch(newValue) { case OperationMode.Disabled: timer.Enabled = false; break; case OperationMode.Continuous: case OperationMode.ContinuousReload: timer.Mode = WorkMode.Periodic; timer.Enabled = true; timer.EventEnabled = true; break; case OperationMode.Once: timer.Mode = WorkMode.OneShot; timer.Enabled = true; timer.EventEnabled = true; break; } }
public void OnTimerLimitReached(LimitTimer timer) { if(timer == timer12 && interruptEnable12.Value) { interruptOccurred12.Value = true; Update(); } else if(timer == timer34 && interruptEnable34.Value) { interruptOccurred34.Value = true; Update(); } }
private void OnEnableModeChanged(OperationMode oldValue, OperationMode newValue, LimitTimer timer) { switch (newValue) { case OperationMode.Disabled: timer.Enabled = false; break; case OperationMode.Continuous: case OperationMode.ContinuousReload: timer.Mode = WorkMode.Periodic; timer.Enabled = true; timer.EventEnabled = true; break; case OperationMode.Once: timer.Mode = WorkMode.OneShot; timer.Enabled = true; timer.EventEnabled = true; break; } }
public InnerTimer(Machine machine, int frequency) { CoreTimer = new LimitTimer(machine, frequency, limit: InitialLimit, direction: Direction.Descending, eventEnabled: true); }
public void ShouldFireAlarmWhenInterruptsAreEnabled() { using(var machine = new Machine()) { var timer = new LimitTimer(machine, 1, 10, Direction.Descending, true); var manualClockSource = new ManualClockSource(); machine.SetClockSource(manualClockSource); timer.EventEnabled = true; var ticked = false; timer.LimitReached += () => ticked = true; machine.Start(); // var val =timer.Value; manualClockSource.AdvanceBySeconds(110); Assert.IsTrue(ticked); } }
public void ShouldSwitchDirectionProperly() { using(var machine = new Machine()) { var timer = new LimitTimer(machine, 100, 100000, Direction.Ascending, true); var manualClockSource = new ManualClockSource(); machine.SetClockSource(manualClockSource); timer.EventEnabled = true; var ticked = false; timer.LimitReached += () => ticked = true; machine.Start(); manualClockSource.AdvanceBySeconds(2); timer.Direction = Direction.Descending; // and then change the direction manualClockSource.AdvanceBySeconds(2); Assert.IsTrue(ticked); } }
public InnerTimer(Machine machine, int frequency) { CoreTimer = new LimitTimer(machine, frequency, limit: InitialLimit, direction : Direction.Descending); }