Forum Discussion
Altera_Forum
Honored Contributor
11 years agoFT2232H write from PC to FPGA not working
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;
4 Replies
- Altera_Forum
Honored Contributor
I believe D_Readed needs to be a registered signal, not a variable.
- Altera_Forum
Honored Contributor
--- 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. - Altera_Forum
Honored Contributor
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.
Cheers, Alexlibrary 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; - Altera_Forum
Honored Contributor
--- 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.
Cheers, Alex --- Quote End --- Finally I got it working with your tips. Thanks so much, Alex. :)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;