#ifndef     __SLCAN_H__
#define     __SLCAN_H__

#include <windows.h>

#define     STDCALL  __stdcall
#ifdef      SLCAN_EXPORT
#define     SLCANAPI __declspec(dllexport)
#else
#define     SLCANAPI __declspec(dllimport)
#endif

#define     SLCAN_PROPERTY_INDEX_LINKNAME        0
#define     SLCAN_PROPERTY_INDEX_INSTANCEID      1

#define     SLCAN_PROPERTY_INDEX_DEVICEDESC      2
#define     SLCAN_PROPERTY_INDEX_FRIENDLYNAME    3
#define     SLCAN_PROPERTY_INDEX_PHOBJECTNAME    4
#define     SLCAN_PROPERTY_INDEX_MFG             5
#define     SLCAN_PROPERTY_INDEX_LOCATIONINFO    6
#define     SLCAN_PROPERTY_INDEX_ENUMERATOR      7
#define     SLCAN_PROPERTY_INDEX_CLASS           8
#define     SLCAN_PROPERTY_INDEX_CLASSGUID       9
#define     SLCAN_PROPERTY_INDEX_SERVICE         10
#define     SLCAN_PROPERTY_INDEX_DRIVER          11
#define     SLCAN_PROPERTY_INDEX_PORTNAME        12
#define     SLCAN_PROPERTY_INDEX_PRODUCT         13L
#define     SLCAN_PROPERTY_INDEX_MANUFACTURER    14L
#define     SLCAN_PROPERTY_INDEX_CONFIGURATION   15L
#define     SLCAN_PROPERTY_INDEX_INTERFACE       16L
#define     SLCAN_PROPERTY_INDEX_SERIAL          17L
#define     SLCAN_PROPERTY_INDEX_ALIAS           18L
#define     SLCAN_PROPERTY_INDEX_CHANNELLINK     19L
#define     SLCAN_PROPERTY_INDEX_SERIALID        20L


#define     SLCAN_MODE_CONFIG                  0x00
#define     SLCAN_MODE_NORMAL                  0x01
#define     SLCAN_MODE_LISTENONLY              0x02
#define     SLCAN_MODE_LOOPBACK                0x03
#define     SLCAN_MODE_SLEEP                   0x04

#define     SLCAN_BR_CIA_1000K                   0x8000
#define     SLCAN_BR_CIA_800K                    0x8001
#define     SLCAN_BR_CIA_500K                    0x8002
#define     SLCAN_BR_CIA_250K                    0x8003
#define     SLCAN_BR_CIA_125K                    0x8004
#define     SLCAN_BR_CIA_50K                     0x8005
#define     SLCAN_BR_CIA_20K                     0x8006
#define     SLCAN_BR_CIA_10K                     0x8007
#define     SLCAN_BR_400K                        0x8008
#define     SLCAN_BR_200K                        0x8009
#define     SLCAN_BR_100K                        0x800A
#define     SLCAN_BR_83333                       0x800B
#define     SLCAN_BR_33333                       0x800C
#define     SLCAN_BR_25K                         0x800D
#define     SLCAN_BR_5K                          0x800E
#define     SLCAN_BR_30K                         0x800F
#define     SLCAN_BR_300K                        0x8010
#define     SLCAN_BR_LASTINDEX                 SLCAN_BR_300K





#define     SLCAN_CAP_MODE_NORMAL               0x01
#define     SLCAN_CAP_MODE_LISTEN_ONLY          0x02
#define     SLCAN_CAP_MODE_LOOP_BACK            0x04
#define     SLCAN_CAP_MODE_SLEEP                0x08

#define     SLCAN_CAP_TXMODE_ONE_SHOT           0x01
#define     SLCAN_CAP_TXMODE_TIMESTAMP          0x02


#define     SLCAN_CAP_CONTR_EXTERNAL            0x00
#define     SLCAN_CAP_CONTR_MCP2515             0x01
#define     SLCAN_CAP_CONTR_SJA1000             0x02

