#ifndef __XPACSDK_H
#define __XPACSDK_H

#ifdef __cplusplus
extern "C" {
#endif

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <Winuser.h>
#include <memory.h>

#ifdef XPACSDK_EXPORTS
#define XPAC_API __declspec(dllexport)
#else
#define XPAC_API __declspec(dllimport)
#endif

#define XPAC_PRIVATE_API XPAC_API
#define XPAC_SERAL_NUMBER_LENGTH		8


#define PAC_PARALLEL 0x80
#define PAC_SCAN     0x40
#define PAC_DI32     0xE3
#define PAC_32BIT    0x20
#define PAC_DO32     0xE0
#define PAC_DI16DO16 0xE2
#define PAC_DI16     0xC3
#define PAC_DO16     0xC0
#define PAC_DI8DO8   0xC2
#define PAC_8K		 8000


//=============================================================================
//  System Functions
//=============================================================================
XPAC_API int  pac_GetModuleType(BYTE slot);
XPAC_API int  pac_GetModuleName(BYTE slot, LPSTR strName);
XPAC_API int  pac_GetRotaryID();
XPAC_API void pac_EnableLED(int pin,bool bFlag); //only for XPAC-ATOM
XPAC_API void pac_GetSerialNumber(LPSTR SerialNumber);
XPAC_API void pac_GetCPUVersion(LPSTR cpu_version);
XPAC_API void pac_GetOSVersion(LPSTR os_version);
XPAC_API void pac_GetSDKVersion(LPSTR sdk_version);
XPAC_API void pac_GetMacAddress(BYTE LAN, LPSTR MacAddr);
XPAC_API void pac_ChangeSlot(BYTE slotNo);
XPAC_API BOOL pac_CheckSDKVersion(DWORD version);
XPAC_API void pac_Reboot();

//=============================================================================
// Backplane API
//=============================================================================
XPAC_API int  pac_GetDIPSwitch();
XPAC_API int  pac_GetSlotCount();
XPAC_API void pac_GetBackplaneID(LPSTR backplane_version);
XPAC_API BOOL pac_ModuleExists(HANDLE hPort, int slot);
XPAC_API void pac_RegistryHotPlug(DWORD hWnd, DWORD msgID);
XPAC_API void pac_UnregistryHotPlug(DWORD hWnd);
XPAC_API void pac_EnableRetrigger(BYTE iValues);
XPAC_API int  pac_GetBatteryLevel(int nBattery);

XPAC_API void pac_EnableHotPlug(BOOL bEnable); //undocumented API
XPAC_API BOOL pac_GetHotPlugStatus(); //undocumented API
XPAC_API void pac_ClearHotPlug(); //undocumented API
XPAC_API BOOL pac_GetHotPlugIRQState(); //undocumented API
XPAC_API void pac_ResetSystemToDefault(); //undocumented API
XPAC_API void pac_EOI(); //undocumented API
XPAC_API void pac_ResetBackplane(); //undocumented API

//=============================================================================
// Memory API
//=============================================================================
#define XPAC_MEM_SRAM	0
#define XPAC_MEM_EEPROM	1

XPAC_API DWORD pac_GetMemorySize(int mem_type);
XPAC_API BOOL  pac_ReadMemory(DWORD address, LPBYTE lpBuffer, DWORD dwLength, int mem_type);
XPAC_API BOOL  pac_WriteMemory(DWORD address, LPBYTE lpBuffer, DWORD dwLength, int mem_type);
XPAC_API void  pac_EnableEEPROM(BOOL bEnable);

//=============================================================================
// Watch Dog Timer Functions
//=============================================================================
#define XPAC_WDT_HW		0
#define XPAC_WDT_OS		1

XPAC_API BOOL  pac_EnableWatchDog(int wdt, DWORD value);
XPAC_API void  pac_DisableWatchDog(int wdt);
XPAC_API void  pac_RefreshWatchDog(int wdt);
XPAC_API BOOL  pac_GetWatchDogState(int wdt);
XPAC_API DWORD pac_GetWatchDogTime(int wdt);
XPAC_API BOOL  pac_SetWatchDogTime(int wdt, DWORD value);

//=============================================================================
// UART API
//=============================================================================
#define CTO_TIMEOUT_ALL    		0
#define CTO_READ_RETRY_TIMEOUT  1
#define CTO_READ_TOTAL_TIMEOUT	2
#define CTO_WRITE_TOTAL_TIMEOUT	3

#define CTS	0
#define DSR	1
#define RI	2
#define CD	3

#define IN_DATA		0
#define OUT_DATA	1

XPAC_API HANDLE uart_Open(LPCSTR ConnectionString); 
XPAC_API HANDLE uart_OpenEx(LPCSTR ConnectionString);

XPAC_API BOOL   uart_Close(HANDLE hPort);
XPAC_API BOOL   uart_Write(HANDLE hPort, LPCSTR buf);
XPAC_API BOOL   uart_Read(HANDLE hPort, LPSTR buf);

XPAC_API BOOL   uart_Send(HANDLE hPort, LPCSTR buf);
XPAC_API BOOL   uart_Recv(HANDLE hPort, LPSTR buf);
XPAC_API BOOL   uart_SendCmd(HANDLE hPort, LPCSTR cmd, LPSTR szResult);
   
XPAC_API BOOL   uart_WriteExt(HANDLE hPort, LPCSTR buf, DWORD out_Len);
XPAC_API BOOL   uart_ReadExt(HANDLE hPort, LPSTR buf, DWORD in_Len);   

XPAC_API BOOL   uart_SendExt(HANDLE hPort, LPCSTR buf, DWORD out_Len);
XPAC_API BOOL   uart_RecvExt(HANDLE hPort, LPSTR buf, DWORD in_Len);
XPAC_API BOOL   uart_SendCmdExt(HANDLE hPort, LPCSTR cmd, DWORD out_Len, LPSTR szResult, DWORD in_Len);


XPAC_API void   uart_SetTimeOut(HANDLE hPort, DWORD msec, int ctoType);
XPAC_API void   uart_EnableCheckSum(HANDLE hPort, BOOL bEnable);  // Disable by default
XPAC_API void   uart_SetTerminator(HANDLE hPort, LPCSTR szTerm); // CR by default

XPAC_API BOOL   uart_BinSend(HANDLE hPort, LPCSTR buf, DWORD in_Len);
XPAC_API BOOL   uart_BinSendCmd(HANDLE hPort, LPCSTR ByteCmd, DWORD in_Len, LPSTR ByteResult, DWORD out_Len);
XPAC_API BOOL   uart_BinRecv(HANDLE hPort, LPSTR buf, DWORD in_Len);

XPAC_API DWORD  uart_GetDataSize(HANDLE hPort, int data_type);
XPAC_API BOOL   uart_GetLineStatus(HANDLE hPort, int pin);
XPAC_API DWORD  uart_SetLineStatus(HANDLE port,int pin,int mode);
XPAC_API DWORD  uart_GetOutputLineStatus(HANDLE hPort);

//=============================================================================
// Slot Interrupt API
//=============================================================================

#define PAC_INTR_DONE 0
#define PAC_INTR_EXIT 1
#define PAC_INTR_FAIL 2

#define INTR_RISING_TRIG  0
#define INTR_LEVEL_TRIG   1
#define INTR_Falling_TRIG 2

typedef int (CALLBACK * PAC_CALLBACK_FUNC)();

XPAC_API BOOL    pac_RegisterSlotInterrupt(BYTE slot, PAC_CALLBACK_FUNC f);
XPAC_API BOOL    pac_UnregisterSlotInterrupt(BYTE slot);
XPAC_API BOOL    pac_SetSlotInterruptPriority(BYTE slot, int nPriority);
XPAC_API void    pac_EnableSlotInterrupt(BYTE slot, BOOL bEnable);
XPAC_API void    pac_InterruptDone(BYTE slot);
XPAC_API HANDLE  pac_GetSlotInterruptEvent(BYTE slot);                   
XPAC_API void    pac_SetTriggerType(BYTE slot, int iType); //0: Rising edge trigger(default), 1: Level trigger, 2: Falling edge trigger
XPAC_API BOOL    pac_InterruptInitialize( BYTE slot );
XPAC_API void    pac_SetSlotInterruptEvent(BYTE slot, HANDLE hEvent);



//=============================================================================
// Error Handling API
//=============================================================================
XPAC_API DWORD	 pac_GetLastError();
XPAC_API void	 pac_SetLastError(DWORD errno);
XPAC_API void	 pac_ClearLastError(DWORD errno);
XPAC_API void    pac_GetErrorMessage(DWORD dwMessageID, LPTSTR lpBuffer);

//=============================================================================
// PAC Local/Remote IO API
//=============================================================================
#define PAC_REMOTE_IO_BASE		(0x1000)
#define PAC_REMOTE_IO(iAddress) (PAC_REMOTE_IO_BASE+iAddress)

#define pac_GetBit(v, ndx) (v & (1<<ndx))

XPAC_API BOOL  pac_WriteDO(HANDLE hPort, int slot, int iDO_TotalCh, DWORD lDO_Value);
XPAC_API BOOL  pac_WriteDOBit(HANDLE hPort, int slot, int iDO_TotalCh, int iChannel, int iBitValue);
XPAC_API BOOL  pac_ReadDO(HANDLE hPort, int slot,int iDO_TotalCh, DWORD *lDO_Value);
XPAC_API BOOL  pac_ReadDI(HANDLE hPort, int slot,int iDI_TotalCh, DWORD *lDI_Value);
XPAC_API BOOL  pac_ReadDIO(HANDLE hPort, int slot,int iDI_TotalCh,int iDO_TotalCh, DWORD* lDI_Value, DWORD* lDO_Value);
XPAC_API BOOL  pac_ReadDILatch(HANDLE hPort, int slot, int iDI_TotalCh,int iLatchType, DWORD *lDI_Latch_Value);
XPAC_API BOOL  pac_ClearDILatch(HANDLE hPort, int slot);
XPAC_API BOOL  pac_ReadDIOLatch(HANDLE hPort, int slot,int iDI_TotalCh,int iDO_TotalCh,int iLatchType, DWORD *lDI_Latch_Value,DWORD *lDO_Latch_Value);
XPAC_API BOOL  pac_ClearDIOLatch(HANDLE hPort, int slot);
XPAC_API BOOL  pac_ReadDICNT(HANDLE hPort, int slot,int iChannel,int iDI_TotalCh, DWORD *lCounter_Value);
XPAC_API BOOL  pac_ClearDICNT(HANDLE hPort, int slot,int iChannel,int iDI_TotalCh);
XPAC_API BOOL  pac_WriteAO(HANDLE hPort, int slot,int iChannel,int iAO_TotalCh,float fValue);
XPAC_API BOOL  pac_ReadAO(HANDLE hPort, int slot,int iChannel,int iAO_TotalCh,float *fValue);
XPAC_API BOOL  pac_ReadAI(HANDLE hPort, int slot,int iChannel, int iAI_TotalCh,float *fValue);
XPAC_API BOOL  pac_ReadAIHex(HANDLE hPort, int slot,int iChannel, int iAI_TotalCh,int *iValue);
XPAC_API BOOL  pac_ReadAIAll(HANDLE hPort, int slot,float fValue[]);
XPAC_API BOOL  pac_ReadAIAllHex(HANDLE hPort, int slot, int iValue[]);
XPAC_API BOOL  pac_ReadCNT(HANDLE hPort, int slot, int iChannel, DWORD *lCounter_Value);
XPAC_API BOOL  pac_ClearCNT(HANDLE hPort, int slot,int iChannel);
XPAC_API BOOL  pac_ReadCNTOverflow(HANDLE hPort, int slot, int iChannel, int *iOverflow);



//=============================================================================
// MISC API
//=============================================================================
XPAC_API void pac_WideToAnsiString(LPCTSTR wstr, LPSTR astr);
XPAC_API void pac_AnsiToWideString(LPCSTR astr, LPTSTR wstr);
XPAC_API void pac_DoEvents();


//=============================================================================
// Undocumented API
//=============================================================================
#define PAC_INP			_pac_inp
#define PAC_OUTP		_pac_outp
#define PAC_SLOT_INP	_pac_slot_inp
#define PAC_SLOT_OUTP	_pac_slot_outp


XPAC_PRIVATE_API BYTE	_pac_inp(int addr);
XPAC_PRIVATE_API void	_pac_outp(int addr, BYTE val);
XPAC_PRIVATE_API WORD   _pac_inpw(int addr);
XPAC_PRIVATE_API void   _pac_outpw(int addr, WORD val);
XPAC_PRIVATE_API BYTE   _pac_slot_inp(BYTE slot, int addr);
XPAC_PRIVATE_API void   _pac_slot_outp(BYTE slot, int addr, BYTE val);
XPAC_PRIVATE_API PBYTE  _pac_slot_map(BYTE slot, int addr);
XPAC_PRIVATE_API DWORD  _pac_get_slot_offset(BYTE slot);
XPAC_PRIVATE_API PBYTE  _pac_get_base_address();
XPAC_PRIVATE_API void   _pac_us_delay(DWORD microsecond);
XPAC_PRIVATE_API void   _pac_ticks_delay(DWORD ticks);
XPAC_PRIVATE_API float	_pac_delay(WORD wUSec);
XPAC_PRIVATE_API DWORD  _pac_slot_addr(BYTE slot, int addr);
XPAC_PRIVATE_API WORD   _pac_get_CPUtype(void);

//=============================================================================
// Error Handle
//=============================================================================
#define PAC_ERR_SUCCESS						0x00000
#define PAC_ERR_UNKNOWN						0x00001

//Basic=====================================================================
#define PAC_ERR_BASE						0x10000
#define PAC_ERR_SLOT_REGISTERED				(PAC_ERR_BASE + 1)
#define PAC_ERR_SLOT_NOT_REGISTERED			(PAC_ERR_BASE + 2)
#define PAC_ERR_UNKNOWN_MODULE				(PAC_ERR_BASE + 3)
#define PAC_ERR_MODULE_UNEXISTS				(PAC_ERR_BASE + 4)

//Memory Access=============================================================
#define PAC_ERR_MEMORY_BASE					0x11000
#define PAC_ERR_EEP_INVALID_ADDRESS 		(PAC_ERR_MEMORY_BASE + 1)
#define PAC_ERR_SRAM_INVALID_ADDRESS        (PAC_ERR_MEMORY_BASE + 2)
#define PAC_ERR_MEMORY_INVALID_TYPE			(PAC_ERR_MEMORY_BASE + 3)

//Watch Dog=================================================================
#define PAC_ERR_WDT_BASE					0x12000
#define PAC_ERR_WDT_INVALID_VALUE			(PAC_ERR_WDT_BASE + 1)
#define PAC_ERR_WDT_UNEXIST					(PAC_ERR_WDT_BASE + 2)
#define PAC_ERR_WDT_BASE_NOT_SET			(PAC_ERR_WDT_BASE + 3)

//Interrupt=================================================================
#define PAC_ERR_INTR_BASE					0x13000
#define PAC_ERR_INTR_CRATE_EVENT_FAILURE	(PAC_ERR_INTR_BASE + 1)

//UART======================================================================
#define PAC_ERR_UART_BASE					0x14000
#define PAC_ERR_UART_CHECKSUM				(PAC_ERR_UART_BASE+1)
#define PAC_ERR_UART_READ_TIMEOUT			(PAC_ERR_UART_BASE+2)
#define PAC_ERR_UART_RESPONSE				(PAC_ERR_UART_BASE+3)
#define PAC_ERR_UART_UNDER_INPUT_RANGE		(PAC_ERR_UART_BASE+4)
#define PAC_ERR_UART_EXCEED_INPUT_RANGE		(PAC_ERR_UART_BASE+5)
#define PAC_ERR_UART_OPEN_FAILED		    (PAC_ERR_UART_BASE+6)
#define PAC_ERR_UART_GET_COMM_STATUS_ERROR	(PAC_ERR_UART_BASE+7)
#define PAC_ERR_UART_INVALID_VALUE			(PAC_ERR_UART_BASE+8)
#define PAC_ERR_UART_INTERNAL_BUFFER_OVERFLOW (PAC_ERR_UART_BASE+9)

//IO========================================================================
#define PAC_ERR_IO_BASE						0x15000
#define PAC_ERR_IO_NOT_SUPPORT				(PAC_ERR_IO_BASE+1)
#define PAC_ERR_IO_ID						(PAC_ERR_IO_BASE+2)
#define PAC_ERR_IO_SLOT						(PAC_ERR_IO_BASE+3)
#define PAC_ERR_IO_CHANNEL					(PAC_ERR_IO_BASE+4)
#define PAC_ERR_IO_GAIN						(PAC_ERR_IO_BASE+5)
#define PAC_ERR_IO_INT_MODE  				(PAC_ERR_IO_BASE+6)
#define PAC_ERR_IO_VALUE_OUT_OF_RANGE		(PAC_ERR_IO_BASE+7)
#define PAC_ERR_IO_CHANNEL_OUT_OF_RANGE		(PAC_ERR_IO_BASE+8)

//======================================================================  =======
//Backplane timer
//=============================================================================
//Backplane Timer==================================================================
#define PAC_ERR_BPTIMER_BASE					0x16000

#define PAC_ERR_BPTIMER_REGISTERED				(PAC_ERR_BPTIMER_BASE + 1)
#define PAC_ERR_BPTIMER_NOT_REGISTERED			(PAC_ERR_BPTIMER_BASE + 2)

#define TIMEROUT  0
#define TIMER1   	1
#define TIMER2   	2

typedef int (CALLBACK * PAC_TIMEROUT_CALLBACK_FUNC)();

XPAC_API bool pac_SetBPTimerOut(unsigned int uHighElapse,unsigned int uLOwElapse, PAC_TIMEROUT_CALLBACK_FUNC f);
XPAC_API bool pac_SetBPTimer(int type,unsigned int uElapse, PAC_TIMEROUT_CALLBACK_FUNC f);
XPAC_API void pac_KillBPTimer(int type);
XPAC_API DWORD pac_GetBPTimerTimeTick_ms(void);
XPAC_API WORD pac_GetBPTimerTimeTick_us(void);
XPAC_API bool pac_SetBPTimerInterruptPriority(int type, int nPriority);
//Special IO================================================================
#define PAC_ERR_SPECIAL_IO					0x17000

//For User==================================================================
#define PAC_ERR_USER						0x20000



#ifdef __cplusplus
}
#endif

#pragma warning(disable:4996)		//disable sprintf to sprintf_s warning

#endif // __XPACSDK_H
									
