/***********************************\
*	GAGE_LOW.H		VERSION 3.00.	*
*									*
*	WRITTEN FOR BC31, MSC70, WC90.	*
*									*
*	COPYRIGHT (C) GAGE APPLIED		*
*	SCIENCES INC.			1998.	*
*									*
*	LAST UPDATE:		99/06/27.	*
\***********************************/

/*----------------------------------------------------------*/

#ifndef	__GAGE_LOW_H__
#define __GAGE_LOW_H__

#include	<stdlib.h>

#ifndef	__WHICHDRV_H__
    #include "whichdrv.h"
#endif //__WHICHDRV_H__

/*----------------------------------------------------------*/

/*	CompuScope definition for number of registers on any board.	*/

#define	GAGE_NUMBER_REGS		0x14

/*----------------------------------------------------------*/

/*	CompuScope power management definitions.	*/

#define	GAGE_POWER_OFF				0
#define	GAGE_POWER_ON				1
#define	GAGE_POWER_AUTO				2
#define	GAGE_POWER_LAST				3

#define	GAGE_POWER_ON_MASK			0x0001
#define	GAGE_POWER_AUTO_MASK		0x0002

#define	GAGE_POWER_ON_SHIFT			2	/*	Preserve LS two bits.	*/

#define	GAGE_POWER_ON_DELAY			100	/*	10  Milliseconds.	*/
#define	GAGE_POWER_ON_DELAY_2XX5	100	/*	10  Milliseconds.	*/
#define	GAGE_POWER_ON_DELAY_X012	80	/*	80  Milliseconds.	*/
#define	GAGE_POWER_ON_DELAY_121X0	80	/*	8   Milliseconds.	*/
#define	GAGE_POWER_ON_DELAY_MASK	3	/*	Preserve LS two bits.	*/

/*----------------------------------------------------------*/

/*	Regarding trigger offsets.
	==========================

	Trigger level offsets have three components, one beyond
	our control but the other two are trigger level offset
	and trigger address offset.  Trigger level offset refers
	to the fact that the actual trigger level is different
	from the value set by the driver into hardware.  This
	offset is different for positive and negative slopes.
	The trigger address offset is an offset from the trigger
	address as returned by hardware.  This is dependant on
	both the mode an the sample rate.  It is consistant
	below 5 MHz single or dual mode for the CS2125/265.

	A similar scheme is in place for the CS1610.  This card
	currently only operates in dual channel mode.  The
	EEPROM is encoded differently (uInt8's not uInt4's as
	on the CS2125/265) therefore, there are only 8 entries
	versus 16 entries for the CS2125/265.  Thus only the
	first 8 entries of the trig_addr_off array are used.	*/

/*----------------------------------------------------------*/

/*	Definitions for correcting trigger offsets.	*/

/*	Nomenclature:	CS2125_TAOI_S_250
		TAOI	:	Trigger Address Offset Index
		S|D		:	Single or Dual channel
		250		:	sample rate in MHz.	*/

#define	CS2125_TAOI_NONE	0
#define	CS2125_TAOI_S_250	1
#define	CS2125_TAOI_S_120	2
#define	CS2125_TAOI_S_100	3
#define	CS2125_TAOI_S_60	4
#define	CS2125_TAOI_S_50	5
#define	CS2125_TAOI_S_30	6
#define	CS2125_TAOI_S_20	7
#define	CS2125_TAOI_S_10	8
#define	CS2125_TAOI_S_5		9
#define	CS2125_TAOI_D_125	10
#define	CS2125_TAOI_D_60	11
#define	CS2125_TAOI_D_50	12
#define	CS2125_TAOI_D_30	13
#define	CS2125_TAOI_D_20	14
#define	CS2125_TAOI_D_10	15
#define	CS2125_TAOI_D_5		16
#define	CS2125_TAOI_EXT		17

#define	CS2125_TAOI_SINGLE	CS2125_TAOI_S_250
#define	CS2125_TAOI_DUAL	CS2125_TAOI_D_125
#define	CS2125_TAOI_MAX		18