#define     SLCAN_CAP_CONTR_INTERNAL            0x80
#define     SLCAN_CAP_CONTR_LPC                 0x81
#define     SLCAN_CAP_CONTR_STM32               0x82
#define     SLCAN_CAP_CONTR_STM8                0x83
#define     SLCAN_CAP_CONTR_PIC                 0x84
#define     SLCAN_CAP_CONTR_PIC_ECAN            0x85

#define     SLCAN_CAP_PHYS_HS                   0x01
#define     SLCAN_CAP_PHYS_LS                   0x02
#define     SLCAN_CAP_PHYS_SW                   0x04
#define     SLCAN_CAP_PHYS_J1708                0x08
#define     SLCAN_CAP_PHYS_LIN                  0x10
#define     SLCAN_CAP_PHYS_KLINE                0x20

#define     SLCAN_CAP_PHYS_LOAD                 0x01

#define     SLCAN_CAP_BITRATE_INDEX             0x01
#define     SLCAN_CAP_BITRATE_CUSTOM            0x02
#define     SLCAN_CAP_BITRATE_AUTOMATIC         0x04


#define     SLCAN_EVT_LEVEL_RX_MSG              0
#define     SLCAN_EVT_LEVEL_TIME_STAMP          1
#define     SLCAN_EVT_LEVEL_TX_MSG              2
#define     SLCAN_EVT_LEVEL_BUS_STATE           3
#define     SLCAN_EVT_LEVEL_COUNTS              4
#define     SLCAN_EVT_LEVEL_ERRORS              5

#define     SLCAN_EVT_TYPE_RX                   0x0
#define     SLCAN_EVT_TYPE_START_TX             0x1
#define     SLCAN_EVT_TYPE_END_TX               0x2
#define     SLCAN_EVT_TYPE_ABORT_TX             0x3
#define     SLCAN_EVT_TYPE_BUS_STATE            0x4
#define     SLCAN_EVT_TYPE_ERROR_COUNTS         0x5
#define     SLCAN_EVT_TYPE_BUS_ERROR            0x6
#define     SLCAN_EVT_TYPE_ARBITRATION_ERROR    0x7
#define     SLCAN_EVT_STAMP_INC                 0xF

#define     SLCAN_BUS_STATE_ERROR_ACTIVE        0x00
#define     SLCAN_BUS_STATE_ERROR_ACTIVE_WARN   0x01
#define     SLCAN_BUS_STATE_ERROR_PASSIVE       0x02
#define     SLCAN_BUS_STATE_BUSOFF              0x03

#define     SLCAN_MES_INFO_EXT               0x01
#define     SLCAN_MES_INFO_RTR               0x02
#define     SLCAN_MES_INFO_ONESHOT           0x04



#define     SLCAN_DEVOP_CREATE              0x00000000
#define     SLCAN_DEVOP_CREATEHANDLE        0x00000001
#define     SLCAN_DEVOP_OPEN                0x00000002
#define     SLCAN_DEVOP_CLOSE               0x00000003
#define     SLCAN_DEVOP_DESTROYHANDLE       0x00000004
#define     SLCAN_DEVOP_DESTROY             0x00000005


#define     SLCAN_INVALID_HANDLE_ERROR          0xE0001001
#define     SLCAN_DEVICE_INVALID_HANDLE_ERROR   0xE0001120
#define     SLCAN_HANDLE_INIT_ERROR             0xE0001017
#define     SLCAN_DEVICE_NOTOPEN_ERROR          0xE0001121

#define     SLCAN_EVT_ERR_TYPE_BIT               0x00
#define     SLCAN_EVT_ERR_TYPE_FORM              0x01
#define     SLCAN_EVT_ERR_TYPE_STUFF             0x02
#define     SLCAN_EVT_ERR_TYPE_OTHER             0x03

