libusb: create a solution without the class struggle!€™12 lab procedure 2l01i libusb - create a...

22
DevCon’12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 1 of 22 LibUSB: Create a Solution Without the Class Struggle! RX USB lab 2L01I Description: Use a LibUSB PC Host application together with an target board USB Device. Lab Sections 1 Download LibUSB target code .............................................................. 2 2 Make the LibUSB target known to Windows .......................................... 5 3 Windows ‘Found New Hardware’........................................................... 7 4 Pipes and endpoints ............................................................................ 10 5 Host app: Learn about the USB target ................................................. 13 6 Host app: Communicate with target bulk endpoints ............................. 16 7 Add an interrupt IN endpoint................................................................ 19 8 Appendix. Use LibUSB Install-filter to access any device! ................... 21 9 (Lab restore)........................................................................................ 22 Lab objectives Understand how to easily create a PC Host RX solution by using LibUSB. You will learn 1. That you don’t have to follow a class specification. 2. How make a USB peripheral known to Windows using LibUSB so that a PC host app can connect to it. 3. How to use and modify both a simple host (PC) application and the target board to create a solution. 4. Show example USB transfers using Control, Bulk, and Interrupt endpoints. Skill Level Knowledge of Basic USB host and peripheral concepts. Some USB hardware and class knowledge is preferred, but not necessary. Some proficiency in C. This is a hands-on debug session. Time to Complete 120 Minutes Lab Materials Please verify you have the following materials at your lab station. SW E2studio min 1.0.1.14. RX compiler min. v. 1.2.1. Python min. v. 2.7 and PyUSB Directory C:\Workspace\e2studio\LibUSB_Demo should contain sub-directories LibUSB_Demo and LibUSB_Demo\LibUSB_HostPC. HW RDK63N Black A to mini-B USB cable for JLink debugger Black A to mini-B USB cable used for target board peripheral USB0 port to PC.

Upload: dinhdang

Post on 28-May-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 1 of 22

LibUSB: Create a Solution Without the Class Struggle! RX USB lab 2L01I Description: Use a LibUSB PC Host application together with an target board USB Device.

Lab Sections 1 Download LibUSB target code .............................................................. 22 Make the LibUSB target known to Windows .......................................... 53 Windows ‘Found New Hardware’ ........................................................... 74 Pipes and endpoints ............................................................................ 105 Host app: Learn about the USB target ................................................. 136 Host app: Communicate with target bulk endpoints ............................. 167 Add an interrupt IN endpoint ................................................................ 198 Appendix. Use LibUSB Install-filter to access any device! ................... 219 (Lab restore) ........................................................................................ 22

Lab objectives Understand how to easily create a PC Host RX solution by using LibUSB. You will learn 1. That you don’t have to follow a class

specification. 2. How make a USB peripheral known

to Windows using LibUSB so that a PC host app can connect to it.

3. How to use and modify both a simple host (PC) application and the target board to create a solution.

4. Show example USB transfers using Control, Bulk, and Interrupt endpoints.

Skill Level Knowledge of Basic USB host and peripheral concepts. Some USB hardware and class knowledge is preferred, but not necessary. Some proficiency in C. This is a hands-on debug session.

Time to Complete 120 Minutes

Lab Materials Please verify you have the following materials at your lab station. SW

• E2studio min 1.0.1.14. • RX compiler min. v. 1.2.1. • Python min. v. 2.7 and PyUSB • Directory

C:\Workspace\e2studio\LibUSB_Demo should contain sub-directories LibUSB_Demo and LibUSB_Demo\LibUSB_HostPC.

HW • RDK63N • Black A to mini-B USB cable for JLink

debugger • Black A to mini-B USB cable used for

target board peripheral USB0 port to PC.

Page 2: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 2 of 22

1 Download LibUSB target code

Overview Download and run the LibUSB peripheral (“function” or “device”) code on the target board.

Procedural Steps

Step 1.1

Step 1.2 Start e2studio. It will ask you for the path to the workspace to open. Enter

Plug the USB A-to-mini-B cable to the PC and the YRDK63N Segger USB port (next to the DB9 connector).

C:\Workspace\e2studio\LibUSB_Demo

Step 1.3 A build configuration with include paths etc has been prepared for the project. Make sure that this build configuration is the active build configuration: Highlight the project folder, then select Project=> Build Configuration=>Manage.

