// Test_misc.cpp
//
// Generated by DriverWizard version DriverStudio 3.0.0 (Build 1268)
//
// This console application demonstrates how to open a handle
// to a device in your driver, and communicate with the driver
// using Read, Write, and DeviceIoControl calls, as appropriate.
//
// This test program attempts to open the device with link name
// MiscDevice, which corresponds to Unit 0 of the
// MiscDevice device class in the driver.

//
// You can build this application using the command line compiler with
// the following command:
//
//		cl Test_misc.cpp
//


#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <conio.h>

#include <winioctl.h>
#include "kommiscioctl.h"


typedef void VOIDFUNC();

// Prototypes
void Usage(void);
void ShowIoctlValues(void);

//	TODO:
//		You can redefine the IOCTL handler prototypes as needed, adding
//		appropriate parameters that can be collected from the command line.
//		To do this you must modify the command line parsing logic.  An
//		example of this is shown in comments throughout the test application.
//
//=== Parameterized IOCTL Example ===
// void Test_IOCTL_PARAMETERIZED(int nVal, ULONG dwVal);
void Test_MISC_IOCTL_WDG_SET_TIMEOUT(void);
void Test_MISC_IOCTL_WDG_RETRIGGER(void);
void Test_MISC_IOCTL_WDG_START(void);
void Test_MISC_IOCTL_WDG_CHECK_FOR_TIMEOUT(void);
void Test_MISC_IOCTL_WDG_GET_CONFIG(void);
void Test_MISC_IOCTL_HSWP_GET_HANDLE_STATE(void);
void Test_MISC_IOCTL_HSWP_SET_LED(void);
void Test_MISC_IOCTL_HSWP_GET_LED(void);
void Test_MISC_IOCTL_USR_SET_LED(void);
void Test_MISC_IOCTL_BOARD_GET_ID(void);
void Test_MISC_IOCTL_USR_GET_OVRTEMP_LED(void);
void Test_MISC_IOCTL_USR_ASGN_OVRTEMP_LED(void);
void Test_MISC_IOCTL_WDG_GET_HWRESET(void);
void CloseIfOpen(void);
UINT TestWatchdog(void);
DWORD WINAPI WaitForTimeout(LPVOID lpParameter);
// Global data


#define N_IOCODES	13

// Names of IOCTL codes
//
char *IOnames[N_IOCODES+1] =
{

//=== Parameterized IOCTL Example ===
//	"IOCTL_PARAMETERIZED",
	"KOMMISC_IOCTL_WDG_SET_TIMEOUT",
	"KOMMISC_IOCTL_WDG_RETRIGGER",
	"KOMMISC_IOCTL_WDG_START",
	"KOMMISC_IOCTL_WDG_CHECK_FOR_TIMEOUT",
	"KOMMISC_IOCTL_WDG_GET_CONFIG",
	"KOMMISC_IOCTL_HSWP_GET_HANDLE_STATE",
	"KOMMISC_IOCTL_HSWP_SET_LED",
	"KOMMISC_IOCTL_HSWP_GET_LED",
	"KOMMISC_IOCTL_USR_SET_LED",
	"KOMMISC_IOCTL_BOARD_GET_ID",
	"KOMMISC_IOCTL_USR_GET_OVRTEMP_LED",
	"KOMMISC_IOCTL_USR_ASGN_OVRTEMP_LED",
	"KOMMISC_IOCTL_WDG_GET_HWRESET"
	""
};

// IOCTL codes
//
int IOcodes[N_IOCODES+1] =
{

//=== Parameterized IOCTL Example ===
//	IOCTL_PARAMETERIZED,
	KOMMISC_IOCTL_WDG_SET_TIMEOUT,
	KOMMISC_IOCTL_WDG_RETRIGGER,
	KOMMISC_IOCTL_WDG_START,
	KOMMISC_IOCTL_WDG_CHECK_FOR_TIMEOUT,
	KOMMISC_IOCTL_WDG_GET_CONFIG,
	KOMMISC_IOCTL_HSWP_GET_HANDLE_STATE,
	KOMMISC_IOCTL_HSWP_SET_LED,
	KOMMISC_IOCTL_HSWP_GET_LED,
	KOMMISC_IOCTL_USR_SET_LED,
	KOMMISC_IOCTL_BOARD_GET_ID,
	KOMMISC_IOCTL_USR_GET_OVRTEMP_LED,
	KOMMISC_IOCTL_USR_ASGN_OVRTEMP_LED,
	KOMMISC_IOCTL_WDG_GET_HWRESET,
	0
};

