Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21594 Discussions

FT2232H 245 Synchronous FIFO Mode problem

Altera_Forum
Honored Contributor II
8,132 Views

Hello 

 

Im very new to FPGA's and am still learning so please be kind if the problem is obvious :) 

 

 

i have a FT2232H set to 245 Synchronous FIFO Mode. 

 

i have a program on the pc using the d2xx drivers sending exactly 512 bytes. 

 

 

the problem is when the fpga receives these 512 bytes and places them into a ram block module i am using, every time i send the 512 bytes it seams to read in 2 empty bytes first then reads in the correct 512 offsetting every thing by 2 bytes. then the next frame i send every thing is offset by 4 bytes then 6 and so on 

 

my code is very simple 

 

it has 2 buffers that are 3072 bytes (im only using 512 at the moment) 

it fills one then once that is full it swaps to the next one and fills that one. 

 

another bit of code is reading the none filling buffer and cycling the data to a dot matrix display (this part of the design is ok and can be ignored) 

 

 

below is the timing diagram for the 245 FIFI 

http://img580.imageshack.us/img580/5303/ft2232htiming.jpg  

 

i have attached my code. all dot matrix display update code can be ignored. the problem lies in the FIFO section. 

 

apart from these extra 2 bytes every frame (causing the buffer to be offset by 2 bytes every frame) it seams to behave correctly. 

 

 

 

CLK = 50mhz 

fifo_clk = 60mhz from FT2232H 

 

 

im not sure if its a timing fault or a fault in my state machine. 

i have attached my verilog file 

 

any help would be much appreciated or just to be pointed in the right direction :) 

 

its so close to working just this one little problem!
0 Kudos
15 Replies
Altera_Forum
Honored Contributor II
6,413 Views

Hi 

 

I am having the same problem. So far, in my application, I can live with it, just dealing with the two extra bytes. 

 

However, I am curious if you figured out what the issue was? If so I would appreciate any advice you may have. 

 

Thanks 

 

Hans
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

yup the issue was the way i set up the hardware. i had to add a clk termination resister to stop signal bounce back :) the second i added this one resister it works perfect :)

0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

Hi  

 

I assume that you are referring to the 60MHz clock coming from the FTDI chip to the FPGA? 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

yes :) thats correct

0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

 

--- Quote Start ---  

yes :) thats correct 

--- Quote End ---  

 

 

I use morphic-ii from FTDI and the eeprom has channel A configured as FIFO 245. But, i can't see any clock(60MHz) in pin 32 of FT2232H. 

Is there any set we need to get 60MHz in pin 32 ? Is there any command to send by usb ?
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

 

--- Quote Start ---  

I use morphic-ii from FTDI and the eeprom has channel A configured as FIFO 245. But, i can't see any clock(60MHz) in pin 32 of FT2232H. 

Is there any set we need to get 60MHz in pin 32 ? Is there any command to send by usb ? 

--- Quote End ---  

 

 

you need some code like this to enable the clock 

 

FT_SetBitMode(ftHandle, 0xff, 0x40); 

 

'0x40 = Single Channel Synchronous 245 FIFO Mode (FT2232H and FT232H devices only)'
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

Setbitmode works fine. But, i'd like to use this clock into fpga to my state machine.  

In the schematic clkout pin is connected to FPGA J2 pin. My state machine is not running. 

I copy pin J2 to another pin (debug pin) to see the waveform in oscilloscope. The debug pin remains in zero level. Is pin clockout from FT2232H connected to FPGA J2 pin ?
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

i also wanted to use this as my fpga clock but seeing as its dead untill the pc enables it, its pretty much useless as a main clock :( 

 

so i had to add another clock for my fpga
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

Could you give me more info on resistor value and where you have added it? 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

 

--- Quote Start ---  

Could you give me more info on resistor value and where you have added it? 

 

Thanks 

--- Quote End ---  

 

 

I only needed the resistor when breadboarding the projrct. Once on pcb it was not needed as the two ftdi/fpga where only a few mm from each other. 

On the breadboard I placed it as close to the fgpa clk input as I could. I cant remember the value, I think it was 100ohm.
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

Thank you very much for your reply. 

 

I have a bad problem with FT232H which is very similar to FT2232H, but only 1 channel instead of 2. 

I have a data loss every 510 bit (tested on Win7 and Win8.1) and more in other cases.  

In sw I use this code with C# .NET library (v1.0.14.0) to read data 

 

Pseudocode: 

 

OpenBySerialNumber("FTXE2X2D"); SetBitMode(0xFF, FTD2XX_NET.FTDI.FT_BIT_MODES.FT_BIT_MODE_RESET); Thread.Sleep(10); SetBitMode(0xFF, FTD2XX_NET.FTDI.FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO); Purge(FTD2XX_NET.FTDI.FT_PURGE.FT_PURGE_RX) --Cycle Read(dataBuffer, 1024, ref numBytesRead); --End cycle Close(); 

 

*Data loss even with SetFlowControl(FTD2XX_NET.FTDI.FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0, 0); 

 

I have tried to change buffer size (1024 in pseudocode) with other values. If buffer size is 1 no errors, in other case I have a lot of errors (about 0.016% data loss with buffer = 1024 bytes) 

 

Timing of FT232H are: 

 

http://imagizer.imageshack.us/v2/xq90/13/7cmg.png  

 

In VHDL I have this simple code: 

 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ft232h_tx is port ( FT_CLK : in std_logic; -- 60 MHz FT232H clock nTXE : in std_logic; -- Can TX nRXF : in std_logic; -- Can RX nRD : out std_logic; -- Read nSIWU : out std_logic; -- Send Immediate / WakeUp nOE : out std_logic; -- Output enable nWR : out std_logic; -- FIFO Buffer Write Enable ADBUS : out std_logic_vector(7 downto 0) -- Bidirectional FIFO data ); end entity; architecture rtl of ft232h_tx is signal counter : unsigned (7 downto 0) := "00000000"; begin -- don't read nOE <= '1'; nSIWU <= '1'; nRD <= '1'; process(FT_CLK, nTXE) variable state : std_logic := '0'; begin if (rising_edge(FT_CLK)) then if(nTXE = '0') then if(state = '1') then nWR <= '0'; -- last data not valid if nTXE goes LOW ADBUS <= std_logic_vector(counter); counter <= counter + 1; end if; state := '1'; else nWR <= '1'; state := '0'; end if; end if; end process; end rtl;  

 

That is a simply counter that continuously count up to 255 and so send 0,1,2..,254,255,0,1,2...,254,255 to pc 

and in SDC file I have set these constraints: 

 

create_clock -name "FT_CLK" -period 16.67ns set_input_delay -clock { FT_CLK } -min 9ns nTXE set_input_delay -clock { FT_CLK } -max 0ns nTXE set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns }] set_output_delay -max -clock "FT_CLK" 7.500ns set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns }] set_output_delay -min -clock "FT_CLK" 0ns  

 

