/// <summary> /// Close the SPI Channel /// </summary> public void Close() { if (ftHandle != IntPtr.Zero) { DllWraper.FT_SetBitMode(ftHandle, 0, 0); DllWraper.FT_Close(ftHandle); ftHandle = IntPtr.Zero; } }
/// <summary> /// Initialize the MPSSE /// </summary> /// <param name="index">the device index</param> /// <exception cref="FTDIException"></exception> public void FT_MPSSE_Init(int index = 0) { status = DllWraper.FT_Open(index, ref ftHandle); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Open FTDI device"); } status = DllWraper.FT_ResetDevice(ftHandle); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Reset FTDI device"); } status = DllWraper.FT_SetUSBParameters(ftHandle, 10000, 10000); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Set USB on FTDI"); } status = DllWraper.FT_SetLatencyTimer(ftHandle, 2); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Set Latency in FTDI"); } status = DllWraper.FT_SetFlowControl(ftHandle, 0x0100, 0x00, 0x00); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Set Flow Control in FTDI"); } status = DllWraper.FT_SetBitMode(ftHandle, 0, 0); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Reset FTDI Chip"); } status = DllWraper.FT_SetBitMode(ftHandle, 0, 2); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Initialize MPSSE on FTDI"); } status = DllWraper.FT_Purge(ftHandle, 3); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Initialize MPSSE on FTDI"); } // Config MPSSE byte[] outBuf = new byte[8]; byte[] inBuf = new byte[8]; uint szSent = 0, szRead = 0; IntPtr inptr = Marshal.AllocHGlobal(inBuf.Length); IntPtr outptr = Marshal.AllocHGlobal(outBuf.Length); outBuf[0] = 0x84; //Loopback Marshal.Copy(outBuf, 0, outptr, 8); status = DllWraper.FT_Write(ftHandle, outptr, 1, ref szSent); //Check Receive Data status = DllWraper.FT_GetQueueStatus(ftHandle, ref szRead); if (szRead != 0) { DllWraper.FT_SetBitMode(ftHandle, 0, 0); DllWraper.FT_Close(ftHandle); ftHandle = IntPtr.Zero; throw new FTDIException("MPSSE Initialization Error, MPSSE receive buffer not zero"); } //Bad Command outBuf[0] = 0xAB; Marshal.Copy(outBuf, 0, outptr, 8); status = DllWraper.FT_Write(ftHandle, outptr, 1, ref szSent); do { status = DllWraper.FT_GetQueueStatus(ftHandle, ref szRead); } while (szRead == 0 && status == FTStatus.OK); status = DllWraper.FT_Read(ftHandle, inptr, szRead, ref szRead); Marshal.Copy(inptr, inBuf, 0, (int)szRead); bool echod = false; for (int i = 0; i < szRead - 1; i++) { if (inBuf[i] == 0xFA && (inBuf[i + 1] == 0xAB)) { echod = true; break; } } if (!echod) { DllWraper.FT_Close(ftHandle); throw new FTDIException("Error in Sync the MPSSE"); } outBuf[0] = 0x85; Marshal.Copy(outBuf, 0, outptr, 1); status = DllWraper.FT_Write(ftHandle, outptr, 1, ref szSent); status = DllWraper.FT_GetQueueStatus(ftHandle, ref szRead); if (szRead != 0) { DllWraper.FT_SetBitMode(ftHandle, 0, 0); DllWraper.FT_Close(ftHandle); throw new FTDIException("MPSSE Receive Buffer not Empty"); } outBuf[0] = 0x8A; //Disable Clock Divide outBuf[1] = 0x8D; //Disable 3 phase data clocking outBuf[2] = 0x97; //Disable adaptive clocking Marshal.Copy(outBuf, 0, outptr, 3); status = DllWraper.FT_Write(ftHandle, outptr, 3, ref szSent); // Clean the unmanaged memory Marshal.FreeHGlobal(outptr); Marshal.FreeHGlobal(inptr); }