#ifndef _USB5601_DEVICE_
#define _USB5601_DEVICE_

#include "windows.h"

// #################### 人性化的数据类型定义 #####################
// Humanized data types definition
typedef char				I8;		// 8位有符号整型数据
typedef unsigned char		U8;		// 8位无符号整型数据
typedef short				I16;	// 16位有符号整型数据
typedef unsigned short		U16;	// 16位无符号整型数据
typedef long				I32;	// 32位有符号整型数据
typedef unsigned long		U32;	// 32位无符号整型数据
typedef __int64				I64;	// 64位有符号整型数据
typedef unsigned __int64	U64;	// 64位无符号整型数据
typedef float				F32;	// 32位浮点数据(单精度，同为labVIEW中的SGL)
typedef double				F64;	// 64位浮点数据(双精度，同为labVIEW中的DBL)

// ########################## 设备功能指标 ########################
#define USB5601_AI_MAX_CHANNELS		8	// 本卡最多支持16路模拟量单端输入通道
#define USB5601_DIO_MAX_PORTS		2	// 本卡最多支持2个数字量端口
#define USB5601_DIO_PORT_DI			0	// 数字量输入端口号 = 0
#define USB5601_DIO_PORT_DO			1	// 数字量输出端口号 = 1
#define USB5601_DIO_PORT0_MAX_LINES	8	// 数字量端口0支持8条线
#define USB5601_DIO_PORT1_MAX_LINES	8	// 数字量端口1支持8条线


typedef struct _USB5601_AI_PARAM // 跟整个AI有关的硬件工作参数(简称AI工作参数)
{// 通道参数

	U32 nFirstChannel;		// 采集首通道[0,7]
	U32 nSampChanCount;		// 采样通道总数[1,8]
	U32 nSampleRange[8];	// 采样量程, 0~7元素分别对应AI0~AI7通道

	U32 nReserved0;			// 保留字段(暂未定义)
	U32 nReserved1;			// 保留字段(暂未定义)
} USB5601_AI_PARAM, *PUSB5601_AI_PARAM;


// AI硬件参数结构体USB5601_AI_PARAM中的nSampleRange参数所使用的采样范围挡位选项
#define USB5601_AI_SAMPRANGE_N50_P50mV			0	// ±50mV	0x02
#define USB5601_AI_SAMPRANGE_N100_P100mV		1	// ±100mV	0x03
#define USB5601_AI_SAMPRANGE_N500_P500mV		2	// ±100mV	0x05
#define USB5601_AI_SAMPRANGE_N1_P1V				3	// ±1V		0x06
#define USB5601_AI_SAMPRANGE_N2p5_P2p5V			4	// ±2.5V	0x07
#define USB5601_AI_SAMPRANGE_N5_P5V				5	// ±5V		0x08
#define USB5601_AI_SAMPRANGE_N10_P10V			6	// ±10V	0x09

#define USB5601_AI_SAMPRANGE_N20_P20mA			7	// ±20mA	0x0A
#define USB5601_AI_SAMPRANGE_P4_P20mA			8	// 4~20mA	0x0C

#define USB5601_AI_SAMPRANGE_J					9	// J型热电偶	0℃～1200℃		0x10
#define USB5601_AI_SAMPRANGE_K					10	// K型热电偶	0℃～1300℃		0x11
#define USB5601_AI_SAMPRANGE_T					11	// T型热电偶	-200℃～400℃	0x12
#define USB5601_AI_SAMPRANGE_E					12	// E型热电偶	0℃～1000℃		0x13
#define USB5601_AI_SAMPRANGE_R					13	// R型热电偶	0℃～1700℃		0x14
#define USB5601_AI_SAMPRANGE_S					14	// S型热电偶	0℃～1768℃		0x15
#define USB5601_AI_SAMPRANGE_B					15	// B型热电偶	0℃～1800℃		0x16

#define USB5601_AI_SAMPRANGE_MAXCOUNT			16


