//#include "omp.h"
#include "UniDAQ.h"
#include "windows.h"
#include "stdio.h"
#include "conio.h"
#include "process.h"
#include "dos.h"
#include "time.h"

volatile WORD wThreadStauts0,wThreadStauts1,wProcessing;
WORD wTotalBoards;
WORD wReturnCode,i;
WORD wBoardNo,wGainCode;
WORD wPortWidth,wPortNo;

HANDLE hProcess;
DWORD dwProc, dwSystem;   

//Thread 0 Proc
DWORD WINAPI ThreadProcess0(LPVOID lpParam)
{
	WORD wIndex = 0;

	wThreadStauts0 =1;

	for(;;)
	{
		if(wProcessing)
		{
//#pragma omp parallel for
			for(wIndex =0; wIndex<wPortWidth; wIndex++)
			{
				wReturnCode = Ixud_WriteDOBit(wBoardNo,wPortNo,wIndex,1);
				wReturnCode = Ixud_WriteDOBit(wBoardNo,wPortNo,wIndex,0);
			}
			break;
		}
	}

	wThreadStauts0 = 2;
	return 0;
}
//Thread 1 Proc
DWORD WINAPI ThreadProcess1(LPVOID lpParam)
{

	WORD wIndex = 0;
	wThreadStauts1 = 1;

	for(;;)
	{
		if(wProcessing)
		{
//#pragma omp parallel for
			for(wIndex =0; wIndex<wPortWidth; wIndex++)
			{
				wReturnCode = Ixud_WriteDOBit(wBoardNo,wPortNo,wIndex,1);
				wReturnCode = Ixud_WriteDOBit(wBoardNo,wPortNo,wIndex,0);
			}
			break;
		}
	}

	wThreadStauts1=2;

	return 0;
}

void main(int argc, char* argv[])
{
	
	HANDLE hThread0,hThread1;
	DWORD ThreadID0,ThreadID1;

    IXUD_DEVICE_INFO A;
    IXUD_CARD_INFO B;
	SYSTEM_INFO SysInfo;
	int CPU_Number;

	char szModelName[20]="Unknow";	
	
	GetSystemInfo(&SysInfo);                                     
	CPU_Number = SysInfo.dwNumberOfProcessors;      //CPU Number

	printf("The number of Processors: %d", CPU_Number);

	//Open Multi Processor Mode
	wReturnCode=Ixud_OptionMode(0x1);

	wReturnCode=Ixud_DriverInit(&wTotalBoards);

	if(CPU_Number>=2)
	{
		hProcess =  GetCurrentProcess();
		SetProcessAffinityMask( hProcess, 3L );// Run the process on CPU 0&1
		//GetProcessAffinityMask(hProcess, &dwProc, &dwSystem);
		//printf("\nThe Process run on CPU No. %d",dwProc);
	}
	
	printf("\nThe Total Boards is %d\n",wTotalBoards);

	printf("ModelName ModelNo. VendorID  DeviceID  SubVendor  SubDevice  SubAux\n");
	//printf("Bar0 Bar1 Bar2 Bar3 Bar4 Bar5");
	for (i=0;i<wTotalBoards;i++)
	{
		wReturnCode=Ixud_GetCardInfo(i,&A,&B,szModelName);
		if (wReturnCode!=0)
			printf("Get Card %d Info has Error!!!\n",i);
		else
			printf("%0.15s 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",szModelName,B.dwModelNo ,A.wVendorID,A.wDeviceID,A.wSubVendorID ,A.wSubDeviceID ,A.Aux  );
		
	}

	printf("Please selection board (Board 0 ~ %d)):\n",wTotalBoards-1);
	scanf("%d",&wBoardNo);
    //system("cls");

	wThreadStauts0=0;
	wThreadStauts1=0; 

	printf("Selection the Port Number:");
	scanf("%d",&wPortNo);

	wPortWidth = B.wDIOPortWidth;

	if(B.wDIOPorts>0)
	{
		wReturnCode = Ixud_SetDIOModes32(wBoardNo,1);
	}

	wReturnCode = Ixud_WriteDO(wBoardNo,wPortNo,0x0);
	//Create the Thread 0
	hThread0 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProcess0,(LPVOID)wBoardNo, 0,&ThreadID0);
	//Create the Thread 1
	hThread1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProcess1,(LPVOID)wBoardNo, 0,&ThreadID1);

	if(CPU_Number>=2)
	{
		//Thread 0 run on CPU1.//Bit 0 is 1
		SetThreadAffinityMask(hThread0, 0x00000001L);
		//Threads 1 run on CPU 2.//Bit 1 is 1  
		SetThreadAffinityMask(hThread1, 0x00000002L);   
	}
	printf("\nPress any key to start DO.");
	getch();

	if(wThreadStauts0&&wThreadStauts1)
		wProcessing = 1;

    for(;;)
	{
		if((wThreadStauts0==2)&&(wThreadStauts1==2))
			break;
	}
	//Driver Close
	wReturnCode=Ixud_DriverClose();

	printf("\nDriver Close.\n");

	system("PAUSE");
}