 /* @file apci3600.h
  * 
  * @brief Define the public API for the apci3600 ADDI-DATA board. 
  * 
  * 
  */

/** @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 library is free software; you can redistribute it and/or modify it under 
 the terms of the GNU Lesser General Public License as published by the 
 Free Software Foundation; either version 2.1 of the License, 
 or (at your option) any later version.
 
 This library 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 Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public License 
 along with this library; if not, write to the Free Software Foundation, 
 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 
 You also shoud find the complete LGPL in the LGPL.txt file accompanying 
 this source code.
 
 @endverbatim
**/

#ifndef __APCI3600_H__
#define __APCI3600_H__


#define APCI3600_DRIVER_VERSION_MAJOR 2026
#define APCI3600_DRIVER_VERSION_MINOR 06
#define APCI3600_DRIVER_VERSION_PATCH 1

#include <apci.h>

//GENERAL DEFINE
#define APCI3600_BOARD_NAME                      "APCI3600"
#define APCI3600_BOARD_VENDOR_ID                 0x15B8
#define APCI3600_BOARD_DEVICE_ID                 0x300F

/* value used for CMD_APCI3600_CheckAndGetPCISlotNumber ! DEPRECATED ! */
#ifndef CONFIG_APCI3600_MAX_BOARD_NBR
#define CONFIG_APCI3600_MAX_BOARD_NBR                   (3)
#endif // CONFIG_APCI3600_MAX_BOARD_NBR

// for compatibility with older driver (deprecated)
#define APCI3600_MAX_BOARD_NBR CONFIG_APCI3600_MAX_BOARD_NBR


// Begin 15/09/2005 CG
#define	 PCI3600_ENABLE	   1
#define	 PCI3600_DISABLE   0

#define  PCI3600_ASYNCHRONOUS_MODE 0
#define  PCI3600_SYNCHRONOUS_MODE  1

#define	 PCI3600_MAX_BOARD_DETECTION 30
#define  PCI3600_MAX_NBR_COMPUTER_BUFFER 50


/*******************************/
/* Clock Initialisation define */
/*******************************/
#define  PCI3600_MASTER_MODE  0
#define	 PCI3600_SLAVE_MODE   1
#define  PCI3600_DIVISOR_4    4
#define	 PCI3600_DIVISOR_5    5
#define	 PCI3600_DIVISOR_6    6
#define	 PCI3600_DIVISOR_8    8
#define	 PCI3600_DIVISOR_10   10
#define	 PCI3600_DIVISOR_12   12
#define	 PCI3600_DIVISOR_16   16
#define	 PCI3600_DIVISOR_20   20
#define	 PCI3600_DIVISOR_25   25
#define	 PCI3600_DIVISOR_40   40
#define	 PCI3600_DIVISOR_50   50
#define	 PCI3600_DIVISOR_60   60
#define	 PCI3600_DIVISOR_80   80
#define	 PCI3600_DIVISOR_100  100

#define	 PCI3600_CLK_GENERATOR_1 0
#define	 PCI3600_CLK_GENERATOR_2 1
#define	 PCI3600_CHRONOMETER_0_LATCH_INPUT   2
#define	 PCI3600_CHRONOMETER_1_LATCH_INPUT   3

#define	 PCI3600_EXT_CLOCK_1  0
#define	 PCI3600_EXT_CLOCK_2  1

#define	 PCI3600_CHRONOMETER_DIVISOR_1	  0
#define	 PCI3600_CHRONOMETER_DIVISOR_10	  1
#define	 PCI3600_CHRONOMETER_DIVISOR_100  2


#define	 PCI3600_SINGLE_ENDED_MODE  0
#define	 PCI3600_DIFFERENTIAL_MODE  1

#define	 PCI3600_DC_COUPLING  0
#define	 PCI3600_AC_COUPLING  1

#define	 PCI3600_SAMPLING_CLOCK1 0
#define	 PCI3600_SAMPLING_CLOCK2 1

#define	 PCI3600_SINGLE_SPEED 0
#define	 PCI3600_DOUBLE_SPEED 1
#define	 PCI3600_QUAD_SPEED   2

#define	 PCI3600_RISING_EDGE  1
#define	 PCI3600_FALLING_EDGE 2
#define	 PCI3600_BOTH_EDGE    3


#define  PCI3600_FREE_RUN_MODE	    0
#define  PCI3600_AUTO_STOP_MODE	    0
#define  PCI3600_RING_BUFFER_MODE   1
// End 15/09/2005 CG

