#ifndef __APCI3600_KAPI__
#define __APCI3600_KAPI__

/*
 * Due to restrictions in the symbol export mechanism, we had to shrink the name of some symbols.
 * AnalogIn -> AnalogInput
 * AnalogOut -> AnalogOutput
 * Incr -> Increment
 */
#ifndef __KERNEL__
#error This header is intended for use in kernel context only
#endif

#include "apci3600.h"
#include <linux/pci.h>
#include "apci.h"

typedef void (*v_PCI3600_UserInterruptHandler) (struct pci_dev *pdev,
		uint32_t dw_InterruptSource,
		uint32_t  dw_InterruptMask,
		uint32_t  dw_NbrOfComputerBuffer,
		uint32_t* pdw_ComputerBufferAddressKernelLevel,
		uint32_t* pdw_ComputerBufferAddressApplicLevel);


/** \defgroup PCI3600 xPCI3600 functions
 * @{
 */

/**		\addtogroup General xPCI3600 General functions
 * 		\ingroup PCI3600
 *		@{
 */

/* i_PCI3600_InitBoard*/
/**
 * Init the board
 * This function initializes the board and release all analog inputs and outputs to initial state.
 * @param [in] pdev	The device to use
 * @param [in] b_MasterSlaveMode	Selection of the mode of the board :
 *                       \li  0 : Master Mode
 *                       \li  1 : Slave Mode
 *                       \li  In slave mode, the Clock1&2 selection and divisor
 *                         must be the same that the master board.
 * @param [in] b_ClockGen1_Divisor	Selection of the divisor for the clock generator 1.
 * @param [in] b_ClockGen2_Divisor	Selection of the divisor for the clock generator 2.
 * @param [in] b_SamplingClock1_Selection	Selection of the clock for the sampling clock 1.
 * @param [in] b_SamplingClock2_Selection	Selection of the clock for the sampling clock 2.
 * @param [in] b_SlaveSamplingClock1_Selection	Selection of the clock for the sampling clock 1
 *                         for the slave board
 *                       \li  0 : PCI3600_EXT_CLOCK_1
 *                       \li  1 : PCI3600_EXT_CLOCK_2
 * @param [in] b_SlaveSamplingClock2_Selection	Selection of the clock for the sampling clock 2
 *                         for the slave board
 *                       \li  0 : PCI3600_EXT_CLOCK_1
 *                       \li  1 : PCI3600_EXT_CLOCK_2
 * @param [in] b_Chronometer_MasterClock_Divisor	Selection of the divisor for the master clock
 *                         for the Chronometer:
 *                       \li PCI3600_CHRONOMETER_DIVISOR_1
 *                       \li PCI3600_CHRONOMETER_DIVISOR_10
 *                       \li PCI3600_CHRONOMETER_DIVISOR_100
 *
 * @retval 0 : success
 * @retval -1 : system error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Master,Slave mode parameter is wrong
 * @retval -3 : one or both of the selected bus clock divisor parameter is wrong
 * @retval -4 : one or both of the clock selection is wrong
 * @retval -5 : Slave sampling clock selection is wrong
 * @retval -6 : Chronometer master clock divisor parameter is wrong
 * @retval -7 : The board is already initialised by another process
 * @retval -8 : The board is in use : Release all channels to reinitialise it
 */
int __needlock i_PCI3600_InitBoard (struct pci_dev *pdev,
		uint8_t b_MasterSlaveMode,
		uint8_t b_ClockGen1_Divisor,
		uint8_t b_ClockGen2_Divisor,
		uint8_t b_SamplingClock1_Selection,
		uint8_t b_SamplingClock2_Selection,
		uint8_t b_SlaveSamplingClock1_Selection,
		uint8_t b_SlaveSamplingClock2_Selection,
		uint8_t b_Chronometer_MasterClock_Divisor);

/* i_PCI3600_GetBoardInitialisation*/
/**
 * Get board initialization state
 *
 * @param [in] pdev	The device to use.
 * @param [out] pb_MasterSlaveMode	Selection of the mode of the board :
 *                         \li 0 : Master Mode
 *                         \li 1 : Slave Mode
 *                         \li In slave mode, the Clock1&2 selection and divisor must be the same that the master board.
 * @param [out] pb_ClockGen1_Divisor	Selection of the divisor for the clock generator 1
 * @param [out] pb_ClockGen2_Divisor	Selection of the divisor for the clock generator 2
 * @param [out] pb_SamplingClock1_Selection	Selection of the clock for the sampling clock 1
 * @param [out] pb_SamplingClock2_Selection	Selection of the clock for the sampling clock 2
 * @param [out] pb_SlaveSamplingClock1_Selection	Selection of the clock for the sampling clock 1 for the slave board
 *                         \li 0 : PCI3600_EXT_CLOCK_1
 *                         \li 1 : PCI3600_EXT_CLOCK_2
 * @param [out] pb_SlaveSamplingClock2_Selection	Selection of the clock for the sampling clock 2 for the slave board
 *                         \li 0 : PCI3600_EXT_CLOCK_1
 *                         \li 1 : PCI3600_EXT_CLOCK_2
 * @param [out] pb_Chronometer_MasterClock_Divisor	Selection of the divisor for the master clock for the Chronometer:
 *                         \li PCI3600_CHRONOMETER_DIVISOR_1
 *                         \li PCI3600_CHRONOMETER_DIVISOR_10
 *                         \li PCI3600_CHRONOMETER_DIVISOR_100
 *
 * @retval  0 : success
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : The board is not initialised
 */
int __needlock i_PCI3600_GetBoardInitialisation (struct pci_dev *pdev,
		uint8_t* pb_MasterSlaveMode,
		uint8_t* pb_ClockGen1_Divisor,
		uint8_t* pb_ClockGen2_Divisor,
		uint8_t* pb_SamplingClock1_Selection,
		uint8_t* pb_SamplingClock2_Selection,
		uint8_t* pb_SlaveSamplingClock1_Selection,
		uint8_t* pb_SlaveSamplingClock2_Selection,
		uint8_t* pb_Chronometer_MasterClock_Divisor);

