Example #1
0
        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);
        }
Example #3
0
        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);
            }
        }
Example #5
0
        /// <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}.");
            }
        }
Example #7
0
        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}.");
                }
            }
        }