char *TimeoutSetting[12] =
{
	"000.125 sec",
	"000.250 sec",
	"000.500 sec",
	"1 sec",
	"2 sec",
	"4 sec",
	"8 sec",
	"16 sec",
	"32 sec",
	"64 sec",
	"128 sec",
	"256 sec"
};

// Handle to device opened in driver.
//
HANDLE	hDevice = INVALID_HANDLE_VALUE;

// Name used to open device
//
char *sLinkName = "\\\\.\\kommisc0";
ULONG nBoardVersion;
int tout,hwreset;

////////////////////////////////////////////////////////////////////////
// OpenByName
//
//		Open a handle to the requested device
//
HANDLE OpenByName(void)
{
	// Create a handle to the driver
	return CreateFile(sLinkName,
					  GENERIC_READ | GENERIC_WRITE,
					  FILE_SHARE_READ,
					  NULL,
					  OPEN_EXISTING,
					  0,
					  NULL);
}



////////////////////////////////////////////////////////////////////////
// Exit
//
//		Print a message and exit
//
   void Exit(int res)
{
	printf("\nExiting...\n\n");
	CloseIfOpen();
	exit(res);
}


////////////////////////////////////////////////////////////////////////
// Main entry point
//
//
int __cdecl main(int argc, char *argv[])
{
	int		nArgIndex;				// Walk through command line arguments
	int		nArgIncrement = 0;
	int		val;

//=== Parameterized IOCTL Example ===
//	int		nVal;
//	ULONG	dwVal;

	printf("Test application Test_misc starting...\n");

	hDevice = OpenByName();
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("ERROR opening device: (0x%0x) returned from CreateFile\n", GetLastError());
		Exit(1);
	}
	else
	{
		printf("--KOMmisc Device found, handle open.\n\n");
	}

	// Parse the command line

	if (argc < 2) Usage();

	nArgIndex = 1;
	while (nArgIndex < argc)
	{
		// Parse ahead to determine numeric value of argument

		if (nArgIndex+1 >= argc) Usage();
		if (!isdigit(argv[nArgIndex+1][0])) Usage();
		val = atoi(argv[nArgIndex+1]);

		switch (argv[nArgIndex][0])
		{

			case 'r':
			case 'R':
				printf("Driver does not have a read handler\n");
				nArgIncrement = 2;
				break;

			case 'w':
			case 'W':
				printf("Driver does not have a write handler\n");
				nArgIncrement = 2;
				break;

			case 't':
            case 'T':

				
				if(!TestWatchdog()==ERROR_SUCCESS)
				{
					printf("ERROR: %d\n",GetLastError());	
				}
				Exit(1);
				break;

			case 'i':
			case 'I':
				if (val >= N_IOCODES)
				{
					printf("IO control code index must be less than %d\n", N_IOCODES);
					ShowIoctlValues();
					Exit(1);
				}
				switch (IOcodes[val])
				{

//=== Parameterized IOCTL Example ===
//					case IOCTL_PARAMETERIZED:
//						if (nArgIndex+3 >= argc) Usage();
//						nVal = atoi(argv[nArgIndex+2]);
//						dwVal = strtoul(argv[nArgIndex+3], NULL, 0);
//						Test_IOCTL_PARAMETERIZED(nVal, dwVal);
//						nArgIncrement = 4;
//						break;

					case KOMMISC_IOCTL_WDG_SET_TIMEOUT:
						Test_MISC_IOCTL_WDG_SET_TIMEOUT();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_WDG_RETRIGGER:
						Test_MISC_IOCTL_WDG_RETRIGGER();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_WDG_START:
						Test_MISC_IOCTL_WDG_START();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_WDG_CHECK_FOR_TIMEOUT:
						Test_MISC_IOCTL_WDG_CHECK_FOR_TIMEOUT();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_WDG_GET_CONFIG:
						Test_MISC_IOCTL_WDG_GET_CONFIG();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_HSWP_GET_HANDLE_STATE:
						Test_MISC_IOCTL_HSWP_GET_HANDLE_STATE();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_HSWP_SET_LED:
						Test_MISC_IOCTL_HSWP_SET_LED();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_HSWP_GET_LED:
						Test_MISC_IOCTL_HSWP_GET_LED();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_USR_SET_LED:
						Test_MISC_IOCTL_USR_SET_LED();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_BOARD_GET_ID:
						Test_MISC_IOCTL_BOARD_GET_ID();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_USR_GET_OVRTEMP_LED:
						Test_MISC_IOCTL_USR_GET_OVRTEMP_LED();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_USR_ASGN_OVRTEMP_LED:
						Test_MISC_IOCTL_USR_ASGN_OVRTEMP_LED();
						nArgIncrement = 2;
						break;

					case KOMMISC_IOCTL_WDG_GET_HWRESET:
						Test_MISC_IOCTL_WDG_GET_HWRESET();
						nArgIncrement = 2;
						break;

					default:
						printf("IO control code not valid\n");
						Exit(1);

				}
				break;

			case '?':
			case 'h':
			default:
				Usage();
		}
		nArgIndex += nArgIncrement;
	}

	return 0;
}


