1 //
2 // Copyright (c) 2010-2022 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;
8 using System.Collections.Generic;
9 using Antmicro.Renode.Core;
10 using Antmicro.Renode.Core.Structure.Registers;
11 
12 namespace Antmicro.Renode.Peripherals.Miscellaneous
13 {
14     public class MAX32650_GCR : BasicDoubleWordPeripheral, IKnownSize
15     {
MAX32650_GCR(IMachine machine, IHasFrequency nvic)16         public MAX32650_GCR(IMachine machine, IHasFrequency nvic) : base(machine)
17         {
18             DefineRegisters();
19 
20             nvic.Frequency = SysClk;
21             SysClkChanged += (frequency) =>
22             {
23                 nvic.Frequency = frequency;
24             };
25         }
26 
27         public Action<long> SysClkChanged;
28 
29         public long SysClk
30         {
31             get
32             {
33                 return oscillators[(int)sysclkSelect.Value] >> (int)sysclkPrescaler.Value;
34             }
35         }
36 
37         public long Size => 0x400;
38 
DefineRegisters()39         private void DefineRegisters()
40         {
41             Registers.ClockControl.Define(this, 0x0C0C0010)
42                 .WithReservedBits(0, 6)
43                 .WithValueField(6, 3, out sysclkPrescaler, name: "SYSCLK_PRESCALE",
44                     changeCallback: (_, __) =>
45                     {
46                         SysClkChanged?.Invoke(SysClk);
47                     })
48                 .WithValueField(9, 3, out sysclkSelect, name: "SYSOSC_SEL",
49                     changeCallback: (_, __) =>
50                     {
51                         SysClkChanged?.Invoke(SysClk);
52                     })
53                 .WithReservedBits(12, 1)
54                 .WithFlag(13, name: "SYSOSC_RDY", valueProviderCallback: _ => true)
55                 .WithReservedBits(14, 1)
56                 .WithTaggedFlag("CCD", 15)
57                 .WithReservedBits(16, 1)
58                 .WithFlag(17, name: "X32K_EN")
59                 .WithFlag(18, name: "HIRC50M_EN")
60                 .WithFlag(19, name: "HIRCMM_EN")
61                 .WithFlag(20, name: "HIRC7M_EN")
62                 .WithTaggedFlag("HIRC7M_VS", 21)
63                 .WithReservedBits(22, 3)
64                 .WithTaggedFlag("X32K_RDY", 25)
65                 .WithTaggedFlag("HIRC50M_RDY", 26)
66                 .WithTaggedFlag("HIRCMM_RDY", 27)
67                 .WithTaggedFlag("HIRC7M_RDY", 28)
68                 .WithTaggedFlag("LIRC8K_RDY", 29)
69                 .WithReservedBits(30, 2);
70         }
71 
72         private IValueRegisterField sysclkPrescaler;
73         private IValueRegisterField sysclkSelect;
74 
75         // Frequencies of oscillators (in Hz)
76         private readonly List<long> oscillators = new List<long>
77         {
78             50000000,
79             0, // Reserved
80             0, // Reserved
81             8000,
82             120000000,
83             7372800,
84             32768,
85             0 // Reserved
86         };
87 
88         private enum Registers
89         {
90             SystemControl = 0x00,
91             Reset0 = 0x04,
92             ClockControl = 0x08,
93             PowerManagement = 0x0C,
94             PeripheralClockDivisor = 0x18,
95             PeripheralClocksDisable0 = 0x24,
96             MemoryClock = 0x2C,
97             MemoryZeroize = 0x40,
98             Reset1 = 0x44,
99             PeripheralClocksDisable1 = 0x48,
100             EventEnable = 0x4C,
101             Revision = 0x50,
102         }
103     }
104 }
105