/// <summary> /// Gets all available FTDI-based bus devices. /// </summary> /// <returns>A list of <see cref="IBusDevice">devices</see> communicating to a bus.</returns> public Task <IEnumerable <IBusDevice> > GetConnectors() { return(Task.Factory.StartNew(() => { FTDI.FT_STATUS status; // Determine the number of channels on all FTDI devices connected to the machine uint channelCount; status = I2C.NativeMethods_I2C.I2C_GetNumChannels(out channelCount); if (status != FTDI.FT_STATUS.FT_OK) { throw new Exception("Unable to retrieve number of channels on devices connected to computer. (Result: " + status + ")"); } var allNodes = new List <NativeMethods.FT_DEVICE_LIST_INFO_NODE>((int)channelCount); for (int i = 0; i < channelCount; i++) { var deviceInfo = new NativeMethods.FT_DEVICE_LIST_INFO_NODE(); status = I2C.NativeMethods_I2C.I2C_GetChannelInfo((uint)i, deviceInfo); if (status != FTDI.FT_STATUS.FT_OK) { throw new Exception("Unable to retrieve information about I2C channel. (Status: " + status + ")"); } allNodes.Add(deviceInfo); } var devices = new List <IBusDevice>(); foreach (var group in allNodes.GroupBy(x => x.SerialNumber)) { int deviceChannelIndex = 0; foreach (var deviceInfo in group) { devices.Add(new I2C.Device(deviceInfo, deviceChannelIndex)); deviceChannelIndex++; } } return (IEnumerable <IBusDevice>)devices; })); }
/// <summary> /// Connects to the FTDI device. /// </summary> /// <param name="serialNumber">A FTDI device serial number.</param> /// <param name="deviceChannelIndex">A channel index in the device.</param> public virtual Task Connect(string serialNumber, int deviceChannelIndex) { return(Task.Run(() => { FTDI.FT_STATUS status; NativeMethods.Init_libMPSSE(); // Find requested channel uint channelCount; status = NativeMethods_I2C.I2C_GetNumChannels(out channelCount); if (status != FTDI.FT_STATUS.FT_OK) { throw new CommunicationException("Unable to find number of I2C channels. (Status: " + status + ")"); } uint channelIndex; var deviceNode = new NativeMethods.FT_DEVICE_LIST_INFO_NODE(); var tmpChannelIndex = deviceChannelIndex; for (channelIndex = 0; channelIndex < channelCount; channelIndex++) { status = NativeMethods_I2C.I2C_GetChannelInfo(0, deviceNode); if (status != FTDI.FT_STATUS.FT_OK) { throw new CommunicationException("Unable to get information about channel " + channelIndex + ". (Status: " + status + ")"); } if (deviceNode.SerialNumber == serialNumber) { if (tmpChannelIndex > 0) { tmpChannelIndex--; } else { break; } } } if (channelIndex >= channelCount) { throw new CommunicationException("Unable to find channel " + deviceChannelIndex + " on device with serial number '" + serialNumber + "'."); } this.DeviceNode = deviceNode; // Open channel IntPtr handle; status = NativeMethods_I2C.I2C_OpenChannel(channelIndex, out handle); if (status != FTDI.FT_STATUS.FT_OK) { throw new CommunicationException("Unable to open I2C channel. (Status: " + status + ")"); } this.ChannelHandle = handle; // Configure channel // NativeMethods.ClockRate.Standard var config = new NativeMethods_I2C.ChannelConfig((NativeMethods_I2C.ClockRate) 10000, 1, NativeMethods_I2C.ConfigOptions.I2C_ENABLE_DRIVE_ONLY_ZERO); status = NativeMethods_I2C.I2C_InitChannel(this.ChannelHandle, config); if (status != FTDI.FT_STATUS.FT_OK) { throw new CommunicationException("Unable to initialize I2C channel. (Status: " + status + ")"); } })); }
/// <summary> /// Initializes a new instance of the <see cref="Device"/> class. /// </summary> /// <param name="deviceNode">A FTDI device info node.</param> /// <param name="deviceChannelIndex">A channel index.</param> public Device(NativeMethods.FT_DEVICE_LIST_INFO_NODE deviceNode, int deviceChannelIndex) : base(deviceNode, deviceChannelIndex) { }
/// <summary> /// Connects to the FTDI device. /// </summary> /// <param name="serialNumber">A FTDI device serial number.</param> /// <param name="deviceChannelIndex">A channel index in the device.</param> public virtual Task Connect(string serialNumber, int deviceChannelIndex) { return(Task.Run(() => { FTDI.FT_STATUS status; NativeMethods.Init_libMPSSE(); // Find requested channel uint channelCount; status = SPI.NativeMethods_SPI.SPI_GetNumChannels(out channelCount); if (status != FTDI.FT_STATUS.FT_OK) { throw new InvalidOperationException("Unable to find number of SPI channels. (Status: " + status + ")"); } uint channelIndex; var deviceNode = new NativeMethods.FT_DEVICE_LIST_INFO_NODE(); var tmpChannelIndex = deviceChannelIndex; for (channelIndex = 0; channelIndex < channelCount; channelIndex++) { status = SPI.NativeMethods_SPI.SPI_GetChannelInfo(0, deviceNode); if (status != FTDI.FT_STATUS.FT_OK) { throw new InvalidOperationException("Unable to get information about channel " + channelIndex + ". (Status: " + status + ")"); } if (deviceNode.SerialNumber == serialNumber) { if (tmpChannelIndex > 0) { tmpChannelIndex--; } else { break; } } } if (channelIndex >= channelCount) { throw new InvalidOperationException("Unable to find channel " + deviceChannelIndex + " on device with serial number '" + serialNumber + "'."); } this.DeviceNode = deviceNode; // Open channel IntPtr handle; status = SPI.NativeMethods_SPI.SPI_OpenChannel(channelIndex, out handle); if (status != FTDI.FT_STATUS.FT_OK) { throw new InvalidOperationException("Unable to open SPI channel. (Status: " + status + ")"); } this.ChannelHandle = handle; // Configure channel var configOptions = SPI.NativeMethods_SPI.ConfigOptions.SPI_CONFIG_OPTION_MODE0 | SPI.NativeMethods_SPI.ConfigOptions.SPI_CONFIG_OPTION_CS_DBUS3 | SPI.NativeMethods_SPI.ConfigOptions.SPI_CONFIG_OPTION_CS_ACTIVELOW; var config = new SPI.NativeMethods_SPI.ChannelConfig(250000, 2, configOptions, 0); status = SPI.NativeMethods_SPI.SPI_InitChannel(this.ChannelHandle, config); if (status != FTDI.FT_STATUS.FT_OK) { throw new InvalidOperationException("Unable to initialize SPI channel. (Status: " + status + ")"); } })); }