using System; using System.Threading.Tasks; using Unosquare.RaspberryIO.Abstractions; using Unosquare.RaspberryIO.Abstractions.Native; namespace Unosquare.WiringPi { /// /// 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(Int32 deviceId, Int32 fileDescriptor) { this.DeviceId = deviceId; this.FileDescriptor = fileDescriptor; } /// public Int32 DeviceId { get; } /// public Int32 FileDescriptor { get; } /// public Byte Read() { lock(this._syncLock) { Int32 result = Native.WiringPi.WiringPiI2CRead(this.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(this.Read); /// /// Reads a buffer of the specified length, one byte at a time. /// /// The length. /// The byte array from device. public Byte[] Read(Int32 length) { lock(this._syncLock) { Byte[] buffer = new Byte[length]; for(Int32 i = 0; i < length; i++) { Int32 result = Native.WiringPi.WiringPiI2CRead(this.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(Int32 length) => Task.Run(() => this.Read(length)); /// /// Writes a byte of data the specified file descriptor. /// /// The data. public void Write(Byte data) { lock(this._syncLock) { Int32 result = Native.WiringPi.WiringPiI2CWrite(this.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(() => this.Write(data)); /// /// Writes a set of bytes to the specified file descriptor. /// /// The data. public void Write(Byte[] data) { lock(this._syncLock) { foreach(Byte b in data) { Int32 result = Native.WiringPi.WiringPiI2CWrite(this.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(() => this.Write(data)); /// /// These write an 8 or 16-bit data value into the device register indicated. /// /// The register. /// The data. public void WriteAddressByte(Int32 address, Byte data) { lock(this._syncLock) { Int32 result = Native.WiringPi.WiringPiI2CWriteReg8(this.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(Int32 address, UInt16 data) { lock(this._syncLock) { Int32 result = Native.WiringPi.WiringPiI2CWriteReg16(this.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(Int32 address) { lock(this._syncLock) { Int32 result = Native.WiringPi.WiringPiI2CReadReg8(this.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 UInt16 ReadAddressWord(Int32 address) { lock(this._syncLock) { Int32 result = Native.WiringPi.WiringPiI2CReadReg16(this.FileDescriptor, address); if(result < 0) { HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressWord)); } return Convert.ToUInt16(result); } } } }