ZYNQ-ZedBoard USB HOST问题初探

时间:2024-02-18 18:45:48

在用Vivado (2015.4.2)在ZedBoard上搭建如图所示的PS最小系统时,USB-OTG无法正常使用且在启动LOG中报错。

经过与原厂的各个启动文件进行对比替换,最后确定是Vivado工程生成的bit流出了问题。也就是说建立的工程不对。

USB 启动错误提示信息:外置PHY芯片初始化失败,载入模块失败。

ehci_hcd: USB 2.0 \'Enhanced\' Host Controller (EHCI) Driver
usbcore: registered new interface driver usb-storage
usbcore: registered new interface driver usbserial
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver ftdi_sio
usbserial: USB Serial support registered for FTDI USB Serial Device
e0002000.usb supply vbus not found, using dummy regulator
ci_hdrc ci_hdrc.0: unable to init phy: -110
ci_hdrc: probe of ci_hdrc.0 failed with error -110
mousedev: PS/2 mouse device common for all mice

由于已经排除了fsbl,uboot,内核镜像的问题,那么剩下来看,最可能与硬件配置有关。在查阅USB-PHY部分电路时发现,PHY芯片除了与MIO信号线连接之外,还有两条线:复位OTG-RESETN和5V电源控制线OTG-VBUSOC。其中OTG-VBUSOC已经正常引出,因此只剩下一条就是OTG-RESETN信号线,实际上并未从系统引出。

那么问题会不会出现在这里呢?

首先,查看sysfs中gpio相关信息

root@linaro-ubuntu-desktop:~# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 906-1023, parent: platform/e000a000.gpio, zynq_gpio:

显示为空,即不存在包括otg-resetn这个引脚在内的任何gpio的调用信息。

再看看综合后的RTL网表

也未找到关于OTG-RESETN的任何信息,看来OTG-RESETN确实是没有的。

 

下面是官方样板工程,打开.xdc文件查看,确实有OTG-RESETN输出,对应G17引脚,网络名称是gpio_bd[31]

set_property  -dict {PACKAGE_PIN  H15   IOSTANDARD LVCMOS25} [get_ports gpio_bd[27]]      ; ## XADC-GIO0
set_property  -dict {PACKAGE_PIN  R15   IOSTANDARD LVCMOS25} [get_ports gpio_bd[28]]      ; ## XADC-GIO1
set_property  -dict {PACKAGE_PIN  K15   IOSTANDARD LVCMOS25} [get_ports gpio_bd[29]]      ; ## XADC-GIO2
set_property  -dict {PACKAGE_PIN  J15   IOSTANDARD LVCMOS25} [get_ports gpio_bd[30]]      ; ## XADC-GIO3

set_property  -dict {PACKAGE_PIN  G17   IOSTANDARD LVCMOS25} [get_ports gpio_bd[31]]      ; ## OTG-RESETN

 在回头查看gpio_bd, 在顶层实例文件中找到相关信息

再查找与gpio_bd相关联的模块,在ad_iobuf 模块中做了例化。

  ad_iobuf #(
    .DATA_WIDTH(32)
  ) i_iobuf (
    .dio_t(gpio_t[31:0]),
    .dio_i(gpio_o[31:0]),
    .dio_o(gpio_i[31:0]),
    .dio_p(gpio_bd));

那么这个ad_iobuf又是做什么的呢?

module ad_iobuf (

  dio_t,
  dio_i,
  dio_o,
  dio_p);

  parameter     DATA_WIDTH = 1;              //参数可配置,总共例化DATA_WIDTH个实例

  input   [(DATA_WIDTH-1):0]  dio_t;
  input   [(DATA_WIDTH-1):0]  dio_i;
  output  [(DATA_WIDTH-1):0]  dio_o;
  inout   [(DATA_WIDTH-1):0]  dio_p;

  genvar n;
  generate
  for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_iobuf
  assign dio_o[n] = dio_p[n];
  assign dio_p[n] = (dio_t[n] == 1\'b1) ? 1\'bz : dio_i[n];
  end
  endgenerate

endmodule

这是ADI公司自己写的一个模块,实际上是实现了一个通用gpio的功能,通过EMIO原有的输入(dio_i),输出(dio_o),高阻(dio_t)组合而成一个标准的双向可编程gpio。并由顶层实例中的32个gpio_bd引脚。(注意ad_iobuf

中的多重例化)

 

 实际上它对应的正是EMIO的第31位。

再结合之前xdc文件中的描述我们可以知道,OTG-RESETN引脚即是gpio_bd[31].

在自己建立的工程中加入EMIO后,并为OTG-RESETN分配好引脚和网络

set_property  -dict {PACKAGE_PIN  G17   IOSTANDARD LVCMOS25} [get_ports gpio_bd[31]]      ; ## OTG-RESETN

重新生成bit流文件,和BOOT.BIN,启动后一切正常。