///
/// @file sequence.h
/// @authors k. headley
/// @date 05 dec 2019

/// Carbon Waveglider IO sequencing API 

/// @sa doxygen-examples.c for more examples of Doxygen markup


/////////////////////////
// Terms of use
/////////////////////////
/*
 Copyright Information
  
 Copyright 2002-2019 MBARI
 Monterey Bay Aquarium Research Institute, all rights reserved.
 
 Terms of Use
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version. You can access the GPLv3 license at
 http://www.gnu.org/licenses/gpl-3.0.html
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details
 (http://www.gnu.org/licenses/gpl-3.0.html)
 
 MBARI provides the documentation and software code "as is", with no warranty,
 express or implied, as to the software, title, non-infringement of third party
 rights, merchantability, or fitness for any particular purpose, the accuracy of
 the code, or the performance or results which you may obtain from its use. You
 assume the entire risk associated with use of the code, and you agree to be
 responsible for the entire cost of repair or servicing of the program with
 which you are using the code.
 
 In no event shall MBARI be liable for any damages, whether general, special,
 incidental or consequential damages, arising out of your use of the software,
 including, but not limited to, the loss or corruption of your data or damages
 of any kind resulting from use of the software, any prohibited use, or your
 inability to use the software. You agree to defend, indemnify and hold harmless
 MBARI and its officers, directors, and employees against any claim, loss,
 liability or expense, including attorneys' fees, resulting from loss of or
 damage to property or the injury to or death of any person arising out of the
 use of the software.
 
 The MBARI software is provided without obligation on the part of the
 Monterey Bay Aquarium Research Institute to assist in its use, correction,
 modification, or enhancement.
 
 MBARI assumes no responsibility or liability for any third party and/or
 commercial software required for the database or applications. Licensee agrees
 to obtain and maintain valid licenses for any additional third party software
 required.
 */

// Always do this
#ifndef SEQUENCING_H
#define SEQUENCING_H

/////////////////////////
// Includes 
/////////////////////////
#include <stdint.h>

/////////////////////////
// Macros
/////////////////////////

#define MX_PULSE_HILO(b,t1_ms,t2_ms) do{MPRINT(MOD_ACT,"MX_PULSE_HILO[x%08lX,%u,%u]\r\n",b,t1_ms,t2_ms);doSetBits(b,HI); if(t1_ms>0)tkDelayMs(t1_ms); doSetBits(b,LO); if(t2_ms>0)tkDelayMs(t2_ms);}while(0)
#define MX_PULSE_LOHI(b,t1_ms,t2_ms) do{MPRINT(MOD_ACT,"MX_PULSE_LOHI[x%08lX,%u,%u]\r\n",b,t1_ms,t2_ms);doSetBits(b,LO); if(t1_ms>0)tkDelayMs(t1_ms); doSetBits(b,HI); if(t2_ms>0)tkDelayMs(t2_ms);}while(0)
#define MX_PULSE_50PCT(b,ms)         do{MPRINT(MOD_ACT,"MX_PULSE_50PCT[x%08lX,%u]\r\n",b,ms);doSetBits(b,HI); if(ms>0)tkDelayMs(ms); doSetBits(b,LO); if(ms>0)tkDelayMs(ms);}while(0)
#define MX_PULSE_100PCT(b,ms)        do{MPRINT(MOD_ACT,"MX_PULSE_100PCT[x%08lX,%u]\r\n",b,ms);doSetBits(b,HI); if(ms>0)tkDelayMs(ms); doSetBits(b,LO);}while(0)
#define MX_ON_DELAY(b,ms)            do{MPRINT(MOD_ACT,"MX_ON_DELAY[x%08lX,%u]\r\n",b,ms);doSetBits(b,HI); if(ms>0)tkDelayMs(ms);}while(0)
#define MX_OFF_DELAY(b,ms)           do{MPRINT(MOD_ACT,"MX_OFF_DELAY[x%08lX,%u]\r\n",b,ms);doSetBits(b,LO); if(ms>0)tkDelayMs(ms);}while(0)
#define MX_DELAY(ms)                 do{MPRINT(MOD_ACT,"MX_DELAY[%u]\r\n",ms);if(ms>0)tkDelayMs(ms);}while(0)
#define MX_ON(b)                     do{MPRINT(MOD_ACT,"MX_ON[x%08lX]\r\n",b);doSetBits(b,HI);}while(0)
#define MX_OFF(b)                    do{MPRINT(MOD_ACT,"MX_OFF[x%08lX]\r\n",b);doSetBits(b,LO);}while(0)
#define MX_ASSERT(b,dir)             do{MPRINT(MOD_ACT,"MX_ASSERT[x%08lX] dir[%c]\r\n",b,(dir==0? 'L' : 'H'));doSetBits(b,(dir==0?LO:HI));}while(0)

