Question

Good afternoon!

I am trying to get USB interfacing to work on the Zybo. Because I eventually want to build my own board, I am familiarizing myself with all parts of a functional toolchain. My toolchain looks like this:

  1. Generate hardware platform with Vivado 2016.2, using Digilent HW Platform Guide as a reference. Exporting hardware from Vivado. (Note: Hello World SDK project runs successfully from this HW design).
  2. Use Petalinux 2016.2 to create a project, load in files as necessary, and generate boot image, as described in UG1144. (Using hdf and bit generated with Vivado, FSBL and Device Tree unchanged from petalinux defaults)
  3. Copy BOOT.BIN and image.ub to SD card

Linux boots properly, and I have shell access over UART. However, plugging and unplugging USB devices has no effect. By contrast, the prebuilt image provided in this Petalinux BSP repository based on the Digilent Linux BD can detect and identify USB peripherals.

The default device tree and kernel configuration *look* complaint with the Zynq Linux USB Xilinx wiki page, with the exception that the device tree lines are divided between zynq-7000.dtsi and pcw.dtsi, and Generic ULPI Transceiver Driver is not an option when running petalinux-config -c kernel.

Also, dmesg yields some information when run on the Zynq:

root@julianzybo:~# dmesg | grep -i usb
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
usbcore: registered new interface driver usb-storage
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver

but lsusb isn't even present:

root@julianzybo:~# lsusb
-sh: lsusb: not found

Has anyone successfully built Linux from a custom hardware platform, and gotten USB to work?

EDIT: I have not connected any reset to USB0, but I do see the line

usb-reset = <&gpio0 46 0>;

in the Petalinux-BSP repository device tree. Perhaps a USB reset is necessary?

Edited by jcloiacon

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Hi,

with ZYBO usb I slammed my head for quite a while !!!

The USB pin reset on ZYBO is controlled during the "First Stage Bootloader" :

