/******************************************************************************
// Hydraulic/Vent prototypes for Spray2008 SPI control
// CS assignment = CS_HYD is done in spi_cmd.h
// created Dec2008
//
// 0902 Jan2010, max_amp stored to hyd->max_amp in scaled units.
// 092.5 feb11, increased vent time
// 0903.5 nov11 add debug menu
// 0904.1 dec14 service_wdog when watching the pump.
// 0904.3 jun15 adding auto-degas (adg) functions.
//
//==== Future Expansion =======================================================
//
//	1. 
//  2. simplify the menu and create a debug menu for other stuff
//
*****************************************************************************/
#include	<cfxbios.h>		// Persistor BIOS and I/O Definitions
#include	<cfxpico.h>		// Persistor PicoDOS Definitions

#include	<assert.h>
#include	<ctype.h>
#include	<errno.h>
#include	<float.h>
#include	<limits.h>
#include	<locale.h>
#include	<math.h>
#include	<setjmp.h>
#include	<signal.h>
#include	<stdarg.h>
#include	<stddef.h>
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<time.h>

#include	<dirent.h>		// PicoDOS POSIX-like Directory Access Defines
#include	<dosdrive.h>	// PicoDOS DOS Drive and Directory Definitions
#include	<fcntl.h>		// PicoDOS POSIX-like File Access Definitions
#include	<stat.h>		// PicoDOS POSIX-like File Status Definitions
#include	<termios.h>		// PicoDOS POSIX-like Terminal I/O Definitions
#include	<unistd.h>		// PicoDOS POSIX-like UNIX Function Definitions

#include    "cf2_qsm332.h"
#include    "spi_cmd.h"
#include    "gpio_mux.h"
#include    "dat_fnx.h"
#include    "pump.h"
#include    "setup.h"
#include    "lifo.h"
#include    "sbd.h"
#include    "sbe.h"
 
// globals
extern char   Verbose;  // switch for displaying more info
extern char   IRQ_Flag; // interrupt flag: says what caused the interrupt
extern short  iparam [ MAX_PARAM ]; // global parameter settings
extern struct all_param all;

//--- local prototypes -------------------------------------------
void   get_user_setup ( void  );
void   hyd_main_menu  ( void  );
void   hyd_d_menu     ( void  );
void   hyd_debug      ( void  );
short  watch_d_pmp    ( short tmax, short take_dat );
void   adg_bench_test ( void  );

//*****************************************************************************
//*****************************************************************************
void hyd_flash_menu  ( struct spi_param *ss ) //*******************************
{ // display flash options in the GPIO msp430
  short  nval, ncnts, n1, n2;


  cprintf(" Give flash-eeprom addr to update \n" );

  cprintf(" %2d : MSP430 Board Serial Number \n", F_SER_NO );

  cprintf(" %2d : Hydraulic Min Pump Time (s) \n", F_TMIN );
  cprintf(" %2d : Hydraulic Max Pump Time (s) \n", F_TMAX );
  cprintf(" %2d : Hydraulic Max Oil-Sense a/d# \n", F_OIL_MAX );
  cprintf(" %2d : Max current (.01A) before shutting off motor\n", F_AMP_MAX );
  cprintf(" %2d : Amps*100  = (COEF * counts/100)\n", F_H_C2U_I );
  cprintf(" %2d : Volts*100 = (COEF * counts/100)\n", F_H_C2U_V );
  //cprintf(" %2d : True #s per Hyd430 1000s guess\n",    F_1000S );
  
  cprintf(" Give address \n");
  n1 = get_num(&nval);
  if (n1 ==1 )
  {  
     cprintf(" Give the new value to store \n");
     n2 = get_num(&ncnts);
  }
  
  if (n1 ==0  || n2 ==0 )
  { cprintf(" ILLEGAL VALUE \n");
    return;
  }
  // else proceed
  
   switch ( nval ) 
   { // make sure it is legal
     case F_SER_NO : 
     case F_TMIN : 
     case F_TMAX : 
     case F_OIL_MAX : 
     case F_AMP_MAX : 
     case F_H_C2U_I : 
     case F_H_C2U_V : 
     //case F_1000S : 

     
     // these are all legal values
     
       spi_flash_write( nval, ncnts, ss );
       break;

     default : cprintf("ILLEGAL address \n");

    } // end switch
         
  
  return ;
}//****************************************************************************

short  init_hyd_iparam ( void ) //*********************************************
{ // read in the hydraulic module flash data block,
  // and assign the iparam[] arrays accordingly
  short rstat;
  
  //rstat = rqst_flash_0 ( CS_HYD );
  rstat = spi_cmd_ver  ( CS_HYD );
  if (rstat==0)
    display_hydflash ();
  else cprintf("%d Error getting MSP430 HYD flash \n", rstat );
  
  return ( rstat );
} //***************************************************************************

void hyd_set_default  ( void ) //**********************************************
{ // apr11: set gpio flash values to default
  // this is used for a brand-new board
  short  nval, n1, tmso = 300;
  struct spi_param *ss;
  
  ss = all.sspi;
  setup_spi ( CS_HYD, ss ); // re-init the SPI info


  cprintf(" Give New MSP430 HYD serial # \n");
  n1 = get_num(&nval);
  if (n1 !=1  || nval<1 || nval>32767 )
  { cprintf(" ILLEGAL s/n\n");
    return;
  }
  // else proceed
  spi_flash_write( F_SER_NO  , nval, ss );
  DelayMilliSecs(tmso);
  spi_flash_write( F_TMIN    ,  380, ss ); // Hydraulic Min Pump Time (s)
  DelayMilliSecs(tmso);
  spi_flash_write( F_TMAX    ,  600, ss ); // Hydraulic Max Pump Time (s) 
  DelayMilliSecs(tmso);
  spi_flash_write( F_OIL_MAX , 2000, ss ); // Hydraulic Max Oil-Sense a/d#
  DelayMilliSecs(tmso);
  spi_flash_write( F_AMP_MAX ,  300, ss ); // Max current (.01A)
  DelayMilliSecs(tmso);
  spi_flash_write( F_H_C2U_I ,   61, ss ); // Amps*100  = (COEF * counts/100)
  DelayMilliSecs(tmso);
  spi_flash_write( F_H_C2U_V,    67, ss ); // Volts*100 = (COEF * counts/100)
  DelayMilliSecs(tmso);

  // display contents
  init_hyd_iparam(  );
         
  
  return ;
}//****************************************************************************


void display_hydflash  ( void  ) //********************************************
{ // display flash eeprom values
  // first flash data (addr=0 offset in MSP430) is at sdat[2]
  // msp430 is lsb, msb convention
  short sn, ver, tmin, tmax, oil, amp, c2i, c2v, t1000;
  short *w, val=0, i=0;
  struct spi_param *ss;
  
  ss = all.sspi;

  ver = ss->sdat[1]; // code-compilation version
  w = ( short * ) &( ss->sdat[2] ); // flash data starts at sdat[2]

  
  sn   = w[i++]; // serial #
  tmin = w[i++]; // min pump time
  tmax = w[i++]; // max pump time
  oil  = w[i++]; // max oil a/d val before shutting off
  amp  = w[i++]; // max amps before shutting off
  c2i  = w[i++]; // cnts 2 amps conversion factor
  c2v  = w[i++]; // cnts 2 volts conversion factor
  t1000= w[i++]; // true #s per 1000s cnts (ti calibration)

  iparam [ MA_hyd_sn  ] = sn;
  iparam [ MA_hyd_ver ] = ver;
  iparam [ IA_oil_max ] = oil;
  iparam [ MA_hyd_c2i ] = c2i;
  iparam [ MA_hyd_c2v ] = c2v;

  // tmin is already set by the .CFG, so do NOT update iparam
  // tmax is already set by the .CFG, so do NOT update iparam
  // oil  is already set by the .CFG, so do NOT update iparam

    cprintf("MSP430 EEPROM settings for the Hydraulics Module\n");
    
  cprintf(" %4d : Hyd MSP430 Board Serial Number \n",     sn );
  cprintf(" %4d : Hyd MSP430 Firmware Version # \n",     ver );
  cprintf(" %4d : Min pump time (s) \n",     tmin );
  cprintf(" %4d : Max pump time (s) \n",     tmax );
  cprintf(" %4d : Max oil sense a/d \n",     oil );
  cprintf(" %4d : Max pump current (0.01a) to allow \n",  amp );
  cprintf(" %4d : Amps*100  = cnts * F_C2U_I / 100 \n",   c2i );
  cprintf(" %4d : Volts*100 = cnts * F_C2U_V / 100 \n",   c2v );
  //cprintf(" %4d : True #s per Hyd430 1000s guess \n",   t1000 ); //feb09, not needed
  
  return ;
}//****************************************************************************

void  display_hyd_query (short rstat, struct spi_param *ss ) //****************
{ // display the query results
  // rstat is passed along so it can be displayed in parse_query_ss
  // if Verbose is on

  short cmd;
  
  cmd = parse_query_ss(rstat, ss);
  
  switch ( cmd ) //====================================================
  { // display results accordingly
    case 0           : break;  // not valid!
    case SPI_VER     : display_ver (  );
                   break;

    case AUX_PWR    : display_hyd_pwr ( ss );
                   break;

    case GO_PUMP    : 
                   display_pump    ( ss ); // and display
                   break;

    case SPI_MEASURE : display_general_ad12 (  ss );
                   break;

    case FL_BLOCK_RD : if (Verbose) display_dump ( ss );
                         
                   break;
                   
    default          : display_dump ( ss );
                   break;
  } //=================================================================
  
  
  return;
} //***************************************************************************

