1 //
2 // Copyright (c) 2010-2019 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.Core;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using Antmicro.Renode.Logging;
11 using Antmicro.Renode.Peripherals.Bus;
12 using Antmicro.Renode.Peripherals.Timers;
13 
14 namespace Antmicro.Renode.Peripherals.UART
15 {
16     public class LowPower_Timer : LimitTimer, IDoubleWordPeripheral, IKnownSize
17     {
LowPower_Timer(IMachine machine, long frequency = 8000000)18         public LowPower_Timer(IMachine machine, long frequency = 8000000) : base(machine.ClockSource, frequency, null, "", eventEnabled: true)
19         {
20             IRQ = new GPIO();
21 
22             this.LimitReached += () =>
23             {
24                 this.Log(LogLevel.Noisy, "IRQ set");
25                 IRQ.Set();
26             };
27 
28             var registersMap = new Dictionary<long, DoubleWordRegister>
29             {
30                 {(long)Registers.Control, new DoubleWordRegister(this)
31                     .WithFlag(0, name: "TimerEnable",
32                             valueProviderCallback: _ => this.Enabled,
33                             writeCallback: (_, val) =>
34                             {
35                                 this.Enabled = val;
36                             })
37                     .WithFlag(7, name: "TimerCompareFlag",
38                             writeCallback: (_, val) =>
39                             {
40                                 if(val)
41                                 {
42                                     IRQ.Set(false);
43                                     this.Log(LogLevel.Noisy, "IRQ cleared");
44                                 }
45                             })
46                 },
47 
48                 {(long)Registers.Compare, new DoubleWordRegister(this)
49                     .WithValueField(0, 32, valueProviderCallback: _ => (uint)this.Limit,
50                             writeCallback: (_, val) =>
51                             {
52                                 this.Limit = val;
53                                 this.Value = 0;
54                             })
55                 },
56 
57                 {(long)Registers.Counter, new DoubleWordRegister(this)
58                     .WithValueField(0, 32, valueProviderCallback: _ => (uint)this.Value,
59                             writeCallback: (_, val) =>
60                             {
61                                 this.Value = val;
62                             })
63                 },
64             };
65 
66             registers = new DoubleWordRegisterCollection(this, registersMap);
67         }
68 
Reset()69         public override void Reset()
70         {
71             base.Reset();
72             IRQ.Set(false);
73             registers.Reset();
74         }
75 
ReadDoubleWord(long offset)76         public uint ReadDoubleWord(long offset)
77         {
78             return registers.Read(offset);
79         }
80 
WriteDoubleWord(long offset, uint value)81         public void WriteDoubleWord(long offset, uint value)
82         {
83             registers.Write(offset, value);
84         }
85 
86         public GPIO IRQ { get; set; }
87 
88         public long Size => 0x10;
89 
90         private readonly DoubleWordRegisterCollection registers;
91 
92         private enum Registers
93         {
94             Control = 0x0,
95             Prescale = 0x4,
96             Compare = 0x8,
97             Counter = 0xC
98         }
99     }
100 }
101