001-45471 AN45471 Create Your Own USB Vendor Commands Using FX2LP
001-45471 AN45471 Create Your Own USB Vendor Commands Using FX2LP
The document following this cover page is marked as “Cypress” document as this is the
company that originally developed the product. Please note that Infineon will continue
to offer the product to new and existing customers as part of the Infineon product
portfolio.
www.infineon.com
AN45471
Create Your Own USB Vendor Commands Using FX2LP™
This application note explains how to create a custom USB device using EZ-USB® FX2LP™ and communicate using
vendor requests. The associated code example implements six different vendor commands which can be tested using
the FX2LP Development Board (CY3684) and the Cypress USB Control Center application.
Contents
1 Introduction
Standard USB products, such as keyboards, mice, and disk drives, follow a class of devices defined by the USB
Implementers Forum (USB-IF). These device classes provide the standardization that has helped make USB
successful.
However, the architects of USB realized that not all devices would fit into a standard class. In addition, sometimes
there are advantages to adding functionality to a class. To handle these situations, the architects created the “vendor-
specific” request type.
In the USB specification, a special code designates this type, and specific values for fields using these requests are
not defined — each vendor is required to define them. FX2LP firmware source code is attached to this application
note to demonstrate the use of USB vendor commands.
Using the new USB commands added in the attached example, you can send a hexadecimal number to the
7-segment readout, illuminate the four LEDs, read the onboard EEPROM/device RAM and write to the EEPROM.
You could easily add this new set of commands (and others) to FX2LP code under development to help with
debugging.
As another usage example, a data mover app might use BULK IN and OUT endpoints to stream data and custom
commands to implement out-of-band control that does not interfere with data in the BULK endpoints. Custom
commands might include “start sending”, “stop sending”, and “loop data”. This natural separation of data and control
makes for clean and efficient designs.
To see how this works, let’s first inspect the 8 bytes defined by USB as a device request. USB uses this request to
launch all USB operations in a device.
2 Vendor Commands
This section shows the format of a USB device request and describes the different USB requests based on the
bmRequestType value.
Table 1. USB Device Request Packet Format
Table 1 shows the USB device request packet format. Each request consists of an 8-byte data packet. Requests
always use the control endpoint EP0. This packet is the main USB dispatcher; it determines the request direction, the
type, and the recipient of the request. Standard requests travel in SETUP packets, and they may optionally be
followed by DATA packets if required by the request.
Table 2. Definition of the bmRequestType Bits
Table 2 shows the format for the first byte, bmRequestType. Bit 7 tells us the direction for the request. Bits 6:5 specify
the request type.
0 bmRequestType 1 01 00001
1 bRequest GET_REPORT = 0x01
2 wValue Report Type and ID
4 wIndex Interface number
6 wLength Report Length
After a standard request is directed to a USB class (the highlighted “01” in the bmRequestType field), the remaining
fields are defined by that class’ specification. For example, for the HID “GET_REPORT” request, the wValueH byte is
defined as a report type (01=Input, 02=Output, 03=Feature), and the wValueL byte is defined as an optional Report
ID. Don’t worry about what these mean; the point is that a class request predefines the meanings of the remaining
bytes in the standard request packet.
CY3684 Development Kit. This kit contains the FX2LP Evaluation Board, which this application note uses as its
custom device.
The latest version of the free CY3684 EZ-USB® FX2LP folder, which is available at
http://www.cypress.com/?rID=14321. Unzip this file and run the CY3684Setup.exe file. Select the “Typical” install
and the setup program will create the installation directory at C:\Cypress\USB. This directory includes Windows
drivers, the free Keil toolset (full-function but limited to 4-Kbyte code size), and other FX2LP goodies (such as
hardware design files of the FX2LP DVK, documents to use FX2LP DVK and firmware examples). For this app
note, we need only the Windows driver and the Keil tools. The app note code is under 4 Kbytes, so you can use
the free Keil version to study and modify this code (within reason).
The app. Download, unzip, and install the file associated with this app note (same link as the app note) as
C:\Cypress\Custom_Requests. This installs the sub-folder “Source,” which contains all of the source files.
This note uses a VC# program to test the custom device. You can download Cypress’s free set of Visual Studio
development tools at http://www.cypress.com/?rID=34870. This installation creates the directory C:\Cypress\Cypress
Suite USB x.y.z, where xyz is the version number. This folder contains a Visual Studio project called “USB Control
Center,” which you can use to test our custom FX2LP device. Included are both the compiled .exe file and its source
code so that you can run it or modify the source with a free copy of Microsoft Visual Studio Express 2008, 2010, or
2012. The executable is in the CyUSB.NET\bin subdirectory.
4 Test Drive
Before delving into the code, this section shows you how to test the custom device we will define. Follow these steps
to see the custom device in action.
1. Prepare the FX2LP board jumpers according to Table 4.
Table 4. EZ-USB FX2LP Board Jumper Settings
JP State Purpose
2. In the lower-left corner of the board, move the EEPROM ENABLE slide switch to the “NO EEPROM” (down)
position. This allows the FX2LP chip to enumerate as a bare device, ready to download code into either onboard
RAM or EEPROM. The other slide switch (EEPROM SELECT) can be in either position.
3. Plug the FX2LP board into a PC USB port. If this is the first time, you should see popup messages asking you to
install a USB driver. Navigate to:
C:\Cypress\USB
\CY3684_EZ-USB_FX2LP_DVK\1.0
\Drivers\cyusbfx1_fx2lp
6. Now we’re ready to load the FX2LP custom device app into the board. Click on the Cypress device entry to
highlight it, then select Program FX2/RAM.
7. Navigate to C:\Cypress\Custom_Requests\Output and select the Custom_Requests.hex file. Note that there is
another hex file in C:\Cypress\Custom_Requests, “mon-ext-sio1-c0.hex”, which we will explain later. Click
OPEN.
8. Watch the USB Control Center left panel. If your PC sound is on, you will hear the “USB disconnect” sound
immediately followed by the “USB connect” sound, and a new device will appear (see Figure 4). As a sanity
check, the seven-segment decimal point should be lit, and the four LEDs at the top of the board should be OFF.
This is Cypress ReNumeration™ at work. The initial device (in Figure 1) is a USB loader that is hard-wired into the
FX2LP device. The “NO EEPROM” switch setting ensures that the loader ID information in the FX2LP chip is used,
rather than anything stored in external EEPROM. After your code is loaded into FX2LP RAM, the loader electrically
disconnects and reconnects as the new USB device—the one defined by your custom code. As you develop code,
you will repeat steps 6 and 7 for every new code build to be tested.
Note: You can also make your code a permanent addition to the FX2LP board by moving the EEPROM ENABLE
switch to its “EEPROM” (up) position, moving the EEPROM SELECT switch to its “LARGE EEPROM” (up) setting,
then selecting “64KB EEPROM” in step 6. The file to load is Custom_Requests.iic. After programming, disconnect
and re-connect to USB and your program will automatically load and run.
The code we just loaded implements a custom USB device that responds to the custom (vendor) requests shown in
Table 5. Note that the fields in the left column are exactly the ones shown in Table 3, but our code assigns these
fields to suit the purposes of the custom USB device. Also note that there are many “don’t cares” (the x entries) that
are not required by the requests. You could easily define parameters for your device in these fields.
You are free to create as many vendor requests as you wish and to define the fields in Table 5 in any way that suits
your application. This is the power of vendor requests.
Table 5. Our Custom Vendor Requests
I2C 7 EEPROM
Upload Renum LED Write
Rate Seg
bRequest
0xa2 0xa3 0xa4 0xa5 0xa6 0xa7
SETUPDAT [1]
wValueL 0:100
addrL x digit L[3:0] addrL
SETUPDAT [2] 1:400
wValueH
addrH x x x x addrH
SETUPDAT [3]
wIndexL 0:EEPROM
x x x x x
SETUPDAT [4] 1:RAM
wIndexH
x x x x x x
SETUPDAT [5]
wLengthL
LenL x x x x LenL
SETUPDAT [6]
wLengthH
LenH x x x x LenH
SETUPDAT [7]
The code defines six custom (vendor) request columns. The particular request (Upload, Renum, etc.) is selected by
the bRequest field. For example, bRequest=0xa5 sends a hex digit to the FX2LP board seven-segment readout for
display. Use the USB Control Center to test this request as follows.
Configure the USB Control Center “Data Transfers” tab as shown in Figure 5. Make sure the “Control endpoint
(0x00)” item is selected in the left panel and make the following settings:
“Bytes to Transfer” to 0
Direction to “Out”
Now test the LED Request (Table 5, last column) by setting Req Code to 0xa6, wValue to 5, and pressing Transfer
Data. You should see D4 and D2 illuminate. The wValue number is an LED bit map with bit3=D5, bit2=D4, bit1=D3
and bit0=D2. Therefore, 5 = 0101 = off-on-off-on.
For testing the “Upload” request, keep the USB control center fields as in Figure 6 and press “Transfer Data”. The
first 64 bytes of program RAM starting from the address 0x0000 will be uploaded and displayed.
To upload the data from the EEPROM, the wIndex value should be kept as 0.Other fields can be kept same as in the
Figure 6. Also make sure that the EEPROM enable is in “EEPROM” (up) position and EEPROM SELECT switch is in
“LARGE EEPROM” (up) position.
This request uses an IN packet in addition to the standard request packet to transfer data. This is because the fields
in a standard request are “write-only”, sending requests to a device but not accepting data on their own. The “Bytes
To Transfer” field should contain the number of bytes that you want read and “Direction” field should be changed to
IN.
Finally, test the “EEPROM Write” request by filling out the fields as shown in the Figure 7 and press “Transfer Data”
after providing the data in the “Text to Send” field. This will perform EEPROM write and the count provided in the
“Bytes to transfer” will be written to the large EEPROM through I 2C writes.
The “EEPROM Write” command can be verified by performing the “Upload” request which will read the EEPROM
data and display in the control center. To perform this read operation, set the fields as provided in the Figure 8 and
press “Transfer data”.
The vend_ax code example provided in the FX2LP DVK also demonstrates the implementation of different vendor
commands. This can be accessed from the following path once the FX2LP DVK is installed.
<CY3684 DVK installation path>\Cypress\USB\CY3684_EZ-USB_FX2LP_DVK\1.1\Firmware\Vend_ax
5 How It Is Done
Launch the Keil project for this FX2LP code by navigating to C:\Cypress\Custom_Requests and double-clicking on
the Keil project file called Custom_Requests.Uv2. This brings up the Keil integrated development environment (IDE)
and displays the data in the “Files” tab, as shown in Figure 9.
5.1 fw.c
This file, written by Cypress, is called the USB Frameworks. All USB standard commands are processed by this file
so your code does not have to do it. Code is included to handle USB standard requests, including the one we’re
investigating − vendor requests. Usually you do not need to modify the fw.c frameworks file. However, you can trace
the firmware in this file to see how the device responds to the various Chapter 9 requests during enumeration.
5.2 Custom_Request_Descriptors.a51
This assembly language file defines USB descriptors and contains all USB-related definitions. In this file, you can
make the required modifications to configure USB resources. Typical modifications include changing the VID/PID
(Vendor and Product ID), endpoint configuration, interface class, and informative strings.
5.3 EEPROM.C
This file includes EEPROM-related functions. This file shows how to perform an EEPROM read/write and how to get
page size information.
5.4 EZUSB.LIB
The EZ-USB library is an 8051 .LIB file that implements functions common to many firmware projects (such as I2C
read/Write routines, delay, and USB disconnect functions). Because these functions do not need to be modified, they
are provided in library form. However, the FX2LP development kit includes the source code for the library in the event
that you need to modify a function or if you just want to know how something is done.
5.5 Custom_Requests.c
You can study this file to learn how vendor commands work. It can be used as a starting point to create your own
vendor commands. Six vendor commands are defined in this file. Note that Cypress reserves vendor commands
0xa0-0xaf for purposes such as code download and app notes, such as this one.
5.6 USBJmpTb.OBJ
This is an object file that contains the ISR jump table for USB and GPIF interrupts.
6 Code Analysis
Creating a vendor command is a simple two-step process. Refer to the example Custom_Requests.c code. The first
step is to give the vendor commands symbolic names:
When the FX2LP USB Frameworks code receives a vendor request, it calls the function:
BOOL DR_VendorCmnd(void)
The heart of this function is a switch statement with one case entry per custom request. Here is the seven-segment
update case (with abbreviated comments):
switch(SETUPDAT[1])
{
case VR_7SEG:
while (I2CS & bmSTOP); // wait for STOP
I2CS = bmSTART; // set START bit
I2DAT = 0x42; // I2C address
while (!(I2CS & bmDONE)); // wait for done
val = SETUPDAT[2]; // wValueL=digit 0x00-0x0F
if(val<=0x0F)
I2DAT = ~LOOKUP7[SETUPDAT[2]];// 0-F
else I2DAT = 0x7F; // d.p. only
while (!(I2CS & bmDONE)); // wait for done
I2CS = bmSTOP; // set the STOP bit
break;
The switch statement examines SETUPDAT[1], which is the bRequest field of the Standard Request (Table 3). Note
that the USB Frameworks code saved the work of examining the SETUPDAT[0] field in the SETUP packet that just
arrived. Precisely because the bmRequestType byte (Table 3) indicated a vendor request, the Frameworks called the
DR_VendorCmnd function. Simply fill in code for the various bRequest (SETUPDAT[1]) values we defined for our
custom requests in Table 5.
The first four lines in the case statement (a) wait for the FX2LP I2C controller to be free; (b) set the START bit; (c)
send the I2C address of 0x42, which is the I2C expander chip on the FX2LP board that connects to the seven-
segment readout; and (d) wait for the address byte to transmit.
Then the code examines SETUPDAT[2], which is the wValueL byte in the request (Table 5). We defined this byte to
be a hex digit from 0x00 to 0x0F. The code looks up the segments if the value is in range. Otherwise, it displays only
the decimal point. Finally, the code sends the I2C STOP signal and we’re done.
This request has bytes SETUPDAT[3-7] “empty”; you could think of other uses for these bytes to transmit to your
custom device.
Plug the serial adapter into SIO-1 (top) DB-9 connector. Here’s how to tell the Keil IDE to use this port:
1. In the Files tab, right-click on the top item, “Custom_Requests”, and select “Options for Target
Custom_Requests”
2. Select the Debug tab
3. Click the “Settings” button in the upper right
4. Choose your COM port in the “Port” dropdown
5. Set the baud rate to 38400
6. Make sure “Serial Interrupt” is checked (see Figure 10)
The last step is to download a serial debugger, which runs alongside your development code. Go back to your USB
Control Center, select ‘Program FX2/RAM”, and navigate to the Cypress\Custom_Requests folder. You should see
the file “mon-ext-sio1-c0.hex; click on it to download it onto the FX2LP board. A green LED near the USB connector
turns ON to indicate that the monitor is running.
Note: In the file “mon-ext-sio1-c0.hex, ‘mon’ means monitor, ‘ext’ means use external RAM, “sio1” means use the
SIO-1 serial connector (next to the USB connector), and “c0” specifies the load type. AN42499 − Setting Up, Using,
and Troubleshooting the Keil(TM) Debugger Environment” has details.
Select Debug/Start-Stop Debug Session or click the magnifying glass to start the session. Run the code by selecting
Debug/Go. After the code is running, the USB Control Center can send vendor commands as before.
To stop the debugger, select Debug/Stop Running; to exit the debugger, first stop running, then select Debug/Start-
Stop Debug Session.
If you are interested in debugging your code by printing messages on HyperTerminal or Tera Term, then please refer
to AN58009 − Serial (UART) Port Debugging of FX1/FX2LP Firmware.
Detailed information about using the KEIL debugger environment is in the app note AN42499 − Using and
Troubleshooting the KEIL Debugger Environment.
Detailed information about serial port debugging is in AN58009 − Serial (UART) Port Debugging of FX1/FX2LP
Firmware.
To find good reference materials and examples of USB Vendor Command Design and HID Class Usage, go to
Jan Axelson’s Lakeview Research website.
USB Complete, by Jan Axelson, is a book that describes USB details clearly and completely.
11 Summary
This application note explained a built-in USB feature called vendor requests. The requests allow you to create your
own USB commands. The example firmware provided with this application note implements six custom commands to
interact with the FX2LP development board. A Windows app, written in C#, demonstrates Windows communication,
and allows full testing of the custom device. Source code and step-by-step instructions teach you how to run and
debug the code on the FX2LP.
Document History
Document Title: AN45471 - Create Your Own USB Vendor Commands Using FX2LP™
Document Number: 001-45471
Products
PSoC® Solutions
ARM® Cortex® Microcontrollers cypress.com/arm
PSoC 1 | PSoC 3 | PSoC 4 | PSoC 5LP
Automotive cypress.com/automotive
Clocks & Buffers cypress.com/clocks Cypress Developer Community
Interface cypress.com/interface Forums | WICED IOT Forums | Projects | Videos | Blogs |
Internet of Things cypress.com/iot Training | Components
PSoC is a registered trademark and PSoC Creator is a trademark of Cypress Semiconductor Corporation.
Cypress Semiconductor
198 Champion Court
San Jose, CA 95134-1709
© Cypress Semiconductor Corporation, 2009-2017. This document is the property of Cypress Semiconductor Corporation and its subsidiaries, including
Spansion LLC (“Cypress”). This document, including any software or firmware included or referenced in this document (“Software”), is owned by
Cypress under the intellectual property laws and treaties of the United States and other countries worldwide. Cypress reserves all rights under such
laws and treaties and does not, except as specifically stated in this paragraph, grant any license under its patents, copyrights, trademarks, or other
intellectual property rights. If the Software is not accompanied by a license agreement and you do not otherwise have a written agreement with
Cypress governing the use of the Software, then Cypress hereby grants you a personal, non-exclusive, nontransferable license (without the right to
sublicense) (1) under its copyright rights in the Software (a) for Software provided in source code form, to modify and reproduce the Software solely for
use with Cypress hardware products, only internally within your organization, and (b) to distribute the Software in binary code form externally to end
users (either directly or indirectly through resellers and distributors), solely for use on Cypress hardware product units, and (2) under those claims of
Cypress’s patents that are infringed by the Software (as provided by Cypress, unmodified) to make, use, distribute, and import the Software solely for
use with Cypress hardware products. Any other use, reproduction, modification, translation, or compilation of the Software is prohibited.
TO THE EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD
TO THIS DOCUMENT OR ANY SOFTWARE OR ACCOMPANYING HARDWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. To the extent permitted by applicable law, Cypress reserves the right to
make changes to this document without further notice. Cypress does not assume any liability arising out of the application or use of any product or
circuit described in this document. Any information provided in this document, including any sample design information or programming code, is
provided only for reference purposes. It is the responsibility of the user of this document to properly design, program, and test the functionality and
safety of any application made of this information and any resulting product. Cypress products are not designed, intended, or authorized for use as
critical components in systems designed or intended for the operation of weapons, weapons systems, nuclear installations, life-support devices or
systems, other medical devices or systems (including resuscitation equipment and surgical implants), pollution control or hazardous substances
management, or other uses where the failure of the device or system could cause personal injury, death, or property damage (“Unintended Uses”). A
critical component is any component of a device or system whose failure to perform can be reasonably expected to cause the failure of the device or
system, or to affect its safety or effectiveness. Cypress is not liable, in whole or in part, and you shall and hereby do release Cypress from any claim,
damage, or other liability arising from or related to all Unintended Uses of Cypress products. You shall indemnify and hold Cypress harmless from and
against all claims, costs, damages, and other liabilities, including claims for personal injury or death, arising from or related to any Unintended Uses of
Cypress products.
Cypress, the Cypress logo, Spansion, the Spansion logo, and combinations thereof, WICED, PSoC, CapSense, EZ-USB, F-RAM, and Traveo are
trademarks or registered trademarks of Cypress in the United States and other countries. For a more complete list of Cypress trademarks, visit
cypress.com. Other names and brands may be claimed as property of their respective owners.