/*
 * config.c
 *
 *  Created on: Apr 23, 2021
 *      Author: thomm
 */

// Config - data field selection, modes of operation, driver config, set/get and print functions (moved from system.c)


#include "system.h"
#include "config.h"

#include "user_io.h"
#include "ads1248_iso.h"
#include "ads1248_noniso.h"

#include "board_util.h"

#include "ctd_base.h"
#include "optode.h"

#include "sleep.h"
#include "sample.h"
#include "microsd.h"
#include "uartstdio.h"  // User local version with larger RX buffer

#include "ymodem.h"

extern FIL FileObject;      // for import and read cal file on MFET

extern int microSD_flg;
extern int dbg_flag;
extern struct systemSamplingData sys_samp;
extern struct ctdDriver ctd;

extern unsigned char prnBuf[SIZEOF_PRNBUF+4];      // size is defd in system.h

extern int calFileFlg;                  // defd in main.c, set in config.c, used and cleared in ymodem.c

void config_adc24_sampling_parms(void)
{
#ifdef NOCODE
    uint32_t Vrsi_sps;              //Vrsi_sps  //418 pH Vint data rate setting (sps)
    uint32_t Vrsi_trials;           //Vrsi_trials
    uint32_t Vrse_sps;
    uint32_t Vrse_trials;
    uint32_t Vtherm_sps;
    uint32_t Vtherm_trials;
    uint32_t Ik_sps;
    uint32_t Ik_trials;
    uint32_t Vk_sps;
    uint32_t Vk_trials;
    uint32_t Ib_sps;
    uint32_t Ib_trials;
    uint32_t Vb_sps;
    uint32_t Vb_trials;
    uint32_t Vbias_sps;
    uint32_t Vbias_trials;

    // pH Vint sample rate setting
    while(1)
    {
        uprintf("\r\nEnter pH Vint sample rate setting [%d]: ", sys_data.Vrsi_sps);
        if(getUserInput(buff, 20))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp == 5 || temp == 10 || temp == 20 || temp == 40 || temp == 80 || temp == 160
                        || temp == 320 || temp == 640 || temp == 1000 || temp == 2000)
                {
                    sys_data.Vrsi_sps = temp;
                    uprintf("\r\npH Vint data rate now %d sps\r\n\r\n", sys_data.Vrsi_sps);
                    break;
                }
                else uprintf("\r\nEnter 5, 10, 20, 40, 80, 160, 320, 640, 1000, or 2000");
                continue;
            }
            else break;
        }
        else break;
    }

    break;


    // pH Vint gain setting
    while(1)
    {
        uprintf("\r\nEnter pH Vint gain setting [%d]: ", sys_data.Vint_gain);
        if(getUserInput(buff, 20))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp == 1 || temp == 2 || temp == 4 || temp == 8 || temp == 16 || temp == 32)
                {
                    sys_data.Vint_gain = temp;
                    uprintf("\r\npH Vint gain now %d\r\n\r\n", sys_data.Vint_gain);
                    break;
                }
                else uprintf("\r\nEnter 1, 2, 4, 8, 16, or 32");
                continue;
            }
            else break;
        }
        else break;
    }


#endif



    while(1)
    {
        uprintf("\r\nThird batch of 20 sys_data fields:\r\n\r\n");

        uprintf("Vrsi_sps [%u]: ", sys_data.Vrsi_sps);
        edit_uint(&sys_data.Vrsi_sps, 0, 80);

        uprintf("Vrsi_trials [%u]: ", sys_data.Vrsi_trials);
        edit_uint(&sys_data.Vrsi_trials, 0, 80);

        uprintf("Vrse_sps [%u]: ", sys_data.Vrse_sps);
        edit_uint(&sys_data.Vrse_sps, 0, 80);

        uprintf("Vrse_trials [%u]: ", sys_data.Vrse_trials);
        edit_uint(&sys_data.Vrse_trials, 0, 80);

        uprintf("Vtherm_sps [%u]: ", sys_data.Vtherm_sps);
        edit_uint(&sys_data.Vtherm_sps, 0, 80);

        uprintf("Vtherm_trials [%u]: ", sys_data.Vtherm_trials);
        edit_uint(&sys_data.Vtherm_trials, 0, 80);

        uprintf("Vtherm_trials [%u]: ", sys_data.Vtherm_trials);
        edit_uint(&sys_data.Vtherm_trials, 0, 80);

        uprintf("Ik_sps [%u]: ", sys_data.Ik_sps);
        edit_uint(&sys_data.Ik_sps, 0, 80);

        uprintf("Ik_trials [%u]: ", sys_data.Ik_trials);
        edit_uint(&sys_data.Ik_trials, 0, 80);

        uprintf("Vk_sps [%u]: ", sys_data.Vk_sps);
        edit_uint(&sys_data.Vk_sps, 0, 80);

        uprintf("Vk_trials [%u]: ", sys_data.Vk_trials);
        edit_uint(&sys_data.Vk_trials, 0, 80);

        uprintf("Ib_sps [%u]: ", sys_data.Ib_sps);
        edit_uint(&sys_data.Ib_sps, 0, 80);

        uprintf("Ib_trials [%u]: ", sys_data.Ib_trials);
        edit_uint(&sys_data.Ib_trials, 0, 80);

        uprintf("Vb_sps [%u]: ", sys_data.Vb_sps);
        edit_uint(&sys_data.Vb_sps, 0, 80);

        uprintf("Vb_trials [%u]: ", sys_data.Vb_trials);
        edit_uint(&sys_data.Vb_trials, 0, 80);

        uprintf("Vbias_sps [%u]: ", sys_data.Vbias_sps);
        edit_uint(&sys_data.Vbias_sps, 0, 80);

        uprintf("Vbias_trials [%u]: ", sys_data.Vbias_trials);
        edit_uint(&sys_data.Vbias_trials, 0, 80);

        uprintf("offset_Ik [%u]: ", sys_data.offset_Ik);
        edit_uint(&sys_data.offset_Ik, 0, 80);

        uprintf("offset_Ib [%u]: ", sys_data.offset_Ib);
        edit_uint(&sys_data.offset_Ib, 0, 80);

        break;

    }

}

void advanced_setup_menu(void)
{
    char input, buff[100];
    int response;
    time_t usersTime, timer, current_time;


    while(1)
    {
        uprintf("A -- App Config Fields\r\n");
        uprintf("D -- assign Default values to EEPROM sys_data and FRAM sys_samp structures\r\n");
        uprintf("E -- Edit/Copy EEPROM sys_data structure\r\n");          // Copy and edit sys_data EEPROM structure after firmware upgrade\r\n");
        uprintf("S -- Print EEPROM Sys_data structure\r\n");              //
        uprintf("T -- Print FRAM sys_samp sampling and pump sequence data structure\r\n");
        uprintf("I -- Init FRAM sys_samp data structure\r\n");
        uprintf("Z -- ADC 24bit Sampling Parameters\r\n");
        // reset_defaults - sys_data and sys_samp

        uprintf("M -- MetaData\r\r\n");
        uprintf("R -- print QA Report\r\r\n");                                      // was uprintf("P -- Print QA report\r\r\n");
        uprintf("Q -- QA and setup after board manufacture\r\r\n");
        // T print sys_data
        uprintf("V -- debug print flag (v to clear, V to set)\r\n");
        uprintf("9 -- Exit to Main Menu\r\n");
        uprintf("\r\nEnter Selection [9]: ");

        // Get user's selection with a 5 min timeout
        UARTFlushRx();
        timer = 300 + ROM_HibernateRTCGet();

        while(1)
        {
            if( UARTRxBytesAvail() )
            {
                input = get_key();
                break;
            }

            if( timer <= ROM_HibernateRTCGet() ) sleep(IDLE, 0);
        }

        switch(input)
        {
            case 'A':
            case 'a':
                edit_appcfg_fields();
                break;

            case 'c':
            case 'C':
                exercise_iso();
                break;

            case 'd':
            case 'D':
                response = yesOrNoMenuChoice("\r\r\n\r\r\nAssign defaults will reset ALL custom config and setup data, do you wish to proceed? [N]? ", NO);
                if(response == YES)
                {
                    init_sys_data_default();
                    init_sys_samp_default();            // saves to fram
                    storeSysDataVariables();
                    uprintf("\r\nDefaults assigned and stored in EEPROM for sys_data and FRAM for sys_samp structures\r\n\r\n");
                    retrieveSysDataVariables();
                    print_sys_data_structure();
                    uprintf("\r\n\r\n");
                    print_sys_samp_data_structure();


                }

                break;

            case 'e':
            case 'E':
                copy_edit_sys_data_structure();
                break;

            case 'T':
            case 't':
                print_sys_samp_data_structure();
                break;

            case 'I':
            case 'i':
                init_sys_samp_default();
                print_sys_samp_data_structure();
                break;

            case 'F':
            case 'f':
                uprintf("\r\nfram test:\r\n\r\n");
                if( fram_probe() != 0xAA55AA55)           // read the manufacturer id, or read byte signature in the case of no manufactuerer id
                {
                    uprintf("\r\nERROR: FRAM probe fails\r\n");
                }
                else
                {
                    uprintf("\r\nPASS: FRAM probe\r\n");
                }

                print_sys_samp_data_structure();

                fram_test();

                uprintf("\r\nfram sys samp volatile data restore\r\n\r\n");
                fram_sys_samp_store();

                break;

            case 'M':
            case 'm':
                // print metadata header
                current_time = ROM_HibernateRTCGet();
                print_write_metadata_header(current_time, 1, 0);
                break;

            case 'Q':
            case 'q':
                response = yesOrNoMenuChoice("\r\r\n\r\r\nQA for new board, this will wipe out ALL config and setup data, do you wish to proceed? [N]? ", NO);
                if(response == YES)
                {
                    board_qa_and_init(1); // pass in 1 for init of Flash mem
                }

                break;

            case 'R':
            case 'r':           // was P 10 Apr 2022
                uprintf("\r\r\n\r\r\nQA Report:  \r\r\n\r\r\n");
                print_qa_report();
                break;

            case 'S':
            case 's':
                if(sys_data.app_cfg[APPCFG_MENU_LEVEL] == 1)
                {
                    uprintf("sys_data structure:\r\r\n\r\r\n");
                    print_sys_data_structure();

                    uprintf("\r\r\n");
                    uint32_t temp;
                    temp = sizeof(struct systemData);
                    uprintf("sizeof sys_data = %u\r\r\n", temp);

                    temp = EEPROMSizeGet(); // Get EEPROM Size
                    uprintf("EEPROM Size %d bytes\r\r\n", temp);

                }
                break;

            case 'v':
                sys_data.debug_flag = 0;
                uprintf("\r\nsys_data.debug_flag is OFF\r\n");
                break;
            case 'V':
                sys_data.debug_flag = 1;
                dbg_printf("\r\nsys_data.debug_flag is ON\r\n");
                break;

            case 'z':
            case 'Z':
                config_adc24_sampling_parms();
                break;

            default: //Exit
                // Write the sys_data struct into EEPROM.  Last argument ensures # of bytes is multiple of 4
                if(storeSysDataVariables())                     //if(EEPROMProgram((uint32_t*) &sys_data, 0x400, (sizeof(sys_data) + 3) & ~3))
                {
                    uprintf("\r\n\r\nError storing system data.\r\n");
                }
                else uprintf("\r\n\r\nSystem data stored.  \r\n");
                return;
        }
    }
}

/********************************************************************************************
 *  Configuration Menu, aka config_menu
 ********************************************************************************************/
void configuration_menu(void)
{
    char input, buff[100];
    int response;
    time_t usersTime, timer, current_time;
    unsigned long temp;
    float ftemp;


    while(1)
    {
        //print out config menu
        //uprintf("\r\n\r\n\r\nConfiguration Menu -- %s", VERSION);
        uprintf("\r\n\r\n\r\nConfiguration Menu:\r\n");
        uprintf("1 -- Set Clock\r\n");
        uprintf("2 -- Change File Name\r\n");
        uprintf("3 -- Set Deployment Parameters\r\n");
        uprintf("4 -- Enter pH Sensor Calibration Coefficients\r\n");
        uprintf("5 -- Calculate pH Sensor Calibration Coefficients\r\n");
        uprintf("6 -- Change Baud Rate\r\n");
        uprintf("7 -- Config Data Fields\r\n");
        uprintf("8 -- Metadata Settings\r\n");        // was a hidden menu requiring password
        uprintf("\r\n");
        uprintf("D -- Data Header, Sample Data, Sample Timing\r\n");
        uprintf("E -- Export Calibration data\r\n");
        uprintf("M -- Metadata\r\n");
        //uprintf("E -- Edit/Copy EEPROM sys_data structure\r\n");          // Copy and edit sys_data EEPROM structure after firmware upgrade\r\n");
        //uprintf("S -- Print EEPROM Sys_data structure\r\n");              // turn this on by 'Q' in Help menu (main.c)
        //uprintf("A -- App Config Fields\r\n");
        //uprintf("Z -- ADC 24bit Sampling Parameters\r\n");
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
        uprintf("P -- Pump Sequencer Setup\r\n");
#endif
        //uprintf("\r\n");
        uprintf("Y -- Advanced Setup Menu\r\n");  // advanced_setup_menu
        uprintf("\r\n");
        uprintf("9 -- Exit to Main Menu\r\n");
        uprintf("\r\nEnter Selection [9]: ");

        // Get user's selection with a 5 min timeout
        UARTFlushRx();
        timer = 300 + ROM_HibernateRTCGet();

        while(1)
        {
            if( UARTRxBytesAvail() )
            {
                input = get_key();
                break;
            }

            if( timer <= ROM_HibernateRTCGet() ) sleep(IDLE, 0);
        }

        switch(input)
        {
            case 'Y':
            case 'y':
                advanced_setup_menu();
                break;
#ifdef MOVEDMENU
            case 'z':
            case 'Z':
                config_adc24_sampling_parms();
                break;
#endif
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
            case 'P':
            case 'p':
                // Pump Sequencer Setup
                pump_sequencer_setup();
                break;
#endif
#ifdef MOVEDMENU
            case 'A':
            case 'a':
                edit_appcfg_fields();
                break;

            case 'S':
            case 's':
                print_sys_data_structure();
                break;

            case 'c':
            case 'C':
                exercise_iso();
                break;
#endif
            case 'd':
                test_get_sample_timing();
                break;
            case 'D':
                test_get_sample_loop();
                break;

            case 'e':
            case 'E':
                export_pH_sensor_cal_coeff();
                break;

            case 'm':
            case 'M':
                current_time = ROM_HibernateRTCGet();
                print_write_metadata_header(current_time, 1, 0);
                break;

#ifdef MAKESAMEASTESTDd
            case 'd':
            case 'D':
            //case ' ':
                //print_config_data_fields();
                uprintf("\r\n Data Fields:\r\n\r\n");
                print_write_config_data_fields(1,0,1);  // print with pad of // 
                uprintf("\r\n\r\n");
                print_data_header();     // defd in config.c
                sys_data.app_cfg[APPCFG_SAMPLING_DIAG] = 1;
                sys_samp.pump_seq_state = 0;   // initialize pump sequence variable to disable pumps
                get_sample(1,0);
                sys_data.app_cfg[APPCFG_SAMPLING_DIAG] = 0;
                break;
#endif
#ifdef MOVEDMENU
            case 'e':
            case 'E':
                copy_edit_sys_data_structure();
                break;
#endif
#ifdef OLDCODE
            case 'm':
            case 'M':
                //microsd_logging();
                if(sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 1)
                {
                    response = yesOrNoMenuChoice("\r\n\r\nDisable MicroSD logging? (Y/N) [N]? ", NO);
                    if(response == YES)
                    {
                        sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;
                        storeSysDataVariables();
                    }
                }
                else
                {
                    response = yesOrNoMenuChoice("\r\n\r\nEnable MicroSD logging? (Y/N) [N]? ", NO);
                    if(response == YES)
                    {
                        sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;
                        storeSysDataVariables();
                    }
                }

                if(sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 1)
                    uprintf("MicroSD logging is Enabled\r\n\r\n");
                else
                    uprintf("MicroSD card DISabled, no Logging\r\n\r\n");
                break;
#endif
            case '1':  // Set Clock
                response = yesOrNoMenuChoice("\r\n\r\nIs time GMT? (Y/N) [N]? ", NO);
                if(response == YES) sys_data.GMT = true;
                else sys_data.GMT = false;

                usersTime = getDateAndTime();

                if(usersTime)
                {
                    ROM_HibernateRTCSet(usersTime); // Set time if user entered valid time
                    uprintf("\r\nTime now: ");
                    printCurrentTime();
                    if(sys_data.GMT) uprintf(" GMT");
                    else uprintf(" Local");
                    uprintf("\r\n\r\nNote: Daylight Savings not observed. Use GMT when this will be an issue.\r\n");
                }
                break;

            case '2':  //Set / Change file name
                uprintf("\r\nEnter data file name (no spaces, 8 characters before .txt or .xls) [%s]: ", sys_data.fileName);
                if( getUserInput(buff, MAX_FILENAME) )
                {
                    strcpy(sys_data.fileName, buff);
                    uprintf("\r\nFile name now: %s\r\n", sys_data.fileName);
                }

                uprintf("\r\n\r\nEnter user initials [%s]: ", sys_data.user);

                if( getUserInput(buff, MAX_USER_INITIALS) )
                {
                    strcpy(sys_data.user, buff);
                    uprintf("\r\nUser initials now: %s\r\n", sys_data.user);
                }
                break;

            case '3':  //Set timing (query user for values, save them in EEPROM)

                // Sample period
                if(sys_data.sample_aligned == true)  // THOM new 23Apr2019
                {
                    response = yesOrNoMenuChoice("\r\n\r\nSample aligned to hour? (Y/N) [Y]? ", YES);
                }
                else
                {
                    response = yesOrNoMenuChoice("\r\n\r\nSample aligned to hour? (Y/N) [N]? ", NO);
                }

                if(response == YES) sys_data.sample_aligned = true;
                else sys_data.sample_aligned = false;

                while(1)
                {
                    uprintf("\r\nEnter sample period [%u] sec: ", sys_data.sampling_period);
                    if(getUserInput(buff, 20))
                    {
                        if(sscanf(buff, "%u", &temp) == 1)
                        {

                            // sample_period = 0 means POLLED MODE
                            // use COMMAND mode to keep from going into DEPLOY   THOMHERE

                            if(temp == 0)
                            {
                                uprintf("\r\nSample period is zero - polled mode\r\n");
                            }


                            if(sys_data.sample_aligned)     // Sample aligned to hour?
                            {
                                //if(3600 % temp)
                                if((3600 % temp) && (temp > 0))     // BUG Fix 6 May 2019, per request to allow sample aligned to hour in polled mode (sample period = 0) - Not sure the sense of it though since in polled mode, the poller is determining the time
                                {
                                    uprintf("\r\nSample period must evenly divide hour (e.g. 5, 10, 15, 20, 30 minutes)");
                                    continue;
                                }
                            }

                            if(temp <= MAX_SAMPLING_PERIOD)        // Check if less than hour 3600 seconds
                            {
                                sys_data.sampling_period = temp;
                                uprintf("Sample period now %u sec.\r\n\r\n", sys_data.sampling_period);
                                break;
                            }
                            else
                            {
                                uprintf("\r\nEnter time less than or equal to %u sec", MAX_SAMPLING_PERIOD);
                            }

                            continue;
                        } // scanf
                        else break;

                    }
                    else break;
                }
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
                pump_sequencer_setup();
#endif

#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                // Low battery voltage
                while(1)
                    {
#if BOARD_MFET >= 1
                        sprintf(buff, "\r\nEnter low battery_voltage (ex. 5.5 V) [%.1f V]: ", sys_data.low_batt_volt);
#endif
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
                        sprintf(buff, "\r\nEnter low battery_voltage (ex. 10.5 V with Pump) [%.1f V]: ", sys_data.low_batt_volt);
#endif
#if BOARD_NANOFET >= 1
                        //sprintf(buff, "\r\nEnter low battery_voltage (ex. 5.5 V) [%.1f V]: ", sys_data.low_batt_volt);
                        sprintf(buff, "\r\nBattery voltage check not available on NanoFET  [%.1f V]: ", sys_data.low_batt_volt);
#endif

                        uprintf("%s", buff);
                        if(getUserInput(buff, strlen(buff) ))
                        {
                            if(sscanf(buff, "%f", &ftemp) == 1)
                            {
                                if(ftemp >= 0 && ftemp <= 30)
                                {
                                    sys_data.low_batt_volt = ftemp;
                                    sprintf(buff, "\r\nLow battery_voltage now [%.1f V]\r\n\r\n", sys_data.low_batt_volt);
                                    uprintf("%s", buff);
                                break;
                                }
                                else uprintf("\r\nEnter voltage less than 30 V");
                                continue;
                            }
                            else break;
                        }
                            else break;
                    }
#endif

                // Output mode
                uprintf("\r\nOutput mode menu\r\n");
                uprintf("1 -- Normal  (Data only)\r\n");
                uprintf("2 -- Verbose (Data with prompts)\r\n");
                uprintf("\r\nEnter Selection [%d]: ", (int)sys_data.output);

                input = get_key();

                if(input)
                {
                    switch(input)
                    {
                        case '1': sys_data.output = NORMAL;
                        uprintf("\r\n\r\nOutput mode now: NORMAL");
                            break;

                        case '2': sys_data.output = VERBOSE;
                        uprintf("\r\n\r\nOutput mode now: VERBOSE");
                            break;
                    }

                }

                // Error check the setup

                uint32_t sampTimeEst;
                sampTimeEst = sys_data.pump1_ontime * 1000;


                if((sys_data.data_cfg[CFG_UART3_INST] > INST_OPTODE_NOTDEFD) ||  (sys_data.data_cfg[CFG_UART4_INST] > INST_CTD_NOTDEFD))
                    sampTimeEst += 2500;        // TBD

                if(sys_data.data_cfg[CFG_BIAS_BAT_NEG] > 0)
                    sampTimeEst += ((VBIAS_TRIALS * 1000) / VBIAS_SPS);
                if(sys_data.data_cfg[CFG_BIAS_BAT_POS] > 0)
                    sampTimeEst += ((VBIAS_TRIALS * 1000) / VBIAS_SPS);
                if(sys_data.data_cfg[CFG_I_SUBSTRATE] > 0)
                    sampTimeEst += ((IB_TRIALS * 1000) / IB_SPS);
                if(sys_data.data_cfg[CFG_I_COUNTER] > 0)
                    sampTimeEst += ((IK_TRIALS * 1000) / IK_SPS);
                if(sys_data.data_cfg[CFG_V_COUNTER_ELECT] > 0)
                    sampTimeEst += ((VK_TRIALS * 1000) / VK_SPS);
                if(sys_data.data_cfg[CFG_V_THERMISTOR] > 0)
                    sampTimeEst += ((VTHERM_TRIALS * 1000) / VTHERM_SPS);
                if(sys_data.data_cfg[CFG_VRSI_BIASED] > 0)
                    sampTimeEst += ((VRSI_TRIALS * 1000) / VRSI_SPS);
                if(sys_data.data_cfg[CFG_VRSI] > 0)
                    sampTimeEst += ((VRSI_TRIALS * 1000) / VRSI_SPS);
                if(sys_data.data_cfg[CFG_VRSE_BIASED] > 0)
                    sampTimeEst += ((VRSE_TRIALS * 1000) / VRSE_SPS);
                if(sys_data.data_cfg[CFG_VRSE] > 0)
                    sampTimeEst += ((VRSE_TRIALS * 1000) / VRSE_SPS);

                sampTimeEst += 150;


                if(sampTimeEst > (250 + sys_data.sampling_period*1000)) // 250msec is margin (somewhat arbitrarily set)
                {
                    if(sys_data.sampling_period > 0)
                        uprintf("\r\nError: Estimated sample time = %.2f sec, is greater than sample period = %u sec.  Increase sample period\r\n", (float)sampTimeEst/1000.0, sys_data.sampling_period);
                    else
                        uprintf("\r\nEstimated sample time = %.2f sec in polled mode (sample period is 0)\r\n", (float)sampTimeEst/1000.0, sys_data.sampling_period);  // buf fix 22 Jul 2021
                }
                else
                {
                    uprintf("\r\nEstimated sample time = %.2f sec, sample period = %u sec\r\n", (float)sampTimeEst/1000.0, sys_data.sampling_period);

                }

                break;

            //float ftemp;
            case '4': //Enter pH Sensor Calibration Coefficients
                //Eo_int_25
                enter_pH_sensor_cal_coeff();
                break;

            case '5': //Calculate pH Sensor Calibration Coeffcients
                ph_calib();
                break;

            case '6':  // Change baud rate
                change_baud_rate();
                break;

            case '7':  // Config data fields (select which fields are logged and displayed)
                config_data_fields();
                break;

            case '8': // Was a Hidden menu option, now metadata menu 2 Apr 2021
                uprintf("\r\nMetadata Settings:\r\n");

                enter_metadata();  // user entry of metadata settings

                break;



#ifdef FUTURECODE_ENTERTRIALSSPS
            case 'Q':

                // pH Vint sample rate setting
                while(1)
                {
                    uprintf("\r\nEnter pH Vint sample rate setting [%d]: ", sys_data.Vrsi_sps);
                    if(getUserInput(buff, 20))
                    {
                        if(sscanf(buff, "%d", &temp) == 1)
                        {
                            if(temp == 5 || temp == 10 || temp == 20 || temp == 40 || temp == 80 || temp == 160
                                    || temp == 320 || temp == 640 || temp == 1000 || temp == 2000)
                            {
                                sys_data.Vrsi_sps = temp;
                                uprintf("\r\npH Vint data rate now %d sps\r\n\r\n", sys_data.Vrsi_sps);
                                break;
                            }
                            else uprintf("\r\nEnter 5, 10, 20, 40, 80, 160, 320, 640, 1000, or 2000");
                            continue;
                        }
                        else break;
                    }
                    else break;
                }

                break;


                // pH Vint gain setting
                while(1)
                {
                    uprintf("\r\nEnter pH Vint gain setting [%d]: ", sys_data.Vint_gain);
                    if(getUserInput(buff, 20))
                    {
                        if(sscanf(buff, "%d", &temp) == 1)
                        {
                            if(temp == 1 || temp == 2 || temp == 4 || temp == 8 || temp == 16 || temp == 32)
                            {
                                sys_data.Vint_gain = temp;
                                uprintf("\r\npH Vint gain now %d\r\n\r\n", sys_data.Vint_gain);
                                break;
                            }
                            else uprintf("\r\nEnter 1, 2, 4, 8, 16, or 32");
                            continue;
                        }
                        else break;
                    }
                    else break;
                }

#endif
            default: //Exit
                // Write the sys_data struct into EEPROM.  Last argument ensures # of bytes is multiple of 4
                if(storeSysDataVariables())                     //if(EEPROMProgram((uint32_t*) &sys_data, 0x400, (sizeof(sys_data) + 3) & ~3))
                {
                    uprintf("\r\n\r\nError storing system data.\r\n");
                }
                else uprintf("\r\n\r\nSystem data stored.  -- Press enter to bring up main menu\r\n");
                return;
        }
    }
}


void pump_sequencer_setup(void)
{

    char input, buff[100];
    int response;
    uint32_t temp;

    // Pump Sequence Type
    while(1)
    {
        if(sys_data.pump_seq_type == TYPE_PUMP_NOTDEFD)     // For now, dont allow 'not defined', default is single pump
            sys_data.pump_seq_type = TYPE_PUMP_SINGLE;

        // initialize pump seq volatile vars
        sys_samp.pump_seq_state = 0;  //ST_SEQ_NADA, disables pump sequencer
        sys_samp.pump1_cnt = 0;
        sys_samp.pump2_cnt = 0;

        fram_sys_samp_store();

        uprintf("\r\nEnter Pump Sequence Type (1=Single, 2=Two Pump Alt BEAMSv1, 3=Two Pump BEAMSv2, 4=Self Cal [%d]: ", sys_data.pump_seq_type);
        //uprintf("\r\nEnter Pump Sequence Type (1=Single, 2=Two Pump Alt BEAMSv1 [%d]: ", sys_data.pump_seq_type);
        if(getUserInput(buff, 2))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                // from system.h
                // #define TYPE_PUMP_NOTDEFD       0
                // #define TYPE_PUMP_SINGLE        1
                // #define TYPE_2PUMP_BEAMSV1      2
                // #define TYPE_2PUMP_BEAMSV2      3
                // #define TYPE_PUMP_SELFCAL       4
                //if(temp == 1 || temp == 2 || temp == 3)
                if(temp == 0)
                {
                    sys_data.pump_seq_type = temp;
                    uprintf("\r\nPump Sequence Type = %d, Disabled\r\n\r\n", sys_data.pump_seq_type);
                }
                if(temp == 1 || temp == 2|| temp == 3|| temp == 4)
                {
                    sys_data.pump_seq_type = temp;
                    uprintf("\r\nPump Sequence Type = %d\r\n\r\n", sys_data.pump_seq_type);
                    break;
                }
                else uprintf("\r\nEnter 1,2,3,4 to select pump sequencer, 0 to disable");
                continue;
            }
            else break;
        }
        else break;
    }

    //else uprintf("\r\nEnter time less than 3600 sec");
    if(sys_data.pump_seq_type == TYPE_PUMP_SINGLE)
    {
        // Pump on time
        while(1)
        {
            //uprintf("\r\nEnter pump on time [%u] sec: ", sys_data.pump1_ontime);
            uprintf("Enter Pump1 run time [%u] sec: ", sys_data.pump1_ontime);
            if(getUserInput(buff, 20))
            {
                if(sscanf(buff, "%u", &temp) == 1)
                {
                    if(temp <= 3600)
                    {
                        sys_data.pump1_ontime = temp;
                        uprintf("Pump on time now %u sec.\r\n\r\n", sys_data.pump1_ontime);
                        break;
                    }
                    else uprintf("\r\nEnter time less than 3600 sec");
                    continue;
                }
                else
                    break;
            }
            else
                break;
        }
    }

    uprintf("\r\nEnter Experiment Delay Start feature is not yet implemented...\r\n");
    uprintf("\r\nEnter Experiment Duty Cycle feature is not yet implemented...\r\n");