#define     SLCAN_EVT_ERR_DIR_TX                 0x00
#define     SLCAN_EVT_ERR_DIR_RX                 0x01

#define     SLCAN_EVT_ERR_FRAME_SOF              0x03
#define     SLCAN_EVT_ERR_FRAME_ID28_ID21        0x02
#define     SLCAN_EVT_ERR_FRAME_ID20_ID18        0x06
#define     SLCAN_EVT_ERR_FRAME_SRTR             0x04
#define     SLCAN_EVT_ERR_FRAME_IDE              0x05
#define     SLCAN_EVT_ERR_FRAME_ID17_ID13        0x07
#define     SLCAN_EVT_ERR_FRAME_ID12_ID5         0x0F
#define     SLCAN_EVT_ERR_FRAME_ID4_ID0          0x0E
#define     SLCAN_EVT_ERR_FRAME_RTR              0x0C
#define     SLCAN_EVT_ERR_FRAME_RSRV0            0x0D
#define     SLCAN_EVT_ERR_FRAME_RSRV1            0x09
#define     SLCAN_EVT_ERR_FRAME_DLC              0x0B
#define     SLCAN_EVT_ERR_FRAME_DATA             0x0A
#define     SLCAN_EVT_ERR_FRAME_CRC_SEQ          0x08
#define     SLCAN_EVT_ERR_FRAME_CRC_DEL          0x18
#define     SLCAN_EVT_ERR_FRAME_ACK_SLOT         0x19
#define     SLCAN_EVT_ERR_FRAME_ACK_DEL          0x1B
#define     SLCAN_EVT_ERR_FRAME_EOF              0x1A
#define     SLCAN_EVT_ERR_FRAME_INTER            0x12
#define     SLCAN_EVT_ERR_FRAME_AER_FLAG         0x11
#define     SLCAN_EVT_ERR_FRAME_PER_FLAG         0x16
#define     SLCAN_EVT_ERR_FRAME_TDB              0x13
#define     SLCAN_EVT_ERR_FRAME_ERR_DEL          0x17
#define     SLCAN_EVT_ERR_FRAME_OVER_FLAG        0x1C

#define     SLCAN_TX_STATUS_OK                   0x00
#define     SLCAN_TX_STATUS_TIMEOUT              0x01
#define     SLCAN_TX_STATUS_BUSOFF               0x02
#define     SLCAN_TX_STATUS_ABORT                0x03
#define     SLCAN_TX_STATUS_NOT_ENA              0x04
#define     SLCAN_TX_STATUS_ERROR_ONE_SHOT       0x05
#define     SLCAN_TX_STATUS_INVALID_MODE         0x06
#define     SLCAN_TX_STATUS_UNKNOWN              0x0F

#define     SLCAN_PURGE_TX_ABORT                 0x01
#define     SLCAN_PURGE_RX_ABORT                 0x02
#define     SLCAN_PURGE_TX_CLEAR                 0x04
#define     SLCAN_PURGE_RX_CLEAR                 0x08

#pragma pack(push,1)

