/*
 ******************************************************************************
 *  Copyright 1998DeltaLink bv. All Rights Reserved.
 ******************************************************************************
 *
 * DeltaLink Siemens SAPI protocol library
 *
 * File: protocol.h
 *
 * This file contains the implementation of the Siemens H1 protocol conform the
 * DeltaLink communication interface for FactoryLink.
 *
 * SIEMENS H1 specific definitions internally
 *
 */
#ifndef _H1_DEFS_INCLUDED /* { */
#define _H1_DEFS_INCLUDED 1


/*
 *	DEFINE BOARD NUMBERS
 */
#define S7_BOARD_0	0
#define S7_BOARD_1	1
#define S7_BOARD_2	2
#define S7_BOARD_3	3
#define S7_BOARD_4	4
#define S7_BOARD_5	5

/*
 * SIEMENS Data Type Codes
 */
#define H1_RWNO    0             /* Data type unkown because this is a Read/Write=No device */
#define H1_DB      1             /* data block */
#define H1_FY      2             /* flag byte  */
#define H1_IY      3             /* input byte  */
#define H1_QY      4             /* output bytes  */
#define H1_PY      5             /* peripheral bytes  */
#define H1_CW      6             /* counter words  */
#define H1_TW      7             /* timer words  */
#define H1_BW      8             /* system words (BS)  */
#define H1_AW      9             /* absolute address words  */
#define H1_DX      10						 /* expanded data block words (S5-135U)  */
#define H1_DE      16						 /* external data block words (S5-150U) */
#define H1_PE      17            /* external peripheral bytes (S5-150U) */

#define RW_BYTEH	 20  				   /* byte boundary with high to low direction */
#define RW_BYTEL   21  					 /* byte boundary with low to high direction */
#define RW_WORDH   22  					 /* word boundary with high to low direction */
#define RW_WORDL   23  					 /* word boundary with low to high direction */
#define RW_LONGH   24  					 /* long boundary with high to low direction */
#define RW_LONGL   25  					 /* long boundary with low to high direction */

/* Data type codes for db number greater then 255 */
#define H1_D20     120           /* data block 256 - 511 */
#define H1_D21     121           /* data block 512 - 767 */
#define H1_D22     122           /* data block 768 - 1023 */
#define H1_D23     123           /* data block 1024 - 1279 */
#define H1_D24     124           /* data block 1280 - 1535 */
#define H1_D25     125           /* data block 1536 - 1791 */
#define H1_D26     126           /* data block 1792 - 2047 */
#define H1_D27     127           /* data block 2048 - 2303 */
#define H1_D28     128           /* data block 2304 - 2559 */
#define H1_D29     129           /* data block 2560 - 2815 */
#define H1_D30     130           /* data block 2816 - 3071 */
#define H1_D31     131           /* data block 3072 - 3327 */
#define H1_D32     132           /* data block 3328 - 3583 */
#define H1_D33     133           /* data block 3584 - 3839 */
#define H1_D34     134           /* data block 3840 - 4095 */

/*
 * define S7 SAPI error codes
 */
//#define S7_BASE          300     /* H1 protocol errors start from 300 */


#define SAPI_CONNECT     300     /* H1 protocol errors start from 300 */



#define H1_SUCCESS       0x00    /* no error from plc */
#define H1_BADQZTYP      0x01    /* Incorrect Q/Z type at handling block */
#define H1_NOAREA        0x02    /* Area not present in AG */
#define H1_AREATOOSMALL  0x03    /* Area in AG too small */
#define H1_AKDERROR      0x04    /* AKD Error in the AG */
#define H1_ERRCONDWORD   0x05    /* Error with condition codeword */
#define H1_BADORGFORMAT  0x06    /* No valid ORG format */
#define H1_NODATABUFFER  0x07    /* No free data buffer */
#define H1_NOXPORTLINKS  0x08    /* No free transport links */
#define H1_READWRITEERR  0x09    /* Remote error with Read/Write */
#define H1_DATALINKERR   0x0A    /* Data Link error */
#define H1_HANDSHAKE     0x0B    /* Handshake error */
#define H1_INITERR       0x0C    /* Initiation error */
#define H1_RESETABORT    0x0D    /* Abort after reset */
#define H1_BOOTSTRAPJOB  0x0E    /* Job with boot strap function */
#define H1_NOJOBPRESENT  0x0F    /* Job not present */