/* i_PCI3600_GetBoardInformation*/
/**
 * Gets generic device information.
 *
 *  Return the memory information of the board and the allocated memory
 *  from the computer for this board.
 *
 * @param [in] pdev	The device to use.
 *
 * @param [out] pdw_OnBoardRAMTotalSize	Return the size of the RAM of the board (Size in MBytes).
 * @param [out] pb_NbrOfComputerBufferAllocated	Return the number of buffer allocated in the computer RAM
 * @param [out] pdw_ComputerBufferSizeArray 	Return the size of the buffer allocated in the computer RAM.(Size in Byte).
 *
 * @retval  0 : success
 * @retval  -1 : The handle parameter of the board is wrong
 */
int __needlock i_PCI3600_GetBoardInformation (struct pci_dev *pdev,
		uint32_t* pdw_OnBoardRAMTotalSize,
		uint8_t* pb_NbrOfComputerBufferAllocated,
		uint32_t* pdw_ComputerBufferSizeArray);

/* i_PCI3600_SetBoardIntKernelRoutine*/
/**
 * Registers an interrupt callback function.
 * This callback function will be called each time the board generates an interruption.
 * The value of dw_InterruptSource will enable you to determine the source of the interruption:
 *
 * @param [in] pdev	The device to use.
 * @param [out] v_UserInterruptHandler	The device to use.
 *  \n	\b dw_InterruptSource : Source of the interrupt
 *                       \li bit 0 : Analog output 0
 *                       \li bit 1 : Analog output 1
 *                       \li bit 2 : Analog input module 0
 *                       \li bit 3 : Analog input module 1
 *                       \li bit 4 : Analog input module 2
 *                       \li bit 5 : Analog input module 3
 *                       \li bit 6 : Chronometer 0
 *                       \li bit 7 : Chronometer 1
 *                       \li bit 8 : Chronometer 2
 *                       \li bit 9 : Chronometer 3
 *
 * \n	\b dw_InterruptMask: Source of the interrupt Analog inputs
 *                       \li bit 0 -> DMA interrupt
 *                       \li bit 1 -> Internal FIFO error
 *                       \li bit 2 -> SDRAM Overflow error
 *                       \li bit 3 -> Not used
 *                       \li bit 4 -> Auto stop interrupt
 *
 *
 * @retval   0 : No Error
 * @retval  -1 : The handle parameter of the board is wrong
 * @retval  -2 : This function cannot be call in kernel level
 * @retval  -3 : Wrong calling mode
 * @retval  -4 : Not any memory free for the user globale buffer
 * @retval  -5 : The interrupt management is not supported by this compiler
 * @retval  -6 : User interrupt routine calling mode selection wrong
 * @retval  -7 : Interrupt already installed
 * @retval  -8 : Interrupt not attribuate
 * @retval  -9 : ACPI activ but Windows NT 4 used
 * @retval -10 : PNP OS activ but Windows NT 4 used
 * @retval -11 : Create user shared memory Error
 * @retval -12 : Prepare user function to kernel execution error
 * @retval -13 : Create API interrupt event error
 * @retval -14 : Create API interrupt thread function error
 * @retval -15 : Create call back API function error
 * @retval -16 : Install API interrupt function error
 * @retval -17 : Create Interrupt Parameter shared memory error
 * @retval -18 : Critical section preparation error
 */
int __needlock i_PCI3600_SetBoardIntKernelRoutine (struct pci_dev *pdev,
		v_PCI3600_UserInterruptHandler v_UserInterruptHandler);

/* i_PCI3600_ResetBoardIntKernelRoutine*/
/**
 * Deregisters the current interrupt callback function.
 *
 * @param [in] pdev	The device to use.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : This function cannot be call in kernel level
 * @retval -3 : Interrupt Routine not installed
 */
int __needlock i_PCI3600_ResetBoardIntKernelRoutine (struct pci_dev *pdev);

/**		@}
 */


/**		\addtogroup Digitalinput xPCI3600 Digital input functions
 * 		\ingroup PCI3600
 *		@{
 */

/* i_PCI3600_Read1DigitalInput*/
/**
 * Indicates the state of an input channel.
 *  The variable b_Channel passes the input channel to be read (0 to 7).
 *  A value is returned with the variable  pb_ChannelValue : 0 (low) or
 *  1 (high).
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Channel to read (0-7)
 *
 * @param [out] pb_ChannelValue	Channel value :
 *                                \li 0 : Low
 *                                \li 1 : High
 *
 * @retval 0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : The channel number parameter is wrong
 */
int i_PCI3600_Read1DigitalInput (struct pci_dev *pdev,
		uint8_t   b_Channel,
		uint8_t* pb_ChannelValue);

/* i_PCI3600_Read4DigitalInputs*/
/**
 * Specifies the status of the port. The variable b port passes the port to be read (1 or 2).
 * The variable pb_PortValue contain the status of the port.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Port	Port to be read ( 1 or 2)
 * @param [out] pb_PortValue	Status of the port
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : The channel number parameter is wrong
 */
int i_PCI3600_Read4DigitalInputs (struct pci_dev *pdev,
		uint8_t b_Port,
		uint8_t* pb_PortValue);

/* i_PCI3600_Read8DigitalInputs*/
/**
 * Indicates the status of the digital inputs.
 *
 * @param [in] pdev	The device to use.
 * @param [out] pb_Value	Status of digital inputs
 *
 * @retval 0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 */
int i_PCI3600_Read8DigitalInputs (struct pci_dev *pdev,
		uint8_t* pb_Value);

/**		@}
 */

/**		\addtogroup Digitaloutput xPCI3600 Digital input functions
 * 		\ingroup PCI3600
 *		@{
 */

/* i_PCI3600_EnableDisableDigitalOutputMemory*/
/**
 * Activate/Deactivate the digital output memory.
 * After calling activate the digital output memory, the output channels you have previously activated with the functions
 * "i_PCI3600_SetXDigitalOutputOn" are not reset. You can reset them with the function "i_PCI3600_SetXDigitalOutputOff".
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Flag  \li 0 : deactivate the digital output memory
 *                     \li 1 : activate the digital output memory
 *
 * @retval : No Error
 * @retval -1 : The handle parameter of the board is wrong
 */
int __needlock i_PCI3600_EnableDisableDigitalOutputMemory(struct pci_dev *pdev,
		uint8_t b_Flag);

