I am trying to use FT4232 ports for SPI communication. For this, I am using the ADBUS for SPI using the usual SPI configuration (AD0 -> SCK, AD1 -> MOSI, AD2 -> MISO, AD3 -> CS).
Now I have to use SPI available in BDBUS. As I understand, the FT4232 allows SPI in BDBUS. So far, I am stuck about using BDBUS.
The code using ADBUS is as follow
/********* 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);
}
Which command do we send to use BDBUS, first I modified string serialnumber = "FTKI02B"; // "FTKI02A"; ftStatus = SPI_Device.OpenBySerialNumber(serialnumber);
To send and receive data through BDBUS which in the following line ?
// Chip select enable
outputBuffer[numBytesToSend++] = 0x80; // GPIO command ADBUS
I was not able to communicate in SPI may be because of capacitance. When I connected oscilloscope probe to the SPI lines, the communication worked perfectly.
I completed the communication using BDBUS in the following way during initialization.
"FTKI02B" is the serial number of the FT4232 that I am using.
ftStatus = SPI_Device_B.OpenBySerialNumber("FTKI02B");
To send data to Port B, I changed nothing.
outputBuffer[numBytesToSend++] = 0x80; //Command to set data bits.