提交 f45fda09 编写于 作者: G Greg Ingram 提交者: Jose Perez Rodriguez

Cleanup for I2C drivers (#143)

* Added editconfig file

* Cleanup for I2C drivers

* Cleanup for I2C drivers

* Updated wording

* Updated for feedback
上级 8b42ce21
......@@ -7,22 +7,37 @@ using System.Runtime.InteropServices;
namespace System.Device.I2c.Drivers
{
/// <summary>
/// Represents an I2C communication channel running on Unix.
/// </summary>
public class UnixI2cDevice : I2cDevice
{
private I2cConnectionSettings _settings;
private readonly I2cConnectionSettings _settings;
private const string DefaultDevicePath = "/dev/i2c";
private int _deviceFileDescriptor = -1;
private I2cFunctionalityFlags _functionalities;
private static readonly object s_InitializationLock = new object();
private static readonly object s_initializationLock = new object();
/// <summary>
/// Initializes new instance of UnixI2cDevice that will use the specified settings to communicate with the I2C device.
/// </summary>
/// <param name="settings">
/// The connection settings of a device on an I2C bus.
/// </param>
public UnixI2cDevice(I2cConnectionSettings settings)
{
_settings = settings;
DevicePath = DefaultDevicePath;
}
/// <summary>
/// Path to I2C resources located on the platform.
/// </summary>
public string DevicePath { get; set; }
/// <summary>
/// The connection settings of a device on an I2C bus.
/// </summary>
public override I2cConnectionSettings ConnectionSettings => _settings;
private unsafe void Initialize()
......@@ -33,7 +48,7 @@ namespace System.Device.I2c.Drivers
}
string deviceFileName = $"{DevicePath}-{_settings.BusId}";
lock (s_InitializationLock)
lock (s_initializationLock)
{
if (_deviceFileDescriptor >= 0)
{
......@@ -43,7 +58,7 @@ namespace System.Device.I2c.Drivers
if (_deviceFileDescriptor < 0)
{
throw new IOException($"Cannot open I2c device file '{deviceFileName}'");
throw new IOException($"Can not open I2C device file '{deviceFileName}'.");
}
I2cFunctionalityFlags tempFlags;
......@@ -96,16 +111,16 @@ namespace System.Device.I2c.Drivers
};
}
var tr = new i2c_rdwr_ioctl_data()
var msgset = new i2c_rdwr_ioctl_data()
{
msgs = messagesPtr,
nmsgs = (uint)messageCount
};
int result = Interop.ioctl(_deviceFileDescriptor, (uint)I2cSettings.I2C_RDWR, new IntPtr(&tr));
int result = Interop.ioctl(_deviceFileDescriptor, (uint)I2cSettings.I2C_RDWR, new IntPtr(&msgset));
if (result < 0)
{
throw new IOException("Error when attempting to perform the I2c data transfer.");
throw new IOException("Error performing I2C data transfer.");
}
}
......@@ -114,7 +129,7 @@ namespace System.Device.I2c.Drivers
int result = Interop.ioctl(_deviceFileDescriptor, (uint)I2cSettings.I2C_SLAVE_FORCE, (ulong)_settings.DeviceAddress);
if (result < 0)
{
throw new IOException("Error performing I2c data transfer");
throw new IOException("Error performing I2C data transfer.");
}
if (writeBuffer != null)
......@@ -122,7 +137,7 @@ namespace System.Device.I2c.Drivers
result = Interop.write(_deviceFileDescriptor, new IntPtr(writeBuffer), writeBufferLength);
if (result < 0)
{
throw new IOException("Error performing I2c data transfer");
throw new IOException("Error performing I2C data transfer.");
}
}
......@@ -131,11 +146,15 @@ namespace System.Device.I2c.Drivers
result = Interop.read(_deviceFileDescriptor, new IntPtr(readBuffer), readBufferLength);
if (result < 0)
{
throw new IOException("Error performing I2c data transfer");
throw new IOException("Error performing I2C data transfer.");
}
}
}
/// <summary>
/// Reads a byte from the I2C device.
/// </summary>
/// <returns>A byte read from the I2C device.</returns>
public override unsafe byte ReadByte()
{
Initialize();
......@@ -146,6 +165,13 @@ namespace System.Device.I2c.Drivers
return result;
}
/// <summary>
/// Reads data from the I2C device.
/// </summary>
/// <param name="buffer">
/// The buffer to read the data from the I2C device.
/// The length of the buffer determines how much data to read from the I2C device.
/// </param>
public override unsafe void Read(Span<byte> buffer)
{
Initialize();
......@@ -156,6 +182,10 @@ namespace System.Device.I2c.Drivers
}
}
/// <summary>
/// Writes a byte to the I2C device.
/// </summary>
/// <param name="data">The byte to be written to the I2C device.</param>
public override unsafe void WriteByte(byte data)
{
Initialize();
......@@ -164,6 +194,13 @@ namespace System.Device.I2c.Drivers
Transfer(&data, null, length, 0);
}
/// <summary>
/// Writes data to the I2C device.
/// </summary>
/// <param name="data">
/// The buffer that contains the data to be written to the I2C device.
/// The data should not include the I2C device address.
/// </param>
public override unsafe void Write(Span<byte> data)
{
Initialize();
......
......@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Device.I2c.Drivers
{
public class UnixI2cDevice : I2cDevice
......
......@@ -7,11 +7,18 @@ using WinI2c = Windows.Devices.I2c;
namespace System.Device.I2c.Drivers
{
/// <summary>
/// Represents an I2C communication channel running on Windows 10 IoT.
/// </summary>
public class Windows10I2cDevice : I2cDevice
{
private readonly I2cConnectionSettings _settings;
private WinI2c.I2cDevice _winDevice;
private WinI2c.I2cDevice _winI2cDevice;
/// <summary>
/// Initializes new instance of Windows10I2cDevice that will use the specified settings to communicate with the I2C device.
/// </summary>
/// <param name="settings">The connection settings of a device on an I2C bus.</param>
public Windows10I2cDevice(I2cConnectionSettings settings)
{
_settings = settings;
......@@ -23,46 +30,71 @@ namespace System.Device.I2c.Drivers
DeviceInformationCollection deviceInformationCollection = DeviceInformation.FindAllAsync(deviceSelector).WaitForCompletion();
if (deviceInformationCollection.Count == 0)
{
throw new ArgumentException($"No I2C device exists for BusId {settings.BusId}", $"{nameof(settings)}.{nameof(settings.BusId)}");
throw new ArgumentException($"No I2C device exists for bus ID {settings.BusId}.", $"{nameof(settings)}.{nameof(settings.BusId)}");
}
_winDevice = WinI2c.I2cDevice.FromIdAsync(deviceInformationCollection[0].Id, winSettings).WaitForCompletion();
if (_winDevice == null)
_winI2cDevice = WinI2c.I2cDevice.FromIdAsync(deviceInformationCollection[0].Id, winSettings).WaitForCompletion();
if (_winI2cDevice == null)
{
throw new PlatformNotSupportedException($"I2C devices are not supported.");
}
}
/// <summary>
/// The connection settings of a device on an I2C bus.
/// </summary>
public override I2cConnectionSettings ConnectionSettings => _settings;
/// <summary>
/// Reads a byte from the I2C device.
/// </summary>
/// <returns>A byte read from the I2C device.</returns>
public override byte ReadByte()
{
byte[] buffer = new byte[1];
_winDevice.Read(buffer);
_winI2cDevice.Read(buffer);
return buffer[0];
}
/// <summary>
/// Reads data from the I2C device.
/// </summary>
/// <param name="buffer">
/// The buffer to read the data from the I2C device.
/// The length of the buffer determines how much data to read from the I2C device.
/// </param>
public override void Read(Span<byte> buffer)
{
byte[] byteArray = new byte[buffer.Length];
_winDevice.Read(byteArray);
_winI2cDevice.Read(byteArray);
new Span<byte>(byteArray).CopyTo(buffer);
}
/// <summary>
/// Writes a byte to the I2C device.
/// </summary>
/// <param name="data">The byte to be written to the I2C device.</param>
public override void WriteByte(byte data)
{
_winDevice.Write(new[] { data });
_winI2cDevice.Write(new[] { data });
}
/// <summary>
/// Writes data to the I2C device.
/// </summary>
/// <param name="data">
/// The buffer that contains the data to be written to the I2C device.
/// The data should not include the I2C device address.
/// </param>
public override void Write(Span<byte> data)
{
_winDevice.Write(data.ToArray());
_winI2cDevice.Write(data.ToArray());
}
public override void Dispose(bool disposing)
{
_winDevice?.Dispose();
_winDevice = null;
_winI2cDevice?.Dispose();
_winI2cDevice = null;
base.Dispose(disposing);
}
......
......@@ -5,7 +5,7 @@
namespace System.Device.I2c
{
/// <summary>
/// The connection settings of a device on a I2C bus.
/// The connection settings of a device on an I2C bus.
/// </summary>
public sealed class I2cConnectionSettings
{
......@@ -14,8 +14,8 @@ namespace System.Device.I2c
/// <summary>
/// Initializes new instance of I2cConnectionSettings.
/// </summary>
/// <param name="busId">The bus ID the device is connected to.</param>
/// <param name="deviceAddress">The bus address of the device.</param>
/// <param name="busId">The bus ID the I2C device is connected to.</param>
/// <param name="deviceAddress">The bus address of the I2C device.</param>
public I2cConnectionSettings(int busId, int deviceAddress)
{
BusId = busId;
......@@ -23,12 +23,12 @@ namespace System.Device.I2c
}
/// <summary>
/// The bus ID the device is connected to.
/// The bus ID the I2C device is connected to.
/// </summary>
public int BusId { get; }
/// <summary>
/// The bus address of the device.
/// The bus address of the I2C device.
/// </summary>
public int DeviceAddress { get; }
}
......
......@@ -4,12 +4,44 @@
namespace System.Device.I2c
{
/// <summary>
/// The communications channel to a device on an I2C bus.
/// </summary>
public abstract class I2cDevice : IDisposable
{
/// <summary>
/// The connection settings of a device on an I2C bus.
/// </summary>
public abstract I2cConnectionSettings ConnectionSettings { get; }
/// <summary>
/// Reads a byte from the I2C device.
/// </summary>
/// <returns>A byte read from the I2C device.</returns>
public abstract byte ReadByte();
/// <summary>
/// Reads data from the I2C device.
/// </summary>
/// <param name="buffer">
/// The buffer to read the data from the I2C device.
/// The length of the buffer determines how much data to read from the I2C device.
/// </param>
public abstract void Read(Span<byte> buffer);
/// <summary>
/// Writes a byte to the I2C device.
/// </summary>
/// <param name="data">The byte to be written to the I2C device.</param>
public abstract void WriteByte(byte data);
/// <summary>
/// Writes data to the I2C device.
/// </summary>
/// <param name="data">
/// The buffer that contains the data to be written to the I2C device.
/// The data should not include the I2C device address.
/// </param>
public abstract void Write(Span<byte> data);
public void Dispose()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册