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 Antmicro.Renode.Peripherals.Bus; 8 using Antmicro.Renode.Core.Structure.Registers; 9 using System.Collections.Generic; 10 using System; 11 using Antmicro.Renode.Logging; 12 using Antmicro.Renode.Utilities; 13 14 namespace Antmicro.Renode.Peripherals.Miscellaneous.SiLabs 15 { 16 public class EFR32_GPCRC : IDoubleWordPeripheral, IKnownSize 17 { EFR32_GPCRC()18 public EFR32_GPCRC() 19 { 20 gpcrc = new CRCEngine(DefaultPolynomial); 21 var registerMap = new Dictionary<long, DoubleWordRegister> 22 { 23 {(long)Registers.Control, new DoubleWordRegister(this) 24 .WithFlag(0, changeCallback: (_, enable) => { isEnabled = enable; }, name: "EN") 25 .WithReservedBits(1, 3) 26 .WithFlag(4, changeCallback: (_, polySel) => 27 { 28 if(polySel) 29 { 30 this.Log(LogLevel.Warning, "16-bit polynomial is not supported"); 31 } 32 }, name: "POLYSEL") 33 .WithReservedBits(5, 3) 34 .WithTaggedFlag("BYTEMODE", 8) 35 .WithTag("BITEREVERSE", 9, 1) 36 .WithTaggedFlag("BYTEREVERSE", 10) 37 .WithReservedBits(11, 2) 38 .WithTaggedFlag("AUTOINIT", 13) 39 .WithReservedBits(14, 18) 40 }, 41 {(long)Registers.Command, new DoubleWordRegister(this) 42 .WithFlag(0, FieldMode.Write, changeCallback: (_, value) => { if(value) { UpdateInitVal(); } }, name: "INIT") 43 .WithReservedBits(1, 31) 44 }, 45 {(long)Registers.Init, new DoubleWordRegister(this) 46 .WithValueField(0, 32, out initDataField, name: "INIT") 47 }, 48 {(long)Registers.InputData, new DoubleWordRegister(this) 49 .WithValueField(0, 32, FieldMode.Write, writeCallback: (_, value) => 50 { 51 gpcrc.Update(BitConverter.GetBytes((uint)value)); 52 }, name: "INPUTDATA") 53 }, 54 {(long)Registers.Data, new DoubleWordRegister(this) 55 .WithValueField(0, 32, FieldMode.Read, name: "DATA", valueProviderCallback: _ => gpcrc.Value) 56 }, 57 }; 58 registers = new DoubleWordRegisterCollection(this, registerMap); 59 } 60 Reset()61 public void Reset() 62 { 63 registers.Reset(); 64 isEnabled = false; 65 } 66 ReadDoubleWord(long offset)67 public uint ReadDoubleWord(long offset) 68 { 69 return registers.Read(offset); 70 } 71 WriteDoubleWord(long offset, uint value)72 public void WriteDoubleWord(long offset, uint value) 73 { 74 registers.Write(offset, value); 75 } 76 77 public long Size => 0x400; 78 UpdateInitVal()79 private void UpdateInitVal() 80 { 81 if(isEnabled) 82 { 83 gpcrc.RawValue = (uint)initDataField.Value; 84 } 85 } 86 87 private CRCEngine gpcrc; 88 private readonly DoubleWordRegisterCollection registers; 89 private bool isEnabled; 90 private IValueRegisterField initDataField; 91 92 private readonly CRCPolynomial DefaultPolynomial = CRCPolynomial.CRC32; 93 94 private enum Registers 95 { 96 Control = 0x00, 97 Command = 0x04, 98 Init = 0x08, 99 Polynomial = 0x0C, 100 InputData = 0x10, 101 InputDataHWord = 0x14, 102 InputDataByte = 0x18, 103 Data = 0x1C, 104 DataReverse = 0x20, 105 DataByteReverse = 0x24, 106 } 107 } 108 } 109