#ifndef _PCIE8543_DEVICE_
#define _PCIE8543_DEVICE_
//#################### AD硬件参数PCIE8543_PARA_AD定义 #####################
// 用于AD采样的实际硬件参数
typedef struct _PCIE8543_PARA_AD     
{
	LONG bChannelArray[4];	// 采样通道选择阵列，分别控制4个通道，=TRUE表示该通道采样，否则不采样(由于在DMA传输过程中必须保持数据128bit对齐，因此使能通道个数只能为1、2、4，不能出现三个通道使能现象)
	LONG InputRange[4];		// 模拟量输入量程选择
	LONG CouplingType[4];	// 耦合类型(1直流耦合, 0交流耦合)
	LONG Frequency;         // 采集频率, 单位为Hz, 最高采样率40MHz
	LONG TriggerMode;		// 触发模式选择
	LONG TriggerSource;		// 触发源选择
	LONG TriggerType;		// 触发类型选择
	LONG TriggerDir;		// 触发方向选择(正向/负向触发)
	LONG TrigWindow;		// 触发灵敏窗[1, 255]
	LONG ATRTriggerChannel;	// ATR通道选择
	LONG TrigLevelVolt;		// 触发电平(根据ATR通道选择的量程)
	LONG ClockSource;		// 时钟源选择
	LONG bMasterEn;			// 主设备使能  
							// =0：从设备，通过Trigger信号接收主设备发送的同步触发信号
							// =1：主设备，通过Trigger信号为从设备发送自身的触发信号
							// 注：在多模块同步系统中，只能设定其中一个设备为主设备，其余需设定为从设备，如果系统中只有一个设备或者有多个设备但是不要求同步，需将所有设备设定为从设备

	LONG TrigSignalSource;	// 同步信号触发源
} PCIE8543_PARA_AD, *PPCIE8543_PARA_AD;

// AD参数PCI8552_PARA_AD中的InputRange[X]使用的硬件增益选项
const long PCIE8543_INPUT_N5000_P5000mV		= 0x00; // ±5000mV
const long PCIE8543_INPUT_N1000_P1000mV		= 0x02; // ±1000mV

// AD参数PCIE8543_PARA_AD中的CouplingType耦合类型所使用的选项
const long PCIE8543_COUPLING_AC					= 0x00;	// 交流耦合
const long PCIE8543_COUPLING_DC					= 0x01;	// 直流耦合

//***********************************************************
// AD硬件参数PCIE8543_PARA_AD中的TriggerMode触发模式所使用的选项
const long PCIE8543_TRIGMODE_SOFT				= 0x00; // 软件触发
const long PCIE8543_TRIGMODE_POST				= 0x01; // 硬件触发

//***********************************************************
// AD硬件参数PCIE8543_PARA_AD中的TriggerSource触发源信号所使用的选项
const long PCIE8543_TRIGSRC_DTR					= 0x00; // 选择DTR作为触发源
const long PCIE8543_TRIGSRC_ATR					= 0x01; // 选择ATR作为触发源
const long PCIE8543_TRIGSRC_TRIGGER				= 0x02; // 同步触发信号（用于多卡同步）

// AD硬件参数PCIE8543_PARA_AD中的TriggerType触发类型所使用的选项
const long PCIE8543_TRIGTYPE_EDGE				= 0x00; // 边沿触发
const long PCIE8543_TRIGTYPE_PULSE				= 0x01; // 脉冲触发(电平)

//***********************************************************
// AD硬件参数PCIE8543_PARA_AD中的TriggerDir触发方向所使用的选项
const long PCIE8543_TRIGDIR_NEGATIVE			= 0x00; // 负向触发(低脉冲/下降沿触发)
const long PCIE8543_TRIGDIR_POSITIVE			= 0x01; // 正向触发(高脉冲/上升沿触发)
const long PCIE8543_TRIGDIR_POSIT_NEGAT			= 0x02; // 正负向触发(高/低脉冲或上升/下降沿触发)