#ifdef MANIFOLD_V0
#define MXB_LICOR  MBIT(LICOR_DC)
#define MXB_AIPUMP MBIT(PUMP0_DC)
#define MXB_SWPUMP MBIT(PUMP1_DC)
#define MXB_SAPUMP MBIT(SV0B)
#define MXB_ACPUMP MBIT(SV0A)
#define MXB_SV0A   MBIT(SV0A)
#define MXB_SV0B   MBIT(SV0B)
#define MXB_SV1A   MBIT(SV1A)
#define MXB_SV1B   MBIT(SV1B)
#define MXB_SV2A   MBIT(SV2A)
#define MXB_SV2B   MBIT(SV2B)
#define MXB_SV3A   MBIT(SV3A)
#define MXB_SV3B   MBIT(SV3B)
#define MXB_SV4A   MBIT(SV4A)
#define MXB_SV4B   MBIT(SV4B)
#define MXB_SV5A   MBIT(SV5A)
#define MXB_SV5B   MBIT(SV5B)
#define MXB_SV6A   MBIT(SV6A)
#define MXB_SV6B   MBIT(SV6B)
#define MXB_SV7A   MBIT(SV7A)
#define MXB_SV7B   MBIT(SV7B)
#define MXB_SV8A   MBIT(SV8A)
#define MXB_SV8B   MBIT(SV8B)
#define MXB_SV9A   MBIT(SV9A)
#define MXB_SV9B   MBIT(SV9B)

#define MX_PUMP_TON_MSEC  200
#define MX_PUMP_TOFF_MSEC 300
#define MX_VALVE_TON_MSEC 200
#define MX_BLANK_MSEC     1000
#define MX_BLANK_INVALID  0xFFFFFFFF

#define MACID_ACPUMP           MXB_ACPUMP
#define MACID_ACPUMP_TON_MSEC  MX_PUMP_TON_MSEC
#define MACID_ACPUMP_TOFF_MSEC MX_PUMP_TOFF_MSEC
#define MACID_ACPUMP_CYC       20

#define MAIR_VSET            (MXB_SV1A|MXB_SV2B|MXB_SV3A|MXB_SV5A|MXB_SV6A)
#define MAIR_VCLR            (MXB_SV1B|MXB_SV2A|MXB_SV3B|MXB_SV5B|MXB_SV6B)
#define MAIR_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MAIR_AIPUMP          MXB_AIPUMP
#define MAIR_AIPUMP_DON_MSEC 5000
#define MAIR_MEAS_MSEC       10000
#define MAIR_MEAS_PERIOD_SEC 0.5
#define MAIR_BLANK_MSEC      MX_BLANK_MSEC
#define MAIR_MEAS_N          10

#define MFILL_VSET            (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV5A|MXB_SV6A)
#define MFILL_VCLR            (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV5B|MXB_SV6B)
#define MFILL_VALVE_TON_MSEC   MX_VALVE_TON_MSEC
#define MFILL_SWPUMP           MXB_SWPUMP
#define MFILL_SWPUMP_DON_MSEC  5000
#define MFILL_SAPUMP           MXB_SAPUMP
#define MFILL_SAPUMP_CYC       30
#define MFILL_SAPUMP_TON_MSEC  MX_PUMP_TON_MSEC
#define MFILL_SAPUMP_TOFF_MSEC MX_PUMP_TOFF_MSEC
#define MFILL_BLANK_MSEC       MX_BLANK_MSEC

#define MSAMPLE_VSET            (MXB_SV2A|MXB_SV3A|MXB_SV5B|MXB_SV6A)
#define MSAMPLE_VCLR            (MXB_SV2B|MXB_SV3B|MXB_SV5A|MXB_SV6B)
#define MSAMPLE_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MSAMPLE_AIPUMP          MXB_AIPUMP
#define MSAMPLE_MEAS_MSEC       30000
#define MSAMPLE_MEAS_PERIOD_SEC 0.5
#define MSAMPLE_MEAS_N          60
#define MSAMPLE_PREBL_N         5
#define MSAMPLE_POSTBL_N        5

#define MZCAL_MEAS_N 8
#define MSCAL_MEAS_N 8
#define MCAL_PRES_N  5
#define MCAL_POSTS_N 5