#define H1_UNID_DATA     201     /* unidentified data */
#define H1_NOT_ENCODE    202     /* encode value not supported */
#define H1_UNKNOWN_TYPE  203     /* unknown type of data received */
#define H1_PACKET_LEN    204     /* the size off the H1 packet was too small  */
#define H1_ERR_PACKET    205     /* error in received H1 protocol header */
#define H1_ERR_MEM       206     /* no memory in TSR available any more */
#define H1_TSDU_SIZE     207     /* TSDU's not supported by this transport povider */
#define H1_SERVICE       208     /* Service not supported by this transport povider */
#define H1_RW_ERROR      209     /* Decive is not capable for Read/Write=Yes commands */

/*
 * header structure used for H1 communication
 */
#define H1_OPCODE_ID       0x01    /* id of OPCODE section */
#define H1_OPCODE_LEN      0x03    /* length of opcode section */

#define H1_WRITE_REQUEST   0x03    /* opcode used for WRITE request in H1 header */
#define H1_WRITE_ACK       0x04    /* opcode used for WRITE response in H1 header */

#define H1_READ_REQUEST    0x05    /* opcode used for READ request in H1 header */
#define H1_READ_ACK        0x06    /* opcode used for READ acknowledge in H1 header */

#define H1_ORG_ID          0x03    /* id of ORG section */
#define H1_ORG_LEN         0x08    /* length of ORG section */

#define H1_ACK_ID          0x0f    /* READ acknowledge section  */
#define H1_ACK_LEN         0x03    /* read acknowledge section len */


typedef struct
{
  char					system_id1;           /* System identification 'S' */
  char					system_id2;           /* System identification '7' */

  unsigned char hdr_length;           /* total H1 header length which is 16   */ 

  char					opcode_id;            /* OPCODE section */
  char					opcode_len;           /* opcode section length */
  char					opcode;               /* opcode of this H1 command */

  char					org_id;               /* ORG section */
  char					org_len;              /* org section length */

  union {

    char type;                  /* data type in case of sending */
    char error;                 /* error number of response */

  } blk;

  unsigned char  db_no;                 /* Data Block number */
  unsigned short start;                 /* start address */
  unsigned short length;                /* length of data */
     
  unsigned char  empty;                 /* always the same */
  unsigned char  empty_len;             /* always the same */

} H1_HDR;

/*
 * define macros H1 Header information
 */
#define h1_set_start( h, v)  { \
                                 (( H1_HDR *)(h))->start |= (( (v) >> 8) & 0x00ff);	\
                                 (( H1_HDR *)(h))->start |= (( (v) << 8 ) & 0xff00 ); \
                               }

#define h1_get_start( h )   ( ( (( H1_HDR *)(h))->start >> 8) & 0x00ff ) | (( (( H1_HDR *)(h))->start << 8) & 0xff00 )

#define h1_set_length( h, v)  { \
                                (( H1_HDR *)(h))->length |= (( (v) >> 8) & 0x00ff); \
                                (( H1_HDR *)(h))->length |= (( (v) << 8) & 0xff00 );\
                               }
#define h1_get_length( h )   ( ( (( H1_HDR *)(h))->length >> 8) & 0x00ff) | (( (( H1_HDR *)(h))->length << 8) & 0xff00)


#define   h1_get_type( h )             (( H1_HDR *)(h))->blk.type
#define   h1_get_dbno( h )						 (( H1_HDR *)(h))->db_no

#define   h1_set_type( h, v)           ( (( H1_HDR *)(h))->blk.type = (v) )
#define   h1_set_dbno( h, v)					 ( (( H1_HDR *)(h))->db_no = (v) )

/*
 * lay-out of encoded data for a SIEMENS plc
 */
typedef struct _encode
{
  unsigned char  org;                 /* H1 ORG type ( D, M etc) */
  unsigned char  type;                /* data type */

  unsigned short db_nr;               /* Data Block number */
  unsigned short address;             /* address   */ 

  unsigned char  bit;                 /* bit number   */ 
  unsigned char  chg_flag;            /* change flag to notify PLC incoming command */

} ENCODE;

#endif /* _H1_DEFS_INCLUDED */