////////////////////////////////////////////////////////////////////////
// CloseIfOpen
//
//		Close the device if we previously opened a handle to it.
//
void CloseIfOpen(void)
{
	if (hDevice != INVALID_HANDLE_VALUE)
	{
		// Close the handle to the driver
		if (!CloseHandle(hDevice))
		{
			printf("ERROR: CloseHandle returns 0x%0x.\n", GetLastError());
		}
		hDevice = INVALID_HANDLE_VALUE;
	}
}






////////////////////////////////////////////////////////////////////////
// Usage
//
//		Print a usage message describing arguments to this program
//
void Usage(void)
{
	printf("Usage: Test_misc [i n]\n");
	printf("       i initiates an IO Control Code message with specified index value\n");
	ShowIoctlValues();
	printf("Example:\n");
	printf("    Test_misc i 8\n");
	printf("for TEST of Watchdog: enter   test_misc t 0\n");
	

	Exit(1);
}



#define	IOCTL_INBUF_SIZE	512
#define	IOCTL_OUTBUF_SIZE	512

//=== Parameterized IOCTL Example ===
//void Test_IOCTL_PARAMETERIZED(int nVal, ULONG dwVal)
//{
//  Function body same as other IOCTL handlers, with command line
//	parameters 'nVal' and 'dwVal' available as input.
//}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_WDG_SET_TIMEOUT
//
// Valid for CP6000,605,306,304,304, 6500V
// 
// Comments: Sets selected timeout

void Test_MISC_IOCTL_WDG_SET_TIMEOUT(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application

	
	
	ULONG	nOutput;						// Count written to bufOutput
	ULONG   nInput;
	int i;




	for (i=0; i<12; i++)
	{
		if (i==0)
			printf( "         Watchdog Timeout Settings:\n");
		printf( "           %d = %s \n", i, TimeoutSetting[i] );
	}


	printf("new Timeout selection?: ");
	scanf("%d",&nInput);

	// Call device IO Control interface (MISC_IOCTL_WDG_SET_TIMEOUT) in driver
	printf("Issuing Ioctl KOMMISC_IOCTL_WDG_SET_TIMEOUT to device - \n");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_SET_TIMEOUT,
						 &nInput,
						 sizeof(ULONG),//IOCTL_INBUF_SIZE,
						 NULL,
						 0,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
	{
		printf("done - no errors");
	}
}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_WDG_RETRIGGER
//
// Valid for CP6000,605,306,304,304, 6500V
// 
// Comments: retriggers watchdog
//
void Test_MISC_IOCTL_WDG_RETRIGGER(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application


	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (MISC_IOCTL_WDG_RETRIGGER) in driver
	printf("Issuing Ioctl KOMMISC_IOCTL_WDG_RETRIGGER to device - ");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_RETRIGGER,
						 NULL,
						 0,
						 NULL,
						 0,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
		printf("\ndone - Watchdog retriggered again!");
}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_WDG_START
//
// Valid for CP6000,605,306,304,304, 6500V
// 
// Comments: Starts the Watchdog

