Beispiel #1
0
        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;
                    }
                }
            };
        }
Beispiel #2
0
 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();
                                   }
     };
 }
Beispiel #3
0
 public void OnTimerLimitReached(LimitTimer timer)
 {
     if (timer == timer12 && interruptEnable12.Value)
     {
         interruptOccurred12.Value = true;
         Update();
     }
     else if (timer == timer34 && interruptEnable34.Value)
     {
         interruptOccurred34.Value = true;
         Update();
     }
 }
Beispiel #4
0
 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();
 }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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();
        }
Beispiel #7
0
 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();
     }
 }
Beispiel #8
0
 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();
     }
 }
Beispiel #9
0
 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;
     }
 }
Beispiel #10
0
 public void OnTimerLimitReached(LimitTimer timer)
 {
     if(timer == timer12 && interruptEnable12.Value)
     {
         interruptOccurred12.Value = true;
         Update();
     }
     else if(timer == timer34 && interruptEnable34.Value)
     {
         interruptOccurred34.Value = true;
         Update();
     }
 }
Beispiel #11
0
        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);
 }
Beispiel #13
0
 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);
     }
 }
Beispiel #14
0
 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);
       
     }
 }
Beispiel #15
0
 public InnerTimer(Machine machine, int frequency)
 {
     CoreTimer = new LimitTimer(machine, frequency, limit: InitialLimit, direction : Direction.Descending);
 }