void display_hyd_pwr  ( struct spi_param *ss ) //******************************
{ // display the power switch info
  short val, off, stat;
  
  val = ss->sdat[1]; // sensor channel switched
  off = ss->sdat[2]; // whether turned on or off
  stat= ss->sdat[3]; // whether it was successful
  
  printf("Hydraulic Sensor ID %3d was turned ",val);
  if (off) printf("OFF"); else printf("ON");
  if (stat>0) printf(" OK"); else printf(" FAILED");
  printf("\n");
  
  return ;
} //***************************************************************************

void   get_user_setup ( void  ) //*********************************************
{ // get the user-desired values and store to RAM
	short nval, n, tmin, tmax, oil_limit, imax;

	cprintf("   give minimum pump time \n");
	n = get_num(&nval);
	if (n==1) tmin = nval;
	else      tmin = 0;
	iparam [ IA_min_pump ] = tmin;
	
	cprintf("   give maximum pump time \n");
	n = get_num(&nval);
	if (n==1) tmax = nval;
	else      tmax = 600;
	iparam [ IA_max_pump ] = tmax;
	
	cprintf("   give oil sense trigger value \n");
	n = get_num(&nval);
	if (n==1) oil_limit = nval;
	else      oil_limit = 2000;
	iparam [ IA_oil_max ] = oil_limit;
	
	cprintf("   give max pump current (a/d counts) \n");
	n = get_num(&nval);
	if (n==1) imax = nval;
	else      imax = 2000;
	iparam [ IA_max_amp ] = imax;
	
	return;
}//****************************************************************************

short       setup_pump  ( void ) //********************************************
{ // initialize the pump parameters
// these are stored in eeprom in the hydraulic module msp430.
// if these values agree already with those, eeprom is not rewritten,
// thus saving write cycles.
  short rstat, i, *w;
  struct spi_param *ss;
  
  ss = all.sspi;  //point to the spi struct
  setup_spi ( CS_HYD, ss ); // re-init the SPI info
	
	//===================================================================
	
	
	w = ( short*) &(ss->mdat[0]); // point to start
	i=1; // index used to write out shorts into mdat: skip first 2 bytes
	ss->mdat[0] = SETUP_PUMP; // dat[0] = cmd byte
	ss->mdat[1] = 0;    // place-holder, could be sub-cmd??
	
	w[i++] = iparam [ IA_min_pump ]; // min pump time
	w[i++] = iparam [ IA_max_pump ]; // max pump time
	w[i++] = iparam [ IA_oil_max  ]; // oil a/d value to trigger shutting off pump
	w[i++] = iparam [ IA_max_amp ];  // max pump current, 0.01A
	
	ss->nbyte = 2*i; // total # of bytes

	rstat = spi_try_send ( ss, 3 ); // send the command

	
	DelayMilliSecs ( 5 ); // delay for computation
	rstat = spi_query( ss ); // get the reply
	display_hyd_query (rstat, ss ); // display the results

  return ( rstat );
} //***************************************************************************


short last_hyd ( void ) //*****************************************************
{  // get the last pump operation statistics
   // returns TRUE if good,
   // returns 0 if failed (use to decide whether to dump to flash)
   
  short rstat, ch ;
  
  struct spi_param *ss;
  ss = all.sspi;
  setup_spi ( CS_HYD, ss ); // re-init the SPI info

  ss->mdat[0] = LAST_RQST;   // dat[0] = cmd byte
  ss->nbyte = 1; // send the above  byte
  
  rstat = spi_try_send ( ss, 2 ); // send the request
  DelayMilliSecs ( 20 );
  rstat = spi_query( ss ); // get the reply
  ch = parse_query_ss( rstat, ss ); // ch is the command response
    
  if ( ch == GO_PUMP ) //====================================
  { // then a succesful reply
    display_pump ( ss ); //put in a struct
  } //=======================================================
  
  //next step would be either to display, or write to flash

  return ( ch==GO_PUMP );
  
} //***************************************************************************

short clear_hyd_pmp ( void ) //************************************************
{  // clear the hyd module structure of the pump stats from the last op
   
  short rstat ;
  
  struct spi_param *ss;
  ss = all.sspi;
  setup_spi ( CS_HYD, ss ); // re-init the SPI info

  ss->mdat[0] = CLEAR_RQST;   // dat[0] = cmd byte
  ss->nbyte = 1; // send the above  byte
  
  rstat = spi_try_send ( ss, 3 ); // send the request

  return ( rstat );
  
} //***************************************************************************


void display_pump  (  struct spi_param *ss ) //********************************
{ // display the pump result

  short merr, oil, jt, amp, volt,total,max_amp, ti_max;
  long tmp;
  short *w; // point to a word (2-byte value)
  struct hyd_param *hyd;
  
  hyd = all.hyd; // point to the hydraulic struct so we can save info
  
  
  hyd->status = merr = ss->sdat[1]; // pump status
  w    = (short*) &(ss->sdat[2]); // have w point to the next char value
  jt   = *w++;   // time (0.1s incr)
  hyd->ti = jt/10; // #s run so far
  amp  = *w++;   // last measured amps
  volt = *w++;   // last measured volts
  hyd->oil = oil  = *w++;   // last oil reading
  hyd->max_amp =max_amp = *w++; // maximum amp [counts]
  hyd->ti_max  = ti_max = *w++; // time of max amp
  hyd->total   = total  = *w++;   // total #s accumulated so far
  
  //volts and amps are a/d counts from module, convert to V*100, amps*100
  if ( iparam[ MA_hyd_c2v]>0 )
  {
      if (Verbose) cprintf("Vcnts=%d ", volt);
      tmp = (long)volt * iparam[ MA_hyd_c2v];
      tmp = tmp*0.01; // now in 0.01 V
      volt = tmp;
      if (Verbose) cprintf("V*100=%d\n",volt);
  }
  if ( iparam[ MA_hyd_c2i]>0 )
  {
      if (Verbose) cprintf("Icnts=%d ", amp);
      tmp = (long)amp * iparam[ MA_hyd_c2i];
      tmp = tmp*0.01; // now in 0.01 amps
      amp = tmp;
      if (Verbose) cprintf("I*100=%d\n",amp);
      tmp = (long)max_amp * iparam[ MA_hyd_c2i];
      tmp = tmp*0.01; // now in 0.01 amps
      max_amp = tmp;
      
  }
  
  // save calibrated values
  hyd->amp     = amp;
  hyd->volt    = volt;
  hyd->max_amp = max_amp; // NEW 0902; was not scaled in 0901 version
  
  printf( "PUMP " );
  switch ( merr )
  { // display motor status
    case PUMP_WAIT    :   cprintf("Is running... "); break;
    case PUMP_OK      :   cprintf("Ran OK,            "); break;
    case PUMP_OIL_END :   cprintf("off via oil sensor "); break;
    case PUMP_AMPS    :   cprintf("AMPS >max allowed  "); 
         hyd->bad_amp = TRUE;  //flag that max amps was exceeded
         hyd->nbad++; // increment counter
         break;
    case PUMP_STOP    :   cprintf("stopped by user    "); break;
    case PUMP_TMAX    :   cprintf("AT MAX TIME        "); break;
    case PUMP_OFF     :   cprintf("Pump is off        "); break;

    default       :   printf("UNKOWN[%d] = ",merr);
  } //=======================================================
  
     printf("time %4.1f: amp=%5d v=%5d oil=%5d MaxAmp=%5d @time=%4.1f ",
             jt*0.1, amp, volt, oil, max_amp, ti_max*0.1 );
     
	 cdrain();   // wait for completion of last SCI_Tx
     if (merr != PUMP_WAIT )
       printf("  Total time = %5d\n", total);
     else printf("\n");
  
  
  return ;
} //***************************************************************************



//*****************************************************************************
short hyd_stop_pump ( void ) //************************************************
{  // send the command to stop the hydraulic pump
  short rstat;
  struct spi_param *ss;
  
  ss = all.sspi;
  setup_spi( CS_HYD, ss );  // initializes the SPI info
  
  ss->mdat[0] = HYD_STOP_PUMP;   // dat[0] = cmd byte
  ss->nbyte = 1; // send the above  byte
  
  rstat = spi_try_send ( ss, 3 ); // try up to 3x

  
  return ( rstat );
} //***************************************************************************


//*****************************************************************************
short hyd_more_pump ( short t  ) //********************************************
{  // send the command for an incremental pump more...
   // this is done without turning off the pump
   // t = time (s) to pump more
  short rstat;
  struct spi_param *ss;
  
  ss = all.sspi;
  setup_spi( CS_HYD, ss );  // initializes the SPI info
  
  rstat = ( t + 5 )/10;  // round to the nearest 10s
  if (rstat<1) rstat =1; // do at least 10s more
  
  ss->mdat[0] = HYD_MORE_PUMP;   // dat[0] = cmd byte
  ss->mdat[1] = rstat; // #more rstat*10 s to pump
  ss->nbyte = 2; // # of bytes
  
  rstat = spi_try_send ( ss, 3 ); // send the command
  
  return ( rstat );
} //***************************************************************************


