blob: 4e580d66d7b37efc9488a67816948f2a41e690f9 [file]
//
// Copyright (c) 2010-2024 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using Antmicro.Renode.Core;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Peripherals.UART;
using Antmicro.Renode.Plugins.CoSimulationPlugin.Connection;
using Antmicro.Renode.Plugins.CoSimulationPlugin.Connection.Protocols;
using Range = Antmicro.Renode.Core.Range;
namespace Antmicro.Renode.Peripherals.CoSimulated
{
[AllowedTranslations(AllowedTranslation.ByteToDoubleWord)]
public class CoSimulatedUART : CoSimulatedPeripheral, IUART
{
public 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)
: base(machine, maxWidth, useAbsoluteAddress, frequency,
simulationFilePathLinux, simulationFilePathWindows, simulationFilePathMacOS,
simulationContextLinux, simulationContextWindows, simulationContextMacOS,
limitBuffer, timeout, address, createConnection, renodeToCosimSignalsOffset,
cosimToRenodeSignalRange)
{
IRQ = new GPIO();
}
public void WriteChar(byte value)
{
connection.Send((ActionType)UARTActionNumber.UARTRxd, 0, value);
}
public bool HandleReceivedMessage(ProtocolMessage message)
{
if(message.ActionId == (ActionType)UARTActionNumber.UARTTxd)
{
CharReceived?.Invoke((byte)message.Data);
return true;
}
return false;
}
public override void ReceiveGPIOChange(int coSimNumber, bool value)
{
if(!cosimToRenodeSignalRange.HasValue)
{
this.Log(LogLevel.Warning, $"Received GPIO change from co-simulation, but no cosimToRenodeSignalRange is defined.");
return;
}
var localNumber = coSimNumber - (int)cosimToRenodeSignalRange.Value.StartAddress;
if (localNumber != RxdInterrupt)
{
this.Log(LogLevel.Warning, "Unhandled interrupt: '{0}'", localNumber);
return;
}
IRQ.Set(value);
}
public override void OnConnectionAttached(CoSimulationConnection connection)
{
base.OnConnectionAttached(connection);
connection.OnReceive += HandleReceivedMessage;
}
public override void OnConnectionDetached(CoSimulationConnection connection)
{
connection.OnReceive -= HandleReceivedMessage;
base.OnConnectionDetached(connection);
}
// StopBits, ParityBit and BaudRate are not in sync with the cosimulated model
public Bits StopBits { get { return Bits.One; } }
public Parity ParityBit { get { return Parity.None; } }
public uint BaudRate { get { return 115200; } }
public event Action<byte> CharReceived;
public GPIO IRQ { get; private set; }
private const int RxdInterrupt = 1;
}
// UARTActionNumber must be in sync with integration library
public enum UARTActionNumber
{
UARTTxd = 13,
UARTRxd = 14
}
}