// AI 采样值结构体
typedef struct _USB5601_AI_CH_DATA // AI通道参数结构体
{
	U32 nChannel;			// 通道号[0, 7]，分别表示物理通道号AI0－AI7
	U32	nProteSts;			// 断偶状态，仅在热电偶量程下有效。1=断偶 0=正常
	U32 nSampleRange;		// 采样范围(Sample Range)档位选择, 具体见下面常量名定义(此参数在单点采样有效，未此注明的参数则在单点采样模式中无效)
	U16 wBinaryBuf;		// 采样数据原码值 16位 
	U16 wReserved0;		// 保留(未用)
	F32 fAnalogBuf;			// 采样数据浮点值
	U32 nReserved1;			// 保留(未用)
	U32 nReserved2;			// 保留(未用)
} USB5601_AI_CH_DATA, *PUSB5601_AI_CH_DATA;

typedef struct _USB5601_AI_DATA // AI通道参数结构体
{
	USB5601_AI_CH_DATA CHData[8];	// 各个通道数据，0~7元素分别对应0~7通道
} USB5601_AI_DATA, *PUSB5601_AI_DATA;


// #################### AI采样范围信息结构体(USB5601_AI_VOLT_RANGE_INFO) #######################
typedef struct _USB5601_AI_VOLT_RANGE_INFO
{
	ULONG nSampleRange;		// 当前采样范围挡位号
	ULONG nReserved0;			// 保留字段(暂未定义)
	double fMaxVolt;			// 采样范围的最大电压值,单位:毫伏(mV)或者摄氏度(℃)
	double fMinVolt;			// 采样范围的最小电压值,单位:毫伏(mV)或者摄氏度(℃)
	double fAmplitude;			// 采样范围幅度,单位:毫伏(mV)或者摄氏度(℃)
	double fCodeWidth;			// 编码宽度,毫伏(mV)或者摄氏度(℃), 即每个单位码值所分配的电压值（温度值）
	LONG nMaxCode;			// 原码最大值
	LONG nMinCode;	        // 原码最小值

	ULONG nReserved1;			// 保留字段(暂未定义)
	ULONG nReserved2;			// 保留字段(暂未定义)
	ULONG nReserved3;			// 保留字段(暂未定义)
	ULONG nReserved4;			// 保留字段(暂未定义)
} USB5601_AI_VOLT_RANGE_INFO, *PUSB5601_AI_VOLT_RANGE_INFO;

// ################################ 设备驱动接口申明 ################################
#ifndef _USB5601_DRIVER_
#define DEVLIB __declspec(dllimport)
#else
#define DEVLIB __declspec(dllexport)
#endif