#define MXMEAS_TYPE              RT_USER
#define MXMEAS_CTX               RC_ANY
#define MXMEAS_HANDLER           HID_AVG
#define MXMEAS_MEAS_MSEC         5000
#define MXMEAS_MEAS_PERIOD_SEC   0.5
#define MXMEAS_AIR_STATE         '-'
#define MXMEAS_SEA_STATE         '-'
#define MXMEAS_LICOR_STATE       '+'
#define MXMEAS_OUTPUT            "A"
#define MXMEAS_SWPUMP            MXB_SWPUMP
#define MXMEAS_AIPUMP            MXB_AIPUMP
#define MXMEAS_CAL_WR            '-'
#define MXMEAS_PREBL_BLANK_MSEC  1000
#define MXMEAS_POSTBL_BLANK_MSEC 1000
#define MXMEAS_PRES_BLANK_MSEC   1000
#define MXMEAS_POSTS_BLANK_MSEC  1000
#define MXMEAS_SAMPLE_BLANK_MSEC 1000
#define MXMEAS_ZCAL_BLANK_MSEC   1000
#define MXMEAS_SCAL_BLANK_MSEC   1000

#define MPURGE_VSET            (MXB_SV1B|MXB_SV2B|MXB_SV3A|MXB_SV5A|MXB_SV6A)
#define MPURGE_VCLR            (MXB_SV1A|MXB_SV2A|MXB_SV3B|MXB_SV5B|MXB_SV6B)
#define MPURGE_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MPURGE_AIPUMP          MXB_AIPUMP
#define MPURGE_AIPUMP_DON_MSEC 10000
#define MPURGE_REST_SET        (MPURGE_VCLR|MXB_SV6B)

#define MREST_VSET           (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV5A|MXB_SV6A)
#define MREST_VCLR           (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV5B|MXB_SV6B)
#define MREST_VALVE_TON_MSEC MX_VALVE_TON_MSEC

#define MSTD_VSET            (MXB_SV1A|MXB_SV5A|MXB_SV6A)
#define MSTD_VCLR            (MXB_SV1B|MXB_SV5B|MXB_SV6B)
#define MSTD_FILL_VSET       (MXB_SV4A)
#define MSTD_FILL_VCLR       (MXB_SV4B)
#define MSTD_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MSTD_AIPUMP          MXB_AIPUMP
#define MSTD_AIPUMP_DON_MSEC 5000
#define MSTD_MEAS_MSEC       5000
#define MSTD_MEAS_PERIOD_SEC 0.5
#define MSTD_BLANK_MSEC      MX_BLANK_MSEC
#define MSTD_MEAS_N          10

#define MZCAL_VSET            (MXB_SV3A|MXB_SV5A|MXB_SV6B)
#define MZCAL_VCLR            (MXB_SV3B|MXB_SV5B|MXB_SV6A)
#define MZCAL_AIPUMP_DON_MSEC 5000
#define MZCAL_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MZCAL_AIPUMP          MXB_AIPUMP

#define MSZERO_VSET            (MXB_SV1A|MXB_SV2A|MXB_SV3B|MXB_SV5B|MXB_SV6A)
#define MSZERO_VCLR            (MXB_SV1B|MXB_SV2B|MXB_SV3A|MXB_SV5A|MXB_SV6B)
#define MSZERO_VENT_VSET       (MXB_SV5A)
#define MSZERO_VENT_VCLR       (MXB_SV5B)
#define MSZERO_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MSZERO_AIPUMP          MXB_AIPUMP
#define MSZERO_AIPUMP_DON_MSEC 5000
#define MSZERO_BLANK_MSEC      MX_BLANK_MSEC

#define MZERO_VSET           (MXB_SV1A|MXB_SV2A|MXB_SV3B|MXB_SV5B|MXB_SV6A)
#define MZERO_VCLR           (MXB_SV1B|MXB_SV2B|MXB_SV3A|MXB_SV5A|MXB_SV6B)
#define MZERO_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MZERO_AIPUMP          MXB_AIPUMP
#define MZERO_AIPUMP_DON_MSEC 20000
#define MZERO_VENT_VSET       (MXB_SV5B)
#define MZERO_VENT_VCLR       (MXB_SV5A)
#define MZERO_VENT_PUL_MSEC   MX_VALVE_TON_MSEC
#define MZERO_BLANK_MSEC      MX_BLANK_MSEC
#define MZERO_MEAS_N          10
#endif

#define MANIFOLD_V1
#ifdef MANIFOLD_V1