#ifdef FUTURECODE
    // Duty Cycle On
    while(1)
    {

        uprintf("\r\nEnter Experiment Duty Cycle ON Time in hours (0 for Disable) [%d]: ", sys_data.sampleCnt_duty_on/3600);
        if(getUserInput(buff, 4))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 1000)
                {
                    sys_data.sampleCnt_duty_on = 3600 * temp;       // on time in seconds
                    uprintf("\r\nExperiment Duty Cycle On Time = %d\r\n\r\n", sys_data.sampleCnt_duty_on/3600);
                    break;
                }
                else uprintf("\r\nEnter a number less than 1000 hours");
                continue;
            }
            else break;
        }
        else break;
    }

    // Duty Cycle Off
    if(sys_data.sampleCnt_duty_on > 0)
    {
        while(1)
        {
            uprintf("\r\nEnter Experiment Duty Cycle OFF Time in hours [%d]: ", sys_data.sampleCnt_duty_off/3600);
            if(getUserInput(buff, 4))
            {
                if(sscanf(buff, "%d", &temp) == 1)
                {
                    if((temp <= 1000) || (temp == 0))
                    {
                        sys_data.sampleCnt_duty_off = 3600 * temp;       // on time in seconds
                        uprintf("\r\nExperiment Duty Cycle On Time = %d\r\n\r\n", sys_data.sampleCnt_duty_off/3600);
                        break;
                    }
                    else uprintf("\r\nEnter a number greater than 0, less than 1000 hours");
                    continue;
                }
                else break;
            }
            else break;
        }
    }
#endif


    if((sys_data.pump_seq_type == TYPE_2PUMP_BEAMSV1) || (sys_data.pump_seq_type == TYPE_2PUMP_BEAMSV2))
    {
        config_two_pump_beams_v1();
    }



}







void config_two_pump_beams_v1(void)
{
    char input, buff[100];
    int response;
    uint32_t temp;


    // Pump 1 ontime (seconds)
    while(1)
    {
        uprintf("\r\nEnter Pump1 run time [%d] sec: ", sys_data.pump1_ontime);
        if(getUserInput(buff, 8))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 5*3600)
                {
                    sys_data.pump1_ontime = temp;       // on time in seconds
                    uprintf("Pump1 run time = %d sec\r\n\r\n", sys_data.pump1_ontime);
                    break;
                }
                else uprintf("\r\nEnter a number less than or equal to %d seconds", 5*3600);
                continue;
            }
            else break;
        }
        else break;
    }

    // Pump 2 ontime (seconds)
    while(1)
    {
        uprintf("\r\nEnter Pump2 run time [%d] sec: ", sys_data.pump2_ontime);
        if(getUserInput(buff, 8))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 5*3600)
                {
                    sys_data.pump2_ontime = temp;       // on time in seconds
                    uprintf("\r\nPump2 run time = %d sec\r\n\r\n", sys_data.pump2_ontime);
                    break;
                }
                else uprintf("\r\nEnter a number less than or equal to %d seconds", 5*3600);
                continue;
            }
            else break;
        }
        else break;
    }


    // Pump 1 cycles
    while(1)
    {
        uprintf("\r\nEnter number of sampling cycles for Pump1 [%d]: ", sys_data.pump1_cycles);
        if(getUserInput(buff, 4))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 1000)
                {
                    sys_data.pump1_cycles = temp;       // on time in seconds
                    uprintf("\r\nSampling cycles Pump1 = %d\r\n\r\n", sys_data.pump1_cycles);
                    break;
                }
                else uprintf("\r\nEnter a number less than 1000 cycles");
                continue;
            }
            else break;
        }
        else break;
    }




    // Pump 2 cycles
    while(1)
    {
        uprintf("\r\nEnter number of sampling cycles for Pump2 [%d]: ", sys_data.pump2_cycles);
        if(getUserInput(buff, 4))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 1000)
                {
                    sys_data.pump2_cycles = temp;       // on time in seconds
                    uprintf("\r\nSampling cycles Pump2 = %d\r\n\r\n", sys_data.pump2_cycles);
                    break;
                }
                else uprintf("\r\nEnter a number less than 1000 cycles");
                continue;
            }
            else break;
        }
        else break;
    }
}


void config_two_pump_beams_v2(void)
{
    char input, buff[100];
    int response;
    uint32_t temp;

    //Sampling routine will change to: turn pump1 on for X minutes, and while pump is on, keep polling sensors at Y second intervals. Then switch to pump2, then back to pump1, etc.
    //This is a significant hit to the power budget since we will constantly be operating a pump. To extend battery life (goal is to do long term benthic flux measurements), it would be great if we have some duty cycle on the order of days. So like 3 days on, 3 days off, etc; all user configurable.

    // Pump 1 ontime (seconds)
    while(1)
    {
        uprintf("\r\nEnter Pump1 run time [%d] sec: ", sys_data.pump1_ontime);
        if(getUserInput(buff, 8))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 5*3600)
                {
                    sys_data.pump1_ontime = temp;       // on time in seconds
                    uprintf("Pump1 run time = %d sec\r\n\r\n", sys_data.pump1_ontime);
                    break;
                }
                else uprintf("\r\nEnter a number less than or equal to %d seconds", 5*3600);
                continue;
            }
            else break;
        }
        else break;
    }

    // Pump 2 ontime (seconds)
    while(1)
    {
        uprintf("\r\nEnter Pump2 run time [%d] sec: ", sys_data.pump2_ontime);
        if(getUserInput(buff, 8))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 5*3600)
                {
                    sys_data.pump2_ontime = temp;       // on time in seconds
                    uprintf("\r\nPump2 run time = %d sec\r\n\r\n", sys_data.pump2_ontime);
                    break;
                }
                else uprintf("\r\nEnter a number less than or equal to %d seconds", 5*3600);
                continue;
            }
            else break;
        }
        else break;
    }


    // Pump 1 cycles
    while(1)
    {
        uprintf("\r\nEnter number of sampling cycles for Pump1 [%d]: ", sys_data.pump1_cycles);
        if(getUserInput(buff, 4))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 1000)
                {
                    sys_data.pump1_cycles = temp;       // on time in seconds
                    uprintf("\r\nSampling cycles Pump1 = %d\r\n\r\n", sys_data.pump1_cycles);
                    break;
                }
                else uprintf("\r\nEnter a number less than 1000 cycles");
                continue;
            }
            else break;
        }
        else break;
    }




    // Pump 2 cycles
    while(1)
    {
        uprintf("\r\nEnter number of sampling cycles for Pump2 [%d]: ", sys_data.pump2_cycles);
        if(getUserInput(buff, 4))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 1000)
                {
                    sys_data.pump2_cycles = temp;       // on time in seconds
                    uprintf("\r\nSampling cycles Pump2 = %d\r\n\r\n", sys_data.pump2_cycles);
                    break;
                }
                else uprintf("\r\nEnter a number less than 1000 cycles");
                continue;
            }
            else break;
        }
        else break;
    }
}

void config_self_cal(void)
{
    char input, buff[100];
    int response;
    uint32_t temp;

    // Pump 1 ontime (seconds)
    while(1)
    {
        uprintf("\r\nEnter Pump1 run time [%d] sec: ", sys_data.pump1_ontime);
        if(getUserInput(buff, 8))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 5*3600)
                {
                    sys_data.pump1_ontime = temp;       // on time in seconds
                    uprintf("Pump1 run time = %d sec\r\n\r\n", sys_data.pump1_ontime);
                    break;
                }
                else uprintf("\r\nEnter a number less than or equal to %d seconds", 5*3600);
                continue;
            }
            else break;
        }
        else break;
    }

    // Pump 2 ontime (seconds)
    while(1)
    {
        uprintf("\r\nEnter Pump2 run time [%d] sec: ", sys_data.pump2_ontime);
        if(getUserInput(buff, 8))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 5*3600)
                {
                    sys_data.pump2_ontime = temp;       // on time in seconds
                    uprintf("\r\nPump2 run time = %d sec\r\n\r\n", sys_data.pump2_ontime);
                    break;
                }
                else uprintf("\r\nEnter a number less than or equal to %d seconds", 5*3600);
                continue;
            }
            else break;
        }
        else break;
    }


    // Pump 1 cycles
    while(1)
    {
        uprintf("\r\nEnter number of sampling cycles for Pump1 [%d]: ", sys_data.pump1_cycles);
        if(getUserInput(buff, 4))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 1000)
                {
                    sys_data.pump1_cycles = temp;       // on time in seconds
                    uprintf("\r\nSampling cycles Pump1 = %d\r\n\r\n", sys_data.pump1_cycles);
                    break;
                }
                else uprintf("\r\nEnter a number less than 1000 cycles");
                continue;
            }
            else break;
        }
        else break;
    }




    // Pump 2 cycles
    while(1)
    {
        uprintf("\r\nEnter number of sampling cycles for Pump2 [%d]: ", sys_data.pump2_cycles);
        if(getUserInput(buff, 4))
        {
            if(sscanf(buff, "%d", &temp) == 1)
            {
                if(temp <= 1000)
                {
                    sys_data.pump2_cycles = temp;       // on time in seconds
                    uprintf("\r\nSampling cycles Pump2 = %d\r\n\r\n", sys_data.pump2_cycles);
                    break;
                }
                else uprintf("\r\nEnter a number less than 1000 cycles");
                continue;
            }
            else break;
        }
        else break;
    }
}

//thomthom

// custom fgets for parsing strings terminated by carriage return, aka efgets
// uses global variable FileObject (assumed open for reading)
// writes the result in array pointed by bufPtr
void efgets(char *bufPtr)
{
    uint32_t indx2;
    UINT br;

    for(indx2=0; indx2<24; indx2++)
    {
        f_read(&FileObject, bufPtr+indx2, 1, &br);

        if(*(bufPtr+indx2) == 0x0d)
        {
            *(bufPtr+indx2) = 0;
        }
        if(*(bufPtr+indx2) == 0x0a)
        {
            *(bufPtr+indx2) = 0;
            return;
        }
    }

}

// read from ymodem packet to string buffer
char* egets(char *linePtr, char *bufPtr)
{
    uint32_t indx2;
    UINT br;

#define MAX_STRLINE_CAL_FILE       32

    for(indx2=0; indx2<MAX_STRLINE_CAL_FILE; indx2++)
    {
        *(linePtr+indx2) = *(bufPtr+indx2);

        if(*(bufPtr+indx2) == 0x0d)
        {
            *(linePtr+indx2) = 0;
        }
        if(*(bufPtr+indx2) == 0x0a)
        {
            *(linePtr+indx2) = 0;
            return((bufPtr+indx2+1));       // return pointer to start of next string
        }
    }

    return((bufPtr+indx2));     // not sure what to return - this is an error state

}

// pass in pointer to ymodem data packet
void parse_cal_packet(char *bufPtr)
{
    char line[80];

    //char cal_filename[16];  //was 16 16 Oct 2023
    char sensor_SN[16];  //--> sensor_SN[8]
    char isfet_SN[16];  // --> isfet_SN[8]
    char ise_SN[16];    //  --> ise_SN[8]
    char PT_Cal_date[16];
    float k2_C0 = 0.0;
    float k2_C1 = 0.0;
    float k2_C2 = 0.0;
    float k2_C3 = 0.0;
    float fP_0 = 0.0;
    float fP_1 = 0.0;
    float fP_2 = 0.0;
    float fP_3 = 0.0;
    float fP_4 = 0.0;
    float fP_5 = 0.0;
    float fP_6 = 0.0;
    char k0_Cal_date[16];
    float k0_HCl = 0.0;
    float k0_SW = 0.0;
    float k0std_SW = 0.0;
    char service_date[16];

    uint32_t file_size;
    uint32_t indx, indx2;


    bufPtr = egets(line, bufPtr);
    sscanf(line, "Sensor_SN,%s", sensor_SN);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "ISFET_SN,%s", isfet_SN);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "ISE_SN,%s", ise_SN);

    for(indx=0; indx<sizeof(PT_Cal_date); indx++)       // Not needed.
        PT_Cal_date[indx] = 0;

    bufPtr = egets(line, bufPtr);
    sscanf(line, "PT_Cal_date,%s", PT_Cal_date);

    PT_Cal_date[10] = 0;        // fixing an extra letter bug

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k2_C0,%f", &k2_C0);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k2_C1,%f", &k2_C1);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k2_C2,%f", &k2_C2);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k2_C3,%f", &k2_C3);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "fP_0,%f", &fP_0);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "fP_1,%f", &fP_1);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "fP_2,%f", &fP_2);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "fP_3,%f", &fP_3);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "fP_4,%f", &fP_4);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "fP_5,%f", &fP_5);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "fP_6,%f", &fP_6);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k0_Cal_date,%s", k0_Cal_date);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k0_HCl,%f", &k0_HCl);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k0_SW,%f", &k0_SW);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "k0std_SW,%f", &k0std_SW);

    bufPtr = egets(line, bufPtr);
    sscanf(line, "service_date,%s", service_date);


    strncpy(sys_data.sensor_SN, sensor_SN, 7);  //--> sensor_SN[8]
    sys_data.sensor_SN[MAX_SENSOR_SN-1] = 0;
    strncpy(sys_data.isfet_SN, isfet_SN, 7);  // --> isfet_SN[8]
    sys_data.isfet_SN[MAX_ISFET_SN-1] = 0;
    strncpy(sys_data.ise_SN, ise_SN, 7);    //  --> ise_SN[8]
    sys_data.ise_SN[MAX_ISE_SN-1] = 0;
    strncpy(sys_data.PT_Cal_date, PT_Cal_date, 10);  // --> PT_Cal_date[12]
    sys_data.PT_Cal_date[MAX_PT_CAL_DATE-1] = 0;
    sys_data.K2_Cal[0] = k2_C0;
    sys_data.K2_Cal[1] = k2_C1;
    sys_data.K2_Cal[2] = k2_C2;
    sys_data.K2_Cal[3] = k2_C3;
    sys_data.fP_Cal[0] = fP_0;
    sys_data.fP_Cal[1] = fP_1;
    sys_data.fP_Cal[2] = fP_2;
    sys_data.fP_Cal[3] = fP_3;
    sys_data.fP_Cal[4] = fP_4;
    sys_data.fP_Cal[5] = fP_5;
    sys_data.fP_Cal[6] = fP_6;
    strncpy(sys_data.k0_Cal_date, k0_Cal_date, 10);
    sys_data.k0_Cal_date[10] = 0;
    sys_data.k0_HCL = k0_HCl;
    sys_data.k0_SW = k0_SW;
    sys_data.k0std_SW = k0std_SW;
    strncpy(sys_data.service_date, service_date, 10);
    sys_data.service_date[10] = 0;
}


//thomthom
void import_ymodem_cal_coeff(void)
{
    int response;
    int indx;

    //run ymodem, transfer a '*.cal' file, parse and store in sys_data variables
    // ymodem modified to operate without the filesystem.
    response = yesOrNoMenuChoice("\r\n\r\nTransfer Cal file via Teraterm YMODEM? (Y/N) [N]? ", NO);
    if(response == NO)
    {
        return;
    }

    uprintf("OK!  Calling ymodem_receive...(Ctrl-C to cancel)\r\n");
    wait_consoleTx();       //wait for transmit
    uprintf("TeraTerm: File->Transfer->Ymodem->Send *.cal file\r\n");
    wait_consoleTx();       //wait for transmit
    if(sys_data.baud_rate != 115200)
    {
        uprintf("   Note: 15 sec delay after transfer for slow baud ymodem workaround\r\n");
        wait_consoleTx();       //wait for transmit
    }

    calFileFlg = 1;
    ymodem_receive(1, "yr");      //calls parse_cal_packet(char *bufPtr);


    if(sys_data.baud_rate != 115200)
    {
        for(indx=0; indx<8; indx++)
        {
            uprintf("   delay...\r\n");
            ms_delay(2000);
        }

        UARTFlushRx();
    }

    uprintf("\r\n\r\n");

}


void set_cal_filename(char *filename_ptr)
{
    int len;

    len = strlen(filename_ptr);
    if(len >= MAX_CAL_FILENAME)
        len = MAX_CAL_FILENAME-1;
    strncpy(sys_data.cal_filename, filename_ptr, len);   //was 12
    sys_data.cal_filename[len] = 0;      //8.cal // was 12
}

// This import function is for test/development
// called for test from main menu with 'i' - needs to read line at a time (fread)
// test func
void import_pH_sensor_cal_coeff(void)
{
    char line[80];
    int rv;

    // Declare variables to store the data read from the file.

    char cal_filename[16];
    char sensor_SN[16];  //--> sensor_SN[8]
    char isfet_SN[16];  // --> isfet_SN[8]
    char ise_SN[16];    //  --> ise_SN[8]
    char PT_Cal_date[16];
    float k2_C0;
    float k2_C1;
    float k2_C2;
    float k2_C3;
    float fP_0;
    float fP_1;
    float fP_2;
    float fP_3;
    float fP_4;
    float fP_5;
    float fP_6;
    char k0_Cal_date[16];
    float k0_HCl;
    float k0_SW;
    float k0std_SW;
    char service_date[16];

    uint32_t file_size;
    FRESULT fresult;
    UINT br;        // Bytes read
    uint32_t indx, indx2;

    UARTEchoSet(false);     // Disable console echo

    strcpy(cal_filename, "DF384.cal");

    // Open the file for reading.
    fresult = f_open(&FileObject, cal_filename, FA_READ);
    if(fresult != FR_OK)
    {
        uprintf("f_open error: %s\n", StringFromFresult(fresult) );
        //error = -1;
        //goto abort;
        UARTEchoSet(true);      // Enable console echo
        return;
    }

    file_size = (unsigned long)(FileObject.fsize);  // Set file size
    //uprintf("File size = %lu\n", file_size);

    uprintf("importing %s, %lu bytes...\r\n", cal_filename, file_size);    //uprintf("Ymodem sending %s...\r\n", filename);
    UARTFlushTx(false);

    //efgets(line);
    //uprintf("%s\r\n", line);
    //sscanf(line, "Filename,%s", cal_filename);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "Sensor_SN,%s", sensor_SN);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "ISFET_SN,%s", isfet_SN);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "ISE_SN,%s", isfet_SN);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "PT_Cal_date,%s", PT_Cal_date);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k2_C0,%f", &k2_C0);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k2_C1,%f", &k2_C1);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k2_C2,%f", &k2_C2);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k2_C3,%f", &k2_C3);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "fP_0,%f", &fP_0);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "fP_1,%f", &fP_1);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "fP_2,%f", &fP_2);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "fP_3,%f", &fP_3);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "fP_4,%f", &fP_4);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "fP_5,%f", &fP_5);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "fP_6,%f", &fP_6);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k0_Cal_date,%s", &k0_Cal_date);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k0_HCl,%f", &k0_HCl);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k0_SW,%f", &k0_SW);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "k0std_SW,%f", &k0std_SW);
    efgets(line);
    uprintf("%s\r\n", line);
    sscanf(line, "service_date,%s", &service_date);

    uprintf("\r\n\r\n");

    // Print the data that was read.
    uprintf("Filename: %s\r\n", cal_filename);
    uprintf("Sensor_SN: %s\r\n", sensor_SN);
    uprintf("ISFET_SN: %s\r\n", isfet_SN);
    uprintf("ISE_SN: %s\r\n", isfet_SN);
    uprintf("PT_Cal_date: %s\r\n", PT_Cal_date);
    uprintf("k2_C0: %e\r\n", k2_C0);
    uprintf("k2_C1: %e\r\n", k2_C1);
    uprintf("k2_C2: %e\r\n", k2_C2);
    uprintf("k2_C3: %e\r\n", k2_C3);
    uprintf("fP_0: %e\r\n", fP_0);
    uprintf("fP_1: %e\r\n", fP_1);
    uprintf("fP_2: %e\r\n", fP_2);
    uprintf("fP_3: %e\r\n", fP_3);
    uprintf("fP_4: %e\r\n", fP_4);
    uprintf("fP_5: %e\r\n", fP_5);
    uprintf("fP_6: %e\r\n", fP_6);
    uprintf("k0_Cal_date: %s\r\n", k0_Cal_date);
    uprintf("k0_HCl: %e\r\n", k0_HCl);
    uprintf("k0_SW: %e\r\n", k0_SW);
    uprintf("k0std_SW: %e\r\n", k0std_SW);
    uprintf("service_date: %s\r\n", service_date);

    strcpy(sys_data.cal_filename, cal_filename);
    strcpy(sys_data.sensor_SN, sensor_SN);
    strcpy(sys_data.isfet_SN, isfet_SN);
    strcpy(sys_data.isfet_SN, isfet_SN);
    //sys_data.PT_Cal_date
    sys_data.K2_Cal[0] = k2_C0;
    sys_data.K2_Cal[1] = k2_C1;
    sys_data.K2_Cal[2] = k2_C2;
    sys_data.K2_Cal[3] = k2_C3;
    sys_data.fP_Cal[0] = fP_0;
    sys_data.fP_Cal[1] = fP_1;
    sys_data.fP_Cal[2] = fP_2;
    sys_data.fP_Cal[3] = fP_3;
    sys_data.fP_Cal[4] = fP_4;
    sys_data.fP_Cal[5] = fP_5;
    sys_data.fP_Cal[6] = fP_6;
    //sys_data.k0_Cal_date
    //sys_data.k0_HCL
    //sys_data.k0_SW
    //sys_data.k0std_SW
    strcpy(sys_data.service_date, service_date);

    uprintf("\r\n\r\n");

    f_close(&FileObject);
    UARTEchoSet(true);      // Enable console echo

#ifdef NOCODE
    // Read the line from the file.
    rv = fgets(line);

    // Use sscanf to read the data from the line.
    rv = sscanf(line, "%s,%s,%s,%s,%s,%f,%f,%f,%f,%f,%f,%f,%f,%s,%f,%f,%f",
                filename, sensorSN, ISFET_SN, ISE_SN, PT_Cal_date, &k2_C0, &k2_C1, &k2_C2, &k2_C3,
                &fP_0, &fP_1, &fP_2, &fP_3, &fP_4, &fP_5, &fP_6, &k0_Cal_date, &k0_HCl, &k0_SW, &k0std_SW);

    // Check if the read was successful.
    if (rv != 18) {
      printf("Error reading line: %s\n", line);
      return 1;
    }

    // Print the data that was read.
    printf("Filename: %s\n", filename);
    printf("SensorSN: %s\n", sensorSN);
    printf("ISFET_SN: %s\n", ISFET_SN);
    printf("ISE_SN: %s\n", ISE_SN);
    printf("PT_Cal_date: %s\n", PT_Cal_date);
    printf("k2_C0: %lf\n", k2_C0);
    printf("k2_C1: %lf\n", k2_C1);
    printf("k2_C2: %lf\n", k2_C2);
    printf("k2_C3: %lf\n", k2_C3);
    printf("fP_0: %lf\n", fP_0);
    printf("fP_1: %lf\n", fP_1);
    printf("fP_2: %lf\n", fP_2);
    printf("fP_3: %lf\n", fP_3);
    printf("fP_4: %lf\n", fP_4);
    printf("fP_5: %lf\n", fP_5);
    printf("fP_6: %lf\n", fP_6);
    printf("k0_Cal_date: %s\n", k0_Cal_date);
    printf("k0_HCl: %lf\n", k0_HCl);
    printf("k0_SW: %lf\n", k0_SW);
    printf("k0std_SW: %lf\n", k0std_SW);


#endif

}

// called as test function from main menu with 'g'.  From deploy mode, 'gc' Print to console the pH cal coefficients stored in sys_data
void get_pH_sensor_cal_coeff(void)
{
    int indx;
    int bufIndx;
    int prnIndx;


    bufIndx=0;
    prnIndx=0;

    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%s\t", sys_data.sensor_SN);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%s\t", sys_data.isfet_SN);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%s\t", sys_data.ise_SN);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%s\t", sys_data.PT_Cal_date);

    for(indx=0; indx<NUMOF_K2_CAL_FIELDS; indx++)
    {
        bufIndx += sprintf((char *)&prnBuf[bufIndx], "%e\t", sys_data.K2_Cal[indx]);
    }

    prnBuf[bufIndx] = 0;
    uprintf("%s", &prnBuf[prnIndx]);
    wait_consoleTx();
    prnIndx = bufIndx;

    for(indx=0; indx<NUMOF_FP_CAL_FIELDS; indx++)
    {
        bufIndx += sprintf((char *)&prnBuf[bufIndx], "%e\t", sys_data.fP_Cal[indx]);
    }

    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%s\t", sys_data.k0_Cal_date);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%e\t", sys_data.k0_HCL);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%e\t", sys_data.k0_SW);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%e\t", sys_data.k0std_SW);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "%s\r\n", sys_data.service_date);

    //bufIndx += sprintf((char *)&prnBuf[bufIndx], "\r\n");

    //uprintf("%s", prnBuf);
    prnBuf[bufIndx] = 0;
    uprintf("%s", &prnBuf[prnIndx]);
    wait_consoleTx();
    prnIndx = bufIndx;
}

// output cal coeff in format same as file
void export_pH_sensor_cal_coeff(void)
{
    int indx;
    int bufIndx;
    int prnIndx;


#ifdef CALFILEDEF
    Sensor_SN,DSD1234
    ISFET_SN,ISF1234
    ISE_SN,ISE1234
    PT_Cal_date,12/15/2022
    k2_C0,-9.641540E-04
    k2_C1,-1.610570E-09
    k2_C2,-4.624490E-12
    k2_C3,7.304790E-15
    fP_0,-1.270040E+00
    fP_1,-3.832110E-06
    fP_2,1.960530E-08
    fP_3,-3.195020E-11
    fP_4,2.544840E-14
    fP_5,-9.926440E-18
    fP_6,1.500790E-21
    k0_Cal_date,8/15/2023
    k0_HCl,-1.270010E+00
    k0_SW,-1.32E+00
    k0std_SW,1.20E-04
    service_date,11/30/2025
#endif

    uprintf("\r\n");

    bufIndx=0;
    prnIndx=0;

    bufIndx += sprintf((char *)&prnBuf[bufIndx], "Cal filename: %s\r\n\r\n", sys_data.cal_filename);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "Sensor_SN,%s\r\n", sys_data.sensor_SN);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "ISFET_SN,%s\r\n", sys_data.isfet_SN);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "ISE_SN,%s\r\n", sys_data.ise_SN);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "PT_Cal_date,%s\r\n", sys_data.PT_Cal_date);

    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k2_C0,%e\r\n", sys_data.K2_Cal[0]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k2_C1,%e\r\n", sys_data.K2_Cal[1]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k2_C2,%e\r\n", sys_data.K2_Cal[2]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k2_C3,%e\r\n", sys_data.K2_Cal[3]);

    prnBuf[bufIndx] = 0;
    uprintf("%s", &prnBuf[prnIndx]);
    wait_consoleTx();
    prnIndx = bufIndx;

    bufIndx += sprintf((char *)&prnBuf[bufIndx], "fP_0,%e\r\n", sys_data.fP_Cal[0]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "fP_1,%e\r\n", sys_data.fP_Cal[1]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "fP_2,%e\r\n", sys_data.fP_Cal[2]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "fP_3,%e\r\n", sys_data.fP_Cal[3]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "fP_4,%e\r\n", sys_data.fP_Cal[4]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "fP_5,%e\r\n", sys_data.fP_Cal[5]);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "fP_6,%e\r\n", sys_data.fP_Cal[6]);

    prnBuf[bufIndx] = 0;
    uprintf("%s", &prnBuf[prnIndx]);
    wait_consoleTx();
    prnIndx = bufIndx;

    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k0_Cal_date,%s\r\n", sys_data.k0_Cal_date);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k0_HCl,%e\r\n", sys_data.k0_HCL);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k0_SW,%e\r\n", sys_data.k0_SW);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "k0std_SW,%e\r\n", sys_data.k0std_SW);
    bufIndx += sprintf((char *)&prnBuf[bufIndx], "service_date,%s\r\n", sys_data.service_date);

    //bufIndx += sprintf((char *)&prnBuf[bufIndx], "\r\n");

    //uprintf("%s", prnBuf);
    prnBuf[bufIndx] = 0;
    uprintf("%s", &prnBuf[prnIndx]);
    wait_consoleTx();
    prnIndx = bufIndx;

    uprintf("\r\n");
}