/* i_PCI3600_Set1DigitalOutputOn*/
/**
 * Sets the output channel which has been passed with b_Channel.
 * Setting an output channel means setting an output channel on high.
 * Switching on the digital output memory (ON)
 * see function "i_PCI3600_EnableDisableDigitalOutputMemory (...)?
 * b_Channel= 1
 * The output channel 1 is set. The others output channels hold their state.
 * Switching off the digital output memory (OFF)
 * see function " i_PCI3600_EnableDisableDigitalOutputMemory (...)?
 * b_Channel= 1
 * The output channel 1 is set. The others output channels are reset.
 * If you have switched off the digital output memory (OFF), all the others
 * input channels are set to "0".
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Number of the output channel you want to set (0 to 7).
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : The channel number is not between 0 and 7
 */
int __needlock i_PCI3600_Set1DigitalOutputOn (struct pci_dev *pdev,
		uint8_t b_Channel);

/* i_PCI3600_Set1DigitalOutputOff*/
/**
 * Resetting an output channel means setting to low.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Number of the output channel you want to reset (0 to 7).
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : Digital output memory is not on
 */
int __needlock i_PCI3600_Set1DigitalOutputOff (struct pci_dev *pdev,
		uint8_t b_Channel);

/* i_PCI3600_Set4DigitalOutputsOn*/
/**
 * Sets one or several output channels of a port. Setting an output channel
 * means setting to high.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Port	Number of the output port (0 or 1)
 * @param [in] b_PortValue	Output value (0 to 15)
 *
 *@retval  0 : No Error
 *@retval -1 : The handle parameter of the board is wrong
 *@retval -2 : The port number is wrong
 *@retval -3 : The port value is wrong
 */
int __needlock i_PCI3600_Set4DigitalOutputsOn (struct pci_dev *pdev,
		uint8_t b_Port,
		uint8_t b_PortValue);

/* i_PCI3600_Set4DigitalOutputsOff*/
/**
 * Resets one or several output channels of one port. Resetting means setting
 * to low.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Port	Number of the output port (0 or 1)
 * @param [in] b_PortValue	Output value (0 to 15)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Digital output memory is not on
 * @retval -3 : The port number is wrong
 * @retval -4 : The port value is wrong
 */
int __needlock i_PCI3600_Set4DigitalOutputsOff (struct pci_dev *pdev,
		uint8_t b_Port,
		uint8_t b_PortValue);

/* i_PCI3600_Set8DigitalOutputsOn*/
/**
 * Sets one or several output channels of board APCI-3600
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Value	Output value (0 to 255)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 */
int __needlock i_PCI3600_Set8DigitalOutputsOn (struct pci_dev *pdev,
		uint8_t b_Value);

/* i_PCI3600_Set8DigitalOutputsOff*/
/**
 * Resets one or several output channels of board APCI-3600.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Value	Output value (0 to 255)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : The digital output memory is not on
 */
int __needlock i_PCI3600_Set8DigitalOutputsOff (struct pci_dev *pdev,
		uint8_t b_Value);

/**		@}
 */

 /**		\addtogroup AnalogInput xPCI3600 Analog input functions
 * 		\ingroup PCI3600
 *		@{
 */

/*  i_PCI3600_InitAnalogInModule */
/**
 *  Initialise the analog input module b_Module.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3)
 * @param [in] pb_SingleDiffMode : Single-Ended / Differential Mode of each channel
 *                                     \li pb_SingleDiffMode[0] : Left channel
 *                                     \li pb_SingleDiffMode[1] : Right channel
 *                                     \li 0 : Single-Ended
 *                                     \li 1 : Differential
 * @param [in] pb_Coupling	Coupling mode of each channel
 *                                     \li pb_Coupling [0] : Left channel
 *                                     \li pb_Coupling [1] : Right channel
 *                                     \li 0 : DC
 *                                     \li 1 : AC
 * @param [in] pb_EnableCurrentSource	Enable / Disable the current source for each channel
 *                                     \li pb_EnableCurrentSource[0] : Left channel
 *                                     \li pb_EnableCurrentSource[1] : Right channel
 *                                     \li 0 : Disable
 *                                     \li 1 : Enable
 * @param [in] pb_GainSelection	Gain selection
 *                                     \li pb_GainSelection[0] : Left Channel
 *                                     \li pb_GainSelection[1] : Right Channel
 *                                     \li 0 : Gain 1
 *                                     \li 1 : Gain 10
 * @param [in] b_SamplingClockSelection	Clock selection for the analog input module
 *                                     \li 0 : Sampling Clock 1
 *                                     \li 1 : Sampling Clock 2
 * @param [in] b_SpeedMode	ADC Speed mode selection
 *                                     \li 00 : Single speed mode (2KHz - 50KHz)
 *                                     \li 01 : Double speed mode (50KHz - 100KHz)
 *                                     \li 10 : Quadruple speed mode (100KHz - 200KHz)                                                        |
 *
 *
 * @retval 0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : Wrong Single/Diff Mode selection
 * @retval -4 : Wrong coupling selection
 * @retval -5 : Wrong Current source flag
 * @retval -6 : Wrong gain selection
 * @retval -7 : Wrong clock selection
 * @retval -8 : wrong Speed mode parameter
 * @retval -9 : The board is not initialised
 * @retval -10: Speed mode not available
 * @retval -11: The current source are only available on the 2 first module
 * @retval -12: When the current source is used, the configuration of the channel
 *              must be Sinlge-Ended and AC
 * @retval -13: The module is already initialised by another process
 * @retval -14: Initialisation Error
 */
int __needlock i_PCI3600_InitAnalogInModule (struct pci_dev *pdev,
		uint8_t b_Module,
		uint8_t* pb_SingleDiffMode,
		uint8_t* pb_Coupling,
		uint8_t* pb_EnableCurrentSource,
		uint8_t* pb_GainSelection,
		uint8_t b_SamplingClockSelection,
		uint8_t b_SpeedMode);

/*  i_PCI3600_ReleaseAnalogInModule */
/**
 * Release the analog input module b_Module.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The module is not initialised or initialised by another process
 */

int __needlock i_PCI3600_ReleaseAnalogInModule (struct pci_dev *pdev,
		uint8_t b_Module);