#define MXB_LICOR  MBIT(LICOR_DC)
#define MXB_XCVR_LICOR  MBIT(XCVR_LICOR)
#define MXB_AIPUMP MBIT(PUMP0_DC)
#define MXB_SWPUMP MBIT(PUMP3_DC)
#define MXB_SAPUMP MBIT(PUMP1_DC)
#define MXB_ACPUMP MBIT(PUMP2_DC)
#define MXB_SV0A   MBIT(SV0A)
#define MXB_SV0B   MBIT(SV0B)
#define MXB_SV1A   MBIT(SV1A)
#define MXB_SV1B   MBIT(SV1B)
#define MXB_SV2A   MBIT(SV2A)
#define MXB_SV2B   MBIT(SV2B)
#define MXB_SV3A   MBIT(SV3A)
#define MXB_SV3B   MBIT(SV3B)
#define MXB_SV4A   MBIT(SV4A)
#define MXB_SV4B   MBIT(SV4B)
#define MXB_SV5A   MBIT(SV5A)
#define MXB_SV5B   MBIT(SV5B)
#define MXB_SV6A   MBIT(SV6A)
#define MXB_SV6B   MBIT(SV6B)
#define MXB_SV7A   MBIT(SV7A)
#define MXB_SV7B   MBIT(SV7B)
#define MXB_SV8A   MBIT(SV8A)
#define MXB_SV8B   MBIT(SV8B)
#define MXB_SV9A   MBIT(SV9A)
#define MXB_SV9B   MBIT(SV9B)

#define MX_PUMP_TON_MSEC  200
#define MX_PUMP_TOFF_MSEC 300
#define MX_VALVE_TON_MSEC 200
#define MX_BLANK_MSEC     1000
#define MX_BLANK_INVALID  0xFFFFFFFF
#define MX_LI_PERIOD_SEC  0.5
#define MX_CAL_WR_ON      '+'
#define MX_CAL_WR_OFF     '-'
#define MX_CAL_TON_MSEC  3000

#define MACID_ACPUMP           MXB_ACPUMP
#define MACID_ACPUMP_TON_MSEC  MX_PUMP_TON_MSEC
#define MACID_ACPUMP_TOFF_MSEC MX_PUMP_TOFF_MSEC
#define MACID_ACPUMP_CYC       15 //20

#define MAIR_VSET             (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV4B|MXB_SV6A|MXB_SV7A|MXB_SV8A)
#define MAIR_VCLR             (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV4A|MXB_SV6B|MXB_SV7B|MXB_SV8B)
#define MAIR_VALVE_TON_MSEC   MX_VALVE_TON_MSEC
#define MAIR_AIPUMP           MXB_AIPUMP
#define MAIR_AIPUMP_DON_MSEC  15000
#define MAIR_AIPUMP_DOFF_MSEC 3000
#define MAIR_MEAS_MSEC        10000
#define MAIR_MEAS_PERIOD_SEC  MX_LI_PERIOD_SEC
#define MAIR_BLANK_MSEC       MX_BLANK_MSEC
#define MAIR_MEAS_N           10

#define MFILL_VSET             (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV4A|MXB_SV6A|MXB_SV7A|MXB_SV8A)
#define MFILL_VCLR             (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV4B|MXB_SV6B|MXB_SV7B|MXB_SV8B)
#define MFILL_VALVE_TON_MSEC   MX_VALVE_TON_MSEC
#define MFILL_SWPUMP           MXB_SWPUMP
#define MFILL_SWPUMP_DON_MSEC  5000
#define MFILL_SAPUMP           MXB_SAPUMP
#define MFILL_SAPUMP_CYC       30
#define MFILL_SAPUMP_TON_MSEC  MX_PUMP_TON_MSEC
#define MFILL_SAPUMP_TOFF_MSEC MX_PUMP_TOFF_MSEC
#define MFILL_BLANK_MSEC       MX_BLANK_MSEC

#define MSAMPLE_VSET            (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV4A|MXB_SV6A|MXB_SV7A|MXB_SV8A)
#define MSAMPLE_VCLR            (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV4B|MXB_SV6B|MXB_SV7B|MXB_SV8B)
#define MSAMPLE_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MSAMPLE_AIPUMP          MXB_AIPUMP
#define MSAMPLE_AIPUMP_DON_MSEC 15000
#define MSAMPLE_MEAS_MSEC       30000
#define MSAMPLE_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC
#define MSAMPLE_MEAS_N          60
#define MSAMPLE_BLANK_MSEC      MX_BLANK_MSEC

#define MBLINE_MEAS_N          5
#define MBLINE_BLANK_MSEC      1000
#define MBLINE_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC
#define MPREB_MEAS_N           5
#define MPREB_BLANK_MSEC       1000
#define MPREB_MEAS_PERIOD_SEC  MX_LI_PERIOD_SEC
#define MPOSTB_MEAS_N          5
#define MPOSTB_BLANK_MSEC      1000
#define MPOSTB_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC

#define MXMEAS_TYPE            RT_USER
#define MXMEAS_CTX             RC_ANY
#define MXMEAS_HANDLER         HID_AVG
#define MXMEAS_MEAS_MSEC       5000
#define MXMEAS_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC
#define MXMEAS_AIR_STATE       '-'
#define MXMEAS_SEA_STATE       '-'
#define MXMEAS_LICOR_STATE     '+'
#define MXMEAS_OUTPUT          "A"
#define MXMEAS_SWPUMP          MXB_SWPUMP
#define MXMEAS_AIPUMP          MXB_AIPUMP
#define MXMEAS_CAL_WR          '-'

