News:

Attention: For security reasons,please choose a user name *different* from your login name.
Also make sure to choose a secure password and change it regularly.

Main Menu

USB on TE0720 Petalinux 2014.4

Started by whitsydaddy, September 30, 2015, 10:50:43 PM

Previous topic - Next topic

whitsydaddy

Hello,
I have a TE0720 and am building a linux PS. I need to interface to a USB camera on this system.  On bootup I get an error: unable to init USB: phy missing?  This is on bootup of the system.  I saw an earlier post about this problem and that the USB needs to be reset either in the FSBL or u-boot.  I do not see where I would do this.  Can you help?  Thanks, Scott

Oleksandr Kiyenko

Hello Scott,

Usually that should be done in FSBL.
Edit fsbl_hooks.c and add code


#include "xemacps.h"
#include "xparameters.h"

...

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");
   u16 rval16;

   XEmacPs Emac;
   XEmacPs_Config *Mac_Config;

   unsigned char mac_addr[6];
   int i = 0;
   // MII Patch
   *((int *)0xE000B000) = 0x00000010;
   *((int *)0xE000B004) = 0x00100000;


   Mac_Config = XEmacPs_LookupConfig(XPAR_PS7_ETHERNET_0_DEVICE_ID);
   if(Mac_Config == NULL) {
      return XST_FAILURE;
   }

   Status = XEmacPs_CfgInitialize(&Emac, Mac_Config, Mac_Config->BaseAddress);
   if(Status != XST_SUCCESS){
      return XST_FAILURE;
   }

   Status = XEmacPs_PhyRead(&Emac, 0x1A,  9, &rval16);
   if(Status != XST_SUCCESS){
      return XST_FAILURE;
   }
   mac_addr[0] = (unsigned char)(rval16 >> 8);   mac_addr[1] = (unsigned char)(rval16 & 0xFF);

   Status = XEmacPs_PhyRead(&Emac, 0x1A,  10, &rval16);
   if(Status != XST_SUCCESS){
      return XST_FAILURE;
   }
   mac_addr[2] = (unsigned char)(rval16 >> 8);   mac_addr[3] = (unsigned char)(rval16 & 0xFF);

   Status = XEmacPs_PhyRead(&Emac, 0x1A,  11, &rval16);
   if(Status != XST_SUCCESS){
      return XST_FAILURE;
   }
   mac_addr[4] = (unsigned char)(rval16 >> 8);   mac_addr[5] = (unsigned char)(rval16 & 0xFF);

    xil_printf("\n\r+----------------------------------------------------------------+\n\r");
      xil_printf("|           TE0720 Unique MAC Addr: ");
      for(i = 0; i < 6; i++) {
         xil_printf("%02x ", mac_addr);
      }
      xil_printf("           |\n\r");
    xil_printf("+----------------------------------------------------------------+\n\r" );

   Status = XEmacPs_SetMacAddress(&Emac, mac_addr, 1);
   if(Status != XST_SUCCESS){
      return XST_FAILURE;
   }
   XEmacPs_GetMacAddress(&Emac, mac_addr, 1);
   if(Status != XST_SUCCESS){
      return XST_FAILURE;
   }

   // Disable fiber
   Status = XEmacPs_PhyWrite(&Emac, 0x00, 0x16, 0x0012);
   Status = XEmacPs_PhyWrite(&Emac, 0x00, 0x14, 0x8210);
   Status = XEmacPs_PhyWrite(&Emac, 0x00, 0x16, 0x0000);
   // Reset USB
   Status = XEmacPs_PhyWrite(&Emac, 0x1A, 0x07, 0x0010);
   Status = XEmacPs_PhyWrite(&Emac, 0x1A, 0x07, 0x0000);

   return (Status);
}


That or similar code you can found in all our examples
Best regards
Oleksandr Kiyenko

whitsydaddy

So I see a bit of code dealing with the Ethernet phy and getting and setting the mac address as well as the reset to the USB.  I don't need all of that correct? Just the code that initializes the emac driver?

Oleksandr Kiyenko

Hello,

If you need only USB and not use Ethernet, you need only code with XEmacPs_LookupConfig and then
// Reset USB
   Status = XEmacPs_PhyWrite(&Emac, 0x1A, 0x07, 0x0010);
   Status = XEmacPs_PhyWrite(&Emac, 0x1A, 0x07, 0x0000);
System controller is listen MDIO bus and this commands operate USB reset

Best regards
Oleksandr Kiyenko

whitsydaddy

So I had to put the USB reset on the backburner for a bit. So from what I see here I will need to have the system controller (CPLD) connected to reset the USB?

Antti Lukats

you just need to use our FSBL or add a few lines that resets the PHY during FSBL startup.

the system controller appears as EXTRA PHY and can be addressed over MDIO bus, that what the code does. You do not need anything in FPGA that all is connected to PS MIO peripheral pins and is available when FPGA is not loaded.

whitsydaddy

Antti,
So I added code the code in fsbl_hooks.c per Oleksandr's instrunctions (MAC lookup, control LEDs and reset the USB phy).  I see that my changes are incorporated in the zynq_fsbl.elf when I boot up.  When I plug in a USB device it is still not recognized.  I also notice that there is no voltage on the USB connector power pin.  Now if I flip the DIP switch on our 0703 carrier board and boot up to the default build I can see 5V on the USB power pin and the OS will recognize my USB device.
Is there something else I need to do to setup the USB?  Note that I have now moved up to Petalinux 2015.2 and Vivado 2015.2.

Antti Lukats

did phy init succeed in linux?

if not you still have issue with the phy and nothing will work.

whitsydaddy

Antti,
I still don't have it working.  From what I see I think Xilinx broke it in the new tools (petaLinux2015.2)  >:(.
https://forums.xilinx.com/t5/Embedded-Linux/Petalinux-2015-2-1-usb-not-working/td-p/654349

When I get a chance I will try to resolve this.  Thanks for your help.

Antti Lukats

there is was a mess with the driver change for ethernet, but 2015.4 it does work again, just the device tree change is needed.

whitsydaddy

That is adding the USB to system-top.dts in that forum post?

Antti Lukats

no not that post, no.

this example from our ZynqBerry (has same PHY)

================
/{
   usb_phy0: usb_phy@0 {
      compatible = "ulpi-phy";
      #phy-cells = <0>;
      reg = <0xe0002000 0x1000>;
      view-port = <0x0170>;
      drv-vbus;
   };
};

&usb0 {
   usb-phy = <&usb_phy0>;
} ;

================
this is ALL changes required for the top devicetree. thats it. 2015.4, not sure about 2015.2,


whitsydaddy

Antti,
Thanks, the device tree edits with the fsbl_hooks.c updates to reset the USB worked.