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