1 // 2 // Copyright (c) 2010-2025 Antmicro 3 // Copyright (c) 2022-2025 Silicon Labs 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 9 using System.Collections.Generic; 10 using System.IO; 11 using Antmicro.Renode.Core; 12 using Antmicro.Renode.Core.Structure.Registers; 13 using Antmicro.Renode.Exceptions; 14 using Antmicro.Renode.Logging; 15 using Antmicro.Renode.Peripherals.Bus; 16 using Antmicro.Renode.Peripherals.Timers; 17 using Antmicro.Renode.Time; 18 using Antmicro.Renode.Peripherals.CPU; 19 20 namespace Antmicro.Renode.Peripherals.Miscellaneous.SiLabs 21 { 22 public class EFR32xG24_FlashUserData : IBytePeripheral, IKnownSize 23 { EFR32xG24_FlashUserData(Machine machine)24 public EFR32xG24_FlashUserData(Machine machine) 25 { 26 this.machine = machine; 27 this.uid = ++count; 28 } 29 Reset()30 public void Reset() 31 { 32 } 33 ReadByte(long offset)34 public byte ReadByte(long offset) 35 { 36 if (offset >= (long)ManufacturerToken.mfgCustomEui64 && offset < (long)ManufacturerToken.mfgCustomEui64 + (long)ManufacturerTokenLength.mfgCustomEui64Length) 37 { 38 return Eui64(offset); 39 } 40 else if (offset >= (long)ManufacturerToken.mfgCcaThreshold && offset < (long)ManufacturerToken.mfgCcaThreshold + (long)ManufacturerTokenLength.mfgCcaThresholdLength) 41 { 42 return CcaThreshold(offset); 43 } 44 else 45 { 46 this.Log(LogLevel.Error, "Unhandled read at offset 0x{0:X}", offset); 47 } 48 49 return 0; 50 } 51 WriteByte(long offset, byte value)52 public void WriteByte(long offset, byte value) 53 { 54 this.Log(LogLevel.Error, "Writing manufacturer token space"); 55 } 56 Eui64(long offset)57 public byte Eui64(long offset) 58 { 59 int byteIndex = (int)(offset - (long)ManufacturerToken.mfgCustomEui64); 60 61 if (byteIndex >= Eui64Size) 62 { 63 this.Log(LogLevel.Error, "EUI64 index out of bounds {0}", byteIndex); 64 return 0; 65 } 66 67 // Most significant bytes represent the company OUI 68 if (byteIndex >= (Eui64Size - Eui64OUILength)) { 69 return SiliconLabsEui64OUI[byteIndex - (Eui64Size - Eui64OUILength)]; 70 } 71 // Least significant 4 bytes are the UID 72 else if (byteIndex < 4) 73 { 74 return (byte)((uid >> byteIndex*8) & 0xFF); 75 } 76 // We set the rest of the bytes to zeros 77 else 78 { 79 return 0; 80 } 81 } 82 83 // The format of this token is: 84 // uint8_t ccaThresholdSubNeg : 7, // bits <15:9> unsigned but negated 85 // bool ccaThreshold2p4Invalid : 1, // bit <8> 1=invalid 0=valid 86 // int8_t ccaThreshold2p4 : 8, // bits <7:0> signed 2's complement 87 // where: 88 // ccaThresholdSubNeg is 7-bit unsigned value where values 0 and 127 89 // both mean "use default" (which is what allows us to jam SubGHz 90 // CCA threshold oonfiguration into this pre-existing token), and 91 // values 1..126 are negated to map to -1..-126 dBm, respectively. 92 // ccaThreshold2p4Invalid indicates whether ccaThreshold2p4 is valid; 93 // ccaThreshold2p4 is the actual signed 2's complement CCA threshold; CcaThreshold(long offset)94 public byte CcaThreshold(long offset) 95 { 96 int byteIndex = (int)(offset - (long)ManufacturerToken.mfgCcaThreshold); 97 if (byteIndex == 0) 98 { 99 return (byte)ccaThreshold; 100 } 101 else 102 { 103 return 0; 104 } 105 } 106 107 public long Size => 0xA; 108 private const uint Eui64Size = 8; 109 public const uint Eui64OUILength = 3; 110 private uint uid; 111 private readonly Machine machine; 112 private static uint count = 0; 113 public static readonly byte[] SiliconLabsEui64OUI = {0xCC, 0xCC, 0xCC}; 114 public static sbyte ccaThreshold = -75; 115 private enum ManufacturerToken 116 { 117 mfgCustomEui64 = 0x002, 118 mfgCustomVersion = 0x00C, 119 mfgString = 0x010, 120 mfgBoardName = 0x020, 121 mfgManufacturerId = 0x030, 122 mfgPhyConfig = 0x034, 123 mfgAshConfig = 0x038, 124 mfgSynthFrequencyOffset = 0x060, 125 mfgCcaThreshold = 0x064, 126 mfgEzspStorage = 0x068, 127 mfgXoTune = 0x070, 128 mfgZwaveCountryFrequency = 0x074, 129 mfgZwaveHardwareVersion = 0x078, 130 mfgZwavePseudoRng = 0x07C, 131 mfgSerialNumber = 0x08C, 132 mfgLfxoTune = 0x09C, 133 mfgCtune = 0x100, 134 mfgKitSignature = 0x104, 135 } 136 137 private enum ManufacturerTokenLength 138 { 139 mfgCustomEui64Length = 8, 140 mfgCustomVersionLength = 2, 141 mfgStringLength = 16, 142 mfgBoardNameLength = 16, 143 mfgManufacturerIdLength = 2, 144 mfgPhyConfigLength = 2, 145 mfgAshConfigLength = 40, 146 mfgSynthFrequencyOffsetLength = 2, 147 mfgCcaThresholdLength = 2, 148 mfgEzspStorageLength = 8, 149 mfgXoTuneLength = 2, 150 mfgZwaveCountryFrequencyLength = 1, 151 mfgZwaveHardwareVersionLength = 1, 152 mfgZwavePseudoRngLength = 16, 153 mfgSerialNumberLength = 16, 154 mfgLfxoTuneLength = 1, 155 mfgCtuneLength = 2, 156 mfgKitSignatureLength = 4, 157 } 158 } 159 }