1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using System.Linq; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Core.Structure; 12 using System.Collections.Generic; 13 using System.Collections.ObjectModel; 14 using Antmicro.Renode.UserInterface; 15 using Antmicro.Renode.Logging; 16 using Antmicro.Renode.Utilities; 17 18 namespace Antmicro.Renode.Peripherals.GPIOPort 19 { 20 [Icon("gpio")] 21 public abstract class BaseGPIOPort : INumberedGPIOOutput, IPeripheralRegister<IGPIOReceiver, NullRegistrationPoint>, 22 IPeripheralRegister<IGPIOSender, NullRegistrationPoint>, IPeripheralRegister<IGPIOReceiver, NumberRegistrationPoint<int>>, 23 IPeripheral, IGPIOReceiver, IPeripheralRegister<IGPIOSender, NumberRegistrationPoint<int>> 24 { Register(IGPIOSender peripheral, NumberRegistrationPoint<int> registrationPoint)25 public void Register(IGPIOSender peripheral, NumberRegistrationPoint<int> registrationPoint) 26 { 27 machine.RegisterAsAChildOf(this, peripheral, registrationPoint); 28 } 29 Unregister(IGPIOSender peripheral)30 public void Unregister(IGPIOSender peripheral) 31 { 32 machine.UnregisterAsAChildOf(this, peripheral); 33 } 34 Register(IGPIOSender peripheral, NullRegistrationPoint registrationPoint)35 public void Register(IGPIOSender peripheral, NullRegistrationPoint registrationPoint) 36 { 37 machine.RegisterAsAChildOf(this, peripheral, registrationPoint); 38 } 39 Register(IGPIOReceiver peripheral, NullRegistrationPoint registrationPoint)40 public void Register(IGPIOReceiver peripheral, NullRegistrationPoint registrationPoint) 41 { 42 machine.RegisterAsAChildOf(this, peripheral, registrationPoint); 43 } 44 Unregister(IGPIOReceiver peripheral)45 public void Unregister(IGPIOReceiver peripheral) 46 { 47 machine.UnregisterAsAChildOf(this, peripheral); 48 foreach(var gpio in Connections.Values) 49 { 50 var endpoints = gpio.Endpoints; 51 for(var i = 0; i < endpoints.Count; ++i) 52 { 53 if(endpoints[i].Number == 0 && endpoints[i].Receiver == peripheral) 54 { 55 gpio.Disconnect(endpoints[i]); 56 } 57 } 58 } 59 } 60 Register(IGPIOReceiver peripheral, NumberRegistrationPoint<int> registrationPoint)61 public void Register(IGPIOReceiver peripheral, NumberRegistrationPoint<int> registrationPoint) 62 { 63 machine.RegisterAsAChildOf(this, peripheral, registrationPoint); 64 } 65 Reset()66 public virtual void Reset() 67 { 68 foreach(var connection in Connections.Values) 69 { 70 connection.Unset(); 71 } 72 for(int i = 0; i < State.Length; ++i) 73 { 74 State[i] = false; 75 } 76 } 77 BaseGPIOPort(IMachine machine, int numberOfConnections)78 protected BaseGPIOPort(IMachine machine, int numberOfConnections) 79 { 80 var innerConnections = new Dictionary<int, IGPIO>(); 81 this.NumberOfConnections = numberOfConnections; 82 State = new bool[numberOfConnections]; 83 for(var i = 0; i < numberOfConnections; i++) 84 { 85 innerConnections[i] = new GPIO(); 86 } 87 this.machine = machine; 88 Connections = new ReadOnlyDictionary<int, IGPIO>(innerConnections); 89 } 90 SetConnectionsStateUsingBits(uint bits)91 protected void SetConnectionsStateUsingBits(uint bits) 92 { 93 foreach(var cn in Connections) 94 { 95 if((bits & 1u << cn.Key) != 0) 96 { 97 cn.Value.Set(); 98 } 99 else 100 { 101 cn.Value.Unset(); 102 } 103 } 104 } 105 GetSetConnectionBits()106 protected uint GetSetConnectionBits() 107 { 108 return BitHelper.GetValueFromBitsArray(Connections.Where(x => x.Key >= 0).OrderBy(x => x.Key).Select(x => x.Value.IsSet)); 109 } 110 CheckPinNumber(int number)111 protected bool CheckPinNumber(int number) 112 { 113 if(number < 0 || number >= NumberOfConnections) 114 { 115 this.Log(LogLevel.Error, $"This peripheral supports gpio inputs from 0 to {NumberOfConnections}, but {number} was called."); 116 return false; 117 } 118 return true; 119 } 120 OnGPIO(int number, bool value)121 public virtual void OnGPIO(int number, bool value) 122 { 123 if(!CheckPinNumber(number)) 124 { 125 return; 126 } 127 128 State[number] = value; 129 } 130 131 public IReadOnlyDictionary<int, IGPIO> Connections { get; } 132 133 protected readonly int NumberOfConnections; 134 protected bool[] State; 135 protected readonly IMachine machine; 136 } 137 } 138 139