void Test_MISC_IOCTL_WDG_START(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application

	//CHAR	bufInput[IOCTL_INBUF_SIZE];		// Input to device
	//CHAR	bufOutput[IOCTL_OUTBUF_SIZE];	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (MISC_IOCTL_WDG_START) in driver
	printf("Issuing Ioctl KOMMISC_IOCTL_WDG_START to device - \n");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_START,
						 NULL,
						 0,
						 NULL,
						 0,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
		printf("     done - Watchdog is enabled.\n");
}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_WDG_CHECK_FOR_TIMEOUT
//
// Valid for CP6000,605,306,304,304, 6500V
// 
// Comments: shows weather a timeout occured.

void Test_MISC_IOCTL_WDG_CHECK_FOR_TIMEOUT(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application

	
	CHAR	bufOutput[IOCTL_OUTBUF_SIZE];	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (MISC_IOCTL_WDG_CHECK_FOR_TIMEOUT) in driver
	printf("Issuing Ioctl MISC_IOCTL_WDG_CHECK_FOR_TIMEOUTto device - \n");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_CHECK_FOR_TIMEOUT,
						 NULL,
						 0,
						 bufOutput,
						 IOCTL_OUTBUF_SIZE,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
		if ((int)bufOutput[0] == 0) 
			printf("     no timeout occured (%d)\n", (int) bufOutput[0]);
		else
			printf("     Timeout triggered! (%d)\n", (int) bufOutput[0]);

}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_WDG_GET_CONFIG
//
// Valid for CP6000,605,306,304,304,6500V
// 
// Comments: This IOCTL retrieves Watchdog status, timeout setting and hardware reset status 

void Test_MISC_IOCTL_WDG_GET_CONFIG(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application

	
	tMiscWdgConfig	bufOutput;				// Output from device
	ULONG	nOutput;						// Count written to bufOutput



	// Call device IO Control interface (MISC_IOCTL_WDG_GET_CONFIG) in driver
	printf("Issuing Ioctl KOMMISC_IOCTL_WDG_GET_CONFIG to device - \n");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_GET_CONFIG,
						 NULL,
						 0,
						 &bufOutput,
						 sizeof(bufOutput),
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
	{
		if (TRUE == bufOutput.bEnable)
			printf("    Attention: Watchdog timer is enabled:\n");
		else
			printf("    Watchdog timer is disabled!\n");

		printf("        Timeout setting: %s\n\n",TimeoutSetting[(int)bufOutput.bTimeout]);

		tout = (int)bufOutput.bTimeout;
	}

	//check harware reset condition
	Test_MISC_IOCTL_WDG_GET_HWRESET();
}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_HSWP_GET_HANDLE_STATE
//
// Valid for CP6000,605,306,304,304
// 
// Comments:This IOCTL retrieves the present status (locked/unlocked) of the
//			Hotswap Handle

void Test_MISC_IOCTL_HSWP_GET_HANDLE_STATE(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application

	
	CHAR	bufOutput[IOCTL_OUTBUF_SIZE];	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (MISC_IOCTL_HSWP_GET_HANDLE_STATE) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_HSWP_GET_HANDLE_STATE,
						 NULL,
						 0,
						 bufOutput,
						 IOCTL_OUTBUF_SIZE,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
	{
		if ((int)bufOutput[0] == 0)
			printf("HotSwap handle: UNLOCKED! (%d)\n", (int) bufOutput[0]);
		else
			printf("HotSwap handle: locked (%d)\n", (int) bufOutput[0]);
	}
}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_HSWP_SET_LED
//
// Valid for CP605,306,304,304
// 
// Comments:This IOCTL switches the Hotswap LED on/off
//	
// Note:	Not for CP6000; the register is read-only!
		
