Forum Discussion
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 proce...
Altera_Forum
Honored Contributor
12 years agoI found my problem.... I switched the input pins TXE and RXF of the FTDI in my FPGA program.
I didn't noticed the problem directly because I also inverted the signals TXE and RXF. Below the working code of my FTDI controller :library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FTDI_Controller is
port(
-- communication with software
State_WR : in std_logic; -- start writing
State_RD : in std_logic; -- start reading
State_DONE : out std_logic; -- finished with reading or writing
State_Accepted : in std_logic;
State_ReadyToRead : out std_logic;
State_ReadyToWrite : out std_logic; -- when FTDI is ready to write
D_ToWrite : in std_logic_vector(7 downto 0); -- data to write
D_Readed : out std_logic_vector(7 downto 0); -- data readed by interface
-- Connection to hardware FTDI (FT245 COnfiguration)
FTDI_RXF_n : in std_logic; -- When low -> there is Data availible in the fifo
FTDI_TXE_n : in std_logic; -- When low -> Data can be written into the fifo
FTDI_RD_n : out std_logic; -- When low (and RXF_n low)-> Data is clocked to D0..D7 to receive
FTDI_WR_n : out std_logic; -- When low (and TXF_n low)-> Data is written to transmit FIFO
FTDI_OE_n : out std_logic; -- Output enable -> Should be low one clock to drive data onto D0..D7
FTDI_Data : inout std_logic_vector(7 downto 0); -- Data vector
-- Other Connections:
CLK_FTDI : in std_logic ; -- 60 MHz clock driven by FDTI
Reset_n : in std_logic ; -- reset input
);
end FTDI_Controller;
architecture RTL of FTDI_Controller is
-- Create state machine cases
type T_STM_RD is (rd_idle, do_OE, do_RD, read_data,read_done);
type T_STM_WR is (wr_idle, do_WR, burst_write, wr_pause, slow_wr);
signal STM_RD : T_STM_RD;
signal STM_WR : T_STM_WR;
begin
--# EXECUTE EACH CLOCK PULS
process(CLK_FTDI,reset_n)
begin
if(Reset_n = '0') then
D_Readed <= (others => '0');
elsif (rising_edge(CLK_FTDI)) then
if (State_RD = '1' ) then
--# Start sequence of setting flags to read from the FTDI
STM_WR <= wr_idle;
State_ReadyToWrite <='0';
-- Evaluate the read STM.
case STM_RD is
--# # READ IDLE : initialize variables
when rd_idle =>
State_ReadyToRead <='0';
test_outC<='0';
FTDI_OE_n <= '1';
FTDI_RD_n <= '1';
FTDI_Data <= (others => 'Z');
D_Readed <= (others => '0');
-- If FTDI pulls RXF low then data is available. We need to do OE next.
if(FTDI_RXF_n = '0') then
STM_RD <= do_OE;
end if;
--## OUTPUT ENABLE : enable to start reading
when do_OE =>
-- Set output enable one clock pulse before reading command
FTDI_OE_n <= '0';
STM_RD <= do_RD;
--## READ FLAG : Pull RD_n low and go to read state
when do_RD =>
FTDI_RD_n <= '0';
State_ReadyToRead <='1';
STM_RD <= read_data;
--## READING : read until FTDI stops
when read_data =>
-- Finish read operation ?
if(FTDI_RXF_n = '1') then
-- reset FT245 signals
FTDI_OE_n <= '1';
FTDI_RD_n <= '1';
STM_RD <= read_done;
State_DONE<='1';
else
-- *** Here data is comming @ 60MHz ***
D_Readed <= FTDI_Data;
end if;
when read_done =>
State_ReadyToRead <='0';
test_outC<='1';
if(State_Accepted='1') then
State_DONE <='0';
STM_RD<= rd_idle;
else
State_DONE<='1';
end if;
when others =>
end case;
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';
FTDI_Data <= (others => 'Z');
--If FTDI_TXE_n is 0, then FTDI will allow data to be transmitted
if(FTDI_TXE_n ='0') 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;
when burst_write =>
-- If FTDI_TXE_n is asserted, FTDI does not want data anymore, so we pause XMIT:
if(FTDI_TXE_n ='1') then
STM_WR <= wr_pause;
FTDI_WR_n <= '1'; -- Disable write enable
else
FTDI_Data <= D_ToWrite;
end if;
--# # PAUSE : FTDI chip needs a break...
when wr_pause =>
State_ReadyToWrite <='0';
if(FTDI_TXE_n ='0') then
State_ReadyToWrite <='1';
STM_WR <= burst_write;
FTDI_WR_n <= '0'; -- enable writing again
FTDI_Data <= (others => 'Z');
end if;
when others =>
end case;
else
STM_WR <= wr_idle;
STM_RD <= rd_idle;
-- disable FTDI actions
FTDI_WR_n <= '1';
FTDI_OE_n <= '1';
FTDI_RD_n <= '1';
State_ReadyToWrite <='0';
State_ReadyToRead <='0';
State_DONE <='0';
D_Readed<=(others=>'0');
end if;
end if;
end process;
end RTL;