1 // 2 // Copyright (c) 2010-2024 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 Antmicro.Renode.Logging; 10 using Antmicro.Renode.Peripherals.Sensor; 11 using Antmicro.Renode.Utilities; 12 13 namespace Antmicro.Renode.Network.ExternalControl 14 { 15 public class ADC : BaseCommand, IInstanceBasedCommand<IADC> 16 { ADC(ExternalControlServer parent)17 public ADC(ExternalControlServer parent) 18 : base(parent) 19 { 20 Instances = new InstanceCollection<IADC>(); 21 } 22 23 public override Response Invoke(List<byte> data) => this.InvokeHandledWithInstance(data); 24 Invoke(IADC instance, List<byte> data)25 public Response Invoke(IADC instance, List<byte> data) 26 { 27 if(data.Count < 1) 28 { 29 return Response.CommandFailed(Identifier, $"Expected at least {1 + InstanceBasedCommandHeaderSize} bytes of payload"); 30 } 31 var command = (ADCCommand)data[0]; 32 33 var expectedCount = GetExpectedPayloadCount(command); 34 if(expectedCount != data.Count) 35 { 36 return Response.CommandFailed(Identifier, $"Expected {expectedCount + InstanceBasedCommandHeaderSize} bytes of payload"); 37 } 38 39 switch(command) 40 { 41 case ADCCommand.GetCount: 42 var channelCount = instance.ADCChannelCount; 43 parent.Log(LogLevel.Debug, "Executing ADC GetCount command, returned {0}", channelCount); 44 return Response.Success(Identifier, channelCount.AsRawBytes()); 45 46 case ADCCommand.GetValue: 47 DecodeChannelArgument(data, out var channel); 48 var value = instance.GetADCValue(channel); 49 parent.Log(LogLevel.Debug, "Executing ADC GetValue command, channel #{0} returned {1}", channel, value); 50 return Response.Success(Identifier, value.AsRawBytes()); 51 52 case ADCCommand.SetValue: 53 DecodeSetValueArguments(data, out channel, out value); 54 parent.Log(LogLevel.Debug, "Executing ADC SetValue command, channel #{0} set to {1}", channel, value); 55 instance.SetADCValue(channel, value); 56 return Response.Success(Identifier); 57 58 default: 59 return Response.CommandFailed(Identifier, "Unexpected command format"); 60 } 61 } 62 63 public InstanceCollection<IADC> Instances { get; } 64 65 public override Command Identifier => Command.ADC; 66 public override byte Version => 0x0; 67 GetExpectedPayloadCount(ADCCommand command)68 private int GetExpectedPayloadCount(ADCCommand command) 69 { 70 switch(command) 71 { 72 case ADCCommand.GetValue: 73 return sizeof(byte) + sizeof(uint); 74 case ADCCommand.SetValue: 75 return sizeof(byte) + sizeof(uint) * 2; 76 default: 77 return sizeof(byte); 78 } 79 } 80 DecodeChannelArgument(List<byte> data, out int channel)81 private void DecodeChannelArgument(List<byte> data, out int channel) 82 { 83 channel = BitConverter.ToInt32(data.GetRange(1, sizeof(uint)).ToArray(), 0); 84 } 85 DecodeSetValueArguments(List<byte> data, out int channel, out uint value)86 private void DecodeSetValueArguments(List<byte> data, out int channel, out uint value) 87 { 88 DecodeChannelArgument(data, out channel); 89 value = BitConverter.ToUInt32(data.GetRange(5, sizeof(uint)).ToArray(), 0); 90 } 91 92 private const int InstanceBasedCommandHeaderSize = IInstanceBasedCommandExtensions.HeaderSize; 93 94 private enum ADCCommand : byte 95 { 96 GetCount = 0, 97 GetValue, 98 SetValue, 99 } 100 } 101 } 102