Jungo Ltd
Copyright ©1997 - 2005 Jungo Ltd. All Rights Reserved
Information in this document is subject to change without notice. The software described in this document is furnished under a license agreement. The software may be used, copied or distributed only in accordance with that agreement. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or any means, electronically or mechanically, including photocopying and recording for any purpose without the written permission of Jungo Ltd.
Windows, Win32, Windows 98, Windows Me, Windows CE, Windows NT, Windows
2000, Windows XP and Windows Server 2003 are trademarks of Microsoft Corp.
WinDriver and KernelDriver are trademarks of Jungo. Other brand and product
names are trademarks or registered trademarks of their respective holders.
****************************************************************************************
| NOTE | |
| This manual outlines WinDriver's support for USB devices on
Windows 98/Me/2000/XP/Server2003/CE.NET and Linux.
WinDriver also supports development for PCI/PCMCIA/CardBus/ISA/ISAPnP/EISA/CompactPCI/PCI Express devices. For detailed information regarding WinDriver's support for these buses, please refer to the WinDriver Product Line page on our web-site (http://www.jungo.com/windriver.html) and to the WinDriver PCI/PCMCIA/CardBus/ISA/ISAPnP/EISA/CompactPCI/PCI Express User's Manual, which is available on-line at: http://www.jungo.com/support/manuals.html#manuals. Support for USB on Windows NT 4.0 is provided in a separate tool-kit - see our WinDriver USB for NT web-page: http://www.jungo.com/wdusb_nt.html. |
WinDriver is a development toolkit that dramatically simplifies the difficult task of creating device drivers and hardware access applications. WinDriver includes a wizard and code generation features that automatically detect your hardware and generate the driver to access it from your application. The driver and application you develop using WinDriver is source code compatible between all supported operating systems (WinDriver currently supports Windows 98/Me/2000/XP/Server2003/CE.NET and Linux.). The driver is binary compatible between Windows 98/Me/2000/XP/Server 2003. WinDriver provides a complete solution for creating high performance drivers.
Don't let the size of this manual fool you. WinDriver makes developing device drivers an easy task that takes hours instead of months. Most of this manual deals with the features that WinDriver offers to the advanced user. However, most developers will find that reading this chapter and glancing through the DriverWizard and function reference chapters is all they need to successfully write their driver.
WinDriver supports development for all USB chipsets. Enhanced support is offereed for Cypress, STMicroelectronics, Microchip, Texas Instruments, Silicon Laboratories and National Semiconductors chipsets, as outlined in Chapter [8] of the manual.
Visit Jungo's web site at http://www.jungo.com for the latest news about WinDriver and other driver development tools that Jungo offers.
Good luck with your project!
In protected operating systems such as Windows and Linux, a programmer cannot access hardware directly from the application level (user mode), where development work is usually done. Hardware can only be accessed from within the operating system itself (kernel mode or Ring-0), utilizing software modules called device drivers. In order to access a custom hardware device from the application level, a programmer must do the following:
Your hardware access application will run on all the supported platforms: Windows 98/Me/2000/XP/Server2003/CE.NET and Linux- just re-compile the code for the target platform. (The code is binary compatible between Windows 98/Me/2000/XP/Server 2003 platforms, so there is no need to rebuild the code when porting the driver between these operating systems.)
For hardware access, your application calls one of the WinDriver user-mode functions. The user-mode function calls the WinDriver kernel, which accesses the hardware for you through the native calls of the operating system.
WinDriver supports Windows 98/Me/2000/XP/Server2003/CE.NET and Linux.
The same source code will run on all supported platforms - simply re-compile it for the target platform. The source code is binary compatible across Windows 98/Me/2000/XP/Server 2003, so executables created with WinDriver can be ported between these operating systems without re-compilation.
Even if your code is meant only for one of the supported operating systems, using WinDriver will give you the flexibility to move your driver to another operating system in the future without needing to change your code.
All the evaluation versions of WinDriver USB Host toolkit are full featured. No functions are limited or crippled in any way. The evaluation version of WinDriver varies from the registered version in the following ways:
For more details please refer to appendix F.
****************************************************************************************
| NOTE | |
| The code generated by DriverWizard is in fact a diagnostics program that contains functions that perform data transfers on the device's pipes, send requests to the control pipe, change the active alternate setting, reset pipes, and more. |
The Windows CE version also includes:
WinDriver provides custom wrapper APIs and sample code for major USB controllers (see Chapter 8), including for the following controllers:
The samples directories typically include the following sub-directories:
In addition to the samples provided for specific chipsets [1.9.3], WinDriver includes a variety of samples that demonstrate how to use WinDriver's API to communicate with your device and perform various driver tasks.
Yes. WinDriver is purchased as a development toolkit, and any device driver created using WinDriver may be distributed, royalties free, in as many copies as you wish. See the license agreement (WinDriver/docs/license.txt) for more details.
Jungo offers two driver development products: WinDriver and KernelDriver.
A USB driver developed with WinDriver will run on Windows 98/Me/2000/XP/Server2003/CE.NET and Linux.
Typically, using WinDriver a developer that has no previous driver knowledge can get a driver running in a matter of a few hours (compared to several weeks with a kernel-mode driver).
A USB driver created with KernelDriver can run on Windows 98/Me/2000/XP/Server2003/CE and Linux. KernelDriver dramatically simplifies the difficult task of creating kernel-mode device drivers, by providing a hardware access API in the kernel mode, which is portable across the supported operating systems.
This chapter provides you with a general introduction to device drivers and takes you through the structural elements of a device driver.
****************************************************************************************
| NOTE | |
| Using WinDriver, you do not need to familiarize yourself with the internal workings of driver development. As explained in Chapter 1 of the manual, WinDriver enables you to communicate with your hardware and develop a driver for your device from the user mode, using only WinDriver's simple APIs, without any need for driver or kernel development knowledge. |
Device drivers are the software segments that provides an interface between the operating system
and the specific hardware devices such as terminals, disks, tape drives, video cards and network media.
The device driver brings the device into and out of service, sets hardware parameters in
the device, transmits data from the kernel to the device, receives data from the device and
passes it back to the kernel, and handles device errors.
A driver acts like a translator between the device and programs that use the device. Each device has its own set of specialized commands that only its driver knows. In contrast, most programs access devices by using generic commands. The driver, therefore, accepts generic commands from a program and then translates them into specialized commands for the device.
There are numerous driver types, differing in their functionality. This subsection briefly describes three of the most common driver types.
Monolithic drivers are device drivers that embody all the functionality needed to support a hardware device. A monolithic driver is accessed by one or more user applications, and directly drives a hardware device. The driver communicates with the application through I/O control commands (IOCTLs) and drives the hardware using calls to the different DDK, ETK, DDI/DKI functions.
Monolithic drivers are supported in all operating systems including all Windows platforms and all Unix platforms.
Layered drivers are device drivers that are part of a stack of device drivers that together process an I/O request. An example of a layered driver is a driver that intercepts calls to the disk and encrypts/decrypts all data being transferred to/from the disk. In this example, a driver would be hooked on to the top of the existing driver and would only do the encryption/decryption.
Layered drivers are sometimes also known as filter drivers, and are supported in all operating systems including all Windows platforms and all Unix platforms.
A Miniport driver is an add-on to a class driver that supports miniport drivers.
It is used so the miniport driver does not have to implement all of the functions
required of a driver for that class. The class driver provides the basic class
functionality for the miniport driver.
A class driver is a driver that supports a group of devices of common functionality,
such as all HID devices or all network devices.
Miniport drivers are also called miniclass drivers or minidrivers, and are supported in the Windows NT (or 2000) family, namely Windows NT/2000/XP and Server 2003.
Windows NT/2000/XP/Server 2003 provide several driver classes (called ports) that handle the common functionality of their class. It is then up to the user to add only the functionality that has to do with the inner workings of the specific hardware.
The NDIS miniport driver is one example of such a driver. The NDIS miniport framework is used to create network drivers that hook up to NT's communication stacks, and are therefore accessible to common communication calls used by applications. The Windows NT kernel provides drivers for the various communication stacks and other code that is common to communication cards. Due to the NDIS framework, the network card developer does not have to write all of this code, only the code that is specific to the network card he is developing.
WDM (Windows Driver Model) drivers are kernel-mode drivers within the Windows NT
and Windows 98 operating system families. Windows NT family includes Windows
NT/2000/XP/Server 2003, and Windows 98 family includes Windows 98 and Windows Me.
WDM works by channeling some of the work of the device driver into portions of the
code that are integrated into the operating system. These portions of code handle
all of the low-level buffer management, including DMA and Plug and Play (Pnp) device
enumeration.
WDM drivers are PnP drivers that support power management protocols, and include
monolithic drivers, layered drivers and miniport drivers.
VxD drivers are Windows 95/98/Me Virtual Device Drivers, often called VxDs because the filenames end with the .vxd extension. VxD drivers are typically monolithic in nature. They provide direct access to hardware and privileged operating system functions. VxD drivers can be stacked or layered in any fashion, but the driver structure itself does not impose any layering.
In the classic Unix driver model, devices belong to one of three categories: character (char) devices, block devices and network devices. Drivers that implement these devices are correspondingly known as char drivers, block drivers or network drivers. Under Unix, drivers are code units linked into the kernel that run in privileged kernel mode. Generally, driver code runs on behalf of a user-mode application. Access to Unix drivers from user-mode applications is provided via the file system. In other words, devices appear to the applications as special device files that can be opened.
Unix device drivers are either layered or monolithic drivers. A monolithic driver can be perceived as a one-layer layered driver.
Linux device drivers are based on the classic Unix device driver model. In addition, Linux introduces some new characteristics.
Under Linux, a block device can be accessed like a character device, as in Unix, but also has a block-oriented interface that is invisible to the user or application.
Traditionally, under Unix, device drivers are linked with the kernel, and the system is brought down and restarted after installing a new driver. Linux introduces the concept of a dynamically loadable driver called a module. Linux modules can be loaded or removed dynamically without requiring the system to be shut down. A Linux driver can be written so that it is statically linked or written in a modular form that allows it to be dynamically loaded. This makes Linux memory usage very efficient because modules can be written to probe for their own hardware and unload themselves if they cannot find the hardware they are looking for.
Like Unix device drivers, Linux device drivers are either layered or monolithic drivers.
Every device driver must have one main entry point, like the main() function in a C console application. This entry point is called DriverEntry() in Windows and init_module() in Linux. When the operating system loads the device driver, this driver entry procedure is called.
There is some global initialization that every driver needs to perform only once when it is loaded for the first time. This global initialization is the responsibility of the DriverEntry()/init_module() routine. The entry function also registers which driver callbacks will be called by the operating system. These driver callbacks are operating system requests for services from the driver. In Windows, these callbacks are called dispatch routines, and in Linux they are called file operations. Each registered callback is called by the operating system as a result of some criteria, such as disconnection of hardware, for example.
Operating systems differ in how they link a device to its driver.
In Windows, the link is performed by the INF file, which registers the device to work with the
driver. This association is performed before the DriverEntry() routine is called.
The operating system recognizes the device, looks up in its database which INF file is associated
with the device, and according to the INF file, calls the driver's entry point.
In Linux, the link between a device and its driver is defined in the init_module() routine. The init_module() routine includes a callback which states what hardware the driver is designated to handle. The operating system calls the driver's entry point, based on the definition in the code.
A driver can create an instance, thus enabling an application to open a handle to the
driver through which the application can communicate with it.
The applications communicate with the drivers using a file access API (Application
Program Interface). Applications open a handle to the driver using CreateFile()
call (in Windows), or open() call (in Linux)
with the name of the device as the file name. In order to read from and write to the device,
the application calls ReadFile() and WriteFile() (in Windows), or
read(), write() in Linux.
Sending requests is accomplished using an I/O control call, called DeviceIoControl()
(in Windows), and ioctl() in Linux.
In this I/O control call, the application specifies:
The data passed between the driver and the application is encapsulated into a structure. In Windows, this structure is called an I/O Request Packet (IRP), and is encapsulated by the I/O Manager. This structure is passed on to the device driver, which may modify it and pass it down to other device drivers.
This chapter explores the basic characteristics of the Universal Serial Bus (USB) and introduces WinDriver USB's features and architecture.
****************************************************************************************
| NOTE | |
| The references to the WinDriver USB toolkit in this chapter relate to the
standard WinDriver USB toolkit for development of USB host
drivers.
The WinDriver USB Device toolkit, designed for development of USB device firmware, is discussed separately in Chapter 12. |
USB (Universal Serial Bus) is an industry standard extension to the PC architecture for attaching peripherals to the computer. It was originally developed in 1995 by leading PC and telecommunication industry companies, such as Intel, Compaq, Microsoft and NEC. USB was developed to meet several needs, among them the needs for an inexpensive and widespread connectivity solution for peripherals in general and for computer telephony integration in particular, an easy-to-use and flexible method of reconfiguring the PC, and a solution for adding a large number of external peripherals. The USB standard meets these needs.
The USB specification allows for the connection of a maximum of 127 peripheral devices (including hubs) to the system, either on the same port or on different ports.
USB also supports Plug and Play installation and hot swapping.
The USB 1.1 standard supports both isochronous and asynchronous data transfers and has dual speed data transfer: 1.5 Mb/s (megabits per second) for low-speed USB devices and 12 Mb/s for high-speed USB devices (much faster than the original serial port). Cables connecting the device to the PC can be up to five meters (16.4 feet) long. USB includes built-in power distribution for low power devices and can provide limited power (up to 500 mA of current) to devices attached on the bus.
The USB 2.0 standard supports a signalling rate of 480 Mb/s, known as
''high-speed'', which is 40 times faster than the USB 1.1 full-speed
transfer rate.
USB 2.0 is fully forward- and backward-compatible with USB 1.1 and uses
existing cables and connectors.
USB 2.0 supports connections with PC peripherals that provide expanded
functionality and require wider bandwidth. In addition, it can handle a larger
number of peripherals simultaneously.
USB 2.0 enhances the user's experience of many applications, including
interactive gaming, broadband Internet access, desktop and Web publishing,
Internet services and conferencing.
Because of its benefits (described also in section 3.2 below), USB is currently enjoying broad market acceptance.
This section describes the main benefits of the USB standard and the WinDriver USB toolkit, which supports this standard:
The Universal Serial bus is comprised of the following primary components:
During the operation of a USB device, the host can initiate a flow of data between the client software and the device.
Data can be transferred between the host and only one device at a time (peer to peer communication). However, two hosts cannot communicate directly, nor can two USB devices (with the exception of On-The-Go (OTG) devices, where one device acts as the master (host) and the other as the slave.)
The data on the USB bus is transferred via pipes that run between software memory buffers on the host and endpoints on the device.
Data flow on the USB bus is half-duplex, i.e. data can be transmitted only in one direction at a given time.
An endpoint is a uniquely identifiable entity on a USB device, which
is the source or terminus of the data that flows from or to the device. Each
USB device, logical or physical, has a collection of independent endpoints.
The three USB speeds (low, full and high) all support one bi-directional
control endpoint (endpoint zero) and 15 unidirectional endpoints. Each
endpoint unidirectional endpoint can be used for either inbound or outbound
transfers, so theoretically there are 30 supported endpoints.
Each endpoint has the following attributes: bus access frequency,
bandwidth requirement, endpoint number, error handling mechanism, maximum
packet size that can be transmitted or received, transfer type and direction
(into or out of the device).
A pipe is a logical component that represents an association between an endpoint on the USB device and software on the host. Data is moved to and from a device through a pipe. A pipe can be either a stream pipe or a message pipe, depending on the type of data transfer used in the pipe. Stream pipes handle interrupt, bulk and isochronous transfers, while message pipes support the control transfer type. The different USB transfer types are discussed below [3.6].
The USB standard supports two kinds of data exchange between a host and a device: functional data exchange and control exchange.
Figure 3.2 below depicts a USB device with one bi-directional control pipe (endpoint) and six functional data transfer pipes (endpoints), as identified by WinDriver's DriverWizard utility (discussed in Chapter 5).
More information on how to implement the control transfer by sending setup packets can be found in Chapter 9.
The USB device (function) communicates with the host by transferring data through a pipe between a memory buffer on the host and an endpoint on the device. USB supports four different transfer types. A type is selected for a specific endpoint according to the requirements of the device and the software. The transfer type of a specific endpoint is determined in the endpoint descriptor.
The USB specification provides for the following data transfer types:
Control Transfer is mainly intended to support configuration, command and status operations between the software on the host and the device.
This transfer type is used for low-, full- and high-speed devices.
Each USB device has at least one control pipe (default pipe), which provides access to the configuration, status and control information.
Control transfer is bursty, non-periodic communication.
The control pipe is bi-directional - i.e. data can flow in both directions.
Control transfer has a robust error detection, recovery and retransmission mechanism and retries are made without the involvement of the driver.
The maximum packet size for control endpoints can be only 8 bytes for low-speed devices; 8, 16, 32, or 64 bytes for full-speed devices; and only 64 bytes for high-speed devices.
Isochronous Transfer is most commonly used for time-dependent information, such as multimedia streams and telephony.
This transfer type can be used by full-speed and high-speed devices, but not by low-speed devices.
Isochronous transfer is periodic and continuous.
The isochronous pipe is unidirectional, i.e. a certain endpoint can either transmit or receive information. Bi-directional isochronous communication requires two isochronous pipes, one in each direction.
USB guarantees the isochronous transfer access to the USB bandwidth (i.e. it reserves the required amount of bytes of the USB frame) with bounded latency, and guarantees the data transfer rate through the pipe, unless there is less data transmitted.
Since timeliness is more important than correctness in this type of transfer, no retries are made in case of error in the data transfer. However, the data receiver can determine that an error occurred on the bus.
Interrupt Transfer is intended for devices that send and receive small amounts of data infrequently or in an asynchronous time frame.
This transfer type can be used for low-, full- and high-speed devices.
Interrupt transfer type guarantees a maximum service period and that delivery will be re-attempted in the next period if there is an error on the bus.
The interrupt pipe, like the isochronous pipe, is unidirectional and periodical.
The maximum packet size for interrupt endpoints can be 8 bytes or less for low-speed devices; 64 bytes or less for full-speed devices; and 1,024 bytes or less for high-speed devices.
Bulk Transfer is typically used for devices that transfer large amounts of non-time sensitive data, and that can use any available bandwidth, such as printers and scanners.
This transfer type can be used by full-speed and high-speed devices, but not by low-speed devices.
Bulk transfer is non-periodic, large packet, bursty communication.
Bulk transfer allows access to the bus on an "as-available" basis, guarantees the data transfer but not the latency, and provides an error check mechanism with retries attempts. If part of the USB bandwidth is not being used for other transfers, the system will use it for bulk transfer.
Like the other stream pipes (isochronous and interrupt), the bulk pipe is also unidirectional, so bi-directional transfers require two endpoints.
The maximum packet size for bulk endpoints can be 8, 16, 32, or 64 bytes for full-speed devices, and 512 bytes for high-speed devices.
Before the USB function (or functions, in a compound device) can be operated, the device must be configured. The host does the configuring by acquiring the configuration information from the USB device. USB devices report their attributes by descriptors. A descriptor is the defined structure and format in which the data is transferred. A complete description of the USB descriptors can be found in Chapter 9 of the USB Specification (see http://www.usb.org for the full specification).
It is best to view the USB descriptors as a hierarchical structure with four
levels:
There is only one device descriptor for each USB device. Each device has one or more configurations, each configuration has one or more interfaces, and each interface has zero or more endpoints, as demonstrated in Figure 3.3 below.
In addition, an interface may have alternate settings. The alternate settings allow the endpoints or their characteristics to be varied after the device is configured.
The same endpoint can have different properties (and consequently different uses) in different alternate settings.
Seems complicated? Not at all! WinDriver automates the USB configuration process. The included DriverWizard utility [5] and USB diagnostics application scan the USB bus, detect all USB devices and their configurations, interfaces, alternate settings and endpoints, and enable you to pick the desired configuration before starting driver development.
WinDriver identifies the endpoint transfer type as determined in the endpoint descriptor. The driver created with WinDriver contains all configuration information acquired at this early stage.
WinDriver USB enables developers to quickly develop high-performance drivers for USB-based devices, without having to learn the USB specifications or the operating system's internals.
Using WinDriver USB, developers can create USB drivers without having to use the operating system's development kits (such as the Windows DDK); In addition, Windows developers do not need to familiarize themselves with Microsoft's Win32 Driver Module (WDM).
The driver code developed with WinDriver USB is binary compatible across the supported Windows platforms - Windows 98/Me/2000/XP/Server 2003 - and source code compatible across all supported operating systems - Windows 98/Me/2000/XP/Server2003/CE.NET and Linux. (For an up-to-date list of supported operating systems, visit Jungo's web site at: http://www.jungo.com.
WinDriver USB is a generic tool kit that supports all USB devices from all vendors and with all types of configurations.
WinDriver USB encapsulates the USB specification and architecture, letting you focus on your application logic. WinDriver USB features the graphical DriverWizard utility [5], which enables you to easily detect your hardware, view its configuration information, and test it, before writing a single line of code: DriverWizard first lets you choose the desired configuration, interface and alternate setting combination, using a friendly graphical user interface. After detecting and configuring your USB device, you can proceed to test the communication with the device - perform data transfers on the pipes, send control requests, reset the pipes, etc. - in order to ensure that all your hardware resources function as expected.
After your hardware is diagnosed, you can use DriverWizard to automatically generate your device driver source code in C, Delphi or Visual Basic. WinDriver USB provides user-mode APIs, which you can call from within your application in order to implement the communication with your device. The WinDriver USB API includes USB-unique operations such as reset of a pipe or a device. The generated DriverWizard code implements a diagnostics application, which demonstrates how to use WinDriver's USB API to drive your specific device. In order to use the application you just need to compile and run it. You can jump-start your development cycle by using this application as your skeletal driver and then modifying the code, as needed, to implement the desired driver functionality for your specific device.
DriverWizard also automates the creation of an INF file that registers your
device to work with WinDriver, which is an essential step in order to correctly
identify and handle USB devices using WinDriver. For an explanation on why you
need to create an INF file for your USB device, refer to section
of the manual. For detailed information on creation of INF files
with DriverWizard, refer to section 5.2 (see
specifically step 3).
With WinDriver USB, all development is done in the user mode, using familiar development and debugging tools and your favorite compiler (such as MSDEV/Visual C/C++, Borland Delphi, Borland C++ or Visual Basic).
To access your hardware, your application calls the WinDriver kernel module using functions from the WinDriver USB API. The high-level functions utilize the low-level functions, which use IOCTLs to enable communication between the WinDriver kernel module and your user-mode application. The WinDriver kernel module accesses your USB device resources through the native operating system calls.
There are two layers responsible for abstracting the USB device to the USB device driver. The upper layer is the USB Driver (USBD) layer, which includes the USB Hub Driver and the USB Core Driver. The lower level is the Host Controller Driver (HCD) layer. The division of duties between the HCD and USBD layers is not defined and is operating system dependent. Both the HCD and USBD are software interfaces and components of the operating system, where the HCD layer represents a lower level of abstraction.
The HCD is the software layer that provides an abstraction of the host controller hardware, while the USBD provides an abstraction of the USB device and the data transfer between the host software and the function of the USB device.
The USBD communicates with its clients (the specific device driver, for example) through the USB Driver Interface (USBDI). At the lower level, the Core Driver and USB Hub Driver implement the hardware access and data transfer by communicating with the HCD using the Host Controller Driver Interface (HCDI).
The USB Hub Driver is responsible for identifying the addition and removal of devices from a particular hub. When the Hub Driver receives a signal that a device was attached or detached, it uses additional host software and the USB Core Driver to recognize and configure the device. The software implementing the configuration can include the hub driver, the device driver, and other software.
WinDriver USB abstracts the configuration procedure and hardware access described above for the developer. With WinDriver's USB API, developers can perform all the hardware-related operations without having to master the lower-level implementation for supporting these operations.
Almost all monolithic drivers (drivers that need to access specific USB devices) can be written with WinDriver USB. In cases where a standard driver is required, e.g. NDIS driver, SCSI driver, Display driver, USB to Serial port drivers, USB layered drivers, etc., use KernelDriver USB (also from Jungo).
For quicker development time, select WinDriver USB over KernelDriver USB whenever possible.
This chapter takes you through the WinDriver installation process, and shows you how to verify that your WinDriver is properly installed. The last section discusses the uninstall procedure.
****************************************************************************************
| NOTE | |
| The version of the GCC compiler should match the compiler version used for building the running Linux kernel. |
The WinDriver CD contains all versions of WinDriver for all the
different operating systems. The CD's root directory contains the
Windows 98/Me and 2000/XP/Server 2003 version. This will automatically
begin when you insert the CD into your CD drive. The other
versions of WinDriver are located in subdirectories, i.e.,
Linux,
Wince and so on.
****************************************************************************************
| NOTE | |
| You must have administrative privileges in order to install WinDriver on Windows 98, Me, 2000, XP and Server 2003. |
****************************************************************************************
| NOTE | |
| The WinDriver installation defines a WD_BASEDIR environment
variable, which is set to point to the location of your WinDriver directory,
as selected during the installation. This variable is used during the
DriverWizard [5] code generation - it determines the
default directory for saving your generated code and is used in the include
paths of the generated project/make files.
Therefore, if you decide to change the name and/or location of your WinDriver directory after the installation, you should also edit the value of the WD_BASEDIR environment variable and set it to point to the location of your new WinDriver directory. You can edit the value of WD_BASEDIR by following these steps:
|
The following steps are for registered users only:
In order to register your copy of WinDriver with the license you received from Jungo, follow the steps below:
The following instructions apply to platform developers who build Windows CE kernel images using Windows CE Platform Builder:
****************************************************************************************
| NOTE | |
| We recommend that you read Microsoft's documentation and understand the Windows CE and device driver integration procedure before you perform the installation. |
This step is only necessary if you want the WinDriver CE kernel file (windrvr6.dll) to be a permanent part of the Windows CE image (NK.BIN). This would be the case if you were transferring the file to your target platform using a floppy disk. If you prefer to have the file windrvr6.dll loaded on demand via the CESH/PPSH services, you need not carry out this step until you build a permanent kernel.
The following instructions apply to driver developers who do not build the Windows CE kernel, but only download their drivers, built using Microsoft eMbedded Visual C++, to a ready-made Windows CE platform:
The WinDriver installation on the host Windows 2000/XP/Server 2003 PC defines a WD_BASEDIR environment variable, which is set to point to the location of your WinDriver directory, as selected during the installation. This variable is used during the DriverWizard [5] code generation - it determines the default directory for saving your generated code and is used in the include paths of the generated project/make files.
Therefore, if you decide to change the name and/or location of your host WinDriver directory after the installation, you should also edit the value of the WD_BASEDIR environment variable and set it to point to the location of your new WinDriver directory. You can edit the value of WD_BASEDIR by following these steps:
Note that if you install the WinDriver Windows 98/Me/2000/XP/Server 2003 tool-kit on the same host PC, the installation will override the value of the WD_BASEDIR variable from the Windows CE installation.
In Linux, kernel modules must be compiled with the same header files that the kernel itself was compiled with. Since WinDriver installs the kernel module windrvr6.o/.ko, it must compile with the header files of the Linux kernel during the installation process.
Therefore, before you install WinDriver for Linux, verify that the Linux source code and the file versions.h are installed on your machine:
Install the Linux kernel source code:
Install version.h:
In order to run GUI WinDriver applications (e.g. DriverWizard [5] ; Debug Monitor [7.2]) you must also have version 5.0 of the libstdc++ library - libstdc++.so.5. If you do not have this file, install it from the relevant RPM in your Linux distribution (e.g. compat-libstdc++).
Before proceeding with the installation, you must also make sure that you have
a `linux' symbolic link. If you do not, please create one by typing:
/usr/src$ ln -s <target kernel>/ linux
For example, for the Linux 2.4 kernel type:
/usr/src$ ln -s linux-2.4/ linux
For example:
****************************************************************************************
| NOTE | |
| The configure script creates a makefile based on your specific running kernel. You may run the configure script based on another kernel source you have installed, by adding the flag --with-kernel-source=<path> to the configure script. The <path> is the full path to the kernel source directory, e.g. /usr/src/linux. |
If you are using a Linux 2.6.x kernel that has the udev file
system, change the permissions by modifying your
/etc/udev/permissions.d/50-udev.permissions file. For
example, add the following line to provide read and write permissions:
windrvr6:root:root:0666
Otherwise, use the chmod command, for example:
chmod /dev/windrvr6 666
****************************************************************************************
| TIP | |
| To avoid the need to reload the driver module
(windrvr6.o/.ko) each time you restart your system, add the
following line to your Linux /etc/rc.d/rc.local file:
/sbin/modprobe windrvr6 |
The following steps are for registered users only
In order to register your copy of WinDriver with the license you received from Jungo, follow the steps below:
Restricting Hardware Access on Linux
****************************************************************************************
| CAUTION! | |
| Since /dev/windrvr6 gives direct hardware access to user
programs, it may compromise kernel stability on multi-user Linux systems.
Please restrict access to the DriverWizard and the device file
/dev/windrvr6 to trusted users.
For security reasons the WinDriver installation script does not automatically perform the steps of changing the permissions on /dev/windrvr6 and the DriverWizard executable (wdwizard). |
To upgrade to a new version of WinDriver on Windows, follow the steps outlined in Section 4.2.1, which illustrates the process of installing WinDriver for Windows 98/Me/2000/XP/Server 2003. You can either choose to overwrite the existing installation or install to a separate directory.
After installation, start DriverWizard and enter the new license string, if you have received one. This completes the upgrade of WinDriver.
To upgrade your source code, pass the new license string as a parameter to WDU_Init() [A.3.1] (or to WD_License() [A.5.9] when using the old WD_UsbXXX() APIs).
The procedure for upgrading your installation on other operating systems is the same as the one described above. Please check the respective installation sections for installation details.
This section will help you to uninstall either the evaluation or registered version of WinDriver.
****************************************************************************************
| NOTES | |
|
On Windows 98/Me: Uninstall (Remove) the device manually from the Device Manager.
The uninstall will stop and unload the WinDriver kernel module
(windrvr6.sys); delete the copy of the
windrvr6.inf file from the
%windir%
inf
directory (on Windows
2000/XP/Server 2003) or %windir%
inf
other
directory (on Windows 98/Me); delete WinDriver from Windows'
Start menu; delete the WinDriver
installation directory (except for files that you added to this
directory); and delete the short-cut icons to the DriverWizard and
Debug Monitor utilities from the Desktop.
****************************************************************************************
| NOTE | |
| When running this command, windrvr6.sys should reside in the same directory as windrvr6.inf. |
(On the development PC, the wdreg uninstall command is executed for you by the uninstall utility.)
****************************************************************************************
| NOTES | |
|
****************************************************************************************
| NOTE | |
| You must be logged in as root to perform the uninstall procedure. |
This chapter describes WinDriver DriverWizard's hardware diagnostics and
driver code generation capabilities.
To find out how you can use the WinDriver USB Device DriverWizard to develop
device firmware, refer to Chapter 12.
DriverWizard (included in the WinDriver toolkit) is a GUI-based diagnostics and driver generation tool that allows you to write to and read from the hardware, before writing a single line of code. The hardware is diagnosed through a Graphical User Interface--memory ranges are read, registers are toggled and interrupts are checked. Once the device is operating to your satisfaction, DriverWizard creates the skeletal driver source code, with functions to access all your hardware resources.
If you are developing a driver for a device that is based on one of the enhanced-support USB chipsets (The Cypress EZ-USB family, Microchip PIC18F4550, Texas Instruments TUSB3410, TUSB3210, TUSB2136, TUSB5052, Silicon Laboratories C8051F320), we recommend you read Chapter 8, which explains WinDriver's enhanced support for specific chipsets, before starting your driver development.
DriverWizard can be used to diagnose your hardware and can generate an INF file for hardware running under Windows 98/Me/2000/XP/Server 2003. Avoid using DriverWizard to generate code for a device based on one of the supported USB chipsets [8], as DriverWizard generates generic code which will have to be modified according to the specific functionality of the device in question. Preferably, use the complete source code libraries and sample applications (supplied in the package) tailored to the various USB chipsets.
DriverWizard is an excellent tool for two major phases in your HW/Driver development:
The code generated by DriverWizard is composed of the following elements:
To use DriverWizard:
****************************************************************************************
| NOTE | |
| On Windows 98, if you do not see your USB device in the list, reconnect it and make sure the New Hardware Found/Add New Hardware wizard appears for your device. Do not close the dialog box until you have generated an INF for your device using the steps below. |
Whenever developing a driver for a Plug and Play Windows operating
system (i.e., Windows 98/Me/2000/XP/Server 2003) you are required to install an INF file for
your device. This file will register your Plug and Play device to work
with the windrvr6.sys driver. The file generated by the
DriverWizard in this step should later be distributed to your customers
using Windows 98/Me/2000/XP/Server 2003, and installed on their PCs.
The INF file you generate here is also designed to enable DriverWizard
to diagnose your device. As explained earlier, this is required only
when using WinDriver to support a Plug and Play device (such as USB) on
a Plug and Play system (Windows 98/Me/2000/XP/Server 2003). Additional
information concerning the need for an INF file is explained in
Section 11.3.1.
If you do not need to generate an INF file (e.g. if you are using DriverWizard on Linux), skip this step and proceed to the next one.
To generate the INF file with the DriverWizard, follow the steps below:
On Windows 2000/XP/Server 2003 you can choose to
automatically install the INF file from the DriverWizard by
checking the Automatically Install the INF file option
in the DriverWizard's INF generation dialog (this option is
checked by default for USB devices).
On Windows 98/Me you must install the INF file manually,
using Windows Add New Hardware Wizard or
Upgrade Device Driver Wizard, as explained in
Section 11.3.
If the automatic INF file installation on Windows 2000/XP/Server
2003 fails, DriverWizard will notify you and provide manual
installation instructions for this OS as well.
DriverWizard will display the pipes information for the selected alternate setting.
****************************************************************************************
| NOTE | |
| For USB devices with only one alternate setting configured, DriverWizard automatically selects the detected alternate setting and therefore the Select Device Interface dialog will not be displayed. |
When you select one of the available standard USB requests, the setup packet information for the selected request is automatically filled and the request description is displayed in the Request Description box.
For a custom request, you are required to enter the setup packet information and write data (if exists) yourself. The size of the setup packet should be eight bytes and it should be defined using little endian byte ordering. The setup packet information should conform to the USB specification parameters (bmRequestType, bRequest, wValue, wIndex, wLength).
****************************************************************************************
| NOTE | |
| More detailed information on the standard USB requests, on how to implement the control transfer and how to send setup packets can be found in Chapter 9. |
You have the option to log all the WinDriver API calls using the DriverWizard, with the API calls input and output parameters. You can select this option by selecting the Log API calls option from the Tools menu or by clicking on the Log API calls toolbar icon in the DriverWizard's opening window.
The wizard logger is the empty window that opens along with the Device Resources dialog box when you open a new project. The logger keeps track of all of the input and output during the diagnostics stage, so that you may analyze your device's physical performance at a later time. You can save the log for future reference. When saving the project, your log is saved as well. Each log is associated with one project.
After you have finished diagnosing your device and have ensured that it runs according to your specifications, you are ready to write your driver.
Choose Generate Code from the Build menu. DriverWizard will generate the source code for your driver, and place it along with the project file (xxx.wdp, where "xxx" is the project name). The files are saved in a directory DriverWizard creates for every development environment and operating system selected in the Generate Code dialog box.
In the source code directory you now have a new xxx_diag.c
source file (where xxx is the name you selected for your
DriverWizard project). This file implements a diagnostic USB application,
which demonstrates how to use WinDriver's USB API to locate and communicate
with your USB device(s), including detection of Plug and Play events (device
insertion/removal, etc.), performing read/write transfers on the pipes,
resetting the pipes and changing the device's active alternate setting.
The generated application supports handling of multiple identical USB devices.
For Windows 98, Me, 2000, XP, CE and Server 2003 (Using MSDEV):
This will generate Visual Basic or Delphi project and files, similar to the MSDEV projects described in above [5.3.3.2].
This chapter takes you through the WinDriver driver development cycle.
****************************************************************************************
| NOTE | |
| If your device is based on one of the chipsets for which WinDriver provides enhanced support (The Cypress EZ-USB family, Microchip PIC18F4550, Texas Instruments TUSB3410, TUSB3210, TUSB2136, TUSB5052, Silicon Laboratories C8051F320), read the following overview and then skip straight to Chapter 8. |
Please see Appendix A for a detailed description of
WinDriver's USB APIs.
To learn how to implement control transfers with WinDriver, refer to
Chapter 9 of the manual.
There may be times when you select to write your driver directly, without using DriverWizard. In either case, proceed according to the steps outlined below, or choose a sample that most closely resembles what your driver should do, and modify it.
#include "wdu_lib.h"
When using the wd_utils DLL/shared object, you will need to distribute WinDriver/redist/wd_utils.dll (Windows 98/Me/2000/XP/Server 2003 and Windows CE) / WinDriver/lib/libwd_utils.so (Linux) with your driver - see Chapter 11.
When developing your driver on Windows CE platforms, you must first register your device to work with WinDriver. This is similar to installing an INF file for your device when developing a driver for a Plug and Play Windows operating system (i.e., Windows 98, Me, 2000, XP or Server 2003). Refer to Section 11.3 for understanding the INF file.
In order to register your USB device to work with WinDriver, you can perform one of two of the following:
OR
[HKEY_LOCAL_MACHINE\DRIVERS\USB\LoadClients\<ID>\Default\Default\WDR]: "DLL"="windrvr6.dll"
<ID> is comprised of your vendor ID and product ID, separated by an underscore character: <MY VENDOR ID>_<MY PRODUCT ID>.
Insert your device specific information to this key. The key registers your device with Windows CE Plug-and-Play (USB driver) and enables identification of the device during boot. You can refer to the registry after calling WDU_Init() and then this key will exist. From that moment the device will be recognized by CE. If your device has a persistent registry, this addition will remain until you remove it.
For more information, refer to MSDN Library, under USB Driver Registry Settings section.
The entire WinDriver API can be used when developing drivers in Visual Basic and Delphi.
DriverWizard can be used to diagnose your hardware and verify that it is working properly before you start coding. You can then proceed to automatically generate source code with the wizard in a variety of languages, including Delphi and Visual Basic. For more information, refer to Chapter 5 and Section 6.4.3 below.
Samples for drivers written using the WinDriver API in Delphi or Visual Basic can be found in:
Use these samples as a starting point for your own driver.
The method of development in Visual Basic is the same as the method in C using the automatic code generation feature of DriverWizard.
Your work process should be as follows:
The following sections describe how to debug your hardware access application code.
Debug Monitor is a powerful graphical- and console-mode tool for monitoring all activities handled by the WinDriver kernel (windrvr6.sys/windrvr6.dll/windrvr6.o/.ko). You can use this tool to monitor how each command sent to the kernel is executed.
Debug Monitor has two modes: graphical mode and console mode. The following sections explain how to operate Debug Monitor in both modes.
Applicable for Windows 98, Me, 2000, XP, Server 2003 and Linux. You may also use Debug Monitor to debug your Windows CE driver code running on CE emulation on a Windows 2000/XP/Server 2003 platform. For Windows CE targets use Debug Monitor in console mode.
****************************************************************************************
| TIP | |
| Choose carefully those sections that you would like to monitor. Checking more options than necessary could result in an overflow of information, making it harder for you to locate your problem. |
This option enables you to send to an external kernel debugger all the debug
information that is received from WinDriver's kernel module (which calls WD_DebugAdd() [A.5.6] in your code).
Now run your application, reproduce the problem, and view the debug information in the external kernel debugger's log.
Windows users can use Microsoft's WinDbg tool, for example, which is freely supplied with Microsoft's Driver Development Kit (DDK) and from Microsoft's web site (Microsoft Debugging Tools page).
This tool is available in all supported operating systems. To
use it, run:
WinDriver
util> wddebug
with the appropriate
switches.
For a list of switches that can be used with Debug Monitor in console mode,
type:
> wddebug
To see activity logged by the Debug Monitor, type:
> wddebug dump.
On Windows CE, Debug Monitor is only available in console mode. You first need to start a Windows CE command window (CMD.EXE) on the Windows CE target computer and then run the program WDDEBUG.EXE inside this shell.
In addition to the standard WinDriver API and the DriverWizard code generation capabilities described in this manual, which support development of drivers for any USB device, WinDriver offers enhanced support for specific chipsets. The enhanced support includes custom API and sample diagnostics code, which are designed specifically for these chipsets.
WinDriver's enhanced support is currently available for the following
chipsets: The Cypress EZ-USB family,
Microchip PIC18F4550, Texas Instruments TUSB3410, TUSB3210, TUSB2136,
TUSB5052, Silicon Laboratories C8051F320.
****************************************************************************************
| NOTE | |
| The WinDriver USB Device toolkit's enhanced support for development of USB device firmware for the Cypress EZ-USB FX2LP CY7C68013A, Silicon Laboratories C8051F320 and Microchip PIC18F4550 chipsets, is discussed separately in Chapter 12. |
When developing a driver for a device based on one of the enhanced-support chipsets [8.1], you can use WinDriver's chipset-set specific support by following these steps:
Most of the sample diagnostics program names are derived from
the sample's main purpose (e.g. download_sample
for a firmware download sample) and their source code can be found
directly under the specific chip_name/ directory.
The program's executable is found under a sub-directory for your
target operating system (e.g. WIN32
for Windows.)
The USB standard supports two kinds of data exchange between the host and the device:
The control transaction always begins with a setup stage. The setup stage is followed by zero or more control data transactions (data stage) that carry the specific information for the requested operation, and finally a status transaction completes the control transfer by returning the status to the host.
During the setup stage, an 8-byte setup packet is used to transmit information to the control endpoint of the device. The setup packet's format is defined by the USB specification.
A control transfer can be a read transaction or a write transaction. In a read transaction the setup packet indicates the characteristics and amount of data to be read from the device. In a write transaction the setup packet contains the command sent (written) to the device and the number of control data bytes that will be sent to the device in the data stage.
Refer to Figure 9.2 (taken from the USB
specification) for a sequence of read and write transactions.
`(in)' indicates data flow from the device to the host.
`(out)' indicates data flow from the host to the device.
The setup packets (combined with the control data stage and the status stage) are used to configure and send commands to the device. Chapter 9 of the USB specification defines standard device requests. USB requests such as these are sent from the host to the device, using setup packets. The USB device is required to respond properly to these requests. In addition, each vendor may define device-specific setup packets to perform device-specific operations. The standard setup packets (standard USB device requests) are detailed below. The vendor's device-specific setup packets are detailed in the vendor's data book for each USB device.
The table below shows the format of the USB setup packet. For more information, please refer to the USB specification at http://www.usb.org.
| Byte | Field | Description |
|---|---|---|
| 0 | bmRequest Type | Bit 7: Request direction (0=Host to device -
Out, 1=Device to host - In).
Bits 5-6: Request type (0=standard, 1=class, 2=vendor, 3=reserved). Bits 0-4: Recipient (0=device, 1=interface, 2=endpoint,3=other). |
| 1 | bRequest | The actual request (see the Standard Device Request Codes table [9.1.5]). |
| 2 | wValueL | A word-size value that varies according to the request. For example, in the CLEAR_FEATURE request the value is used to select the feature, in the GET_DESCRIPTOR request the value indicates the descriptor type and in the SET_ADDRESS request the value contains the device address. |
| 3 | wValueH | The upper byte of the Value word. |
| 4 | wIndexL | A word-size value that varies according to the request. The index is generally used to specify an endpoint or an interface. |
| 5 | wIndexH | The upper byte of the Index word. |
| 6 | wLengthL | A word-size value that indicates the number of bytes to be transferred if there is a data stage. |
| 7 | wLengthH | The upper byte of the Length word. |
The table below shows the standard device request codes.
| bRequest | Value |
|---|---|
| GET_STATUS | 0 |
| CLEAR_FEATURE | 1 |
| Reserved for future use | 2 |
| SET_FEATURE | 3 |
| Reserved for future use | 4 |
| SET_ADDRESS | 5 |
| GET_DESCRIPTOR | 6 |
| SET_DESCRIPTOR | 7 |
| GET_CONFIGURATION | 8 |
| SET_CONFIGURATION | 9 |
| GET_INTERFACE | 10 |
| SET_INTERFACE | 11 |
| SYNCH_FRAME | 12 |
This example of a standard USB device request illustrates the setup packet format and its fields. The setup packet is in Hex format.
The following setup packet is for a control read transaction that retrieves the device descriptor from the USB device. The device descriptor includes information such as USB standard revision, vendor ID and product ID.
| 80 | 06 | 00 | 01 | 00 | 00 | 12 | 00 |
Setup packet meaning:
| Byte | Field | Value | Description |
|---|---|---|---|
| 0 | BmRequest Type | 80 | 8h=1000b bit 7=1 -> direction of data is from device to host. 0h=0000b bits 0..1=00 -> the recipient is the device. |
| 1 | bRequest | 06 | The Request is GET_DESCRIPTOR. |
| 2 | wValueL | 00 | |
| 3 | wValueH | 01 | The descriptor type is device (values defined in USB spec). |
| 4 | wIndexL | 00 | The index is not relevant in this setup packet since there is only one device descriptor. |
| 5 | wIndexH | 00 | |
| 6 | wLengthL | 12 | Length of the data to be retrieved: 18(12h) bytes (this is the length of the device descriptor). |
| 7 | wLengthH | 00 |
In response, the device sends the device descriptor data. A device descriptor of Cypress EZ-USB Integrated Circuit is provided as an example:
| Byte No. | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Content | 12 | 01 | 00 | 01 | ff | ff | ff | 40 | 47 | 05 | 80 |
| Byte No. | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
|---|---|---|---|---|---|---|---|
| Content | 00 | 01 | 00 | 00 | 00 | 00 | 01 |
As defined in the USB specification, byte 0 indicates the length of the descriptor, bytes 2-3 contain the USB specification release number, byte 7 is the maximum packet size for endpoint 00, bytes 8-9 are the Vendor ID, bytes 10-11 are the Product ID, etc.
WinDriver allows you to easily send and receive control transfers on Pipe00, while using DriverWizard to test your device. You can either use the API generated by DriverWizard [5] for your hardware, or directly call the WinDriver WDU_Transfer() [A.3.7] function from within your application.
To perform a read or write transaction on the control pipe, you can either use the API generated by DriverWizard for your hardware, or directly call the WinDriver WDU_Transfer() [A.3.7] function from within your application.
Fill the setup packet in the BYTE SetupPacket[8] array and call these functions to send setup packets on Pipe00 and to retrieve control and status data from the device.
setupPacket[0] = 0x80; /* BmRequstType */
setupPacket[1] = 0x6; /* bRequest [0x6 == GET_DESCRIPTOR] */
setupPacket[2] = 0; /* wValue */
setupPacket[3] = 0x1; /* wValue [Descriptor Type: 0x1 == DEVICE] */
setupPacket[4] = 0; /* wIndex */
setupPacket[5] = 0; /* wIndex */
setupPacket[6] = 0x12; /* wLength [Size for the returned buffer] */
setupPacket[7] = 0; /* wLength */
WDU_TransferDefaultPipe(hDev, TRUE, 0, pBuffer, dwSize,
bytes_transferred, &setupPacket[0], 10000);
WDU_TransferDefaultPipe(hDev, FALSE, 0, NULL, 0,
bytes_transferred, &setupPacket[0], 10000);
For further information regarding WDU_TransferDefaultPipe(), refer to Section A.3.9. For further information regarding WDU_Transfer(), refer to Section A.3.7.
When adding a new driver, you may be required to reboot the system in order for it to load your new driver into the system. WinDriver is a dynamically loadable driver, which enables your customers to start your application immediately after installing it, without needing to reboot. You can dynamically load your driver whether you have created a user-mode or a kernel-mode driver.
****************************************************************************************
| NOTE | |
| In order to successfully UNLOAD your driver, make sure there are no open handles to the driver from WinDriver applications or from connected devices that were registered with WinDriver using an INF file. |
Windows drivers can be implemented as either of the following types:
The WinDriver USB Windows kernel module - windrvr6.sys - is a full WDM drivers, which can be installed using the wdreg utility, as explained in the following sections.
WinDriver provides a utility for dynamically loading and unloading your driver, which
replaces the slower manual process using Windows' Device Manager (which can still be
used for the device INF).
For Windows 2000/XP/Server 2003, this utility is provided in two forms:
wdreg and wdreg_gui. Both utilities can be
found under the
WinDriver
util directory, can be run from
the command line, and provide the same functionality. The difference is that
wdreg_gui displays installation messages graphically, while
wdreg displays them in console mode.
For Windows 98/Me the wdreg16 utility is provided.
This section describes the usage of wdreg/
wdreg_gui/wdreg16 on Windows operating systems.
****************************************************************************************
| NOTE | |
| The explanations and examples below refer to wdreg, but for
Windows 2000/XP/Server 2003 you can replace any references to
wdreg with wdreg_gui.
For Windows 98/Me, replace the references to wdreg with wdreg16. |
This section explains how to use the wdreg utility to install the WDM windrvr6.sys driver on Windows 98/Me/2000/XP/Server 2003, or to install INF files that register USB devices to work with this driver on Windows 2000/XP/Server 2003.
****************************************************************************************
| NOTE | |
| On Windows 98/Me you can only use wdreg16 to install the windrvr6.sys WDM driver, by installing windrvr6.inf but you cannot use wdreg16 to install any other INF files. |
Usage: The wdreg utility can be used in two ways as demonstrated here:
****************************************************************************************
| NOTE | |
| In order to successfully disable/uninstall WinDriver, you must first close any open handles to the windrvr6.sys service. This includes closing any open WinDriver applications and uninstalling (from the Device Manager or using wdreg) any USB devices that are registered to work with the windrvr6.sys service (or otherwise removing such devices). wdreg will display a relevant warning message if you attempt to stop the windrvr6.sys when there are still open handles to the service, and will enable you to select whether to close all open handles and Retry, or Cancel and reboot the PC to complete the command's operation. |
When using WinDriver, you develop a user-mode application that controls and
accesses your hardware by using the generic driver windrvr6.sys
(WinDriver's kernel module). Therefore, you might want to dynamically load
and unload the driver windrvr6.sys - which you can do using
wdreg.
In addition, in WDM-compatible operating systems, you also need to dynamically
load INF files for your Plug and Play devices. wdreg enables
you to do so automatically on Windows 2000, XP and Server 2003.
This section includes example implementations that are based on the detailed
description of wdreg contained in the previous section.
Example implementations:
To unload the driver/INF file, use the same commands, but simply replace install in the samples above with uninstall.
Read this chapter in the final stages of driver development. It will guide you in preparing your driver for distribution.
****************************************************************************************
| NOTE | |
| For Windows 2000/XP/Server 2003, all references to wdreg in this
chapter can be replaced with wdreg_gui, which offers the same
functionality but displays GUI messages instead of console-mode
messages.
For Windows 98/Me, all references to wdreg should be replaced with wdreg16. For more information regarding the wdreg utility, see Chapter 10. |
To purchase a WinDriver license, complete the order form, found under
WinDriver
docs
order.txt,
and fax or email it to Jungo. Complete details are included on the order form.
Alternatively, you can order WinDriver on-line. Visit http://www.jungo.com for more details.
In order to install the registered version of WinDriver and to activate driver code that you have developed during the evaluation period on the development machine, please follow the installation instructions found in Section 4.2 above.
Distributing the driver you created is a multi-step process. First, create a distribution package that includes all the files required for the installation of the driver on the target computer. Second, install the driver on the target machine. This involves installing windrvr6.sys and windrvr6.inf, and installing the specific INF file for your device. Finally, you need to install and execute the hardware control application that you developed with WinDriver. These steps can be performed using wdreg utility.
Your distribution package should include the following files:
****************************************************************************************
| NOTE | |
| The user must have administrative privileges on the target computer in order to install your driver. |
Follow the instructions below in the order specified to properly install your driver on the target computer:
On Windows 2000/XP/Server 2003 type from the command line:
> wdreg -inf <path to windrvr6.inf>
install
On Windows 98/Me type from the command line:
> wdreg16 -inf <path to windrvr6.inf>
install
For example, if windrvr6.inf and
windrvr6.sys are in the d:
MyDevice
directory on the target computer, the command should
be:
> wdreg -inf d:
MyDevice
windrvr6.inf install
You can find the executable of wdreg in the
WinDriver package under the
WinDriver
util
directory. For a general description of this utility and its
usage, please refer to Chapter 10.
****************************************************************************************
| NOTE | |
| wdreg is an interactive utility. If it fails, it will display a message instructing the user how to overcome the problem. In some cases the user may be asked to reboot the computer. |
****************************************************************************************
| CAUTION! | |
| When distributing your driver, take care not to overwrite a newer
version of windrvr6.sys with an older version of
the file in Windows drivers directory (%windir% |
To automatically install your INF file on Windows
2000/XP/Server 2003 and update Windows Device Manager, run
wdreg with the install command:
> wdreg -inf <path to your INF file>
install
****************************************************************************************
| NOTE | |
| On Windows 2000, if another INF file was previously
installed for the device, which registered the device to work with
the Plug-and-Play driver used in earlier versions of WinDriver
remove any INF file(s) for the device from the
%windir% |
Device information (INF) files are text files that provide information used by the Plug and Play mechanism in Windows 98/Me/2000/XP/Server 2003 to install software that supports a given hardware device. INF files are required for hardware that identifies itself, such as USB and PCI. An INF file includes all necessary information about a device and the files to be installed. When hardware manufacturers introduce new products, they must create INF files to explicitly define the resources and files required for each class of device.
In some cases, the INF file for your specific device is supplied by the operating system. In other cases, you will need to create an INF file for your device. WinDriver's DriverWizard can generate a specific INF file for your device. The INF file is used to notify the operating system that WinDriver now handles the selected device.
For USB devices, you will not be able to access the device with WinDriver (either from the DriverWizard or from the code) without first registering the device to work with windrvr6.sys. This is done by installing an INF file for the device. The DriverWizard will offer to automatically generate the INF file for your device.
You can use the DriverWizard to generate the INF file on the development machine - as explained in Section 5.2 of the manual - and then install the INF file on any machine to which you distribute the driver, as explained in the following sections.
****************************************************************************************
| NOTE | |
| You must have administrative privileges in order to install an INF file on Windows 98, Me, 2000, XP and Server 2003. |
On Windows 2000/XP/Server 2003 you can use the wdreg utility
with the install command to automatically install the INF file:
> wdreg -inf <path to the INF file> install
See Section 10.2.2 of the manual for more information.
On the development PC, you can have the INF file automatically installed when selecting to generate the INF file with the DriverWizard, by checking the Automatically Install the INF file option in the DriverWizard's INF generation window (see Section 5.2).
It is also possible to install the INF file manually on Windows 2000/XP/Server 2003, using
either of the following methods:
On Windows 98/Me you need to install the INF file for your
USB device manually, either via Windows
Add New Hardware Wizard or Upgrade Device Driver Wizard,
as explained below:
****************************************************************************************
| NOTE | |
| This method can be used if no other driver is currently installed for the device or if the user first uninstalls (removes) the current driver for the device. Otherwise, Windows New Hardware Found Wizard, which activates the Add New Hardware Wizard, will not appear for this device. |
****************************************************************************************
| NOTE | |
| You must have administrative privileges in order to replace a driver on Windows 98, Me, 2000, XP and Server 2003. |
You can use the wdreg utility with the
install command to automatically install the INF file on Windows
2000/XP/Server 2003:
> wdreg -inf <path to INF file> install
See Section 10.2.2 of the manual for more information.
On the development PC, you can have the INF file automatically installed when selecting to generate the INF file with the DriverWizard, by checking the Automatically Install the INF file option in the DriverWizard's INF generation window (see Section 5.2).
It is also possible to install the INF file manually on Windows 2000/XP/Server 2003, using
either of the following methods:
We recommend using the wdreg utility to install the INF file automatically, instead of installing it manually.
****************************************************************************************
| NOTE | |
| This method can be used if no other driver is currently installed for the device or if the user first uninstalls (removes) the current driver for the device. Otherwise, the Windows Found New Hardware Wizard, which activates the Add New Hardware Wizard, will not appear for this device. |
To distribute the driver you developed with WinDriver to a target Windows CE platform, follow these steps:
If your hardware control application/DLL uses
wd_utils.dll (as is the case for the sample and
generated DriverWizard WinDriver projects), also copy
wd_utils.dll from the WinDriver
redist directory on the development PC to the target's
Windows
directory.
The Linux kernel is continuously under development and kernel data structures are subject to frequent changes. To support such a dynamic development environment and still have kernel stability, the Linux kernel developers decided that kernel modules must be compiled with header files identical to those with which the kernel itself was compiled. They enforce this by including a version number in the kernel header files that is checked against the version number encoded into the kernel. This forces Linux driver developers to facilitate recompilation of their driver based on the target system's kernel version.
Since windrvr6.o/.ko is a kernel module, it must be recompiled for every kernel version on which it is loaded. To facilitate this, we supply the following components to insulate the WinDriver kernel module from the Linux kernel:
You need to distribute these components along with your driver source code or object code.
Copy the hardware control application/shared objects that you created with WinDriver to the target.
If your hardware control application/shared objects use the libwd_utils.so shared object (as is the case for the sample and generated DriverWizard WinDriver projects), copy libwd_utils.so from the WinDriver/lib directory on the development PC to the target's library directory (/usr/lib/ - for 32-bit PowerPC or 32-bit x86 targets; /user/lib64 - for 64-bit x86 targets).
Since the user-mode hardware control application/shared objects do not have to be matched against the kernel version number, you are free to distribute it as binary code (if you wish to protect your source code from unauthorized copying) or as source code.
****************************************************************************************
| CAUTION! | |
| If you select to distribute your source code, make sure you do not distribute your WinDriver license string, which is used in the code. |
We suggest that you supply an installation shell script that copies your driver executables/DLL to the correct locations (perhaps /usr/local/bin) and then invokes make or gmake to build and install the WinDriver kernel module.
This chapter describes the WinDriver USB Device tool-kit for development of USB device firmware for devices based on the Cypress EZ-USB FX2LP CY7C68013A, Silicon Laboratories C8051F320 and Microchip PIC18F4550 development boards.
****************************************************************************************
| NOTE | |
| The WinDriver USB Device tool-kit is currently only supported on Windows - see section 12.2 for details regarding the supported operating systems. |
The WinDriver USB Device tool-kit simplifies and facilitates the development of firmware for USB devices based on the Cypress EZ-USB FX2LP CY7C68013A, Silicon Laboratories C8051F320 and Microchip PIC18F4550 development boards. These development boards will henceforth be referred to in this chapter as ''the target boards''.
This tool-kit complements the WinDriver USB driver development tool-kit. Together these tool-kits provide a complete USB device development software solution - both for the device firmware and the host driver development stages.
USB device manufacturers need to support the Universal Serial Bus (USB) specification (see Chapter 3 for an overview of USB). The USB interface is implemented in two levels: The lower level of the USB protocol is implemented via a Serial Interface Engine (SIE). The higher layer of the protocol is implemented via the device firmware.
Firmware consists of software programs and data that define the device's configuration and are installed semi-permanently into memory using various types of programmable ROM chips, such as PROMS, EPROMs, EEPROMs, and flash chips.
WinDriver USB Device enables developers of devices based on the target boards to easily create firmware that defines the desired USB interface for their target device, using a Graphical User Interface (GUI).
WinDriver USB Device includes firmware libraries for the target boards [12.3.4]. These libraries contain functions for performing common USB firmware functionality, thus releasing device manufacturers of the time-consuming effort of writing this firmware code themselves.
WinDriver USB Device features the graphical DriverWizard utility from the WinDriver USB driver development tool-kit, but with different functionality, which enables you to define your device's USB interface [12.4.1] - i.e. the device IDs and device class, the number of interfaces, alternate settings and endpoints and their attributes, etc. - using friendly GUI dialogs, and then proceed to generate firmware code for the device, based on the information defined in the wizard's dialogs [12.4.2]. The generated DriverWizard firmware code includes convenient APIs, which utilize the WinDriver USB Device firmware library API to implement a fully functional device firmware.
Appendices B, C and D provide a detailed description of the WinDriver USB Device firmware libraries and generated DriverWizard API.
****************************************************************************************
| NOTE | |
| The provided APIs and the wizard options for your target board are based on Chapter 9 of the USB 2.0 Specification and on the target board's specification, thus freeing you of the need to study these specifications yourself. |
After generating the firmware code, you can proceed to modify it, as needed, in order to implement your desired firmware, using the WinDriver USB Device API to simplify the development process [12.4.3]. When the firmware implementation is completed, you can simply build the firmware [12.4.3.2] and download it to the device [12.4.3.3].
The hardware diagnostics feature of the WinDriver USB driver development DriverWizard, as outlined in Chapter 5, is also available in the WinDriver USB Device DriverWizard. Therefore, once you develop the firmware and download it to the device, you can use DriverWizard to debug the hardware by viewing the device's configuration and testing the communication with the device from the wizard's graphical interface [12.4.4].
If you are also a registered user of the WinDriver USB driver development tool-kit, when the device firmware development and the hardware debugging is completed, you can use the WinDriver USB tool-kit to develop a driver for your device [12.4.5].
This section describes the directory structure and files of the
WinDriver
wdf directory.
The wdf
directory contains the following sub-directories:
The WinDriver
wdf
cypress
directory contains the
following directories:
The FX2LP
directory contains the following sub-directories and
files:
The WinDriver
wdf
microchip
directory contains the
following directories:
The 18F4550
directory contains the following sub-directories and
files:
The WinDriver
wdf
silabs
directory contains the
following directories:
The F320
directory contains the following sub-directories and
files:
When generating firmware code with DriverWizard using the registered version of the WinDriver USB Device tool-kit, the generated code includes WinDriver USB Device firmware library source files, which contain API for performing common USB firmware functionality (see the description of the generated files in section 12.4.3.1.) These source files are not part of the evaluation version of the tool-kit. In order to enable an evaluation of WinDriver USB Device, this tool-kit includes pre-compiled evaluation libraries, which are utilized by the device firmware samples and the generated DriverWizard evaluation firmware code.
The evaluation libraries provide the same functionality as the registered library files, subject to the following single limitation: they only enable you to perform a pre-set number of transfers (25,000). When this amount is exceeded the library will cease to work.
To build the samples from the WinDriver
wdf
cypressFX2LP
samples
,
WinDriver
wdf
microchip18F4550
samples
or
WinDriver
wdf
silabsF320
samples
directory, use the
build.bat utility for the selected sample (e.g.
WinDriver
wdf
cypressFX2LP
samples
loopback
build.bat):
set KEIL=C:\Keil
For example, if you installed Keil under D:
set KEIL=D:\MyTools\Keil
set CYPRESS=C:\Cypress
For example, if you installed the Cypress EZ-USB development kit under
D:
set CYPRESS=D:\Cypress
set MCC=C:\mcc18
For example, if you installed the mcc18 compiler under
D:
set CYPRESS=D:\microchip\mcc18
Use WinDriver USB Device to develop firmware for your USB device (based on any of the target boards) by following the steps below:
Use the WinDriver USB Device DriverWizard utility to define your device's USB interface:
The dialog enables you to add device interfaces, add alternate settings for each interface, and add the required endpoints for each alternate setting.
When adding components, the wizard allows you define the relevant attributes for each component (such as the interface's class and sub-class or the endpoint's address, transfer type, maximum packet size, etc.). The wizard further assists you by only providing the relevant configuration options for your device and by warning you if there is a potential error in your configuration definitions.
More information on how to configure the endpoints on the Cypress EZ-USB FX2LP CY7C68013A development board can be found at the end of this section [12.4.1.1].
****************************************************************************************
| NOTE | |
| Definition of multiple interfaces is not currently supported for the
Silicon Laboratories C8051F320 development board.
For the other target boards, if you select to define more than one interface, DriverWizard will generate firmware code for a composite device. The wizard will warn you about this when you select to add a second interface. |
You can also delete any component that you have added or edit the configuration information, at any time, from the device configuration dialog.
When you have finished defining the device's USB interface, proceed to generate device firmware code, based on your DriverWizard definitions, as outlined in the following section [12.4.2].
This section contains a quote from section 1.18 of the EZ-USB Technical
Reference Manual (EZ-USB_TRM.pdf) regarding EZ-USB endpoint
buffers configuration. This information can be useful when using DriverWizard
to define the endpoint configuration for devices based on the
Cypress EZ-USB FX2LP CY7C68013A development board.
For more information, refer to the EZ-USB Technical Manual, which is available
under the Cypress
USB
Doc
FX2LP
directory or
on-line at: http://www.keil.com/dd/docs/datashts/cypress/fx2_trm.pdf.
The USB Specification defines an endpoint as a source or sink of data. Since USB is a serial bus, a device endpoint is actually a FIFO which sequentially empties or fills with USB data bytes. The host selects a device endpoint by sending a 4-bit address and a direction bit. Therefore, USB can uniquely address 32 endpoints, IN0 through IN15 and OUT0 through OUT15.
From the EZ-USB's point of view, an endpoint is a buffer full of bytes received or held for transmission over the bus. The EZ-USB reads host data from an OUT endpoint buffer, and writes data for transmission to the host to an IN endpoint buffer.
EZ-USB contains three 64-byte endpoint buffers, plus 4 KB of buffer space that can be configured 12 ways, as indicated in Figure 1-16. The three 64-byte buffers are common to all configurations.
Generate device firmware code from the Configure Your Device
dialog, using either of the following methods:
The wizard's Select Code Generation Options dialog will be
displayed:
Verify that all directory paths in the device firmware code generation dialog
point to the correct locations on your PC:
You can select to generate a specific project file for any of the supported development environments for your board [12.2] by checking the relevant check-box in the Select Code Generation Options dialog.
When selecting to generate a project file for the Keil uVision IDE or Silicon Laboratories IDE, the wizard will automatically change the IDE to Invoke to your selected IDE. If you do not change the IDE to invoke, the wizard will attempt to invoke this IDE after generating the code.
The Generate host side driver code option, shown in the dialog screen shots above, is available during the evaluation of the tool-kit and for registered users of the WinDriver USB driver development tool-kit. When this option is selected, in addition to the device firmware code the wizard will also generate a skeletal WinDriver USB device driver application for your USB device (as defined in the wizard). - see Chapter 5 and section 12.4.5 for details regarding the DriverWizard device driver code generation.
After you have generated the firmware code with the wizard, you are free to modify it, as needed, in order to implement your desired firmware functionality, using the library and generated WinDriver USB Device firmware API to facilitate your development efforts.
The API of the USB firmware libraries and generated code is described in detail in Appendices B, C and D.
****************************************************************************************
| NOTE | |
When modifying the WinDriver library and generated device firmware code, make
sure that your code complies with your development board's hardware
specification:
|
When generating device firmware code, DriverWizard creates an xxx_FW directory, which contains the following files:
The periph.h header file, which declares the prototypes
of the functions implemented in the periph.c source
file, is found in the WinDriver
<device_dir>
include
directory, e.g.
WinDriver
wdf
cypressFX2LP
include
- see
section 12.3.
The following files contain the source code of the WinDriver USB Device firmware library. These files are generated only when using the registered version of the WinDriver USB Device tool-kit:
To build the generated firmware code for your device, use any of the following
alternative methods:
The build output is an xxx.hex firmware file (where xxx is the name you selected for your firmware project.)
****************************************************************************************
| NOTE | |
| The generated build.bat and specific-IDE project files are
different for the registered and for the evaluation version of WinDriver USB Device
and produce a different output.
The evaluation version of these files uses the evaluation firmware libraries and the output firmware will be limited to a maximum of 25,000transfers (see above [12.3.4].) The registered version uses the generated library source files and is not subject to the evaluation limitations. After registering your WinDriver USB Device tool-kit, open the DriverWizard device firmware project file that you created during the evaluation period (xxx.wdp) and re-generate the firmware code with the wizard in order to create new registered versions of the build.bat and project files. Then use these files to build a registered, full-featured, firmware (xxx.hex), and download the firmware to the device. |
After building the firmware, download it to the hardware using the board vendor's firmware download tools.
NOTE: For the Cypress EZ-USB FX2LP CY7C68013A and Microchip PIC18F4550
boards, if you also have a valid license for the WinDriver USB driver development tool-kit, or if
you are using the evaluation version of the WinDriver USB Device tool-kit (which also
includes an evaluation of the WinDriver USB driver development kit), you can download firmware to
your device using the kit's sample firmware download application (Cypress: see
download_sample.exe in the
WinDriver
cypress
firmware_sample
WIN32
directory; Microchip: see bootloader_demo.exe in the
WinDriver
microchip
pic18f4550
bootloader_sample
WIN32
directory).
Once you have downloaded the firmware to the device, you can use the DriverWizard utility to debug the firmware, as outlined in section 5.2 (refer to the USB explanations in this Chapter.) NOTE: The device driver code generation option described in section 5.2 is not part of the WinDriver USB Device license.
When the device development is completed, if you have also purchased a license
for the WinDriver USB driver development tool-kit, or if you are using the evaluation version of
WinDriver, you can proceed to use WinDriver to develop a driver for your
device, as explained in Chapter 6.
As indicated in section 12.4.2 above, if you have a
compatible license you will also be given the option to generate a skeletal
WinDriver USB device driver application from DriverWizard's firmware
generation dialog.
This section provides a general overview of WinDriver's USB Library (WDU), including:
The WDU library's interface is found in the /WinDriver/include/wdu_lib.h and /WinDriver/include/windrvr.h header files, which should be included from any source file that calls the WDU API. (wdu_lib.h already includes windrvr.h).
The WinDriver WDU_xxx USB API is designed to support event-driven transfers between your user-mode USB application and USB devices. This is in contrast to earlier versions, in which USB devices were initialized and controlled using a specific sequence of function calls.
You can implement the three user callback functions specified in the next section: WDU_ATTACH_CALLBACK [A.2.1], WDU_DETACH_CALLBACK [A.2.2] and WDU_POWER_CHANGE_CALLBACK [A.2.3] (at the very least WDU_ATTACH_CALLBACK). These functions are used to notify your application when a relevant system event occurs, such as the attaching or detaching of a USB device. For best performance, minimal processing should be done in these functions.
Your application calls WDU_Init() [A.3.1] and provides the criteria according to which the system identifies a device as relevant or irrelevant. The WDU_Init() function must also pass pointers to the user callback functions.
Your application then simply waits to receive a notification of an event. Upon receipt of such a notification, processing continues. Your application may make use of any functions defined in the high- or low-level APIs below. The high-level functions, provided for your convenience, make use of the low-level functions, which in turn use IOCTLs to enable communication between the WinDriver kernel module and your user-mode application.
When exiting, your application calls WDU_Uninit() [A.3.6] to stop listening to devices matching the given criteria and to un-register the notification callbacks for these devices.
The following figure depicts the calling sequence described above. Each vertical line represents a function or process. Each horizontal arrow represents a signal or request, drawn from the initiator to the recipient. Time progresses from top to bottom.
The following piece of meta-code can serve as a framework for your user-mode application's code:
attach()
{
...
if this is my device
/*
Set the desired alternate setting ;
Signal main() about the attachment of this device
*/
return TRUE;
else
return FALSE;
}
detach()
{
...
signal main() about the detachment of this device
...
}
main()
{
WDU_Init(...);
...
while (...)
{
/* wait for new devices */
...
/* issue transfers */
...
}
...
WDU_Uninit();
}
The WinDriver WDU_xxx USB API, provided beginning with version 6.00, is designed to support event-driven transfers between your user-mode USB application and USB devices. This is in contrast to earlier versions, in which USB devices were initialized and controlled using a specific sequence of function calls.
As a result of this change, you will need to modify your USB applications that were designed to interface with earlier versions of WinDriver to ensure that they will work with WinDriver v6.X on all supported platforms and not only on Microsoft Windows. You will have to reorganize your application's code so that it conforms with the framework illustrated by the piece of meta-code provided in Section A.1.1.
In addition, the functions that collectively define the USB API have been changed. The new functions, described in the next few sections, provide an improved interface between user-mode USB applications and the WinDriver kernel module. Note that the new functions receive their parameters directly, unlike the old functions, which received their parameters using a structure.
The table below lists the legacy functions in the left column and indicates in the right column which function or functions replace(s) each of the legacy functions. Use this table to quickly determine which new functions to use in your new code.
| Problem | Solution |
|---|---|
| High Level API | |
| This function... | has been replaced by... |
| WD_Open()
WD_Version() WD_UsbScanDevice() |
WDU_Init() [A.3.1] |
| WD_UsbDeviceRegister() | WDU_SetInterface() [A.3.2] |
| WD_UsbGetConfiguration() | WDU_GetDeviceInfo() [A.3.4] |
| WD_UsbDeviceUnregister() | WDU_Uninit() [A.3.6] |
| Low Level API | |
| This function... | has been replaced by... |
| WD_UsbTransfer() | WDU_Transfer() [A.3.7]
WDU_TransferDefaultPipe() [A.3.9] WDU_TransferBulk() [A.3.10] WDU_TransferIsoch() [A.3.11] WDU_TransferInterrupt() [A.3.12] |
| USB_TRANSFER_HALT option | WDU_HaltTransfer() [A.3.13] |
| WD_UsbResetPipe() | WDU_ResetPipe() [A.3.14] |
| WD_UsbResetDevice()
WD_UsbResetDeviceEx() |
WDU_ResetDevice() [A.3.15] |
****************************************************************************************
| NOTE | |
| Some of the functions described below take as parameters structures that are comprised of several elements. These structures, indicated by (), are described in Section A.4. |
PURPOSE
WinDriver calls this function when a new device, matching the given
criteria, is attached, provided it is not yet controlled by another driver.
This callback is called once for each matching interface.
PROTOTYPE
typedef BOOL (DLLCALLCONV *WDU_ATTACH_CALLBACK)(WDU_DEVICE_HANDLE hDevice,
WDU_DEVICE *pDeviceInfo, PVOID pUserData);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| WDU_DEVICE * [A.4.3] | Input () | |
| PVOID | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface | |
| Pointer to device configuration details; Valid until the end of the function. | |
| Pointer that was passed to WDU_Init() [A.3.1] (in the event table); Points to the user-mode data for the attach function. |
RETURN VALUE
If the WD_ACKNOWLEDGE flag was set in the call to WDU_Init()
[A.3.1] (within the dwOptions parameter), the callback function
should check if it wants to control the device, and if so - return TRUE
(otherwise - return FALSE).
If the WD_ACKNOWLEDGE flag was not set in the call to
WDU_Init(), then the return value of the callback function is
insignificant.
PURPOSE
WinDriver calls this function when a controlled device has been
detached from the system.
PROTOTYPE
typedef void (DLLCALLCONV *WDU_DETACH_CALLBACK)(WDU_DEVICE_HANDLE hDevice,
PVOID pUserData);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| PVOID | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface | |
| Pointer that was passed to WDU_Init() [A.3.1] (in the event table); Points to the user-mode data for the attach function |
RETURN VALUE
None
PURPOSE
WinDriver calls this function when a controlled device has changed
its power settings.
PROTOTYPE
typedef BOOL (DLLCALLCONV *WDU_POWER_CHANGE_CALLBACK)(WDU_DEVICE_HANDLE hDevice,
DWORD dwPowerState, PVOID pUserData);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| DWORD | Input | |
| PVOID | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface | |
| Number of the power state selected | |
| Pointer that was passed to WDU_Init() [A.3.1] (in the event table); Points to the user-mode data for the attach function. |
RETURN VALUE
TRUE/FALSE. Currently there is no significance to the return value.
REMARKS
This callback is supported only in Windows operating systems, starting from Windows 2000.
****************************************************************************************
| NOTE | |
| Some of the functions described below take as parameters structures that are comprised of many elements. These structures, indicated by (), are described in Section A.4. |
PURPOSE
Starts listening to devices matching input criteria and registers
notification callbacks for these devices.
PROTOTYPE
DWORD WDU_Init(WDU_DRIVER_HANDLE *phDriver,
WDU_MATCH_TABLE *pMatchTables, DWORD dwNumMatchTables,
WDU_EVENT_TABLE *pEventTable, const char *sLicense, DWORD dwOptions);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DRIVER_HANDLE * | Output | |
| WDU_MATCH_TABLE * [A.4.1] | Input () | |
| DWORD | Input | |
| WDU_EVENT_TABLE * [A.4.2] | Input () | |
| const char * | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Handle to the registration of events & criteria | |
| Array of match tables defining the devices' criteria | |
| Number of elements in pMatchTables | |
| Addresses of notification callback functions for changes in the device's status + relevant data for the callbacks | |
| WinDriver's license string | |
| Can be zero (0) or:
WD_ACKNOWLEDGE - the user can seize control over the device when returning value in WDU_ATTACH_CALLBACK [A.2.1] |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Sets the alternate setting for the specified interface.
PROTOTYPE
DWORD WDU_SetInterface(WDU_DEVICE_HANDLE hDevice, DWORD dwInterfaceNum,
DWORD dwAlternateSetting);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| DWORD | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface | |
| The interface's number | |
| The desired alternate setting value |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Gets USB address that the device uses. The address number is
written to the caller supplied pAddress.
PROTOTYPE
DWORD WDU_GetDeviceAddr(WDU_DEVICE_HANDLE hDevice, ULONG *pAddress);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| ULONG | Output |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for a device/interface | |
| A pointer to ULONG, in which the result is returned |
REMARKS
This function is supported on Windows only.
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Gets configuration information from a device, including all the
descriptors in a WDU_DEVICE [A.4.3] structure.
The caller should free *ppDeviceInfo after use by calling
WDU_PutDeviceInfo() [A.3.5].
PROTOTYPE
DWORD WDU_GetDeviceInfo(WDU_DEVICE_HANDLE hDevice,
WDU_DEVICE **ppDeviceInfo);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| WDU_DEVICE ** [A.4.3] | Output () |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for a device/interface | |
| Pointer to pointer to a buffer containing device information |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Receives a device information pointer, allocated with a previous
WDU_GetDeviceInfo() [A.3.4] call, in order to
perform the necessary cleanup.
PROTOTYPE
DWORD WDU_PutDeviceInfo(WDU_DEVICE *pDeviceInfo);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE * [A.4.3] | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to a buffer containing the device information, as returned by a previous call to WDU_GetDeviceInfo() |
RETURN VALUE
None
PURPOSE
Stops listening to devices matching a given criteria and
unregisters the notification callbacks for these devices.
PROTOTYPE
void WDU_Uninit(WDU_DRIVER_HANDLE hDriver);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DRIVER_HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Handle to the registration received from WDU_Init() [A.3.1] |
PURPOSE
Transfers data to or from a device.
PROTOTYPE
DWORD WDU_Transfer(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum,
DWORD fRead, DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize,
PDWORD pdwBytesTransferred, PBYTE pSetupPacket, DWORD dwTimeout);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| DWORD | Input | |
| DWORD | Input | |
| DWORD | Input | |
| PVOID | Input | |
| DWORD | Input | |
| PDWORD | Output | |
| PBYTE | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface received from WDU_Init() [A.3.1] | |
| The number of the pipe through which the data is transferred | |
| TRUE for read, FALSE for write | |
| A bit mask flag: |
|
| Address of the data buffer. | |
| Number of bytes to transfer. The buffer size is not limited to the device's maximum packet size; therefore, you can use larger buffers by setting the buffer size to a multiple of the maximum packet size. Use large buffers to reduce the number of context switches and thereby improve performance. | |
| Number of bytes actually transferred. | |
| An 8-byte packet to transfer to control pipes. | |
| Timeout interval of the transfer, in milliseconds (ms). If dwTimeout is zero, the function's timeout interval never elapses (infinite wait). |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
The resolution of the timeout (the dwTimeout parameter) is according to the operating system scheduler's timeslot. For example, in Windows the timeout's resolution is 10 milliseconds (ms).
PURPOSE
Enables/Disables the wakeup feature.
PROTOTYPE
DWORD WDU_Wakeup(WDU_DEVICE_HANDLE hDevice, DWORD dwOptions);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface. | |
| Can be either WDU_WAKEUP_ENABLE - enables wakeup, or WDU_WAKEUP_DISABLE - disables wakeup. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Transfers data to or from a device through the default pipe.
PROTOTYPE
DWORD WDU_TransferDefaultPipe(WDU_DEVICE_HANDLE hDevice,
DWORD fRead, DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize,
PDWORD pdwBytesTransferred, PBYTE pSetupPacket, DWORD dwTimeout);
PARAMETERS
See description of WDU_Transfer() [A.3.7].
Note that dwPipeNum is not a parameter of this function.
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
See description of WDU_Transfer() [A.3.7] .
PURPOSE
Performs bulk data transfer to or from a device.
PROTOTYPE
DWORD WDU_TransferBulk(WDU_DEVICE_HANDLE hDevice,
DWORD dwPipeNum, DWORD fRead, DWORD dwOptions, PVOID pBuffer,
DWORD dwBufferSize, PDWORD pdwBytesTransferred, DWORD dwTimeout);
PARAMETERS
See description of WDU_Transfer() [A.3.7].
Note that pSetupPacket is not a parameter of this function.
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
See description of WDU_Transfer() [A.3.7].
PURPOSE
Performs isochronous data transfer to or from a device.
PROTOTYPE
DWORD WDU_TransferIsoch(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum,
DWORD fRead, DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize,
PDWORD pdwBytesTransferred, DWORD dwTimeout);
PARAMETERS
PARAMETERS
See description of WDU_Transfer() [A.3.7].
Note that pSetupPacket is not a parameter of this function.
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
See description of WDU_Transfer() [A.3.7].
PURPOSE
Performs interrupt data transfer to or from a device.
PROTOTYPE
DWORD WDU_TransferInterrupt(WDU_DEVICE_HANDLE hDevice,
DWORD dwPipeNum, DWORD fRead, DWORD dwOptions, PVOID pBuffer,
DWORD dwBufferSize, PDWORD pdwBytesTransferred, DWORD dwTimeout);
PARAMETERS
See description of WDU_Transfer() [A.3.7].
Note that pSetupPacket is not a parameter of this function.
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
See description of WDU_Transfer() [A.3.7].
PURPOSE
Halts the transfer on the specified pipe (only one simultaneous
transfer per pipe is allowed by WinDriver).
PROTOTYPE
DWORD WDU_HaltTransfer(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface | |
| The number of the pipe |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Resets a pipe by clearing both the halt condition on the host side
of the pipe and the stall condition on the endpoint. This function is
applicable for all pipes except pipe00.
PROTOTYPE
DWORD WDU_ResetPipe(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface | |
| The pipe's number |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
This function should be used if a pipe is halted, in order to clear the halt.
PURPOSE
Resets a device to help recover from an error, when a device is
marked as connected but is not enabled.
PROTOTYPE
DWORD WDU_ResetDevice(WDU_DEVICE_HANDLE hDevice, DWORD dwOptions);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface. | |
| Can be either 0 or WD_USB_HARD_RESET - will reset the device even if it is not disabled. After using this option it is advised to set the interface of the device, using WDU_SetInterface() [A.3.2]. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
PURPOSE
Reads a list of supported language IDs and/or the number of
supported language IDs from a device.
PROTOTYPE
DWORD DLLCALLCONV WDU_GetLangIDs(WDU_DEVICE_HANDLE hDevice,
PBYTE pbNumSupportedLangIDs, WDU_LANGID *pLangIDs, BYTE bNumLangIDs);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| PBYTE | Output | |
| WDU_LANGID * | Output | |
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface. | |
| Parameter to receive number of supported language IDs. | |
| Array of language IDs. If bNumLangIDs is not 0 the function will fill this array with the supported language IDs for the device. | |
| Number of IDs in the pLangIDs array. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
PURPOSE
Reads a string descriptor from a device by string index.
PROTOTYPE
DWORD DLLCALLCONV WDU_GetStringDesc(WDU_DEVICE_HANDLE hDevice,
BYTE bStrIndex, PCHAR pcDescStr, DWORD dwSize, WDU_LANGID langID);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| WDU_DEVICE_HANDLE | Input | |
| BYTE | Input | |
| PBYTE | Output | |
| DWORD | Input | |
| WDU_LANGID | Input | |
| PDWORD | Output |
DESCRIPTION
| Name | Description |
|---|---|
| A unique identifier for the device/interface | |
| A string index | |
| The read string descriptor (the descriptor is returned as a bytes array) | |
| The size of pbBuf | |
| The language ID to be used in the get string descriptor request that is sent to the device. If the langID param is 0, the function will use the first supported language ID returned from the device (if exists). | |
| If not NULL, will be updated with the size of the returned descriptor |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
The following figure depicts the structure hierarchy used by WinDriver's USB API. The arrays situated in each level of the hierarchy may contain more elements than are depicted in the diagram. Arrows are used to represent pointers. In the interest of clarity, only one structure at each level of the hierarchy is depicted in full detail (with all of its elements listed and pointers from it pictured).
****************************************************************************************
| NOTE | |
| (*) For all field members, if value is set to 0 - match all. |
| Name | Type | Description |
|---|---|---|
| wVendorId | WORD | Required USB Vendor ID to detect, as assigned by USB-IF (*) |
| wProductId | WORD | Required USB Product ID to detect, as assigned by the product manufacturer (*) |
| bDeviceClass | BYTE | The device's class code, as assigned by USB-IF (*) |
| bDeviceSubClass | BYTE | The device's sub-class code, as assigned by USB-IF (*) |
| bInterfaceClass | BYTE | The interface's class code, as assigned by USB-IF (*) |
| bInterfaceSubClass | BYTE | The interface's sub-class code, as assigned by USB-IF (*) |
| bInterfaceProtocol | BYTE | The interface's protocol code, as assigned by USB-IF (*) |
| Name | Type | Description |
|---|---|---|
| pfDeviceAttach | WDU_ATTACH_CALLBACK | Will be called by WinDriver when a device is attached |
| pfDeviceDetach | WDU_DETACH_CALLBACK | Will be called by WinDriver when a device is detached |
| pfPowerChange | WDU_POWER_CHANGE_CALLBACK | Will be called by WinDriver when there is a change in a device's power state |
| pUserData | PVOID | Pointer to user-mode data to be passed to the callbacks |
| Name | Type | Description |
|---|---|---|
| Descriptor | WDU_DEVICE_DESCRIPTOR | Contains basic information about a device |
| Pipe0 | WDU_PIPE_INFO | Stores information about the device's default pipe |
| pConfigs | WDU_CONFIGURATION * | Pointer to buffer containing information about a device's configurations |
| pActiveConfig | WDU_CONFIGURATION * | Pointer to buffer containing information about the active configuration |
| pActiveInterface | WDU_INTERFACE * | Pointer to buffer containing information about the active interface |
| Name | Type | Description |
|---|---|---|
| Descriptor | WDU_CONFIGURATION_DESCRIPTOR | Contains basic information about a configuration |
| dwNumInterfaces | DWORD | Number of interfaces supported by this configuration |
| pInterfaces | WDU_INTERFACE * | Pointer to buffer containing information about this configuration's interfaces |
| Name | Type | Description |
|---|---|---|
| pAlternateSettings | WDU_ALTERNATE_SETTING * | Pointer to buffer containing information about the interface's alternate settings |
| dwNumAltSettings | DWORD | Number of alternate settings |
| pActiveAltSetting | WDU_ALTERNATE_SETTING * | Pointer to buffer containing information about the active alternate setting |
| Name | Type | Description |
|---|---|---|
| Descriptor | WDU_INTERFACE_DESCRIPTOR | Contains basic information about an interface |
| pEndpointDescriptors | WDU_ENDPOINT_DESCRIPTOR * | Pointer to buffers containing information about a device's endpoints |
| pPipes | WDU_PIPE_INFO * | Pointer to buffers containing information about a device's pipes |
| Name | Type | Description |
|---|---|---|
| bLength | UCHAR | Size, in bytes, of the descriptor (18 bytes) |
| bDescriptorType | UCHAR | Device descriptor (0x01) |
| bcdUSB | USHORT | Number of the USB specification with which the device complies |
| bDeviceClass | UCHAR | The device's class |
| bDeviceSubClass | UCHAR | The device's sub-class |
| bDeviceProtocol | UCHAR | The device's protocol |
| bMaxPacketSize0 | UCHAR | Maximum size of transferred packets |
| idVendor | USHORT | Vendor ID, as assigned by USB-IF |
| idProduct | USHORT | Product ID, as assigned by the product manufacturer |
| bcdDevice | USHORT | Device release number |
| iManufacturer | UCHAR | Index of manufacturer string descriptor |
| iProduct | UCHAR | Index of product string descriptor |
| iSerialNumber | UCHAR | Index of serial number string descriptor |
| bNumConfigurations | UCHAR | Number of possible configurations |
| Name | Type | Description |
|---|---|---|
| bLength | UCHAR | Size, in bytes, of the descriptor |
| bDescriptorType | UCHAR | Configuration descriptor (0x02) |
| wTotalLength | USHORT | Total length, in bytes, of data returned |
| bNumInterfaces | UCHAR | Number of interfaces |
| bConfigurationValue | UCHAR | Configuration number |
| iConfiguration | UCHAR | Index of string descriptor that describes this configuration |
| bmAttributes | UCHAR | Power settings for this configuration:
|
| MaxPower | UCHAR | Maximum power consumption for this configuration, in 2mA units |
| Name | Type | Description |
|---|---|---|
| bLength | UCHAR | Size, in bytes, of the descriptor (9 bytes) |
| bDescriptorType | UCHAR | Interface descriptor (0x04) |
| bInterfaceNumber | UCHAR | Interface number |
| bAlternateSetting | UCHAR | Alternate setting number |
| bNumEndpoints | UCHAR | Number of endpoints used by this interface |
| bInterfaceClass | UCHAR | The interface's class code, as assigned by USB-IF |
| bInterfaceSubClass | UCHAR | The interface's sub-class code, as assigned by USB-IF |
| bInterfaceProtocol | UCHAR | The interface's protocol code, as assigned by USB-IF |
| iInterface | UCHAR | Index of string descriptor that describes this interface |
| Name | Type | Description |
|---|---|---|
| bLength | UCHAR | Size, in bytes, of the descriptor (7 bytes) |
| bDescriptorType | UCHAR | Endpoint descriptor (0x05) |
| bEndpointAddress | UCHAR | Endpoint address: Use bits 0-3 for endpoint number, set bits 4-6 to zero (0), and set bit 7 to zero (0) for outbound data and one (1) for inbound data (ignored for control endpoints) |
| bmAttributes | UCHAR | Specifies the transfer type for this endpoint (control, interrupt, isochronous or bulk). See the USB specification for further information. |
| wMaxPacketSize | USHORT | Maximum size of packets this endpoint can send or receive |
| bInterval | UCHAR | Interval, in frame counts, for polling
endpoint data transfers.
Ignored for bulk and control endpoints. Must equal 1 for isochronous endpoints. May range from 1 to 255 for interrupt endpoints. |
| Name | Type | Description |
|---|---|---|
| dwNumber | DWORD | Pipe number; 0 for default pipe |
| dwMaximumPacketSize | DWORD | Maximum size of packets that can be transferred using this pipe |
| type | DWORD | Transfer type for this pipe |
| direction | DWORD | Direction of transfer:
|
| dwInterval | DWORD | Interval in milliseconds (ms).
Relevant only to interrupt pipes. |
The following is a typical calling sequence for the WinDriver API.
****************************************************************************************
| NOTES | |
|
PURPOSE
Opens a handle to access the WinDriver kernel module. The handle is used by all
WinDriver APIs, and therefore must be called before any other WinDriver API is called.
PROTOTYPE
HANDLE WD_Open();
RETURN VALUE
The handle to the WinDriver kernel module.
If device could not be opened, returns INVALID_HANDLE_VALUE.
REMARKS
If you are a registered user, please refer to WD_License() [A.5.9] function reference to see an example of how to register your license.
EXAMPLE
HANDLE hWD;
hWD = WD_Open();
if (hWD==INVALID_HANDLE_VALUE)
{
printf("Cannot open WinDriver device\n");
}
PURPOSE
Returns the version number of the WinDriver kernel module currently
running.
PROTOTYPE
DWORD WD_Version(HANDLE hWD, WD_VERSION *pVer);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input | |
| WD_VERSION * | ||
| DWORD | Output | |
| CHAR | Output |
DESCRIPTION
| Name | Description |
|---|---|
| hWD | The handle to WinDriver's kernel-mode driver received from WD_Open() [A.5.2]. |
| pVer | WD_VERSION elements: |
| dwVer | The version number. |
| cVer[100] | Version info string. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
EXAMPLE
WD_VERSION ver;
BZERO(ver);
WD_Version(hWD, &ver);
printf("%s\n", ver.cVer)
if (ver.dwVer<WD_VER)
{
printf("Error - incorrect WinDriver version\n");
}
PURPOSE
Closes the access to the WinDriver kernel module.
PROTOTYPE
void WD_Close(HANDLE hWD);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hWD | The handle to WinDriver's kernel-mode driver received from WD_Open() [A.5.2]. |
REMARKS
This function must be called when you finish using WinDriver kernel module.
EXAMPLE
WD_Close(hWD);
PURPOSE
Sets debugging level for collecting debug messages.
PROTOTYPE
DWORD WD_Debug(HANDLE hWD, WD_DEBUG *pDebug);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input | |
| WD_DEBUG * | Input | |
| DWORD | Input | |
| DWORD | Input | |
| DWORD | Input | |
| DWORD | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hWD | The handle to WinDriver's kernel-mode driver received from WD_Open() [A.5.2]. |
| pDebug | WD_DEBUG elements: |
| dwCmd | Debug command: Set filter, Clear buffer, etc. For more details please refer to DEBUG_COMMAND in windrvr.h. |
| dwLevel | Used for dwCmd=DEBUG_SET_FILTER. Sets the debugging level to collect: Error, Warning, Info, Trace. For more details please refer to DEBUG_LEVEL in windrvr.h. |
| dwSection | Used for dwCmd=DEBUG_SET_FILTER. Sets the sections to collect: IO, Mem, Int, etc. Use S_ALL for all. For more details please refer to DEBUG_SECTION in windrvr.h. |
| dwLevelMessageBox | Used for dwCmd=DEBUG_SET_FILTER. Sets the debugging level to print in a message box. For more details please refer to DEBUG_LEVEL in windrvr.h. |
| dwBufferSize | Used for dwCmd=DEBUG_SET_BUFFER. The size of buffer in the kernel. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
EXAMPLE
WD_DEBUG dbg; BZERO(dbg); dbg.dwCmd = DEBUG_SET_FILTER; dbg.dwLevel = D_ERROR; dbg.dwSection = S_ALL; dbg.dwLevelMessageBox = D_ERROR; WD_Debug(hWD, &dbg);
PURPOSE
Sends debug messages to the debug log. Used by the driver code.
PROTOTYPE
DWORD WD_DebugAdd(HANDLE hWD, WD_DEBUG_ADD *pData);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input | |
| WD_DEBUG_ADD * | ||
| DWORD | Input | |
| DWORD | Input | |
| CHAR [256] | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hWD | The handle to WinDriver's kernel-mode driver received from WD_Open() [A.5.2]. |
| pData | WD_DEBUG_ADD elements: |
| dwLevel | Assigns the level in the Debug Monitor, in which the data will be declared.
If dwLevel is 0, D_ERROR will be declared. For more details please refer to DEBUG_LEVEL in windrvr.h. |
| dwSection | Assigns the section in the Debug Monitor, in which the data will be declared.
If dwSection is 0, S_MISC section will be declared. For more details please refer to DEBUG_SECTION in windrvr.h. |
| pcBuffer | The string to copy into the message log. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
EXAMPLE
WD_DEBUG_ADD add;
BZERO(add);
add.dwLevel = D_WARN;
add.dwSection = S_MISC;
sprintf(add.pcBuffer, "This message will be displayed in "
"the debug monitor\n");
WD_DebugAdd(hWD, &add);
PURPOSE
Retrieves debug messages buffer.
PROTOTYPE
DWORD WD_DebugDump(HANDLE hWD, WD_DEBUG_DUMP *pDebugDump);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input | |
| WD_DEBUG_DUMP * | Input | |
| PCHAR | Input/Output | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hWD | The handle to WinDriver's kernel-mode driver received from WD_Open() [A.5.2]. |
| pDebugDump | WD_DEBUG_DUMP elements: |
| pcBuffer | Buffer to receive debug messages |
| dwSize | Size of buffer in bytes |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
EXAMPLE
char buffer[1024]; WD_DEBUG_DUMP dump; dump.pcBuffer=buffer; dump.dwSize = sizeof(buffer); WD_DebugDump(hWD, &dump);
PURPOSE
Delays execution for a specific duration of time.
PROTOTYPE
DWORD WD_Sleep(HANDLE hWD, WD_SLEEP *pSleep);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input | |
| WD_SLEEP * | ||
| DWORD | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hWD | The handle to WinDriver's kernel-mode driver received from WD_Open() [A.5.2]. |
| pSleep | WD_SLEEP elements: |
| dwMicroSeconds | Sleep time in microseconds - 1/1,000,000 of a second. |
| dwOptions | A bit mask flag:
Default - Busy sleep. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
Example usage: to access slow response hardware.
EXAMPLE
WD_Sleep slp; BZERO(slp); slp.dwMicroSeconds = 200; WD_Sleep(hWD, &slp);
PURPOSE
Transfers the license string to the WinDriver kernel module and
returns information regarding the license type of the specified license string.
PROTOTYPE
DWORD WD_License(HANDLE hWD, WD_LICENSE *pLicense);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input | |
| WD_LICENSE * | ||
| CHAR | Input | |
| DWORD | Output | |
| DWORD | Output |
DESCRIPTION
| Name | Description |
|---|---|
| hWD | The handle to WinDriver's kernel-mode driver received from WD_Open() [A.5.2]. |
| pLicense | WD_LICENSE elements: |
| cLicense[] | A buffer to contain the license string that is to be transferred to the WinDriver kernel module. If an empty string is transferred, then WinDriver kernel module returns the current license type to the parameter dwLicense. |
| dwLicense | Returns the license type of the specified license string (cLicnese). The return value is a mask of license type flags, defined as an enum in windrvr.h. 0 = Invalid license string. Additional flags for determining the license type will be returned in dwLicense2, if needed. |
| dwLicense2 | Returns additional flags for determining the license type, if dwLicense could not hold all the relevant information (otherwise - 0). |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
When using a registered version, this function must be called before any other WinDriver API call, apart from WD_Open(), in order to register the license from the code.
Example usage: Add registration routine to your application.
EXAMPLE
DWORD RegisterWinDriver()
{
HANDLE hWD;
WD_LICENSE lic;
DWORD dwStatus = WD_INVALID_HANDLE;
hWD = WD_Open();
if (hWD!=INVALID_HANDLE_VALUE)
{
BZERO(lic);
// replace the following string with your license string
strcpy(lic.cLicense, "12345abcde12345.CompanyName");
dwStatus = WD_License(hWD, &lic);
WD_Close(hWD);
}
return dwStatus;
}
PURPOSE
Opens a log file.
PROTOTYPE
DWORD WD_LogStart(const char *sFileName, const char *sMode)
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| const char * | Input | |
| const char * | Input |
DESCRIPTION
| Name | Description |
|---|---|
| sFileName | Name of log file to be opened. |
| sMode | Type of access permitted. For example, when NULL or w, opens an empty file for writing. If the given file exists, its contents are destroyed. When a, opens for writing at the end of the file (appending). |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
REMARKS
Once a log file is opened, all API calls are logged in this file. You may add your own printouts to the log file by calling WD_LogAdd() [A.5.12].
PURPOSE
Closes a log file.
PROTOTYPE
VOID WD_LogStop()
RETURN VALUE
None
PURPOSE
Adds user printouts into log file.
PROTOTYPE
VOID DLLCALLCONV WD_LogAdd(const char *sFormat...)
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| const char * | Input | |
| Input |
DESCRIPTION
| Name | Description |
|---|---|
| sFormat | Format-control string |
| argument | Optional arguments |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
Most of the WinDriver API functions return a status code, where 0 (WD_STATUS_SUCCESS) means success and a non-zero value means failure. The Stat2Str() and WDL_Stat2Str() can be used to retrieve the status description string for a given status code. The status codes and their descriptive strings are listed below.
| Status Code | Description |
|---|---|
| WD_STATUS_SUCCESS | Success |
| WD_STATUS_INVALID_WD_HANDLE | Invalid WinDriver handle |
| WD_WINDRIVER_STATUS_ERROR | Error |
| WD_INVALID_HANDLE | Invalid handle |
| WD_INVALID_PIPE_NUMBER | Invalid pipe number |
| WD_READ_WRITE_CONFLICT | Conflict between read and write operations |
| WD_ZERO_PACKET_SIZE | Packet size is zero |
| WD_INSUFFICIENT_RESOURCES | Insufficient resources |
| WD_UNKNOWN_PIPE_TYPE | Unknown pipe type |
| WD_SYSTEM_INTERNAL_ERROR | Internal system error |
| WD_DATA_MISMATCH | Data mismatch |
| WD_NO_LICENSE | No valid license |
| WD_NOT_IMPLEMENTED | Function not implemented |
| WD_FAILED_ENABLING_INTERRUPT | Failed enabling interrupt |
| WD_INTERRUPT_NOT_ENABLED | Interrupt not enabled |
| WD_RESOURCE_OVERLAP | Resource overlap |
| WD_DEVICE_NOT_FOUND | Device not found |
| WD_WRONG_UNIQUE_ID | Wrong unique ID |
| WD_OPERATION_ALREADY_DONE | Operation already done |
| WD_USB_DESCRIPTOR_ERROR | Usb descriptor error |
| WD_SET_CONFIGURATION_FAILED | Set configuration operation failed |
| WD_CANT_OBTAIN_PDO | Cannot obtain PDO |
| WD_TIME_OUT_EXPIRED | Timeout expired |
| WD_IRP_CANCELED | IRP operation cancelled |
| WD_FAILED_USER_MAPPING | Failed to map in user space |
| WD_FAILED_KERNEL_MAPPING | Failed to map in kernel space |
| WD_NO_RESOURCES_ON_DEVICE | No resources on the device |
| WD_NO_EVENTS | No events |
| WD_INVALID_PARAMETER | Invalid parameter |
| WD_INCORRECT_VERSION | Incorrect WinDriver version installed |
| WD_TRY_AGAIN | Try again |
| WD_INVALID_IOCTL | Received an invalid IOCTL |
The following WinDriver status codes comply with USBD_XXX status codes returned by the USB stack drivers.
| Status Code | Description |
|---|---|
| USBD Status Types | |
| WD_USBD_STATUS_SUCCESS | USBD: Success |
| WD_USBD_STATUS_PENDING | USBD: Operation pending |
| WD_USBD_STATUS_ERROR | USBD: Error |
| WD_USBD_STATUS_HALTED | USBD: Halted |
| USBD Status Codes (NOTE: These are comprised of one of the status types above and an error code, i.e., 0xXYYYYYYYL, where X=status type and YYYYYYY=error code. The same error codes may also appear with one of the other status types as well.) | |
| HC (Host Controller) Status Codes (NOTE: These use the WD_USBD_STATUS_HALTED status type.) | |
| WD_USBD_STATUS_CRC | HC status: CRC |
| WD_USBD_STATUS_BTSTUFF | HC status: Bit stuffing |
| WD_USBD_STATUS_DATA_TOGGLE_MISMATCH | HC status: Data toggle mismatch |
| WD_USBD_STATUS_STALL_PID | HC status: PID stall |
| WD_USBD_STATUS_DEV_NOT_RESPONDING | HC status: Device not responding |
| WD_USBD_STATUS_PID_CHECK_FAILURE | HC status: PID check failed |
| WD_USBD_STATUS_UNEXPECTED_PID | HC status: Unexpected PID |
| WD_USBD_STATUS_DATA_OVERRUN | HC status: Data overrun |
| WD_USBD_STATUS_DATA_UNDERRUN | HC status: Data underrun |
| WD_USBD_STATUS_RESERVED1 | HC status: Reserved1 |
| WD_USBD_STATUS_RESERVED2 | HC status: Reserved2 |
| WD_USBD_STATUS_BUFFER_OVERRUN | HC status: Buffer overrun |
| WD_USBD_STATUS_BUFFER_UNDERRUN | HC status: Buffer Underrun |
| WD_USBD_STATUS_NOT_ACCESSED | HC status: Not accessed |
| WD_USBD_STATUS_FIFO | HC status: Fifo |
| For Windows only: | |
| WD_USBD_STATUS_XACT_ERROR | HC status: The host controller has set the Transaction Error (XactErr) bit in the transfer descriptor's status field |
| WD_USBD_STATUS_BABBLE_DETECTED | HC status: Babble detected |
| WD_USBD_STATUS_DATA_BUFFER_ERROR | HC status: Data buffer error |
| For Windows CE only: | |
| WD_USBD_STATUS_NOT_COMPLETE | USBD: Transfer not completed |
| WD_USBD_STATUS_CLIENT_BUFFER | USBD: Cannot write to buffer |
| For all platforms: | |
| WD_USBD_STATUS_CANCELED | USBD: Transfer cancelled |
| Returned by HCD (Host Controller Driver) if a transfer is submitted to an endpoint that is stalled: | |
| WD_USBD_STATUS_ENDPOINT_HALTED | HCD: Transfer submitted to stalled endpoint |
| Software Status Codes (NOTE: Only the error bit is set): | |
| WD_USBD_STATUS_NO_MEMORY | USBD: Out of memory |
| WD_USBD_STATUS_INVALID_URB_FUNCTION | USBD: Invalid URB Jfunction |
| WD_USBD_STATUS_INVALID_PARAMETER | USBD: Invalid parameter |
| Returned if client driver attempts to close an endpoint/interface or configuration with outstanding transfers: | |
| WD_USBD_STATUS_ERROR_BUSY | USBD: Attempted to close endpoint/interface/configuration with outstanding transfer |
| Returned by USBD if it cannot complete a URB request. Typically this will be returned in the URB status field (when the Irp is completed) with a more specific NT error code. The Irp status codes are indicated in WinDriver's Debug Monitor tool (wddebug_gui): | |
| WD_USBD_STATUS_REQUEST_FAILED | USBD: URB request failed |
| WD_USBD_STATUS_INVALID_PIPE_HANDLE | USBD: Invalid pipe handle |
| Returned when there is not enough bandwidth available to open a requested endpoint: | |
| WD_USBD_STATUS_NO_BANDWIDTH | USBD: Not enough bandwidth for endpoint |
| Generic HC (Host Controller) error: | |
| WD_USBD_STATUS_INTERNAL_HC_ERROR | USBD: Host controller error |
| Returned when a short packet terminates the transfer, i.e., USBD_SHORT_TRANSFER_OK bit not set: | |
| WD_USBD_STATUS_ERROR_SHORT_TRANSFER | USBD: Transfer terminated with short packet |
| Returned if the requested start frame is not within USBD_ISO_START_FRAME_RANGE of the current USB frame (NOTE: The stall bit is set): | |
| WD_USBD_STATUS_BAD_START_FRAME | USBD: Start frame outside range |
| Returned by HCD (Host Controller Driver) if all packets in an isochronous transfer complete with an error: | |
| WD_USBD_STATUS_ISOCH_REQUEST_FAILED | HCD: Isochronous transfer completed with error |
| Returned by USBD if the frame length control for a given HC (Host Controller) is already taken by another driver: | |
| WD_USBD_STATUS_FRAME_CONTROL_OWNED | USBD: Frame length control already taken |
| Returned by USBD if the caller does not own frame length control and attempts to release or modify the HC frame length: | |
| WD_USBD_STATUS_FRAME_CONTROL_NOT_OWNED | USBD: Attempted operation on frame length control not owned by caller |
| Additional software error codes added for USB 2.0 (for Windows only): | |
| WD_USBD_STATUS_NOT_SUPPORTED | USBD: API not supported/implemented |
| WD_USBD_STATUS_INAVLID_CONFIGURATION_DESCRIPTOR | USBD: Invalid configuration descriptor |
| WD_USBD_STATUS_INSUFFICIENT_RESOURCES | USBD: Insufficient resources |
| WD_USBD_STATUS_SET_CONFIG_FAILED | USBD: Set configuration failed |
| WD_USBD_STATUS_BUFFER_TOO_SMALL | USBD: Buffer too small |
| WD_USBD_STATUS_INTERFACE_NOT_FOUND | USBD: Interface not found |
| WD_USBD_STATUS_INAVLID_PIPE_FLAGS | USBD: Invalid pipe flags |
| WD_USBD_STATUS_TIMEOUT | USBD: Timeout |
| WD_USBD_STATUS_DEVICE_GONE | USBD: Device gone |
| WD_USBD_STATUS_STATUS_NOT_MAPPED | USBD: Status not mapped |
| Extended isochronous error codes returned by USBD. These errors appear in the packet status field of an isochronous transfer: |
|
| WD_USBD_STATUS_ISO_NOT_ACCESSED_BY_HW | USBD: The controller did not access the TD associated with this packet |
| WD_USBD_STATUS_ISO_TD_ERROR | USBD: Controller reported an error in the TD |
| WD_USBD_STATUS_ISO_NA_LATE_USBPORT | USBD: The packet was submitted in time by the client but failed to reach the miniport in time |
| WD_USBD_STATUS_ISO_NOT_ACCESSED_LATE | USBD: The packet was not sent because the client submitted it too late to transmit |
This section describes a number of user-mode utility functions you will find useful for implementing various tasks. These utility functions are multi-platform, implemented on all operating systems supported by WinDriver.
PURPOSE
Retrieves the status string that corresponds to a status code.
PROTOTYPE
const char * Stat2Str(DWORD dwStatus);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| dwStatus | numeric status code |
RETURN VALUE
Returns the verbal status description (string) that corresponds to the specified numeric status code.
REMARKS
See Section A.6 for a complete list of status codes and strings.
PURPOSE
Retrieves the type of the operating system.
PROTOTYPE
OS_TYPE get_os_type();
RETURN VALUE
None
Returns the type of the operating system.
If the operating system type is not detected, returns OS_CAN_NOT_DETECT.
PURPOSE
Creates a thread.
PROTOTYPE
DWORD ThreadStart(HANDLE *phThread, HANDLER_FUNC pFunc, void *pData);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE * | Output | |
| HANDLER_FUNC | Input | |
| VOID * | Input |
DESCRIPTION
| Name | Description |
|---|---|
| phThread | Returns the handle to the created thread |
| pFunc | Starting address of the code that the new thread is to execute |
| pData | Pointer to the data to be passed to the new thread |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Waits for a thread to exit.
PROTOTYPE
void ThreadWait(HANDLE hThread);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
| Name | Description |
|---|---|
| hThread | The handle to the thread whose completion is awaited |
RETURN VALUE
None
PURPOSE
Creates an event object.
PROTOTYPE
DWORD OsEventCreate(HANDLE *phOsEvent);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE * | Output |
DESCRIPTION
| Name | Description |
|---|---|
| phOsEvent | The pointer to a variable that receives a handle to the newly created event object |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Closes a handle to an event object.
PROTOTYPE
void OsEventClose(HANDLE hOsEvent)
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hOsEvent | The handle to the event object to be closed |
RETURN VALUE
None
PURPOSE
Waits until a specified event object is in the signaled state or the time-out interval elapses.
PROTOTYPE
DWORD OsEventWait(HANDLE hOsEvent, DWORD dwSecTimeout)
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input | |
| DWORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hOsEvent | The handle to the event object |
| dwSecTimeout | Time-out interval of the event, in seconds. If dwSecTimeout is INFINITE, the function's time-out interval never elapses. |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Sets the specified event object to the signaled state.
PROTOTYPE
DWORD OsEventSignal(HANDLE hOsEvent);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hOsEvent | The handle to the event object |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Resets the specified event object to the non-signaled state.
PROTOTYPE
DWORD OsEventReset(HANDLE hOsEvent);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hOsEvent | The handle to the event object |
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Creates a mutex object.
PROTOTYPE
DWORD OsMutexCreate(HANDLE *phOsMutex);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE * | Output |
DESCRIPTION
| Name | Description |
|---|---|
| phOsMutex | The pointer to a variable that receives a handle to the newly created mutex object |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Closes a handle to a mutex object.
PROTOTYPE
void OsMutexClose(HANDLE hOsMutex);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hOsMutex | The handle to the mutex object to be closed |
RETURN VALUE
None
PURPOSE
Locks the specified mutex object.
PROTOTYPE
DWORD OsMutexLock(HANDLE hOsMutex)
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hOsMutex | The handle to the mutex object to be locked |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Releases (unlocks) a locked mutex object.
PROTOTYPE
DWORD OsMutexUnlock(HANDLE hOsMutex);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| HANDLE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| hOsMutex | The handle to the mutex object to be unlocked |
RETURN VALUE
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A.6].
PURPOSE
Sends debug messages to the debug monitor.
PROTOTYPE
void PrintDbgMessage(DWORD dwLevel, DWORD dwSection,
const char *format[, argument]...);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| DWORD | Input | |
| DWORD | Input | |
| const char * | Input | |
| Input |
DESCRIPTION
| Name | Description |
|---|---|
| dwLevel | Assigns the level in the Debug Monitor, in which the data will be declared.
If dwLevel is 0, then D_ERROR will be declared. For more details please refer to DEBUG_LEVEL in windrvr.h. |
| dwSection | Assigns the section in the Debug Monitor, in which the data will be declared.
If dwSection is 0, then S_MISC section will be declared. For more details please refer to DEBUG_SECTION in windrvr.h. |
| format | Format-control string |
| argument | Optional arguments, limited to 256 bytes |
RETURN VALUE
None
This section describes the WinDriver USB Device firmware library API for the
Cypress EZ-USB FX2LP CY7C68013A development board. The functions and general types and
definitions described in this section are declared and defined (respectively)
in the FX2LP
include
wdf_cypress_lib .h header
file. The functions are implemented in the generated DriverWizard
wdf_cypress_lib .c file - for registered users, or in the
FX2LP
wdf_cypress_fx2lp_eval.lib evaluation firmware library - for
evaluation users (see section 12.3.4 for details).
****************************************************************************************
| NOTE | |
| Registered users can modify the library source code. When modifying the code, make sure that you comply with your development board's hardware specification - see note in section 12.4.3. |
The APIs described in this section are defined in
FX2LP
wdf_cypress_lib .h.
Enumeration of endpoint directions:
| Enum Value | Description |
|---|---|
| DIR_OUT | Direction OUT (write from the host to the device) |
| DIR_IN | Direction IN (read from the device to the host) |
Enumeration of endpoint types.
The endpoint's type determines the type of transfers to be performed on the
endpoint - bulk, interrupt or isochronous.
| Enum Value | Description |
|---|---|
| ISOCHRONOUS | Isochronous endpoint |
| BULK | Bulk endpoint |
| INTERRUPT | Interrupt endpoint |
Enumeration of endpoint buffering types:
| Enum Value | Description |
|---|---|
| DOUBLE_BUFFERING | Double buffering |
| TRIPLE_BUFFERING | Triple buffering |
| QUAD_BUFFERING | Quadruple buffering |
PURPOSE
Configures endpoint 1 for IN transfers (WDF_EP1INConfig())
or OUT transfers (WDF_EPOUTConfig()).
PROTOTYPE
void WDF_EP1INConfig(EP_TYPE type); void WDF_EP1OUTConfig(EP_TYPE type);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_TYPE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| type | The endpoint's transfer type [B.1.1.2] |
RETURN VALUE
None
****************************************************************************************
| NOTE | |
| The prototype and description of WDF_EP2Config() and WDF_EP6Config() is identical, except for the endpoint number. The description below will refer to endpoint 2, but you can simply replace all "2" references with "6" to get the description of WDF_EP6Config(). |
PURPOSE
Configures endpoint 2.
PROTOTYPE
void WDF_EP2Config(EP_DIR dir, EP_TYPE type,
EP_BUFFERING buffering, int size, int nPacketPerMF);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DIR | Input | |
| EP_TYPE | Input | |
| EP_BUFFERING | Input | |
| int | Input | |
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| dir | The endpoint's direction [B.1.1.1] |
| type | The endpoint's transfer type [B.1.1.2] |
| buffering | The endpoint's buffering type [B.1.1.3] |
| size | The size of the endpoint's FIFO buffer (in bytes) |
| nPacketPerMF | Number of packets per microframe |
RETURN VALUE
None
****************************************************************************************
| NOTE | |
| The prototype and description of WDF_EP4Config() and WDF_EP8Config() is identical, except for the endpoint number. The description below will refer to endpoint 4, but you can simply replace all "4" references with "8" to get the description of WDF_EP8Config(). |
PURPOSE
Configures endpoint 4.
PROTOTYPE
void WDF_EP4Config(EP_DIR dir, EP_TYPE type);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DIR | Input | |
| EP_TYPE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| dir | The endpoint's direction [B.1.1.1] |
| type | The endpoint's transfer type [B.1.1.2] |
RETURN VALUE
None
PURPOSE
Restores an endpoint's FIFO (First In First Out) buffer to its
default state.
PROTOTYPE
void WDF_FIFOReset(int ep);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
RETURN VALUE
None
PURPOSE
Signals an endpoint's FIFO (First In First Out) buffer to ignore
received OUT packets.
PROTOTYPE
void WDF_SkipOutPacket(int ep);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
RETURN VALUE
None
PURPOSE
Writes data to an endpoint's FIFO (First In First Out) buffer.
The call to this function should be followed by a call to
WDF_SetEPByteCount() [B.1.11].
PROTOTYPE
void WDF_FIFOWrite(int ep, BYTE buf, int size);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input | |
| BYTE [ ] | Input | |
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
| buf | Data buffer to write |
| size | Number of bytes to write |
RETURN VALUE
None
PURPOSE
Reads data from an endpoint's FIFO (First In First Out) buffer.
The call to this function should be preceded by a call to
WDF_GetEPByteCount() [B.1.12] in order to
determine the amount of bytes to read.
PROTOTYPE
void WDF_FIFORead(int ep, BYTE buf, int size);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input | |
| BYTE [ ] | Output | |
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
| buf | Buffer to hold the read data |
| size | Number of bytes to read from the FIFO buffer |
RETURN VALUE
None
PURPOSE
Checks if an endpoint's FIFO (First In First Out) buffer is
completely full.
PROTOTYPE
BOOL WDF_FIFOFull(int ep);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
RETURN VALUE
Returns TRUE if the endpoint's FIFO buffer is full; otherwise returns FALSE.
PURPOSE
Checks if an endpoint's FIFO (First In First Out) buffer is
empty.
PROTOTYPE
BOOL WDF_FIFOEmpty(int ep);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
RETURN VALUE
Returns TRUE if the endpoint's FIFO buffer is empty; otherwise returns FALSE.
PURPOSE
Sets the bytes count of an endpoint's FIFO (First In First Out)
buffer.
The call to this function should be preceded by a call to
WDF_FIFOWrite() [B.1.7] in order to update the
endpoint's FIFO buffer with the data to be transferred to the host.
PROTOTYPE
void WDF_SetEPByteCount(int ep, WORD bytes_count);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input | |
| WORD | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
| bytes_count | Bytes count to set |
RETURN VALUE
None
PURPOSE
Gets the current bytes count of an endpoint's FIFO (First In First
Out) buffer.
This function should be called before calling WDF_FIFORead()
[B.1.8] to read from the endpoint's FIFO buffer, in order
to determine the amount of bytes to read.
PROTOTYPE
WORD WDF_GetEPByteCount(int ep);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ep | Endpoint number (address) |
RETURN VALUE
Returns the endpoint's FIFO bytes count.
PURPOSE
Initializes the I2C bus.
PROTOTYPE
void WDF_I2CInit(void);
RETURN VALUE
None
PURPOSE
Displays the specified digit in the development board's digit LED.
PROTOTYPE
void WDF_SetDigitLed(int digit);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| int | Input |
DESCRIPTION
| Name | Description |
|---|---|
| The digit to diplay |
RETURN VALUE
None
PURPOSE
Writes data to a specified address on the I2C bus.
PROTOTYPE
BOOL WDF_I2CWrite(BYTE addr, BYTE len, BYTE xdata *dat);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input | |
| BYTE | Input | |
| xdata* | Input |
DESCRIPTION
| Name | Description |
|---|---|
| The address to which to write | |
| The number of bytes to write | |
| Pointer to a buffer containing the data to write |
RETURN VALUE
Returns TRUE for a successful write operation; otherwise returns FALSE.
PURPOSE
Reads data from a specified address on the I2C bus.
PROTOTYPE
BOOL WDF_I2CRead(BYTE addr, BYTE len, BYTE xdata *dat);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input | |
| BYTE | Input | |
| xdata* | Output |
DESCRIPTION
| Name | Description |
|---|---|
| The address from which to read | |
| The number of bytes to read | |
| Pointer to a buffer containing the data that is read |
RETURN VALUE
Returns TRUE for a successful read operation; otherwise returns FALSE.
PURPOSE
Waits for the completion of the current write operation on the
specified I2C bus address.
PROTOTYPE
void WDF_I2CWaitForEEPROMWrite(BYTE addr);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| The I2C bus address on which to wait |
RETURN VALUE
None
PURPOSE
Gets the current status of the I2C bus.
PROTOTYPE
int WDF_I2CGetStatus(void);
RETURN VALUE
Returns the I2C bus status.
PURPOSE
Clears the I2C bus status from errors/NAKs.
PROTOTYPE
void WDF_I2CClearStatus(void);
RETURN VALUE
None
This section describes the WinDriver USB Device generated DriverWizard firmware API
for the Cypress EZ-USB FX2LP CY7C68013A development board. The functions described in this
section are declared in the
FX2LP
include
periph.h header
file and implemented in the generated DriverWizard periph.c
file, according to the device configuration information defined in the
wizard.
The firmware's entry point - main() in main.c (source code provided for registered users only) - implements a Task Dispatcher, which calls the WDF_xxx() functions declared in periph.h (and implemented in periph.c) in order to communicate with the peripheral device.
****************************************************************************************
| NOTE | |
| When modifying the generated code, make sure that you comply with your development board's hardware specification - see note in section [12.4.3]. |
PURPOSE
Initializes the device.
This function is automatically called from the firmware's main() function
in order to perform the required initialization to enable communication with
the device.
PROTOTYPE
void WDF_Init(void);
RETURN VALUE
None
PURPOSE
Polls the device for FIFO data.
The Task Dispatcher calls this function repeatedly while the device is idle.
PROTOTYPE
void WDF_Poll(void);
RETURN VALUE
None
PURPOSE
This function is called by the Task Dispatcher before the device
goes into suspend mode.
PROTOTYPE
BOOL WDF_Suspend(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher after the device
resumes activity.
PROTOTYPE
BOOL WDF_Resume(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a GET
DESCRIPTOR command is received.
PROTOTYPE
BOOL WDF_GetDescriptor(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a SET
CONFIGURATION command is received.
PROTOTYPE
BOOL WDF_SetConfiguration(BYTE config);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| config | Configuration number to set |
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a GET
CONFIGURATION command is received.
PROTOTYPE
BOOL WDF_GetConfiguration(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a SET INTERFACE
command is received.
PROTOTYPE
BOOL WDF_SetInterface(BYTE ifc, BYTE alt_set);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input | |
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ifc | Interface number to set |
| alt_set | Alternate setting number to set |
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a GET INTERFACE
command is received.
PROTOTYPE
BOOL WDF_GetInterface(BYTE ifc);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| ifc | Interface number |
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a GET STATUS
command is received.
PROTOTYPE
BOOL WDF_GetStatus(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a CLEAR FEATURE
command is received.
PROTOTYPE
BOOL WDF_ClearFeature(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a SET FEATURE
command is received.
PROTOTYPE
BOOL WDF_SetFeature(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a
vendor-specific command is received.
PROTOTYPE
BOOL WDF_VendorCmnd(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
This section describes the WinDriver USB Device firmware library API for the
Microchip PIC18F4550 development board. The functions and general types and
definitions described in this section are declared and defined (respectively)
in the 18F4550
include
wdf_microchip_lib .h
header file. The functions are implemented in the generated DriverWizard
wdf_microchip_lib .c file - for registered users, or in the
18F4550
wdf_microchip_18f4550_eval.lib evaluation firmware library - for
evaluation users (see section 12.3.4 for details).
****************************************************************************************
| NOTE | |
| Registered users can modify the library source code. When modifying the code, make sure that you comply with your development board's hardware specification - see note in section 12.4.3. |
The data types described in this section are defined in the
18F4550
include
types.h header file.
Enumeration of endpoint directions:
| Enum Value | Description |
|---|---|
| OUT | Direction OUT (write from the host to the device) |
| IN | Direction IN (read from the device to the host) |
Enumeration of endpoint types.
The endpoint's type determines the type of transfers to be performed on the
endpoint - bulk, interrupt or isochronous.
| Enum Value | Description |
|---|---|
| ISOCHRONOUS | Isochronous endpoint |
| BULK | Bulk endpoint |
| INTERRUPT | Interrupt endpoint |
Endpoint buffer descriptor status union type:
| Name | Type | Description |
|---|---|---|
| byte | ||
| struct | ||
|
|
bit field (1) | Bit 8 of the endpoint's last transfer byte count |
|
|
bit field (1) | Bit 9 (MSB) of the endpoint's last transfer byte count |
|
|
bit field (1) | Buffer stall enable |
|
|
bit field (1) | Data toggle synchronization enable |
|
|
bit field (1) | Address increment disable |
|
|
bit field (1) | Buffer descriptor keep enable |
|
|
bit field (1) | Data toggle synchronization value |
|
|
bit field (1) | USB ownership |
| struct | ||
|
|
bit field (1) | Bit 8 of the endpoint's last transfer byte count |
|
|
bit field (1) | Bit 9 (MSB) of the endpoint's last transfer byte count |
|
|
bit field (1) | Bit 0 of the packet identifier |
|
|
bit field (1) | Bit 1 of the packet identifier |
|
|
bit field (1) | Bit 2 of the packet identifier |
|
|
bit field (1) | Bit 3 of the packet identifier |
|
|
bit field (1) | Reserved |
|
|
bit field (1) | USB ownership |
| struct | ||
|
|
bit field (2) | Reserved |
|
|
bit field (4) | Packet identifier |
|
|
bit field (2) | Reserved |
Endpoint buffer descriptor table union type:
| Name | Type | Description |
|---|---|---|
| struct | ||
|
|
BD_STAT | Buffer descriptor status [C.1.1.3] |
|
|
byte | The endpoint's last transfer byte count. The byte count's most significant bits are stored in the BC8 and BC9 fields of the BD_STAT union (Stat) |
|
|
byte | Low buffer address |
|
|
byte | High buffer address |
| struct | ||
|
|
bit field (8) | Reserved |
|
|
bit field (8) | Reserved |
|
|
byte* | Pointer to the buffer address |
Endpoint data structure type.
The structure consists of the following members:
| Name | Type | Description |
|---|---|---|
| number | byte | Endpoint number |
| reg | near byte* | UEPn register address |
| max_packet | word | The endpoint's maximum packet size (in bytes) |
| e_bdt | BDT* | Pointer to the endpoint's even buffer descriptor table [C.1.1.4] |
| o_bdt | BDT* | Pointer to the endpoint's odd buffer descriptor table [C.1.1.4] |
| e_buffer | byte* | Pointer to the endpoint's even data buffer |
| o_buffer | byte* | Pointer to the endpoint's odd data buffer |
PURPOSE
Configures and enables a given endpoint for USB transfers.
PROTOTYPE
void WDF_EPConfig(
EP_DATA *ep_data,
byte ep_num,
EP_DIR dir,
EP_TYPE type,
word max_packet,
near byte *reg,
BDT *e_bdt,
byte *e_buffer,
BDT *o_bdt,
byte *o_buffer);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DATA* | Input/Output | |
| byte | Input | |
| EP_DIR | Input | |
| EP_TYPE | Input | |
| word | Input | |
| near byte* | Input | |
| BDT* | Input | |
| byte* | Input | |
| BDT* | Input | |
| byte* | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to an endpoint data structure [C.1.1.5] | |
| The endpoint's number | |
| The endpoint's direction [C.1.1.1] | |
| The endpoint's transfer type [C.1.1.2] | |
| The endpoint's maximum packet size (in bytes) | |
| Pointer to the endpoint's UEPn register | |
| Pointer to the endpoint's even buffer descriptor table [C.1.1.4] | |
| Pointer to the endpoint's even data buffer | |
| Pointer to the endpoint's odd buffer descriptor table [C.1.1.4] | |
| Pointer to the endpoint's odd data buffer |
RETURN VALUE
None
PURPOSE
Writes data to a given endpoint.
The call to this function should be followed by a call to
WDF_TriggerWriteTransfer() [C.1.6].
PROTOTYPE
void WDF_EPWrite(EP_DATA *ep_data, byte *buffer, word len);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DATA* | Input | |
| byte* | Input | |
| word | len |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to an endpoint data structure [C.1.1.5] | |
| Pointer to a buffer containing the data to write | |
| The number of bytes to write |
RETURN VALUE
None
PURPOSE
Reads data from a given endpoint.
The call to this function should be followed by a call to
WDF_TriggerReadTransfer() [C.1.7].
PROTOTYPE
word WDF_EPRead(EP_DATA *ep_data, byte *buffer, word len);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DATA* | Input | |
| byte* | Output | |
| word | len |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to an endpoint data structure [C.1.1.5] | |
| Pointer to a buffer to be updated with the read data | |
| The number of bytes to read |
RETURN VALUE
Returns the number of bytes that were read.
PURPOSE
Checks if the given endpoint is currently busy.
PROTOTYPE
BOOL WDF_IsEPBusy(EP_DATA *ep_data);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DATA* | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to an endpoint data structure [C.1.1.5] |
RETURN VALUE
Returns TRUE if the endpoint is currently busy; otherwise returns FALSE.
PURPOSE
Triggers a write data transfer on a given endpoint, transferring
the USB ownership of the relevant buffer descriptor to the SIE.
PROTOTYPE
void WDF_TriggerWriteTransfer(EP_DATA *ep_data);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DATA* | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to an endpoint data structure [C.1.1.5] |
RETURN VALUE
None
PURPOSE
Triggers a read data transfer on a given endpoint, transferring
the USB ownership of the relevant buffer descriptor to the SIE.
PROTOTYPE
void WDF_TriggerReadTransfer(EP_DATA *ep_data);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DATA* | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to an endpoint data structure [C.1.1.5] |
RETURN VALUE
None
PURPOSE
Gets the current bytes count in a given endpoint's read buffer.
This function should be called before calling WDF_EPRead()
[C.1.4] to read from the endpoint, in order to determine
the amount of bytes to read.
PROTOTYPE
WORD WDF_GetReadBytesCount(EP_DATA *ep_data);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| EP_DATA* | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Pointer to an endpoint data structure [C.1.1.5] |
RETURN VALUE
Returns the endpoint's read buffer bytes count.
PURPOSE
Disables endpoints 1 to 15.
PROTOTYPE
void WDF_DisableEP1to15(void);
RETURN VALUE
None
This section describes the WinDriver USB Device generated DriverWizard firmware API
for the Microchip PIC18F4550 development board. The functions described in this
section are declared in the
18F4550
include
periph.h header
file and implemented in the generated DriverWizard periph.c
file, according to the device configuration information defined in the
wizard.
The firmware's entry point - main() in main.c (source code provided for registered users only) - implements a Task Dispatcher, which calls the WDF_xxx() functions declared in periph.h (and implemented in periph.c) in order to communicate with the peripheral device.
****************************************************************************************
| NOTE | |
| When modifying the generated code, make sure that you comply with your development board's hardware specification - see note in section [12.4.3]. |
PURPOSE
Initializes the device.
This function is automatically called from the firmware's main() function
in order to perform the required initialization to enable communication with
the device.
PROTOTYPE
void WDF_Init(void);
RETURN VALUE
None
PURPOSE
Polls the device for FIFO data.
The Task Dispatcher calls this function repeatedly while the device is idle.
PROTOTYPE
void WDF_Poll(void);
RETURN VALUE
None
PURPOSE
Start of frame interrupt handler function.
PROTOTYPE
void WDF_SOFHandler(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher before the device
goes into suspend mode.
PROTOTYPE
BOOL WDF_Suspend(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher after the device
resumes activity.
PROTOTYPE
BOOL WDF_Resume(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
USB error interrupt handler function.
PROTOTYPE
void WDF_ErrorHandler(void);
RETURN VALUE
None
PURPOSE
This function is called by the Task Dispatcher when a SET
CONFIGURATION command is received.
PROTOTYPE
void WDF_SetConfiguration(byte config);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| byte | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Configuration number to set |
RETURN VALUE
None
PURPOSE
This function is called by the Task Dispatcher when a SET INTERFACE
command is received.
PROTOTYPE
void WDF_SetInterface(byte ifc, byte alt_set);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| byte | Input | |
| byte | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Interface number to set | |
| Alternate setting number to set |
RETURN VALUE
None
PURPOSE
This function is called by the Task Dispatcher when a GET INTERFACE
command is received.
PROTOTYPE
byte WDF_GetInterface(byte ifc);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| byte | Input |
DESCRIPTION
| Name | Description |
|---|---|
| Interface number |
RETURN VALUE
Returns the number of the active alternate setting for the given interface.
PURPOSE
This function is called by the Task Dispatcher when a
vendor-specific command is received.
PROTOTYPE
BOOL WDF_VendorCmnd(
byte bRequest,
word wValue,
word wIndex,
word wLength);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| byte | Input | |
| word | Input | |
| word | Input | |
| word | Input |
DESCRIPTION
| Name | Description |
|---|---|
| The actual request | |
| The request's wValue field | |
| The request's wIndex field | |
| The number of bytes to transfer (if the request has a data stage) |
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a CLEAR FEATURE
command is received.
PROTOTYPE
BOOL WDF_ClearFeature(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
PURPOSE
This function is called by the Task Dispatcher when a SET FEATURE
command is received.
PROTOTYPE
BOOL WDF_SetFeature(void);
RETURN VALUE
Returns TRUE if successful; otherwise returns FALSE.
This section describes the WinDriver USB Device firmware library API for the
Silicon Laboratories C8051F320 development board. The functions and general types and
definitions described in this section are declared and defined (respectively)
in the
F320
include
wdf_silabs_lib .h
header file. The functions are implemented in the generated DriverWizard
wdf_silabs_lib .c file - for registered users, or in the
F320
wdf_silabs_f320_eval.lib evaluation firmware library - for
evaluation users (see section 12.3.4 for details).
****************************************************************************************
| NOTE | |
| Registered users can modify the library source code. When modifying the code, make sure that you comply with your development board's hardware specification - see note in section 12.4.3. |
The APIs described in this section are defined in
F320
wdf_silabs_lib .h.
Enumeration of endpoint directions:
| Enum Value | Description |
|---|---|
| DIR_OUT | Direction OUT (write from the host to the device) |
| DIR_IN | Direction IN (read from the device to the host) |
Enumeration of endpoint types.
The endpoint's type determines the type of transfers to be performed on the
endpoint - bulk, interrupt or isochronous.
| Enum Value | Description |
|---|---|
| ISOCHRONOUS | Isochronous endpoint |
| BULK | Bulk endpoint |
| INTERRUPT | Interrupt endpoint |
Enumeration of endpoint buffering types:
| Enum Value | Description |
|---|---|
| NO_BUFFERING | No buffering |
| DOUBLE_BUFFERING | Double buffering |
Enumeration of endpoint's FIFO (First In First Out) buffer split modes
| Enum Value | Description |
|---|---|
| NO_SPLIT | Do not split the endpoint's FIFO buffer |
| SPLIT | Split the endpoint's FIFO buffer |
The APIs described in this section are defined in
F320
c8051f320.h.
The following preprocessor definitions depict an endpoint's address (i.e. its number):
| Name | Description |
|---|---|
| EP1_IN | Endpoint 1, direction IN - address 0x81 |
| EP1_OUT | Endpoint 1, direction OUT - address 0x01 |
| EP2_IN | Endpoint 2, direction IN - address 0x82 |
| EP2_OUT | Endpoint 2, direction OUT - address 0x02 |
| EP3_IN | Endpoint 3, direction IN - address 0x83 |
| EP3_OUT | Endpoint 3, direction OUT - address 0x03 |
The following preprocessor definitions depict an endpoint's state:
| Name | Description |
|---|---|
| EP_IDLE | The endpoint is idle |
| EP_TX | The endpoint is transferring data |
| EP_ERROR | An error occurred in the endpoint |
| EP_HALTED | The endpoint is halted |
| EP_RX | The endpoint is receiving data |
| EP_NO_CONFIGURED | The endpoint is not configured |
Endpoint interrupt handler function pointer type.
typedef void (*EP_INT_HANDLER)(PEP_STATUS);
Control endpoint (Pipe 0) host command information structure type.
The structure consists of the following members:
| Name | Type | Description |
|---|---|---|
| bmRequestType | BYTE | Request Type: Bit 7: Request direction (0=Host to device - Out, 1=Device to host - In). Bits 5-6: Request type (0=standard, 1=class, 2=vendor, 3=reserved). Bits 0-4: Recipient (0=device, 1=interface, 2=endpoint,3=other). |
| bRequest | BYTE | The specific request |
| wValue | WORD | A WORD-size value that varies according to the request |
| wIndex | WORD | A WORD-size value that varies according to the request. This value is typically used to specify an endpoint or an interface. |
| wLength | WORD | The length (in bytes) of the data segment for the request - i.e. the number of bytes to transfer if there is a data stage |
Endpoint status information structure type, used for IN, OUT and endpoint 0 (control) requests.
The structure consists of the following members:
| Name | Type | Description |
|---|---|---|
| bEp | BYTE | Endpoint address [D.1.2.1] |
| uNumBytes | UINT | Number of bytes available for transfer |
| uMaxP | UINT | Maximum packet size |
| bEpState | BYTE | Endpoint state |
| pData | void* | Pointer to a data buffer used for transferring data to/from the endpoint |
| wData | WORD | Storage for small data packets |
| pfIsr | EP_INT_HANDLER | Interrupt Service Routine (ISR) [D.1.2.3] |
Pointer to an EP_STATUS structure [D.1.2.5].
Interface status structure type.
The structure consists of the following members:
| Name | Type | Description |
|---|---|---|
| bNumAlts | BYTE | Number of alternate settings choices for the interface |
| bCurrentAlt | BYTE | Current active alternate setting for the interface |
| bIfNumber | BYTE | Interface number |
Pointer to an IF_STATUS structure.
PURPOSE
Configure endpoints 1-3 for IN transfers
PROTOTYPE
void WDF_EPINConfig(
PEP_STATUS pEpStatus,
BYTE address,
EP_TYPE type,
int maxPacketSize,
EP_INT_HANDLER pfIsr,
EP_BUFFERING buffering,
EP_SPLIT splitMode);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| PEP_STATUS | Output | |
| BYTE | Input | |
| EP_TYPE | Input | |
| int | Input | |
| EP_INT_HANDLER | Input | |
| EP_BUFFERING | Input | |
| EP_SPLIT | Input |
DESCRIPTION
| Name | Description |
|---|---|
| pEpStatus | Pointer to an endpoint's status information structure [D.1.2.6]. The function updates the structure with the relevant status information. |
| address | Endpoint address [D.1.2.1] |
| type | The endpoint's transfer type [D.1.1.2] |
| maxPacketSize | The endpoint's maximum packet size |
| pfIsr | The endpoint's interrupt handler [D.1.2.3] |
| buffering | The endpoint's buffering type [D.1.1.3] |
| splitMode | The endpoint's split mode [D.1.1.4] |
RETURN VALUE
None
PURPOSE
Configure endpoints 1-3 for OUT transfers
PROTOTYPE
void WDF_EPOUTConfig(
PEP_STATUS pEpStatus,
BYTE address,
EP_TYPE type,
int maxPacketSize,
EP_INT_HANDLER pfIsr,
EP_BUFFERING buffering);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| PEP_STATUS | Output | |
| BYTE | Input | |
| EP_TYPE | Input | |
| int | Input | |
| EP_INT_HANDLER | Input | |
| EP_BUFFERING | Input |
DESCRIPTION
| Name | Description |
|---|---|
| pEpStatus | Pointer to an endpoint's status information structure [D.1.2.6]. The function updates the structure with the relevant status information. |
| address | Endpoint address [D.1.2.1] |
| type | The endpoint's transfer type [D.1.1.2] |
| maxPacketSize | The endpoint's maximum packet size |
| pfIsr | The endpoint's interrupt handler [D.1.2.3] |
| buffering | The endpoint's buffering type [D.1.1.3] |
RETURN VALUE
None
PURPOSE
Halt an endpoint
PROTOTYPE
BYTE WDF_HaltEndpoint(PEP_STATUS pEpStatus);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| PEP_STATUS | Input/Output |
DESCRIPTION
| Name | Description |
|---|---|
| pEpStatus | Pointer to an endpoint's status information structure [D.1.2.6] |
RETURN VALUE
Returns the endpoint's state [D.1.2.2].
PURPOSE
Enable an endpoint
PROTOTYPE
BYTE WDF_EnableEndpoint(PEP_STATUS pEpStatus);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| PEP_STATUS | Input/Output |
DESCRIPTION
| Name | Description |
|---|---|
| pEpStatus | Pointer to an endpoint's status information structure [D.1.2.6] |
RETURN VALUE
Returns the endpoint's state [D.1.2.2].
PURPOSE
Sets the bytes count of an endpoint's FIFO (First In First Out)
buffer.
The call to this function should be preceded by a call to
WDF_FIFOWrite() [D.1.12] in order to update the
endpoint's FIFO buffer with the data to be transferred to the host.
PROTOTYPE
void WDF_SetEPByteCount(BYTE bEp, UINT bytes_count);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input | |
| UINT | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
| bytes_count | Bytes count to set |
RETURN VALUE
None
PURPOSE
Gets the current bytes count of an endpoint's FIFO (First In First
Out) buffer.
This function should be called before calling WDF_FIFORead()
[D.1.13] to read from the endpoint's FIFO buffer, in order
to determine the amount of bytes to read.
PROTOTYPE
UINT WDF_GetEPByteCount(BYTE bEp);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
RETURN VALUE
Returns the endpoint's FIFO bytes count.
PURPOSE
Empties and endpoint's FIFO (First In First Out) buffer
PROTOTYPE
void WDF_FIFOClear(BYTE bEp);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
RETURN VALUE
None
PURPOSE
Checks if an endpoint's FIFO (First In First Out) buffer is
completely full
PROTOTYPE
BOOL WDF_FIFOFull(BYTE bEp);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
RETURN VALUE
Returns TRUE if the endpoint's FIFO buffer is full; otherwise returns FALSE.
PURPOSE
Checks if an endpoint's FIFO (First In First Out) buffer is empty
PROTOTYPE
BOOL WDF_FIFOEmpty(BYTE bEp);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
RETURN VALUE
Returns TRUE if the endpoint's FIFO buffer is empty; otherwise returns FALSE.
PURPOSE
Write data to an endpoint's FIFO (First In First Out) buffer.
The call to this function should be followed by a call to
WDF_SetEPByteCount() [D.1.7].
PROTOTYPE
void WDF_FIFOWrite (BYTE bEp, UINT uNumBytes, BYTE *pData);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input | |
| BYTE* | Input | |
| UINT | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
| pData | Data buffer to write |
| uNumBytes | Number of bytes to write |
RETURN VALUE
None
PURPOSE
Read data from an endpoint's FIFO (First In First Out) buffer.
The call to this function should be preceded by a call to
WDF_GetEPByteCount() [D.1.8] in order to
determine the amount of bytes to read.
PROTOTYPE
void WDF_FIFORead (BYTE bEp, UINT uNumBytes, BYTE *pData);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input | |
| BYTE* | Output | |
| UINT | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
| pData | Buffer to hold the read data |
| uNumBytes | Number of bytes to read from the FIFO buffer |
RETURN VALUE
None
PURPOSE
Gets an endpoint's status information
PROTOTYPE
PEP_STATUS WDF_GetEPStatus(BYTE bEp);
PARAMETERS
| Name | Type | Input/Output |
|---|---|---|
| BYTE | Input |
DESCRIPTION
| Name | Description |
|---|---|
| bEp | Endpoint address [D.1.2.1] |
RETURN VALUE
Returns a pointer to a structure that holds the endpoint's status information [D.1.2.6].
This section describes the WinDriver USB Device generated DriverWizard
firmware API for the Silicon Laboratories C8051F320 development board. The functions
described in this section are declared in the
F320
include
periph.h header
file and implemented in the generated DriverWizard periph.c
file, according to the device configuration information defined in the wizard.
****************************************************************************************
| NOTE | |
| When modifying the generated code, make sure that you comply with your development board's hardware specification - see note in section [12.4.3]. |
PURPOSE
Initializes the device status information to zero (0) and resets all
endpoints
PROTOTYPE
void WDF_USBReset(void);
RETURN VALUE
None
PURPOSE
Handles a SET ADDRESS request
PROTOTYPE
void WDF_SetAddressRequest(void);
RETURN VALUE
None
PURPOSE
Handles a SET ADDRESS request
PROTOTYPE
void WDF_SetFeatureRequest(void);
RETURN VALUE
None
PURPOSE
Handles a CLEAR FEATURE request
PROTOTYPE
void WDF_ClearFeatureRequest(void);
RETURN VALUE
None
PURPOSE
Handles a SET CONFIGURATION request
PROTOTYPE
void WDF_SetConfigurationRequest(void);
RETURN VALUE
None
PURPOSE
Handles a SET DESCRIPTOR request
PROTOTYPE
void WDF_SetDescriptorRequest(void);
RETURN VALUE
None
PURPOSE
Handles a SET INTERFACE request
PROTOTYPE
void WDF_SetInterfaceRequest(void);
RETURN VALUE
None
PURPOSE
Handles a GET STATUS request
PROTOTYPE
void WDF_GetStatusRequest(void);
RETURN VALUE
None
PURPOSE
Handles a GET DESCRIPTOR request
PROTOTYPE
void WDF_GetDescriptorRequest(void);
RETURN VALUE
None
PURPOSE
Handles a GET CONFIGURATION request
PROTOTYPE
void WDF_GetConfigurationRequest(void);
RETURN VALUE
None
PURPOSE
Handles a GET INTERFACE request
PROTOTYPE
void WDF_GetInterfaceRequest(void);
RETURN VALUE
None
Fill in the order form found in Start | WinDriver | Order Form on your Windows start menu, and send it to Jungo via email, fax or mail (see details below).
Your WinDriver package will be sent to you via Fedex or standard postal mail. The WinDriver license string will be emailed to you immediately.
E M A I L
Support: support@jungo.com
Sales: sales@jungo.com
P H O N E / F A X
Phone:
USA (Toll-Free): 1-877-514-0537
Worldwide: +972-9-8859365
Fax:
USA (Toll-Free): 1-877-514-0538
Worldwide: +972-9-8859366
W E B:
P O S T A L A D D R E S S
Jungo Ltd.
P.O.Box 8493
Netanya 42504
ISRAEL
WinDriver is licensed per-seat. The WinDriver license allows one developer on a single computer to develop an unlimited number of device drivers, and to freely distribute the created drivers without royalties, as outlined in the license agreement in the WinDriver/docs/license.txt file.
The most updated WinDriver User's manual can be found on Jungo's site at:
http://www.jungo.com/support/manuals.html#manuals
Version History
If you wish to view WinDriver version history, please refer to
http://www.jungo.com/wdver.html.
Here you will be able to view a list of all new features, enhancements and fixes which have
been added in each WinDriver version.
Technical Documents
For additional information, you may refer to the Technical Documents database on our site at:
http://www.jungo.com/support/tech_docs_indexes/main_index.html.
The Technical Documents database includes detailed descriptions of WinDriver's
features, utilities and APIs and their correct usage, troubleshooting
of common problems, useful tips and answers to frequently asked questions.