diff --git a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.Linux.cs b/src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.Linux.cs similarity index 94% rename from src/System.Device.Gpio/System/Device/Spi/SpiDevice.Linux.cs rename to src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.Linux.cs index ea6e9bc049..0d1ed856e3 100644 --- a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.Linux.cs +++ b/src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.Linux.cs @@ -14,6 +14,6 @@ public abstract partial class SpiDevice : IDisposable /// /// The connection settings of a device on a SPI bus. /// A communications channel to a device on a SPI bus running on Unix. - public static SpiDevice Create(SpiConnectionSettings settings) => new Drivers.UnixSpiDevice(settings); + public static SpiDevice Create(SpiConnectionSettings settings) => new UnixSpiDevice(settings); } } diff --git a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.Windows.cs b/src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.Windows.cs similarity index 94% rename from src/System.Device.Gpio/System/Device/Spi/SpiDevice.Windows.cs rename to src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.Windows.cs index 132e98ea5e..1f0413a0f9 100644 --- a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.Windows.cs +++ b/src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.Windows.cs @@ -14,6 +14,6 @@ public abstract partial class SpiDevice : IDisposable /// /// The connection settings of a device on a SPI bus. /// A communications channel to a device on a SPI bus running on Windows 10 IoT. - public static SpiDevice Create(SpiConnectionSettings settings) => new Drivers.Windows10SpiDevice(settings); + public static SpiDevice Create(SpiConnectionSettings settings) => new Windows10SpiDevice(settings); } } diff --git a/src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs b/src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.cs similarity index 100% rename from src/System.Device.Gpio/System/Device/Spi/SpiDevice.cs rename to src/System.Device.Gpio/System/Device/Spi/Devices/SpiDevice.cs diff --git a/src/System.Device.Gpio/System/Device/Spi/Drivers/UnixSpiDevice.Linux.cs b/src/System.Device.Gpio/System/Device/Spi/Devices/UnixSpiDevice.Linux.cs similarity index 99% rename from src/System.Device.Gpio/System/Device/Spi/Drivers/UnixSpiDevice.Linux.cs rename to src/System.Device.Gpio/System/Device/Spi/Devices/UnixSpiDevice.Linux.cs index e3281344f8..30e500d8eb 100644 --- a/src/System.Device.Gpio/System/Device/Spi/Drivers/UnixSpiDevice.Linux.cs +++ b/src/System.Device.Gpio/System/Device/Spi/Devices/UnixSpiDevice.Linux.cs @@ -6,12 +6,12 @@ using System.IO; using System.Runtime.InteropServices; -namespace System.Device.Spi.Drivers +namespace System.Device.Spi { /// /// Represents an SPI communication channel running on Unix. /// - public class UnixSpiDevice : SpiDevice + internal class UnixSpiDevice : SpiDevice { private const string DefaultDevicePath = "/dev/spidev"; private const uint SPI_IOC_MESSAGE_1 = 0x40206b00; diff --git a/src/System.Device.Gpio/System/Device/Spi/Drivers/Windows10SpiDevice.Windows.cs b/src/System.Device.Gpio/System/Device/Spi/Devices/Windows10SpiDevice.Windows.cs similarity index 96% rename from src/System.Device.Gpio/System/Device/Spi/Drivers/Windows10SpiDevice.Windows.cs rename to src/System.Device.Gpio/System/Device/Spi/Devices/Windows10SpiDevice.Windows.cs index a3613f85e7..b98bd36a48 100644 --- a/src/System.Device.Gpio/System/Device/Spi/Drivers/Windows10SpiDevice.Windows.cs +++ b/src/System.Device.Gpio/System/Device/Spi/Devices/Windows10SpiDevice.Windows.cs @@ -1,141 +1,141 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Device.Gpio; -using Windows.Devices.Enumeration; -using WinSpi = Windows.Devices.Spi; - -namespace System.Device.Spi.Drivers -{ - /// - /// Represents an SPI communication channel running on Windows 10 IoT. - /// - public class Windows10SpiDevice : SpiDevice - { - private readonly SpiConnectionSettings _settings; - private WinSpi.SpiDevice _winDevice; - - /// - /// Initializes new instance of Windows10SpiDevice that will use the specified settings to communicate with the SPI device. - /// - /// - /// The connection settings of a device on a SPI bus. - /// - public Windows10SpiDevice(SpiConnectionSettings settings) - { - if (settings.DataFlow != DataFlow.MsbFirst || settings.ChipSelectLineActiveState != PinValue.Low) - { - throw new PlatformNotSupportedException($"Changing {nameof(settings.DataFlow)} or {nameof(settings.ChipSelectLineActiveState)} options is not supported on the current platform."); - } - - _settings = settings; - var winSettings = new WinSpi.SpiConnectionSettings(_settings.ChipSelectLine) - { - Mode = ToWinMode(settings.Mode), - DataBitLength = settings.DataBitLength, - ClockFrequency = settings.ClockFrequency, - }; - - string busFriendlyName = $"SPI{settings.BusId}"; - string deviceSelector = WinSpi.SpiDevice.GetDeviceSelector(busFriendlyName); - - DeviceInformationCollection deviceInformationCollection = DeviceInformation.FindAllAsync(deviceSelector).WaitForCompletion(); - if (deviceInformationCollection.Count == 0) - { - throw new ArgumentException($"No SPI device exists for bus ID {settings.BusId}.", $"{nameof(settings)}.{nameof(settings.BusId)}"); - } - - _winDevice = WinSpi.SpiDevice.FromIdAsync(deviceInformationCollection[0].Id, winSettings).WaitForCompletion(); - } - - /// - /// The connection settings of a device on a SPI bus. - /// - public override SpiConnectionSettings ConnectionSettings => _settings; - - /// - /// Reads a byte from the SPI device. - /// - /// A byte read from the SPI device. - public override byte ReadByte() - { - byte[] buffer = new byte[1]; - _winDevice.Read(buffer); - return buffer[0]; - } - - /// - /// Reads data from the SPI device. - /// - /// - /// The buffer to read the data from the SPI device. - /// The length of the buffer determines how much data to read from the SPI device. - /// - public override void Read(Span buffer) - { - if (buffer.Length == 0) - throw new ArgumentException($"{nameof(buffer)} cannot be empty."); - - byte[] byteArray = new byte[buffer.Length]; - _winDevice.Read(byteArray); - new Span(byteArray).CopyTo(buffer); - } - - /// - /// Writes a byte to the SPI device. - /// - /// The byte to be written to the SPI device. - public override void WriteByte(byte value) - { - _winDevice.Write(new[] { value }); - } - - /// - /// Writes data to the SPI device. - /// - /// - /// The buffer that contains the data to be written to the SPI device. - /// - public override void Write(ReadOnlySpan buffer) - { - _winDevice.Write(buffer.ToArray()); - } - - /// - /// Writes and reads data from the SPI device. - /// - /// The buffer that contains the data to be written to the SPI device. - /// The buffer to read the data from the SPI device. - public override void TransferFullDuplex(ReadOnlySpan writeBuffer, Span readBuffer) - { - if (writeBuffer.Length != readBuffer.Length) - { - throw new ArgumentException($"Parameters '{nameof(writeBuffer)}' and '{nameof(readBuffer)}' must have the same length."); - } - byte[] byteArray = new byte[readBuffer.Length]; - _winDevice.TransferFullDuplex(writeBuffer.ToArray(), byteArray); - byteArray.CopyTo(readBuffer); - } - - public override void Dispose(bool disposing) - { - _winDevice?.Dispose(); - _winDevice = null; - - base.Dispose(disposing); - } - - private static WinSpi.SpiMode ToWinMode(SpiMode mode) - { - return mode switch - { - SpiMode.Mode0 => WinSpi.SpiMode.Mode0, - SpiMode.Mode1 => WinSpi.SpiMode.Mode1, - SpiMode.Mode2 => WinSpi.SpiMode.Mode2, - SpiMode.Mode3 => WinSpi.SpiMode.Mode3, - _ => throw new ArgumentException($"SPI mode {mode} not supported.", nameof(mode)) - }; - } - } -} +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Device.Gpio; +using Windows.Devices.Enumeration; +using WinSpi = Windows.Devices.Spi; + +namespace System.Device.Spi +{ + /// + /// Represents an SPI communication channel running on Windows 10 IoT. + /// + internal class Windows10SpiDevice : SpiDevice + { + private readonly SpiConnectionSettings _settings; + private WinSpi.SpiDevice _winDevice; + + /// + /// Initializes new instance of Windows10SpiDevice that will use the specified settings to communicate with the SPI device. + /// + /// + /// The connection settings of a device on a SPI bus. + /// + public Windows10SpiDevice(SpiConnectionSettings settings) + { + if (settings.DataFlow != DataFlow.MsbFirst || settings.ChipSelectLineActiveState != PinValue.Low) + { + throw new PlatformNotSupportedException($"Changing {nameof(settings.DataFlow)} or {nameof(settings.ChipSelectLineActiveState)} options is not supported on the current platform."); + } + + _settings = settings; + var winSettings = new WinSpi.SpiConnectionSettings(_settings.ChipSelectLine) + { + Mode = ToWinMode(settings.Mode), + DataBitLength = settings.DataBitLength, + ClockFrequency = settings.ClockFrequency, + }; + + string busFriendlyName = $"SPI{settings.BusId}"; + string deviceSelector = WinSpi.SpiDevice.GetDeviceSelector(busFriendlyName); + + DeviceInformationCollection deviceInformationCollection = DeviceInformation.FindAllAsync(deviceSelector).WaitForCompletion(); + if (deviceInformationCollection.Count == 0) + { + throw new ArgumentException($"No SPI device exists for bus ID {settings.BusId}.", $"{nameof(settings)}.{nameof(settings.BusId)}"); + } + + _winDevice = WinSpi.SpiDevice.FromIdAsync(deviceInformationCollection[0].Id, winSettings).WaitForCompletion(); + } + + /// + /// The connection settings of a device on a SPI bus. + /// + public override SpiConnectionSettings ConnectionSettings => _settings; + + /// + /// Reads a byte from the SPI device. + /// + /// A byte read from the SPI device. + public override byte ReadByte() + { + byte[] buffer = new byte[1]; + _winDevice.Read(buffer); + return buffer[0]; + } + + /// + /// Reads data from the SPI device. + /// + /// + /// The buffer to read the data from the SPI device. + /// The length of the buffer determines how much data to read from the SPI device. + /// + public override void Read(Span buffer) + { + if (buffer.Length == 0) + throw new ArgumentException($"{nameof(buffer)} cannot be empty."); + + byte[] byteArray = new byte[buffer.Length]; + _winDevice.Read(byteArray); + new Span(byteArray).CopyTo(buffer); + } + + /// + /// Writes a byte to the SPI device. + /// + /// The byte to be written to the SPI device. + public override void WriteByte(byte value) + { + _winDevice.Write(new[] { value }); + } + + /// + /// Writes data to the SPI device. + /// + /// + /// The buffer that contains the data to be written to the SPI device. + /// + public override void Write(ReadOnlySpan buffer) + { + _winDevice.Write(buffer.ToArray()); + } + + /// + /// Writes and reads data from the SPI device. + /// + /// The buffer that contains the data to be written to the SPI device. + /// The buffer to read the data from the SPI device. + public override void TransferFullDuplex(ReadOnlySpan writeBuffer, Span readBuffer) + { + if (writeBuffer.Length != readBuffer.Length) + { + throw new ArgumentException($"Parameters '{nameof(writeBuffer)}' and '{nameof(readBuffer)}' must have the same length."); + } + byte[] byteArray = new byte[readBuffer.Length]; + _winDevice.TransferFullDuplex(writeBuffer.ToArray(), byteArray); + byteArray.CopyTo(readBuffer); + } + + public override void Dispose(bool disposing) + { + _winDevice?.Dispose(); + _winDevice = null; + + base.Dispose(disposing); + } + + private static WinSpi.SpiMode ToWinMode(SpiMode mode) + { + return mode switch + { + SpiMode.Mode0 => WinSpi.SpiMode.Mode0, + SpiMode.Mode1 => WinSpi.SpiMode.Mode1, + SpiMode.Mode2 => WinSpi.SpiMode.Mode2, + SpiMode.Mode3 => WinSpi.SpiMode.Mode3, + _ => throw new ArgumentException($"SPI mode {mode} not supported.", nameof(mode)) + }; + } + } +} diff --git a/src/System.Device.Gpio/System/Device/Spi/Drivers/UnixSpiDevice.Windows.cs b/src/System.Device.Gpio/System/Device/Spi/Drivers/UnixSpiDevice.Windows.cs deleted file mode 100644 index c91e58ef43..0000000000 --- a/src/System.Device.Gpio/System/Device/Spi/Drivers/UnixSpiDevice.Windows.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// 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.Spi.Drivers -{ - public class UnixSpiDevice : SpiDevice - { - public UnixSpiDevice(SpiConnectionSettings settings) => throw new PlatformNotSupportedException($"The {GetType().Name} class is not available on Windows."); - - public string DevicePath { get; set; } - - public override SpiConnectionSettings ConnectionSettings => throw new PlatformNotSupportedException(); - - public override void Read(Span buffer) => throw new PlatformNotSupportedException(); - - public override byte ReadByte() => throw new PlatformNotSupportedException(); - - public override void TransferFullDuplex(ReadOnlySpan writeBuffer, Span readBuffer) => throw new PlatformNotSupportedException(); - - public override void Write(ReadOnlySpan buffer) => throw new PlatformNotSupportedException(); - - public override void WriteByte(byte value) => throw new PlatformNotSupportedException(); - } -} diff --git a/src/System.Device.Gpio/System/Device/Spi/Drivers/Windows10SpiDevice.Linux.cs b/src/System.Device.Gpio/System/Device/Spi/Drivers/Windows10SpiDevice.Linux.cs deleted file mode 100644 index af9ea192f1..0000000000 --- a/src/System.Device.Gpio/System/Device/Spi/Drivers/Windows10SpiDevice.Linux.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// 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.Spi.Drivers -{ - public class Windows10SpiDevice : SpiDevice - { - public Windows10SpiDevice(SpiConnectionSettings settings) => - throw new PlatformNotSupportedException($"The {GetType().Name} class is not available on Linux."); - - public override SpiConnectionSettings ConnectionSettings => throw new PlatformNotSupportedException(); - - public override byte ReadByte() => throw new PlatformNotSupportedException(); - - public override void Read(Span buffer) => throw new PlatformNotSupportedException(); - - public override void WriteByte(byte value) => throw new PlatformNotSupportedException(); - - public override void Write(ReadOnlySpan buffer) => throw new PlatformNotSupportedException(); - - public override void TransferFullDuplex(ReadOnlySpan writeBuffer, Span readBuffer) => throw new PlatformNotSupportedException(); - } -} diff --git a/tools/DevicesApiTester/Commands/Spi/ReadBytes.cs b/tools/DevicesApiTester/Commands/Spi/ReadBytes.cs index 6b00177807..19ab1cca21 100644 --- a/tools/DevicesApiTester/Commands/Spi/ReadBytes.cs +++ b/tools/DevicesApiTester/Commands/Spi/ReadBytes.cs @@ -14,14 +14,9 @@ public class ReadBytes : SpiCommand, ICommandVerb { /// Executes the command. /// The command's exit code. - /// - /// NOTE: This test app uses the base class's method to create a device.
- /// Real-world usage would simply create an instance of a implementation: - /// using (var spi = SpiDevice.Create(connectionSettings)) - ///
public int Execute() { - Console.WriteLine($"ByteCount={ByteCount}, BusId={BusId}, ChipSelectLine={ChipSelectLine}, Mode={Mode}, DataBitLength={DataBitLength}, ClockFrequency={ClockFrequency}, Device={Device}"); + Console.WriteLine($"ByteCount={ByteCount}, BusId={BusId}, ChipSelectLine={ChipSelectLine}, Mode={Mode}, DataBitLength={DataBitLength}, ClockFrequency={ClockFrequency}"); var connectionSettings = new SpiConnectionSettings(BusId, ChipSelectLine) { @@ -30,7 +25,7 @@ public int Execute() Mode = Mode, }; - using (var spiDevice = CreateSpiDevice(connectionSettings)) + using (var spiDevice = SpiDevice.Create(connectionSettings)) { // Read bytes of data var buffer = new byte[ByteCount]; diff --git a/tools/DevicesApiTester/Commands/Spi/SpiCommand.cs b/tools/DevicesApiTester/Commands/Spi/SpiCommand.cs index b81dc09cbe..d3c2e0c4ac 100644 --- a/tools/DevicesApiTester/Commands/Spi/SpiCommand.cs +++ b/tools/DevicesApiTester/Commands/Spi/SpiCommand.cs @@ -24,13 +24,5 @@ public abstract class SpiCommand : DebuggableCommand [Option('f', "clock-frequency", HelpText = "the clock frequency in Hz for the connection", Required = false, Default = 500_000)] public int ClockFrequency { get; set; } - - [Option('d', "device", HelpText = "The SpiDevice to use: { Windows | UnixSysFs }", Required = true)] - public SpiDriverType Device { get; set; } - - protected SpiDevice CreateSpiDevice(SpiConnectionSettings connectionSettings) - { - return DriverFactory.CreateFromEnum(Device, connectionSettings); - } } } diff --git a/tools/DevicesApiTester/Commands/Spi/SpiDriverType.cs b/tools/DevicesApiTester/Commands/Spi/SpiDriverType.cs deleted file mode 100644 index a6cd3f0fe5..0000000000 --- a/tools/DevicesApiTester/Commands/Spi/SpiDriverType.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Device.Spi.Drivers; -using DeviceApiTester.Infrastructure; - -namespace DeviceApiTester.Commands.Spi -{ - public enum SpiDriverType - { - [ImplementationType(typeof(Windows10SpiDevice))] - Windows, - - [ImplementationType(typeof(UnixSpiDevice))] - Unix, - } -} diff --git a/tools/DevicesApiTester/Commands/Spi/SpiWriteBytes.cs b/tools/DevicesApiTester/Commands/Spi/SpiWriteBytes.cs index abb6c7b73a..21ee12b719 100644 --- a/tools/DevicesApiTester/Commands/Spi/SpiWriteBytes.cs +++ b/tools/DevicesApiTester/Commands/Spi/SpiWriteBytes.cs @@ -17,14 +17,9 @@ public class SpiWriteBytes : SpiCommand, ICommandVerb /// Executes the command. /// The command's exit code. - /// - /// NOTE: This test app uses the base class's method to create a device.
- /// Real-world usage would simply create an instance of a implementation: - /// using (var spi = SpiDevice.Create(connectionSettings)) - ///
public int Execute() { - Console.WriteLine($"Device={Device}, BusId={BusId}, ChipSelectLine={ChipSelectLine}, Mode={Mode}, DataBitLength={DataBitLength}, ClockFrequency={ClockFrequency}, HexString={HexString}"); + Console.WriteLine($"BusId={BusId}, ChipSelectLine={ChipSelectLine}, Mode={Mode}, DataBitLength={DataBitLength}, ClockFrequency={ClockFrequency}, HexString={HexString}"); var connectionSettings = new SpiConnectionSettings(BusId, ChipSelectLine) { @@ -33,7 +28,7 @@ public int Execute() Mode = Mode, }; - using (var spiDevice = CreateSpiDevice(connectionSettings)) + using (var spiDevice = SpiDevice.Create(connectionSettings)) { // This will verify value as in hexadecimal. var writeBuffer = HexStringUtilities.HexStringToByteArray(HexString); diff --git a/tools/DevicesApiTester/Commands/Spi/WriteRandomBytes.cs b/tools/DevicesApiTester/Commands/Spi/WriteRandomBytes.cs index 413a8a65b0..59ab0f9567 100644 --- a/tools/DevicesApiTester/Commands/Spi/WriteRandomBytes.cs +++ b/tools/DevicesApiTester/Commands/Spi/WriteRandomBytes.cs @@ -14,14 +14,9 @@ public class WriteRandomBytes : SpiCommand, ICommandVerb { /// Executes the command. /// The command's exit code. - /// - /// NOTE: This test app uses the base class's method to create a device.
- /// Real-world usage would simply create an instance of a implementation: - /// using (var spi = SpiDevice.Create(connectionSettings)) - ///
public int Execute() { - Console.WriteLine($"ByteCount={ByteCount}, BusId={BusId}, ChipSelectLine={ChipSelectLine}, Mode={Mode}, DataBitLength={DataBitLength}, ClockFrequency={ClockFrequency}, Device={Device}"); + Console.WriteLine($"ByteCount={ByteCount}, BusId={BusId}, ChipSelectLine={ChipSelectLine}, Mode={Mode}, DataBitLength={DataBitLength}, ClockFrequency={ClockFrequency}"); var connectionSettings = new SpiConnectionSettings(BusId, ChipSelectLine) { @@ -30,7 +25,7 @@ public int Execute() Mode = Mode, }; - using (var spiDevice = CreateSpiDevice(connectionSettings)) + using (var spiDevice = SpiDevice.Create(connectionSettings)) { // Write random bytes of data var buffer = new byte[ByteCount];