#define MPURGE_VSET            (MXB_SV1A|MXB_SV2A|MXB_SV3B|MXB_SV4B|MXB_SV6A|MXB_SV7A|MXB_SV8A)
#define MPURGE_VCLR            (MXB_SV1B|MXB_SV2B|MXB_SV3A|MXB_SV4A|MXB_SV6B|MXB_SV7B|MXB_SV8B)
#define MPURGE_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MPURGE_AIPUMP          MXB_AIPUMP
#define MPURGE_AIPUMP_DON_MSEC 10000
#define MPURGE_REST_SET        (MPURGE_VCLR|MXB_SV6B)

#define MREST_VSET           (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV4A|MXB_SV6A|MXB_SV7B|MXB_SV8B)
#define MREST_VCLR           (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV4B|MXB_SV6B|MXB_SV7A|MXB_SV8A)
#define MREST_VALVE_TON_MSEC MX_VALVE_TON_MSEC

#define MSTD_VSET            (MXB_SV1A|MXB_SV5A|MXB_SV6A)
#define MSTD_VCLR            (MXB_SV1B|MXB_SV5B|MXB_SV6B)
#define MSTD_FILL_VSET       (MXB_SV4A)
#define MSTD_FILL_VCLR       (MXB_SV4B)
#define MSTD_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MSTD_AIPUMP          MXB_AIPUMP
#define MSTD_AIPUMP_DON_MSEC 5000
#define MSTD_MEAS_MSEC       5000
#define MSTD_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC
#define MSTD_BLANK_MSEC      MX_BLANK_MSEC
#define MSTD_MEAS_N          10

#define MPRES_MEAS_N          5
#define MPRES_BLANK_MSEC      MX_BLANK_MSEC
#define MPRES_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC

#define MPOSTS_MEAS_N          5
#define MPOSTS_BLANK_MSEC      MX_BLANK_MSEC
#define MPOSTS_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC

#define MPREZ_MEAS_N          8
#define MPREZ_BLANK_MSEC      MX_BLANK_MSEC
#define MPREZ_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC

#define MPOSTZ_MEAS_N          8
#define MPOSTZ_BLANK_MSEC      MX_BLANK_MSEC
#define MPOSTZ_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC

#define MZCAL_VSET             (MXB_SV1A|MXB_SV2A|MXB_SV3B|MXB_SV4A|MXB_SV6A|MXB_SV7B|MXB_SV8A)
#define MZCAL_VCLR             (MXB_SV1B|MXB_SV2B|MXB_SV3A|MXB_SV4B|MXB_SV6B|MXB_SV7A|MXB_SV8B)
#define MZCAL_MEAS_N           8
#define MZCAL_AIPUMP_DON_MSEC  20000
#define MZCAL_AIPUMP_DOFF_MSEC 3000
#define MZCAL_VALVE_TON_MSEC   MX_VALVE_TON_MSEC
#define MZCAL_AIPUMP           MXB_AIPUMP
#define MZCAL_BLANK_MSEC       MX_BLANK_MSEC
#define MZCAL_MEAS_PERIOD_SEC  MX_LI_PERIOD_SEC

#define MSCAL_VSET              (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV4A|MXB_SV6A|MXB_SV7A|MXB_SV8A)
#define MSCAL_VCLR              (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV4B|MXB_SV6B|MXB_SV7B|MXB_SV8B)
#define MSCAL_GAS_VSET          (MXB_SV5A)
#define MSCAL_GAS_VCLR          (MXB_SV5B)
#define MSCAL_GAS_PUMP          MXB_AIPUMP
#define MSCAL_GAS_PUMP_DON_MSEC 5000
#define MSCAL_MEAS_N            8
#define MSCAL_WAIT_DON_MSEC     10000
#define MSCAL_VALVE_TON_MSEC    MX_VALVE_TON_MSEC
#define MSCAL_BLANK_MSEC        MX_BLANK_MSEC
#define MSCAL_MEAS_PERIOD_SEC   MX_LI_PERIOD_SEC

#define MSZERO_VSET            (MXB_SV1A|MXB_SV2A|MXB_SV3A|MXB_SV4A|MXB_SV6A|MXB_SV7A|MXB_SV8A)
#define MSZERO_VCLR            (MXB_SV1B|MXB_SV2B|MXB_SV3B|MXB_SV4B|MXB_SV6B|MXB_SV7B|MXB_SV8B)
#define MSZERO_VENT_VSET       (MXB_SV5A)
#define MSZERO_VENT_VCLR       (MXB_SV5B)
#define MSZERO_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MSZERO_AIPUMP          MXB_AIPUMP
#define MSZERO_AIPUMP_DON_MSEC 5000
#define MSZERO_BLANK_MSEC      MX_BLANK_MSEC