void Test_MISC_IOCTL_HSWP_SET_LED(void)
{
	int Val;
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application
	CHAR	bufInput[IOCTL_INBUF_SIZE];		// Input to device
	
	ULONG	nOutput;						// Count written to bufOutput

	printf("Set(1) or clear(0) LED:\n");
	scanf("%d",&Val);

	if(Val)
		bufInput[0] = 1;
	else
		bufInput[0] = 0;

	// Call device IO Control interface (MISC_IOCTL_HSWP_SET_LED) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_HSWP_SET_LED,
						 bufInput,
						 IOCTL_INBUF_SIZE,
						 NULL,
						 0,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_HSWP_GET_LED
//
// Valid for CP6000,605,306,304,304
// 
// Comments:This IOCTL retrieves the present status (on/off) of the
//			Hotswap LED

void Test_MISC_IOCTL_HSWP_GET_LED(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application

	
	CHAR	bufOutput[IOCTL_OUTBUF_SIZE];	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (MISC_IOCTL_HSWP_GET_LED) in driver
	printf("Issuing Ioctl KOMMISC_IOCTL_HSWP_GET_LED to device - ");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_HSWP_GET_LED,
						 NULL,
						 0,
						 bufOutput,
						 IOCTL_OUTBUF_SIZE,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
	{
		if ((int)bufOutput[0] == 0) 
			printf("LED state: OFF (%d)\n", (int) bufOutput[0]);
		else
			printf("LED state: ON (%d)\n", (int) bufOutput[0]);
	}
}


////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_USR_SET_LED
//
// Valid for CP6000,605,306,304,304
// 
// Comments:This IOCTL allows to switch the user LED's on/off.
//          Single,several or all LED's can be switched simultanously by
//			selecting a number between 1 and 255. In order to calculate
//			the number for serveral LED's, just add up the individual values
//			of the desired LED's (see list below).
// Note:	Only CP6000 has 8 LED's available, CP605,306,304,304 have only 2 LED's
			 	 
void Test_MISC_IOCTL_USR_SET_LED(void)
{
	int Val,LedNo;

// Note that Input and Output are named from the point of view
// of the DEVICE:

	
	ULONG   nInput;							// supplies data to the device
	ULONG	nOutput;						// Count written to bufOutput
	
	Test_MISC_IOCTL_BOARD_GET_ID();

		printf("Select user LED(s) number \n\n");
		printf("values for LED's (decimal)\n");
		if (nBoardVersion == 0x67)
		{
			printf("    LED7	LED6	LED5	LED4	LED3	LED2	LED1	LED0\n");
			printf("    -------------------------------------------------------------\n");
			printf("    128      64      32      16      8       4       2       1\n");

			printf("    example: LED4 and LED2 = 20 (16+4)\n");
			printf("             LED4 only     = 16 \n");
		}
		else
		{
			printf("    LED1	LED0\n");
			printf("    -------------\n");
			printf("     2       1\n");

			printf("    example: LED0 and LED1 = 3 (2+1)\n");
			printf("             LED1 only     = 2 \n");

		}

		scanf("%d",&LedNo);
		printf("Set(1) or clear(0) user LED(s) %d:\n",LedNo);
		scanf("%d",&Val);
		

		if(Val)			
			nInput = MISC_LED_MAX + LedNo;
		else
			nInput = LedNo;
			

		// Call device IO Control interface in driver
		printf("Issuing Ioctl KOMMISC_IOCTL_USR_SET_LED to device - ");
		if (!DeviceIoControl(hDevice,
							 KOMMISC_IOCTL_USR_SET_LED,
							 &nInput, //bufInput,
							 sizeof(ULONG),//IOCTL_INBUF_SIZE,
							 NULL,
							 0,
							 &nOutput,
							 NULL)
		   )
		{
			if (GetLastError() == ERROR_ACCESS_DENIED)
			{
				if (LedNo == 1)
					printf("\nInfo: LED0 is reserved for Watchdog! (%d)", GetLastError());
				else
					printf("\nInfo: LED1 is reserved for Overtemp control! (%d)", GetLastError());
			}
			else
			    printf("\nERROR: DeviceIoControl returns 0x%0x.", GetLastError());

			Exit(1);
		}

	

}

////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_BOARD_GET_ID
//
// Valid for CP6000,605,306,304,304, 6500V
// 
// Comments:This IOCTL retrieves the Bord Type.


void Test_MISC_IOCTL_BOARD_GET_ID(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application


	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (KOMMISC_IOCTL_BOARD_GET_ID) in driver
	printf("Issuing KOMMISC_IOCTL_BOARD_GET_ID to device - ");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_BOARD_GET_ID,
						 NULL,
						 0,
						 &nBoardVersion,
						 IOCTL_OUTBUF_SIZE,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
	{
		char buffer[10];

		switch (nBoardVersion)
		{
		case 0x70: {sprintf(buffer,"CP6500-V"); break;}

		case 0x60: {sprintf(buffer,"CP605"); break;}

		case 0x67: {sprintf(buffer,"CP6000");break;}

		case 0x63: {sprintf(buffer,"CP306");break;}

		case 0x64: {sprintf(buffer,"CP306-V");break;}

		case 0x51: {sprintf(buffer,"CP304");break;}

		case 0x50: {sprintf(buffer,"CP303");break;}
				
		default: {sprintf(buffer,"unknown");break;}
		}
		printf("\n**********************************\n");
		printf("    Board Version: %s (0x%0x)\n", buffer, nBoardVersion);
		printf("\n**********************************\n");
	}
}


////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_USR_GET_OVRTEMP_LED
//
// Valid for CP605,306,304,304
// 
// Comments:This IOCTL retrieves the present dedication of the 
//			Overtemperatue LED.
//
//
void Test_MISC_IOCTL_USR_GET_OVRTEMP_LED(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application


	CHAR	bufOutput[IOCTL_OUTBUF_SIZE];	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (KOMMISC_IOCTL_USR_GET_OVRTEMP_LED) in driver
	printf("Issuing Ioctl MISC_IOCTL_USR_GET_OVRTEMP_LED to device - \n");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_USR_GET_OVRTEMP_LED,
						 NULL,
						 0,
						 bufOutput,
						 IOCTL_OUTBUF_SIZE,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
	{
		if ((int)bufOutput[0] == 1)
		printf("LED available for general purpose use (%d)\n", (int) bufOutput[0]);
		else
		printf("LED assigned to overtemp condition: (%d)\n", (int) bufOutput[0]);
	}
}



////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_WDG_GET_HWRESET
//
// Valid for CP6000, 605,306,304,304
// 
// Comments:This IOCTL retrieves the present dedication of the 
//			Overtemperatue LED.
//
//
void Test_MISC_IOCTL_WDG_GET_HWRESET(void)
{
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application


	CHAR	bufOutput[IOCTL_OUTBUF_SIZE];	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	// Call device IO Control interface (KOMMISC_IOCTL_USR_GET_OVRTEMP_LED) in driver
	printf("Issuing Ioctl KOMMISC_IOCTL_WDG_GET_HWRESET to device - \n");

	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_GET_HWRESET,
						 NULL,
						 0,
						 bufOutput,
						 sizeof(bufOutput),
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: KOMMISC_IOCTL_WDG_GET_HWRESET returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
	{
		if ((int)bufOutput[0] == 1)
		printf("     HARDWARE reset enabled - Watchdog timeout will immediately reset the system! (%d)\n", (int) bufOutput[0]);
		else
		printf("     Hardware reset is disabled.: (%d)\n", (int) bufOutput[0]);

		hwreset = (int)bufOutput[0];
	}
}


////////////////////////////////////////////////////////////////////////
// Test_MISC_IOCTL_USR_ASGN_OVRTEMP_LED
//
// Valid for CP605,306,304,304
// 
// Comments:This IOCTL assigns the dedication for the 
//			Overtemperatue LED.
//
void Test_MISC_IOCTL_USR_ASGN_OVRTEMP_LED(void)
{
	int Val;
// Note that Input and Output are named from the point of view
// of the DEVICE:
//		bufInput  supplies data to the device
//		bufOutput is written by the device to return data to this application
	CHAR	bufInput[IOCTL_INBUF_SIZE];		// Input to device
	ULONG	nOutput;						// Count written to bufOutput

	printf("Assign LED to Overtemp            = 0\n");
	printf("Assign LED to general purpose use = 1\n");
	printf("Selection? : ");
	scanf("%d",&Val);

	if(Val)
		bufInput[0] = 0;
	else
		bufInput[0] = 1;

	// Call device IO Control interface (MISC_IOCTL_USR_ASGN_OVRTEMP_LED) in driver
	printf("Issuing Ioctl MISC_IOCTL_USR_ASGN_OVRTEMP_LED to device - \n");
	if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_USR_ASGN_OVRTEMP_LED,
						 bufInput,
						 IOCTL_INBUF_SIZE,
						 NULL,
						 0,
						 &nOutput,
						 NULL)
	   )
	{
		printf("ERROR: DeviceIoControl returns 0x%0x.", GetLastError());
		Exit(1);
	}
	else
		printf("\ndone - no errors");
}