/*	Generic names for CS12100, CS1250, CS12130 and CS1610.

	Nomenclature:	CS1XXX0_TAOI_S_SR1
		TAOI	:	Trigger Address Offset Index
		S|D		:	Single or Dual channel
		SR1		:	sample rate 1 (generic meaning).	*/

#define	CS1XXX0_TAOI_NONE	0
#define	CS1XXX0_TAOI_S_SR1	1
#define	CS1XXX0_TAOI_S_SR2	2
#define	CS1XXX0_TAOI_S_SR3	3
#define	CS1XXX0_TAOI_S_SR4	4
#define	CS1XXX0_TAOI_D_SR1	5
#define	CS1XXX0_TAOI_D_SR2	6
#define	CS1XXX0_TAOI_D_SR3	7
#define	CS1XXX0_TAOI_D_SR4	8
#define	CS1XXX0_TAOI_EXT	9

#define	CS1XXX0_TAOI_SINGLE	CS1XXX0_TAOI_S_SR1
#define	CS1XXX0_TAOI_DUAL	CS1XXX0_TAOI_D_SR1
#define	CS1XXX0_TAOI_MAX	CS2125_TAOI_MAX		/*	18	*/

/*	Specific names for CS1610.

	Nomenclature:	CS1610_TAOI_S_20
		TAOI	:	Trigger Address Offset Index
		S|D		:	Single or Dual channel
		20		:	sample rate in MHz.	*/

#define	CS1610_TAOI_NONE	CS1XXX0_TAOI_NONE
#define	CS1610_TAOI_S_40	CS1XXX0_TAOI_S_SR1	/*	No planned support for this mode.	*/
#define	CS1610_TAOI_S_20	CS1XXX0_TAOI_S_SR2	/*	No planned support for this mode.	*/
#define	CS1610_TAOI_S_10	CS1XXX0_TAOI_S_SR3	/*	No planned support for this mode.	*/
#define	CS1610_TAOI_S_5		CS1XXX0_TAOI_S_SR4	/*	No planned support for this mode.	*/
#define	CS1610_TAOI_D_20	CS1XXX0_TAOI_D_SR1
#define	CS1610_TAOI_D_10	CS1XXX0_TAOI_D_SR2
#define	CS1610_TAOI_D_5		CS1XXX0_TAOI_D_SR3
#define	CS1610_TAOI_D_2_5	CS1XXX0_TAOI_D_SR4
#define	CS1610_TAOI_EXT		CS1XXX0_TAOI_EXT

#define	CS1610_TAOI_SINGLE	CS1610_TAOI_S_20
#define	CS1610_TAOI_DUAL	CS1610_TAOI_D_10
#define	CS1610_TAOI_MAX		CS1XXX0_TAOI_MAX

/*----------------------------------------------------------*/

/*	CompuScope internal board node structure alternate definitions.	*/

/*#define	power_setting	b_bit0_invert	*/

/*----------------------------------------------------------*/

/*	CompuScope internal board node structure definition.	*/