//***********************************************************
// AD硬件参数PCIE8543_PARA_AD中的ATRTriggerChannel成员变量所使用ATR触发通道选项
const long PCIE8543_ATRTRIG_CH0					= 0x00; // 通道0信号作为ATR输入
const long PCIE8543_ATRTRIG_CH1					= 0x01; // 通道1信号作为ATR输入
const long PCIE8543_ATRTRIG_CH2					= 0x02; // 通道2信号作为ATR输入
const long PCIE8543_ATRTRIG_CH3					= 0x03; // 通道3信号作为ATR输入

//***********************************************************
// AD硬件参数PCIE8543_PARA_AD中的ClockSource时钟源所使用的选项
const long PCIE8543_CLOCKSRC_IN					= 0x00; // 使用内部时钟
const long PCIE8543_CLOCKSRC_MAIN10M			= 0x01; // 使用主卡10M时钟
const long PCIE8543_CLOCKSRC_OUT				= 0x02; // 使用外部时钟
const long PCIE8543_CLOCKSRC_EXTERNAL10M		= 0x03; // 使用外部10M时钟

//***********************************************************
// AD硬件参数PCIE8543_PARA_AD中的TrigSignalSource同步信号触发源所使用的选项
const long PCIE8543_SIGNALSRC_TRIGGER0			= 0x00; // 选择同步TRIG0信号触发
const long PCIE8543_SIGNALSRC_TRIGGER1			= 0x01; // 选择同步TRIG1信号触发
const long PCIE8543_SIGNALSRC_TRIGGER2			= 0x02; // 选择同步TRIG2信号触发
const long PCIE8543_SIGNALSRC_TRIGGER3			= 0x03; // 选择同步TRIG3信号触发
const long PCIE8543_SIGNALSRC_TRIGGER4			= 0x04; // 选择同步TRIG4信号触发
const long PCIE8543_SIGNALSRC_TRIGGER5			= 0x05; // 选择同步TRIG5信号触发
const long PCIE8543_SIGNALSRC_TRIGGER6			= 0x06; // 选择同步TRIG6信号触发
const long PCIE8543_SIGNALSRC_TRIGGER7			= 0x07; // 选择同步TRIG7信号触发

//***********************************************************
// 用户函数接口
#ifndef _PCIE8543_DRIVER_
#define DEVAPI __declspec(dllimport)
#else
#define DEVAPI __declspec(dllexport)
#endif

