/**
 * \brief Common defines for iqInterface control DLL
 * \copyright 2013-2014, IQ� Development GmbH, Neckartenzlingen. All rights reserved.
 */

#ifndef _iqi_define_h
#define _iqi_define_h

/** \brief Maximum IO-Link Revision ID supported by this iqInterface control DLL. */
#define IOLINK_REVISION_ID 0x11

/** \brief Current version of this iqInterface control DLL. */
#define IQI_DLL_VERSION_MAJOR    0x02
#define IQI_DLL_VERSION_MINOR    0x00

#ifdef EXPORT_API
#define DLL_API __declspec(dllexport)
#else
#ifdef IMPORT_API
#define DLL_API __declspec(dllimport)
#else
#define DLL_API
#endif
#endif

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdint.h>

#ifdef _MSC_VER
#define snprintf _snprintf_s
#endif

#ifdef _CVI_
#pragma C99_extensions_on 
#endif

#define MAX_COMPORT_NUM 128

#define CYCLE_TIME_BASE_01_MS 0x00
#define CYCLE_TIME_BASE_04_MS 0x40
#define CYCLE_TIME_BASE_16_MS 0x80
#define CYCLE_TIME_BASE_RESERVED 0xC0

#define CYCLE_TIME_01_MS 1
#define CYCLE_TIME_04_MS 4
#define CYCLE_TIME_16_MS 16

#define CYCLE_TIME_ADD_FOR_BASE_01_MS 0
#define CYCLE_TIME_ADD_FOR_BASE_04_MS 64
#define CYCLE_TIME_ADD_FOR_BASE_16_MS 320

#define MIN_CYCLE_TIME 4
#define MAX_CYCLE_TIME_01MS 63
#define MAX_CYCLE_TIME_04MS 316
#define MAX_CYCLE_TIME 1328

#define MAX_ERR_STR_LEN 256

#define MAX_OD_BUF_LEN 232
#define MAX_PD_BUF_LEN 32

typedef uint8_t       boolean;    //b
typedef int8_t        char08;     //c
typedef uint8_t       uchar08;    //uc
typedef int16_t       int16;      //i
typedef uint16_t      uint16;     //ui
typedef int32_t       long32;     //l
typedef uint32_t      ulong32;    //ul
typedef int64_t       long64;     //l64
typedef uint64_t      ulong64;    //l64

#define FALSE 0
#define TRUE  1

#define GET_BIGEND_INT16(ptr) \
  (int16)(((((uchar08*)(ptr))[0]) << 8) \
        + ((((uchar08*)(ptr))[1])))

#define GET_BIGEND_UINT16(ptr) \
  (uint16)(((((uchar08*)(ptr))[0]) << 8) \
         + ((((uchar08*)(ptr))[1])))

#define GET_LITEND_UINT16(ptr) \
  (uint16)(((((uchar08*)(ptr))[1]) << 8) \
         + ((((uchar08*)(ptr))[0])))

#define GET_BIGEND_LONG32(ptr) \
  (long32)(((((uchar08*)(ptr))[0]) << 24) \
         + ((((uchar08*)(ptr))[1]) << 16) \
         + ((((uchar08*)(ptr))[2]) <<  8) \
         + ((((uchar08*)(ptr))[3])))

#define GET_BIGEND_ULONG32(ptr) \
  (ulong32)(((((uchar08*)(ptr))[0]) << 24) \
          + ((((uchar08*)(ptr))[1]) << 16) \
          + ((((uchar08*)(ptr))[2]) <<  8) \
          + ((((uchar08*)(ptr))[3])))

#define SET_BIGEND_INT16(ptr, val) \
  do { \
    ((uchar08*)(ptr))[0] = (uchar08)(((val) >> 8) & 0xFF); \
    ((uchar08*)(ptr))[1] = (uchar08)(((val)     ) & 0xFF); \
  } while(0)

#define SET_BIGEND_UINT16(ptr, val) \
  SET_BIGEND_INT16(ptr, val)

#define SET_BIGEND_LONG32(ptr, val) \
  do { \
    ((uchar08*)(ptr))[0] = (uchar08)(((val) >> 24) & 0xFF); \
    ((uchar08*)(ptr))[1] = (uchar08)(((val) >> 16) & 0xFF); \
    ((uchar08*)(ptr))[2] = (uchar08)(((val) >>  8) & 0xFF); \
    ((uchar08*)(ptr))[3] = (uchar08)(((val)      ) & 0xFF); \
  } while(0)

#define SET_BIGEND_ULONG32(ptr, val) \
  SET_BIGEND_LONG32(ptr, val)
  
// return values (if positive) and common error codes (if negative)

