namespace Unosquare.WiringPi { using Native; using RaspberryIO.Abstractions; using RaspberryIO.Abstractions.Native; using System; using System.Threading.Tasks; /// /// Represents a device on the I2C Bus. /// public class I2CDevice : II2CDevice { private readonly object _syncLock = new object(); /// /// Initializes a new instance of the class. /// /// The device identifier. /// The file descriptor. internal I2CDevice(int deviceId, int fileDescriptor) { DeviceId = deviceId; FileDescriptor = fileDescriptor; } /// public int DeviceId { get; } /// public int FileDescriptor { get; } /// public byte Read() { lock (_syncLock) { var result = WiringPi.WiringPiI2CRead(FileDescriptor); if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Read)); return (byte)result; } } /// /// Reads a byte from the specified file descriptor. /// /// The byte from device. public Task ReadAsync() => Task.Run(Read); /// /// Reads a buffer of the specified length, one byte at a time. /// /// The length. /// The byte array from device. 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; } } /// /// Reads a buffer of the specified length, one byte at a time. /// /// The length. /// The byte array from device. public Task ReadAsync(int length) => Task.Run(() => Read(length)); /// /// Writes a byte of data the specified file descriptor. /// /// The data. public void Write(byte data) { lock (_syncLock) { var result = WiringPi.WiringPiI2CWrite(FileDescriptor, data); if (result < 0) HardwareException.Throw(nameof(I2CDevice), nameof(Write)); } } /// /// Writes a byte of data the specified file descriptor. /// /// The data. /// The awaitable task. public Task WriteAsync(byte data) => Task.Run(() => { Write(data); }); /// /// Writes a set of bytes to the specified file descriptor. /// /// The data. 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)); } } } /// /// Writes a set of bytes to the specified file descriptor. /// /// The data. /// The awaitable task. public Task WriteAsync(byte[] data) => Task.Run(() => { Write(data); }); /// /// These write an 8 or 16-bit data value into the device register indicated. /// /// The register. /// The data. 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)); } } /// /// These write an 8 or 16-bit data value into the device register indicated. /// /// The register. /// The data. 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)); } } /// /// These read an 8 or 16-bit value from the device register indicated. /// /// The register. /// The address byte from device. 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; } } /// /// These read an 8 or 16-bit value from the device register indicated. /// /// The register. /// The address word from device. 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); } } } }