/****************************************************************************/
/* Copyright 2005 MBARI.													*/
/* MBARI Proprietary Information. All rights reserved.						*/
/****************************************************************************/
#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 <sysLog.h>
#include <sensors.h>
#include <cfxpico.h>		/* Persistor PicoDOS definitions	*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "env.h"			/* OASIS serial I/O definitions			*/

#define DATA_FILE		"env.txt"	/* log file for enviornmental data		*/

#define VOLTAGE_CHAN	0			/* Anlog channel 0 for Battery volts	*/
#define VOLTAGE_SAMPLES 100			/* Number of samples to average			*/

Extern Nat32 lowVoltLimit;	 /* Contoller low voltage reset */
MLocal EnvSample lastSample;

/* function prototypes */
MLocal Int16 sampleEnv(Driver* dp, EnvSample* sample);
MLocal Void logEnvData(EnvSample* sample);

/************************************************************************/
/* Function	   : logEnvData												*/
/* Purpose	   : log contents of environmental cample to a data file	*/
/* Inputs	   : Environmental sample									*/
/* Outputs	   : None													*/
/************************************************************************/
MLocal Void logEnvData(EnvSample* sample)
{
	FILE *fd;
	char time_str[64];
	struct tm *tm_struct;
 
	/* convert the time stamp to a time structure */
	tm_struct = localtime(&sample->time_stamp);

	/* 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, %6.2f, %6.2f, %6.2f\r\n", 
				time_str, sample->volt, sample->temp, sample->pres);
		/* close it !*/
		fclose(fd);
	}
  
	/* release the file semaphore */
	giveFileSem();
}


/************************************************************************/
/* Function	   : lastEnvSample											*/
/* Purpose	   : get the last environmental sample						*/
/* Inputs	   : Driver pointer, EnvSample pointer, verbose flag		*/
/* Outputs	   : OK or ERROR											*/
/************************************************************************/
Int16 lastEnvSample(Driver* dp, EnvSample* sample, MBool verbose)
{
#pragma unused(dp)
	
	char time_str[64];
	struct tm *tm_struct;
	
/* grab last sample semaphore */
	memcpy(sample, &lastSample, sizeof(EnvSample));
/* release last sample semaphore */

	/* print the optrode sample to the console */
	if ( verbose )
	{
		xprintf("volt : %-6.2f VDC\n", sample->volt);
		xprintf("temp : %-6.2f C\n", sample->temp);
		xprintf("pres : %-6.2f PSI\n", sample->pres);

		/* convert the time stamp to a time structure */
		tm_struct = localtime(&sample->time_stamp);

		/* 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);

		xprintf("time : %s\n", time_str);
	}

	return OK;
}


/************************************************************************/
/* Function	   : sampleEnv												*/
/* Purpose	   : Sample BRS environmental sensors						*/
/* Inputs	   : Driver pointer, EnvSample pointer						*/
/* Outputs	   : OK or ERROR											*/
/************************************************************************/
#define VOLT_CHAN	0
#define TEMP_CHAN	1
#define PRES_CHAN	2

Int16 sampleEnv(Driver* dp, EnvSample* sample)
{
#pragma unused(dp)
	
	Nat16 data[3];
	float tmp_flt;
	
	/* time stamp the sample */
	sample->time_stamp = time(NULL);
	
	/* gead volts, pressure, temp */
	get_analog(0, 3, 10, data);
/*
	AD0	 batt volts
	0-4095 = 0-17.5 vdc

	AD1	 can temp
	0-4095 = 0-2.5 vdc = 10mv/deg C + 600mv	 

	example 20 Deg = (20deg x 10mv = 200mv) + 600mv = 800mv

	AD2	 can pressure
	0-4095 = 0-2.5 vdc
	2.9 - 36.3 PSI = .1 - 2.45 vdc
*/

#define VOLT_GAIN	17.5
#define VOLT_OFFSET 0.0
	
#define TEMP_GAIN	100.0	
#define TEMP_OFFSET -60.0
	
#define PRES_GAIN	14.21
#define PRES_OFFSET 1.48
	
	/*****************************/ 
	/*** calculate can voltage ***/ 
	/*****************************/ 
	tmp_flt = (float)data[VOLT_CHAN];
	
	/* covert to volts */
	tmp_flt /= 4095.0;
	sample->volt = ((tmp_flt * VOLT_GAIN) + VOLT_OFFSET);

	/*********************************/ 
	/*** calculate can temperature ***/ 
	/*********************************/ 
	tmp_flt = (float)data[TEMP_CHAN];
	
	/* covert to volts */
	tmp_flt /= 4095.0;
	tmp_flt *= 2.5;

	/* apply temperature calibration values */
	sample->temp = ((tmp_flt * TEMP_GAIN) + TEMP_OFFSET);

	/******************************/ 
	/*** calculate can pressure ***/ 
	/******************************/ 
	tmp_flt = (float)data[PRES_CHAN];
	
	/* covert to volts */
	tmp_flt /= 4095.0;
	tmp_flt *= 2.5;

	/* apply pressure calibration values */
	sample->pres = ((tmp_flt * PRES_GAIN) + PRES_OFFSET);
	
/* grab last sample semaphore */
	
	/* copy sample to last sample buffer */
	memcpy(&lastSample, sample, sizeof(EnvSample));

/* release last sample semaphore */

	return OK;
}

/************************************************************************/
/* Function	   : checkBatteryVolts										*/
/* Purpose	   : Read analog channel to check battery voltage break to	*/
/*				 Picodos if below threshold								*/
/* Inputs	   : None													*/
/* Outputs	   : None													*/
/************************************************************************/
MLocal Void checkBatteryVolts()
{
	Nat16 volts; 
	
	/* Read Analog Batery Voltage */
	get_analog(VOLTAGE_CHAN, 1, VOLTAGE_SAMPLES, &volts);
	
	/* If Battery volts is lower than 12.5v */
	if ( volts < ((Nat16)lowVoltLimit) ) 
	{
	   sysLogPrintf("env driver shutting down system, battery count = %d\n",
					volts);
	   dprintf("counts = %d\n", volts);
	   io_power(0L);					/* Power-off the world! */
	   PZCacheFlush(DRIVE);
	   BIOSResetToPicoDOS();	/* Jump to picoDOS */  
	}  
}

/************************************************************************/
/* Function	   : envDrv													*/
/* Purpose	   : Driver BRS environmental sensors temp, battery, and	*/
/*				 pressure												*/
/* Inputs	   : Driver Pointer																*/
/* Outputs	   : None																			*/
/************************************************************************/
Void envDrv(Driver *dp)
{
	EnvSample sample;
	
	checkBatteryVolts();   
	sampleEnv(dp, &sample);
	
	/* if PARM0 is set use subsampling */
	if ( dp->drv_parms[PARM0] > 0 )
	{
		if ( (dp->drv_cnt % dp->drv_parms[PARM0]) == 0 )
			logEnvData(&sample);
	}
	else
	{
		logEnvData(&sample);
	}

	/* increment cycle counter */
	++dp->drv_cnt;
}