////////////////////////////////////////////////////////////////////////
// ShowIoctlValues
//
//		Print list of IO Control Code values for usage display
//
void ShowIoctlValues(void)
{
	int i;

	Test_MISC_IOCTL_BOARD_GET_ID();

	for (i=0; i<N_IOCODES; i++)
	{
		if (i==0)
			printf( "         IO control code index\n");
		printf( "           %d is code %s [%x]\n", i, IOnames[i], IOcodes[i]);

	}
}


////////////////////////////////////////////////////////////////////////
// Test_Watchdog
//
// Valid for all CPUs with watchdog
// 
// Comments: This function tests the function of the watchdog, by starting a thread
//			 which waits for the timeout. Then the watchdog will be retriggered in
//           a loop until a key is pressed. This will trigger the timeout after the timout
//			 setting has elapsed. 
//           if hardware reset has been selected in the property page, a shut down occurs,
//           In case of IRQ 5 routing, the interrupt will be triggered. 	
UINT TestWatchdog(void)
{
	UINT status = ERROR_SUCCESS;
	DWORD dwAlertThreadId;
	ULONG lOutput;
	ULONG lThreadStatus;
    HANDLE hAlertThread;


	// clear any old watchdog timeouts
	Test_MISC_IOCTL_WDG_CHECK_FOR_TIMEOUT();

		// start a thread waiting for watchdog timeout
	hAlertThread = CreateThread(NULL, 0, WaitForTimeout, NULL, 0, &dwAlertThreadId);
	if(NULL == hAlertThread)
	{
		status = ERROR_SERVICE_NO_THREAD;
		CloseIfOpen();
		return status;
	}

	
	// start the watchdog
	Test_MISC_IOCTL_WDG_START();
	

	// get configuration of watchdog
	Test_MISC_IOCTL_WDG_GET_CONFIG();

	// cyclic retrigger the watchdog
	printf("     Press any key to stop retrigger\n");

	do
	{
		
		if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_RETRIGGER,
						 NULL,
						 0,
						 NULL,
						 0,
						 &lOutput,
						 NULL))
		{
			CloseIfOpen();
			status = GetLastError();
			return status;
		}
	
	printf("Trigger\b\b\b\b\b\b\b\b");
	

	} while( !_kbhit() );
	printf("Retrigger stopped\n");
	if (hwreset == 1)
		printf("...system shut down in %s seconds!!!...",TimeoutSetting[tout]);
	else
		printf("...further action in %s seconds!...",TimeoutSetting[tout]);
	// retrigger stopped

	// wait for watchdog alert
	while(!GetExitCodeThread(hAlertThread, &lThreadStatus) || lThreadStatus == STILL_ACTIVE);


	return status;

}

////////////////////////////////////////////////////////////////////////
// Timeout thread for watchdog test

DWORD WINAPI WaitForTimeout(LPVOID lpParameter)
{
	DWORD dwStatus = ERROR_SUCCESS;
	ULONG lOutput;
	BOOLEAN bTimeout;

	printf("     Timeout Thread started\n");

	do
	{
		if (!DeviceIoControl(hDevice,
						 KOMMISC_IOCTL_WDG_CHECK_FOR_TIMEOUT,
						 NULL,
						 0,
						 &bTimeout,
						 sizeof(bTimeout),
						 &lOutput,
						 NULL))
		{
			dwStatus = GetLastError();
			break;
		}
		else if(bTimeout)
		{
			// watchdog has timed out
			printf("Watchdog has run into timeout!\n");
			
			break;
		}

		// wait a second before checking again for status
		Sleep(1000);
	}while(1);

	ExitThread(dwStatus);

	return dwStatus;
}