With signaltap I have take this screenshot: 

 

http://imagizer.imageshack.us/v2/xq90/30/e0pc.png (https://imageshack.com/i/0ue0pcp

 

But I can not find the error.. :(
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

Hello 

 

Its been a while seen i placed with this stuff hehe, I ended up going with a STM32F04 micro instead of the ftdi/fpga 

 

Here is my code, hopefully if helps you out :) 

I am sending data the opposite direction, from the pc to the fpga. 

 

.c 

FT_SetBitMode(ftHandle, 0xff, 0); Sleep(10); FT_SetBitMode(ftHandle, 0xff, 0x40); FT_SetLatencyTimer(ftHandle, 16); FT_SetUSBParameters(ftHandle,0x10000, 0x10000); FT_SetFlowControl(ftHandle, FT_FLOW_RTS_CTS, 0x0, 0x0); FT_Purge(ftHandle, FT_PURGE_RX); Sleep(10);  

 

fpga 

// ***************************** // FT2232H Synchronous 245 FIFO // ***************************** always @(posedge fifo_clk) begin case(fifo_state) 0: begin // wait for rxf to go low (byte available) if(rxf==0) begin oe=0; fifo_cnt=0; fifo_state=1; end end 1: begin rd = 0; fifo_state=2; end 2: begin // keep reading data untill rxf goes high if(rxf==1) begin rd = 1; oe = 1; fifo_state=0; end else begin // check frame preamble bytes if(preamble_state<3) begin wr_addr = 0; if(preamble==data_in) preamble_state=preamble_state+1; else preamble_state=0; end else if(preamble_state==3) begin // command byte (unused) preamble_state=4; end else begin // frame data bytes wr_addr = wr_addr + 1; // read in 2048 bytes (full frame) if(wr_addr == 2048) begin wr_addr=0; preamble_state = 0; // swap to next buffer buf_ready=!buf_ready; end end end end endcase end  

 

The fpga side of things a little bit more complex that you might need it as im checking the first three bytes in my packet to keep every thing in sync, if they are wrong it will discard the packet, you can chop this bit of code out if you want. It was for basic error checking and frame sync. 

 

The above code is just the logic for reading in the bytes from the ftdi, give me a shout if you want the full source. It is sort of mixed in with the full project though hehe.
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

So USB data can be corrupted by design by FT232H and we have to implement a CRC check over it?

0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

Its usually ok but in my project i was streaming video frames at a very high fps and if some thing went wrong (very rare) It would screw up the image alignment, So in my case a needed to put in the simple frame header checking just to make sure I new where I was in case there was a little rare glitch. 

 

Im sure you will not need this for sending some data from the fpga to the pc occasionally.
0 Kudos
Altera_Forum
Honored Contributor II
6,413 Views

With great FTDI support I have solved problem TXE signal can go HIGH on falling edge of clock and so it must not be checked only on rising edge. 

 

Working code: 

 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ft232h_tx is port ( FT_CLK : in std_logic; -- 60 MHz FT232H clock nTXE : in std_logic; -- Can TX nRXF : in std_logic; -- Can RX nRD : out std_logic; -- Read nSIWU : out std_logic; -- Send Immediate / WakeUp nOE : out std_logic; -- Output enable nWR : buffer std_logic; -- FIFO Buffer Write Enable ADBUS : out std_logic_vector(7 downto 0) -- Bidirectional FIFO data ); end entity; architecture rtl of ft232h_tx is signal counter : unsigned (7 downto 0) := "00000000"; signal state : std_logic := '0'; begin -- don't read nOE <= '1'; nSIWU <= '1'; nRD <= '1'; process(FT_CLK, nTXE) begin if (rising_edge(FT_CLK)) then if(nTXE = '0') then if(state = '1') then --nWR <= '0'; ADBUS <= std_logic_vector(counter); counter <= counter + 1; end if; state <= '1'; else --nWR <= '1'; state <= '0'; end if; end if; end process; nWR <= '1' when nTXE = '1' else '0' when (nTXE ='0' and state = '1'); end rtl; 

 

Thanks to all
0 Kudos
Reply