/*  i_PCI3600_GetAnalogInModuleCalibrationStatus */
/**
 * Gets the status of the calibration of the analog input module b_Module.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [out] pb_Status	Status of the calibration.
 *                           \li 1 : Calibration is running
 *                           \li 0 : End of the calibration, the module is ready
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 */
int i_PCI3600_GetAnalogInModuleCalibrationStatus (struct pci_dev *pdev,
		uint8_t   b_Module,
		uint8_t*  pb_Status);

/*  i_PCI3600_StartAnalogInModuleSingleAcquisition */
/**
 * Start on the analog input module b_Module a single acquisition.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The module is not initialised
 * @retval -4 : The module is initialised for the cyclic acquisition mode
 * @retval -5 : A conversion is already started
 * @retval -6 : The calibration is running on the module
 */
int __needlock i_PCI3600_StartAnalogInModuleSingleAcquisition (struct pci_dev *pdev,
		uint8_t   b_Module);

/*  i_PCI3600_GetAnalogInModuleSingleAcquisitionStatus */
/**
 * i_PCI3600_GetAnalogInModuleSingleAcquisitionStatus
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [out] pb_Status	Status of the single acquisition (equal to the status of the FIFO)
 *							\li 0 : Value not available
 *							\li 1 : Value available
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The module is not initialised
 * @retval -4 : The calibration is running on the module
 */
int __needlock i_PCI3600_GetAnalogInModuleSingleAcquisitionStatus (struct pci_dev *pdev,
		uint8_t b_Module,
		uint8_t* pb_Status);

/*  i_PCI3600_ReadAnalogInSingleAcquisitionValues */
/**
 * Read the value of the right/left channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [out] pdw_Values	Values of the single acquisition
 *                            \li pdw_Values[0] : Value of the left channel
 *                            \li pdw_Values[1] : Value of the right channel
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The module is not initialised
 * @retval -4 : The values are not available
 * @retval -5 : The calibration is running on the module
 */
int __needlock i_PCI3600_ReadAnalogInSingleAcquisitionValues(struct pci_dev *pdev,
		uint8_t b_Module,
		uint32_t* pdw_Values);

/*  i_PCI3600_GetAnalogInModuleValues */
/**
 * Start and read the value of the right/left channel of the analog input module b_Module.
 * The function wait that the values are available to read it.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [out] pdw_Values	Values of the single acquisition
 *                            \li pdw_Values[0] : Value of the left channel
 *                            \li pdw_Values[1] : Value of the right channel
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The module is not initialised
 * @retval -4 : Start analog input module acquisition error
 * @retval -5 : Time function error
 * @retval -6 : Get analog input module status error
 * @retval -7 : Read analog input module values error
 * @retval -8 : Time out occur
 */
int __needlock i_PCI3600_GetAnalogInModuleValues (struct pci_dev *pdev,
		uint8_t b_Module,
		uint32_t* pdw_Values);

/*  i_PCI3600_InitAnalogInModuleCyclicAcquisition */
/**
 * Initialise the cyclic acquisition for the analog input module b_Module.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [in] b_Mode	Define the mode used
 *                          \li 0 : AUTO-STOP Mode In this mode, the On board buffer is filled with value.
 *							When the On board buffer is full, the acquisition is stopped and an interrupt occur.
 *							\li 1 : RING Buffer Mode In this mode, the on board buffer is always fill with value.
 *							In both modes: Each time the number of the value in the buffer reach the dw_CompareValue,
 *							an interrupt occur to permit to the software to read the value from the buffer.
 * @param [in] dw_OnBoardBufferSize	Size (in nbr of bytes : 1024 * 2 dw_OnBoardBufferSize )
 *                                     of the On-board buffer (in the on-board RAM) to used for the analog input module.
 * @param [in] dw_CompareValue	Define the number of acquisition to have in the on-board
 *                                Buffer to generate an interrupt for start a DMA transfer.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : Wrong mode parameter
 * @retval -4 : The module is not initialised
 * @retval -5 : No computer buffer available
 * @retval -6 : The compare value cannot be :
 *              - greater that the size of the on board buffer in Auto Stop mode
 *              - greater or equal that the size of the on board buffer in Ring Buffer mode
 *              - null
 * @retval -7 : The cyclic acquisition is already initialised by another
 *              process
 * @retval -8 : The cyclic acquisition is running
 * @retval -9 : Not enough place in the on board RAM
 * @retval -10 : The interrupt routine is not installed
 * @retval -11 : Primary Init Error
 * @retval -12 : The calibration is running on the module
 */
int __needlock i_PCI3600_InitAnalogInModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module,
		uint8_t b_Mode,
		uint32_t dw_OnBoardBufferSize,
		uint32_t dw_CompareValue);

/*  i_PCI3600_StartAnalogInModuleCyclicAcquisition */
/**
 * Starts the analog input cyclic acquisition for the module b_Module.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The Cyclic acquisition is not initialised or not by this process
 */
int __needlock i_PCI3600_StartAnalogInModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module);

/*  i_PCI3600_StartMoreAnalogInModuleCyclicAcquisition */
/**
 * Starts the analog input cyclic acquisition for the module b_Module.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Mask	Mask
 *
 *  @retval -1 : The handle parameter of the board is wrong
 *  @retval -2 : wrong module number
 *  @retval -3 : Cyclique acquisition not initialised or not by this process
 *  @retval -4 : Acqusition ready started
 */
int __needlock i_PCI3600_StartMoreAnalogInModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Mask);

/*  i_PCI3600_GetAnalogInModuleCyclicAcquisitionStatus */
/**
 * Returns the status and the number of value in the on-board RAM for the module b_Module
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [out] pb_Status	Status of the cyclic acquisition
 *                            \li status 0: not started,
 *                            \li status 1: started
 * @param [out] pdw_NbrOfValue	Number of value in the buffer in the on-board RAM for the module.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The module is not initialised
 */
int __needlock i_PCI3600_GetAnalogInModuleCyclicAcquisitionStatus (struct pci_dev *pdev,
		uint8_t b_Module,
		uint8_t* pb_Status,
		uint32_t* pdw_NbrOfValue);

/*  i_PCI3600_QueryAnalogInputCyclicAcquisitionBufferSize */
/**
 * returns the size of the allocated DMA buffer
 *
 * @param [in] pdev	The device to use.
 * @param [out] pdw_BufferSize	size of the allocated DMA buffer
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 */
int __needlock i_PCI3600_QueryAnalogInputCyclicAcquisitionBufferSize (struct pci_dev *pdev, uint32_t* pdw_BufferSize);

