/** @file sample_apcie1516_digital_io.c

   This sample demonstartes how to use digital input / output in user mode.

   @par CREATION
   @author Krauth Julien
   @date   08.01.09

   @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 <sys/sysmacros.h> /* major() minor() */

#include <signal.h> /* For signal */

#include <apcie1516.h>

/* This global variable is used to stop each single samples */
unsigned char stop;

//------------------------------------------------------------------------------

/** Move the consol cursor on the specified point.
*
* @param x	Horizontal position of the cursor.
* @param y	Vertical position of the cursor.
*
* retval 0 No error.
*/
int gotoxy(int x, int y)
{
	char essq[100]; // String variable to hold the escape sequence
	char xstr[100]; // Strings to hold the x and y coordinates
	char ystr[100]; // Escape sequences must be built with characters

	// Convert the screen coordinates to strings
	sprintf(xstr, "%d", x);
	sprintf(ystr, "%d", y);

	// Build the escape sequence (vertical move)
	essq[0] = '\0';
	strcat(essq, "\033[");
	strcat(essq, ystr);

	// Described in man terminfo as vpa=\\E[%p1%dd
	// Vertical position absolute
	strcat(essq, "d");

	// Horizontal move
	// Horizontal position absolute
	strcat(essq, "\033[");
	strcat(essq, xstr);

	// Described in man terminfo as hpa=\\E[%p1%dG
	strcat(essq, "G");

	// Execute the escape sequence
	// This will move the cursor to x, y
	printf("%s", essq);

	return 0;
}

//------------------------------------------------------------------------------

/** Test APCIE-1532 digital input.
*
* @param [in]	fd	File descriptor of the borad to use.
*
* @retval 0	No error.
* @retval 1	Error.
*/
int apcie1516_test_digital_input (int fd)
{
	uint8_t PortState = 0;

	//Clean the screen before display input status
	system("clear");

	while (!stop)
	{
		// Read all digital input state
		printf ("CMD_APCIE1516_Read8DigitalInputs\n");
		if ( ioctl (fd,CMD_APCIE1516_Read8DigitalInputs,&PortState) < 0 )
		{
			perror("ioctl");
			exit(1);
		}

		/* Set the cursor on screen top */
		gotoxy (0,0);
		printf ("\n+-------------------------------------+");
		printf ("\n| DIGITAL INPUTS STATES               |");
		printf ("\n+---+---+---+---+---+---+---+---+-----+");
		printf ("\n| 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | Hex |");
		printf ("\n+---+---+---+---+---+---+---+---+-----+");
		printf ("\n|%3s|%3s|%3s|%3s|%3s|%3s|%3s|%3s| %3x |",
				(PortState & 128)?"ON":"OFF",
				(PortState & 64)?"ON":"OFF",
				(PortState & 32)?"ON":"OFF",
				(PortState & 16)?"ON":"OFF",
				(PortState & 8)?"ON":"OFF",
				(PortState & 4)?"ON":"OFF",
				(PortState & 2)?"ON":"OFF",
				(PortState & 1)?"ON":"OFF",
				PortState);
		printf ("\n+-------------------------------------+");
		printf ("\n");
		printf ("\n");
		printf ("ctrl + c for the next test\n");
		printf ("\n");
	}

	return 0;
}

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

	int apcie1516_card_fd;

	if (argc < 2 )
	{
		printf("not enough arguments\n");

		exit(1);
	}

	if ( ( apcie1516_card_fd = open(argv[1], O_RDWR)) == -1 )
	{
		perror("open");
		exit(1);
	}

	{
		struct stat file_stat;
		if ( fstat(apcie1516_card_fd,&file_stat) )
		{
			perror("fstat");
			exit(1);
		}
		if (!S_ISCHR(file_stat.st_mode))
		{
			/* should never happen !*/
			printf("file %s is not a character device\n",argv[1]);
			printf("failed");
			exit(1);
		}
		printf("%s, major:%d minor:%d \n",argv[1], major(file_stat.st_rdev),minor(file_stat.st_rdev));
	}
	printf("\n+++++++++++++++++++++++++++++++++++++\nrunning test on device %s  \n+++++++++++++++++++++++++++++++++++++\n\n\n",argv[1]);

	/* run test */
	{
		int i;
		for (i=0;i< apcie1516_card_fd; i++)
		{
			printf("\n\nRunning digital input test on device of minor number %d\n\n\n\n",i);
			apcie1516_test_digital_input (apcie1516_card_fd);

		}
	}

	return 0;

}

