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 8 using System.Collections.Generic; 9 using System.IO; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Core.Structure.Registers; 12 using Antmicro.Renode.Exceptions; 13 using Antmicro.Renode.Logging; 14 using Antmicro.Renode.Peripherals.Bus; 15 16 namespace Antmicro.Renode.Peripherals.Miscellaneous 17 { 18 public class EFR32_CMU : BasicDoubleWordPeripheral, IKnownSize 19 { EFR32_CMU(IMachine machine)20 public EFR32_CMU(IMachine machine) : base(machine) 21 { 22 DefineRegisters(); 23 } 24 Reset()25 public override void Reset() 26 { 27 base.Reset(); 28 } 29 30 public long Size => 0x200; 31 DefineRegisters()32 private void DefineRegisters() 33 { 34 Registers.OscillatorEnableDisableCommand.Define32(this) 35 .WithFlag(0, FieldMode.Write, name: "HFRCOEN", writeCallback: (_, val) => { if(val) { hfrcoens.Value = true; } }) 36 .WithFlag(1, FieldMode.Write, name: "HFRCODIS", writeCallback: (_, val) => { if(val) { hfrcoens.Value = false; } }) 37 .WithFlag(2, FieldMode.Write, name: "HFXOEN", writeCallback: (_, val) => { if(val) { hfxoens.Value = true; } }) 38 .WithFlag(3, FieldMode.Write, name: "HFXODIS", writeCallback: (_, val) => { if(val) { hfxoens.Value = false; } }) 39 .WithFlag(4, FieldMode.Write, name: "AUXHRFCOEN", writeCallback: (_, val) => { if(val) { auxhrfcoens.Value = true; } }) 40 .WithFlag(5, FieldMode.Write, name: "AUXHRFCODIS", writeCallback: (_, val) => { if(val) { auxhrfcoens.Value = false; } }) 41 .WithFlag(6, FieldMode.Write, name: "LFRCOEN", writeCallback: (_, val) => { if(val) { lfrcoens.Value = true; } }) 42 .WithFlag(7, FieldMode.Write, name: "LFRCODIS", writeCallback: (_, val) => { if(val) { lfrcoens.Value = false; } }) 43 .WithFlag(8, FieldMode.Write, name: "LFXOEN", writeCallback: (_, val) => { if(val) { lfxoens.Value = true; } }) 44 .WithFlag(9, FieldMode.Write, name: "LFXODIS", writeCallback: (_, val) => { if(val) { lfxoens.Value = false; } }) 45 .WithReservedBits(10, 22) 46 ; 47 48 Registers.LowFrequencyEClockSelect.Define32(this) 49 // This field has to be RW with memory, because SW is reading back written value 50 .WithEnumField<DoubleWordRegister, LowFrequencyClockSelectMode>(0, 3, name: "LFE") 51 .WithReservedBits(3, 29) 52 ; 53 54 Registers.Status.Define32(this) 55 .WithFlag(0, out hfrcoens, FieldMode.Read, name: "HFRCOENS") 56 .WithFlag(1, FieldMode.Read, valueProviderCallback: _ => hfrcoens.Value, name: "HFRCORDY") 57 .WithFlag(2, out hfxoens, FieldMode.Read, name: "HFXOENS") 58 .WithFlag(3, FieldMode.Read, valueProviderCallback: _ => hfxoens.Value, name: "HFXORDY") 59 .WithFlag(4, out auxhrfcoens, FieldMode.Read, name: "AUXHRFCOENS") 60 .WithFlag(5, FieldMode.Read, valueProviderCallback: _ => auxhrfcoens.Value, name: "AUXHRFCORDY") 61 .WithFlag(6, out lfrcoens, FieldMode.Read, name: "LFRCOENS") 62 .WithFlag(7, FieldMode.Read, valueProviderCallback: _ => lfrcoens.Value, name: "LFRCORDY") 63 .WithFlag(8, out lfxoens, FieldMode.Read, name: "LFXOENS") 64 .WithFlag(9, FieldMode.Read, valueProviderCallback: _ => lfxoens.Value, name: "LFXORDY") 65 .WithReservedBits(10, 6) 66 .WithFlag(16, name: "CALRDY", valueProviderCallback: _ => true) 67 .WithReservedBits(17, 4) 68 .WithTaggedFlag("HFXOREQ", 21) 69 .WithFlag(22, name: "HFXOPEAKDETRDY", valueProviderCallback: _ => true) 70 .WithFlag(23, name: "HFXOSHUNTOPTRDY", valueProviderCallback: _ => true) 71 .WithTaggedFlag("HFXOAMPHIGH", 24) 72 .WithTaggedFlag("HFXOAMPLOW", 25) 73 .WithTaggedFlag("HFXOREGILOW", 26) 74 .WithReservedBits(27, 5) 75 ; 76 77 Registers.HighFrequencyClockSelectCommand.Define32(this) 78 .WithEnumField(0, 3, out highFrequencyClockSelect, FieldMode.Write, name: "HF") 79 .WithReservedBits(3, 29) 80 ; 81 82 Registers.HighFrequencyClockStatus.Define32(this) 83 .WithEnumField<DoubleWordRegister, ClockSource>(0, 3, FieldMode.Read, name: "SELECTED", valueProviderCallback: _ => highFrequencyClockSelect.Value) 84 .WithReservedBits(3, 29) 85 ; 86 87 Registers.HighFrequencyBusClockEnable.Define32(this) 88 .WithTaggedFlag("CRYPTO0", 0) 89 .WithTaggedFlag("CRYPTO1", 1) 90 .WithTaggedFlag("LE", 2) 91 .WithTaggedFlag("GPIO", 3) 92 .WithTaggedFlag("PRS", 4) 93 .WithTaggedFlag("LDMA", 5) 94 .WithTaggedFlag("GPCRC", 6) 95 .WithReservedBits(7, 25) 96 ; 97 98 Registers.HighFrequencyRadioPeripheralClockEnable.Define32(this) 99 // Those fields have to be RW with memory, because SW is reading back written values 100 .WithFlag(0, name: "PROTIMER") 101 .WithFlag(1, name: "RFSENSE") 102 .WithFlag(2, name: "RAC") 103 .WithFlag(3, name: "FRC") 104 .WithFlag(4, name: "CRC") 105 .WithFlag(5, name: "SYNTH") 106 .WithFlag(6, name: "MODEM") 107 .WithFlag(7, name: "AGC") 108 .WithReservedBits(8, 24) 109 ; 110 111 Registers.RadioDeFeaturing.Define32(this, 0x3f0000) 112 .WithTag("SYNTHLODIVFREQCTRL", 0, 9) 113 .WithTaggedFlag("RACIFLILTENABLE", 9) 114 .WithTaggedFlag("RACAUXPLL", 10) 115 .WithTaggedFlag("MODEMDEC1", 11) 116 .WithTaggedFlag("MODEMANTDIVMODE", 12) 117 .WithTaggedFlag("RACIFPGAENPGA", 13) 118 .WithTag("RACPASLICE", 14, 7) 119 .WithTaggedFlag("RACSGPAEN", 21) 120 .WithTaggedFlag("RACPAEN", 22) 121 .WithTaggedFlag("RACPAEN0DBM", 23) 122 .WithTaggedFlag("FRCCONVMODE", 24) 123 .WithReservedBits(25, 1) 124 .WithTaggedFlag("FRCPAUSING", 26) 125 .WithTaggedFlag("MODEMDSSS", 27) 126 .WithTaggedFlag("MODEMMODFORMAT", 28) 127 .WithTaggedFlag("MODEMDUALSYNC", 29) 128 .WithReservedBits(30, 1) 129 .WithTaggedFlag("UNLOCKED", 31) 130 ; 131 } 132 133 private IFlagRegisterField hfrcoens; 134 private IFlagRegisterField hfxoens; 135 private IFlagRegisterField auxhrfcoens; 136 private IFlagRegisterField lfrcoens; 137 138 private IFlagRegisterField lfxoens; 139 140 private IEnumRegisterField<ClockSource> highFrequencyClockSelect; 141 142 private enum ClockSource 143 { 144 HighFrequencyResistorCapacitorOscillator = 0x1, 145 HighFrequencyCrystalOscillator = 0x2, 146 LowFrequencyResistorCapacitorOscillator = 0x3, 147 LowFrequencyCrystalOscillator = 0x4, 148 HighFrequencyResistorCapacitorOscillatorDividedBy2 = 0x5, 149 ClockInput0 = 0x7, 150 } 151 152 private enum LowFrequencyClockSelectMode 153 { 154 Disabled = 0x0, 155 LowFrequencyResistorCapacitorOscillator = 0x1, 156 LowFrequencyCrystalOscillator = 0x2, 157 HighFrequencyClockLowEnergy = 0x3, 158 UltraLowFrequencyResistorCapacitorOscillator = 0x4, 159 PrecisionLowFrequencyResistorCapacitorOscillator = 0x5, 160 } 161 162 private enum Registers 163 { 164 Control = 0x000, 165 HFRCOControl = 0x010, 166 HFRCOLDOControl = 0x014, 167 AUXHFRCOControl = 0x018, 168 AuxiliaryHFRCOLDOControl = 0x01C, 169 LFRCOControl = 0x020, 170 HFXOControl = 0x024, 171 HFXOSTARTUPControl = 0x02C, 172 HFXOSteadyStateControl = 0x030, 173 HFXOTimeoutControl = 0x034, 174 LFXOControl = 0x038, 175 ULFRCOControl = 0x03C, 176 DPLLControl = 0x040, 177 DPLLControl1 = 0x044, 178 CalibrationControl = 0x050, 179 CalibartionCounter = 0x054, 180 OscillatorEnableDisableCommand = 0x060, 181 Command = 0x064, 182 DebugTraceClockSelect = 0x070, 183 HighFrequencyClockSelectCommand = 0x074, 184 LowFrequencyAClockSelect = 0x080, 185 LowFrequencyBClockSelect = 0x084, 186 LowFrequencyEClockSelect = 0x088, 187 Status = 0x090, 188 HighFrequencyClockStatus = 0x094, 189 HFXOTrimStatus = 0x09C, 190 InterruptFlag = 0x0A0, 191 InterruptFlagSet = 0x0A4, 192 InterruptFlagClear = 0x0A8, 193 InterruptEnable = 0x0AC, 194 HighFrequencyBusClockEnable = 0x0B0, 195 HighFrequencyCoreClockEnable = 0x0B8, 196 HighFrequencyPeripheralClockEnable = 0x0C0, 197 HighFrequencyRadioPeripheralClockEnable = 0x0C8, 198 HighFrequencyAlternateRadioPeripheralClockEnable = 0x0CC, 199 HighFrequencyUndividedClockEnable = 0x0D0, 200 LowFrequencyAClockEnable = 0x0E0, 201 LowFrequencyBClockEnable = 0x0E8, 202 LowFrequencyEClockEnable = 0x0F0, 203 HighFrequencyClockPrescaler = 0x100, 204 HighFrequencyCoreClockPrescaler = 0x108, 205 HighFrequencyPeripheralClockPrescaler = 0x10C, 206 HighFrequencyRadioPeripheralClockPrescaler = 0x110, 207 HighFrequencyExportClockPrescaler = 0x114, 208 LowFrequencyAPrescaler = 0x120, 209 LowFrequencyBPrescaler = 0x128, 210 LowFrequencyEPrescaler = 0x130, 211 HighFrequencyAlternateRadioPeripheralClockPrescaler = 0x138, 212 SynchronizationBusy = 0x140, 213 Freeze = 0x144, 214 PCNTControl = 0x150, 215 LVDSControl = 0x158, 216 ADCControl = 0x15C, 217 RoutingPinEnable = 0x170, 218 RoutingLocation0 = 0x174, 219 RoutingLocation1 = 0x178, 220 ConfigurationLoc = 0x180, 221 HFRCOSpreadSpectrum = 0x184, 222 RadioDeFeaturing = 0x188, 223 HighFrequencyBusClockLock = 0x190, 224 HighFrequencyCoreClockLock = 0x194, 225 HighFrequencyPeripheralClockLock = 0x198, 226 HighFrequencyRadioPeripheralClockLock = 0x1A4, 227 AlternateRadioPeripheralClockLock = 0x1AC, 228 HighFrequencyUndividedClockLock = 0x1B0, 229 LowFrequencyAClockLock = 0x1B4, 230 LowFrequencyBClockLock = 0x1BC, 231 LowFrequencyEClockLock = 0x1C4, 232 PCNTClockLock = 0x1CC, 233 Test = 0x1D0, 234 HFRCOTestControl = 0x1D4, 235 AUXHRCOTestControl = 0x1D8, 236 LFRCOTestControl = 0x1DC, 237 HFXOTestControl = 0x1E0, 238 LFXOTestControl = 0x1E4, 239 DPLLOffset = 0x1FC, 240 } 241 } 242 } 243