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

/** @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 Rheinmuenster
 Germany
 Tel: +49(0)7229/1847-0
 Fax: +49(0)7229/1847-200
 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 __APCI3120_H__
#define __APCI3120_H__


#include "apci.h"

/* APCI 3120 */
#define APCI3120_BOARD_NAME                      "apci3120"
#define APCI3120_BOARD_VENDOR_ID                 0x10E8
#define APCI3120_BOARD_DEVICE_ID                 0x818D

/* APCIE 3120 (express) */
#define APCIE3120_BOARD_NAME                      "apcie3120"
#define APCIE3120_BOARD_VENDOR_ID                 0x15B8
#define APCIE3120_BOARD_DEVICE_ID                 0x303D


#define APCI3120_1_GAIN                           0x00
#define APCI3120_2_GAIN                           0x10
#define APCI3120_5_GAIN                           0x20
#define APCI3120_10_GAIN                          0x30

#define APCI3120_BIPOLAR                          0x00
#define APCI3120_UNIPOLAR                         0x80

#define APCI3120_DISABLE                         0
#define APCI3120_ENABLE                          1

#define APCI3120_DMA_USED           1
#define APCI3120_DMA_NOT_USED       0
#define APCI3120_SIMPLE_MODUS         0
#define APCI3120_DELAY_MODUS          1
#define APCI3120_SINGLE               0
#define APCI3120_CONTINUOUS           1


#define  APCI3120_CHANNEL_0	0
#define  APCI3120_CHANNEL_1	1
#define  APCI3120_CHANNEL_2	2
#define  APCI3120_CHANNEL_3	3
#define  APCI3120_CHANNEL_4	4
#define  APCI3120_CHANNEL_5	5
#define  APCI3120_CHANNEL_6	6
#define  APCI3120_CHANNEL_7	7
#define  APCI3120_CHANNEL_8	8
#define  APCI3120_CHANNEL_9	9
#define  APCI3120_CHANNEL_10	10
#define  APCI3120_CHANNEL_11	11
#define  APCI3120_CHANNEL_12	12
#define  APCI3120_CHANNEL_13	13
#define  APCI3120_CHANNEL_14	14
#define  APCI3120_CHANNEL_15	15

#define APCI3120_MAX_CHANNEL_NBR 16

#define APCI3120_COUNTER                   0
#define APCI3120_TIMER                     1
#define APCI3120_WATCHDOG                  2

#define APCI3120_AMCC_OP_REG_INTCSR      0x38
#define APCI3120_TIMER_STATUS_REGISTER 0xd
#define APCI3120_CLEAR_WRITE_TC_INT               0x00040000L
#define APCI3120_ENABLE_WRITE_TC_INT              0x00004000L

#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
#define APCI3120_DISABLE_BUS_MASTER_ADD_ON        0x0
#define APCI3120_DISABLE_BUS_MASTER_PCI           0x0

/* value used for CMD_APCI3120_CheckAndGetPCISlotNumber ! DEPRECATED ! */
#ifndef CONFIG_APCI3120_MAX_BOARD_NBR
#define CONFIG_APCI3120_MAX_BOARD_NBR                   (3)
#endif // CONFIG_APCI3120_MAX_BOARD_NBR

// for compatibility with older driver (deprecated)
#define APCI3120_MAX_BOARD_NBR CONFIG_APCI3120_MAX_BOARD_NBR

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

/**
 * @param (char*) area of size CONFIG_APCI3120_MAX_BOARD_NBR+1
 *
 * @deprecated
 *
 */
#define CMD_APCI3120_CheckAndGetPCISlotNumber   _IOR(APCI3120_MAGIC, 1, char*)

#define CMD_APCI3120_SetBoardInformation        _IOW(APCI3120_MAGIC, 2, uint16_t)

/**
 * @deprecated
 */
#define CMD_APCI3120_GetHardwareInformation     _IOR(APCI3120_MAGIC, 3, str_BaseInformations*)

/** Read 1 analog input channel.
 *
 * This function call all kapi functions to read 1 analog input channel.
 * It can be possible to use separate functions to do that once they are
 * implemented.
 *
 * @param [in] pdev								: The device to initialize.
 * @param [in] arg[0] (b_Channel)				: Number of the analog input to be read.
 * @param [in] arg[1] (b_Gain)					: Gain selection.
 * @param [in] arg[2] (b_Polarity)				: Selection of the input voltage range of the analog input to convert.
 * @param [in] arg[3] (ui_ConvertinTiming)		: Selection of the conversion time from 10 microseconds to 32767 microseconds.
 * @param [in] arg[4] (b_InterruptFlag)			: This parameter has to be 0 or PCI3120_DISABLE.<br>
 * 																The interrupt is not implemented!
 * @param [out] arg[0] (ui_AnalogInputValue)	: The analog value.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: Number of the analog input is wrong.
 * @retval 3: The selected gain is wrong.
 * @retval 4: The selected input voltage range is wrong.
 * @retval 5: The selected conversion time is wrong.
 * @retval 6: A wrong parameter has been passed for <br>
 *				b_InterruptFlag or the user interrupt routine has <br>
 *				not been installed.
 * @retval 7: Time out.
 * @retval -EFAULT : Fail to retrieve user data.
 */