/*  i_PCI3600_IncrAnalogInCyclicAcqBufferReadPointer */
/**
 * Permits to increment the read pointer of the ring buffer used to do the DMA transfer.
 *
 * @param [in] pdev	The device to use.
 * @param [in] dw_NbrOfValue	Number of value.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 */
int __needlock i_PCI3600_IncrAnalogInCyclicAcqBufferReadPointer (struct pci_dev *pdev,
		uint32_t dw_NbrOfValue);

/*  i_PCI3600_StopAnalogInModuleCyclicAcquisition */
/**
 * Stops the analog input cyclic acquisition for the module b_Module
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The Cyclic Acquisition is not started or started by another   process
 */
int __needlock i_PCI3600_StopAnalogInModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module);

/*  i_PCI3600_ReleaseAnalogInModuleCyclicAcquisition */
/**
 * Releases the analog input cyclic acquisition for the module b_Module
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The module is not initialised
 */
int __needlock i_PCI3600_ReleaseAnalogInModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module);

/*  i_PCI3600_AnalogIn_EnableDisableDigitalInputExternalTrigger */
/**
 * Enables/disables the digital input external trigger (digital input 0) for the analog input module b_Module.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [in] b_ExternTriggerFlag	Enable/disable flag for the digital input external trigger
 *                                   \li 0 : Disable
 *                                   \li 1 : Enable
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : Extern trigger flag is wrong
 * @retval -4 : The module is not initialised
 * @retval -5 : The digital external trigger is not initialised
 */
int __needlock i_PCI3600_AnalogIn_EnableDisableDigitalInputExternalTrigger (struct pci_dev *pdev,
		uint8_t b_Module,
		uint8_t b_ExternTriggerFlag);


/**		@}
 */

 /**		\addtogroup AnalogOutput xPCI3600 Analog output functions
 * 		\ingroup PCI3600
 *		@{
 */


/* i_PCI3600_InitAnalogOutChannel*/
/**
 * Initialises the analog output channel b_Channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] b_SamplingClockSelection	Clock selection for the analog output channel
 *                                       \li 0 : Sampling clock 1
 *                                       \li 1 : Sampling clock 2
 * @param [in] b_SpeedMode	DAC speed mode selection
 *                            \li 00 : Single speed mode (2KHz ? 50KHz)
 *                            \li 01 : Double speed mode (50KHz ? 100KHz)
 *                            \li 10 : Quadruple speed mode (100KHz ? 200KHz)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : Wrong clock selection
 * @retval -4 : Wrong Speed mode parameter
 * @retval -5 : The board is not initialised
 * @retval -6 : Speed mode not available
 * @retval -7 : The channel is already initialised by another process
 * @retval -8 : Initialisation Error
 */
int __needlock i_PCI3600_InitAnalogOutChannel (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t b_SamplingClockSelection,
		uint8_t b_SpeedMode);

/* i_PCI3600_ReleaseAnalogOutChannel*/
/**
 * Releases the analog output channel b_Channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The channel is not initialised or initialised by another
 *              process
 */
int __needlock i_PCI3600_ReleaseAnalogOutChannel (struct pci_dev *pdev,
		uint8_t b_Channel);

/* i_PCI3600_GetAnalogOutReadyBitStatus*/
/**
 * Returns the status of the ready bit to know if a value can be written on the analog output channel b_Channel.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [out] pb_ReadyBitStatus	Status of the ready bit for the analog output channel
 *                                  \li 0: channel not ready to receive a value
 *                                  \li 1: channel ready to receive a value
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The channel is not initialised
 * @retval -4 : The channel is initialised for the signal generator mode
 */
int __needlock i_PCI3600_GetAnalogOutReadyBitStatus (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t* pb_ReadyBitStatus);

/* i_PCI3600_WriteAnalogOutValue*/
/**
 * Writes the value w_Value on the analog output b_Channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] w_Value	Value to write on the analog output (0 to 65535)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The channel is not initialised
 * @retval -4 : This function cannot work if the digital external trigger is enabled
 * @retval -5 : The channel is initialised for the signal generator mode
 * @retval -6 : The channel is not ready to receive a new value
 */
int __needlock i_PCI3600_WriteAnalogOutValue (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint16_t w_Value);

/* i_PCI3600_Set1AnalogOutChannel*/
/**
 * Sets the analog output channel b_Channel to the value w_Value. The ready bit is tested in the function.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] w_Value	Value to write on the analog output (0 to 65535)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The channel is not initialised
 * @retval -4 : This function cannot work if the digital external trigger is
 *              enabled
 * @retval -5 : The channel is initialised for the signal generator mode
 * @retval -6 : Time function error
 * @retval -7 : Time out occur
 */
int __needlock i_PCI3600_Set1AnalogOutChannel (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint16_t w_Value);

/* i_PCI3600_ReserveAnalogOutSignalGeneratorComputerBuffer*/
/**
 * Reserves a part of the computer buffer allocated for the analog output b_Channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] dw_BufferSize	Size (in nbr of acquisition) of the buffer to used for the analog output module
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : Buffer Size error
 * @retval -4 : The buffer is already reserved by another process
 * @retval -5 : The PC DMA Buffer is in use
 * @retval -6 : The channel is initialised in signal generator mode
 */
int __needlock i_PCI3600_ReserveAnalogOutSignalGeneratorComputerBuffer (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint32_t dw_BufferSize);

/* i_PCI3600_FreeAnalogOutSignalGeneratorComputerBuffer*/
/**
 * Releases the part of the computer buffer allocated by ADDIREG for the analog output b_Channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The buffer is not reserved or reserved by another process
 * @retval -4 : The channel is initialised in signal generator mode
 */
int __needlock i_PCI3600_FreeAnalogOutSignalGeneratorComputerBuffer (struct pci_dev *pdev,
		uint8_t b_Channel);

/* i_PCI3600_WriteAnalogOutSignalGeneratorComputerRAM*/
/**
 * Writes analog output values for the analog output b_Channel in the computer RAM buffer for this channel.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] dw_NbrOfValue	Number of value to write in the buffer
 * @param [in] pw_ValueArray	Value to write in the computer RAM buffer
 * @param [out] pdw_NbrOfWrittenValues	Number of values written in the computer buffer
 * @param [out] pdw_NbrOfFreeValues	Number of values who can be written in the computer buffer
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The buffer is not reserved
 * @retval -4 : The buffer is full
 */
