IO-Warrior Kit C++ library V1.2.4.

(C) 2003 by Code Mercenaries Hard- 
und Software GmbH
Programming by Yuri Y. Chebotarev

This library is intended to be used with Visual C++ 6.0 and later.

IO-Warrior kit library provides functions which
can be used to work with IO-Warrior.

IO-Warrior library consists of the following functions:

----------------------------------------------------------------------------------

IOWKIT_HANDLE IowKitOpenDevice(VOID);

Open IO-Warrior device.
This function returns an opaque handle for one IO-Warrior or NULL.
If no IO-Warrior is found or something goes wrong (no memory, etc).
Use GetLastError() to get the error code.
If multiple IO-Warriors are present this function will return the handle
for the first IO-Warrior found.

Sample usage:
	IOWKIT_HANDLE ioHandle;

	// Open IO-Warrior device
	ioHandle = IowKitOpenDevice();
	// Check if we opened anything
	if (ioHandle == NULL) {
		... didn't open IoWarrior, handle error
	}


----------------------------------------------------------------------------------
BOOLEAN IowKitSetLegacyOpenMode(ULONG legacyOpenMode);

IowKitSetLegacyOpenMode() sets legacy devices open mode.

legacyOpenMode specifies which open mode to use if old IOW40 chips are present.
IOW_OPEN_SIMPLE - open simple endpoints only.
IOW_OPEN_COMPLEX - open complex endpoints only.
Legacy open mode doesn't affect new IO-Warrior chips which have serial number
support (V1.0.1.0 and later), IOW SDK opens all endpoints for new IOWs.
IowKitSetLegacyOpenMode() returns TRUE if the requested open mode can be set
and FALSE otherwise.
By default IOW SDK opens only simple endpoints on old IOW40 chips, so if you want 
to open the complex endpoints, you must call
IowKitSetLegacyOpenMode(IOW_OPEN_COMPLEX) before calling IowKitOpenDevice().
Note that because the SDK opens only one endpoint for each legacy device,
there will always be only one endpipe for each device, thus you should use 0
as numPipe in calls to IowKitRead/Write() functions.


----------------------------------------------------------------------------------

ULONG IowKitGetNumDevs(VOID);

IOW SDK has support for multiple IOW devices.
To use more than one device it is necessary to enumerate them.
IowKitGetNumDevs() returns the number of IOWs present.


----------------------------------------------------------------------------------

IOWKIT_HANDLE IowKitGetDeviceHandle(ULONG numDevice);

This function returns the device handle for numDevice or NULL if numDevice is
more than number of IO-Warriors present.
Devices are numbered starting from 1 to the number of IOWs present in the system.
The handle returned for each device is used to identify this specific device 
when writing to it or reading from it.


----------------------------------------------------------------------------------

USHORT IowKitGetProductId(IOWKIT_HANDLE iowHandle);

This functions returns the IO-Warrior product ID or zero if the handle is invalid.
Since there can be different kinds of IO-Warrior devices plugged in
(IOW40, IOW24), you should use this function to determine the product ID.


----------------------------------------------------------------------------------

BOOLEAN IowKitGetSerialNumber(IOWKIT_HANDLE iowHandle, PWCHAR serialNumber);

Since there can be many IO-Warrior devices present, the only way to properly
identify them is to use serial numbers.

On success, this function copies the IO-Warrior serial number string to the buffer
and returns TRUE. It fails and returns FALSE if the IO-Warrior doesn't have serial
number, or if either the handle or buffer are invalid.

The buffer must be big enough to hold 9 WCHAR symbols (ie 8 serial number
unicode characters and the ending zero).


----------------------------------------------------------------------------------

VOID IowKitCloseDevice(IOWKIT_HANDLE devHandle);

Close device.
You must call this function when you're done using IO-Warrior in your program.
If multiple IO-Warriors are present all will be closed by this function.

Sample usage:
	// OK, we're done, close IO-Warrior
	IowKitCloseDevice(ioHandle);
	...