Select Renesas’ “HardwareDebug”, and press ‘Set Active’ if it isn’t already the active configuration.

.

Step 1.4 Compile (Ctrl+B). Make sure that LibUSB_Demo.x is built. If it is, it should be visible in in the Project browser like this.

The RX LibUSB firmware is based on the common code USB Basic FW found in all Renesas USB firmware downloads from the Software Library. The LibUSB package is the Basic FW with an added application that does not follow any class. The application demonstrates USB communication with the target board to light LEDs, write to the board display, and read the ADC. The target board runs as the USB peripheral (or USB ‘function’). The PC will be the USB host.

Page 3: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 3 of 22

Step 1.5 Let’s see if we can download and debug. Select Run=>Debug Configurations. Click on LibUSB_Demo_JLink, which is a member of “Renesas GDB Hardware Debug”. Press ‘Debug’.

If asked to select debug hardware, select Segger JLink. As target device, select R5F63NB.

Step 1.6 If you connect successfully, you should see the binary being downloaded in the console window.

Step 1.7 Make sure the Renesas Debug “Perspective” (tab) is active, if it wasn’t selected automatically.

You can switch between the C/C++ and debug perspectives when you are debugging to more easily search code etc.

Press the Reset symbol. The program counter should now equal the value of the reset vector. Step (over) with F6 to see if you are connected successfully. The green back-ground shows where the program counter is.

Step 1.8 Hit Go (F8). If you hit a breakpoint that was left in a previous debug session, just hit Go again. (To halt execution press the NOT the red square which exits debug!)

Pause symbol,

If you have come this far, compiling and debugging with e2studio and works. With that out of the way we can focus on LibUSB!

Page 4: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 4 of 22

Step 1.9 Make sure target is running (F8), then connect the USB A-to-mini-B cable between the target board USB port and the PC.

Step 1.10 If the ‘Found New Hardware Wizard’ pops up, click ‘Cancel.’ We will go through the process of installing the driver later.

Question The RX target won’t enumerate unless someone previously ran the lab on the PC. If it doesn’t enumerate, what do you think is missing? _______________________________________________________________________________ Hint: Read the green box.

With the YRDK the cable must be reconnected after the board executes the USB code in order to enumerate. The ‘Found New Hardware Wizard’ will pop up when the USB cable is connected if the RX peripheral was never connected to the PC before. In order for Windows to select the right driver for this USB peripheral we need to point to an INF-file.

Page 5: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 5 of 22

2 Make the LibUSB target known to Windows

Overview Create an .INF-file so that windows can access the USB peripheral (target board).

The LibUSB INF Wizard

Step 2.1 Start the LibUSB INF Wizard; C:\Workspace\e2studio\LibUSB_Demo\LibUSB_Demo\LibUSB_HostPC\libusb-win32-bin-1.2.6.0\bin\inf-wizard.exe

Step 2.2 With the target board running and connected to the PC, you should find the Lib USB Demo among other USB devices that are attached.

You will probably not see this many devices in the lab. The screenshot is from a desktop.

and click Next.

The only way our Windows PC host can access a peripheral is by first providing information about it. To provide information for USB peripherals, Windows uses INF-files. When connecting a device for the very first time, Windows will try to find an INF-file from the windows\inf folder that matches the VID and PID from the descriptors of the device. If a matching INF is not found, Windows will ask you for one. We will create an INF-file for the LibUSB target. As an alternative method to access a device via Windows, you can use the \libusb-win32-bin-1.2.6.0\bin\x86\ install-filter-win.exe. This is much faster and great for testing devices but not realistic for something that is to be deployed as a product. See Appendix.

Page 6: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22

Step 2.3 Select the RX600 LibUSB Demo and press ‘Next’.

Step 2.4 The wizard is about to create an INF file. As manufacturer you can enter your last name (whatever you like). You can also change the device name if you like, for example “DevCon 2012 LibUSB Demo”. You can leave the MI field blank.

Step 2.5 Press ‘Next’. Make a note of the filename in the question box below.

Step 2.6 Save the INF-file to C:\Windows\inf – but in some machines the INF directory is e.g. C:\Windows\system32\inf

Step 2.7 Press ‘Done.’ Note the option to ‘Install Now.’ This option guides you through the process of copying

