cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Participant
Participant
12,045 Views
Registered: ‎09-14-2010

zynq- usb core as peripherial

Jump to solution

hey guys. Im stuck. Can anyone point me at a doc that describes how to change the Zynqs usb core to configure as a peripherial rather than as a host? Based on the output that I am getting out dmesg, with xilinx default device tree and default kernel, an ehci host driver is associating itself with a particular USB bus, but I can't get the device controller driver to do the same.

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Participant
Participant
12,300 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

got it working. I can ping the board as I would any other ethernet device.  Dumb problem, as it turns out... first stage boot loader was wrong. I only started paying attention to it when I starting messing with it in standalone mode. Ah well.

View solution in original post

0 Kudos
18 Replies
Highlighted
Xilinx Employee
Xilinx Employee
12,041 Views
Registered: ‎09-10-2008

Re: zynq- usb core as peripherial

Jump to solution

Hi,

 

Sorry for our lack of documentation, we need to work on the device tree bindings.

 

The dr_mode should be "host", "otg" or "peripheral".

 

Thanks.

0 Kudos
Highlighted
Participant
Participant
12,037 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

john,

 

perfectly alright about documentation, we have the same problem at Pico.

 

you are refering to the field in the zynq-zc702.dts? I've already modified that and had no success.

 

I'm defining "success" here as being detected by my host Windows system. I had another ARM board working as a peripherial, and for windows to detect the device, the only thing I had to do was "modprobe g_ether". I am trying an "insmod $(the path to the file on the ramdisk)/g_ether.ko"  on the zynq serial terminal I have, and it appears to be binding to the xilinx_usbps_udc driver, but windows still doesn't spot a new device.

 

Let me put together some output for you and I'll show you more precisely what I mean.

 

On a tangential note, zynq-zc702.dts didn't work for me out of the box, either on the 702 (I don't have it any more) or on our board, without removing a few of the listings for unrelated devices; qspi, ethernet (for now) and i2c. 

0 Kudos
Highlighted
Participant
Participant
12,034 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

----------------output from dtc with zynq-zc702 from GIT----------------------

rootfs image is not initramfs (no cpio magic); looks like an initrd
Freeing initrd memory: 8192K
PMU: registered new PMU device of type 0
xscugtimer xscugtimer.0: ioremap f8f00200 to d880c200 with size 400
pl330 dev 0 probe success
highmem bounce pool size: 64 pages
JFFS2 version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red Hat, Inc.
msgmni has been set to 710
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
e0001000.uart: ttyPS0 at MMIO 0xe0001000 (irq = 82) is a xuartps
console [ttyPS0] enabled
xdevcfg f8007000.devcfg: ioremap f8007000 to d8862000 with size 1000
brd: module loaded
loop: module loaded
----------------output from dtc with zynq-zc702 with qspi, ethernet, and i2c sections removed----------------------
 
e0001000.uart: ttyPS0 at MMIO 0xe0001000 (irq = 82) is a xuartps
console [ttyPS0] enabled
xdevcfg f8007000.devcfg: ioremap f8007000 to d8862000 with size 1000
brd: module loaded
loop: module loaded
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
xusbps-ehci xusbps-ehci.0: Xilinx PS USB EHCI Host Controller
xusbps-ehci xusbps-ehci.0: new USB bus registered, assigned bus number 1
xusbps-ehci xusbps-ehci.0: irq 53, io mem 0x00000000
xusbps-ehci xusbps-ehci.0: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
Xilinx PS USB Device Controller driver (Apr 01, 2011)
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
...
...
++ Mounting filesystem
++ Setting up mdev
++ Starting telnet daemon
++ Starting http daemon
++ Starting ftp daemon
++ Starting dropbear (ssh) daemon
rcS Complete
zynq>
----------------output from dtc with zynq-zc702 with qspi, ethernet, and i2c sections removed, and dr_mode = "otg" -------
brd: module loaded
loop: module loaded
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
Xilinx PS USB Device Controller driver (Apr 01, 2011)
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
Linux video capture interface: v2.00
gspca: v2.13.0 registered
usbcore: registered new interface driver uvcvideo
USB Video Class driver (v1.1.0)
...
...
++ Mounting filesystem
++ Setting up mdev
++ Starting telnet daemon
++ Starting http daemon
++ Starting ftp daemon
++ Starting dropbear (ssh) daemon
rcS Complete
zynq>

