USB is the most common of the high-speed interfaces today. Ethernet, PCIe, etc. are similarly powerful in terms of data rate but because of their lack of simplicity you won't find them in a phone or pocket gadget.
The USB protocol distinguishes between Host and Devices. Hosts are typically computers or machines where "things are plugged into" and devices are simpler end devices that either provide data (like a mouse or a webcam), receive data (like a printer) or both (like a USB drive) but in all these cases the "intelligence" is in the host.
From the developer point of view, USB is not as trivial as, for example, an UART. In most cases it requires an OS (Operating System) like Linux or Windows, or at least an RTOS. And developing a Host USB is more complex than a Device one.
Thankfully, the wheel doesn't have to be reinvented and nothing has to be developed to have a Host USB with Linux as its kernel provides all the necessary drivers.
In this project I'm using the MYIR MYD-CZU3EG development board, with a Zynq Ultrascale+ xczu3eg and a range of interfaces from PMODs to Ethernet. There is one micro USB connector connected to the PS UART typically used for debug and a type-C USB capable of USB 3.0 that uses the PS ULPI interface and the PS MGT transceivers.
How to get USB 3 details from the schematicBelow is the MYIR board schematic part showing the USB type-C connector. Signals include the traditional USB DP and DN (that's why it is back compatible) plus 2 pairs of high speed serial lines SSTX-1 and -2 and SSRX-1 and -2.
Looking further in the schematic, it is found that the high speed serial lines come from the PS transceiver, PS_MGTRTX-2 and PS_MGTRRX-2. It's important to note it's the Lane 2 as this is used in the PS configuration. If you try to bring up the USB for another board, the MGT lane could be different.
For this project I created a basic Vivado project based on a block diagram with only the PS as shown below.
The PS has to be configured for the board, this can be quickly done with a configuration TCL file. Below the PS USB configuration is shown. Note that there are two parts, is the 'USB 3.0' box is unticked, then it would be just an USB 2.0. Here the USB 3.0 is enabled and the MGT Lane 2 selected. For the pins above, the correct ones must be chosen according to the board, this is done by checking the schematics.
Once this is checked and the block diagram validated, I make the HDL wrapper and build the project, create the bitstream and export the project (as XSA) including the bitstream. This will be used by Petalinux next.
Start the Petalinux projectPetalinux will create all the software elements to make a bootable SD card. The key pints for this project are the linux kernel configuration and the rootfs package selection.
First, create a project as usual with:
petalinux-create -t project -n <name> --template zynqMP
Then inside the project folder (name), source the hardware description from the XSA file created with Vivado:
project-config --get-hw-description=<path-to-xsa>
Note that the path above is to the folder where the XSA is, not the file itself.
The above command will trigger the general petalinux configuration, in my case I need to change the SD card from sd0 to sd1. Depending on your board you may need different settings here.
Once it's done, the kernel is configured with:
petalinux-config -c kernel
That brings the corresponding configuration GUI. The changes needed are:
In Device drivers --> USB support:
- Enable USB ULPI PHY interface support.
- Enable EHCI HCD (USB 2.0) support.
- In USB Physical Layer drivers, enable Generic ULPI transceiver driver
- Enable USB Type-C Support.
- In USB Type-C Support, enable USB Type-C Port Controller Manager.
Next step is to configure the root file system with:
petalinux-config -c rootfs
Here I change:
In Filesystem packages --> base --> usbutils, enable usbutils
After saved and exit, it can be built with:
petalinux-build
It takes its time. After that, the boot image is created with:
petalinux-package --boot --fsbl --u-boot --fpga
Then as usual, the files boot.scr, BOOT.BIN and image.ub in images/linux are copied to a FAT-formatted micro SD card.
The card is inserted in the board, the boot mode switches set to boot from it, a USB canble connected to the debug (UART) USB, a console started on the PC and... power!
The boot goes smoothly to the end, it can be seen in the log that it found the USB peripheral.
Then I plugged an iPhone to it (just because it happens is the only gadhet I have at hand with USB 3) and it detected the new USB device. After unlocking it, it shows what it is connected. Now ready to use it as a zynq peripheral!
Comments
Please log in or sign up to comment.