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
}
}
}