【问题标题】:Problem communicating FPGA and PC with UM245R USB-parallel conversor使用 UM245R USB 并行转换器通信 FPGA 和 PC 时出现问题
【发布时间】:2021-03-09 03:48:17
【问题描述】:

我想为我遇到的问题提供一些帮助。 我正在尝试通过 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/Modules/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; 
} 

【问题讨论】:

  • 您的WriteDevice 函数正在递归地调用自己。你确定那是你想要的吗?我从未见过在设备 I/O 例程中使用递归。还有WriteDevice没有参数列表(这个有点草率)。
  • 嗨,我很抱歉,你所说的递归是真的。我编辑了代码。我试图执行一个 hibrid,因为 C 代码很大,我想让你看到数组“datos”的起源。但是现在(编辑)的方式实际上是我拥有代码的方式。很抱歉。

标签: c vhdl fpga ftdi labwindows


【解决方案1】:

你可能有几个问题:

  • 根据 UM245R 的数据表,RXF## 代表反转将始终为高,直到 FIFO 缓冲区中有数据,如果有数据,标志将变为低

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

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

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

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

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

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

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

【讨论】:

  • 我一直以为PWREN是一个输出,UM245R数据表上说“设备通过USB配置后变低,USB挂起时变高。可用于控制外部逻辑P通道的电源逻辑电平 MOSFET 开关。这种方式使用 PWREN# 引脚时启用接口下拉选项。”,我没有在挂起模式下使用它。
  • 在 VHDL 代码中的读取过程中,我的时钟有一个 1 us 周期,所以状态机每 1 us 改变一次状态,我认为这样我可以避免所有的过程等待 UM245 数据表中提到的 T3 和 T5 时间。如果我错了,请告诉我,当我模拟 VHDL 代码时,它可以正常运行
  • 在模拟中,您将无法正确获得噪声和“上升时间”。一些智能工具可以识别这样的某些情况(例如具有瞬态分析的 TINA),但并非总是如此,也不是在任何情况下。在现实生活中,双方都会涉及到一个电容,不仅来自 UM245R,还包括 FPGA。 FPGA 门需要一些时间来改变输出状态,并且需要一些时间来稳定输入的状态,然后才能读取。当输入完全稳定时,这无关紧要,但由于您在同一边触发所有这可能会导致问题。
  • 所以实际上你正在处理T - FPGA up + T3 - RD# Active Valid + T -FPGA Read Valid。如果您试图“保存”时钟。 T5 - RD# Inactive to RXF# 不是问题,您可以忽略,因为在 RD# 变低后,您有 2 个周期。
  • 我按照你说的做了,我的意思是,我添加了一个时钟脉冲用于什么都不做,只是为了等待,在状态机的状态之间并没有工作,它有同样的随机问题一次同时,我也快要放弃了。任何其他建议将不胜感激
猜你喜欢
  • 1970-01-01
  • 2015-08-30
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-05
相关资源
最近更新 更多