/* minor number enumeration for board devices */  
enum 
{
	APCI3600_DEV_MINOR_BASE 			= 0, /* functions general to the board */
	APCI3600_DEV_MINOR_ANALOG_OUTPUT_0	= 1, 
	APCI3600_DEV_MINOR_ANALOG_OUTPUT_1	= 2,
	APCI3600_DEV_MINOR_ANALOG_INPUT_0	= 3,
	APCI3600_DEV_MINOR_ANALOG_INPUT_1	= 4,
	APCI3600_DEV_MINOR_ANALOG_INPUT_2	= 5,
	APCI3600_DEV_MINOR_ANALOG_INPUT_3	= 6,
	APCI3600_DEV_MINOR_CHRONO_0			= 7,
	APCI3600_DEV_MINOR_CHRONO_1			= 8,
	APCI3600_DEV_MINOR_CHRONO_2			= 9,
	APCI3600_DEV_MINOR_CHRONO_3			= 10,
	APCI3600_DEV_MINOR_DIGITAL_INPUT	= 11,
	APCI3600_DEV_MINOR_DIGITAL_OUTPUT	= 12,
	APCI3600_DEV_MINOR_EXTERNAL_TRIGGER	= 13,
	APCI3600_DEV_MINOR_MAX	= 14, /* use to know the maximum value for dev minor = APCI3600_DEV_MINOR_MAX-1 */
};

// IOCTL define part
#define APCI3600_MAGIC (char) 'A'

/**
 * @param (char*) area of size CONFIG_APCI3600_MAX_BOARD_NBR+1
 * 
 * @deprecated
 * 
 */
#define CMD_APCI3600_CheckAndGetPCISlotNumber   							_IOR(APCI3600_MAGIC, 1,char*)

#define CMD_APCI3600_SetBoardInformation        							_IOW(APCI3600_MAGIC, 2,uint16_t)

/**
 * @deprecated
 */
#define CMD_APCI3600_GetHardwareInformation     							_IOR(APCI3600_MAGIC, 3,str_BaseInformations*)

//-------------------------------------------------------------------------------------------------------------------
/* InitBoard */

/**
@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   
*/

typedef struct {
	uint8_t b_MasterSlaveMode; /**< Selection of the mode of the board : - 0 : Master Mode , 1 : Slave Mode */
	uint8_t b_ClockGen1_Divisor; /**< Selection of the divisor for the clock generator 1 */
	uint8_t b_ClockGen2_Divisor; /**< Selection of the divisor for the clock generator 2 */
	uint8_t b_SamplingClock1_Selection; /**< Selection of the clock for the sampling clock 1 */
	uint8_t b_SamplingClock2_Selection; /**< Selection of the clock for the sampling clock 2 */
	uint8_t b_SlaveSamplingClock1_Selection; /**< Selection of the clock for the sampling clock 1 for the slave board - 0 : PCI3600_EXT_CLOCK_1 , 1 : PCI3600_EXT_CLOCK_2 */
	uint8_t b_SlaveSamplingClock2_Selection; /**< Selection of the clock for the sampling clock 2 for the slave board - 0 : PCI3600_EXT_CLOCK_1 , 1 : PCI3600_EXT_CLOCK_2 */
	uint8_t b_Chronometer_MasterClock_Divisor; /* Selection of the divisor for the master clock for the Chronometer - PCI3600_CHRONOMETER_DIVISOR_1, PCI3600_CHRONOMETER_DIVISOR_10 , PCI3600_CHRONOMETER_DIVISOR_100 */
	
} str_InitBoardArg_t ;

/* IMPORTANT: In slave mode, the Clock1 and Clock2 selection and divisor MUST be the same that the master board. */

#define CMD_APCI3600_InitBoard												_IOW(APCI3600_MAGIC, 4, str_InitBoardArg_t *)

//-------------------------------------------------------------------------------------------------------------------
/* for debugging only - do not use */
#define CMD_APCI3600_GetDMATransferStatus									_IOR(APCI3600_MAGIC, 5, uint8_t*)

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

/* for debugging only */ 
#define CMD_APCI3600_DumpDMAController										_IOR(APCI3600_MAGIC, 6, long)


//-------------------------------------------------------------------------------------------------------------------
/* GetBoardInitialisation */

