Electronic – Working with FTDI library for accessing FPGA memory

embeddedflashfpgaftdiusb

I asked a related question here.
The board is Lattice MACHX02 1200 ZE.
I am using FTDI Library FTCSPI to access Lattice FPGA UFM through FTDI chip FT2232H. I configured the FPGA in SPI slave by using IPExpress. I am confident that the FPGA is now configured well as the following code is giving me correct value of device Id.

    WriteControlBuffer[0]=224; //0xe0

    Status = SPI_ReadHiSpeedDevice(ftHandle, &ReadStartCondition, true, false, NUM_LATTICE_CMD_CONTOL_BITS,
            &WriteControlBuffer, NUM_LATTICE_CMD_CONTOL_BYTES, true, false, NUM_LATTICE_CMD_DATA_BITS,
            &ReadDataBuffer, &dwNumDataBytesReturned, &HighPinsWriteActiveStates);

    if (Status == FTC_SUCCESS)
    { 
        printf(" success ");
    }
    else
    {
        printf("failed");
    }

    printf(" ID read = %x%x%x%x", ReadDataBuffer[0],ReadDataBuffer[1], ReadDataBuffer[2], ReadDataBuffer[3]);
}

This prints: enter image description here

I wrote

WriteControlBuffer[0]=224; //0xe0

because the Lattice FPGA UFM programming guide on page no. 17-61 says that the command for reading device Id is E0 or 224 in decimal.

Now the next problem I am facing is regarding the usage of the code for verifying device ID i.e 0xE2 00 00 00 01 2B 20 43. Below is a screen shot of the page I am talking about:

enter image description here

Now I am unable to understand which function from FTDI library I have to use for this purpose. SPI_ReadHiSpeedDevice is used for reading some data. But here I have to verify, so wondering if the library has any other function for such purpose.

If not then what could be the other way to pass the command E2 with the inputs 01 2B 20 43 as is shown in the Lattice programming guide and screenshot above.

Example code from FTDI. This is for accessing some EEPROM and not for FPGA.

Some more Examples are given.

Summary

After reading the device ID using command E0 (I am able to do this correctly), I have to verify Device ID using another command: 0xE2 00 00 00 01 2B 20 43. My simple problem is how to input the command 0xE2 00 00 00 01 2B 20 43 to my C functions, and which C function from library I have to use? The document says that the command 0xE2 00 00 00 is used with 32 bit input (in my case it is 01 2B 20 43) to verify the device_ID. This will set 27th bit in SR, that is what is mentioned in Lattice Document. How to achieve this using FTCSPI library function?

This document is another guide for programming

This is on P no: 14-38
enter image description here

I am unable to do Id Match ? stage. This is done by sending command E2 0 0 0 01 2B 20 43.

This is my code so far that correctly reads device ID:

