/******************************************************************************
 * general prototype and setup parameters for Spray2008 CF2 v1.0 controller
 * created Oct2008
 * updated:Jan2010 0902
 * 0902 code now keeps track of a profile number, versus
 * the dive # = dive-set# = #surfacings.
 * For multiple cycles/dive-set, the profile# increments for ea cycle
 * updated aug11
 * v0903.4 aug11 code handles Benthos acoustic modem
 * search for 'Benthos' for changes
 * v0903.5 nov11 updates pump fnx watch_pump and moved benthos bottom_turn call
 * v0903.6 dec11, longer hyd surface wait, hole to allow opmode to be set remotely
 *         current-crossing turns off manual heading
 *         bad GPS packet sets hdop = 124; shore value =12.4
 *         fixed opmode bug on power-reset
 * v0903.12 SEP14 mount NTK fwd or aft
 * v0903.13 sep14 fix bug in store_dat2flash, size of profile data
 * v0903.14 oct14 re-work of SBE63 DO code for better error-catching
 *==================================================================
 * v0904.01 dec14 adding variable 50m pump, plus writing SPI error packets
 *          dec14 more service_wdog for gps, sbd, and watch_pump
 * v0904.02 jan15 add bottom_turn err catch for bad V values
 * v0904.03 jun15 add auto-degas, including shore cmd '51'
 * v0904.04 aug15 nortek mods, forced current-bucking if SBD rcvry mode, + zooglider
 * v0904.05 jan16 non-volatile ram for surface, profile counters
 *          also allows negative tau values for heading control
 * v0904.06 may16 more checks of flash card, + tries to re-mount.
 * v0904.07 aug16 turn off the drift mode if the SBD breaks.
 *                also updated ACM code with more service_wdog() calls.
 * v0904.08 oct16 make sure that the Nortek LED is disabled.
 *
 *****************************************************************************/

#ifndef FALSE
   #define FALSE 	(0)
   #define TRUE 	(!FALSE)
#endif

#define USE_ADG 0  // jun15 set to 0/1 to include auto-degas code
#define DEBUG   0  // set flag if want to compile a version for bench-debug work

//*****************************************************************************
//**** SOFTWARE VERSION DECLARATION *******************************************
#define MAJ_VER    904   // YYMM of creation
#define MIN_VER      8   // revision number
#define SHORE_VER    1   // Shore command revision number (updated via sensor suite)
#define PASSWORD  4321   // standard password value: could be in eeprom instead.
//*****************************************************************************
// MAJ_VER =major revision (implements new way of processing, etc).
// MIN_VER =minor revision (no change to shore commands nor shore processing)
// SHORE_VER= revision to the shore commands
//            the shore-processing code should be up-to-date to SHORE_VER.
//===============================================================
// 2014: using SHORE_VER to point to different sensor suites.
// 1 = normal
// 2 = Benthos ACM (add shore cmds specific to ACM)
// 3 = Nortek AD2CP
//===============================================================

// v0902.1 apr10 minor_ver 1 = fixed bug in dat_fnx.c sample_all vac output
// v0902.2 May10 fixes bug in top_turn regarding adp_post_process order (minor).
// v0902.3 Aug10 fixes bug so optical data<0 are NOT averaged into sat data.
// v0902.4 Oct10 fixes exception bug on wdmin from 0xf000 to 0x8000
//
// v0903.1 feb11 increase air vent time, more heading control options.
//               add option for different sample times for descent/ascent.
//               add pump-time parameter for the drift mode.
//               drift occurs after set pump time, then normal bottom turn.
// 
// v0903.2 mar11 adding PolyPlus cell monitoring, DOX sensor option
// v0903.3 jun11 added CellEnd for ADP setup
// v0903.4 aug11 added Benthos code from BDJ 15mar11 code
// v0903.5 nov11 hydraulic debug menu
// v0903.6 dec11 mods to remote setting of opmode, hydraulic timing, gps error msg
//         set SHORE_VER = 1 as flag that had more shore commands than v.0
// v0903.7 jan12 leapseconds flag ignored in UBX time-valid code.
//         feb12 will abort if NO SBD and in shallow water.
//         feb12 added Polyplus changes to turn OFF loads in the bottom turn.
// v0903.8 may12 fix to eng. time series emax so no buffer over-run
// v0903.9 jan13 ability to re-open TPU UART ports if bad communication
//         jan13 fixed pointer offset error in data_pack: should now pack
//               correctly in drift mode.
// v0903.10 oct13 modified GPS LIFO packing to handle +/-0 deg values correctly
//                also displays correctly when checking GPS via monitor
//  
// jul13 - adding macros for GPIO A/D on/off           
//         jul13 added DOX63 capability, search for DO6   
//
// v0903.11 apr14 slight mod for Nortek to store params to flash as well.
//
// v0903.13 sep14 fix bug for size of profile data in store_dat2flash.
// v0903.14 oct14 add more DO error catches, longer time-delays
//                revamp the SENSE_CFG to more easily select sensor suite
// v0904.01 dec14 adding variable 50m pump, plus writing SPI error packets
//          dec14 more service_wdog for gps, sbd, and watch_pump
// v0904.02 jan15 add bottom_turn err catch for bad V values
// v0904.03 jun15 add auto-degas, including shore cmd '51'
// v0904.04 aug15 Nortek minor bug fixes
// v0904.04 aug15 ensured current-bucking if SBD_recovery is needed.
// v0904.04 sep15 = ZOOG mods for zooCam control for ea dive
// v0904.05 jan16 = non-volatile ram for surface, profile counter
//          also allows negative tau values for heading control
// v0904.06 may16 more checks of flash card, + tries to re-mount.
// v0904.07 aug16 turn off drift if bad SBD, plus ACM mods.
// v0904.08 oct16 Nortek: enable LED for bench test, then disable when turned off.
//*****************************************************************************

//*****************************************************************************
//*** SENSOR CONFIGURATION: MODIFY FOR CUSTOM INSTRUMENTS *********************
//*****************************************************************************
// oct14, following copied from 08xx code
// ALL Sprays assumed to have CTD + optical slot.
// extra sensors are defined bit values
#define BIT_ADP  0x01 // bit0 set = 0x01 = Sontek ADP installed.
#define BIT_DOX  0x02 // bit1 set = 0x02 = DOx SBE43 installed.
#define BIT_ISUS 0x04 // bit2 set = 0x04 = ISUS installed.
#define BIT_PPLS 0x08 // bit3 set = 0x08 = polyplus test (should be 09xx electronics only)
//-----next nibble ------------------------------------
#define BIT_ACM  0x10 // bit4 set = 0x10 = Benthos (should be 09xx electronics only)
//--09xx did NOT use 30deg ADP mount option, so differs from 08xx starting here.
//#define BIT_30D  0x20 // bit5 set = 0x20 = 30deg ADP mount angle
#define BIT_DO6  0x20 // bit5 set = 0x20 = DOX SBE63 installed //oct12 bdj
#define BIT_NTK  0x40 // bit6 set = 0x40 = Nortek adp installed //JAN13 bdj
#define MOUNT_ANGLE 17  //standard Sontek ADP mount angle
#define BIT_ZOOG 0x80 // bit7 set = 0x80 = ZooGlider
//--- next nibble
#define BIT_NPS  0x100 //bit8 set = 0x100 = NPS DAT installed
#define BIT_PH   0x200 //bit9 set = 0x200 = YUI pH installed

//--- no BOB code for 09xx

//*********************************************************************
//--- set SENSE_CFG to the installed sensor suite ---------------------
//#define SENSE_CFG 0                     // CTD + optical only (BASE sensor suite )
//#define SENSE_CFG   BIT_ADP             // Sontek   ADP
//#define SENSE_CFG   BIT_ACM             // Benthos modem
//#define SENSE_CFG   BIT_NPS             // NPS DAT modem
//#define SENSE_CFG   BIT_PH			  // pH sensor
  #define SENSE_CFG ( BIT_PH  + BIT_DO6 ) // pH sensor + SBE63
//#define SENSE_CFG   BIT_NTK             // Nortek   AD2CP
//#define SENSE_CFG ( BIT_ADP + BIT_DO6 ) // Sontek + SBE63
//#define SENSE_CFG ( BIT_ADP + BIT_DOX ) // Sontek + DOX
//#define SENSE_CFG ( BIT_NTK + BIT_DO6 ) // Nortek + SBE63
//#define SENSE_CFG   BIT_ZOOG            // Zooglider: ZooCam + ZooNar
//*********************************************************************

//---set default values ------------------------
	#define ADP     0 // default is no Sontek ADP
 	#define NTK     0 // default is no Nortek ad2cp 
    #define DOX     0 // default is no SBE43 DO
    #define DO6     0 // default is no SBE63 DO
    #define ISUS    0 // default is no ISUS
    #define PPLUS   0 // default is no polyplus
    #define BENTHOS 0  // default = NO Benthos modem
    #define ZOOG    0  // default = NO ZooGlider stuff
    #define NPS     0  // default = NO NPS DAT
    #define PH      0  // default = NO pH sensor
    
//--- modify defaults as per the above SENSE_CFG
//--- this sets up the pre-compiler flags as needed

//-- set up for Sontek ADP ----------------------
#if  ( ( SENSE_CFG & BIT_ADP ) > 0 )
  #undef  ADP
  #define ADP  1 // has a Sontek ADP
#endif
//-- set up for Nortek ad2cp --------------------
#if  ( ( SENSE_CFG & BIT_NTK ) > 0 )
  #undef  NTK
  #define NTK  1 // has an NTK AD2CP
  #undef  MOUNT_ANGLE
  #define MOUNT_ANGLE 17.4  // pitch=+17.4 puts 3-beam system vertically-down
  #undef  SHORE_VER
  #define SHORE_VER    3   // Shore cmd rev. #
#endif
//-- set up for SBE43 DO sensor -----------------    
#if  ( ( SENSE_CFG & BIT_DOX ) > 0 )
  #undef  DOX
  #define DOX  1 // has a DOX
#endif
//-- set up for SBE63 DO sensor -----------------
#if  ( ( SENSE_CFG & BIT_DO6 ) > 0 )
  #undef  DO6
  #define DO6  1 // has a DO6
#endif
//--set up for ISUS   ---------------------------
#if  ( ( SENSE_CFG & BIT_ISUS ) > 0 )
  #undef  ISUS
  #define ISUS  1 // has an ISUS
#endif
//--set up for PolyPlus -------------------------
#if  (  ( SENSE_CFG & BIT_PPLS ) > 0 )
  #undef  PPLUS
  #define PPLUS  1 // has Polyplus battery cells
#endif
// set up for Benthos ACM -----------------------
#if  ( ( SENSE_CFG & BIT_ACM ) > 0 )
  #undef  BENTHOS
  #define BENTHOS  1 // has Benthos ACM
  #undef  SHORE_VER
  #define SHORE_VER    2   // Shore cmd rev. #
#endif
// set up for ZooGlider   -----------------------
#if  ( ( SENSE_CFG & BIT_ZOOG ) > 0 )
  #undef  ZOOG
  #define ZOOG  1 // has ZooGlider
  #undef  SHORE_VER
  #define SHORE_VER    4   // Shore cmd rev. #
