You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用FTD2XX_NET通过FT4232的BDBUS实现SPI通信

使用FT4232 BDBUS实现SPI的GPIO命令替换方案

问题

我正尝试使用FT4232端口进行SPI通信,目前已通过常规配置将ADBUS用于SPI(AD0→SCK、AD1→MOSI、AD2→MISO、AD3→CS)。已知FT4232支持BDBUS实现SPI,但在使用BDBUS时遇到瓶颈。我已修改代码中的序列号为“FTKI02B”以打开对应端口,但不清楚需替换原ADBUS的GPIO命令(代码中0x80)的具体指令,来通过BDBUS收发数据。原ADBUS的SPI实现代码如下:

/*********  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替代ADBUS进行SPI通信,需将代码中所有用于ADBUS GPIO配置的0x80指令替换为0x82。

指令说明

  • 0x80:MPSSE指令,用于配置**ADBUS(A通道)**的引脚方向和输出电平
  • 0x82:对应MPSSE指令,用于配置**BDBUS(B通道)**的引脚方向和输出电平

具体修改点

  1. SPI_Config函数中的引脚配置
    将原代码中的0x80替换为0x82:

    // 原代码
    outputBuffer[numBytesToSend++] = 0x80;    // Command to set directions of lower 8 pins and force value on bits set as output on ADBUS
    // 修改后
    outputBuffer[numBytesToSend++] = 0x82;    // Command to set directions of lower 8 pins and force value on bits set as output on BDBUS
    
  2. WREN_Command函数中的CS控制
    两处GPIO命令都需要替换:

    // CS使能部分
    // 原代码
    outputBuffer[numBytesToSend++] = 0x80;  // GPIO command ADBUS
    // 修改后
    outputBuffer[numBytesToSend++] = 0x82;  // GPIO command BDBUS
    
    // CS禁用部分
    // 原代码
    outputBuffer[numBytesToSend++] = 0x80;  // GPIO command ADBUS
    // 修改后
    outputBuffer[numBytesToSend++] = 0x82;  // GPIO command BDBUS
    

额外注意事项

  • 引脚方向配置字节0x0B无需修改,因为BDBUS的引脚分配和ADBUS一致:BD0→SCK、BD1→MOSI、BD2→MISO、BD3→CS,该字节对应bit0、bit1、bit3为输出,bit2为输入
  • 确保已正确打开B通道设备(序列号“FTKI02B”对应的端口),避免通道混淆

内容的提问来源于stack exchange,提问作者sujan_014

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:35:14