int _tmain(int argc, _TCHAR* argv[])
{
  FTC_STATUS Status = FTC_SUCCESS;
  DWORD dwNumHiSpeedDevices = 0;
  char szDeviceName[100];
  char szChannel[5];
  DWORD dwLocationID = 0;
  DWORD dwHiSpeedDeviceType = 0;
  DWORD dwHiSpeedDeviceIndex = 0;
  FTC_HANDLE ftHandle = 0;
  char szDeviceDetails[150];
  BYTE timerValue = 0;
  DWORD dwClockFrequencyHz = 0;
  BOOL bPerformCommandSequence = false;
  FTC_CHIP_SELECT_PINS ChipSelectsDisableStates;
  FTH_INPUT_OUTPUT_PINS HighInputOutputPins;
  FTH_LOW_HIGH_PINS HighPinsInputData;
  FTC_INIT_CONDITION WriteStartCondition;
  FTC_WAIT_DATA_WRITE WaitDataWriteComplete;
  WriteControlByteBuffer WriteControlBuffer;
  WriteDataByteBuffer WriteDataBuffer;
  DWORD dwNumDataBytesToWrite = 0;

  FTH_HIGHER_OUTPUT_PINS HighPinsWriteActiveStates;
  FTC_CLOSE_FINAL_STATE_PINS CloseFinalStatePinsData;
  DWORD dwDataWordInitValue = 0;
  DWORD dwDataWordValue = 0;
  DWORD dwWriteDataWordAddress = 0;
  DWORD dwControlLocAddress1 = 0;
  DWORD dwControlLocAddress2 = 0;
  FTC_INIT_CONDITION ReadStartCondition;
  DWORD dwReadDataWordAddress = 0;
  DWORD dwReadWordValue = 0;
  ReadDataWordBuffer ReadWordData;
  DWORD dwNumDataBytesReturned = 0;
  DWORD dwDataWordWritten = 0;
  DWORD dwCharCntr = 0;
  ReadDataByteBuffer ReadDataBuffer;
  DWORD dwReadDataIndex = 0;
  ReadCmdSequenceDataByteBuffer ReadCmdSequenceDataBuffer;
  int MsgBoxKeyPressed = 0;
  DWORD dwLoopCntr = 0;

  //DECLARATION WRITE
  PFTC_INIT_CONDITION pWriteStartCondition;




  char szDllVersion[10];
  char szTitleErrorMessage[100];
  char szStatusErrorMessage[100];
  char szErrorMessage[200];
  char szMismatchMessage[100];

  for (dwCharCntr = 0; (dwCharCntr < 100); dwCharCntr++)
    szMismatchMessage[dwCharCntr] = '\0';

  Status = SPI_GetDllVersion(szDllVersion, 10);   // Get version of DLL file
  MessageBox(NULL, szDllVersion, "FTCSPI DLL Version", MB_OK);

  Status = SPI_GetNumHiSpeedDevices(&dwNumHiSpeedDevices);

  if ((Status == FTC_SUCCESS) && (dwNumHiSpeedDevices > 0))
  {
    do
    {

    // This gets the name and location identifier for any FTDI HiSpeed device connected to the host.

      Status = SPI_GetHiSpeedDeviceNameLocIDChannel(dwHiSpeedDeviceIndex, szDeviceName, 100, &dwLocationID, szChannel, 5, &dwHiSpeedDeviceType);

      dwHiSpeedDeviceIndex = dwHiSpeedDeviceIndex + 1; // Increment to look for other HiSpeed device connected to host.
    }
    while ((Status == FTC_SUCCESS) && (dwHiSpeedDeviceIndex < dwNumHiSpeedDevices) && (strcmp(szChannel, "A") != 0));

    if (Status == FTC_SUCCESS)
    {
      if (strcmp(szChannel, "A") != 0)
        Status = FTC_DEVICE_IN_USE;
    }

    if (Status == FTC_SUCCESS) {

    // Opens a handle to the Hi Speed device and initializes the device to default state.

      Status = SPI_OpenHiSpeedDevice(szDeviceName, dwLocationID, szChannel, &ftHandle);
      if (Status == FTC_SUCCESS) {

    // Returns the device type, either FT2232H or FT4232H.

        Status = SPI_GetHiSpeedDeviceType(ftHandle, &dwHiSpeedDeviceType);
        if (Status == FTC_SUCCESS) {

          strcpy_s(szDeviceDetails, "Type = ");

          if (dwHiSpeedDeviceType == FT4232H_DEVICE_TYPE)  // Is the device a FT4232H ?
            strcat_s(szDeviceDetails, "FT4232H");

          else if (dwHiSpeedDeviceType == FT2232H_DEVICE_TYPE) // Is the device a FT222H ?
            strcat_s(szDeviceDetails, "FT2232H");

          strcat_s(szDeviceDetails, ", Name = ");
          strcat_s(szDeviceDetails, szDeviceName);

          MessageBox(NULL, szDeviceDetails, "Hi Speed Device", MB_OK);
        }
      }
    }






     Status = SPI_InitDevice(ftHandle, MAX_FREQ_LATTICE_CLOCK_DIVISOR); 

          Status = SPI_SetDeviceLatencyTimer(ftHandle, 16);

          Status = SPI_GetDeviceLatencyTimer(ftHandle, &timerValue);

          }


              ReadStartCondition.bClockPinState = false;
              ReadStartCondition.bDataOutPinState = false;
              ReadStartCondition.bChipSelectPinState = true; //Chip Select is active high.
              ReadStartCondition.dwChipSelectPin = ADBUS3ChipSelect;

              { 



                  {



             WriteControlBuffer[0]=224; //0xe0 COMMAND FOR READING DEVICE Id



            Status = SPI_ReadHiSpeedDevice(ftHandle, &ReadStartCondition, true, false, NUM_LATTICE_CMD_CONTOL_BITS,
                                                 &WriteControlBuffer, NUM_LATTICE_CMD_CONTOL_BYTES, true, false, NUM_LATTICE_CMD_DATA_BITS,
                                                 &ReadDataBuffer, &dwNumDataBytesReturned, &HighPinsWriteActiveStates);

                   if (Status == FTC_SUCCESS)

                   { 
                       printf(" success ");
                   }
                   else

                   {
                       printf("failed");
                   }




                  printf(" ID read = %x%x%x%x", ReadDataBuffer[0],ReadDataBuffer[1], ReadDataBuffer[2], ReadDataBuffer[3]);

                  }

              }

Best Answer

It still isn't entirely clear what the problem is. You should be able to use the SPI_ReadHiSpeedDevice() function again, just like you did with the first command. Something like this:

/* issue the "verify device ID" command
 */
Writecontrolbuffer[0] = 0xE2;
WriteControlBuffer[1] = 0x00;
WriteControlBuffer[2] = 0x00;
WriteControlBuffer[3] = 0x00;
WriteControlBuffer[4] = 0x01;
WriteControlBuffer[5] = 0x2B;
WriteControlBuffer[6] = 0x20;
WriteControlBuffer[7] = 0x43;
Status = SPI_ReadHiSpeedDevice (ftHandle,
                                &ReadStartCondition,
                                true,
                                false,
                                8*8,        // length of command in bits
                                &WriteControlBuffer,
                                8,          // length of command in bytes
                                true,
                                false,
                                NUM_LATTICE_CMD_DATA_BITS,
                                &ReadDataBuffer,
                                &dwNumDataBytesReturned,
                                &HighPinsWriteActiveStates);

/* read the status register to get the results
 */
Writecontrolbuffer[0] = 0x3C;
WriteControlBuffer[1] = 0x00;
WriteControlBuffer[2] = 0x00;
WriteControlBuffer[3] = 0x00;
Status = SPI_ReadHiSpeedDevice (ftHandle,
                                &ReadStartCondition,
                                true,
                                false,
                                4*8,        // length of command in bits
                                &WriteControlBuffer,
                                4,          // length of command in bytes
                                true,
                                false,
                                NUM_LATTICE_CMD_DATA_BITS,
                                &ReadDataBuffer,
                                &dwNumDataBytesReturned,
                                &HighPinsWriteActiveStates);
printf(" SR read = %02x%02x%02x%02x", ReadDataBuffer[0], ReadDataBuffer[1],
   ReadDataBuffer[2], ReadDataBuffer[3]);