#define MZERO_VSET            (MXB_SV1A|MXB_SV2A|MXB_SV3B|MXB_SV4A|MXB_SV6B|MXB_SV7A|MXB_SV8B)
#define MZERO_VCLR            (MXB_SV1B|MXB_SV2B|MXB_SV3A|MXB_SV4B|MXB_SV6A|MXB_SV7B|MXB_SV8A)
#define MZERO_VALVE_TON_MSEC  MX_VALVE_TON_MSEC
#define MZERO_AIPUMP          MXB_AIPUMP
#define MZERO_AIPUMP_DON_MSEC 20000
#define MZERO_MEAS_PERIOD_SEC MX_LI_PERIOD_SEC
#define MZERO_VENT_VSET       (MXB_SV5B)
#define MZERO_VENT_VCLR       (MXB_SV5A)
#define MZERO_VENT_PUL_MSEC   MX_VALVE_TON_MSEC
#define MZERO_BLANK_MSEC      MX_BLANK_MSEC
#define MZERO_MEAS_N          10

#define MVEX_S1_VSET  (MXB_SV1A|MXB_SV4A|MXB_SV8A) 
#define MVEX_S2_VSET  (MXB_SV1B|MXB_SV4B|MXB_SV8B) 
#define MVEX_S3_VSET  (MXB_SV2A|MXB_SV6A) 
#define MVEX_S4_VSET  (MXB_SV2B|MXB_SV6B) 
#define MVEX_S5_VSET  (MXB_SV3A|MXB_SV7A) 
#define MVEX_S6_VSET  (MXB_SV3B|MXB_SV7B) 
#define MVEX_S7_VSET  (MXB_SV1A|MXB_SV4A|MXB_SV8A) 
#define MVEX_S8_VSET  (MXB_SV2A|MXB_SV7A) 
#define MVEX_PUL_MSEC MX_VALVE_TON_MSEC
#endif// MANIFOLD_V1

/////////////////////////
// Type Definitions
/////////////////////////

/// @enum ACT_IO_IDX_t
/// @brief sequence actuation IO definition lookup indices
typedef enum{
    AIO_AIPUMP_ON=0,
    AIO_AIPUMP_OFF,
    AIO_SWPUMP_ON,
    AIO_SWPUMP_OFF,
    AIO_LICOR_ON,
    AIO_LICOR_OFF,
    AIO_XCVR_LICOR_ON,
    AIO_XCVR_LICOR_OFF,
    AIO_PURGE_VSET,
    AIO_PURGE_VCLR,
    AIO_FILL_VSET,
    AIO_FILL_VCLR,
    AIO_SAPUMP,
    AIO_ACPUMP,
    AIO_ZERO_VSET,
    AIO_ZERO_VCLR,
    AIO_ZERO_VENT_VSET,
    AIO_ZERO_VENT_VCLR,
    AIO_ZCAL_VSET,
    AIO_ZCAL_VCLR,
    AIO_SZERO_VSET,
    AIO_SZERO_VCLR,
    AIO_SZERO_VENT_VSET,
    AIO_SZERO_VENT_VCLR,
    AIO_SAMPLE_VSET,
    AIO_SAMPLE_VCLR,
    AIO_AIR_VSET,
    AIO_AIR_VCLR,
    AIO_STD_VSET,
    AIO_STD_VCLR,
    AIO_STDFILL_VSET,
    AIO_STDFILL_VCLR,
    AIO_REST_VSET,
    AIO_REST_VCLR,
    AIO_VEX_S1_VSET,
    AIO_VEX_S2_VSET,
    AIO_VEX_S3_VSET,
    AIO_VEX_S4_VSET,
    AIO_VEX_S5_VSET,
    AIO_VEX_S6_VSET,
    AIO_VEX_S7_VSET,
    AIO_VEX_S8_VSET,
    AIO_SCAL_VSET,
    AIO_SCAL_VCLR,
    AIO_SCAL_GAS_VSET,
    AIO_SCAL_GAS_VCLR,
    AIO_IDX_COUNT
 }ACT_IO_IDX_t;

/// @enum ACT_PARAM_IDX_t
/// @brief sequence parameter lookup indices
typedef enum{
    APAR_FILL_SWPUMP,
    APAR_FILL_SAPUMP,
    APAR_PURGE_AIPUMP,
    APAR_ACPUMP,
    APAR_ZERO_AIPUMP,
    APAR_ZCAL_AIPUMP_ON,
    APAR_ZCAL_AIPUMP_OFF,
    APAR_SZERO_AIPUMP,
    APAR_SAMPLE_AIPUMP_ON,
    APAR_AIR_AIPUMP_ON,
    APAR_AIR_AIPUMP_OFF,
    APAR_STD_AIPUMP_ON,
    APAR_VEX_VALVE_DFL,
    APAR_SCAL_GAS,
    APAR_SCAL_WAIT,
    APAR_POWER_DFL,
    APAR_VALVE_DFL,
    APAR_LICOR_DFL,
    APAR_LICOR_CAL,
    APAR_IDX_COUNT
}ACT_PARAM_IDX_t;

