The PortIO95 Parallel Port Interface
Sample Source: writectl.c
/* ****************************************************************************
* writectl.c - This file provides example code illustrating the use of the
* PortIO95 VxD. Its function is to write the ctl register
* (pins 1, 14, 16, 17) of the specified LPT port. The ctl
* register of the parallel port is read/write. This sample
* script only illustrates writing the ctl port. If you hook
* up a series of LED's and 330 ohm resistors as shown below, you
* should be able see this program cycle the LEDS on and off
*
* Pins on the Parallel Port D connector
* 1 14 16 17 18
* | | | | |
* | | | | | Note: V is a LED Diode
* V V V V | Z is a 330 ohm resistor
* | | | | |
* | | | | | Note: Pin 1 is C0, Pin 17 is C3
* Z Z Z Z | Pin 18 is Gnd
* | | | | |
* ----------------------------
*
* As written, this program compiles cleanly under Visual C++ 4.0
* using the command line compiler. It is designed to work only
* with the PortIO95 parallel port handler VxD
*
* Note: This file is best viewed with tab stops of 4
*
* DISCLAIMER !!!
* There is no warranty - you use PortIO95 entirely at your own risk. Net 2000 Ltd. does
* not warrant PortIO95's suitability for any purpose, does not guarantee PortIO95's
* uninterrupted functionality, or even its functionality. Net 2000 Ltd. is not liable
* for any damage or loss that may occur to you, your computer or the things that your
* computer is controlling.
*
* NOTE: This program uses LPT1 by default. See the variable cPortToUse below to change this.
*
* See the PortIO95 documentation and FAQ at http://ds.dial.pipex.com/town/close/ec63 for
* more information.
*
* Copyright (c) 1997 Net 2000 Ltd.
*/
#include
#include
#include
#include
#include "portio95.h"
#define PAUSETIME 250 /* led on time in milli seconds */
/* function prototypes */
void Handle_Error(char *);
/* ##### IMPORTANT ##### Change this to the port you wish to use */
char cPortToUse='1'; /* set it for '1'=LPT1, '2'=LPT2, '3'=LPT3 */
char cOutData; /* use this byte to get data from PortIO95 */
char cInData; /* use this byte to get data from PortIO95 */
/* global variables */
HANDLE hDevice;
void main(int ac, char* av[])
{
BOOL retval;
int i;
DWORD err;
/* Load the name of the vxd in here where we can pass it as a pointer
* Note that the format is really "\\.\VXDNAME.VXD" but we have to
* escape the back slashes with more back slashes because of the
* special significance the backslash has in C */
const PCHAR VxDName = "\\\\.\\PORTIO95.VXD";
printf("\n");
printf("Preparing to Dynamically Load VxD ->%s\n",VxDName);
/* the VxD opens just like a regular file. Windows will look for it as follows:
* * if it has an .VXD extension
* - current directory
* - windows directory
* - on the path (the autoexec.bat one that win95 sees when it starts)
* * if there is no .VXD extension
* - in the registry under the KnownVxD's Key
* see [HAZZAH 227]. The FILE_FLAG_DELETE_ON_CLOSE will cause the VxD to
* be dynamically removed when the program ends. */
hDevice = CreateFile(VxDName, 0,0,0,CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);
/* By now the PortIO95 VxD should be loaded - lets check */
if (hDevice == INVALID_HANDLE_VALUE)
{
/* Get the Last Error Value see also [PortIO95.doc, Appendix A] */
err = GetLastError();
printf("Could Not Load VxD, error=%08lx\n", err );
/* There is one error we have to handle carefully. It implies that
* the PortIO95 VxD was found ok but didn't handle the dyamic
* loading properly. This error shouldn't happen. But if it
* does we cope with it here. We dynamically unload the vxd
* before we exit. NOTE there is no .VXD extension on this call
* otherwise you really do delete the VXD file rather than just
* forcing an unload. */
if (err == ERROR_NOT_SUPPORTED) DeleteFile("\\\\.\\PORTIO95");
exit(1);
}
/* now lets set the PortIO95 Vxd to use an LPT for its Input and output */
retval=DeviceIoControl(hDevice, PORTIO_SETPORT, &cPortToUse, sizeof(cPortToUse), NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_SETPORT");
printf("PortIO95 set to use LPT%c\n",cPortToUse);
/* In order to write from the LPT ports control register we
* must first set the pins up for output. This is required
* due to the design of the PC LPT port. PortIO95 offers
* the ability to mix and match the pins in the control port
* as input and output. - just make calls like:
* PORTIO_SETPIN14INPUT or PORTIO_SETPIN1OUTPUT
* If you try to write to a pin that is set as an input or
* vice-versa an error will be returned. There are also
* functions to set the entire register as input or output.
* We use this in the example below. Note that setting the
* control port up for output has the effect of causing the
* pins to present a logical low (until they are specifically
* set high) to any equipment reading the pins */
retval=DeviceIoControl(hDevice, PORTIO_SET_PINS_1_14_16_17_AS_OUTPUT, NULL, 0, NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_SET_PINS_1_14_16_17_AS_OUTPUT");
/* now lets set pin1 high then low */
retval=DeviceIoControl(hDevice, PORTIO_PIN1HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN1LOW, NULL, 0, NULL, 0, NULL, NULL);
/* now lets set pin14 high then low */
retval=DeviceIoControl(hDevice, PORTIO_PIN14HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN14LOW, NULL, 0, NULL, 0, NULL, NULL);
/* now lets set pin16 high then low */
retval=DeviceIoControl(hDevice, PORTIO_PIN16HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN16LOW, NULL, 0, NULL, 0, NULL, NULL);
/* now lets set pin17 high then low */
retval=DeviceIoControl(hDevice, PORTIO_PIN17HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN17LOW, NULL, 0, NULL, 0, NULL, NULL);
/* now lets write the ctl register in raw mode - we put (the low nibble)
* of the byte we send right into the parallel ports control reg
* Note that pins: 1=bit0, 14=Bit1, 16=Bit2, 17=Bit3. Bits 0,1,3 are
* hardware NOT'ted by the port so will be the opposite to the state set
* ie 0xE will turn bits 0 and 2 on */
cInData=0xE;
retval=DeviceIoControl(hDevice, PORTIO_WRITECREGRAW, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_WRITECREGRAW");
Sleep(PAUSETIME*4); /* wait for a short time */
/* now lets write a nibble out to the ctl register in cooked mode.
* This call is designed to simplify the matter by setting the
* pins to the logical values you provide. Basically PortIO95 does
* some bit twiddling before writing to the ctl port.
*
* Note that pin: 1=bit0, 14=Bit1, 16=Bit2, 17=Bit3 in the input byte.
* Bits 0,1,3 are logically NOT'ted by the VxD and so the
* true pin states will reflect the logical state of the nibble.
* ie 0xA will turn bits 1 and 3 on */
cInData=0xA;
retval=DeviceIoControl(hDevice, PORTIO_SEND_BYTE_TO_PINS1_14_16_17, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_SEND_BYTE_TO_PINS1_14_16_17");
/* unset our port, this is desirable as it resets things */
retval=DeviceIoControl(hDevice, PORTIO_UNSETPORT, NULL, 0, NULL, 0, NULL, NULL);
CloseHandle( hDevice );
}
/* ********************************************************************
* Handle_Error - a simple function to print out errors for us
* Saves having to put this code after every call
*
*/
void Handle_Error(char * szErrStr)
{
printf("%s DeviceIoControl failed, error=%d\n", szErrStr, GetLastError() );
exit (1);
}
[Previous] [PortIO95 Home][PortIO95 Source Home]
[Next]