#endif
// set up forNPS DAT   -----------------------
#if  ( ( SENSE_CFG & BIT_NPS ) > 0 )
  #undef  NPS
  #define NPS  1 // has NPS DAT modem
  #undef  SHORE_VER
  #define SHORE_VER    2   // Shore cmd rev. #
#endif
//-- set up for PH -----------------
#if  ( ( SENSE_CFG & BIT_PH ) > 0 )
  #undef  PH
  #define PH  1 // has a PH
#endif

#define ANT_XFR_SW 1 // set =1 if Spray has the antenna transfer switch

//=== jan13 added exception flag settings for exc_stat ========================
#define EXC_PUMP_RCVRY      0x0001  // needed a pump recovery
#define EXC_BURN_ON         0x0002  // burn wire turned on
#define EXC_BELOW_SURF      0x0004  // not at the surface
#define EXC_TOO_DEEP        0x0008  // got too deep in glide
//-------------
#define EXC_BOT_DETECT      0x0010  // altimeter detected the bottom
#define EXC_BACK_OFF        0x0020  // backed off of the surface
#define EXC_EXTRA_PUMP      0x0040  // extra pumps needed to get to surface
#define EXC_HI_SURF_TM      0x0080  // required too long to leave the surface
//-------------
#define EXC_BAD_FLASH       0x0100  // problem closing the flash
#define EXC_BAD_AMP         0x0200  // high amps at 50m pump
#define EXC_BAD_PRESS       0x0400  // bad SBE pressure @surf:triggers UART reset
#define EXC_SBD_RCVRY       0x0800  // SBD bad for too long or needed UART reset
//-------------
#define EXC_HIGH_CURRENT    0x1000  // cannot overcome the ocean current
#define EXC_SPURIOUS_RST    0x2000  // Spurious RESET of the glider
#define EXC_ADP             0x4000  // System has an ADP
#define EXC_NOT_SINKING     0x8000  // no longer sinking in descend; also Divide-by-zero
//=============================================================================

//===SBE offsets and gains ====================================================
//===they are defined so they are included in the parameter list
#define PR_OFF	-10		// dBar offset
#define PR_GAIN	 40		// Gain*1000:  dBar =cnts*gn/1000 + PR_OFF
// if the above two are modified, also modify the next 3
#define F_PR_GN (0.04)  // PR_GAIN/1000: multiplier actually used in the code
#define INV_PGN (25)    // 1/F_PR_GN, divisor used in intPval
#define PR_MIN 250		// nominal pr cnts @ surface

#define T_OFF	-5		// T offset degC
#define T_GAIN 	 1		// Gain*1000:  degC =cnts*gn/1000 + T_OFF
#define S_OFF	-1		// S offset, PSU
#define S_GAIN   1		// Gain*1000:  degC =cnts*gn/1000 + S_OFF
// if the above gains are modified, also modify the next two
#define F_TS_GN (0.001) // multiplier actually used in the code = gain/1000
#define INV_TSGN 1000   // divisor =1/F_TS_GN
//*****************************************************************************
//=== Altimeter, optical gain to mVolts===========================
//    circuit = 2.5Vrev, with 1/2V divider:
//    5V in = full scale: cnts 2 mV = cnt*5000/4096
#define C2mV  (1.2207) // opt, alt cnts to mV
#define IC2mV  12207   // multiplier to mV*1e4
#define AC2Z  (0.0244) // Tritech: 5V = 100m, 
//*****************************************************************************
//=== Doppler coefficients  =======================================
//=== Apr14 shift values dependent upon Nortek or Sontek
#if NTK==1
  #define ALPHA   38  // dB loss per meter*100,1 MHz
  #define K1_ABS   2  // First bin to use for ABS measurement
  #define K2_ABS   3  // Last  bin to use for ABS measurement
  #define BD       1  // blanking distance, [m*10]; Nortek default = 0.1m
#else // it is the Sontek
  #define ALPHA   22  // dB loss per meter*100, 750 kHz, 25 degree angle
  #define K1_ABS   2  // First bin to use for ABS measurement
  #define K2_ABS   3  // Last  bin to use for ABS measurement
  #define BD      40  // blanking distance, [m*10]
#endif


//*** 0902.5 feb11 ee_ro_use heading control bits *****************************
//*** ee_ro_use default = 1; other bits used to turn OFF 0720 changes
#define RO_USE       0x01  // bit0 set = do heading control (believe roll angle)
#define RO_SET_0     0x02  // bit1 set = do NOT update r0dn, r0up
#define RO_ESUM      0x04  // bit2 set = do NOT reset esum @ bottom turn
#define RO_BOTTOM    0x08  // bit3 set = do active steering control in bottom turn
#define RO_WEIGHT    0xf0  // upper nibble is alternative r0up, r0dn weighting
//*****************************************************************************

//SENSOR TYPES, used to select offset, gain for converting to eng. units
enum sensor_type {
	W_14V,     // 14V battery from watchdog/gpio a/d
	W_07V,     // 07V battery from watchdog/gpio a/d
	W_VAC,     // vacuum from watchdog/gpio
	W_ALT,     // altimeter
	W_OPT,     // optical
	P_AMP,     // pitch amps
	P_VOLT,    // pitch volts
	R_AMP,     // roll amps
	R_VOLT,    // roll volts
	H_VOLT,    // hyd volts
	H_AMP      // hyd amps
}; //==========================================================================

//*****************************************************************************
// *** the following groups should be left alone
// clock speeds, for awake mode and sleep mode
#define	LOW_CLOCK_SPEED		640L	//Lower power from a slower clock
#define	HIGH_CLOCK_SPEED	3680L	//This is the clock speed when we are awake...lowering it will save power.
#define MAX_HIBERNATE 13       // max time to go to low power = 13 s, set by PIT51
// oct08, used to define unix time, for gps week conversion
#define TI_UX0   315964800L    // unix time, for 1/6/1980, 00:00 UTC = GPS Week 0
#define S_PER_WK    604800L    // #s per week
#define S_PER_DAY    86400L    // #s per day
// ux_ti = TI_UX0 + gps_week*S_PER_WK + gps_sec;

#define ATTACK_ANGLE 3 // assume attack angle is 3 degrees
#define SBD 1 // Jun06, SBD ONLY is supported!
#define SBE 1 // Jun06, SBE ONLY is supported!
#define ETAU_M 2 // May07, multiplier for roll PI integrater portion
// prior to may07, this was hardwired to 2...can now try less weight on I
#define ANG_ROLL  0  // used by avg_tcm2 to return avg of roll, pitch, head
#define ANG_PITCH 1  // : pitch
#define ANG_HEAD  2  // : heading
//*****************************************************************************


//*****************************************************************************
// PIN ASSIGNMENTS

// TPU SERIAL Channels ========================================================
#define N_TU_PORTS 4 // # of TPU UART ports
#define FROM_SAT   2 // pin23 = TPU2 is used as cmos input from rs232 sat-comms
#define   TO_SAT   4 // pin25 = TPU4  = cmos output to sat-comms
#define BAUD_SAT   19200  // satellite baud rate
#define   TU_SAT   0 // TPU UART pointer into *tu_port array

#define FROM_MUX1  6 // pin27 = TPU6  = cmos input  from MUX1 chip
#define   TO_MUX1  8 // pin29 = TPU8  = cmos output   to MUX1 chip
#define BAUD_MUX1  9600 // default mux1 baud rate
#define   TU_MUX1  1 // TPU UART pointer into *tu_port array
					 // mux1 is used by adp, gps, aux1, aux2
#define   TU_ADP  1 // ADP  uses TUport 1
#define   TU_GPS  1 // GPS  uses TUport 1
// aux1, aux2 are straight cmos into mux1 chip
#define   TU_AUX1 1 // aux1 uses TUport 1
#define   TU_AUX2 1 // aux2 uses TUport 1
// mar11, use aux1 for polyplus comms = port J11 = top row next to GPS aux battery
#define   TU_PPLUS TU_AUX1 // using aux1
#define   BAUD_PPLUS 1200 // uses much slower baud

#define FROM_MUX2  5 // pin26 = TPU5  = cmos input  from MUX1 chip
#define   TO_MUX2  7 // pin28 = TPU7  = cmos output   to MUX1 chip
#define BAUD_MUX2  9600 // default mux2 baud rate
#define   TU_MUX2  2 // TPU UART pointer into *tu_port array
					 // mux2 is used by compass, isus, aux3, aux4
#define   TU_COMP  2 // compass  uses TUport 2
#define   TU_ISUS  2 // ISUS  uses TUport 2
#define   TU_AUX3  2 // aux3  uses TUport 2
#define   TU_AUX4  2 // aux4  uses TUport 2
 
#define FROM_SBE   1 // pin22 = TPU1  = cmos input from SBE sensor
#define   TO_SBE   3 // pin24 = TPU3  = cmos output  to SBE sensor
#define BAUD_SBE   9600 // SBE baud rate
#define   TU_SBE   3 // TPU UART pointer into *tu_port array


// TPU pins that are presently not used =======================================
#define TPU9  30 // pin30 = TPU9,  not used
#define TPU10 31 // pin31 = TPU10, not used
#define TPU11 32 // pin32 = TPU11, not used
#define TPU12 33 // pin33 = TPU12, not used
#define TPU13 34 // pin34 = TPU13, not used

//TPU pins associated with other functions ====================================
#define V7_BKUP    35 // pin35 = TPU14, controls aux regulator for V7 backup
#define RES_WDOG   37 // pin37 = TPU15, available to reset GPIO/watchdog msp430?
#define ATTN_2_CF2 39 // pin39 = IRQ5 = input from wdog_msp430

//other available IRQ inputs are IRQ2 and IRQ7
//*****************************************************************************


// Antenna Switch settings ====================================================
#define ANT_GPS_2_STBD   1 // connect GPS to stbd antenna, SBD to port
#define ANT_GPS_2_PORT   2 // connect GPS to port antenna, SBD to stbd

#define STBD_WING 0 // will roll the starboard wing up
#define PORT_WING 1 // roll_wing(PORT_WING) will roll port wing up
#define ZERO_WING 2 // will go to zero roll (no wing up)
#define ALT_WING  2 // see RF_Wing_Setup; alternates wing to use
#define MAX_WING_ERR 3 // max wing error accum value before switching
#define GPS_UNIT  0 //  defines what unit to configure the switch for
#define SBD_UNIT  1 //  for either GPS or the SBD

// Low-Power interrupt settings ===============================================
#define PIT_ONLY 0 // wake up on Periodic Interrupt Timer Only
#define PIT_IRQ2 1 // wake up on PIT or IRQ2
#define PIT_IRQ2_RXD 2 // wake up on PIT or IRQ2 or RXD 

#define AWAKE_PIT  1  // awoken by the PIT
#define AWAKE_IRQ2 2 // awoken by the IRQ2 = WDOG
#define AWAKE_RXD  3  // awoken by the RXD

#define STAY_LOWPWR -99 // put sleep_check into an infinite loop