/// @enum SEQ_IDX_t
/// @brief sequence definition lookup indices
typedef enum{
    SEQ_FILL=0,
    SEQ_PURGE,
    SEQ_ACID,
    SEQ_ZERO,
    SEQ_ZCAL,
    SEQ_SZERO,
    SEQ_SAMPLE,
    SEQ_AIR,
    SEQ_STD,
    SEQ_MTERM,
    SEQ_REST,
    SEQ_IDX_COUNT
}SEQ_IDX_t;

/// @enum ACT_ID_t
/// @brief actuation type IDs
typedef enum {
    ACT_NONE=0,
    ACT_VALVE_HL,
    ACT_VALVE_LH,
    ACT_PUMP_HL,
    ACT_PUMP_LH,
    ACT_ON,
    ACT_OFF,
}ACT_ID_t;

/// @enum IODIR_t
/// @brief IO direction values
typedef enum{
    IOX=-1,
    IOL=0,
    IOH=1
}IODIR_t;

/// @enum ACT_TIMING_IDX_t
/// @brief IO timing (seq_param_t.timing) array indices
typedef enum{
    ATIM_P0=0,
    ATIM_P1,
    ATIM_DELAY
}ACT_TIMING_IDX_t;

/// @enum ATIM_SUB_FLAGS_t
/// @brief IO timing override selector flags
typedef enum{
    ATSF_P0=0x1,
    ATSF_P1=0x2,
    ATSF_D=0x4,
    ATSF_C=0x8,        
}ATIM_SUB_FLAGS_t;

/// @typedef struct seq_param_s seq_param_t
/// @brief sequence actuation parameters
typedef struct seq_param_s {
    /// @var seq_param_t::timing
    /// @brief timing parameters, indexed using ACT_TIMING_IDX_t
    /// 0: pulse on time
    /// 1: pulse off time
    /// 3: post actuation delay
    int16_t timing[3];
    /// @var seq_param_t::cycles
    /// @brief number of actuation cycles (e.g. pump pulse cycles)
    int16_t  cycles;
}seq_param_t;

/// @typedef struct seq_actuation_s seq_actuation_t
/// @brief sequence actuation definition
typedef struct seq_actuation_s {
    /// @var seq_actuation_t::name
    /// @brief name (for lookup, output)
    const char *name;
    /// @var seq_actuation_t::iomask
    /// @brief IO bits
    uint32_t iomask; 
    /// @var seq_actuation_t::act
    /// @brief actuation type ID
    ACT_ID_t act;
 }seq_actuation_t;

/// @typedef struct sequence_step_s sequence_step_t
/// @brief sequence step definition
typedef struct sequence_step_s {
    /// @var sequence_step_t::act_io
    /// @brief actuation IO and type
    const seq_actuation_t *act_io;
    /// @var sequence_step_t::act_param
    /// @brief actuation parameters (timing, cycles)
    const seq_param_t *act_param;
}sequence_step_t;

/// @typedef struct sequence_s sequence_t
/// @brief sequence definition
typedef struct sequence_s {
    /// @var sequence_t::name
    /// @brief sequence name (for lookup, output)
    const char *name;
    /// @var sequence_t::s_count
    /// @brief number of steps
    uint16_t s_count;
    /// @var sequence_t::steps
    /// @brief array of steps
    const sequence_step_t *steps;
 }sequence_t;

/// @typedef struct meas_profile_s meas_profile_t
/// @brief measurement profile (parameters) definition
typedef struct meas_profile_s{
    /// @var meas_profile_t::rtid
    /// @brief Record type ID
    /// @sa licor8xx-shared.h RTID_* 
    uint16_t rtid;
    /// @var meas_profile_t::rmid
    /// @brief Record measurement ID 
    /// @sa licor8xx-shared.h RMID_* 
    uint16_t rmid;
    /// @var meas_profile_t::mmid
    /// @brief Measurement type ID (logged value, may be set to arbitrary value)
    /// @sa licor8xx-shared.h RMID_* 
    uint16_t mmid;
    /// @var meas_profile_t::blank_ms
    /// @brief blanking interval (msec)
    /// Licor pre-sample delay
    uint32_t blank_ms;
    /// @var meas_profile_t::meas_n
    /// @brief number of licor raw samples
    uint32_t meas_n;
    /// @var meas_profile_t::meas_ms
    /// @brief measurement time (msec)
    uint32_t meas_ms;
    /// @var meas_profile_t::period_s
    /// @brief Licor period (decimal sec, =0.0 or >=0.5)
    float period_s;
    /// @var meas_profile_t::to_msec
    /// @brief timeout (msec)
    uint32_t to_msec;
    /// @var meas_profile_t::cal_wr
    /// @brief enable cal value write to licor if '+' 
    /// and op_id == MMID_SCAL or MMID_ZCAL
    uint16_t cal_wr;
    /// @var meas_profile_t::op_id
    /// @brief true mmid; op_id used to identify actual measurement.
    /// when op_id == MMID_SCAL or MMID_ZCAL, uses cal_wr to enable/disable
    /// cal value updates to licor.
    uint16_t op_id;
}meas_profile_t;

