private unsafe void Initialize() { if (_deviceFileDescriptor >= 0) { return; } lock (s_initializationLock) { // -1 means ignore Chip Select Line int chipSelectLine = _settings.ChipSelectLine == -1 ? 0 : _settings.ChipSelectLine; string deviceFileName = $"{DevicePath}{_settings.BusId}.{chipSelectLine}"; if (_deviceFileDescriptor >= 0) { return; } _deviceFileDescriptor = Interop.open(deviceFileName, FileOpenFlags.O_RDWR); if (_deviceFileDescriptor < 0) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not open SPI device file '{deviceFileName}'."); } UnixSpiMode mode = SpiSettingsToUnixSpiMode(); IntPtr nativePtr = new IntPtr(&mode); int result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MODE, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI mode to {_settings.Mode}."); } byte dataLengthInBits = (byte)_settings.DataBitLength; nativePtr = new IntPtr(&dataLengthInBits); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_BITS_PER_WORD, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI data bit length to {_settings.DataBitLength}."); } int clockFrequency = _settings.ClockFrequency; nativePtr = new IntPtr(&clockFrequency); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MAX_SPEED_HZ, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI clock frequency to {_settings.ClockFrequency}."); } } }
private UnixSpiMode SpiSettingsToUnixSpiMode() { UnixSpiMode mode = SpiModeToUnixSpiMode(_settings.Mode); if (_settings.ChipSelectLineActiveState == PinValue.High) { mode |= UnixSpiMode.SPI_CS_HIGH; } if (_settings.DataFlow == DataFlow.LsbFirst) { mode |= UnixSpiMode.SPI_LSB_FIRST; } return(mode); }
private unsafe void Initialize() { if (_deviceFileDescriptor >= 0) { return; } lock (s_InitializationLock) { string deviceFileName = $"{DevicePath}{_settings.BusId}.{_settings.ChipSelectLine}"; if (_deviceFileDescriptor >= 0) { return; } _deviceFileDescriptor = Interop.open(deviceFileName, FileOpenFlags.O_RDWR); if (_deviceFileDescriptor < 0) { throw new IOException($"Cannot open Spi device file '{deviceFileName}'"); } UnixSpiMode mode = SpiModeToUnixSpiMode(_settings.Mode); IntPtr nativePtr = new IntPtr(&mode); int result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MODE, nativePtr); if (result == -1) { throw new IOException($"Cannot set Spi mode to {_settings.Mode}"); } byte dataLengthInBits = (byte)_settings.DataBitLength; nativePtr = new IntPtr(&dataLengthInBits); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_BITS_PER_WORD, nativePtr); if (result == -1) { throw new IOException($"Cannot set Spi data bit length to {_settings.DataBitLength}"); } int clockFrequency = _settings.ClockFrequency; nativePtr = new IntPtr(&clockFrequency); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MAX_SPEED_HZ, nativePtr); if (result == -1) { throw new IOException($"Cannot set Spi clock frequency to {_settings.ClockFrequency}"); } } }
private unsafe void Initialize() { if (_deviceFileDescriptor >= 0) { return; } string deviceFileName = $"{DevicePath}{_settings.BusId}.{_settings.ChipSelectLine}"; _deviceFileDescriptor = open(deviceFileName, FileOpenFlags.O_RDWR); if (_deviceFileDescriptor < 0) { throw Utils.CreateIOException($"Cannot open Spi device file '{deviceFileName}'", _deviceFileDescriptor); } UnixSpiMode mode = SpiModeToUnixSpiMode(_settings.Mode); var ptr = new IntPtr(&mode); int ret = ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MODE, ptr); if (ret == -1) { throw Utils.CreateIOException($"Cannot set Spi mode to '{_settings.Mode}'", ret); } byte bits = (byte)_settings.DataBitLength; ptr = new IntPtr(&bits); ret = ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_BITS_PER_WORD, ptr); if (ret == -1) { throw Utils.CreateIOException($"Cannot set Spi data bit length to '{_settings.DataBitLength}'", ret); } uint speed = _settings.ClockFrequency; ptr = new IntPtr(&speed); ret = ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MAX_SPEED_HZ, ptr); if (ret == -1) { throw Utils.CreateIOException($"Cannot set Spi clock frequency to '{_settings.ClockFrequency}'", ret); } }
/// <summary> /// Initialize an SPI device /// </summary> /// <param name="devNode">Path to the /dev node</param> /// <param name="speed">Transfer speed in Hz</param> /// <param name="transferMode">Transfer mode</param> public unsafe SpiDevice(string devNode, int speed, int transferMode) { _speed = (uint)speed; _deviceFileDescriptor = Interop.open(devNode, FileOpenFlags.O_RDWR); if (_deviceFileDescriptor < 0) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not open SPI device file '{devNode}'."); } UnixSpiMode mode = transferMode switch { 0 => UnixSpiMode.SPI_MODE_0, 1 => UnixSpiMode.SPI_MODE_1, 2 => UnixSpiMode.SPI_MODE_2, 3 => UnixSpiMode.SPI_MODE_3, _ => throw new ArgumentException($"Transfer mode '{transferMode}' not regignized. Must be between 0 and 3."), }; IntPtr nativePtr = new IntPtr(&mode); int result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MODE, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI mode to {mode}."); } byte dataLengthInBits = 8; nativePtr = new IntPtr(&dataLengthInBits); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_BITS_PER_WORD, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI data bit length to 8."); } nativePtr = new IntPtr(&speed); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MAX_SPEED_HZ, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI clock frequency to {speed}."); } }
/// <summary> /// Initialize an SPI device /// </summary> /// <param name="devNode">Path to the /dev node</param> /// <param name="speed">Transfer speed in Hz</param> public unsafe SpiDevice(string devNode, int speed) { _speed = (uint)speed; _deviceFileDescriptor = Interop.open(devNode, FileOpenFlags.O_RDWR); if (_deviceFileDescriptor < 0) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not open SPI device file '{devNode}'."); } UnixSpiMode mode = UnixSpiMode.SPI_MODE_0; IntPtr nativePtr = new IntPtr(&mode); int result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MODE, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI mode to {mode}."); } byte dataLengthInBits = 8; nativePtr = new IntPtr(&dataLengthInBits); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_BITS_PER_WORD, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI data bit length to 8."); } nativePtr = new IntPtr(&speed); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MAX_SPEED_HZ, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI clock frequency to {speed}."); } }
private unsafe void Initialize() { if (_deviceFileDescriptor >= 0) { return; } lock (s_initializationLock) { // -1 means ignore Chip Select Line int chipSelectLine = _settings.ChipSelectLine == -1 ? 0 : _settings.ChipSelectLine; string deviceFileName = $"{DevicePath}{_settings.BusId}.{chipSelectLine}"; if (_deviceFileDescriptor >= 0) { return; } _deviceFileDescriptor = Interop.open(deviceFileName, FileOpenFlags.O_RDWR); if (_deviceFileDescriptor < 0) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not open SPI device file '{deviceFileName}'."); } UnixSpiMode mode = SpiSettingsToUnixSpiMode(); IntPtr nativePtr = new IntPtr(&mode); int result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MODE, nativePtr); if (result == -1) { // We should try the other mode and invert the buffers manually // RPI can't open Mode0 in LSB for example if (_settings.DataFlow == DataFlow.LsbFirst) { mode &= ~UnixSpiMode.SPI_LSB_FIRST; } else { mode |= UnixSpiMode.SPI_LSB_FIRST; } nativePtr = new IntPtr(&mode); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MODE, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI mode to {_settings.Mode}."); } _isInverted = true; } byte dataLengthInBits = (byte)_settings.DataBitLength; nativePtr = new IntPtr(&dataLengthInBits); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_BITS_PER_WORD, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI data bit length to {_settings.DataBitLength}."); } int clockFrequency = _settings.ClockFrequency; nativePtr = new IntPtr(&clockFrequency); result = Interop.ioctl(_deviceFileDescriptor, (uint)SpiSettings.SPI_IOC_WR_MAX_SPEED_HZ, nativePtr); if (result == -1) { throw new IOException($"Error {Marshal.GetLastWin32Error()}. Can not set SPI clock frequency to {_settings.ClockFrequency}."); } } }