int __needlock i_PCI3600_WriteAnalogOutSignalGeneratorComputerRAM (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint32_t dw_NbrOfValue,
		uint16_t* pw_ValueArray,
		uint32_t* pdw_NbrOfWrittenValues,
		uint32_t* pdw_NbrOfFreeValues);

/* i_PCI3600_InitAnalogOutSignalGenerator*/
/**
 * Initialise the signal generator for the analog output channel b_Channel.
 * Load the on-board RAM buffer with the values of the computer buffer.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] b_Mode	Mode of the analog output channel
 *                       \li 0 : Free Run Mode In this mode,
 *                       the on-board RAM buffer is filled one time and then this value are
 *                       always given to the analog output channel. The reserved computer buffer size
 *                       for this analog output must be equal to the On-board buffer size. No under run
 *                       error can occur in this mode. And no interrupt occur in this mode.
 *                       \li 1 : Ring Buffer Mode In this mode, the on-board RAM buffer is filled before the
 *                       start and then the value are given to the analog output channel. When the minimal
 *                       number of value is reached, an interrupt occur and the software load the buffer
 *                       with new values of the computer buffer (the user loads new values in the computer
 *                       buffer with the following function: i_PCI3600_WriteAnalogOutputSignalGeneratorComputerBufferValues(?)).
 *                       When the local DMA transfer is too speed, an under run error occur.
 * @param [in] dw_OnBoardBufferSize	Size (= n from 1024 * 2n bytes) of the On-board buffer
 *                                    (in the on-board RAM) to used for the analog output module
 * @param [in] dw_CompareValue	Define the number minimum of free place of the on-board RAM
 *                               to generate an interrupt.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : Wrong mode parameter
 * @retval -4 : The channel is not initialised
 * @retval -5 : The buffer is not reserved
 * @retval -6 : The compare value cannot be greater that the size of the on
 *              board buffer and cannot be null
 * @retval -7 : The Signal generator is already initialised by another process
 * @retval -8 : The signal generator is running
 * @retval -9 : Not enough place in the on board RAM
 * @retval -10 : A cycle acquisition or a signal generator is running
 * @retval -11 : The compare value must be greater than the actual free place
 *              in the on board RAM
 * @retval -12 : The size of the PC RAM buffer must be the same as the
 *              On Board Buffer size and it must be full
 * @retval -13 : The interrupt routine is not installed
 * @retval -14 : Time function error
 * @retval -15 : Time out occur
 * @retval -16 : Prepare DMA transfer Error
 */
int __needlock i_PCI3600_InitAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t   b_Channel,
		uint8_t   b_Mode,
		uint32_t dw_OnBoardBufferSize,
		uint32_t dw_CompareValue);

/* i_PCI3600_StartAnalogOutSignalGenerator*/
/**
 * Start the signal generator of the analog output channel b_Channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The signal generator is not initialised or not by this process
 * @retval -4 : The signal generator is already started
 */
int __needlock i_PCI3600_StartAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t b_Channel);

/* i_PCI3600_GetAnalogOutSignalGeneratorStatus*/
/**
 * Return the status and the number of value in the on-board RAM and in the computer RAM for the analog output channel b_Channel
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 *
 * @param [out] pb_Status	Status of the signal generator 0: not started, 1: started
 * @param [out] pdw_NbrOfValueInOnBoardRAM	Number of the value in the on-board RAM buffer
 * @param [out] pdw_NbrOfValueInComputerRAM	Number of the value in the computer RAM buffer
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The signal generator is not started or started by another process
 */
int __needlock i_PCI3600_GetAnalogOutSignalGeneratorStatus (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t* pb_Status,
		uint32_t* pdw_NbrOfValueInOnBoardRAM,
		uint32_t* pdw_NbrOfValueInComputerRAM);

/* i_PCI3600_StopAnalogOutSignalGenerator*/
/**
 * Stop the signal generator of the analog output channel b_Channel.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The signal generator is not started or started by another
 *              process
 */
int __needlock i_PCI3600_StopAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t b_Channel);

/* i_PCI3600_ReleaseAnalogOutSignalGenerator*/
/**
 * Release the signal generator of the analog output channel b_Channel.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : The signal generator is not initialised or not initialised by
 *              this process
 */
int __needlock i_PCI3600_ReleaseAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t b_Channel);

/* i_PCI3600_AnalogOut_EnableDisableDigitalInputExternalTrigger*/
/**
 * Enabled/Disable the digital input external trigger (digital input 0) for the analog output channel b_Channel.
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] b_ExternTriggerFlag	Enable/disable Flag for the digital input external trigger
 *                                  \li 0 : Disable
 *                                  \li 1 : Enable
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : Extern trigger flag is wrong
 * @retval -4 : The channel is not initialised
 * @retval -5 : The digital external trigger is not initialised
 */
int __needlock i_PCI3600_AnalogOut_EnableDisableDigitalInputExternalTrigger (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t b_ExternTriggerFlag);

/**		@}
 */

/**		\addtogroup Chronometer xPCI3600 Chronometer functions
 * 		\ingroup PCI3600
 *		@{
 */

/* i_PCI3600_InitChronometerModule*/
/**
 * Initialises the chronometer module b_ChronometerModule
 *
 * @param [in] pdev	The device to use
 * @param [in] b_ChronometerModule	Index of the chronometer module (0 to 3)
 * @param [in] b_ClockDivisor	Input divisor (0 to 15)
 *                               \li 0 : 20 -> divisor = 1
 *                               \li 1 : 21 -> divisor = 2
 *                               \li  ?
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong chronometer number
 * @retval -3 : Wrong clock divisor selection
 * @retval -4 : The Chronometer is already initialised by another process
 * @retval -5 : Initialisation Error
 */
int __needlock i_PCI3600_InitChronometerModule (struct pci_dev *pdev,
		uint8_t b_ChronometerModule,
		uint8_t b_ClockDivisor);

/* */
/**
 * Release the chronometer module b_ChronometerModule
 *
 * @param [in] pdev	The device to use
 * @param [in] b_ChronometerModule	Index of the chronometer module (0 to 3)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong Chronometer number
 * @retval -3 : The Chronometer is not initialised or initialised by another
 *              process
 */