short       go_pump       ( short t, short use_oil ) //************************
{ // send the command to pump for t s.
  // use_oil = usage of the oil sensor, see pump.h, OIL_NO, OIL_AFTER_T, OIL_YES
  
	short rstat, i, *w;
    struct spi_param *ss;
    
    ss = all.sspi;
    setup_spi( CS_HYD, ss );  // initializes the SPI info
	    
	
	w = ( short*) &(ss->mdat[0]); // point to start
	i=1; // index used to write out shorts into mdat: skip first 2 bytes
	ss->mdat[0] = GO_PUMP;    // dat[0] = cmd byte
	ss->mdat[1] = use_oil;    // pay attn to oil sensor??
	w[i++] = t; // max time to run the pump
	
	ss->nbyte = 2*i; // total # of bytes

	rstat = spi_try_send ( ss, 3 ); // send the command
	
	all.hyd->status = PUMP_WAIT; // pump is on, waiting for it to finish
	all.hyd->bad_amp= 0; // no bad amps yet


  return ( rstat );
} //***************************************************************************

short watch_pump ( short tmax, short take_dat ) //*****************************
{ // watches the pump and returns when it is done pumping
  // or when time tmax expires
  // if take_dat = TRUE, than records data every dt s as well.
  // nov11 updated status check location
  // dec14, service the wdog every 60s
  
  // returns the amount of time that it pumped
  long tnow, tstop, tnext, twdog;
  short t, status=0, dt, dtwdog =60; 
  struct hyd_param *hyd;
  
  hyd = all.hyd;
  dt  = SAMP_DT_UP;  // 0903 feb11, time between samples
  
  tnow = RTCGetTime( 0, 0);
  tstop = tnow + tmax;
  tnext = tnow + dt; // time for next sample
  twdog = tnow + dtwdog; // next time for servicing the wdog
  //assume pump is on & we're waiting for it to finish
  status = hyd->status = PUMP_WAIT; 
  // hyd->status only gets updated when successful query in get_hyd_ad
  
  do //================================================================
  { // cycle until it stops running, or times out
         
     if ( take_dat && tnow>tnext ) //----------------------
     { // time to take data
       take_data ( ); // this updates status as well
       tnext += dt;
       DelayMilliSecs( 1000 ); // wait awhile longer
     } //--------------------------------------------------
     
     if ( tnow>twdog ) //----------------------------------
     { // dec14 time to make sure the wdog is happy
       service_wdog();
       twdog += dtwdog;
     } //--------------------------------------------------
      
     if ( status == PUMP_WAIT ) //-------------------------
     { // pump is still running
       get_hyd_ad ( ); // get the latest status
       DelayMilliSecs( 1000 ); // wait awhile longer
     } //--------------------------------------------------
     
     tnow = RTCGetTime( 0, 0); // update the time
     status = hyd->status;     // last successful status
  } while ( status == PUMP_WAIT && tnow<tstop ); //====================
  
  if (status != PUMP_WAIT ) //nov11 =======================
  { // has stopped, get the last pump-time
    last_hyd(); // gets the last values
  } //=====================================================
  t = hyd->ti;  // time that it has run

  return ( t );
} //***************************************************************************

short watch_d_pmp ( short tmax, short take_dat ) //****************************
{ // DEBUG version of watch_pump nov11
  
  // returns the amount of time that it pumped
  long tnow, tstop, tnext;
  short t, status=0, dt; 
  struct hyd_param *hyd;
  
  hyd = all.hyd;
  dt  = SAMP_DT_UP;  // 0903 feb11, time between samples
  
  tnow = RTCGetTime( 0, 0);
  tstop = tnow + tmax;
  tnext = tnow + dt; // time for next sample
  //assume pump is on & we're waiting for it to finish
  status = hyd->status = PUMP_WAIT; 
  // hyd->status only gets updated when successful query in get_hyd_ad
  
  do //================================================================
  { // cycle until it stops running, or times out
    
        get_hyd_ad ( );
     if ( status == PUMP_WAIT )
     { // pump is still running
       DelayMilliSecs( 1000 ); // wait awhile longer
     }
     tnow = RTCGetTime( 0, 0); //update the time
     if ( take_dat && tnow>tnext ) //----------------------
     { //nov11, take_data() does the following
       get_hyd_ad ( ); //take_data ( ); 
       tnext += dt;
     } //--------------------------------------------------
      
     tnow = RTCGetTime( 0, 0); //update the time
     status = hyd->status; // last successful status
  } while ( status == PUMP_WAIT && tnow<tstop ); //====================
  
  /*
  if (status != PUMP_WAIT ) //nov11 =======================
  { // has stopped, get the last pump-time
    last_hyd(); // gets the last values
  } //=====================================================
  */
  t = hyd->ti;  // time that it has run
  
  return ( t );
} //***************************************************************************

short get_hyd_ad ( void ) //***************************************************
{ // request, wait, and then get hydraulics data
  // storing to the data structure
  // this specifically handles the case of when the pump is running
  short err, pump_q;
  struct spi_param *ss;
  
  ss = all.sspi; // point to the spi structure

  setup_spi( CS_HYD, ss );  // initializes the SPI info
  
  err = spi_query( ss ); // get the queued reply
  pump_q = ( err== SPI_CRC_OK && ss->sdat[0] == GO_PUMP );
  //cprintf("initial pump query = %d\n",pump_q);
  
  // pump_q tells us if we have a valid pump status report
  if (!pump_q  && err == SPI_NO_Q ) //====================================
  {  // then we need to request the a/d readings
        ss->mdat[0] = SPI_MEASURE;  // dat[0] = cmd byte
        ss->mdat[1] = AD_HYD_ALL ;  // sample all
        ss->nbyte = 2;              // 2 bytes to send
        err = spi_try_send ( ss, 1 ); // send the command
     if (err != SPI_CRC_OK)  cprintf("rqst err =%d\n",err);
     DelayMilliSecs(100); // delay for computation
     err = spi_query( ss ); // get the queued reply
     pump_q = ( err== SPI_CRC_OK && ss->sdat[0] == GO_PUMP );
     if (!pump_q)
       cprintf("ERR=%d  cmd=%d, ch=%d\n", err, ss->sdat[0], ss->sdat[1] );
  } //====================================================================


  //cprintf("final pump query = %d\n",pump_q);
  if (pump_q) //==========================================================
  { // then we have a valid reply to parse
    display_pump ( ss );
    // this updates the hyd struct
  }

  return ( err );
} //***************************************************************************


//**** 0711 G : Air vent only (check valve + vacuum pump + LLD ) **************
//**** electronics only allows vacuum pump to run when LLD sees air

short  check_vent ( void ) //**************************************************
{ // if the Spray has an installed vent, perform the requested cmd,
  // as per the IA_cntl_vent value
  // returns #of seconds vent ran
  short cntl, lld0=0,  lld2=0, ti, tick=0, n, cntl0;
  
  cntl0 = cntl = iparam [ IA_cntl_vent ];
  if (cntl>10) cntl = cntl % 10; // leaves cntl0 = original value
  
  // cntl = 0 = do nothing
  // cntl = 1 = just report the LLD value
  // cntl = 2 = run the vent if air is detected.

  
  ti = iparam [ IA_tm_vent ];  // Max time to run the vent.
  if (ti>60) ti=60; //v0902.5 feb11 swapped from 4s to 60s.
  cprintf("Vent control= %d, max time=%d\n",cntl, ti);
  
  if (cntl <1) return(0); // no action taken
  
  //  start off by getting an LLD sample
  lld0 = get_lld();  // >0 if there is air
  
  
  if (cntl>1) //++++++++++++++++++++++++++++++++++++++++++++++++++++
  { // then we want to run the vent if needed

    if ( lld0>0  ) //--------------------------------
    {  // if air, then run the vent 
       if (ti>0)
         tick = run_vent( ti, &lld0, &lld2 ); // vent the air out
    } // end if lld0>0 ------------------------------
    
  } // else cntl==1, just return lld0 value ++++++++++++++++++++++++

  // lld2 = get_lld(); // get the final LLD value
      
  if (cntl0<20) iparam [ IA_cntl_vent ] =1;  // reset to=1 = sense only
  // if cntl0>20, then it is NOT reset, and ea dive will run the vent.
  
  //save the values into the engineering buffer
  n = tick << 8;    // move value into MSB
  n += lld2*2 + lld0;     // add into the LSB the LLD values
  all.eng->vent = n; //save the value
  
  return ( tick );
} //***************************************************************************

short  get_lld ( void ) //*****************************************************
{ // power on, and read in the liquid-level-detect value
  // returns 1=air at LLD, else 0=no air.
  // This is only called when the vent pump is OFF, otherwise
  // the LLD is automatically on when the vent pump is on.
  
  // returns:
  // 0=oil
  // 1=air
  // 2=spi_err
  
  short  rstat, ch, lld=2;
  struct spi_param *ss;
    
  ss = all.sspi;
  setup_spi( CS_HYD, ss );  // initializes the SPI info
  
  power_on_off( CS_HYD, LLD_SAMP,    1 ); // does the sample
  DelayMilliSecs(200); 	// wait for it to sample
  rstat = spi_query( ss ); // get the queued reply
  
  if ( rstat == SPI_CRC_OK) //=============================
  { // then was received successfully

      ch = parse_query_ss(rstat, ss);

      if ( ch == AUX_PWR && ss->sdat[1] == LLD_SAMP ) // correct packet
         lld = ss->sdat[2]; // returned value
      else 
         cprintf("Bad hyd lld packet\n" );

  } //=====================================================
  else if (Verbose) 
          cprintf("bad spi_query stat = %d\n",rstat);
  
  
    /* essentially what the code in the msp430 does
    LLD_On;                 // turn on the LLD
    DelayMilliSecs(100); 	// wait to transition
    val =  LLD value;  		// read in the value:  SPI module call
    LLD_Off;                // turn off the LLD
    /**/
    
  return ( lld );
} //***************************************************************************


