Coding styles

This commit is contained in:
2019-12-03 18:43:54 +01:00
parent d75c3bc73f
commit 186792fde8
37 changed files with 5871 additions and 6009 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+166 -200
View File
@@ -1,201 +1,167 @@
namespace Unosquare.RaspberryIO.Gpio
{
using System;
public partial class GpioPin
{
#region Static Pin Definitions
internal static readonly Lazy<GpioPin> Pin08 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin08, 3)
{
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSDA },
Name = "BCM 2 (SDA)"
});
internal static readonly Lazy<GpioPin> Pin09 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin09, 5)
{
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSCL },
Name = "BCM 3 (SCL)"
});
internal static readonly Lazy<GpioPin> Pin07 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin07, 7)
{
Capabilities = new[] { PinCapability.GP, PinCapability.GPCLK },
Name = "BCM 4 (GPCLK0)"
});
internal static readonly Lazy<GpioPin> Pin00 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin00, 11)
{
Capabilities = new[] { PinCapability.GP, PinCapability.UARTRTS },
Name = "BCM 17"
});
internal static readonly Lazy<GpioPin> Pin02 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin02, 13)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 27"
});
internal static readonly Lazy<GpioPin> Pin03 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin03, 15)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 22"
});
internal static readonly Lazy<GpioPin> Pin12 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin12, 19)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMOSI },
Name = "BCM 10 (MOSI)"
});
internal static readonly Lazy<GpioPin> Pin13 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin13, 21)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMISO },
Name = "BCM 9 (MISO)"
});
internal static readonly Lazy<GpioPin> Pin14 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin14, 23)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPICLK },
Name = "BCM 11 (SCLCK)"
});
internal static readonly Lazy<GpioPin> Pin30 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin30, 27)
{
Capabilities = new[] { PinCapability.I2CSDA },
Name = "BCM 0 (ID_SD)"
});
internal static readonly Lazy<GpioPin> Pin31 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin31, 28)
{
Capabilities = new[] { PinCapability.I2CSCL },
Name = "BCM 1 (ID_SC)"
});
internal static readonly Lazy<GpioPin> Pin11 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin11, 26)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPICS },
Name = "BCM 7 (CE1)"
});
internal static readonly Lazy<GpioPin> Pin10 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin10, 24)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPICS },
Name = "BCM 8 (CE0)"
});
internal static readonly Lazy<GpioPin> Pin06 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin06, 22)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 25"
});
internal static readonly Lazy<GpioPin> Pin05 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin05, 18)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 24"
});
internal static readonly Lazy<GpioPin> Pin04 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin04, 16)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 23"
});
internal static readonly Lazy<GpioPin> Pin01 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin01, 12)
{
Capabilities = new[] { PinCapability.GP, PinCapability.PWM },
Name = "BCM 18 (PWM0)"
});
internal static readonly Lazy<GpioPin> Pin16 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin16, 10)
{
Capabilities = new[] { PinCapability.UARTRXD },
Name = "BCM 15 (RXD)"
});
internal static readonly Lazy<GpioPin> Pin15 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin15, 8)
{
Capabilities = new[] { PinCapability.UARTTXD },
Name = "BCM 14 (TXD)"
});
internal static readonly Lazy<GpioPin> Pin21 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin21, 29)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 5"
});
internal static readonly Lazy<GpioPin> Pin22 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin22, 31)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 6"
});
internal static readonly Lazy<GpioPin> Pin23 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin23, 33)
{
Capabilities = new[] { PinCapability.GP, PinCapability.PWM },
Name = "BCM 13 (PWM1)"
});
internal static readonly Lazy<GpioPin> Pin24 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin24, 35)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMISO },
Name = "BCM 19 (MISO)"
});
internal static readonly Lazy<GpioPin> Pin25 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin25, 37)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 26"
});
internal static readonly Lazy<GpioPin> Pin29 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin29, 40)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPICLK },
Name = "BCM 21 (SCLK)"
});
internal static readonly Lazy<GpioPin> Pin28 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin28, 38)
{
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMOSI },
Name = "BCM 20 (MOSI)"
});
internal static readonly Lazy<GpioPin> Pin27 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin27, 36)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 16"
});
internal static readonly Lazy<GpioPin> Pin26 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin26, 32)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 12 (PWM0)"
});
internal static readonly Lazy<GpioPin> Pin17 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin17, 3)
{
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSDA },
Name = "BCM 28 (SDA)"
});
internal static readonly Lazy<GpioPin> Pin18 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin18, 4)
{
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSCL },
Name = "BCM 29 (SCL)"
});
internal static readonly Lazy<GpioPin> Pin19 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin19, 5)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 30"
});
internal static readonly Lazy<GpioPin> Pin20 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin20, 6)
{
Capabilities = new[] { PinCapability.GP },
Name = "BCM 31"
});
#endregion
}
using System;
namespace Unosquare.RaspberryIO.Gpio {
public partial class GpioPin {
#region Static Pin Definitions
internal static readonly Lazy<GpioPin> Pin08 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin08, 3) {
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSDA },
Name = "BCM 2 (SDA)"
});
internal static readonly Lazy<GpioPin> Pin09 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin09, 5) {
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSCL },
Name = "BCM 3 (SCL)"
});
internal static readonly Lazy<GpioPin> Pin07 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin07, 7) {
Capabilities = new[] { PinCapability.GP, PinCapability.GPCLK },
Name = "BCM 4 (GPCLK0)"
});
internal static readonly Lazy<GpioPin> Pin00 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin00, 11) {
Capabilities = new[] { PinCapability.GP, PinCapability.UARTRTS },
Name = "BCM 17"
});
internal static readonly Lazy<GpioPin> Pin02 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin02, 13) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 27"
});
internal static readonly Lazy<GpioPin> Pin03 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin03, 15) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 22"
});
internal static readonly Lazy<GpioPin> Pin12 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin12, 19) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMOSI },
Name = "BCM 10 (MOSI)"
});
internal static readonly Lazy<GpioPin> Pin13 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin13, 21) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMISO },
Name = "BCM 9 (MISO)"
});
internal static readonly Lazy<GpioPin> Pin14 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin14, 23) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPICLK },
Name = "BCM 11 (SCLCK)"
});
internal static readonly Lazy<GpioPin> Pin30 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin30, 27) {
Capabilities = new[] { PinCapability.I2CSDA },
Name = "BCM 0 (ID_SD)"
});
internal static readonly Lazy<GpioPin> Pin31 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin31, 28) {
Capabilities = new[] { PinCapability.I2CSCL },
Name = "BCM 1 (ID_SC)"
});
internal static readonly Lazy<GpioPin> Pin11 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin11, 26) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPICS },
Name = "BCM 7 (CE1)"
});
internal static readonly Lazy<GpioPin> Pin10 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin10, 24) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPICS },
Name = "BCM 8 (CE0)"
});
internal static readonly Lazy<GpioPin> Pin06 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin06, 22) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 25"
});
internal static readonly Lazy<GpioPin> Pin05 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin05, 18) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 24"
});
internal static readonly Lazy<GpioPin> Pin04 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin04, 16) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 23"
});
internal static readonly Lazy<GpioPin> Pin01 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin01, 12) {
Capabilities = new[] { PinCapability.GP, PinCapability.PWM },
Name = "BCM 18 (PWM0)"
});
internal static readonly Lazy<GpioPin> Pin16 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin16, 10) {
Capabilities = new[] { PinCapability.UARTRXD },
Name = "BCM 15 (RXD)"
});
internal static readonly Lazy<GpioPin> Pin15 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin15, 8) {
Capabilities = new[] { PinCapability.UARTTXD },
Name = "BCM 14 (TXD)"
});
internal static readonly Lazy<GpioPin> Pin21 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin21, 29) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 5"
});
internal static readonly Lazy<GpioPin> Pin22 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin22, 31) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 6"
});
internal static readonly Lazy<GpioPin> Pin23 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin23, 33) {
Capabilities = new[] { PinCapability.GP, PinCapability.PWM },
Name = "BCM 13 (PWM1)"
});
internal static readonly Lazy<GpioPin> Pin24 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin24, 35) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMISO },
Name = "BCM 19 (MISO)"
});
internal static readonly Lazy<GpioPin> Pin25 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin25, 37) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 26"
});
internal static readonly Lazy<GpioPin> Pin29 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin29, 40) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPICLK },
Name = "BCM 21 (SCLK)"
});
internal static readonly Lazy<GpioPin> Pin28 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin28, 38) {
Capabilities = new[] { PinCapability.GP, PinCapability.SPIMOSI },
Name = "BCM 20 (MOSI)"
});
internal static readonly Lazy<GpioPin> Pin27 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin27, 36) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 16"
});
internal static readonly Lazy<GpioPin> Pin26 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin26, 32) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 12 (PWM0)"
});
internal static readonly Lazy<GpioPin> Pin17 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin17, 3) {
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSDA },
Name = "BCM 28 (SDA)"
});
internal static readonly Lazy<GpioPin> Pin18 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin18, 4) {
Capabilities = new[] { PinCapability.GP, PinCapability.I2CSCL },
Name = "BCM 29 (SCL)"
});
internal static readonly Lazy<GpioPin> Pin19 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin19, 5) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 30"
});
internal static readonly Lazy<GpioPin> Pin20 = new Lazy<GpioPin>(() => new GpioPin(WiringPiPin.Pin20, 6) {
Capabilities = new[] { PinCapability.GP },
Name = "BCM 31"
});
#endregion
}
}
File diff suppressed because it is too large Load Diff
+87 -93
View File
@@ -1,93 +1,87 @@
namespace Unosquare.RaspberryIO.Gpio
{
using Native;
using Swan.Abstractions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
/// <summary>
/// A simple wrapper for the I2c bus on the Raspberry Pi
/// </summary>
public class I2CBus : SingletonBase<I2CBus>
{
// TODO: It would be nice to integrate i2c device detection.
private static readonly object SyncRoot = new object();
private readonly Dictionary<int, I2CDevice> _devices = new Dictionary<int, I2CDevice>();
/// <summary>
/// Prevents a default instance of the <see cref="I2CBus"/> class from being created.
/// </summary>
private I2CBus()
{
// placeholder
}
/// <summary>
/// Gets the registered devices as a read only collection.
/// </summary>
public ReadOnlyCollection<I2CDevice> Devices => new ReadOnlyCollection<I2CDevice>(_devices.Values.ToArray());
/// <summary>
/// Gets the <see cref="I2CDevice"/> with the specified device identifier.
/// </summary>
/// <value>
/// The <see cref="I2CDevice"/>.
/// </value>
/// <param name="deviceId">The device identifier.</param>
/// <returns>A reference to an I2C device</returns>
public I2CDevice this[int deviceId] => GetDeviceById(deviceId);
/// <summary>
/// Gets the device by identifier.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The device reference</returns>
public I2CDevice GetDeviceById(int deviceId)
{
lock (SyncRoot)
{
return _devices[deviceId];
}
}
/// <summary>
/// Adds a device to the bus by its Id. If the device is already registered it simply returns the existing device.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The device reference</returns>
/// <exception cref="KeyNotFoundException">When the device file descriptor is not found</exception>
public I2CDevice AddDevice(int deviceId)
{
lock (SyncRoot)
{
if (_devices.ContainsKey(deviceId))
return _devices[deviceId];
var fileDescriptor = SetupFileDescriptor(deviceId);
if (fileDescriptor < 0)
throw new KeyNotFoundException($"Device with id {deviceId} could not be registered with the I2C bus. Error Code: {fileDescriptor}.");
var device = new I2CDevice(deviceId, fileDescriptor);
_devices[deviceId] = device;
return device;
}
}
/// <summary>
/// This initializes the I2C system with your given device identifier.
/// The ID is the I2C number of the device and you can use the i2cdetect program to find this out.
/// wiringPiI2CSetup() will work out which revision Raspberry Pi you have and open the appropriate device in /dev.
/// The return value is the standard Linux filehandle, or -1 if any error – in which case, you can consult errno as usual.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The Linux file handle</returns>
private static int SetupFileDescriptor(int deviceId)
{
lock (SyncRoot)
{
return WiringPi.WiringPiI2CSetup(deviceId);
}
}
}
}
using Unosquare.RaspberryIO.Native;
using Unosquare.Swan.Abstractions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System;
namespace Unosquare.RaspberryIO.Gpio {
/// <summary>
/// A simple wrapper for the I2c bus on the Raspberry Pi
/// </summary>
public class I2CBus : SingletonBase<I2CBus> {
// TODO: It would be nice to integrate i2c device detection.
private static readonly Object SyncRoot = new Object();
private readonly Dictionary<Int32, I2CDevice> _devices = new Dictionary<Int32, I2CDevice>();
/// <summary>
/// Prevents a default instance of the <see cref="I2CBus"/> class from being created.
/// </summary>
private I2CBus() {
// placeholder
}
/// <summary>
/// Gets the registered devices as a read only collection.
/// </summary>
public ReadOnlyCollection<I2CDevice> Devices => new ReadOnlyCollection<I2CDevice>(this._devices.Values.ToArray());
/// <summary>
/// Gets the <see cref="I2CDevice"/> with the specified device identifier.
/// </summary>
/// <value>
/// The <see cref="I2CDevice"/>.
/// </value>
/// <param name="deviceId">The device identifier.</param>
/// <returns>A reference to an I2C device</returns>
public I2CDevice this[Int32 deviceId] => this.GetDeviceById(deviceId);
/// <summary>
/// Gets the device by identifier.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The device reference</returns>
public I2CDevice GetDeviceById(Int32 deviceId) {
lock(SyncRoot) {
return this._devices[deviceId];
}
}
/// <summary>
/// Adds a device to the bus by its Id. If the device is already registered it simply returns the existing device.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The device reference</returns>
/// <exception cref="KeyNotFoundException">When the device file descriptor is not found</exception>
public I2CDevice AddDevice(Int32 deviceId) {
lock(SyncRoot) {
if(this._devices.ContainsKey(deviceId)) {
return this._devices[deviceId];
}
Int32 fileDescriptor = SetupFileDescriptor(deviceId);
if(fileDescriptor < 0) {
throw new KeyNotFoundException($"Device with id {deviceId} could not be registered with the I2C bus. Error Code: {fileDescriptor}.");
}
I2CDevice device = new I2CDevice(deviceId, fileDescriptor);
this._devices[deviceId] = device;
return device;
}
}
/// <summary>
/// This initializes the I2C system with your given device identifier.
/// The ID is the I2C number of the device and you can use the i2cdetect program to find this out.
/// wiringPiI2CSetup() will work out which revision Raspberry Pi you have and open the appropriate device in /dev.
/// The return value is the standard Linux filehandle, or -1 if any error – in which case, you can consult errno as usual.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The Linux file handle</returns>
private static Int32 SetupFileDescriptor(Int32 deviceId) {
lock(SyncRoot) {
return WiringPi.WiringPiI2CSetup(deviceId);
}
}
}
}
+193 -195
View File
@@ -1,195 +1,193 @@
namespace Unosquare.RaspberryIO.Gpio
{
using System;
using System.Threading.Tasks;
using Native;
/// <summary>
/// Represents a device on the I2C Bus
/// </summary>
public class I2CDevice
{
private readonly object _syncLock = new object();
/// <summary>
/// Initializes a new instance of the <see cref="I2CDevice"/> class.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <param name="fileDescriptor">The file descriptor.</param>
internal I2CDevice(int deviceId, int fileDescriptor)
{
DeviceId = deviceId;
FileDescriptor = fileDescriptor;
}
/// <summary>
/// Gets the device identifier.
/// </summary>
/// <value>
/// The device identifier.
/// </value>
public int DeviceId { get; }
/// <summary>
/// Gets the standard POSIX file descriptor.
/// </summary>
/// <value>
/// The file descriptor.
/// </value>
public int FileDescriptor { get; }
/// <summary>
/// Reads a byte from the specified file descriptor
/// </summary>
/// <returns>The byte from device</returns>
public byte Read()
{
lock (_syncLock)
{
var result = WiringPi.WiringPiI2CRead(FileDescriptor);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Read));
return (byte)result;
}
}
/// <summary>
/// Reads a byte from the specified file descriptor
/// </summary>
/// <returns>The byte from device</returns>
public Task<byte> ReadAsync() => Task.Run(() => Read());
/// <summary>
/// Reads a buffer of the specified length, one byte at a time
/// </summary>
/// <param name="length">The length.</param>
/// <returns>The byte array from device</returns>
public byte[] Read(int length)
{
lock (_syncLock)
{
var buffer = new byte[length];
for (var i = 0; i < length; i++)
{
var result = WiringPi.WiringPiI2CRead(FileDescriptor);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Read));
buffer[i] = (byte)result;
}
return buffer;
}
}
/// <summary>
/// Reads a buffer of the specified length, one byte at a time
/// </summary>
/// <param name="length">The length.</param>
/// <returns>The byte array from device</returns>
public Task<byte[]> ReadAsync(int length) => Task.Run(() => Read(length));
/// <summary>
/// Writes a byte of data the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
public void Write(byte data)
{
lock (_syncLock)
{
var result = WiringPi.WiringPiI2CWrite(FileDescriptor, data);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Write));
}
}
/// <summary>
/// Writes a byte of data the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>The awaitable task</returns>
public Task WriteAsync(byte data) => Task.Run(() => { Write(data); });
/// <summary>
/// Writes a set of bytes to the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
public void Write(byte[] data)
{
lock (_syncLock)
{
foreach (var b in data)
{
var result = WiringPi.WiringPiI2CWrite(FileDescriptor, b);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Write));
}
}
}
/// <summary>
/// Writes a set of bytes to the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>The awaitable task</returns>
public Task WriteAsync(byte[] data)
{
return Task.Run(() => { Write(data); });
}
/// <summary>
/// These write an 8 or 16-bit data value into the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <param name="data">The data.</param>
public void WriteAddressByte(int address, byte data)
{
lock (_syncLock)
{
var result = WiringPi.WiringPiI2CWriteReg8(FileDescriptor, address, data);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressByte));
}
}
/// <summary>
/// These write an 8 or 16-bit data value into the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <param name="data">The data.</param>
public void WriteAddressWord(int address, ushort data)
{
lock (_syncLock)
{
var result = WiringPi.WiringPiI2CWriteReg16(FileDescriptor, address, data);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressWord));
}
}
/// <summary>
/// These read an 8 or 16-bit value from the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <returns>The address byte from device</returns>
public byte ReadAddressByte(int address)
{
lock (_syncLock)
{
var result = WiringPi.WiringPiI2CReadReg8(FileDescriptor, address);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressByte));
return (byte)result;
}
}
/// <summary>
/// These read an 8 or 16-bit value from the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <returns>The address word from device</returns>
public ushort ReadAddressWord(int address)
{
lock (_syncLock)
{
var result = WiringPi.WiringPiI2CReadReg16(FileDescriptor, address);
if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressWord));
return Convert.ToUInt16(result);
}
}
}
}
using System;
using System.Threading.Tasks;
using Unosquare.RaspberryIO.Native;
namespace Unosquare.RaspberryIO.Gpio {
/// <summary>
/// Represents a device on the I2C Bus
/// </summary>
public class I2CDevice {
private readonly Object _syncLock = new Object();
/// <summary>
/// Initializes a new instance of the <see cref="I2CDevice"/> class.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <param name="fileDescriptor">The file descriptor.</param>
internal I2CDevice(Int32 deviceId, Int32 fileDescriptor) {
this.DeviceId = deviceId;
this.FileDescriptor = fileDescriptor;
}
/// <summary>
/// Gets the device identifier.
/// </summary>
/// <value>
/// The device identifier.
/// </value>
public Int32 DeviceId {
get;
}
/// <summary>
/// Gets the standard POSIX file descriptor.
/// </summary>
/// <value>
/// The file descriptor.
/// </value>
public Int32 FileDescriptor {
get;
}
/// <summary>
/// Reads a byte from the specified file descriptor
/// </summary>
/// <returns>The byte from device</returns>
public Byte Read() {
lock(this._syncLock) {
Int32 result = WiringPi.WiringPiI2CRead(this.FileDescriptor);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(Read));
}
return (Byte)result;
}
}
/// <summary>
/// Reads a byte from the specified file descriptor
/// </summary>
/// <returns>The byte from device</returns>
public Task<Byte> ReadAsync() => Task.Run(() => this.Read());
/// <summary>
/// Reads a buffer of the specified length, one byte at a time
/// </summary>
/// <param name="length">The length.</param>
/// <returns>The byte array from device</returns>
public Byte[] Read(Int32 length) {
lock(this._syncLock) {
Byte[] buffer = new Byte[length];
for(Int32 i = 0; i < length; i++) {
Int32 result = WiringPi.WiringPiI2CRead(this.FileDescriptor);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(Read));
}
buffer[i] = (Byte)result;
}
return buffer;
}
}
/// <summary>
/// Reads a buffer of the specified length, one byte at a time
/// </summary>
/// <param name="length">The length.</param>
/// <returns>The byte array from device</returns>
public Task<Byte[]> ReadAsync(Int32 length) => Task.Run(() => this.Read(length));
/// <summary>
/// Writes a byte of data the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
public void Write(Byte data) {
lock(this._syncLock) {
Int32 result = WiringPi.WiringPiI2CWrite(this.FileDescriptor, data);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(Write));
}
}
}
/// <summary>
/// Writes a byte of data the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>The awaitable task</returns>
public Task WriteAsync(Byte data) => Task.Run(() => this.Write(data));
/// <summary>
/// Writes a set of bytes to the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
public void Write(Byte[] data) {
lock(this._syncLock) {
foreach(Byte b in data) {
Int32 result = WiringPi.WiringPiI2CWrite(this.FileDescriptor, b);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(Write));
}
}
}
}
/// <summary>
/// Writes a set of bytes to the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>The awaitable task</returns>
public Task WriteAsync(Byte[] data) => Task.Run(() => this.Write(data));
/// <summary>
/// These write an 8 or 16-bit data value into the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <param name="data">The data.</param>
public void WriteAddressByte(Int32 address, Byte data) {
lock(this._syncLock) {
Int32 result = WiringPi.WiringPiI2CWriteReg8(this.FileDescriptor, address, data);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressByte));
}
}
}
/// <summary>
/// These write an 8 or 16-bit data value into the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <param name="data">The data.</param>
public void WriteAddressWord(Int32 address, UInt16 data) {
lock(this._syncLock) {
Int32 result = WiringPi.WiringPiI2CWriteReg16(this.FileDescriptor, address, data);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressWord));
}
}
}
/// <summary>
/// These read an 8 or 16-bit value from the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <returns>The address byte from device</returns>
public Byte ReadAddressByte(Int32 address) {
lock(this._syncLock) {
Int32 result = WiringPi.WiringPiI2CReadReg8(this.FileDescriptor, address);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressByte));
}
return (Byte)result;
}
}
/// <summary>
/// These read an 8 or 16-bit value from the device register indicated.
/// </summary>
/// <param name="address">The register.</param>
/// <returns>The address word from device</returns>
public UInt16 ReadAddressWord(Int32 address) {
lock(this._syncLock) {
Int32 result = WiringPi.WiringPiI2CReadReg16(this.FileDescriptor, address);
if(result < 0) {
HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressWord));
}
return Convert.ToUInt16(result);
}
}
}
}
+69 -69
View File
@@ -1,72 +1,72 @@
namespace Unosquare.RaspberryIO.Gpio
{
using Swan.Abstractions;
using System;
using Unosquare.Swan.Abstractions;
namespace Unosquare.RaspberryIO.Gpio {
/// <summary>
/// The SPI Bus containing the 2 SPI channels
/// </summary>
public class SpiBus : SingletonBase<SpiBus> {
/// <summary>
/// The SPI Bus containing the 2 SPI channels
/// Prevents a default instance of the <see cref="SpiBus"/> class from being created.
/// </summary>
public class SpiBus : SingletonBase<SpiBus>
{
/// <summary>
/// Prevents a default instance of the <see cref="SpiBus"/> class from being created.
/// </summary>
private SpiBus()
{
// placeholder
}
#region SPI Access
/// <summary>
/// Gets or sets the channel 0 frequency in Hz.
/// </summary>
/// <value>
/// The channel0 frequency.
/// </value>
public int Channel0Frequency { get; set; }
/// <summary>
/// Gets the SPI bus on channel 1.
/// </summary>
/// <value>
/// The channel0.
/// </value>
public SpiChannel Channel0
{
get
{
if (Channel0Frequency == 0)
Channel0Frequency = SpiChannel.DefaultFrequency;
return SpiChannel.Retrieve(SpiChannelNumber.Channel0, Channel0Frequency);
}
}
/// <summary>
/// Gets or sets the channel 1 frequency in Hz
/// </summary>
/// <value>
/// The channel1 frequency.
/// </value>
public int Channel1Frequency { get; set; }
/// <summary>
/// Gets the SPI bus on channel 1.
/// </summary>
/// <value>
/// The channel1.
/// </value>
public SpiChannel Channel1
{
get
{
if (Channel1Frequency == 0)
Channel1Frequency = SpiChannel.DefaultFrequency;
return SpiChannel.Retrieve(SpiChannelNumber.Channel1, Channel1Frequency);
}
}
#endregion
}
private SpiBus() {
// placeholder
}
#region SPI Access
/// <summary>
/// Gets or sets the channel 0 frequency in Hz.
/// </summary>
/// <value>
/// The channel0 frequency.
/// </value>
public Int32 Channel0Frequency {
get; set;
}
/// <summary>
/// Gets the SPI bus on channel 1.
/// </summary>
/// <value>
/// The channel0.
/// </value>
public SpiChannel Channel0 {
get {
if(this.Channel0Frequency == 0) {
this.Channel0Frequency = SpiChannel.DefaultFrequency;
}
return SpiChannel.Retrieve(SpiChannelNumber.Channel0, this.Channel0Frequency);
}
}
/// <summary>
/// Gets or sets the channel 1 frequency in Hz
/// </summary>
/// <value>
/// The channel1 frequency.
/// </value>
public Int32 Channel1Frequency {
get; set;
}
/// <summary>
/// Gets the SPI bus on channel 1.
/// </summary>
/// <value>
/// The channel1.
/// </value>
public SpiChannel Channel1 {
get {
if(this.Channel1Frequency == 0) {
this.Channel1Frequency = SpiChannel.DefaultFrequency;
}
return SpiChannel.Retrieve(SpiChannelNumber.Channel1, this.Channel1Frequency);
}
}
#endregion
}
}
+151 -151
View File
@@ -1,154 +1,154 @@
namespace Unosquare.RaspberryIO.Gpio
{
using Native;
using Swan;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Unosquare.RaspberryIO.Native;
using Unosquare.Swan;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Unosquare.RaspberryIO.Gpio {
/// <summary>
/// Provides access to using the SPI buses on the GPIO.
/// SPI is a bus that works like a ring shift register
/// The number of bytes pushed is equal to the number of bytes received.
/// </summary>
public sealed class SpiChannel {
/// <summary>
/// Provides access to using the SPI buses on the GPIO.
/// 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 minimum frequency of an SPI Channel
/// </summary>
public sealed class SpiChannel
{
/// <summary>
/// The minimum frequency of an SPI Channel
/// </summary>
public const int MinFrequency = 500000;
/// <summary>
/// The maximum frequency of an SPI channel
/// </summary>
public const int MaxFrequency = 32000000;
/// <summary>
/// The default frequency of SPI channels
/// This is set to 8 Mhz wich is typical in modern hardware.
/// </summary>
public const int DefaultFrequency = 8000000;
private static readonly object SyncRoot = new object();
private static readonly Dictionary<SpiChannelNumber, SpiChannel> Buses = new Dictionary<SpiChannelNumber, SpiChannel>();
private readonly object _syncLock = new object();
/// <summary>
/// Initializes a new instance of the <see cref="SpiChannel"/> class.
/// </summary>
/// <param name="channel">The channel.</param>
/// <param name="frequency">The frequency.</param>
private SpiChannel(SpiChannelNumber channel, int frequency)
{
lock (SyncRoot)
{
Frequency = frequency.Clamp(MinFrequency, MaxFrequency);
Channel = (int)channel;
FileDescriptor = WiringPi.WiringPiSPISetup((int)channel, Frequency);
if (FileDescriptor < 0)
{
HardwareException.Throw(nameof(SpiChannel), channel.ToString());
}
}
}
/// <summary>
/// Gets the standard initialization file descriptor.
/// anything negative means error.
/// </summary>
/// <value>
/// The file descriptor.
/// </value>
public int FileDescriptor { get; }
/// <summary>
/// Gets the channel.
/// </summary>
public int Channel { get; }
/// <summary>
/// Gets the frequency.
/// </summary>
public int Frequency { get; }
/// <summary>
/// Sends data and simultaneously receives the data in the return buffer
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <returns>The read bytes from the ring-style bus</returns>
public byte[] SendReceive(byte[] buffer)
{
if (buffer == null || buffer.Length == 0)
return null;
lock (_syncLock)
{
var spiBuffer = new byte[buffer.Length];
Array.Copy(buffer, spiBuffer, buffer.Length);
var result = WiringPi.WiringPiSPIDataRW(Channel, spiBuffer, spiBuffer.Length);
if (result < 0) HardwareException.Throw(nameof(SpiChannel), nameof(SendReceive));
return spiBuffer;
}
}
/// <summary>
/// Sends data and simultaneously receives the data in the return buffer
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <returns>
/// The read bytes from the ring-style bus
/// </returns>
public Task<byte[]> SendReceiveAsync(byte[] buffer) => Task.Run(() => SendReceive(buffer));
/// <summary>
/// Writes the specified buffer the the underlying FileDescriptor.
/// Do not use this method if you expect data back.
/// This method is efficient if used in a fire-and-forget scenario
/// like sending data over to those long RGB LED strips
/// </summary>
/// <param name="buffer">The buffer.</param>
public void Write(byte[] buffer)
{
lock (_syncLock)
{
var result = Standard.Write(FileDescriptor, buffer, buffer.Length);
if (result < 0)
HardwareException.Throw(nameof(SpiChannel), nameof(Write));
}
}
/// <summary>
/// Writes the specified buffer the the underlying FileDescriptor.
/// Do not use this method if you expect data back.
/// This method is efficient if used in a fire-and-forget scenario
/// like sending data over to those long RGB LED strips
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <returns>The awaitable task</returns>
public Task WriteAsync(byte[] buffer) => Task.Run(() => { Write(buffer); });
/// <summary>
/// Retrieves the spi bus. If the bus channel is not registered it sets it up automatically.
/// If it had been previously registered, then the bus is simply returned.
/// </summary>
/// <param name="channel">The channel.</param>
/// <param name="frequency">The frequency.</param>
/// <returns>The usable SPI channel</returns>
internal static SpiChannel Retrieve(SpiChannelNumber channel, int frequency)
{
lock (SyncRoot)
{
if (Buses.ContainsKey(channel))
return Buses[channel];
var newBus = new SpiChannel(channel, frequency);
Buses[channel] = newBus;
return newBus;
}
}
}
public const Int32 MinFrequency = 500000;
/// <summary>
/// The maximum frequency of an SPI channel
/// </summary>
public const Int32 MaxFrequency = 32000000;
/// <summary>
/// The default frequency of SPI channels
/// This is set to 8 Mhz wich is typical in modern hardware.
/// </summary>
public const Int32 DefaultFrequency = 8000000;
private static readonly Object SyncRoot = new Object();
private static readonly Dictionary<SpiChannelNumber, SpiChannel> Buses = new Dictionary<SpiChannelNumber, SpiChannel>();
private readonly Object _syncLock = new Object();
/// <summary>
/// Initializes a new instance of the <see cref="SpiChannel"/> class.
/// </summary>
/// <param name="channel">The channel.</param>
/// <param name="frequency">The frequency.</param>
private SpiChannel(SpiChannelNumber channel, Int32 frequency) {
lock(SyncRoot) {
this.Frequency = frequency.Clamp(MinFrequency, MaxFrequency);
this.Channel = (Int32)channel;
this.FileDescriptor = WiringPi.WiringPiSPISetup((Int32)channel, this.Frequency);
if(this.FileDescriptor < 0) {
HardwareException.Throw(nameof(SpiChannel), channel.ToString());
}
}
}
/// <summary>
/// Gets the standard initialization file descriptor.
/// anything negative means error.
/// </summary>
/// <value>
/// The file descriptor.
/// </value>
public Int32 FileDescriptor {
get;
}
/// <summary>
/// Gets the channel.
/// </summary>
public Int32 Channel {
get;
}
/// <summary>
/// Gets the frequency.
/// </summary>
public Int32 Frequency {
get;
}
/// <summary>
/// Sends data and simultaneously receives the data in the return buffer
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <returns>The read bytes from the ring-style bus</returns>
public Byte[] SendReceive(Byte[] buffer) {
if(buffer == null || buffer.Length == 0) {
return null;
}
lock(this._syncLock) {
Byte[] spiBuffer = new Byte[buffer.Length];
Array.Copy(buffer, spiBuffer, buffer.Length);
Int32 result = WiringPi.WiringPiSPIDataRW(this.Channel, spiBuffer, spiBuffer.Length);
if(result < 0) {
HardwareException.Throw(nameof(SpiChannel), nameof(SendReceive));
}
return spiBuffer;
}
}
/// <summary>
/// Sends data and simultaneously receives the data in the return buffer
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <returns>
/// The read bytes from the ring-style bus
/// </returns>
public Task<Byte[]> SendReceiveAsync(Byte[] buffer) => Task.Run(() => this.SendReceive(buffer));
/// <summary>
/// Writes the specified buffer the the underlying FileDescriptor.
/// Do not use this method if you expect data back.
/// This method is efficient if used in a fire-and-forget scenario
/// like sending data over to those long RGB LED strips
/// </summary>
/// <param name="buffer">The buffer.</param>
public void Write(Byte[] buffer) {
lock(this._syncLock) {
Int32 result = Standard.Write(this.FileDescriptor, buffer, buffer.Length);
if(result < 0) {
HardwareException.Throw(nameof(SpiChannel), nameof(Write));
}
}
}
/// <summary>
/// Writes the specified buffer the the underlying FileDescriptor.
/// Do not use this method if you expect data back.
/// This method is efficient if used in a fire-and-forget scenario
/// like sending data over to those long RGB LED strips
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <returns>The awaitable task</returns>
public Task WriteAsync(Byte[] buffer) => Task.Run(() => this.Write(buffer));
/// <summary>
/// Retrieves the spi bus. If the bus channel is not registered it sets it up automatically.
/// If it had been previously registered, then the bus is simply returned.
/// </summary>
/// <param name="channel">The channel.</param>
/// <param name="frequency">The frequency.</param>
/// <returns>The usable SPI channel</returns>
internal static SpiChannel Retrieve(SpiChannelNumber channel, Int32 frequency) {
lock(SyncRoot) {
if(Buses.ContainsKey(channel)) {
return Buses[channel];
}
SpiChannel newBus = new SpiChannel(channel, frequency);
Buses[channel] = newBus;
return newBus;
}
}
}
}