/////////////////////////
// Exports
/////////////////////////

#ifdef __cplusplus
extern "C" {
#endif

    /// @fn void seq_param_show(const seq_param_t *self, uint16_t indent)
    /// @brief output sequence parameters to console
    /// @param self pointer to instance
    /// @param indent space to indent output
    /// @return none
    void seq_param_show(const seq_param_t *self, uint16_t indent);

    /// @fn void seq_actuation_show(const seq_actuation_t *self, uint16_t indent)
    /// @brief output actuation parameters to console
    /// @param self pointer to instance
    /// @param indent space to indent output
    /// @return none
    void seq_actuation_show(const seq_actuation_t *self, uint16_t indent);

    /// @fn void sequence_show(const sequence_t *self, uint16_t indent)
    /// @brief output sequence definition to console
    /// @param self pointer to instance
    /// @param indent space to indent output
    /// @return none
    void sequence_show(const sequence_t *self, uint16_t indent);

    /// @fn void meas_profile_show(const meas_profile_t *self, uint16_t indent)
    /// @brief output measurement profile definition to console
    /// @param self pointer to instance
    /// @param indent space to indent output
    /// @return none
    void meas_profile_show(const meas_profile_t *self, uint16_t indent);

    /// @fn const seq_actuation_t *seq_actuation_slookup(const char *key)
    /// @brief lookup actuation definition by name
    /// @param key actuation name
    /// @return seq_actuation_t instance on success, NULL otherwise
    const seq_actuation_t *seq_actuation_slookup(const char *key);

    /// @fn const seq_actuation_t *seq_actuation_ilookup(ACT_IO_IDX_t key)
    /// @brief lookup actuation definition by ID (index)
    /// @param key actuation ID
    /// @return seq_actuation_t instance on success, NULL otherwise
    const seq_actuation_t *seq_actuation_ilookup(ACT_IO_IDX_t key);

    /// @fn const sequence_t *seq_slookup(const char *key)
    /// @brief lookup sequence definition by name 
    /// @param key sequence name
    /// @return sequence_t instance on success, NULL otherwise
    const sequence_t *seq_slookup(const char *key);

    /// @fn const sequence_t *seq_ilookup(SEQ_IDX_t key)
    /// @brief lookup sequence definition by ID (index) 
    /// @param key sequence ID
    /// @return sequence_t instance on success, NULL otherwise
    const sequence_t *seq_ilookup(SEQ_IDX_t key);

    /// @fn uint32_t seq_actuation_sbits(const char *key)
    /// @brief lookup actuation IO bits by name 
    /// @param key actuation definition name
    /// @return IO bits (bitfield) on success, 0 otherwise
    uint32_t seq_actuation_sbits(const char *key);

    /// @fn uint32_t seq_actuation_ibits(ACT_IO_IDX_t key)
    /// @brief lookup actuation IO bits by ID (index) 
    /// @param key actuation definition ID
    /// @return IO bits (bitfield) on success, 0 otherwise
    uint32_t seq_actuation_ibits(ACT_IO_IDX_t key);

    /// @fn int seq_actuation_run(const seq_actuation_t *self, const seq_param_t *logic)
    /// @brief run actuation definition
    /// @param self actuation definition instance
    /// @param params actuation parameters (timing, cycles)
    /// @return 0 success, -1 otherwise
    int seq_actuation_run(const seq_actuation_t *self, const seq_param_t *params);

    /// @fn int seq_run(const sequence_t *self, seq_param_t *alt_pump, seq_param_t *alt_valve)
    /// @brief run sequence
    /// @param self sequence definition instance
    /// @param alt_pump alternative pump actuation parameters (NULL if unused)
    /// @param alt_valve alternative valve actuation parameters (NULL if unused)
    /// @return 0 success, -1 otherwise
    int seq_run(const sequence_t *self, seq_param_t *alt_pump, seq_param_t *alt_valve);

#ifdef __cplusplus
}
#endif

#endif // THIS_FILE