#ifdef __cplusplus
extern "C" {
#endif
	//######################## 设备对象管理函数 ##############################
	HANDLE DEVAPI FAR PASCAL PCIE8543_CreateDevice(int DeviceLgcID = 0);		// 用逻辑号创建设备对象
	HANDLE DEVAPI FAR PASCAL PCIE8543_CreateDeviceEx(LONG DevicePhysID);		// 创建设备对象(该函数使用物理ID最大255）
	LONG DEVAPI FAR PASCAL PCIE8543_GetDeviceCount(HANDLE hDevice);				// 取得设备总台数
	BOOL DEVAPI FAR PASCAL PCIE8543_SetDevicePhysID(HANDLE hDevice, LONG DevicePhysID); // 设置当前设备的物理ID号[0:255]
	BOOL DEVAPI FAR PASCAL PCIE8543_GetDeviceCurrentID(HANDLE hDevice,			// 取得当前设备相应的ID号
													PLONG DeviceLgcID, 
													PLONG DevicePhysID);
	BOOL DEVAPI FAR PASCAL PCIE8543_ListDeviceDlg(HANDLE hDevice);				// 以对话框窗体方式列表系统当中的所有的该PCI设备
    BOOL DEVAPI FAR PASCAL PCIE8543_ReleaseDevice(HANDLE hDevice);				// 仅释放设备对象

	//####################### AD数据读取函数 #################################
	// 适于大多数普通用户，这些接口最简单、最快捷、最可靠，让用户不必知道设备
	// 低层复杂的硬件控制协议和繁多的软件控制编程，仅用下面的初始化设备和读取
	// AD数据两个函数便能轻松高效地实现高速、连续的数据采集

	BOOL DEVAPI FAR PASCAL PCIE8543_ADCalibration(			// 设备校准.		
									HANDLE hDevice);	

	BOOL DEVAPI FAR PASCAL PCIE8543_InitDeviceProAD(		// 初始化设备，当返回TRUE后,设备即准备就绪.
									HANDLE hDevice,			// 设备对象,它由CreateDevice函数创建
									PPCIE8543_PARA_AD pADPara); // 硬件参数, 它仅在此函数中决定硬件状态

    BOOL DEVAPI FAR PASCAL PCIE8543_StartDeviceProAD(		// 在初始化之后，启动设备
									HANDLE hDevice);		// 设备对象句柄,它由CreateDevice函数创建
		
    BOOL DEVAPI FAR PASCAL PCIE8543_StopDeviceProAD(		// 在启动设备之后，暂停设备
									HANDLE hDevice);		// 设备对象句柄,它由CreateDevice函数创建

	BOOL DEVAPI FAR PASCAL PCIE8543_ReleaseDeviceProAD(		// 关闭AD设备,禁止传输,且释放资源
									HANDLE hDevice);		// 设备句柄,它由CreateDevice函数创建

	PVOID DEVAPI FAR PASCAL PCIE8543_AllocateBuffer(		// 申请内存
									ULONG ulRequsetSize);	// 申请内存大小，单位字节

	BOOL DEVAPI FAR PASCAL PCIE8543_FreeBuffer(				// 释放申请的内存
									PVOID pData);

	BOOL DEVAPI FAR PASCAL PCIE8543_ReadDeviceAD(			// DMA读AD数据
									HANDLE hDevice,			// 设备句柄
									USHORT pReadBuffer[],	// 读数据缓冲区
									ULONG ReadSizeULong,	// 读数据缓冲区长度
									ULONG* RetReadSizeULongs);// 返回实际读数据的长度
	
	//##################### AD的硬件参数操作函数 ###########################
	BOOL DEVAPI FAR PASCAL PCIE8543_SaveParaAD(HANDLE hDevice, PPCIE8543_PARA_AD pADPara); // 将当前的AD采样参数保存至系统中
    BOOL DEVAPI FAR PASCAL PCIE8543_LoadParaAD(HANDLE hDevice, PPCIE8543_PARA_AD pADPara); // 将AD采样参数从系统中读出
    BOOL DEVAPI FAR PASCAL PCIE8543_ResetParaAD(HANDLE hDevice, PPCIE8543_PARA_AD pADPara); // 将AD采样参数恢复至出厂默认值

	//################# 内存映射寄存器直接操作及读写函数 ########################
	// 适用于用户对本设备更直接、更特殊、更低层、更复杂的控制。比如根据特殊的
	// 控制对象需要特殊的控制流程和控制效率时，则用户可以使用这些接口予以实现。
	BOOL DEVAPI FAR PASCAL PCIE8543_GetDeviceBar(			// 取得指定的指定设备寄存器组BAR地址
									HANDLE hDevice,			// 设备对象句柄,它由CreateDevice函数创建
									__int64 pbPCIBar[6]);	// 返回PCI BAR所有地址,具体PCI BAR中有多少可用地址请看硬件说明书

	BOOL DEVAPI FAR PASCAL PCIE8543_GetDevVersion(			// 获取设备固件及程序版本
									HANDLE hDevice,			// 设备对象句柄,它由CreateDevice函数创建
									PULONG pulFmwVersion,	// 固件版本
									PULONG pulDriverVersion);// 驱动版本

    BOOL DEVAPI FAR PASCAL PCIE8543_WriteRegisterByte(		// 往指定寄存器空间位置写入单节字数据
									HANDLE hDevice,			// 设备对象句柄,它由CreateDevice函数创建
									__int64 pbLinearAddr,		// 指定寄存器的线性基地址,它等于GetDeviceAddr中的pbLinearAddr参数返回值
									ULONG OffsetBytes,		// 相对于线性基地址基地址的偏移位置(字节)
									BYTE Value);			// 往指定地址写入单字节数据（其地址由线性基地址和偏移位置决定）

	BOOL DEVAPI FAR PASCAL PCIE8543_WriteRegisterWord(		// 写双字节数据（其余同上）
									HANDLE hDevice, 
									__int64 pbLinearAddr, 
									ULONG OffsetBytes,  
									WORD Value);

	BOOL DEVAPI FAR PASCAL PCIE8543_WriteRegisterULong(		// 写四节字数据（其余同上）
									HANDLE hDevice, 
									__int64 pbLinearAddr, 
									ULONG OffsetBytes,  
									ULONG Value);

	BYTE DEVAPI FAR PASCAL PCIE8543_ReadRegisterByte(		// 读入单字节数据（其余同上）
									HANDLE hDevice, 
									__int64 pbLinearAddr, 
									ULONG OffsetBytes);

	WORD DEVAPI FAR PASCAL PCIE8543_ReadRegisterWord(		// 读入双字节数据（其余同上）
									HANDLE hDevice, 
									__int64 pbLinearAddr, 
									ULONG OffsetBytes);

	ULONG DEVAPI FAR PASCAL PCIE8543_ReadRegisterULong(		// 读入四字节数据（其余同上）
									HANDLE hDevice, 
									__int64 pbLinearAddr, 
									ULONG OffsetBytes);

	//################# I/O端口直接操作及读写函数 ########################
	// 适用于用户对本设备更直接、更特殊、更低层、更复杂的控制。比如根据特殊的
	// 控制对象需要特殊的控制流程和控制效率时，则用户可以使用这些接口予以实现。
	// 但这些函数主要适用于传统设备，如ISA总线、并口、串口等设备，不能用于本PCI设备
    BOOL DEVAPI FAR PASCAL PCIE8543_WritePortByte(			// 8位写端口
									HANDLE hDevice,			// 设备句柄(由CreateDevice创建)
									__int64 pPort,				// 端口地址
									BYTE Value);			// 写出的8位整型数据

    BOOL DEVAPI FAR PASCAL PCIE8543_WritePortWord(HANDLE hDevice, __int64 pPort, WORD Value);
    BOOL DEVAPI FAR PASCAL PCIE8543_WritePortULong(HANDLE hDevice, __int64 pPort, ULONG Value);

    BYTE DEVAPI FAR PASCAL PCIE8543_ReadPortByte(HANDLE hDevice, __int64 pPort);
    WORD DEVAPI FAR PASCAL PCIE8543_ReadPortWord(HANDLE hDevice, __int64 pPort);
    ULONG DEVAPI FAR PASCAL PCIE8543_ReadPortULong(HANDLE hDevice, __int64 pPort);
	// 如果您要在用户模式下，直接访问硬件端口，请安装并使用ISA\CommUser下的驱动ReadPortByteEx等函数

	//########################### 附加操作函数 ######################################
	HANDLE DEVAPI FAR PASCAL PCIE8543_CreateSystemEvent(void); // 创建内核事件对象，供InitDeviceDmaAD和VB子线程等函数使用
	BOOL DEVAPI FAR PASCAL PCIE8543_ReleaseSystemEvent(HANDLE hEvent); // 释放内核事件对象

#ifdef __cplusplus
}
#endif

//***********************************************************
// 各种FIFO存储器的长度(点)
const long FIFO_IDT7202_LENGTH			= 1024;
const long FIFO_IDT7203_LENGTH			= 2048;
const long FIFO_IDT7204_LENGTH			= 4096;
const long FIFO_IDT7205_LENGTH			= 8192;
const long FIFO_IDT7206_LENGTH			= 16384;
const long FIFO_IDT7207_LENGTH			= 32768;

// 自动包含驱动函数导入库
#ifndef _PCIE8543_DRIVER_
	#ifndef _WIN64
		#pragma comment(lib, "PCIE8543_32.lib")
		#pragma message("======== Welcome to use our art company's products!")
		#pragma message("======== Automatically linking with PCIE8543_32.dll...")
		#pragma message("======== Successfully linked with PCIE8543_32.dll")
	#else
		#pragma comment(lib, "PCIE8543_64.lib")
		#pragma message("======== Welcome to use our art company's products!")
		#pragma message("======== Automatically linking with PCIE8543_64.dll...")
		#pragma message("======== Successfully linked with PCIE8543_64.dll")
	#endif
#endif

#endif // _PCIE8543_DEVICE_