public static EdInterfaceObd.InterfaceErrorResult InterfaceSetConfig(int baudRate, int dataBits, EdInterfaceObd.SerialParity parity, bool allowBitBang) { if (_handleFtdi == (IntPtr)0) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } try { Ftd2Xx.FT_STATUS ftStatus; _currentBaudRate = baudRate; _currentWordLength = dataBits; _currentParity = parity; #if USE_BITBANG bool bitBangOld = _bitBangMode; if (allowBitBang && _currentBaudRate <= 19200) { _bitBangMode = true; } else { _bitBangMode = false; } if (_bitBangMode) { byte[] sernum = new byte[16]; byte[] desc = new byte[64]; ftStatus = Ftd2Xx.FT_GetDeviceInfo(_handleFtdi, out _bitBangDeviceType, out _bitBangDeviceId, sernum, desc, IntPtr.Zero); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } int divisor; switch (_bitBangDeviceType) { case Ftd2Xx.FT_DEVICE.FT_DEVICE_232R: // tested range: 1-59 // good values: 27, 29!, 33, 35 divisor = 29; // only odd values allowed! _bitBangBitsPerSendByte = 12000000 / divisor / _currentBaudRate; _bitBangBitsPerRecByte = 12000000 / 16 / _currentBaudRate + 2; return(EdInterfaceObd.InterfaceErrorResult.DeviceTypeError); case Ftd2Xx.FT_DEVICE.FT_DEVICE_232H: divisor = 120000000 / 2 / 50 / 9600; _bitBangBitsPerSendByte = 120000000 / 2 / divisor / _currentBaudRate; _bitBangBitsPerRecByte = _bitBangBitsPerSendByte; break; default: return(EdInterfaceObd.InterfaceErrorResult.DeviceTypeError); } if (_bitBangMode != bitBangOld) { // set al to input to prevent start glitch ftStatus = Ftd2Xx.FT_SetBitMode(_handleFtdi, 0x00, Ftd2Xx.FT_BITMODE_ASYNC_BITBANG); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetDivisor(_handleFtdi, (UInt16)divisor); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetTimeouts(_handleFtdi, WriteTimeout, WriteTimeout); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetUSBParameters(_handleFtdi, BitBangRecBufferSize, 0x10000); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } if (!SetBitBangOutput(_bitBangOutput)) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetBitMode(_handleFtdi, (byte)(BitBangBits.Dtr | BitBangBits.Rts | BitBangBits.Txd), Ftd2Xx.FT_BITMODE_ASYNC_BITBANG); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_Purge(_handleFtdi, Ftd2Xx.FT_PURGE_TX | Ftd2Xx.FT_PURGE_RX); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } } return(EdInterfaceObd.InterfaceErrorResult.NoError); } #endif byte parityLocal; switch (parity) { case EdInterfaceObd.SerialParity.None: parityLocal = Ftd2Xx.FT_PARITY_NONE; break; case EdInterfaceObd.SerialParity.Even: parityLocal = Ftd2Xx.FT_PARITY_EVEN; break; case EdInterfaceObd.SerialParity.Odd: parityLocal = Ftd2Xx.FT_PARITY_ODD; break; case EdInterfaceObd.SerialParity.Mark: parityLocal = Ftd2Xx.FT_PARITY_MARK; break; case EdInterfaceObd.SerialParity.Space: parityLocal = Ftd2Xx.FT_PARITY_SPACE; break; default: return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } byte wordLengthLocal; switch (dataBits) { case 5: wordLengthLocal = Ftd2Xx.FT_BITS_5; break; case 6: wordLengthLocal = Ftd2Xx.FT_BITS_6; break; case 7: wordLengthLocal = Ftd2Xx.FT_BITS_7; break; case 8: wordLengthLocal = Ftd2Xx.FT_BITS_8; break; default: return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetBitMode(_handleFtdi, 0x00, Ftd2Xx.FT_BITMODE_RESET); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetUSBParameters(_handleFtdi, UsbBufferSizeStd, UsbBufferSizeStd); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetBaudRate(_handleFtdi, (uint)baudRate); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_SetDataCharacteristics(_handleFtdi, wordLengthLocal, Ftd2Xx.FT_STOP_BITS_1, parityLocal); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } ftStatus = Ftd2Xx.FT_Purge(_handleFtdi, Ftd2Xx.FT_PURGE_TX | Ftd2Xx.FT_PURGE_RX); if (ftStatus != Ftd2Xx.FT_STATUS.FT_OK) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } } catch (Exception) { return(EdInterfaceObd.InterfaceErrorResult.ConfigError); } return(EdInterfaceObd.InterfaceErrorResult.NoError); }