element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Avnet Boards Forums
  • Products
  • Dev Tools
  • Avnet Boards Community
  • Avnet Boards Forums
  • More
  • Cancel
Avnet Boards Forums
MiniZed Hardware Design FT2232H
  • Forum
  • Documents
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Avnet Boards Forums to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Verified Answer
  • Replies 1 reply
  • Subscribers 323 subscribers
  • Views 1664 views
  • Users 0 members are here
Related

FT2232H

snaseermohamed
snaseermohamed over 3 years ago

good morning,

    I am new to ft2232H. I have tried  to implement serial communication using MPSSE command in loop back mode. I  tried to run code given for serial communication in AN_135
FTDI MPSSE Basics in loop back mode. But it gives 

" Error - MPSSE receive buffer should have the looped-back data ".

I tried both the way 1. using command " byOutputBuffer[dwNumBytesToSend++] = 0x84; " to internally connect TDI/DO PIN and TDO/DI .

                                2. externally also connected both the pins.

i want the solution for this. Please correct me if I made any mistakes as soon as possible. 

int main()
{
// -----------------------------------------------------------
// Variables
// -----------------------------------------------------------
FT_HANDLE ftHandle; // Handle of the FTDI device
FT_STATUS ftStatus; // Result of each D2XX call
DWORD dwNumDevs; // The number of devices
unsigned int uiDevIndex = 0xF; // The device in the list that we'll use
BYTE byOutputBuffer[8]; // Buffer to hold MPSSE commands and data
// to be sent to the FT2232H
BYTE byInputBuffer[8]; // Buffer to hold data read from the FT2232H
DWORD dwCount = 0; // General loop index
DWORD dwNumBytesToSend = 0; // Index to the output buffer
DWORD dwNumBytesSent = 0; // Count of actual bytes sent - used with FT_Write
DWORD dwNumBytesToRead = 0; // Number of bytes available to read
// in the driver's input buffer
DWORD dwNumBytesRead = 0; // Count of actual bytes read - used with FT_Read
DWORD dwClockDivisor = 0xFFFF; // Value of clock divisor, SCL Frequency =
// 60/((1+0x05DB)*2) (MHz) = 1Mhz
// -----------------------------------------------------------
// Does an FTDI device exist?
// -----------------------------------------------------------
printf("Checking for FTDI devices...\n");
ftStatus = FT_CreateDeviceInfoList(&dwNumDevs);
// Get the number of FTDI devices
if (ftStatus != FT_OK) // Did the command execute OK?
{
printf("Error in getting the number of devices\n");
return 1; // Exit with error
}
if (dwNumDevs < 1) // Exit if we don't see any
{
printf("There are no FTDI devices installed\n");
return 1; // Exit with error
}
printf("%lu FTDI devices found \
- the count includes individual ports on a single chip\n", dwNumDevs);
// -----------------------------------------------------------
// Open the port - For this application note, we'll assume the first device is a
// FT2232H or FT4232H. Further checks can be made against the device
// descriptions, locations, serial numbers, etc. before opening the port.
// -----------------------------------------------------------
printf("\nAssume first device has the MPSSE and open it...\n");
ftStatus = FT_Open(0, &ftHandle);
if (ftStatus != FT_OK)
{
printf("Open Failed with error %lu\n", ftStatus);
return 1; // Exit with error
}


// Configure port parameters
printf("\nConfiguring port for MPSSE use...\n");
ftStatus |= FT_ResetDevice(ftHandle);
//Reset USB device
//Purge USB receive buffer first by reading out all old data from FT2232H receive buffer
ftStatus |= FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
// Get the number of bytes in the FT2232H
// receive buffer
if ((ftStatus == FT_OK) && (dwNumBytesToRead > 0))
FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead);
//Read out the data from FT2232H receive buffer
ftStatus |= FT_SetUSBParameters(ftHandle, 65536, 65535);
//Set USB request transfer sizes to 64K
ftStatus |= FT_SetChars(ftHandle, false, 0, false, 0);
//Disable event and error characters
ftStatus |= FT_SetTimeouts(ftHandle, 0, 5000);
//Sets the read and write timeouts in milliseconds
ftStatus |= FT_SetLatencyTimer(ftHandle, 1);
//Set the latency timer to 1mS (default is 16mS)
ftStatus |= FT_SetFlowControl(ftHandle, FT_FLOW_RTS_CTS, 0x00, 0x00);
//Turn on flow control to synchronize IN requests
ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x00);
//Reset controller
ftStatus |= FT_SetBitMode(ftHandle, 0x0, 0x02);
//Enable MPSSE mode
if (ftStatus != FT_OK)
{
printf("Error in initializing the MPSSE %lu\n", ftStatus);
FT_Close(ftHandle);
return 1; // Exit with error
}
Sleep(50); // Wait for all the USB stuff to complete and work
// Enable internal loop-back
byOutputBuffer[dwNumBytesToSend++] = 0x84;
// Enable loopback
ftStatus = FT_Write(ftHandle, byOutputBuffer, \
dwNumBytesToSend, &dwNumBytesSent);
// Send off the loopback command
dwNumBytesToSend = 0; // Reset output buffer pointer
// Check the receive buffer - it should be empty
ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
// the FT2232H receive buffer
if (dwNumBytesToRead != 0)
{
printf("Error - MPSSE receive buffer should be empty\n", ftStatus);
FT_SetBitMode(ftHandle, 0x0, 0x00);
// Reset the port to disable MPSSE
FT_Close(ftHandle); // Close the USB port
return 1; // Exit with error
}
// -----------------------------------------------------------
// Synchronize the MPSSE by sending a bogus opcode (0xAB),
// The MPSSE will respond with "Bad Command" (0xFA) followed by
// the bogus opcode itself.
// -----------------------------------------------------------
byOutputBuffer[dwNumBytesToSend++] = 0xAB;
//Add bogus command ‘0xAB’ to the queue
ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
// Send off the BAD command
dwNumBytesToSend = 0; // Reset output buffer pointer
do
{
ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
// Get the number of bytes in the device input buffer
} while ((dwNumBytesToRead == 0) && (ftStatus == FT_OK));
//or Timeout
bool bCommandEchod = false;
ftStatus = FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead);
//Read out the data from input buffer
for (dwCount = 0; dwCount < dwNumBytesRead - 1; dwCount++)
//Check if Bad command and echo command are received
{
if ((byInputBuffer[dwCount] == 0xFA) && (byInputBuffer[dwCount+1] == 0xAB))
{
bCommandEchod = true;
break;
}
}
if (bCommandEchod == false)
{
printf("Error in synchronizing the MPSSE\n");
FT_Close(ftHandle);
return 1; // Exit with error
}

