Altera_Forum
Honored Contributor
12 years agoMissing Bytes reading FPGA data with FTDI 2232H
Hi,
I recently developing an FPGA program that will be used to measure something. IO inputs will be stored in the FPGA SRAM and later transferred with over USB with the FTDI chip to be processed on a PC. With testing only the USB part of the program I noticed that some bytes are missing (on regular base each 128 bytes there is one missing, and on rare occurrence there are several missing). To test this I implemented a counter in VHDL code generating bytes to transmit to the PC. Part of the VHDL code :elsif (State_WR = '1' ) then
STM_RD<= rd_idle;
--# Start sequence of setting flags to write to the FTDI
case STM_WR is
--## WRITE IDLE : prepare flags of FTDI and RAM
when wr_idle =>
FTDI_OE_n<='1';
--If FTDI_TXE_n is 0, then FTDI will allow data to be transmitted
if(FTDI_TXE_n ='1') then
STM_WR <= do_WR;
end if;
FTDI_WR_n <= '1';
--## WRITE START: start write command to FTDI
when do_WR =>
FTDI_WR_n <= '0'; -- Enables the data byte on the D0...D7 pins to be written into the transmit FIFO buffer
STM_WR <= burst_write;
​
--## WRITE BURST: burst bytes to FTDI
when burst_write =>
-- If FTDI_TXE_n is asserted, FTDI does not want data anymore, so we pause XMIT:
if(FTDI_TXE_n = '0') then
STM_WR <= wr_pause;
FTDI_WR_n <= '1'; -- Disable write enable
else
counter <= counter+1;
--******************Output data*************
FTDI_Data<=std_logic_vector(to_unsigned(counter,8));
end if;
--# # PAUSE : FTDI chip needs a break...
when wr_pause =>
State_ReadyToWrite <='0';
if(FTDI_TXE_n = '1') then
State_ReadyToWrite <='1';
STM_WR <= burst_write;
FTDI_WR_n <= '0'; -- enable writing again
end if;
when others =>
end case; C++ program (used functions): bool FT2232H::Initialize()
{
UCHAR mask = 0xff; // set all IOs to output
UCHAR mode = 0x00; // reset value of bitmode
//UCHAR bitMode;
UCHAR latencyTimer = 2; // default setting is 16
int deviceIndx=0; // Select first FTDI device
FT_STATUS ftStatus;
int readTimeout = 900; //
int writeTimeout =2000; //
// Obtain handle
ftStatus = FT_Open(deviceIndx, &ftHandle);
if (ftHandle == INVALID_HANDLE_VALUE)
cout<<"failed opening connection";
ftStatus = FT_SetBitMode(ftHandle, mask, mode);
Sleep(1000);
mode = 0x40; //Sync FIFO mode
ftStatus = FT_SetBitMode(ftHandle, mask, mode);
if (ftStatus == FT_OK)
{
ftStatus = FT_SetLatencyTimer(ftHandle, latencyTimer);
ftStatus = FT_SetUSBParameters(ftHandle,0x10000,0x10000);
ftStatus = FT_SetFlowControl(ftHandle,FT_FLOW_RTS_CTS,0,0);
ftStatus = FT_SetTimeouts(ftHandle,readTimeout,writeTimeout);
//ftStatus = FT_GetBitMode(ftHandle, &bitMode);
return true;
}
else
{
//TODO add recovery and feedback wheb ftStatus is not OK
return false;
}
}
bool FT2232H::Read(char *pRxBuf,int bufSize)
{
bool isReadDone= false;
DWORD bytesReceived;
FT_STATUS ftStatus;
char *pRxBufCur = pRxBuf;
int maxBufSize = bufSize>MAX_RXBUFF ? MAX_RXBUFF : bufSize; // limit bufsize
int currReceivedBytes=0;
int cyclesToRead=(int) bufSize/maxBufSize + 2;
int cyclesReaded=0;
Purge();
while(cyclesReaded<cyclesToRead){
Sleep(1);
cyclesReaded++;
// prevent to big bufsize on the end of the buffer
maxBufSize = ((bufSize - currReceivedBytes)> maxBufSize)? maxBufSize : bufSize- currReceivedBytes;
ftStatus = FT_Read(ftHandle,pRxBufCur,maxBufSize,&bytesReceived);
if(bytesReceived<maxBufSize)
break;
currReceivedBytes += bytesReceived;
pRxBufCur += maxBufSize; // set pointer further in buffer
if(currReceivedBytes >= bufSize){
break;
}
}
if(currReceivedBytes<bufSize && ftStatus== FT_OK)
{
std::cout<< "Reading failed due timeout: Received"<<std::endl;
}
else if (ftStatus != FT_OK)
{
std::cout<<"Reading failed"<<std::endl;
PrintError(ftStatus);
}
else
{
std::cout<<"Reading successfully: "<<currReceivedBytes<<" received." <<std::endl;
isReadDone= true;
}
return isReadDone? true : false;
}
void FT2232H::Purge()
{
FT_STATUS ftStatus;
ftStatus=FT_Purge(ftHandle,FT_PURGE_RX);
if(ftStatus!=FT_OK)
{
cout<<"READ BUF NOT PURGED"<<endl;
PrintError(ftStatus);
}
ftStatus=FT_Purge(ftHandle,FT_PURGE_TX);
if(ftStatus!=FT_OK)
{
cout<<"READ BUF NOT PURGED"<<endl;
PrintError(ftStatus);
}
}
The result of this read operation is : (counter = 8 bit counter) 0,2,3,4,............127,128,130,131,132,....,255,0,2,3,4,5,......,127,128,130,.........,224,226,227,......,255,0,2,3,4,5,......,12,120,.....127,128,130,131,.......255,.................... => missing one byte on 0->2 and 128->131 occurs on regular base => missing one or more than one byte like 120->120 and 224->226 occurs less frequent and irregular. Does have some one the same experience with the Sync FT245 mode of the FTDI 2232H chip ? Are there suggestions to solve this problem ? Thanks in Advance