// called from 1) Config --> 4) enter pH cal
// uprintf("4 -- Enter pH Sensor Calibration Coefficients\r\n");
void enter_pH_sensor_cal_coeff(void)
{
    char input, buff[100];
    int response;
    time_t usersTime, timer;
    unsigned long temp;
    float ftemp;
    double dtemp;
    uint32_t indx;


    // TODO: rework the data entry from while1's to functions

    while(1)
    {
        // a good default is -0.4
        //sprintf(buff, "\r\nEnter E0_int @25 C (ex. -0.4) [%f]: ", sys_data.Eo_int_25C);
        sprintf(buff, "\r\nEnter k0int (ex. -0.4) [%f]: ", sys_data.k0int);

        uprintf("%s", buff);
        if(getUserInput(buff, 20))
        {
            if(sscanf(buff, "%f", &ftemp) == 1)
            {
                if(ftemp >= (-2) && ftemp <= 2)
                {
                    sys_data.k0int = ftemp;
                    break;
                }
                else uprintf("Enter number between -2 and 2 (ex. -0.4)\r\n\r\n");
                continue;
            }
            else break;
        }
        else break;
    }


    //Eo_ext_25
    while(1)
    {
        // per Yui, a good default is -1.3
        //sprintf(buff, "\r\nEnter E0_ext @25 C (ex. -1.3) [%f]: ", sys_data.Eo_ext_25C);
        sprintf(buff, "\r\nEnter k0ext (ex. -1.3) [%f]: ", sys_data.k0ext);

        uprintf("%s", buff);
        if(getUserInput(buff, 20))
        {
            if(sscanf(buff, "%f", &ftemp) == 1)
            {
                if(ftemp >= (-2) && ftemp <= 2)
                {
                    sys_data.k0ext = ftemp;
                    break;
                }
                else uprintf("Enter number between -2 and 2 (ex. -1.3)\r\n\r\n");
                continue;
            }
            else break;
        }
        else break;
    }

    while(1)
    {
        sprintf(buff, "\r\nEnter k2int (ex. -0.001455) [%f]: ", sys_data.k2int);

        uprintf("%s", buff);
        if(getUserInput(buff, 20))
        {
            if(sscanf(buff, "%f", &ftemp) == 1)
            {
                if(ftemp >= (-2) && ftemp <= 2)
                {
                    sys_data.k2int = ftemp;
                    break;
                }
                else uprintf("Enter number between -2 and 2 (ex. -0.001)\r\n\r\n");
                continue;
            }
            else break;
        }
        else break;
    }

    while(1)
    {
        sprintf(buff, "\r\nEnter k2ext (ex. -0.001081) [%f]: ", sys_data.k2ext);

        uprintf("%s", buff);
        if(getUserInput(buff, 20))
        {
            if(sscanf(buff, "%f", &ftemp) == 1)
            {
                if(ftemp >= (-2) && ftemp <= 2)
                {
                    sys_data.k2ext = ftemp;
                    break;
                }
                else uprintf("Enter number between -2 and 2 (ex. -0.001)\r\n\r\n");
                continue;
            }
            else break;
        }
        else break;
    }


    // new THOM 29 Apr 2019, remove TCOffset per Yui, TCOffset feature restored 3 Feb 2021
    if(sys_data.TCOffset > 400.0 || sys_data.TCOffset < -400.0)  // if offset is whacked, zero it.
        sys_data.TCOffset = 0.0;
    // TCOffset added back 3 Feb 2021
    //TCOffset, standard = 0
    while(1)
    {
        // default of zero is ok
    sprintf(buff, "\r\nEnter TCOffset [%f]: ", sys_data.TCOffset);
    uprintf("%s", buff);
    if(getUserInput(buff, 20))
    {
        if(sscanf(buff, "%f", &ftemp) == 1)
        {
            if(ftemp >= -400.0 && ftemp <= 400.00)
            {
                sys_data.TCOffset = ftemp;
                break;
            }
            else uprintf("Enter a reasonable TCOffset such as 0.0\r\n\r\n");
            continue;
        }
        else break;

        }
        else break;
    }



    // new THOM add entry of default salinity
    if(sys_data.default_sal > 100.0 || sys_data.default_sal < 0.0)  // if salinity is whacked, zero it.
    {
        uprintf("Salinity out of range, recommend running the test menu, qa board menu to initialize vars in eeprom\r\n");
        sys_data.TCOffset = 35.0;
    }

    while(1)
    {
        // default of 35.0
    sprintf(buff, "\r\nEnter Salinity for Ext Ref pH calc (typical is 35) [%f]: ", sys_data.default_sal);
    uprintf("%s", buff);
    if(getUserInput(buff, 20))
    {
        if(sscanf(buff, "%f", &ftemp) == 1)
        {
            if(ftemp >= (0.0) && ftemp <= 100.0)
            {
                sys_data.default_sal = ftemp;
                break;
            }
            else uprintf("Enter 35.0\r\n\r\n");
            continue;
        }
        else break;

        }
        else break;
    }
    if(sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] == 0)
    {
        uprintf("\r\n4 Var S-H coefficients for Thermistor to Temperature Celsius:\r\n");
        uprintf("     c0 = %.11lf\r\n", sys_data.quadTherm_c0);
        uprintf("     c1 = %.11lf\r\n", sys_data.quadTherm_c1);
        uprintf("     c2 = %.11lf\r\n", sys_data.quadTherm_c2);
        uprintf("     c3 = %f.11l\r\n", sys_data.quadTherm_c3);
        uprintf("\r\n");
    }
    if(sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] == 1)
    {
        uprintf("\r\n3 Var S-H coefficients for Thermistor to Temperature Celsius:\r\n");
        uprintf("      A = %.11lff\r\n", sys_data.shTherm_A);
        uprintf("      B = %.11lf\r\n", sys_data.shTherm_B);
        uprintf("      C = %.11lf\r\n", sys_data.shTherm_C);
        uprintf("\r\n");
    }


    if(sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] == 0)
    {

        while(1)
        {
            //sprintf(buff, "\r\nEnter Steinhart-Hart c0 (ex. 340.9819863) [%f]: ", sys_data.quadTherm_c0);
            sprintf(buff, "\r\nEnter 4 Var S-H c0 (ex. 340.9819863) [%.11lf]: ", sys_data.quadTherm_c0);

            uprintf("%s", buff);
            if(getUserInput(buff, 20))
            {
                //if(sscanf(buff, "%f", &ftemp) == 1)
                if(sscanf(buff, "%lf", &dtemp) == 1)
                {
                    if(dtemp >= (0.0) && dtemp <= 500.0)
                    {
                        sys_data.quadTherm_c0 = dtemp;
                        uprintf("c0 = %.11lf", sys_data.quadTherm_c0);
                        break;
                    }
                    else uprintf("Enter number between 0 and 500 (ex. 340.9819863)\r\n\r\n");
                    continue;
                }
                else break;
                }
            else break;
        }

        while(1)                 // -0.0000910257
        {
            sprintf(buff, "\r\nEnter 4 Var S-H c1 (ex. -0.0000910257, -9.10257E-05) [%.11lf]: ", sys_data.quadTherm_c1);

            uprintf("%s", buff);
            if(getUserInput(buff, 20))
            {
                if(sscanf(buff, "%lf", &dtemp) == 1)
                {
                    if(dtemp >= (-0.1) && dtemp <= 0.1)
                    {
                        sys_data.quadTherm_c1 = dtemp;
                        uprintf("c1 = %.11lf", sys_data.quadTherm_c1);
                        break;
                    }
                    else uprintf("Enter number between 0.1 and -0.1 (ex. 0.0000910257)\r\n\r\n");
                    continue;
                }
                else break;
                }
            else break;
        }

        while(1)                 // -0.0000910257
        {
            sprintf(buff, "\r\nEnter 4 Var S-H  c2 (ex. -95.08806667) [%.11lf]: ", sys_data.quadTherm_c2);

            uprintf("%s", buff);
            if(getUserInput(buff, 20))
            {
                if(sscanf(buff, "%lf", &dtemp) == 1)
                {
                    if(dtemp >= (-200.0) && dtemp <= 200.0)
                    {
                        sys_data.quadTherm_c2 = dtemp;
                        uprintf("c2 = %.11lf", sys_data.quadTherm_c2);
                        break;
                    }
                    else uprintf("Enter number between -200.0 and 200.0 (ex. -95.08806667)\r\n\r\n");
                    continue;
                }
                else break;
                }
            else break;
        }


        while(1)                 // -0.0000910257
        {
            sprintf(buff, "\r\nEnter 4 Var S-H  c3 (ex. 0.965370274) [%.11lf]: ", sys_data.quadTherm_c3);

            uprintf("%s", buff);
            if(getUserInput(buff, 20))
            {
                if(sscanf(buff, "%lf", &dtemp) == 1)
                {
                    if(dtemp >= (-2.0) && dtemp <= 2.0)
                    {
                        sys_data.quadTherm_c3 = dtemp;
                        uprintf("c3 = %.11lf", sys_data.quadTherm_c3);
                        break;
                    }
                    else uprintf("Enter number between -2.0 and 2.0 (ex. 0.965370274)\r\n\r\n");
                    continue;
                }
                else break;
                }
            else break;
        }
    } // if 4 var

    if(sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] == 1)
    {
        while(1)
        {
            sprintf(buff, "\r\nEnter 3 Var Steinhart-Hart A  [%.11lf]: ", sys_data.shTherm_A);
            uprintf("%s", buff);
            if(getUserInput(buff, 20))
            {
                if(sscanf(buff, "%lf", &dtemp) == 1)
                {
                    if(dtemp >= (-500.00) && dtemp <= 500.0)
                    {
                        sys_data.shTherm_A = dtemp;
                        uprintf("A = %.11lf", sys_data.shTherm_A);
                        break;
                    }
                    else uprintf("Enter number between -500 and 500, not sure what to recommend \r\n\r\n");
                    continue;
                }
                else break;
                }
            else break;
        }


        while(1)
        {
            sprintf(buff, "\r\nEnter 3 Var Steinhart-Hart B  [%.11lf]: ", sys_data.shTherm_B);
            uprintf("%s", buff);
            if(getUserInput(buff, 20))
            {
                if(sscanf(buff, "%lf", &dtemp) == 1)
                {
                    if(dtemp >= (-500.00) && dtemp <= 500.0)
                    {
                        sys_data.shTherm_B = dtemp;
                        uprintf("B = %.11lf", sys_data.shTherm_B);
                        break;
                    }
                    else uprintf("Enter number between -500 and 500, not sure what to recommend \r\n\r\n");
                    continue;
                }
                else break;
                }
            else break;
        }

        while(1)
        {
            sprintf(buff, "\r\nEnter 3 Var Steinhart-Hart C  [%.11lf]: ", sys_data.shTherm_C);
            uprintf("%s", buff);
            if(getUserInput(buff, 20))
            {
                if(sscanf(buff, "%lf", &dtemp) == 1)
                {
                    if(dtemp >= (-500.00) && dtemp <= 500.0)
                    {
                        sys_data.shTherm_C = dtemp;
                        uprintf("C = %.11lf", sys_data.shTherm_C);
                        break;
                    }
                    else uprintf("Enter number between -500 and 500, not sure what to recommend \r\n\r\n");
                    continue;
                }
                else break;
                }
            else break;
        }
    } // if 3 var
    //uprintf("\r\n*****Calibration Coefficients Saved*****\r\n\r\n");



    // thomthom
    // todo - ymodem finishes transfer rather than aborts
    import_ymodem_cal_coeff();

    ROM_SysCtlDelay(MILLISECOND * 200);
    UARTFlushRx();

    uprintf("cal_filename [%s]: ", sys_data.cal_filename);
    edit_string(&sys_data.cal_filename, MAX_CAL_FILENAME);
    uprintf("             [%s]\r\n", sys_data.cal_filename);

    uprintf("sensor_SN [%s]: ", sys_data.sensor_SN);
    edit_string(&sys_data.sensor_SN, MAX_SENSOR_SN);
    uprintf("          [%s]\r\n", sys_data.sensor_SN);

    uprintf("isfet_SN [%s]: ", sys_data.isfet_SN);
    edit_string(&sys_data.isfet_SN, MAX_ISFET_SN);
    uprintf("         [%s]\r\n", sys_data.isfet_SN);

    uprintf("ise_SN [%s]: ", sys_data.ise_SN);
    edit_string(&sys_data.ise_SN, MAX_ISE_SN);
    uprintf("       [%s]\r\n", sys_data.ise_SN);

    sys_data.PT_Cal_date[10] = 0;       // THOM BUG FIX

    uprintf("PT_Cal_date [%s]: ", sys_data.PT_Cal_date);
    edit_string(&sys_data.PT_Cal_date, MAX_K0_CAL_DATE);
    uprintf("            [%s]\r\n", sys_data.PT_Cal_date);




    for(indx=0; indx<NUMOF_FP_CAL_FIELDS; indx++)   // MAX_NUMOF_FP_CAL_FIELDS=12, NUMOF_K2_CAL_FIELDS=7    // defd in system.h
    {
        uprintf("Enter Fp C%u  [%e]: ", indx, sys_data.fP_Cal[indx]);
        ftemp = sys_data.fP_Cal[indx];
        edit_float(&sys_data.fP_Cal[indx], -500.0, 500.0);
        if(ftemp != sys_data.fP_Cal[indx])
            uprintf("             [%e]\r\n", indx, sys_data.fP_Cal[indx]);
    }

    for(indx=0; indx<NUMOF_K2_CAL_FIELDS; indx++)       // MAX_NUMOF_K2_CAL_FIELDS=6, NUMOF_K2_CAL_FIELDS=4
    {
        uprintf("Enter K2 C%u  [%e]: ", indx, sys_data.K2_Cal[indx]);
        ftemp = sys_data.K2_Cal[indx];
        edit_float(&sys_data.K2_Cal[indx], -500, 500);
        if(ftemp != sys_data.K2_Cal[indx])
            uprintf("             [%e]\r\n", indx, sys_data.K2_Cal[indx]);
    }


    uprintf("k0_Cal_date [%s]: ", sys_data.k0_Cal_date);
    edit_string(&sys_data.k0_Cal_date, MAX_K0_CAL_DATE);
    uprintf("            [%s]\r\n", sys_data.k0_Cal_date);

    uprintf("Enter k0_HCL  [%e]: ", sys_data.k0_HCL);
    ftemp = sys_data.k0_HCL;
    edit_float(&sys_data.k0_HCL, -500, 500);
    if(ftemp != sys_data.k0_HCL)
        uprintf("          [%e]\r\n", sys_data.k0_HCL);

    uprintf("Enter k0_SW  [%e]: ", sys_data.k0_SW);
    ftemp = sys_data.k0_SW;
    edit_float(&sys_data.k0_SW, -500, 500);
    if(ftemp != sys_data.k0_SW)
        uprintf("         [%e]\r\n", sys_data.k0_SW);

    uprintf("Enter k0std_SW  [%e]: ", sys_data.k0std_SW);
    ftemp = sys_data.k0std_SW;
    edit_float(&sys_data.k0std_SW, -500, 500);
    if(ftemp != sys_data.k0std_SW)
        uprintf("             [%e]\r\n", sys_data.k0std_SW);

    uprintf("service_date [%s]: ", sys_data.service_date);
    edit_string(&sys_data.service_date, MAX_SERVICE_DATE);
    uprintf("             [%s]\r\n", sys_data.service_date);

    storeSysDataVariables();        // New 5 Sep 2023

}

void change_baud_rate(void)
{
    char input;
    time_t timer;

    //print out config menu
    uprintf("\r\n\r\n\r\nChange Baud Rate - select baud menu item, change terminal baud rate, then hit 'V' to verify, then main menu, sleep and wakeup");
    //uprintf("\r\nV -- Verify");
    uprintf("\r\n1 -- 115200");
    uprintf("\r\n2 -- 57600");
    uprintf("\r\n3 -- 38400");
    uprintf("\r\n4 -- 19200");
    uprintf("\r\n5 -- 9600");
    uprintf("\r\n6 -- 4800");
    uprintf("\r\n9 -- Exit to Main Menu");
    uprintf("\r\nEnter Selection [9]: ");

    // Get user's selection with a 5 min timeout
    UARTFlushRx();
    timer = 300 + ROM_HibernateRTCGet();

    while(1)
    {
        if( UARTRxBytesAvail() )
        {
            input = get_key();
            break;
        }

        if( timer <= ROM_HibernateRTCGet() ) sleep(IDLE, 0);
    }

    switch(input)
    {
        case 'V':
        case 'v':
            uprintf("\r\nBaud rate verify %u\r\n", sys_data.baud_rate);
            break;
        case '1':
            // 115200
            sys_data.baud_rate = 115200L;
            uprintf("baud rate = %u\r\n", sys_data.baud_rate);
            wait_consoleTx();
            UARTStdioConfig(0, 115200, 16000000);       // 115200 bits per second
            break;
        case '2':
            sys_data.baud_rate = 57600L;
            uprintf("baud rate = %u\r\n", sys_data.baud_rate);
            wait_consoleTx();
            UARTStdioConfig(0, 57600, 16000000);       // 9600 bits per second
            break;
        case '3':
            sys_data.baud_rate = 38400L;
            uprintf("baud rate = %u\r\n", sys_data.baud_rate);
            wait_consoleTx();
            UARTStdioConfig(0, 38400, 16000000);       // 9600 bits per second
            break;
        case '4':
            sys_data.baud_rate = 19200L;
            uprintf("baud rate = %u\r\n", sys_data.baud_rate);
            wait_consoleTx();
            UARTStdioConfig(0, 19200, 16000000);       // 9600 bits per second
            break;
        case '5':
            sys_data.baud_rate = 9600L;
            uprintf("baud rate = %u\r\n", sys_data.baud_rate);
            wait_consoleTx();
            UARTStdioConfig(0, 9600, 16000000);       // 9600 bits per second
            break;
        case '6':
            sys_data.baud_rate = 4800L;
            uprintf("baud rate = %u\r\n", sys_data.baud_rate);
            wait_consoleTx();
            UARTStdioConfig(0, 4800, 16000000);       // 9600 bits per second
            break;
        default:
            // Write the sys_data struct into EEPROM.  Last argument ensures # of bytes is multiple of 4
            if(storeSysDataVariables())                 //if(EEPROMProgram((uint32_t*) &sys_data, 0x400, (sizeof(sys_data) + 3) & ~3))
            {
                uprintf("\r\n\r\nError storing system data.\r\n");
            }
            else
                uprintf("\r\n\r\nSystem data stored.  -- Press enter to bring up main menu\r\n");
            break;

    }

}

