2

我想为我遇到的问题提供一些帮助。我正在尝试通过 FTDI(UM245R USB 并行转换器)将 FPGA(Altera De0 Nano 套件,VHDL 编程)与 PC(LabWindows CVI 软件,C 编程)进行通信。为此,我使用了大约 960 kbps 的异步 FIFO 通信。我一直在使用 FTDI 制造商推荐的库(https://ftdichip.com/wp-content/uploads/2020/08/D2XX_Programmers_GuideFT_000071.pdfhttps://www.ftdichip.com/Support/Documents/DataSheets/模块/DS_UM245R.pdf)。现在我试图在 FPGA 中读取从 PC 发送的数据。在这里我遇到了以下问题:当我想使用 Ft_Write 函数传输多个字节时,有时会发生所有都正确传输,而在其他时候传输被截断并且丢失了一些数据,后者经常发生。为了检查错误,我执行了以下操作:

  1. 根据 FTDI 数据表的建议,在 Modelsim 中模拟 VHDL 代码相对于输入和输出信号的行为,并且所有信号都正常工作。
  2. 我已经寻找了编写 FT_Write 过程的代码示例,并且我已经尝试过它们,获得了相同的结果。
  3. 用示波器分析 UM245R 中的 RXF 标志,表示缓冲区中有数据要被 FPGA 接收,并且它的行为与数据表或技术手册中指示的不同(它始终处于高电平),同样正如我在代码中所要求的那样,RD 信号不起作用,但数据是以我上面提到的方式传输的。我做错了什么?会不会是UM245R有硬件问题坏了?在这里,我将我的代码保留在 VHDL 中,将我的函数保留在 C 中。任何帮助都将不胜感激。

VHDL代码:

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;

这是C代码():

// 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; 
} 
4

1 回答 1

1

你可能有几个问题:

  • 根据 UM245R 的数据表RXF#, 和#代表反转将始终为高,直到 FIFO 缓冲区中有数据,并且标志将变低以防万一

    1. FIFO 缓冲区中的数据 AND
    2. POWEREN#= 0

    因此,您需要确保POWEREN#is 0,并且由于您的协议不需要此信号,因此请使用pull-down电阻器将其取下。

  • 您也有读取数据的问题。根据数据表和图表 4.4

    高电平时,不要从 FIFO 中读取数据。低电平时,FIFO 中有可用数据,可通过选通 RD# 读取

    您在状态机中所做的是WAIT-RXF( CHEQUEO), RD-LOW+READ( LECTURA), RD-HIGH( POSTLECTURA)。这不能保证D[0-7]在您阅读时数据可用。根据图表,当RD#变低时,将有T3 - RD# Active to Valid Data最大 50ns 的延迟。所以你的状态机应该有 4 个状态,如下WAIT-RXF, RD-LOW, DATA-READ, RD-HIGH。根据您的时钟周期持续时间,您可能需要在 和 之间添加一个延迟状态RD-LOW,以确保在开始读取数据总线之前DATA-READ至少有 50ns 的时间变低。RD#

  • 在调试过程中降低 PC 和 UM245R 之间的通信速度(查看规格中限制的注释Data transfer rate to 300 kilobyte / second – VCP Drivers

  • 如果上面是您的真实代码,那么正如 Craig 在评论中提到的那样,不应该有递归调用write=WriteDevice(datos);

于 2021-03-09T05:42:21.427 回答