typedef struct b_node	{
	uInt8			ioport[GAGE_NUMBER_REGS];
	uInt8			creg1;
	uInt16			creg2;
	uInt16			creg3;
	uInt16			delay_clock;
	uInt8 far		*a_buffer;
	uInt16			a_block;
	uInt8 far		*b_buffer;
	uInt16			b_block;
	uInt8 far		*memptr;
	uInt16			memory;
	uInt16			board_type;
	int32			max_memory;
	int32			max_available_memory;
	int32			single_memory;
	int32			dual_memory;
	uInt16			index;
	uInt16			index_offset;
	uInt16			segment;
	uInt16			selector;
	uInt16			offset;
	int16			one_channel_active;
	int16			one_dual_channel_active;
	uInt16			memory_and_value;
	uInt16			memory_mod_value;
	uInt16			bank_offset_value;
	uInt16			b_bit0_invert;
	uInt16			power_setting;
	int16			mode;
	int16			enable_a;
	int16			enable_b;
	int16			rate;
	int16			multiplier;
#if defined(__WIN_95__) || defined(__WIN_NT__)
	uInt32			sample_rate;
#else
	float			sample_rate;
#endif
	uInt16			external_clock_adjust;
	uInt16			x1_clock;
	int16			coupling_a;
	int16			coupling_b;
	int16			coupling_ext;
	int16			gain_a;
	int16			gain_b;
	int16			gain_ext;
	int16			imped_a;
	int16			imped_b;
	int16			diff_input_a;
	int16			diff_input_b;
	int32			trigger_depth;
	int16			infinite_depth;		/*	Flag inhibits 8254 trigger depth counter from counting.	*/
	int16			trigger_level;
	int16			trigger_slope;
	int16			trigger_source;
	int16			trigger_level_2;
	int16			trigger_slope_2;
	int16			trigger_source_2;
	int16			trigger_res;
	int16			trigger_step;
	uInt16 far		*dac_12_bit_values;
	int16			multiple_recording;
	int16			old_gain_a;
	int16			old_gain_b;
	int16			old_op_mode;
#if defined(__WIN_95__) || defined(__WIN_NT__)
	uInt32			old_sample_rate;
#else
	float			old_sample_rate;
#endif
	int32			trigger_address;	/*	For Enhanced Triggering TA determined once per acq.	*/
//	int16			sample_offset_16;
//#ifdef	UNSIGNED_SAMPLE_RESOLUTION
//	uInt16			sample_resolution_16;
//#else
//	int16			sample_resolution_16;
//#endif
	int16			sample_bits;
	int32			sample_offset_32;
	int32			sample_resolution_32;
	uInt16			version;			/*	BCD encoded (eg. 0x0130 = Version 1.30).	*/
	uInt32			eeprom_options;		/*	BIT encoded (see EEPROM_OPTIONS_XXXXXXXX).	*/
	uInt16			eeprom_addr_size;
	uInt16			eeprom_addr_mask;
	uInt16			eeprom_protect;
	uInt16			eeprom_write_reg;
	uInt16			eeprom_read_reg;
	uInt8			eeprom_sdi_bit;
	uInt8			eeprom_clk_bit;
	uInt8			eeprom_prot_bit;
	uInt8			eeprom_cs_bit;
	uInt8			eeprom_sdo_bit;
	int16			eeprom_present;
	int16			eeprom_valid;
	int16			trig_level_off[2];	/*	CS2125 encoding is uInt8.	*/
	int16			trig_level_scale[2];/*	CS2125 encoding is uInt8.	*/
	uInt8			trig_addr_off[CS2125_TAOI_MAX];	/*	[OFFSET], CS2125 encoding is uInt4 (nibbles in uInt16's, layed out linearly -> 0,1,2,3 4,5,6,7 8,9,10,11 12,13,14,15) or	*/
													/*	[OFFSET], CS1610 encoding is uInt8 (bytes   in uInt16's, layed out linearly -> 0,1 2,3 4,5 6,7).	*/
	int32			trigger_address_offset;			/*	Set in cs2125_set_clock (), for example.  When used it is set in board_set_clock () or board_card_set_clock ().	*/
	int16			use_dac_table;	/*	Active HIGH.	*/
	int16			swapped_inputs;
	uInt8			*eib_dac_table;
	void far		*pci;	/*	Void pointer to be cast to "gage_pci_board_type" of connected board.	*/

/*	Routines.	*/

	int16			(*gage_input_control) (int16 channel, int16 enable, int16 coupling, int16 gain);
	int16			(*gage_capture_mode) (int16 mode, int16 rate, int16 multiplier);
	int16			(*gage_trigger_control) (int16 source, int16 ext_coupling, int16 ext_gain, int16 slope, int16 level, int32 depth);
	int16			(*gage_trigger_control_2) (int16 source_1, int16 source_2, int16 ext_coupling, int16 ext_gain, int16 slope_1, int16 slope_2, int16 level_1, int16 level_2, int32 depth, int16 trigger_from_bus, int16 trigger_to_bus);
	void			(*gage_abort) (void);
	int32			(*gage_get_trigger_address) (void);
	int32			(*gage_trigger_address) (void);
	void			(*gage_get_data) (void);
	void			(*gage_get_data_low) (void);
	void			(*gage_get_data_high) (void);
	void			(*gage_need_ram) (int16 need);
	int16			(*gage_mem_read_master) (int32 location);
	int16			(*gage_mem_read_dual) (int16 channel, int32 location);
	int16			(*gage_mem_read_chan_a) (int32 location);
	int16			(*gage_mem_read_chan_b) (int32 location);
	int16			(*gage_mem_read_single) (int32 location);
	void			(*gage_software_clock) (void);
	void			(*gage_software_trigger) (void);
	int16			(*gage_busy) (void);
	int16			(*gage_ram_full) (void);
	int16			(*gage_triggered) (void);
	int16			(*gage_triggered_aux) (void);
	int16			(*gage_read_master_status) (void);
	int16			(*gage_get_status) (void);
	void			(*gage_set_block_number) (uInt16 block);
	void			(*gage_fast_set_block_number) (uInt16 block);
	void			(*gage_32k_to_buffer) (uInt8 far *buffer, int16 high_half, int16 start_block, int16 far *blocks_transfered);
	void			(*gage_trigger_view_transfer) (int16 channel, uInt8 far *buffer, int16 nsamples);
	void far		*(*gage_trigger_view_transfer_2) (int16 channel, void far *buffer, int32 nsamples);
	uInt32			(*gage_trigger_view_transfer_3) (int16 channel, void far *buffer, int32 nsamples);
	void			(*gage_transfer_buffer) (int32 ta, int16 channel, void far *buffer, int32 nsamples);
	void far 		*(*gage_transfer_buffer_2) (int32 ta, int16 channel, void far *buffer, int32 nsamples);
	uInt32	 		(*gage_transfer_buffer_3) (int32 ta, int16 channel, void far *buffer, int32 nsamples);
	void			(*gage_set_segment) (uInt16 segment);
	int16			(*gage_channel_enable) (int16 source, int16 enable);
	int16			(*gage_set_coupling) (int16 channel, int16 coupling);
	int16			(*gage_set_gain) (int16 channel, int16 gain);
	int16			(*gage_set_trigger_depth) (int32 depth);
	int16			(*gage_set_trigger_level) (int16 level);
	int16			(*gage_set_trigger_slope) (int16 slope);
	int16			(*gage_set_trigger_source) (int16 source);
	void			(*gage_trigger_enable) (int16 enable);
	void			(*gage_init_clock) (void);
	void			(*gage_multiple_record_acquisitions) (uInt16 number);
	void			(*gage_multiple_record) (uInt16 mode);
	uInt16			(*gage_pci_real_time_setting) (int16 setting);
	int32			(*gage_pci_rt_start_capture) (void far * buffer, uInt32 record_sizeB, uInt32 padded, int16 auto_trigger);
	int32			(*gage_pci_rt_check_capture) (void);
	int32 			(*gage_pci_rt_unpack) (void far *packed_buf, void far *flat_buf, uInt32 size, uInt32 valid, uInt32 padded, uInt32 interleave);
#if __PTM_8500_1_2__
//PTM begin
	int32			(*gage_ptm_record_depth) ( uInt32 record_size, void **buffer );
	void			(*gage_ensure_pre_trigger_depth) (uInt32 far *depth);
	int32			(*gage_ptm_transfer) (int16 far *channel, int32 far *group, void far *buffer, int32 far *pre_samples, int32 far *post_samples);
//PTM end
#endif /* PTM_CS8500_1_2 */
//#ifdef __8500_ISR_1_2__
#if		__8500_ISR_1_2__
	void			(*gage_attach_isr_func)(void *pFunc, int event);
	void			(*gage_detach_isr_func)(void *pFunc, int event);
	void			(*gage_enable_isr)(int event);
	void			(*gage_disable_isr)(int event);
#endif
	void			(*gage_ets_enable) (int16 ets);
	int16			(*gage_ets_detect) (void);
	void			(*gage_ets_trigger_speed) (int16 fast_source);
	void			(*gage_ets_set_rate) (int16 ets_rate);
	void			(*gage_ets_set_delay) (int16 ets_delay);
	void			(*gage_ets_mem_read_data) (int32 location, uInt8 far *abuf, uInt8 far *bbuf);
	void			(*gage_ets_capture) (int16 auto_trigger, int32 timeout);
	void			(*gage_ets_capture_2) (int16 auto_trigger, int32 timeout, uInt8 far *a_buffer, uInt8 far *b_buffer);
	void			(*gage_ets_average_capture) (int16 auto_trigger, int32 timeout, int16 avgs);
	void			(*gage_ets_average_capture_2) (int16 auto_trigger, int32 timeout, int16 avgs, uInt8 far *a_buffer, uInt8 far *b_buffer);
	int32			(*gage_acquire_average) (int16 channel, int32 nsamples, int32 naverages, int16 sum, int32 far *avg_buffer, void far *data_buffer, int32 data_buffer_size, int32 timeout);
	void			(*gage_set_power) (int16 mode);
	void			(*gage_offset_adjust) (int16 channel, int16 offset_adjust);
	struct b_node far	*next;
} gage_board_node, far *gage_board_type;