-------------------loading g_ether module------------------------

zynq> insmod drivers/usb/gadget/g_ether.ko
g_ether gadget: using random self ethernet address
g_ether gadget: using random host ethernet address
usb0: MAC ea:18:b6:37:f1:57
usb0: HOST MAC 2e:4a:4b:1d:8d:96
g_ether gadget: controller 'xusbps-udc' not recognized; trying CDC Ethernet (ECM
)
g_ether gadget: Ethernet Gadget, version: Memorial Day 2008
g_ether gadget: g_ether ready
xusbps-udc: bind to driver g_ether

0 Kudos
Highlighted
Scholar
Scholar
12,021 Views
Registered: ‎05-28-2012

Re: zynq- usb core as peripherial

Jump to solution

I had problems with the qspi driver hanging the boot. Eventually figured out that any access by the qspi driver to the qspi memory range was causing some sort of exception or bus hang. Traced this down to the qspi pins not being muxed to pins. Seems the Zynq chip won't let you access the qspi registers unless you mux the pins (in FSBL ps7_init.c). The qspi driver cannot just drive a qspi controller connected to the ether. Unlike most other processors.

The "not recognized" warning appears to be due to missing code in
drivers/usb/gadget/gadget_chips.h

#ifdef CONFIG_USB_GADGET_XILINX
#define gadget_is_xlnx(g)       !strcmp("xilinx_udc", (g)->name)
#else
#define gadget_is_xlnx(g)       0
#endif

#ifdef CONFIG_USB_XUSBPS                                         /*ADD*/
#define gadget_is_xlnx_ps(g)    !strcmp("xusbps-udc", (g)->name) /*ADD*/
#else                                                            /*ADD*/
#define gadget_is_xlnx_ps(g)    0                                /*ADD*/
#endif                                                           /*ADD*/
...
static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
{
    if (gadget_is_net2280(gadget))
        return 0x01;
...
    else if (gadget_is_xlnx(gadget))   /*ADD*/
        return 0x00;               /*ADD*//*What's the official value?*/
    else if (gadget_is_xlnx_ps(gadget))/*ADD*/
        return 0x00;               /*ADD*//*What's the official value?*/

    return -ENOENT;
}

The warning probably won't stop the gadget from working. Most of the gadgets will continue with a 0x99 number.

Maybe try a simpler test of g_serial.ko and dr_mode="peripheral". I vaguely remember OTG might need file system hot plug scripts. Or not. Memory is not good on that. Double check the EDK/ISE to see if the USB pins are muxed to pins. I can't remember if they are dedicated pins.

 

0 Kudos
Highlighted
Participant
Participant
12,016 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

norman

you are correct, I don't think the "not recognized" bug is a problem either; its still binding, after all.

it does occur to me, however, that the g_ether gadget is not included in the stock kernel; I think by default only g_zero and g_file_storage are included. I know that insmoding g_zero refuses to start the gadget, but I may not have been through enough testing g_file_system.

 

regarding peripheral mode, I tried that too; it did not behave differently from otg mode.

 

regarding pins, I know that (some of) the pins for both the USB can potentially to assigned to other peripherial ports. I'm not sure if that answers your question though.

 

Is there a testing method either of you would suggest over the one that I am using?

0 Kudos
Highlighted
Scholar
Scholar
12,009 Views
Registered: ‎05-28-2012

Re: zynq- usb core as peripherial

Jump to solution

Not sure about what you mean by gadgets included in the stock kernel. The demo file systems from Xilinx do not even have a /lib//modules/linux* directory.

 

For testing, I usually use the g_serial.ko gadget. It's pretty simple. The mass storage gadgets can get messed up in setting up the backing store and configuring the removable v non-removable bit. If insmod doesn't work, I think you are stuck tracing the HW.

- Scope out the D signals. The Host should try to wiggle the lines.

- Scope out VBus. I'm a firmware guy. Not my specialty. Can't remember if VBus is supposed to be floating or tied for peripheral only functionality.

- Try a different cable. No really. It's surprising how cables can let you down. Something with the the Host deciding on turning VBus on depending on the impedance it sees on the line.

- The USB pins could be unmuxed away by other drivers. Unlikely as Xilinx tries to move all that into the SDK ps7_init.c in the FSBL.

- If you have any USB utils on the PC side, check to see if the PC might have partially enumerated the device. Quick check would be to look into the Device Manager and look for exclamation marks on devices that didn;t load.

 

That's all I got.

 

 

0 Kudos
Highlighted
Participant
Participant
11,966 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

alright. I'm finally getting somewhere.

 

So on a co-worker's suggestion, I tested the board with one of the device mode samples from EDK in standalone mode; one that configures the board as a thumb drive analog. This works, right out of the box. I also found some relevant documentation in the Zynq TRM (Chapter 15 sections 8.1, and 8.2). After biding to a gadget driver, the device control driver is supposed to change the values in the USBMODE, an interrupt control, and the USBCMD registers... and, I think, issue a bus reset after all that. The driver that I'm looking at ($(kernel_root)/drivers/usb/gadget/xilinx_usbps_udc.c; see the dr_controller_run function) only does the first three things... it seems like an error of this sort would stop anything from working... so I figure there's a reasonable chance I'm not looking at the right driver, if this is claimed to work.

 

If this indeed doesn't work, I'm pretty sure I can fix it, but having only cut my teeth on linux development a month ago, I am not sure what I ought to contribute back to git or wherever. or even if I should.

0 Kudos
Highlighted
Participant
Participant
11,946 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

I spoke too soon. still doesn't work.

 

I started looking at the automated devicetree that SDK can produce. Looking at the .tcl script associated with it (device-tree/bsp/device-tree_v0_00_x/data# ./device-tree_v2_1_0.tcl, with the source from http://xilinx.wikidot.com/device-tree-generator). I found that the default for USB0 is 'host', but the default for USB1 is 'device'. 'device' is not even an acceptable mode (the correct term is 'peripheral'). I assume this is a bug?

 

Also, I had previously observed the raw address that xusbps_readl and xusbps_writel calls, in the dr_controller_run function defined in xilinx_usbps.udc.c,  were not reporting the same address defined in devicetree (0xE0860000 vs E0002000). I had thought that they were in a seperate address bank from a data region, but a closer reading of the TRM suggests this is not the case. Unless the definition of readl and writel on the ARM was written NOT to use absolute addressing, in contrast withwhat google claims is the standard definition, this suggests that the address data in devicetree is getting ignored... and yet the dr_mode data in devicetree is not getting ignored.

 

Huh?

0 Kudos
Highlighted
Scholar
Scholar
11,925 Views
Registered: ‎05-28-2012

Re: zynq- usb core as peripherial

Jump to solution

The address that you see in xilinx_usbps.udc.c is probably a virtual address. The dr_regs pointer should match the pdata->regs pointer in xusbps-dr-of.c.

It's been a while but vaguely remember the actual bind() does not occur until the specifc gagdet driver (eg. g_serial.ko) is installed and the USB cable is plugged in.

This Wiki page, http://wiki.xilinx.com/zynq-linux, states that the device tree generator does not support the Zync.

 

0 Kudos
Highlighted
Participant
Participant
8,770 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution
norman,

correct again. xusbps-dr-of.c does indeed do a virtualization step, so a virtual offset isn't something to worry about, at least not necessecarily.

regarding bind(), I know that you can bind independently of a USB cable inserted or not.

regarding device tree generator, I will use the old device tree because I don't see any reason to introduce any more variables than I need to.

that said, it seems believable that the device tree out of the generator can work without much fuss. What I am getting out of it does not behave differently than the devicetree that I did hand-edits on, at least regarding the USB, and booting the linux kernel.
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
8,765 Views
Registered: ‎09-10-2008

Re: zynq- usb core as peripherial

Jump to solution
I've sort of followed this, but then got behind on it. I have tested (not for a bit) the 702 as a device. There are jumpers that need to be set for the device mode also, I would think that's in the user guide for the board but don't know for sure. I used schematics as there was no user guide. You should not need to do anything but set the jumpers and change the dr_mode in the device tree. Thanks.
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
8,761 Views
Registered: ‎09-10-2008

Re: zynq- usb core as peripherial

Jump to solution
I just tested it and it seems to work with the g_mass_storage gadget driver on the ZC702 board. I'm seeing that you don't need to change the jumpers even though I thought you should have to. I just tested on the 14.2 release. All I did was change dr_mode to "peripheral", created a temporary file for the mass storage, and then inserted the g_mass_storage module from the SD card and the PC recognized the FAT file system and allow me to write to it. Hope that helps
0 Kudos
Highlighted
Participant
Participant
12,301 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

got it working. I can ping the board as I would any other ethernet device.  Dumb problem, as it turns out... first stage boot loader was wrong. I only started paying attention to it when I starting messing with it in standalone mode. Ah well.

View solution in original post

0 Kudos
Highlighted
Participant
Participant
8,741 Views
Registered: ‎09-14-2010

Re: zynq- usb core as peripherial

Jump to solution

I recall someone telling me that you used this exact test( embedded linux with g_mass_storage) to benchmark the speed of the zynq in peripheral mode... And that the speed turned out to be 20 MBytes/sec? is that correct? I ask because I just benchmarked the zynq as a peripheral, and the speed topped out at 12 MB/sec (not 12 Mb/sec) . At the moment it seems like my testing apparatus is not up to snuff, but it could also be a limitation of the USB core, or a limitation of the controller driver... if my reccolection is true that would exonerate both of them.

0 Kudos
Highlighted
Visitor
Visitor
8,668 Views
Registered: ‎09-05-2012

Re: zynq- usb core as peripherial

Jump to solution

Hi, I'm new to high-speed usb programming. How exactly did you initialize the usb ulpi as a peripheral and how might I check that its speed is 480Mbps?

 

I'm following the Zynq-7000 EPP Technical Reference Manual, chapter 15. Is there any code or pointers that you would be willing to share so that I do not have to completely re-ivent the wheel? Not that I mind doing so, because I will learn more, but your help will be greatly appreciated.

 

Thank you.

0 Kudos
Highlighted
Visitor
Visitor
8,383 Views
Registered: ‎11-12-2012

Re: zynq- usb core as peripherial

Jump to solution

Hi madboat,

 

Might I ask what you changed in the FSBL to get it working?

My board won't enumerate correctly...

 

 

0 Kudos
Highlighted
Newbie
Newbie
8,221 Views
Registered: ‎01-28-2013

Re: zynq- usb core as peripherial

Jump to solution
hey John Linn ,i see you email about zynq-usb core as peripheral,and i according to your idea,but liinux kernel can't g_file_stroage.ko; my operation step as follows,please give me help: (1)make usb image file zynq> dd bs=1M count=16 if=/dev/zero of=/root/bkup dd: writing '/root/bkup': No space left on device 6+0 records in 4+1 records out 4214784 bytes (4.0MB) copied, 0.044126 seconds, 91.1MB/s zynq> fidsk /root/bkup -/bin/ash: fidsk: not found zynq> fdisk /root/bkup Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT di sklabel Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that the previous content won't be recoverable. Unknown value(s) for: cylinders (settable in the extra functions menu) Command (m for help): x Expert command (m for help): s Number of sectors (1-63, default 63): 8 Warning: setting sector offset for DOS compatiblity Expert command (m for help): h Number of heads (1-256, default 255): 16 Expert command (m for help): c Number of cylinders (1-1048576): 1024 Expert command (m for help): r Command (m for help): p Disk /root/bkup: 4 MB, 4214784 bytes 16 heads, 8 sectors/track, 1024 cylinders Units = cylinders of 128 * 512 = 65536 bytes Device Boot Start End Blocks Id System Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-1024, default 1): Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-1024, default 1024): Using default value 1024 Command (m for help): p Disk /root/bkup: 4 MB, 4214784 bytes 16 heads, 8 sectors/track, 1024 cylinders Units = cylinders of 128 * 512 = 65536 bytes Device Boot Start End Blocks Id System /root/bkup1 1 1024 65532 83 Linux Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table fdisk: WARNING: rereading partition table failed, kernel still uses old table: I nappropriate ioctl for device zynq> ls (2) load kernel g_file_storage error status (kernel:14.4 realease,other realease version 14.2,14.3 the same question) zynq> cd lib/modules/3.6.0/kernel/drivers/usb/gadget/ zynq> pwd /lib/modules/3.6.0/kernel/drivers/usb/gadget zynq> ls g_file_storage.ko g_zero.ko zynq> insmod g_file_storage.ko file=/root/bkup stall=0 removable=1 g_file_storage xusbps-udc.0: failed to start File-backed Storage Gadget: -22 insmod: can't insert 'g_file_storage.ko': invalid parameter (3)load g_zero.ko status as fllows(pc host find not gadget zero drive,why?) zynq> insmod g_zero.ko Gadget Zero: controller 'xusbps-udc' not recognized zero gadget: Gadget Zero, version: Cinco de Mayo 2008 zero gadget: zero ready xusbps-udc: bind to driver zero
0 Kudos
Highlighted
Newbie
Newbie
8,218 Views
Registered: ‎01-28-2013

Re: zynq- usb core as peripherial

Jump to solution
hey John Linn ,i see you email about zynq-usb core as peripheral,and i according to your idea,but liinux kernel can't g_file_stroage.ko; my operation step as follows,please give me help: (1)make usb image file zynq> dd bs=1M count=16 if=/dev/zero of=/root/bkup dd: writing '/root/bkup': No space left on device 6+0 records in 4+1 records out 4214784 bytes (4.0MB) copied, 0.044126 seconds, 91.1MB/s zynq> fidsk /root/bkup -/bin/ash: fidsk: not found zynq> fdisk /root/bkup Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT di sklabel Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that the previous content won't be recoverable. Unknown value(s) for: cylinders (settable in the extra functions menu) Command (m for help): x Expert command (m for help): s Number of sectors (1-63, default 63): 8 Warning: setting sector offset for DOS compatiblity Expert command (m for help): h Number of heads (1-256, default 255): 16 Expert command (m for help): c Number of cylinders (1-1048576): 1024 Expert command (m for help): r Command (m for help): p Disk /root/bkup: 4 MB, 4214784 bytes 16 heads, 8 sectors/track, 1024 cylinders Units = cylinders of 128 * 512 = 65536 bytes Device Boot Start End Blocks Id System Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-1024, default 1): Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-1024, default 1024): Using default value 1024 Command (m for help): p Disk /root/bkup: 4 MB, 4214784 bytes 16 heads, 8 sectors/track, 1024 cylinders Units = cylinders of 128 * 512 = 65536 bytes Device Boot Start End Blocks Id System /root/bkup1 1 1024 65532 83 Linux Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table fdisk: WARNING: rereading partition table failed, kernel still uses old table: I nappropriate ioctl for device zynq> ls (2) load kernel g_file_storage error status (kernel:14.4 realease,other realease version 14.2,14.3 the same question) zynq> cd lib/modules/3.6.0/kernel/drivers/usb/gadget/ zynq> pwd /lib/modules/3.6.0/kernel/drivers/usb/gadget zynq> ls g_file_storage.ko g_zero.ko zynq> insmod g_file_storage.ko file=/root/bkup stall=0 removable=1 g_file_storage xusbps-udc.0: failed to start File-backed Storage Gadget: -22 insmod: can't insert 'g_file_storage.ko': invalid parameter (3)load g_zero.ko status as fllows(pc host find not gadget zero drive,why?) zynq> insmod g_zero.ko Gadget Zero: controller 'xusbps-udc' not recognized zero gadget: Gadget Zero, version: Cinco de Mayo 2008 zero gadget: zero ready xusbps-udc: bind to driver zero
0 Kudos