1 // 2 // Copyright (c) 2010-2025 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.Core.Structure.Registers; 10 using Antmicro.Renode.Core; 11 using Antmicro.Migrant; 12 using Antmicro.Renode.Peripherals.Bus; 13 using Antmicro.Renode.Peripherals.UART; 14 using Antmicro.Renode.Utilities; 15 using Antmicro.Renode.Logging; 16 17 namespace Antmicro.Renode.Peripherals.UART 18 { 19 [AllowedTranslations(AllowedTranslation.WordToDoubleWord | AllowedTranslation.ByteToDoubleWord)] 20 public class MesonUart : UARTBase, IDoubleWordPeripheral, IProvidesRegisterCollection<DoubleWordRegisterCollection>, IKnownSize 21 { MesonUart(IMachine machine)22 public MesonUart(IMachine machine) : base(machine) 23 { 24 IRQ = new GPIO(); 25 RegistersCollection = new DoubleWordRegisterCollection(this); 26 DefineRegisters(); 27 Reset(); 28 } 29 ReadDoubleWord(long offset)30 public uint ReadDoubleWord(long offset) 31 { 32 return RegistersCollection.Read(offset); 33 } 34 WriteDoubleWord(long offset, uint value)35 public void WriteDoubleWord(long offset, uint value) 36 { 37 RegistersCollection.Write(offset, value); 38 } 39 DefineRegisters()40 private void DefineRegisters() 41 { 42 Registers.ReadFifo.Define(this) 43 .WithValueField(0, 7, FieldMode.Read, name: "RFIFO", 44 valueProviderCallback: _ => 45 { 46 if(!TryGetCharacter(out byte value)) 47 { 48 this.Log(LogLevel.Warning, "Trying to read data from empty receive fifo"); 49 return 0; 50 } 51 return value; 52 }) 53 .WithReservedBits(8, 24) 54 ; 55 56 Registers.WriteFifo.Define(this) 57 .WithValueField(0, 7, FieldMode.Write, name: "WFIFO", 58 writeCallback: (_, value) => 59 { 60 TransmitCharacter((byte)value); 61 }) 62 .WithReservedBits(8, 24) 63 ; 64 65 Registers.Control.Define(this) 66 .WithValueField(0, 12, FieldMode.Read, name: "BaudRate", valueProviderCallback: _ => BaudRate) 67 .WithFlag(12, name: "TX Enabled", valueProviderCallback: _ => true) 68 .WithFlag(13, name: "RX Enabled", valueProviderCallback: _ => true) 69 .WithReservedBits(14, 1) 70 .WithTaggedFlag("Two Wire mode", 15) 71 .WithTag("Stop bit length", 16, 2) 72 .WithTaggedFlag("Parity type", 18) 73 .WithTaggedFlag("Parity enable", 19) 74 .WithTag("Character length", 20, 2) 75 .WithTaggedFlag("TX Reset", 22) 76 .WithTaggedFlag("RX Reset", 23) 77 .WithTaggedFlag("Clear Error", 24) 78 .WithTaggedFlag("Invert RX", 25) 79 .WithTaggedFlag("Invert TX", 26) 80 .WithTaggedFlag("RX Byte Interrupt", 27) 81 .WithTaggedFlag("TX Byte Interrupt", 28) 82 .WithTaggedFlag("Invert CTS", 29) 83 .WithTaggedFlag("Mask Error", 30) 84 .WithTaggedFlag("Invert RTS", 31) 85 ; 86 87 Registers.Status.Define(this) 88 .WithValueField(0, 8, FieldMode.Read, name: "Receive FIFO count", valueProviderCallback: _ => (ulong)Count) 89 .WithTag("Transmit FIFO count", 8, 7) 90 .WithReservedBits(15, 1) 91 .WithTaggedFlag("Parity error", 16) 92 .WithTaggedFlag("Frame error", 17) 93 .WithTaggedFlag("Write error", 18) 94 .WithTaggedFlag("Receive FIFO full", 19) 95 .WithFlag(20, FieldMode.Read, name: "Receive FIFO empty", valueProviderCallback: _ => Count == 0) 96 .WithTaggedFlag("Transmit FIFO full", 21) 97 .WithTaggedFlag("Transmit FIFO empty", 22) 98 .WithTaggedFlag("CTS Level", 23) 99 .WithTaggedFlag("Receive FIFO overflow", 24) 100 .WithTaggedFlag("Transmit busy", 25) 101 .WithTaggedFlag("Receive busy", 26) 102 .WithReservedBits(27, 5) 103 ; 104 } 105 106 public GPIO IRQ { get; } 107 108 public DoubleWordRegisterCollection RegistersCollection { get; } 109 public long Size => 0x18; 110 public override Bits StopBits => Bits.One; 111 public override Parity ParityBit => Parity.None; 112 public override uint BaudRate => 115200; 113 CharWritten()114 protected override void CharWritten() 115 { 116 // Intentionally left blank 117 } 118 QueueEmptied()119 protected override void QueueEmptied() 120 { 121 // Intentionally left blank 122 } 123 124 private enum Registers 125 { 126 WriteFifo = 0x0, 127 ReadFifo = 0x4, 128 Control = 0x8, 129 Status = 0xC, 130 Misc = 0x10, 131 Reg5 = 0x14, 132 } 133 } 134 } 135 136