The PortIO95 Parallel Port Interface
Sample Source: writedat.c
/* ****************************************************************************
* writedat.c - This file provides example code illustrating the use of the
* PortIO95 VxD. Its function is to cycle through the pins on the
* data register of the specified LPT port setting each one on in
* turn. If you hook up a series of LEDs and 330 ohm resistors as
* shown below, you should see the lights cycle on and off in sequence.
*
* Pins on the Parallel Port D connector
* 2 3 4 5 6 7 8 9 18
* | | | | | | | | |
* | | | | | | | | | Note: V is a LED Diode
* V V V V V V V V | Z is a 330 ohm resistor
* | | | | | | | | |
* | | | | | | | | | Note: Pin 2 is D0, Pin 9 is D7
* Z Z Z Z 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 cInData; ; /* use this byte to send data to 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);
/* first we will write a zero byte to pins 2 to 9 to turn
* them all off. The byte we write here overwites the existing
* output byte. This has the effect of setting pins 2-9 low */
cInData=0; /* output a zero to the register */
retval=DeviceIoControl(hDevice, PORTIO_SEND_BYTE_TO_PINS2_TO_9, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_SEND_BYTE_TO_PINS2_9");
/* this loop will execute 3 times turning each led on and off in turn
* with a short pause bettween each activation. Not too elegant as code,
* but serves the purpose none the less. You could add the checks to
* the retval here (the same as shown above on the PORTIO_SEND_BYTE_TO_PINS2_TO_9 call) if you wish.
* The PORTIO_PIN*HIGH and PORTIO_PIN*LOW calls affect only the specified pins
* the other pins on the LPT port are unaffected */
for (i=0; i<3; i++)
{
retval=DeviceIoControl(hDevice, PORTIO_PIN2HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN2LOW, NULL, 0, NULL, 0, NULL, NULL);
retval=DeviceIoControl(hDevice, PORTIO_PIN3HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN3LOW, NULL, 0, NULL, 0, NULL, NULL);
retval=DeviceIoControl(hDevice, PORTIO_PIN4HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN4LOW, NULL, 0, NULL, 0, NULL, NULL);
retval=DeviceIoControl(hDevice, PORTIO_PIN5HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN5LOW, NULL, 0, NULL, 0, NULL, NULL);
retval=DeviceIoControl(hDevice, PORTIO_PIN6HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN6LOW, NULL, 0, NULL, 0, NULL, NULL);
retval=DeviceIoControl(hDevice, PORTIO_PIN7HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN7LOW, NULL, 0, NULL, 0, NULL, NULL);
retval=DeviceIoControl(hDevice, PORTIO_PIN8HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN8LOW, NULL, 0, NULL, 0, NULL, NULL);
retval=DeviceIoControl(hDevice, PORTIO_PIN9HIGH, NULL, 0, NULL, 0, NULL, NULL);
Sleep(PAUSETIME); /* wait for a short time */
retval=DeviceIoControl(hDevice, PORTIO_PIN9LOW, NULL, 0, NULL, 0, NULL, NULL);
}
cInData=0xAA; /* turn every second pin off */
retval=DeviceIoControl(hDevice, PORTIO_SEND_BYTE_TO_PINS2_TO_9, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_SEND_BYTE_TO_PINS2_9");
Sleep(4*PAUSETIME); /* wait for a short time */
cInData=0x55; /* turn every other second pin off */
retval=DeviceIoControl(hDevice, PORTIO_SEND_BYTE_TO_PINS2_TO_9, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_SEND_BYTE_TO_PINS2_9");
Sleep(4*PAUSETIME); /* wait for a short time */
/* make sure all of the Data Register Bytes are turned off */
cInData=0; /* output a zero to the register */
retval=DeviceIoControl(hDevice, PORTIO_WRITEDREG, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_WRITEDREG");
/* unset our port, this is desireable 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]