// Interrupt Flags, set in ISR_ATTN dependent upon action
#define IRQ2_F   2 // awoken from IRQ2 = CF2_ATTN line from msp430
#define IRQ3_F   3 // awoken from IRQ3
#define IRQ4_F   4 // awoken by char detected on rs232 Rcv
#define IRQ5_F   5 // awoken from IRQ5
#define IRQ7_F   7 // awoken from IRQ7
#define SPUR_F   8 // awoken by spurious interrupt
#define DIV0_F   9 // divide-by-zero interrupt

//===SBD message-type definitions =============================================
//=== (one-byte tag for message type )
//=== these are defined in function calls mostly,
//=== but are compiled here as an index
//---gps ----------------------------------
#define   SBD_GPS0   0x00   // GPS at start/reset of Spray
#define   SBD_GPS1   0x01   // GPS at start of dive
#define   SBD_GPS2   0x02   // GPS at end of dive
#define   SBD_GPS3   0x03   // GPS in the abort mode
#define   SBD_SURF   0x08   // surface drift
#define   SBD_MARK   0x0f   // Dive-marker
//---profile definitions  -----------------
#define   SBD_PRO_P  0x10   // Pressure    profile
#define   SBD_PRO_T  0x20   // Temperature profile
#define   SBD_PRO_S  0x30   // Salinity    profile
#define   SBD_PRO_O  0x40   // Optical     profile
#define   SBD_DOX    0x48   // DO profile
//---0x5 = adp profile definitions --------------
#define   SBD_ADP_P  0x50   // ADP pressure
#define   SBD_ADP_U  0x51   // ADP U
#define   SBD_ADP_V  0x52   // ADP V
#define   SBD_ADP_I  0x54   // ADP last-bin intensity
#define   SBD_ADP_p  0x55   // ADP pitch
#define   SBD_ADP_r  0x56   // ADP roll
#define   SBD_ADP_h  0x57   // ADP heading
#define   SBD_ADP_B  0x58   // ADP backscatter
#define   SBD_ADP_H  0x5f   // ADP parameter info
//---0x6 = adp shallow definitions --------------
#define   SBD_ADPS_P  0x60   // ADP pressure
#define   SBD_ADPS_1  0x61   // ADP beam 1 vel
#define   SBD_ADPS_2  0x62   // ADP beam 2 vel
#define   SBD_ADPS_3  0x63   // ADP beam 3 vel
#define   SBD_ADPS_1i  0x64   // ADP beam 1 vel
#define   SBD_ADPS_2i  0x65   // ADP beam 2 vel
#define   SBD_ADPS_3i  0x66   // ADP beam 3 vel
#define   SBD_ADPS_h  0x67   // ADP heading
#define   SBD_ADPS_p  0x68   // ADP pitch
#define   SBD_ADPS_r  0x69   // ADP roll
#define   SBD_ADPS_H  0x6f   // ADP parameter info
//---0x7 = isus  ---------------------------------
#define   SBD_ISUS_P   0x70   // ISUS pressure counts
#define   SBD_ISUS_RES 0x71   // ISUS residuals
#define   SBD_ISUS_NO3 0x72   // ISUS nitrate
#define   SBD_ISUS_SP  0x73   // ISUS spectral counts
#define   SBD_ISUS_ENG 0x7f   // ISUS engineering data
//---0xA = Acoustic Modem  -----------------------
#define   SBD_AcDATA   0xa0   // ACM data
#define   SBD_AcRAW    0xa1   // ACM raw data
#define   SBD_AcCMD    0xac   // ACM command reply/status
#define   SBD_AcDIAG   0xad   // ACM diagnostics
//---0xB = polyplus data -------------------------
/**** sep16, making polyplus obsolete, and using for zooGlider ***
#define   SBD_PP_CHAR  0x0b  // character to identify as polyplus
//--
#define   SBD_PP_PARAM 0xb0   // polyplus daq settings
#define   SBD_PP_LOAD  0xb1   // polyplus load values
#define   SBD_PP_VOLT  0xb2   // polyplus voltages cell_0
//                     0xb3   // cell_1
**************************************************/
//--- ZOOGLIDER ----- sep16 updated --------------
//--- for 0xb-, this byte is followed by another ID, which 
//--- allows data-type (P, intensity, ABS, etc), plus bin#, if needed.
#define   SBD_ZZ_CHAR  0x0b   // MSN zooglider value
#define   SBD_ZO_PARAM 0xb0   // zonar settings
#define   SBD_ZO_DAT1  0xb1   // zonar data beam 1
#define   SBD_ZO_DAT2  0xb2   // zonar data beam 2
// 0xb3 reserved
#define   SBD_ZC_PARAM 0xb4   // aug15 zooCam settings
//--- define the 2nd id byte MSN values: defines parameter type
#define   ZO_PR        0x10   // pressure
#define   ZO_AMP       0x20   // return amplitude
// 0xb5-7 available for zooCam data
// 0xb8-f available for other sensors that want to use another byte for further ID.
//------------------------------------------------

//---0xC = eng time series  ----------------------
#define   SBD_ET_Tm   0xc0   // eng-time-series time
#define   SBD_ET_Pr   0xc1   // eng-time-series pressure
#define   SBD_ET_Hd   0xc2   // eng-time-series heading
#define   SBD_ET_Pi   0xc3   // eng-time-series pitch
#define   SBD_ET_Ro   0xc4   // eng-time-series roll
#define   SBD_ET_Pc   0xc5   // eng-time-series pitch counts
#define   SBD_ET_Rc   0xc6   // eng-time-series roll  counts
//---others  -------------------------------
#define   SBD_RTE     0xd1   // route info
#define   SBD_WPT     0xd2   // waypoint info
#define   SBD_PARAM   0xd3   // dump of parameters
#define   SBD_DRIFT   0xd4   // drift mode packet
#define   SBD_PWR     0xd5   // motor power packet
#define   SBD_ECHO    0xde   // echo of shore command
//--0xE
#define   SBD_ENG     0xe7   // engineering packet
//--0xF
#define   SBD_ADG_HDR 0xf0   // auto-degas packet header, jun15
#define   SBD_ADG_DAT 0xf1   // various 1-D data arrays
#define   SBD_ADG_2D  0xf2   // various 2-D data arrays
#define   SBD_TEST    0xff   // test pattern


//===Flash Card Data-Type Tag Definitions =====================================
#define    SB '{'   // start-byte, = 0x7B = starts a data packet
#define    EB '}'   //   end-byte, = 0x7D = ends a data packet
// SB, EB chosen so close to max positive byte value=0x7F,
// so they are least-likely used, therefore most unique

// flash card packet ID follows the SB, where ea nibble is used
// MSN = packet type
// LSN = version #.
#define   CF_DIVE   0x0f   // dive marker
#define   CF_GPS0   0x00   // GPS record: 0=start-mission
#define   CF_GPS1   0x01   // GPS record: 1=start-dive
#define   CF_GPS2   0x02   // GPS record: 2=end-dive
#define   CF_GPS3   0x03   // GPS record: 3=end-mission
#define   CF_ABORT  0x06   // abort status record
#define   CF_SURF   0x08   // UBLOX GPS data, used for surface drift

#define   CF_PDAT   0x11   // 8s profile data , version 1 (no eng. inc.)
#define   CF_EDAT   0x21   // 8s eng. data, version 1 (to match PDAT)
#define   CF_PPDAT  0x2a   // mar11, 8s polyplus data, version 1 (get time from PDAT)
#define   CF_SBE    0x30   // SBE 1Hz data: NOT IMPLEMENTED
#define   CF_ADP    0x50   // ADP profile data
#define   CF_ALT    0x51   // ADP altimeter data
#define   CF_ADPS   0x52   // ADP shallow data
#define   CF_ADP_H  0x5f   // ADP parameter info
#if PH==1 //sep18--------------------------------------------------------
	#define   CF_PH     0x80   // pH sensor data
#endif //----------------------------------------------------------------
#define   CF_ACM    0xb0   // Benthos ACM messages
#define   CF_ZOOG   0xb4   // Zooglider struct param aug15
#define   CF_ZONAR  0xb5   // Zonar post structure
#define   CF_ACA    0xba   // Ascii annotation string (max 251 char)
#define   CF_CONT   0xcc   // continuation of the last record
#define   CF_DRIFT  0xd4   // drift structure
#define   CF_ENG    0xe0   // the eng. packet already contains it's version #
#define   CF_MOTOR  0xe8   // the last motor (pitch or roll) operation stats
#define   CF_HYD    0xf0   // the hydraulic structure
#define   CF_PWR    0xf4   // avg pwr for pitch, roll & hyd
#define   CF_SBD    0xf8   // SBD info
#define   CF_SPI    0xfd   // dec14: SPI comms error.
#define   CF_TEST   0xfe   // Test packet
#define   CF_END    0xff   // end-file marker

// ping-pong buffer definitions
#define   PP_BMAX   1024   // ping-pong buffer size = 2*write buffer
// flash is written when either bottom or top half is full
//=============================================================================
void   flash_dive_mark ( short ncyc );  // write dive, ncyc to the file
void   flash_eng       ( void );  // xfr the engineering data
void   flash_end       ( void );  // write end-of-file marker
void   flash_gps       ( short n );  // xfr the gps data
void   flash_hyd       ( void );  // xfr the hydraulic data
void   flash_drift     ( void  );
void   flash_surf      ( void  );
void   flash_pwr       ( void );  // xfr the avg pwr data
void   flash_sbd       ( void );  // xfr sbd info
void   flash_motor     ( void );  // xfr the motor stats
void   flash_zoog      ( void );  // aug15
void   flash_spi_error ( short k, short rstat );  // xfr the spi error stats
short  flash_store     ( short n,uchar c[], short pid); //* store packet

short  flash_open_file ( char c );  // opens a new file with 1st letter=c
void   flash_open      ( char c );
short  flash_close     ( void   );
short  flash_update_FAT( void   );
short  file_test       ( void   );
short  check_flash_file( void   );

short  write_ppbuf     ( short n, uchar *b );
short  write_pp        ( short n );
short  flush_pp        ( short n );
short  flash_store     ( short n, uchar d[], short pid );
void   flash_test      ( void );

//*****************************************************************************
// spray-specific functions, found in setup.c 
//*****************************************************************************
void     init_pins      (  void  );
void     backup_v7      (  void  );
short    go_lowpower    (  short irq_enable    );
short    hibernate      (  long *time, short dt, short irq_en );
void     hibernate_task ( void   );
short    sleep_check    ( short tmax, short PIT_set, short do_wdog);
short    check_tmo      ( char *c , short tmo );
void     Reset_CF2      ( void   );
void     init_accum_err ( void   );
void     init_serr      ( void   );
void     init_all       ( void   );
void     display_dbg    ( void   ); // dec14, see what changes after reset
void     init_sensors   ( void   );
void     toggle_verbose ( void   );
short    setup_tpu_uart_all ( void ); //jan13
short    setup_one_tpu_uart ( short i ); //jan13

