/************************************************************************/
/* Copyright 2009 MBARI													*/
/************************************************************************/
/* Summary	: Definitions for remote serial and power ports for Respiromters*/
/* Filename : remote.h													*/
/* Author	: Robert Herlien (rah)										*/
/* Project	: Benthic/Midwater Respirometers (BRS/MRS)					*/
/* Revision: 1.0														*/
/* Created	: 04/07/2009												*/
/*																			*/
/* 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:												*/
/* 07apr2009 rah - created												*/
/************************************************************************/

#ifndef INCremoteh
#define INCremoteh		1

#include <FreeRTOS.h>
#include <task.h>
#include <modbus.h>
#include <list.h>
#include <sem.h>


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

#define VIRT_SER_PORTS	32				/* Up to 32 virtual serial ports*/
#define VIRT_PWR_PORTS	32				/* Up to 32 virtual power ports */
#define VIRT_OUT_PORTS	64				/* Up to 64 virtual output ports*/
#define REMOTE_IDS		32				/* Up to 32 chamber controllers */
#define CHAMBER_SER_PORTS 3				/* Num serial ports on chamber ctrlr*/
#define CHAMBER_PWR_PORTS 3				/* Num pwr ports on chamber ctrlr*/
#define CHAMBER_OUT_PORTS 8				/* Num out ports on chamber ctrlr*/
#define SERBUF_SIZE		240				/* Size of serial buffer		*/		
#define SERREG_SIZE		(SERBUF_SIZE/2)
#define RNAME_SIZE		32				/* Size (chars) of remote name	*/

#define DFLT_MULT		(1.0)
#define DFLT_SURGE		500


typedef enum					/****************************************/
{								/* State of RemSerPort					*/
	PortUnused = 0,				/* Nobody's using this entry			*/
	PortAssigned,				/* Assigned via cfg file to virt ser port*/
	PortInUse					/* In use via remSerOpen()				*/
} RemSerState;					/****************************************/

typedef struct					/****************************************/
{								/* Remote Serial Port					*/
	RemSerState assigned;		/* Assigned to virt ser port or in use	*/
	Nat16		bus;			/* ModBus bus							*/
	Nat16		slave;			/* ModBus slave							*/
	Nat16		port;			/* Serial port on the slave				*/
	Semaphore	sem;			/* MUTEX semaphore to access serial port*/
	ModBusHandle handle;		/* Handle to the ModBus bus				*/
	Byte		*bufPtr;		/* Ring buffer output ptr				*/
	Nat16		bufChars;		/* Number of chars valid in buf			*/
	Nat16		rxQueued;		/* RxQueued reg. MUST be immed b4 buf	*/
	Byte		buf[SERBUF_SIZE]; /* Buffer for serial chars			*/
	char		name[RNAME_SIZE]; /* Name								*/
} RemSerPort;					/****************************************/

typedef RemSerPort *RemSerHandle;

typedef struct					/****************************************/
{								/* Used for Remote Power & Output Ports */
	MBool		assigned;		/* Assigned to virt pwr port number		*/
	Nat16		bus;			/* ModBus bus							*/
	Nat16		slave;			/* ModBus slave							*/
	Nat16		coil;			/* Coil number on slave for power bit	*/
	MBool		coilState;		/* State coil is in						*/
	Flt32		multiplier;		/* Time multiplier for calibration		*/
	Nat32		surgeDelayMs;	/* Surge delay in milliseconds			*/
	char		name[RNAME_SIZE]; /* Name								*/
} RemIOPort;					/****************************************/

typedef struct					/****************************************/
{								/* Used keep track of chamber controllers*/
	MBool		assigned;		/* Active								*/
	Nat16		bus;			/* ModBus bus							*/
	Nat16		slave;			/* ModBus slave							*/
} RemID;						/****************************************/


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

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

/* Register and Coil Definitions		*/
#define SerStatusReg			0xff
#define TxBusy(val, port)		(val & (1 << (4*port)))
#define RxAvail(val, port)		(val & (1 << (4*port+1)))
#define TxErr(val, port)		(val & (1 << (4*port+2)))

#define BaudReg(port)			(0x100 * (port + 1))
#define ModeReg(port)			((0x100 * port) + 0x101)
#define RxCtlReg(port)			((0x100 * port) + 0x102)
#define RxQReg(port)			((0x100 * port) + 0x107)
#define TxQueuedReg(port)		((0x100 * port) + 0x183)
#define TxCtlReg(port)			((0x100 * port) + 0x184)
#define TxBreakReg(port)		((0x100 * port) + 0x185)
#define TxReqReg(port)			((0x100 * port) + 0x187)
#define OutputBit(port)			(port + 1)
#define PowerBit(port)			(port + 9)
#define TxEnable(port)			(port + 12)
#define BlinkyDebugCoil			(15)
#define BlinkyStateCoil			(16)

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

/****************************************/
/* Function Declarations				*/
/****************************************/

Void			initRemoteLib(Void);
Void			takeRemoteSem(Void);
Void			giveRemoteSem(Nat32 delay_ms);
Int16			findRemPwrPort(char *s);
Int16			findRemOutputPort(char *s);
RemSerHandle	getVirtSerPort(Nat32 virtPort);
RemSerHandle	findRemSerHandle(Nat16 bus, Nat16 slave, Nat16 port);
RemSerHandle	remSerOpen(Nat16 bus, Nat16 slave, Nat16 port, MBool async);
Errno			openRemSerHandle(RemSerHandle rsh, MBool async);
Errno			remSerClose(RemSerHandle rsh);
Errno			remOpenVirtSer(Nat32 virtPort, MBool async);
Errno			remCloseVirtSer(Nat32 virtPort);
Errno			remSerInit(RemSerHandle rsh, Nat32 baud, Nat32 mode);
Errno			remVirtSerInit(Nat32 virtPort, Nat32 baud, Nat32 mode);
Errno			assignVirtSerial(char *name, Nat32 virtPort, Nat16 bus, Nat16 slave,
								 Nat16 port, Flt32 mult, Nat32 surgeDelay);
Errno			assignVirtPwr(char *name, Nat32 virtPort, Nat16 bus, Nat16 slave,
							  Nat16 coil, Flt32 mult, Nat32 surgeDelay);
Errno			assignVirtOutput(char *name, Nat32 virtPort, Nat16 bus, Nat16 slave,
								 Nat16 coil, Flt32 mult, Nat32 surgeDelay);
Errno			remPower(Nat32 pwrnum, MBool onoff);
Errno			remOutput(Nat32 pwrnum, MBool onoff);
Errno			remIsPowerOn(Nat16 bus);
Errno			remIsOutputOn(Nat16 bus);
Errno			remOff(Void);
Errno			remOutPulseOn(Nat32 bitNum, Flt32 sec);
Errno			remOutPulseOnByVolume(Nat32 bitNum, Flt32 vol);
Errno			remOutPulseOff(Nat32 bitNum, Flt32 sec);
Nat32			remSerRead(RemSerHandle rsh, char *buffer, Nat32 len);
Nat32			remSerWrite(RemSerHandle rsh, const char *buffer, Nat32 len);
Errno			remSerDrain(RemSerHandle rsh, Nat32 tmout);
Errno			remSerIFlush(RemSerHandle rsh);
Errno			remSerOFlush(RemSerHandle rsh);
Int16			remSerRxCount(RemSerHandle rsh);
Errno			remSerBreak(RemSerHandle rsh, Nat16 breakTime);
Void			remTaskExit(TaskHandle_t *td);
Void			remCreateErrorThread();

#endif	/* INCremoteh */