#ifdef __cplusplus
extern "C" {
#endif
	// ################################ DEV设备对象管理函数 ################################
	HANDLE DEVLIB WINAPI USB5601_DEV_Create(				// 创建设备对象句柄(hDevice), 成功返回实际句柄,失败则返回INVALID_HANDLE_VALUE(-1),可调用GetLastError()分析错误原因
									U32 nDeviceIdx,			// 设备序号(逻辑序号或物理序号, 具体使用哪种序号由参数bUsePhysIdx决定)
									BOOL bUsePhysIdx);		// 是否使用物理序号, =TRUE:使用物理序号, =FALSE:使用逻辑序号										

	U32 DEVLIB WINAPI USB5601_DEV_GetCount(void);			// 取得该设备总台数,成功返回值>0, 失败返回0(可调用GetLastError()分析错误原因)

	BOOL DEVLIB WINAPI USB5601_DEV_GetCurrentIdx(			// 获得指定设备中的逻辑序号和物理序号
									HANDLE hDevice,			// 设备对象句柄,它由DEV_Create()函数创建
									U32* pLgcIdx,			// 返回的逻辑序号
									U32* pPhysIdx);			// 返回的物理序号

	BOOL DEVLIB WINAPI USB5601_DEV_GetSpeed(					// 读取设备连接的USB端口速度, 
									HANDLE hDevice,			// 设备对象句柄,它由DEV_Create()函数创建
									U32* pSpeed);			// USB接口速度，=1:USB1.0, =2:USB2.0, =3:USB3.0


	BOOL DEVLIB WINAPI USB5601_DEV_Release(HANDLE hDevice);	// 释放设备对象(关键函数)，设备创建后，经该函数释放


	// ################################ AI模拟量输入实现函数 ################################
	BOOL DEVLIB WINAPI USB5601_AI_InitTask(					// 初始化采集任务(Initialize Task)
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								PUSB5601_AI_PARAM pAIParam, // AI工作参数, 它仅在此函数中决定硬件初始状态和各工作模式,可以事先由AI_VerifyParam()进行参数校验
								HANDLE* pSampEvent);		// 返回采样事件对象句柄,此处不需此参数，可赋值为0

	BOOL DEVLIB WINAPI USB5601_AI_ReadData(					// 从采集任务中读取采样数据(电压数据序列)(Read analog data from the task)
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								PUSB5601_AI_DATA DataBuf);	// 模拟数据数组(电压数组),用于返回采样的电压数据，取值区间由各通道采样时的采样范围决定(单位:V)

	BOOL DEVLIB WINAPI USB5601_AI_ReadCJCTemp(				// 从采集任务中读取冷端补偿数据(原码数据序列)(Read binary data from the task)
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								U16* nBinData,				// 二进制数据数组（原码数组）,用于返回采样的原码数据，取值区间为[-32768, 32767]
								F64* fAnlgData);			// 超时时间，单位：秒(S)

	BOOL DEVLIB WINAPI USB5601_AI_ReleaseTask(HANDLE hDevice); // 释放采集任务


	BOOL DEVLIB WINAPI USB5601_AI_Cal_Restore(				// 校准复位
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								U32 nChannel,				// 设备通道号, 取值范围[0,7]
								U32 nRange);				// 设备通道量程

	BOOL DEVLIB WINAPI USB5601_AI_Cal_Zero(					// 零点校准
								HANDLE hDevice);			// 设备对象句柄,它由DEV_Create()函数创建


	BOOL DEVLIB WINAPI USB5601_AI_Cal_Full(					// 满度校准
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								F32 fFullVal);				// 实际接入信号值, 16位浮点数

	BOOL DEVLIB WINAPI USB5601_AI_SetCJC(					// 冷端补偿温度值设置
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								F32 fCJCVal);				// 待写入CJC偏移量的值, 16位浮点数


	// ========================= AI辅助操作函数 =========================
	BOOL DEVLIB WINAPI USB5601_AI_VerifyParam(				// 校验AI工作参数(Verify Parameter),建议在初始化AI参数前调用此函数校验各参数合法性
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								PUSB5601_AI_PARAM pAIParam);// 待校验的AI工作参数

	BOOL DEVLIB WINAPI USB5601_AI_GetRangeInfo(
								HANDLE hDevice,				// 设备对象句柄,它由DEV_Create()函数创建
								ULONG nRange, 
								PUSB5601_AI_VOLT_RANGE_INFO pRangeInfo);



	BOOL DEVLIB WINAPI USB5601_AI_LoadParam(HANDLE hDevice, PUSB5601_AI_PARAM pAIParam); // 从USB5601.ini中加载AI参数
	BOOL DEVLIB WINAPI USB5601_AI_SaveParam(HANDLE hDevice, PUSB5601_AI_PARAM pAIParam); // 保存AI参数至USB5601.ini
	BOOL DEVLIB WINAPI USB5601_AI_ResetParam(HANDLE hDevice, PUSB5601_AI_PARAM pAIParam); // 将当前AI参数复位至出厂值

	// ############################ DI、DO数字量输入输出实现函数 (Port0为单向DI， Port1为单向DO)##############
	BOOL DEVLIB WINAPI USB5601_DIO_ReadPort(							// 读数字量端口值(Read Digital Port Data)
									HANDLE hDevice,						// 设备对象句柄,它由DEV_Create()函数创建
									U32 nPort,							// 端口号, 取值范围为[0, 1], Port0为单向DI， Port1为单向DO
									U32* pPortData);					// 返回的端口数据, 有效位Bit[15:0]

    BOOL DEVLIB WINAPI USB5601_DIO_WritePort(							// 写数字量端口值(Write Digital Port Data)
									HANDLE hDevice,						// 设备对象句柄,它由DEV_Create()函数创建
									U32 nPort,							// 端口号, 取值为1, 对应Port1单向DO
									U32 nPortData);						// 端口数据, 有效位Bit[15:0]

	BOOL DEVLIB WINAPI USB5601_DIO_ReadLines(							// 读数字量端口值(Read Digital Port Data)
									HANDLE hDevice,						// 设备对象句柄,它由DEV_Create()函数创建
									U32 nPort,							// 端口号, 取值范围为[0, 1], Port0为单向DI， Port1为单向DO
									U32 bLineDataArray[8]);			// 同时返回端口中各线的状态值bLineDataArray[n]=0:表示关(或低)状态, =1表示开(或高)状态

    BOOL DEVLIB WINAPI USB5601_DIO_WriteLines(							// 写数字量端口值(Write Digital Port Data)
									HANDLE hDevice,						// 设备对象句柄,它由DEV_Create()函数创建
									U32 nPort,							// 端口号, 取值为1, 对应Port1 DO
									U32 bLineDataArray[8]);			// 端口中各线的状态值bLineDataArray[n]=0:表示关(或低)状态, =1表示开(或高)状态

    BOOL DEVLIB WINAPI USB5601_DIO_ReadLine(							// 读线值
									HANDLE hDevice,						// 设备对象句柄,它由DEV_Create()函数创建
									U32 nPort,							// 端口号, 取值范围为[0, 1], Port0为单向DI， Port1为单向DO
									U32 nLine,							// 线号,取值范围[0, 15]
									U32* pLineData);					// 线数据, 取值0或1 

    BOOL DEVLIB WINAPI USB5601_DIO_WriteLine(							// 写线值
									HANDLE hDevice,						// 设备对象句柄,它由DEV_Create()函数创建
									U32 nPort,							// 端口号, 取值为1, 对应Port1单向DO
									U32 nLine,							// 线号, 取值范围[0, 15]
									U32 bLineData);						// 线值, 取值0或1

	BOOL DEVLIB WINAPI USB5601_DIO_ReleaseTask(							// 释放DIO任务
									HANDLE hDevice,						// 设备对象句柄,它由DEV_Create()函数创建
									U32 nPort);							// 端口号, 取值范围为[0, 1], 保持与初始化函数中端口号一致
	

	
#ifdef __cplusplus
}
#endif

#ifndef _CVIDEF_H
// 自动包含驱动函数导入库
	#ifndef _USB5601_DRIVER_
		#ifndef LOAD_USB5601_LIB // 如果没有加载LIB库
		#define LOAD_USB5601_LIB

			#ifndef _WIN64
				#pragma comment(lib, "USB5601_32.lib")
				#pragma message("======== Welcome to use our art company's products!")
				#pragma message("======== Automatically linking with USB5601_32.dll...")
				#pragma message("======== Successfully linked with USB5601_32.dll")
			#else
				#pragma comment(lib, "USB5601_64.lib")
				#pragma message("======== Welcome to use our art company's products!")
				#pragma message("======== Automatically linking with USB5601_64.dll...")
				#pragma message("======== Successfully linked with USB5601_64.dll")
			#endif
		#endif // LOAD_USB5601_LIB
	#endif // _USB5601_DRIVER_
#endif // _CVIDEF_H

#endif // _USB5601_DEVICE_