//  compass heading limit prototypes
short ilimit360  (short i); // limit  so 0<=x <= 360
float  limit360  (float x); // limit  so 0<=x <= 360
short ilimit180  (short i); // limit so -180 <= i <= +180
float  limit180  (float x); // limit so -180 <= x <= +180
float  flt_abs   (float x); // return the abs value of x


// simplified trig fnx's, to save space and time ******************************
float  atan_find ( float yt, float xt );
float  asin_find ( float yt );
float  sin_find  ( float xt );
float  cos_find  ( float xt );
float  tan_find  ( float xt );


// fnx's to mimic TT8 calls ***************************************************
void     SerInFlush      ( void );
void     DelayMilliSecs  ( long ms );
void     tput            ( TUPort *tup, char *c );  // send str to TPU uart
void     tputs           ( TUPort *tup, char *c );  // & terminate w/CR-LF

short    tgets           ( TUPort *tup, char *c, short n, short s, 
                           short   eol, short *found );
short    tgetsTmax       ( TUPort  *tup,  char *str,  short n, short tmo, 
                           short   eol, short *found);
#define  NO_EOL  -2 // send eol=NO_EOL in tgets to mimic old tget

//*****************************************************************************
// general-use functions, found in setup.c 
short    fget_line      ( FILE *fp_in, char *s, short n);
short    YesNo          ( void );
short    hex2dec        ( char c );
short    get_num        ( short  *x );
char     ch_l2u         ( char   ch );
void     comma2blank    ( char *s   );
short    bswap          ( short  v  );
void     swap2ch        ( uchar *a, uchar *b);
void     swap4ch        ( uchar *a, uchar *b);
short    b2_store       ( short i, unsigned char ch[], short  w); // store short
short    b4_store       ( short i, unsigned char ch[], long   n); // store long
short    get_substr     ( char *str, char *out, short imax );
short    read_shorts    ( char *str, short imax, short *x  );
short    read_hexes     ( char *str, short imax, short *x  );
//*****************************************************************************
//*****************************************************************************

//*****************************************************************************
//*****************************************************************************
//***Mission configuration parameters are all stored as integers.
//   They are sub-divided into subsets as indicated by the first letter
//   SA_xxx are SET parameters, that are set from modules or eeprom variables,
//          and CANNOT be modified from the configuration file or remote commands.
//   IA_xxx are INTEGER parameters that CAN be modified by by
//          the configuration file plus shore commands.
// This enum serves as the address pointer into the  array
//*****************************************************************************
enum	Param_Addr
{   // these variables are linked to a 6-char name in a lookup table

    // SET ARRAY variables (see above)---------------------------------
    //   software/instrument config, dependent upon compiled version
	SA_major_ver,   // software version (for major revisions)
	SA_minor_ver,   // modification version (minor revisions)
	SA_shore_ver,   // shore command version
	SA_sensor_cfg,  // sensor configuration (CTD,ADP,ISUS,ACM, etc.)
	SA_gpio_ver,    // msp430 GPIO module software version
	SA_pitch_ver,   // msp430 PITCH module software version
	SA_roll_ver,    // msp430 ROLL module software version
	SA_hyd_ver,     // msp430 HYDRAULICS module software version
	SA_pr_off,      // sbe pressure offset
	SA_pr_gain,     // sbe pressure gain
	SA_temp_off,    // sbe temp offset
	SA_temp_gain,   // sbe temp gain
	SA_sal_off,     // sbe salinity offset
	SA_sal_gain,    // sbe salinity gain 
	// 0903 feb11, added up/down dt settings
	SA_dt_dn,       // time btwn samples on descent
	SA_dt_up,       // time btwn samples on ascent
	SA_END,         // end of the Set parameters
	
	// parameters that reside in eeprom
	EA_serno,       // Spray serial number
	EA_op_mode,     // operation mode of instrument
	EA_surf_num,    // surfacing# 0902
	EA_opt_gain,    // optical sensor gain
	EA_prof_num,    // profile number 0902
	EA_END,         // end of eeprom parameters
	

    // settings for pitch control -------------------------------------
	IA_pitch_0,     // pitch pot a/d value for ZERO pitch
	IA_pitch_xmt,   // pitch pot value for zero pitch with bladders full

	IA_pitch_10d,   // pitch  counts to move 10 degrees
	
	IA_pi_wdn,      // Minimum vertical velocity before pitching further down
	IA_pi_stat,     // Pitch sensor status:0=bad angle, 1=OK, 2=bad counts
	IA_pi_dn,       // pitch counts to use on way down.
	IA_pi_up,       // initial pitch counts to use on way up
	IA_pi_pmp,      // guess on change in pitch counts per 10 sec of pumping
	//msp430 values
	MA_pitch_min,   // minimum pitch pot a/d value
	MA_pitch_max,   // maximum pitch pot a/d value
	MA_pi_c2i,      // pitch a/d counts to milli-amps
	MA_pi_c2v,      // pitch a/d counts to centi-volts
	MA_pi_max_amps, // pitch motor max amps to allow
	MA_pitch_dcdt,  // change of pitch pot counts over 1 s interval
	MA_pi_sn,       // pitch module serial #
	MA_pi_ver,      // pitch module firmware version
	
    // settings for roll control --------------------------------------
	IA_roll_0,      // roll  pot a/d value for ZERO roll
	IA_roll_port,   // roll counts for port wing up
	IA_roll_stbd,   // roll counts for stbd wing up
	IA_roll_30,     // roll pot value for >30 degree roll at surface

	IA_roll_10d,    // roll counts to move 10 degrees

	IA_ro_use,      // TRUE if use the roll angle sensor for feedback.
	IA_ro_up,       // roll angle to go straight on  ascent
	IA_ro_dn,       // roll angle to go straight on descent
	IA_ro_rtau,     // roll divider for weighting the heading error.
	IA_ro_etau,     // roll divider for weighting the integrated error
	//msp430 eeprom values
	MA_roll_min,    // minimum roll  pot a/d value
	MA_roll_max,    // maximum roll  pot a/d value
	MA_ro_c2i,      // roll a/d counts to milli-amps
	MA_ro_c2v,      // roll a/d counts to centi-volts
	MA_ro_max_amps, // roll motor max amps to allow
	MA_roll_dcdt,   // change of roll pot counts over 1 s interval
	MA_ro_sn,       // roll module serial #
	MA_ro_ver,      // roll module firmware version
	
	// hydraulics settings  -----------------------------------------
	IA_min_pump,    // minimum pump time before start using the oil sensor
	IA_max_pump,	// max time to run the pump
	IA_buoy_pump,   // time[s] to run after neutrally buoyant @ bottom turn
	IA_delta_pump,  // time[s] to run when w_ascent<wmin
	IA_wmin_up,     // when w_ascent< wmin_up, run pump for delta_pump
	IA_max_amp,     // max amps (.01amp/cnt) for pump motor
	IA_amp_action,  // severity flag, decides action, if bad amps
	IA_oil_max,     // max oil sensor counts before shutting off the pump
	IA_pmp_50m,     // dec14, add ability to change pmp time @ 50m
	// vent control
	IA_cntl_vent,   // sets control action for the air vent
	IA_tm_vent,     // Max time to run the vent
	//msp430 settings
	MA_hyd_c2i,     // hyd a/d counts to milli-amps
	MA_hyd_c2v,     // hyd a/d counts to centi-volts
	MA_hyd_sn,      // hyd module serial #
	MA_hyd_ver,     // hyd module firmware version
	
	
	// navigation parameters ----------------------------------------
	IA_num_route,    // Number of waypoints in the route
	IA_route_now,    // route index to head for NOW
	IA_route_end,    // Action at the end of route
	IA_route_dir,    // direction to proceed through the route (fwd or reverse)
	// route list is stored separately
	
	//compass settings: 
	IA_mag_var,		 // magnetic variation
	IA_use_moff,     // set = TRUE to use the in-house cal, else defaults to TCM2
	IA_moff_x,       // Offsets for magnetometers, x axis
	IA_moff_y,       // y axis
	IA_moff_z,       // z axis
	
	//steering control ----------------------------------------------
	IA_use_set,		 // use set in waypoint calculation
	IA_cross,        // angle to cross the current
	IA_set_nprof,    //  last dive # to cross the current
	IA_set_min,      //  set min angle correction allowed
	IA_set_max,      //  set max angle correction allowed
	IA_man_theta,    //  manual steering, course to steer
	IA_man_nprof,    //  last dive # to use manual heading
	IA_steer_pt,     // steering point [km] to head for.
	IA_steer_nprof,  // last dive # to use the steering point
	
	// primary mission parameters -----------------------------------
	IA_miss_id,      // mission id
	IA_nprofs,		 // number of profiles to do
	IA_first_zmax,	 // max depth for first dive
	IA_zmax,		 // max depth to dive
	IA_max_dive_tm,  // max time, minutes, to dive, one-way
	IA_num_avg,		 // number of points to average
	IA_glide_angle,  // glide pitch angle
	IA_drift_tm,     // minutes to drift at the bottom
	IA_drift_ns,     // # of samples to take in drift mode
	IA_drift_pmp,    // 0903 feb11, #s to pump before entering drift mode
	
	// timing parameters --------------------------------------------
	IA_gps_tm,	 	 // minutes to try GPS
	IA_argos_tm, 	 // minutes to beacon in abort
	IA_min_xmit_tm,  // minimum minutes between surface xmit try
	// mission start-up parameters ----------------------------------
	IA_delay_start,  // time (minutes) to wait before start mission
	IA_try_start,    // #minutes to try the roll water detect
	IA_try_press,    // #hrs to look for p>5 dBar as signal to start
	// sbd timing
	IA_sbd_max_tm,   // max s to try to transmit all SBD packets
	IA_sbd_pack_tm,  // max time to wait to send 1 packet
	
	// exception control --------------------------------------------
	IA_no_gps,       // action to take when no gps fix
	IA_abort_max_sat,// hrs before deciding to abort
	IA_abort_max_gps,// hrs to decide gps is broken
	IA_pmp_rcvry,	 // severity vector if there are pump problems
	IA_sbd_rcvry,    // recovery action if no SBD comms
	IA_max_reset,    // Max #spurious resets before going to the abort code
	IA_argos_mult,   // value*5=minutes to turn on Argos for ea surfacing
	IA_abort_pump,   // flag=1 means to pump again when in the abort mode
	
	// sensor settings ----------------------------------------------
	IA_use_opt,      // use optical sensor, or ignore
	IA_use_alt,		 // use altimeter
	IA_alt_z_1st,    // first depth to start using the altimeter
	IA_alt_z,        // distance from bottom to turn around
	IA_eng_ndec,     // For eng. time series, decimate 8 s sampling by this much
	IA_eng_mask,     // bit mask determines which eng. data to return.
	IA_wing0_GPS,    // wing to use for GPS
	IA_wing0_SBD,    // wing to use for SBD

	// Doppler settings ----------------------------------------------
	IA_adp_zmax,     // max depth to start collecting adp data
	IA_adp_ncell,    // # of cells to process per ensemble
	IA_adp_cellsize, // cell size, in m
	IA_adp_pulse,    // pulse length, m
	IA_adp_minsnr,   // minimum snr to allow when averaging data
	IA_adp_nsh,      // # ensembles to avg in shallow mode
	SA_adp_k1,       // First bin to use for acoustic-backscatter avg
	SA_adp_k2,       // Last bin to use for ABS avg
	SA_adp_bd,       // blanking distance ( [m]*10 )
	SA_adp_alpha,    // attenuation coeff at 750 kHz