#ifdef	GAGE_DRIVER_SOURCE

/*	Variables required, declared allocated storage by the driver and
	available outside the driver to monitor the current state.  */

gage_board_type			gage_current_card;
gage_board_type			gage_boards_master;

/*	This pointer points to either the gage_current_card pointer
	or the gage_boards_master pointer.  These points then point
	to the gage_board_type structure that contains information
	about the current selected card or the master board (the
	first board in a multiple card system).  If this pointer
	points at the gage_current_card pointer then the driver
	behaves like a multiple independant board system.  If on the
	other hand gage_master_independant points to gage_boards_master
	then the system will be in a master/slave mode of operation.
*/

gage_board_type	*gage_master_independant = NULL;

/*----------------------------------------------------------*/

/*	Variables used by the driver and only available to the driver.  */

static gage_board_type	gage_boards_insert;
#else

/*      DLL's can not have GLOBAL DATA. */

extern gage_board_type	gage_current_card;
extern gage_board_type	gage_boards_master;
extern gage_board_type	*gage_master_independant;

#endif

/*----------------------------------------------------------*/

#ifdef	ALLOW_MULTIPLE_SYSTEMS

/*----------------------------------------------------------*/

/*	CompuScope system definitions.  */

#define	GAGE_MAX_SYSTEMS	16	/*	Actually 0 to 15.	*/

