Reputation: 21
I would like some kind of help in a problem I am having. I am trying to communicate an FPGA (Altera De0 Nano kit, VHDL programming) with a PC (LabWindows CVI software, C programming) through an FTDI (UM245R USB-Parallel conversor). For that I am using an asynchronous FIFO communication at about 960 kbps. I have been using the libraries recommended by the FTDI manufacturer ( https://ftdichip.com/wp-content/uploads/2020/08/D2XX_Programmers_GuideFT_000071.pdf and https://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_UM245R.pdf ). Now I am trying to read in the FPGA the data sent from the PC. And here I am having the following problem: when I want to transmit multiple bytes with the Ft_Write function it happens that sometimes all are transmitted correctly, while at other times the transmission is truncated and some data are lost, the latter happens quite frequently. To check for an error I have done the following:
VHDL code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity driver is
port(
clk: in std_logic; --system clock 1MHz
--FTDI ports
datos: in unsigned(7 downto 0); --data bus
rxf: in std_logic; -- signal indicating if data bus can be read (if '1' it cannot be read, if '0' it can be read
rd: out std_logic; -- Reading process can be achieved when '0' and RXF is '0'
leds: out unsigned(7 downto 0)); -- fpga leds
end driver;
architecture driver_arch of driver is
type estado is (CHEQUEO, LECTURA, POSTLECTURA);
signal ME: estado:= CHEQUEO;
begin
process(clk)
begin
if(rising_edge(clk)) then
CASE ME IS
WHEN CHEQUEO=> if(rxf='0') then
rd<='0';
ME<=LECTURA;
end if;
WHEN LECTURA=> leds<=datos;
ME<=POSTLECTURA;
WHEN POSTLECTURA=> rd<='1';
ME<=CHEQUEO;
end CASE;
end if;
end process;
end driver_arch;
And this is the C code ():
// here is the function for sending data
int WriteDevice(char datos[128])
{
// assuming the device is already open
int write=4;
DWORD BytesWritten;
ftStatus = FT_Write(ftHandle, datos, 128, &BytesWritten);
if (ftStatus == FT_OK)
{
// FT_Write OK
write=40;
}
else
{
// FT_Write Failed
write=41;
}
return write;
}
Upvotes: 2
Views: 278
Reputation: 5547
You might have several problems:
As per the datasheet of UM245R, RXF#
, and #
stands for inverted will always be high until there is data in the FIFO buffer, and the flag will go low in case when there is
POWEREN#
= 0So you need to assure POWEREN#
is 0
, and since this signal is not needed to your protocol, take it down with a pull-down
resistor.
You also have issue with the reading of data. As per the datasheet and the diagram 4.4
When high, do not read data from the FIFO. When low, there is data available in the FIFO which can be read by strobing RD#
What you do in the state machine is WAIT-RXF
(CHEQUEO
), RD-LOW+READ
(LECTURA
), RD-HIGH
(POSTLECTURA
). This will not assure that the data available on D[0-7]
when you read it. As per the diagram, when RD#
goes low, there will be a lag of T3 - RD# Active to Valid Data
of maximum 50ns. So your state machine should have 4 states as follows WAIT-RXF
, RD-LOW
, DATA-READ
, RD-HIGH
. Depending on your clock cycle duration, you might need to add a delay state between RD-LOW
and DATA-READ
to assure that there are at least 50ns since RD#
went low before you can start reading the data bus.
Lower the communication speed between the PC and UM245R during debugging (check the comment on the limitation in the specs Data transfer rate to 300 kilobyte / second – VCP Drivers
.
And if the above is your real code, than as Craig mentioned in the comment, there should not be a recursion call write=WriteDevice(datos);
.
Upvotes: 1