Codestyling...

This commit is contained in:
BlubbFish 2019-12-06 21:09:52 +01:00
parent 800b81d88f
commit f9015f8022
21 changed files with 2883 additions and 3036 deletions

View File

@ -1,15 +1,17 @@
namespace Unosquare.WiringPi using System;
{
using RaspberryIO.Abstractions;
using Swan.DependencyInjection; using Swan.DependencyInjection;
using Unosquare.RaspberryIO.Abstractions;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Represents the Bootstrap class to extract resources. /// Represents the Bootstrap class to extract resources.
/// </summary> /// </summary>
/// <seealso cref="Unosquare.RaspberryIO.Abstractions.IBootstrap" /> /// <seealso cref="Unosquare.RaspberryIO.Abstractions.IBootstrap" />
public class BootstrapWiringPi : IBootstrap public class BootstrapWiringPi : IBootstrap
{ {
private static readonly object SyncLock = new object(); private static readonly Object SyncLock = new Object();
/// <inheritdoc /> /// <inheritdoc />
public void Bootstrap() public void Bootstrap()

View File

@ -1,12 +1,10 @@
namespace Unosquare.WiringPi using System;
{
using System;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Defines all the available Wiring Pi Pin Numbers. /// Defines all the available Wiring Pi Pin Numbers.
/// </summary> /// </summary>
public enum WiringPiPin public enum WiringPiPin {
{
/// <summary> /// <summary>
/// Unknown WiringPi pin. /// Unknown WiringPi pin.
/// </summary> /// </summary>
@ -177,8 +175,7 @@
/// Defines the different pin capabilities. /// Defines the different pin capabilities.
/// </summary> /// </summary>
[Flags] [Flags]
public enum PinCapability public enum PinCapability {
{
/// <summary> /// <summary>
/// General Purpose capability: Digital and Analog Read/Write /// General Purpose capability: Digital and Analog Read/Write
/// </summary> /// </summary>
@ -243,8 +240,7 @@
/// <summary> /// <summary>
/// The PWM mode. /// The PWM mode.
/// </summary> /// </summary>
public enum PwmMode public enum PwmMode {
{
/// <summary> /// <summary>
/// PWM pulses are sent using mark-sign patterns (old school) /// PWM pulses are sent using mark-sign patterns (old school)
/// </summary> /// </summary>
@ -259,8 +255,7 @@
/// <summary> /// <summary>
/// Defines GPIO controller initialization modes. /// Defines GPIO controller initialization modes.
/// </summary> /// </summary>
internal enum ControllerMode internal enum ControllerMode {
{
/// <summary> /// <summary>
/// The not initialized /// The not initialized
/// </summary> /// </summary>

View File

@ -1,27 +1,26 @@
namespace Unosquare.WiringPi using System;
{
using Native;
using RaspberryIO.Abstractions;
using Swan;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Swan;
using Unosquare.RaspberryIO.Abstractions;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Represents the Raspberry Pi GPIO controller /// Represents the Raspberry Pi GPIO controller
/// as an IReadOnlyCollection of GpioPins. /// as an IReadOnlyCollection of GpioPins.
/// ///
/// Low level operations are accomplished by using the Wiring Pi library. /// Low level operations are accomplished by using the Wiring Pi library.
/// </summary> /// </summary>
public sealed class GpioController : IGpioController public sealed class GpioController : IGpioController {
{
#region Private Declarations #region Private Declarations
private const string WiringPiCodesEnvironmentVariable = "WIRINGPI_CODES"; private const String WiringPiCodesEnvironmentVariable = "WIRINGPI_CODES";
private static readonly object SyncRoot = new object(); private static readonly Object SyncRoot = new Object();
private readonly List<GpioPin> _pins; private readonly List<GpioPin> _pins;
#endregion #endregion
@ -31,36 +30,34 @@
/// <summary> /// <summary>
/// Initializes static members of the <see cref="GpioController"/> class. /// Initializes static members of the <see cref="GpioController"/> class.
/// </summary> /// </summary>
static GpioController() static GpioController() {
{ Dictionary<EdgeDetection, Int32> wiringPiEdgeDetection = new Dictionary<EdgeDetection, Int32>
var wiringPiEdgeDetection = new Dictionary<EdgeDetection, int>
{ {
{EdgeDetection.FallingEdge, 21}, {EdgeDetection.FallingEdge, 21},
{EdgeDetection.RisingEdge, 1}, {EdgeDetection.RisingEdge, 1},
{EdgeDetection.FallingAndRisingEdge, 3}, {EdgeDetection.FallingAndRisingEdge, 3}
}; };
WiringPiEdgeDetectionMapping = new ReadOnlyDictionary<EdgeDetection, int>(wiringPiEdgeDetection); WiringPiEdgeDetectionMapping = new ReadOnlyDictionary<EdgeDetection, Int32>(wiringPiEdgeDetection);
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="GpioController"/> class. /// Initializes a new instance of the <see cref="GpioController"/> class.
/// </summary> /// </summary>
/// <exception cref="System.Exception">Unable to initialize the GPIO controller.</exception> /// <exception cref="System.Exception">Unable to initialize the GPIO controller.</exception>
internal GpioController() internal GpioController() {
{ if(this._pins != null) {
if (_pins != null)
return; return;
if (IsInitialized == false)
{
var initResult = Initialize(ControllerMode.DirectWithBcmPins);
if (initResult == false)
throw new Exception("Unable to initialize the GPIO controller.");
} }
_pins = new List<GpioPin> if(IsInitialized == false) {
{ Boolean initResult = this.Initialize(ControllerMode.DirectWithBcmPins);
if(initResult == false) {
throw new Exception("Unable to initialize the GPIO controller.");
}
}
this._pins = new List<GpioPin> {
GpioPin.Pin00.Value, GpioPin.Pin00.Value,
GpioPin.Pin01.Value, GpioPin.Pin01.Value,
GpioPin.Pin02.Value, GpioPin.Pin02.Value,
@ -95,19 +92,19 @@
GpioPin.Pin31.Value, GpioPin.Pin31.Value,
}; };
var headerP1 = new Dictionary<int, GpioPin>(_pins.Count); Dictionary<Int32, GpioPin> headerP1 = new Dictionary<Int32, GpioPin>(this._pins.Count);
var headerP5 = new Dictionary<int, GpioPin>(_pins.Count); Dictionary<Int32, GpioPin> headerP5 = new Dictionary<Int32, GpioPin>(this._pins.Count);
foreach (var pin in _pins) foreach(GpioPin pin in this._pins) {
{ if(pin.PhysicalPinNumber < 0) {
if (pin.PhysicalPinNumber < 0)
continue; continue;
}
var header = pin.Header == GpioHeader.P1 ? headerP1 : headerP5; Dictionary<Int32, GpioPin> header = pin.Header == GpioHeader.P1 ? headerP1 : headerP5;
header[pin.PhysicalPinNumber] = pin; header[pin.PhysicalPinNumber] = pin;
} }
HeaderP1 = new ReadOnlyDictionary<int, GpioPin>(headerP1); this.HeaderP1 = new ReadOnlyDictionary<Int32, GpioPin>(headerP1);
HeaderP5 = new ReadOnlyDictionary<int, GpioPin>(headerP5); this.HeaderP5 = new ReadOnlyDictionary<Int32, GpioPin>(headerP5);
} }
/// <summary> /// <summary>
@ -116,12 +113,9 @@
/// <value> /// <value>
/// <c>true</c> if the controller is properly initialized; otherwise, <c>false</c>. /// <c>true</c> if the controller is properly initialized; otherwise, <c>false</c>.
/// </value> /// </value>
public static bool IsInitialized public static Boolean IsInitialized {
{ get {
get lock(SyncRoot) {
{
lock (SyncRoot)
{
return Mode != ControllerMode.NotInitialized; return Mode != ControllerMode.NotInitialized;
} }
} }
@ -130,13 +124,15 @@
/// <summary> /// <summary>
/// Gets the wiring pi edge detection mapping. /// Gets the wiring pi edge detection mapping.
/// </summary> /// </summary>
internal static ReadOnlyDictionary<EdgeDetection, int> WiringPiEdgeDetectionMapping { get; } internal static ReadOnlyDictionary<EdgeDetection, Int32> WiringPiEdgeDetectionMapping {
get;
}
/// <inheritdoc /> /// <inheritdoc />
/// <summary> /// <summary>
/// Gets the number of registered pins in the controller. /// Gets the number of registered pins in the controller.
/// </summary> /// </summary>
public int Count => Pins.Count; public Int32 Count => this.Pins.Count;
/// <summary> /// <summary>
/// Gets or sets the initialization mode. /// Gets or sets the initialization mode.
@ -150,24 +146,28 @@
/// <summary> /// <summary>
/// Gets the PWM base frequency (in Hz). /// Gets the PWM base frequency (in Hz).
/// </summary> /// </summary>
public int PwmBaseFrequency => 19200000; public Int32 PwmBaseFrequency => 19200000;
/// <summary> /// <summary>
/// Gets a red-only collection of all pins. /// Gets a red-only collection of all pins.
/// </summary> /// </summary>
public ReadOnlyCollection<GpioPin> Pins => new ReadOnlyCollection<GpioPin>(_pins); public ReadOnlyCollection<GpioPin> Pins => new ReadOnlyCollection<GpioPin>(this._pins);
/// <summary> /// <summary>
/// Provides all the pins on Header P1 of the Pi as a lookup by physical header pin number. /// Provides all the pins on Header P1 of the Pi as a lookup by physical header pin number.
/// This header is the main header and it is the one commonly used. /// This header is the main header and it is the one commonly used.
/// </summary> /// </summary>
public ReadOnlyDictionary<int, GpioPin> HeaderP1 { get; } public ReadOnlyDictionary<Int32, GpioPin> HeaderP1 {
get;
}
/// <summary> /// <summary>
/// Provides all the pins on Header P5 of the Pi as a lookup by physical header pin number. /// Provides all the pins on Header P5 of the Pi as a lookup by physical header pin number.
/// This header is the secondary header and it is rarely used. /// This header is the secondary header and it is rarely used.
/// </summary> /// </summary>
public ReadOnlyDictionary<int, GpioPin> HeaderP5 { get; } public ReadOnlyDictionary<Int32, GpioPin> HeaderP5 {
get;
}
#endregion #endregion
@ -338,25 +338,24 @@
#region Indexers #region Indexers
/// <inheritdoc /> /// <inheritdoc />
public IGpioPin this[BcmPin bcmPin] => Pins[(int)bcmPin]; public IGpioPin this[BcmPin bcmPin] => this.Pins[(Int32)bcmPin];
/// <inheritdoc /> /// <inheritdoc />
public IGpioPin this[int bcmPinNumber] public IGpioPin this[Int32 bcmPinNumber] {
{ get {
get if(!Enum.IsDefined(typeof(BcmPin), bcmPinNumber)) {
{
if (!Enum.IsDefined(typeof(BcmPin), bcmPinNumber))
throw new IndexOutOfRangeException($"Pin {bcmPinNumber} is not registered in the GPIO controller."); throw new IndexOutOfRangeException($"Pin {bcmPinNumber} is not registered in the GPIO controller.");
}
return Pins[bcmPinNumber]; return this.Pins[bcmPinNumber];
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public IGpioPin this[P1 pinNumber] => HeaderP1[(int)pinNumber]; public IGpioPin this[P1 pinNumber] => this.HeaderP1[(Int32)pinNumber];
/// <inheritdoc /> /// <inheritdoc />
public IGpioPin this[P5 pinNumber] => HeaderP5[(int)pinNumber]; public IGpioPin this[P5 pinNumber] => this.HeaderP5[(Int32)pinNumber];
/// <summary> /// <summary>
/// Gets the <see cref="GpioPin"/> with the specified Wiring Pi pin number. /// Gets the <see cref="GpioPin"/> with the specified Wiring Pi pin number.
@ -366,14 +365,13 @@
/// </value> /// </value>
/// <param name="pinNumber">The pin number.</param> /// <param name="pinNumber">The pin number.</param>
/// <returns>A reference to the GPIO pin.</returns> /// <returns>A reference to the GPIO pin.</returns>
public GpioPin this[WiringPiPin pinNumber] public GpioPin this[WiringPiPin pinNumber] {
{ get {
get if(pinNumber == WiringPiPin.Unknown) {
{
if (pinNumber == WiringPiPin.Unknown)
throw new InvalidOperationException("You can not get an unknown WiringPi pin."); throw new InvalidOperationException("You can not get an unknown WiringPi pin.");
}
return Pins.First(p => p.WiringPiPinNumber == pinNumber); return this.Pins.First(p => p.WiringPiPinNumber == pinNumber);
} }
} }
@ -388,11 +386,9 @@
/// </summary> /// </summary>
/// <param name="group">The group.</param> /// <param name="group">The group.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
public void SetPadDrive(int group, int value) public void SetPadDrive(Int32 group, Int32 value) {
{ lock(SyncRoot) {
lock (SyncRoot) _ = Native.WiringPi.SetPadDrive(group, value);
{
WiringPi.SetPadDrive(group, value);
} }
} }
@ -404,8 +400,7 @@
/// <param name="group">The group.</param> /// <param name="group">The group.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task SetPadDriveAsync(int group, int value) => public Task SetPadDriveAsync(Int32 group, Int32 value) => Task.Run(() => this.SetPadDrive(group, value));
Task.Run(() => SetPadDrive(group, value));
/// <summary> /// <summary>
/// This writes the 8-bit byte supplied to the first 8 GPIO pins. /// This writes the 8-bit byte supplied to the first 8 GPIO pins.
@ -414,17 +409,13 @@
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <exception cref="InvalidOperationException">PinMode.</exception> /// <exception cref="InvalidOperationException">PinMode.</exception>
public void WriteByte(byte value) public void WriteByte(Byte value) {
{ lock(SyncRoot) {
lock (SyncRoot) if(this.Skip(0).Take(8).Any(p => p.PinMode != GpioPinDriveMode.Output)) {
{ throw new InvalidOperationException($"All first 8 pins (0 to 7) need their {nameof(GpioPin.PinMode)} to be set to {GpioPinDriveMode.Output}");
if (this.Skip(0).Take(8).Any(p => p.PinMode != GpioPinDriveMode.Output))
{
throw new InvalidOperationException(
$"All first 8 pins (0 to 7) need their {nameof(GpioPin.PinMode)} to be set to {GpioPinDriveMode.Output}");
} }
WiringPi.DigitalWriteByte(value); Native.WiringPi.DigitalWriteByte(value);
} }
} }
@ -435,8 +426,7 @@
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task WriteByteAsync(byte value) => public Task WriteByteAsync(Byte value) => Task.Run(() => this.WriteByte(value));
Task.Run(() => WriteByte(value));
/// <summary> /// <summary>
/// This reads the 8-bit byte supplied to the first 8 GPIO pins. /// This reads the 8-bit byte supplied to the first 8 GPIO pins.
@ -445,18 +435,14 @@
/// </summary> /// </summary>
/// <returns>A byte from the GPIO.</returns> /// <returns>A byte from the GPIO.</returns>
/// <exception cref="InvalidOperationException">PinMode.</exception> /// <exception cref="InvalidOperationException">PinMode.</exception>
public byte ReadByte() public Byte ReadByte() {
{ lock(SyncRoot) {
lock (SyncRoot)
{
if(this.Skip(0).Take(8).Any(p => if(this.Skip(0).Take(8).Any(p =>
p.PinMode != GpioPinDriveMode.Input && p.PinMode != GpioPinDriveMode.Output)) p.PinMode != GpioPinDriveMode.Input && p.PinMode != GpioPinDriveMode.Output)) {
{ throw new InvalidOperationException($"All first 8 pins (0 to 7) need their {nameof(GpioPin.PinMode)} to be set to {GpioPinDriveMode.Input} or {GpioPinDriveMode.Output}");
throw new InvalidOperationException(
$"All first 8 pins (0 to 7) need their {nameof(GpioPin.PinMode)} to be set to {GpioPinDriveMode.Input} or {GpioPinDriveMode.Output}");
} }
return (byte)WiringPi.DigitalReadByte(); return (Byte)Native.WiringPi.DigitalReadByte();
} }
} }
@ -466,8 +452,7 @@
/// Please note this function is undocumented and unsupported. /// Please note this function is undocumented and unsupported.
/// </summary> /// </summary>
/// <returns>A byte from the GPIO.</returns> /// <returns>A byte from the GPIO.</returns>
public Task<byte> ReadByteAsync() => public Task<Byte> ReadByteAsync() => Task.Run(this.ReadByte);
Task.Run(ReadByte);
#endregion #endregion
@ -479,13 +464,13 @@
/// <returns> /// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection. /// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
/// </returns> /// </returns>
public IEnumerator<GpioPin> GetEnumerator() => Pins.GetEnumerator(); public IEnumerator<GpioPin> GetEnumerator() => this.Pins.GetEnumerator();
/// <inheritdoc /> /// <inheritdoc />
IEnumerator<IGpioPin> IEnumerable<IGpioPin>.GetEnumerator() => Pins.GetEnumerator(); IEnumerator<IGpioPin> IEnumerable<IGpioPin>.GetEnumerator() => this.Pins.GetEnumerator();
/// <inheritdoc /> /// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator() => Pins.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => this.Pins.GetEnumerator();
#endregion #endregion
@ -496,11 +481,9 @@
/// </summary> /// </summary>
/// <param name="wiringPiPinNumber">The wiring pi pin number.</param> /// <param name="wiringPiPinNumber">The wiring pi pin number.</param>
/// <returns>The converted pin.</returns> /// <returns>The converted pin.</returns>
internal static int WiringPiToBcmPinNumber(int wiringPiPinNumber) internal static Int32 WiringPiToBcmPinNumber(Int32 wiringPiPinNumber) {
{ lock(SyncRoot) {
lock (SyncRoot) return Native.WiringPi.WpiPinToGpio(wiringPiPinNumber);
{
return WiringPi.WpiPinToGpio(wiringPiPinNumber);
} }
} }
@ -509,11 +492,9 @@
/// </summary> /// </summary>
/// <param name="headerPinNumber">The header pin number.</param> /// <param name="headerPinNumber">The header pin number.</param>
/// <returns>The converted pin.</returns> /// <returns>The converted pin.</returns>
internal static int HaderToBcmPinNumber(int headerPinNumber) internal static Int32 HaderToBcmPinNumber(Int32 headerPinNumber) {
{ lock(SyncRoot) {
lock (SyncRoot) return Native.WiringPi.PhysPinToGpio(headerPinNumber);
{
return WiringPi.PhysPinToGpio(headerPinNumber);
} }
} }
@ -527,47 +508,41 @@
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">Library was already Initialized.</exception> /// <exception cref="InvalidOperationException">Library was already Initialized.</exception>
/// <exception cref="ArgumentException">The init mode is invalid.</exception> /// <exception cref="ArgumentException">The init mode is invalid.</exception>
private bool Initialize(ControllerMode mode) private Boolean Initialize(ControllerMode mode) {
{ if(SwanRuntime.OS != Swan.OperatingSystem.Unix) {
if (SwanRuntime.OS != Swan.OperatingSystem.Unix)
throw new PlatformNotSupportedException("This library does not support the platform"); throw new PlatformNotSupportedException("This library does not support the platform");
}
lock (SyncRoot) lock(SyncRoot) {
{ if(IsInitialized) {
if (IsInitialized)
throw new InvalidOperationException($"Cannot call {nameof(Initialize)} more than once."); throw new InvalidOperationException($"Cannot call {nameof(Initialize)} more than once.");
}
Environment.SetEnvironmentVariable(WiringPiCodesEnvironmentVariable, "1"); Environment.SetEnvironmentVariable(WiringPiCodesEnvironmentVariable, "1");
int setupResult; Int32 setupResult;
switch (mode) switch(mode) {
{ case ControllerMode.DirectWithWiringPiPins: {
case ControllerMode.DirectWithWiringPiPins: setupResult = Native.WiringPi.WiringPiSetup();
{
setupResult = WiringPi.WiringPiSetup();
break; break;
} }
case ControllerMode.DirectWithBcmPins: case ControllerMode.DirectWithBcmPins: {
{ setupResult = Native.WiringPi.WiringPiSetupGpio();
setupResult = WiringPi.WiringPiSetupGpio();
break; break;
} }
case ControllerMode.DirectWithHeaderPins: case ControllerMode.DirectWithHeaderPins: {
{ setupResult = Native.WiringPi.WiringPiSetupPhys();
setupResult = WiringPi.WiringPiSetupPhys();
break; break;
} }
case ControllerMode.FileStreamWithHardwarePins: case ControllerMode.FileStreamWithHardwarePins: {
{ setupResult = Native.WiringPi.WiringPiSetupSys();
setupResult = WiringPi.WiringPiSetupSys();
break; break;
} }
default: default: {
{
throw new ArgumentException($"'{mode}' is not a valid initialization mode."); throw new ArgumentException($"'{mode}' is not a valid initialization mode.");
} }
} }

View File

@ -1,198 +1,165 @@
namespace Unosquare.WiringPi using System;
{
using RaspberryIO.Abstractions;
using System;
public partial class GpioPin using Unosquare.RaspberryIO.Abstractions;
{
internal static readonly Lazy<GpioPin> Pin00 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio00) namespace Unosquare.WiringPi {
{ public partial class GpioPin {
internal static readonly Lazy<GpioPin> Pin00 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio00) {
Capabilities = PinCapability.GP | PinCapability.I2CSDA, Capabilities = PinCapability.GP | PinCapability.I2CSDA,
Name = $"BCM 0 {(SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? "(SDA)" : "(ID_SD)")}", Name = $"BCM 0 {(SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? "(SDA)" : "(ID_SD)")}",
}); });
internal static readonly Lazy<GpioPin> Pin01 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio01) internal static readonly Lazy<GpioPin> Pin01 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio01) {
{
Capabilities = PinCapability.GP | PinCapability.I2CSCL, Capabilities = PinCapability.GP | PinCapability.I2CSCL,
Name = $"BCM 1 {(SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? "(SCL)" : "(ID_SC)")}", Name = $"BCM 1 {(SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? "(SCL)" : "(ID_SC)")}",
}); });
internal static readonly Lazy<GpioPin> Pin02 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio02) internal static readonly Lazy<GpioPin> Pin02 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio02) {
{
Capabilities = PinCapability.GP | PinCapability.I2CSDA, Capabilities = PinCapability.GP | PinCapability.I2CSDA,
Name = "BCM 2 (SDA)", Name = "BCM 2 (SDA)",
}); });
internal static readonly Lazy<GpioPin> Pin03 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio03) internal static readonly Lazy<GpioPin> Pin03 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio03) {
{
Capabilities = PinCapability.GP | PinCapability.I2CSCL, Capabilities = PinCapability.GP | PinCapability.I2CSCL,
Name = "BCM 3 (SCL)", Name = "BCM 3 (SCL)",
}); });
internal static readonly Lazy<GpioPin> Pin04 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio04) internal static readonly Lazy<GpioPin> Pin04 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio04) {
{
Capabilities = PinCapability.GP | PinCapability.GPCLK, Capabilities = PinCapability.GP | PinCapability.GPCLK,
Name = "BCM 4 (GPCLK0)", Name = "BCM 4 (GPCLK0)",
}); });
internal static readonly Lazy<GpioPin> Pin05 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio05) internal static readonly Lazy<GpioPin> Pin05 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio05) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 5", Name = "BCM 5",
}); });
internal static readonly Lazy<GpioPin> Pin06 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio06) internal static readonly Lazy<GpioPin> Pin06 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio06) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 6", Name = "BCM 6",
}); });
internal static readonly Lazy<GpioPin> Pin07 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio07) internal static readonly Lazy<GpioPin> Pin07 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio07) {
{
Capabilities = PinCapability.GP | PinCapability.SPICS, Capabilities = PinCapability.GP | PinCapability.SPICS,
Name = "BCM 7 (CE1)", Name = "BCM 7 (CE1)",
}); });
internal static readonly Lazy<GpioPin> Pin08 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio08) internal static readonly Lazy<GpioPin> Pin08 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio08) {
{
Capabilities = PinCapability.GP | PinCapability.SPICS, Capabilities = PinCapability.GP | PinCapability.SPICS,
Name = "BCM 8 (CE0)", Name = "BCM 8 (CE0)",
}); });
internal static readonly Lazy<GpioPin> Pin09 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio09) internal static readonly Lazy<GpioPin> Pin09 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio09) {
{
Capabilities = PinCapability.GP | PinCapability.SPIMISO, Capabilities = PinCapability.GP | PinCapability.SPIMISO,
Name = "BCM 9 (MISO)", Name = "BCM 9 (MISO)",
}); });
internal static readonly Lazy<GpioPin> Pin10 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio10) internal static readonly Lazy<GpioPin> Pin10 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio10) {
{
Capabilities = PinCapability.GP | PinCapability.SPIMOSI, Capabilities = PinCapability.GP | PinCapability.SPIMOSI,
Name = "BCM 10 (MOSI)", Name = "BCM 10 (MOSI)",
}); });
internal static readonly Lazy<GpioPin> Pin11 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio11) internal static readonly Lazy<GpioPin> Pin11 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio11) {
{
Capabilities = PinCapability.GP | PinCapability.SPICLK, Capabilities = PinCapability.GP | PinCapability.SPICLK,
Name = "BCM 11 (SCLCK)", Name = "BCM 11 (SCLCK)",
}); });
internal static readonly Lazy<GpioPin> Pin12 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio12) internal static readonly Lazy<GpioPin> Pin12 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio12) {
{
Capabilities = PinCapability.GP | PinCapability.PWM, Capabilities = PinCapability.GP | PinCapability.PWM,
Name = "BCM 12 (PWM0)", Name = "BCM 12 (PWM0)",
}); });
internal static readonly Lazy<GpioPin> Pin13 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio13) internal static readonly Lazy<GpioPin> Pin13 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio13) {
{
Capabilities = PinCapability.GP | PinCapability.PWM, Capabilities = PinCapability.GP | PinCapability.PWM,
Name = "BCM 13 (PWM1)", Name = "BCM 13 (PWM1)",
}); });
internal static readonly Lazy<GpioPin> Pin14 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio14) internal static readonly Lazy<GpioPin> Pin14 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio14) {
{
Capabilities = PinCapability.UARTTXD, Capabilities = PinCapability.UARTTXD,
Name = "BCM 14 (TXD)", Name = "BCM 14 (TXD)",
}); });
internal static readonly Lazy<GpioPin> Pin15 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio15) internal static readonly Lazy<GpioPin> Pin15 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio15) {
{
Capabilities = PinCapability.UARTRXD, Capabilities = PinCapability.UARTRXD,
Name = "BCM 15 (RXD)", Name = "BCM 15 (RXD)",
}); });
internal static readonly Lazy<GpioPin> Pin16 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio16) internal static readonly Lazy<GpioPin> Pin16 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio16) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 16", Name = "BCM 16",
}); });
internal static readonly Lazy<GpioPin> Pin17 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio17) internal static readonly Lazy<GpioPin> Pin17 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio17) {
{
Capabilities = PinCapability.GP | PinCapability.UARTRTS, Capabilities = PinCapability.GP | PinCapability.UARTRTS,
Name = "BCM 17", Name = "BCM 17",
}); });
internal static readonly Lazy<GpioPin> Pin18 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio18) internal static readonly Lazy<GpioPin> Pin18 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio18) {
{
Capabilities = PinCapability.GP | PinCapability.PWM, Capabilities = PinCapability.GP | PinCapability.PWM,
Name = "BCM 18 (PWM0)", Name = "BCM 18 (PWM0)",
}); });
internal static readonly Lazy<GpioPin> Pin19 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio19) internal static readonly Lazy<GpioPin> Pin19 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio19) {
{
Capabilities = PinCapability.GP | PinCapability.PWM | PinCapability.SPIMISO, Capabilities = PinCapability.GP | PinCapability.PWM | PinCapability.SPIMISO,
Name = "BCM 19 (MISO)", Name = "BCM 19 (MISO)",
}); });
internal static readonly Lazy<GpioPin> Pin20 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio20) internal static readonly Lazy<GpioPin> Pin20 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio20) {
{
Capabilities = PinCapability.GP | PinCapability.SPIMOSI, Capabilities = PinCapability.GP | PinCapability.SPIMOSI,
Name = "BCM 20 (MOSI)", Name = "BCM 20 (MOSI)",
}); });
internal static readonly Lazy<GpioPin> Pin21 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio21) internal static readonly Lazy<GpioPin> Pin21 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio21) {
{
Capabilities = PinCapability.GP | PinCapability.SPICLK, Capabilities = PinCapability.GP | PinCapability.SPICLK,
Name = $"BCM 21{(SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? string.Empty : " (SCLK)")}", Name = $"BCM 21{(SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? String.Empty : " (SCLK)")}",
}); });
internal static readonly Lazy<GpioPin> Pin22 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio22) internal static readonly Lazy<GpioPin> Pin22 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio22) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 22", Name = "BCM 22",
}); });
internal static readonly Lazy<GpioPin> Pin23 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio23) internal static readonly Lazy<GpioPin> Pin23 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio23) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 23", Name = "BCM 23",
}); });
internal static readonly Lazy<GpioPin> Pin24 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio24) internal static readonly Lazy<GpioPin> Pin24 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio24) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 24", Name = "BCM 24",
}); });
internal static readonly Lazy<GpioPin> Pin25 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio25) internal static readonly Lazy<GpioPin> Pin25 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio25) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 25", Name = "BCM 25",
}); });
internal static readonly Lazy<GpioPin> Pin26 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio26) internal static readonly Lazy<GpioPin> Pin26 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio26) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 26", Name = "BCM 26",
}); });
internal static readonly Lazy<GpioPin> Pin27 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio27) internal static readonly Lazy<GpioPin> Pin27 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio27) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 27", Name = "BCM 27",
}); });
internal static readonly Lazy<GpioPin> Pin28 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio28) internal static readonly Lazy<GpioPin> Pin28 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio28) {
{
Capabilities = PinCapability.GP | PinCapability.I2CSDA, Capabilities = PinCapability.GP | PinCapability.I2CSDA,
Name = "BCM 28 (SDA)", Name = "BCM 28 (SDA)",
}); });
internal static readonly Lazy<GpioPin> Pin29 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio29) internal static readonly Lazy<GpioPin> Pin29 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio29) {
{
Capabilities = PinCapability.GP | PinCapability.I2CSCL, Capabilities = PinCapability.GP | PinCapability.I2CSCL,
Name = "BCM 29 (SCL)", Name = "BCM 29 (SCL)",
}); });
internal static readonly Lazy<GpioPin> Pin30 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio30) internal static readonly Lazy<GpioPin> Pin30 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio30) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 30", Name = "BCM 30",
}); });
internal static readonly Lazy<GpioPin> Pin31 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio31) internal static readonly Lazy<GpioPin> Pin31 = new Lazy<GpioPin>(() => new GpioPin(BcmPin.Gpio31) {
{
Capabilities = PinCapability.GP, Capabilities = PinCapability.GP,
Name = "BCM 31", Name = "BCM 31",
}); });