short run_vent( short ti, short *lld0, short *lld1 ) //************************
{  // Purge the air from the vent
   // ti = max time (s) to run the vent.
   // returns the time (0.1s ticks)
   // returns lld0 = beginning value
   //         lld1 = end value
   
   short rstat,  ch, i, tik=0;  // bdr may15, added =0 for tik so if garbage, returns zero.
   //float s;
   struct spi_param *ss;
    
   ss = all.sspi;
   setup_spi( CS_HYD, ss );  // initializes the SPI info
  
	ss->mdat[0] = GO_VENT;    // dat[0] = cmd byte
	ss->mdat[1] = ti &0xff;   // max #s to run	
	ss->nbyte = 2; // total # of bytes

	rstat = spi_try_send ( ss, 3); // send the command
	
	//===wait for a valid reply
	i=0;
	do //=============================================
	{  // check every s
	   DelayMilliSecs ( 1000 );
	   rstat = spi_query( ss );
	} while (i++<ti && rstat != SPI_CRC_OK ); //======
	
  if ( rstat == SPI_CRC_OK) //=============================
  { // then was received successfully

      ch = parse_query_ss(rstat, ss);

      if ( ch == GO_VENT  ) 
      { // correct packet
           tik = ss->sdat[1];
         *lld0 = ss->sdat[2]; // begin. lld
         *lld1 = ss->sdat[3]; // end. lld
         //s = 0.1* (float) tik;
         cprintf("Vent ti = %d 0.1s ticks, lld_start=%d, lld_end=%d\n",
                  tik, *lld0, *lld1 );
      }
      else 
         cprintf("Bad hyd go_vent packet\n" );

  } //=====================================================
  else if (Verbose) 
          cprintf("bad spi_query stat = %d\n",rstat);
   
 
  return ( tik );
} //***************************************************************************










//*****************************************************************************
//*** auto-degassing (adg) code : bdr 29may2015 
//*** definitions are in pump.h
//*****************************************************************************

#if USE_ADG == 1 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  // compile the auto-degas stuff @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


//*** static = declare global variables ONLY available to this file ***********
//*** these variables end up on the heap, not the stack.
  static uchar  adgOut_Ncycles = 0;                               // # of total cycles completed so far
  static uchar  adgOut_Nincr = 0;                                 // # of incr. pumps to do, set to n_incr at start of machine
  static ushort adgOut_pumpTimeMax = 0;                           // max time to pump at each increment, set at start of machine (s)
  static uchar  adgOut_bleedTime  = 0;                            // time of bleeding for each cycle (minutes)
  static uchar  adgOut_totalTime = 0;                             // total time of the whole process, in 0.1 hr ticks.
  static uchar  adgOut_pumpTime[N_CYCLES_MAX] = {0};              // total pump time for each outer cycle
  static uchar  adgOut_oilCount[N_CYCLES_MAX][N_INCR_MAX] ={{0}}; // oil pressure at end of each incremental pump, /10
  static ushort adgOut_ventTime[N_CYCLES_MAX] = {0};              // vent time total for each outer cycle, in 0.1s ticks
  static uchar  adgOut_pumpVoltageAve[N_CYCLES_MAX] = {0};        // average voltage for each outer cycle, in 0.1V
  static uchar  adgOut_pumpCurrentAve[N_CYCLES_MAX] = {0};        // average of the average current in 0.1A
  static uchar  adgOut_pumpCurrentMax[N_CYCLES_MAX] = {0};        // max of the max currents for each outer cycle, in 0.1A
  static uchar  adgOut_sbdFirstJ  = 0; // jun15: first cycle index to send thru SBD
  static uchar  dat[MAX_SBD_OUT] = {0}; // jun15 SBD data buffer
  // variables for timer: 
  static ulong unixTime_adgStart;



//*****************************************************************************
short adg_GetPumpInfo(short *pump_status, short *pump_oil,  short *pump_time, 
                     short *pump_volts,  short *pump_amps, short *pump_ampsMax)
{ 
  // extract pump info from the most recent pump run. 
  //---return
  //   istat = status: 1=OK, 0=bad
  short err, istat;
  struct hyd_param *hyd;
  hyd = all.hyd; // local pointer to the hydraulic struct

  err = get_hyd_ad();   // get the latest status
  // above calls display_pump, which loads values into the hyd.struct
  
  if (err == SPI_CRC_OK)
  { // then the data is OK
    *pump_status  = hyd->status;
    *pump_oil     = hyd->oil;
    *pump_time    = hyd->ti;
    
    *pump_volts   = hyd->volt;
    *pump_amps    = hyd->amp;
    *pump_ampsMax = hyd->max_amp;
    istat = 1;
  } else
  { // packet error: but force pump status to PUMP_WAIT = still on.
    cprintf("get_hyd_ad err = %d\n", err);
    
    *pump_status = PUMP_WAIT; 
    /* else keep the last values
       we can use istat to decide what to do with the data
    *pump_oil     = 0;
    *pump_time    = 0;
    *pump_volts   = 0;
    *pump_amps    = 0;
    *pump_ampsMax = 0;
    */
    istat = 0;
  }
  
  return istat;
} //***************************************************************************


void  adg_printState ( int state ) //******************************************
{
  // only for printing out what state the state machine is currently in.
  // states are #defined in pump.h.
  // bdr may15
  
  switch (state)
  {
    case ADG_ST_IDLE:       cprintf("ADG_ST_IDLE"); break;
    case ADG_ST_PUMPING:    cprintf("ADG_ST_PUMPING"); break;
    case ADG_ST_PAUSING_PRE_VENT: cprintf("ADG_ST_PAUSING_PRE_VENT"); break;
    case ADG_ST_VENTING:    cprintf("ADG_ST_VENTING"); break;
    case ADG_ST_BLEEDING:   cprintf("ADG_ST_BLEEDING"); break;
  }
  cprintf("\n");
  
  return;
} //***************************************************************************

void   adg_PrintPacket( void  ) //*********************************************
{
  // print out all the output ADG packet info stored thus far.
  // this is where could send to iridium in addition.
  //
  // bdr may15
  // inputs:  none
  // outputs: none
  // 
  int i,j, n;
  
  n = adgOut_Ncycles; // #cycles COMPLETED
  
    // (see AutoDegassPacketSizing_v1.2.xlsx)
    
    // for now let's print out our final data arrays to the screen as a check...
    cprintf("\n* * DATA OUT * * * * * * \n");
    cprintf("adgOut_Ncycles = %d\n",    n );
    cprintf("adgOut_Nincr = %d\n",      adgOut_Nincr);
    cprintf("adgOut_pumpTimeMax = %d\n",adgOut_pumpTimeMax);
    cprintf("adgOut_bleedTime = %d\n",  adgOut_bleedTime);
    cprintf("adgOut_totalTime = %d\n",  adgOut_totalTime);
    
    cprintf("adgOut_pumpTime = [\n");
    for(i=0; i<n; i++)
      cprintf("%d\n", adgOut_pumpTime[i]);
    cprintf("]\n adgOut_oilCount = [\n");
    for(i=0; i<n; i++)   
    {
      for(j=0; j<adgOut_Nincr; j++)   
        cprintf("%d\t", adgOut_oilCount[i][j]);
      cprintf(";\n");
    }
    cprintf("]\n adgOut_ventTime = [\n");
    for(i=0; i<n; i++)
      cprintf("%d\n", adgOut_ventTime[i]);
    cprintf("]\n adgOut_pumpVoltageAve = [\n");
    for(i=0; i<n; i++)
      cprintf("%d\n", adgOut_pumpVoltageAve[i]);
    cprintf("]\n adgOut_pumpCurrentAve = [\n");
    for(i=0; i<n; i++)
      cprintf("%d\n", adgOut_pumpCurrentAve[i]);
    cprintf("]\n adgOut_pumpCurrentMax = [\n");
    for(i=0; i<n; i++)
      cprintf("%d\n", adgOut_pumpCurrentMax[i]);
    cprintf("]\n");
  
  return;
} //***************************************************************************

void     adg_sbd_make ( void ) //**********************************************
{ // make the adg sbd message
  // this separate fnx allows easier bench test debugging.
  short  j, n;
  
  all.klifo = assign_lifo(all.lifo, 0, 0); // dive#=0, pid=0
  lifo_adg_hdr(); // add the auto-degas header info  
  //---now pack the data
  j = adgOut_sbdFirstJ;    // = first cycle index for this subset
  n = adgOut_Ncycles- j;   // = # of points to send
  adgOut_sbdFirstJ = adgOut_Ncycles; // set the value for next modulo-match.
  // store the arrays
  lifo_adg_dat1( j, n, SBD_ADG_PmpTm , adgOut_pumpTime ); 
  lifo_adg_dat1( j, n, SBD_ADG_Volts , adgOut_pumpVoltageAve ); 
  lifo_adg_dat1( j, n, SBD_ADG_Amps  , adgOut_pumpCurrentAve ); 
  lifo_adg_dat1( j, n, SBD_ADG_AMax  , adgOut_pumpCurrentMax ); 
  lifo_adg_vent( j, n ); // stores the vent data (2 bytes per datum)
  lifo_adg_oil(  j, n ); // stores the oil counts (2-D array)
  
  return ;
} //***************************************************************************