int __needlock i_PCI3600_ReleaseChronometerModule (struct pci_dev *pdev,
		uint8_t b_ChronometerModule);

/* i_PCI3600_ReleaseChronometerModule*/
/**
 * Starts the chronometer module acquisition.
 * When this function is used, the value of the chronometer is latched and saved in the internal FIFO of the board.
 * You can stop the acquisition with the i_PCI3600_StopChronometerModuleAcquisition().
 * The acquisition is automatically stopped when the FIFO is full.
 *
 * @param [in] pdev	The device to use
 * @param [in] b_ChronometerModule	Index of the chronometer module (0 to 3)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong Chronometer number
 * @retval -3 : The Chronometer is not initialised
 * @retval -4 : The acquisition is already started
 */
int __needlock i_PCI3600_StartChronometerModuleAcquisition (struct pci_dev *pdev,
		uint8_t   b_ChronometerModule);

/* i_PCI3600_GetChronometerModuleFIFOStatus*/
/**
 * Returns the status of the internal FIFO to know if the chronometer values are available.
 *
 * @param [in] pdev	The device to use
 * @param [in] b_ChronometerModule	Index of the chronometer module (0 to 3)
 * @param [out]  pb_FIFOStatus	internal FIFO status
 *					 \li 00 : FIFO empty
 *                   \li 01 : FIFO not empty
 *                   \li 10 : FIFO error (Overflow)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong Chronometer number
 * @retval -3 : The Chronometer is not initialised
 */
int __needlock i_PCI3600_GetChronometerModuleFIFOStatus (struct pci_dev *pdev,
		uint8_t   b_ChronometerModule,
		uint8_t* pb_FIFOStatus);

/* i_PCI3600_ReadChronometerModuleValue*/
/**
 * Reads one chronometer value from the internal FIFO
 *
 * @param [in] pdev	The device to use
 * @param [in] b_ChronometerModule	Index of the chronometer module (0 to 3)
 * @param [out] pdw_ChronometerValue	Chronometer value read from the internal FIFO
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong Chronometer number
 * @retval -3 : The Chronometer is not initialised
 * @retval -4 : FIFO is empty
 */
int __needlock i_PCI3600_ReadChronometerModuleValue (struct pci_dev *pdev,
		uint8_t   b_ChronometerModule,
		uint32_t* pdw_ChronometerValue);

/* i_PCI3600_StopChronometerModuleAcquisition*/
/**
 * Stop the acquisition of the chronometer module value
 *
 * @param [in] pdev	The device to use
 * @param [in] b_ChronometerModule	Index of the chronometer module (0 to 3)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong Chronometer number
 * @retval -3 : The Chronometer is not initialised or not initialised by this
 *              process
 */
int __needlock i_PCI3600_StopChronometerModuleAcquisition (struct pci_dev *pdev,
		uint8_t b_ChronometerModule);

/* i_PCI3600_InitChronometerModuleCyclicAcquisition*/
/**
 * Initialise the cyclic acquisition for the chronometer module b_Module
 *
 * @param [in] pdev	The device to use
 * @param [in] b_Module	Index of the chronometer module (0 to 3)
 * @param [in] b_Mode	Define the mode used
 *                      \li 0 : AUTO-STOP Mode In this mode, the On board buffer is fill with value.
 *                          When the On board buffer is full, the acquisition is stopped and an interrupt occur.
 *                      \li 1 : RING Buffer Mode In this mode, the on board buffer is always fill with value.
 *                      In both modes:
 *                      Each time the number of the value in the buffer reach the dw_CompareValue,
 *                      an interrupt occur to permit to the software to read the value from the buffer.
 * @param [in] dw_OnBoardBufferSize	Size (in nbr of bytes : 1024 * 2 dw_OnBoardBufferSize) of the On-board buffer
 *                                     (in the on-board RAM) to used for the chrono.
 * @param [in] dw_CompareValue	Define the number of acquisition to have in the on-board Buffer
 *                              to generate an interrupt for start a DMA transfer.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : Wrong mode parameter
 * @retval -4 : The module is not initialised
 * @retval -5 : No computer buffer available
 * @retval -6 : The compare value cannot be :
 *              - greater that the size of the on board buffer in Auto Stop mode
 *              - greater or equal that the size of the on board buffer in Ring Buffer mode
 *              - null
 * @retval -7 : The cyclic acquisition is already initialised by another
 *              process
 * @retval -8 : The cyclic acquisition is running
 * @retval -9 : Not enough place in the on board RAM
 * @retval -10 : The interrupt routine is not installed
 * @retval -11 : Init Chronometer Error
 */
int __needlock i_PCI3600_InitChronometerModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module,
		uint8_t b_Mode,
		uint32_t dw_OnBoardBufferSize,
		uint32_t dw_CompareValue);

/* i_PCI3600_StartChronometerModuleCyclicAcquisition*/
/**
 * Starts the cyclic acquisition for the chronometer module b_Module
 *
 * @param [in] pdev	The device to use
 * @param [in] b_Module	Index of the chronometer module (0 to 3)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The Cyclic acquisition is not initialised or not by this process
 * @retval -4 : The Cyclic acquisition is already started
 */
int __needlock i_PCI3600_StartChronometerModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module);


/* i_PCI3600_GetChronometerModuleCyclicAcquisitionStatus*/
/**
 * Return the status and the number of value in the on-board RAM for the chronometer module b_Module.
 *
 * @param [in] pdev	The device to use
 * @param [in] b_Module	Index of the chronometer module (0 to 3)
 *
 * @param [out] pb_Status	Status of the cyclic acquisition
 *                          \li  0: not started
 *                          \li  1: started
 * @param [out] pdw_NbrOfValue	Number of value in the buffer in the on-board RAM for the chronometer
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The Cyclic Acquisition is not started or started by another
 *              process
 */
int __needlock i_PCI3600_GetChronometerModuleCyclicAcquisitionStatus (struct pci_dev *pdev,
		uint8_t b_Module,
		uint8_t* pb_Status,
		uint32_t* pdw_NbrOfValue);

