/************************************************************************/
/* Copyright 2009-2016 MBARI											*/
/************************************************************************/
/* Summary	: Definitions for ModBus for Oasis5							*/
/* Filename : modbus.h													*/
/* Author	: Robert Herlien (rah)										*/
/* Project	: Oasis5 Mooring Controller									*/
/* Revision: 1.0														*/
/* Created	: 08/31/2016												*/
/*																			*/
/* 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 Oasis4 version								*/
/* 31aug2016 rah - created Oasis5 version from Oasis4 version			*/
/************************************************************************/

#ifndef INCmodbush
#define INCmodbush		1

#include <mbariTypes.h>
#include <oasis.h>
#include <timer.h>
#include <FreeRTOS.h>					/* FreeRTOS definitions				*/
#include <task.h>						/* FreeRTOS/include task.h			*/


/********************************/
/* Misc Defines					*/
/********************************/

#define BACKUP_MODLOG_FILES		5

#define DEFAULT_BAUD			115200
#define DEFAULT_MODE			(NO_PTY | BIT8 | STOP1)
#define DEFAULT_SER_TMOUT		(TICKS_PER_SECOND/10)
#define RCV_TMOUT				(TICKS_PER_SECOND/2)
#define DEFAULT_TURNAROUND_USECS 500
#define MIN_INTERMSG_USECS		1750
#define INTERMSG_RTC_TICKS		70				/* 1.75 ms in 40 khz ticks */
#define MODSEM_TMOUT       (2*TICKS_PER_SEC)

#define MAX_MSG_LEN				256
#define BASE_QUERY_LEN			6
#define BASE_RESPONSE_LEN		5
#define MAX_BITS				2000
#define MAX_REGS				125
#define IDENT					0x3cf1
#define MAX_SLAVES				16


/****************************************************************/
/* Flag bits													*/
/* Bits 0,1 define power to Modbus when no one has bus open		*/
/****************************************************************/
#define PWROFF_BITS		   3
#define KEEP_PWR		   0	/* 00 = Keep pwr on, even after close	*/
#define PWROFF_IF_NO_PWR   1	/* 01 = Pwr off on close if no pwr bits set*/
#define PWROFF_IF_NO_PWRIO 2	/* 10 = Pwr off on close if no pwr or I/O bits*/
#define PWROFF_ALWAYS	   3	/* 11 = Pwr off on close despite pwr or I/O bits*/

typedef enum
    {MB_IDLE = 0, MB_SEND, MB_WAIT_SENT, MB_WAIT_RCV, MB_RCV} MB_State;

typedef enum
	{MB_UNASSIGNED=0, MB_SER, MB_SPI} ModBusType;


typedef struct					/****************************************/
{								/* Struct for data I/O on Modbus		*/
	MB_State	state;			/* For state transitions on snd/rcv		*/
	Port_t		port;			/* Physical port, serial or SPI			*/
	Nat16		sndLen;			/* Length of data received in sndBuf	*/
	Nat16		sndPos;			/* For use during I/O					*/
	Nat16		rcvLen;			/* Length of data received in rcvBuf	*/
	TaskHandle_t ioTask;		/* Task performing I/O (for Notify)		*/
	Byte		sndBuf[MAX_MSG_LEN];
	Byte		rcvBuf[MAX_MSG_LEN];
} ModBusIO;						/****************************************/

typedef struct					/****************************************/
{								/* Struct to describe one Modbus bus	*/
	ModBusType	busType;		/* Serial or SPI ModBus?				*/
	Port_t		port;			/* Physical port, serial or SPI			*/
	Nat32		flags;			/* Flag bits							*/
	Nat32		baud;			/* Baud rate to use						*/
	Nat32		sermode;		/* Serial mode, default N81				*/
	Nat32		surgeDelayMs;	/* Surge delay in msecs for power on	*/
	Int32		openCount;		/* Number of times opened				*/
	MBool		busIsPowered;	/* TRUE if bus is powered				*/
	Nat16		ident;			/* Ident field to catch errors			*/
								/* Send and receive buffers				*/
	Nat32		totMsgs;		/* Total message count					*/
	Nat32		totErrs;		/* Total error count for this bus		*/
	volatile ModBusIO *ioBuf;	/* I/O buffers							*/
} ModBusStruct;					/****************************************/

typedef ModBusStruct *ModBusHandle;


/********************************/
/* Function Codes				*/
/********************************/
#define FC_READ_COILS			 1
#define FC_READ_INPUTS			 2
#define FC_READ_HOLDING_REGS	 3	
#define FC_READ_INPUT_REGS		 4
#define FC_WRITE_ONE_COIL		 5
#define FC_WRITE_ONE_REG		 6
#define FC_WRITE_MULT_COILS		15
#define FC_WRITE_MULT_REGS		16
#define FC_REPORT_SLAVE_ID		17
#define FC_WRITE_READ_MULT_REGS 23
#define FC_READ_FIFO_QUEUE		24


/********************************/
/* Exception Return Codes		*/
/* OK defined as 0 in oasis.h	*/
/********************************/
/* Exception codes defined by standard */
#define ILLEGAL_FUNCTION		-1
#define ILLEGAL_DATA_ADDRESS	-2
#define ILLEGAL_DATA_VALUE		-3
#define SLAVE_DEVICE_FAILURE	-4
#define ACKNOWLEDGE				-5
#define SLAVE_DEVICE_BUSY		-6
#define NEGATIVE_ACKNOWLEDGE	-7
#define MEMORY_PARITY_ERROR		-8
#define GATEWAY_PROBLEM_PATH	-10
#define GATEWAY_PROBLEM_TARGET	-11

/* Local failure codes			*/
#define SEND_FAILURE			-12
#define COMM_TIME_OUT			-13
#define INVALID_CRC				-14
#define ILLEGAL_RESPONSE		-15
#define INVALID_EXCEPTION_CODE	-16
#define ILLEGAL_PORT			-17
#define DATA_SIZE_ERROR			-18
#define PORT_ERROR				-19
#define RCV_TIMEOUT				-20
#define SLAVE_ID_MISMATCH		-21
#define FUNC_CODE_MISMATCH		-22
#define PORT_CONFLICT			-23				/* Conflict in assigning port		*/
#define PORT_IN_USE				-24

#define NUM_ERR_CODES	24


#endif	/* INCmodbush */