#define CMD_APCI3120_Read1AnalogInput			_IOWR(APCI3120_MAGIC, 4, uint32_t*)

/** Write 1 analog output channel.
 *
 * This function call all kapi functions to write 1 analog output channel.
 * It can be possible to use separate functions to do that once they are
 * implemented.
 *
 * @param [in] pdev								: The device to initialize.
 * @param [in] arg[0] (b_Channel)				: Number of the analog output to be read.
 * @param [in] arg[1] (b_Polarity)				: Selection of the output voltage range of the analog output to convert.
 * @param [in] arg[2] (ui_ValueToWrite)			: Analog value to write on the output.
 *  *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: Number of the analog output is wrong.
 * @retval 3: The selected output voltage range is wrong.
 * @retval 4: Wrong output value for the output channel.
 * @retval 5: Time out.
 * @retval -EFAULT : Fail to retrieve user data.
 */
#define CMD_APCI3120_Write1AnalogOutput			_IOW(APCI3120_MAGIC, 5, uint32_t*)

/** Read more analog input channel.
 *
 * This function call all kapi functions to read more analog input channel.
 *
 * @param [in] pdev					: The device to initialize.
 * @param [in]	arg[0] (b_SequenzArraySize)		: Size of the sequence array (1 to 16 elements).
 * @param [in]	arg[1] (pb_ChannelArray)		: Channels to read (array size = b_SequenzArraySize).
 * @param [in]	arg[...] (pb_GainArray)			: Gain selection array.
 * @param [in]	arg[...] (pb_PolarityArray)		: Selection of the input.
 * @param [in]	arg[...] (ui_ConvertTiming)		: Selection of the conversion time from 10 to 32767 us.
 * @param [in]	arg[...] (b_InterruptFlag)		: This parameter has to be 0 or PCI3120_DISABLE.<br>
 * 																The interrupt is not implemented!
 *
 * @param [out]	arg[0...] (pui_AnalogInputValueArray)	: Read values.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: The size of the sequence table is wrong.
 * @retval 3: Wrong parameter found in table "pb_ChannelArray".
 * @retval 4: Wrong parameter found in table "pb_GainArray".
 * @retval 5: Wrong parameter found in table "pb_PolarityArray".
 * @retval 6: The selected conversion time is wrong.
 * @retval 7: A wrong parameter has been passed for b_InterruptFlag.
 * @retval 8: Time out.
 * @retval -EFAULT : Fail to retrieve user data.
 */
#define CMD_APCI3120_ReadMoreAnalogInputs			_IOWR(APCI3120_MAGIC, 6, uint32_t*)

/** Write more analog output channel.
 *
 * This function call all kapi functions to write 1 analog output channel.
 * It can be possible to use separate functions to do that once they are
 * implemented.
 *
 * @param [in] pdev					: The device to initialize.
 * @param [in] arg[0] (b_FisrtChannel)			: The first channel number up which is to be written.
 * @param [in] arg[1] (b_NumberOfChannel)		: The number of channels to write.
 * @param [in] arg[2] (b_PolarityArray)			: Selection of the output voltage range.
 * @param [in] arg[..] (ui_WriteValueArray)		: Analog values to write on the output channels.
 *  *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: Number of the analog output is wrong.
 * @retval 3: The selected output voltage range is wrong.
 * @retval 4: Wrong output value for the output channel.
 * @retval 5: Time out.
 * @retval -EFAULT : Fail to retrieve user data.
 */
#define CMD_APCI3120_WriteMoreAnalogOutput			_IOW(APCI3120_MAGIC, 7, uint32_t*)

#define CMD_APCI3120_InitReadMoreAnalogInput		_IOW(APCI3120_MAGIC, 8, uint32_t*)
#define CMD_APCI3120_StartReadMoreAnalogInput		_IOW(APCI3120_MAGIC, 9, uint32_t*)
#define CMD_APCI3120_TestEndOfReadMoreConversion	_IO(APCI3120_MAGIC, 10)
#define CMD_APCI3120_TestReadMoreAnalogInput		_IOW(APCI3120_MAGIC, 11, uint32_t*)
#define CMD_APCI3120_ReadMoreValues					_IOWR(APCI3120_MAGIC, 12, uint32_t*)

