1 // 2 // Copyright (c) 2010-2023 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System.Collections.Generic; 8 using Antmicro.Renode.Peripherals.Bus; 9 using Antmicro.Renode.Core.Structure.Registers; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Utilities; 12 using Antmicro.Renode.Logging; 13 14 namespace Antmicro.Renode.Peripherals.Timers 15 { 16 public class NPCX_MTC : IDoubleWordPeripheral, IProvidesRegisterCollection<DoubleWordRegisterCollection>, IKnownSize 17 { NPCX_MTC(IMachine machine)18 public NPCX_MTC(IMachine machine) 19 { 20 IRQ = new GPIO(); 21 22 timer = new LimitTimer(machine.ClockSource, 1, this, "timer", 1, eventEnabled: true); 23 timer.LimitReached += () => 24 { 25 timerValue.Value++; 26 if(BitHelper.GetValue(timerValue.Value, 0, PredefinedTimeBits) == predefinedTime.Value) 27 { 28 predefinedTimeOccurred.Value = true; 29 UpdateInterrupt(); 30 } 31 }; 32 33 var registerMap = new Dictionary<long, DoubleWordRegister> 34 { 35 {(long)Registers.TimingTicksCount, new DoubleWordRegister(this) 36 .WithValueField(0, 32, out timerValue, name: "TTC (Timing Ticks Count)", softResettable: false) 37 }, 38 {(long)Registers.WakeUpTicksCount, new DoubleWordRegister(this) 39 .WithFlag(31, out interruptEnabled, name: "WIE (Wake-Up/Interrupt Enabled)") 40 .WithFlag(30, out predefinedTimeOccurred, FieldMode.Read | FieldMode.WriteOneToClear) 41 .WithReservedBits(25, 5) 42 .WithValueField(0, 25, out predefinedTime, name: "PT (Predefined Time)") 43 .WithWriteCallback((_, __) => UpdateInterrupt()) 44 }, 45 }; 46 RegistersCollection = new DoubleWordRegisterCollection(this, registerMap); 47 48 Reset(); 49 } 50 Reset()51 public void Reset() 52 { 53 RegistersCollection.Reset(); 54 timer.Enabled = true; 55 IRQ.Unset(); 56 } 57 ReadDoubleWord(long offset)58 public uint ReadDoubleWord(long offset) 59 { 60 return RegistersCollection.Read(offset); 61 } 62 WriteDoubleWord(long offset, uint value)63 public void WriteDoubleWord(long offset, uint value) 64 { 65 RegistersCollection.Write(offset, value); 66 } 67 68 public GPIO IRQ { get; } 69 public long Size => 0x08; 70 public DoubleWordRegisterCollection RegistersCollection { get; } 71 UpdateInterrupt()72 private void UpdateInterrupt() 73 { 74 var irqState = interruptEnabled.Value && predefinedTimeOccurred.Value; 75 this.DebugLog("{0} interrupt", irqState ? "Setting" : "Unsetting"); 76 IRQ.Set(irqState); 77 } 78 79 private readonly LimitTimer timer; 80 81 private readonly IValueRegisterField timerValue; 82 private readonly IValueRegisterField predefinedTime; 83 private readonly IFlagRegisterField predefinedTimeOccurred; 84 private readonly IFlagRegisterField interruptEnabled; 85 86 private const int PredefinedTimeBits = 25; 87 88 private enum Registers : long 89 { 90 TimingTicksCount = 0x00, // TTC 91 WakeUpTicksCount = 0x04, // WTC 92 } 93 } 94 } 95