View File

@ -1,66 +1,55 @@
namespace Unosquare.WiringPi using System;
{
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Native;
using RaspberryIO.Abstractions;
using RaspberryIO.Abstractions.Native;
using Swan.Diagnostics;
using Definitions = RaspberryIO.Abstractions.Definitions;
using Swan.Diagnostics;
using Unosquare.RaspberryIO.Abstractions;
using Unosquare.RaspberryIO.Abstractions.Native;
using Definitions = Unosquare.RaspberryIO.Abstractions.Definitions;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Represents a GPIO Pin, its location and its capabilities. /// Represents a GPIO Pin, its location and its capabilities.
/// Full pin reference available here: /// Full pin reference available here:
/// http://pinout.xyz/pinout/pin31_gpio6 and http://wiringpi.com/pins/. /// http://pinout.xyz/pinout/pin31_gpio6 and http://wiringpi.com/pins/.
/// </summary> /// </summary>
public sealed partial class GpioPin : IGpioPin public sealed partial class GpioPin : IGpioPin {
{
#region Property Backing #region Property Backing
private static readonly int[] GpioToWiringPi; private static readonly Int32[] GpioToWiringPi;
private static readonly int[] GpioToWiringPiR1 = 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 };
{
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 int[] GpioToWiringPiR2 = 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 };
{
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 readonly Object _syncLock = new Object();
private GpioPinDriveMode _pinMode; private GpioPinDriveMode _pinMode;
private GpioPinResistorPullMode _resistorPullMode; private GpioPinResistorPullMode _resistorPullMode;
private int _pwmRegister; private Int32 _pwmRegister;
private PwmMode _pwmMode = PwmMode.Balanced; private PwmMode _pwmMode = PwmMode.Balanced;
private uint _pwmRange = 1024; private UInt32 _pwmRange = 1024;
private int _pwmClockDivisor = 1; private Int32 _pwmClockDivisor = 1;
private int _softPwmValue = -1; private Int32 _softPwmValue = -1;
private int _softToneFrequency = -1; private Int32 _softToneFrequency = -1;
#endregion #endregion
#region Constructor #region Constructor
static GpioPin() static GpioPin() => GpioToWiringPi = SystemInfo.GetBoardRevision() == BoardRevision.Rev1 ? GpioToWiringPiR1 : GpioToWiringPiR2;
{
GpioToWiringPi = SystemInfo.GetBoardRevision() ==
BoardRevision.Rev1 ? GpioToWiringPiR1 : GpioToWiringPiR2;
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="GpioPin"/> class. /// Initializes a new instance of the <see cref="GpioPin"/> class.
/// </summary> /// </summary>
/// <param name="bcmPinNumber">The BCM pin number.</param> /// <param name="bcmPinNumber">The BCM pin number.</param>
private GpioPin(BcmPin bcmPinNumber) private GpioPin(BcmPin bcmPinNumber) {
{ this.BcmPin = bcmPinNumber;
BcmPin = bcmPinNumber; this.BcmPinNumber = (Int32)bcmPinNumber;
BcmPinNumber = (int)bcmPinNumber;
WiringPiPinNumber = BcmToWiringPiPinNumber(bcmPinNumber); this.WiringPiPinNumber = BcmToWiringPiPinNumber(bcmPinNumber);
PhysicalPinNumber = Definitions.BcmToPhysicalPinNumber(SystemInfo.GetBoardRevision(), bcmPinNumber); this.PhysicalPinNumber = Definitions.BcmToPhysicalPinNumber(SystemInfo.GetBoardRevision(), bcmPinNumber);
Header = (BcmPinNumber >= 28 && BcmPinNumber <= 31) ? GpioHeader.P5 : GpioHeader.P1; this.Header = (this.BcmPinNumber >= 28 && this.BcmPinNumber <= 31) ? GpioHeader.P5 : GpioHeader.P1;
} }
#endregion #endregion
@ -68,37 +57,50 @@
#region Pin Properties #region Pin Properties
/// <inheritdoc /> /// <inheritdoc />
public BcmPin BcmPin { get; } public BcmPin BcmPin {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public int BcmPinNumber { get; } public Int32 BcmPinNumber {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public int PhysicalPinNumber { get; } public Int32 PhysicalPinNumber {
get;
}
/// <summary> /// <summary>
/// Gets the WiringPi Pin number. /// Gets the WiringPi Pin number.
/// </summary> /// </summary>
public WiringPiPin WiringPiPinNumber { get; } public WiringPiPin WiringPiPinNumber {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public GpioHeader Header { get; } public GpioHeader Header {
get;
}
/// <summary> /// <summary>
/// Gets the friendly name of the pin. /// Gets the friendly name of the pin.
/// </summary> /// </summary>
public string Name { get; private set; } public String Name {
get; private set;
}
/// <summary> /// <summary>
/// Gets the hardware mode capabilities of this pin. /// Gets the hardware mode capabilities of this pin.
/// </summary> /// </summary>
public PinCapability Capabilities { get; private set; } public PinCapability Capabilities {
get; private set;
}
/// <inheritdoc /> /// <inheritdoc />
public bool Value public Boolean Value {
{ get => this.Read();
get => Read(); set => this.Write(value);
set => Write(value);
} }
#endregion #endregion
@ -107,26 +109,21 @@
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="T:System.NotSupportedException">Thrown when a pin does not support the given operation mode.</exception> /// <exception cref="T:System.NotSupportedException">Thrown when a pin does not support the given operation mode.</exception>
public GpioPinDriveMode PinMode public GpioPinDriveMode PinMode {
{ get => this._pinMode;
get => _pinMode;
set set {
{ lock(this._syncLock) {
lock (_syncLock) GpioPinDriveMode mode = value;
{ if(mode == GpioPinDriveMode.GpioClock && !this.HasCapability(PinCapability.GPCLK) ||
var mode = value; mode == GpioPinDriveMode.PwmOutput && !this.HasCapability(PinCapability.PWM) ||
if ((mode == GpioPinDriveMode.GpioClock && !HasCapability(PinCapability.GPCLK)) || mode == GpioPinDriveMode.Input && !this.HasCapability(PinCapability.GP) ||
(mode == GpioPinDriveMode.PwmOutput && !HasCapability(PinCapability.PWM)) || mode == GpioPinDriveMode.Output && !this.HasCapability(PinCapability.GP)) {
(mode == GpioPinDriveMode.Input && !HasCapability(PinCapability.GP)) || throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{mode}'. Pin capabilities are limited to: {this.Capabilities}");
(mode == GpioPinDriveMode.Output && !HasCapability(PinCapability.GP)))
{
throw new NotSupportedException(
$"Pin {BcmPinNumber} '{Name}' does not support mode '{mode}'. Pin capabilities are limited to: {Capabilities}");
} }
WiringPi.PinMode(BcmPinNumber, (int)mode); Native.WiringPi.PinMode(this.BcmPinNumber, (Int32)mode);
_pinMode = mode; this._pinMode = mode;
} }
} }
} }
@ -135,12 +132,16 @@
/// Gets the interrupt callback. Returns null if no interrupt /// Gets the interrupt callback. Returns null if no interrupt
/// has been registered. /// has been registered.
/// </summary> /// </summary>
public InterruptServiceRoutineCallback InterruptCallback { get; private set; } public Native.InterruptServiceRoutineCallback InterruptCallback {
get; private set;
}
/// <summary> /// <summary>
/// Gets the interrupt edge detection mode. /// Gets the interrupt edge detection mode.
/// </summary> /// </summary>
public EdgeDetection InterruptEdgeDetection { get; private set; } public EdgeDetection InterruptEdgeDetection {
get; private set;
}
/// <summary> /// <summary>
/// Determines whether the specified capability has capability. /// Determines whether the specified capability has capability.
@ -149,32 +150,26 @@
/// <returns> /// <returns>
/// <c>true</c> if the specified capability has capability; otherwise, <c>false</c>. /// <c>true</c> if the specified capability has capability; otherwise, <c>false</c>.
/// </returns> /// </returns>
public bool HasCapability(PinCapability capability) => public Boolean HasCapability(PinCapability capability) => (this.Capabilities & capability) == capability;
(Capabilities & capability) == capability;
#endregion #endregion
#region Hardware PWM Members #region Hardware PWM Members
/// <inheritdoc /> /// <inheritdoc />
public GpioPinResistorPullMode InputPullMode public GpioPinResistorPullMode InputPullMode {
{ get => this.PinMode == GpioPinDriveMode.Input ? this._resistorPullMode : GpioPinResistorPullMode.Off;
get => PinMode == GpioPinDriveMode.Input ? _resistorPullMode : GpioPinResistorPullMode.Off;
set set {
{ lock(this._syncLock) {
lock (_syncLock) if(this.PinMode != GpioPinDriveMode.Input) {
{ this._resistorPullMode = GpioPinResistorPullMode.Off;
if (PinMode != GpioPinDriveMode.Input) 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}");
_resistorPullMode = GpioPinResistorPullMode.Off;
throw new InvalidOperationException(
$"Unable to set the {nameof(InputPullMode)} for pin {BcmPinNumber} because operating mode is {PinMode}."
+ $" Setting the {nameof(InputPullMode)} is only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Input}");
} }
WiringPi.PullUpDnControl(BcmPinNumber, (int)value); Native.WiringPi.PullUpDnControl(this.BcmPinNumber, (Int32)value);
_resistorPullMode = value; this._resistorPullMode = value;
} }
} }
} }
@ -185,24 +180,19 @@
/// <value> /// <value>
/// The PWM register. /// The PWM register.
/// </value> /// </value>
public int PwmRegister public Int32 PwmRegister {
{ get => this._pwmRegister;
get => _pwmRegister;
set set {
{ lock(this._syncLock) {
lock (_syncLock) if(!this.HasCapability(PinCapability.PWM)) {
{ this._pwmRegister = 0;
if (!HasCapability(PinCapability.PWM))
{
_pwmRegister = 0;
throw new NotSupportedException( throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
$"Pin {BcmPinNumber} '{Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {Capabilities}");
} }
WiringPi.PwmWrite(BcmPinNumber, value); Native.WiringPi.PwmWrite(this.BcmPinNumber, value);
_pwmRegister = value; this._pwmRegister = value;
} }
} }
} }
@ -215,24 +205,19 @@
/// The PWM mode. /// The PWM mode.
/// </value> /// </value>
/// <exception cref="InvalidOperationException">When pin mode is not set a Pwn output.</exception> /// <exception cref="InvalidOperationException">When pin mode is not set a Pwn output.</exception>
public PwmMode PwmMode public PwmMode PwmMode {
{ get => this.PinMode == GpioPinDriveMode.PwmOutput ? this._pwmMode : PwmMode.Balanced;
get => PinMode == GpioPinDriveMode.PwmOutput ? _pwmMode : PwmMode.Balanced;
set set {
{ lock(this._syncLock) {
lock (_syncLock) if(!this.HasCapability(PinCapability.PWM)) {
{ this._pwmMode = PwmMode.Balanced;
if (!HasCapability(PinCapability.PWM))
{
_pwmMode = PwmMode.Balanced;
throw new NotSupportedException( throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
$"Pin {BcmPinNumber} '{Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {Capabilities}");
} }
WiringPi.PwmSetMode((int)value); Native.WiringPi.PwmSetMode((Int32)value);
_pwmMode = value; this._pwmMode = value;
} }
} }
} }
@ -244,24 +229,19 @@
/// The PWM range. /// The PWM range.
/// </value> /// </value>
/// <exception cref="InvalidOperationException">When pin mode is not set to PWM output.</exception> /// <exception cref="InvalidOperationException">When pin mode is not set to PWM output.</exception>
public uint PwmRange public UInt32 PwmRange {
{ get => this.PinMode == GpioPinDriveMode.PwmOutput ? this._pwmRange : 0;
get => PinMode == GpioPinDriveMode.PwmOutput ? _pwmRange : 0;
set set {
{ lock(this._syncLock) {
lock (_syncLock) if(!this.HasCapability(PinCapability.PWM)) {
{ this._pwmRange = 1024;
if (!HasCapability(PinCapability.PWM))
{
_pwmRange = 1024;
throw new NotSupportedException( throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
$"Pin {BcmPinNumber} '{Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {Capabilities}");
} }
WiringPi.PwmSetRange(value); Native.WiringPi.PwmSetRange(value);
_pwmRange = value; this._pwmRange = value;
} }
} }
} }
@ -273,24 +253,19 @@
/// The PWM clock divisor. /// The PWM clock divisor.
/// </value> /// </value>
/// <exception cref="InvalidOperationException">When pin mode is not set to PWM output.</exception> /// <exception cref="InvalidOperationException">When pin mode is not set to PWM output.</exception>
public int PwmClockDivisor public Int32 PwmClockDivisor {
{ get => this.PinMode == GpioPinDriveMode.PwmOutput ? this._pwmClockDivisor : 0;
get => PinMode == GpioPinDriveMode.PwmOutput ? _pwmClockDivisor : 0;
set set {
{ lock(this._syncLock) {
lock (_syncLock) if(!this.HasCapability(PinCapability.PWM)) {
{ this._pwmClockDivisor = 1;
if (!HasCapability(PinCapability.PWM))
{
_pwmClockDivisor = 1;
throw new NotSupportedException( throw new NotSupportedException($"Pin {this.BcmPinNumber} '{this.Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {this.Capabilities}");
$"Pin {BcmPinNumber} '{Name}' does not support mode '{GpioPinDriveMode.PwmOutput}'. Pin capabilities are limited to: {Capabilities}");
} }
WiringPi.PwmSetClock(value); Native.WiringPi.PwmSetClock(value);
_pwmClockDivisor = value; this._pwmClockDivisor = value;
} }
} }
} }
@ -305,7 +280,7 @@
/// <value> /// <value>
/// <c>true</c> if this instance is in soft tone mode; otherwise, <c>false</c>. /// <c>true</c> if this instance is in soft tone mode; otherwise, <c>false</c>.
/// </value> /// </value>
public bool IsInSoftToneMode => _softToneFrequency >= 0; public Boolean IsInSoftToneMode => this._softToneFrequency >= 0;
/// <summary> /// <summary>
/// Gets or sets the soft tone frequency. 0 to 5000 Hz is typical. /// Gets or sets the soft tone frequency. 0 to 5000 Hz is typical.
@ -314,26 +289,20 @@
/// The soft tone frequency. /// The soft tone frequency.
/// </value> /// </value>
/// <exception cref="InvalidOperationException">When soft tones cannot be initialized on the pin.</exception> /// <exception cref="InvalidOperationException">When soft tones cannot be initialized on the pin.</exception>
public int SoftToneFrequency public Int32 SoftToneFrequency {
{ get => this._softToneFrequency;
get => _softToneFrequency;
set set {
{ lock(this._syncLock) {
lock (_syncLock) if(this.IsInSoftToneMode == false) {
{ Int32 setupResult = Native.WiringPi.SoftToneCreate(this.BcmPinNumber);
if (IsInSoftToneMode == false) if(setupResult != 0) {
{ throw new InvalidOperationException($"Unable to initialize soft tone on pin {this.BcmPinNumber}. Error Code: {setupResult}");
var setupResult = WiringPi.SoftToneCreate(BcmPinNumber);
if (setupResult != 0)
{
throw new InvalidOperationException(
$"Unable to initialize soft tone on pin {BcmPinNumber}. Error Code: {setupResult}");
} }
} }
WiringPi.SoftToneWrite(BcmPinNumber, value); Native.WiringPi.SoftToneWrite(this.BcmPinNumber, value);
_softToneFrequency = value; this._softToneFrequency = value;
} }
} }
} }
@ -348,7 +317,7 @@
/// <value> /// <value>
/// <c>true</c> if this instance is in soft PWM mode; otherwise, <c>false</c>. /// <c>true</c> if this instance is in soft PWM mode; otherwise, <c>false</c>.
/// </value> /// </value>
public bool IsInSoftPwmMode => _softPwmValue >= 0; public Boolean IsInSoftPwmMode => this._softPwmValue >= 0;
/// <summary> /// <summary>
/// Gets or sets the software PWM value on the pin. /// Gets or sets the software PWM value on the pin.
@ -357,21 +326,15 @@
/// The soft PWM value. /// The soft PWM value.
/// </value> /// </value>
/// <exception cref="InvalidOperationException">StartSoftPwm.</exception> /// <exception cref="InvalidOperationException">StartSoftPwm.</exception>
public int SoftPwmValue public Int32 SoftPwmValue {
{ get => this._softPwmValue;
get => _softPwmValue;
set set {
{ lock(this._syncLock) {
lock (_syncLock) if(this.IsInSoftPwmMode && value >= 0) {
{ Native.WiringPi.SoftPwmWrite(this.BcmPinNumber, value);
if (IsInSoftPwmMode && value >= 0) this._softPwmValue = value;
{ } else {
WiringPi.SoftPwmWrite(BcmPinNumber, value);
_softPwmValue = value;
}
else
{
throw new InvalidOperationException($"Software PWM requires a call to {nameof(StartSoftPwm)}."); throw new InvalidOperationException($"Software PWM requires a call to {nameof(StartSoftPwm)}.");
} }
} }
@ -381,7 +344,7 @@
/// <summary> /// <summary>
/// Gets the software PWM range used upon starting the PWM. /// Gets the software PWM range used upon starting the PWM.
/// </summary> /// </summary>
public int SoftPwmRange { get; private set; } = -1; public Int32 SoftPwmRange { get; private set; } = -1;
/// <summary> /// <summary>
/// Starts the software based PWM on this pin. /// Starts the software based PWM on this pin.
@ -391,27 +354,23 @@
/// <exception cref="NotSupportedException">When the pin does not suppoert PWM.</exception> /// <exception cref="NotSupportedException">When the pin does not suppoert PWM.</exception>
/// <exception cref="InvalidOperationException">StartSoftPwm /// <exception cref="InvalidOperationException">StartSoftPwm
/// or.</exception> /// or.</exception>
public void StartSoftPwm(int value, int range) public void StartSoftPwm(Int32 value, Int32 range) {
{ lock(this._syncLock) {
lock (_syncLock) if(!this.HasCapability(PinCapability.GP)) {
{ throw new NotSupportedException($"Pin {this.BcmPinNumber} does not support software PWM");
if (!HasCapability(PinCapability.GP))
throw new NotSupportedException($"Pin {BcmPinNumber} does not support software PWM");
if (IsInSoftPwmMode)
throw new InvalidOperationException($"{nameof(StartSoftPwm)} has already been called.");
var startResult = WiringPi.SoftPwmCreate(BcmPinNumber, value, range);
if (startResult == 0)
{
_softPwmValue = value;
SoftPwmRange = range;
} }
else
{ if(this.IsInSoftPwmMode) {
throw new InvalidOperationException( throw new InvalidOperationException($"{nameof(StartSoftPwm)} has already been called.");
$"Could not start software based PWM on pin {BcmPinNumber}. Error code: {startResult}"); }
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}");
} }
} }
} }
@ -421,18 +380,14 @@
#region Output Mode (Write) Members #region Output Mode (Write) Members
/// <inheritdoc /> /// <inheritdoc />
public void Write(GpioPinValue value) public void Write(GpioPinValue value) {
{ lock(this._syncLock) {
lock (_syncLock) if(this.PinMode != GpioPinDriveMode.Output) {
{ throw new InvalidOperationException($"Unable to write to pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
if (PinMode != GpioPinDriveMode.Output) + $" Writes are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Output}");
{
throw new InvalidOperationException(
$"Unable to write to pin {BcmPinNumber} because operating mode is {PinMode}."
+ $" Writes are only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Output}");
} }
WiringPi.DigitalWrite(BcmPinNumber, (int)value); Native.WiringPi.DigitalWrite(this.BcmPinNumber, (Int32)value);
} }
} }
@ -441,15 +396,14 @@
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task WriteAsync(GpioPinValue value) => Task.Run(() => { Write(value); }); public Task WriteAsync(GpioPinValue value) => Task.Run(() => { this.Write(value); });
/// <summary> /// <summary>
/// Writes the specified bit value. /// Writes the specified bit value.
/// This method performs a digital write. /// This method performs a digital write.
/// </summary> /// </summary>
/// <param name="value">if set to <c>true</c> [value].</param> /// <param name="value">if set to <c>true</c> [value].</param>
public void Write(bool value) public void Write(Boolean value) => this.Write(value ? GpioPinValue.High : GpioPinValue.Low);
=> Write(value ? GpioPinValue.High : GpioPinValue.Low);
/// <summary> /// <summary>
/// Writes the specified bit value. /// Writes the specified bit value.
@ -459,14 +413,14 @@
/// <returns> /// <returns>
/// The awaitable task. /// The awaitable task.
/// </returns> /// </returns>
public Task WriteAsync(bool value) => Task.Run(() => { Write(value); }); public Task WriteAsync(Boolean value) => Task.Run(() => { this.Write(value); });
/// <summary> /// <summary>
/// Writes the specified value. 0 for low, any other value for high /// Writes the specified value. 0 for low, any other value for high
/// This method performs a digital write. /// This method performs a digital write.
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
public void Write(int value) => Write(value != 0 ? GpioPinValue.High : GpioPinValue.Low); public void Write(Int32 value) => this.Write(value != 0 ? GpioPinValue.High : GpioPinValue.Low);
/// <summary> /// <summary>
/// Writes the specified value. 0 for low, any other value for high /// Writes the specified value. 0 for low, any other value for high
@ -474,25 +428,21 @@
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task WriteAsync(int value) => Task.Run(() => { Write(value); }); public Task WriteAsync(Int32 value) => Task.Run(() => { this.Write(value); });
/// <summary> /// <summary>
/// Writes the specified value as an analog level. /// 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. /// You will need to register additional analog modules to enable this function for devices such as the Gertboard.
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
public void WriteLevel(int value) public void WriteLevel(Int32 value) {
{ lock(this._syncLock) {
lock (_syncLock) if(this.PinMode != GpioPinDriveMode.Output) {
{ throw new InvalidOperationException($"Unable to write to pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
if (PinMode != GpioPinDriveMode.Output) + $" Writes are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Output}");
{
throw new InvalidOperationException(
$"Unable to write to pin {BcmPinNumber} because operating mode is {PinMode}."
+ $" Writes are only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Output}");
} }
WiringPi.AnalogWrite(BcmPinNumber, value); Native.WiringPi.AnalogWrite(this.BcmPinNumber, value);
} }
} }
@ -502,7 +452,7 @@
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task WriteLevelAsync(int value) => Task.Run(() => { WriteLevel(value); }); public Task WriteLevelAsync(Int32 value) => Task.Run(() => { this.WriteLevel(value); });
#endregion #endregion
@ -514,22 +464,19 @@
/// <param name="status">status to check.</param> /// <param name="status">status to check.</param>
/// <param name="timeOutMillisecond">timeout to reach status.</param> /// <param name="timeOutMillisecond">timeout to reach status.</param>
/// <returns>true/false.</returns> /// <returns>true/false.</returns>
public bool WaitForValue(GpioPinValue status, int timeOutMillisecond) public Boolean WaitForValue(GpioPinValue status, Int32 timeOutMillisecond) {
{ if(this.PinMode != GpioPinDriveMode.Input) {
if (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}");
throw new InvalidOperationException(
$"Unable to read from pin {BcmPinNumber} because operating mode is {PinMode}."
+ $" Reads are only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Input}");
} }
var hrt = new HighResolutionTimer(); HighResolutionTimer hrt = new HighResolutionTimer();
hrt.Start(); hrt.Start();
do do {
{ if(this.ReadValue() == status) {
if (ReadValue() == status)
return true; return true;
} }
}
while(hrt.ElapsedMilliseconds <= timeOutMillisecond); while(hrt.ElapsedMilliseconds <= timeOutMillisecond);
return false; return false;
@ -539,18 +486,14 @@
/// Reads the digital value on the pin as a boolean value. /// Reads the digital value on the pin as a boolean value.
/// </summary> /// </summary>
/// <returns>The state of the pin.</returns> /// <returns>The state of the pin.</returns>
public bool Read() public Boolean Read() {
{ lock(this._syncLock) {
lock (_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}."
if (PinMode != GpioPinDriveMode.Input && PinMode != GpioPinDriveMode.Output) + $" Reads are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input} or {GpioPinDriveMode.Output}");
{
throw new InvalidOperationException(
$"Unable to read from pin {BcmPinNumber} because operating mode is {PinMode}."
+ $" Reads are only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Input} or {GpioPinDriveMode.Output}");
} }
return WiringPi.DigitalRead(BcmPinNumber) != 0; return Native.WiringPi.DigitalRead(this.BcmPinNumber) != 0;
} }
} }
@ -558,20 +501,19 @@
/// Reads the digital value on the pin as a boolean value. /// Reads the digital value on the pin as a boolean value.
/// </summary> /// </summary>
/// <returns>The state of the pin.</returns> /// <returns>The state of the pin.</returns>
public Task<bool> ReadAsync() => Task.Run(Read); public Task<Boolean> ReadAsync() => Task.Run(this.Read);
/// <summary> /// <summary>
/// Reads the digital value on the pin as a High or Low value. /// Reads the digital value on the pin as a High or Low value.
/// </summary> /// </summary>
/// <returns>The state of the pin.</returns> /// <returns>The state of the pin.</returns>
public GpioPinValue ReadValue() public GpioPinValue ReadValue() => this.Read() ? GpioPinValue.High : GpioPinValue.Low;
=> Read() ? GpioPinValue.High : GpioPinValue.Low;
/// <summary> /// <summary>
/// Reads the digital value on the pin as a High or Low value. /// Reads the digital value on the pin as a High or Low value.
/// </summary> /// </summary>
/// <returns>The state of the pin.</returns> /// <returns>The state of the pin.</returns>
public Task<GpioPinValue> ReadValueAsync() => Task.Run(ReadValue); public Task<GpioPinValue> ReadValueAsync() => Task.Run(this.ReadValue);
/// <summary> /// <summary>
/// Reads the analog value on the pin. /// Reads the analog value on the pin.
@ -581,18 +523,14 @@
/// </summary> /// </summary>
/// <returns>The analog level.</returns> /// <returns>The analog level.</returns>
/// <exception cref="InvalidOperationException">When the pin mode is not configured as an input.</exception> /// <exception cref="InvalidOperationException">When the pin mode is not configured as an input.</exception>
public int ReadLevel() public Int32 ReadLevel() {
{ lock(this._syncLock) {
lock (_syncLock) if(this.PinMode != GpioPinDriveMode.Input) {
{ throw new InvalidOperationException($"Unable to read from pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
if (PinMode != GpioPinDriveMode.Input) + $" Reads are only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input}");
{
throw new InvalidOperationException(
$"Unable to read from pin {BcmPinNumber} because operating mode is {PinMode}."
+ $" Reads are only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Input}");
} }
return WiringPi.AnalogRead(BcmPinNumber); return Native.WiringPi.AnalogRead(this.BcmPinNumber);
} }
} }
@ -603,7 +541,7 @@
/// quick2Wire analog board, etc. /// quick2Wire analog board, etc.
/// </summary> /// </summary>
/// <returns>The analog level.</returns> /// <returns>The analog level.</returns>
public Task<int> ReadLevelAsync() => Task.Run(ReadLevel); public Task<Int32> ReadLevelAsync() => Task.Run(this.ReadLevel);
#endregion #endregion
@ -611,43 +549,34 @@
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentNullException">callback.</exception> /// <exception cref="ArgumentNullException">callback.</exception>
public void RegisterInterruptCallback(EdgeDetection edgeDetection, Action callback) public void RegisterInterruptCallback(EdgeDetection edgeDetection, Action callback) {
{ if(callback == null) {
if (callback == null)
throw new ArgumentNullException(nameof(callback)); throw new ArgumentNullException(nameof(callback));
if (PinMode != GpioPinDriveMode.Input)
{
throw new InvalidOperationException(
$"Unable to {nameof(RegisterInterruptCallback)} for pin {BcmPinNumber} because operating mode is {PinMode}."
+ $" Calling {nameof(RegisterInterruptCallback)} is only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Input}");
} }
lock (_syncLock) if(this.PinMode != GpioPinDriveMode.Input) {
{ throw new InvalidOperationException($"Unable to {nameof(RegisterInterruptCallback)} for pin {this.BcmPinNumber} because operating mode is {this.PinMode}."
var isrCallback = new InterruptServiceRoutineCallback(callback); + $" Calling {nameof(RegisterInterruptCallback)} is only allowed if {nameof(this.PinMode)} is set to {GpioPinDriveMode.Input}");
var registerResult = WiringPi.WiringPiISR(BcmPinNumber, GetWiringPiEdgeDetection(edgeDetection), isrCallback);
if (registerResult == 0)
{
InterruptEdgeDetection = edgeDetection;
InterruptCallback = isrCallback;
} }
else
{ 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)); HardwareException.Throw(nameof(GpioPin), nameof(RegisterInterruptCallback));
} }
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public void RegisterInterruptCallback(EdgeDetection edgeDetection, Action<int, int, uint> callback) => 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.");
throw new NotSupportedException("WiringPi does only support a simple interrupt callback that has no parameters.");
internal static WiringPiPin BcmToWiringPiPinNumber(BcmPin pin) => internal static WiringPiPin BcmToWiringPiPinNumber(BcmPin pin) => (WiringPiPin)GpioToWiringPi[(Int32)pin];
(WiringPiPin)GpioToWiringPi[(int)pin];
private static int GetWiringPiEdgeDetection(EdgeDetection edgeDetection) => private static Int32 GetWiringPiEdgeDetection(EdgeDetection edgeDetection) => GpioController.WiringPiEdgeDetectionMapping[edgeDetection];
GpioController.WiringPiEdgeDetectionMapping[edgeDetection];
#endregion #endregion
} }

View File

@ -1,56 +1,54 @@
namespace Unosquare.WiringPi using System;
{
using Native;
using RaspberryIO.Abstractions;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Unosquare.RaspberryIO.Abstractions;
namespace Unosquare.WiringPi {
/// <inheritdoc /> /// <inheritdoc />
/// <summary> /// <summary>
/// A simple wrapper for the I2c bus on the Raspberry Pi. /// A simple wrapper for the I2c bus on the Raspberry Pi.
/// </summary> /// </summary>
public class I2CBus : II2CBus public class I2CBus : II2CBus {
{
// TODO: It would be nice to integrate i2c device detection. // TODO: It would be nice to integrate i2c device detection.
private static readonly object SyncRoot = new object(); private static readonly Object SyncRoot = new Object();
private readonly Dictionary<int, II2CDevice> _devices = new Dictionary<int, II2CDevice>(); private readonly Dictionary<Int32, II2CDevice> _devices = new Dictionary<Int32, II2CDevice>();
/// <inheritdoc /> /// <inheritdoc />
public ReadOnlyCollection<II2CDevice> Devices public ReadOnlyCollection<II2CDevice> Devices {
{ get {
get lock(SyncRoot) {
{ return new ReadOnlyCollection<II2CDevice>(this._devices.Values.ToArray());
lock (SyncRoot) }
return new ReadOnlyCollection<II2CDevice>(_devices.Values.ToArray());
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public II2CDevice this[int deviceId] => GetDeviceById(deviceId); public II2CDevice this[Int32 deviceId] => this.GetDeviceById(deviceId);
/// <inheritdoc /> /// <inheritdoc />
public II2CDevice GetDeviceById(int deviceId) public II2CDevice GetDeviceById(Int32 deviceId) {
{ lock(SyncRoot) {
lock (SyncRoot) return this._devices[deviceId];
return _devices[deviceId]; }
} }
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="KeyNotFoundException">When the device file descriptor is not found.</exception> /// <exception cref="KeyNotFoundException">When the device file descriptor is not found.</exception>
public II2CDevice AddDevice(int deviceId) public II2CDevice AddDevice(Int32 deviceId) {
{ lock(SyncRoot) {
lock (SyncRoot) if(this._devices.ContainsKey(deviceId)) {
{ return this._devices[deviceId];
if (_devices.ContainsKey(deviceId)) }
return _devices[deviceId];
var fileDescriptor = SetupFileDescriptor(deviceId); Int32 fileDescriptor = SetupFileDescriptor(deviceId);
if (fileDescriptor < 0) if(fileDescriptor < 0) {
throw new KeyNotFoundException($"Device with id {deviceId} could not be registered with the I2C bus. Error Code: {fileDescriptor}."); throw new KeyNotFoundException($"Device with id {deviceId} could not be registered with the I2C bus. Error Code: {fileDescriptor}.");
}
var device = new I2CDevice(deviceId, fileDescriptor); I2CDevice device = new I2CDevice(deviceId, fileDescriptor);
_devices[deviceId] = device; this._devices[deviceId] = device;
return device; return device;
} }
} }
@ -63,10 +61,10 @@
/// </summary> /// </summary>
/// <param name="deviceId">The device identifier.</param> /// <param name="deviceId">The device identifier.</param>
/// <returns>The Linux file handle.</returns> /// <returns>The Linux file handle.</returns>
private static int SetupFileDescriptor(int deviceId) private static Int32 SetupFileDescriptor(Int32 deviceId) {
{ lock(SyncRoot) {
lock (SyncRoot) return Native.WiringPi.WiringPiI2CSetup(deviceId);
return WiringPi.WiringPiI2CSetup(deviceId); }
} }
} }
} }

View File

@ -1,43 +1,45 @@
namespace Unosquare.WiringPi using System;
{
using Native;
using RaspberryIO.Abstractions;
using RaspberryIO.Abstractions.Native;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Unosquare.RaspberryIO.Abstractions;
using Unosquare.RaspberryIO.Abstractions.Native;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Represents a device on the I2C Bus. /// Represents a device on the I2C Bus.
/// </summary> /// </summary>
public class I2CDevice : II2CDevice public class I2CDevice : II2CDevice {
{ private readonly Object _syncLock = new Object();
private readonly object _syncLock = new object();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="I2CDevice"/> class. /// Initializes a new instance of the <see cref="I2CDevice"/> class.
/// </summary> /// </summary>
/// <param name="deviceId">The device identifier.</param> /// <param name="deviceId">The device identifier.</param>
/// <param name="fileDescriptor">The file descriptor.</param> /// <param name="fileDescriptor">The file descriptor.</param>
internal I2CDevice(int deviceId, int fileDescriptor) internal I2CDevice(Int32 deviceId, Int32 fileDescriptor) {
{ this.DeviceId = deviceId;
DeviceId = deviceId; this.FileDescriptor = fileDescriptor;
FileDescriptor = fileDescriptor;
} }
/// <inheritdoc /> /// <inheritdoc />
public int DeviceId { get; } public Int32 DeviceId {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public int FileDescriptor { get; } public Int32 FileDescriptor {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public byte Read() public Byte Read() {
{ lock(this._syncLock) {
lock (_syncLock) Int32 result = Native.WiringPi.WiringPiI2CRead(this.FileDescriptor);
{ if(result < 0) {
var result = WiringPi.WiringPiI2CRead(FileDescriptor); HardwareException.Throw(nameof(I2CDevice), nameof(Read));
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Read)); }
return (byte)result;
return (Byte)result;
} }
} }
@ -45,23 +47,23 @@
/// Reads a byte from the specified file descriptor. /// Reads a byte from the specified file descriptor.
/// </summary> /// </summary>
/// <returns>The byte from device.</returns> /// <returns>The byte from device.</returns>
public Task<byte> ReadAsync() => Task.Run(Read); public Task<Byte> ReadAsync() => Task.Run(this.Read);
/// <summary> /// <summary>
/// Reads a buffer of the specified length, one byte at a time. /// Reads a buffer of the specified length, one byte at a time.
/// </summary> /// </summary>
/// <param name="length">The length.</param> /// <param name="length">The length.</param>
/// <returns>The byte array from device.</returns> /// <returns>The byte array from device.</returns>
public byte[] Read(int length) public Byte[] Read(Int32 length) {
{ lock(this._syncLock) {
lock (_syncLock) Byte[] buffer = new Byte[length];
{ for(Int32 i = 0; i < length; i++) {
var buffer = new byte[length]; Int32 result = Native.WiringPi.WiringPiI2CRead(this.FileDescriptor);
for (var i = 0; i < length; i++) if(result < 0) {
{ HardwareException.Throw(nameof(I2CDevice), nameof(Read));
var result = WiringPi.WiringPiI2CRead(FileDescriptor); }
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Read));
buffer[i] = (byte)result; buffer[i] = (Byte)result;
} }
return buffer; return buffer;
@ -73,18 +75,18 @@
/// </summary> /// </summary>
/// <param name="length">The length.</param> /// <param name="length">The length.</param>
/// <returns>The byte array from device.</returns> /// <returns>The byte array from device.</returns>
public Task<byte[]> ReadAsync(int length) => Task.Run(() => Read(length)); public Task<Byte[]> ReadAsync(Int32 length) => Task.Run(() => this.Read(length));
/// <summary> /// <summary>
/// Writes a byte of data the specified file descriptor. /// Writes a byte of data the specified file descriptor.
/// </summary> /// </summary>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
public void Write(byte data) public void Write(Byte data) {
{ lock(this._syncLock) {
lock (_syncLock) Int32 result = Native.WiringPi.WiringPiI2CWrite(this.FileDescriptor, data);
{ if(result < 0) {
var result = WiringPi.WiringPiI2CWrite(FileDescriptor, data); HardwareException.Throw(nameof(I2CDevice), nameof(Write));
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Write)); }
} }
} }
@ -93,20 +95,19 @@
/// </summary> /// </summary>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task WriteAsync(byte data) => Task.Run(() => { Write(data); }); public Task WriteAsync(Byte data) => Task.Run(() => this.Write(data));
/// <summary> /// <summary>
/// Writes a set of bytes to the specified file descriptor. /// Writes a set of bytes to the specified file descriptor.
/// </summary> /// </summary>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
public void Write(byte[] data) public void Write(Byte[] data) {
{ lock(this._syncLock) {
lock (_syncLock) foreach(Byte b in data) {
{ Int32 result = Native.WiringPi.WiringPiI2CWrite(this.FileDescriptor, b);
foreach (var b in data) if(result < 0) {
{ HardwareException.Throw(nameof(I2CDevice), nameof(Write));
var result = WiringPi.WiringPiI2CWrite(FileDescriptor, b); }
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Write));
} }
} }
} }
@ -116,19 +117,19 @@
/// </summary> /// </summary>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task WriteAsync(byte[] data) => Task.Run(() => { Write(data); }); public Task WriteAsync(Byte[] data) => Task.Run(() => this.Write(data));
/// <summary> /// <summary>
/// These write an 8 or 16-bit data value into the device register indicated. /// These write an 8 or 16-bit data value into the device register indicated.
/// </summary> /// </summary>
/// <param name="address">The register.</param> /// <param name="address">The register.</param>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
public void WriteAddressByte(int address, byte data) public void WriteAddressByte(Int32 address, Byte data) {
{ lock(this._syncLock) {
lock (_syncLock) Int32 result = Native.WiringPi.WiringPiI2CWriteReg8(this.FileDescriptor, address, data);
{ if(result < 0) {
var result = WiringPi.WiringPiI2CWriteReg8(FileDescriptor, address, data); HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressByte));
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressByte)); }
} }
} }
@ -137,12 +138,12 @@
/// </summary> /// </summary>
/// <param name="address">The register.</param> /// <param name="address">The register.</param>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
public void WriteAddressWord(int address, ushort data) public void WriteAddressWord(Int32 address, UInt16 data) {
{ lock(this._syncLock) {
lock (_syncLock) Int32 result = Native.WiringPi.WiringPiI2CWriteReg16(this.FileDescriptor, address, data);
{ if(result < 0) {
var result = WiringPi.WiringPiI2CWriteReg16(FileDescriptor, address, data); HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressWord));
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressWord)); }
} }
} }
@ -151,14 +152,14 @@
/// </summary> /// </summary>
/// <param name="address">The register.</param> /// <param name="address">The register.</param>
/// <returns>The address byte from device.</returns> /// <returns>The address byte from device.</returns>
public byte ReadAddressByte(int address) public Byte ReadAddressByte(Int32 address) {
{ lock(this._syncLock) {
lock (_syncLock) Int32 result = Native.WiringPi.WiringPiI2CReadReg8(this.FileDescriptor, address);
{ if(result < 0) {
var result = WiringPi.WiringPiI2CReadReg8(FileDescriptor, address); HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressByte));
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressByte)); }
return (byte)result; return (Byte)result;
} }
} }
@ -167,12 +168,12 @@
/// </summary> /// </summary>
/// <param name="address">The register.</param> /// <param name="address">The register.</param>
/// <returns>The address word from device.</returns> /// <returns>The address word from device.</returns>
public ushort ReadAddressWord(int address) public UInt16 ReadAddressWord(Int32 address) {
{ lock(this._syncLock) {
lock (_syncLock) Int32 result = Native.WiringPi.WiringPiI2CReadReg16(this.FileDescriptor, address);
{ if(result < 0) {
var result = WiringPi.WiringPiI2CReadReg16(FileDescriptor, address); HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressWord));
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressWord)); }
return Convert.ToUInt16(result); return Convert.ToUInt16(result);
} }