short    adg_sbd_send ( void ) //**********************************************
{ // make and send the auto-degas info
  short istat=0;
  
  adg_sbd_make(); // make the message
  parse_lifo ( all.lifo, all.klifo ); // display the packet
  //=== send the message.
  istat = sbd_surface( 0 ); // 0= NO wing control; returns #packets sent
  
  return istat;
} //***************************************************************************

void   lifo_adg_hdr ( void )  //***********************************************
{ //  store the auto-degas header info
    short i, n;
      
  dat[0] = SBD_ADG_HDR; //assign id = adg packet header
  i = 3; // dat[1], dat[2] = #bytes in the message; set at end of fnx

  dat[i++] = (uchar)adgOut_sbdFirstJ  ; // #first cycle index being sent
  dat[i++] = (uchar)adgOut_Ncycles    ; // #cycles so far
  dat[i++] = (uchar)adgOut_Nincr      ; // #incr. pumps per outer cycle
  dat[i++] = (uchar)adgOut_pumpTimeMax; // incr. pump tm ( lsb = 10 s)
  dat[i++] = (uchar)adgOut_bleedTime  ; // minutes to allow to bleed back in.
  dat[i++] = (uchar)adgOut_totalTime  ; // total time so far ( lsb = 10 minutes)
  dat[i++] = (uchar)TM_VENT_WAIT      ; // time to wait after pump, before venting
  dat[i++] = ';'; // end-of-data char
  n = i; //=# of bytes to transmit : includes 0,1,2 bytes + ';'
  i = b2_store(1,dat,n );
  append_lifo( n,dat); // append to present lifo
  
  return;
} //***************************************************************************

void   lifo_adg_dat1 ( short j0, short np,  short id, uchar *b ) //************
{ //  store the auto-degas 1-d (1-byte) arrays
  // --- inputs ------
  //  j0  = start index
  //  np  = total #points to send
  //  id  = data-type id
  //  *b  = points to data array.
  short i, k, n;
      
  dat[0] = SBD_ADG_DAT; //assign id = adg data array 
  i = 3; // dat[1], dat[2] = #bytes in the message; set at end of fnx
  dat[i++] = id; // identifies the array-type
  dat[i++] =  1; // #bytes per output
  dat[i++] = j0; // start-index
  dat[i++] = np; // total #points
  
  k = j0 + np; // end-index+1
  for (n=j0; n<k; n++) { dat[i++] = b[n]; }
  
  dat[i++] = ';'; // end-of-data char
  n = i; //=# of bytes to transmit : includes 0,1,2 bytes + ';'
  i = b2_store(1,dat,n );
  
  append_lifo( n,dat); // append to present lifo

  return;
} //***************************************************************************

void   lifo_adg_vent ( short j0, short np ) //*********************************
{ //  store the auto-degas vent array
  // --- inputs ------
  //  j0  = start index
  //  np  = # of points to send
    short i, k, n;
      
  dat[0] = SBD_ADG_DAT; //assign id = data array
  i = 3; // dat[1], dat[2] = #bytes in the message; set at end of fnx
  dat[i++] = SBD_ADG_VentTm; // identifies the array
  dat[i++] =  2; // #bytes per output
  dat[i++] = j0; // start-index
  dat[i++] = np; // end-index
  
  k = j0 + np; // end-index+1
  for (n=j0; n<k; n++) 
  { i = b2_store(i, dat, adgOut_ventTime[n] ) ; }
  
  dat[i++] = ';'; // end-of-data char
  n = i; //=# of bytes to transmit : includes 0,1,2 bytes + ';'
  i = b2_store(1,dat,n );
  
  append_lifo( n,dat); // append to present lifo

  return;
} //***************************************************************************

void   lifo_adg_oil ( short j0, short nr ) //**********************************
{ //  store the auto-degas oil (2-D) array
  // --- inputs ------
  //  j   = start row index
  //  nr  = total # of rows
    short i, j, k, n, k0, k1, nc, j1;
    
  //--define the column params
  k0 = 0; // start at the first column spot = first pump for this cycle
  k1 = adgOut_Nincr; // # of incremental pumps = last col index+1
  nc = k1 - k0; // total #columns to write out
  // define the end-row index
  j1 = j0 + nr; // last index + 1
      
  dat[0] = SBD_ADG_2D; //assign id = 2-D data array
  i = 3; // dat[1], dat[2] = #bytes in the message; set at end of fnx
  dat[i++] = SBD_ADG_Oil; // identifies the 2-D array as oil
  dat[i++] =  1; // #bytes per output
  dat[i++] = j0; // start-index row
  dat[i++] = nr; // total #rows
  dat[i++] = k0; // start-index col
  dat[i++] = nc; // total #columns
  // write all of the colums for ea row
  for ( j=j0; j<j1; j++ ) //=======================
  { // do for ea row
    for ( k=k0; k<k1; k++ ) // do for ea col.
    { dat[i++] = adgOut_oilCount[j][k]; }
  } //=============================================
  
  dat[i++] = ';'; // end-of-data char
  n = i; //=# of bytes to transmit : includes 0,1,2 bytes + ';'
  i = b2_store(1,dat,n );
  
  append_lifo( n,dat); // append to present lifo

  return;
} //***************************************************************************

void adg_bench_test ( void ) //*************************************************
{ // setup code for auto-degas bench tests
  int n, n_cyc, tm_pmp, n_incr, tm_bleed;
  
  //--- set up the parameters ----------------------
  cprintf("Give total number of cycles to do \n");
  n = get_num( &n_cyc   );
  if (!n) { cprintf("NOT valid, quitting \n"); return; }
  
  cprintf("Give the bleed time [minutes] between each cycle \n");
  n = get_num( &tm_bleed );
  if (!n) { cprintf("NOT valid, quitting \n"); return; }
  tm_bleed *= 60; // convert to seconds
  
  cprintf("Give number of incremental pumps to do for each cycle\n");
  n = get_num( &n_incr );
  if (!n) { cprintf("NOT valid, quitting \n"); return; }
  
  cprintf("Give max time[s] for each incremental pump"
          " (also will stop when oil pressure hits limit)\n");
  n = get_num( &tm_pmp  );
  if (!n) { cprintf("NOT valid, quitting \n"); return; }
  
  //---all set to go! ---------------
  adg_vent( n_cyc, n_incr, tm_pmp, tm_bleed );
  
  return;
} //***************************************************************************

//*****************************************************************************
//*** code that can be used for bench testing stand-alone *********************
void adg_vent (uchar n_cycles, ushort n_incr, int tm_pump, 
                                              int tm_bleed  ) 
{ // run the auto-degassing cycle, bench-test version
  // bdr may15
  // --- inputs:
  //   n_cycles = total # of outer cycles to complete
  //   n_incr:  = total # of incr. pumps to do per cycle
  //   tm_pump  = max time for ea incr. pump
  //   tm_bleed = time to pause with valve open
  ulong t_now, t_wdog=0;
  short dt = 10; // check in w/things every dt sec.
  uchar state = ADG_ST_IDLE; // initial state is idle = entry point
  
    
  //-- set up the air vent --------------------------
  iparam [ IA_cntl_vent ] =  22;         // set so will always try to vent
  iparam [ IA_tm_vent ]   =  40;         // let it run up to 40s

  
  unixTime_adgStart = RTCGetTime(0, 0); // state-machine start time!
  // start up the while loop for the state machine...    
  do //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  {
    if (Verbose) adg_printState(state);
    
    // jun15, get dropouts 25% of time, ~independent of delay
    //DelayMilliSecs( 1000 ); 
    // service state machine while minimizing power usage.
    t_now = RTCGetTime(0,0); // present time
    hibernate( &t_now, dt, PIT_IRQ2_RXD ); // keep in low-power for dt s.
    // check states/other actions here.
    t_now = RTCGetTime(0,0); // can use t_now to decide other actions.
    
    //---see if we need to service the wdog -----
    if ( t_now - t_wdog > 60 )
    { // service the watchdog
      service_wdog();
      t_wdog = t_now;
    } //-----------------------------------------
    
    // do the necessary auto-degas stuff here.
    state = adg_Loop( state, n_cycles, n_incr, tm_pump, tm_bleed );
      
  } while ( state != ADG_ST_DONE ); 
  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
  return;
} //***************************************************************************