	//NTK settings ---------------------------------------------------
	IA_ntk_zmax,     // max depth to do NTK
	IA_ntk_nc,       // # of cells
	IA_ntk_cs,       // cell size
	IA_ntk_tmDZ,     // sub-sampling in depth(dz) for SAT msg
	IA_ntk_tmCD,     // cell averaging for packing into SAT msg
	IA_ntk_sr,       // =seconds per wakeup and burst sample.	
	IA_ntk_fwd,      // TRUE if the Nortek beam 1 is FORWARD (marked w/arrow)
	                 // IF beam 1 is forward, then serial connector is facing aft.
	                 // (=original 2013 orientation: beam 1 facing aft, ee_ntk_fwd=0 )
	
	// MSP430 Watchdog settings --------------------------------------
	MA_wdt_action,   // action to take when tmo is reached
	MA_wdt_attn,     // #of seconds before setting the CF2_ATTN line low
	MA_wdt_cf2_rst,  // #of s before resetting the CF2
	MA_wdt_430_rst,  // #of s before resetting itself
	MA_wdt_mult,     // multiplier for all of the time above
	                 // i.e. in the lab, could be set to large #
	// MSP430 Watchdog Analog settings -------------------------------
	MA_wdt_c2v_14,   // 14V a/d counts to centi-volts
	MA_wdt_c2v_07,   // 07V a/d counts to centi-volts
	MA_wdt_c2vac,    // vacuum a/d counts to in-Hg
	MA_wdt_Voff,     // vacuum a/d counts offset
	MA_wdt_c2mv,     // generic cnts to mV
	// oct14: MSP430 Watchdog/GPIO s/n, firmware version
	MA_wdt_sn,       // gpio module serial #
	MA_wdt_ver,      // gpio module firmware version

#if BENTHOS==1 || NPS==1
    IA_acm_tm,       //mins for acoustic comms replaces drift_ns
    IA_acm_try,     // number of retries of Ac Modem packet
    IA_acm_binc,    // 0=no blk auto-inc,1=auto-inc, 2=skip 1 blk
    IA_acm_rmdly,   //secs delay betw waits for REM to be idle (60ish)
    IA_acm_mxtry,   //max tries to start an transfer in XferBlk or XferSbBlk
    IA_acm_mode,    // 0=no ac comms, 1=@bottom, 2=@surface
    IA_acm_dpth,    // depth at which to start comms at surface (only)
    IA_acm_lxmt,    // xmit power level of Local modem
    IA_acm_ptch,     // pitch pack position during acoustic comms
#endif
    // jun15 auto-degas variables.
    IA_adg_ncycle,   // # of outer cycles to do for auto-degassing
    IA_adg_incr,     // # of inner cycles
    IA_adg_modulo,   // modulo of ncycle; used to decide when to send back data.
	IA_END // end of IA_Addr
};
//*****************************************************************************

#define MAX_PARAM (IA_END+1)  // max # of parameters allowed
#define LKNAMSIZ 7  //characters in name in lookup table
// define the parameter-set status
#define SET_NO        0  // no mods allowed externally (from config or shore).
#define SET_EE        1  // set by eeprom value
#define SET_ME        2  // MSP430 eeprom...must be set via different fnx
#define SET_OK        3  // OK to modify from shore or config file
#define SET_NV        4  // OK to modify the non-volatile value
// for future implementation??
//#define SET_DEFAULT   4  // has been set to the default setting.
//#define SET_CFG       5  // has been set by the config file
//#define SET_SHORE     6  // has been reset via a shore command.

#define NO_VEE_VAL -99L  // returned value if EE name could not be found

struct lookup
{ char name[LKNAMSIZ]; // ascii string name linked to the address list
  short addr;          // address, from above
  char group;          // group id linked to the name: SET by an external file
  short set_type;      // status of the variable.
  short x0;            // default value, in case the file is corrupted.
  short imin;          // min allowed value
  short imax;          // max allowed value
  char    c1;          // main command
  char    c2;          // sub-command
  char    i1;          // argument index in command
  char label[22]; //label, for display purposes
};

//*** shore command error definitions
#define CMD_OK    0  // command correctly parsed
#define CMD_NO    1  // command was not found - unknown
#define CMD_NARG  2  // command has incorrect #arguments
#define CMD_BOUND 3  // at least one value is out of range
#define CMD_WRITE 4  // error trying to assign new values
#define CMD_NO_FNX 5 // no function defined to parse this command
#define CMD_ROUTE 6  // error with the route
#define CMD_ADDR  7  // no addr for CMD 2

struct shore_cmd //============================================================
{ // shore command info structure
  char       cmd; // main command character
  char       sub; // sub-command character
  char       fnx; // =0 if the command is parsed by using the Param_table
                  // =1 if also requires additional logic checking
                  // =2 if requires a specific fnx and NO FURTHER parsing
  char     group; // group character
  short     imin; // minimum # of inputs
  short     imax; // maximum # of inputs
  char label[22]; //label, for display purposes
};

struct group_param //==========================================================
{ // parameters for each group id = type of parameter
  char   group; // group ID char
  char  label[30]; // label
};

// prototypes for handling lookup tables ======================================
short   set_default_param(  void   ); // oct14, return file error value
void    set_eeprom_param ( short j, short k, short n );
void    set_op_mode      ( short n );
void    set_surf_num     ( short n );
void    set_prof_num     ( short n );
short   incr_surf_num    ( void    );
short   incr_prof_num    ( void    );

short   find_name     (  char name[],  struct lookup *t );
short   find_addr     (  short addr,   struct lookup *t );
short   find_name_addr(  char name[],  struct lookup *t );
void    display_info  (  short addr,   struct lookup *t );
void    fill_name     (  char *in, char *out );
short   check_nshore     ( void    );

void    modify_group     (  struct lookup *t );
void    display_all      (  FILE *fp, struct lookup *t );
void    display_group    (  FILE *fp,  short g,      struct lookup *t );
short   change_param     (  short j, short x, short f, struct lookup *t, short d );
short   change_name_param(  char name[],  short x, struct lookup *t );
void    lifo_store_param (  void );
void    change_miss_id   (  short j, struct lookup *t );

// prototypes for handling files ---------------------------
short   write_config      ( short n  );
void    write_header      ( FILE *fp );
short   read_config       ( short n , short f );
short   read_cfg          ( FILE *fp, short f );
FILE*   open_sco          ( void     );

// prototypes for handling shore commands ------------------
void    display_shore_cmd ( void );
void    display_cmd       ( char c0, char sub );
short   test_shore_cmd    ( void );
short   parse_cmd         ( char str[] );
short   check_passwd      ( short x );
short   cmd_2             ( short sub, short narg, short x[] );
short   cmd_6             ( char *ch ); // parse cmd '6' for Benthos ac modem
short   cmd_7             ( short sub, short narg, short x[] );
short   parse_waypt       ( short sub, char str[] );

// mar11, add parsing of polyplus shore commands
#if PPLUS==1
short   cmd_O_            ( short narg, short x[] );
short   cmd_O1            ( short narg, short x[] );
#endif

#if ZOOG==1
  short   cmd_F2          ( short narg, short x[] );
  short   cmd_F3          ( short narg, short x[] );
#endif

void    test_param        ( void );
//============================================================================


//*****************************************************************************
//*****************************************************************************
// structures 
// structures are used as the primary method to pass data and information
// between all functions.
// After all of the function and module-specific structures, there is one
// overlying structure, 'all', which contains pointers to the rest of
// the specific structures.
//*****************************************************************************

//=== structure with info for the latest SPI communication ================
#define N_SPI_MAX  280   // max number of bytes in a message
     // data length is constrained to 255 bytes, so 280 is overkill
struct spi_param 
{
  short pcs;       // peripheral-chip-select to use
  short nbyte ;    // number of total bytes in the message <255
  short nhex  ;    // number of total hex characters in the message = nbyte*2
  short crc;       // received CRC value
  short ip;        // pointer to the next byte to send/receive
  short pstat;     // parsing status
  short qstat;     // receive module message-queue status (used in slave code only)
  short motor_ph;  // phase of exercise of motor,used for display purposes

  
  uchar  mdat[  N_SPI_MAX]; // data packet to send
  uchar  mhex[2*N_SPI_MAX]; // hexadecimal format of data packet (ready to send)
  uchar  shex[2*N_SPI_MAX]; // hexadecimal format, received while mhex is sent
  uchar  sdat[  N_SPI_MAX]; // shex converted to binary

}; //======================================================================

struct tpu_uart // defines TPU serial port parameters =====================
{ 
  short     rxch;	// receive  channel, = TPU 1 - 15
  short     txch;	// transmit channel, = TPU 1 - 15
  long      baud;	// baud rate for both rcv and xmt
  TUPort    *tup;	// port handle for TU calls : TU = TPU UART
}; //======================================================================

#define MAX_HCAL 90 // max #points in the compass correction lookup table
struct compass_param //====================================================
{ // defines the compass values
  float     head;   // compass heading
  float     pitch;  // compass pitch angle
  float     roll;   // compass roll  angle
  short     err;    // error code with getting compass value
  
  short      dh;    // heading increment into the correction table
  short     num;    // #points in the calibration table
  short     hcal[MAX_HCAL][3]; // calibration correction table
}; //======================================================================

//=== time structure ======================================================
struct time_param
{ // keep track of UX time of various events
  long  ti_last_sbd;        // UX ti of last SBD transmit
  long  ti_last_gps;        // UX ti of last good gps
  long  ti0;                // UX ti of start-of-dive-set
  long  ti_cyc;             // UX ti of present cycle (0902)
}; //======================================================================

//=== data structure for GPS ==============================================
struct  gps_param  
{ // template for gps parameters
  short     nsurf;      // surfacing# stamp for flash card
  short     valid;      // 1 if valid, 0 if not
  short     time;       // #of seconds/10 to acquire fix
  short     lat_sign;   // = +/- 1 for sign of latitude, >0=north
  short     lat_deg;    // degrees of latitude  (unsigned)
  float     lat_min;    // minutes of latitude
  short     lon_sign;   // =+/- 1 for sign of longitude, <0 = west
  short     lon_deg;    // degrees of longitude ( unsigned)
  float     lon_min;    // minutes of longitude
  short     utc_hr;     // hrs  universal coordinated time
  short     utc_min;    // minutes
  short     utc_sec;    // seconds

  short     gps_week;   // gps week number, 1024=22Aug99
  short     gps_day;    // day-of-week, 0..6 : 0=Sunday
  short     nsat;       // #satellites used in fix
  short     smin;       // min signal strength
  short     savg;       // avg signal strength
  short     smax;       // max signal strength
  short     hdop;       // hdop *10

  float     xlat;       // present latitude
  float     xlon;       // present longitude
  float     olat;       // last latitude
  float     olon;       // last longitude
  short     ovalid;     // true if last lat, lon was valid
  short     wing;		// wing used for gps fix
}; //======================================================================