View File

@ -1,5 +1,4 @@
namespace Unosquare.WiringPi.Native namespace Unosquare.WiringPi.Native {
{
/// <summary> /// <summary>
/// A delegate defining a callback for an Interrupt Service Routine. /// A delegate defining a callback for an Interrupt Service Routine.
/// </summary> /// </summary>

View File

@ -1,19 +1,17 @@
namespace Unosquare.WiringPi.Native using System;
{
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
internal static class SysCall namespace Unosquare.WiringPi.Native {
{ internal static class SysCall {
internal const string LibCLibrary = "libc"; internal const String LibCLibrary = "libc";
[DllImport(LibCLibrary, EntryPoint = "chmod", SetLastError = true)] [DllImport(LibCLibrary, EntryPoint = "chmod", SetLastError = true)]
public static extern int Chmod(string filename, uint mode); public static extern Int32 Chmod(String filename, UInt32 mode);
[DllImport(LibCLibrary, EntryPoint = "strtol", SetLastError = true)] [DllImport(LibCLibrary, EntryPoint = "strtol", SetLastError = true)]
public static extern int StringToInteger(string numberString, IntPtr endPointer, int numberBase); public static extern Int32 StringToInteger(String numberString, IntPtr endPointer, Int32 numberBase);
[DllImport(LibCLibrary, EntryPoint = "write", SetLastError = true)] [DllImport(LibCLibrary, EntryPoint = "write", SetLastError = true)]
public static extern int Write(int fd, byte[] buffer, int count); public static extern Int32 Write(Int32 fd, Byte[] buffer, Int32 count);
} }
} }

View File

@ -1,16 +1,15 @@
namespace Unosquare.WiringPi.Native using System;
{
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
public partial class WiringPi namespace Unosquare.WiringPi.Native {
{ public partial class WiringPi {
/// <summary> /// <summary>
/// Simple device read. Some devices present data when you read them without having to do any register transactions. /// Simple device read. Some devices present data when you read them without having to do any register transactions.
/// </summary> /// </summary>
/// <param name="fd">The fd.</param> /// <param name="fd">The fd.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CRead", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CRead", SetLastError = true)]
public static extern int WiringPiI2CRead(int fd); public static extern Int32 WiringPiI2CRead(Int32 fd);
/// <summary> /// <summary>
/// These read an 8-bit value from the device register indicated. /// These read an 8-bit value from the device register indicated.
@ -19,7 +18,7 @@
/// <param name="reg">The reg.</param> /// <param name="reg">The reg.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CReadReg8", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CReadReg8", SetLastError = true)]
public static extern int WiringPiI2CReadReg8(int fd, int reg); public static extern Int32 WiringPiI2CReadReg8(Int32 fd, Int32 reg);
/// <summary> /// <summary>
/// These read a 16-bit value from the device register indicated. /// These read a 16-bit value from the device register indicated.
@ -28,7 +27,7 @@
/// <param name="reg">The reg.</param> /// <param name="reg">The reg.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CReadReg16", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CReadReg16", SetLastError = true)]
public static extern int WiringPiI2CReadReg16(int fd, int reg); public static extern Int32 WiringPiI2CReadReg16(Int32 fd, Int32 reg);
/// <summary> /// <summary>
/// Simple device write. Some devices accept data this way without needing to access any internal registers. /// Simple device write. Some devices accept data this way without needing to access any internal registers.
@ -37,7 +36,7 @@
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CWrite", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CWrite", SetLastError = true)]
public static extern int WiringPiI2CWrite(int fd, int data); public static extern Int32 WiringPiI2CWrite(Int32 fd, Int32 data);
/// <summary> /// <summary>
/// These write an 8-bit data value into the device register indicated. /// These write an 8-bit data value into the device register indicated.
@ -47,7 +46,7 @@
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CWriteReg8", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CWriteReg8", SetLastError = true)]
public static extern int WiringPiI2CWriteReg8(int fd, int reg, int data); public static extern Int32 WiringPiI2CWriteReg8(Int32 fd, Int32 reg, Int32 data);
/// <summary> /// <summary>
/// These write a 16-bit data value into the device register indicated. /// These write a 16-bit data value into the device register indicated.
@ -57,7 +56,7 @@
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CWriteReg16", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CWriteReg16", SetLastError = true)]
public static extern int WiringPiI2CWriteReg16(int fd, int reg, int data); public static extern Int32 WiringPiI2CWriteReg16(Int32 fd, Int32 reg, Int32 data);
/// <summary> /// <summary>
/// This initializes the I2C system with your given device identifier. /// This initializes the I2C system with your given device identifier.
@ -69,6 +68,6 @@
/// <param name="devId">The dev identifier.</param> /// <param name="devId">The dev identifier.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CSetup", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiI2CSetup", SetLastError = true)]
public static extern int WiringPiI2CSetup(int devId); public static extern Int32 WiringPiI2CSetup(Int32 devId);
} }
} }

