예제 #1
0
        /// <summary>
        /// Create an SPI FT4222 class
        /// </summary>
        /// <param name="settings">SPI Connection Settings</param>
        public Ft4222Spi(SpiConnectionSettings settings)
        {
            _settings = settings;
            // Check device
            var devInfos = FtCommon.GetDevices();

            if (devInfos.Count == 0)
            {
                throw new IOException("No FTDI device available");
            }

            // Select the one from bus Id
            // FT4222 propose depending on the mode multiple interfaces. Only the A is available for SPI or where there is none as it's the only interface
            var devInfo = devInfos.Where(m => m.Description == "FT4222 A" || m.Description == "FT4222").ToArray();

            if ((devInfo.Length == 0) || (devInfo.Length < _settings.BusId))
            {
                throw new IOException($"Can't find a device to open SPI on index {_settings.BusId}");
            }

            DeviceInformation = devInfo[_settings.BusId];
            // Open device
            var ftStatus = FtFunction.FT_OpenEx(DeviceInformation.LocId, FtOpenType.OpenByLocation, out _ftHandle);

            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed to open device {DeviceInformation.Description} with error: {ftStatus}");
            }

            // Set the clock but we need some math
            var(ft4222Clock, tfSpiDiv) = CalculateBestClockRate();

            ftStatus = FtFunction.FT4222_SetClock(_ftHandle, ft4222Clock);
            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed set clock rate {ft4222Clock} on device: {DeviceInformation.Description}with error: {ftStatus}");
            }


            SpiClockPolarity pol = SpiClockPolarity.ClockIdleLow;

            if ((_settings.Mode == SpiMode.Mode2) || (_settings.Mode == SpiMode.Mode3))
            {
                pol = SpiClockPolarity.ClockIdelHigh;
            }

            SpiClockPhase pha = SpiClockPhase.ClockLeading;

            if ((_settings.Mode == SpiMode.Mode1) || (_settings.Mode == SpiMode.Mode3))
            {
                pha = SpiClockPhase.ClockTailing;
            }

            // Configure the SPI
            ftStatus = FtFunction.FT4222_SPIMaster_Init(_ftHandle, SpiOperatingMode.Single, tfSpiDiv, pol, pha, (byte)_settings.ChipSelectLine);
            if (ftStatus != FtStatus.Ok)
            {
                throw new IOException($"Failed setup SPI on device: {DeviceInformation.Description} with error: {ftStatus}");
            }
        }