The PortIO95 Parallel Port Interface
Sample Source: readctl.c
/* ****************************************************************************
* readctl.c - This file provides example code illustrating the use of the
* PortIO95 VxD. Its function is to read 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 reading the ctl port. If you hook
* up a series of switches and 220 ohm resistors as shown below, you
* should be able to affect the results reported by this program.
*
* Pins on the Parallel Port D connector
* 1 14 16 17 18
* | | | | |
* | | | | | Note: \ is a dip switch
* \ \ \ \ | Z is a 220 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"
/* 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 read from the LPT ports control register we
* must first set the pins up for input. 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 input has the effect of causing the
* pins to present a logical high to any equipment reading
* pins 1, 14, 16 and 17 */
retval=DeviceIoControl(hDevice, PORTIO_SET_PINS_1_14_16_17_AS_INPUT, NULL, 0, NULL, 0, NULL, NULL);
if (!retval) Handle_Error("PORTIO_SET_PINS_1_14_16_17_AS_INPUT");
/* now lets read pin 1 as input */
retval=DeviceIoControl(hDevice, PORTIO_READPIN1, NULL, 0, &cOutData, sizeof(cOutData), NULL, NULL);
if (!retval) Handle_Error("PORTIO_READPIN1");
if (cOutData == '\0') printf("Pin 1 is LOW\n");
else printf("Pin 1 is HIGH\n");
/* now lets read pin 14 as input */
retval=DeviceIoControl(hDevice, PORTIO_READPIN14, NULL, 0, &cOutData, sizeof(cOutData), NULL, NULL);
if (!retval) Handle_Error("PORTIO_READPIN14");
if (cOutData == '\0') printf("Pin 14 is LOW\n");
else printf("Pin 14 is HIGH\n");
/* now lets read pin 16 as input */
retval=DeviceIoControl(hDevice, PORTIO_READPIN16, NULL, 0, &cOutData, sizeof(cOutData), NULL, NULL);
if (!retval) Handle_Error("PORTIO_READPIN16");
if (cOutData == '\0') printf("Pin 16 is LOW\n");
else printf("Pin 16 is HIGH\n");
/* now lets read pin 17 as input */
retval=DeviceIoControl(hDevice, PORTIO_READPIN17, NULL, 0, &cOutData, sizeof(cOutData), NULL, NULL);
if (!retval) Handle_Error("PORTIO_READPIN17");
if (cOutData == '\0') printf("Pin 17 is LOW\n");
else printf("Pin 17 is HIGH\n");
/* now lets read the ctl register in raw mode - we get exactly what the
* LPT port thinks it has there - the VxD does nothing but read.
* 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 true state */
retval=DeviceIoControl(hDevice, PORTIO_READCREGRAW, NULL, 0, &cOutData, sizeof(cOutData), NULL, NULL);
if (!retval) Handle_Error("PORTIO_READCREGRAW");
printf("The raw C Register is: 0x%X hex\n",cOutData);
/* now lets read the ctl register in cooked mode. This call is designed
* to provide a logical 4 bit input mechanism. Thus the values of the
* Ctrl Register bits are flipped (where necessary) by the PortIO95 VxD
* so that a nice 4 bit nibble is composed and returned
* to the calling program.
*
* Note that pin: 1=bit0, 14=Bit1, 16=Bit2, 17=Bit3 in the returned byte.
* Bits 0,1,3 are logically re-NOT'ted by the VxD and so the returned
* value will reflect the true pin state. All unused bits will be 0. */
retval=DeviceIoControl(hDevice, PORTIO_READCREG, NULL, 0, &cOutData, sizeof(cOutData), NULL, NULL);
if (!retval) Handle_Error("PORTIO_READCREG");
printf("The cooked C Register is: 0x%X hex\n",cOutData);
/* now lets read 8 bits of input. PORTIO_READ_CS_BYTE call will take
* the contents of the status and control registers and assemble it
* into an 8 bit byte. This byte always compensates for any
* hardware inversion (NOT'ting) of the pins and gives you
* bits that reflect the true state of the pins. Basically the
* bit to pin mapping works as follows:
*
* 15=bit0, 13=Bit1, 12=Bit2, 11=Bit3 1=bit4, 14=Bit5, 16=Bit6, 17=Bit7
*
* Basically the status register (minus pin 6 which can be used as an
* interrupt trigger) is the low nibble and the control register
* is the high nibble. Note: the Control Register Pins _MUST_
* be set as inputs here or an error will be returned */
retval=DeviceIoControl(hDevice, PORTIO_READ_CS_BYTE, NULL, 0, &cOutData, sizeof(cOutData), NULL, NULL);
if (!retval) Handle_Error("PORTIO_READ_CS_BYTE");
printf("The CS Byte is: 0x%X hex\n",(char)cOutData);
/* 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]