/** @par LICENCE
* @verbatim
 Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code and the documentation.
        
        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 shoud find the complete GPL in the COPYING file accompanying 
    this source code. 
* @endverbatim
*/
#include <linux/module.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
	#include <linux/config.h>
#else
	#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
		#include <linux/autoconf.h>
	#else
		#include <generated/autoconf.h>
	#endif
#endif

#include <linux/version.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <apci.h>
#include <apci3600.h>
#include <apci3600-kapi.h>

//#include "../apci3600-private.h"

MODULE_LICENSE ("GPL");
MODULE_AUTHOR ("ADDI-DATA GmbH <info@addi-data.com>");
MODULE_DESCRIPTION ("APCI-3600 IOCTL driver sample12");

/*minor of the board*/
static int board_minor=0;

/*can be override*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)  
	MODULE_PARM (board_minor,"i");
	EXPORT_NO_SYMBOLS;
#else
	module_param(board_minor, int, S_IRUGO);
#endif
static int sample12 (struct pci_dev *pdev)
{// Read 1 Analog Input Test
	uint8_t b_Status = 0;
	int i_ReturnValue = 0;
	int i_Cpt = 0;
	uint32_t pdw_Values [2];
	uint8_t pb_EnableCurrentSource[2];
	uint8_t pb_Coupling[2];
	uint8_t pb_SingleDiffMode[2];
	uint8_t pb_Gain[2];

	pb_EnableCurrentSource[0] = 0;
	pb_EnableCurrentSource[1] = 0;

	pb_Coupling[0] = PCI3600_DC_COUPLING;
	pb_Coupling[1] = PCI3600_DC_COUPLING;

	pb_SingleDiffMode[0] = PCI3600_SINGLE_ENDED_MODE;
	pb_SingleDiffMode[1] = PCI3600_SINGLE_ENDED_MODE;

	pb_Gain[0] = 0;
	pb_Gain[1] = 0;


	printk("Read 1 analog Input Test\n");
	/* Initialise the board */
	i_ReturnValue = i_PCI3600_InitBoard (pdev,
										 PCI3600_MASTER_MODE,
										 PCI3600_DIVISOR_4,
										 PCI3600_DIVISOR_4,
										 PCI3600_EXT_CLOCK_1,
										 PCI3600_EXT_CLOCK_1,
										 0,
										 0,
										 PCI3600_CHRONOMETER_DIVISOR_1);

	if (i_ReturnValue == 0)
	{
		printk ("i_PCI3600_InitBoard OK\n");


		/**************************************/
		/* Initialise the analog input module */
		/**************************************/
		i_ReturnValue = i_PCI3600_InitAnalogInModule (pdev,
						0,
						pb_SingleDiffMode,
						pb_Coupling,
						pb_EnableCurrentSource,
						pb_Gain,
						PCI3600_SAMPLING_CLOCK1,
						PCI3600_SINGLE_SPEED);
		if (i_ReturnValue == 0) {
			printk ("i_PCI3600_InitAnalogInModule OK\n");

			/********************************************************/
			/* Start a single conversion on the analog input module */
			/********************************************************/
			i_ReturnValue = i_PCI3600_StartAnalogInModuleSingleAcquisition (pdev,0);

			if (i_ReturnValue == 0) {
				printk ("i_PCI3600_StartAnalogInModuleSingleAcquisition OK\n");

				do {
					i_ReturnValue = i_PCI3600_GetAnalogInModuleSingleAcquisitionStatus (pdev,
									0,
									&b_Status);

					if (i_ReturnValue == 0) {
						printk ("i_PCI3600_GetAnalogInModuleSingleAcquisitionStatus OK\n");

					} else {
						printk ("i_PCI3600_GetAnalogInModuleSingleAcquisitionStatus:%d\n",i_ReturnValue);
						break;

					}
					/***************************************************/
					/* Check the EOC status of the analog input module */
					/***************************************************/
				} while (b_Status == 0);

				/************************************************/
				/* Test if the analog input value are available */
				/************************************************/
				if (b_Status == 1) {
					i_ReturnValue = i_PCI3600_ReadAnalogInSingleAcquisitionValues (pdev,
									0,
									pdw_Values);

					if (i_ReturnValue == 0) {
						printk ("i_PCI3600_ReadAnalogInSingleAcquisitionValues OK\n");

						printk("Value of the left channel : %u\n",pdw_Values[0]);

						printk("Value of the right channel : %u\n",pdw_Values[1]);

						printk("\n");

						for (i_Cpt =0; i_Cpt < 50;i_Cpt ++) {
							/**************************************/
							/* Read the analog input module value */
							/**************************************/
							i_ReturnValue = i_PCI3600_GetAnalogInModuleValues(pdev,
											0,
											pdw_Values);

							if (i_ReturnValue == 0) {
								printk ("Left Over:%u,Ch:%u Left : %08u Right Over:%u,Ch:%u Right : %08u \n",(pdw_Values[0] >> 24) & 0x1,
										(pdw_Values[0] >> 25) & 0xF,
										(pdw_Values[0] & 0xFFFFFF),
										(pdw_Values[1] >> 24) & 0x1,
										(pdw_Values[1] >> 25) & 0xF,
										(pdw_Values[1] & 0xFFFFFF));

							} else {
								printk ("i_PCI3600_GetAnalogInModuleValues Error :%d\n",i_ReturnValue);
								break;
							}


						}
					} else {
						printk ("i_PCI3600_ReadAnalogInSingleAcquisitionValues Error : %d\n",i_ReturnValue);

					}
				}
			} else {
				printk ("i_PCI3600_StartAnalogInModuleSingleAcquisition Error : %d\n",i_ReturnValue);

			}
			/************************************/
			/* Release the analog input channel */
			/************************************/
			i_ReturnValue = i_PCI3600_ReleaseAnalogInModule (pdev, 0);

			if (i_ReturnValue == 0) {
				printk ("i_PCI3600_ReleaseAnalogInModule OK\n");

			} else {
				printk ("i_PCI3600_ReleaseAnalogInModule Error : %d\n",i_ReturnValue);

			}
		} else {
			printk ("i_PCI3600_InitAnalogInModule Error : %d\n",i_ReturnValue);
		}

	} else
	{
		printk ("i_PCI3600_InitBoard Error : %d\n",i_ReturnValue);

	}

	return (0);
}

//------------------------------------------------------------------------------
/** Called when module loads. */
static int __init
apci3600_sample12_init (void)
{

	printk("Using board minor %d (override with board_minor parameter)\n",board_minor);
	sample12(apci3600_lookup_board_by_index(board_minor));
	printk("Succesfull end of the sample, you can unload it...\n");

	return 0;

}

//-------------------------------------------------------------------
/** Called when module is unloaded. */
static void __exit
apci3600_sample12_exit (void)
{



}


//------------------------------------------------------------------------------
module_exit (apci3600_sample12_exit);

module_init (apci3600_sample12_init);