//*****************************************************************************
void remote_adg_vent ( void ) 
{ // run the auto-degassing cycle: triggered by shore cmd.
  // jun15: entry is from miss_fnx.c, try_ship_start()
  ulong  t_now, t_wdog=0, t_press=0, t_max;
  uchar  state = ADG_ST_IDLE; // initial state is idle = entry point
  uchar  n_cycles;
  ushort n_incr, kmod, m;
  int    tm_pump, tm_bleed;
  ushort p;
  float  z;
  short  sent_sbd = true; // flag that sbd msg has been sent
  // by setting it true, we avoid modulo 0 when Ncycles = 0 @ startup.
  short dt = 10; // check in w/things every dt sec.
  
  //-- set up the air vent --------------------------
  iparam [ IA_cntl_vent ] =  22;         // set so will always try to vent
  iparam [ IA_tm_vent ]   =  10;         // let it run up to 10s 10jun15
  
  //-- set up the adg control params
  n_cycles = iparam [ IA_adg_ncycle ]; // # of outer cycles to complete;
  n_incr   = iparam [ IA_adg_incr   ]; // # of incr. pumps to do per cycle
  kmod     = iparam [ IA_adg_modulo ]; // how often to send a report.
  if (kmod <=0) kmod = n_cycles; // force to legal value.
  if (kmod ==1) kmod = 2; // force to every-other, so latching flip-flop works.
  
  // legal values for n_cycles, n_incr are done in the adg_Loop
  tm_pump  = TM_INCR_PUMP  ; // max sec for ea incr. pump
  tm_bleed = TM_BLEED_WAIT ; // sec to pause w/valve open to bleed in ALL of the oil.
  //-------------------------------------------------
  
  unixTime_adgStart = RTCGetTime(0, 0); // state-machine start time!
  // hardwire max time in this fnx to 36 hrs.
  t_max = unixTime_adgStart + ( 36L )*(3600L); 
  
  // start the while loop for the state machine...    
  do //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  {    
    //---keep in low-power for dt. -----------------
    // dt should be chosen to allow adequate service of state,
    // while minimizing power usage.
    t_now = RTCGetTime(0,0); // present time
    hibernate( &t_now, dt, PIT_IRQ2_RXD ); // keep in low-power for dt s.
    // this updates the value of t_now as well.
    
    //---see if we need to service the wdog------
    if ( t_now - t_wdog > 60 )
    { // service the watchdog
      service_wdog();
      t_wdog = t_now;
    } //-----------------------------------------
    
    //---see if we need to check pressure  ------
    if ( t_now - t_press > 300 )
    { // check P every 300s
      p = sbe_avg_p(4);  // get  SBE p avg
      z = dBar( p, all.flt );
      t_press = t_now;
      if  ( z > 10 )
      { // TOO DEEP! set to exit
        state = ADG_ST_DONE; // this will make sure the pump is turned off.
      } 
    } //-----------------------------------------
    
    if ( t_now > t_max ) state = ADG_ST_DONE; // time to quit for sure
    
    //=== service the state machine. =============================
    if (Verbose) adg_printState(state);
    state = adg_Loop( state, n_cycles, n_incr, tm_pump, tm_bleed );
    //============================================================
    
    //---see if time to send --------------------
    // adgOut_Ncycles = #cycles completed
    // values = 0, 1, 2....
    m = adgOut_Ncycles % kmod; // m= 0 if time to send
    if ( state == ADG_ST_DONE )
    {  // force it send for last cycle.
       m = 0; 
       sent_sbd = FALSE;
    }
    if ( m==0 && (z<10) && !sent_sbd )
    { // then it is time to send the latest info
      adg_sbd_send();
      sent_sbd = true; // has been sent!
    } //-----------------------------------------
    if (m !=0 ) sent_sbd = false; // new cycle has started
      
  } while ( state != ADG_ST_DONE ); 
  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
  return;
} //***************************************************************************



//*****************************************************************************
uchar   adg_Loop ( uchar myState, uchar n_cycles, ushort n_incr, 
                     int tm_pump_secs, int tm_bleed_secs )  
{ // this is the loop function that is to be called as often as feasible,
  // This is the state machine that keeps track of where we are.
  //
  // bdr may15
  // inputs:  n_cycles:     =total # of outer cycles to complete
  //          n_incr:       =total # of incr. pumps to do per cycle
  //          tm_pump_secs  =max time for ea incr pump 
  //          tm_bleed_secs =time to pause with valve open
  // outputs: uchar:  returns the state machine state at end of this call 
  //
  
  // i_cycle = outer-loop running counter. = 0..(n_cycles-1)
  // i_incr  = inner-loop running counter: = 0..(n_incr-1)    
  static uchar i_cycle=0, i_incr=0; 

  // info of the most recent pump (from adg_GetPumpInfo) 
  static short pump_status, pump_oil, pump_time, pump_volts, pump_amps, pump_ampsMax; 
  ushort ventTimeTicks; // ticks (0.1s) that the vent ran
  
  // accumulators of inner-cycle values: used to compute avg for ea outer cycle.
  static int  pump_volts_totalTemp =0;
  static int  pump_amps_totalTemp  =0; 
  static int  pump_time_total      =0;
  static int  i_incr_good          =0; // count good pump values

  
  // for unix timing (these are set every time we check what time it is)
  ulong unixTime_now, tm_pump_on_secs;
  short unixTicks;
  short iOK;  // jun15, status of hyd. value
  int avg;
  
  // for unix timing keep track of persistent time stamps with static vars:
  // unixTime_adgStart already defined and initialized
  static ulong unixTime_pumpStart  =0,  unixTime_bleedStart =0;
  static ulong unixTime_pauseStart =0;
  // total_timeTemp = total time since start of this auto-degas.
  static ulong total_timeTemp =0; 
  
  
  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  //  enter the state machine switch statement 
  // (see diagram in AutoDegassPacketSizing_v1.2.xlsx)
  switch (myState)
  { // take appropriate action, dependent upon the state
  
  
    //== ADG_ST_IDLE = ENTRY POINT: INITIALIZE STUFF ======================
    case ADG_ST_IDLE:    
       
      // reset the outer cycle counter and the incremental pump:
      i_cycle=0; i_incr=0; i_incr_good = 0;
      pump_volts_totalTemp=0; pump_amps_totalTemp=0; pump_time_total=0;
      adgOut_sbdFirstJ = 0; 
      adgOut_Ncycles   = 0; // #cycles completed so far

      // set the output packet variables that will be used for this run:
      adgOut_pumpTimeMax = (ushort)(tm_pump_secs/10);   // convert to 10s ticks
      adgOut_bleedTime   = (uchar)(tm_bleed_secs/60); // convert to minutes
      //--- catch illegal values -------------------
      if (n_cycles > N_CYCLES_MAX || n_incr > N_INCR_MAX)
      {
        cprintf("ERROR! n_cycles (=%d) or n_incr (=%d) over maxima\n", n_cycles, n_incr);
        myState = ADG_ST_DONE;
        return ADG_ST_DONE;
      }
          
      adgOut_Nincr       = n_incr; // #of pump increments per cycle
      
      Close_Valve; // close the valve
      // run the pump for the incr. time
      spi_pwr_rst( CS_HYD );  // zero out accum. of pump time
      go_pump(tm_pump_secs, OIL_YES ); // start pump, watching oil sensor
      RTCGetTime(&unixTime_pumpStart, &unixTicks);  // set the start-pmp tm
      cprintf("\n* * TIME = %lu  * * * pump start #%d,%d* * * * * * * * *..\n", 
              unixTime_pumpStart-unixTime_adgStart, i_cycle, i_incr);
      
      // change the state, for next time
      myState = ADG_ST_PUMPING;
       
      break; //============================================================
      
      
    //== ADG_ST_PUMPING = The pump is now running =========================
    case ADG_ST_PUMPING:
      // check if pump is done OR if pump timer expired 
      // (i.e. if enough time passed since started pump)
       
      // calc. how long the pump has been on.
      RTCGetTime(&unixTime_now, &unixTicks);
      tm_pump_on_secs = unixTime_now - unixTime_pumpStart; 

      // wait at least a few seconds to give some time for the 
      // pump SPI to do its thing and be sure it's running
      if ( tm_pump_on_secs < 3  )
        break;
      // iOK = true if got valid pump info  
      iOK = adg_GetPumpInfo(&pump_status, &pump_oil, &pump_time, 
                      &pump_volts, &pump_amps, &pump_ampsMax);
      if (!iOK) 
      { // try one more time
        DelayMilliSecs( 1400 ); 
        iOK = adg_GetPumpInfo(&pump_status, &pump_oil, &pump_time, 
                        &pump_volts, &pump_amps, &pump_ampsMax);
      } //------------------------------------------------------
      
      //-------------------------------------------------------
      if (pump_status != PUMP_WAIT  || tm_pump_on_secs > tm_pump_secs ) 
      {  // either it is off, or it is time to be turned off. 
      
        hyd_stop_pump();  // make sure it is truly off
        RTCGetTime(&unixTime_now, &unixTicks); 
        
        cprintf("pumped for %d seconds, final oil value = %d\n", 
                 pump_time, pump_oil);
      
        if (pump_status == PUMP_OIL_END || pump_oil>1200 )
        { // this allows multiple incremental pumps with most of oil outside
          // 10jun15, added pump oil check as well: almost empty.
          Open_Valve; // since this opening will bleed some back in.
          cprintf("\n* * TIME = %lu * * * valve open \n", 
                   unixTime_now-unixTime_adgStart);
        }
                
        adgOut_oilCount[i_cycle][i_incr] = (uchar)(pump_oil/10); 
        
        if ( iOK ) //--------------------------------------------
        { // then OK to accumulate values
          i_incr_good++; // keep track of #good
          pump_volts_totalTemp += pump_volts, 
          pump_amps_totalTemp  += pump_amps;
        
          //--- also record the highest amps -----
          if (pump_ampsMax==0) pump_ampsMax = pump_amps; // catch bad value
          if (pump_ampsMax > adgOut_pumpCurrentMax[i_cycle])
            adgOut_pumpCurrentMax[i_cycle] = pump_ampsMax;
          
          pump_time_total += pump_time;  // = total pump time
        } //-----------------------------------------------------
        
        //--- next up is pausing before running the vent
        RTCGetTime(&unixTime_pauseStart, &unixTicks); // start-time 
        myState = ADG_ST_PAUSING_PRE_VENT;
      } //---end if -------------------------------------------
      
      break; //============================================================
      
    //== ADG_ST_PAUSING_PRE_VENT = wait before venting ====================
    case ADG_ST_PAUSING_PRE_VENT:
      // check if little pause timer expired
      RTCGetTime(&unixTime_now, &unixTicks);
      
      if ((unixTime_now - unixTime_pauseStart) >  TM_VENT_WAIT ) 
      {
        if (pump_status == PUMP_OIL_END || pump_oil>1200 )  // 10jun15
        // then we just opened the valve some seconds ago
        { // and we've bled some oil back in; 
          Close_Valve; // close valve so we can pump it back out
          RTCGetTime(&unixTime_now, &unixTicks); 
          cprintf("\n* * TIME = %lu * * * valve close.\n", 
                   unixTime_now-unixTime_adgStart);
        }
      
        myState = ADG_ST_VENTING;
      }
      
      break; //============================================================
      
    //== ADG_ST_VENTING = time to vent ====================================
    case ADG_ST_VENTING:
      // if see air, vent here. for now, only stay in here for one call.
      
      // do the venting tick thing here in blocking code
      ventTimeTicks = check_vent(); // 0.1s that the air vent ran.

      RTCGetTime(&unixTime_now, &unixTicks);
      cprintf("\n* * TIME = %lu * * VENTED TICKS (# 0.1s ticks) = %d  \n", 
               unixTime_now-unixTime_adgStart, ventTimeTicks);

      adgOut_ventTime[i_cycle] += ventTimeTicks; //=total vent tm 
           
      i_incr++;  // increment the incr. pump counter
      // now see which state to jump into next call...
      if (i_incr < n_incr) //----------------------------------------
      { // then more incr. pumps to do 
        Close_Valve; 
        // start the pump, watch oil sensor
        go_pump(tm_pump_secs, OIL_YES ); 
        RTCGetTime(&unixTime_pumpStart, &unixTicks); 
        cprintf("\n* * TIME = %lu  * * * pump start #%d,%d* * * * * * * * *..\n", 
                unixTime_pumpStart-unixTime_adgStart, i_cycle, i_incr);
        
        // change the state, for next time
        myState = ADG_ST_PUMPING;  // the pump is on !
      }
      else  // bleed time! ------------------------------------------
      { // we have done all of the incr. pumps
        // time to bleed all of the oil back in.
        RTCGetTime(&unixTime_bleedStart, &unixTicks);
        Open_Valve; 
        cprintf("\n* * TIME = %lu  * * * bleed start for %d seconds * * * *..\n", 
          unixTime_bleedStart-unixTime_adgStart, tm_bleed_secs);

        // change the state, for next time
        myState = ADG_ST_BLEEDING; // oil is now bleeding in.
      } //-----------------------------------------------------------
      break; //============================================================
      
    //== ADG_ST_BLEEDING = let ALL of the oil back in =====================
    case ADG_ST_BLEEDING: // also get ready for another outer cycle.
    
      RTCGetTime(&unixTime_now, &unixTicks);
      
      if ((unixTime_now - unixTime_bleedStart) > ((ulong)tm_bleed_secs  ) ) 
      { // then we're done bleeding.
        // calc. values we want to save
        if ( i_incr_good == 0 ) i_incr_good = 1; // keep legal for divide op.
        avg = (pump_volts_totalTemp/ i_incr_good)*0.1; // now 1 lsb = 0.1V; max ~160 cnts
        cprintf("db: Vavg = %d, n=%d\n", avg, i_incr_good );
        adgOut_pumpVoltageAve[i_cycle] = (uchar)( avg  ); // max < 160 cnts
        avg = pump_amps_totalTemp  / i_incr_good; // 1 lsb = 0.01 amps: max ~ 50
        adgOut_pumpCurrentAve[i_cycle] = (uchar)( avg );
        adgOut_pumpTime[i_cycle] = (uchar)(pump_time_total/10);
        
        // what if over the type cast limit? force to max.
        if (pump_time_total > 2550)
          adgOut_pumpTime[i_cycle] = 255;
        
        // re-init for the next outer pump cycle
        pump_volts_totalTemp=0, pump_amps_totalTemp=0; 
        pump_ampsMax=0; pump_time_total=0; 
        // close the valve
        Close_Valve; 
        RTCGetTime(&unixTime_now, &unixTicks); 

        i_cycle++;  // time for next cycle
        adgOut_Ncycles = i_cycle; //=# completed
          
        if (i_cycle < n_cycles) //-----------------------------------
        { // then we want to do another cycle
          i_incr=0;   // reset the incremental pump ctr 
          i_incr_good = 0; // reset the #good counter.
          cprintf("\n* * TIME = %lu * * * * * * * * starting outer cycle #%d * *\n",
                  unixTime_now-unixTime_adgStart, i_cycle);
          
          // start the pump, watch oil sensor
          spi_pwr_rst( CS_HYD );  // zero out accum. of pump time
          go_pump(tm_pump_secs, OIL_YES ); 
          RTCGetTime(&unixTime_pumpStart, &unixTicks); 
          
          // change the state, for next time
          myState = ADG_ST_PUMPING; // pump is now on.
        }
        else //------------------------------------------------------
        {
          myState = ADG_ST_DONE; // we are now done!
          cprintf("\n* * TIME = %lu * * * * * * * * DONE! * * * * * * * * * *\n", 
                  unixTime_now-unixTime_adgStart);
        }
      }
      break; //============================================================

    //== ADG_ST_DONE = external cmd that we're done   =====================
    //== for normal execution, we would never get here.
    case ADG_ST_DONE: 
        hyd_stop_pump();  // make sure it is truly off
        // anything else to clean up??
       // the if-then below catches the rest of the DONE state.
       // this allows executing that code either 
       // by external entry, or when it is set above, at end-of-bleed.
      
      break; //============================================================
    
  } // end switch state machine
  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
  
  // as long as we're not done, then update the total timer and the cycle counter
  if (myState != ADG_ST_DONE)
  {
    total_timeTemp = unixTime_now-unixTime_adgStart;  // this one is to keep a higher resolution during
    adgOut_totalTime = (uchar)(total_timeTemp/360);   // this one is to send in the end as only 1 byte... (0.1 hr units)
  }
  else // we are done via entry, or by end-of-bleed
  {    // either way, do final chores
       Close_Valve;  // close the valve
       go_pump ( 10, OIL_YES ); // pump just a little out
       watch_pump ( 12, 0 ); // wait for it to finish
        // anything else to clean up??
  } //=============================================================
    
  return myState;
} //***************************************************************************

