/****************************************************************************/
/* Copyright 1995-2015 MBARI												*/
/****************************************************************************/
/* $Header: /home/cvs/oasis4/src/controller/drivers/isfet_pH.c,v 1.1 2015/01/22 18:11:35 bobh Exp $		*/
/* Summary	: Driver Routines for MBARI pH amplifier board front end for	*/
/*			  Sentron or similar analog ISFET pH sensor						*/
/* Filename : isfet_pH.c													*/
/* Author	: Bob Herlien (rah)												*/
/* Project	: Respirometer project (BRS/MRS)								*/
/* $Revision: 1.1 $															*/
/* Created	: 01/14/15														*/
/*																			*/
/* 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:													*/
/* 14jan2015, rah created from optrode driver (mrisi)						*/
/* $Log: isfet_pH.c,v $
/* Revision 1.1	 2015/01/22 18:11:35  bobh
/* Initial revision of ISFET pH driver
/*
 * 
*/
/****************************************************************************/


#include <mbariTypes.h>		/* MBARI type definitions			*/
#include <mbariConst.h>		/* MBARI constants					*/
#include <oasis.h>			/* OASIS controller definitions		*/
#include <io.h>				/* OASIS I/O definitions			*/
#include <file.h>			/* OASIS File I/O Routines			*/
#include <drvr.h>			/* OASIS driver functions			*/
#include <task.h>			/* OASIS Multitasking definitions	*/
#include <utils.h>			/* OASIS Utility routines			*/
#include <stdio.h>			/* Standard I/O functions			*/
#include <debug.h>
#include <cfxpico.h>		/* Persistor PicoDOS definitions	*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

Void pH_drv(Driver *dp);


/************************************************/
/* Parameters used:								*/
/* PARM0:  Retry count							*/
/* PARM1:  Time (secs) to first char (pwrup delay)*/
/* PARM2:  0=log to file, 1=log to oasis log,	*/
/*		   2 or greater = log to both			*/
/************************************************/

#define PH_BUFSIZE	   80			/* Orig 64; add for rec number	*/
#define DATA_FILE		"pH.txt"	/* log file for pH data			*/
#define ERR_FILE		"pH.err"	/* file for logging errors		*/


/************************************************************************/
/* Function	   : logpHData												*/
/* Purpose	   : log contents of sample buffer to a data file			*/
/* Inputs	   : Driver ptr, sample ptr									*/
/* Outputs	   : None													*/
/************************************************************************/
MLocal Void logpHData(Driver* dp, char *sample)
{
	FILE		*fd;
	time_t		now;
	struct tm	*tm_struct;
	char		time_str[64];

	/* convert the time stamp to a time structure */
	now = time(NULL);
	tm_struct = localtime(&now);

	/* create the time stamp string "mm/dd/yyyy hh:mm:ss" for the log file */
	strftime(time_str, 64, "%m/%d/%Y %H:%M:%S", tm_struct);

	/* grab the semaphore for the data file */
	takeFileSem();

	/* open the data file */
	fd = fopen(DATA_FILE, "a");

	/* check the file pointer */
	if (fd == NULL)
		dprintf("Can't open Data file\n");
	else
	{
		fprintf(fd, "%s, %s, %s\r\n", dp->drv_name, time_str, sample);
		fclose(fd);
	}

	/* release the file semaphore */
	giveFileSem();
}


/************************************************************************/
/* Function	   : samplepH												*/
/* Purpose	   : Make one attempt to get a pH sample					*/
/* Inputs	   : Driver pointer, sample buffer							*/
/* Outputs	   : Number of chars in reply								*/
/************************************************************************/
MLocal Int16 samplepH(Driver* dp, char *sampleBuf)
{
	int c;

	/* wait warmup time for first character		*/
	if ((c = xgetc_tmout(dp->drv_parms[PARM1])) == ERROR)
		return(0);

	/* Looking particularly to remove leading CR/LF, but other whitespace removed too */
	while (isspace(c))
		if ((c = xgetc_tmout(dp->drv_parms[TIMEOUT])) == ERROR)
			return(0);
	
	/* Have the first non-space char.  Get the rest */
	*sampleBuf = c;

	return(xgets_tmout(sampleBuf+1, PH_BUFSIZE-1, (Nat16)dp->drv_parms[TIMEOUT]) + 1);
}

/************************************************************************/
/* Function	   : pH_drv													*/
/* Purpose	   : Driver for MBARI pH amplifier board					*/
/* Inputs	   : Driver Pointer											*/
/* Outputs	   : None													*/
/************************************************************************/
Void pH_drv(Driver *dp)
{
	Int16		rtn, retryCnt;
	FILE		*fd;
	time_t		now;
	struct tm	*tm_struct;
	char		pH_buf[PH_BUFSIZE];

	/* grab the serial port for the sensor and power it up */
	drv_ser_port(dp);
	xflush_ser(TICKS_PER_SECOND);

	pH_buf[0] = '\0';
	retryCnt = dp->drv_parms[PARM0];
	if (retryCnt < 1)
		retryCnt = 1;
	while (retryCnt-- > 0)
	{
		drv_pwron(dp);
		rtn = samplepH(dp, pH_buf);
		drv_pwroff(dp);
		xflush_ser(TICKS_PER_SECOND);

		if (rtn > 0)
			break;
		else if (++dp->drv_cnt < 1000)
		{
			/* convert the time stamp to a time structure */
			now = time(NULL);
			tm_struct = localtime(&now);

			/* create the time stamp string "mm/dd/yyyy hh:mm:ss" for the log file */
			strftime(pH_buf, sizeof(pH_buf), "%m/%d/%Y %H:%M:%S", tm_struct);

			takeFileSem();

			if ((fd = fopen(ERR_FILE, "a")) != NULL)
			{
				fprintf(fd, "%s: %s, timeout getting data, %s\r\n",
						dp->drv_name, pH_buf,
						(retryCnt > 0) ? "retry" : "retries exceeded");
				fclose(fd);
			}

			giveFileSem();
		}
	}

	/* release the serial port */
	drv_ser_release(dp);

	if ((dp->drv_parms[PARM2] != 1) && (rtn > 0))
		logpHData(dp, pH_buf);
	
	if (dp->drv_parms[PARM2] >= 1)
	{
		if (rtn > 0)
			drvLog(dp, pH_buf, rtn);
		else
			drvLogError(dp,NO_DATA);
	}
}
