/****************************************************************************/
/* Copyright 1991-2003 MBARI												*/
/****************************************************************************/
/* $Header: /home/cvs/oasis4/src/controller/drivers/sensors.c,v 1.1 2011/10/25 22:39:21 bobh Exp $					*/
/* Summary	: Driver Routines for Default Sensors for OASIS Mooring			*/
/* Filename : sensors.c														*/
/* Author	: Robert Herlien (rah)											*/
/* Project	: OASIS Mooring													*/
/* $Revision: 1.1 $															*/
/* Created	: 02/15/91														*/
/*																			*/
/* 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:													*/
/* 15feb91 rah - created													*/
/* $Log: sensors.c,v $
/* Revision 1.1	 2011/10/25 22:39:21  bobh
/* Initial oasis4 revision
/*
/* Revision 1.2	 2009/06/18 22:38:48  bobh
/* Modifications for 2nd rev of controller board
/*
/* Revision 1.1	 2009/03/25 20:34:41  bobh
/* Initial checkin
/*
/* Revision 1.3	 2003/09/15 21:05:13  headley
/* added pswitch_drv, a simple on_off switch that takes a boolean
/* argument to either turn on the power bit (TRUE) or off (not TRUE)
/*
/* Revision 1.2	 2003/09/02 21:14:48  bobh
/* Changes for configuration by oasis.cfg file
/*
/* Revision 1.1	 2003/08/19 18:57:35  headley
/* no message
/*
 * Revision 4.4	 2001/06/19	 12:15:22  12:15:22	 oasisa (Oasis users)
 * New Repository; 6/19/2001 (klh)
 * 
 * Revision 1.1	 2001/06/19	 11:44:42  11:44:42	 oasisa (Oasis users)
 * Initial revision
 * 
 * Revision 4.0	 98/03/09  11:44:39	 11:44:39  bobh (Bob Herlien)
 * M3 Deployment of March '98, new Sat-Pac driver
 * 
 * Revision 3.5	 96/07/17  13:01:26	 13:01:26  bobh (Bob Herlien)
 * July '96 deployment of M2 with ARGOS code
 * 
 * Revision 3.4	 96/06/18  15:24:20	 15:24:20  bobh (Bob Herlien)
 * June '96 deployment of M1
 * 
 * Revision 3.3	 95/04/13  13:46:54	 13:46:54  hebo (Bob Herlien)
 * Drifter Deployment for Coop (flip) cruise
 * 
 * Revision 3.2	 95/04/11  14:03:26	 14:03:26  hebo (Bob Herlien)
 * Drifter Deployment on IronEx
 * 
 * Revision 3.0	 95/02/21  18:42:42	 18:42:42  hebo (Bob Herlien)
 * February '95 Deployment
 * 
 * Revision 2.6	 94/09/16  14:35:03	 14:35:03  hebo (Bob Herlien)
 * Change CTD to use "TS" for opto-isolated CTD interface
 * 
 * Revision 2.5	 94/01/11  17:41:10	 17:41:10  hebo (Bob Herlien)
 * Fixed bug in "getlog", changed PRR format
 * 
 * Revision 2.4	 93/10/29  18:48:16	 18:48:16  hebo (Bob Herlien)
 * November 1993 Deployment
 * 
 * Revision 2.3	 93/10/12  08:50:20	 08:50:20  hebo (Bob Herlien)
 * Oct '93 Deployment of M2
 * 
 * Revision 2.0	 92/08/26  10:32:18	 10:32:18  hebo (Bob Herlien)
 * August 1992 Deployment
 * 
 * Revision 1.3	 92/03/05  14:23:08	 14:23:08  hebo (Bob Herlien 408-647-3748)
 * New defaults, restart check, perm power stuff, analog command, gps changes
 * 
*/
/****************************************************************************/

#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 <list.h>						/* OASIS Linked List library		*/
#include <sem.h>						/* OASIS Semaphore library			*/
#include <task.h>						/* OASIS task dispatcher			*/
#include <log.h>						/* OASIS data logging definitions	*/
#include <drvr.h>						/* OASIS driver functions			*/
#include <utils.h>						/* OASIS Utility routines			*/
#include <sensors.h>					/* OASIS sensor module				*/
#include <debug.h>

