/** @file sample_apci3200_differential_scan.c

@brief this program exercises output related IOCTLs


@par LICENCE
@verbatim
Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.

ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
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 <errno.h>
#include <sys/sysmacros.h> /* major() minor() */
#define NDEBUG
#include <assert.h>
#include <apci3200.h>
#include "convert.h"
#include "findboards.h"
#include "input.h"
#include "errorlib.h"
#include "errormsg.h"

/** Time to wait with sleep function */
#define WAIT_MILLISECONDS	250000

//--------------------------------------------------------------------------------
int verbose=0;
//--------------------------------------------------------------------------------
/** this function look up for cards in the /proc/sys/apci3200/ directory
* @param cards A pointer to the card area to fill
* @return The number of cards detected (may be zero if nor cards found).
*/
int apci3200_find_cards(int ** cards)
{
	return apci_find_boards("apci3200", cards);
}
//--------------------------------------------------------------------------------
int apci3200_test_output(int fd)
{
	// Set 1 digital output without output memory
	{
		unsigned char chan;
		for (chan=0; chan<3; chan++)
		{
			if(verbose) printf("=> CMD_APCI3200_Set1DigitalOutputOn on output %i\n", chan);
			if ( ioctl (fd,CMD_APCI3200_Set1DigitalOutputOn, chan) == -1)
			{
				perror("ioctl");
				exit(1);
			}
			printf("\t CMD_APCI3200_Set1DigitalOutputOn %i OK\n", chan);

			// Wait a few milliseconds
			usleep(WAIT_MILLISECONDS);
		}

		// Note CMD_APCI3200_Set1DigitalOutputOff is not available
		// when output memory is not activated.

	}

	if(verbose) printf("=> CMD_APCI3200_SetDigitalOutputMemoryOn\n");
	if ( ioctl (fd,CMD_APCI3200_SetDigitalOutputMemoryOn, NULL) == -1)
	{
		perror("ioctl");
		exit(1);
	}
	if(verbose) printf("=> CMD_APCI3200_SetDigitalOutputMemoryOn OK\n");

	{
		unsigned char chan;
		for (chan=0; chan<3; chan++)
		{
			if(verbose) printf("=> CMD_APCI3200_Set1DigitalOutputOn on output %i\n", chan);
			if ( ioctl (fd,CMD_APCI3200_Set1DigitalOutputOn, chan) == -1)
			{
				perror("ioctl");
				exit(1);
			}
			printf("\t CMD_APCI3200_Set1DigitalOutputOn %i OK\n", chan);

			// Wait a few milliseconds
			usleep(WAIT_MILLISECONDS);
		}

		for (chan=0; chan<3; chan++)
		{
			if(verbose) printf("=> CMD_APCI3200_Set1DigitalOutputOff on output %i\n", chan);
			if ( ioctl (fd,CMD_APCI3200_Set1DigitalOutputOff, chan) == -1)
			{
				perror("ioctl");
				exit(1);
			}
			printf("\t CMD_APCI3200_Set1DigitalOutputOff %i OK\n", chan);

			// Wait a few milliseconds
			usleep(WAIT_MILLISECONDS);
		}
	}

	// Set 3 digital outputs with output memory
	// Note: The board has only 3 digital outputs!
	// With CMD_APCI3200_Set3DigitalOutputsXX you have to specify the output value
	// that you want:
	//				+-------+-------+-------+
	// Channel		|	0	|	1	|	2	|
	//				+-------+-------+-------+
	// Bin. value	|	1	|	2	|	4	|
	//				+-------+-------+-------+

	{
		unsigned char chan;
		for (chan=1; chan<8; chan++)
		{
			if(verbose) printf("=> CMD_APCI3200_Set3DigitalOutputsOn on output %i\n", chan);
			if ( ioctl (fd,CMD_APCI3200_Set3DigitalOutputsOn, chan) == -1)
			{
				perror("ioctl");
				exit(1);
			}
			printf("\t CMD_APCI3200_Set3DigitalOutpustOn %i OK\n", chan);

			// Wait a few milliseconds
			usleep(WAIT_MILLISECONDS);
		}

		for (chan=1; chan<8; chan++)
		{
			if(verbose) printf("=> CMD_APCI3200_Set3DigitalOutputsOff on output %i\n", chan);
			if ( ioctl (fd,CMD_APCI3200_Set3DigitalOutputsOff, chan) == -1)
			{
				perror("ioctl");
				exit(1);
			}
			printf("\t CMD_APCI3200_Set3DigitalOutpustOff %i OK\n", chan);

			// Wait a few milliseconds
			usleep(WAIT_MILLISECONDS);
		}
	}

	if(verbose) printf("=> CMD_APCI3200_SetDigitalOutputMemoryOff\n");
	if ( ioctl (fd,CMD_APCI3200_SetDigitalOutputMemoryOff, NULL) == -1)
	{
		perror("ioctl");
		exit(1);
	}
	printf("=> CMD_APCI3200_SetDigitalOutputMemoryOff OK\n");

	return 0;
}
//--------------------------------------------------------------------------------
int main(int argc, char** argv)
{
	int * apci3200_card_fd;

	unsigned int apci3200_card_number = 0;
	{
		apci3200_card_number =  apci_find_boards("apci3200", &apci3200_card_fd);

		printf("total: %d cards\n",apci3200_card_number);
	}

	{
		int index;
		switch(apci3200_card_number)
		{
		case 1:
			index = 0;
			break;
		case 0:
			exit(0);
		default:
			printf("board>");
			index = get_integer(0,apci3200_card_number-1);
		}
		return apci3200_test_output(apci3200_card_fd[index]);
	}
	return 0;
}
//--------------------------------------------------------------------------------