. You can save it to anywhere you want, but Windows searches that directory automatically. If you save it somewhere else you will later have to point to that directory in the ‘Found New Hardware Wizard’ section.

libusb0.sys

to the Windows driver directory. We will copy this file manually instead to show how a user would point to your INF file.

Step 2.8 Open the INF file in e.g. Notepad.

Questions Note the INF-file name you created here. _______________________.INF The idea of course is that a user shouldn’t have to know about it . But as the product designer you probably want to how all this works!

In case you are curious; the string “RX600 LibUSB Demo” is the second string descriptor, the ‘product’ string. It can be modified in file r_usb_vendor_descriptor.c in the data vector usb_gplibusb_string_descriptor2[]. The Renesas Vendor ID (registered with usb.org) and Prodiuct ID can also be found in this file as USB_VENDORID and USB_PRODUCTID.

Questions Do the VID, PID, and product string descriptor, all in r_usb_vendor_descriptor.c, match what the INF Wizard shows? ___________

Questions What is the Device ID (product string)? __________________________. What is the USB class? __________________________.

During enumeration the Windows host will try to match the incoming device descriptor with the the DeviceID, listed under [Strings] DeviceID = … in the INF-file. (It may match this information from what is in the registry if it previously learned about this peripheral.)

Page 7: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 7 of 22

3 Windows ‘Found New Hardware’ Step 3.1 Start Windows Device Manager: In the Start menu, select Run. Type ‘devmgmt.msc’ and click

‘OK.’ (Win7; type “device manager“ into the Windows Run menu) This will help keep track of enumeration status. Keep it open.

Step 3.2 Restart the target by disconnecting and reconnecting the cable. We will follow the ‘Found New HW Wizard’.

Step 3.3 In the Windows ‘Found New HW wizard’, select “No, not this time’ (Win7; Browse my computer…), then ‘Install from a specific location’ (Win7; Let me pick…).

Step 3.4 Click ‘Next.’ When prompted to insert an installation disk, click ‘OK’ then ‘Browse’ and point to the directory C:\Workspace\LibUSB_Demo\LibUSB_Demo\LibUSB_HostPC\libusb-win32-bin-1.2.6.0\bin\x86

. Click ‘OK.’

The correct driver (libusb0.sys) will be found automatically by Windows if the vendor and product ids was used by Windows at some time in the past, for example if someone ran the lab before you. To avoid it all happening in the background, let’s do this in detail to learn how this would work for a customer doing this for the first time with your new product. If then the ‘Found New HW Wizard’ does not appear, right click on ‘Lib USB Demonstration’ in the Device Manager and click on ‘Update Driver.’ Then follow the same steps as below.

If you saved your INF-file to Window’s INF-directory and are given a choice of several INF-files e.g. because someone ran the lab before, identify yours by matching manufacture name. There are several ways to do locate the INF file. Just to make sure we pick the right INF-file, select ‘Don’t search, I will choose driver…’ then ‘Have disk,’ and browse to your INF file.

Page 8: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 8 of 22

Step 3.5 Press OK and Finish.

If something goes wrong, restart the target firmware, uninstall the driver by right-clicking on the device in Device Mgr (Step 9.2), then redo the procedure. An example is shown above for WinXP.

Libusb-win32 (the driver libusb0.sys) Libusb-win32 is a driver library allowing user-space applications to access USB devices on Windows (XP, Vista, Win7) without writing kernel driver code. libusb0.sys comes together with the INF-Wizard. It’s all part of the LibUSB-Win32 download. In your future product install guide the customer must be told where (e.g. a CD) libusb0.sys can be found. If you write a Windows host application, you need to use the API “WinUSB” or Libusb-win32 to access USB devices (unless you are using a Windows .NET USB developer API or similar). Of course you can use Python as we will do, and even a Python-made GUI.

Page 9: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 9 of 22

Step 3.6 In Windows Device Manager, check that Windows has enumerated the RX properly. You should have it listed under the “libusb-win32 device” class.

Summary This whole mechanism which we have now put in place is sometimes referred to as the Windows LibUSB backend. With LibUSB, a PC application can now access ANY connected USB device and its endpoints! See Appendix (Section 8) later for details.

Page 10: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 10 of 22

4 Pipes and endpoints

Overview Find out what endpoints and pipes are used to learn how both the host and function application programs communicate with each other.

