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 Antmicro.Renode.Core; 8 using Antmicro.Renode.Core.Structure.Registers; 9 using Antmicro.Renode.Logging; 10 using Antmicro.Renode.Peripherals.Bus; 11 12 namespace Antmicro.Renode.Peripherals.GPIOPort 13 { 14 public class NPCX_GPIO : BaseGPIOPort, IBytePeripheral, IProvidesRegisterCollection<ByteRegisterCollection>, IKnownSize 15 { NPCX_GPIO(IMachine machine)16 public NPCX_GPIO(IMachine machine) : base(machine, NumberOfPinsPerPort) 17 { 18 RegistersCollection = new ByteRegisterCollection(this); 19 DefineRegisters(); 20 } 21 ReadByte(long offset)22 public byte ReadByte(long offset) 23 { 24 return RegistersCollection.Read(offset); 25 } 26 WriteByte(long offset, byte value)27 public void WriteByte(long offset, byte value) 28 { 29 RegistersCollection.Write(offset, value); 30 } 31 Reset()32 public override void Reset() 33 { 34 base.Reset(); 35 RegistersCollection.Reset(); 36 } 37 38 public long Size => 0x1000; 39 40 public ByteRegisterCollection RegistersCollection { get; } 41 DefineRegisters()42 private void DefineRegisters() 43 { 44 Registers.DataOut.Define(this) 45 .WithFlags(0, 8, name: "DataOut", 46 valueProviderCallback: (index, _) => Connections[index].IsSet, 47 writeCallback: (index, _, value) => 48 { 49 if(!pinDirection[index].Value) 50 { 51 return; 52 } 53 54 if(pinLockControl[index].Value) 55 { 56 this.Log(LogLevel.Warning, "Trying to set pin#{0} while it's locked", index); 57 return; 58 } 59 60 Connections[index].Set(value); 61 }) 62 ; 63 64 Registers.DataIn.Define(this) 65 .WithFlags(0, 8, FieldMode.Read, name: "DataIn", 66 valueProviderCallback: (index, _) => State[index]); 67 ; 68 69 Registers.Direction.Define(this) 70 .WithFlags(0, 8, out pinDirection, name: "Direction") 71 ; 72 73 Registers.PullUpPullDownEnable.Define(this) 74 .WithTaggedFlags("PullUpPullDownEnable", 0, 8) 75 ; 76 77 Registers.PullUpPullDownSelection.Define(this) 78 .WithTaggedFlags("PullUpPullDownSelection", 0, 8) 79 ; 80 81 Registers.DriveEnable.Define(this) 82 .WithTaggedFlags("DriveEnable", 0, 8) 83 ; 84 85 Registers.OutputType.Define(this) 86 .WithTaggedFlags("OutputType", 0, 8) 87 ; 88 89 Registers.LockControl.Define(this) 90 .WithFlags(0, 8, out pinLockControl, name: "LockControl") 91 ; 92 } 93 94 private const int NumberOfPinsPerPort = 8; 95 96 private IFlagRegisterField[] pinDirection; 97 private IFlagRegisterField[] pinLockControl; 98 99 private enum Registers 100 { 101 DataOut = 0x0, 102 DataIn = 0x1, 103 Direction = 0x2, 104 PullUpPullDownEnable = 0x3, 105 PullUpPullDownSelection = 0x4, 106 DriveEnable = 0x5, 107 OutputType = 0x6, 108 LockControl = 0x7 109 } 110 } 111 } 112