Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21615 Discussions

FT2232H write from PC to FPGA not working

Altera_Forum
Honored Contributor II
1,464 Views

I am now using the FT2232H usb chip in FT245 Sync Fifo mode. I tried to write some bytes from PC to FPGA and then read them back. But the following code is not working: what I read back is always 0x55, not what I wrote to FPGA. Here is the code: 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity FTDI_Controller is port( FTDI_RXF_n : in std_logic; FTDI_TXE_n : in std_logic; FTDI_RD_n : out std_logic; FTDI_WR_n : out std_logic; FTDI_OE_n : out std_logic; FTDI_Data : inout std_logic_vector(7 downto 0); CLK_FTDI : in std_logic ); end FTDI_Controller; architecture RTL of FTDI_Controller is begin process(CLK_FTDI) variable rCS: integer range 0 to 2:=0; variable wCS: integer range 0 to 1:=0; variable D_Readed: std_logic_vector(7 downto 0):=x"55"; begin if rising_edge(CLK_FTDI) then --read operations if (FTDI_RXF_n = '0') then FTDI_WR_n <= '1'; wCS:=0; CASE rCS is when 0 => FTDI_OE_n <= '0'; rCS:=1; when 1 => FTDI_RD_n <= '0'; rCS:=2; when 2 => D_Readed := FTDI_Data; when others => rCS:=0; end CASE; else FTDI_RD_n <= '1'; FTDI_OE_n <= '1'; rCS:=0; --write operations if(FTDI_TXE_n ='0') then CASE wCS is when 0 => FTDI_WR_n <= '0'; wCS:=1; when 1 => FTDI_Data <= D_Readed; when others => wCS:=0; end CASE; else FTDI_WR_n <= '1'; wCS:=0; end if; end if; end if; end process; end RTL;
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
719 Views

I believe D_Readed needs to be a registered signal, not a variable.

0 Kudos
Altera_Forum
Honored Contributor II
719 Views

 

--- Quote Start ---  

I believe D_Readed needs to be a registered signal, not a variable. 

--- Quote End ---  

 

I have tried to change D_Readed to a registered signal, but the result is the same. I stuck in this problem for a long time.
0 Kudos
Altera_Forum
Honored Contributor II
719 Views

You can't drive a bidirectional bus in such a simple manner. You need some logic to determine when to drive the bus and when not to. 

 

Try this. I hope it helps and points you in the right direction.library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity FTDI_Controller is port( FTDI_RXF_n : in std_logic; FTDI_TXE_n : in std_logic; FTDI_RD_n : out std_logic; FTDI_WR_n : out std_logic; FTDI_OE_n : out std_logic; FTDI_Data : inout std_logic_vector(7 downto 0); CLK_FTDI : in std_logic ); end FTDI_Controller; architecture RTL of FTDI_Controller is signal D_Readed: std_logic_vector(7 downto 0); signal drive_bus: std_logic; -- Use this to determine control drive of the 'FTDI_Data' bus begin process(CLK_FTDI) variable rCS: integer range 0 to 2:=0; variable wCS: integer range 0 to 1:=0; begin if rising_edge(CLK_FTDI) then drive_bus <= '0'; -- Ensure the bus isnt driven when it shouldn't be --read operations if (FTDI_RXF_n = '0') then FTDI_WR_n <= '1'; wCS:=0; CASE rCS is when 0 => FTDI_OE_n <= '0'; rCS:=1; when 1 => FTDI_RD_n <= '0'; rCS:=2; when 2 => D_Readed <= FTDI_Data; when others => rCS:=0; end CASE; else FTDI_RD_n <= '1'; FTDI_OE_n <= '1'; rCS:=0; --write operations if(FTDI_TXE_n ='0') then CASE wCS is when 0 => FTDI_WR_n <= '0'; drive_bus <= '1'; -- You're writing, so drive the bus... wCS:=1; when 1 => drive_bus <= '0'; -- ... for a bit. Then stop. when others => wCS:=0; end CASE; else FTDI_WR_n <= '1'; wCS:=0; end if; end if; end if; end process; -- Control the data being driven onto the FTDI_Data bus here: FTDI_Data <= D_Readed when drive_bus = '1' else (others => 'Z'); end RTL;  

 

Cheers, 

Alex
0 Kudos
Altera_Forum
Honored Contributor II
719 Views

 

--- Quote Start ---  

You can't drive a bidirectional bus in such a simple manner. You need some logic to determine when to drive the bus and when not to. 

 

Try this. I hope it helps and points you in the right direction.library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity FTDI_Controller is port( FTDI_RXF_n : in std_logic; FTDI_TXE_n : in std_logic; FTDI_RD_n : out std_logic; FTDI_WR_n : out std_logic; FTDI_OE_n : out std_logic; FTDI_Data : inout std_logic_vector(7 downto 0); CLK_FTDI : in std_logic ); end FTDI_Controller; architecture RTL of FTDI_Controller is signal D_Readed: std_logic_vector(7 downto 0); signal drive_bus: std_logic; -- Use this to determine control drive of the 'FTDI_Data' bus begin process(CLK_FTDI) variable rCS: integer range 0 to 2:=0; variable wCS: integer range 0 to 1:=0; begin if rising_edge(CLK_FTDI) then drive_bus <= '0'; -- Ensure the bus isnt driven when it shouldn't be --read operations if (FTDI_RXF_n = '0') then FTDI_WR_n <= '1'; wCS:=0; CASE rCS is when 0 => FTDI_OE_n <= '0'; rCS:=1; when 1 => FTDI_RD_n <= '0'; rCS:=2; when 2 => D_Readed <= FTDI_Data; when others => rCS:=0; end CASE; else FTDI_RD_n <= '1'; FTDI_OE_n <= '1'; rCS:=0; --write operations if(FTDI_TXE_n ='0') then CASE wCS is when 0 => FTDI_WR_n <= '0'; drive_bus <= '1'; -- You're writing, so drive the bus... wCS:=1; when 1 => drive_bus <= '0'; -- ... for a bit. Then stop. when others => wCS:=0; end CASE; else FTDI_WR_n <= '1'; wCS:=0; end if; end if; end if; end process; -- Control the data being driven onto the FTDI_Data bus here: FTDI_Data <= D_Readed when drive_bus = '1' else (others => 'Z'); end RTL;  

 

Cheers, 

Alex 

--- Quote End ---  

 

 

Finally I got it working with your tips. Thanks so much, Alex. :)
0 Kudos
Reply