struct ublox_param //======================================================
{ // ublox gps info kept at higher precision for surface drift calcs
  short  valid[2];  // flag of whether the fix is valid
  long     lat[2];  // scaling = 1e-7
  long     lon[2];  // scaling = 1e-7
  long      ti[2];  // ux sec.
  short     index;  // index (0 or 1), used to set which index to use 
  short        dx;  // x component surf drift, 1m per count
  short        dy;  // y component surf drift, 1m per count
  short        dt;  // time difference over drift
  short n_used[2];  // #sats used in the fix; nov11, for post-processing
}; //======================================================================

struct pwr_param //========================================================
{ // stores the avg watt & time a module ran per dive
  short watt[4]; // hyd, pitch, roll
  short   ti[4];
  short      v7; // 7V battery level
  short     v14; // 14V battery level
}; //======================================================================

//===data structure for navigation info====================================
#define MAX_WAYPTS 40 // max #waypoints that can be defined, including HOME
//===data structure for waypoint info
struct s_waypt {    // template for a single waypt in route
  float lat;        // latitude, decimal degrees
  float lon;        // longitude, decimal degrees
  short valid;      // flag that this waypoint has been set.
}; // end s_waypt

//***data structure for Route info
struct route_param {// template for route parameters
  /* npts, now, end, dir are stored in the global iparam[]
  short  npts;      // =#points in route
  short  now;       // =current waypoint to go to
  short  end;       // determines action when now=npts = end of route
  short  dir;       // direction through route (fwd/reverse)
  */
  short valid;      // = 99 if route has been set: used to catch power resets

  short rlist [MAX_WAYPTS];  // indices point waypt[] to define the route
  short blist [MAX_WAYPTS];  // list of approach bearings to ea route waypoint
  short detect[MAX_WAYPTS];  // arrival detection
  short circle[MAX_WAYPTS];  // watch-circle radius
}; // end route_param

struct nav_param  { // template for navigation parameters

  float wlat;       // present waypoint latitude, decimal degrees
  float wlon;       // present waypoint lon.
  float owlat;      // old (last) waypoint
  float owlon;      // old (last) waypoint longitude
  float range;      // range between old and present waypt
  short bear;       // approach bearing, used to decide if at the waypt
  short sbear;      // route-line bearing, used for steering pt calcs
  
  float xlat;       // present latitude
  float xlon;       // present longitude
  float olat;       // last latitude
  float olon;       // last longitude
  short ovalid;     // true if last lat, lon was valid
  short bad_gps;    // direction to head if bad gps fix:-1=circle

  float drx;        // dead-reckoning x distance, m
  float dry;        // dead-reckoning y distance, m
  short theta;      // direction to travel, 0-360 : if<0, circle
  short true_theta; // TRUE, not magnetic, value
  float dr;         // range to waypt, in km
  short home;       // last known direction to head to get home

  struct route_param  *route;  // point to route parameters
  struct     s_waypt  waypt[MAX_WAYPTS]; // allow up to 20 waypoints
}; //======================================================================

//=========================================================================
//*** structure for flight control
struct flight_param {
  ushort pmin;      // =approx counts @ surface
  float  tau;       // = time constant for heading error dh
  float  etau;      // time constant for integrated error esum
  short  esum;		// integrated error sum
  short  isum;      // 0902.5 feb11; #points accum. in esum
  float  ediv;      // feb11; actual etau used after shore-cmd adjustment
  float  em;        // feb11; if =0, then etau is not used in PI loop
  float  rm;        // feb11; if =0, then etau is not used in PI loop
}; //======================================================================


/*=== structure for mission control =======================================
struct miss_param {
  //short idive;      // =dive # we are now on
  //short ndives;     // =#dives to do
  //short dt;         // #secs between sample & store
  //short pmp1;       // #secs to pump deep, at bottom turn
}; //====================================================================*/

#define N_BZ 4 // # of points to keep track of bottom depth (BZ)
// struct for all exception parameters ====================================
struct except_param {
  short  n_reset;   // dec14: moved here: #of times that has had abnormal reset
  short reset;      // reset flag, used to gracefully reset
  short abort;      // flag, used to abort if a problem is found
  short pgood;      // flag TRUE means pressure is good
  short exc_stat;   // exception bit-status register
  short gps_abort;  // TRUE if gps is bad enough to abort route
  short sbd_bad;    // feb12: TRUE if sbd is broken enough to be bad
  short nose_down;  // Pitch down for argos in abort mode
  short rfx;        // Argos multiplier in abort mode
  short gps_cold;   // dec11, gets set remotely if want to do GPS cold-reset
  short bz[N_BZ];   // array of last N_BZ bottom depths
  short serr[5];    // accum of SPI comms errors for different cs
  short sbe_err;    // oct14 added, for more complete error reports
  short  wdog_error;// dec14 failure of the wdog circuit
}; //======================================================================

struct eng_param //========================================================
{ // parameters for engineering data. 
  // since the structure is essentially transmitted directly,
  // the parameters must be kept to word boundaries to aid unpacking on shore
  char  dum1;		// dummy byte to get isu_type on even boundary.  
  char  isu_type;	// first char = isu identifier
  short nbytes;     // #bytes in the eng_param structure
  short zmax;		// max depth of dive
  short alt;		// altimeter counts at turning depth
  short bat;		// avg battery a/d counts in bottom turn
  short	current;	// avg current a/d counts in bottom turn
  short psurf;		// feb04 avg surface press at the start of the dive
  short pitch;		// pitch, degrees, of dive
  short head;		// heading steered
  short drx;		// dead-reckoning in the x direction
  short dry;		// dead-reckoning in the y direction
  short ydeg;		// way-point degrees latitude
  short dy;			// way-point fractional latitude  x 1000
  short xdeg;		// way-point degrees longitude
  short dx;			// way-point fractionsal longitude x 1000
  char  n_badamp;   // #times had too high of current, jun06 moved to old MSB of navg
  char  navg;		// #points averaged for profile (changed to char jun06)
  short ti_pump;    // pump time, msbyte = pump deep going down, lsb=total ti.
  short vac;        // vacuum a/d counts 
  short iprof;      // 0902 present profile number
  short ncyc;       // 0901 present cycle #: WAS old mission id
  short max_amp;    // time/10 (msb) + max amps (.02 res, lsb) during bottom turn
  char  r_err;      // jun06 : accumulated roll error (was old n_badamp byte)
  char  t_SBD;      // time trying to get SBD message through, [s]

  char  ntries;       // #connect tries from the LAST dive
  char  nsent;		  // #packets sent from the LAST DIVE
  
  char  sbdi_stat;    // SBDI= out-bound transmission status: wing in upper nibble
  char  sbd_shore_stat;  // status of parsing a shore-command
  
  short exc_stat;      // exception status word
  short surf_tm;       // time to leave the surface to 2m depth
  short z_at_alt;      // 0711, depth at altimeter reading
  short vent;          // 0711, air vent status
  char  end;		  // end character for isu packet
  char  dum2;         // end on even-boundary
}; //======================================================================

struct drift_param //======================================================
{  // 0711 data from drifting at the bottom
  short tm;           // drift time
  short nsamp;        // # of P samples to take
  short p0;           // start pressure
  short pavg;         // avg pressure
  short pe;           // end pressure
  short pmp_tm;       // amount pumped
}; //======================================================================

//  LIFO structure for SBD packets ========================================
#define MAX_SBD_OUT 1960  // max #bytes to output in SBD message
#define MAX_SBD_IN  1890  // max #bytes in incoming SBD message
#define LIFO_NBYTE  2048  // make ea LIFO 'sector' this size, >max_SBD
#define NSECTORS      40  // max #LIFO-sectors to store in RAM

struct lifo_param   //=====================================================
{ // template for LIFO parameters
  short nbytes[NSECTORS]; // #bytes of data in packet
  short   stat[NSECTORS]; // status of packet (0=sent with no errors,etc)
  short   dive[NSECTORS]; // dive # of packet
  short     ip[NSECTORS]; // individual packet id
  short   ntry[NSECTORS]; // =#transmit tries
  uchar *buf;             // pointer to the data buffer area
}; //======================================================================

//=== data structure for SBD Iridium modem ================================
struct sbd_param 
{ // template for sbd parameters
  short nsent;		// = #packets sent in last surface session
  short ntries;		// = #tries to connect
  short t_SBD;      // = time spent trying to transmit
  long  t_start;    // = unix start time
  long  t_end;      // = unix end time

  // the following are the returned status from the SBDI command
  short SBD_mtque;     // = # of MT messages (incoming) waiting in queue
  short SBD_mtstat;   // MT = Mobile-Terminated (incoming) status
  //short SBD_mostat; // MO = Mobile-Originated status
  //long  SBD_momsn;  // MO sequence #, set by the ISU
  //long  SBD_mtmsn;  // MT sequence #, set by the earth server system

  // flags for sending other info
  short send_waypts; // if TRUE, send the waypoint list
  short send_param;  // if TRUE, send the parameter list
  // flag to save files
  short save_waypt; // if TRUE, save the waypoint list to file
  short save_route; // if TRUE, save the route list to file
  short calc_route; // if TRUE, recalculate the route params
}; //======================================================================



//=== hydraulic pump data structure =======================================
// needs updating for the new hyd module
struct hyd_param {
  short status;  // Pump status
  short ti;      // time [s] that has run in the present cycle
  short total;   // = total time pumped [s]: accumulates 
  short amp;     // last measured amps [cnts]
  short volt;    // last measured volts [cnts]
  short oil;     // last measured oil sensor value
  short max_amp; // max amps*100 = a/d count: 200 = 2 amps
  short ti_max;  // ti of max amp
  short  watt;   // avg watts[0.01 watt/cnt]
  short vac;     // vacuum reading
  short bad_amp; // flag=TRUE if we've exceed the expected amperage 
  short nbad;    // counter of #bad amps 
}; //======================================================================

// data structure : has scientific and engineering sensor information
// 0612, there are now the following RAM buffer areas:
// *dat points to Scientific ascent-profile data arrays, which includes
//      t, P, T, S, O, and sbe_flag = 6 sensors = 12 bytes per scan
// *eptr points to engineering data, if requested by shore command
//      t, P, H, Pi, Ro, P_Pot, R_Pot = 7 sensors = 14 bytes per scan
// DATA_SIZE = size for scientific profile data: 1 word per sensor
// >BF you want to add O2, Opt2 to SCI, so set DATA_WORDS to 8

#if ISUS==1  // then it is an ADP-ISUS, and we're doing 500m profiles
   #define DATA_SIZE 20000  // only half as far
#else // don't need to scrimp on size
   #define DATA_SIZE 40000  //size, bytes for data storage 
#endif
// 40000 / 12 = 3333 scans * 8 s = 7.4 hr ascent = 4.5 cm/s from 1200 m
// >BF 3333*16 bytes : set data_size to 54000
// ----------

#if DOX==1 || DO6==1 // Using DOX: set DATA_WORDS to 7
   #define DATA_WORDS 7 // #profile words to write out in ea data record
