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;
10 using Antmicro.Renode.Core.Structure.Registers;
11 using Antmicro.Renode.Logging;
12 
13 namespace Antmicro.Renode.Peripherals.UART
14 {
15     public class GD32_UART : UARTBase, IDoubleWordPeripheral, IKnownSize
16     {
GD32_UART(IMachine machine, bool extendedMode = false)17         public GD32_UART(IMachine machine, bool extendedMode = false) : base(machine)
18         {
19             IRQ = new GPIO();
20             registers = new DoubleWordRegisterCollection(this);
21 
22             if(extendedMode)
23             {
24                 DefineExtendedModeRegisters();
25             }
26             else
27             {
28                 DefineBasicModeRegisters();
29             }
30         }
31 
DefineBasicModeRegisters()32         private void DefineBasicModeRegisters()
33         {
34             registers.DefineRegister((long)BasicModeRegisters.Status0)
35                 .WithFlag(0, FieldMode.Read, name: "PERR - Parity error flag", valueProviderCallback: _ => false)
36                 .WithFlag(1, FieldMode.Read, name: "FERR - Frame error flag", valueProviderCallback: _ => false)
37                 .WithFlag(2, FieldMode.Read, name: "NERR - Noise error flag", valueProviderCallback: _ => false)
38                 .WithFlag(3, FieldMode.Read, name: "ORERR - Overrun error", valueProviderCallback: _ => false)
39                 .WithFlag(4, FieldMode.Read, name: "IDLEF - IDLE frame detected flag", valueProviderCallback: _ => false)
40                 .WithFlag(5, FieldMode.Read, name: "RBNE - Read data buffer not empty", valueProviderCallback: _ => Count > 0)
41                 .WithFlag(6, FieldMode.Read, name: "TC - Transmission complete", valueProviderCallback: _ => false)
42                 .WithFlag(7, FieldMode.Read, name: "TBE - Transmit data buffer empty", valueProviderCallback: _ => true)
43                 .WithFlag(8, FieldMode.Read, name: "LBDF - LIN break detection flag", valueProviderCallback: _ => false)
44                 .WithFlag(9, FieldMode.Read, name: "CTSF - CTS change flag", valueProviderCallback: _ => false)
45                 .WithReservedBits(10, 22)
46             ;
47 
48             registers.DefineRegister((long)BasicModeRegisters.Data)
49                 .WithValueField(0, 8, name: "DATA - Data",
50                     valueProviderCallback: _ =>
51                     {
52                         if(!TryGetCharacter(out var c))
53                         {
54                             this.Log(LogLevel.Warning, "Tried to read from an empty FIFO");
55                             return 0;
56                         }
57                         return c;
58                     },
59                     writeCallback: (_, v) => TransmitCharacter((byte)v))
60                 .WithReservedBits(8, 24)
61             ;
62         }
63 
DefineExtendedModeRegisters()64         private void DefineExtendedModeRegisters()
65         {
66             registers.DefineRegister((long)ExtendedModeRegisters.Status)
67                 .WithFlag(0, FieldMode.Read, name: "PERR - Parity error flag", valueProviderCallback: _ => false)
68                 .WithFlag(1, FieldMode.Read, name: "FERR - Frame error flag", valueProviderCallback: _ => false)
69                 .WithFlag(2, FieldMode.Read, name: "NERR - Noise error flag", valueProviderCallback: _ => false)
70                 .WithFlag(3, FieldMode.Read, name: "ORERR - Overrun error", valueProviderCallback: _ => false)
71                 .WithFlag(4, FieldMode.Read, name: "IDLEF - IDLE frame detected flag", valueProviderCallback: _ => false)
72                 .WithFlag(5, FieldMode.Read, name: "RBNE - Read data buffer not empty", valueProviderCallback: _ => Count > 0)
73                 .WithFlag(6, FieldMode.Read, name: "TC - Transmission complete", valueProviderCallback: _ => false)
74                 .WithFlag(7, FieldMode.Read, name: "TBE - Transmit data buffer empty", valueProviderCallback: _ => true)
75                 .WithFlag(8, FieldMode.Read, name: "LBDF - LIN break detection flag", valueProviderCallback: _ => false)
76                 .WithFlag(9, FieldMode.Read, name: "CTSF - CTS change flag", valueProviderCallback: _ => false)
77                 .WithFlag(10, FieldMode.Read, name: "CTS - CTS level", valueProviderCallback: _ => false)
78                 .WithFlag(11, FieldMode.Read, name: "RTF - Receiver timeout", valueProviderCallback: _ => false)
79                 .WithFlag(12, FieldMode.Read, name: "EBF - End of block", valueProviderCallback: _ => false)
80                 .WithReservedBits(13, 3)
81                 .WithFlag(16, FieldMode.Read, name: "BSY - Busy", valueProviderCallback: _ => false)
82                 .WithFlag(17, FieldMode.Read, name: "AMF - ADDR match", valueProviderCallback: _ => false)
83                 .WithFlag(18, FieldMode.Read, name: "SBF - Send break", valueProviderCallback: _ => false)
84                 .WithFlag(19, FieldMode.Read, name: "RWU - Receiver wakeup from mute", valueProviderCallback: _ => false)
85                 .WithFlag(20, FieldMode.Read, name: "WUF - Wakeup from deep-sleep mode", valueProviderCallback: _ => false)
86                 .WithFlag(21, FieldMode.Read, name: "TEA - Transmit enable acknowledge", valueProviderCallback: _ => false)
87                 .WithFlag(22, FieldMode.Read, name: "REA - Receive enable acknowledge", valueProviderCallback: _ => false)
88                 .WithReservedBits(23, 9)
89             ;
90 
91             registers.DefineRegister((long)ExtendedModeRegisters.ReceiveData)
92                 .WithValueField(0, 8, FieldMode.Read, name: "RDATA - Receive data",
93                     valueProviderCallback: _ =>
94                     {
95                         if(!TryGetCharacter(out var c))
96                         {
97                             this.Log(LogLevel.Warning, "Tried to read from an empty FIFO");
98                             return 0;
99                         }
100                         return c;
101                     })
102                 .WithReservedBits(8, 24)
103             ;
104 
105             registers.DefineRegister((long)ExtendedModeRegisters.TransmitData)
106                 .WithValueField(0, 9, name: "TDATA - Transmit data",
107                     writeCallback: (_, v) => TransmitCharacter((byte)v))
108                 .WithReservedBits(9, 23)
109             ;
110         }
111 
Reset()112         public override void Reset()
113         {
114             base.Reset();
115             registers.Reset();
116         }
117 
ReadDoubleWord(long offset)118         public uint ReadDoubleWord(long offset)
119         {
120             return registers.Read(offset);;
121         }
122 
WriteDoubleWord(long offset, uint value)123         public void WriteDoubleWord(long offset, uint value)
124         {
125             registers.Write(offset, value);
126         }
127 
128         public GPIO IRQ { get; }
129 
130         public override uint BaudRate => 115200;
131         public override Parity ParityBit => Parity.None;
132         public override Bits StopBits => Bits.One;
133 
134         public long Size => 0x400;
135 
CharWritten()136         protected override void CharWritten()
137         {
138             // intentionally left blank
139         }
140 
QueueEmptied()141         protected override void QueueEmptied()
142         {
143             // intentionally left blank
144         }
145 
146         private readonly DoubleWordRegisterCollection registers;
147 
148         private enum BasicModeRegisters
149         {
150             Status0 = 0x0,
151             Data = 0x4,
152             BaudRate = 0x8,
153             Control0 = 0xC,
154             Control1 = 0x10,
155             Control2 = 0x14,
156             GuardTimePrescaler = 0x18,
157             Control3 = 0x80,
158             ReceiverTimeout = 0x84,
159             Status1 = 0x88,
160             CoherenceControl = 0xC0,
161         }
162 
163         private enum ExtendedModeRegisters
164         {
165             Control0 = 0x0,
166             Control1 = 0x4,
167             Control2 = 0x8,
168             BaudRate = 0xC,
169             GuartTimePrescaler = 0x10,
170             ReceiverTimeout = 0x14,
171             Command = 0x18,
172             Status = 0x1C,
173             InterruptClear = 0x20,
174             ReceiveData = 0x24,
175             TransmitData = 0x28,
176             ReceiveFifoContolStatus = 0xD0,
177         }
178     }
179 }
180 
181