/** Read 4 digital input.
 *
 * @param [in] pdev                       : The device to manage.
 * @param [out] arg (b_DigitalInputValue) : Digital input value.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval -EFAULT : Fail to retrieve user data.
 */
#define CMD_APCI3120_Read4DigitalInput				_IOW(APCI3120_MAGIC, 13, uint8_t*)

/** Set digital output memory on.
 *
 * When output memory is setting on. Output state is holding, and <br>
 * the new output(s) is(are) set or reset.
 *
 * @param [in] pdev                 : The device to manage.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 */
#define CMD_APCI3120_SetOutputMemoryOn				_IO(APCI3120_MAGIC, 14)

/** Set digital output memory off.
 *
 * @param [in] pdev                 : The device to manage.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 */
#define CMD_APCI3120_SetOutputMemoryOff				_IO(APCI3120_MAGIC, 15)

/** Set 4 digital output on.
 *
 * @param [in] pdev                       : The device to manage.
 * @param [in] arg (b_DigitalOutputValue) : Digital output value.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: The digital output value is wrong.
 */
#define CMD_APCI3120_Set4DigitalOutputOn				_IOW(APCI3120_MAGIC, 16, uint8_t)

/** Set 4 digital output off.
 *
 * Can only be used when i_APCI3120_SetOutputMemoryOn has been called.
 *
 * @param [in] pdev                 : The device to manage.
 * @param [in] arg (b_DigitalOutputValue) : Digital output value.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: The digital output value is wrong.
 * @retval 3: Output memory is not activated (please use i_APCI3120_SetOutputMemoryOn).
 */
#define CMD_APCI3120_Set4DigitalOutputOff				_IOW(APCI3120_MAGIC, 17, uint8_t)



#define CMD_APCI3120_InitAnalogInputSequenceAcquisition		_IOW(APCI3120_MAGIC, 18, uint32_t*)

#define CMD_APCI3120_GetState     _IOR(APCI3120_MAGIC, 19)

#define CMD_APCI3120_StartAnalogInputSequenceAcquisition     _IO(APCI3120_MAGIC, 20)

#define CMD_APCI3120_SetBoardInterruptRoutine     _IOW(APCI3120_MAGIC, 21, void*)

#define CMD_APCI3120_ResetBoardInterruptRoutine     _IO(APCI3120_MAGIC, 22)

#define CMD_APCI3120_StopSequenceAcquisition _IO(APCI3120_MAGIC, 23)

#define CMD_APCI3120_StopSequenceAcquisition _IO(APCI3120_MAGIC, 23)

#define CMD_apci3120_EventEmpty _IO ( APCI3120_MAGIC, 24)

#define CMD_apci3120_EventWait _IOWR ( APCI3120_MAGIC, 25, uint32_t* )

/** Used internally. This is the ioctl CMD with the highest number.
 * @internal
 */
#define __APCI3120_UPPER_IOCTL_CMD 25

/**
 * Type definition
 */
/** Sequence Acquisition data
 * Parameters that are required to do a sequence acquisition
 */
struct apci3120_sequence_acquisition_data
{
	uint8_t acquisition_mode;			// APCI3120_SIMPLE_MODUS or APCI3120_DELAY_MODUS
	uint8_t extern_trigger;				// APCI3120_DISABLE or APCI3120_ENABLE
	uint32_t acquisition_timing; 		// in micro second
	uint64_t delay_timing; 				// in micro second too: the delay between two sequence
	uint32_t number_of_acquisition;		// the number of acquisition before generating an interrupt
	uint8_t dma_mode; 					// use dma or not (for the moment user must use DMA !!!)
	uint8_t acquisition_cycle; 			// APCI3120_SINGLE or APCI3120_CONTINUOUS

	uint8_t sequence_array_size;							// The size of the sequence (how many channels will be acquired)
	uint8_t sequence_channels[APCI3120_MAX_CHANNEL_NBR];	// The channel that will be acquired in the sequence
	uint8_t gain[APCI3120_MAX_CHANNEL_NBR];					// The gain of the selected channel
	uint8_t polarity[APCI3120_MAX_CHANNEL_NBR];				// The polary of the selected channel
};

/*
 * State of our device
 */
enum state
	{ 	STATE_UNINIT,
		STATE_SEQUENCE_INITIALISED,
		STATE_SEQUENCE_STARTED
	};

#endif // __APCI3120_H__
