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 Antmicro.Renode.Core;
9 using Antmicro.Renode.Logging;
10 using Antmicro.Renode.Peripherals.Bus;
11 using Antmicro.Renode.Peripherals.UART;
12 using Antmicro.Renode.Plugins.CoSimulationPlugin.Connection;
13 using Antmicro.Renode.Plugins.CoSimulationPlugin.Connection.Protocols;
14 using Range = Antmicro.Renode.Core.Range;
15 
16 namespace Antmicro.Renode.Peripherals.CoSimulated
17 {
18     [AllowedTranslations(AllowedTranslation.ByteToDoubleWord)]
19     public class CoSimulatedUART : CoSimulatedPeripheral, IUART
20     {
CoSimulatedUART(Machine machine, int maxWidth = 64, bool useAbsoluteAddress = false, long frequency = VerilogTimeunitFrequency, string simulationFilePathLinux = null, string simulationFilePathWindows = null, string simulationFilePathMacOS = null, string simulationContextLinux = null, string simulationContextWindows = null, string simulationContextMacOS = null, ulong limitBuffer = LimitBuffer, int timeout = DefaultTimeout, string address = null, bool createConnection = true, ulong renodeToCosimSignalsOffset = 0, Range? cosimToRenodeSignalRange = null)21         public CoSimulatedUART(Machine machine, int maxWidth = 64, bool useAbsoluteAddress = false, long frequency = VerilogTimeunitFrequency,
22             string simulationFilePathLinux = null, string simulationFilePathWindows = null, string simulationFilePathMacOS = null,
23             string simulationContextLinux = null, string simulationContextWindows = null, string simulationContextMacOS = null,
24             ulong limitBuffer = LimitBuffer, int timeout = DefaultTimeout, string address = null, bool createConnection = true,
25             ulong renodeToCosimSignalsOffset = 0, Range? cosimToRenodeSignalRange = null)
26             : base(machine, maxWidth, useAbsoluteAddress, frequency,
27                     simulationFilePathLinux, simulationFilePathWindows, simulationFilePathMacOS,
28                     simulationContextLinux, simulationContextWindows, simulationContextMacOS,
29                     limitBuffer, timeout, address, createConnection, renodeToCosimSignalsOffset,
30                     cosimToRenodeSignalRange, 0, 0)
31         {
32             IRQ = new GPIO();
33         }
34 
WriteChar(byte value)35         public void WriteChar(byte value)
36         {
37             connection.Send(this, (ActionType)UARTActionNumber.UARTRxd, 0, value);
38         }
39 
HandleReceivedMessage(ProtocolMessage message)40         public bool HandleReceivedMessage(ProtocolMessage message)
41         {
42             if(message.ActionId == (ActionType)UARTActionNumber.UARTTxd)
43             {
44                 CharReceived?.Invoke((byte)message.Data);
45                 return true;
46             }
47 
48             return false;
49         }
50 
ReceiveGPIOChange(int coSimNumber, bool value)51         public override void ReceiveGPIOChange(int coSimNumber, bool value)
52         {
53             if(!cosimToRenodeSignalRange.HasValue)
54             {
55                 this.Log(LogLevel.Warning, $"Received GPIO change from co-simulation, but no cosimToRenodeSignalRange is defined.");
56                 return;
57             }
58 
59             var localNumber = coSimNumber - (int)cosimToRenodeSignalRange.Value.StartAddress;
60             if (localNumber != RxdInterrupt)
61             {
62                  this.Log(LogLevel.Warning, "Unhandled interrupt: '{0}'", localNumber);
63                  return;
64             }
65 
66             IRQ.Set(value);
67         }
68 
OnConnectionAttached(CoSimulationConnection connection)69         public override void OnConnectionAttached(CoSimulationConnection connection)
70         {
71             base.OnConnectionAttached(connection);
72             connection.OnReceive += HandleReceivedMessage;
73         }
74 
OnConnectionDetached(CoSimulationConnection connection)75         public override void OnConnectionDetached(CoSimulationConnection connection)
76         {
77             connection.OnReceive -= HandleReceivedMessage;
78             base.OnConnectionDetached(connection);
79         }
80 
81         // StopBits, ParityBit and BaudRate are not in sync with the cosimulated model
82         public Bits StopBits { get { return Bits.One; } }
83         public Parity ParityBit { get { return Parity.None; } }
84         public uint BaudRate { get { return 115200; } }
85         public event Action<byte> CharReceived;
86         public GPIO IRQ { get; private set; }
87 
88         private const int RxdInterrupt = 1;
89     }
90 
91     // UARTActionNumber must be in sync with integration library
92     public enum UARTActionNumber
93     {
94         UARTTxd = 13,
95         UARTRxd = 14
96     }
97 }
98