View File

@ -1,9 +1,8 @@
namespace Unosquare.WiringPi.Native using System;
{
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
public partial class WiringPi namespace Unosquare.WiringPi.Native {
{ public partial class WiringPi {
/// <summary> /// <summary>
/// This opens and initialises the serial device and sets the baud rate. It sets the port into “raw” mode (character at a time and no translations), /// This opens and initialises the serial device and sets the baud rate. It sets the port into “raw” mode (character at a time and no translations),
/// and sets the read timeout to 10 seconds. The return value is the file descriptor or -1 for any error, in which case errno will be set as appropriate. /// and sets the read timeout to 10 seconds. The return value is the file descriptor or -1 for any error, in which case errno will be set as appropriate.
@ -15,7 +14,7 @@
/// <param name="baud">The baud.</param> /// <param name="baud">The baud.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "serialOpen", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "serialOpen", SetLastError = true)]
public static extern int SerialOpen(string device, int baud); public static extern Int32 SerialOpen(String device, Int32 baud);
/// <summary> /// <summary>
/// Closes the device identified by the file descriptor given. /// Closes the device identified by the file descriptor given.
@ -23,7 +22,7 @@
/// <param name="fd">The fd.</param> /// <param name="fd">The fd.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "serialClose", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "serialClose", SetLastError = true)]
public static extern int SerialClose(int fd); public static extern Int32 SerialClose(Int32 fd);
/// <summary> /// <summary>
/// Sends the single byte to the serial device identified by the given file descriptor. /// Sends the single byte to the serial device identified by the given file descriptor.
@ -31,7 +30,7 @@
/// <param name="fd">The fd.</param> /// <param name="fd">The fd.</param>
/// <param name="c">The c.</param> /// <param name="c">The c.</param>
[DllImport(WiringPiLibrary, EntryPoint = "serialPutchar", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "serialPutchar", SetLastError = true)]
public static extern void SerialPutchar(int fd, byte c); public static extern void SerialPutchar(Int32 fd, Byte c);
/// <summary> /// <summary>
/// Sends the nul-terminated string to the serial device identified by the given file descriptor. /// Sends the nul-terminated string to the serial device identified by the given file descriptor.
@ -39,7 +38,7 @@
/// <param name="fd">The fd.</param> /// <param name="fd">The fd.</param>
/// <param name="s">The s.</param> /// <param name="s">The s.</param>
[DllImport(WiringPiLibrary, EntryPoint = "serialPuts", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "serialPuts", SetLastError = true)]
public static extern void SerialPuts(int fd, string s); public static extern void SerialPuts(Int32 fd, String s);
/// <summary> /// <summary>
/// Returns the number of characters available for reading, or -1 for any error condition, /// Returns the number of characters available for reading, or -1 for any error condition,
@ -48,7 +47,7 @@
/// <param name="fd">The fd.</param> /// <param name="fd">The fd.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "serialDataAvail", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "serialDataAvail", SetLastError = true)]
public static extern int SerialDataAvail(int fd); public static extern Int32 SerialDataAvail(Int32 fd);
/// <summary> /// <summary>
/// Returns the next character available on the serial device. /// Returns the next character available on the serial device.
@ -57,13 +56,13 @@
/// <param name="fd">The fd.</param> /// <param name="fd">The fd.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "serialGetchar", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "serialGetchar", SetLastError = true)]
public static extern int SerialGetchar(int fd); public static extern Int32 SerialGetchar(Int32 fd);
/// <summary> /// <summary>
/// This discards all data received, or waiting to be send down the given device. /// This discards all data received, or waiting to be send down the given device.
/// </summary> /// </summary>
/// <param name="fd">The fd.</param> /// <param name="fd">The fd.</param>
[DllImport(WiringPiLibrary, EntryPoint = "serialFlush", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "serialFlush", SetLastError = true)]
public static extern void SerialFlush(int fd); public static extern void SerialFlush(Int32 fd);
} }
} }

