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.Collections.Generic;
8 using Antmicro.Renode.Peripherals.Bus;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using Antmicro.Renode.Core;
11 using Antmicro.Renode.Logging;
12 
13 namespace Antmicro.Renode.Peripherals.UART
14 {
15     public class Potato_UART : UARTBase, IQuadWordPeripheral, IKnownSize
16     {
Potato_UART(IMachine machine)17         public Potato_UART(IMachine machine) : base(machine)
18         {
19             var registersMap = new Dictionary<long, QuadWordRegister>
20             {
21                 {(long)Registers.TransmitRx, new QuadWordRegister(this)
22                     .WithValueField(0, 64, writeCallback: (_, value) => this.TransmitCharacter((byte)value), name: "TransmitRx")
23                 },
24                 {(long)Registers.ReceiveRx, new QuadWordRegister(this)
25                     .WithValueField(0, 64, FieldMode.Read, valueProviderCallback: _ =>
26                     {
27                         if(!TryGetCharacter(out var character))
28                         {
29                             this.Log(LogLevel.Warning, "Trying to read data from empty receive fifo");
30                             return 0x0;
31                         }
32                         return character;
33                     }, name: "ReceiveRx")
34                 },
35                 {(long)Registers.StatusRx, new QuadWordRegister(this)
36                     .WithFlag(0, valueProviderCallback: _ => Count == 0, name: "ReceiveRxEmpty")
37                     .WithFlag(1, valueProviderCallback: _ => Count == 0, name: "TransmitRxEmpty")
38                     .WithFlag(2, valueProviderCallback: _ => false, name: "ReceiveRxFull")
39                     .WithFlag(3, valueProviderCallback: _ => false, name: "TransmitRxFull")
40                     .WithReservedBits(4, 60)
41                  },
42                 {(long)Registers.ClockDivider, new QuadWordRegister(this)
43                     .WithValueField(0, 64, name: "ClkDiv")
44                 },
45                 {(long)Registers.InterruptEnableRx, new QuadWordRegister(this)
46                     .WithFlag(0, valueProviderCallback: _ => false, name: "Interrupt_Receive")
47                     .WithFlag(1, valueProviderCallback: _ => false, name: "Interrupt_Transmit")
48                     .WithReservedBits(2, 62)
49                  },
50              };
51             registers = new QuadWordRegisterCollection(this, registersMap);
52         }
53 
ReadQuadWord(long offset)54         public ulong ReadQuadWord(long offset)
55         {
56             return registers.Read(offset);
57         }
58 
WriteQuadWord(long offset, ulong value)59         public void WriteQuadWord(long offset, ulong value)
60         {
61             registers.Write(offset, value);
62         }
63 
Reset()64         public override void Reset()
65         {
66             base.Reset();
67             registers.Reset();
68         }
69 
70         public long Size => 0x100;
71 
72         public override Bits StopBits => Bits.One;
73 
74         public override Parity ParityBit => Parity.None;
75 
76         public override uint BaudRate => 115200;
77 
CharWritten()78         protected override void CharWritten()
79         {
80             // intentionally left blank
81         }
82 
QueueEmptied()83         protected override void QueueEmptied()
84         {
85             // intentionally left blank
86         }
87 
88         private readonly QuadWordRegisterCollection registers;
89 
90         private enum Registers : long
91         {
92             TransmitRx = 0x0,
93             ReceiveRx = 0x08,
94             StatusRx = 0x10,
95             ClockDivider = 0x18,
96             InterruptEnableRx = 0x20,
97         }
98     }
99 }
100