Esempio n. 1
0
        internal void SpiInitialize()
        {
            // Do we already have SPI setup?
            if (IsSpiModeEnabled)
            {
                // No need to initialize everything
                return;
            }

            GetHandle();
            IsSpiModeEnabled = true;
            var ftStatus = FtFunction.FT_SetLatencyTimer(_ftHandle, 1);

            ftStatus = FtFunction.FT_SetUSBParameters(_ftHandle, 65535, 65535);
            ftStatus = FtFunction.FT_SetChars(_ftHandle, 0, 0, 0, 0);
            ftStatus = FtFunction.FT_SetTimeouts(_ftHandle, 3000, 3000);
            ftStatus = FtFunction.FT_SetLatencyTimer(_ftHandle, 1);
            // Reset
            ftStatus = FtFunction.FT_SetBitMode(_ftHandle, 0x00, 0x00);
            // Enable MPSSE mode
            ftStatus = FtFunction.FT_SetBitMode(_ftHandle, 0x00, 0x02);
            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed to setup device {Description}, status: {ftStatus} in MPSSE mode");
            }

            // 50 ms according to thr doc for all USB to complete
            Thread.Sleep(50);
            DiscardInput();
            SetupMpsseMode();

            int         idx    = 0;
            Span <byte> toSend = stackalloc byte[10];

            toSend[idx++] = (byte)FtOpcode.DisableClockDivideBy5;
            toSend[idx++] = (byte)FtOpcode.TurnOffAdaptativeClocking;
            toSend[idx++] = (byte)FtOpcode.Disable3PhaseDataClocking;
            toSend[idx++] = (byte)FtOpcode.SetDataBitsLowByte;
            // Pin clock output, MISO output, MOSI input
            GpioLowDir = (byte)((GpioLowDir & 0xF8) | 0x03);
            // clock, MOSI and MISO to 0
            GpioLowData   = (byte)(GpioLowData & 0xF8);
            toSend[idx++] = GpioLowDir;
            toSend[idx++] = GpioLowData;
            // The SK clock frequency can be worked out by below algorithm with divide by 5 set as off
            // TCK period = 60MHz / (( 1 + [ (0xValueH * 256) OR 0xValueL] ) * 2)
            // Command to set clock divisor
            toSend[idx++] = (byte)FtOpcode.SetClockDivisor;
            uint clockDivisor = (uint)(60000 / ((ConnectionSettings[0].ClockFrequency / 1000) * 2) - 1);

            toSend[idx++] = (byte)(clockDivisor & 0xFF);
            toSend[idx++] = (byte)(clockDivisor >> 8);
            // loopback off
            toSend[idx++] = (byte)FtOpcode.DisconnectTDItoTDOforLoopback;
            Write(toSend);
            // Delay as in the documentation
            Thread.Sleep(30);
        }
Esempio n. 2
0
        /// <inheritdoc/>
        public void Reset()
        {
            var ftStatus = FtFunction.FT4222_I2CMaster_Reset(FtHandle);

            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed to reset: {ftStatus}");
            }
        }
Esempio n. 3
0
        /// <inheritdoc/>
        public void WriteEx(int slaveAddress, I2cMasterFlags flags, ReadOnlySpan <byte> buffer)
        {
            var ftStatus = FtFunction.FT4222_I2CMaster_WriteEx(FtHandle, (ushort)slaveAddress, (byte)flags, in MemoryMarshal.GetReference(buffer), (ushort)buffer.Length, out _);

            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"{nameof(WriteEx)} failed to write, error: {ftStatus}");
            }
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public void ReadEx(int slaveAddress, I2cMasterFlags flags, Span <byte> buffer)
        {
            var result = FtFunction.FT4222_I2CMaster_ReadEx(FtHandle, (ushort)slaveAddress, (byte)flags, in MemoryMarshal.GetReference(buffer), (ushort)buffer.Length, out _);

            if (result != FtStatus.Ok)
            {
                throw new IOException();
            }
        }
Esempio n. 5
0
        /// <inheritdoc/>
        public void Read(int slaveAddress, Span <byte> buffer)
        {
            var ftStatus = FtFunction.FT4222_I2CMaster_Read(FtHandle, (ushort)slaveAddress, in MemoryMarshal.GetReference(buffer), (ushort)buffer.Length, out _);

            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"{nameof(Read)} failed to read, error: {ftStatus}");
            }
        }
Esempio n. 6
0
        /// <inheritdoc/>
        public byte GetStatus()
        {
            var ftStatus = FtFunction.FT4222_I2CMaster_GetStatus(FtHandle, out var controllerStatus);

            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed to get status: {ftStatus}");
            }

            return(controllerStatus);
        }
