/** @file sample_xpci3009_digital_in.c
 
   This demonstarte how to use digital I/O in user mode.
 
   @par CREATION  
   @author Krauth Julien
   @date   30.05.06
   
   @par VERSION
   @verbatim
   $LastChangedRevision:$
   $LastChangedDate:$
   @endverbatim   
   
   @par LICENCE
   @verbatim
    Copyright (C) 2009  ADDI-DATA GmbH for the source code of this module.
        
    ADDI-DATA GmbH
    Airpark Business Center
    Airport Boulevard B210
    77836 Rheinm�nster
    Germany
    Tel: +49(0)7229/1847-0
    Fax: +49(0)7229/1847-200
    http://www.addi-data-com
    info@addi-data.com
        
   This program is free software; you can redistribute it and/or modify it under 
   the terms of the GNU General Public License as published by the Free Software 
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, 
   but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
   or FITNESS FOR A PARTICULAR PURPOSE. 
   See the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along with 
   this program; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

   You shoud also find the complete GPL in the COPYING file 
   accompanying this source code.
   @endverbatim   
 */ 

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <signal.h>
#include <sys/sysmacros.h> /* major() minor() */

#include <xpci3009.h>

#include "findboards.h"

void sample (int fd)
	{
	unsigned char  b_ModuleNbr = 0;             // Module number to test
	unsigned char  b_ChannelStatus;		// Digital input status
	unsigned char  b_ChannelCpt;		// Channel counter
	int            i_ReturnValue;           // Return error code
	unsigned char  b_ArgArray[3];


	/* Print sample information */
	printf ("\n+---------------------------------------------------+");
	printf ("\n| XPCI-3009 Digital I/O:                            |");
	printf ("\n| Digital input channel sample                      |");
	printf ("\n| Channel A and channel B for input                 |");
	printf ("\n+---------------------------------------------------+");

	/* 
	 * Initialise the digital I/O module
	 * Channel A and Channel B for input
	 */
 	
 	/* Module number to configure (0 to 3).*/
	b_ArgArray[0] = b_ModuleNbr;
	
	/*
	 * Channel A mode selection
	 * 0 : Channel used for digital input
	 * 1 : Channel used for digital output
	 */	
	b_ArgArray[1] = 0;

	/*
	 * Channel B mode selection
	 * 0 : Channel used for digital input
	 * 1 : Channel used for digital output
	 */	
	b_ArgArray[2] = 0;
			
	i_ReturnValue = ioctl (fd,CMD_XPCI3009_InitDigitalIO, b_ArgArray);

	/* Test the return value */
	switch (i_ReturnValue)
		{
		case 0:
		printf ("\nCMD_XPCI3009_InitDigitalIO OK");

		for (;;)
			{
			/* Test all digital I/O inputs */
			for (b_ChannelCpt = 0; b_ChannelCpt < 7; b_ChannelCpt ++)
				{
			 	/* Module number to configure (0 to 3).*/
				b_ArgArray[0] = b_ModuleNbr;
				
				/*
				 * Selection from digital input (0 to 6) 
				 * 0 : Channel C
				 * 1 : Channel D
				 * 2 : Channel E
				 * 3 : Channel F
				 * 4 : Channel G
				 * 5 : Channel A
				 * 6 : Channel B   
				 */	
				b_ArgArray[1] = b_ChannelCpt;
				i_ReturnValue = ioctl (fd,CMD_XPCI3009_ReadDigitalIOChlValue, b_ArgArray);
				
				/* Test the return value */
				switch (i_ReturnValue)
					{
					case 0:
					b_ChannelStatus = b_ArgArray[0];
				
					if (b_ChannelCpt < 5)
						printf ("\nDigital input channel %c = %d", 'C' + b_ChannelCpt, b_ChannelStatus);
					else
						printf ("\nDigital input channel %c = %d", 'A' + b_ChannelCpt - 5, b_ChannelStatus);
					break;

					case 1:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
					break;

					case 2:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d. The module parameter is wrong", i_ReturnValue);
					break;

					case 3:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d. The module is not a digital I/O module", i_ReturnValue);
					break;

					case 4:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d. The selected digital input is wrong", i_ReturnValue);
					break;
					
					case 5:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d. Digital I/O not initialised", i_ReturnValue);
					break;
					
					case 6:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d. The digital channel A is used for output", i_ReturnValue);
					break;
					
					case 7:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d. The digital channel B is used for output", i_ReturnValue);
					break;
					
					default:
					printf ("\nCMD_XPCI3009_ReadDigitalIOChlValue error");
					printf ("\nError = %d.", i_ReturnValue);
					break;
					}
				} // for (...)

			} // for (;;)
		break;

		case 1:
		printf ("\nCMD_XPCI3009_InitDigitalIO error");
		printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
		break;

		case 2:
		printf ("\nCMD_XPCI3009_InitDigitalIO error");
		printf ("\nError = %d. The module parameter is wrong", i_ReturnValue);
		break;

		case 3:
		printf ("\nCMD_XPCI3009_InitDigitalIO error");
		printf ("\nError = %d. The module is not a digital I/O module", i_ReturnValue);
		break;

		case 4:
		printf ("\nCMD_XPCI3009_InitDigitalIO error");
		printf ("\nError = %d. Bi-directional channel A configuration error", i_ReturnValue);
		break;

		case 5:
		printf ("\nCMD_XPCI3009_InitDigitalIO error");
		printf ("\nError = %d. Bi-directional channel B configuration error", i_ReturnValue);
		break;

		default:
		printf ("\nCMD_XPCI3009_InitDigitalIO error");
		printf ("\nError = %d", i_ReturnValue);
		break;
		} // switch (i_ReturnValue)

	}
	
//--------------------------------------------------------------------------------

int main(int argc, char** argv)
{

	int * xpci3009_card_fd;
	unsigned int xpci3009_card_number = 0;
	{
		xpci3009_card_number = apci_find_boards("xpci3009", &xpci3009_card_fd);
		
		printf("total: %d cards\n",xpci3009_card_number);
	}	
	
	{
		int i;
		for (i=0;i< xpci3009_card_number; i++)
		{
			printf("\n+++++++++++++++++++++++++++++++++++++\nrunning test on device of minor number %d\n+++++++++++++++++++++++++++++++++++++\n\n\n",i);
			
			/* Compare logic sample */
			sample (xpci3009_card_fd[i]);
		}
	}

	

	return 0;
}
//--------------------------------------------------------------------------------
