如何使用 FTD2XX_NET 将 FTDI 的 BDBUS 用于 SPI

问题描述 投票:0回答:1

我正在尝试使用 FT4232 端口进行 SPI 通信。 为此,我使用通常的 SPI 配置(AD0 -> SCK、AD1 -> MOSI、AD2 -> MISO、AD3 -> CS)将 ADBUS 用于 SPI。

现在我必须使用 BDBUS 中可用的 SPI。据我了解,FT4232 允许在 BDBUS 中使用 SPI。到目前为止,我一直坚持使用 BDBUS。

使用ADBUS的代码如下

    /*********  SPI INIT AND CONFIG **********/
    void SPI_Init()
    {
        
        Console.WriteLine("Scanning Device");
        ftStatus = SPI_Device.GetNumberOfDevices(ref ftdiDeviceCount);
        if (ftStatus != FTDI.FT_STATUS.FT_OK)
        {
            Console.WriteLine("ftStatus NOT OK");
        }
        Console.WriteLine("Number of device = " + ftdiDeviceCount);
        if (ftdiDeviceCount == 0)
        {
            return;
        }
        FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
        ftStatus = SPI_Device.GetDeviceList(ftdiDeviceList);

        if (ftStatus != FTDI.FT_STATUS.FT_OK)
            return;
        
        string serialnumber = "FTKI02A";
        ftStatus = SPI_Device.OpenBySerialNumber(serialnumber);
        Console.WriteLine("FTKI02B open status: {0}", ftStatus);
        if (ftStatus != FTDI.FT_STATUS.FT_OK)
        {
            Console.WriteLine(serialnumber + " port open failed");
        }
        ftStatus = SPI_Config();

        Console.WriteLine("\nConfig status: {0}", ftStatus);

        if (ftStatus == FTDI.FT_STATUS.FT_OK)
            spi_initialized = true;
    }

    FTDI.FT_STATUS SPI_Config()
    {

        FTDI.FT_STATUS stat = FTDI.FT_STATUS.FT_OK;
        stat = SPI_Device.ResetDevice();

        //Purge USB receive buffer first by reading out all old data from FT2232H receive buffer
        //stat |= SPI_Device.Purge(FTDI.FT_PURGE.FT_PURGE_RX);
        stat |= SPI_Device.GetRxBytesAvailable(ref numBytesRead);
        Console.WriteLine("Input buffer size: {0}", numBytesRead);
        if (stat == FTDI.FT_STATUS.FT_OK && numBytesRead > 0)
        {
            numBytesToRead = numBytesRead;
            stat |= SPI_Device.Read(inputBuffer, numBytesToRead, ref numBytesRead);
        }
        stat |= SPI_Device.SetCharacters(0, false, 0, false);
        stat |= SPI_Device.SetTimeouts(5000, 5000);
        stat |= SPI_Device.SetLatency(16);
        //stat |= SPI_Device.SetFlowControl(FTDI.FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x00, 0x00);      // This is not done in SPI pdf
        stat |= SPI_Device.SetBitMode(0x00, 0x00);
        stat |= SPI_Device.SetBitMode(0x00, 0x02);         // MPSSE mode

        if (stat != FTDI.FT_STATUS.FT_OK)
        {
            Console.WriteLine("Failed to initialize SPI");
            return stat;
        }
        Delay(50);

        // SYNCHRONIZATION WITH BAD COMMAND IS OMITTED HERE

        uint dwClockDivisor = 29;
        // Configure MPSSE for SPI communication with EEPROM
        numBytesToSend = numBytesSent = 0;
        outputBuffer[numBytesToSend++] = 0x8A;    // disable clock divide by 5 for 60MHz master clock
        outputBuffer[numBytesToSend++] = 0x97;    // turn off adaptive clocking
        outputBuffer[numBytesToSend++] = 0x8D;    //  3 phase data clock disable

        outputBuffer[numBytesToSend++] = 0x80;    // Command to set directions of lower 8 pins and force value on bits set as output on ADBUS
        outputBuffer[numBytesToSend++] = 0x00;    // Initial state = 0            
        outputBuffer[numBytesToSend++] = 0x0B;    // Set SCK,DO,CS -> output, DI-> input
                                                // The SK clock frequency can be worked out by below algorithm with divide by 5 set as off
                                                // SK frequency = 60MHz /((1 + [(1 + 0xValueH*256) OR 0xValueL])*2)
        outputBuffer[numBytesToSend++] = 0x86;  // command to set clock divisor
        outputBuffer[numBytesToSend++] = (byte) (dwClockDivisor & 0xFF);  //Set 0xValue L of clock divisor
        outputBuffer[numBytesToSend++] = (byte) (dwClockDivisor >> 8);  // Set 0xValue H of clock divisor            
        stat |= SPI_Device.Write(outputBuffer, numBytesToSend, ref numBytesSent);

        Delay(20);

        // Turn Off loop back in case
        numBytesToSend = 0;
        outputBuffer[numBytesToSend++] = 0x85;
        stat |= SPI_Device.Write(outputBuffer, numBytesToSend, ref numBytesSent);

        if (stat == FTDI.FT_STATUS.FT_OK)
            Console.WriteLine("\nSPI INITIALIZATION SUCCESSFUL.");

        return stat;
    }

    /*********  SEND DATA **********/
    void WREN_Command()
    {
        // This command writes WREN command
        numBytesToSend = numBytesSent = 0;
        // Chip select enable
        outputBuffer[numBytesToSend++] = 0x80;  // GPIO command ADBUS
        outputBuffer[numBytesToSend++] = 0x00;  // set values -> CS High, MOSI and SCL low
        outputBuffer[numBytesToSend++] = 0x0B;  // set directions -> bit3: CS, bit2: MISO, bit1: MOSI, bit0: SCK

        outputBuffer[numBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
        outputBuffer[numBytesToSend++] = 7;
        outputBuffer[numBytesToSend++] = FLASH_CMD_WREN;   // Write WREN command to SPI FLASH

        //SPI_CS_Disable
        outputBuffer[numBytesToSend++] = 0x80;  // GPIO command ADBUS
        outputBuffer[numBytesToSend++] = 0x08;  // set values -> CS, MOSI and SCL low
        outputBuffer[numBytesToSend++] = 0x0B;  // set directions -> bit3: CS, bit2: MISO, bit1: MOSI, bit0: SCK
        
        ftStatus = SPI_Device.Write(outputBuffer, numBytesToSend, ref numBytesSent);
    }

我们发送哪个命令来使用BDBUS,首先我修改了 字符串序列号 = "FTKI02B"; // "FTKI02A"; ftStatus = SPI_Device.OpenBySerialNumber(序列号);

通过下一行中的BDBUS发送和接收数据?

        // Chip select enable
        outputBuffer[numBytesToSend++] = 0x80;  // GPIO command ADBUS
c# ftdi d2xx
1个回答
0
投票

我无法在 SPI 中通信可能是因为电容。当我将示波器探头连接到 SPI 线时,通信工作正常。

我在初始化的时候按照下面的方式完成了使用BDBUS的通讯

"FTKI02B" is the serial number of the FT4232 that I am using.
ftStatus = SPI_Device_B.OpenBySerialNumber("FTKI02B");

为了向端口 B 发送数据,我什么也没改变。

outputBuffer[numBytesToSend++] = 0x80;  //Command to set data bits.
© www.soinside.com 2019 - 2024. All rights reserved.