// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Threading;
using System.Threading.Tasks;
namespace System.Device.Gpio;
///
/// Base class for Gpio Drivers.
/// A Gpio driver provides methods to read from and write to digital I/O pins.
///
public abstract class GpioDriver : IDisposable
{
///
/// The number of pins provided by the driver.
///
protected internal abstract int PinCount { get; }
///
/// Converts a board pin number to the driver's logical numbering scheme.
///
/// The board pin number to convert.
/// The pin number in the driver's logical numbering scheme.
protected internal abstract int ConvertPinNumberToLogicalNumberingScheme(int pinNumber);
///
/// Opens a pin in order for it to be ready to use.
/// The driver attempts to open the pin without changing its mode or value.
///
/// The pin number in the driver's logical numbering scheme.
protected internal abstract void OpenPin(int pinNumber);
///
/// Closes an open pin.
///
/// The pin number in the driver's logical numbering scheme.
protected internal abstract void ClosePin(int pinNumber);
///
/// Sets the mode to a pin.
///
/// The pin number in the driver's logical numbering scheme.
/// The mode to be set.
protected internal abstract void SetPinMode(int pinNumber, PinMode mode);
///
/// Sets the mode to a pin and sets an initial value for an output pin.
///
/// The pin number in the driver's logical numbering scheme.
/// The mode to be set.
/// The initial value if the is output. The driver will do it's best to prevent glitches to the other value when
/// changing from input to output.
protected internal virtual void SetPinMode(int pinNumber, PinMode mode, PinValue initialValue)
{
SetPinMode(pinNumber, mode);
if (mode == PinMode.Output)
{
Write(pinNumber, initialValue);
}
}
///
/// Gets the mode of a pin.
///
/// The pin number in the driver's logical numbering scheme.
/// The mode of the pin.
protected internal abstract PinMode GetPinMode(int pinNumber);
///
/// Checks if a pin supports a specific mode.
///
/// The pin number in the driver's logical numbering scheme.
/// The mode to check.
/// The status if the pin supports the mode.
protected internal abstract bool IsPinModeSupported(int pinNumber, PinMode mode);
///
/// Reads the current value of a pin.
///
/// The pin number in the driver's logical numbering scheme.
/// The value of the pin.
protected internal abstract PinValue Read(int pinNumber);
///
/// Toggle the current value of a pin.
///
/// The pin number in the driver's logical numbering scheme.
protected internal virtual void Toggle(int pinNumber) => Write(pinNumber, !Read(pinNumber));
///
/// Writes a value to a pin.
///
/// The pin number in the driver's logical numbering scheme.
/// The value to be written to the pin.
protected internal abstract void Write(int pinNumber, PinValue value);
///
/// Blocks execution until an event of type eventType is received or a cancellation is requested.
///
/// The pin number in the driver's logical numbering scheme.
/// The event types to wait for.
/// The cancellation token of when the operation should stop waiting for an event.
/// A structure that contains the result of the waiting operation.
protected internal abstract WaitForEventResult WaitForEvent(int pinNumber, PinEventTypes eventTypes, CancellationToken cancellationToken);
///
/// Async call until an event of type eventType is received or a cancellation is requested.
///
/// The pin number in the driver's logical numbering scheme.
/// The event types to wait for.
/// The cancellation token of when the operation should stop waiting for an event.
/// A task representing the operation of getting the structure that contains the result of the waiting operation
protected internal virtual ValueTask WaitForEventAsync(int pinNumber, PinEventTypes eventTypes, CancellationToken cancellationToken)
{
return new ValueTask(Task.Run(() => WaitForEvent(pinNumber, eventTypes, cancellationToken)));
}
///
/// Adds a handler for a pin value changed event.
///
/// The pin number in the driver's logical numbering scheme.
/// The event types to wait for.
/// Delegate that defines the structure for callbacks when a pin value changed event occurs.
protected internal abstract void AddCallbackForPinValueChangedEvent(int pinNumber, PinEventTypes eventTypes, PinChangeEventHandler callback);
///
/// Removes a handler for a pin value changed event.
///
/// The pin number in the driver's logical numbering scheme.
/// Delegate that defines the structure for callbacks when a pin value changed event occurs.
protected internal abstract void RemoveCallbackForPinValueChangedEvent(int pinNumber, PinChangeEventHandler callback);
///
/// Disposes this instance, closing all open pins
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Disposes this instance
///
/// True if explicitly disposing, false if in finalizer
protected virtual void Dispose(bool disposing)
{
// Nothing to do in base class.
}
}