如何使用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通道)**的引脚方向和输出电平
具体修改点
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 BDBUSWREN_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
相关产品推荐
相关产品推荐

