using System; using System.Collections.Generic; using System.Linq; using System.Text; using libMPSSEWrapper.Exceptions; using libMPSSEWrapper.Types; namespace libMPSSEWrapper.Spi { /// /// The chass definitions for SpiDevice /// public abstract class SpiDevice : IDisposable { private static IntPtr _handle = IntPtr.Zero; private static FtdiChannelConfig _currentGlobalConfig; private FtdiChannelConfig _cfg; private bool _isDisposed; private SpiConfiguration _spiConfig; /// /// Constructor for the SPI Device in the LibMpsseSpi Wrapper /// /// protected SpiDevice(FtdiChannelConfig config) : this(config, null) { } /// /// Constructor for the SPI Device in the LibMpsseSpi Wrapper /// /// /// protected SpiDevice(FtdiChannelConfig config, SpiConfiguration spiConfig) { _spiConfig = spiConfig ?? SpiConfiguration.ChannelZeroConfiguration; _cfg = config; InitLibAndHandle(); } /// /// Destructor for the SPI Device in the LibMpsseSpi Wrapper /// //~SpiDevice() //{ // FtResult result; // result = LibMpsseSpi.SPI_CloseChannel(_handle); //} private void InitLibAndHandle() { FtResult result; if (_handle != IntPtr.Zero) return; LibMpsse.Init(); result = LibMpsseSpi.SPI_OpenChannel(_spiConfig.ChannelIndex, out _handle); CheckResult(result); if (_handle == IntPtr.Zero) throw new SpiChannelNotConnectedException(FtResult.InvalidHandle); result = LibMpsseSpi.SPI_InitChannel(_handle, ref _cfg); CheckResult(result); _currentGlobalConfig = _cfg; } /// /// The Wrapper for SPI_Write() /// /// /// /// /// /// protected FtResult Write(byte[] buffer, int sizeToTransfer, out int sizeTransfered, FtSpiTransferOptions options) { EnforceRightConfiguration(); return LibMpsseSpi.SPI_Write(_handle, buffer, sizeToTransfer, out sizeTransfered, options); } /// /// The Wrapper for Write() /// /// /// /// /// protected FtResult Write(byte[] buffer, out int sizeTransfered, FtSpiTransferOptions options) { return Write(buffer, buffer.Length, out sizeTransfered, options); } /// /// The Wrapper for Write() /// /// /// /// /// protected FtResult Write(byte[] buffer, int sizeToTransfer, out int sizeTransfered) { return Write(buffer, sizeToTransfer, out sizeTransfered, FtSpiTransferOptions.ToogleChipSelect); } /// /// The Wrapper for Write() /// /// /// /// protected FtResult Write(byte[] buffer, out int sizeTransfered) { return Write(buffer, out sizeTransfered, FtSpiTransferOptions.ToogleChipSelect); } /// /// The Wrapper for Read() /// /// /// /// /// /// protected FtResult Read(byte[] buffer, int sizeToTransfer, out int sizeTransfered, FtSpiTransferOptions options) { EnforceRightConfiguration(); return LibMpsseSpi.SPI_Read(_handle, buffer, sizeToTransfer, out sizeTransfered, options); } /// /// The Wrapper for Read() /// /// /// /// /// protected FtResult Read(byte[] buffer, out int sizeTransfered, FtSpiTransferOptions options) { return Read(buffer, buffer.Length, out sizeTransfered, options); } /// /// The Wrapper for Read() /// /// /// /// /// protected FtResult Read(byte[] buffer,int sizeToTransfer, out int sizeTransfered) { return Read(buffer, buffer.Length, out sizeTransfered, FtSpiTransferOptions.ToogleChipSelect); } /// /// The Wrapper for Read() /// /// /// /// protected FtResult Read(byte[] buffer, out int sizeTransfered) { return Read(buffer, out sizeTransfered, FtSpiTransferOptions.ToogleChipSelect); } /// /// Throw an Exception if the I/O didn't work correctly /// /// protected static void CheckResult(FtResult result) { if (result != FtResult.Ok) throw new SpiChannelNotConnectedException(result); } private void EnforceRightConfiguration() { if (_currentGlobalConfig.configOptions != _cfg.configOptions) { LibMpsseSpi.SPI_ChangeCS(_handle, _cfg.configOptions); _currentGlobalConfig = _cfg; } } /// /// Dispose of the LibMpsseSpi Wrapper /// public void Dispose() { //FtResult result; if (_isDisposed) return; _isDisposed = true; //Yes we are disposed //result = LibMpsseSpi.SPI_CloseChannel(_handle); //Close the SPI channel //_handle = IntPtr.Zero; //Zero the handle LibMpsse.Cleanup(); //Cleanup the library } } }