#ifdef __cplusplus
extern "C"{
#endif

typedef     PVOID   HSLCAN;

typedef    struct _SLCAN_CAPABILITIES{

    BYTE    bModes;
    BYTE    bTXModes;
	BYTE    bMaxEventLevel;
	BYTE    bController;
    BYTE    bPhysical;
    BYTE    bPhysicalLoad;
    BYTE    bBitrates;
    BYTE    bAdvancedModes;
    DWORD   dwCanBaseClk;
    DWORD   dwTimeStampClk;
	WORD    wMaxBRP;
}SLCAN_CAPABILITIES,*PSLCAN_CAPABILITIES;

typedef struct   _SLCAN_BITRATE {
    WORD    BRP;
    BYTE    TSEG1;
    BYTE    TSEG2;
    BYTE    SJW;
	BYTE    SAM;
}SLCAN_BITRATE,*PSLCAN_BITRATE;


typedef    void (STDCALL* SLCAN_DEVICE_CALLBACK)(
	HSLCAN      hDevice,
	DWORD       dwIndex,
	DWORD       dwOperation,
	PVOID       pContext,
	DWORD       dwContextSize
);

typedef  VOID (STDCALL* SLCAN_DEVICELIST_CALLBACK)(
	HSLCAN      hDevice,
	DWORD       dwIndex,
	PVOID       pContext,
	DWORD       dwContextSize
);

typedef struct _SLCAN_MESSAGE{
    BYTE    Info;
    DWORD   ID;
    BYTE    DataCount;
    BYTE    Data[8];
}SLCAN_MESSAGE,*PSLCAN_MESSAGE;

typedef struct _SLCAN_TXMESSAGE{
    LONG            dwDelay;
    SLCAN_MESSAGE   Msg;
}SLCAN_TXMESSAGE,*PSLCAN_TXMESSAGE;

typedef struct _SLCAN_EVENT{
    BYTE    EventType;
    DWORD   TimeStampLo;
    union {
        SLCAN_MESSAGE Msg;
        DWORD TimeStamp[2];
        DWORD64 TimeStamp64;
        struct {
            BYTE BusMode;
            BYTE Dummy1;
            BYTE ErrCountRx;
            BYTE ErrCountTx;
            BYTE ErrType;
            BYTE ErrDir;
            BYTE ErrFrame;
            BYTE LostArbitration;
        };
    };
}SLCAN_EVENT,*PSLCAN_EVENT;

typedef struct _SLCAN_STATE{
    BYTE BusMode;
    BYTE Dummy1;
    BYTE ErrCountRX;
    BYTE ErrCountTX;
}SLCAN_STATE,*PSLCAN_STATE;

typedef union _SLCAN_TIMESTAMP{
    UINT64 Value;
    DWORD  dwValue[2];
    USHORT wValue[4];
    BYTE   bValue[8];
}SLCAN_TIMESTAMP,*PSLCAN_TIMESTAMP;



SLCANAPI BOOL STDCALL SlCan_Load(
   SLCAN_DEVICE_CALLBACK DeviceProc,
   SLCAN_DEVICELIST_CALLBACK DeviceListProc
);

SLCANAPI BOOL STDCALL SlCan_Free(
	BOOL    bDoCallBack
);

SLCANAPI BOOL STDCALL SlCan_Update();

SLCANAPI HSLCAN STDCALL SlCan_GetDevice(
	DWORD       dwIndex
);

SLCANAPI DWORD STDCALL SlCan_GetDeviceCount();


SLCANAPI HANDLE STDCALL SlCan_DeviceGetHandle(
	DWORD       dwIndex
);

SLCANAPI DWORD STDCALL SlCan_DeviceGetProperty(
   HSLCAN       hDevice,
   DWORD        dwIndex,
   PCHAR        pBuf,
   DWORD        dwSize
);

SLCANAPI DWORD STDCALL SlCan_DeviceGetPropertyW(
   HSLCAN       hDevice,
   DWORD        dwIndex,
   PWCHAR       pBuf,
   DWORD        dwSize
);

SLCANAPI HKEY STDCALL SlCan_DeviceGetRegKey(
   HSLCAN       hDevice,
   DWORD        dwIndex
);

SLCANAPI PVOID STDCALL SlCan_DeviceSetContext(
   HSLCAN       hDevice,
   PVOID        pBuf,
   DWORD        dwBufSize
);

SLCANAPI PVOID STDCALL SlCan_DeviceGetContext(
   HSLCAN       hDevice
);

SLCANAPI DWORD STDCALL SlCan_DeviceGetContextSize(
   HSLCAN       hDevice
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetAlias(
   HSLCAN       hDevice,
   PCHAR        pBuf
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetAliasW(
   HSLCAN       hDevice,
   PWCHAR        pBuf
);

SLCANAPI DWORD STDCALL SlCan_DeviceGetAlias(
   HSLCAN       hDevice,
   PCHAR        pBuf,
   DWORD        dwSize
);

SLCANAPI DWORD STDCALL SlCan_DeviceGetAliasW(
   HSLCAN       hDevice,
   PWCHAR        pBuf,
   DWORD        dwSize
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetCapabilities(
  HSLCAN        hDevice,
  PSLCAN_CAPABILITIES   pCapabilities
);

SLCANAPI BOOL STDCALL SlCan_DeviceOpen(
  HSLCAN        hDevice
);

SLCANAPI BOOL STDCALL SlCan_DeviceClose(
  HSLCAN   hDevice
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetMode(
  HSLCAN        hDevice,
  DWORD         dwMode
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetMode(
  HSLCAN        hDevice,
  PDWORD        pdwMode
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetState(
  HSLCAN        hDevice,
  PSLCAN_STATE  pState
);


SLCANAPI BOOL STDCALL SlCan_DeviceSetTXTimeOut(
  HSLCAN            hDevice,
  DWORD             dwMillisecond
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetTXTimeOut(
  HSLCAN            hDevice,
  PDWORD            pdwMillisecond
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetBitRate(
  HSLCAN            hDevice,
  PSLCAN_BITRATE    pBitRate
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetBitRate(
  HSLCAN            hDevice,
  PSLCAN_BITRATE    pBitRate
);


SLCANAPI BOOL STDCALL SlCan_DeviceEnaRec(
  HSLCAN            hDevice,
  BYTE              bValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetLatency(
  HSLCAN            hDevice,
  BYTE              bValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetLatency(
  HSLCAN            hDevice,
  PBYTE             pbValue
);

SLCANAPI BOOL STDCALL SlCan_DevicePurge(
  HSLCAN            hDevice,
  BYTE              bValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetEventLevel(
  HSLCAN            hDevice,
  BYTE              bValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetEventLevel(
  HSLCAN            hDevice,
  PBYTE             pbValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetStartTimeStamp(
  HSLCAN            hDevice,
  PSLCAN_TIMESTAMP  pValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetStartTimeStamp(
  HSLCAN            hDevice,
  PSLCAN_TIMESTAMP  pValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetTimeStamp(
  HSLCAN            hDevice,
  PSLCAN_TIMESTAMP  pValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetTimeStampPeriod(
  HSLCAN            hDevice,
  LONG              lValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetTimeStampPeriod(
  HSLCAN            hDevice,
  PLONG             plValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceSetExMode(
  HSLCAN            hDevice,
  BYTE              bValue
);

SLCANAPI BOOL STDCALL SlCan_DeviceGetExMode(
  HSLCAN            hDevice,
  PBYTE             pbValue
);


SLCANAPI BOOL STDCALL SlCan_DeviceWriteMessages(
  HSLCAN            hDevice,
  PSLCAN_MESSAGE    pMsg,
  DWORD             dwCount,
  PBYTE             pbStatus
);

SLCANAPI BOOL STDCALL SlCan_DeviceWriteMessagesEx(
  HSLCAN            hDevice,
  PSLCAN_TXMESSAGE  pMsg,
  DWORD             dwCount,
  PBYTE             pbStatus,
  PDWORD            pdwCount
);

SLCANAPI BOOL STDCALL SlCan_DeviceReadMessages(
  HSLCAN            hDevice,
  DWORD             dwTimeOut,
  PSLCAN_MESSAGE    pMsg,
  DWORD             dwCount,
  PDWORD            pdwCount
);

SLCANAPI BOOL STDCALL SlCan_DeviceReadEvents(
  HSLCAN            hDevice,
  DWORD             dwTimeOut,
  PSLCAN_EVENT      pEvent,
  DWORD             dwCount,
  PDWORD            pdwCount
);

#ifdef      __cplusplus
}
#endif

#pragma     pack(pop)

#endif      //__SLCAN_H