#else
   #define DATA_WORDS 6 // #profile words to write out in ea data record
#endif
struct dat_sensor //=======================================================
{ // list of all data sensors to store to RAM while profiling
  // this is then post-processed at the end for SBD transmission
  ushort secs;      // # secs since start of dive
  ushort p;         // press 16bit a/d counts
  ushort t;         // temp 16bit a/d counts
  ushort c;         // cond/salinity  16bit a/d counts
  short  optic;     // optical sensor
  #if DOX==1 || DO6==1
    short d;        // mar11 include dissolved oxygen
  #endif
  short  nsbe;       // 1=TS is valid, 0=not taken (not in profile mode)
  //below goes to CF card only
  #if DO6==1
    short dT,dU;  // jul 13 include SBE63 dissolved oxygen
  #endif  
}; //==========================================================================

// define params for the engineering time-series data
#define EDAT_SIZE 10000  // engineering buffer area, bytes
// 10000 / ( ET_WORD*2) = 500 scans: this sets the decimation for a full dive:
// 500m dive takes ~ 3hrs; if decimate by 4=32s, 500*32s = 4.4 hrs, OK
// 1000m dive takes ~8 hrs max: decimate by 8=64s = 8.8 hrs,OK
#define ENG_WORDS 11 // #words in the eng_sensor struct
#define ET_WORDS   5 // for engineering time series (ET), use first 5 only
struct eng_sensor //=======================================================
{ // list of all eng sensors to store to RAM at approp. decimation
  // secs and p are also stored.
  // at end of dive, this data is packed for eng. time-series for SBD
  short  comp;       // compass, degrees
  short  pitch;      // pitch, degrees
  short  roll;       // roll, degrees
  short  ad_pitch;   // pitch counts
  short  ad_roll;    // roll counts
  short  ad_bat_14;  // 14V battery pack Volts counts
  short  ad_current; // Hydraulic pump current counts
  short  ad_oil;     // Hydraulic oil sensor
  short  ad_bat_07;  // 7V battery pack
  short  ad_alt;     // altimeter
  short  eng_err;    // error flag avail for recording problems
}; //==========================================================================


struct dat_param //========================================================
{  // data structure to store to ram
  short i;           // points to next profile output index
  short max;         // max #pts in the profile data
  short *dat;        // points to the profile data buffer
  
  // buffer area for engineering time series
  short isamp;       // #samples counter; used for eng. data dec.
  short ie;          // points to the next engineering data index
  short emax;        // max #pts in engineering scan
  short *eptr;       // points to engineering data buffer
  
  short nrec;        //  #data pts per profile record = DATA_WORDS
  short sbe_pro_on;  //  flag that SBE is profiling (take TS data!)
  
  short  take_adp;   //  TRUE if we want to take ADP data
  float  p_adp;      //  pressure to take the next ADP sample
  
  float  dbar;       // JAN06 dBar pressure
  float  ftemp;      // oct08, temperature, as float (used by ISUS)
  float  fsal;       // oct08, salinity, as float (used by ISUS)
  
  struct dat_sensor ds; //present sensor scan values (gets stored to flash).
  struct eng_sensor es; //present sensor scan values (gets stored to flash).
  
}; //==========================================================================

#define ADP_NCELL 5 // MAX # of cells(range bins) to sample, max val=5, min val=1
#define ADP_NSCANS 140 // MAX SCANS allocated, this # assumes 140 4 m bins to 560 m
// ADP_NSCANS=160 TESTED OK FEB06 : used for array sizes in _adp_post_process
// if too large, the call to _adp_post_process will try to allocate too much memory
// and will cause the TT8 to hang up in a serious way
// oct08, lowered from 150 to 140 after adding ISUS as well, to allow more overhead

// apr13, allow Nortek to redefine to a larger buffer area
#if NTK==1 // Nortek instead of Sontek
  #undef  ADP_NSCANS
  #define ADP_NSCANS 255 // 250*4m = 1km max depth range (1020m actual)
#endif

//---for the Nortek, we also need to define the max #input cells
#define NTK_NCELL  20   // MAX # of INPUT cells(range bins) to sample, max val=20, min val=1 
//---above needs to be outside #if so compiler doesn't complain w/ntk.c
//---when compiled with NTK==0

struct adp_param //============================================================
{
  short pmax;		// max pressure to sample the ADP, dBar
  float pmin;		// min pressure that the ADP was sampled
  //float dp;			// sample ADP every dp dBar
  short nscans;		// max #scans (ensembles) allocated in the buffer array
  short iscan;		// present scan to write out
  unsigned char  *buf;		// points to the data buffer area
  short amin[3];    // array with min amps for ea beam (=noise floor levels)
  short  on_adp;     // JAN06 TRUE if the ADP is on
  short alt_db;     // last detected bottom altimeter [counts]
  short alt_z0;     // meters from the bottom
}; //==========================================================================

//***structure for NORTEK ADP (NTK) sensor  JAN2013 ***************************
struct ntk_param {

  //aug14 add beam mapping ability
  short   FWD;
  short   PORT;
  short   AFT;
  short   STBD;
  
  //PLAN
  //short    micp;	//Profile interval(s) -- moved to eeprom
  /*following plan variables hardwired
  short    cp;      //current profile disabled/enabled
  short    burst;	//burst measurement disabled/enabled
  short    miburst;	//burst interval(s)
  short    fn;      //filename of the raw data (should be prof#.BRT)
  short    so;      //serial output*/
  
  //CLOCK
  short	   yy;
  short    mm;
  short    dd;
  short    hr;
  short    mn;
  short    ss;
  
  // TM = telemetry //just used to turn off!
  short    sd;		//store bin data - descend
  short    sa;		//store bin data - ascend
  short    cd;        //cells divisor
  short    pd; 		//packet divisor //*/
  
  //CP
  //short    nccp;  	//# of cells -- moved to eeprom
  float    cscp;	//cell size (m) 0.5-2.0 --keep for float
  //float    plcp;    //power level (is this really a float? need to ask) not implemented yet
                      //will probably want in eeprom anyway
  
  /*BURST //not used
  short    ncb;		//# of cells
  short    nbb;		//# of beams
  float    csb;		//cell size (m) 0.2 - 4.0
  float    bdb;     //blanking distance
  float    plb;     //power level
  short    srb;     //sampling rate (Hz)  1-8
  float    vpb;     //velocity precision
  */
  
  //18MAR
  //packet header
  unsigned char  sync;
  unsigned char  hdrSize;	
  unsigned char  ID;
  unsigned char  family;
  unsigned short dataSize;     
  unsigned short dataChecksum; 
  unsigned short hdrChecksum;
  
  //data
   unsigned char  	version;
   unsigned char  	offsetOfData;
   unsigned char    config;
 /*  struct  {
      unsigned char  	press        : 1; // 0
      unsigned char  	temp         : 1; // 1
      unsigned char  	compass      : 1; // 2
      unsigned char  	tilt         : 1; // 3
      unsigned char  	_empty       : 1; // 4
      unsigned char  	velIncluded  : 1; // 5
      unsigned char  	ampIncluded  : 1; // 6
      unsigned char  	corrIncluded : 1; // 7
   } headconfig;//*/
   unsigned long    serialNumber;
   unsigned char  	year;
   unsigned char  	month;
   unsigned char  	day;
   unsigned char  	hour;
   unsigned char  	minute;
   unsigned char  	seconds;
   unsigned short 	microSeconds100;
   unsigned short 	soundSpeed;
   short 		    temperature;
   unsigned long 	pressure;
   unsigned short 	heading;
   short            pitch;
   short            roll;
   unsigned short 	beams_cy_cells;
   unsigned short 	cellSize;
   unsigned short 	blanking;
   unsigned short 	velocityRange;
   unsigned short 	battery;
   short            magnHxHyHz[3];
   short            acc13D[3];
   unsigned short   ambVelocity;
   unsigned short   transmitEnergy;
   unsigned short   DataSetDescription; 
   char   		    velocityScaling;
   char             powerlevel;
   short            magnTemperature;
   short            rtcTemperature;
   unsigned short 	error;
   unsigned short 	status;
   unsigned long    ensemblecnt;



   unsigned char  	ncell; // mar13 changing from pad to ncell
   signed short 	data_vel[4][NTK_NCELL]; //4 beams max, 30m * 0.5m bins = 60 bins max
   signed short 	data_amp[4][NTK_NCELL]; //4 beams max, 30m * 0.5m bins = 60 bins max
   signed short 	data_cor[4][NTK_NCELL]; //4 beams max, 30m * 0.5m bins = 60 bins max
   
   float            Vscale; // = 10^velocityScaling (m/s)

  
}; //**************************************************************************

#if PH==1
#define N_PH_OUT 6 // Number of ph sensor values to send back
#define PH_NSCANS 3333 //see DATA_WORDS calc.  
#define PH_V_OFFSET 2.6
struct ph_param  //structure for ph data
{ 
  short i; 				//sample index
  short max;         	//max #pts in the profile data
  ushort secs;          //# secs since start of dive
  ulong s_no;           //sample number
  short hum;            //board humidity
  short phv1;
  short phv2;
  short phv3;
  short phv4;
  short phv5;
  short phv6;
  
  unsigned char  *buf;		// points to the data buffer area
  
}; //end ph_param
#endif

//=== global structure for last motor run
struct motor_stat // ==========================================================
{ // stats of the last motor operation
  short cs;        // chip-select (either pitch or roll )
  short result;    // final result of the operation
  short pot_start; // pot at start of operation
  short pot_stop;  // pot at the end
  short amp;       // avg amps
  short volt;      // avg volts
  short ti;        // time [0.1s] that it ran
  short limit;     // limit sw status (1=open)
}; //==========================================================================

//define Polyplus cell parameters
#define PP_LMAX 4 // max # of valid load settings per dive
//each cell will store (load,a/d_val) to RAM for SBD packing
// each record = (load, a/d_val ) = 2 shorts = 4 bytes
//PP_MAX_REC = #records for each cell: 1000 readings = 4000 bytes
#define PP_MAX_REC     1000  // ea record has load, cell volts = 2 shorts
#define PP_SHORT_PER_REC  2  // #of shorts per record
//actual bytes used PER CELL = 1000*4 = 4000 : for both cells = 8000 bytes
#define PP_PRE_DT     64  // time to sample cells before applying a load
#define PP_POST_DT   192  // time to sample after the final load.

//--define phases for polyplus sampling
enum pp_phase_enum {
	PP_OFF,       // no loads are applied, not acquring
	PP_PRE_LOAD,  // sampling before applying the load
	PP_LOAD,      // sampling while  applying the load
	PP_POST_LOAD, // sampling after  applying the load
	PP_DONE       // finished with data-collection
}; //====================================================