typedef struct
{
	uint8_t b_MasterSlaveMode; /* 0 : board in Master Mode 1 : board is in slave Mode */ 
	uint8_t b_ClockGen1_Divisor; /* Get the divisor for the clock generator 1  see table */
	uint8_t b_ClockGen2_Divisor; /* Get the divisor for the clock generator 2 see table */
	uint8_t b_SamplingClock1_Selection; /* Get the clock for the sampling clock 1 */
	uint8_t b_SamplingClock2_Selection; /* Get the clock for the sampling clock 2 */
	uint8_t b_SlaveSamplingClock1_Selection; /* Get the clock for the sampling clock 1 for the slave board 0 : PCI3600_EXT_CLOCK_1 1 : PCI3600_EXT_CLOCK_2 */
	uint8_t b_SlaveSamplingClock2_Selection; /* Get the clock for the sampling clock 2 for the slave board 0 : PCI3600_EXT_CLOCK_1 1 : PCI3600_EXT_CLOCK_2 */		
	uint8_t b_Chronometer_MasterClock_Divisor; /* Get the divisor for the master clock for the Chronometer: 0 : PCI3600_CHRONOMETER_DIVISOR_1 1 : PCI3600_CHRONOMETER_DIVISOR_10 2 : PCI3600_CHRONOMETER_DIVISOR_100 */
}
str_GetBoardInitialisation_t;

//-------------------------------------------------------------------------------------------------------------------
/* retval 0 success 
 * @retval -1 system error
 * @retval 1 : The handle parameter of the board is wrong
 * @retval 2 : The board is not initialised
*/

#define CMD_APCI3600_GetBoardInitialisation 								_IOR(APCI3600_MAGIC, 7, str_GetBoardInitialisation_t*)


/* EVENTS ****************************************************************************/

/** Empty event FIFO of all pending events.
 * 
 * @param arg None (Use NULL)
 * 
 * @return 0 on success, -1 on failure (see errno then) 
 * 
 */
#define CMD_APCI3600_EventEmpty         									_IOW(APCI3600_MAGIC, 8,void*)

//-------------------------------------------------------------------------------------------------------------------
/** Wait for an event.
 * 
 * @param[in] arg apci3600_event_t*
 * }
 * 
 * @return 0 on success, -1 on failure (see errno then) 
 * 
 */


#define CMD_APCI3600_EventWait         										_IOW(APCI3600_MAGIC, 9, apci3600_event_t*)

/* returns the size in bytes of the driver memory buffer */
#define CMD_APCI3600_QueryAnalogInputCyclicAcquisitionBufferSize			_IOR(APCI3600_MAGIC, 10, unsigned long*)

/* reset buffer - warning: all data are lost ! */
#define CMD_APCI3600_ResetAcquisitionBuffer									_IOR(APCI3600_MAGIC, 11, unsigned long)

/*  */
#define CMD_APCI3600_QueryAnalogInputCyclicAcquisitionNumberOfData			_IOR(APCI3600_MAGIC, 12, unsigned long*)

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

/* To start all analog input cyclic acquisitions in a same time
 * @param[in] mask	Module mask, set the module bit to start on 1.
 * 					Module 0: bit 0
 * 					Module 1: bit 1
 * 					Module 2: bit 2
 * 					Module 3: bit 3
 */
#define CMD_APCI3600_StartMoreAnalogInputModuleCyclicAcquisition			_IOR(APCI3600_MAGIC, 13, uint8_t)

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


/* DIGITAL INPUTS ****************************************************************************/

#define CMD_APCI3600_Read8DigitalInputs										_IOR(APCI3600_MAGIC, 1, uint8_t)


/* DIGITAL OUTPUTS ****************************************************************************/

#define CMD_APCI3600_EnableDisableDigitalOutputMemory						_IOW(APCI3600_MAGIC, 1, uint8_t)
#define CMD_APCI3600_Set1DigitalOutputOn									_IOW(APCI3600_MAGIC, 2, uint8_t)
#define CMD_APCI3600_Set1DigitalOutputOff									_IOW(APCI3600_MAGIC, 3, uint8_t)
#define CMD_APCI3600_Set8DigitalOutputsOn									_IOW(APCI3600_MAGIC, 4, uint8_t)
#define CMD_APCI3600_Set8DigitalOutputsOff									_IOW(APCI3600_MAGIC, 5, uint8_t)

//-------------------------------------------------------------------------------------------------------------------
/** Used internally. This is the ioctl CMD with the highest number.
 * @internal
 */
#define __APCI3600_BASE_UPPER_IOCTL_CMD 13

#define __APCI3600_ANALOG_OUTPUT_UPPER_IOCTL_CMD 0
 
#define __APCI3600_CHRONOMETER_UPPER_IOCTL_CMD 0

#define __APCI3600_DIGITAL_INPUT_UPPER_IOCTL_CMD 1

#define __APCI3600_DIGITAL_OUTPUT_UPPER_IOCTL_CMD 5

#include <apci3600-analoginput.h>
#include <apci3600-externaltrigger.h>

#endif // __APCI3600_H__
