FTDI Community

Please login or register.

Login with username, password and session length.
Advanced Search  

News:

Welcome to the FTDI Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ FTDI Support


New Bridgetek Community is now open

Please note that we have created the Bridgetek Community to discuss all Bridgetek products e.g. EVE, MCU.

Please follow this link and create a new user account to get started.

Bridgetek Community

Author Topic: MPSSE_SPI - long time between end of transmit and disasserting SS  (Read 1411 times)

dania

  • Newbie
  • *
  • Posts: 1
    • View Profile

Hello,

time between end of transmit and disasserting SS is several miliseconds. It's possible to shorten it?
Logged

FTDI Community

  • Administrator
  • Sr. Member
  • *****
  • Posts: 471
    • View Profile
Re: MPSSE_SPI - long time between end of transmit and disasserting SS
« Reply #1 on: October 28, 2019, 02:29:56 PM »

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
Logged

FTDI_user

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: MPSSE_SPI - long time between end of transmit and disasserting SS
« Reply #2 on: June 22, 2020, 10:14:16 AM »

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...
Logged

FTDI Community

  • Administrator
  • Sr. Member
  • *****
  • Posts: 471
    • View Profile
Re: MPSSE_SPI - long time between end of transmit and disasserting SS
« Reply #3 on: June 22, 2020, 02:01:23 PM »

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


Logged

FTDI_user

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: MPSSE_SPI - long time between end of transmit and disasserting SS
« Reply #4 on: July 17, 2020, 01:07:40 PM »

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

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);

}

Logged