#ifdef __cplusplus
extern "C" {
#endif

#define		mOFFSET( s, m )			( (ULONG) & ( ( ( s * ) 0 ) -> m ) )	// 定义获取结构成员相对偏移地址的宏

#ifndef		max
#define		max( a, b )				( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )	// 较大值
#endif

#ifndef		min
#define		min( a, b )				( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )	// 较小值
#endif

#ifdef		ExAllocatePool
#undef		ExAllocatePool						// 删除带TAG的内存分配
#endif

#ifndef		NTSTATUS
typedef		LONG	NTSTATUS;					// 返回状态
#endif

#define DllExport   __declspec( dllexport )     //隐试输出dll

typedef struct _FRAME{

		UCHAR		 StartFrame;				//启始帧
		UCHAR		 IDRegion;					//域代号
		UCHAR		 IDSub;						//子类代号
		UCHAR		 Func;						//功能代号
		UCHAR		 Func_Ex;					//功能模式模式扩展0xff@@(低四位无关)
		UCHAR		 DATA[8];					//传送最多8位数据

} m_Frame,* p_Frame;
//CH36_IO_REG DEFINE!
typedef	struct	_CH365_IO_REG {					// CH365芯片的I/O空间
	UCHAR			mCh365IoPort[0xf0];			// 00H-EFH,共240字节为标准的I/O端口
	union	{									// 以字或者以字节为单位进行存取
		USHORT		mCh365MemAddr;				// F0H 存储器接口: A15-A0地址设定寄存器
		struct	{								// 以字节为单位进行存取
			UCHAR	mCh365MemAddrL;				// F0H 存储器接口: A7-A0地址设定寄存器
			UCHAR	mCh365MemAddrH;				// F1H 存储器接口: A15-A8地址设定寄存器
		};
	};
	UCHAR			mCh365IoResv2;				// F2H
	UCHAR			mCh365MemData;				// F3H 存储器接口: 存储器数据存取寄存器
	UCHAR			mCh365I2cData;				// F4H I2C串行接口: I2C数据存取寄存器
	UCHAR			mCh365I2cCtrl;				// F5H I2C串行接口: I2C控制和状态寄存器
	UCHAR			mCh365I2cAddr;				// F6H I2C串行接口: I2C地址设定寄存器
	UCHAR			mCh365I2cDev;				// F7H I2C串行接口: I2C设备地址和命令寄存器
	UCHAR			mCh365IoCtrl;				// F8H 芯片控制寄存器,高5位只读
	UCHAR			mCh365IoBuf;				// F9H 本地数据输入缓存寄存器
	UCHAR			mCh365Speed;				// FAH 芯片速度控制寄存器
	UCHAR			mCh365IoResv3;				// FBH
	UCHAR			mCh365IoTime;				// FCH 硬件循环计数寄存器
	UCHAR			mCh365IoResv4[3];			// FDH
} mCH365_IO_REG, *mPCH365_IO_REG;


typedef	struct	_CH365_MEM_REG {				// CH365芯片的存储器空间
	UCHAR			mCh365MemPort[0x8000];		// 0000H-7FFFH,共32768字节为标准的存储器单元
} mCH365_MEM_REG, *mPCH365_MEM_REG;


typedef	struct	_WIN32_COMMAND {				// 定义WIN32命令接口结构
	union	{
		ULONG		mFunction;					// 输入时指定功能代码
		NTSTATUS	mStatus;					// 输出时返回操作状态
	};
	PVOID			mAddress;					// 起始地址,返回地址
	ULONG			mLength;					// 存取长度,返回后续数据的长度
	UCHAR			mBuffer[16];				// 数据缓冲区,长度为0至32KB
} mWIN32_COMMAND, *mPWIN32_COMMAND;

// 应用层接口的功能代码
#define		mFuncNoOperation			0x00000000	// 无操作
#define		mFuncGetVersion				0x00000001	// 获取驱动程序版本号
#define		mFuncGetIoBaseAddr			0x00000002	// 读取I/O端口基址
#define		mFuncGetMemBaseAddr			0x00000003	// 读取 存储器基址
#define     mFuncCanInitialize			0x00000004  // CAN 设备初始化例程
#define     mFuncCanReceive	  			0x00000005  // CAN 设备接收例程
#define     mFuncCanSend				0x00000006	// CAN 设备发送例程
#define		mFuncSetInterLine			0x00000007  // 设置设备中断线程
#define   	mFuncWaitingSend           	0x00000008  // 发送等待例程
#define   	mFuncWaitingReceive         0x00000009  // 接收等待例程
#define     mFuncGetInterLine           0x0000000a	// 取得中断号
#define     mFuncAbortWaitInter			0x0000000b	// 放弃等待中断

typedef		VOID	( CALLBACK	* mPCAN_INT_ROUTINE ) ( VOID );		// CAN 中断服务程序

// WIN32应用层接口命令
#define		IOCTL_CH365_COMMAND		( FILE_DEVICE_UNKNOWN << 16 | FILE_ANY_ACCESS << 14 | 0x0f36 << 2 | METHOD_BUFFERED )	// 专用接口

#define		mWIN32_COMMAND_HEAD		mOFFSET( mWIN32_COMMAND, mBuffer )	// WIN32命令接口的头长度

#define		mMAX_BUFFER_LENGTH		max( sizeof( mCH365_IO_REG ), sizeof( mCH365_MEM_REG ) )	// 数据缓冲区最大长度

#define		mMAX_COMMAND_LENGTH		( mWIN32_COMMAND_HEAD + mMAX_BUFFER_LENGTH )	// 最大数据长度加上命令结构头的长度

#define		mCH365_MEM_BASE_AUTO	( (PVOID)0xffffffff )	// 自动设定CH365的存储器基址

#define		mCH365_INT_LINE_AUTO	0xffffffff			// 自动检测CH365的中断号

#define     MAX_RECE_BUFFER_SIZE    1024



DllExport ULONG	WINAPI	CH365_CAN_GetDrvVersion( );

DllExport HANDLE	WINAPI	CH365_Can_mOpenDevice( )  ;

DllExport BOOL	WINAPI	CH365_Can_mGetIntLine(	// 获取中断号
	PULONG			oIntLine );		// 保存中断号的单元地址

DllExport BOOL	WINAPI	CH365_Can_mSetIntLine(	// 设定中断号
	ULONG			iIntLine );		// 指定中断号,为0则关闭中断,为-1则自动检测并设定

DllExport BOOL WINAPI CH365_CanBus_Init(
		UCHAR			AMR_Code[],	//AMR	掩码
		UCHAR			ACR_Code[],	//ACR	识别码
		UCHAR			m_Time1	,	//
		UCHAR			m_Time2	,	//波特率设定
		UCHAR			DebugMode);	//调试模式

DllExport BOOL	WINAPI	CH365mGetIoBaseAddr(  // 获取I/O端口的基址
	mPCH365_IO_REG	*oIoBaseAddr );  // 保存I/O端口基址的单元地址

DllExport BOOL	WINAPI	CH365mGetMemBaseAddr(  // 获取存储器的基址
	mPCH365_MEM_REG	* oMemBaseAddr ) ; // 保存存储器基址的单元地址

DllExport BOOL WINAPI CH365_CanBus_Send(	
		UCHAR			iRegion		,//域名代码
		UCHAR			iSubId		,//子类代码
		UCHAR			iFunc		,//功能代号
		UCHAR			iExFunc		,//功能扩展
		PUCHAR			m_Data		,//数据区
		UCHAR			iMode		);//iMode=0:数据帧；1：远程帧

DllExport BOOL WINAPI CH365_CanRece(p_Frame  my_Frame);

DllExport BOOL	WINAPI	CH365_CanIntRoutine(  // 设定中断服务程序
		mPCAN_INT_ROUTINE	iIntRoutine,// 指定中断服务程序,为NULL则取消中断服务,否则在中断时调用该程序
		LONG				ServerPTR )	;//等待类型

DllExport BOOL  WINAPI  CH365_CanAbortWaitInt();

DllExport VOID	WINAPI	CH365mCloseDevice( ) ;

#ifdef __cplusplus
}
#endif