/*----------------------------------------------------------*/

/*	CompuScope global system information structure definition.  */

typedef struct	{
	char	system_name[_MAX_PATH];
	int16	system_result;
	int16	system_number;
	int16	systems_installed;

}	gage_system_info_type;

/*	CompuScope internal system node structure definition.  */

typedef struct s_node	{
	LPSTR			system_name;	/*	Filename of the system ".INC" file.	*/
	int16			system_result;	/*	Result from gage_driver_initialize.	*/
	uInt16			board_location[GAGE_B_L_BUFFER_SIZE];
	int16			boards_number;
	int16			all_boards_trigger;
	uInt16			external_clock_delay;
#if	defined(__WIN_NT__) || defined(__WIN_95__)
	DWORD			external_clock_rate;
#else
	float			external_clock_rate;
#endif
	int32			trigger_view_offset;
	int16			driver_initialized;
	int16			boards_found;
	int16			ets_operation;
	uInt16			delay_trigger;
	int16			dsp_link_available;
	int16			override_trigger_depth;

#ifdef	ALLOW_INDEPENDANT_OPERATION

	int16			independant_operation;

#endif

	gage_board_type	current_card;
	gage_board_type	boards_master;

	struct s_node far	*next;
} gage_system_node, far	*gage_system_type;

/*----------------------------------------------------------*/

#ifdef	GAGE_DRIVER_SOURCE

/*----------------------------------------------------------*/

/*	Variables required, declared allocated storage by the driver and
	available outside the driver to monitor the current state.  */

