1 // 2 // Copyright (c) 2010-2021 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; 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.Utilities; 16 using Antmicro.Renode.Time; 17 using Antmicro.Renode.Peripherals.Bus; 18 using Antmicro.Renode.Peripherals.Timers; 19 using Antmicro.Renode.Peripherals.DMA; 20 using static System.Math; 21 22 namespace Antmicro.Renode.Peripherals.Analog 23 { 24 public class ADCChannel 25 { ADCChannel(IPeripheral parent, int channelId)26 public ADCChannel(IPeripheral parent, int channelId) 27 { 28 this.channelId = channelId; 29 this.parent = parent; 30 samples = new Queue<uint>(); 31 } 32 PrepareSample()33 public void PrepareSample() 34 { 35 lock(lockObject) 36 { 37 if(samples.Count == 0 && bufferedSamples != null) 38 { 39 samples.EnqueueRange(bufferedSamples); 40 } 41 42 if(!samples.TryDequeue(out currentSample)) 43 { 44 currentSample = 0; 45 parent.Log(LogLevel.Warning, "No more samples available in channel {0}", channelId); 46 } 47 } 48 } 49 GetSample()50 public uint GetSample() 51 { 52 lock(lockObject) 53 { 54 return currentSample; 55 } 56 } 57 FeedSample(uint sample, int repeat = 1)58 public void FeedSample(uint sample, int repeat = 1) 59 { 60 lock(lockObject) 61 { 62 if(repeat == -1) 63 { 64 bufferedSamples = new uint [] { sample }; 65 } 66 else 67 { 68 bufferedSamples = null; 69 for(var i = 0; i < repeat; i++) 70 { 71 samples.Enqueue(sample); 72 } 73 } 74 } 75 } 76 FeedSample(IEnumerable<uint> samplesCollection, int repeat = 1)77 public void FeedSample(IEnumerable<uint> samplesCollection, int repeat = 1) 78 { 79 lock(lockObject) 80 { 81 if(repeat == -1) 82 { 83 bufferedSamples = samplesCollection; 84 } 85 else 86 { 87 bufferedSamples = null; 88 for(var i = 0; i < repeat; i++) 89 { 90 samples.EnqueueRange(samplesCollection); 91 } 92 } 93 } 94 } 95 Reset()96 public void Reset() 97 { 98 lock(lockObject) 99 { 100 bufferedSamples = null; 101 samples.Clear(); 102 currentSample = 0; 103 } 104 } 105 ParseSamplesFile(string path)106 public static IEnumerable<uint> ParseSamplesFile(string path) 107 { 108 var localQueue = new Queue<uint>(); 109 var lineNumber = 0; 110 111 try 112 { 113 using(var reader = File.OpenText(path)) 114 { 115 var line = ""; 116 while((line = reader.ReadLine()) != null) 117 { 118 ++lineNumber; 119 if(!uint.TryParse(line.Trim(), out var sample)) 120 { 121 throw new RecoverableException($"Wrong data file format at line {lineNumber}. Expected an unsigned integer number, but got '{line}'"); 122 } 123 124 localQueue.Enqueue(sample); 125 } 126 } 127 } 128 catch(Exception e) 129 { 130 if(e is RecoverableException) 131 { 132 throw; 133 } 134 135 // this is to nicely handle IO errors in monitor 136 throw new RecoverableException(e.Message); 137 } 138 139 return localQueue; 140 } 141 142 private readonly IPeripheral parent; 143 private readonly int channelId; 144 145 private object lockObject = new object(); 146 147 // Sample returned when queried 148 private uint currentSample; 149 // Used for implementing repeat, need to store a sequence of samples 150 private IEnumerable<uint> bufferedSamples; 151 // The current sample sequence 152 private readonly Queue<uint> samples; 153 } 154 } 155