Alejandro Benitez
Alejandro Benitez

Reputation: 21

Problem communicating FPGA and PC with UM245R USB-parallel conversor

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:

  1. Simulate in the Modelsim the behavior of the VHDL code with respect to the input and output signals based on what the FTDI datasheet proposes and all the signals work correctly.
  2. I have looked for examples of codes to program the FT_Write process and I have tried them, obtaining the same results.
  3. Analyze with an oscilloscope the RXF flag in the UM245R that indicates there is data in the buffer to be received by the FPGA and it does not behave as indicated in the datasheet or the technical manuals (it is always at high level ), in the same way the RD signal does not work as I ask in the code, and yet data is transmitted in the way I mentioned above. What could it be that I'm doing wrong? Could it be that the UM245R has some hardware problem and is broken?. Here I leave my code in VHDL and my function in C. Any help will be apreciated.

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

Answers (1)

jordanvrtanoski
jordanvrtanoski

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

    1. Data in the FIFO buffer AND
    2. POWEREN# = 0

    So 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

Related Questions