#endif //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@ end if auto-degas @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@



//*****************************************************************************
void   test_hyd ( void  )    //************************************************
{ // nov11 re-org to just basic functions
  char ch;  //input char
  short  done,  n, val, nval, use_oil, oil, tmo=0;
  long tnow;
  struct spi_param *ss;
  
  ss = all.sspi;
  all.hyd->nbad = 0; // Set #bad amps during pump to 0
  
	cprintf("         Test of Hydraulic Module : %s \n", __DATE__);
	hyd_main_menu();
	spi_pwr_rst  ( CS_HYD ); //dec11, make sure counters are reset
  
	done = false;
	tnow = RTCGetTime(0,0);  // gets present time
	while (!done) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	{  //cycle until we get a quit command

	    // re-init the SPI info
	    setup_spi( CS_HYD, ss );  // initializes the SPI info

	    EIAEnableRx(1);
		
		while ( SCIRxQueuedCount() )
		    SCIRxFlush(); // delete any old stuff 
        if (ch !=' ' && ch>0 ) cprintf("H_1>\n"); // display directory prompt
	    ch = -1; // illegal value - means it timed out
	    ch = SCIRxGetCharWithTimeout( 1000 ); // get a new character
	    tmo = check_tmo ( &ch, tmo );
	    // increments the tmo counter if ch<0, and
	    // goes to sleep mode after max_tmo.  Returns *ch as upper-case

	    //================================================================
	    switch(ch ) //====================================================
	    { // and depending upon the cmd, do the appropriate action =======
	    
        case 'Q' : done=1; break; //quit function
        case '?' :  break; // causes directory prompt to be displayed
        case ' ' :  break; // wait for another character
        case  -1 :  break; // wait for another character
	    case '+' :  toggle_verbose(); // toggle verbose mode
				    break;


				    
	    case 'C' :  // close the valve
	                // spi_aux_pwr( HYD_CLOSE_VALVE, ss );
	                Close_Valve;
	                cprintf("Valve is closed\n");
				    break;
	    case 'O' :  // open the valve
	                // spi_aux_pwr( HYD_OPEN_VALVE, ss );
	                Open_Valve;
	                cprintf("Valve is opened\n");
				    break;

	    case 'D' :  hyd_debug (); // go to debug functions 
			        // and inits iparam accordingly
				    break;
				    
	    case 'H' :  // run the pump for #seconds
			        printf("   give #s to run the pump \n");
				    n = get_num(&nval);
				    if (n==1) //then a legal read of value
				    {  // send command 
	                  cprintf("   OIL sense setting: 0=no, 1=after tmin, 2=yes \n");
	                  n = get_num(&oil);
	                  if (n==1) use_oil = oil;
	                  else      use_oil = 2; //default to yes
	                  
				       val = go_pump( nval, use_oil );
				       val = watch_pump( nval, 0); 
				       cprintf("Pump time= %d s\n",val);
				    }
				    break;

	    case 'L' :  // get the liquid-level-detect
	                n = get_lld( );
	                cprintf("LLD detects ");
	                if (n) cprintf("air\n");
	                  else cprintf("oil\n");
				    break;


        case 'U' :  hyd_main_menu(); 
                    break; // show the main menu

        case 'V' :  val = spi_cmd_ver  ( CS_HYD );
                    if (val==0) display_ver ();
                    break; 

				    
	    case 'X' :  // send pump stop request
	                hyd_stop_pump(  );
	                cprintf("stop sent\n");
				    break;
				    
	    case '>' :  // run the air vent
	                val = iparam [ IA_cntl_vent ]; // save value
	                iparam [ IA_cntl_vent ] = 2;   // set to test
	                check_vent();
	                iparam [ IA_cntl_vent ] = val; // restore
				    break;
                    
                   
        case '1' :  last_hyd ();
                    break; 

        default  : printf(" input unknown \n");
	    } //==============================================================
	     
	  
	} // end while !done
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
  return;
} //***************************************************************************


