/// <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 + ")"); } })); }