Beyond Logic



Win NT/2000/XP Driver for DeVaSys USBLPTPD11(D) USB Development Boards

USBLPTPD11.SYS is a Windows NT/2000/XP driver for the DeVaSys USBLPT-PD11 series of USB Development Boards. A device driver is needed for protected operating systems such as Windows NT, Windows 2000 and Windows XP as direct I/O access is prohibited and will cause a privileged instruction exception. (See Porttalk for further information.) The driver has been designed to be as painless and transparent as possible. On loading, the driver will interrogate your operating system and parport.sys to obtain the number of parallel ports you have and their parameters. Handles to the driver can then be made by opening "\\.\usblptpd11_x" where x defines your LPT port number minus 1. e.g. opening usblptpd11_0 opens a handle to the device on LPT1, usblptpd11_1 for the device on LPT2 etc.

This allows unlimited number of USBLPTPD11(D) devices to be used concurrently, the only limitations reflect the number of parallel ports your system has. On opening a handle to the driver, it will try to acquire the port from parport.sys. If this is successful, you will be able to successfully create a handle to the driver. If not, you either have another program accessing this driver handle or you have a parallel port device using the same parallel port. On closing the handle to USBLPTPD11, the driver will release the port so other parallel devices can access the parallel port.


USBLPT-PD11 by DeVaSys

As the USBLPTPD11 driver communicates with parport.sys, there is no need to pass the driver a Port Address or Interrupt number. The driver will obtain these details from parport.sys on loading. Simply, if your existing LPT1 port works, simply connect the DeVaSys USBLPTPD11(D) board to your system and open the handle for LPT1. If you change Parallel Port details after the driver has been loaded, these changes will not be reflected by the USBLPTPD11 driver until the driver is reloaded.

Interrupt support has been provided in the driver. However Windows 2000 and Windows XP defaults to "Never use an interrupt" under the settings for the Parallel Ports in Device Manager. If you intend to use interrupts that are recommended, please change your ports to either "Try not to use an Interrupt" or "Use any interrupt assigned to the port". As Windows 2000 and XP has a bug, you will need to reboot the machine after making these changes as the O/S increments the number of parallel ports you have, even though you have only changed itís parameters. The driver protects against this bug.

If your system is set up not to use interrupts, a call to Wait_for_interrupt will return immediately. As most PDIUSBPD11 routines will simply read the interrupt register and act if a condition exists, calling the wait_for_interrupt IOCTL call will be transparent in systems that support interrupts and those systems who donít.

Starting and installing the driver

In most cases, the USBLPTPD11.SYS driver isn't required to be explicitly installed. When running the usermode executable such as hidmouse.exe, it will check for the device driver and if it cannot be opened, it will install and start the driver for you. However for this to happen correctly, the USBLPTPD11.SYS driver must be in the same directory than the usermode executable and the user must have administrator privileges. It is also wise to run it from a fixed disk, preferably your main system volume. While this will not effect operation for the first time, when Windows next loads it will try to load the driver at bootup and report a failure in your event viewer. It will not cause damage to your system, only an annoying message each time you boot.

Once the driver has been installed for the first time, any user with normal user privileges can access the device driver normally. This is ideal in classroom and corporate environments where security is paramount. The driver can also be installed manually using the registry file included. Copy the USBLPTPD11.SYS to your /system32/drivers directory and click on the USBLPT.REG file to load the required registry keys. Then reboot the computer and on boot-up the USBLPTPD11.SYS driver will load and start automatically. This is recommended for classroom/corporate use where the driver can be stored away securely in the system directory.

Checked and Free Driver Versions

Two versions of the driver exists. The standard distribution is a free compiled version which has debugging statements removed and thus executes faster. However when writing your own code, or debugging problems, a checked version of the driver is provided which displays debugging messages such as which call is being made, if the interrupt service routine was called or the I2C_Read and I2C_Write functions including the number of bytes to send/receive and the byDevID. These debug messages can be read with any good debug viewer. One such recommended viewer is the System Internals DebugView which can be downloaded from their website - www.sysinternals.com for free.

Capture of DebugView showing USBLPTPD11.SYS debug info

The checked build of the driver is provided in the checked folder of the distribution. Simply replace the USBLPTPD11.SYS with this driver and reload to display debug information.

Recompiling the code

The code for the device driver has been compiled using Microsoft Visual C and the Windows 2000 DDK. The source code is provided, but during the normal development cycle it is not required to be recompiled. The usermode program, hidmouse.exe in which all the development work is done will need to be recompiled in order to make changes. The code was originally compiled in Borland C 5.02. Borland offers their Borland C++ 5.5 command line compiler tools for download from their web site free of charge. A make file has been included for the command line compiler. To rebuild the code using the free Borland C 5.5 compiler use

	MAKE -f hidmouse.mak

on the command line, otherwise use your perfered development enviroment.

Testing it out

The distribution comes with two files, hidmouselpt1.exe and hidmouselpt2.exe based on DeVaSys's HIDMouse source. Permission has been sought to redistribute these files with the driver. However please note that the source code remains Copyright of DeVaSys. Please see the header files for more information.

