/*
 * counter_without_interrupt.c
 *
 * This program enables to test the internal counter of the xpci3009 board
 *
 *  Created on: Nov 8, 2010
 *      Author: Jordan ROSE
 */


#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>
#include <errno.h>
#include <limits.h>

#include <xpci3009.h>

#include "errorlib.h"
#include "findboards.h"
#include "errormsg.h"
#include "input.h"

//--------------------------------------------------------------------------------
/** This function do the test to the counter
* @param int fd The file descriptor to the device
* @return 0 if success, other value if error
*/
int do_test ( int fd )
{

	// ---------------------------------------
	// Variables
	int ret = 0;
	int cpt_index = 0;
	int sleep_time = 0;
	int duration_time = 0;
	int nb_iteration_todo = 0;
	int i = 0;

	uint32_t init_arg[4] = {0};
	uint32_t read_arg[2] = {0};
	// --------------------------------------

	printf("Enter the counter you want to test: \n");
	cpt_index = get_integer(0, 2);

	printf("To do action on the counter, use the pin %d to put your signal \n", (22-cpt_index) );

	printf("Enter the number of ms you want to wait between two read: \n");
	sleep_time = get_integer( 1, 10000 );

	printf("Enter the wished duration of the sample (in s ) ; \n");
	duration_time = get_integer(1 , 30 );

	// Computation the number of iteration to do
	nb_iteration_todo = (duration_time * 1000) / sleep_time;
	sleep_time = sleep_time * 1000 ; // convert in us

	printf("Initialization of the counter %d \n", cpt_index);
	init_arg[0] = cpt_index;                 //	counter index
	init_arg[1] = ADDIDATA_DOWN;     //	Count down
	init_arg[2] = ADDIDATA_HIGH;     //	High level count
	init_arg[3] = 10;                //	Reload value = 10

	ret = ioctl (fd, CMD_xpci3009_InitCounter, init_arg );

	if ( ret != 0 )
	{
		printf("Error with CMD_xpci3009_InitCounter : %d \n", ret );
		exit(1);
	}

	printf("Start the counter %d \n", cpt_index);
	ret = ioctl (fd,CMD_xpci3009_StartCounter,&cpt_index);

	if ( ret != 0 )
	{
		printf("Error with CMD_xpci3009_StartCounter : %d \n", ret );
		exit(1);
	}

	// READ the counter values
	for ( i = 0 ; i < nb_iteration_todo ; i++ )
	{
		read_arg[0] = cpt_index; //	counter index
		read_arg[1] = 0; //	counter value, will be set by the ioctl function

		ret = ioctl (fd,CMD_xpci3009_ReadCounterValue,read_arg);
		if ( ret  != 0 )
		{
			printf("Error with CMD_xpci3009_ReadCounterValue : %d \n", ret );
			exit(1);
		}

		printf("\tCounter value : %d \n", read_arg[1]);

		usleep( sleep_time );
	}

	printf("Stop the counter %d \n", cpt_index);
	ret = ioctl (fd,CMD_xpci3009_StopCounter,&cpt_index);
	if ( ret != 0 )
	{
		printf("Error with CMD_xpci3009_StopCounter :  %d \n", ret );
		exit(1);
	}

	printf("Release the counter %d \n", cpt_index);
	ret = ioctl (fd,CMD_xpci3009_ReleaseCounter,&cpt_index);
	if ( ret != 0)
	{
		printf("Error with CMD_xpci3009_ReleaseCounter :  %d \n", ret );
		exit(1);
	}

	return 0;
}


//--------------------------------------------------------------------------------
/** this function look up for cards in the /proc/sys/xpci3009/ 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 xpci3009_find_cards(int ** cards)
{
	return apci_find_boards("xpci3009", cards);
}

//--------------------------------------------------------------------------------
int main(int argc, char** argv)
{
	int * fd = NULL;
	int  i = 0;
	int number_of_boards = 0;

	// This is the first function to call in order to get the board handler
	number_of_boards = xpci3009_find_cards(&fd);
	printf("Number of boards in the computer: %d \n",number_of_boards);

	for ( i = 0; i < number_of_boards ; i++ )
	{
		do_test( fd[i] );
	}

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