1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using Antmicro.Renode.Core; 8 using Antmicro.Renode.Core.Structure.Registers; 9 10 namespace Antmicro.Renode.Peripherals.Miscellaneous 11 { 12 public class LPC_Clock0 : BasicDoubleWordPeripheral, IKnownSize 13 { LPC_Clock0(IMachine machine)14 public LPC_Clock0(IMachine machine) : base(machine) 15 { 16 DefineRegisters(); 17 } 18 19 public long Size => 0x1000; 20 DefineRegisters()21 private void DefineRegisters() 22 { 23 Registers.FreeRunningOscillatorControl.Define(this) 24 .WithValueField(0, 16, out freeRunningOscillatorExpectedCount, name: "EXP_COUNT") 25 .WithValueField(16, 5, name: "THRESH_RANGE_UP") 26 .WithValueField(21, 5, name: "THRESH_RANGE_LOW") 27 .WithReservedBits(26, 5) 28 .WithFlag(31, name: "ENA_TUNE"); 29 30 Registers.FreeRunningOscillatorCapturedValue.Define(this) 31 .WithValueField(0, 16, FieldMode.Read, name: "CAPVAL", 32 valueProviderCallback: _ => freeRunningOscillatorExpectedCount.Value) 33 .WithReservedBits(16, 15) 34 // It's set to true at the end of each measurement cycle. 35 // We set it on read, to handle situtaions, where software is waiting on new measurement. 36 .WithFlag(31, out freeRunningOscillatorCapvalDataValid, FieldMode.ReadToSet, name: "DATA_VALID"); 37 38 Registers.FreeRunningOscillatorTrim.Define(this, 0x3bf) 39 .WithValueField(0, 6, name: "TRIM", 40 writeCallback: (_, __) => freeRunningOscillatorCapvalDataValid.Value = false) 41 .WithReservedBits(6, 26); 42 43 Registers.FreeRunningOscillatorScTrim.Define(this) 44 .WithValueField(0, 6, name: "TRIM") 45 .WithReservedBits(6, 26); 46 47 Registers.FreeRunningOscillatorClockStatus.Define(this) 48 .WithFlag(0, name: "CLK_OK", valueProviderCallback: _ => true) 49 .WithReservedBits(1, 31); 50 51 Registers.FreeRunningOscillatorEnable.Define(this) 52 .WithFlag(0, name: "FRO_DIV1_O_EN") 53 .WithFlag(1, name: "FRO_DIV2_O_EN") 54 .WithFlag(2, name: "FRO_DIV4_O_EN") 55 .WithFlag(3, name: "FRO_DIV8_O_EN") 56 .WithFlag(4, name: "FRO_DIV16_O_EN") 57 .WithReservedBits(5, 27); 58 59 Registers.SystemOscillatorControl0.Define(this) 60 .WithFlag(0, name: "LP_ENABLE") 61 .WithFlag(1, name: "BYPASS_ENABLE") 62 .WithReservedBits(2, 30); 63 64 Registers.OscillatorClockSource.Define(this) 65 .WithValueField(0, 3, name: "SEL") 66 .WithReservedBits(3, 29); 67 68 Registers.LowPowerOscilatorControl0.Define(this) 69 .WithReservedBits(0, 31) 70 .WithFlag(31, name: "CLKRDY", valueProviderCallback: _ => true); 71 72 Registers.SystemPll0ClockSelect.Define(this) 73 .WithValueField(0, 3, name: "SEL") 74 .WithReservedBits(3, 29); 75 76 Registers.SystemPll0ClockControl0.Define(this) 77 .WithTaggedFlag("BYPASS", 0) 78 .WithTaggedFlag("RESET", 1) 79 .WithReservedBits(2, 11) 80 .WithFlag(13, name: "HOLDRINGOFF_ENA") 81 .WithReservedBits(14, 2) 82 .WithValueField(16, 8, name: "MULT") 83 .WithReservedBits(24, 8); 84 85 Registers.SystemPll0Numerator.Define(this) 86 .WithValueField(0, 30, name: "NUM") 87 .WithReservedBits(30, 2); 88 89 Registers.SystemPll0Denominator.Define(this) 90 .WithValueField(0, 30, name: "DENOM") 91 .WithReservedBits(30, 2); 92 93 Registers.SystemPll0Pfd.Define(this) 94 .WithValueField(0, 6, name: "PFD0") 95 .WithFlag(6, name: "PFD0_CLKRDY", valueProviderCallback: _ => true) 96 .WithFlag(7, name: "PFD0_CLKGATE") 97 .WithValueField(8, 6, name: "PFD1") 98 .WithFlag(14, name: "PFD1_CLKRDY", valueProviderCallback: _ => true) 99 .WithFlag(15, name: "PFD1_CLKGATE") 100 .WithValueField(16, 6, name: "PFD2") 101 .WithFlag(22, name: "PFD2_CLKRDY", valueProviderCallback: _ => true) 102 .WithFlag(23, name: "PFD2_CLKGATE") 103 .WithValueField(24, 6, name: "PFD3") 104 .WithFlag(30, name: "PFD3_CLKRDY", valueProviderCallback: _ => true) 105 .WithFlag(31, name: "PFD3_CLKGATE"); 106 107 Registers.Aux0PllClockDivider.Define(this) 108 .WithValueField(0, 8, name: "DIV") 109 .WithReservedBits(8, 21) 110 .WithTaggedFlag("RESET", 29) 111 .WithTaggedFlag("HALT", 30) 112 .WithTaggedFlag("REQFLAG", 31); 113 114 Registers.Aux1PllClockDivider.Define(this) 115 .WithValueField(0, 8, name: "DIV") 116 .WithReservedBits(8, 21) 117 .WithTaggedFlag("RESET", 29) 118 .WithTaggedFlag("HALT", 30) 119 .WithTaggedFlag("REQFLAG", 31); 120 121 Registers.SystemCpuAhbClockDivider.Define(this) 122 .WithValueField(0, 8, name: "DIV") 123 .WithReservedBits(8, 23) 124 .WithTaggedFlag("REQFLAG", 31); 125 126 Registers.MainClockSelectA.Define(this) 127 .WithValueField(0, 3, name: "SEL") 128 .WithReservedBits(3, 29); 129 130 Registers.MainClockSelectB.Define(this) 131 .WithValueField(0, 3, name: "SEL") 132 .WithReservedBits(3, 29); 133 134 Registers.HighSpeedUsbClockDivider0.Define(this) 135 .WithValueField(0, 8, name: "DIV") 136 .WithReservedBits(8, 21) 137 .WithTaggedFlag("RESET", 29) 138 .WithTaggedFlag("HALT", 30) 139 .WithTaggedFlag("REQFLAG", 31); 140 141 Registers.HighSpeedUsbClockDivider1.Define(this) 142 .WithValueField(0, 8, name: "DIV") 143 .WithReservedBits(8, 21) 144 .WithTaggedFlag("RESET", 29) 145 .WithTaggedFlag("HALT", 30) 146 .WithTaggedFlag("REQFLAG", 31); 147 148 Registers.FlexSpi0ClockSelect.Define(this) 149 .WithValueField(0, 3, name: "SEL") 150 .WithReservedBits(3, 29); 151 152 Registers.FlexSpi0ClockDivider.Define(this) 153 .WithValueField(0, 8, name: "DIV") 154 .WithReservedBits(8, 21) 155 .WithTaggedFlag("RESET", 29) 156 .WithTaggedFlag("HALT", 30) 157 .WithTaggedFlag("REQFLAG", 31); 158 159 Registers.FlexSpi1ClockSelect.Define(this) 160 .WithValueField(0, 3, name: "SEL") 161 .WithReservedBits(3, 29); 162 163 Registers.FlexSpi1ClockDivider.Define(this) 164 .WithValueField(0, 8, name: "DIV") 165 .WithReservedBits(8, 21) 166 .WithTaggedFlag("RESET", 29) 167 .WithTaggedFlag("HALT", 30) 168 .WithTaggedFlag("REQFLAG", 31); 169 170 Registers.Sdio0FunctionalClockSelect.Define(this) 171 .WithValueField(0, 3, name: "SEL") 172 .WithReservedBits(3, 29); 173 174 Registers.Sdio0FunctionalClockDivider.Define(this) 175 .WithValueField(0, 8, name: "DIV") 176 .WithReservedBits(8, 21) 177 .WithTaggedFlag("RESET", 29) 178 .WithTaggedFlag("HALT", 30) 179 .WithTaggedFlag("REQFLAG", 31); 180 181 Registers.Sdio1FunctionalClockSelect.Define(this) 182 .WithValueField(0, 3, name: "SEL") 183 .WithReservedBits(3, 29); 184 185 Registers.Sdio1FunctionalClockDivider.Define(this) 186 .WithValueField(0, 8, name: "DIV") 187 .WithReservedBits(8, 21) 188 .WithTaggedFlag("RESET", 29) 189 .WithTaggedFlag("HALT", 30) 190 .WithTaggedFlag("REQFLAG", 31); 191 192 Registers.Adc0ClockSelect0.Define(this) 193 .WithValueField(0, 3, name: "SEL") 194 .WithReservedBits(3, 29); 195 196 Registers.Adc0ClockSelect1.Define(this) 197 .WithValueField(0, 3, name: "SEL") 198 .WithReservedBits(3, 29); 199 200 Registers.Adc0ClockDivider.Define(this) 201 .WithValueField(0, 8, name: "DIV") 202 .WithReservedBits(8, 21) 203 .WithTaggedFlag("RESET", 29) 204 .WithTaggedFlag("HALT", 30) 205 .WithTaggedFlag("REQFLAG", 31); 206 207 Registers.SystickFunctionalClockDivider.Define(this) 208 .WithValueField(0, 8, name: "DIV") 209 .WithReservedBits(8, 21) 210 .WithTaggedFlag("RESET", 29) 211 .WithTaggedFlag("HALT", 30) 212 .WithTaggedFlag("REQFLAG", 31); 213 } 214 215 private IValueRegisterField freeRunningOscillatorExpectedCount; 216 private IFlagRegisterField freeRunningOscillatorCapvalDataValid; 217 218 private enum Registers 219 { 220 FreeRunningOscillatorControl = 0x080, 221 FreeRunningOscillatorCapturedValue = 0x084, 222 FreeRunningOscillatorTrim = 0x08c, 223 FreeRunningOscillatorScTrim = 0x090, 224 FreeRunningOscillatorClockStatus = 0x10c, 225 FreeRunningOscillatorEnable = 0x110, 226 SystemOscillatorControl0 = 0x160, 227 OscillatorClockSource = 0x168, 228 LowPowerOscilatorControl0 = 0x190, 229 SystemPll0ClockSelect = 0x200, 230 SystemPll0ClockControl0 = 0x204, 231 SystemPll0Numerator = 0x210, 232 SystemPll0Denominator = 0x214, 233 SystemPll0Pfd = 0x218, 234 Aux0PllClockDivider = 0x248, 235 Aux1PllClockDivider = 0x24c, 236 SystemCpuAhbClockDivider = 0x400, 237 MainClockSelectA = 0x430, 238 MainClockSelectB = 0x434, 239 HighSpeedUsbClockDivider0 = 0x500, 240 HighSpeedUsbClockDivider1 = 0x504, 241 FlexSpi0ClockSelect = 0x620, 242 FlexSpi0ClockDivider = 0x624, 243 FlexSpi1ClockSelect = 0x630, 244 FlexSpi1ClockDivider = 0x634, 245 Sdio0FunctionalClockSelect = 0x680, 246 Sdio0FunctionalClockDivider = 0x684, 247 Sdio1FunctionalClockSelect = 0x690, 248 Sdio1FunctionalClockDivider = 0x694, 249 Adc0ClockSelect0 = 0x6d0, 250 Adc0ClockSelect1 = 0x6d4, 251 Adc0ClockDivider = 0x6d8, 252 SystickFunctionalClockDivider = 0x764, 253 } 254 } 255 } 256