// PP_DAT_SIZE/5 = # of points that can be stored
struct pp_cell // =============================================================
{ // struct for one cell load settings during a dive
  short  iload;    // pointer to which load to use
  short  nload;    // iload<nload are valid settings (nload<=PP_LMAX)
  short  phase;    // present phase of measurement (see pp_phase_enum)
  short tstart;    // time since start of dive to start load-sampling
  long    tmax;    // time to stop sampling for present phase.
  short   kdec;    // decimation of the data for SBD packing
  short     kp;    // #points taken so far in this phase: used with kdec
  short   kout;    // output pointer, for SBD messages
  short t[PP_LMAX+1]; // duration to sample load[i];
  short L[PP_LMAX+1]; // load setting [0..4]
  short   *dat;    // points to the SBD data buffer for this cell
  short Lnow;      // ---Feb12, present load setting
}; //==========================================================================

struct pp_daq //===============================================================
{ // struct for pp_cell and the data
  struct pp_cell cell[2]; // info for ea cell

  short max;         // max #pts in the  data
  short baud;        // baud of mux1; copy to use to restore after done with PP
  short load;        // last load value
  short val0;        // last cell 0 reading
  short val1;        // last cell 1 reading
  //---Feb12, add values for turning off during the bottom turn
  short bot;         // flag=TRUE if in the bottom turn; don't change loads
  long  tbot;        // time when entering the bottom turn
}; //==========================================================================

struct pp_buf //===============================================================
{ // struct for the ping-pong buffer for file writes
  // dec14 moved here so it will persist across resets
  short   ipp;               // index into ping-pong
  uchar   ppbuf[PP_BMAX  ];  // ping-pong buffer
}; //==========================================================================
  

#if ZOOG==1   // ZooGlider structs ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
struct zcam_param  //------------------------------------------
{ // Zooglider, ZooCam params
  char  zcamState;         // state of the zoocam-state-machine
  char  zcam_stat;         // status of zoocam
  short n_img;             // image #
  short n_err;             // # of errors
  short avg;               // avg intensity of last image
  long  uxti;              // unix time w/n_img
  short ntry;              // oct15, add #tries to start up
};
struct zonar_param  //-----------------------------------------
{ // Zooglider, Zonar params
  char  zonarState;        // state of the zonar-state-machine
  char  zonar_stat;        // status of zonar
  long  uxti;              // unix time of state operation
  //---parameters from zonar itself
  short zonarSN;  // zonar SN
  short nPings;   // #pings per burst
  short dtBurst;  // #s between bursts (if continuous mode)
  short warmup;   // [ms] warmup time
  short tBin;     // [ms] per output bin
  short barker;   // if=1, use Barker code (no implemented yet)
  short nBit;     // #bits in the Barker code.
  // beam1
  short f1;       // kHz xmit freq
  short pulse1;   // transmit pulse len [ms]
  short blank1;   // blank distance [m]
  short dt1;      // [us] period between scans = 1/sampRate
  short tScan1;   // [ms] duration to take scans
  short tPing1;   // [ms] interval between pings
  short nScan1;   // #scans to take = 1000*tScan/dt
  short tWait1;   // [ms] to wait between last scan & next ping
  short nBin1;    // #scans to avg per output bin
  // beam2
  short f2;       // kHz xmit freq
  short pulse2;   // transmit pulse len [ms]
  short blank2;   // blank distance [m]
  short dt2;      // [us] period between scans = 1/sampRate
  short tScan2;   // [ms] duration to take scans
  short tPing2;   // [ms] interval between pings
  short nScan2;   // #scans to take = 1000*tScan/dt
  short tWait2;   // [ms] to wait between last scan & next ping
  short nBin2;    // #scans to avg per output bin
  // shore param markers
  char  f2Num;    // # of params to update in F2 command
  char  f3Num;    // # of params to update in F3 command.
};
struct zonar_scan  //------------------------------------------
{ // zonar output scan struct; gets written to flash as well.
  short    pr;               // pressure dBar = pr*0.1
  ushort   tm;               // time of scan   
  short  n[2];               // #of bins for beam 1 and 2
  short  amp[2][ADP_NCELL];  // array w/data
};   
#endif //ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ  

//*****************************************************************************
// The big all-inclusive structure
//*****************************************************************************
struct all_param // this is the struct passed around to everyone else
{  //========================================================================
  // this is a global, that gets set to zeros on a reset:
  // any variables that you want to live through a reset should live
  // in  a struct.  dec14: moved many of the variables.
  uchar   bdat[LIFO_NBYTE];  // buffer area for SBD data
  uchar   edat[LIFO_NBYTE];  // buffer area to echo shore commands
  short   klifo;             // = lifo buffer to use for present dive
  short   necho;             // #bytes stored in edat
  char   fdat_name[20];      // data file name: save so can be closed/opened to flush
  FILE   *fp_sco;            // points to the Spray Change Order file
  FILE   *fp_dat;            // points to the Spray data file
  FILE   *fp_adp;            // points to the Spray adp file
  //short  exc_stat;           // dec14: using exc->exc_stat for exception register
  short  roll_stat;          // roll exception register
  short  wing_now[2];        // wing to use for gps/iridium 
  short  ncyc;               // cycle # index for present dive-set#

  struct pp_buf         *ppb;      // points to the ping-pong buffer
  struct tpu_uart       *tu_port;  // points to tpu serial port info
  struct spi_param      *sspi;     // points to spi comms structure
  struct compass_param  *comp;     // compass parameters
  struct time_param     *time;     // UX time of various events
  struct gps_param      *gps;      // gps structure
  struct ublox_param    *ubx;       // ublox gps info
  struct sbd_param      *sbd;      // sbd iridium structure
  struct lifo_param     *lifo;     // LIFO structure
  struct flight_param   *flt;      // flight params
  struct nav_param      *nav;      // navigation parameters
  struct except_param   *exc;      // exception parameters
  struct eng_param      *eng;      // engineering parameters
  struct drift_param    *drift;    // drift params
  struct hyd_param      *hyd;      // hydraulics params
  struct dat_param      *dat;      // data params
  struct adp_param      *adp;      // adp params
  struct ntk_param      *ntk;      // nortek AD2CP
  struct motor_stat     *mot;      // pitch/roll stats of last operation
  struct pwr_param      *pwr;      // hyd, pitch, roll pwr #'s
  struct pp_daq         *pp;       // polyplus parameter settings
  #if BENTHOS==1 || NPS==1
    struct acm_param    *acm;      // acoustic modem struct
  #endif
  #if PH==1
    struct ph_param     *ph;       // ph struct
  #endif
  #if ZOOG==1
    struct zcam_param   *zcam;     // zooglider zoocam struct
    struct zonar_param *zonar;     // zooglider zonar  struct
    struct zonar_scan     *zs;     // zonar 1-scan data struct
  #endif
}; //========================================================================

//*****************************************************************************

//***macros for pitch and roll, for easier calling names
#define Pitch_Xmit  ( send_p_r_run ( CS_PITCH, 1, iparam[ IA_pitch_xmt ] ) )
#define Pitch_Level ( send_p_r_run ( CS_PITCH, 1, iparam[ IA_pitch_0   ] ) )

#define Roll_Zero   ( send_p_r_run ( CS_ROLL,  1, iparam[ IA_roll_0    ] ) )
#define Roll_Port_W_Up ( send_p_r_run(CS_ROLL, 1, iparam[ IA_roll_port ] ) )
#define Roll_Stbd_W_Up ( send_p_r_run(CS_ROLL, 1, iparam[ IA_roll_stbd ] ) )

#define Close_Valve ( power_on_off( CS_HYD, HYD_CLOSE_VALVE, 1  )  )
#define Open_Valve  ( power_on_off( CS_HYD, HYD_OPEN_VALVE,  1  )  )

#define LLD_On      ( power_on_off( CS_HYD, HYD_ON_LLD,    AUX_ON ) )
#define LLD_Off     ( power_on_off( CS_HYD, HYD_ON_LLD,    AUX_OFF) )

#define Vent_On     ( power_on_off( CS_HYD, HYD_ON_VENT,   AUX_ON ) )
#define Vent_Off    ( power_on_off( CS_HYD, HYD_ON_VENT,   AUX_OFF) )

#define Opt_On      ( power_on_off( CS_GPIO, AUX_ON_OPT,   AUX_ON ) )
#define Opt_Off     ( power_on_off( CS_GPIO, AUX_ON_OPT,   AUX_OFF) )

#define Burn_On     ( power_on_off( CS_GPIO, AUX_ON_BURN,  AUX_ON ) )
#define Burn_Off    ( power_on_off( CS_GPIO, AUX_ON_BURN,  AUX_OFF) )

#define Argos_On    ( power_on_off( CS_GPIO, AUX_ON_ARGOS, AUX_ON ) )
#define Argos_Off   ( power_on_off( CS_GPIO, AUX_ON_ARGOS, AUX_OFF) )

#define Alt_On      ( power_on_off( CS_GPIO, AUX_ON_ALT, AUX_ON ) )
#define Alt_Off     ( power_on_off( CS_GPIO, AUX_ON_ALT, AUX_OFF) )

#define SBD_On      ( power_on_off( CS_GPIO, AUX_ON_SBD, AUX_ON ) )
#define SBD_Off     ( power_on_off( CS_GPIO, AUX_ON_SBD, AUX_OFF) )

//--jul13 addition to force on/off the GPIO a/d
#define AD_On       ( power_on_off( CS_GPIO, AUX_ON_AD,  AUX_ON ) )
#define AD_Off      ( power_on_off( CS_GPIO, AUX_ON_AD,  AUX_OFF) )

//*** definitions for initial parameters **************************************

// following are set for a 8 s sampling period
// 0903, added new sample up/down times
#define SAMP_DT_UP   8      // sample & store every X secs on ascent
#define SAMP_DT_DN   8      // sample & store every X secs on descent
#define T_ACT       64      // do active control every  XX s
#define TSTART      32      // start averaging XX s after active control
#define DHDR     0.030      // dh/dt per degree roll : from 10/23/02 test 

// after the glider starts to come up, it will pump for BUOY_PUMP more time
// :: Jul01 : parameters to control ascent rate
#define BUOY_PUMP     150   //#s to get right buoyancy after first start to rise
#define DPUMP          35   //#s to pump to get back up to speed after w<wmin
#define WMIN           10   // minimum cm/s rise rate allowed before pumping more

/* obsolete
//#define SAMP_DT    8      // sample & store every X secs
#define R_0          0      // guess roll needed to go straight
#define VARY_PITCH FALSE    // set true to allow variable pitch
#define MIN_PITCH  12       // min pitch to use
#define MAX_PITCH  40       // max pitch to use
/**/

#define PITCH_DOWN    120    //guess for 20 deg down @ start

//*** that are changed by DEBUG ***********************************************
#if DEBUG==1 //*****then want to use the debug settings

	#define SURF_WAIT    60   // #s to wait to leave surface
	#define VALVE_TIME  120   //after X seconds on descent, close valve
	#define PMP_TRY      30   // max secs to try pump on abort
	#define RF_TM_1      30   // #secs with argos on @ end of 1st dive

#else //***else mission mode

	#define SURF_WAIT    700  // #s to wait to leave the surface
	#define VALVE_TIME  1000  //after 1000 seconds on descent, close valve
	#define PMP_TRY      200  // max secs to try pump on abort
	#define RF_TM_1      300  // #secs with argos on @ end of 1st dive


#endif

//**** END ********************************************************************