#include <string.h>						/* Std C string library				*/


/************************************************************************/
/* Function	   : get_analog												*/
/* Purpose	   : Read analog value for one or more A/D ports			*/
/* Inputs	   : A/D port, number of ports, number of samples to average*/
/*				 ticks to delay between samples, buffer to put results	*/
/* Output	   : None													*/
/* Comments	   : Used by analog_drv() and analog() user function		*/
/*				 Returns A/D values in array result[]					*/
/************************************************************************/
		Void
get_analog(Nat16 port, Nat16 nports, Nat16 samples, Nat16 *result)
{
  Reg Nat16		i;						/* Temps OK to destroy by task sw*/
  Nat16			cnt;					/* Temps we need between task switch*/
  Nat32			ad_accum[NAD_PORTS];	/* Accumulator for averaging		*/

  memset(ad_accum, 0, sizeof(ad_accum)); /* Zero accumulator buffer			*/
  if (port >= NAD_PORTS)
	return;

  io_AtoDPwrOn(port);					/* Turn on A/D chip and +5 power	*/
  task_delay(30);

  if ( (port + nports) > NAD_PORTS )
	nports = NAD_PORTS - port;

  for ( cnt = 0; cnt < samples; cnt++ )
  {										/* Loop to read A/D channels		*/
	task_delay( 1 );					/* Delay between iterations			*/

	for ( i = 0; i < nports; i++ )
	  ad_accum[i] += io_atod(port +i);	/* Read nports chans & accumulat*/
  }

  io_AtoDPwrOff();						/* Turn off Analog enable & chip	*/

  for ( i = 0; i < nports; i++ )		/* Calculate average values */
	result[i] = (Nat16)(ad_accum[i] / samples);

} /* get_analog() */


/************************************************************************/
/* Function	   : analog_drv												*/
/* Purpose	   : Driver for General Purpose Analog Sensor				*/
/* Inputs	   : Driver Pointer											*/
/* Outputs	   : None													*/
/* Comments	   : Used for Pressure sensor, batteries, PARs				*/
/*				 Turns on power, waits for device to stabilize for		*/
/*				 TIMEOUT seconds.  Then reads channels PARM0 to			*/
/*				 PARM0 + PARM1 (total of PARM1 channels), and averages	*/
/*				 PARM2 readings, taken each tick.  Averages accumulated */
/*				 as 32 bits, then divided by PARM2 and stored as 16 bits*/
/************************************************************************/
		Void
analog_drv( Driver *dp )
{
  Nat16			nports;
  Nat16			ad_sample[NAD_PORTS];	/* A/D samples				*/

  drv_pwron( dp );						/* Turn on device				*/

  delay_secs( dp->drv_parms[TIMEOUT] );

  nports = dp->drv_parms[PARM1];

  get_analog(dp->drv_parms[PARM0], nports, dp->drv_parms[PARM2], ad_sample);

  drvLogWords( dp, ad_sample, nports );

  drv_pwroff( dp );						/* Turn off device				*/

} /* analog_drv() */


/************************************************************************/
/* Function	   : onoff_drv												*/
/* Purpose	   : Simple driver to turn a device on and off				*/
/* Inputs	   : Driver Pointer											*/
/* Outputs	   : None													*/
/************************************************************************/
		Void
onoff_drv( Driver *dp )
{
  drv_pwron( dp );						/* Turn on device				*/
  delay_secs ( dp->drv_parms[TIMEOUT] );
  drv_pwroff( dp );						/* Turn off device				*/

} /* onoff_drv() */


/************************************************************************/
/* Function	   : pswitch_drv											*/
/* Purpose	   : Another (non-timed) driver to turn a device on and off */
/* Inputs	   : Driver Pointer											*/
/*				 drv_usrparm=TRUE:on ELSE:off							*/
/* Outputs	   : None													*/
/************************************************************************/
		Void
pswitch_drv( Driver *dp )
{
  if(dp->drv_usrparm == TRUE)
	drv_pwron( dp );					/* Turn on device				*/
  else
	drv_pwroff( dp );					/* Turn off device				*/

} /* pswitch_drv() */