RX demo pipes and endpoints

Step 4.1 Let’s examine the RX peripheral demo’s endpoints and pipes. Open the file r_usb_vendor_descriptor.c as shown below, from the folder APL.

Basics of USB communication - before we start this section. In order for data to be shared by host and peripheral, endpoints are defined by the peripheral. The host must learn about these endpoints via the descriptors. A pipe is a node’s means of communication to and from an endpoint. A pipe consists of the device address of the peripheral and an endpoint number, available bandwidth, transfer type, direction of data flow (IN, OUT) and max buffer size. The default, or control pipe is a bidirectional pipe made up of endpoint zero. In USB at the lowest level, the host always initiates transaction of data, even for interrupt endpoints.

Only a USB function (or “device”) has descriptor data defined in the source code. A USB function needs to send this to a host when asked, so that the host knows how to communicate.

Question The host always starts by asking for the device descriptor which contains the VID and the PID of the peripheral. These are listed near the top of the file. Write them down here. Vendor ID Product ID

Page 11: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 11 of 22

Step 4.2 In this file we also have the pipe information table usb_gpvendor_smpl_eptbl1[]

Step 4.3 Let’s see what pipes and endpoints the host application must use to communicate with the target board.

and the descriptors at the end of the file.

Step 4.4 The endpoints are listed in the configuration descriptor structure, usb_gpvendor_smpl_ConfigurationF_1

right after the first interface descriptor, located around line 221.

Step 4.5 By studying the structure, try to fill out the first three columns of the EP-table below.

Step 4.6 Now look at the pipe information table, usb_gpvendor_smpl_eptbl1

, ~line 115. This is where endpoints and pipes are paired together for the RX USB peripheral. Which pipe is used for an endpoint is only relevant inside a USB node. (The configuration descriptor is what is sent to host. On the other end of the USB cable only the EP number is needed. The host selects its own pipe.)

Question Fill in this ‘endpoint table’

Endpoints

Transfer type at lowest USB protocol level: Control, Bulk, Interrupt or Isochronous

Payload data flow direction as seen from host. IN or OUT.

Interface number 0, 1 ,2,..

Pipe nr 0-9 for RX6xx (Step 4.6)

EP1 descriptor

EP2 descriptor

EP3 descriptor

EP4 descriptor

Question Which pipes are used by each respective endpoint? Fill in pipe numbers in the table’s last column. (Hint: 2nd item in each pipe “record” - end of line.)

When the host asks for the configuration descriptor, all the descriptors in this structure are sent; configuration, interface and endpoint descriptors. That’s why are in the same structure.

Page 12: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 12 of 22

String Descriptors

Step 4.7 Now look at the string descriptors at the bottom of the file.

Step 4.8 In Windows Device Manager, right-click on the LibUSB target and select Properties.

According to the USB specification, inclusion of string descriptors is optional. The string descriptors can be fetched by the host application using the standard USB request get_descriptor as we will see later. If string descriptors are included, string descriptor 0 must contain the language ID.

Pipes cannot be chosen randomly for the RX. From the HW manual we can see that: - PIPE0 is for control transfers only. - PIPE1 and 2 are for bulk transfers or isochronous transfers. - PIPE3 to 5 are for bulk transfers only. - PIPE6 to 9 for interrupt transfers only.

The pipe information table for peripherals is described in section 3.6.3 in the Basic FW manual (r01an0512ej0200_usb.pdf). This can be downloaded from am.renesas.com.

There is another way to get device information! Sometimes you don’t have source code, but want to learn about a device anyway.

… Use LibUSB!..

Question Fill in the string descriptors of the target. String descriptor 0: The sixteen-bit ‘LANGID’ field, at offset 2 bytes: ___ ___ (hex) String descriptor 1” “____________________” String descriptor 2: “____________________________________________________” Apparently, the INF Wizard asked for the string descriptors since it displayed String descriptor2 in Step 2.2!

Question Does Windows use any of the string descriptors to show a connected device in Device manager? ________________________________. Hint: Check Device manager when target has enumerated, then check the INF-file.

Page 13: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 13 of 22

5 Host app: Learn about the USB target

Overview: We will run a PC USB Host application written in Python. You will see how you can learn about a USB function by reading its descriptors from the host’s application program. You can then configure it and finally have some useful communication take place between the host and function application layers.

