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.Peripherals.Bus;
10 using Antmicro.Renode.Core.Structure.Registers;
11 
12 namespace Antmicro.Renode.Peripherals.I2C
13 {
14     public class EFR32_I2CController : EFR32_GenericI2CController, IDoubleWordPeripheral
15     {
EFR32_I2CController(IMachine machine)16         public EFR32_I2CController(IMachine machine) : base(machine)
17         {
18             var map = new Dictionary<long, DoubleWordRegister>
19             {
20                 {(long)Registers.Control, GenerateControlRegister()},
21                 {(long)Registers.Command, GenerateCommandRegister()},
22                 {(long)Registers.State, GenerateStateRegister()},
23                 {(long)Registers.Status, GenerateStatusRegister()},
24                 {(long)Registers.ClockDivision, GenerateClockDivisionRegister()},
25                 {(long)Registers.SlaveAddress, GenerateSlaveAddressRegister()},
26                 {(long)Registers.SlaveAddressMask, GenerateSlaveAddressMaskRegister()},
27                 {(long)Registers.ReceiveBufferData, GenerateReceiveBufferDataRegister()},
28                 {(long)Registers.ReceiveBufferDoubleData, GenerateReceiveBufferDoubleDataRegister()},
29                 {(long)Registers.ReceiveBufferDataPeek, GenerateReceiveBufferDataPeekRegister()},
30                 {(long)Registers.ReceiveBufferDoubleDataPeek, GenerateReceiveBufferDoubleDataPeekRegister()},
31                 {(long)Registers.TransmitBufferData, GenerateTransmitBufferDataRegister()},
32                 {(long)Registers.TransmitBufferDoubleData, GenerateTransmitBufferDoubleDataRegister()},
33                 {(long)Registers.InterruptFlag, GenerateInterruptFlagRegister()},
34                 {(long)Registers.InterruptFlagSet, GenerateInterruptFlagSetRegister()},
35                 {(long)Registers.InterruptFlagClear, GenerateInterruptFlagClearRegister()},
36                 {(long)Registers.InterruptEnable, GenerateInterruptEnableRegister()},
37                 {(long)Registers.IORoutingPinEnable, new DoubleWordRegister(this)
38                     .WithTaggedFlag("SDAPEN", 0)
39                     .WithTaggedFlag("SCLPEN", 1)
40                 },
41                 {(long)Registers.IORoutingLocation, new DoubleWordRegister(this)
42                     .WithTag("SDALOC", 0, 6)
43                     .WithReservedBits(6, 2)
44                     .WithTag("SCLLOC", 8, 6)
45                     .WithReservedBits(14, 18)
46                 },
47             };
48             registers = new DoubleWordRegisterCollection(this, map);
49         }
50 
ReadDoubleWord(long offset)51         public uint ReadDoubleWord(long offset)
52         {
53             return registers.Read(offset);
54         }
55 
WriteDoubleWord(long offset, uint value)56         public void WriteDoubleWord(long offset, uint value)
57         {
58             registers.Write(offset, value);
59         }
60 
Reset()61         public override void Reset()
62         {
63             base.Reset();
64             registers.Reset();
65         }
66 
67         private readonly DoubleWordRegisterCollection registers;
68 
69         private enum Registers
70         {
71             Control = 0x00,
72             Command = 0x04,
73             State = 0x08,
74             Status = 0x0C,
75             ClockDivision = 0x10,
76             SlaveAddress = 0x14,
77             SlaveAddressMask = 0x18,
78             ReceiveBufferData = 0x1C,
79             ReceiveBufferDoubleData = 0x20,
80             ReceiveBufferDataPeek = 0x24,
81             ReceiveBufferDoubleDataPeek = 0x28,
82             TransmitBufferData = 0x2C,
83             TransmitBufferDoubleData = 0x30,
84             InterruptFlag = 0x34,
85             InterruptFlagSet = 0x38,
86             InterruptFlagClear = 0x3C,
87             InterruptEnable = 0x40,
88             IORoutingPinEnable = 0x44,
89             IORoutingLocation = 0x48
90         }
91     }
92 }
93