/* i_PCI3600_IncrChronoCyclicAcquisitionBufferReadPointer*/
/**
 * Permits to increment the read pointer of the ring buffer used to do the DMA transfer
 *
 * @param [in] pdev	The device to use
 * @param [in] dw_NbrOfValue	Number of value
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 */
int __needlock i_PCI3600_IncrChronoCyclicAcquisitionBufferReadPointer (struct pci_dev *pdev,
		uint32_t dw_NbrOfValue);

/* i_PCI3600_StopChronometerModuleCyclicAcquisition*/
/**
 * Stops the cyclic acquisition for the chronometer module b_Module
 *
 * @param [in] pdev	The device to use
 * @param [in] b_Module	Index of the chronometer module (0 to 3)
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The Cyclic Acquisition is not started or started by another
 *              process
 */
int __needlock i_PCI3600_StopChronometerModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module);

/* i_PCI3600_ReleaseChronometerModuleCyclicAcquisition*/
/**
 * Releases the cyclic acquisition for the chronometer module b_Module
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Module number
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : The Cyclic Acquisition is not initialised or not initialised by
 *              this process
 */
int __needlock  i_PCI3600_ReleaseChronometerModuleCyclicAcquisition (struct pci_dev *pdev,
		uint8_t b_Module);

/* i_PCI3600_Chronometer_EnableDisableDigitalInputExternalTrigger*/
/**
 * Enable or diable the digital Input extern trigger
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_ChronometerModule	Chronometer module
 * @param [in] b_ExternTriggerFlag
 *                                 \li 0 Flag Disabled
 *                                 \li  1 Flag Enabled
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong chronometer number
 * @retval -3 : Extern trigger flag is wrong
 * @retval -4 : The chronometer is not initialised
 * @retval -5 : The digital external trigger is not initialised
 */
int __needlock i_PCI3600_Chronometer_EnableDisableDigitalInputExternalTrigger (struct pci_dev *pdev,
		uint8_t b_ChronometerModule,
		uint8_t b_ExternTriggerFlag);

/**		@}
 */



/**		\addtogroup ExternalTrigger xPCI3600 External trigger functions
 * 		\ingroup PCI3600
 *		@{
 */

/* i_PCI3600_InitDigitalInputExternalTrigger*/
 /**
 * Initialise the digital input external trigger (digital input 0).
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_TriggerLevel	Define the front of the digital input whose activate the external trigger.
 *                                     \li 01 : rising edge
 *                                     \li 10 : falling edge
 *                                     \li 11 : both edge
 * @param [in] w_TriggerCountValue	Define the number of trigger to wait that the firmware take in account the trigger.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong trigger level selection
 * @retval -3 : Wrong trigger count value
 * @retval -4 : The ext trigger is already initialised by another process
 */
int __needlock i_PCI3600_InitDigitalInputExternalTrigger (struct pci_dev *pdev,
		uint8_t b_TriggerLevel,
		uint16_t w_TriggerCountValue);

/**		@}
 */


/**		\addtogroup Mastertrigger xPCI3600 Master trigger functions
 * 		\ingroup PCI3600
 *		@{
 */

/*  i_PCI3600_AnalogIn_EnableDisableMasterTrigger */
/**
 * Enables/disables the master trigger for the analog input module b_Module
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_Module	Index of the analog input module (0 to 3).
 * @param [in] b_MasterTriggerFlag	Enable/disable Flag for the master trigger
 *                                     \li 0 : Disable
 *                                     \li 1 : Enable
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong module number
 * @retval -3 : Master trigger flag is wrong
 * @retval -4 : The module is not initialised
 */
int __needlock i_PCI3600_AnalogIn_EnableDisableMasterTrigger (struct pci_dev *pdev,
		uint8_t  b_Module,
		uint8_t  b_MasterTriggerFlag);

/* i_PCI3600_AnalogOut_EnableDisableMasterTrigger*/
/**
 * Enables/disables the master trigger for the analog output channel b_Channel.
 * @param [in] pdev	The device to use.
 * @param [in] b_Channel	Index of the analog output channel (0 to 1)
 * @param [in] b_MasterTriggerFlag	Enable/disable Flag for the master trigger
 *                                     \li 0 : Disable
 *                                     \li 1 : Enable
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong channel number
 * @retval -3 : Extern trigger flag is wrong
 * @retval -4 : The channel is not initialised
 */
int __needlock i_PCI3600_AnalogOut_EnableDisableMasterTrigger (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t b_MasterTriggerFlag);

/* i_PCI3600_MasterTrigger*/
/**
 * Generate a master trigger.
 *        Can only be use if the board is initialised in master mode.
 *
 * @param [in] pdev	The device to use.
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : The board is not initialised as master
 */
int __needlock i_PCI3600_MasterTrigger (struct pci_dev *pdev);

/* i_PCI3600_Chronometer_EnableDisableMasterTrigger*/
/**
 * Enable or disable the master trigger
 *
 * @param [in] pdev	The device to use.
 * @param [in] b_ChronometerModule	Chronometer module
 * @param [in] b_MasterTriggerFlag
 *                                  \li 0 Flag Disabled
 *                                  \li  1 Flag Enabled
 *
 * @retval  0 : No Error
 * @retval -1 : The handle parameter of the board is wrong
 * @retval -2 : Wrong chronometer number
 * @retval -3 : Extern trigger flag is wrong
 * @retval -4 : The chronometer is not initialised
 */
int __needlock i_PCI3600_Chronometer_EnableDisableMasterTrigger (struct pci_dev *pdev,
		uint8_t b_ChronometerModule,
		uint8_t b_MasterTriggerFlag);

/**		@}
*/


/**
 * find a apci 3600 device of a given index in the system PCI device list.
 * @param index The index (minor number) to lookup
 * @return A pointer to the device or NULL
 *
 * This function is used to map a minor number to an actual device.
 */
static __inline__  struct pci_dev * apci3600_lookup_board_by_index(unsigned int index)
{
	struct pci_dev * dev = NULL;
	int i = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
	while ( (dev = pci_find_device(APCI3600_BOARD_VENDOR_ID,APCI3600_BOARD_DEVICE_ID,dev)) )
#else
		while ( (dev = pci_get_device(APCI3600_BOARD_VENDOR_ID,APCI3600_BOARD_DEVICE_ID,dev)) )
#endif
		{
			if (i == index) return dev;
			i++;
		}

	return NULL;

}

#endif