View File

@ -1,9 +1,8 @@
namespace Unosquare.WiringPi.Native using System;
{
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
public partial class WiringPi namespace Unosquare.WiringPi.Native {
{ public partial class WiringPi {
#region WiringPi - Shift Library #region WiringPi - Shift Library
/// <summary> /// <summary>
@ -16,7 +15,7 @@
/// <param name="order">The order.</param> /// <param name="order">The order.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "shiftIn", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "shiftIn", SetLastError = true)]
public static extern byte ShiftIn(byte dPin, byte cPin, byte order); public static extern Byte ShiftIn(Byte dPin, Byte cPin, Byte order);
/// <summary> /// <summary>
/// The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin. /// The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin.
@ -28,7 +27,7 @@
/// <param name="order">The order.</param> /// <param name="order">The order.</param>
/// <param name="val">The value.</param> /// <param name="val">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "shiftOut", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "shiftOut", SetLastError = true)]
public static extern void ShiftOut(byte dPin, byte cPin, byte order, byte val); public static extern void ShiftOut(Byte dPin, Byte cPin, Byte order, Byte val);
#endregion #endregion

View File

@ -1,9 +1,8 @@
namespace Unosquare.WiringPi.Native using System;
{
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
public partial class WiringPi namespace Unosquare.WiringPi.Native {
{ public partial class WiringPi {
#region WiringPi - Soft PWM (https://github.com/WiringPi/WiringPi/blob/master/wiringPi/softPwm.h) #region WiringPi - Soft PWM (https://github.com/WiringPi/WiringPi/blob/master/wiringPi/softPwm.h)
/// <summary> /// <summary>
@ -16,7 +15,7 @@
/// <param name="pwmRange">The PWM range.</param> /// <param name="pwmRange">The PWM range.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "softPwmCreate", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "softPwmCreate", SetLastError = true)]
public static extern int SoftPwmCreate(int pin, int initialValue, int pwmRange); public static extern Int32 SoftPwmCreate(Int32 pin, Int32 initialValue, Int32 pwmRange);
/// <summary> /// <summary>
/// This updates the PWM value on the given pin. The value is checked to be in-range and pins that havent previously /// This updates the PWM value on the given pin. The value is checked to be in-range and pins that havent previously
@ -25,14 +24,14 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "softPwmWrite", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "softPwmWrite", SetLastError = true)]
public static extern void SoftPwmWrite(int pin, int value); public static extern void SoftPwmWrite(Int32 pin, Int32 value);
/// <summary> /// <summary>
/// This function is undocumented. /// This function is undocumented.
/// </summary> /// </summary>
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
[DllImport(WiringPiLibrary, EntryPoint = "softPwmStop", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "softPwmStop", SetLastError = true)]
public static extern void SoftPwmStop(int pin); public static extern void SoftPwmStop(Int32 pin);
/// <summary> /// <summary>
/// This creates a software controlled tone pin. You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. /// This creates a software controlled tone pin. You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used.
@ -41,14 +40,14 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "softToneCreate", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "softToneCreate", SetLastError = true)]
public static extern int SoftToneCreate(int pin); public static extern Int32 SoftToneCreate(Int32 pin);
/// <summary> /// <summary>
/// This function is undocumented. /// This function is undocumented.
/// </summary> /// </summary>
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
[DllImport(WiringPiLibrary, EntryPoint = "softToneStop", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "softToneStop", SetLastError = true)]
public static extern void SoftToneStop(int pin); public static extern void SoftToneStop(Int32 pin);
/// <summary> /// <summary>
/// This updates the tone frequency value on the given pin. The tone will be played until you set the frequency to 0. /// This updates the tone frequency value on the given pin. The tone will be played until you set the frequency to 0.
@ -56,7 +55,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="freq">The freq.</param> /// <param name="freq">The freq.</param>
[DllImport(WiringPiLibrary, EntryPoint = "softToneWrite", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "softToneWrite", SetLastError = true)]
public static extern void SoftToneWrite(int pin, int freq); public static extern void SoftToneWrite(Int32 pin, Int32 freq);
#endregion #endregion

View File

@ -1,9 +1,8 @@
namespace Unosquare.WiringPi.Native using System;
{
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
public partial class WiringPi namespace Unosquare.WiringPi.Native {
{ public partial class WiringPi {
#region WiringPi - SPI Library Calls #region WiringPi - SPI Library Calls
/// <summary> /// <summary>
@ -12,7 +11,7 @@
/// <param name="channel">The channel.</param> /// <param name="channel">The channel.</param>
/// <returns>Unknown.</returns> /// <returns>Unknown.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPIGetFd", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPIGetFd", SetLastError = true)]
public static extern int WiringPiSPIGetFd(int channel); public static extern Int32 WiringPiSPIGetFd(Int32 channel);
/// <summary> /// <summary>
/// This performs a simultaneous write/read transaction over the selected SPI bus. Data that was in your buffer is overwritten by data returned from the SPI bus. /// This performs a simultaneous write/read transaction over the selected SPI bus. Data that was in your buffer is overwritten by data returned from the SPI bus.
@ -25,7 +24,7 @@
/// <param name="len">The length.</param> /// <param name="len">The length.</param>
/// <returns>The result.</returns> /// <returns>The result.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPIDataRW", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPIDataRW", SetLastError = true)]
public static extern int WiringPiSPIDataRW(int channel, byte[] data, int len); public static extern Int32 WiringPiSPIDataRW(Int32 channel, Byte[] data, Int32 len);
/// <summary> /// <summary>
/// This function is undocumented. /// This function is undocumented.
@ -35,7 +34,7 @@
/// <param name="mode">The mode.</param> /// <param name="mode">The mode.</param>
/// <returns>Unkown.</returns> /// <returns>Unkown.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPISetupMode", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPISetupMode", SetLastError = true)]
public static extern int WiringPiSPISetupMode(int channel, int speed, int mode); public static extern Int32 WiringPiSPISetupMode(Int32 channel, Int32 speed, Int32 mode);
/// <summary> /// <summary>
/// This is the way to initialize a channel (The Pi has 2 channels; 0 and 1). The speed parameter is an integer /// This is the way to initialize a channel (The Pi has 2 channels; 0 and 1). The speed parameter is an integer
@ -46,7 +45,7 @@
/// <param name="speed">The speed.</param> /// <param name="speed">The speed.</param>
/// <returns>The Linux file descriptor for the device or -1 for error.</returns> /// <returns>The Linux file descriptor for the device or -1 for error.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPISetup", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSPISetup", SetLastError = true)]
public static extern int WiringPiSPISetup(int channel, int speed); public static extern Int32 WiringPiSPISetup(Int32 channel, Int32 speed);
#endregion #endregion
} }

View File

@ -1,15 +1,14 @@
namespace Unosquare.WiringPi.Native using System.Runtime.InteropServices;
{ using System;
using System.Runtime.InteropServices;
namespace Unosquare.WiringPi.Native {
/// <summary> /// <summary>
/// Provides native C WiringPi Library function call wrappers /// Provides native C WiringPi Library function call wrappers
/// All credit for the native library goes to the author of http://wiringpi.com/ /// All credit for the native library goes to the author of http://wiringpi.com/
/// The wrappers were written based on https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.h. /// The wrappers were written based on https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.h.
/// </summary> /// </summary>
public partial class WiringPi public partial class WiringPi {
{ internal const String WiringPiLibrary = "libwiringPi.so.2.50";
internal const string WiringPiLibrary = "libwiringPi.so.2.50";
#region WiringPi - Core Functions (https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.h) #region WiringPi - Core Functions (https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.h)
@ -21,7 +20,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetup", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetup", SetLastError = true)]
public static extern int WiringPiSetup(); public static extern Int32 WiringPiSetup();
/// <summary> /// <summary>
/// This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. /// This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly.
@ -36,7 +35,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupSys", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupSys", SetLastError = true)]
public static extern int WiringPiSetupSys(); public static extern Int32 WiringPiSetupSys();
/// <summary> /// <summary>
/// This is identical to wiringPiSetup, however it allows the calling programs to use the Broadcom GPIO /// This is identical to wiringPiSetup, however it allows the calling programs to use the Broadcom GPIO
@ -46,7 +45,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupGpio", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupGpio", SetLastError = true)]
public static extern int WiringPiSetupGpio(); public static extern Int32 WiringPiSetupGpio();
/// <summary> /// <summary>
/// Identical to wiringPiSetup, however it allows the calling programs to use the physical pin numbers on the P1 connector only. /// Identical to wiringPiSetup, however it allows the calling programs to use the physical pin numbers on the P1 connector only.
@ -54,7 +53,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupPhys", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupPhys", SetLastError = true)]
public static extern int WiringPiSetupPhys(); public static extern Int32 WiringPiSetupPhys();
/// <summary> /// <summary>
/// This function is undocumented. /// This function is undocumented.
@ -62,7 +61,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="mode">The mode.</param> /// <param name="mode">The mode.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pinModeAlt", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pinModeAlt", SetLastError = true)]
public static extern void PinModeAlt(int pin, int mode); public static extern void PinModeAlt(Int32 pin, Int32 mode);
/// <summary> /// <summary>
/// This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. /// This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK.
@ -75,7 +74,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="mode">The mode.</param> /// <param name="mode">The mode.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pinMode", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pinMode", SetLastError = true)]
public static extern void PinMode(int pin, int mode); public static extern void PinMode(Int32 pin, Int32 mode);
/// <summary> /// <summary>
/// This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. /// This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input.
@ -89,7 +88,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="pud">The pud.</param> /// <param name="pud">The pud.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pullUpDnControl", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pullUpDnControl", SetLastError = true)]
public static extern void PullUpDnControl(int pin, int pud); public static extern void PullUpDnControl(Int32 pin, Int32 pud);
/// <summary> /// <summary>
/// This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) depending on the logic level at the pin. /// This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) depending on the logic level at the pin.
@ -97,7 +96,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "digitalRead", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "digitalRead", SetLastError = true)]
public static extern int DigitalRead(int pin); public static extern Int32 DigitalRead(Int32 pin);
/// <summary> /// <summary>
/// Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output. /// Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output.
@ -106,7 +105,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "digitalWrite", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "digitalWrite", SetLastError = true)]
public static extern void DigitalWrite(int pin, int value); public static extern void DigitalWrite(Int32 pin, Int32 value);
/// <summary> /// <summary>
/// Writes the value to the PWM register for the given pin. The Raspberry Pi has one /// Writes the value to the PWM register for the given pin. The Raspberry Pi has one
@ -117,7 +116,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmWrite", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pwmWrite", SetLastError = true)]
public static extern void PwmWrite(int pin, int value); public static extern void PwmWrite(Int32 pin, Int32 value);
/// <summary> /// <summary>
/// This returns the value read on the supplied analog input pin. You will need to /// This returns the value read on the supplied analog input pin. You will need to
@ -126,7 +125,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "analogRead", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "analogRead", SetLastError = true)]
public static extern int AnalogRead(int pin); public static extern Int32 AnalogRead(Int32 pin);
/// <summary> /// <summary>
/// This writes the given value to the supplied analog pin. You will need to register additional /// This writes the given value to the supplied analog pin. You will need to register additional
@ -135,7 +134,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "analogWrite", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "analogWrite", SetLastError = true)]
public static extern void AnalogWrite(int pin, int value); public static extern void AnalogWrite(Int32 pin, Int32 value);
/// <summary> /// <summary>
/// This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and /// This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and
@ -143,7 +142,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piBoardRev", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "piBoardRev", SetLastError = true)]
public static extern int PiBoardRev(); public static extern Int32 PiBoardRev();
/// <summary> /// <summary>
/// This function is undocumented. /// This function is undocumented.
@ -154,7 +153,7 @@
/// <param name="overVolted">The over volted.</param> /// <param name="overVolted">The over volted.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piBoardId", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "piBoardId", SetLastError = true)]
public static extern int PiBoardId(ref int model, ref int mem, ref int maker, ref int overVolted); public static extern Int32 PiBoardId(ref Int32 model, ref Int32 mem, ref Int32 maker, ref Int32 overVolted);
/// <summary> /// <summary>
/// This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account. /// This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account.
@ -162,7 +161,7 @@
/// <param name="wPiPin">The w pi pin.</param> /// <param name="wPiPin">The w pi pin.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wpiPinToGpio", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wpiPinToGpio", SetLastError = true)]
public static extern int WpiPinToGpio(int wPiPin); public static extern Int32 WpiPinToGpio(Int32 wPiPin);
/// <summary> /// <summary>
/// This returns the BCM_GPIO pin number of the supplied physical pin on the P1 connector. /// This returns the BCM_GPIO pin number of the supplied physical pin on the P1 connector.
@ -170,7 +169,7 @@
/// <param name="physPin">The physical pin.</param> /// <param name="physPin">The physical pin.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "physPinToGpio", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "physPinToGpio", SetLastError = true)]
public static extern int PhysPinToGpio(int physPin); public static extern Int32 PhysPinToGpio(Int32 physPin);
/// <summary> /// <summary>
/// This sets the “strength” of the pad drivers for a particular group of pins. /// This sets the “strength” of the pad drivers for a particular group of pins.
@ -180,7 +179,7 @@
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "setPadDrive", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "setPadDrive", SetLastError = true)]
public static extern int SetPadDrive(int group, int value); public static extern Int32 SetPadDrive(Int32 group, Int32 value);
/// <summary> /// <summary>
/// Undocumented function. /// Undocumented function.
@ -188,7 +187,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "getAlt", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "getAlt", SetLastError = true)]
public static extern int GetAlt(int pin); public static extern Int32 GetAlt(Int32 pin);
/// <summary> /// <summary>
/// Undocumented function. /// Undocumented function.
@ -197,7 +196,7 @@
/// <param name="freq">The freq.</param> /// <param name="freq">The freq.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "pwmToneWrite", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pwmToneWrite", SetLastError = true)]
public static extern int PwmToneWrite(int pin, int freq); public static extern Int32 PwmToneWrite(Int32 pin, Int32 freq);
/// <summary> /// <summary>
/// This writes the 8-bit byte supplied to the first 8 GPIO pins. /// This writes the 8-bit byte supplied to the first 8 GPIO pins.
@ -205,7 +204,7 @@
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "digitalWriteByte", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "digitalWriteByte", SetLastError = true)]
public static extern void DigitalWriteByte(int value); public static extern void DigitalWriteByte(Int32 value);
/// <summary> /// <summary>
/// This writes the 8-bit byte supplied to the first 8 GPIO pins. /// This writes the 8-bit byte supplied to the first 8 GPIO pins.
@ -213,7 +212,7 @@
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "digitalWriteByte2", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "digitalWriteByte2", SetLastError = true)]
public static extern void DigitalWriteByte2(int value); public static extern void DigitalWriteByte2(Int32 value);
/// <summary> /// <summary>
/// Undocumented function /// Undocumented function
@ -222,7 +221,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "digitalReadByte", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "digitalReadByte", SetLastError = true)]
public static extern uint DigitalReadByte(); public static extern UInt32 DigitalReadByte();
/// <summary> /// <summary>
/// Undocumented function /// Undocumented function
@ -231,7 +230,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "digitalReadByte2", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "digitalReadByte2", SetLastError = true)]
public static extern uint DigitalReadByte2(); public static extern UInt32 DigitalReadByte2();
/// <summary> /// <summary>
/// The PWM generator can run in 2 modes “balanced” and “mark:space”. The mark:space mode is traditional, /// The PWM generator can run in 2 modes “balanced” and “mark:space”. The mark:space mode is traditional,
@ -239,14 +238,14 @@
/// </summary> /// </summary>
/// <param name="mode">The mode.</param> /// <param name="mode">The mode.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmSetMode", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pwmSetMode", SetLastError = true)]
public static extern void PwmSetMode(int mode); public static extern void PwmSetMode(Int32 mode);
/// <summary> /// <summary>
/// This sets the range register in the PWM generator. The default is 1024. /// This sets the range register in the PWM generator. The default is 1024.
/// </summary> /// </summary>
/// <param name="range">The range.</param> /// <param name="range">The range.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmSetRange", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pwmSetRange", SetLastError = true)]
public static extern void PwmSetRange(uint range); public static extern void PwmSetRange(UInt32 range);
/// <summary> /// <summary>
/// This sets the divisor for the PWM clock. /// This sets the divisor for the PWM clock.
@ -255,7 +254,7 @@
/// </summary> /// </summary>
/// <param name="divisor">The divisor.</param> /// <param name="divisor">The divisor.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmSetClock", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "pwmSetClock", SetLastError = true)]
public static extern void PwmSetClock(int divisor); public static extern void PwmSetClock(Int32 divisor);
/// <summary> /// <summary>
/// Undocumented function. /// Undocumented function.
@ -263,7 +262,7 @@
/// <param name="pin">The pin.</param> /// <param name="pin">The pin.</param>
/// <param name="freq">The freq.</param> /// <param name="freq">The freq.</param>
[DllImport(WiringPiLibrary, EntryPoint = "gpioClockSet", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "gpioClockSet", SetLastError = true)]
public static extern void GpioClockSet(int pin, int freq); public static extern void GpioClockSet(Int32 pin, Int32 freq);
/// <summary> /// <summary>
/// This function registers a function to received interrupts on the specified pin. /// This function registers a function to received interrupts on the specified pin.
@ -284,7 +283,7 @@
/// <param name="method">The method.</param> /// <param name="method">The method.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiISR", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "wiringPiISR", SetLastError = true)]
public static extern int WiringPiISR(int pin, int mode, InterruptServiceRoutineCallback method); public static extern Int32 WiringPiISR(Int32 pin, Int32 mode, InterruptServiceRoutineCallback method);
/// <summary> /// <summary>
/// This function creates a thread which is another function in your program previously declared using the PI_THREAD declaration. /// This function creates a thread which is another function in your program previously declared using the PI_THREAD declaration.
@ -295,7 +294,7 @@
/// <param name="method">The method.</param> /// <param name="method">The method.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piThreadCreate", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "piThreadCreate", SetLastError = true)]
public static extern int PiThreadCreate(ThreadWorker method); public static extern Int32 PiThreadCreate(ThreadWorker method);
/// <summary> /// <summary>
/// These allow you to synchronise variable updates from your main program to any threads running in your program. keyNum is a number from 0 to 3 and represents a key. /// These allow you to synchronise variable updates from your main program to any threads running in your program. keyNum is a number from 0 to 3 and represents a key.
@ -306,7 +305,7 @@
/// </summary> /// </summary>
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
[DllImport(WiringPiLibrary, EntryPoint = "piLock", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "piLock", SetLastError = true)]
public static extern void PiLock(int key); public static extern void PiLock(Int32 key);
/// <summary> /// <summary>
/// These allow you to synchronise variable updates from your main program to any threads running in your program. keyNum is a number from 0 to 3 and represents a key. /// These allow you to synchronise variable updates from your main program to any threads running in your program. keyNum is a number from 0 to 3 and represents a key.
@ -317,7 +316,7 @@
/// </summary> /// </summary>
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
[DllImport(WiringPiLibrary, EntryPoint = "piUnlock", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "piUnlock", SetLastError = true)]
public static extern void PiUnlock(int key); public static extern void PiUnlock(Int32 key);
/// <summary> /// <summary>
/// This attempts to shift your program (or thread in a multi-threaded program) to a higher priority /// This attempts to shift your program (or thread in a multi-threaded program) to a higher priority
@ -332,7 +331,7 @@
/// <param name="priority">The priority.</param> /// <param name="priority">The priority.</param>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piHiPri", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "piHiPri", SetLastError = true)]
public static extern int PiHiPri(int priority); public static extern Int32 PiHiPri(Int32 priority);
/// <summary> /// <summary>
/// This causes program execution to pause for at least howLong milliseconds. /// This causes program execution to pause for at least howLong milliseconds.
@ -341,7 +340,7 @@
/// </summary> /// </summary>
/// <param name="howLong">The how long.</param> /// <param name="howLong">The how long.</param>
[DllImport(WiringPiLibrary, EntryPoint = "delay", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "delay", SetLastError = true)]
public static extern void Delay(uint howLong); public static extern void Delay(UInt32 howLong);
/// <summary> /// <summary>
/// This causes program execution to pause for at least howLong microseconds. /// This causes program execution to pause for at least howLong microseconds.
@ -353,7 +352,7 @@
/// </summary> /// </summary>
/// <param name="howLong">The how long.</param> /// <param name="howLong">The how long.</param>
[DllImport(WiringPiLibrary, EntryPoint = "delayMicroseconds", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "delayMicroseconds", SetLastError = true)]
public static extern void DelayMicroseconds(uint howLong); public static extern void DelayMicroseconds(UInt32 howLong);
/// <summary> /// <summary>
/// This returns a number representing the number of milliseconds since your program called one of the wiringPiSetup functions. /// This returns a number representing the number of milliseconds since your program called one of the wiringPiSetup functions.
@ -361,7 +360,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "millis", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "millis", SetLastError = true)]
public static extern uint Millis(); public static extern UInt32 Millis();
/// <summary> /// <summary>
/// This returns a number representing the number of microseconds since your program called one of /// This returns a number representing the number of microseconds since your program called one of
@ -369,7 +368,7 @@
/// </summary> /// </summary>
/// <returns>The result code.</returns> /// <returns>The result code.</returns>
[DllImport(WiringPiLibrary, EntryPoint = "micros", SetLastError = true)] [DllImport(WiringPiLibrary, EntryPoint = "micros", SetLastError = true)]
public static extern uint Micros(); public static extern UInt32 Micros();
#endregion #endregion
} }