#define ERR_NONE                0                                                // also as 'FALSE' or 0 result
#define ERR_INTERNAL            -1
#define ERR_NOTFOUND            -2
#define ERR_BUFFER_OVERFLOW     -3
#define ERR_PARAMETER           -4
#define ERR_OPERATION           -5
#define ERR_DATA                -6
#define ERR_CUSTOM              -7

#define ASSIGN_RETURN(var, exp) \
    do { \
        int16 __res = exp; \
        if (__res < 0) return __res; \
        var = __res; \
    } while(0)

#define CHK_RETURN(exp) \
    do { \
        int16 __res = exp; \
        if (__res < 0) return __res; \
    } while(0)

#define CHK_RETURN_MES(exp, message, cpErrMsg) \
    do { \
        int16 __res = exp; \
        char08 __buf[MAX_ERR_STR_LEN];\
        if (__res < 0) \
        { \
          snprintf(__buf, MAX_ERR_STR_LEN,  MAX_ERR_STR_LEN,\
            "%s: %s ", message, cpErrMsg); \
          snprintf(cpErrMsg, MAX_ERR_STR_LEN, MAX_ERR_STR_LEN, \
            "%s", __buf); \
          return __res; \
        } \
    } while(0)

#define IQPAR_LEN_ERR_MESSAGE "Wrong data length read from iqInterface of %s iqParamter - %d bytes (should be %d)."

#define IQPAR_CHECK_LEN(iqPar,iActSize,iSize) \
  if (iActSize != iSize)\
  {\
    snprintf(cpErrMsg, MAX_ERR_STR_LEN, MAX_ERR_STR_LEN,\
      IQPAR_LEN_ERR_MESSAGE, iqPar, iActSize, iSize);\
    return ERR_DATA;\
  }

#define __LEN(array)  ((int)(sizeof(array) / sizeof(*(array))))

typedef enum
{
  /** \brief sdci communication with baudrate COM1 4,8   kbit/s */
  IOL_BAUDRATE_COM1 = 0,
  /** \brief sdci communication with baudrate COM2 38,4  kbit/s */
  IOL_BAUDRATE_COM2 = 1,
  /** \brief sdci communication with baudrate COM3 230,4 kbit/s */
  IOL_BAUDRATE_COM3 = 2,
  
} IOLBaudrateT;

typedef enum
{
  IOL_REV_ID_V1_0 = 0x10,
  IOL_REV_ID_V1_1 = 0x11

} IOLRevisionIDT;

typedef struct
{
  uint16  Time01ms; // cycle time in ms = Time01ms/10
  uchar08 Base;
  uchar08 Base01MS;
  uint16  BaseAddTime01ms;
  uchar08 Multiplier;
  uchar08 Packed;
  
} IOLCycleTimeT;

typedef enum
{
  EVENT_INSTANCE_UNKNOWN = 0,
  EVENT_INSTANCE_PL      = 1,
  EVENT_INSTANCE_DL      = 2,
  EVENT_INSTANCE_AL      = 3,
  EVENT_INSTANCE_APPL    = 4

} EventInstanceT;

typedef enum
{
  EVENT_SOURCE_REMOTE = 0,
  EVENT_SOURCE_LOCAL  = 1

} EventSourceT;

typedef enum
{
  EVENT_TYPE_RESERVED     = 0,
  EVENT_TYPE_NOTIFICATION = 1,
  EVENT_TYPE_WARNING      = 2,
  EVENT_TYPE_ERROR        = 3

} EventType;

typedef enum 
{
  EVENT_MODE_RESERVED    = 0,
  EVENT_MODE_SINGLE_SHOT = 1,
  EVENT_MODE_DISAPPEARS  = 2,
  EVENT_MODE_APPEARS     = 3

} EventModeT;

typedef struct
{
  uchar08 Instance : 3; // 0-2 bit
  uchar08 Source   : 1; // 3 bit
  uchar08 Type     : 2; // 4-5 bit
  uchar08 Mode     : 2; // 6-7 bit
  
} EventQualifierFieldsT;

typedef union
{
  EventQualifierFieldsT Fields;
  uchar08 Byte;
  
} EventQualifierT;

typedef struct
{
  char08 cpIqInterfaceIpAddr[17];   // ip address of iqInterface TCP connection over ethernet: "xxx.xxx.xxx.xxx" (string in dec format)
  uint16 uiPort;                    // port of iqInterface TCP connection over ethernet
  char08 cpIqInterfaceMacAddr[19];  // MAC address of iqInterface ethernet connection: "HH:HH:HH:HH:HH:HH" (string in hex format)
  ulong64 ul64SerialNumber;         // serial number of iqInterface
  char08 cpLocalIpAddr[17];         // local (PC) ip address of network adapter in which subnet iqInterface is availiable

} enet_ConnectionT;

#endif
