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 System; 8 using System.Collections.Generic; 9 using System.Globalization; 10 11 namespace Antmicro.Renode.Utilities.RESD 12 { 13 public abstract class RESDSample : IAutoLoadType 14 { TryReadMetadata(SafeBinaryReader reader)15 public virtual bool TryReadMetadata(SafeBinaryReader reader) 16 { 17 Metadata = MetadataBlock.ReadFromStream(reader); 18 return true; 19 } 20 Skip(SafeBinaryReader reader, int count)21 public virtual bool Skip(SafeBinaryReader reader, int count) 22 { 23 if(!Width.HasValue) 24 { 25 throw new RESDException($"This sample type ({this.GetType().Name}) doesn't allow for skipping data."); 26 } 27 28 if(reader.BaseStream.Position + count * Width.Value > reader.Length) 29 { 30 return false; 31 } 32 33 reader.SkipBytes(count * Width.Value); 34 return true; 35 } 36 37 public abstract int? Width { get; } TryReadFromStream(SafeBinaryReader reader)38 public abstract bool TryReadFromStream(SafeBinaryReader reader); 39 40 public IDictionary<string, MetadataValue> Metadata { get; private set; } 41 42 // Ensure decimal dots are always used regardless of the system locale 43 // for consistent output formatting. DecimalToString(decimal value)44 protected static string DecimalToString(decimal value) 45 { 46 return value.ToString(CultureInfo.InvariantCulture); 47 } 48 } 49 50 [SampleType(SampleType.Temperature)] 51 public class TemperatureSample : RESDSample 52 { 53 public override int? Width => 4; 54 55 public int Temperature { get; private set; } 56 TryReadFromStream(SafeBinaryReader reader)57 public override bool TryReadFromStream(SafeBinaryReader reader) 58 { 59 Temperature = reader.ReadInt32(); 60 61 return true; 62 } 63 ToString()64 public override string ToString() 65 { 66 return $"{DecimalToString(Temperature / (decimal)1e3)} °C"; 67 } 68 } 69 70 [SampleType(SampleType.Acceleration)] 71 public class AccelerationSample : RESDSample 72 { 73 public override int? Width => 4 * 3; 74 75 public int AccelerationX { get; private set; } 76 public int AccelerationY { get; private set; } 77 public int AccelerationZ { get; private set; } 78 TryReadFromStream(SafeBinaryReader reader)79 public override bool TryReadFromStream(SafeBinaryReader reader) 80 { 81 AccelerationX = reader.ReadInt32(); 82 AccelerationY = reader.ReadInt32(); 83 AccelerationZ = reader.ReadInt32(); 84 85 return true; 86 } 87 ToString()88 public override string ToString() 89 { 90 var xStr = DecimalToString(AccelerationX / (decimal)1e6); 91 var yStr = DecimalToString(AccelerationY / (decimal)1e6); 92 var zStr = DecimalToString(AccelerationZ / (decimal)1e6); 93 94 return $"[{xStr}, {yStr}, {zStr}] g"; 95 } 96 } 97 98 [SampleType(SampleType.AngularRate)] 99 public class AngularRateSample : RESDSample 100 { 101 public override int? Width => 4 * 3; 102 103 public int AngularRateX { get; private set; } 104 public int AngularRateY { get; private set; } 105 public int AngularRateZ { get; private set; } 106 TryReadFromStream(SafeBinaryReader reader)107 public override bool TryReadFromStream(SafeBinaryReader reader) 108 { 109 AngularRateX = reader.ReadInt32(); 110 AngularRateY = reader.ReadInt32(); 111 AngularRateZ = reader.ReadInt32(); 112 113 return true; 114 } 115 ToString()116 public override string ToString() 117 { 118 var xStr = DecimalToString(AngularRateX / (decimal)1e5); 119 var yStr = DecimalToString(AngularRateY / (decimal)1e5); 120 var zStr = DecimalToString(AngularRateZ / (decimal)1e5); 121 122 return $"[{xStr}, {yStr}, {zStr}] rad/s"; 123 } 124 } 125 126 [SampleType(SampleType.Voltage)] 127 public class VoltageSample : RESDSample 128 { 129 public override int? Width => 4; 130 131 public uint Voltage { get; private set; } 132 TryReadFromStream(SafeBinaryReader reader)133 public override bool TryReadFromStream(SafeBinaryReader reader) 134 { 135 Voltage = reader.ReadUInt32(); 136 137 return true; 138 } 139 ToString()140 public override string ToString() 141 { 142 return $"{DecimalToString(Voltage / (decimal)1e6)} V"; 143 } 144 } 145 146 [SampleType(SampleType.ECG)] 147 public class ECGSample : RESDSample 148 { 149 public override int? Width => 4; 150 151 public int ECG { get; private set; } 152 TryReadFromStream(SafeBinaryReader reader)153 public override bool TryReadFromStream(SafeBinaryReader reader) 154 { 155 ECG = reader.ReadInt32(); 156 157 return true; 158 } 159 ToString()160 public override string ToString() 161 { 162 return $"{ECG} nV"; 163 } 164 } 165 166 [SampleType(SampleType.Humidity)] 167 public class HumiditySample : RESDSample 168 { 169 public override int? Width => 4; 170 171 public uint Humidity { get; private set; } 172 TryReadFromStream(SafeBinaryReader reader)173 public override bool TryReadFromStream(SafeBinaryReader reader) 174 { 175 Humidity = reader.ReadUInt32(); 176 177 return true; 178 } 179 ToString()180 public override string ToString() 181 { 182 return $"{DecimalToString(Humidity / 1e3m)} %RH"; 183 } 184 } 185 186 [SampleType(SampleType.Pressure)] 187 public class PressureSample : RESDSample 188 { 189 public override int? Width => 8; 190 191 public ulong Pressure { get; private set; } 192 TryReadFromStream(SafeBinaryReader reader)193 public override bool TryReadFromStream(SafeBinaryReader reader) 194 { 195 Pressure = reader.ReadUInt64(); 196 197 return true; 198 } 199 ToString()200 public override string ToString() 201 { 202 return $"{DecimalToString(Pressure / (decimal)1e3)} Pa"; 203 } 204 } 205 206 [SampleType(SampleType.MagneticFluxDensity)] 207 public class MagneticSample : RESDSample 208 { 209 public override int? Width => 4 * 3; 210 211 public int MagneticFluxDensityX { get; private set; } 212 public int MagneticFluxDensityY { get; private set; } 213 public int MagneticFluxDensityZ { get; private set; } 214 TryReadFromStream(SafeBinaryReader reader)215 public override bool TryReadFromStream(SafeBinaryReader reader) 216 { 217 MagneticFluxDensityX = reader.ReadInt32(); 218 MagneticFluxDensityY = reader.ReadInt32(); 219 MagneticFluxDensityZ = reader.ReadInt32(); 220 221 return true; 222 } 223 ToString()224 public override string ToString() 225 { 226 return $"[{MagneticFluxDensityX}, {MagneticFluxDensityY}, {MagneticFluxDensityZ}] nT"; 227 } 228 } 229 230 public class SampleTypeAttribute : Attribute 231 { SampleTypeAttribute(SampleType sampleType)232 public SampleTypeAttribute(SampleType sampleType) 233 { 234 this.SampleType = sampleType; 235 } 236 237 public SampleType SampleType { get; } 238 } 239 240 public enum SampleType 241 { 242 // General sample types 243 Temperature = 0x0001, 244 Acceleration = 0x002, 245 AngularRate = 0x0003, 246 Voltage = 0x0004, 247 ECG = 0x0005, 248 Humidity = 0x0006, 249 Pressure = 0x0007, 250 MagneticFluxDensity = 0x0008, 251 252 // Custom sample types 253 Custom = 0xF000, 254 } 255 } 256