Run a host sample application in Python

Step 5.1 Open directory C:\Workspace\e2studio\LibUSB_Demo\LibUSB_Demo\LibUSB_HostPC\lab-docs

Step 5.2 Locate the USB host application file

.

Renesas_libusb_host_lab.py

Step 5.3 Right-click on the file and select “Edit with Idle”. This will open the Editor window. The console window will appear when you run the code for the first time. When we refer to Idle below we mean the editor.

.

Step 5.4 In Idle, scroll down to ################################################## # # # M A I N # # # ################################################## … at the bottom third of the file, around line 200. Line number is at the bottom right in Idle. Even further down, around line 245 you will see … ############### # Find the RX # ############### my_usb_object = RenesasLibUsbDevice(0, 0)

Windows, using the LibUSB backend that we set up in section 2 takes care of basic enumeration to learn what driver to use for the PID and VID of the function. After enumeration is done, all a PC application needs to do is connect to the LibUSB backend with the right VID and PID to be able to talk to the device and do something useful!

If you are interested, study the code later. Right now we will just see what we can do with LibUSB from the PC side.

Python is object-oriented - we will now try to find the object of interest, the target board! We can do this as the program uses the Python add on package PyUSB [in C:\Python27\Lib\site-packages\usb ] which enables us to talk to the Windows LibUSB backend (libusb0.sys).

Page 14: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 14 of 22

Step 5.5 We need to enter the PID and VID of the target board on this line. Since it is easy to forget these numbers, a feature is added to the code to see what devices are available via the LibUSB backend. At the beginning of main (~line 225), this line does exactly that: devices = usb.core.find(find_all=True)

Step 5.6 Make sure the target is running (F8 in e2studio). Does the board display say “LibUSB successful open? If not, reconnect the USB cable.

Step 5.7 Run the program with F5 in Idle (the editor) and study the output.

Step 5.8 If all is working, you should see the target board PID and VID listed at the very beginning of the output. For example: __main__ List USB devices found: [<usb.core.Device object at 0x01903CD0>, <usb.core.Device object at 0x019031D0> ] In detail: Vendor ID 0x483 & Product ID = 0x2016 Vendor ID 0x45b & Product ID = 0x512