----------------------------------------------------------------------------------

ULONG IowKitRead(IOWKIT_HANDLE devHandle, ULONG numPipe, PCHAR buffer, ULONG length);

Read data from IO-Warrior.
This function reads length bytes from IO-Warrior and returns the number of bytes
read if successful.
Note that you must specify the number of the interface (see IO-Warrior specs)
to read from.

It returns the number of bytes read, so you should always check if it reads the correct 
number of bytes, you can use GetLastError() to get error details.

ATTENTION!
Note that this function blocks the current thread until something changes on
IO-Warrior (i.e. until user presses a button connected to an input pin,
or until IIC data arrives), so if you don't want your program to be blocked
you should use a separate thread for reading from IO-Warrior.
If you don't want a blocking read use IowKitReadImmediate (see next).

Sample usage:
		CHAR buffer[5];
		ULONG res;

		// Read 32 bits from IO-Warrior
		if ((res = IowKitRead(ioHandle, 0, &buffer, sizeof(val)) != 5) {
			// Didn't read, handle error
			...
		}


----------------------------------------------------------------------------------

BOOLEAN IowKitReadImmediate(IOWKIT_HANDLE devHandle, PDWORD value);

Return last value read from IO-Warrior.
This function returns the last value read from interface zero.
It returns TRUE if something has been read from interface zero, or
FALSE if nothing was read from interface zero.

There is no non-blocking read for interface 1 (Special Mode Functions).


----------------------------------------------------------------------------------

ULONG IowKitWrite(IOWKIT_HANDLE devHandle, ULONG numPipe, PCHAR buffer, ULONG length);

Write data to IO-Warrior.
This function writes length bytes value to IO-Warrior.
Note that you must specify number of the interface (see IO-Warrior specs)
to write to.

It returns the number of bytes written, so you should always check if it writes 
the correct number of bytes, Use GetLastError() to get error information in case
of an error.

Writing to IO-Warrior is used to set up its pins for input/output and to do
other stuff.

Sample writing to interface zero:
DWORD value consists of 32 bits, which correspond to 32 IO-Warrior pins
and each bit has the following meaning:
To use a pin as an input, set it to 1.
To use a pin as an output, set it to 0.
For example, writing 0 (all 32 bits are zero) to IO-Warrior
sets all pins as outputs driving low (so if you have LEDs connected to
them they will be on).

Writing 0xfffffffful (value in hex, all 32 bits set) sets all pins as inputs.
Note that if you want to use a pin as an input, you must first set it up as input,
in other words, you must write a 1 to it.

Sample code:
	CHAR buffer[5];
	ULONG res;

	// Set 1st pin as input,
	// others as output
	// Report ID 0
	buffer[0] = 0;
	// Set 1st bit
	buffer[1] = 1;
	buffer[2] = 0;
	buffer[3] = 0;
	buffer[4] = 0;
	// Write to IO-Warrior
	if ((res = IowKitWrite(ioHandle, 0, &buffer, sizeof(buffer))) != 5) {
		// Handle error
		...
	}


--------------------------------------------------------------------------------
BOOLEAN IowKitSetTimeout(IOWKIT_HANDLE devHandle, ULONG timeout);
Set read I/O timeout (in milliseconds).

This function sets read I/O timeout value for IO-Warrior.

USB bus can lose USB (HID?) device reports, when used in some hardware
configurations (for example, where there is some data generating
USB device plugged in the same HUB with IO-Warrior).

When applications doesn't get expected report (for example, reply to
IO-Warrior I2C transaction) it blocks until report is received.
Since report has already been lost, this will make app stuck and wait forever.
If you experience such problems you can use SetTimeout() function to handle
"lost reports" problem.

When you set timeout to non-zero value, IowKitRead() will timeout if it
didn't read anything in specified period of time.
If IowKitRead() times out, you have to restart any pending transaction
(for example, I2C write or read transaction) from the beginning.

It's recommended to use 1 second (1000) or bigger timeout values.
