在用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,启动后一切正常。