/// <summary> /// Enable the chip select /// </summary> /// <param name="en">true low,false high</param> private void _CS_enable(bool en) { uint szSent = 0; byte[] datatosend = new byte[3]; datatosend[0] = 0x80; if (en) { datatosend[1] = 0x00; } else { datatosend[1] = 0x08; } datatosend[2] = 0xfb; IntPtr outptr = Marshal.AllocHGlobal(3); Marshal.Copy(datatosend, 0, outptr, 3); status = DllWraper.FT_Write(ftHandle, outptr, 3, ref szSent); if (status != FTStatus.OK) { throw new FTDIException(status, "send data Error"); } Marshal.FreeHGlobal(outptr); }
/// <summary> /// Send Data to SPI bus /// </summary> /// <param name="data">The data to be send</param> /// <param name="length">The length of data to be send</param> /// <returns>The real data sent out</returns> /// <remarks>The real data sent out is length +3</remarks> public int Write(byte[] data, int length) { if (length > data.Length) { throw new ArgumentOutOfRangeException("length", "length is over data Length"); } if (ftHandle == IntPtr.Zero) { throw new InvalidOperationException("FTDI device not initialized"); } byte OpCode = 0x00; switch (mode) { case SPIMode.MODE0: OpCode = 0x11; //Out Falling Edge break; case SPIMode.MODE1: OpCode = 0x10; //Out Rising Edge break; } byte[] datatosend; IntPtr outptr; uint szSent = 0, szRealOut = 0; int szToSend, lenremain = length; int i = 0; //First Make CS Low _CS_enable(true); // Then Shift the data out; while (lenremain > 0) { //Separate data in with maxinum 65536 bytes szToSend = (lenremain > 65536) ? 65536 : lenremain; lenremain -= szToSend; datatosend = new byte[szToSend + 3]; datatosend[0] = OpCode; // The 2 byte length datatosend[1] = (byte)((szToSend - 1) & 0x00ff); datatosend[2] = (byte)(((szToSend - 1) >> 8) & 0x00ff); Array.Copy(data, 65536 * i, datatosend, 3, szToSend); outptr = Marshal.AllocHGlobal(szToSend + 2); Marshal.Copy(datatosend, 0, outptr, szToSend + 3); status = DllWraper.FT_Write(ftHandle, outptr, (uint)szToSend + 3, ref szSent); if (status != FTStatus.OK) { throw new FTDIException(status, "send data Error"); } szRealOut += szSent; Marshal.FreeHGlobal(outptr); i++; System.Threading.Thread.Sleep(20); } // CS HIGH _CS_enable(false); return((int)szRealOut); }
/// <summary> /// Initialize the FTDI device /// </summary> /// <param name="info">The node info of FTDI device</param> /// <returns>The number of FTDI device connected</returns> /// <exception cref="FTDIException"> When there are failures in the procedure</exception> public uint FTDevInit(out FTDeviceListInfoNode[] info) { uint devNum = 0; status = DllWraper.FT_CreateDeviceInfoList(ref devNum); if (status != FTStatus.OK) { throw new FTDIException(status); } if (devNum == 0) { info = null; return(devNum); } // Allocate the memory for unmanaged data IntPtr ptrInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FTDeviceListInfoNode)) * (int)devNum); // Allocate memory for managed data info = new FTDeviceListInfoNode[devNum]; status = DllWraper.FT_GetDeviceInfoList(ptrInfo, ref devNum); if (status != FTStatus.OK) { throw new FTDIException(status); } for (int i = 0; i < devNum; i++) { IntPtr ptrElement = new IntPtr(ptrInfo.ToInt64() + Marshal.SizeOf(typeof(FTDeviceListInfoNode)) * i); FTDeviceListInfoNode node = (FTDeviceListInfoNode)Marshal.PtrToStructure(ptrElement, typeof(FTDeviceListInfoNode)); info[i] = node; } Marshal.FreeHGlobal(ptrInfo); return(devNum); }
/// <summary> /// Initialize the MPSSE /// </summary> /// <param name="index">the device index</param> 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, 64000, 64000); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Set USB on FTDI"); } status = DllWraper.FT_SetLatencyTimer(ftHandle, 10); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Set Latency 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"); } }
/// <summary> /// Initialize the spi interface /// </summary> /// <param name="clkdiv">The clock division of clock</param> /// <param name="mode">SPI Operation Mode</param> public void SPI_Init(ushort clkdiv = 0x0000, SPIMode mode = SPIMode.MODE0) { if (ftHandle == IntPtr.Zero) { throw new InvalidOperationException("The FTDI device is not initialized"); } byte[] outBuffer = new byte[8]; //byte[] inBuffer = new byte[8]; uint szWrite = 0; IntPtr outptr; //inptr = Marshal.AllocHGlobal(8); outptr = Marshal.AllocHGlobal(8); //SPI Clock Speed outBuffer[0] = 0x86; outBuffer[1] = (byte)(clkdiv & 0x00ff); outBuffer[2] = (byte)((clkdiv >> 8) & 0x00ff); outBuffer[3] = 0x80; outBuffer[4] = 0x08; // All low, CS High outBuffer[5] = 0xFB; // OOIOOOOO Marshal.Copy(outBuffer, 0, outptr, 6); status = DllWraper.FT_Write(ftHandle, outptr, 6, ref szWrite); outBuffer[0] = 0x82; outBuffer[1] = 0x0f; outBuffer[2] = 0x0f; Marshal.Copy(outBuffer, 0, outptr, 3); status = DllWraper.FT_Write(ftHandle, outptr, 3, ref szWrite); Marshal.FreeHGlobal(outptr); this.mode = mode; }
/// <summary> /// Get the Information of Channel /// </summary> /// <param name="channel">The index of channel</param> /// <exception cref="FTDIException">When Get channel information failed</exception> /// <returns>The Device Info Class</returns> public DeviceInfo GetChannelInfo(uint channel) { FTDeviceListInfoNode node = new FTDeviceListInfoNode(); status = SPIDllDriver.SPI_GetChannelInfo(channel, ref node); if (status != FTStatus.OK) { throw new FTDIException(status); } return(node); }
public void SPIInit(uint clock = 30000000, byte latency = 1, SPIConfigOption options = SPIConfigOption.MODE0 | SPIConfigOption.CS_DBUS3 | SPIConfigOption.CS_ACTIVELOW, uint pin = 0) { channelconfig = new ChannelConfig(); channelconfig.ClockRate = clock; channelconfig.LatencyTimer = latency; channelconfig.configOptions = (uint)options; channelconfig.Pin = pin; status = SPIDllDriver.SPI_InitChannel(ftHandle, ref channelconfig); if (status != FTStatus.OK) { throw new FTDIException(status, "Error in initializing spi channel"); } }
/// <summary> /// Read From SPI device /// </summary> /// <param name="length">The length of data to be read</param> /// <param name="buffer">The data to be stored</param> /// <exception cref="FTDIException">When failed to read from the spi channel.</exception> /// <returns>the real transfered length</returns> public uint Read(uint length, out byte[] buffer) { buffer = new byte[length]; uint sizetransfered = 0; if (ftHandle == IntPtr.Zero) { throw new NullReferenceException("The SPI Interface is not initialized!"); } status = SPIDllDriver.SPI_Read(ftHandle, ref buffer, (uint)length, ref sizetransfered, (uint)(SPITransferOption.SIZE_IN_BYTES | SPITransferOption.CHIPSELECT_ENABLE | SPITransferOption.CHIPSELECT_DISABLE)); if (status != FTStatus.OK) { throw new FTDIException(status, "Error is Reading From SPI bus!"); } return(sizetransfered); }
/// <summary> /// Send data to SPI bus /// </summary> /// <param name="buffer">The data to be send</param> /// <param name="length">The length of data to be send, this number must smaller than the legnth of data</param> /// <returns>The real length send out</returns> public uint Write(byte[] buffer, uint length = 0) { uint sizetransfered = 0; if (buffer.Length < length) { throw new ArgumentOutOfRangeException("length", "The length given in arguments is out of data length"); } if (length == 0) { length = (uint)buffer.Length; } if (ftHandle == IntPtr.Zero) { throw new NullReferenceException("The SPI Interface is not initialized!"); } status = SPIDllDriver.SPI_Write(ftHandle, buffer, length, ref sizetransfered, (uint)(SPITransferOption.SIZE_IN_BYTES | SPITransferOption.CHIPSELECT_ENABLE | SPITransferOption.CHIPSELECT_DISABLE)); if (status != FTStatus.OK) { throw new FTDIException(status, "Error is Send data to SPI bus!"); } return(sizetransfered); }
/// <summary> /// Read Write data on SPI /// </summary> /// <param name="indata">data send to SPI</param> /// <param name="outdata">data read from SPI</param> /// <param name="length">the lenght to send/receive </param> /// <returns>the real numbers of data sent/received </returns> public uint ReadWrite(byte[] indata, out byte[] outdata, uint length) { uint sizetransfered = 0; outdata = new byte[length]; if (indata.Length < length) { throw new ArgumentOutOfRangeException("length", "The length given in arguments is out of data length"); } if (length == 0) { length = (uint)indata.Length; } if (ftHandle == IntPtr.Zero) { throw new NullReferenceException("The SPI Interface is not initialized!"); } status = SPIDllDriver.SPI_ReadWrite(ftHandle, indata, ref outdata, length, ref sizetransfered, (uint)(SPITransferOption.SIZE_IN_BYTES | SPITransferOption.CHIPSELECT_ENABLE | SPITransferOption.CHIPSELECT_DISABLE)); if (status != FTStatus.OK) { throw new FTDIException(status, "Error in ReadWrite data on SPI bus!"); } return(sizetransfered); }
public int ReadWrite(byte[] dSend, ref byte[] dRecv, int length) { if (length > dSend.Length || length > dRecv.Length) { throw new ArgumentOutOfRangeException("length", "The length is over data length"); } if (ftHandle == IntPtr.Zero) { throw new InvalidOperationException("SPI device not initialized"); } byte OpCode = 0x00; switch (mode) { case SPIMode.MODE0: OpCode = 0x31; //Out Falling Edge break; case SPIMode.MODE1: OpCode = 0x34; //Out Rising Edge break; } int lenremain = length, i = 0, szTransfered = 0; uint szToTransfer = 0, szSent = 0, szRead = 0; IntPtr ptrIn, ptrOut; byte[] dIn, dOut; _CS_enable(true); while (lenremain > 0) { szToTransfer = (lenremain > 65536) ? 65536 : (uint)lenremain; lenremain -= (int)szToTransfer; dIn = new byte[szToTransfer]; dOut = new byte[szToTransfer + 3]; dOut[0] = OpCode; dOut[1] = (byte)((szToTransfer - 1) & 0xff); dOut[2] = (byte)(((szToTransfer - 1) >> 8) & 0xff); Array.Copy(dSend, i * 65536, dOut, 3, szToTransfer); ptrOut = Marshal.AllocHGlobal((int)szToTransfer + 3); Marshal.Copy(dOut, 0, ptrOut, dOut.Length); status = DllWraper.FT_Write(ftHandle, ptrOut, szToTransfer + 3, ref szSent); System.Threading.Thread.Sleep(20); do { status = DllWraper.FT_GetQueueStatus(ftHandle, ref szRead); System.Threading.Thread.Sleep(20); } while (szRead != szToTransfer && status == FTStatus.OK); ptrIn = Marshal.AllocHGlobal((int)szToTransfer); status = DllWraper.FT_Read(ftHandle, ptrIn, szToTransfer, ref szRead); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Read data"); } Marshal.Copy(ptrIn, dIn, 0, (int)szToTransfer); Array.Copy(dIn, 0, dRecv, i * 65536, szToTransfer); szTransfered += (int)szRead; Marshal.FreeHGlobal(ptrIn); Marshal.FreeHGlobal(ptrOut); i++; } _CS_enable(false); return(szTransfered); }
/// <summary> /// Read Data from SPI /// </summary> /// <param name="data">the read data</param> /// <param name="length">The length of data to read</param> /// <returns>The real read bytes</returns> public int Read(ref byte[] data, int length) { if (data.Length < length) { throw new IndexOutOfRangeException("The data doesn't have enough memory"); } if (ftHandle == IntPtr.Zero) { throw new InvalidOperationException("SPI Driver not initialized"); } byte[] ftcmd = new byte[3]; IntPtr ptrCmd = Marshal.AllocHGlobal(3); IntPtr ptrRead; switch (mode) { case SPIMode.MODE0: ftcmd[0] = 0x20; //In in rising edge break; case SPIMode.MODE1: ftcmd[0] = 0x24; // In in falling edge break; } int lenreamin = length, i = 0, szReceiveAll = 0; uint szSent = 0, szToRead = 0, szRead = 0; _CS_enable(true); while (lenreamin > 0) { szToRead = (lenreamin > 65536) ? 65536 : (uint)lenreamin; lenreamin -= (int)szToRead; ptrRead = Marshal.AllocHGlobal((int)szToRead); ftcmd[1] = (byte)((szToRead - 1) & 0x00ff); ftcmd[2] = (byte)(((szToRead - 1) >> 8) & 0x00ff); Marshal.Copy(ftcmd, 0, ptrCmd, 3); status = DllWraper.FT_Write(ftHandle, ptrCmd, 3, ref szSent); if (status != FTStatus.OK) { throw new FTDIException(status, "Error in sending reading command"); } do { status = DllWraper.FT_GetQueueStatus(ftHandle, ref szRead); System.Threading.Thread.Sleep(20); } while (szRead != szToRead && status == FTStatus.OK); status = DllWraper.FT_Read(ftHandle, ptrRead, szToRead, ref szRead); if (status != FTStatus.OK) { throw new FTDIException(status, "Cannot Read data"); } Marshal.Copy(ptrRead, data, i * 65536, (int)szRead); szReceiveAll += (int)szRead; Marshal.FreeHGlobal(ptrRead); } _CS_enable(false); return(szReceiveAll); }
public FTException(FTStatus status) : base("Call failed: " + status) { API = "Unknown"; Status = status; }
public FTDIException(FTStatus status, string message, Exception inner) : base("FTDI Driver Returned Status:" + status + "Type:" + Enum.GetName(typeof(FTStatus), status) + " Message: " + message, inner) { }
/// <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); }
public FTDIException(FTStatus status) : base("FTDI Driver Returned Status:" + status + "Type:" + Enum.GetName(typeof(FTStatus), status)) { }
public FTException(string api, FTStatus status) : base("'" + api + "' call failed: " + status) { API = api; Status = status; }
/// <summary> /// Opens a connection to the ledstrip controller with the specified controller number. /// </summary> /// <param name="ControllerNumber">The controller number.</param> public void Open(int ControllerNumber) { lock (FT245RLocker) { Close(); bool OK = false; string Desc = ""; this.ControllerNumber = ControllerNumber; FT245R = new FTDI(); FTDI.FT_STATUS FTStatus; //Get number of devices uint DeviceCnt = 0; FTStatus = FT245R.GetNumberOfDevices(ref DeviceCnt); if (FTStatus == FTDI.FT_STATUS.FT_OK && DeviceCnt > 0) { FTDI.FT_DEVICE_INFO_NODE[] Devices = new FTDI.FT_DEVICE_INFO_NODE[DeviceCnt]; //for (uint i = 0; i < DeviceCnt; i++) //{ // FTStatus = FT245R.OpenByIndex(i); // // Log.Write("Open {0}: Result: {1}".Build(i, FTStatus.ToString())); // if (FT245R.IsOpen) // { // string D = ""; // FT245R.GetDescription(out D); // Log.Write("Desc: {0}".Build(D)); // try // { // FTStatus = FT245R.Close(); // Log.Write("Close {i}: Result: {1}".Build(i, FTStatus.ToString())); // } // catch { } // } //} //Log.Write("All listed"); FTStatus = FT245R.GetDeviceList(Devices); if (FTStatus == FTDI.FT_STATUS.FT_OK) { foreach (FTDI.FT_DEVICE_INFO_NODE DI in Devices) { if (DI != null && DI.Type == FTDI.FT_DEVICE.FT_DEVICE_232R) { if (ControllerNameBase.Any(N => DI.Description == N.Trim() + " " + ControllerNumber)) { Desc = DI.Description; FT245R.CharReceived += new EventHandler <EventArgs>(FT245R_CharReceived); FTStatus = FT245R.OpenByLocation(DI.LocId); if (FTStatus == FTDI.FT_STATUS.FT_OK) { FTStatus = FT245R.Purge(FTDI.FT_PURGE.FT_PURGE_RX + FTDI.FT_PURGE.FT_PURGE_TX); if (FTStatus == FTDI.FT_STATUS.FT_OK) { OK = true; break; } else { Log.Exception("Purge failed for WS2811StripController {0}. Error: {1}".Build(ControllerNumber, FTStatus.ToString())); } } else { Log.Exception("Open failed for WS2811StripController {0}. Error: {1}".Build(ControllerNumber, FTStatus.ToString())); } } } } } else { Log.Exception("Could not fetch devicelist for WS2811StripControllers. Error: {0}".Build(FTStatus.ToString())); } } if (!OK) { if (!Desc.IsNullOrWhiteSpace()) { Log.Warning("{0} detected, but could not open connection.".Build(Desc)); } else { Log.Warning("Direct Strip Controller with number {0} not found.".Build(ControllerNumber)); } Close(); } else { Log.Write("{0} detected and connection opend.".Build(Desc)); } } }