dwNumBytesToSend = 0; // Reset output buffer pointer
// Check the receive buffer - it should be empty
ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
// Get the number of bytes in
// the FT2232H receive buffer
if (dwNumBytesToRead != 0)
{
printf("Error - MPSSE receive buffer should be empty\n", ftStatus);
FT_SetBitMode(ftHandle, 0x0, 0x00);
// Reset the port to disable MPSSE
FT_Close(ftHandle); // Close the USB port
return 1; // Exit with error
}

//MPSSE Setup
// -----------------------------------------------------------
// Configure the MPSSE settings for JTAG
// Multple commands can be sent to the MPSSE with one FT_Write
// -----------------------------------------------------------
dwNumBytesToSend = 0; // Start with a fresh index
// Set up the Hi-Speed specific commands for the FTx232H
byOutputBuffer[dwNumBytesToSend++] = 0x8A;
// Use 60MHz master clock (disable divide by 5)
byOutputBuffer[dwNumBytesToSend++] = 0x97;
// Turn off adaptive clocking (may be needed for ARM)
byOutputBuffer[dwNumBytesToSend++] = 0x8D;
// Disable three-phase clocking
ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
// Send off the HS-specific commands
dwNumBytesToSend = 0; // Reset output buffer pointer
// Set TCK frequency
// TCK = 60MHz /((1 + [(1 +0xValueH*256) OR 0xValueL])*2)
byOutputBuffer[dwNumBytesToSend++] = '\x86';
// Command to set clock divisor
byOutputBuffer[dwNumBytesToSend++] = dwClockDivisor & 0xFF;
// Set 0xValueL of clock divisor
byOutputBuffer[dwNumBytesToSend++] = (dwClockDivisor >> 8) & 0xFF;
// Set 0xValueH of clock divisor
ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
// Send off the clock divisor commands
dwNumBytesToSend = 0; // Reset output buffer pointer
// Set initial states of the MPSSE interface
// - low byte, both pin directions and output values
// Pin name Signal Direction Config Initial State Config
// ADBUS0 TCK/SK output 1 high 1
// ADBUS1 TDI/DO output 1 low 0
// ADBUS2 TDO/DI input 0 0
// ADBUS3 TMS/CS output 1 high 1
// ADBUS4 GPIOL0 output 1 low 0
// ADBUS5 GPIOL1 output 1 low 0
// ADBUS6 GPIOL2 output 1 high 1
// ADBUS7 GPIOL3 output 1 high 1
byOutputBuffer[dwNumBytesToSend++] = 0x80;
// Configure data bits low-byte of MPSSE port
byOutputBuffer[dwNumBytesToSend++] = 0xC9;
// Initial state config above
byOutputBuffer[dwNumBytesToSend++] = 0xFB;
// Direction config above
ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
// Send off the low GPIO config commands
dwNumBytesToSend = 0; // Reset output buffer pointer
// Note that since the data in subsequent sections will be clocked on the rising edge, the
// inital clock state of high is selected. Clocks will be generated as high-low-high.
// For example, in this case, data changes on the rising edge to give it enough time
// to have it available at the device, which will accept data *into* the target device
// on the falling edge.
// Set initial states of the MPSSE interface
// - high byte, both pin directions and output values
// Pin name Signal Direction Config Initial State Config
// ACBUS0 GPIOH0 input 0 0
// ACBUS1 GPIOH1 input 0 0
// ACBUS2 GPIOH2 input 0 0
// ACBUS3 GPIOH3 input 0 0
// ACBUS4 GPIOH4 input 0 0
// ACBUS5 GPIOH5 input 0 0
// ACBUS6 GPIOH6 input 0 0
// ACBUS7 GPIOH7 input 0 0
byOutputBuffer[dwNumBytesToSend++] = 0x82;
// Configure data bits low-byte of MPSSE port
byOutputBuffer[dwNumBytesToSend++] = 0x00;
// Initial state config above
byOutputBuffer[dwNumBytesToSend++] = 0x00;
// Direction config above
ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
// Send off the high GPIO config commands
dwNumBytesToSend = 0; // Reset output buffer pointer
for(dwCount = 0; dwCount < 8; dwCount++)
{ // Clear out the input and output buffers
byInputBuffer[dwCount] = 0x00;
byOutputBuffer[dwCount] = 0x00;
}
// Data Transmit, no receive
dwNumBytesToSend = 0;
byOutputBuffer[dwNumBytesToSend++] = 0x84;
// Enable loopback
ftStatus = FT_Write(ftHandle, byOutputBuffer, \
dwNumBytesToSend, &dwNumBytesSent);
//sleep(2);
dwNumBytesToSend = 0;
byOutputBuffer[dwNumBytesToSend++] = 0x10;
// Output on rising clock, no input
// MSB first, clock a number of bytes out
byOutputBuffer[dwNumBytesToSend++] = 0x01; // Length L
byOutputBuffer[dwNumBytesToSend++] = 0x00; // Length H
// Length = 0x0001 + 1
byOutputBuffer[dwNumBytesToSend++] = 0xA5;
byOutputBuffer[dwNumBytesToSend++] = 0x0F;
// Data = 0xA50F
ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
// Send off the command
dwNumBytesToSend = 0; // Reset output buffer pointer
Sleep(2); // Wait for data to be transmitted and status
// to be returned by the device driver
// - see latency timer above
// Check the receive buffer - it should be empty
ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
// Get the number of bytes in
// the FT2232H receive buffer
// It should be zero since there was
// no data clocked *in*
FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead);
if (dwNumBytesToRead != 0)
{
printf("Error - MPSSE receive buffer should be empty\n", ftStatus);
FT_SetBitMode(ftHandle, 0x0, 0x00);
// Reset the port to disable MPSSE
FT_Close(ftHandle); // Close the USB port
return 1; // Exit with error
}
printf("Press <Enter> to continue\n");
getchar(); // wait for a carriage return
// Now repeat the transmission with the send and receive op-code in place of transmit-only
// Data Transmit, with receive
byOutputBuffer[dwNumBytesToSend++] = 0x34;
// Output on rising clock, input on falling clock
// MSB first, clock a number of bytes out
byOutputBuffer[dwNumBytesToSend++] = 0x01; // Length L
byOutputBuffer[dwNumBytesToSend++] = 0x00; // Length H
// Length = 0x0001 + 1
byOutputBuffer[dwNumBytesToSend++] = 0xA5;
byOutputBuffer[dwNumBytesToSend++] = 0x0F;
// Data = 0xA50F
ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
// Send off the command
dwNumBytesToSend = 0; // Reset output buffer pointer
Sleep(2); // Wait for data to be transmitted and status
// to be returned by the device driver
// - see latency timer above
// Check the receive buffer - it should contain the looped-back data
ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
// Get the number of bytes in
// the FT2232H receive buffer
// It should be zero since there was
// no data clocked *in*
FT_Read(ftHandle, &byInputBuffer, dwNumBytesToRead, &dwNumBytesRead);
// The input buffer should contain the same number of bytes as those output
printf("\n size:%d",dwNumBytesToRead);
if (dwNumBytesToRead != 2)
{
printf("Error - MPSSE receive buffer should have the looped-back data\n");
FT_SetBitMode(ftHandle, 0x0, 0x00);
// Reset the port to disable MPSSE
FT_Close(ftHandle); // Close the USB port
return 1; // Exit with error
}
printf("The correct number of bytes have been received\n");
// Check to be sure it's the same.
for(dwCount = 0; dwCount <= dwNumBytesRead - 1; dwCount++)
{
if (byInputBuffer[dwCount] != byOutputBuffer[dwCount + 3])
// Output data begins at location 3,
// after the opcode and length
{
printf("Error - Data received does not match data output\n");
FT_SetBitMode(ftHandle, 0x0, 0x00);
// Reset the port to disable MPSSE
FT_Close(ftHandle); // Close the USB port
return 1; // Exit with error
}
}
printf("The input data matches the output data\n");
printf("Press <Enter> to continue\n");
getchar(); // wait for a carriage return
// Clear the buffers
for(dwCount = 0; dwCount < 8; dwCount++)
{
byInputBuffer[dwCount] = 0x00;
byOutputBuffer[dwCount] = 0x00;
}
FT_Close(ftHandle);
return 0;
}

  • Sign in to reply
  • Cancel

Top Replies

  • shabaz
    shabaz over 3 years ago +1 verified
    Hi, There's no code formatting, so it's unlikely anyone will enjoy spending the time examining your code. You'll need to either format the code using the editor tools, or place the code on a site that…
  • shabaz
    +1 shabaz over 3 years ago

    Hi,

    There's no code formatting, so it's unlikely anyone will enjoy spending the time examining your code. You'll need to either format the code using the editor tools, or place the code on a site that displays it in a nice format.

    If you make things easy for others, then they will spend more time.

    At a very vague glance, I don't see anywhere that you are trying to troubleshoot the issue. The FTDI library contains a function to print information based on error code, it is either ftdi_get_error_string() or FTID_GetErrorCodeString() so you could try that wherever there is an error condition, to see more precisely what could have gone wrong. You could also check to see if anything is transmitted by using a 'scope or similar.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Reject Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube