UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor teastham
Visitor
8,674 Views
Registered: ‎11-11-2016

How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3

I am presently designing a peripheral device with a ZC702 board using PetaLinux. The examples provided for USB OTG peripherals are either mass storage or Ethernet over USB. Both of these examples work with the board. I am now trying to implement the board as a simple OTG peripheral with a Bulk In/Out set of endpoints so I can just send bulk transfer commands to it and have the board send back bulk responses. The chipidea driver is expecting a function to be setup under the usb gadget. The previous functions for mass storage and Ethernet were accomplished by creating directories for mass_storage.ms0 and rndis.rn0, respectively. When I don't create a function, it gives me an error saying there is no function when I call echo "ci_hdrc.0" > UDC. Here are my calls from the prompt once PetaLinux is booted up:

zynq> mount /dev/mmcblk0p1 /mnt
zynq> insmod /mnt/configfs.ko
zynq> insmod /mnt/libcomposite.ko
zynq> mount -t configfs none /sys/kernel/config
zynq> cd /sys/kernel/config/usb_gadget
zynq> mkdir g1
zynq> cd g1
zynq> echo "64" > bMaxPacketSize0
zynq> echo "0x200" > bcdUSB
zynq> echo "0x100" > bcdDevice
zynq> echo "0x0114" > idVendor
zynq> echo "0x0019" > idProduct
zynq> mkdir strings/0x409
zynq> cd strings
zynq> cd 0x409
zynq> echo “0123456789” > serialnumber
zynq> echo “My Company” > manufacturer
zynq> echo “MyDevice” > product
zynq> mkdir configs/c1.1
zynq> echo "ci_hdrc.0" > UDC

How do I implement an OTG peripheral device with Bulk endpoints? Any resources that might help me on this journey?

Thanks.

0 Kudos
8 Replies
Moderator
Moderator
8,620 Views
Registered: ‎04-17-2011

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3

http://www.wiki.xilinx.com/Zynq-7000+AP+SoC+USB+Mass+Storage+Device+Class+Design+Example+Techtip
Regards,
Debraj
----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------
0 Kudos
Visitor krishnam
Visitor
8,599 Views
Registered: ‎12-02-2016

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3

Hi,

Iam also trying to develop a bulk user driver application using gadgetfs on zc702.

Could you able to find how this can be achieved in Zynq? were you successful in this?

 

I am actually followed below steps to test the functionality.


We are using Zynq7000 with linux kernel version 4.4, we need to use zynq board as a USB Peripheral device(Slave Device)

Using gadgetfs, chip idea driver enabled the kernel, And Zynq board is booted.

And in the bootlog we found "USB Gadget filesystem, version 24 Aug 2004"
Step 1:
created /dev/gadget and mounted gadgetfs
mkdir /dev/gadget
mount -t gadgetfs gadgetfs /dev/gadget
---------------------------------------------------------
Step 2:
On zynq i am running usb.c(userspace driver) to test the usb, downloaded from the link "http://www.linux-usb.org/gadget/usb.c"
Launched the usb.c application using XSDK in debug mode.
In the Kernel configuration, Kernel Debug is enabled and called dump_stack() functions to trace the flow.

It is observed that Zynq USB device is not enumerating on windows or linux host.
The device doesn't respond and hangs in write system call.
For your analysis please find attached log file as reference.

Any input or suggestions or reference for this would be a great help.

Regards,
Krishna

0 Kudos
Visitor teastham
Visitor
8,588 Views
Registered: ‎11-11-2016

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3


@debrajr wrote:
http://www.wiki.xilinx.com/Zynq-7000+AP+SoC+USB+Mass+Storage+Device+Class+Design+Example+Techtip

Debrajr,

 

This is one of the examples for mass storage.  If you read my original posting, my question is about how to do bulk transfers without the mass storage or ethernet over usb.  For a generic bulk device, how do I setup the bulk endpoints and do file io with the endpoints if I am not using canned mass storage or ethernet like all the examples?

 

Thanks,

Tim

0 Kudos
Xilinx Employee
Xilinx Employee
8,583 Views
Registered: ‎07-01-2010

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3

@teastham

 

The CDC tech-tip has the bulk transfer example.

http://www.wiki.xilinx.com/Zynq-7000+AP+SoC+USB+CDC+Device+Class+Design+Example+Techtip

 

See if this helps.

 

Regards,
Achutha

---------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------
0 Kudos
Visitor krishnam
Visitor
8,578 Views
Registered: ‎12-02-2016

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3

Hi Achuta,

 

All the links that are available/provided by the zynq from xilinx are checked by me.

I haven't seen not even single link or document explaining how USB OTG can be used as bulk end point which can reach the user space in the Zynq.

All the examples provided include either mass storage, serial ethernet (RNDIS) or zero or any other driver are managed within the Kernel.

 

If you have tried any time to use Zynq USB as peripheral and which can handle in the user space application using file system would be a great help.

 

Regards,

Krishna

0 Kudos
Visitor teastham
Visitor
8,566 Views
Registered: ‎11-11-2016

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3


@achutha wrote:

@teastham

 

The CDC tech-tip has the bulk transfer example.

http://www.wiki.xilinx.com/Zynq-7000+AP+SoC+USB+CDC+Device+Class+Design+Example+Techtip

 

See if this helps.

 

Regards,
Achutha


Achutha,

 

That is an example of ACM, which I believe is basically using a special black box driver for RS232 communications over USB.  Just like mass storage and ECM (Ethernet), this still does not tell me how to do my own bulk in/out transfers.  These are all canned, black box drivers that work really well but are not transparent in implementation.

 

I downloaded the design files for the ACM project you specified, but the source folder for Linux is empty so there is no source code for the Linux part, which might describe how the bulk in/out is done.

 

If I could have an example of something like the following that would be great:

1. Create a bulk IN endpoint on endpoint 2.

2. Create a bulk OUT endpoint on endpoint 4.

3. Open a pipe to endpoint 2.

4. Open a pipe to endpoint 4.

5. Wait for endpoint 4 to receive a specific character string from the Host like "sendcode".

6. Once "sendcode" is received, send the string "code sent" out endpoint 2 to the Host.

 

Thanks,

Tim

0 Kudos
Visitor teastham
Visitor
8,479 Views
Registered: ‎11-11-2016

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3


@krishnam wrote:

Hi,

Iam also trying to develop a bulk user driver application using gadgetfs on zc702.

Could you able to find how this can be achieved in Zynq? were you successful in this?

 

I am actually followed below steps to test the functionality.


We are using Zynq7000 with linux kernel version 4.4, we need to use zynq board as a USB Peripheral device(Slave Device)

Using gadgetfs, chip idea driver enabled the kernel, And Zynq board is booted.

And in the bootlog we found "USB Gadget filesystem, version 24 Aug 2004"
Step 1:
created /dev/gadget and mounted gadgetfs
mkdir /dev/gadget
mount -t gadgetfs gadgetfs /dev/gadget
---------------------------------------------------------
Step 2:
On zynq i am running usb.c(userspace driver) to test the usb, downloaded from the link "http://www.linux-usb.org/gadget/usb.c"
Launched the usb.c application using XSDK in debug mode.
In the Kernel configuration, Kernel Debug is enabled and called dump_stack() functions to trace the flow.

It is observed that Zynq USB device is not enumerating on windows or linux host.
The device doesn't respond and hangs in write system call.
For your analysis please find attached log file as reference.

Any input or suggestions or reference for this would be a great help.

Regards,
Krishna


Krishna,

 

When I execute the code based upon usb.c, I receive "?? don't recognize /dev/gadget bulk device" as an error.  From my research online, it means that the PCD is not supported by the code.  Did you overcome this error by editing autoconfig?  I think you are on the right track.

 

Here is someone discussing the generic issue:

http://mkl-note.blogspot.com/2009/08/testing-isochronous-transfer-by.html

 

Thanks,

Tim

0 Kudos
Highlighted
Explorer
Explorer
6,910 Views
Registered: ‎11-24-2013

Re: How to Setup Bulk In/Out USB Endpoints for OTG peripheral in PetaLinux 2016.3

Hello @teastham@krishnam@achutha@debrajr,

 

I am trying to develop a Linux application to send some bytes via USB with a Zynq under Linux which is exactly the same as described on the first post of this thread.

 

I configured my board so that it can work as USB Device (required modules, device tree...) and tested the Ethernet and Mass Storage examples, which are working fine.

 

My objective is:

Plug the board to the host, get it recognized and being able to write/read from the host to the endpoints.

 

My status is:

 

  • I compiled the kernel with the "gadgetfs" module and "xilinx udc" module.
  • I downloaded the example: http://www.linux-usb.org/gadget/usb.c
  • I executed the following commands:
  • modprobe gadgetfs
    mkdir /dev/gadget/ -p
    mount -t gadgetfs none /dev/gadget
    ls -l /dev/gadget/

 

  • The last one (ls command) shows a file called: e0002000.usb
  • I modify the code of usb.c to include it, since apparently the Xilinx UDC is not supported by the example. For doing that, I use the EP names of the module source code (udc-xilinx.c).The modification is (in function autoconfig()):
  • } else if (stat (DEVNAME = "e0002000.usb", &statb) == 0) {
    		HIGHSPEED = 1;
    		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0108);
    
    		fs_source_desc.bEndpointAddress
    			= hs_source_desc.bEndpointAddress
    			= USB_DIR_IN | 1;
    		EP_IN_NAME = "ep1in";
    		fs_sink_desc.bEndpointAddress
    			= hs_sink_desc.bEndpointAddress
    			= USB_DIR_OUT | 2;
    		EP_OUT_NAME = "ep2out";
    
    		source_sink_intf.bNumEndpoints = 3;
    		fs_status_desc.bEndpointAddress
    			= hs_status_desc.bEndpointAddress
    			= USB_DIR_IN | 3;
    		EP_STATUS_NAME = "ep3in";
    
    	} 
  • Then I compile and run the code, and if I "ls" the /dev/gadget folder, there is some files corresponding to the End points. In the host, the Gadget get recognized.

Gadget side (board):

  • ls /dev/gadget/ 
    e0002000.usb  ep10in  ep10out  ep11in  ep11out	ep1in  ep1out  ep2in  ep2out  ep3in  ep3out  ep4in  ep4out  ep5in  ep5out  ep6in  ep6out  ep7in  ep7out  ep8in	ep8out	ep9in  ep9outHost side (Ubuntu PC)

     

Host side (PC with Ubuntu 16):

 

dmesg | tail

[ 9469.452325] usb 2-1.2: new high-speed USB device number 24 using xhci_hcd
[ 9469.556153] usb 2-1.2: New USB device found, idVendor=0525, idProduct=a4a4
[ 9469.556161] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 9469.556166] usb 2-1.2: Product: My Source/Sink Product
[ 9469.556170] usb 2-1.2: Manufacturer: Licensed to Code, LLC
[ 9469.556174] usb 2-1.2: SerialNumber: 4bx9sd22thsvd6hsgaiorjnjb7cf09snhxi7hr9ym40hdas4glgs3nzz6bi19rf
[ 9469.561932] usbtest 2-1.2:3.0: Linux user mode test driver
[ 9469.561940] usbtest 2-1.2:3.0: high-speed {control bulk-in bulk-out} tests (+alt)

 

 

My question is: [OBSOLETE]

What's next? When I was given the task of sending bytes via USB, I did an initial research. All resources pointed out to the USB gadget drivers. I read at the USB Gadget website (http://www.linux-usb.org/gadget/) about the gadgetfs module:

 

GadgetFS ... since not every developer wants to program in the kernel, or rely specifically on the Linux kernel APIs, a user mode API is available. An example user mode driver is usb.c. (It also needs usbstring.c and usbstring.h.) [from: http://www.linux-usb.org/gadget/]

 

I don't know where to get more information about this example (usb.c) and about the gadgetfs and how to use it to develop user space drivers.

 

I would really appreciate If you could indicate where to find this information or simply how to continue in order to be able to send data in the created end points.

 

Thanks in advance!

 

[UPDATE]

 

A starting point is to have a look at the functions:

static unsigned long fill_in_buf(void *buf, unsigned long nbytes)
static int empty_out_buf(void *buf, unsigned long nbytes)

Nevertheless, the example (usb.c) is not compatible with USB3, which was my purpose. The maximum data rate I got was 25 MByte/s (USB2). 

 

Regards,

Ignacio

0 Kudos