/******************************************************************************
* This function is the hook which will be called  before the FSBL does a handoff
* to the application. The user can add all the customized code required to be
* executed before the handoff to this routine.
*
* @param None
*
* @return
*		- XST_SUCCESS to indicate success
*		- XST_FAILURE.to indicate failure
*
****************************************************************************/
u32 FsblHookBeforeHandoff(void)
{
	u32 Status;

	Status = XST_SUCCESS;

	/*
	 * User logic to be added here.
	 * Errors to be stored in the status variable and returned
	 */
	fsbl_printf(DEBUG_INFO,"In FsblHookBeforeHandoff function \r\n");

	/* Read Out MAC Address */
	{
		int Status;
		XIicPs Iic;
		XIicPs_Config *Iic_Config;
		XEmacPs Emac;
		XEmacPs_Config *Mac_Config;

		unsigned char mac_addr[6];
		int i = 0;

		fsbl_printf(DEBUG_GENERAL,"Look Up I2C Configuration\n\r");
		Iic_Config = XIicPs_LookupConfig(XPAR_PS7_I2C_0_DEVICE_ID);
		if(Iic_Config == NULL) {
			return XST_FAILURE;
		}

		fsbl_printf(DEBUG_GENERAL,"I2C Initialization\n\r");
		Status = XIicPs_CfgInitialize(&Iic, Iic_Config, Iic_Config->BaseAddress);
		if(Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		fsbl_printf(DEBUG_GENERAL,"Set I2C Clock\n\r");
		XIicPs_SetSClk(&Iic, 200000);

		mac_addr[0] = 0xFA;

		fsbl_printf(DEBUG_GENERAL,"Set Memory Read Address\n\r");
		XIicPs_MasterSendPolled(&Iic, mac_addr, 1, 0x50);
		while(XIicPs_BusIsBusy(&Iic));
		fsbl_printf(DEBUG_GENERAL,"Get Mac Address\n\r");
		XIicPs_MasterRecvPolled(&Iic, mac_addr, 6, 0x50);
		while(XIicPs_BusIsBusy(&Iic));

		fsbl_printf(DEBUG_GENERAL,"MAC Addr: ");
		for(i = 0; i < 6; i++) {
			fsbl_printf(DEBUG_GENERAL,"%02x ", mac_addr[i]);
		}
		fsbl_printf(DEBUG_GENERAL,"\n\r");

		fsbl_printf(DEBUG_GENERAL,"Look Up Emac Configuration\n\r");
		Mac_Config = XEmacPs_LookupConfig(XPAR_PS7_ETHERNET_0_DEVICE_ID);
		if(Mac_Config == NULL) {
			return XST_FAILURE;
		}

		fsbl_printf(DEBUG_GENERAL,"Emac Initialization\n\r");
		Status = XEmacPs_CfgInitialize(&Emac, Mac_Config, Mac_Config->BaseAddress);
		if(Status != XST_SUCCESS){
			return XST_FAILURE;
		}

		fsbl_printf(DEBUG_GENERAL,"Set Emac MAC Address\n\r");
		Status = XEmacPs_SetMacAddress(&Emac, mac_addr, 1);
		if(Status != XST_SUCCESS){
			return XST_FAILURE;
		}

		fsbl_printf(DEBUG_GENERAL,"Verify Emac MAC Address\n\r");
		XEmacPs_GetMacAddress(&Emac, mac_addr, 1);
		if(Status != XST_SUCCESS){
			return XST_FAILURE;
		}
	}

	/* Reset SMSC USB3320 ULPI transceiver */
	{
		int Status;
		XGpioPs Gpio;
		XGpioPs_Config *ConfigPtr;
		volatile int Delay;
		#define RESET_PIN	46
		#define DELAY		10000

		/* Initialize the GPIO driver. */
		ConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
		Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		/* RESET in output mode */
		XGpioPs_SetDirectionPin(&Gpio, RESET_PIN, 1);
		XGpioPs_SetOutputEnablePin(&Gpio, RESET_PIN, 1);

		/* Set the RESET to be high. */
		XGpioPs_WritePin(&Gpio, RESET_PIN, 1);

		/* Delay */
		for (Delay = 0; Delay < DELAY; Delay++);

		/* Set the RESET to be low. */
		XGpioPs_WritePin(&Gpio, RESET_PIN, 0);

		/* Delay */
		for (Delay = 0; Delay < DELAY; Delay++);

		/* Set the RESET to be high. */
		XGpioPs_WritePin(&Gpio, RESET_PIN, 1);

		/* Delay */
		for (Delay = 0; Delay < DELAY; Delay++);

		/* Set the direction for the RESET to be input. */
		XGpioPs_SetDirectionPin(&Gpio, RESET_PIN, 0);
	}

	return (Status);
}

With other test I have compiled working version of linux 3.18 with this "dts" change:

ps7_usb_0: ps7-usb@e0002000 {
    clocks = <&clkc 28>;
    compatible = "xlnx,ps7-usb-1.00.a", "xlnx,zynq-usb-1.00.a";
    dr_mode = "host";
    interrupt-parent = <&ps7_scugic_0>;
    interrupts = <0 21 4>;
    phy_type = "ulpi";
    reg = <0xe0002000 0x1000>;
    xlnx,usb-reset = "MIO 46";
} ;

Linux dmesg:

[    0.890631] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.895843] ehci-pci: EHCI PCI platform driver
[    0.899112] ULPI transceiver vendor/product ID 0x0424/0x0007
[    0.903562] Found SMSC USB3320 ULPI transceiver.
[    0.906790] ULPI integrity check: passed.
[    0.909662] zynq-ehci zynq-ehci.0: Xilinx Zynq USB EHCI Host Controller
[    0.914968] zynq-ehci zynq-ehci.0: new USB bus registered, assigned bus number 1
[    0.949942] zynq-ehci zynq-ehci.0: irq 53, io mem 0x00000000
[    0.969908] zynq-ehci zynq-ehci.0: USB 2.0 started, EHCI 1.00
[    0.975019] hub 1-0:1.0: USB hub found
[    0.977409] hub 1-0:1.0: 1 port detected
[    0.980549] usbcore: registered new interface driver usb-storage
[    1.092779] usbcore: registered new interface driver usbhid
[    1.096961] usbhid: USB HID core driver

debugasm

Share this post


Link to post
Share on other sites
  • 0

jpeyron, something must've gone wonky. This thread is still very much open :(

debugasm, thank you for your answer! Unfortunately, the manual reset in the FSBL has not enabled USB by itself, nor in combination with the proposed device tree changes.

Did you need to make any funky changes to the hardware platform? Also, might there be changes in the way Linux 4 deals with USB?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now