FTDI Community
General Category => Discussion - Software => Topic started by: dania on October 23, 2019, 09:42:45 am
-
Hello,
time between end of transmit and disasserting SS is several miliseconds. It's possible to shorten it?
-
Hello,
It is not possible to shorten this time unfortunately as the end of the transfer is sent over a separate USB frame after the end of the data and so there is always a gap of more than one USB frame interval.
Best Regards,
FTDI Community
-
Hi Dania,
I face the same problem. Did you find out, how to solve it?
When I measure the transmition, I see different behavior using MPSSE_SPI vs D2XX library.
Setup:
-SPI
-3MHz CLK
D2XX:
Duration transmit data = 22us
Duration disasserting SS = 171us
MPSSE:
Duration transimt data = 22 us
Duration disasserting SS = 2.9ms
The problem seems to be related to the MPSSE library. Otherwise the duration time to release the SS should be the same for D2XX and MPSSE.
Can somebody from FTDI support re-check the MPSSE library? Especially the releasing SS part of the code...
-
Hello,
The libMPSSE uses separate FT_Write commands to send each part of the SPI transaction and so there will be a delay between the data and the CS operations as each FT_Write will be a new request to the host controller and will be at least on the next USB uframe (could be longer depending how the host schedules it). This is to make the library more generic as SPI peripherals have many different requirements.
As you mentioned, you can use D2xx and you can send the chip select GPIO command and the clocking command and data and the CS de-assert GPIO command all in one buffer with one FT_Write. If you add all these into one data array and pass to FT_Write, there will be much less delay between them (almost no delay between CS and data if you only clock in/out a few bytes).
When you have a known peripheral which needs a certain sequence, optimising the code like this will make a big improvement.
We also have the source code of libMPSSE and you can make the same change there.
Best Regards, FTDI Community
-
I contacted the FTDI support directly and managed to solve my problem. To help others, which may have the same problem, I want to share my solution here.
Removing the LibMPSSE and using D2XX library will increase the speed of writing and reading a lot. My solution is based on this example:
https://www.ftdichip.com/Support/Documents/AppNotes/AN_114_FTDI_Hi_Speed_USB_To_SPI_Example.pdf (https://www.ftdichip.com/Support/Documents/AppNotes/AN_114_FTDI_Hi_Speed_USB_To_SPI_Example.pdf)
U4 SPI_FTDI_WRITE(FT_HANDLE handle, SPI_READBUFFER_pt pReadBuf, uint8* buffer, const U4 sizeToTransfer)
{
uint32 sizeTransfered = 0;
//SPI_Enable();
for (int loop = 0; loop < 5; loop++) //one 0x80 command can keep 0.2us, do 5 times to stay in this situation for 1us
{
OutputBuffer[dwNumBytesToSend++] = '\x80'; // GPIO command for ADBUS
OutputBuffer[dwNumBytesToSend++] = '\xf0'; // set CS low, MOSI and SCL
OutputBuffer[dwNumBytesToSend++] = '\xfb'; // bit3: CS, bit2: MISO, bit1: MOSI, bit0: SCK
}
//send data
OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT_IN; // 0x11 Write command
OutputBuffer[dwNumBytesToSend++] = (sizeToTransfer - 1); // Length lower byte
OutputBuffer[dwNumBytesToSend++] = (sizeToTransfer - 1) >> 8; // Length higher byte
for (U4 i = 0; i < sizeToTransfer; i++) // size to transfer
{
OutputBuffer[dwNumBytesToSend++] = buffer;
}
//SPI_CSDisable();
for (int loop = 0; loop < 5; loop++) //one 0x80 command can keep 0.2us, do 5 times to stay in this situation for 1us
{
OutputBuffer[dwNumBytesToSend++] = '\x80'; //GPIO command for ADBUS
OutputBuffer[dwNumBytesToSend++] = '\xf8'; //set CS, MOSI and SCL low
OutputBuffer[dwNumBytesToSend++] = '\xfb'; //bit3:CS, bit2:MISO, bit1:MOSI, bit0 : SCK
}
ftStatus = FT_Write(handle, OutputBuffer, dwNumBytesToSend, &sizeTransfered);
dwNumBytesToSend = 0;
ftStatus = FT_Read(handle, inBuffer, sizeToTransfer, &dwNumBytesRead);
sizeTransfered = sizeTransfered ? sizeTransfered - 33 : sizeTransfered;
}
uint32 SPI_FTDI_READ(FT_HANDLE handle, SPI_READBUFFER_pt pReadBuf, uint8* spiData, uint32 size)
{
const uint32 secureSize = MIN(50, size);
uint32 sizeRead;
dwNumBytesSent = 0;
//SPI_Enable();
for (int loop = 0; loop < 5; loop++) //one 0x80 command can keep 0.2us, do 5 times to stay in this situation for 1us
{
OutputBuffer[dwNumBytesToSend++] = '\x80';// GPIO command for ADBUS
OutputBuffer[dwNumBytesToSend++] = '\xf2';// set CS, MOSI and SCL low
OutputBuffer[dwNumBytesToSend++] = '\xfb';// bit3:CS, bit2:MISO, bit1:MOSI, bit0 : SCK
}
//read data
OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_IN;
OutputBuffer[dwNumBytesToSend++] = (secureSize - 1);
OutputBuffer[dwNumBytesToSend++] = (secureSize - 1) >> 8;
//SPI_CSDisable();
for (int loop = 0; loop < 5; loop++) //one 0x80 command can keep 0.2us, do 5 times to stay in this situation for 1us
{
OutputBuffer[dwNumBytesToSend++] = '\x80';//GPIO command for ADBUS
OutputBuffer[dwNumBytesToSend++] = '\xfa';//set CS, MOSI and SCL low
OutputBuffer[dwNumBytesToSend++] = '\xfb';//bit3:CS, bit2:MISO, bit1:MOSI, bit0 : SCK
}
ftStatus = FT_Write(handle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
dwNumBytesToSend = 0;
ftStatus = FT_Read(handle, spiDataRest, secureSize, &sizeRead);
}