To test out the driver and your board, simply run hidmouselpt1.exe for a DeVaSys board connected to LPT1. You should see a dump of the enumeration as shown below, then your device enumerates as a mouse, and you pointer starts moving in a small square pattern.

    
    USBLPT-PD11 Cypress Mouse Emulation, Copyright 2001 DeVaSys
    USBLPT-PD11: The USBLPT-PD11 driver is already running.
    
    PDIUSBD11 Reset - Configured USB waiting for Connection
     wIrq = 0x4000  A bus reset occured - Reinitalising PDIUSBD11
    
    PDIUSBD11 Reset - Configured USB waiting for Connection
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Get Descriptor (device)
                                           64 USB_CtlTx Loading first 8 bytes
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 10 Sending packet of 8 bytes p=0x40C6B8
     wIrq = 0x4000  A bus reset occured - Reinitalising PDIUSBD11
    
    PDIUSBD11 Reset - Configured USB waiting for Connection
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Set Address 
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Set Device Address 82
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Get Descriptor (device) 18 
                                           USB_CtlTx Loading first 8 bytes
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 10 Sending packet of 8 bytes p=0x40C6B8
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Sending last 2 bytes at p=0x40c6c0
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 41
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) RdEpIdx02 Null { 0x00, 0x00 } 
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Get Descriptor (configuration) 9 
                                           USB_CtlTx Loading first 8 bytes
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Sending last 1 bytes at p=0x40c6ca
     wIrq = 0x000c  Irq - Ep0_Out (EpIdx2) Standard Device request - Get Descriptor (configuration) 255 
                                           USB_CtlTx Loading first 8 bytes 
                    Irq - Ep0_In  (EpIdx3) 26 Sending packet of 8 bytes p=0x40C6CA
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 18 Sending packet of 8 bytes p=0x40C6D2
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 10 Sending packet of 8 bytes p=0x40C6DA
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Sending last 2 bytes at p=0x40c6e2
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 41
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) RdEpIdx02 Null { 0x00, 0x00 } 
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Get Descriptor (device) 18 
                                           USB_CtlTx Loading first 8 bytes
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 10 Sending packet of 8 bytes p=0x40C6B8
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Sending last 2 bytes at p=0x40c6c0
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 41
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Get Descriptor (configuration) 9 
                                           USB_CtlTx Loading first 8 bytes
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Sending last 1 bytes at p=0x40c6ca
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 1
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) RdEpIdx02 Null { 0x00, 0x00 } 
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Get Descriptor (configuration) 34 
                                           USB_CtlTx Loading first 8 bytes
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 26 Sending packet of 8 bytes p=0x40C6CA
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 18 Sending packet of 8 bytes p=0x40C6D2
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 10 Sending packet of 8 bytes p=0x40C6DA
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Sending last 2 bytes at p=0x40c6e2
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 41
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) RdEpIdx02 Null { 0x00, 0x00 } 
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Device request - Set Configuration  Setup - Set 
                                           Standard Device Configuration 1 
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 41
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Class Interface request - Idle 
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 41
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) Standard Interface request - Get Descriptor (report) 
                                           USB_CtlTx Loading first 8 bytes
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 42 Sending packet of 8 bytes p=0x40C6EC
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 34 Sending packet of 8 bytes p=0x40C6F4
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 26 Sending packet of 8 bytes p=0x40C6FC
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 18 Sending packet of 8 bytes p=0x40C704
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) 10 Sending packet of 8 bytes p=0x40C70C
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) Sending last 2 bytes at p=0x40c714
     wIrq = 0x0008  Irq - Ep0_In  (EpIdx3) End of Transmission, Getting Status Byte 41
     wIrq = 0x0004  Irq - Ep0_Out (EpIdx2) RdEpIdx02 Null { 0x00, 0x00 } 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
     wIrq = 0x0010  Irq - Ep1_In  (EpIdx4) Sending Mouse Report of size 3 bytes 
    

Downloading the Source, Drivers and Usermode Programs

  • Version 1.2, 140K bytes
    • Revision History
      • 10th November 2001 - Version 1.2.
        • Modified usermode source code to compile with Visual C, Borland C 5.01 and the free Borland C 5.5 Command Line Compiler.
      • 4th November 2001 - Version 1.1.
        • Improved automatic loading of driver. Now copies USBLPTPD11.SYS to /system32/drivers directory on first install.
        • Added usblpt.reg which was omitted from version 1.0
        • Re-tested on Windows 2000 SP2 and Windows XP RTM.
      • 31st October 2001 - First official release, version 1.0.
        • Added parport.sys support enabling more than one USBLPT-PD11 device to be used at the same time.
        • Added interrupt support.
        • Tested on Windows 2000 SP2 and Windows XP RTM.
      • 22nd October 2001 Ė Beta release 0.1.
        • Tested I2C Routines.
        • Required Port Address to be passed to driver.
        • Tested on Windows 2000 SP2 and Windows XP RC1.

    Where can I buy one of these USBLPT-PD11 things?

    The USBLPT-PD11 USB development board is avaliable from DeVaSys Embedded Systems in two versions, a desktop and a dongle version. The dongle version starts at $59US.



    A special thanks to Michael DeVault from DeVaSys Embedded Systems for sending out a USB I2C/IO Interface Board, USBLPT-PD11 USB development board (desktop version) and a USBLPT-PD11D, USB development board (dongle version) for evaluation.



    Copyright 2001-2005 Craig Peacock 15th June 2005.