void hyd_main_menu ( void )
{ //print out menu selections *************************************************
 cprintf("              Hydraulics Menu\n"
		 "     Q.uit menu      :  U.pdate menu    :  D.ebug Pump\n"
         "                        + toggle Verbose:  V.ersion, s/n \n" 
         "     O.pen Valve     :  C.lose Valve \n"
         "     H.yd Pump       :  X. STOP PUMP    :  1,Last Status\n"
         "     L.LD value      :  >.Vent air\n" 
         );

 return;
} //***************************************************************************

//*** nov11 moved most hyd test functions to this debug menu
void  hyd_debug ( void ) //****************************************************
{
  char ch;  //input char
  short  done,  n, val, nval, use_oil, oil, rstat, tmo=0;
  long tnow;
  struct spi_param *ss;
  
  ss = all.sspi;
  all.hyd->nbad = 0; // Set #bad amps during pump to 0
  
	cprintf("         Debug Hydraulic Module : %s \n", __DATE__);
	hyd_d_menu();
  
	done = false;
	tnow = RTCGetTime(0,0);  // gets present time
	while (!done) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	{  //cycle until we get a quit command

	    // re-init the SPI info
	    setup_spi( CS_HYD, ss );  // initializes the SPI info

	    EIAEnableRx(1);
		
		while ( SCIRxQueuedCount() )
		    SCIRxFlush(); // delete any old stuff 
        if (ch !=' ' && ch>0 ) cprintf("H_2>\n"); // display directory prompt
	    ch = -1; // illegal value - means it timed out
	    ch = SCIRxGetCharWithTimeout( 1000 ); // get a new character
	    tmo = check_tmo ( &ch, tmo );
	    // increments the tmo counter if ch<0, and
	    // goes to sleep mode after max_tmo.  Returns *ch as upper-case

	    //================================================================
	    switch(ch ) //====================================================
	    { // and depending upon the cmd, do the appropriate action =======
	    
        case 'Q' : done=1; break; //quit function
        case '?' :  break; // causes directory prompt to be displayed
        case ' ' :  break; // wait for another character
        case  -1 :  break; // wait for another character
	    case '+' :  toggle_verbose(); // toggle verbose mode
				    break;



	    case 'A' :  // a/d sample
			        cprintf("   give a/d channel to sample [0,1,2] \n");
				    n = get_num(&nval);
				    if (n==1  ) //then a legal read of value
				    {  // send command
				       if (nval<8) // valid a/d chan 
				          val = spi_ad12( nval, ss );
				       else // assume we want to measure all
				          get_hyd_ad ( );
				    }
				    break;
				    
	    case 'C' :  // close the valve
	                // spi_aux_pwr( HYD_CLOSE_VALVE, ss );
	                Close_Valve;
	                cprintf("Valve is closed\n");
				    break;
	    case 'O' :  // open the valve
	                // spi_aux_pwr( HYD_OPEN_VALVE, ss );
	                Open_Valve;
	                cprintf("Valve is opened\n");
				    break;

	    case 'D' :  init_hyd_iparam (); // gets the flash, displays 
			        // and inits iparam accordingly
				    break;
				    
	    case 'F' :  // write one word to flash
	                hyd_flash_menu( ss );
				    break;

        case 'G' :  val = spi_query  ( ss );
                    display_hyd_query (val, ss ); // display the results
                    break; 

	    case 'H' :  // run the pump for #seconds
			        printf("   give #s to run the pump \n");
				    n = get_num(&nval);
				    if (n==1) //then a legal read of value
				    {  // send command 
	                  cprintf("   OIL sense setting: 0=no, 1=after tmin, 2=yes \n");
	                  n = get_num(&oil);
	                  if (n==1) use_oil = oil;
	                  else      use_oil = 2; //default to yes
	                  
				       val = go_pump( nval, use_oil );
				    }
				    break;

	    case 'I' :  // incremental
			        printf("   give #s more to run the pump \n");
				    n = get_num(&nval);
				    if (n==1) //then a legal read of value
				    {  // send command 
				       val = hyd_more_pump( nval  );
				    }
				    break;
				    
        case 'J' :  hpr_pwr_get  ( CS_HYD );
                    break; 

	    case 'L' :  // get the liquid-level-detect
	                n = get_lld( );
	                cprintf("LLD detects ");
	                if (n) cprintf("air\n");
	                  else cprintf("oil\n");
				    break;

	    case 'P' :  // power on/off a sensor
			        printf("   give sensor id to control power \n");
				    n = get_num(&nval);
				    if (n==1) //then a legal read of value
				    {  // send command 
				       val = spi_aux_pwr( nval, ss );
				       DelayMilliSecs(5); // delay for computation
				       rstat = spi_query( ss ); // get the reply
                       display_hyd_query (rstat, ss ); // display the results
				    }
				    break;

				    

        case 'U' :  hyd_d_menu(); 
                    break; // show the debug menu

        case 'V' :  val = spi_cmd_ver  ( CS_HYD );
                    if (val==0) display_ver ();
                    break; 

	    case 'W' :  // watch the pump
			        cprintf("   give max #s to watch pump \n");
				    n = get_num(&nval);
				    if (n==1) //then a legal read of value
				    {  // send command 
				       val = watch_pump( nval, 0);
				       cprintf("Pump time= %d s\n",val);
				    }
				    break;
				    
	    case 'X' :  // send pump stop request
	                hyd_stop_pump(  );
	                cprintf("stop sent\n");
				    break;
				    
        case 'Z' :  spi_pwr_rst  ( CS_HYD );
                    break; 

        case '0' :  cprintf("User-input values (Y) or use CFG values? (N) ");
                    if ( YesNo() ) get_user_setup ( ); 
                    setup_pump  ( );
                    break; 

        case '8' :  val = xfr_SPI_byte(CS_HYD, SPI_RESET);
                    cprintf("soft reset return = %c",val);
                    if (val==' ') cprintf("OK");
                    cprintf("\n");
                    break; 
                    
        case '7' :  //--- nov11, mimic start of surface
                    go_pump ( 7, OIL_NO );      // turn on the pump
                    //DelayMilliSecs( 12000);
                    val   = watch_pump ( 6, 0 );   // wait for pump to finish
                    DelayMilliSecs(300); // wait before getting last info
                    last_hyd(); // gets the last values no matter what
                    DelayMilliSecs(300); // wait before getting avg pwr info
                    hpr_pwr_get( CS_HYD ); // =final values
                    n = all.hyd->total; // total pump time
                    cprintf("pmp_tm = %d, tot_tm = %d\n",val,n);
                    break; 
                    
        case '9' :  //--- nov11, mimic surface code
                    go_pump ( 24, OIL_NO );      // turn on the pump
                    val   = watch_d_pmp ( 26, TRUE );   // wait for pump to finish
                    cprintf("pump ran for %d s\n", val);
                    break; 
                    
	    case '>' :  // run the air vent
	                val = iparam [ IA_cntl_vent ]; // save value
	                iparam [ IA_cntl_vent ] = 2;   // set to test
	                check_vent();
	                iparam [ IA_cntl_vent ] = val; // restore
				    break;
                   
        case '1' :  last_hyd ();
                    break; 

        case '2' :  clear_hyd_pmp ();
                    break; 

#if USE_ADG == 1 // include adg test fnx's        
                    
        case '3' :  adg_bench_test (); // jun15
                    break; 
                    
        case '4' :  remote_adg_vent (); // jun15
                    break; 
        
        case '5' :  adg_PrintPacket (); // jun15
                    break; 

        case '6' :  adg_sbd_make (); // jun15
                    parse_lifo ( all.lifo, all.klifo );
                    break; 
#endif                    
        case '!' :  // set flash msp430 eeprom to default values
                    cprintf("Do you really want to reset HYD flash to default (y/n)? >\n");
                    if (YesNo() )
                      { hyd_set_default ( ); } 
                    break;

        default  : printf(" input unknown \n");
	    } //==============================================================
	     
	  
	} // end while !done
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
  return;
} //***************************************************************************


void hyd_d_menu ( void ) // debug menu nov11
{ //print out menu selections *************************************************
 cprintf("              Hydraulics Debug Menu\n"
		 "                        Q.uit menu      :  U.pdate menu \n"
         "     A./D sample     :  D.ump Flash     :  F.lash write word \n"
         "     O.pen Valve     :  C.lose Valve \n"
         "     G.et queued info:  + toggle Verbose:  V.ersion, s/n \n" 
         "     P.ower Control  :  0.Init Params   :  H.yd pump   \n" 
         "     J.oules avg get :  Z.ero Joules Accum X. STOP PUMP \n"
         "     W.atch Pump     :  L.LD value      :  >.Vent air\n" 
         "     1.Last Pump stat:  2.Clear Pump Stat\n" 
         "     3.ADG Bench Test:  4.Remote ADG code: 5. Print ADG Results\n"
         "     6.Make ADG Packet and display \n"
         );

 return;
} //***************************************************************************


//*** end *********************************************************************
