584 lines
21 KiB
C#
584 lines
21 KiB
C#
using System;
|
||
using System.Threading.Tasks;
|
||
|
||
using Swan.Diagnostics;
|
||
|
||
using Unosquare.RaspberryIO.Abstractions;
|
||
using Unosquare.RaspberryIO.Abstractions.Native;
|
||
|
||
using Definitions = Unosquare.RaspberryIO.Abstractions.Definitions;
|
||
|
||
namespace Unosquare.WiringPi {
|
||
/// <summary>
|
||
/// Represents a GPIO Pin, its location and its capabilities.
|
||
/// Full pin reference available here:
|
||
/// http://pinout.xyz/pinout/pin31_gpio6 and http://wiringpi.com/pins/.
|
||
/// </summary>
|
||
public sealed partial class GpioPin : IGpioPin {
|
||
#region Property Backing
|
||
|
||
private static readonly Int32[] GpioToWiringPi;
|
||
|
||
private static readonly Int32[] GpioToWiringPiR1 = { 8, 9, -1, -1, 7, -1, -1, 11, 10, 13, 12, 14, -1, -1, 15, 16, -1, 0, 1, -1, -1, 2, 3, 4, 5, 6, -1, -1, -1, -1, -1, -1 };
|
||
|
||
private static readonly Int32[] GpioToWiringPiR2 = { 30, 31, 8, 9, 7, 21, 22, 11, 10, 13, 12, 14, 26, 23, 15, 16, 27, 0, 1, 24, 28, 29, 3, 4, 5, 6, 25, 2, 17, 18, 19, 20 };
|
||
|
||
private readonly Object _syncLock = new Object();
|
||
private GpioPinDriveMode _pinMode;
|
||
private GpioPinResistorPullMode _resistorPullMode;
|
||
private Int32 _pwmRegister;
|
||
private PwmMode _pwmMode = PwmMode.Balanced;
|
||
private UInt32 _pwmRange = 1024;
|
||
private Int32 _pwmClockDivisor = 1;
|
||
private Int32 _softPwmValue = -1;
|
||
private Int32 _softToneFrequency = -1;
|
||
|
||
#endregion
|
||
|
||
#region Constructor
|
||
|
||
static GpioPin() => GpioToWiringPi = SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? GpioToWiringPiR1 : GpioToWiringPiR2;
|
||
|
||
/// <summary>
|
||
/// Initializes a new instance of the <see cref="GpioPin"/> class.
|
||
/// </summary>
|
||
/// <param name="bcmPinNumber">The BCM pin number.</param>
|
||
private GpioPin(BcmPin bcmPinNumber) {
|
||
this.BcmPin = bcmPinNumber;
|
||
this.BcmPinNumber = (Int32)bcmPinNumber;
|
||
|
||
this.WiringPiPinNumber = BcmToWiringPiPinNumber(bcmPinNumber);
|
||
this.PhysicalPinNumber = Definitions.BcmToPhysicalPinNumber(SystemInfo.GetBoardRevision(), bcmPinNumber);
|
||
this.Header = (this.BcmPinNumber >= 28 && this.BcmPinNumber <= 31) ? GpioHeader.P5 : GpioHeader.P1;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Pin Properties
|
||
|
||
/// <inheritdoc />
|
||
public BcmPin BcmPin {
|
||
get;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public Int32 BcmPinNumber {
|
||
get;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public Int32 PhysicalPinNumber {
|
||
get;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the WiringPi Pin number.
|
||
/// </summary>
|
||
public WiringPiPin WiringPiPinNumber {
|
||
get;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public GpioHeader Header {
|
||
get;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the friendly name of the pin.
|
||
/// </summary>
|
||
public String Name {
|
||
get; private set;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the hardware mode capabilities of this pin.
|
||
/// </summary>
|
||
public PinCapability Capabilities {
|
||
get; private set;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public Boolean Value {
|
||
get => this.Read();
|
||
set => this.Write(value);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Hardware-Specific Properties
|
||
|
||
/// <inheritdoc />
|
||
/// <exception cref="T:System.NotSupportedException">Thrown when a pin does not support the given operation mode.</exception>
|
||
public GpioPinDriveMode PinMode {
|
||
get => this._pinMode;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
GpioPinDriveMode mode = value;
|
||
if(mode == GpioPinDriveMode.GpioClock && !this.HasCapability(PinCapability.GPCLK) ||
|
||
mode == GpioPinDriveMode.PwmOutput && !this.HasCapability(PinCapability.PWM) ||
|
||
mode == GpioPinDriveMode.Input && !this.HasCapability(PinCapability.GP) ||
|
||
mode == GpioPinDriveMode.Output && !this.HasCapability(PinCapability.GP)) {
|
||
throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{mode}'. Pin capabilities are limited to: {this.Capabilities}");
|
||
}
|
||
|
||
Native.WiringPi.PinMode(this.BcmPinNumber, (Int32)mode);
|
||
this._pinMode = mode;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the interrupt callback. Returns null if no interrupt
|
||
/// has been registered.
|
||
/// </summary>
|
||
public Native.InterruptServiceRoutineCallback InterruptCallback {
|
||
get; private set;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the interrupt edge detection mode.
|
||
/// </summary>
|
||
public EdgeDetection InterruptEdgeDetection {
|
||
get; private set;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Determines whether the specified capability has capability.
|
||
/// </summary>
|
||
/// <param name="capability">The capability.</param>
|
||
/// <returns>
|
||
/// <c>true</c> if the specified capability has capability; otherwise, <c>false</c>.
|
||
/// </returns>
|
||
public Boolean HasCapability(PinCapability capability) => (this.Capabilities & capability) == capability;
|
||
|
||
#endregion
|
||
|
||
#region Hardware PWM Members
|
||
|
||
/// <inheritdoc />
|
||
public GpioPinResistorPullMode InputPullMode {
|
||
get => this.PinMode == GpioPinDriveMode.Input ? this._resistorPullMode : GpioPinResistorPullMode.Off;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
if(this.PinMode != GpioPinDriveMode.Input) {
|
||
this._resistorPullMode = GpioPinResistorPullMode.Off;
|
||
throw new InvalidOperationException($"Unable to set the {nameof(this.InputPullMode)} for pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
|
||
+ $" Setting the {nameof(this.InputPullMode)} is only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input}");
|
||
}
|
||
|
||
Native.WiringPi.PullUpDnControl(this.BcmPinNumber, (Int32)value);
|
||
this._resistorPullMode = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets or sets the PWM register.
|
||
/// </summary>
|
||
/// <value>
|
||
/// The PWM register.
|
||
/// </value>
|
||
public Int32 PwmRegister {
|
||
get => this._pwmRegister;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
if(!this.HasCapability(PinCapability.PWM)) {
|
||
this._pwmRegister = 0;
|
||
|
||
throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
|
||
}
|
||
|
||
Native.WiringPi.PwmWrite(this.BcmPinNumber, value);
|
||
this._pwmRegister = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// The PWM generator can run in 2 modes – “balanced” and “mark:space”. The mark:space mode is traditional,
|
||
/// however the default mode in the Pi is “balanced”.
|
||
/// </summary>
|
||
/// <value>
|
||
/// The PWM mode.
|
||
/// </value>
|
||
/// <exception cref="InvalidOperationException">When pin mode is not set a Pwn output.</exception>
|
||
public PwmMode PwmMode {
|
||
get => this.PinMode == GpioPinDriveMode.PwmOutput ? this._pwmMode : PwmMode.Balanced;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
if(!this.HasCapability(PinCapability.PWM)) {
|
||
this._pwmMode = PwmMode.Balanced;
|
||
|
||
throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
|
||
}
|
||
|
||
Native.WiringPi.PwmSetMode((Int32)value);
|
||
this._pwmMode = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// This sets the range register in the PWM generator. The default is 1024.
|
||
/// </summary>
|
||
/// <value>
|
||
/// The PWM range.
|
||
/// </value>
|
||
/// <exception cref="InvalidOperationException">When pin mode is not set to PWM output.</exception>
|
||
public UInt32 PwmRange {
|
||
get => this.PinMode == GpioPinDriveMode.PwmOutput ? this._pwmRange : 0;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
if(!this.HasCapability(PinCapability.PWM)) {
|
||
this._pwmRange = 1024;
|
||
|
||
throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
|
||
}
|
||
|
||
Native.WiringPi.PwmSetRange(value);
|
||
this._pwmRange = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets or sets the PWM clock divisor.
|
||
/// </summary>
|
||
/// <value>
|
||
/// The PWM clock divisor.
|
||
/// </value>
|
||
/// <exception cref="InvalidOperationException">When pin mode is not set to PWM output.</exception>
|
||
public Int32 PwmClockDivisor {
|
||
get => this.PinMode == GpioPinDriveMode.PwmOutput ? this._pwmClockDivisor : 0;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
if(!this.HasCapability(PinCapability.PWM)) {
|
||
this._pwmClockDivisor = 1;
|
||
|
||
throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
|
||
}
|
||
|
||
Native.WiringPi.PwmSetClock(value);
|
||
this._pwmClockDivisor = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Software Tone Members
|
||
|
||
/// <summary>
|
||
/// Gets a value indicating whether this instance is in software based tone generator mode.
|
||
/// </summary>
|
||
/// <value>
|
||
/// <c>true</c> if this instance is in soft tone mode; otherwise, <c>false</c>.
|
||
/// </value>
|
||
public Boolean IsInSoftToneMode => this._softToneFrequency >= 0;
|
||
|
||
/// <summary>
|
||
/// Gets or sets the soft tone frequency. 0 to 5000 Hz is typical.
|
||
/// </summary>
|
||
/// <value>
|
||
/// The soft tone frequency.
|
||
/// </value>
|
||
/// <exception cref="InvalidOperationException">When soft tones cannot be initialized on the pin.</exception>
|
||
public Int32 SoftToneFrequency {
|
||
get => this._softToneFrequency;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
if(this.IsInSoftToneMode == false) {
|
||
Int32 setupResult = Native.WiringPi.SoftToneCreate(this.BcmPinNumber);
|
||
if(setupResult != 0) {
|
||
throw new InvalidOperationException($"Unable to initialize soft tone on pin {this.BcmPinNumber}. Error Code: {setupResult}");
|
||
}
|
||
}
|
||
|
||
Native.WiringPi.SoftToneWrite(this.BcmPinNumber, value);
|
||
this._softToneFrequency = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Software PWM Members
|
||
|
||
/// <summary>
|
||
/// Gets a value indicating whether this pin is in software based PWM mode.
|
||
/// </summary>
|
||
/// <value>
|
||
/// <c>true</c> if this instance is in soft PWM mode; otherwise, <c>false</c>.
|
||
/// </value>
|
||
public Boolean IsInSoftPwmMode => this._softPwmValue >= 0;
|
||
|
||
/// <summary>
|
||
/// Gets or sets the software PWM value on the pin.
|
||
/// </summary>
|
||
/// <value>
|
||
/// The soft PWM value.
|
||
/// </value>
|
||
/// <exception cref="InvalidOperationException">StartSoftPwm.</exception>
|
||
public Int32 SoftPwmValue {
|
||
get => this._softPwmValue;
|
||
|
||
set {
|
||
lock(this._syncLock) {
|
||
if(this.IsInSoftPwmMode && value >= 0) {
|
||
Native.WiringPi.SoftPwmWrite(this.BcmPinNumber, value);
|
||
this._softPwmValue = value;
|
||
} else {
|
||
throw new InvalidOperationException($"Software PWM requires a call to {nameof(StartSoftPwm)}.");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the software PWM range used upon starting the PWM.
|
||
/// </summary>
|
||
public Int32 SoftPwmRange { get; private set; } = -1;
|
||
|
||
/// <summary>
|
||
/// Starts the software based PWM on this pin.
|
||
/// </summary>
|
||
/// <param name="value">The value.</param>
|
||
/// <param name="range">The range.</param>
|
||
/// <exception cref="NotSupportedException">When the pin does not suppoert PWM.</exception>
|
||
/// <exception cref="InvalidOperationException">StartSoftPwm
|
||
/// or.</exception>
|
||
public void StartSoftPwm(Int32 value, Int32 range) {
|
||
lock(this._syncLock) {
|
||
if(!this.HasCapability(PinCapability.GP)) {
|
||
throw new NotSupportedException($"Pin {this.BcmPinNumber} does not support software PWM");
|
||
}
|
||
|
||
if(this.IsInSoftPwmMode) {
|
||
throw new InvalidOperationException($"{nameof(StartSoftPwm)} has already been called.");
|
||
}
|
||
|
||
Int32 startResult = Native.WiringPi.SoftPwmCreate(this.BcmPinNumber, value, range);
|
||
|
||
if(startResult == 0) {
|
||
this._softPwmValue = value;
|
||
this.SoftPwmRange = range;
|
||
} else {
|
||
throw new InvalidOperationException($"Could not start software based PWM on pin {this.BcmPinNumber}. Error code: {startResult}");
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Output Mode (Write) Members
|
||
|
||
/// <inheritdoc />
|
||
public void Write(GpioPinValue value) {
|
||
lock(this._syncLock) {
|
||
if(this.PinMode != GpioPinDriveMode.Output) {
|
||
throw new InvalidOperationException($"Unable to write to pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
|
||
+ $" Writes are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Output}");
|
||
}
|
||
|
||
Native.WiringPi.DigitalWrite(this.BcmPinNumber, (Int32)value);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Writes the value asynchronously.
|
||
/// </summary>
|
||
/// <param name="value">The value.</param>
|
||
/// <returns>The awaitable task.</returns>
|
||
public Task WriteAsync(GpioPinValue value) => Task.Run(() => this.Write(value));
|
||
|
||
/// <summary>
|
||
/// Writes the specified bit value.
|
||
/// This method performs a digital write.
|
||
/// </summary>
|
||
/// <param name="value">if set to <c>true</c> [value].</param>
|
||
public void Write(Boolean value) => this.Write(value ? GpioPinValue.High : GpioPinValue.Low);
|
||
|
||
/// <summary>
|
||
/// Writes the specified bit value.
|
||
/// This method performs a digital write.
|
||
/// </summary>
|
||
/// <param name="value">The value.</param>
|
||
/// <returns>
|
||
/// The awaitable task.
|
||
/// </returns>
|
||
public Task WriteAsync(Boolean value) => Task.Run(() => this.Write(value));
|
||
|
||
/// <summary>
|
||
/// Writes the specified value. 0 for low, any other value for high
|
||
/// This method performs a digital write.
|
||
/// </summary>
|
||
/// <param name="value">The value.</param>
|
||
public void Write(Int32 value) => this.Write(value != 0 ? GpioPinValue.High : GpioPinValue.Low);
|
||
|
||
/// <summary>
|
||
/// Writes the specified value. 0 for low, any other value for high
|
||
/// This method performs a digital write.
|
||
/// </summary>
|
||
/// <param name="value">The value.</param>
|
||
/// <returns>The awaitable task.</returns>
|
||
public Task WriteAsync(Int32 value) => Task.Run(() => this.Write(value));
|
||
|
||
/// <summary>
|
||
/// Writes the specified value as an analog level.
|
||
/// You will need to register additional analog modules to enable this function for devices such as the Gertboard.
|
||
/// </summary>
|
||
/// <param name="value">The value.</param>
|
||
public void WriteLevel(Int32 value) {
|
||
lock(this._syncLock) {
|
||
if(this.PinMode != GpioPinDriveMode.Output) {
|
||
throw new InvalidOperationException($"Unable to write to pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
|
||
+ $" Writes are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Output}");
|
||
}
|
||
|
||
Native.WiringPi.AnalogWrite(this.BcmPinNumber, value);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Writes the specified value as an analog level.
|
||
/// You will need to register additional analog modules to enable this function for devices such as the Gertboard.
|
||
/// </summary>
|
||
/// <param name="value">The value.</param>
|
||
/// <returns>The awaitable task.</returns>
|
||
public Task WriteLevelAsync(Int32 value) => Task.Run(() => this.WriteLevel(value));
|
||
|
||
#endregion
|
||
|
||
#region Input Mode (Read) Members
|
||
|
||
/// <summary>
|
||
/// Wait for specific pin status.
|
||
/// </summary>
|
||
/// <param name="status">status to check.</param>
|
||
/// <param name="timeOutMillisecond">timeout to reach status.</param>
|
||
/// <returns>true/false.</returns>
|
||
public Boolean WaitForValue(GpioPinValue status, Int32 timeOutMillisecond) {
|
||
if(this.PinMode != GpioPinDriveMode.Input) {
|
||
throw new InvalidOperationException($"Unable to read from pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
|
||
+ $" Reads are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input}");
|
||
}
|
||
|
||
HighResolutionTimer hrt = new HighResolutionTimer();
|
||
hrt.Start();
|
||
do {
|
||
if(this.ReadValue() == status) {
|
||
return true;
|
||
}
|
||
}
|
||
while(hrt.ElapsedMilliseconds <= timeOutMillisecond);
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Reads the digital value on the pin as a boolean value.
|
||
/// </summary>
|
||
/// <returns>The state of the pin.</returns>
|
||
public Boolean Read() {
|
||
lock(this._syncLock) {
|
||
if(this.PinMode != GpioPinDriveMode.Input && this.PinMode != GpioPinDriveMode.Output) {
|
||
throw new InvalidOperationException($"Unable to read from pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
|
||
+ $" Reads are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input} or {GpioPinDriveMode.Output}");
|
||
}
|
||
|
||
return Native.WiringPi.DigitalRead(this.BcmPinNumber) != 0;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Reads the digital value on the pin as a boolean value.
|
||
/// </summary>
|
||
/// <returns>The state of the pin.</returns>
|
||
public Task<Boolean> ReadAsync() => Task.Run(this.Read);
|
||
|
||
/// <summary>
|
||
/// Reads the digital value on the pin as a High or Low value.
|
||
/// </summary>
|
||
/// <returns>The state of the pin.</returns>
|
||
public GpioPinValue ReadValue() => this.Read() ? GpioPinValue.High : GpioPinValue.Low;
|
||
|
||
/// <summary>
|
||
/// Reads the digital value on the pin as a High or Low value.
|
||
/// </summary>
|
||
/// <returns>The state of the pin.</returns>
|
||
public Task<GpioPinValue> ReadValueAsync() => Task.Run(this.ReadValue);
|
||
|
||
/// <summary>
|
||
/// Reads the analog value on the pin.
|
||
/// This returns the value read on the supplied analog input pin. You will need to register
|
||
/// additional analog modules to enable this function for devices such as the Gertboard,
|
||
/// quick2Wire analog board, etc.
|
||
/// </summary>
|
||
/// <returns>The analog level.</returns>
|
||
/// <exception cref="InvalidOperationException">When the pin mode is not configured as an input.</exception>
|
||
public Int32 ReadLevel() {
|
||
lock(this._syncLock) {
|
||
if(this.PinMode != GpioPinDriveMode.Input) {
|
||
throw new InvalidOperationException($"Unable to read from pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
|
||
+ $" Reads are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input}");
|
||
}
|
||
|
||
return Native.WiringPi.AnalogRead(this.BcmPinNumber);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Reads the analog value on the pin.
|
||
/// This returns the value read on the supplied analog input pin. You will need to register
|
||
/// additional analog modules to enable this function for devices such as the Gertboard,
|
||
/// quick2Wire analog board, etc.
|
||
/// </summary>
|
||
/// <returns>The analog level.</returns>
|
||
public Task<Int32> ReadLevelAsync() => Task.Run(this.ReadLevel);
|
||
|
||
#endregion
|
||
|
||
#region Interrupts
|
||
|
||
/// <inheritdoc />
|
||
/// <exception cref="ArgumentNullException">callback.</exception>
|
||
public void RegisterInterruptCallback(EdgeDetection edgeDetection, Action callback) {
|
||
if(callback == null) {
|
||
throw new ArgumentNullException(nameof(callback));
|
||
}
|
||
|
||
if(this.PinMode != GpioPinDriveMode.Input) {
|
||
throw new InvalidOperationException($"Unable to {nameof(RegisterInterruptCallback)} for pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
|
||
+ $" Calling {nameof(RegisterInterruptCallback)} is only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input}");
|
||
}
|
||
|
||
lock(this._syncLock) {
|
||
Native.InterruptServiceRoutineCallback isrCallback = new Native.InterruptServiceRoutineCallback(callback);
|
||
Int32 registerResult = Native.WiringPi.WiringPiISR(this.BcmPinNumber, GetWiringPiEdgeDetection(edgeDetection), isrCallback);
|
||
if(registerResult == 0) {
|
||
this.InterruptEdgeDetection = edgeDetection;
|
||
this.InterruptCallback = isrCallback;
|
||
} else {
|
||
HardwareException.Throw(nameof(GpioPin), nameof(RegisterInterruptCallback));
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public void RegisterInterruptCallback(EdgeDetection edgeDetection, Action<Int32, Int32, UInt32> callback) => throw new NotSupportedException("WiringPi does only support a simple interrupt callback that has no parameters.");
|
||
|
||
internal static WiringPiPin BcmToWiringPiPinNumber(BcmPin pin) => (WiringPiPin)GpioToWiringPi[(Int32)pin];
|
||
|
||
private static Int32 GetWiringPiEdgeDetection(EdgeDetection edgeDetection) => GpioController.WiringPiEdgeDetectionMapping[edgeDetection];
|
||
|
||
#endregion
|
||
}
|
||
}
|