/************************************************************************/
/* Copyright 2009-2015 MBARI                                            */
/************************************************************************/
/* Summary  : Definitions for serial & power I/O to O5Expander          */
/* Filename : o5eLib.h                                                  */
/* Author   : Robert Herlien (rah)                                      */
/* Project  : OASIS5                                                    */
/* Revision: 1.0                                                        */
/* Created  : 11/5/2015 from sensorNode.h                               */
/*                                                                          */
/* MBARI provides this documentation and code "as is", with no warranty,    */
/* express or implied, of its quality or consistency. It is provided without*/
/* support and without obligation on the part of the Monterey Bay Aquarium  */
/* Research Institute to assist in its use, correction, modification, or    */
/* enhancement. This information should not be published or distributed to  */
/* third parties without specific written permission from MBARI.            */
/*                                                                          */
/************************************************************************/
/* Modification History:                                                */
/* 5nov2015, rah, created from snLib.h                                  */
/************************************************************************/

#ifndef INCo5eLibh
#define INCo5eLibh

//#define O5ELIB
#include <sys/types.h>

typedef struct remSerPort *RemSerHandle;
typedef struct o5eStruct *O5ExpHandle;

#include <o5expander.h>
#include <modbus.h>


/****************************************/
/* Typedefs and definitions             */
/****************************************/

#define DEVNAME_LEN     256             /* Length of device name field  */
#define SERBUF_SIZE     240             /* Size of serial buffer        */      
#define SERREG_SIZE     (SERBUF_SIZE/2)

/* Message response timeout in microseconds (== 600ms) */
#define RESPONSE_TIMEOUT 600000

/* Inter-character timeout in microseconds (== 50ms)    */
#define BYTE_TIMEOUT 50000


typedef struct remSerPort       /****************************************/
{                               /* Remote Serial Port                   */
    struct o5eStruct *o5ep;     /* o5eStruct for this ser port          */
    modbus_t    *ctx;           /* libmodbus context from o5ep for convenience*/
    uint16_t    port;           /* Serial port on the slave             */
    uint16_t    useCount;       /* Number of times opened               */
    uint16_t    bufChars;       /* Number of chars valid in read buffer */
    uint16_t    bufIndex;       /* Read buffer output index             */
    uint16_t    rbuf[SERREG_SIZE+1]; /* Read Register Buffer            */
    uint16_t    wbuf[SERREG_SIZE+1]; /* Write Register Buffer           */
} RemSerPort;                   /****************************************/

typedef struct o5eStruct        /****************************************/
{                               /* Modbus Connection to O5 Expander     */
    modbus_t    *ctx;           /* libmodbus context                    */
    uint16_t    slaveID;        /* SlaveID on this connection           */
    uint16_t    useCount;       /* Number of times opened               */
    uint16_t    boardType;      /* Type of board we're talking to       */
    uint16_t    numSerPorts;    /* Number of remote ser ports on O5exp  */
    uint16_t    numPwrPorts;    /* Number of power/serial relays on O5exp*/
    char        devName[DEVNAME_LEN];    /* Modbus serial port          */
    RemSerPort  serPorts[O5E_SER_PORTS]; /* O5Exp remote serial ports   */
} O5EStruct;                    /****************************************/


/****************************************/
/* Remote I/O Definitions               */
/****************************************/

#define MIN_READ                10  /* Min number of serial regs to read */


/************************************************************************/
/* Register and Coil Definitions                                        */
/* Note that the Modbus addresses below use the Modbus convention where */
/* address n is represented on Modbus by (n-1).  I would have expected  */
/* libmodbus to make this transparent, but it doesn't.                  */
/************************************************************************/
#define BoardTypeReg            (0x00)
#define NumSerPortsReg          (0x01)
#define NumRelaysReg            (0x02)
#define NumDIOReg               (0x03)
#define NumAnalogReg            (0x04)
#define SerIsSwitchedReg        (0x05)
#define ControlReg              (0x06)
#define BlinkyReg               (0x07)

#define SerialNum               (0x0f)
#define SoftwareRev             (0x10)
#define ModBusIDReg             (0x13)
#define ModBusBaudReg           (0x14)
#define PwrStatusReg            (0x15)
#define MbTimeoutReg            (0x17)

#define SerRxStatusReg          (0xfd)
#define SerTxStatusReg          (0xfe)
#define RxAvail(val, port)      (val & (1 << port))
#define TxBusy(val, port)       (val & (1 << (2*port)))
#define TxErr(val, port)        (val & (1 << (2*port+1)))

#define BaudReg(port)           ((0x100 * port) + 0xff)
#define ModeReg(port)           ((0x100 * port) + 0x100)
#define RxCtlReg(port)          ((0x100 * port) + 0x101)
#define RxErrReg(port)          ((0x100 * port) + 0x103)
#define RxQReg(port)            ((0x100 * port) + 0x106)
#define TxQueuedReg(port)       ((0x100 * port) + 0x182)
#define TxCtlReg(port)          ((0x100 * port) + 0x183)
#define TxBreakReg(port)        ((0x100 * port) + 0x184)
#define TxReqReg(port)          ((0x100 * port) + 0x186)

#define PowerBit(port)          (port)
#define TxEnable(port)          (port + 8)
#define ConfigModeCoil          (23)

#define REM_NO_PTY      0
#define REM_EVEN_PTY    2
#define REM_ODD_PTY     4
#define REM_STOP2       1
#define REM_RCV_ENBL    8
#define REM_TX_FLUSH    0x20
#define REM_RX_FLUSH    0x20
#define REM_BREAK       1

#endif  /* INCo5eLibh */