View File

@ -1,24 +1,19 @@
namespace Unosquare.WiringPi.Resources using System;
{
using Native;
using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using Unosquare.WiringPi.Native;
namespace Unosquare.WiringPi.Resources {
/// <summary> /// <summary>
/// Provides access to embedded assembly files. /// Provides access to embedded assembly files.
/// </summary> /// </summary>
internal static class EmbeddedResources internal static class EmbeddedResources {
{
/// <summary> /// <summary>
/// Initializes static members of the <see cref="EmbeddedResources"/> class. /// Initializes static members of the <see cref="EmbeddedResources"/> class.
/// </summary> /// </summary>
static EmbeddedResources() static EmbeddedResources() => ResourceNames = new ReadOnlyCollection<String>(typeof(EmbeddedResources).Assembly.GetManifestResourceNames());
{
ResourceNames =
new ReadOnlyCollection<string>(typeof(EmbeddedResources).Assembly.GetManifestResourceNames());
}
/// <summary> /// <summary>
/// Gets the resource names. /// Gets the resource names.
@ -26,36 +21,32 @@
/// <value> /// <value>
/// The resource names. /// The resource names.
/// </value> /// </value>
public static ReadOnlyCollection<string> ResourceNames { get; } public static ReadOnlyCollection<String> ResourceNames {
get;
}
/// <summary> /// <summary>
/// Extracts all the file resources to the specified base path. /// Extracts all the file resources to the specified base path.
/// </summary> /// </summary>
public static void ExtractAll() public static void ExtractAll() {
{ String basePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var basePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); Int32 executablePermissions = SysCall.StringToInteger("0777", IntPtr.Zero, 8);
var executablePermissions = SysCall.StringToInteger("0777", IntPtr.Zero, 8);
foreach (var resourceName in ResourceNames) foreach(String resourceName in ResourceNames) {
{ String filename = resourceName.Substring($"{typeof(EmbeddedResources).Namespace}.".Length);
var filename = resourceName.Substring($"{typeof(EmbeddedResources).Namespace}.".Length); String targetPath = Path.Combine(basePath, filename);
var targetPath = Path.Combine(basePath, filename); if(File.Exists(targetPath)) {
if (File.Exists(targetPath)) return; return;
}
using (var stream = typeof(EmbeddedResources).Assembly using(Stream stream = typeof(EmbeddedResources).Assembly.GetManifestResourceStream(resourceName)) {
.GetManifestResourceStream(resourceName)) using(FileStream outputStream = File.OpenWrite(targetPath)) {
{
using (var outputStream = File.OpenWrite(targetPath))
{
stream?.CopyTo(outputStream); stream?.CopyTo(outputStream);
} }
try try {
{ _ = SysCall.Chmod(targetPath, (UInt32)executablePermissions);
SysCall.Chmod(targetPath, (uint)executablePermissions); } catch {
}
catch
{
/* Ignore */ /* Ignore */
} }
} }

View File

@ -1,42 +1,44 @@
namespace Unosquare.WiringPi using System;
{
using RaspberryIO.Abstractions;
using Unosquare.RaspberryIO.Abstractions;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// The SPI Bus containing the 2 SPI channels. /// The SPI Bus containing the 2 SPI channels.
/// </summary> /// </summary>
public class SpiBus : ISpiBus public class SpiBus : ISpiBus {
{
/// <inheritdoc /> /// <inheritdoc />
public int Channel0Frequency { get; set; } public Int32 Channel0Frequency {
get; set;
}
/// <inheritdoc /> /// <inheritdoc />
public int Channel1Frequency { get; set; } public Int32 Channel1Frequency {
get; set;
}
/// <inheritdoc /> /// <inheritdoc />
public int DefaultFrequency => 8000000; public Int32 DefaultFrequency => 8000000;
/// <inheritdoc /> /// <inheritdoc />
public ISpiChannel Channel0 public ISpiChannel Channel0 {
{ get {
get if(this.Channel0Frequency == 0) {
{ this.Channel0Frequency = this.DefaultFrequency;
if (Channel0Frequency == 0) }
Channel0Frequency = DefaultFrequency;
return SpiChannel.Retrieve(SpiChannelNumber.Channel0, Channel0Frequency); return SpiChannel.Retrieve(SpiChannelNumber.Channel0, this.Channel0Frequency);
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public ISpiChannel Channel1 public ISpiChannel Channel1 {
{ get {
get if(this.Channel1Frequency == 0) {
{ this.Channel1Frequency = this.DefaultFrequency;
if (Channel1Frequency == 0) }
Channel1Frequency = DefaultFrequency;
return SpiChannel.Retrieve(SpiChannelNumber.Channel1, Channel1Frequency); return SpiChannel.Retrieve(SpiChannelNumber.Channel1, this.Channel1Frequency);
} }
} }
} }

View File

@ -1,76 +1,79 @@
namespace Unosquare.WiringPi using System;
{
using Native;
using RaspberryIO.Abstractions;
using RaspberryIO.Abstractions.Native;
using Swan;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Swan;
using Unosquare.RaspberryIO.Abstractions;
using Unosquare.RaspberryIO.Abstractions.Native;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Provides access to using the SPI buses on the GPIO. /// Provides access to using the SPI buses on the GPIO.
/// SPI is a bus that works like a ring shift register /// SPI is a bus that works like a ring shift register
/// The number of bytes pushed is equal to the number of bytes received. /// The number of bytes pushed is equal to the number of bytes received.
/// </summary> /// </summary>
public sealed class SpiChannel : ISpiChannel public sealed class SpiChannel : ISpiChannel {
{
/// <summary> /// <summary>
/// The minimum frequency of a SPI Channel. /// The minimum frequency of a SPI Channel.
/// </summary> /// </summary>
public const int MinFrequency = 500000; public const Int32 MinFrequency = 500000;
/// <summary> /// <summary>
/// The maximum frequency of a SPI channel. /// The maximum frequency of a SPI channel.
/// </summary> /// </summary>
public const int MaxFrequency = 32000000; public const Int32 MaxFrequency = 32000000;
private static readonly object SyncRoot = new object(); private static readonly Object SyncRoot = new Object();
private static readonly Dictionary<SpiChannelNumber, SpiChannel> Buses = new Dictionary<SpiChannelNumber, SpiChannel>(); private static readonly Dictionary<SpiChannelNumber, SpiChannel> Buses = new Dictionary<SpiChannelNumber, SpiChannel>();
private readonly object _syncLock = new object(); private readonly Object _syncLock = new Object();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SpiChannel"/> class. /// Initializes a new instance of the <see cref="SpiChannel"/> class.
/// </summary> /// </summary>
/// <param name="channel">The channel.</param> /// <param name="channel">The channel.</param>
/// <param name="frequency">The frequency.</param> /// <param name="frequency">The frequency.</param>
private SpiChannel(SpiChannelNumber channel, int frequency) private SpiChannel(SpiChannelNumber channel, Int32 frequency) {
{ lock(SyncRoot) {
lock (SyncRoot) this.Frequency = frequency.Clamp(MinFrequency, MaxFrequency);
{ this.Channel = (Int32)channel;
Frequency = frequency.Clamp(MinFrequency, MaxFrequency); this.FileDescriptor = Native.WiringPi.WiringPiSPISetup((Int32)channel, this.Frequency);
Channel = (int)channel;
FileDescriptor = WiringPi.WiringPiSPISetup((int)channel, Frequency);
if (FileDescriptor < 0) if(this.FileDescriptor < 0) {
{
HardwareException.Throw(nameof(SpiChannel), channel.ToString()); HardwareException.Throw(nameof(SpiChannel), channel.ToString());
} }
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public int FileDescriptor { get; } public Int32 FileDescriptor {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public int Channel { get; } public Int32 Channel {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public int Frequency { get; } public Int32 Frequency {
get;
}
/// <inheritdoc /> /// <inheritdoc />
public byte[] SendReceive(byte[] buffer) public Byte[] SendReceive(Byte[] buffer) {
{ if(buffer == null || buffer.Length == 0) {
if (buffer == null || buffer.Length == 0)
return null; return null;
}
lock (_syncLock) lock(this._syncLock) {
{ Byte[] spiBuffer = new Byte[buffer.Length];
var spiBuffer = new byte[buffer.Length];
Array.Copy(buffer, spiBuffer, buffer.Length); Array.Copy(buffer, spiBuffer, buffer.Length);
var result = WiringPi.WiringPiSPIDataRW(Channel, spiBuffer, spiBuffer.Length); Int32 result = Native.WiringPi.WiringPiSPIDataRW(this.Channel, spiBuffer, spiBuffer.Length);
if (result < 0) HardwareException.Throw(nameof(SpiChannel), nameof(SendReceive)); if(result < 0) {
HardwareException.Throw(nameof(SpiChannel), nameof(SendReceive));
}
return spiBuffer; return spiBuffer;
} }
@ -83,19 +86,18 @@
/// <returns> /// <returns>
/// The read bytes from the ring-style bus. /// The read bytes from the ring-style bus.
/// </returns> /// </returns>
public Task<byte[]> SendReceiveAsync(byte[] buffer) => Task.Run(() => SendReceive(buffer)); public Task<Byte[]> SendReceiveAsync(Byte[] buffer) => Task.Run(() => this.SendReceive(buffer));
/// <inheritdoc /> /// <inheritdoc />
public void Write(byte[] buffer) public void Write(Byte[] buffer) {
{ lock(this._syncLock) {
lock (_syncLock) Int32 result = Native.SysCall.Write(this.FileDescriptor, buffer, buffer.Length);
{
var result = SysCall.Write(FileDescriptor, buffer, buffer.Length);
if (result < 0) if(result < 0) {
HardwareException.Throw(nameof(SpiChannel), nameof(Write)); HardwareException.Throw(nameof(SpiChannel), nameof(Write));
} }
} }
}
/// <summary> /// <summary>
/// Writes the specified buffer the the underlying FileDescriptor. /// Writes the specified buffer the the underlying FileDescriptor.
@ -105,7 +107,7 @@
/// </summary> /// </summary>
/// <param name="buffer">The buffer.</param> /// <param name="buffer">The buffer.</param>
/// <returns>The awaitable task.</returns> /// <returns>The awaitable task.</returns>
public Task WriteAsync(byte[] buffer) => Task.Run(() => { Write(buffer); }); public Task WriteAsync(Byte[] buffer) => Task.Run(() => { this.Write(buffer); });
/// <summary> /// <summary>
/// Retrieves the spi bus. If the bus channel is not registered it sets it up automatically. /// Retrieves the spi bus. If the bus channel is not registered it sets it up automatically.
@ -114,14 +116,13 @@
/// <param name="channel">The channel.</param> /// <param name="channel">The channel.</param>
/// <param name="frequency">The frequency.</param> /// <param name="frequency">The frequency.</param>
/// <returns>The usable SPI channel.</returns> /// <returns>The usable SPI channel.</returns>
internal static ISpiChannel Retrieve(SpiChannelNumber channel, int frequency) internal static ISpiChannel Retrieve(SpiChannelNumber channel, Int32 frequency) {
{ lock(SyncRoot) {
lock (SyncRoot) if(Buses.ContainsKey(channel)) {
{
if (Buses.ContainsKey(channel))
return Buses[channel]; return Buses[channel];
}
var newBus = new SpiChannel(channel, frequency); SpiChannel newBus = new SpiChannel(channel, frequency);
Buses[channel] = newBus; Buses[channel] = newBus;
return newBus; return newBus;
} }

View File

@ -1,40 +1,37 @@
namespace Unosquare.WiringPi using System;
{
using Native;
using RaspberryIO.Abstractions;
using System;
using Unosquare.RaspberryIO.Abstractions;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Represents the WiringPi system info. /// Represents the WiringPi system info.
/// </summary> /// </summary>
/// <seealso cref="ISystemInfo" /> /// <seealso cref="ISystemInfo" />
public class SystemInfo : ISystemInfo public class SystemInfo : ISystemInfo {
{ private static readonly Object Lock = new Object();
private static readonly object Lock = new object(); private static Boolean _revGetted;
private static bool _revGetted;
private static BoardRevision _boardRevision = BoardRevision.Rev2; private static BoardRevision _boardRevision = BoardRevision.Rev2;
/// <inheritdoc /> /// <inheritdoc />
public BoardRevision BoardRevision => GetBoardRevision(); public BoardRevision BoardRevision => GetBoardRevision();
/// <inheritdoc /> /// <inheritdoc />
public Version LibraryVersion public Version LibraryVersion {
{ get {
get String[] libParts = Native.WiringPi.WiringPiLibrary.Split('.');
{ Int32 major = Int32.Parse(libParts[libParts.Length - 2]);
var libParts = WiringPi.WiringPiLibrary.Split('.'); Int32 minor = Int32.Parse(libParts[libParts.Length - 1]);
var major = int.Parse(libParts[libParts.Length - 2]);
var minor = int.Parse(libParts[libParts.Length - 1]);
return new Version(major, minor); return new Version(major, minor);
} }
} }
internal static BoardRevision GetBoardRevision() internal static BoardRevision GetBoardRevision() {
{ lock(Lock) {
lock (Lock) if(_revGetted) {
{ return _boardRevision;
if (_revGetted) return _boardRevision; }
var val = WiringPi.PiBoardRev();
Int32 val = Native.WiringPi.PiBoardRev();
_boardRevision = val == 1 ? BoardRevision.Rev1 : BoardRevision.Rev2; _boardRevision = val == 1 ? BoardRevision.Rev1 : BoardRevision.Rev2;
_revGetted = true; _revGetted = true;
} }

View File

@ -1,17 +1,16 @@
namespace Unosquare.WiringPi using System;
{
using Native;
using RaspberryIO.Abstractions;
using RaspberryIO.Abstractions.Native;
using Swan;
using System;
using Swan;
using Unosquare.RaspberryIO.Abstractions;
using Unosquare.RaspberryIO.Abstractions.Native;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Use this class to access threading methods using interop. /// Use this class to access threading methods using interop.
/// </summary> /// </summary>
/// <seealso cref="IThreading" /> /// <seealso cref="IThreading" />
public class Threading : IThreading public class Threading : IThreading {
{
/// <summary> /// <summary>
/// This attempts to shift your program (or thread in a multi-threaded program) to a higher priority and /// This attempts to shift your program (or thread in a multi-threaded program) to a higher priority and
/// enables a real-time scheduling. The priority parameter should be from 0 (the default) to 99 (the maximum). /// enables a real-time scheduling. The priority parameter should be from 0 (the default) to 99 (the maximum).
@ -21,11 +20,12 @@
/// (as long as no other programs are running with elevated priorities). /// (as long as no other programs are running with elevated priorities).
/// </summary> /// </summary>
/// <param name="priority">The priority.</param> /// <param name="priority">The priority.</param>
public void SetThreadPriority(int priority) public void SetThreadPriority(Int32 priority) {
{
priority = priority.Clamp(0, 99); priority = priority.Clamp(0, 99);
var result = WiringPi.PiHiPri(priority); Int32 result = Native.WiringPi.PiHiPri(priority);
if (result < 0) HardwareException.Throw(nameof(Timing), nameof(SetThreadPriority)); if(result < 0) {
HardwareException.Throw(nameof(Timing), nameof(SetThreadPriority));
}
} }
/// <summary> /// <summary>
@ -34,7 +34,7 @@
/// it will be stalled until the first process has unlocked the same key. /// it will be stalled until the first process has unlocked the same key.
/// </summary> /// </summary>
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
public void Lock(ThreadLockKey key) => WiringPi.PiLock((int)key); public void Lock(ThreadLockKey key) => Native.WiringPi.PiLock((Int32)key);
/// <summary> /// <summary>
/// These allow you to synchronize variable updates from your main program to any threads running in your program. /// These allow you to synchronize variable updates from your main program to any threads running in your program.
@ -42,7 +42,7 @@
/// it will be stalled until the first process has unlocked the same key. /// it will be stalled until the first process has unlocked the same key.
/// </summary> /// </summary>
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
public void Unlock(ThreadLockKey key) => WiringPi.PiUnlock((int)key); public void Unlock(ThreadLockKey key) => Native.WiringPi.PiUnlock((Int32)key);
/// <inheritdoc /> /// <inheritdoc />
/// <summary> /// <summary>
@ -50,23 +50,22 @@
/// See the manual pages on Posix threads (man pthread) if you need more control over them. /// See the manual pages on Posix threads (man pthread) if you need more control over them.
/// </summary> /// </summary>
/// <exception cref="ArgumentNullException">worker.</exception> /// <exception cref="ArgumentNullException">worker.</exception>
public void StartThread(Action worker) public void StartThread(Action worker) {
{ if(worker == null) {
if (worker == null)
throw new ArgumentNullException(nameof(worker)); throw new ArgumentNullException(nameof(worker));
}
var result = WiringPi.PiThreadCreate(new ThreadWorker(worker)); Int32 result = Native.WiringPi.PiThreadCreate(new Native.ThreadWorker(worker));
if (result != 0) if(result != 0) {
HardwareException.Throw(nameof(Timing), nameof(StartThread)); HardwareException.Throw(nameof(Timing), nameof(StartThread));
} }
}
/// <inheritdoc /> /// <inheritdoc />
public UIntPtr StartThreadEx(Action<UIntPtr> worker, UIntPtr userData) => public UIntPtr StartThreadEx(Action<UIntPtr> worker, UIntPtr userData) => throw new NotSupportedException("WiringPi does only support a simple thread callback that has no parameters.");
throw new NotSupportedException("WiringPi does only support a simple thread callback that has no parameters.");
/// <inheritdoc /> /// <inheritdoc />
public void StopThreadEx(UIntPtr handle) => public void StopThreadEx(UIntPtr handle) => throw new NotSupportedException("WiringPi does not support stopping threads.");
throw new NotSupportedException("WiringPi does not support stopping threads.");
} }
} }

View File

@ -1,20 +1,19 @@
namespace Unosquare.WiringPi using System;
{
using Native;
using RaspberryIO.Abstractions;
using Unosquare.RaspberryIO.Abstractions;
namespace Unosquare.WiringPi {
/// <summary> /// <summary>
/// Provides access to timing and threading properties and methods. /// Provides access to timing and threading properties and methods.
/// </summary> /// </summary>
public class Timing : ITiming public class Timing : ITiming {
{
/// <inheritdoc /> /// <inheritdoc />
/// <summary> /// <summary>
/// This returns a number representing the number of milliseconds since your program /// This returns a number representing the number of milliseconds since your program
/// initialized the GPIO controller. /// initialized the GPIO controller.
/// It returns an unsigned 32-bit number which wraps after 49 days. /// It returns an unsigned 32-bit number which wraps after 49 days.
/// </summary> /// </summary>
public uint Milliseconds => WiringPi.Millis(); public UInt32 Milliseconds => Native.WiringPi.Millis();
/// <inheritdoc /> /// <inheritdoc />
/// <summary> /// <summary>
@ -22,15 +21,15 @@
/// program initialized the GPIO controller /// program initialized the GPIO controller
/// It returns an unsigned 32-bit number which wraps after approximately 71 minutes. /// It returns an unsigned 32-bit number which wraps after approximately 71 minutes.
/// </summary> /// </summary>
public uint Microseconds => WiringPi.Micros(); public UInt32 Microseconds => Native.WiringPi.Micros();
/// <inheritdoc cref="ITiming.SleepMilliseconds(uint)" /> /// <inheritdoc cref="ITiming.SleepMilliseconds(UInt32)" />
public static void Sleep(uint millis) => WiringPi.Delay(millis); public static void Sleep(UInt32 millis) => Native.WiringPi.Delay(millis);
/// <inheritdoc /> /// <inheritdoc />
public void SleepMilliseconds(uint millis) => Sleep(millis); public void SleepMilliseconds(UInt32 millis) => Sleep(millis);
/// <inheritdoc /> /// <inheritdoc />
public void SleepMicroseconds(uint micros) => WiringPi.DelayMicroseconds(micros); public void SleepMicroseconds(UInt32 micros) => Native.WiringPi.DelayMicroseconds(micros);
} }
} }