1 //
2 // Copyright (c) 2010-2023 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.Core;
9 using Antmicro.Renode.Core.Structure;
10 using Antmicro.Renode.Core.Structure.Registers;
11 using Antmicro.Renode.Peripherals.Bus;
12 using Antmicro.Renode.Peripherals.UART.Silabs;
13 
14 namespace Antmicro.Renode.Peripherals.UART
15 {
16     [AllowedTranslations(AllowedTranslation.ByteToDoubleWord | AllowedTranslation.DoubleWordToByte)]
17     public class EFR32_USART : EFR32_GenericUSART, IDoubleWordPeripheral
18     {
EFR32_USART(IMachine machine, uint clockFrequency = 19000000)19         public EFR32_USART(IMachine machine, uint clockFrequency = 19000000) : base(machine, clockFrequency)
20         {
21             var registersMap = new Dictionary<long, DoubleWordRegister>
22             {
23                 {(long)Registers.Control, GenerateControlRegister()},
24                 {(long)Registers.FrameFormat, GenerateFrameFormatRegister()},
25                 {(long)Registers.TriggerControl, GenerateTriggerControlRegister()},
26                 {(long)Registers.Command, GenerateCommandRegister()},
27                 {(long)Registers.Status, GenerateStatusRegister()},
28                 {(long)Registers.ClockControl, GenerateClockControlRegister()},
29                 {(long)Registers.RxBufferDataExtended, GenerateRxBufferDataExtendedRegister()},
30                 {(long)Registers.RxBufferData, GenerateRxBufferDataRegister()},
31                 {(long)Registers.RxBufferDoubleDataExtended, GenerateRxBufferDoubleDataExtendedRegister()},
32                 {(long)Registers.RxBufferDoubleData, GenerateRxBufferDoubleDataRegister()},
33                 {(long)Registers.RxBufferDataExtendedPeek, GenerateRxBufferDataExtendedPeekRegister()},
34                 {(long)Registers.RxBufferDoubleDataExtendedPeek, GenerateRxBufferDoubleDataExtendedPeekRegister()},
35                 {(long)Registers.TxBufferDataExtended, GenerateTxBufferDataExtendedRegister()},
36                 {(long)Registers.TxBufferData, GenerateTxBufferDataRegister()},
37                 {(long)Registers.TxBufferDoubleDataExtended, GenerateTxBufferDoubleDataExtendedRegister()},
38                 {(long)Registers.TxBufferDoubleData, GenerateTxBufferDoubleDataRegister()},
39                 {(long)Registers.InterruptFlag, GenerateInterruptFlagRegister()},
40                 {(long)Registers.InterruptFlagSet, GenerateInterruptFlagSetRegister()},
41                 {(long)Registers.InterruptFlagClear, GenerateInterruptFlagClearRegister()},
42                 {(long)Registers.InterruptEnable, GenerateInterruptEnableRegister()},
43                 {(long)Registers.IrDAControl, GenerateIrDAControlRegister()},
44                 {(long)Registers.USARTInput, GenerateUSARTInputRegister()},
45                 {(long)Registers.I2SControl, GenerateI2SControlRegister()},
46                 {(long)Registers.Timing, GenerateTimingRegister()},
47                 {(long)Registers.ControlExtended, GenerateControlExtendedRegister()},
48                 {(long)Registers.TimeCompare0, GenerateTimeCompare0Register()},
49                 {(long)Registers.TimeCompare1, GenerateTimeCompare1Register()},
50                 {(long)Registers.TimeCompare2, GenerateTimeCompare2Register()},
51                 {(long)Registers.IORoutingPinEnable, new DoubleWordRegister(this)
52                     .WithTaggedFlag("RXPEN", 0)
53                     .WithTaggedFlag("TXPEN", 1)
54                     .WithTaggedFlag("CSPEN", 2)
55                     .WithTaggedFlag("CLKPEN", 3)
56                     .WithTaggedFlag("CTSPEN", 4)
57                     .WithTaggedFlag("RTSPEN", 5)
58                     .WithReservedBits(6, 26)
59                 },
60                 {(long)Registers.IORoutingLocation0, new DoubleWordRegister(this)
61                     .WithTag("RXLOC", 0, 6)
62                     .WithReservedBits(6, 2)
63                     .WithTag("TXLOC", 8, 6)
64                     .WithReservedBits(14, 2)
65                     .WithTag("CSLOC", 16, 6)
66                     .WithReservedBits(22, 2)
67                     .WithTag("CLKLOC", 24, 6)
68                     .WithReservedBits(30, 2)
69                 },
70                 {(long)Registers.IORoutingLocation1, new DoubleWordRegister(this)
71                     .WithTag("CTSLOC", 0, 6)
72                     .WithReservedBits(6, 2)
73                     .WithTag("RTSLOC", 8, 6)
74                     .WithReservedBits(14, 18)
75                 },
76                 {(long)Registers.Test, GenerateTestRegister()},
77             };
78             registers = new DoubleWordRegisterCollection(this, registersMap);
79         }
80 
ReadDoubleWord(long offset)81         public uint ReadDoubleWord(long offset)
82         {
83             return registers.Read(offset);
84         }
85 
WriteDoubleWord(long address, uint value)86         public void WriteDoubleWord(long address, uint value)
87         {
88             registers.Write(address, value);
89         }
90 
Reset()91         public override void Reset()
92         {
93             base.Reset();
94         }
95 
96         private enum Registers
97         {
98             Control = 0x0,
99             FrameFormat = 0x4,
100             TriggerControl = 0x8,
101             Command = 0xC,
102             Status = 0x10,
103             ClockControl = 0x14,
104             RxBufferDataExtended = 0x18,
105             RxBufferData = 0x1C,
106             RxBufferDoubleDataExtended = 0x20,
107             RxBufferDoubleData = 0x24,
108             RxBufferDataExtendedPeek = 0x28,
109             RxBufferDoubleDataExtendedPeek = 0x2C,
110             TxBufferDataExtended = 0x30,
111             TxBufferData = 0x34,
112             TxBufferDoubleDataExtended = 0x38,
113             TxBufferDoubleData = 0x3C,
114             InterruptFlag = 0x40,
115             InterruptFlagSet = 0x44,
116             InterruptFlagClear = 0x48,
117             InterruptEnable = 0x4C,
118             IrDAControl = 0x50,
119             USARTInput = 0x58,
120             I2SControl = 0x5C,
121             Timing = 0x60,
122             ControlExtended = 0x64,
123             TimeCompare0 = 0x68,
124             TimeCompare1 = 0x6C,
125             TimeCompare2 = 0x70,
126             IORoutingPinEnable = 0x74,
127             IORoutingLocation0 = 0x78,
128             IORoutingLocation1 = 0x7C,
129             Test = 0x80,
130         }
131 
132         private readonly DoubleWordRegisterCollection registers;
133     }
134 }
135