// pass in printFlg, writeFlg = 2 to pad the string with //
void print_write_config_data_fields(uint32_t printFlg, uint32_t writeFlg, uint32_t padFlg)
{
    FIL fileObject;     // File object
    FRESULT fresult;
    UINT bw;
    int retVal;
    char padString[10];




    retVal = 0;     // assume a good return (1 is error due to SD card

    if(sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 0)        // Fix 6 Aug 2021
    {
        retVal = 0;  // pretend it's good
        writeFlg = 0;
    }

    padString[0] = 0;
    if(padFlg == 1)
    {
        strcpy(padString, "// ");
    }

    if(writeFlg == 1)
    {

        // Open a file
        fresult = f_open(&fileObject, sys_data.fileName, FA_READ |FA_WRITE |FA_OPEN_ALWAYS);
        if(fresult != FR_OK)
        {
            uprintf("f_open error: %s\r\n", StringFromFresult(fresult));
            retVal = 1;
            writeFlg = 0;
            //return 1;
        }

        // Seek to the end, to append our file
        fresult = f_lseek(&fileObject, fileObject.fsize);
        if(fresult != FR_OK)
        {
            uprintf("f_lseek error: %s\r\n", StringFromFresult(fresult));
            retVal = 1;
            writeFlg = 0;
        }

    }

    if(printFlg==1)                 uprintf("%sA -- Sample Num               = %u\r\n", padString, sys_data.data_cfg[CFG_SAMPLE_NUM]);                 //A + Sample_Number\t
    if(writeFlg==1) sd_fprintf(&fileObject, "%sA -- Sample Num               = %u\r\n", padString, sys_data.data_cfg[CFG_SAMPLE_NUM]);                 //A + Sample_Number\t

    if( sys_data.data_cfg[CFG_TIMESTAMP] == 0 || sys_data.data_cfg[CFG_TIMESTAMP] == TYPE_US_DATETIME)
    {
        if(printFlg==1)                  uprintf("%sB -- MM/DD/YYYY HH:MM:SS      = %u\r\n", padString, sys_data.data_cfg[CFG_TIMESTAMP]);                   //B + MM/DD/YYYY HH:MM:SS\t
        if(writeFlg==1) sd_fprintf(&fileObject,  "%sB -- MM/DD/YYYY HH:MM:SS      = %u\r\n", padString, sys_data.data_cfg[CFG_TIMESTAMP]);                   //B + MM/DD/YYYY HH:MM:SS\t
    }
    if( sys_data.data_cfg[CFG_TIMESTAMP] == TYPE_EPOCH_MSEC)
    {
        if(printFlg==1)                  uprintf("%sB -- MM/DD/YYYY HH:MM:SS      = %u,  Epoch millisec\r\n\r\n", padString, sys_data.data_cfg[CFG_TIMESTAMP]);                   //B + MM/DD/YYYY HH:MM:SS\t
        if(writeFlg==1) sd_fprintf(&fileObject,  "%sB -- MM/DD/YYYY HH:MM:SS      = %u,  Epoch millisec\r\n\r\n", padString, sys_data.data_cfg[CFG_TIMESTAMP]);                   //B + MM/DD/YYYY HH:MM:SS\t
    }



    //if(printFlg==1)                  uprintf("\r\n");
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1 || BOARD_MSC == 2 // Not available on nanoFET
    if(printFlg==1)                 uprintf("%sC -- Battery Volt             = %u\r\n", padString, sys_data.data_cfg[CFG_VIN_BAT_VOLT]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sC -- Battery Volt             = %u\r\n", padString, sys_data.data_cfg[CFG_VIN_BAT_VOLT]);
#endif

    if(printFlg==1)                 uprintf("%sD -- Bias Battery Pos         = %u\r\n", padString, sys_data.data_cfg[CFG_BIAS_BAT_POS]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sD -- Bias Battery Pos         = %u\r\n", padString, sys_data.data_cfg[CFG_BIAS_BAT_POS]);
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2 || BOARD_NANOFET >= 1 // Not available on nanoFET, but we allow config - will measure as 0.0.  Glider usecase, MFET/NanoFET same data 6 Sept 2023
    if(printFlg==1)                 uprintf("%sE -- Bias Battery Neg         = %u\r\n", padString, sys_data.data_cfg[CFG_BIAS_BAT_NEG]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sE -- Bias Battery Neg         = %u\r\n", padString, sys_data.data_cfg[CFG_BIAS_BAT_NEG]);
#endif
    if(printFlg==1)                 uprintf("%sF -- Board Temperature        = %u\r\n", padString, sys_data.data_cfg[CFG_BRD_TEMP]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sF -- Board Temperature        = %u\r\n", padString, sys_data.data_cfg[CFG_BRD_TEMP]);

    if(printFlg==1)                 uprintf("%sG -- Board Humidity           = %u\r\n", padString, sys_data.data_cfg[CFG_BRD_HUMIDITY]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sG -- Board Humidity           = %u\r\n", padString, sys_data.data_cfg[CFG_BRD_HUMIDITY]);

    //if(printFlg==1) uprintf("\r\n");

    if(printFlg==1)                 uprintf("%sH -- Vthermistor              = %u\r\n", padString, sys_data.data_cfg[CFG_V_THERMISTOR]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sH -- Vthermistor              = %u\r\n", padString, sys_data.data_cfg[CFG_V_THERMISTOR]);

    if(printFlg==1)                 uprintf("%s     Vtermistor Std           = %u\r\n", padString, sys_data.data_cfg[CFG_V_THERMISTOR_STD]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%s     Vtermistor Std           = %u\r\n", padString, sys_data.data_cfg[CFG_V_THERMISTOR_STD]);

    if(printFlg==1)                 uprintf("%sI -- Temperature Calc         = %u\r\n", padString, sys_data.data_cfg[CFG_CALC_TEMP]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sI -- Temperature Calc         = %u\r\n", padString, sys_data.data_cfg[CFG_CALC_TEMP]);

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    if(printFlg==1)                 uprintf("%sJ -- Vrsi (Int Ref pH volt)   = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sJ -- Vrsi (Int Ref pH volt)   = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI]);

    if(printFlg==1)                 uprintf("%s     Vrsi Std                 = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI_STD]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%s     Vrsi Std                 = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI_STD]);

    if(printFlg==1)                 uprintf("%sK -- pH Vrsi Calc             = %u\r\n", padString, sys_data.data_cfg[CFG_CALC_PH_VRSI]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sK -- pH Vrsi Calc             = %u\r\n", padString, sys_data.data_cfg[CFG_CALC_PH_VRSI]);
#endif

    if(printFlg==1)                 uprintf("%sL -- Vrse (Ext Ref pH volt)   = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sL -- Vrse (Ext Ref pH volt)   = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE]);

    if(printFlg==1)                 uprintf("%s     Vrse Std                 = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE_STD]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%s     Vrse Std                 = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE_STD]);

    if(printFlg==1)                 uprintf("%sM -- pH Vrse Calc             = %u\r\n", padString, sys_data.data_cfg[CFG_CALC_PH_VRSE]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sM -- pH Vrse Calc             = %u\r\n", padString, sys_data.data_cfg[CFG_CALC_PH_VRSE]);
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    if(printFlg==1)                 uprintf("%sN -- Vrsi Biased (7pH=0v)     = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI_BIASED]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sN -- Vrsi Biased (7pH=0v)     = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI_BIASED]);

    if(printFlg==1)                 uprintf("%sO -- Vrsi Biased Std          = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI_BIASED_STD]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sO -- Vrsi Biased Std          = %u\r\n", padString, sys_data.data_cfg[CFG_VRSI_BIASED_STD]);

    if(printFlg==1)                 uprintf("%sP -- Vrse Biased (7pH=0v)     = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE_BIASED]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sP -- Vrse Biased (7pH=0v)     = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE_BIASED]);

    if(printFlg==1)                 uprintf("%sQ -- Vrse Biased Std          = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE_BIASED_STD]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sQ -- Vrse Biased Std          = %u\r\n", padString, sys_data.data_cfg[CFG_VRSE_BIASED_STD]);
#endif
    //if(printFlg==1) uprintf("\r\n");

    if(printFlg==1)                 uprintf("%sR -- Counter Electrode Vk     = %u\r\n", padString, sys_data.data_cfg[CFG_V_COUNTER_ELECT]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sR -- Counter Electrode Vk     = %u\r\n", padString, sys_data.data_cfg[CFG_V_COUNTER_ELECT]);

    if(printFlg==1)                 uprintf("%s     Counter Electrode Vk Std = %u\r\n", padString, sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%s     Counter Electrode Vk Std = %u\r\n", padString, sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD]);

    if(printFlg==1)                 uprintf("%sT -- Counter Electrode Cur Ik = %u\r\n", padString, sys_data.data_cfg[CFG_I_COUNTER]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sT -- Counter Electrode Cur Ik = %u\r\n", padString, sys_data.data_cfg[CFG_I_COUNTER]);

    if(printFlg==1)                 uprintf("%sU -- Substrate Current        = %u\r\n", padString, sys_data.data_cfg[CFG_I_SUBSTRATE]);
    if(writeFlg==1) sd_fprintf(&fileObject, "%sU -- Substrate Current        = %u\r\n", padString, sys_data.data_cfg[CFG_I_SUBSTRATE]);

    //if(printFlg==1) uprintf("\r\n");

#if BOARD_MPHOX >= 1 || BOARD_MFET >= 1  || BOARD_MSC == 2  // BUG 28 Dec 2021 (NANOFET instead of MFET on conditional)
    //if(printFlg==1)                 uprintf("%sV -- Optode                   = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    //if(writeFlg==1) sd_fprintf(&fileObject, "%sV -- Optode                   = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OPTODE_NOTDEFD)
    {
        if(printFlg==1)                 uprintf("%sV -- Optode port Uart3 driver = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sV -- Optode port Uart3 driver = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OPTODE)
    {
        if(printFlg==1)                 uprintf("%sV -- Optode 4831              = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sV -- Optode 4831              = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OCR504)
    {
        if(printFlg==1)                 uprintf("%sV -- OCR-504                  = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sV -- OCR-504                  = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_NANOFET)
    {
        if(printFlg==1)                 uprintf("%sV -- NanoFET pH               = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sV -- NanoFET pH               = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_PICOPH)
    {
        if(printFlg==1)                 uprintf("%sV -- Pico pH                  = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sV -- Pico pH                  = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    }

#endif
#if BOARD_MPHOX >= 1
    if( sys_data.data_cfg[CFG_UART4_INST] == INST_CTD_NOTDEFD)
    {
        if(printFlg==1)                 uprintf("%sW -- CTD port / Uart4 driver  = %u\r\n", padString, sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sW -- CTD port / Uart4 driver  = %u\r\n", padString, sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
    }
    if( sys_data.data_cfg[CFG_UART4_INST] == INST_SBE37_MICROCAT)
    {
        if(printFlg==1)                 uprintf("%sW -- CTD SBE37 MicroCat       = %u\r\n", padString, sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sW -- CTD SBE37 MicroCat       = %u\r\n", padString, sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
    }
    if( sys_data.data_cfg[CFG_UART4_INST] == INST_AANDERAA_5860)
    {
        if(printFlg==1)                 uprintf("%sW -- CTD Aanderaa 5860        = %u\r\n", padString, sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
        if(writeFlg==1) sd_fprintf(&fileObject, "%sW -- CTD Aanderaa 5860        = %u\r\n", padString, sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
    }
#endif

    // close the file
    if(writeFlg == 1)
    {
        sys_samp.next_gdata_fptr = fileObject.fptr;     // Store the file pointer for the first sample (for gdata)

        // Close the file
        fresult = f_close( &fileObject);
        if(fresult != FR_OK)
        {
            uprintf("f_close error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }
    }

}

// added for commandline / m2m
void print_config(void)
{
    uprintf("sampnum=%u\r\n", sys_data.data_cfg[CFG_SAMPLE_NUM]);

    if( sys_data.data_cfg[CFG_TIMESTAMP] == 0 || sys_data.data_cfg[CFG_TIMESTAMP] == TYPE_US_DATETIME)
    {
        //uprintf("timestamp=%u  MM/DD/YY HH:MM:SS\r\n", sys_data.data_cfg[CFG_TIMESTAMP]);
        uprintf("timestamp=%u\r\n", sys_data.data_cfg[CFG_TIMESTAMP]);
    }
    if( sys_data.data_cfg[CFG_TIMESTAMP] == TYPE_EPOCH_MSEC)
    {
        //uprintf("timestamp=%u,  Epoch millisec\r\n", sys_data.data_cfg[CFG_TIMESTAMP]);
        uprintf("timestamp=%u\r\n", sys_data.data_cfg[CFG_TIMESTAMP]);
    }



    // uprintf("\r\n");
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    uprintf("vbat=%u\r\n", sys_data.data_cfg[CFG_VIN_BAT_VOLT]);
#endif

    uprintf("biaspos=%u\r\n", sys_data.data_cfg[CFG_BIAS_BAT_POS]);
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2 || BOARD_NANOFET >= 1 // Not available on nanoFET, but we allow config - will measure as 0.0.  Glider usecase, MFET/NanoFET same data 6 Sept 2023
    uprintf("biasneg=%u\r\n", sys_data.data_cfg[CFG_BIAS_BAT_NEG]);
#endif
    uprintf("brdtemp=%u\r\n", sys_data.data_cfg[CFG_BRD_TEMP]);

    uprintf("brdhumid=%u\r\n", sys_data.data_cfg[CFG_BRD_HUMIDITY]);

    uprintf("vtherm=%u\r\n", sys_data.data_cfg[CFG_V_THERMISTOR]);

    uprintf("vtherm_std=%u\r\n", sys_data.data_cfg[CFG_V_THERMISTOR_STD]);

    uprintf("tempc=%u\r\n", sys_data.data_cfg[CFG_CALC_TEMP]);

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    uprintf("vrsi=%u\r\n", sys_data.data_cfg[CFG_VRSI]);

    uprintf("vrsi_std=%u\r\n", sys_data.data_cfg[CFG_VRSI_STD]);

    uprintf("ph_vrsi=%u\r\n", sys_data.data_cfg[CFG_CALC_PH_VRSI]);
#endif

    uprintf("vrse=%u\r\n", sys_data.data_cfg[CFG_VRSE]);

    uprintf("vrse_std=%u\r\n", sys_data.data_cfg[CFG_VRSE_STD]);

    uprintf("ph_vrse=%u\r\n", sys_data.data_cfg[CFG_CALC_PH_VRSE]);


    uprintf("vk=%u\r\n", sys_data.data_cfg[CFG_V_COUNTER_ELECT]);

    uprintf("vk_std=%u\r\n", sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD]);

    uprintf("ik=%u\r\n", sys_data.data_cfg[CFG_I_COUNTER]);

    uprintf("ib=%u\r\n", sys_data.data_cfg[CFG_I_SUBSTRATE]);

#ifdef OLDCODE
#if BOARD_MPHOX >= 1 || BOARD_MFET >= 1   // BUG 28 Dec 2021 (NANOFET instead of MFET on conditional)
    //uprintf("%sV -- Optode                   = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    //if(writeFlg==1) sd_fprintf(&fileObject, "%sV -- Optode                   = %u\r\n", padString, sys_data.data_cfg[CFG_UART3_INST]);
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OPTODE_NOTDEFD)
    {
        uprintf("%sV -- Optode port Uart3 driver = %u\r\n", sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OPTODE)
    {
        uprintf("%sV -- Optode 4831              = %u\r\n", sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OCR504)
    {
        uprintf("%sV -- OCR-504                  = %u\r\n", sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_NANOFET)
    {
        uprintf("%sV -- NanoFET pH               = %u\r\n", sys_data.data_cfg[CFG_UART3_INST]);
    }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_PICOPH)
    {
        uprintf("%sV -- Pico pH                  = %u\r\n", sys_data.data_cfg[CFG_UART3_INST]);
    }

#endif
#if BOARD_MPHOX >= 1
    if( sys_data.data_cfg[CFG_UART4_INST] == INST_CTD_NOTDEFD)
    {
        uprintf("%sW -- CTD port / Uart4 driver  = %u\r\n", sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
    }
    if( sys_data.data_cfg[CFG_UART4_INST] == INST_SBE37_MICROCAT)
    {
        uprintf("%sW -- CTD SBE37 MicroCat       = %u\r\n", sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
    }
    if( sys_data.data_cfg[CFG_UART4_INST] == INST_AANDERAA_5860)
    {
        uprintf("%sW -- CTD Aanderaa 5860        = %u\r\n", sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD);
    }
#endif
#endif
}

void print_config_data_fields(void)
{
    print_write_config_data_fields(1,0,1);    // 2 prints //, 1 has no // pad

}

void user_select_ctd(void)
{
    char input;

    uprintf("Select CTD port Uart4 Instrument driver[%u]:  1 -- SBE37 MicroCat, 2 -- Aanderaa 5860  ", (sys_data.data_cfg[CFG_UART4_INST] - INST_CTD_NOTDEFD));
    while(1)
    {
        if( UARTRxBytesAvail() )
        {
            input = get_key();
            if(input == '0')
            {
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;           //0;
                uprintf("\r\nCTD type not selected\r\n");
                break;
            }
            if(input == '1')
            {
                sys_data.data_cfg[CFG_UART4_INST] = INST_SBE37_MICROCAT;        //1;
                uprintf("\r\nCTD SBE37 MicroCat selected\r\n");
                break;
            }
            if(input == '2')
            {
                sys_data.data_cfg[CFG_UART4_INST] = INST_AANDERAA_5860;         //2;
                uprintf("\r\nCTD Aanderaa 5860 selected\r\n");

                break;
            }
            if(input == 24)     // Ctrl-x
            {
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;           //0;
                uprintf("\r\nCTD type not selected\r\n");
                break;
            }
            uprintf("Enter 1 or 2:  1 for SBE37 MicroCat, 2 for Aanderaa 5860, Ctrl-X <enter> to exit  ");
        }

    }
}


void user_select_optode(void)
{
    char input;

    uprintf("Select Optode port Uart3 Instrument driver[%u]:  1 -- Aanderaa Optode, 2 -- Seabird OCR-504, 3 -- NanoFET, 4 -- Pico pH   ", sys_data.data_cfg[CFG_UART3_INST]);
    while(1)
    {
        if( UARTRxBytesAvail() )
        {
            input = get_key();
            if(input == '0')
            {
                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;           //0;
                uprintf("\r\nUart3 driver not selected\r\n");
                break;
            }
            if(input == '1')
            {
                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE;
                uprintf("\r\nAanderaa Optode driver selected\r\n");
                break;
            }
            if(input == '2')
            {
                sys_data.data_cfg[CFG_UART3_INST] = INST_OCR504;
                uprintf("\r\nOCR504 selected\r\n");

                break;
            }
            if(input == '3')
            {
                sys_data.data_cfg[CFG_UART3_INST] = INST_NANOFET;
                uprintf("\r\nNanoFET selected\r\n");

                break;
            }
            if(input == '4')
            {
                sys_data.data_cfg[CFG_UART3_INST] = INST_PICOPH;
                uprintf("\r\nPico pH selected\r\n");

                break;
            }
            if(input == 24)     // Ctrl-x
            {
                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;           //0;
                uprintf("\r\nUart3 driver not selected\r\n");
                break;
            }
            uprintf("Select Optode port Uart3 Instrument driver[%u]:  1 -- Aanderaa Optode, 2 -- Seabird OCR-504, 3 -- NanoFET, 4 -- Pico pH   ", sys_data.data_cfg[CFG_UART3_INST]);
        }

    }
}



void user_select_timestamp(void)
{
    char input;

    uprintf("Select Timestamp type[%u]:  1 -- MM/DD/YYYY HH:MM:SS, 2 -- Epoch millisec ");
    while(1)
    {
        if( UARTRxBytesAvail() )
        {
            input = get_key();
            if(input == '1')
            {
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;        //1;
                break;
            }
            if(input == '2')
            {
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_EPOCH_MSEC;         //2;
                break;
            }
            if(input == 24)     // Ctrl-x
            {
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;           // Default
                break;
            }
            uprintf("Enter 1 or 2:  1 for MM/DD/YYYY HH:MM:SS, 2 for Epoch milli-seconds 13digit, Ctrl-X <enter> to exit  ");
        }

    }
}


void config_data_fields_all(int prnFlg)
{
    // all set
    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B

#if BOARD_NANOFET >= 1   // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

    sys_data.data_cfg[CFG_VRSI] = 0;                //
    sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
    //sys_data.data_cfg[CFG_OCR] = 0;
#endif

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // t
#endif
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // u
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // v
#endif
    sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // w
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // x

    sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // c
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    // d
    sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // e

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
    sys_data.data_cfg[CFG_VRSI] = 1;               // f
    sys_data.data_cfg[CFG_VRSI_STD] = 1;           // g
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;          // h
#endif
    sys_data.data_cfg[CFG_VRSE] = 1;               // i
    sys_data.data_cfg[CFG_VRSE_STD] = 1;           // j
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 1;          // k

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
    sys_data.data_cfg[CFG_VRSI_BIASED] = 1;        // l
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 1;    // m
    sys_data.data_cfg[CFG_VRSE_BIASED] = 1;        // n
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 1;    // o
#endif
    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // p
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // q
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // r
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // s

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE;              // V   // OCR is a special case for MFET only, connected on Optode port
    //sys_data.data_cfg[CFG_OCR] = 0;
#endif

    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;      //1;                 // W
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
    user_select_ctd();
#endif
    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;            // Enable MicroSD card
    if(prnFlg == 1) uprintf("MicroSD card enabled\r\n");
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEFAULT;
    if(prnFlg == 1) uprintf("Deploy mode sampling enabled, sleep between samples\r\n");
}

void config_data_fields_none(int prnFlg)
{
    // all clear
    sys_data.data_cfg[CFG_SAMPLE_NUM] = 0;          // a
    sys_data.data_cfg[CFG_TIMESTAMP] = 0;            // b

    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // t
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 0;        // u
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // v
    sys_data.data_cfg[CFG_BRD_TEMP] = 0;            // w
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 0;        // x

    sys_data.data_cfg[CFG_V_THERMISTOR] = 0;        // c
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 0;    // d
    sys_data.data_cfg[CFG_CALC_TEMP] = 0;           // e

    sys_data.data_cfg[CFG_VRSI] = 0;               // f
    sys_data.data_cfg[CFG_VRSI_STD] = 0;           // g
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // h

    sys_data.data_cfg[CFG_VRSE] = 0;               // i
    sys_data.data_cfg[CFG_VRSE_STD] = 0;           // j
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // k

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // l
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // m
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // n
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // o

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 0;     // p
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 0; // q
    sys_data.data_cfg[CFG_I_COUNTER] = 0;           // r
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 0;         // s

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // y
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // z
    //sys_data.data_cfg[CFG_OCR] = 0;
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
}

void config_data_fields_glider(int prnFlg)
{
#if BOARD_NANOFET >= 1   // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

    sys_data.data_cfg[CFG_VRSI] = 0;                //
    sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
    //sys_data.data_cfg[CFG_OCR] = 0;
#endif

    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // c  NEW, Vin is OFF for Glider use case
#endif
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D  // NEW
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2 // Not available on nanoFET, NEW 6 Sep 2023, allow for Glider config consistency between MFET/NanoFET
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // E
#endif
    sys_data.data_cfg[CFG_BRD_TEMP] = 0;            // f
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 0;        // g

    sys_data.data_cfg[CFG_V_THERMISTOR] = 0;        // h
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 0;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 0;           // i

    sys_data.data_cfg[CFG_VRSI] = 0;               // j
    sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // k

    sys_data.data_cfg[CFG_VRSE] = 1;               // L
    sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // M

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w

    // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
    if(prnFlg == 1) uprintf("Default ADS1248 sps and trial settings\r\n");
    ads1248_sampling_defaults();
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
    if(prnFlg == 1) uprintf("Deploy mode sampling enabled, sleep between samples\r\n");
}

void config_data_fields_mfet(int prnFlg)
{
#if BOARD_NANOFET >= 1   // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

    sys_data.data_cfg[CFG_VRSI] = 0;                //
    sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
#endif


    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1   || BOARD_MSC == 2 // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // C
#endif
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // E
#endif
    sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // F
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

    sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_VRSI] = 1;               // J
    sys_data.data_cfg[CFG_VRSI_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;          // K
#endif
    sys_data.data_cfg[CFG_VRSE] = 0;               // l
    sys_data.data_cfg[CFG_VRSE_STD] = 0;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
    //A,B,C,D,E,F,G,L,M,P,Q,R,S,T,U,V,W,X
    //sys_data.data_cfg[CFG_OCR] = 0;

    // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
    if(prnFlg == 1) uprintf("Default ADS1248 sps and trial settings\r\n");
    ads1248_sampling_defaults();
    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;            // Enable MicroSD card
    if(prnFlg == 1) uprintf("MicroSD card enabled\r\n");
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
    if(prnFlg == 1) uprintf("Deploy mode sampling enabled, sleep between samples\r\n");
}

void config_data_fields_mphox(int prnFlg)
{
#if BOARD_NANOFET >= 1   // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

    sys_data.data_cfg[CFG_VRSI] = 0;                //
    sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
    //sys_data.data_cfg[CFG_OCR] = 0;
#endif
    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // C
#endif
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // E
#endif
    sys_data.data_cfg[CFG_BRD_TEMP] = 1;            // F
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

    sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_VRSI] = 0;               // J
    sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // K
#endif
    sys_data.data_cfg[CFG_VRSE] = 1;               // L
    sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 1;          // M

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    //sys_data.data_cfg[CFG_OCR] = 0;
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE;              // V
    //sys_data.data_cfg[CFG_OCR] = 0;
#endif
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_UART4_INST] = INST_SBE37_MICROCAT;                 // W   MicroCAT is default
    user_select_ctd();
#endif
    sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] =  1;      // echo deployment command characters
    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;            // MicroSD enabled for logging
    if(prnFlg == 1) uprintf("MicroSD data logging is enabled\r\n");
    if(prnFlg == 1) uprintf("Console echo of deployment commands is enabled\r\n");

    // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
    if(prnFlg == 1) uprintf("Default ADS1248 sps and trial settings\r\n");
    ads1248_sampling_defaults();
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
    if(prnFlg == 1) uprintf("Deploy mode sampling mode enabled, sleep between samples\r\n");
}

void config_data_fields_m2m_mphox(int prnFlg)
{
#if BOARD_NANOFET >= 1   // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

    sys_data.data_cfg[CFG_VRSI] = 0;                //
    sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
    //sys_data.data_cfg[CFG_OCR] = 0;
#endif

    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = 0;            // b
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // C
#endif
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // E
#endif
    sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // F
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

    sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2   // Not available on nanoFET
    sys_data.data_cfg[CFG_VRSI] = 1;               // J
    sys_data.data_cfg[CFG_VRSI_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;          // K
#endif
    sys_data.data_cfg[CFG_VRSE] = 0;               // l
    sys_data.data_cfg[CFG_VRSE_STD] = 0;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
    sys_data.data_cfg[CFG_VRSI_BIASED] = 1;        // N     // New 18 Aug 2021 - 28 Dec 2021 (No longer required to calc pH, leaving the field on to keep compat with nsFOCE labview parsing
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q
#endif
    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
    //sys_data.data_cfg[CFG_OCR] = 0;

    sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] =  0;          // Disable Echo
    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;            // Disable MicroSD card
    if(prnFlg == 1) uprintf("MicroSD data logging is Disabled\r\n");
    if(prnFlg == 1) uprintf("Console echo of deployment commands is disabled\r\n");

    // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
    if(prnFlg == 1) uprintf("Default ADS1248 sps and trial settings\r\n");
    ads1248_sampling_defaults();
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
    if(prnFlg == 1) uprintf("Deploy mode sampling mode enabled, sleep between samples\r\n");
}

void config_data_fields_nanofet(int prnFlg)
{
    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B

    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // c
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // e
    sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // F
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

    sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I

    sys_data.data_cfg[CFG_VRSI] = 0;               // j
    sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // k

    sys_data.data_cfg[CFG_VRSE] = 1;               // L
    sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
    //sys_data.data_cfg[CFG_OCR] = 0;

    // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
    if(prnFlg == 1) uprintf("Default ADS1248 sps and trial settings\r\n");
    ads1248_sampling_defaults();

    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;            // Disable Datalogging, not present on nanoFET
    if(prnFlg == 1) uprintf("Data logging is Disabled\r\n");
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
    if(prnFlg == 1) uprintf("Deploy mode sampling mode enabled, sleep between samples\r\n");
}

void config_data_fields_wirewalker(int prnFlg)
{
#if BOARD_NANOFET >= 1   // Not available on nanoFET
    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

    sys_data.data_cfg[CFG_VRSI] = 0;                //
    sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
    //sys_data.data_cfg[CFG_OCR] = 0;
#endif

    sys_data.data_cfg[CFG_SAMPLE_NUM] = 0;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_EPOCH_MSEC;            // B

    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // c
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 0;        // D
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // e
    sys_data.data_cfg[CFG_BRD_TEMP] = 0;           // F
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

    sys_data.data_cfg[CFG_V_THERMISTOR] = 0;        // H
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 0;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 0;           // I

    sys_data.data_cfg[CFG_VRSI] = 0;               // j
    sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // k

    sys_data.data_cfg[CFG_VRSE] = 1;               // L
    sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m

    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
    //sys_data.data_cfg[CFG_OCR] = 0;

    // Yui's request for RBR (100hz -> 160hz)
    //Vrse (20Hz, 5 samples)
    //Vrse_std
    //Vk (100 Hz, 1 sample)
    //Ik (100Hz, 1 sample)
    //Ib (100Hz,1 sample)

    if(prnFlg == 1) uprintf("Changes from default ADS1248 sps and trials:\r\n");
    sys_data.Vrse_sps = 20;
    if(prnFlg == 1) uprintf("   Vrse_sps = %u\r\n", sys_data.Vrse_sps);
    sys_data.Vrse_trials = 5;
    if(prnFlg == 1) uprintf("   Vrse_trials = %u\r\n", sys_data.Vrse_trials);

    sys_data.Vk_sps = 320;
    if(prnFlg == 1) uprintf("   Vk_sps = %u\r\n", sys_data.Vk_sps);
    sys_data.Vk_trials = 3;
    if(prnFlg == 1) uprintf("   Vk_trials = %u\r\n", sys_data.Vk_trials);
    sys_data.Ik_sps = 160;
    if(prnFlg == 1) uprintf("   Ik_sps = %u\r\n", sys_data.Ik_sps);
    sys_data.Ik_trials = 1;
    if(prnFlg == 1) uprintf("   Ik_trials = %u\r\n", sys_data.Ik_trials);

    sys_data.Ib_sps = 160;
    if(prnFlg == 1) uprintf("   Ib_sps = %u\r\n", sys_data.Ib_sps);
    sys_data.Ib_trials = 1;
    if(prnFlg == 1) uprintf("   Ib_trials = %u\r\n", sys_data.Ib_trials);

    if(prnFlg == 1) uprintf("\r\n");
    sys_data.sampling_period = 2;
    if(prnFlg == 1) uprintf("Sampling period = %u\r\n", sys_data.sampling_period);


    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;            // Disable MicroSD card
    if(prnFlg == 1) uprintf("MicroSD data logging is Disabled\r\n");
    sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_EPOCH_MSEC;   //Timestamp in Posix msec (Epoch msec)
    if(prnFlg == 1) uprintf("Timestamp in Epoch millisec format\r\n");
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_FASTSAMP;
    if(prnFlg == 1) uprintf("Continuous sampling mode (databarf) enabled\r\n");
}

/********************************************************************************************
 *  Config Data Fields
 ********************************************************************************************/
void config_data_fields(void)
{
    char input;
    time_t timer;
    //unsigned char cfg;
    //unsigned char index;

    while(1)
    {
        //print out config menu
        uprintf("\r\n\r\n\r\nChange Data Field - lower case turns data field off (=0), upper case turns field on (=1)\r\n\r\n\r\n");

        //print_config_data_fields();
        print_write_config_data_fields(1,0,0);  // print, not write, no pad
        wait_consoleTx();

        uprintf("\r\n0 -- Zero (Clear) all config fields");
        uprintf("\r\n1 -- Set all config fields");
        ROM_SysCtlDelay(MILLISECOND * 200);   // 128 byte fifo, use case 5 causes max q so give some time for xmit
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2   // Not available on nanoFET
        uprintf("\r\n2 -- Use Case: GLIDER,          (A,B,C,D,L,M,R,T,U)"); // (A,B,C,D,E,L,M,R,T,U)"); //(A,B,G,M,N,O,P,Q)");  //(A,B,C,O,P,Q,R,S,T)");  //ABIJPQRS  removed E (bias neg) 13 Apr 2022
        uprintf("\r\n3 -- Use Case: mFET Default,    (A,B,C,D,E,F,G,H,I,J,K,R,T,U)"); //  FIELDS ACTIVE for MiniFET: A= Samp #, B= Time, C= Batt Volt, D= Board Temp, E= Humidity, G= Vtherm, H= Vtherm_STD, I= Vint_off, J= Vint_off_STD, M= Vint, N= Vint_STD, Q= Vk (counter electrode Voltage), R= Vk_STD, S= Counter electrode current, T= Substrate current, Z= Fast mode ON
        uprintf("\r\n4 -- Use Case: MpHOx Default,   (A,B,C,D,F,G,H,I,L,M,R,T,U,V,W)");  //(A,B,C,D,E,F,G,H,I,J,K,L,M,R,T,U,V,W)");   //A,C,D,E,F,G,H,I,J,Q,R,S,T,U,V  removed E,J,K 13 Apr 2022
        uprintf("\r\n5 -- Use Case: MpHOx m2m,       (A,C,D,E,F,G,H,I,J,K,N,R,T,U)");   //A,C,D,E,F,G,H,I,J,Q,R,S,T,U,V   // Added 'N' for pHcalc
        uprintf("\r\n6 -- Use Case: nanoFET Default, (A,B,D,F,G,H,I,L,R,S,T,U)");
        uprintf("\r\n7 -- Use Case: MFET WireWalker, (B,G,L,R,T,U)");
#endif
#if BOARD_NANOFET >= 1
        uprintf("\r\n     Use cases are tailored for nanoFET capability");
        uprintf("\r\n2 -- Use Case: GLIDER,          (A,B,D,L,M,R,T,U)"); //(A,B,G,M,N,O,P,Q)");  //(A,B,C,O,P,Q,R,S,T)");  //ABIJPQRS
        uprintf("\r\n3 -- Use Case: mFET Default,    (A,B,D,F,G,H,I,R,T,U)"); //  FIELDS ACTIVE for MiniFET: A= Samp #, B= Time, C= Batt Volt, D= Board Temp, E= Humidity, G= Vtherm, H= Vtherm_STD, I= Vint_off, J= Vint_off_STD, M= Vint, N= Vint_STD, Q= Vk (counter electrode Voltage), R= Vk_STD, S= Counter electrode current, T= Substrate current, Z= Fast mode ON
        uprintf("\r\n4 -- Use Case: MpHOx Default,   (A,B,D,F,G,H,I,L,M,R,T,U)");   //A,C,D,E,F,G,H,I,J,Q,R,S,T,U,V
        uprintf("\r\n5 -- Use Case: MpHOx m2m,       (A,D,F,G,H,I,R,T,U)");   //A,C,D,E,F,G,H,I,J,Q,R,S,T,U,V   // Added 'N' for p
        uprintf("\r\n6 -- Use Case: nanoFET Default, (A,B,D,F,G,H,I,L,R,S,T,U)");  //(A,B,C,D,E,F,G,H,I,L,R,T,U)");    //(A,B,C,D,E,F,G,H,O,P,Q,R,S,T)");
#endif
        uprintf("\r\n");
        //if(sys_data.diag == 1) uprintf("\r\n8 -- get_sample() Flex Sampling = %u\t\t\t", sys_data.app_cfg[APPCFG_SAMP_FLEX]);

        //uprintf("\r\n");
        uprintf("\r\n9 -- Exit to Main Menu");
        uprintf("\r\nEnter Selection [9]: ");

        // Get user's selection with a 5 min timeout
        UARTFlushRx();
        timer = 300 + ROM_HibernateRTCGet();

        while(1)
        {
            if( UARTRxBytesAvail() )
            {
                input = get_key();
                break;
            }

            if( timer <= ROM_HibernateRTCGet() ) sleep(IDLE, 0);
        }



        switch(input)
        {
            case 'A':
                sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;   //
                break;
            case 'a':
                sys_data.data_cfg[CFG_SAMPLE_NUM] = 0;
                break;
            case 'B':
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;
                // Ask the user which TIMESTAMP?
                user_select_timestamp();
                break;
            case 'b':
                sys_data.data_cfg[CFG_TIMESTAMP] = 0;
                break;

            case 'C':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
#endif

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2 || BOARD_NANOFET >= 1  // Not available on nanoFET  6 Sep 2023 - allow NanoFET config of negbias
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;   //        2   //+ Battery_Volt
#endif
                break;
            case 'c':
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
                break;
            case 'D':
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;   //        5   //+ bias bat pos volt
                break;
            case 'd':
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 0;
                break;
            case 'E':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;   //        5   //new
#endif
                break;
            case 'e':
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;
                break;

            case 'F':
                sys_data.data_cfg[CFG_BRD_TEMP] = 1;   //        3   //+ Board_Temperature\t
                break;
            case 'f':
                sys_data.data_cfg[CFG_BRD_TEMP] = 0;
                break;
            case 'G':
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;   //        4   // + Humidity_sensor
                break;
            case 'g':
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 0;
                break;


            case 'H':
                sys_data.data_cfg[CFG_V_THERMISTOR] = 1;   //        6       //+ Vthermistor\t
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;            // New 13 May 2021
                break;
            case 'h':
                sys_data.data_cfg[CFG_V_THERMISTOR] = 0;
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 0;
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;
                break;
            case 'I':
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;   //           20   //+ calculated_temperature_Vthermistor\t
                break;
            case 'i':
                sys_data.data_cfg[CFG_CALC_TEMP] = 0;
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // cant calc vrsi pH without temp   19 Jul 2021
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // cant calc vrsi pH without temp   19 Jul 2021
                break;

            case 'J':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_VRSI] = 0;
                sys_data.data_cfg[CFG_VRSI_STD] = 0;
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VRSI] = 1;   //               12   //+ Vint\t
                sys_data.data_cfg[CFG_VRSI_STD] = 1;
#endif
                break;
            case 'j':
                sys_data.data_cfg[CFG_VRSI] = 0;
                sys_data.data_cfg[CFG_VRSI_STD] = 0;
                break;
            case 'K':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;   //          21   //+ estimated_pH_int\r\r\n
                sys_data.data_cfg[CFG_V_THERMISTOR] = 1; // new 29 Apr 2021
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1; // new 17 Jul 2021
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;   // new 29 Apr 2021
                //sys_data.data_cfg[CFG_VRSI_BIASED] = 1; // new 29 Apr 2021
                sys_data.data_cfg[CFG_VRSI] = 1; // new 29 Dec 2021 Removed dependency on VRSI_BIASED
#endif
                break;
            case 'k':
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;
                break;

            case 'L':
                sys_data.data_cfg[CFG_VRSE] = 1;   //               14   //+ Vext
                sys_data.data_cfg[CFG_VRSE_STD] = 1;
                break;
            case 'l':
                sys_data.data_cfg[CFG_VRSE] = 0;
                sys_data.data_cfg[CFG_VRSE_STD] = 0;
                break;
            case 'M':
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 1;   //          22   //+ estimated_pH_ext\r\r\n (new 6May2019 TM)
                sys_data.data_cfg[CFG_V_THERMISTOR] = 1; // new 29 Apr 2021
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1; // new 17 Jul 2021
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;   // new 29 Apr 2021
                sys_data.data_cfg[CFG_VRSE] = 1; // new 17 Jan 2022  // Get rid of Biased
#if GETTINGRIDOFBIASED
                sys_data.data_cfg[CFG_VRSE_BIASED] = 1; // new 29 Apr 2021
#endif
                break;
            case 'm':
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;
                break;

            case 'N':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;   //        8   //+ Vint_offset\t  No VRSI or VRSI_B on nanofet
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VRSI_BIASED] = 1;   //        8   //+ Vint_offset\t
#endif
                break;
            case 'n':
                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;
                break;
            case 'O':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;       //8   //+ Vint_offset\t  No VRSI or VRSI_B on nanofet
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 1;   //    9   //+ Vint_offset_std\t
                sys_data.data_cfg[CFG_VRSI_BIASED] = 1;
#endif
                break;
            case 'o':
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;
                break;
            case 'P':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;   //        10   //+ Vext_offset\t
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VRSE_BIASED] = 1;   //        10   //+ Vext_offset\t
#endif
                break;
            case 'p':
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;
                break;
            case 'Q':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;   //    11   //+ Vext_offset_std\t
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 1;   //    11   //+ Vext_offset_std\t
                sys_data.data_cfg[CFG_VRSE_BIASED] = 1;
#endif
                break;
            case 'q':
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;
                break;

            case 'R':
                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;   //     16   //+ Vcounter_electrode
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1;
                break;
            case 'r':
                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 0;
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 0;
                break;
                //S is up for grabs! 22 Jul 2021 (bug fix)
            case 'S':
                //sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1;   //   //+ Vcounter_electrode_std
                //sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;
                break;
            case 's':
                //sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 0;
                break;

            case 'T':
                sys_data.data_cfg[CFG_I_COUNTER] = 1;   //           18   // + Counter_current
                break;
            case 't':
                sys_data.data_cfg[CFG_I_COUNTER] = 0;
                break;
            case 'U':
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;   //         19   //+ Substrate_current
                break;
            case 'u':
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 0;
                break;

            case 'V':
#if BOARD_NANOFET >= 1
                sys_data.data_cfg[CFG_UART3_INST] = 0;
#endif
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                user_select_optode();
                //sys_data.data_cfg[CFG_UART3_INST] = 1;
                //sys_data.data_cfg[CFG_OCR] = 0;             // either OCR or OPTODE, can't be both (same port)
#endif
                break;
            case 'v':
                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
                break;

            case 'W':
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
                // Ask the user which CTD?
                user_select_ctd();
#endif
                break;
            case 'w':
//#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;      //0;
//#endif
                break;

            case 'X':
#if BOARD_MPHOX >= 1 || BOARD_MFET >= 2  || BOARD_MSC == 2
                //sys_data.data_cfg[CFG_OCR] = 1;
                //sys_data.data_cfg[CFG_UART3_INST] = 0;
#endif
                break;
            case 'x':
#if BOARD_MPHOX >= 1 || BOARD_MFET >= 2  || BOARD_MSC == 2
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif
                break;
            case 'Y':
                break;
            case 'y':
                break;
            case 'Z':
                break;
            case 'z':
                break;

            case '0':
                config_data_fields_none(1);
#ifdef NOCODE
                // all clear
                sys_data.data_cfg[CFG_SAMPLE_NUM] = 0;          // a
                sys_data.data_cfg[CFG_TIMESTAMP] = 0;            // b

                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // t
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 0;        // u
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // v
                sys_data.data_cfg[CFG_BRD_TEMP] = 0;            // w
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 0;        // x

                sys_data.data_cfg[CFG_V_THERMISTOR] = 0;        // c
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 0;    // d
                sys_data.data_cfg[CFG_CALC_TEMP] = 0;           // e

                sys_data.data_cfg[CFG_VRSI] = 0;               // f
                sys_data.data_cfg[CFG_VRSI_STD] = 0;           // g
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // h

                sys_data.data_cfg[CFG_VRSE] = 0;               // i
                sys_data.data_cfg[CFG_VRSE_STD] = 0;           // j
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // k

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // l
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // m
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // n
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // o

                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 0;     // p
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 0; // q
                sys_data.data_cfg[CFG_I_COUNTER] = 0;           // r
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 0;         // s

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // y
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // z
                //sys_data.data_cfg[CFG_OCR] = 0;
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
#endif      //NOCODE
                break;

            case '1':
                // all set
                config_data_fields_all(1);
#ifdef NOCODE
                sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B

#if BOARD_NANOFET >= 1   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

                sys_data.data_cfg[CFG_VRSI] = 0;                //
                sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // t
#endif
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // u
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // v
#endif
                sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // w
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // x

                sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // c
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    // d
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // e

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VRSI] = 1;               // f
                sys_data.data_cfg[CFG_VRSI_STD] = 1;           // g
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;          // h
#endif
                sys_data.data_cfg[CFG_VRSE] = 1;               // i
                sys_data.data_cfg[CFG_VRSE_STD] = 1;           // j
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 1;          // k

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_VRSI_BIASED] = 1;        // l
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 1;    // m
                sys_data.data_cfg[CFG_VRSE_BIASED] = 1;        // n
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 1;    // o
#endif
                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // p
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // q
                sys_data.data_cfg[CFG_I_COUNTER] = 1;           // r
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // s

#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE;              // V   // OCR is a special case for MFET only, connected on Optode port
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif

                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;      //1;                 // W
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
                user_select_ctd();
#endif
                sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;            // Enable MicroSD card
                uprintf("MicroSD card enabled\r\n");
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEFAULT;
                uprintf("Deploy mode sampling enabled, sleep between samples\r\n");
#endif  //NOCODE
                break;

            case '2':
                // -- Glider Data Config Set
                // A Sample Num
                // B MM/DD/YYYY HH:MM:SS
                // C Battery Volt
                // O Vext Ref
                // P Vext Ref Std
                // Q Vcounter Electrode
                // R Vcounter Electrode Std
                // S Counter Electrode Current
                // T Substrate Current
                // Z FAST

                //sys_data.fast_mode = 1;                         // Z
                //ABCDELMRSTU
                config_data_fields_glider(1);
#ifdef NOCODE
#if BOARD_NANOFET >= 1   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

                sys_data.data_cfg[CFG_VRSI] = 0;                //
                sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif

                sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1   || BOARD_MSC == 2 // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // c  NEW, Vin is OFF for Glider use case
#endif
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D  // NEW
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2 || BOARD_NANOFET >= 1 // Not available on nanoFET, NEW 6 Sep 2023, allow for Glider config consistency between MFET/NanoFET
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // E
#endif
                sys_data.data_cfg[CFG_BRD_TEMP] = 0;            // f
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 0;        // g

                sys_data.data_cfg[CFG_V_THERMISTOR] = 0;        // h
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 0;    //
                sys_data.data_cfg[CFG_CALC_TEMP] = 0;           // i

                sys_data.data_cfg[CFG_VRSI] = 0;               // j
                sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // k

                sys_data.data_cfg[CFG_VRSE] = 1;               // L
                sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // M

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
                sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w

                // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
                uprintf("Default ADS1248 sps and trial settings\r\n");
                ads1248_sampling_defaults();
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
                uprintf("Deploy mode sampling enabled, sleep between samples\r\n");
#endif  //NOCODE
                //TODO - add m2m setting?  Also, nanoFET should have uSD off
                break;

            case '3':           // Updated to add Calc Temp 23 Mar 2021   MFET Default
                    //Default for MFET fields
                // A,B,C,D,E,F,G,H,I,J,R,S,T,U
                config_data_fields_mfet(1);
#ifdef NOCODE
#if BOARD_NANOFET >= 1   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

                sys_data.data_cfg[CFG_VRSI] = 0;                //
                sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
#endif


                sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // C
#endif
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2   // Not available on nanoFET
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // E
#endif
                sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // F
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

                sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2   // Not available on nanoFET
                sys_data.data_cfg[CFG_VRSI] = 1;               // J
                sys_data.data_cfg[CFG_VRSI_STD] = 1;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;          // K
#endif
                sys_data.data_cfg[CFG_VRSE] = 0;               // l
                sys_data.data_cfg[CFG_VRSE_STD] = 0;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
                sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
                //A,B,C,D,E,F,G,L,M,P,Q,R,S,T,U,V,W,X
                //sys_data.data_cfg[CFG_OCR] = 0;

                // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
                uprintf("Default ADS1248 sps and trial settings\r\n");
                ads1248_sampling_defaults();
                sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;            // Enable MicroSD card
                uprintf("MicroSD card enabled\r\n");
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
                uprintf("Deploy mode sampling enabled, sleep between samples\r\n");
#endif  //NOCODE
                break;


            case '4':
                //sys_data.fast_mode = 2;
                //Use Case: MPHOX/ nsFOCE, fields for use with another master controller (time not needed).  Defaults for Durafet, not deepsee durafet
                //A,C,D,E,F,G,H,I,J,K,R,S,T,U
                config_data_fields_mphox(1);
#ifdef NOCODE
#if BOARD_NANOFET >= 1   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

                sys_data.data_cfg[CFG_VRSI] = 0;                //
                sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif
                sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // C
#endif
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1   || BOARD_MSC == 2 // Not available on nanoFET
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // E
#endif
                sys_data.data_cfg[CFG_BRD_TEMP] = 1;            // F
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

                sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
                sys_data.data_cfg[CFG_VRSI] = 0;               // J
                sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // K
#endif
                sys_data.data_cfg[CFG_VRSE] = 1;               // L
                sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 1;          // M

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
                sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

                //sys_data.data_cfg[CFG_OCR] = 0;
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE;              // V
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
                sys_data.data_cfg[CFG_UART4_INST] = INST_SBE37_MICROCAT;                 // W   MicroCAT is default
                user_select_ctd();
#endif
                sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] =  1;      // echo deployment command characters
                sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;            // MicroSD enabled for logging
                uprintf("MicroSD data logging is enabled\r\n");
                uprintf("Console echo of deployment commands is enabled\r\n");

                // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
                uprintf("Default ADS1248 sps and trial settings\r\n");
                ads1248_sampling_defaults();
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
                uprintf("Deploy mode sampling mode enabled, sleep between samples\r\n");
#endif  //NOCODE

                break;

            case '5':
                //sys_data.fast_mode = 2;
                //Use Case: MPHOX m2m/ nsFOCE, fields for use with another master controller (time not needed).  Defaults for Durafet, not deepsee durafet
                //A,C,D,E,F,G,H,I,J,K,N,R,S,T,U
                config_data_fields_m2m_mphox(1);
#ifdef NOCODE
#if BOARD_NANOFET >= 1   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

                sys_data.data_cfg[CFG_VRSI] = 0;                //
                sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif

                sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
                sys_data.data_cfg[CFG_TIMESTAMP] = 0;            // b
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // C
#endif
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1   || BOARD_MSC == 2  // Not available on nanoFET
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // E
#endif
                sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // F
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

                sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2   // Not available on nanoFET
                sys_data.data_cfg[CFG_VRSI] = 1;               // J
                sys_data.data_cfg[CFG_VRSI_STD] = 1;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;          // K
#endif
                sys_data.data_cfg[CFG_VRSE] = 0;               // l
                sys_data.data_cfg[CFG_VRSE_STD] = 0;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m
#if BOARD_MFET >= 2 || BOARD_MPHOX >= 1  || BOARD_MSC == 2  // Not available on nanoFET
                sys_data.data_cfg[CFG_VRSI_BIASED] = 1;        // N     // New 18 Aug 2021 - 28 Dec 2021 (No longer required to calc pH, leaving the field on to keep compat with nsFOCE labview parsing
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q
#endif
                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
                sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
                //sys_data.data_cfg[CFG_OCR] = 0;

                sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] =  0;          // Disable Echo
                sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;            // Disable MicroSD card
                uprintf("MicroSD data logging is Disabled\r\n");
                uprintf("Console echo of deployment commands is disabled\r\n");

                // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
                uprintf("Default ADS1248 sps and trial settings\r\n");
                ads1248_sampling_defaults();
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
                uprintf("Deploy mode sampling mode enabled, sleep between samples\r\n");
#endif  //NOCODE
                break;


            case '6':
                //Use Case: nanoFET default, fields
                // A,B,D,F,G,H,I,L,R,S,T,U
                config_data_fields_nanofet(1);
#ifdef NOCODE
                sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_US_DATETIME;            // B

                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // c
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // e
                sys_data.data_cfg[CFG_BRD_TEMP] = 1;        // F
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

                sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
                sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I

                sys_data.data_cfg[CFG_VRSI] = 0;               // j
                sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // k

                sys_data.data_cfg[CFG_VRSE] = 1;               // L
                sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
                sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
                //sys_data.data_cfg[CFG_OCR] = 0;

                // restore sample rates 9 Apr 2022, prevent user error when switching between 'use case' configs that modify ADS1248 sampling parms
                uprintf("Default ADS1248 sps and trial settings\r\n");
                ads1248_sampling_defaults();

                sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;            // Disable Datalogging, not present on nanoFET
                uprintf("Data logging is Disabled\r\n");
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEPLOY;
                uprintf("Deploy mode sampling mode enabled, sleep between samples\r\n");
#endif  //NOCODE
                break;


            case '7':
                uprintf("\r\nMFET config and fast sample for wire walker\r\n");
                // MFET fast sample, wire walker
                //time stamp (posix msec)
                // Humidity
                //Vrse (20Hz, 5 samples)
                //Vrse_std
                //Vk (160 Hz, 2 samples)
                //Vk_std
                //Ik (160Hz, 1 sample)
                //Ib (160Hz,1 sample)

                // A,B,D,F,G,H,I,L,R,S,T,U
#ifdef NOCODE
#if BOARD_NANOFET >= 1   // Not available on nanoFET
                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        //

                sys_data.data_cfg[CFG_VRSI] = 0;                //
                sys_data.data_cfg[CFG_VRSI_STD] = 0;            //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;        //

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;     //
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;         //
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;     //

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;
                //sys_data.data_cfg[CFG_OCR] = 0;
#endif

                sys_data.data_cfg[CFG_SAMPLE_NUM] = 0;          // A
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_EPOCH_MSEC;            // B

                sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // c
                sys_data.data_cfg[CFG_BIAS_BAT_POS] = 0;        // D
                sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // e
                sys_data.data_cfg[CFG_BRD_TEMP] = 0;           // F
                sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

                sys_data.data_cfg[CFG_V_THERMISTOR] = 0;        // H
                sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 0;    //
                sys_data.data_cfg[CFG_CALC_TEMP] = 0;           // I

                sys_data.data_cfg[CFG_VRSI] = 0;               // j
                sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // k

                sys_data.data_cfg[CFG_VRSE] = 1;               // L
                sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
                sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m

                sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
                sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
                sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
                sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

                sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
                sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; // S
                sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
                sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

                sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
                sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w
                //sys_data.data_cfg[CFG_OCR] = 0;

                // Yui's request for RBR (100hz -> 160hz)
                //Vrse (20Hz, 5 samples)
                //Vrse_std
                //Vk (100 Hz, 1 sample)
                //Ik (100Hz, 1 sample)
                //Ib (100Hz,1 sample)

                uprintf("Changes from default ADS1248 sps and trials:\r\n");
                sys_data.Vrse_sps = 20;
                uprintf("   Vrse_sps = %u\r\n", sys_data.Vrse_sps);
                sys_data.Vrse_trials = 5;
                uprintf("   Vrse_trials = %u\r\n", sys_data.Vrse_trials);

                sys_data.Vk_sps = 320;
                uprintf("   Vk_sps = %u\r\n", sys_data.Vk_sps);
                sys_data.Vk_trials = 3;
                uprintf("   Vk_trials = %u\r\n", sys_data.Vk_trials);
                sys_data.Ik_sps = 160;
                uprintf("   Ik_sps = %u\r\n", sys_data.Ik_sps);
                sys_data.Ik_trials = 1;
                uprintf("   Ik_trials = %u\r\n", sys_data.Ik_trials);

                sys_data.Ib_sps = 160;
                uprintf("   Ib_sps = %u\r\n", sys_data.Ib_sps);
                sys_data.Ib_trials = 1;
                uprintf("   Ib_trials = %u\r\n", sys_data.Ib_trials);

                uprintf("\r\n");
                sys_data.sampling_period = 2;
                uprintf("Sampling period = %u\r\n", sys_data.sampling_period);


                sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;            // Disable MicroSD card
                uprintf("MicroSD data logging is Disabled\r\n");
                sys_data.data_cfg[CFG_TIMESTAMP] = TYPE_EPOCH_MSEC;   //Timestamp in Posix msec (Epoch msec)
                uprintf("Timestamp in Epoch millisec format\r\n");
                sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_FASTSAMP;
                uprintf("Continuous sampling mode (databarf) enabled\r\n");
#endif
                break;

            case '8':
                break;


            case '9':
            default:
                sys_data.fast_mode = 1;  // removed from config 21 Apr 2021
                // Write the sys_data struct into EEPROM.  Last argument ensures # of bytes is multiple of 4
                if(storeSysDataVariables())                         //if(EEPROMProgram((uint32_t*) &sys_data, 0x400, (sizeof(sys_data) + 3) & ~3))
                {
                    uprintf("\r\n\r\nError storing system data.\r\n");
                }
                else
                    uprintf("\r\n\r\nSystem data stored. (910) -- Press enter to bring up main menu\r\n");
                return;

        }  // end of switch statement

    }
}







void print_all_metadata(void)
{
    time_t  current_time;

    current_time = ROM_HibernateRTCGet();

    print_write_metadata_header(current_time, 1, 0);

}

void enter_metadata(void)
{
    char buff[128];

    uprintf("\r\nEnter data file name (no spaces, 8.3 format) [%s]: ", sys_data.fileName);  // 8 + 1 + 3 + 1 = 13  (null terminate)
    if( getUserInput(buff, 13) ) // was MAX_FILENAME-1) )  // storage size is 80, user input size was 100 - fixed a BUG!
    {
        strcpy(sys_data.fileName, buff);
        uprintf("\r\nFile name now: %s\r\n", sys_data.fileName);
    }

    uprintf("\r\nEnter user initials [%s]: ", sys_data.user);
    if( getUserInput(buff, MAX_USER_INITIALS-1) )       // was 10 user initials
    {
        strcpy(sys_data.user, buff);
        uprintf("\r\nUser initials now: %s\r\n", sys_data.user);
    }

    //char board_SN[MAX_BOARD_SN];   MAX_BOARD_SN 30
#if BOARD_MFET >= 1
    uprintf("\r\nEnter MFET Serial # [%s]: ", sys_data.board_SN);
#endif
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
    uprintf("\r\nEnter MPHOX Serial # [%s]: ", sys_data.board_SN);
#endif
#if BOARD_NANOFET >= 1
    uprintf("\r\nEnter nanoFET Serial # [%s]: ", sys_data.board_SN);
#endif
    if( getUserInput(buff, MAX_BOARD_SN-1) )       // board serial number
    {
        strcpy(sys_data.board_SN, buff);
        uprintf("\r\nBoard Serial #: %s\r\n", sys_data.board_SN);
    }


    // char mcap_SN[MAX_MCAP_SN];  MAX_MCAP_SN  30
#if BOARD_MFET >= 1 || BOARD_MPHOX >= 1  || BOARD_MSC == 2
    uprintf("\r\nEnter MCAP Serial # [%s]: ", sys_data.mcap_SN);
    if( getUserInput(buff, MAX_MCAP_SN-1) )       // board serial number
    {
        strcpy(sys_data.mcap_SN, buff);
        uprintf("\r\nMCAP Serial #: %s\r\n", sys_data.mcap_SN);
    }
#endif


    // char board_fab_note[MAX_board_fab_note];   MAX_board_fab_note 80
    uprintf("\r\nEnter Package Fabrication notes [%s]: ", sys_data.package_fab_note);   // was board now package fab
    if( getUserInput(buff, MAX_PACKAGE_FABNOTE-1) )       // board fabricaton notes
    {
        strcpy(sys_data.package_fab_note, buff);
        uprintf("\r\nBoard Fab notes: %s\r\n", sys_data.package_fab_note);
    }

    uprintf("\r\nEnter Package name [%s]: ", sys_data.package_name);
    if( getUserInput(buff, MAX_PACKAGE_NAME-1) )
    {
        strcpy(sys_data.package_name, buff);
        uprintf("\r\nPackage name: %s\r\n", sys_data.package_name);
    }

    //char sensor_SN[MAX_SENSOR_SN];  8
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2 | BOARD_MFET >= 2
    uprintf("\r\nEnter Sensor/Durafet Serial # [%s]: ", sys_data.sensor_SN);
#endif
#if BOARD_NANOFET >= 1
    uprintf("\r\nEnter Sensor Serial # [%s]: ", sys_data.sensor_SN);
#endif
    if( getUserInput(buff, MAX_SENSOR_SN) )       // was MAX_SENSOR_SN-1)
    {
        strcpy(sys_data.sensor_SN, buff);
        sys_data.sensor_SN[MAX_SENSOR_SN-1] = 0;
        uprintf("\r\nSensor Serial #: %s\r\n", sys_data.sensor_SN);
    }

    // new 20 Sep 2023
    uprintf("\r\nEnter ISFET Serial # [%s]: ", sys_data.isfet_SN);
    if( getUserInput(buff, MAX_ISFET_SN) )       //
    {
        strcpy(sys_data.isfet_SN, buff);
        sys_data.isfet_SN[MAX_ISFET_SN-1] = 0;
        uprintf("\r\nISFET Serial #: %s\r\n", sys_data.isfet_SN);
    }

    // new 20 Sep 2023
    uprintf("\r\nEnter ISE Serial # [%s]: ", sys_data.ise_SN);
    if( getUserInput(buff, MAX_ISE_SN) )       //
    {
        strcpy(sys_data.ise_SN, buff);
        sys_data.ise_SN[MAX_ISE_SN-1] = 0;
        uprintf("\r\nISE Serial #: %s\r\n", sys_data.ise_SN);
    }

    //char optode_SN[MAX_OPTODE_SN];
    uprintf("\r\nEnter Optode Serial # [%s]: ", sys_data.optode_SN);
    if( getUserInput(buff, MAX_OPTODE_SN-1) )       //
    {
        strcpy(sys_data.optode_SN, buff);
        uprintf("\r\nOptode Serial #: %s\r\n", sys_data.optode_SN);
    }

#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
    uprintf("\r\nEnter Conductivity Serial # [%s]: ", sys_data.ctd_SN);
    if( getUserInput(buff, MAX_CTD_SN-1) )       //
    {
        strcpy(sys_data.ctd_SN, buff);
        uprintf("\r\nConductivity Serial #: %s\r\n", sys_data.ctd_SN);
    }

    //char pump_SN[MAX_PUMP_SN];
    uprintf("\r\nEnter Pump1 Serial #  [%s]: ", sys_data.pump_SN);
    if( getUserInput(buff, MAX_PUMP_SN-1) )       //
    {
        strcpy(sys_data.pump_SN, buff);
        uprintf("\r\nPump Serial #: %s\r\n", sys_data.pump_SN);
    }
    //char pump_SN[MAX_PUMP_SN];
    uprintf("\r\nEnter Pump2 Serial #  [%s]: ", sys_data.pump2_SN);
    if( getUserInput(buff, MAX_PUMP_SN-1) )       //
    {
        strcpy(sys_data.pump2_SN, buff);
        uprintf("\r\nPump Serial #: %s\r\n", sys_data.pump2_SN);
    }
#endif


}



// write deployment header to SD card, NOTE: the format should match print_deployment_header except for tabs in the print to format for human readable vs machine readable ascii
int write_metadata_header(const time_t currentTime)   // was deployment header
{
    return(print_write_metadata_header(currentTime, 0, 1));
    //return 0;
}




int print_write_data_header(uint32_t printFlg, uint32_t writeFlg)
{
    struct tm *time_struct;
    char buff[TIMESTAMPLENGTH];
    FIL fileObject;     // File object
    FRESULT fresult;
    UINT bw;
    int retVal;
    uint32_t indx;

    retVal = 0;     // assume a good return (1 is error due to SD card

    indx = 0;

    uprintf("\r\n\r\n");

    if(sys_data.data_cfg[CFG_SAMPLE_NUM] > 0)       { indx += sprintf(&prnBuf[indx], " SampNum\t");     }
    if(sys_data.data_cfg[CFG_TIMESTAMP] == TYPE_US_DATETIME)
    {
        if(sys_data.data_cfg[CFG_TIMESTAMP] > 0)         { indx += sprintf(&prnBuf[indx], "     MM/DD/YYYY HH:MM:SS\t");   }
    }
    if(sys_data.data_cfg[CFG_TIMESTAMP] == TYPE_EPOCH_MSEC)
    {
        if(sys_data.data_cfg[CFG_TIMESTAMP] > 0)         { indx += sprintf(&prnBuf[indx], "Epoch millisec\t");   }   //if(sys_data.data_cfg[CFG_TIMESTAMP] > 0)         { indx += sprintf(&prnBuf[indx], "     Epoch milliseconds \t");   }
    }


//--- board sensors

    if(sys_data.data_cfg[CFG_VIN_BAT_VOLT] > 0)     { indx += sprintf(&prnBuf[indx], "VbatMain\t");     }
    if(sys_data.data_cfg[CFG_BIAS_BAT_POS] > 0)     { indx += sprintf(&prnBuf[indx], "VbiasPos\t");     }
    if(sys_data.data_cfg[CFG_BIAS_BAT_NEG] > 0)     { indx += sprintf(&prnBuf[indx], "VbiasNeg\t");     }
    if(sys_data.data_cfg[CFG_BRD_TEMP] > 0)         { indx += sprintf(&prnBuf[indx], " TC_cont\t");     }
    if(sys_data.data_cfg[CFG_BRD_HUMIDITY] > 0)     { indx += sprintf(&prnBuf[indx], "Humidity\t");     }

//--- pH voltages
    if(sys_data.data_cfg[CFG_V_THERMISTOR] > 0)     { indx += sprintf(&prnBuf[indx], "  Vtherm\t");     }
    if(sys_data.data_cfg[CFG_V_THERMISTOR_STD] > 0) { indx += sprintf(&prnBuf[indx], "VthrmStd\t");     }
    if(sys_data.data_cfg[CFG_CALC_TEMP] > 0)        { indx += sprintf(&prnBuf[indx], " TC_Dfet\t");     }
//---

    if(sys_data.data_cfg[CFG_VRSI] > 0)             { indx += sprintf(&prnBuf[indx], "    Vrsi\t");     }
    if(sys_data.data_cfg[CFG_VRSI_STD] > 0)         { indx += sprintf(&prnBuf[indx], "Vrsi_std\t");     }
    if(sys_data.data_cfg[CFG_CALC_PH_VRSI] > 0)     { indx += sprintf(&prnBuf[indx], "pHintEst\t");     }
    if(sys_data.data_cfg[CFG_VRSE] > 0)             { indx += sprintf(&prnBuf[indx], "    Vrse\t");     }
    if(sys_data.data_cfg[CFG_VRSE_STD] > 0)         { indx += sprintf(&prnBuf[indx], "Vrse_std\t");     }
    if(sys_data.data_cfg[CFG_CALC_PH_VRSE] > 0)     { indx += sprintf(&prnBuf[indx], "pHextEst\t");     }

//---

    if(sys_data.data_cfg[CFG_VRSI_BIASED] > 0)      { indx += sprintf(&prnBuf[indx], "  Vrsi_B\t");     }
    if(sys_data.data_cfg[CFG_VRSI_BIASED_STD] > 0)  { indx += sprintf(&prnBuf[indx], "VrsiBstd\t");     }
    if(sys_data.data_cfg[CFG_VRSE_BIASED] > 0)      { indx += sprintf(&prnBuf[indx], "  Vrse_B\t");     }
    if(sys_data.data_cfg[CFG_VRSE_BIASED_STD] > 0)  { indx += sprintf(&prnBuf[indx], "VrseBstd\t");     }


//--- ISFET diagnostics
    if(sys_data.data_cfg[CFG_V_COUNTER_ELECT] > 0)  { indx += sprintf(&prnBuf[indx], "      Vk\t");     }
    if(sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] > 0) { indx += sprintf(&prnBuf[indx], "  Vk_std\t");  }
    if(sys_data.data_cfg[CFG_I_COUNTER] > 0)        { indx += sprintf(&prnBuf[indx], "      Ik\t");     }
    if(sys_data.data_cfg[CFG_I_SUBSTRATE] > 0)      { indx += sprintf(&prnBuf[indx], "      Ib\t");     }



//---- External Instruments

    //if(sys_data.data_cfg[CFG_UART3_INST] > 0)           { indx += sprintf(&prnBuf[indx], "Opt_PN\tOpt_SN\tMoxy\tO2satper\tTC_opt\tDphase\tBphase\tRphase\tBamp\tBpot\tRamp\tOpt_rawtemp\t");   }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OPTODE)   { indx += sprintf(&prnBuf[indx], "Opt_PN\tOpt_SN\tMoxy\tO2satper\tTC_opt\tDphase\tBphase\tRphase\tBamp\tBpot\tRamp\tOpt_rawtemp\t");   }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_OCR504)   { indx += sprintf(&prnBuf[indx], "OCR_PN  \tChan_1 \tChan_2 \tChan_3 \tChan_4 \t");   }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_NANOFET)  { indx += sprintf(&prnBuf[indx], " SampNum\tMM/DD/YYYY HH:MM:SS\tVbiasPos\t TC_cont\tHumidity\t  Vtherm\tVthrmStd\t TC_Dfet\t    Vrse\tVrse_std\t      Vk\t  Vk_std\t      Ik \t      Ib\t");   }
    if(sys_data.data_cfg[CFG_UART3_INST] == INST_PICOPH)   { indx += sprintf(&prnBuf[indx], "MEA  \tChan \tSensors \tErrors \tdphi \t0 \t0 \t0 \tTC_samp \tTC_case \tsigInt \tambLight \tPres \tHum \tTO_res \t0 \t0 \tpH \t0 \t0 \t0 \t ");   }



    //if(sys_data.data_cfg[CFG_UART4_INST] != INST_CTD_NOTDEFD)  // if(sys_data.data_cfg[CFG_UART4_INST] > 0)
    //{                                             //01234567
    if((sys_data.data_cfg[CFG_UART4_INST]) == INST_SBE37_MICROCAT)      { indx += sprintf(&prnBuf[indx], "TC_MCat\tCond\tPres\tpSal\tDate_MC\tTime_MC\t");   } // bug fix 19May2022 swapped pSal/Press"TC_MCat\tCond\tpSal\tPres\tDate_MC\tTime_MC\t");   }//if(ctd.type == 1)        // microCAT SBE37
    if((sys_data.data_cfg[CFG_UART4_INST]) == INST_AANDERAA_5860)       { indx += sprintf(&prnBuf[indx], "Cond_PN\tCond_SN\tCond\tTemp\tSal\tDensity \tSSpeed\t");   }   //if(ctd.type == 2)        // aanderaa 5860
    //}
    //if(sys_data.data_cfg[CFG_OCR] > 0)              { indx += sprintf(&prnBuf[indx], "OCR_PN  \tChan_1 \tChan_2 \tChan_3 \tChan_4 \t");   }

    if(sys_data.pump_seq_type == 2)                 { indx += sprintf(&prnBuf[indx], "   Pump\t");   }

    // fix trailing tab 28 Dec 2021
    indx--;
    prnBuf[indx] = '\r';        // line termination is CR-LF (0x0d, 0x0a)  25 Mar 2022   Old UARTwrite would insert \r (bad practice)
    indx++;
    prnBuf[indx] = '\n';
    indx++;
    prnBuf[indx] = 0;

    if(printFlg == 1) UARTwrite(prnBuf, strlen(prnBuf));

    // BUG FIX 28 Dec 2021 (does not write data header due to missing f_close)
    if( (sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 1) && (writeFlg == 1) )
    {
        // Open a file
        fresult = f_open(&fileObject, sys_data.fileName, FA_READ |FA_WRITE |FA_OPEN_ALWAYS);
        if(fresult != FR_OK)
        {
            uprintf("f_open error: %s\r\n", StringFromFresult(fresult));
            retVal = 1;
            writeFlg = 0;
            //return 1;
        }

        // Seek to the end, to append our file
        fresult = f_lseek(&fileObject, fileObject.fsize);
        if(fresult != FR_OK)
        {
            uprintf("f_lseek error: %s\r\n", StringFromFresult(fresult));
            retVal = 1;
            writeFlg = 0;
            //return 1;
        }

        // Write the formatted data string in the prnBuf buffer to the SD card
         fresult = f_write( &fileObject, prnBuf, strlen(prnBuf), (UINT*)&bw);
         if(fresult != FR_OK)
         {
             uprintf("f_write error: %s\r\n", StringFromFresult(fresult));
         }

        sys_samp.next_gdata_fptr = fileObject.fptr;     // Store the file pointer for the first sample (for gdata)

        // Close the file
        fresult = f_close( &fileObject);
        if(fresult != FR_OK)
        {
            uprintf("f_close error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }
    }

    if(printFlg == 1)    wait_consoleTx();

    return(retVal);

}

void print_data_header(void)
{
    print_write_data_header(1,0);

}


int write_data_header(void)
{
    return(print_write_data_header(0,1));
}


/*
 * stub for older get_header (used in COMMAND mode gh
 */
void get_header(void)
{
    print_write_data_header(1,0);
}

/*
 * enter_deployment_note with timeout
 */
int enter_deployment_note(uint32_t timeout)
{
    int byteCnt = 0;
    char noteBuf[84];

    noteBuf[0] = ' ';
    noteBuf[1] = 0x00;
    byteCnt = 1;

    sys_data.deploy_note[0] = ' ';
    sys_data.deploy_note[1] = 0;
    uprintf("\r\nEnter Deployment Note [ ]: ");
    if( getUserInputTimeLimit(noteBuf, (MAX_DEPLOY_NOTE-4), timeout) )
    {
        byteCnt = strcpy(sys_data.deploy_note, noteBuf);
        uprintf("\r\n%s\r\n", sys_data.deploy_note);
    }

    return(byteCnt);
}








/*
 * print_write_metadata_header() was written to improve maintainability and consistency of formatted output
 *
 * replaces print_metadata_header and write_metadata_header
 *
 * returns: 0 for success,  1 if error writing file
 */

int print_write_metadata_header(const time_t currentTime, uint32_t printFlg, uint32_t writeFlg)
{

    struct tm *time_struct;
    char buff[TIMESTAMPLENGTH];
    FIL fileObject;     // File object
    FRESULT fresult;
    UINT bw;
    int retVal;

    retVal = 0;     // assume a good return (1 is error due to SD card

    if(sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 0)        // fix 6 Aug 2021, force writeFlg to zero
    {
        retVal = 0;  // pretend it's good
        writeFlg = 0;
    }

    if(writeFlg == 1)
    {

        // Open a file
        fresult = f_open(&fileObject, sys_data.fileName, FA_READ |FA_WRITE |FA_OPEN_ALWAYS);
        if(fresult != FR_OK)
        {
            uprintf("f_open error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }

        // Seek to the end, to append our file
        fresult = f_lseek(&fileObject, fileObject.fsize);
        if(fresult != FR_OK)
        {
            uprintf("f_lseek error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }

    }

    if(writeFlg == 1)   sd_fprintf(&fileObject, "\r\n\r\n");
    if(printFlg == 1)                   uprintf("\r\n\r\n");
    if(writeFlg == 1)   sd_fprintf(&fileObject, "//++************** Deployment Settings ***************\r\n");
    if(printFlg == 1)                   uprintf("//++************** Deployment Settings ***************\r\n");

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Firmware version: \t%s\r\n", sys_data.firmware_version); // 10Oct2022 sys_data.qa.firmware_version);
    if(printFlg == 1)                 uprintf("// Firmware version: \t%s\r\n", sys_data.firmware_version);


    if(writeFlg == 1) sd_fprintf(&fileObject, "// Sampling period (s)\t%u\r\n", sys_data.sampling_period);
    if(printFlg == 1)                 uprintf("// Sampling period (s)\t%u\r\n", sys_data.sampling_period);

    if(sys_data.sample_aligned)
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Samples hour align:\tYes\r\n");
        if(printFlg == 1)                 uprintf("// Samples hour align:\tYes\r\n");
    }
    else
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Samples hour align:\tNo\r\n");
        if(printFlg == 1)                 uprintf("// Samples hour align:\tNo\r\n");
    }

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Vrsi sps,trials: \t%u, %u\r\n", sys_data.Vrsi_sps, sys_data.Vrsi_trials);
    if(printFlg == 1)                 uprintf("// Vrsi sps,trials: \t%u, %u\r\n", sys_data.Vrsi_sps, sys_data.Vrsi_trials);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Vrse sps,trials: \t%u, %u\r\n", sys_data.Vrse_sps, sys_data.Vrse_trials);
    if(printFlg == 1)                 uprintf("// Vrse sps,trials: \t%u, %u\r\n", sys_data.Vrse_sps, sys_data.Vrse_trials);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Vtherm sps,trials\t%u, %u\r\n", sys_data.Vtherm_sps, sys_data.Vtherm_trials);
    if(printFlg == 1)                 uprintf("// Vtherm sps,trials\t%u, %u\r\n", sys_data.Vtherm_sps, sys_data.Vtherm_trials);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Ik sps, trials:   \t%u, %u\r\n", sys_data.Ik_sps, sys_data.Ik_trials);
    if(printFlg == 1)                 uprintf("// Ik sps, trials:   \t%u, %u\r\n", sys_data.Ik_sps, sys_data.Ik_trials);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Vk sps, trials:   \t%u, %u\r\n", sys_data.Vk_sps, sys_data.Vk_trials);
    if(printFlg == 1)                 uprintf("// Vk sps, trials:   \t%u, %u\r\n", sys_data.Vk_sps, sys_data.Vk_trials);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Ib sps, trials:   \t%u, %u\r\n", sys_data.Ib_sps, sys_data.Ib_trials);
    if(printFlg == 1)                 uprintf("// Ib sps, trials:   \t%u, %u\r\n", sys_data.Ib_sps, sys_data.Ib_trials);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Vb sps, trials:   \t%u, %u\r\n", sys_data.Vb_sps, sys_data.Vb_trials);
    if(printFlg == 1)                 uprintf("// Vb sps, trials:   \t%u, %u\r\n", sys_data.Vb_sps, sys_data.Vb_trials);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Vbias sps,trials: \t%u, %u\r\n", sys_data.Vbias_sps, sys_data.Vbias_trials);
    if(printFlg == 1)                 uprintf("// Vbias sps,trials: \t%u, %u\r\n", sys_data.Vbias_sps, sys_data.Vbias_trials);




    if(sys_data.pump1_ontime > 0)
    {
        if(sys_data.start_pump_time > 0)            // new 24 Feb 2022
        {
            time_struct = localtime(&sys_data.start_pump_time);
            strftime(buff, sizeof(buff),"// Pump delay until:\t%Y/%m/%d %H:%M:%S\r\n", time_struct);
        }
        else
        {
            sprintf(buff, "// Pump start delay: \t0\r\n");
        }


        if(writeFlg == 1)
        {
            fresult = f_write(&fileObject, buff, strlen(buff), &bw);
            if(fresult != FR_OK)
            {
                uprintf("Current time f_write error: %s\r\n", StringFromFresult(fresult));
                //return 1;
                retVal = 1;
                writeFlg = 0;
            }
        }
        if(printFlg == 1)  uprintf("%s", buff);
    }

    if(sys_data.pump1_ontime == 0)
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(printFlg == 1)                 uprintf("// Pump on time (s):\t%u\r\n", sys_data.pump1_ontime);
    }

    if((sys_data.pump1_ontime > 0) && (sys_data.pump_seq_type == TYPE_PUMP_SINGLE))
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump seq type:   \tPUMP_SINGLE\r\n");
        if(printFlg == 1)                 uprintf("// Pump seq type:   \tPUMP_SINGLE\r\n");

        if(sys_data.test_mode)
        {
            if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump on time (s):\t%u  (TEST MODE, pump disabled)\r\n", sys_data.pump1_ontime);
            if(printFlg == 1)                 uprintf("// Pump on time (s):\t%u  (TEST MODE, pump disabled)\r\n", sys_data.pump1_ontime);
        }
        else
        {
            if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump on time (s):\t%u\r\n", sys_data.pump1_ontime);
            if(printFlg == 1)                 uprintf("// Pump on time (s):\t%u\r\n", sys_data.pump1_ontime);
        }
    }

    if((sys_data.pump1_ontime > 0) && (sys_data.pump_seq_type == TYPE_2PUMP_BEAMSV1))
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump seq type:   \t2PUMP_BEAMSV1\r\n");
        if(printFlg == 1)                 uprintf("// Pump seq type:   \t2PUMP_BEAMSV1\r\n");

        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump1 on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(printFlg == 1)                 uprintf("// Pump1 on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump2 on time (s):\t%u\r\n", sys_data.pump2_ontime);
        if(printFlg == 1)                 uprintf("// Pump2 on time (s):\t%u\r\n", sys_data.pump2_ontime);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump1 cycles:     \t%u\r\n", sys_data.pump1_cycles);
        if(printFlg == 1)                 uprintf("// Pump1 cycles:     \t%u\r\n", sys_data.pump1_cycles);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump2 cycles:     \t%u\r\n", sys_data.pump2_cycles);
        if(printFlg == 1)                 uprintf("// Pump2 cycles:     \t%u\r\n", sys_data.pump2_cycles);
    }

    if((sys_data.pump1_ontime > 0) && (sys_data.pump_seq_type > TYPE_2PUMP_BEAMSV1))
    {
        //if(writeFlg == 1) sd_fprintf(&fileObject, "// Hey there, add pump sequencer metadata for new seq_type=%u\t%u\r\n", sys_data.pump_seq_type);
        //if(printFlg == 1)                 uprintf("// Hey there, add pump sequencer metadata for new seq_type=%u\t%u\r\n", sys_data.pump_seq_type);


        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump seq type:   \t2PUMP_BEAMSV2\r\n");
        if(printFlg == 1)                 uprintf("// Pump seq type:   \t2PUMP_BEAMSV2\r\n");

        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump1 on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(printFlg == 1)                 uprintf("// Pump1 on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump2 on time (s):\t%u\r\n", sys_data.pump2_ontime);
        if(printFlg == 1)                 uprintf("// Pump2 on time (s):\t%u\r\n", sys_data.pump2_ontime);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump1 cycles:     \t%u\r\n", sys_data.pump1_cycles);
        if(printFlg == 1)                 uprintf("// Pump1 cycles:     \t%u\r\n", sys_data.pump1_cycles);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump2 cycles:     \t%u\r\n", sys_data.pump2_cycles);
        if(printFlg == 1)                 uprintf("// Pump2 cycles:     \t%u\r\n", sys_data.pump2_cycles);

    }

    if((sys_data.pump1_ontime > 0) && (sys_data.pump_seq_type > TYPE_PUMP_SELFCAL))
    {
        //if(writeFlg == 1) sd_fprintf(&fileObject, "// Hey there, add pump sequencer metadata for new seq_type=%u\t%u\r\n", sys_data.pump_seq_type);
        //if(printFlg == 1)                 uprintf("// Hey there, add pump sequencer metadata for new seq_type=%u\t%u\r\n", sys_data.pump_seq_type);


        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump seq type:   \t2PUMP_SELFCAL\r\n");
        if(printFlg == 1)                 uprintf("// Pump seq type:   \t2PUMP_SELFCAL\r\n");

        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump1 on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(printFlg == 1)                 uprintf("// Pump1 on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump2 on time (s):\t%u\r\n", sys_data.pump2_ontime);
        if(printFlg == 1)                 uprintf("// Pump2 on time (s):\t%u\r\n", sys_data.pump2_ontime);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump1 cycles:     \t%u\r\n", sys_data.pump1_cycles);
        if(printFlg == 1)                 uprintf("// Pump1 cycles:     \t%u\r\n", sys_data.pump1_cycles);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump2 cycles:     \t%u\r\n", sys_data.pump2_cycles);
        if(printFlg == 1)                 uprintf("// Pump2 cycles:     \t%u\r\n", sys_data.pump2_cycles);

    }
    if(sys_data.sampleCnt_duty_on > 0)
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Exp Duty Cycle On \t%u\r\n", sys_data.sampleCnt_duty_on);
        if(printFlg == 1)                 uprintf("// Exp Duty Cycle On \t%u\r\n", sys_data.sampleCnt_duty_on);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Exp Duty Cycle Off\t%u\r\n", sys_data.sampleCnt_duty_off);
        if(printFlg == 1)                 uprintf("// Exp Duty Cycle Off\t%u\r\n", sys_data.sampleCnt_duty_on);

    }


#ifdef NOCODE
    if(sys_data.test_mode)
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump on time (s):\t%u  (TEST MODE, pump disabled)\r\n", sys_data.pump1_ontime);
        if(printFlg == 1)                 uprintf("// Pump on time (s):\t%u  (TEST MODE, pump disabled)\r\n", sys_data.pump1_ontime);
    }
    else
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump on time (s):\t%u\r\n", sys_data.pump1_ontime);
        if(printFlg == 1)                 uprintf("// Pump on time (s):\t%u\r\n", sys_data.pump1_ontime);
    }
#endif


    if(writeFlg == 1) sd_fprintf(&fileObject, "// Low battery voltage:\t%.1f\r\n", sys_data.low_batt_volt);
    if(printFlg == 1)                 uprintf("// Low battery voltage:\t%.1f\r\n", sys_data.low_batt_volt);

    if(sys_data.output == 1)
    {                                              // Low battery voltage:\t%.1f\r\n"
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Output mode:        \tNormal\r\n");
        if(printFlg == 1)                 uprintf("// Output mode:        \tNormal\r\n");

    }
    if(sys_data.output == 2)
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// Output mode:        \tVerbose\r\n");
        if(printFlg == 1)                 uprintf("// Output mode:        \tVerbose\r\n");
    }

    time_struct = localtime(&sys_data.deploy_time);
    strftime(buff, sizeof(buff),"// Deploy time:   \t%Y/%m/%d %H:%M:%S\r\n", time_struct);
    if(writeFlg == 1)
    {
        fresult = f_write(&fileObject, buff, strlen(buff), &bw);
        if(fresult != FR_OK)
        {
            uprintf("Current time f_write error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }
    }
    if(printFlg == 1)  uprintf("%s", buff);

    // Store timezone
    if(sys_data.GMT)
    {
        if(writeFlg == 1)   sd_fprintf(&fileObject, "// Time zone:       \tGMT\r\n");
        if(printFlg == 1)                   uprintf("// Time zone:       \tGMT\r\n");
    }
    else
    {
        if(writeFlg == 1)   sd_fprintf(&fileObject, "// Time zone:       \tLocal\r\n");
        if(printFlg == 1)                   uprintf("// Time zone:       \tLocal\r\n");
    }


    if(printFlg == 1)    wait_consoleTx();       // defd in uartstdio.c  TODO add timeout


    if(writeFlg == 1) sd_fprintf(&fileObject, "// TCOffset:     \t%f\r\n", sys_data.TCOffset);
    if(printFlg == 1)                 uprintf("// TCOffset:     \t%f\r\n", sys_data.TCOffset);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// k0int:        \t%f\r\n", sys_data.k0int);
    if(printFlg == 1)                 uprintf("// k0int:        \t%f\r\n", sys_data.k0int);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// k0ext:        \t%f\r\n", sys_data.k0ext);
    if(printFlg == 1)                 uprintf("// k0ext:        \t%f\r\n", sys_data.k0ext);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// k2int:        \t%f\r\n", sys_data.k2int);
    if(printFlg == 1)                 uprintf("// k2int:        \t%f\r\n", sys_data.k2int);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// k2ext:        \t%f\r\n", sys_data.k2ext);
    if(printFlg == 1)                 uprintf("// k2ext:        \t%f\r\n", sys_data.k2ext);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Def Sal (ppt):\t%f\r\n", sys_data.default_sal);
    if(printFlg == 1)                 uprintf("// Def Sal (ppt):\t%f\r\n", sys_data.default_sal);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Offset Ik:    \t%f\r\n", sys_data.offset_Ik);
    if(printFlg == 1)                 uprintf("// Offset Ik:    \t%f\r\n", sys_data.offset_Ik);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Offset Ib:    \t%f\r\n", sys_data.offset_Ib);
    if(printFlg == 1)                 uprintf("// Offset Ib:    \t%f\r\n", sys_data.offset_Ib);
    if(sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] == 0)
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// S-H c0        \t%f\r\n", sys_data.quadTherm_c0);
        if(printFlg == 1)                 uprintf("// s-h c0        \t%f\r\n", sys_data.quadTherm_c0);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// S-H c1        \t%f\r\n", sys_data.quadTherm_c1);
        if(printFlg == 1)                 uprintf("// s-h c1        \t%f\r\n", sys_data.quadTherm_c1);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// S-H c2        \t%f\r\n", sys_data.quadTherm_c2);
        if(printFlg == 1)                 uprintf("// s-h c2        \t%f\r\n", sys_data.quadTherm_c2);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// S-H c3        \t%f\r\n", sys_data.quadTherm_c3);
        if(printFlg == 1)                 uprintf("// s-h c3        \t%f\r\n", sys_data.quadTherm_c3);
    }
    if(sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] == 1)
    {
        if(writeFlg == 1) sd_fprintf(&fileObject, "// S-H A         \t%f\r\n", sys_data.shTherm_A);
        if(printFlg == 1)                 uprintf("// s-h A         \t%f\r\n", sys_data.shTherm_A);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// S-H B         \t%f\r\n", sys_data.shTherm_B);
        if(printFlg == 1)                 uprintf("// s-h B         \t%f\r\n", sys_data.shTherm_B);
        if(writeFlg == 1) sd_fprintf(&fileObject, "// S-H C         \t%f\r\n", sys_data.shTherm_C);
        if(printFlg == 1)                 uprintf("// s-h C         \t%f\r\n", sys_data.shTherm_C);
    }

    //-- Cal Data, new 20Sep2023
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Cal filename  \t%s\r\n", sys_data.cal_filename);
    if(printFlg == 1)                 uprintf("// Cal filename  \t%s\r\n", sys_data.cal_filename);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// PT_Cal_date   \t%s\r\n", sys_data.PT_Cal_date);
    if(printFlg == 1)                 uprintf("// PT_Cal_date   \t%s\r\n", sys_data.PT_Cal_date);


    if(writeFlg == 1) sd_fprintf(&fileObject, "// k2_C0         \t%e\r\n", sys_data.K2_Cal[0]);
    if(printFlg == 1)                 uprintf("// k2_C0         \t%e\r\n", sys_data.K2_Cal[0]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// k2_C1         \t%e\r\n", sys_data.K2_Cal[1]);
    if(printFlg == 1)                 uprintf("// k2_C1         \t%e\r\n", sys_data.K2_Cal[1]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// k2_C2         \t%e\r\n", sys_data.K2_Cal[2]);
    if(printFlg == 1)                 uprintf("// k2_C2         \t%e\r\n", sys_data.K2_Cal[2]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// k2_C3         \t%e\r\n", sys_data.K2_Cal[3]);
    if(printFlg == 1)                 uprintf("// k2_C3         \t%e\r\n", sys_data.K2_Cal[3]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// fP_0          \t%e\r\n", sys_data.fP_Cal[0]);
    if(printFlg == 1)                 uprintf("// fP_0          \t%e\r\n", sys_data.fP_Cal[0]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// fP_1          \t%e\r\n", sys_data.fP_Cal[1]);
    if(printFlg == 1)                 uprintf("// fP_1          \t%e\r\n", sys_data.fP_Cal[1]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// fP_2          \t%e\r\n", sys_data.fP_Cal[2]);
    if(printFlg == 1)                 uprintf("// fP_2          \t%e\r\n", sys_data.fP_Cal[2]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// fP_3          \t%e\r\n", sys_data.fP_Cal[3]);
    if(printFlg == 1)                 uprintf("// fP_3          \t%e\r\n", sys_data.fP_Cal[3]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// fP_4          \t%e\r\n", sys_data.fP_Cal[4]);
    if(printFlg == 1)                 uprintf("// fP_4          \t%e\r\n", sys_data.fP_Cal[4]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// fP_5          \t%e\r\n", sys_data.fP_Cal[5]);
    if(printFlg == 1)                 uprintf("// fP_5          \t%e\r\n", sys_data.fP_Cal[5]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// fP_6          \t%e\r\n", sys_data.fP_Cal[6]);
    if(printFlg == 1)                 uprintf("// fP_6          \t%e\r\n", sys_data.fP_Cal[6]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// k0_Cal_date   \t%s\r\n", sys_data.k0_Cal_date);
    if(printFlg == 1)                 uprintf("// k0_Cal_date   \t%s\r\n", sys_data.k0_Cal_date);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// k0_HCl        \t%e\r\n", sys_data.k0_HCL);
    if(printFlg == 1)                 uprintf("// k0_HCl        \t%e\r\n", sys_data.k0_HCL);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// k0_SW         \t%e\r\n", sys_data.k0_SW);
    if(printFlg == 1)                 uprintf("// k0_SW         \t%e\r\n", sys_data.k0_SW);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// k0std_SW      \t%e\r\n", sys_data.k0std_SW);
    if(printFlg == 1)                 uprintf("// k0std_SW      \t%e\r\n", sys_data.k0std_SW);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// service_date  \t%s\r\n", sys_data.service_date);
    if(printFlg == 1)                 uprintf("// service_date  \t%s\r\n", sys_data.service_date);

    //-- Cal File end

    if(writeFlg == 1)   sd_fprintf(&fileObject, "// Version Info: \t%s\r\n", VERSION);
    if(printFlg == 1)                   uprintf("// Version Info: \t%s\r\n", VERSION);


    // Store the tab delimited deployment header. (Excel treats quoted string as text)
    if(writeFlg == 1) sd_fprintf(&fileObject, "// File name:     \t%s\r\n", sys_data.fileName);
    if(printFlg == 1)                 uprintf("// File name:     \t%s\r\n", sys_data.fileName);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// User initials: \t%s\r\n", sys_data.user);
    if(printFlg == 1)                 uprintf("// User initials: \t%s\r\n", sys_data.user);

    if(printFlg == 1)    wait_consoleTx();       // defd in uartstdio.c  TODO add timeout

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Board SN:      \t%s\r\n", sys_data.board_SN);
    if(printFlg == 1)                 uprintf("// Board SN:      \t%s\r\n", sys_data.board_SN);
//#if BOARD_MPHOX == 1  || BOARD_MSC == 2 || BOARD_MFET >= 1
    if(writeFlg == 1) sd_fprintf(&fileObject, "// MCAP SN:       \t%s\r\n", sys_data.mcap_SN);
    if(printFlg == 1)                 uprintf("// MCAP SN:       \t%s\r\n", sys_data.mcap_SN);
//#endif
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Sensor SN:     \t%s\r\n", sys_data.sensor_SN);
    if(printFlg == 1)                 uprintf("// Sensor SN:     \t%s\r\n", sys_data.sensor_SN);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// ISFET SN:      \t%s\r\n", sys_data.isfet_SN);
    if(printFlg == 1)                 uprintf("// ISFET SN:      \t%s\r\n", sys_data.isfet_SN);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// ISE SN:        \t%s\r\n", sys_data.ise_SN);
    if(printFlg == 1)                 uprintf("// ISE SN:        \t%s\r\n", sys_data.ise_SN);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Optode SN:     \t%s\r\n", sys_data.optode_SN);
    if(printFlg == 1)                 uprintf("// Optode SN:     \t%s\r\n", sys_data.optode_SN);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// CTD SN:        \t%s\r\n", sys_data.ctd_SN);
    if(printFlg == 1)                 uprintf("// CTD SN:        \t%s\r\n", sys_data.ctd_SN);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump1 SN:      \t%s\r\n", sys_data.pump_SN);
    if(printFlg == 1)                 uprintf("// Pump1 SN:      \t%s\r\n", sys_data.pump_SN);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Pump2 SN:      \t%s\r\n", sys_data.pump2_SN);
    if(printFlg == 1)                 uprintf("// Pump2 SN:      \t%s\r\n", sys_data.pump2_SN);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Package name:  \t%s\r\n", sys_data.package_name);
    if(printFlg == 1)                 uprintf("// Package name:  \t%s\r\n", sys_data.package_name);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Fab Note:      \t%s\r\n", sys_data.package_fab_note);
    if(printFlg == 1)                 uprintf("// Fab Note:      \t%s\r\n", sys_data.package_fab_note);
    if(writeFlg == 1) sd_fprintf(&fileObject, "// Deploy note:   \t%s\r\n", sys_data.deploy_note);
    if(printFlg == 1)                 uprintf("// Deploy note:   \t%s\r\n", sys_data.deploy_note);

    // write app config state  new 21 June 2022
    if(writeFlg == 1) sd_fprintf(&fileObject, "// MicroSD Logging:  \t%u\r\n", sys_data.app_cfg[APPCFG_MICROSD_ENABLE]);
    if(printFlg == 1)                 uprintf("// MicroSD Logging:  \t%u\r\n", sys_data.app_cfg[APPCFG_MICROSD_ENABLE]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// Uart Echo:     \t%u\r\n", sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO]);
    if(printFlg == 1)                 uprintf("// Uart Echo:     \t%u\r\n", sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO]);

    if(writeFlg == 1) sd_fprintf(&fileObject, "// App Exec:      \t%u\r\n", sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI]);
    if(printFlg == 1)                 uprintf("// App Exec:      \t%u\r\n", sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI]);

    // HACK, problem with passing pointers and short on time to code (arrgg)
    if(writeFlg == 1)
    {
        sys_samp.next_gdata_fptr = fileObject.fptr;     // Store the file pointer for the first sample (for gdata)

        // Close the file
        fresult = f_close( &fileObject);
        if(fresult != FR_OK)
        {
            uprintf("f_close error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }
    }

    // BUG 28 Dec 2021, write_config_data fields is NOT writing to uSD  (problem with fopen, fclose)
    print_write_config_data_fields(printFlg, writeFlg, 1);  // new 27 Jul 2021  2 prints // pad



    if(writeFlg == 1)
    {

        // Open a file
        fresult = f_open(&fileObject, sys_data.fileName, FA_READ |FA_WRITE |FA_OPEN_ALWAYS);
        if(fresult != FR_OK)
        {
            uprintf("f_open error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }

        // Seek to the end, to append our file
        fresult = f_lseek(&fileObject, fileObject.fsize);
        if(fresult != FR_OK)
        {
            uprintf("f_lseek error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }

    }



    if(writeFlg == 1) sd_fprintf(&fileObject, "//--**************************************************\r\n");
    if(printFlg == 1)                 uprintf("//--**************************************************\r\n");

    if(writeFlg == 1) sd_fprintf(&fileObject, "\r\n\r\n");
    if(printFlg == 1)                 uprintf("\r\n\r\n");


    if(writeFlg == 1)
    {
        sys_samp.next_gdata_fptr = fileObject.fptr;     // Store the file pointer for the first sample (for gdata)

        // Close the file
        fresult = f_close( &fileObject);
        if(fresult != FR_OK)
        {
            uprintf("f_close error: %s\r\n", StringFromFresult(fresult));
            //return 1;
            retVal = 1;
            writeFlg = 0;
        }
    }

    if(printFlg == 1)    wait_consoleTx();       // defd in uartstdio.c  TODO add timeout

    //return 0;  // all went well, return 0 for OK
    return(retVal);

}


void print_metadata_header(const time_t currentTime)
{
    print_write_metadata_header(currentTime, 1, 0);

}


void print_sys_samp_data_structure(void)
{
    uprintf("\r\n");
    uprintf("// ------ sys_samp FRAM volatile data structure, size = %u ---- \r\n", sizeof(struct systemSamplingData));
    uprintf("// state:           %u    0=IDLE,1=START,2=DEPLOYED,3=COMMAND\r\n", sys_samp.state);
    uprintf("// nextWakeUp:      %u    \r\n", sys_samp.nextWakeUp);
    uprintf("// next_gdata_fptr: %u    \r\n", sys_samp.next_gdata_fptr);
    uprintf("// current_sample:  %u    \r\n", sys_samp.current_sample);
    uprintf("// AD24_std:        %8.6f    \r\n", sys_samp.AD24_std);
    uprintf("// sensor_sal:      %8.4f    \r\n", sys_samp.sensor_sal);
    uprintf("// spare1:          %8.4f    \r\n", sys_samp.spare1);
    uprintf("// spare2:          %8.4f    \r\n", sys_samp.spare2);
    uprintf("// spare3:          %8.4f    \r\n", sys_samp.spare3);
    uprintf("// spare4:          %8.4f    \r\n", sys_samp.spare4);
    uprintf("// initNum:         %08x    \r\n", sys_samp.initNum);
    uprintf("// pump_seq_state:  %u    \r\n", sys_samp.pump_seq_state);
    uprintf("// pump1_cnt:       %u    \r\n", sys_samp.pump1_cnt);
    uprintf("// pump2_cnt:       %u    \r\n", sys_samp.pump2_cnt);
    uprintf("// start_pump_cntdown: %u    \r\n", sys_samp.start_pump_cntdown);
    uprintf("\r\n");


}

void print_sys_data_structure(void)
{
    uprintf("\r\n");
    uprintf("// ------ sys_data EEPROM structure, size = %u ---- \r\n", sizeof(struct systemData));
    uprintf("// firmware version: %s\r\n", sys_data.firmware_version);  // new 10Oct2022
    uprintf("// sampling_period: %u\r\n", sys_data.sampling_period);
    uprintf("// chksum:          %u\r\n", sys_data.chksum);
    uprintf("// averaging_interval: %u\r\n", sys_data.averaging_interval);
    uprintf("// pump1_ontime: %u\r\n", sys_data.pump1_ontime);
    uprintf("// low_batt_volt: %.2f\r\n", sys_data.low_batt_volt);
    uprintf("\r\n");
    uprintf("// TCOffset: %.6f\r\n", sys_data.TCOffset);
    uprintf("// k0ext: %.6f\r\n", sys_data.k0ext);
    uprintf("// k0int: %.6f\r\n", sys_data.k0int);
    uprintf("// k2ext: %.6f\r\n", sys_data.k2ext);
    uprintf("// k2int: %.6f\r\n", sys_data.k2int);
    uprintf("// quadTherm_c0: %.11lf\r\n", sys_data.quadTherm_c0);
    uprintf("// quadTherm_c2: %.11lf\r\n", sys_data.quadTherm_c1);
    uprintf("// quadTherm_c3: %.11lf\r\n", sys_data.quadTherm_c2);
    uprintf("// quadTherm_c4: %.11lf\r\n", sys_data.quadTherm_c3);
    uprintf("// shTherm_A: %.11lf\r\n", sys_data.shTherm_A);                // steinhart-hart coefficient A
    uprintf("// shTherm_B: %.11lf\r\n", sys_data.shTherm_B);                // steinhart-hart coefficient C
    uprintf("// shTherm_C: %.11lf\r\n", sys_data.shTherm_C);                // steinhart-hart coefficient B
    uprintf("// default_sal: %.6f\r\n", sys_data.default_sal);
    uprintf("// sensor_sal: %.6f\r\n", sys_samp.sensor_sal);

    uprintf("//\r\n");
    wait_consoleTx();

    uprintf("// Vrsi_sps: %u\r\n", sys_data.Vrsi_sps);
    uprintf("// Vrsi_trials: %u\r\n", sys_data.Vrsi_trials);
    uprintf("// Vrse_sps: %u\r\n", sys_data.Vrse_sps);
    uprintf("// Vrse_trials: %u\r\n", sys_data.Vrse_trials);
    uprintf("// Vtherm_sps: %u\r\n", sys_data.Vtherm_sps);
    uprintf("// Vtherm_trials: %u\r\n", sys_data.Vtherm_trials);
    uprintf("// Ik_sps: %u\r\n", sys_data.Ik_sps);
    uprintf("// Ik_trials: %u\r\n", sys_data.Ik_trials);
    uprintf("// Vk_sps: %u\r\n", sys_data.Vk_sps);
    uprintf("// Vk_trials: %u\r\n", sys_data.Vk_trials);
    uprintf("// Ib_sps: %u\r\n", sys_data.Ib_sps);
    uprintf("// Ib_trials: %u\r\n", sys_data.Ib_trials);
    uprintf("// Vb_sps: %u\r\n", sys_data.Vb_sps);
    uprintf("// Vb_trials: %u\r\n", sys_data.Vb_trials);
    uprintf("// Vbias_sps: %u\r\n", sys_data.Vbias_sps);
    uprintf("// Vbias_trials: %u\r\n", sys_data.Vbias_trials);
    uprintf("// offset_Ik: %u\r\n", sys_data.offset_Ik);
    uprintf("// offset_Ib: %u\r\n", sys_data.offset_Ib);

    uprintf("//\r\n");
    wait_consoleTx();

    uprintf("// output: %u\r\n", sys_data.output);
    uprintf("// test_mode: %u\r\n", sys_data.test_mode);
    uprintf("// fast_mode: %u\r\n", sys_data.fast_mode);

    uprintf("// solenoid_on2hold_msec: %u msec\r\n", sys_data.solenoid_on2hold_msec);
    uprintf("// solenoid_hold_pwm: %u\r\n", sys_data.solenoid_hold_pwm);
    uprintf("// solenoid_holdtime: %u sec\r\n", sys_data.solenoid_holdtime);

    uprintf("// baud_rate: %u\r\n", sys_data.baud_rate);
    uprintf("//\r\n");
    wait_consoleTx();

    print_write_config_data_fields(1,0,1);
    wait_consoleTx();

    uprintf("//\r\n");
    uprintf("// app_cfg[APPCFG_SAMPLING_DIAG]: %u\r\n", sys_data.app_cfg[APPCFG_SAMPLING_DIAG]);
    uprintf("// app_cfg[APPCFG_TEMPC_SH_ALG]: %u\r\n", sys_data.app_cfg[APPCFG_TEMPC_SH_ALG]);
    uprintf("// app_cfg[APPCFG_MICROSD_ENABLE]: %u\r\n", sys_data.app_cfg[APPCFG_MICROSD_ENABLE]);
    uprintf("// app_cfg[APPCFG_MENU_LEVEL]: %u\r\n", sys_data.app_cfg[APPCFG_MENU_LEVEL]);
    uprintf("// app_cfg[APPCFG_DEPLOY_UARTECHO]: %u\r\n", sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO]);
    uprintf("// app_cfg[APPCFG_EXEC_SWITCHERONI]: %u\r\n", sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI]);
    uprintf("//\r\n");
    wait_consoleTx();

    uprintf("// GMT: %u\r\n", sys_data.GMT);
    uprintf("// sample_aligned: %u\r\n", sys_data.sample_aligned);
    uprintf("// deploy_time: %u\r\n", sys_data.deploy_time);
    uprintf("// start_pump_time: ");       print_time_t_Time(sys_data.start_pump_time);

    uprintf("// pHOffset: %.6f\r\n", sys_data.pHOffset);
    uprintf("// pHSlope:  %.6f\r\n", sys_data.pHSlope);
    uprintf("// TCSlope: %.6f\r\n", sys_data.TCSlope);
    uprintf("// sensor_ctd_TC:  %.6f\r\n", sys_data.sensor_ctd_TC);
    uprintf("// sensor_optode_TC:  %.6f\r\n", sys_data.sensor_optode_TC);

    uint32_t indx;
    for(indx=0; indx<4; indx++)   uprintf("// spare[%u] : %.6f\r\n", indx, sys_data.spare[indx]);

    wait_consoleTx();

    uprintf("// Cal filename: %s\r\n", sys_data.cal_filename);
    uprintf("// PT_Cal_date,%s\r\n", sys_data.PT_Cal_date);

    uprintf("// k2_C0,%e\r\n", sys_data.K2_Cal[0]);
    uprintf("// k2_C1,%e\r\n", sys_data.K2_Cal[1]);
    uprintf("// k2_C2,%e\r\n", sys_data.K2_Cal[2]);
    uprintf("// k2_C3,%e\r\n", sys_data.K2_Cal[3]);

    wait_consoleTx();

    uprintf("// fP_0,%e\r\n", sys_data.fP_Cal[0]);
    uprintf("// fP_1,%e\r\n", sys_data.fP_Cal[1]);
    uprintf("// fP_2,%e\r\n", sys_data.fP_Cal[2]);
    uprintf("// fP_3,%e\r\n", sys_data.fP_Cal[3]);
    uprintf("// fP_4,%e\r\n", sys_data.fP_Cal[4]);
    uprintf("// fP_5,%e\r\n", sys_data.fP_Cal[5]);
    uprintf("// fP_6,%e\r\n", sys_data.fP_Cal[6]);

    wait_consoleTx();

    uprintf("// k0_Cal_date,%s\r\n", sys_data.k0_Cal_date);
    uprintf("// k0_HCl,%e\r\n", sys_data.k0_HCL);
    uprintf("// k0_SW,%e\r\n", sys_data.k0_SW);
    uprintf("// k0std_SW,%e\r\n", sys_data.k0std_SW);
    uprintf("// service_date,%s\r\n", sys_data.service_date);

    wait_consoleTx();

    uprintf("// fileName: %s\r\n", sys_data.fileName);
    uprintf("// user: %s\r\n", sys_data.user);
    uprintf("// board_SN: %s\r\n", sys_data.board_SN);
    uprintf("// mcap_SN: %s\r\n", sys_data.mcap_SN);
    uprintf("// sensor_SN: %s\r\n", sys_data.sensor_SN);
    uprintf("// isfet_SN: %s\r\n", sys_data.isfet_SN);
    uprintf("// ise_SN: %s\r\n", sys_data.ise_SN);
    uprintf("// package_name: %s\r\n", sys_data.package_name);
    uprintf("// optode_SN: %s\r\n", sys_data.optode_SN);
    uprintf("// ctd_SN: %s\r\n", sys_data.ctd_SN);
    uprintf("// pump1_SN: %s\r\n", sys_data.pump_SN);
    uprintf("// pump2_SN: %s\r\n", sys_data.pump2_SN);
    uprintf("// deploy_note: %s\r\n", sys_data.deploy_note);
    uprintf("// package_fab_note: %s\r\n", sys_data.package_fab_note);
    uprintf("//\r\n");

    wait_consoleTx();
    //uprintf("// state: %u\r\n", sys_samp.state);
    //uprintf("// nextWakeUp: %u\r\n", sys_samp.nextWakeUp);
    //uprintf("// next_gdata_fptr: %u\r\n", sys_samp.next_gdata_fptr);
    //uprintf("// current_sample: %u\r\n", sys_samp.current_sample);
    //uprintf("// AD24_std: %.6f\r\n", sys_samp.AD24_std);


}



void ads1248_sampling_defaults(void)
{
    sys_data.Vtherm_trials = VTHERM_TRIALS;
    sys_data.Vtherm_sps = VTHERM_SPS;

    sys_data.Vrsi_trials = VRSI_TRIALS;
    sys_data.Vrsi_sps = VRSI_SPS;

    sys_data.Vrse_trials = VRSE_TRIALS;
    sys_data.Vrse_sps = VRSE_SPS;

    sys_data.Ik_trials = IK_TRIALS;
    sys_data.Ik_sps = IK_SPS;

    sys_data.Vk_trials = VK_TRIALS;
    sys_data.Vk_sps = VK_SPS;

    sys_data.Ib_trials = IB_TRIALS;
    sys_data.Ib_sps = IB_SPS;

    sys_data.Vb_trials = VB_TRIALS;
    sys_data.Vb_sps = VB_SPS;

    sys_data.Vbias_trials = VBIAS_TRIALS;
    sys_data.Vbias_sps = VBIAS_SPS;       // used for vbias bat
}


void init_sys_samp_default(void)
{
    initSysSampFRAMVariables();   //defd in system.c
}


void init_sys_data_default(void)
//void config_sys_data_default_init(void)
{
    int indx;

    strcpy(sys_data.firmware_version, VERSION);  //new 10Oct2022

    sys_data.deploy_time = ROM_HibernateRTCGet();

    sys_data.low_batt_volt = 9.2;
#if BOARD_MFET >= 1
    sys_data.low_batt_volt = 5.5;
#endif
#if BOARD_MPHOX >= 1  || BOARD_MSC == 2
    sys_data.low_batt_volt = 10.0;
#endif
#if BOARD_NANOFET >= 1
    sys_data.low_batt_volt = 5.5;
#endif
    sys_data.sampling_period = 0;
    sys_data.chksum = 0;           // was sample average
    sys_data.averaging_interval = 60;
    sys_data.sample_aligned = false;
    sys_data.GMT = false;                       //456 GMT or Local time
    sys_data.sample_aligned = true;            //460 Sample aligned to hour
    sys_data.pump1_ontime = 0;
    sys_data.TCOffset = 0.0;
    sys_data.k0ext = -1.3;
    sys_data.k0int = -0.4;
    sys_data.k2ext = -0.001081;
    sys_data.k2int = -0.001455;


    // steinhart-hart coefficients for thermistor (why are the 4 coeff, thought there should only be 3)
    sys_data.quadTherm_c0 = 340.9819863;
    sys_data.quadTherm_c1 = -9.10257E-05;  // -0.0000910257
    sys_data.quadTherm_c2 = -95.08806667;
    sys_data.quadTherm_c3 = 0.965370274;

    sys_data.shTherm_A = 0.002108508173;
    sys_data.shTherm_B = 0.00007979204727;
    sys_data.shTherm_C = 0.0000006535076315;

    for(indx=0; indx<MAX_NUMOF_K2_CAL_FIELDS; indx++)
    {
        sys_data.K2_Cal[indx] = 0.0000;
    }

    for(indx=0; indx<MAX_NUMOF_FP_CAL_FIELDS; indx++)
    {
        sys_data.fP_Cal[indx] = 0.0000;
    }

    sys_data.k0_HCL = 0.0;
    sys_data.k0_SW = 0.0;
    sys_data.k0std_SW = 0.0;

    strcpy(sys_data.service_date, " ");
    strcpy(sys_data.PT_Cal_date, " ");
    strcpy(sys_data.k0_Cal_date, " ");
    strcpy(sys_data.cal_filename, " ");

    sys_data.default_sal = 35.0;
    sys_samp.sensor_sal = 0.0;

    ads1248_sampling_defaults();

    sys_data.offset_Ik = 0.000800;             // 800uV or so, tbd measure a QA step.
    sys_data.offset_Ib = 0.000800;

    sys_data.output = NORMAL;
    sys_data.test_mode = 0;
    sys_data.fast_mode = 1;
    sys_data.solenoid_on2hold_msec = 100;   // hit
    sys_data.solenoid_hold_pwm = 40;        // hold
    sys_data.solenoid_holdtime = 10;        // seconds


    //state;                      //430 IDLE, DEPLOYED, COMMAND,  NOT USER MODIFIABLE                        <<<<<------
    //uint32_t nextWakeUp;            //434 Next intended RTC match (wake-up time) NOT USER MODIFIABLE           <<<<<------
    //unsigned long next_gdata_fptr;  //438 The file position of the next gdata sample. NOT USER MODIFIABLE      <<<<<------
    //unsigned int current_sample;    //442 The current data record to be stored. NOT USER MODIFIABLE            <<<<<------
    //float AD24_std;                 //464 standard deviation for AD24                                          <<<<--------
    sys_samp.state = IDLE;
    //sys_data.nextWakeUp = current_time + 30;
    sys_samp.nextWakeUp = ROM_HibernateRTCGet()+sys_data.sampling_period;
    sys_samp.next_gdata_fptr = 0;
    sys_samp.AD24_std = 0.0;
    sys_samp.current_sample = 0;
    sys_samp.start_pump_cntdown = 0;

    sys_data.deploy_time = 0;
    sys_data.start_pump_time = 0;         // Wakeup on sampling interval, but check the 'start deployment time' before actual pumping/sampling 16 Feb 2022

    sys_data.pump_seq_type = TYPE_PUMP_SINGLE;             // 0) legacy single pump, 1) BEAMS v1 dual pump seq, 2) BEAMS v2
    //uint32_t pump_seq_state;          // defd in FRAM volatile data struct
    sys_data.sampleCnt_duty_on = 0;         // duty cycle for extending experiment.   3 days on, 5 days off.   Number of 'sample periods' on
    sys_data.sampleCnt_duty_off = 0;        // in sample periods.    Accept input in hours, translate to sample periods (keep implementation simple for now).
    //uint32_t sampling_interval;         // = 1 min  (see sampling_period above)
    sys_data.pump1_cycles = 1;                   // = 10 cycles
    sys_data.pump2_cycles = 0;                   // = 5 cycles
    sys_data.pump1_ontime = 0;
    sys_data.pump2_ontime = 0;


    if(sys_data.baud_rate != 115200)
    {
        uprintf("Baud rate is changed to default: 115200\r\n");
        wait_consoleTx();
        UARTStdioConfig(0, 115200, 16000000);       // 115200 bits per second
    }

    sys_data.baud_rate = 115200L;


    for(indx=0; indx<MAX_NUMOF_CONFIG_FIELDS; indx++)
        sys_data.data_cfg[indx] = 0;


    sys_data.pHOffset = 0.0;
    sys_data.pHSlope = 1.0;
    sys_data.TCSlope = 1.0;
    sys_data.sensor_ctd_TC = 0.0;
    sys_data.sensor_optode_TC = 0.0;

    sys_data.spare[0] = 0.0;
    sys_data.spare[1] = 0.0;
    sys_data.spare[2] = 0.0;
    sys_data.spare[3] = 0.0;


    sys_data.diag = 0;                      // diagnostics, enables sample time measurement
    sys_data.debug_flag = 0;                // diagnostic printf (dbg_printf() enabled)
    sys_data.GMT = false;                       //456 GMT or Local time
    sys_data.sample_aligned = false;            //460 Sample aligned to hour

    sys_data.pHOffset = 0.0;
    sys_data.pHSlope = 1.0;
    sys_data.fast_mode = 1;

    strcpy(sys_data.fileName, "noname.txt");
    strcpy(sys_data.user, "abc");
    strcpy(sys_data.board_SN, " ");
    strcpy(sys_data.package_fab_note, " ");
    strcpy(sys_data.mcap_SN, " ");
    strcpy(sys_data.sensor_SN, " ");
    strcpy(sys_data.isfet_SN, " ");
    strcpy(sys_data.ise_SN, " ");
    strcpy(sys_data.optode_SN, " ");
    strcpy(sys_data.ctd_SN, " ");
    strcpy(sys_data.pump_SN, " ");
    strcpy(sys_data.pump2_SN, " ");
    strcpy(sys_data.pump3_SN, " ");
    strcpy(sys_data.package_name, " ");   // instrument package name, ex. underway system, glider pH
    strcpy(sys_data.deploy_note, " ");

    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = 1;            // B

    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 1;        // C
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 1;        // E

    sys_data.data_cfg[CFG_BRD_TEMP] = 1;            // F
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

    sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I

    sys_data.data_cfg[CFG_VRSI] = 1;               // J
    sys_data.data_cfg[CFG_VRSI_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 1;          // K

    sys_data.data_cfg[CFG_VRSE] = 1;               // L
    sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m


    sys_data.data_cfg[CFG_VRSI_BIASED] = 1;        // N
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; //
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w

    sys_data.data_cfg[CFG_SPARE1] = 0;
    sys_data.data_cfg[CFG_SPARE2] = 0;
    sys_data.data_cfg[CFG_SPARE3] = 0;
    sys_data.data_cfg[CFG_SPARE4] = 0;
    sys_data.data_cfg[CFG_SPARE5] = 0;
    sys_data.data_cfg[CFG_SPARE6] = 0;

    sys_data.app_cfg[APPCFG_SAMPLING_DIAG] = 0;
    sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] = 0;
    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;        // enable micro sd card
    sys_data.app_cfg[APPCFG_MENU_LEVEL] = 0;
    sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] = 1;       // 1 Echo ON
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEFAULT;       // 0
    sys_data.app_cfg[APPCFG_SPARE6] = 0;
    sys_data.app_cfg[APPCFG_SPARE7] = 0;
    sys_data.app_cfg[APPCFG_SPARE8] = 0;
    sys_data.app_cfg[APPCFG_SPARE9] = 0;
    sys_data.app_cfg[APPCFG_SPARE10] = 0;
    sys_data.app_cfg[APPCFG_SPARE11] = 0;
    sys_data.app_cfg[APPCFG_SPARE12] = 0;
    sys_data.app_cfg[APPCFG_SPARE13] = 0;
    sys_data.app_cfg[APPCFG_SPARE14] = 0;
    sys_data.app_cfg[APPCFG_SPARE15] = 0;

// override NANOFET specifics...
#if BOARD_NANOFET >= 1
    sys_data.data_cfg[CFG_SAMPLE_NUM] = 1;          // A
    sys_data.data_cfg[CFG_TIMESTAMP] = 1;            // B

    sys_data.data_cfg[CFG_VIN_BAT_VOLT] = 0;        // c
    sys_data.data_cfg[CFG_BIAS_BAT_POS] = 1;        // D
    sys_data.data_cfg[CFG_BIAS_BAT_NEG] = 0;        // e

    sys_data.data_cfg[CFG_BRD_TEMP] = 1;            // F
    sys_data.data_cfg[CFG_BRD_HUMIDITY] = 1;        // G

    sys_data.data_cfg[CFG_V_THERMISTOR] = 1;        // H
    sys_data.data_cfg[CFG_V_THERMISTOR_STD] = 1;    //
    sys_data.data_cfg[CFG_CALC_TEMP] = 1;           // I

    sys_data.data_cfg[CFG_VRSI] = 0;               // j
    sys_data.data_cfg[CFG_VRSI_STD] = 0;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSI] = 0;          // K

    sys_data.data_cfg[CFG_VRSE] = 1;               // L
    sys_data.data_cfg[CFG_VRSE_STD] = 1;           //
    sys_data.data_cfg[CFG_CALC_PH_VRSE] = 0;          // m


    sys_data.data_cfg[CFG_VRSI_BIASED] = 0;        // n
    sys_data.data_cfg[CFG_VRSI_BIASED_STD] = 0;    // o
    sys_data.data_cfg[CFG_VRSE_BIASED] = 0;        // p
    sys_data.data_cfg[CFG_VRSE_BIASED_STD] = 0;    // q

    sys_data.data_cfg[CFG_V_COUNTER_ELECT] = 1;     // R
    sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] = 1; //
    sys_data.data_cfg[CFG_I_COUNTER] = 1;           // T
    sys_data.data_cfg[CFG_I_SUBSTRATE] = 1;         // U

    sys_data.data_cfg[CFG_UART3_INST] = INST_OPTODE_NOTDEFD;              // v
    sys_data.data_cfg[CFG_UART4_INST] = INST_CTD_NOTDEFD;                 // w

    sys_data.data_cfg[CFG_SPARE1] = 0;
    sys_data.data_cfg[CFG_SPARE2] = 0;
    sys_data.data_cfg[CFG_SPARE3] = 0;
    sys_data.data_cfg[CFG_SPARE4] = 0;
    sys_data.data_cfg[CFG_SPARE5] = 0;
    sys_data.data_cfg[CFG_SPARE6] = 0;

    sys_data.app_cfg[APPCFG_SAMPLING_DIAG] = 0;
    sys_data.app_cfg[APPCFG_TEMPC_SH_ALG] = 0;
    sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;        // disable micro sd card
    sys_data.app_cfg[APPCFG_MENU_LEVEL] = 0;
    sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] = 1;       // 1 Echo ON
    sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEFAULT;      // For alternate 'application function' aka, Irene Hu enabling
    sys_data.app_cfg[APPCFG_SPARE6] = 0;
    sys_data.app_cfg[APPCFG_SPARE7] = 0;
    sys_data.app_cfg[APPCFG_SPARE8] = 0;
    sys_data.app_cfg[APPCFG_SPARE9] = 0;
    sys_data.app_cfg[APPCFG_SPARE10] = 0;
    sys_data.app_cfg[APPCFG_SPARE11] = 0;
    sys_data.app_cfg[APPCFG_SPARE12] = 0;
    sys_data.app_cfg[APPCFG_SPARE13] = 0;
    sys_data.app_cfg[APPCFG_SPARE14] = 0;
    sys_data.app_cfg[APPCFG_SPARE15] = 0;
#endif

    //config_qa_data_init();   //init of qa removed 3 Nov 2022

}


void config_qa_data_init(void)
{

    sys_data.qa.microSD = 0;            // microSD
    sys_data.qa.time = 0;               // time of QA
    sys_data.qa.test_time = 0;          // time it took to run QA
    sys_data.qa.eeprom = 0;
    sys_data.qa.sys_data_init = 0;      // was the data initialized
    sys_data.qa.fram = 0;
    sys_data.qa.adc12onchip = 0;
    sys_data.qa.adc24 = 0;              // how many of the ADC fields are out of expected Jensenian range


    sys_data.qa.Vrsi = 0.0;
    sys_data.qa.Vrsi_std = 0.0;
    sys_data.qa.Vrsi_err = 0.0;
    sys_data.qa.Vrse = 0.0;
    sys_data.qa.Vrse_std = 0.0;
    sys_data.qa.Vrse_err = 0.0;
    sys_data.qa.Vtherm = 0.0;
    sys_data.qa.Vtherm_std = 0.0;
    sys_data.qa.Vtherm_err = 0.0;

    sys_data.qa.Ik = 0.0;
    sys_data.qa.Ik_std = 0.0;
    sys_data.qa.Ik_err = 0.0;

    sys_data.qa.Vk = 0.0;
    sys_data.qa.Vk_std = 0.0;
    sys_data.qa.Vk_err = 0.0;

    sys_data.qa.Ib = 0.0;
    sys_data.qa.Ib_std = 0.0;
    sys_data.qa.Ib_err = 0.0;

    sys_data.qa.Vb = 0.0;
    sys_data.qa.Vb_std = 0.0;
    sys_data.qa.Vb_err = 0.0;

    sys_data.qa.Vbias_pos = 0.0;
    sys_data.qa.Vbias_neg = 0.0;

    sys_data.qa.aux_pwr1 = 0;
    sys_data.qa.aux_pwr2 = 0;
    sys_data.qa.aux_pwr3 = 0;

    sys_data.qa.ctd = 0;
    sys_data.qa.optode = 0;
    sys_data.qa.comm_pwr = 0;

    strcpy(sys_data.qa.tester, "Count Zero");
    strcpy(sys_data.qa.firmware_version, "Version Not Defined");


}

uint32_t edit_uint(uint32_t *uint_data, uint32_t negLim, uint32_t posLim)
{
    uint32_t temp;
    char buff[24];

    temp = 0;
    if(getUserInput(buff, 20))
    {
        if(sscanf(buff, "%u", &temp) == 1)
        {
             *uint_data = temp;

        }
    }
    return(temp);
}

float edit_expfloat(float *float_data, float negLim, float posLim)
{
    float temp;
    char buff[24];

    temp = 0.0;

    if(getUserInput(buff, 20))
    {
        if(sscanf(buff, "%e", &temp) == 1)
        {
             *float_data = temp;
             //return(temp);
        }
    }
    return(temp);
}



float edit_float_6(float *float_data, float negLim, float posLim)
{
    float temp;
    char buff[24];

    temp = 0.0;

    if(getUserInput(buff, 20))
    {
        if(sscanf(buff, "%.6f", &temp) == 1)
        {
             *float_data = temp;
             //return(temp);
        }
    }
    return(temp);
}

float edit_float(float *float_data, float negLim, float posLim)
{
    float temp;
    char buff[24];

    temp = 0.0;

    if(getUserInput(buff, 20))
    {
        if(sscanf(buff, "%f", &temp) == 1)
        {
             *float_data = temp;
             //return(temp);
        }
    }
    return(temp);
}

uint32_t edit_string(char *char_data, uint32_t max_chars)
{
    char buff[128];

    if( getUserInput(buff, max_chars) )
    {
        strcpy(char_data, buff);        // oops: strcpy(*char_data, buff);
        //uprintf("\r\nFile name now: %s\r\n", sys_data.fileName);
    }

    return(strlen(buff));
}


double edit_double(double *double_data, double negLim, double posLim)
{
    double temp;
    char buff[24];

    temp = 0.0;

    if(getUserInput(buff, 20))
    {
        if(sscanf(buff, "%lf", &temp) == 1)     // BUG fix %f to %lf
        {
             *double_data = temp;
             //return(temp);
        }
    }
    return(temp);
}


void edit_appcfg_fields(void)
{
    int response;

    uint32_t  old, new;

    //microsd_logging();
    old = sys_data.app_cfg[APPCFG_MICROSD_ENABLE];
    if(sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 1)
    {
        response = yesOrNoMenuChoice("\r\n\r\nEnable MicroSD logging? (Y/N) [Y]? ", YES);
        if(response == YES)
        {
            sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;
        }
        else
        {
            sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;
        }
        storeSysDataVariables();
    }
    else
    {
        response = yesOrNoMenuChoice("\r\n\r\nEnable MicroSD logging? (Y/N) [N]? ", NO);
        if(response == YES)
        {
            sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 1;
        }
        else
        {
            sys_data.app_cfg[APPCFG_MICROSD_ENABLE] = 0;
        }
        storeSysDataVariables();
    }

    if(sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 1)
        uprintf("MicroSD logging is Enabled\r\n\r\n");
    else
        uprintf("MicroSD card DISabled, no Logging\r\n\r\n");

    if((old == 0) && (sys_data.app_cfg[APPCFG_MICROSD_ENABLE] == 1))
    {
        // init the filesystem
        if( uSD_present() )
        {
            uprintf("\r\nMicroSD card is Initialized....\r\n");
            Init_SDCard();
            microSD_flg = 1;
        }
        else
        {
            uprintf("\r\nError: MicroSD card is not detected\r\n");
            microSD_flg = 0;
        }
    }

    //---------------------------------------------------------------


    // console echo enable/disable
    if(sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] == 1)
    {
        response = yesOrNoMenuChoice("\r\n\r\nEnable character echo for deployment commands? (Y/N) [Y]? ", YES);
        if(response == YES)
        {
            sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] = 1;
        }
        else
        {
            sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] = 0;
        }
        storeSysDataVariables();
    }
    else
    {
        response = yesOrNoMenuChoice("\r\n\r\nEnable character echo for deployment commands? (Y/N) [N]? ", NO);
        if(response == YES)
        {
            sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] = 1;
        }
        else
        {
            sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] = 0;
        }
        storeSysDataVariables();
    }

    if(sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO] == 1)
        uprintf("Deployment command character echo is Enabled (typical case)\r\n\r\n");
    else
        uprintf("Deployment command character echo Disabled for m2m\r\n\r\n");


    while(1)
    {
        uprintf("EXEC_DEPLOY is 0\r\n");
        uprintf("EXEC_EDDY_COVARIANCE is 1\r\n");
        uprintf("EXEC_FASTSAMP is 2\r\n\r\n");

        uprintf("app_cfg[APPCFG_EXEC_SWITCHERONI] [%u]: ", sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI]);
        edit_uint(&sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI], 0, 500);

        uprintf("\r\n");

        if(sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] > EXEC_MAXDEFD)
        {
            uprintf("\r\nEntry out of bounds, %u   Try again\r\n", sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI]);
            sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] = EXEC_DEFAULT;
            uprintf("app_cfg[APPCFG_EXEC_SWITCHERONI] [%u]: ", sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI]);
        }
        else
        {
            if(sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI] == EXEC_FASTSAMP)  // New 31 Oct 2023
            {
                sys_data.sampling_period = 2;       // if sampling_period = 0, then v5 does not RTC Wake properly
            }
            uprintf("\r\n\r\n");
            break;
        }

    }



}


void copy_edit_sys_data_structure(void)
{
    char buff[68];
    uint32_t temp, indx;
    int response;



    uprintf("// ------ sys_data structure, size = %u ---- \r\n", sizeof(struct systemData));

    while(1)
    {
        uprintf("\r\nFirst 5 sys_data fields:\r\n\r\n");

        uprintf("sampling_period [%u] sec: ", sys_data.sampling_period);
        edit_uint(&sys_data.sampling_period, 0, 6000);

        uprintf("sampling_average [%u] sec: ", sys_data.chksum);
        //edit_uint(&sys_data.sampling_period, 0, 300);

        uprintf("averaging_interval: [%u] sec: ", sys_data.averaging_interval);
        edit_uint(&sys_data.averaging_interval, 0, 360);

        uprintf("pump1_ontime [%u] sec: ", sys_data.pump1_ontime);
        edit_uint(&sys_data.pump1_ontime, 0, 3600);

        uprintf("low_batt_volt [%.1f]: ", sys_data.low_batt_volt);
        edit_float(&sys_data.k0ext, 5.5, 18.0);

        //uprintf("\r\n");
        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            {
            uprintf("\r\n");
            break;
            }
    }
    //----
    while(1)
    {
        uprintf("\r\nSecond batch of 13 sys_data fields:\r\n\r\n");

        uprintf("TCOffset [%.6f]: ", sys_data.TCOffset);
        edit_float(&sys_data.TCOffset, -10.0, 10.0);

        uprintf("k0ext [%.6f]: ", sys_data.k0ext);
        edit_float(&sys_data.k0ext, -10.0, 10.0);

        uprintf("k0int [%.6f]: ", sys_data.k0int);
        edit_float(&sys_data.k0int, -10.0, 10.0);

        uprintf("k2ext [%.6f]: ", sys_data.k2ext);
        edit_float(&sys_data.k2ext, -10.0, 10.0);

        uprintf("k2int [%.6f]: ", sys_data.k2int);
        edit_float(&sys_data.k2int, -10.0, 10.0);

        uprintf("quadTherm_c0 [%.11f]: ", sys_data.quadTherm_c0);
        edit_double(&sys_data.quadTherm_c0, -10.0, 10.0);

        uprintf("quadTherm_c1 [%.11f]: ", sys_data.quadTherm_c1);
        edit_double(&sys_data.quadTherm_c1, -10.0, 10.0);

        uprintf("quadTherm_c2 [%.11f]: ", sys_data.quadTherm_c2);
        edit_double(&sys_data.quadTherm_c2, -10.0, 10.0);

        uprintf("quadTherm_c3 [%.11f]: ", sys_data.quadTherm_c3);
        edit_double(&sys_data.quadTherm_c3, -10.0, 10.0);

        uprintf("shTherm_A [%.11f]: ", sys_data.shTherm_A);
        edit_double(&sys_data.shTherm_A, -10.0, 10.0);

        uprintf("shTherm_B [%.11f]: ", sys_data.shTherm_B);
        edit_double(&sys_data.shTherm_B, -10.0, 10.0);

        uprintf("default_sal [%.3f]: ", sys_data.default_sal);
        edit_float(&sys_data.default_sal, 0, 50.0);

        uprintf("sensor_sal [%.3f]: ", sys_samp.sensor_sal);
        edit_float(&sys_samp.sensor_sal, 0, 50.0);

        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }
    //----
    while(1)
    {
        uprintf("\r\nThird batch of 20 sys_data fields:\r\n\r\n");

        uprintf("Vrsi_sps [%u]: ", sys_data.Vrsi_sps);
        edit_uint(&sys_data.Vrsi_sps, 0, 80);

        uprintf("Vrsi_trials [%u]: ", sys_data.Vrsi_trials);
        edit_uint(&sys_data.Vrsi_trials, 0, 80);

        uprintf("Vrse_sps [%u]: ", sys_data.Vrse_sps);
        edit_uint(&sys_data.Vrse_sps, 0, 80);

        uprintf("Vrse_trials [%u]: ", sys_data.Vrse_trials);
        edit_uint(&sys_data.Vrse_trials, 0, 80);

        uprintf("Vtherm_sps [%u]: ", sys_data.Vtherm_sps);
        edit_uint(&sys_data.Vtherm_sps, 0, 80);

        uprintf("Vtherm_trials [%u]: ", sys_data.Vtherm_trials);
        edit_uint(&sys_data.Vtherm_trials, 0, 80);

        uprintf("Vtherm_trials [%u]: ", sys_data.Vtherm_trials);
        edit_uint(&sys_data.Vtherm_trials, 0, 80);

        uprintf("Ik_sps [%u]: ", sys_data.Ik_sps);
        edit_uint(&sys_data.Ik_sps, 0, 80);

        uprintf("Ik_trials [%u]: ", sys_data.Ik_trials);
        edit_uint(&sys_data.Ik_trials, 0, 80);

        uprintf("Vk_sps [%u]: ", sys_data.Vk_sps);
        edit_uint(&sys_data.Vk_sps, 0, 80);

        uprintf("Vk_trials [%u]: ", sys_data.Vk_trials);
        edit_uint(&sys_data.Vk_trials, 0, 80);

        uprintf("Ib_sps [%u]: ", sys_data.Ib_sps);
        edit_uint(&sys_data.Ib_sps, 0, 80);

        uprintf("Ib_trials [%u]: ", sys_data.Ib_trials);
        edit_uint(&sys_data.Ib_trials, 0, 80);

        uprintf("Vb_sps [%u]: ", sys_data.Vb_sps);
        edit_uint(&sys_data.Vb_sps, 0, 80);

        uprintf("Vb_trials [%u]: ", sys_data.Vb_trials);
        edit_uint(&sys_data.Vb_trials, 0, 80);

        uprintf("Vbias_sps [%u]: ", sys_data.Vbias_sps);
        edit_uint(&sys_data.Vbias_sps, 0, 80);

        uprintf("Vbias_trials [%u]: ", sys_data.Vbias_trials);
        edit_uint(&sys_data.Vbias_trials, 0, 80);

        uprintf("offset_Ik [%u]: ", sys_data.offset_Ik);
        edit_uint(&sys_data.offset_Ik, 0, 80);

        uprintf("offset_Ib [%u]: ", sys_data.offset_Ib);
        edit_uint(&sys_data.offset_Ib, 0, 80);

        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }
    //----
    while(1)
    {
        uprintf("\r\nFourth batch of 7 sys_data fields:\r\n\r\n");

        uprintf("output [%u]: ", sys_data.output);
        edit_uint(&sys_data.output, 0, 5);

        uprintf("test_mode [%u]: ", sys_data.test_mode);
        edit_uint(&sys_data.test_mode, 0, 80);

        uprintf("fast_mode [%u]: ", sys_data.fast_mode);
        edit_uint(&sys_data.fast_mode, 0, 80);

        uprintf("solenoid_on2hold_msec [%u]: ", sys_data.solenoid_on2hold_msec);
        edit_uint(&sys_data.solenoid_on2hold_msec, 0, 80);

        uprintf("solenoid_hold_pwm [%u]: ", sys_data.solenoid_hold_pwm);
        edit_uint(&sys_data.solenoid_hold_pwm, 0, 80);

        uprintf("solenoid_holdtime [%u]: ", sys_data.solenoid_holdtime);
        edit_uint(&sys_data.solenoid_holdtime, 0, 80);

        uprintf("baud_rate [%u]: ", sys_data.baud_rate);
        edit_uint(&sys_data.baud_rate, 0, 500000);

        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }
    //----

    while(1)
    {
        uprintf("\r\nFifth batch of 32 sys_data fields:\r\n\r\n");

        // data cfg  MAX_NUMOF_CONFIG_FIELDS
        //print_write_config_data_fields(1,0,0);
        uprintf("sys_data.data_cfg[CFG_SAMPLE_NUM] [%u]: ", sys_data.data_cfg[CFG_SAMPLE_NUM]);
        edit_uint(&sys_data.data_cfg[CFG_SAMPLE_NUM], 0, 5);
        uprintf("sys_data.data_cfg[CFG_TIMESTAMP] [%u]: ", sys_data.data_cfg[CFG_TIMESTAMP]);
        edit_uint(&sys_data.data_cfg[CFG_TIMESTAMP], 0, 5);
        uprintf("sys_data.data_cfg[CFG_V_THERMISTOR] [%u]: ", sys_data.data_cfg[CFG_V_THERMISTOR]);
        edit_uint(&sys_data.data_cfg[CFG_V_THERMISTOR], 0, 5);
        sys_data.data_cfg[CFG_V_THERMISTOR_STD] = sys_data.data_cfg[CFG_V_THERMISTOR];
        uprintf("sys_data.data_cfg[CFG_V_THERMISTOR_STD] [%u]: ", sys_data.data_cfg[CFG_V_THERMISTOR_STD]);
        edit_uint(&sys_data.data_cfg[CFG_V_THERMISTOR_STD], 0, 5);
        uprintf("sys_data.data_cfg[CFG_CALC_TEMP] [%u]: ", sys_data.data_cfg[CFG_CALC_TEMP]);
        edit_uint(&sys_data.data_cfg[CFG_CALC_TEMP], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSI] [%u]: ", sys_data.data_cfg[CFG_VRSI]);
        edit_uint(&sys_data.data_cfg[CFG_VRSI], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSI_STD] [%u]: ", sys_data.data_cfg[CFG_VRSI_STD]);
        edit_uint(&sys_data.data_cfg[CFG_VRSI_STD], 0, 5);
        uprintf("sys_data.data_cfg[CFG_CALC_PH_VRSI] [%u]: ", sys_data.data_cfg[CFG_CALC_PH_VRSI]);
        edit_uint(&sys_data.data_cfg[CFG_CALC_PH_VRSI], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSE] [%u]: ", sys_data.data_cfg[CFG_VRSE]);
        edit_uint(&sys_data.data_cfg[CFG_VRSE], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSE_STD] [%u]: ", sys_data.data_cfg[CFG_VRSE_STD]);
        edit_uint(&sys_data.data_cfg[CFG_VRSE_STD], 0, 5);
        uprintf("sys_data.data_cfg[CFG_CALC_PH_VRSE] [%u]: ", sys_data.data_cfg[CFG_CALC_PH_VRSE]);
        edit_uint(&sys_data.data_cfg[CFG_CALC_PH_VRSE], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSI_BIASED] [%u]: ", sys_data.data_cfg[CFG_VRSI_BIASED]);
        edit_uint(&sys_data.data_cfg[CFG_VRSI_BIASED], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSI_BIASED_STD] [%u]: ", sys_data.data_cfg[CFG_VRSI_BIASED_STD]);
        edit_uint(&sys_data.data_cfg[CFG_VRSI_BIASED_STD], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSE_BIASED] [%u]: ", sys_data.data_cfg[CFG_VRSE_BIASED]);
        edit_uint(&sys_data.data_cfg[CFG_VRSE_BIASED], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VRSE_BIASED_STD] [%u]: ", sys_data.data_cfg[CFG_VRSE_BIASED_STD]);
        edit_uint(&sys_data.data_cfg[CFG_VRSE_BIASED_STD], 0, 5);
        uprintf("sys_data.data_cfg[CFG_V_COUNTER_ELECT] [%u]: ", sys_data.data_cfg[CFG_V_COUNTER_ELECT]);
        edit_uint(&sys_data.data_cfg[CFG_V_COUNTER_ELECT], 0, 5);
        uprintf("sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD] [%u]: ", sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD]);
        edit_uint(&sys_data.data_cfg[CFG_V_COUNTER_ELECT_STD], 0, 5);
        uprintf("sys_data.data_cfg[CFG_I_COUNTER] [%u]: ", sys_data.data_cfg[CFG_I_COUNTER]);
        edit_uint(&sys_data.data_cfg[CFG_I_COUNTER], 0, 5);
        uprintf("sys_data.data_cfg[CFG_I_SUBSTRATE] [%u]: ", sys_data.data_cfg[CFG_I_SUBSTRATE]);
        edit_uint(&sys_data.data_cfg[CFG_I_SUBSTRATE], 0, 5);
        uprintf("sys_data.data_cfg[CFG_VIN_BAT_VOLT] [%u]: ", sys_data.data_cfg[CFG_VIN_BAT_VOLT]);
        edit_uint(&sys_data.data_cfg[CFG_VIN_BAT_VOLT], 0, 5);
        uprintf("sys_data.data_cfg[CFG_BIAS_BAT_POS] [%u]: ", sys_data.data_cfg[CFG_BIAS_BAT_POS]);
        edit_uint(&sys_data.data_cfg[CFG_BIAS_BAT_POS], 0, 5);
        uprintf("sys_data.data_cfg[CFG_BIAS_BAT_NEG] [%u]: ", sys_data.data_cfg[CFG_BIAS_BAT_NEG]);
        edit_uint(&sys_data.data_cfg[CFG_BIAS_BAT_NEG], 0, 5);
        uprintf("sys_data.data_cfg[CFG_BRD_TEMP] [%u]: ", sys_data.data_cfg[CFG_BRD_TEMP]);
        edit_uint(&sys_data.data_cfg[CFG_BRD_TEMP], 0, 5);
        uprintf("sys_data.data_cfg[CFG_BRD_HUMIDITY] [%u]: ", sys_data.data_cfg[CFG_BRD_HUMIDITY]);
        edit_uint(&sys_data.data_cfg[CFG_BRD_HUMIDITY], 0, 5);
        uprintf("sys_data.data_cfg[CFG_UART3_INST] [%u]: ", sys_data.data_cfg[CFG_UART3_INST]);
        edit_uint(&sys_data.data_cfg[CFG_UART3_INST], 0, 5);
        uprintf("sys_data.data_cfg[CFG_UART4_INST] [%u]: ", sys_data.data_cfg[CFG_UART4_INST]);
        edit_uint(&sys_data.data_cfg[CFG_UART4_INST], 0, 5);

        uprintf("sys_data.data_cfg[CFG_SPARE1] [%u]: ", sys_data.data_cfg[CFG_SPARE1]);    // was uprintf("sys_data.data_cfg[CFG_SPARE1] [%u]: ", sys_data.data_cfg[CFG_SPARE1]);
        edit_uint(&sys_data.data_cfg[CFG_SPARE1], 0, 5);
        uprintf("sys_data.data_cfg[CFG_SPARE2] [%u]: ", sys_data.data_cfg[CFG_SPARE2]);
        edit_uint(&sys_data.data_cfg[CFG_SPARE2], 0, 5);
        uprintf("sys_data.data_cfg[CFG_SPARE3] [%u]: ", sys_data.data_cfg[CFG_SPARE3]);
        edit_uint(&sys_data.data_cfg[CFG_SPARE3], 0, 5);
        uprintf("sys_data.data_cfg[CFG_SPARE4] [%u]: ", sys_data.data_cfg[CFG_SPARE4]);
        edit_uint(&sys_data.data_cfg[CFG_SPARE4], 0, 5);
        uprintf("sys_data.data_cfg[CFG_SPARE5] [%u]: ", sys_data.data_cfg[CFG_SPARE5]);
        edit_uint(&sys_data.data_cfg[CFG_SPARE5], 0, 5);
        uprintf("sys_data.data_cfg[CFG_SPARE6] [%u]: ", sys_data.data_cfg[CFG_SPARE6]);
        edit_uint(&sys_data.data_cfg[CFG_SPARE6], 0, 5);
        //uprintf("sys_data.data_cfg[] [%u]: ", sys_data.data_cfg[]);
        //edit_uint(&sys_data.data_cfg[], 0, 5);

        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }
    //----
    while(1)
    {
        uprintf("\r\nSixth batch of 8 sys_data fields:\r\n\r\n");

        // app cfg   MAX_NUMOF_APP_CONFIG_FIELDS
        uprintf("app_cfg[APPCFG_SAMPLING_DIAG] [%u]: ", sys_data.app_cfg[APPCFG_SAMPLING_DIAG]);
        edit_uint(&sys_data.app_cfg[APPCFG_SAMPLING_DIAG], 0, 500000);

        uprintf("app_cfg[APPCFG_TEMPC_SH_ALG] [%u]: ", sys_data.app_cfg[APPCFG_TEMPC_SH_ALG]);
        edit_uint(&sys_data.app_cfg[APPCFG_TEMPC_SH_ALG], 0, 500);

        uprintf("app_cfg[APPCFG_MICROSD_ENABLE] [%u]: ", sys_data.app_cfg[APPCFG_MICROSD_ENABLE]);
        edit_uint(&sys_data.app_cfg[APPCFG_MICROSD_ENABLE], 0, 5);
        //microSD_flg = sys_data.app_cfg[APPCFG_MICROSD_ENABLE];      // deprecated 6 Aug 2021

        uprintf("app_cfg[APPCFG_MENU_LEVEL] [%u]: ", sys_data.app_cfg[APPCFG_MENU_LEVEL]);
        edit_uint(&sys_data.app_cfg[APPCFG_MENU_LEVEL], 0, 500);

        uprintf("app_cfg[APPCFG_DEPLOY_UARTECHO] [%u]: ", sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO]);
        edit_uint(&sys_data.app_cfg[APPCFG_DEPLOY_UARTECHO], 0, 500);

        uprintf("app_cfg[APPCFG_EXEC_SWITCHERONI] [%u]: ", sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI]);
        edit_uint(&sys_data.app_cfg[APPCFG_EXEC_SWITCHERONI], 0, 500);

        // No edit for spare appcfg
        sys_data.app_cfg[APPCFG_SPARE6] = 0;
        sys_data.app_cfg[APPCFG_SPARE7] = 0;
        sys_data.app_cfg[APPCFG_SPARE8] = 0;
        sys_data.app_cfg[APPCFG_SPARE9] = 0;
        sys_data.app_cfg[APPCFG_SPARE10] = 0;
        sys_data.app_cfg[APPCFG_SPARE11] = 0;
        sys_data.app_cfg[APPCFG_SPARE12] = 0;
        sys_data.app_cfg[APPCFG_SPARE13] = 0;
        sys_data.app_cfg[APPCFG_SPARE14] = 0;
        sys_data.app_cfg[APPCFG_SPARE15] = 0;


        //uprintf("app_cfg[APPCFG_SPARE7] [%u]: ", sys_data.app_cfg[APPCFG_SPARE7]);
        //edit_uint(&sys_data.app_cfg[APPCFG_SPARE7], 0, 500);

        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }
    //----

    while(1)
    {
        uprintf("\r\nSeventh batch of 14 sys_data fields:\r\n\r\n");

        uprintf("GMT [%u]: ", sys_data.GMT);
        edit_uint(&sys_data.GMT, 0, 80);

        uprintf("sample_aligned [%u]: ", sys_data.sample_aligned);
        edit_uint(&sys_data.sample_aligned, 0, 80);

        sys_data.deploy_time = 0;
        uprintf("deploy_time [%u]: ", sys_data.deploy_time);
        edit_uint(&sys_data.deploy_time, 0, 80);

        sys_data.start_pump_time = ROM_HibernateRTCGet();
        uprintf("start_pump_time [%u]: ", sys_data.start_pump_time);
        edit_uint(&sys_data.start_pump_time, 0, 80);

        sys_samp.start_pump_cntdown = sys_data.start_pump_time - ROM_HibernateRTCGet();
        uprintf("start_pump_cntdown [%u]: ", sys_samp.start_pump_cntdown);
        edit_uint(&sys_samp.start_pump_cntdown, 0, 80);

        uprintf("diag [%u]: ", sys_data.diag);
        edit_uint(&sys_data.diag, 0, 80);

        uprintf("debug_flag [%u]: ", sys_data.debug_flag);
        edit_uint(&sys_data.debug_flag, 0, 80);
        dbg_flag = sys_data.debug_flag;

        uprintf("pHOffset [%.6f]: ", sys_data.pHOffset);
        edit_float(&sys_data.pHOffset, -1.0, 1.0);

        uprintf("pHSlope [%.6f]: ", sys_data.pHSlope);
        edit_float(&sys_data.pHSlope, -1.0, 1.0);

        uprintf("TCSlope [%.6f]: ", sys_data.TCSlope);
        edit_float(&sys_data.TCSlope, -1.0, 1.0);

        uprintf("sensor_ctd_TC [%.6f]: ", sys_data.sensor_ctd_TC);
        edit_float(&sys_data.sensor_ctd_TC, -1.0, 1.0);

        uprintf("sensor_optode_TC [%.6f]: ", sys_data.sensor_optode_TC);
        edit_float(&sys_data.sensor_optode_TC, -1.0, 1.0);

        uprintf("spare[0] [%.6f]: ", sys_data.spare[0]);
        edit_float(&sys_data.spare[0], -1.0, 1.0);

        uprintf("spare[1] [%.6f]: ", sys_data.spare[1]);
        edit_float(&sys_data.spare[1], -1.0, 1.0);

        uprintf("spare[2] [%.6f]: ", sys_data.spare[2]);
        edit_float(&sys_data.spare[2], -1.0, 1.0);

        uprintf("spare[3] [%.6f]: ", sys_data.spare[3]);
        edit_float(&sys_data.spare[3], -1.0, 1.0);


        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }
    //----

    // pump sequencer variables
    while(1)
    {
        uprintf("\r\nEighth batch of 7 sys_data fields:\r\n\r\n");

        //uint32_t pump_seq_type;             // 0) legacy single pump, 1) BEAMS v1 dual pump seq, 2) BEAMS v2

        uprintf("pump_seq_type [%u]: ", sys_data.pump_seq_type);
        edit_uint(&sys_data.pump_seq_type, 0, 80);

        //uint32_t sampleCnt_duty_on;         // duty cycle for extending experiment.   3 days on, 5 days off.   Number of 'sample periods' on
        uprintf("sampleCnt_duty_on [%u]: ", sys_data.sampleCnt_duty_on);
        edit_uint(&sys_data.sampleCnt_duty_on, 0, 80);

        //uint32_t sampleCnt_duty_off;        // in sample periods.    Accept input in hours, translate to sample periods (keep implementation simple for now).
        uprintf("sampleCnt_duty_off [%u]: ", sys_data.sampleCnt_duty_off);
        edit_uint(&sys_data.sampleCnt_duty_off, 0, 80);

        //uint32_t pump1_cycles;                   // = 10 cycles
        uprintf("pump1_cycles [%u]: ", sys_data.pump1_cycles);
        edit_uint(&sys_data.pump1_cycles, 0, 80);

        //uint32_t pump2_cycles;                   // = 5 cycles
        uprintf("pump2_cycles [%u]: ", sys_data.pump2_cycles);
        edit_uint(&sys_data.pump2_cycles, 0, 80);

        //uint32_t pump1_ontime;          //20 Active pump time;                 // = 30 cycles
        uprintf("pump1_ontime [%u]: ", sys_data.pump1_ontime);
        edit_uint(&sys_data.pump1_ontime, 0, 80);

        //uint32_t pump2_ontime;                 // = 10 cycles
        uprintf("pump2_ontime [%u]: ", sys_data.pump2_ontime);
        edit_uint(&sys_data.pump2_ontime, 0, 80);

        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;

    }




    while(1)
    {
        uprintf("\r\nNineth batch of 11 sys_data fields:\r\n\r\n");

        uprintf("Filename [%s]: ", sys_data.fileName);
        edit_string(&sys_data.fileName, MAX_FILENAME);
        //uprintf("  %s\r\n\r\n", sys_data.fileName);

        uprintf("User Initials [%s]: ", sys_data.user);
        edit_string(&sys_data.user, MAX_USER_INITIALS);

        uprintf("board_SN [%s]: ", sys_data.board_SN);
        edit_string(&sys_data.board_SN, MAX_BOARD_SN);

        uprintf("mcap_SN [%s]: ", sys_data.mcap_SN);
        edit_string(&sys_data.mcap_SN, MAX_MCAP_SN);

        uprintf("sensor_SN [%s]: ", sys_data.sensor_SN);
        edit_string(&sys_data.sensor_SN, MAX_SENSOR_SN);

        uprintf("package_name [%s]: ", sys_data.package_name);
        edit_string(&sys_data.package_name, MAX_PACKAGE_NAME);

        uprintf("optode_SN [%s]: ", sys_data.optode_SN);
        edit_string(&sys_data.optode_SN, MAX_OPTODE_SN);

        uprintf("ctd_SN [%s]: ", sys_data.ctd_SN);
        edit_string(&sys_data.ctd_SN, MAX_CTD_SN);

        uprintf("pump1_SN [%s]: ", sys_data.pump_SN);
        edit_string(&sys_data.pump_SN, MAX_PUMP_SN);

        uprintf("pump2_SN [%s]: ", sys_data.pump2_SN);
        edit_string(&sys_data.pump2_SN, MAX_PUMP_SN);

        uprintf("package_fab_note [%s]: ", sys_data.package_fab_note);
        edit_string(&sys_data.package_fab_note, MAX_BOARD_FABNOTE);

        uprintf("deploy_note [%s]: ", sys_data.deploy_note);
        edit_string(&sys_data.deploy_note, MAX_DEPLOY_NOTE);

        uprintf("\r\nOld firmware version: %s\r\n", sys_data.firmware_version);  //uprintf("\r\nOld firmware version: %s\r\n", sys_data.qa.firmware_version);
        uprintf("New firmware version: %s\r\n", VERSION);
        strcpy(sys_data.firmware_version, VERSION);   //strcpy(sys_data.qa.firmware_version, VERSION);

        uprintf("\r\nIf the old firmware version is corrupt or shifted, please re-run QA routine\r\n\r\n");

        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }

    while(1)
    {
        uprintf("\r\nTenth batch, Cal data, sys_data fields:\r\n\r\n");

        uprintf("cal_filename [%s]: ", sys_data.cal_filename);
        edit_string(&sys_data.cal_filename, MAX_CAL_FILENAME);
        //uprintf("cal_filename [%s]: ", sys_data.cal_filename);

        uprintf("sensor_SN [%s]: ", sys_data.sensor_SN);
        edit_string(&sys_data.sensor_SN, MAX_SENSOR_SN);
        //uprintf("sensor_SN [%s]: ", sys_data.sensor_SN);

        uprintf("isfet_SN [%s]: ", sys_data.isfet_SN);
        edit_string(&sys_data.isfet_SN, MAX_ISFET_SN);
        //uprintf("isfet_SN [%s]: ", sys_data.isfet_SN);

        uprintf("ise_SN [%s]: ", sys_data.ise_SN);
        edit_string(&sys_data.ise_SN, MAX_ISE_SN);
        //uprintf("ise_SN [%s]: ", sys_data.ise_SN);

        uprintf("PT_Cal_date [%s]: ", sys_data.PT_Cal_date);
        edit_string(&sys_data.PT_Cal_date, MAX_K0_CAL_DATE);
        //uprintf("PT_Cal_date [%s]: ", sys_data.PT_Cal_date);

        for(indx=0; indx<MAX_NUMOF_K2_CAL_FIELDS; indx++)
        {
            uprintf("Enter K2_C%u  [%e]: ", indx, sys_data.K2_Cal[indx]);
            edit_float(&sys_data.K2_Cal[indx], -500, 500);
            //uprintf("  K2_C%u  [%e]: ", indx, sys_data.K2_Cal[indx]);
        }

        for(indx=0; indx<MAX_NUMOF_FP_CAL_FIELDS; indx++)
        {
            uprintf("Enter Fp_%u  [%e]: ", indx, sys_data.fP_Cal[indx]);
            edit_float(&sys_data.fP_Cal[indx], -500, 500);
            //uprintf("  Fp_%u  [%e]: ", indx, sys_data.fP_Cal[indx]);
        }

        uprintf("Enter k0_HCL  [%e]: ", sys_data.k0_HCL);
        edit_float(&sys_data.k0_HCL, -500, 500);
        //uprintf("  k0_HCL  [%e]: ", sys_data.k0_HCL);

        uprintf("Enter k0_SW  [%e]: ", sys_data.k0_SW);
        edit_float(&sys_data.k0_SW, -500, 500);
        //uprintf("  k0_SW  [%e]: ", sys_data.k0_SW);

        uprintf("Enter k0std_SW  [%e]: ", sys_data.k0std_SW);
        edit_float(&sys_data.k0std_SW, -500, 500);
        //uprintf("  k0std_SW  [%e]: ", sys_data.k0std_SW);

        uprintf("k0_Cal_date [%s]: ", sys_data.k0_Cal_date);
        edit_string(&sys_data.k0_Cal_date, MAX_K0_CAL_DATE);
        //uprintf("k0_Cal_date [%s]: ", sys_data.k0_Cal_date);

        uprintf("service_date [%s]: ", sys_data.service_date);
        edit_string(&sys_data.service_date, MAX_SERVICE_DATE);
        //uprintf("service_date [%s]: ", sys_data.service_date);


        response = yesOrNoMenuChoice("\r\n\r\nRe-visit? (Y/N) [N]? ", NO);
        if(response == NO)
            break;
    }



    uprintf("\r\nEEPROM sys_data copy/edit is complete\r\n\r\n");

    //uprintf(" [%s]: ", sys_data.);
    //edit_string(&sys_data., MAX);

    //uprintf(" [%.6f]: ", sys_data.);
    //edit_float(&sys_data., -1.0, 1.0);

    //uprintf(" [%u]: ", sys_data.);
    //edit_uint(&sys_data., 0, 80);
    //print_sys_data_structure();

    storeSysDataVariables();

}