int16				gage_system_number = 0;	/*	The number of the current active system.  */
int16				gage_systems_installed = 0;	/*	The number of systems found during initialization.  */

gage_system_info_type	gage_system_info;

gage_system_type		gage_current_system;
gage_system_type		gage_systems_head;

/*	Variables used by the driver and only available to the driver.  */

static int16			gage_system_initialized = FALSE;

/*----------------------------------------------------------*/

#else

/*----------------------------------------------------------*/

/*      DLL's can not have GLOBAL DATA. */

extern int16			gage_system_number;
extern int16			gage_systems_installed;

extern gage_system_info_type	gage_system_info;

extern gage_system_type		gage_current_system;
extern gage_system_type		gage_systems_head;

/*----------------------------------------------------------*/

#endif

/*----------------------------------------------------------*/

#ifdef	__cplusplus

extern "C"	{

#endif

/*----------------------------------------------------------*/

void  GAGEAPI	gage_reset_driver_vars (void);
int16 GAGEAPI	gage_select_system (int16 system);
void  GAGEAPI	gage_get_system_info (gage_system_info_type far *gsi);
int16 GAGEAPI	gage_system_initialize (int16 max_boards, int16 board_type, int16 memory_size);
void  GAGEAPI	gage_system_remove (void);

/*----------------------------------------------------------*/

#ifdef	__cplusplus

}

#endif

/*----------------------------------------------------------*/

#endif

/*----------------------------------------------------------*/

/*	OLD NAMES: For compatibility.
	-----------------------------	*/

/*  CompuScope global routines.	*/

#define	gage_get_current_driver_structure	gage_get_current_drv_structure

/*	Global routines: defined in the GAGE_DRV.C driver source file.
	--------------------------------------------------------------	*/

/*----------------------------------------------------------*/

#ifdef	__cplusplus

extern "C"	{

#endif

/*----------------------------------------------------------*/

/*	The following nine routines are currently not callable from Windows.	*/

/*	Routines that control how the memory buffers are accessed and located.  */

void  GAGEAPI	gage_set_segment (uInt16 segment);

/*	Routines that handle low level input control functionality.  */

int16 GAGEAPI	gage_channel_enable (int16 source, int16 enable);
int16 GAGEAPI	gage_set_coupling (int16 channel, int16 coupling);
int16 GAGEAPI	gage_set_gain (int16 channel, int16 gain);

/*	Routines that handle low level trigger control functionality.  */

int16 GAGEAPI	gage_set_trigger_depth (int32 depth);
int16 GAGEAPI	gage_set_trigger_level (int16 level);
int16 GAGEAPI	gage_set_trigger_slope (int16 slope);
int16 GAGEAPI	gage_set_trigger_source (int16 source);
void  GAGEAPI	gage_trigger_enable (int16 enable);

#if	defined(__WIN_NT__) || defined(__WIN_95__)
DWORD	gage_make_sample_rate (int16 rate, int16 multiplier);
#else
float	gage_make_sample_rate (int16 rate, int16 multiplier);
#endif
/*	Routines that handle special features and additional functionality.  */

void  GAGEAPI	gage_get_data_low (void);
void  GAGEAPI	gage_get_data_high (void);
void  GAGEAPI	gage_get_current_drv_structure (gage_board_type far *gbm, int32 far *gbt_size, int32 far *gbt_routines);
int16 GAGEAPI	gage_select_current_board (int16 board, gage_board_type far *gcc);

/*----------------------------------------------------------*/

/*	Routines that handle memory allocation between different operating
	environments to present the programmer a consistant memory management
	strategy.  This simplifies readability and maintainability.  */

void	*gage_alloc (size_t size);
void	gage_free (void *ptr);

#ifdef	__DOS_16__

void far *gage_far_alloc (uInt32 size);
void	gage_far_free (void far *ptr);

#endif	/*	__DOS_16__	*/

/*----------------------------------------------------------*/

#ifdef	__cplusplus

}

#endif

/*----------------------------------------------------------*/
#endif /* __GAGE_LOW_H__ */
/*	End of GAGE_LOW.H.  */
