Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding virtual GpioController and virtual GpioPin #2180

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/System.Device.Gpio/System.Device.Gpio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@
<!-- Need this for record support in older runtimes -->
<Compile Remove="System\Device\IsExternalInit.cs" />
</ItemGroup>

</Project>
10 changes: 7 additions & 3 deletions src/System.Device.Gpio/System/Device/Gpio/GpioController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ public class GpioController : IDisposable
/// If a pin element exists, that pin is open. Uses current controller's numbering scheme
/// </summary>
private readonly ConcurrentDictionary<int, PinValue?> _openPins;
private readonly ConcurrentDictionary<int, GpioPin> _gpioPins;

/// <summary>
/// The GPIO pins open in the GpioController.
/// </summary>
protected readonly ConcurrentDictionary<int, GpioPin> _gpioPins;
Ellerbach marked this conversation as resolved.
Show resolved Hide resolved
private GpioDriver _driver;

/// <summary>
Expand Down Expand Up @@ -103,7 +107,7 @@ protected virtual int GetLogicalPinNumber(int pinNumber)
/// The driver attempts to open the pin without changing its mode or value.
/// </summary>
/// <param name="pinNumber">The pin number in the controller's numbering scheme.</param>
public GpioPin OpenPin(int pinNumber)
public virtual GpioPin OpenPin(int pinNumber)
{
if (IsPinOpen(pinNumber))
{
Expand Down Expand Up @@ -160,7 +164,7 @@ public GpioPin OpenPin(int pinNumber, PinMode mode, PinValue initialValue)
/// If allowed by the driver, the state of the pin is not changed.
/// </summary>
/// <param name="pinNumber">The pin number in the controller's numbering scheme.</param>
public void ClosePin(int pinNumber)
public virtual void ClosePin(int pinNumber)
{
if (!IsPinOpen(pinNumber))
{
Expand Down
55 changes: 41 additions & 14 deletions src/System.Device.Gpio/System/Device/Gpio/GpioPin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,40 @@ namespace System.Device.Gpio
/// </summary>
public class Gpio​Pin
{
private readonly int _pinNumber;
private readonly GpioDriver _driver;
private readonly int _externalPinNumber;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment explaining how's this different to DriverPinNumber and why we need this here and not just i.e. on the virtual pin?


internal Gpio​Pin(int pinNumber, GpioDriver driver)
/// <summary>
/// Gets or sets the internal pin number used by the driver.
/// </summary>
internal int DriverPinNumber { get; set; }

/// <summary>
/// Gets or sets the <see cref="GpioDriver"/>.
/// </summary>
internal GpioDriver Driver { get; set; }

/// <summary>
/// Creates an instance of GPIO Pin with a new pin number based on an existing <see cref="GpioDriver"/>.
/// </summary>
/// <param name="pinNumber">The GPIO pin number.</param>
/// <param name="driver">The GpioDriver.</param>
protected internal Gpio​Pin(int pinNumber, GpioDriver driver)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two APIs should also be Experimental.

{
Driver = driver;
DriverPinNumber = pinNumber;
_externalPinNumber = -1;
}

/// <summary>
/// Creates an instance of GPIO Pin with a new pin number based on an existing <see cref="GpioPin"/>.
/// </summary>
/// <param name="gpioPin">The GpioPin.</param>
/// <param name="pinNumber">The new pin number to associate.</param>
protected internal GpioPin(GpioPin gpioPin, int pinNumber)
{
_driver = driver;
_pinNumber = pinNumber;
Driver = gpioPin.Driver;
DriverPinNumber = gpioPin.DriverPinNumber;
_externalPinNumber = pinNumber;
}

/// <summary>
Expand All @@ -23,14 +50,14 @@ public class Gpio​Pin
/// <value>
/// The pin number of the GPIO pin.
/// </value>
public virtual int PinNumber => _pinNumber;
public virtual int PinNumber => _externalPinNumber >= 0 ? _externalPinNumber : DriverPinNumber;

/// <summary>
/// Gets the current pin mode for the general-purpose I/O (GPIO) pin. The pin mode specifies whether the pin is configured as an input or an output, and determines how values are driven onto the pin.
/// </summary>
/// <returns>An enumeration value that indicates the current pin mode for the GPIO pin.
/// The pin mode specifies whether the pin is configured as an input or an output, and determines how values are driven onto the pin.</returns>
public virtual PinMode GetPinMode() => _driver.GetPinMode(_pinNumber);
public virtual PinMode GetPinMode() => Driver.GetPinMode(DriverPinNumber);

/// <summary>
/// Gets whether the general-purpose I/O (GPIO) pin supports the specified pin mode.
Expand All @@ -40,7 +67,7 @@ public class Gpio​Pin
/// <see langword="true"/> if the GPIO pin supports the pin mode that pinMode specifies; otherwise false.
/// If you specify a pin mode for which this method returns <see langword="false"/> when you call <see cref="SetPinMode"/>, <see cref="SetPinMode"/> generates an exception.
/// </returns>
public virtual bool IsPinModeSupported(PinMode pinMode) => _driver.IsPinModeSupported(_pinNumber, pinMode);
public virtual bool IsPinModeSupported(PinMode pinMode) => Driver.IsPinModeSupported(DriverPinNumber, pinMode);

/// <summary>
/// Sets the pin mode of the general-purpose I/O (GPIO) pin.
Expand All @@ -49,13 +76,13 @@ public class Gpio​Pin
/// <param name="value">An enumeration value that specifies pin mode to use for the GPIO pin.
/// The pin mode specifies whether the pin is configured as an input or an output, and determines how values are driven onto the pin.</param>
/// <exception cref="ArgumentException">The GPIO pin does not support the specified pin mode.</exception>
public virtual void SetPinMode(PinMode value) => _driver.SetPinMode(_pinNumber, value);
public virtual void SetPinMode(PinMode value) => Driver.SetPinMode(DriverPinNumber, value);

/// <summary>
/// Reads the current value of the general-purpose I/O (GPIO) pin.
/// </summary>
/// <returns>The current value of the GPIO pin. If the pin is configured as an output, this value is the last value written to the pin.</returns>
public virtual PinValue Read() => _driver.Read(_pinNumber);
public virtual PinValue Read() => Driver.Read(DriverPinNumber);

/// <summary>
/// Drives the specified value onto the general purpose I/O (GPIO) pin according to the current pin mode for the pin
Expand All @@ -66,7 +93,7 @@ public class Gpio​Pin
/// <para>If the GPIO pin is configured as an input, the method updates the latched output value for the pin. The latched output value is driven onto the pin when the configuration for the pin changes to output.</para>
/// </param>
/// <exception cref="InvalidOperationException">This exception will be thrown on an attempt to write to a pin that hasn't been opened or is not configured as output.</exception>
public virtual void Write(PinValue value) => _driver.Write(_pinNumber, value);
public virtual void Write(PinValue value) => Driver.Write(DriverPinNumber, value);

/// <summary>
/// Occurs when the value of the general-purpose I/O (GPIO) pin changes, either because of an external stimulus when the pin is configured as an input, or when a value is written to the pin when the pin in configured as an output.
Expand All @@ -75,18 +102,18 @@ public virtual event PinChangeEventHandler ValueChanged
{
add
{
_driver.AddCallbackForPinValueChangedEvent(_pinNumber, PinEventTypes.Falling | PinEventTypes.Rising, value);
Driver.AddCallbackForPinValueChangedEvent(DriverPinNumber, PinEventTypes.Falling | PinEventTypes.Rising, value);
}

remove
{
_driver.RemoveCallbackForPinValueChangedEvent(_pinNumber, value);
Driver.RemoveCallbackForPinValueChangedEvent(DriverPinNumber, value);
}
}

/// <summary>
/// Toggles the output of the general purpose I/O (GPIO) pin if the pin is configured as an output.
/// </summary>
public virtual void Toggle() => _driver.Toggle(_pinNumber);
public virtual void Toggle() => Driver.Toggle(DriverPinNumber);
}
}
Loading