Esempio n. 7
0
        /// <inheritdoc/>
        public FtVersion GetVersionValues()
        {
            var ftStatus = FtFunction.FT4222_GetVersion(FtHandle, out var ftVersion);

            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Can't find versions of chipset and FT4222, status: {ftStatus}");
            }

            return(ftVersion);
        }
Esempio n. 8
0
        internal void GetHandle()
        {
            if ((_ftHandle == null) || _ftHandle.IsClosed)
            {
                // Open device if not opened
                var ftStatus = FtFunction.FT_OpenEx(LocId, FtOpenType.OpenByLocation, out _ftHandle);

                if (ftStatus != FtStatus.Ok)
                {
                    throw new IOException($"Failed to open device {Description}, status: {ftStatus}");
                }
            }
        }
Esempio n. 9
0
        internal void InitializeGpio()
        {
            if (IsI2cModeEnabled || IsSpiModeEnabled)
            {
                return;
            }

            // Reset
            var ftStatus = FtFunction.FT_SetBitMode(_ftHandle, 0x00, 0x00);

            // Enable MPSSE mode
            ftStatus = FtFunction.FT_SetBitMode(_ftHandle, 0x00, 0x02);
            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed to setup device {Description}, status: {ftStatus} in MPSSE mode");
            }

            // 50 ms according to thr doc for all USB to complete
            Thread.Sleep(50);
            DiscardInput();
            SetupMpsseMode();
        }
Esempio n. 10
0
        internal void I2cInitialize()
        {
            GetHandle();
            // check is any of the first 3 GPIO are open
            if (PinOpen[0] || PinOpen[1] || PinOpen[2])
            {
                throw new IOException("Can't open I2C if GPIO 0, 1 or 2 are open");
            }

            if (IsSpiModeEnabled)
            {
                throw new IOException("Can't open I2C if SPI mode is used");
            }

            var ftStatus = FtFunction.FT_SetTimeouts(_ftHandle, 5000, 5000);

            ftStatus = FtFunction.FT_SetLatencyTimer(_ftHandle, 16);
            ftStatus = FtFunction.FT_SetFlowControl(_ftHandle, (ushort)FtFlowControl.FT_FLOW_RTS_CTS, 0x00, 0x00);
            ftStatus = FtFunction.FT_SetBitMode(_ftHandle, 0x00, 0x00);
            ftStatus = FtFunction.FT_SetBitMode(_ftHandle, 0x00, 0x02);

            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed to setup device {Description}, status: {ftStatus} in MPSSE mode");
            }

            IsI2cModeEnabled = true;
            DiscardInput();
            SetupMpsseMode();

            // Now setup the clock and other elements
            Span <byte> toSend = stackalloc byte[13];
            int         idx    = 0;

            // Disable clock divide by 5 for 60Mhz master clock
            toSend[idx++] = (byte)FtOpcode.DisableClockDivideBy5;
            // Turn off adaptive clocking
            toSend[idx++] = (byte)FtOpcode.TurnOffAdaptativeClocking;
            // Enable 3 phase data clock, used by I2C to allow data on both clock edges
            toSend[idx++] = (byte)FtOpcode.Enable3PhaseDataClocking;
            // The SK clock frequency can be worked out by below algorithm with divide by 5 set as off
            // TCK period = 60MHz / (( 1 + [ (0xValueH * 256) OR 0xValueL] ) * 2)
            // Command to set clock divisor
            toSend[idx++] = (byte)FtOpcode.SetClockDivisor;
            uint clockDivisor = 60000 / (I2cMasterFrequencyKbps * 2) - 1;

            toSend[idx++] = (byte)(clockDivisor & 0x00FF);
            toSend[idx++] = (byte)((clockDivisor >> 8) & 0x00FF);
            // loopback off
            toSend[idx++] = (byte)FtOpcode.DisconnectTDItoTDOforLoopback;
            // Enable the FT232H's drive-zero mode with the following enable mask
            toSend[idx++] = (byte)FtOpcode.SetIOOnlyDriveOn0AndTristateOn1;
            // Low byte (ADx) enables - bits 0, 1 and 2
            toSend[idx++] = 0x07;
            // High byte (ACx) enables - all off
            toSend[idx++] = 0x00;
            // Command to set directions of lower 8 pins and force value on bits set as output
            toSend[idx++] = (byte)FtOpcode.SetDataBitsLowByte;
            // SDA and SCL both output high (open drain)
            GpioLowData   = (byte)(I2cDataSDAhiSCLhi | (GpioLowData & 0xF8));
            GpioLowDir    = (byte)(I2cDirSDAoutSCLout | (GpioLowDir & 0xF8));
            toSend[idx++] = GpioLowData;
            toSend[idx++] = GpioLowDir;
            Write(toSend);
        }
Esempio n. 11
0
 private void Close()
 {
     FtFunction.FT4222_UnInitialize(FtHandle);
     FtFunction.FT_Close(FtHandle);
 }