Question Was your USB target (the RX) found? ____________ List PID and VID pairs found. You should have at least one peripheral connected to the PC – the RX target board! PID________ VID _________ ( PID________ VID _________ PID________ VID _________ (If you get only one, that’s fine. To get all connected USB devices to show up, see section 8.)

Any devices listed in the Python output window are accessible to a LibUSB host PC application – otherwise they wouldn’t be in the list. If you don’t see the other USB devices connected to your PC and you would like to interface with them, for example to read the descriptors, use the LibUSB Install-filter described in section 8 to make it visible…

…You can talk to ANY USB device via LibUSB!

If Python output says that there is no LibUSB backend it didn’t associate the PID and VID of the device with the libusb0.sys driver, or, it cannot find libusb0.sys because it was never installed. This shouldn’t happen if you successfully ran the INF-wizard in section 2. But here then again is a summary of how to get the Windows LibUSB backend working: To have Windows install libusb0.sys properly and use it for your device, the Found New HW pop-up must read the correct INF-file with the same VID and PID as your peripheral, and, if libusb0.sys was never installed, tell it where to find it (Browse…). To ‘debug’; control what is happening by not letting Windows do these steps automatically when the pop-up appears.(Step 3.1…). If the pop up does not appear, or the device does not appear correctly in Device Mgr., select ‘Uninstall’ from Device Mgr, then ‘Update Driver’ and follow Step 3.1…

Page 15: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 15 of 22

Step 5.9 To control the device, enter the PID and VID of the RX as arguments in the my_usb_object ..

Step 5.10 Run the Python code by hitting F5 inside Idle.

call as my_usb_object = RenesasLibUsbDevice(0x<VID>, 0x<PID>)

Question What information does the host app manage to get from the target using the calls my_usb_object = RenesasLibUsbDevice( ) (~line 245) and my_usb_object.ListDescriptors() (~line 250)? You don’t have to list everything, just be impressed by the fact that we are actually communicating with the target board. _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________ _______________________________________________________________________________

We used LibUSB to list configurations, interfaces, endpoints and string descriptors. This was added to the host application for debug purposes, for learn about a connected device. This Python code was added for you to copy and use at your convenience in your future test & development!

Page 16: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 16 of 22

6 Host app: Communicate with target bulk endpoints

Overview: We will use the endpoints that you listed in the table (page 11) for a simple application.

Control the target application

Step 6.1 Find what endpoint is used to control the target application. In e2studio, open r_usb_vendor_papl.c and go to function usb_pvendor_apl_task (

line ~315).

Step 6.2 Put a breakpoint where the code is that runs when a bulk receive transfer to the peripheral (OUT as seen from host) occurs, at line case USB_PSTD_BULK_RECEIVE_END: /* Data reception complete for BULK OUT transfer Make sure the target is running (F8 in e2studio).

Step 6.3 Before we run the Python code, answer a few questions about this case statement that will handle received bulk data.

The default LibUSB target board application code can do some basic things like set an LED and write to the board display. We can send demo commands to the target using one of the endpoints. This is described in the application note r01an0492ej_usb.pdf. This application note is included in your workspace under LibUSB_Demo\LibUSB_HostPC\lab-docs.

Here is how reading data over USB works When the application task usb_pvendor_apl_task (an OS-like process) receives the message USB_PSTD_OPEN it calls the open() function for vendor class communication. Using control() It then registers an automatic “call-back” to be triggered due to a call to read(). The call-back will then trigger only when these two conditions are met: 1) A read-call was issued 2) a subsequent BULK transfer completes in hardware. The call-back when such a transfer completes, in our case, is therefore usb_pvendor_smp_BulkRead_Notify. (See line ~390. Don’t need to check this now, but its all in this file.) When this call-back is later called by the stack it in turn sends a message back to this same application process with the flag USB_PSTD_BULK_RECEIVE_END, together with the data from host. See line ~470. Perhaps a bit more complex than a simple “read”, but the USB firmware uses processes and callbacks so that we don’t wait in while-loops for things to complete. We don’t know when data is going to be sent, and we want to be prepared beforehand to manage incoming data in realtime, in an “event handling” manner. Writing operates in a similar way.

Page 17: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 17 of 22

Control LEDs

Step 6.4 In the Python code, enable the section that controls the LEDs by enabling that section right below the ***LED*** heading. (Change if 0: to if 1:).

Step 6.5 If you try to run the Python code you will see error messages due to a missing EP address. We need to define the EP-address for the command endpoint in the Python code. Enter this on line ~230.

Step 6.6 Run the Python code with F5. Python will complain, but this should be due to that the target is not responding since your breakpoint triggered. Look in e2studio. If the BP in triggered, you know we have a connection!

Step 6.7 The first test data we are sending from the host is in

my_usb_object.WriteEP(EP1_ADDR_CMD_OUT, '\x01' + '\x02\x03\x04\x05\x06\x07')

The data 0x01 0x02 0x03 0x04 0x05 0x06 0x07 is now available for the RX inside usb_gcvendor_smpl_trn_ptr

, the variable registered at the read() call.

Step 6.8 Step (F6=step over) until you reach usb_plibusb_LibUsbCmdChk(). Step into (F5) usb_plibusb_LibUsbCmdChk(). Continue stepping (F6) all the way to

Step 6.9 The data from the host (in

case USB_LIBUSB_CMD_LED:.

usb_gcvendor_smpl_trn_ptr) is passed as the string host_command_string

. View the content by opening it in the Expressions tab in e2studio.

Step 6.10 Check that all LEDs toggle when the Python app runs.

Question Which pipe does the target board use to receive application demo commands? ______ Which endpoint is that pipe set up to use? (Ref. your table in section 4.) _______

Question The function usb_plibusb_LibUsbCmdChk(), triggered when our bulk pipe (and associated endpoint) receives data from the host, is defined at the end of the file. What value must be the first byte we need to send from the Python app to the demo command pipe to

- Control the LED? ____________

- Trigger the ADC to be read? ____________

- Write to the LCD? ____________.

Now that you know how to see the data received in the RX. Get rid of the BP when you don’t need it, or the PC Python code will time out. Use as needed to debug only.

Page 18: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 18 of 22

Write to LCD

Step 6.11 Write to the LCD by enabling that section. Two strings are written alternatively each main program loop, with a delay, to show that it’s running. Write your own text to the display; max 12 characters. The second byte is the line number. This must be 0-7.

Read ADC

Step 6.12 Now enable the section to read the ADC by enabling that section in the Python code.

Step 6.13 Enter the EP-address used for reading the ADC data value. The EP-address value for the ADC IN is right below the command EP-address.

Step 6.14 Run with F5.

Question Since we did Step 6.7we know that ______ is the command byte to be sent to the target through pipe 1 and EP1 (OUT) to trigger an ADC read, but which pipe and EP (IN) is used for reading the ADC data coming from target? _______. Hint: You can find this by looking at what pipe nr is used under “case USB_LIBUSB_CMD_ADC:” Then use your EP table on page 10 to determine the endpoint.

To read the ADC we must first write to the demo command OUT endpoint with the right value, then read another IN endpoint to get the ADC data.

Reading ADC data from the pipe is done by the line adc_array = my_usb_object.ReadEP(EP2_ADDR_ADC_IN, 32, EP_TIMEOUT) The rest of the .py code after my_usb_object.ReadEP() is there to convert the ADC-value from an array to a string and make it look nice.

The host does not use endpoint number, but EP-address. According to the USB 2.0 spec, the EP-address is made up of one byte, where - bit 7 indicates direction, 0 being OUT and 1 being IN. - bit 6-0 indicate EP-number. The EP-address for EP2 then becomes 10000000 + 00000010 = 10000010 = 0x82. For EP1, since bit 7 should be set to 0 (OUT), the address is simply 0x01.

Question What does the ADC value vary between? It should change when you turn the ADC potentiometer, located to the left of the circle of LEDs? _________ to __________.

Page 19: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 19 of 22

7 Add an interrupt IN endpoint

Overview: If you have time, add an interrupt endpoint to the target and use it with a target board switch.

Step 7.1 Open file r_usb_vendor_descriptor.c

Step 7.2 An interrupt endpoint is already added to the configuration descriptor in the USB Basic FW by default, so we don’t need to add this endpoint, change descriptor length

and go to Endpoint Descriptor 3.

USB_SMPLCONFLEN

etc.

Step 7.3 Back in r_usb_vendor_papl.c at the bottom of the file, there is code added that is triggered when SW1 (IRQ8 - defined in rx_rsk.c

Step 7.4 In the Python code, enable the interrupt IN code. Enter the EP-address above by adding EP3_ADDR_EXTRA_IN and enabling the interrupt endpoint reading code with “if 1:”.

) on the board is pressed. A series of integers is sent each time the switch is pressed.

Step 7.5 Disable the sections LED, ADC and LCD. We want fast response!

Step 7.6 Set NR_TEST_LOOPS to e.g. 10 in the Python code. (Right before the demo loop.)

Step 7.7 In the command result_array = my_usb_object.device.read(EP3_ADDR_EXTRA_IN, USB_SMP_II_TRNSIZE, 0, EP_TIMEOUT*10)

the interface is set to 0. Change it appropriately according to what is set in the endpoint descriptor in r_usb_vendor_descriptor.c and run the Python code.

So far we have used: - Control EP 0. We don’t fiddle with pipe and EP 0. The control endpoint was used during enumeration and by the get-descriptor commands we used in the Python code. - Bulk EP 1 (OUT) and 2 (IN). Bulk EP1 was for the demo commands, and Bulk EP 2 was used by the host used to read ADC data. If you have time, let’s use an interrupt endpoint and have it do something when a target switch is pressed! Observe that even for interrupt endpoints, the host initiates all communication on the bus. An interrupt endpoint is thus ‘polled’ like all other endpoints, but does have a maximum latency. The max. latency is given by the device endpoint descriptor’s bInterval field, and can be between 1 and 255 ms.

Question Aside from this being an interrupt endpoint, this endpoint is part of a different ________________. (Hint, there are two of them, one is for EP 1 & 2, and one is for EP 3 & 4.) Which one should we use if we want to press a switch on the target and have it as soon as possible transmit some (IN) data to the host? ________. What is then the EP-address, which we need to use in the Python code? ________. Hint: Step 6.12.

Page 20: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 20 of 22

Step 7.8 The code will stall waiting for the interrupt IN data. There is a timeout setting, so don’t wait too long to press SW1!

Step 7.9 Change all “if 0:” to “if 1:” in the Python code. Now the board switch triggers everything to occur in the loop, once per switch press!

Step 7.10 As a last step, run the GUI Renesas_libusb_host_gui.py!

Question Summarize what’s happening! ________________________________________________________ _________________________________________________________________________________ (You should get the interrupt IN data from EP3 each time SW1 is pressed. The data is just an incrementing series of integers.) The data at the USB bus level in has a determined max latency. What is this max latency value set to? _________________ Hint see the top green field and Step 7.1. Check the value of bInterval, which can be 1-255 ms

Page 21: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 21 of 22

8 Appendix. Use LibUSB Install-filter to access any device! Using the LibUSB filter application to access a device through Windows. Do this at home!

Overview: Try this at home to put the Python code we made for you to use! This section describes how to access any USB device via the LibUSB Windows backend. The LibUSB “Install-filter” can add and remove libusb-win32 as a driver to an existing driver installation.

Step 8.1 Run C:\Workspace\e2studio\LibUSB_Demo\LibUSB_Demo\LibUSB_HostPC\libusb-win32-bin-1.2.6.0\bin\x86\ install-filter-win.exe

.

Step 8.2 Start the “Install filter”.

Step 8.3 Select “Install a device filter”, press Next.

Step 8.4 Select the device you would like to interface with via LibUSB.

Step 8.5 Now you should be able to communicate with the device via the Windows LibUSB backend. Run the Python code by hitting F5 again in Idle.

Step 8.6 Study the beginning of the .py output. You should now see the added device under the target board’s LibUSB VID and PID. Here is example output from the python output window: __main__ start … List USB devices found: [<usb.core.Device object at 0x00C242F0>] In detail: Vendor ID 0x45b & Product ID = 0x2016 Vendor ID 0x46d & Product ID = 0xc016 This is our LibUSB target!

/ LAB END

Devices available to a PC host application via LibUSB are listed in the output (Step 5.6) with the command: usb.core.find() If you don’t see a particular USB device but would like to interface it (e.g. to see actual descriptor values) you can use the LibUSB filter application to make it visible. The tool ...\libusb-win32-bin-1.2.6.0\bin\x86\ install-filter-win.exe provides a convenient way to gain access to a device. This is perhaps not realistic for something that is to be deployed as a product as asking the customer to use this “filter” is not standard procedure, unless it could be run as part of an install procedure.

Now you know how to interface with a device of another class using LibUSB. But be careful. Setting a configuration of a device already used by a Windows driver may cause the Windows USB driver interaction to become corrupted! Either the device must be reconnected, or worst case if you are not careful, Windows must be restarted. (Windows logout and login may be enough.)

Page 22: LibUSB: Create a Solution Without the Class Struggle!€™12 lab procedure 2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 6 of 22 Step 2.3 Select the

DevCon’12 lab procedure

2L01I LibUSB - Create a Solution Without the Class Struggle_LabProcedure Page 22 of 22

9 (Lab restore)

Overview Prepare the PC for the lab. If Win7 is used, the screenshot and text will differ, but the restorage steps are similar.

Procedural Steps

Step 9.1 Start by Section 1, that is run the target code. Then come back here.

Step 9.2 In Windows Device Manager, right-click on the device you should see under class “libusb-win32-devices and select “Uninstall”.

Step 9.3 Start regedit and delete all entries under HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/USB/VID_045B&PID0512

.

Step 9.4 Search C:\Windows\INF, could be e.g. in

or wherever the Windows INF-folder is – it C:\Windows\system32\INF

filename = ), with search parameters

.inffor “libusb” without space. Use advanced search with Case sensitive

, and Word or phrase in the file = “lib usb”. Search also

unchecked.

Step 9.5 Delete any files found.

Step 9.6 Go to the folder C:\Workspace\e2studio\LibUSB_Demo\LibUSB_HostPCand delete the file

Renesas_libusb_host.py

Step 9.7 Make a copy of

.

Renesas_libusb_host_lab_restore.pythe

. Rename copy Renesas_libusb_host_lab.py

in the previous step. to replace the one you deleted

/DONE!

Tthis section should be done prior to the lab by the DevCon crew. This lab assumes that Python, PyUSB, and libusb0.sys are installed. See the top of file ..\rea-host\Renesas_LibUSB_0492_Lab_v1.00.py for more info on how to install.