/*
 * MBARI software for MFET and SeaFET boards, derived from Scripps Institute
 *     SeapHOx software for Rev-E PC board Version 2.0
 *
 * David Muller, davehmuller@gmail.com
 * Germán Alfaro, alfaro.germanevera@gmail.com
 * Rob Glatts, rglatts@ucsd.edu (from 4/2014)
 * Taylor Wirth, twirth@ucsd.edu (from 4/2015)
 *
 * Thom Maughan (TM), MBARI, tm@mbari.org (from 2/2018)
 */

#include "System.h"
#include "Init.h"
#include "IO.h"
#include "SDCard.h"
#include "fatfs/src/ff.h"
#include "ADS1248_iso.h"
#include "ADS1248_noniso.h"
#include "Sleep.h"
#include "AUX1.h"
#include "AUX2.h"
#include "uartstdio.h"	// User local version with larger RX buffer

// Force a compile error if more than one board is =1
#if (BOARD_SEAFET==1 && BOARD_MFET==1) || (BOARD_SEAFET==0 && BOARD_MFET==0)
    PROBLEM  Right click project->properties, Build->Compiler->Predefine Symbols and define only one BOARD_XXX=1
#endif

/*
 * Global System variables.
 */
struct systemData sys_data;

    //sys_data.press_full_scale = 100;
    //sys_data.Vint_gain = 1;
    //sys_data.Vint_sps = 20;


void configuration(void);
void test(void);
void deploy(deploy_state state);

extern void ADS1248_gpio2(uint32_t state);
extern void ADS1248_gpio2_test(void);


extern uint16_t read_adc_temperature(void);
extern uint16_t read_adc(uint32_t chan);
void test_24bit_adc_mux(void);
extern void ADS1248_gpio_ADG1609_mux(uint32_t chan);
extern unsigned long Timer_10ms(bool reset);

void adc_onchip_init(void);
uint16_t * read_all_adc(void);
void state_dump(void);

unsigned int iso_flag = 1;
int dbg_flag = 0;                 // global var used for dbg_printf

extern uint32_t adc_data[];
/*
 * main.c
 */


int main(void)
{
	char input;
	time_t timer;

	Init();		// Initialize pins and ports

	// NOTE: ADS1248_gpio_init() is not called until after openADS1248_iso power supply is turned on

	// testing ADS1248_gpio2
	//ADS1248_gpio2_test();


	// Symbols for board builds are define in Project Properties (right click project, Select properties,
	// then select Build->ARM Compiler->Predefined Symbols.  Edit the BOARD_XXX and define = 1.  Only 1 board
	// should be =1, the deselected board is =0
#if BOARD_SEAFET == 1
    dbg_printf("\n***** BOARD_SEAFET = 1 *****\n");
#endif
#if BOARD_MFET == 1
    dbg_printf("\n***** BOARD_MFET = 1 *****\n");
#endif

    if( sys_data.state == IDLE)
    {
        dbg_printf("\nstate = IDLE\n");
    }
    if(sys_data.state == DEPLOYED)
    {
        dbg_printf("\nstate = DEPLOYED\n");
    }
    if( sys_data.state == COMMAND)
    {
        dbg_printf("\nstate = COMMAND\n");
    }

	// when you upload a new program, it goes straight into deplyoment.YT 4/29/2015 fix later.
	if(sys_data.state == DEPLOYED)
	{
        dbg_printf("\ncalling deploy(DEPLOYED)\n");
	    deploy(DEPLOYED);
	    //state_dump();       // DEBUG
	}

	if( sys_data.state == COMMAND)
	{
        dbg_printf("\ncalling deploy(COMMAND)\n");
	    deploy(COMMAND);

	}





	while(1) //added while loop for user to choose command or enter deployment automatically --1/24/2017 -TW
		{
		uprintf("\n*****Press enter to bring up main menu*****\n");

        // Else must be IDLE mode
        while(1)
        {
            // Get user's selection with a 30 sec timeout - enter deployment mode --1/24/2017 -TW
            UARTFlushRx();
            timer = 30 + ROM_HibernateRTCGet(); // 30 second delay | timer = 300 + ROM_HibernateRTCGet();

            while(1)
            {
                if( UARTRxBytesAvail() )
                {
                    input = get_key();
                    break;    // break from while(1)
                }
                if( timer <= ROM_HibernateRTCGet() )
                {
                    dbg_printf("\n***** D E P L O Y *****\n");  // THOM DEBUG

                     deploy(START); //enter deployment mode | if( timer <= ROM_HibernateRTCGet() ) sleep(IDLE, 0);
                }
            }


            // Print out the menu:
            uprintf("\n\n\nMain Menu--SeaFET/MFET %s  -- Will deploy in 30 seconds", VERSION);      // VERSION is defd in system.h
            uprintf("\n1 -- Configure");
            uprintf("\n2 -- Deploy");
            uprintf("\n3 -- Test");
            uprintf("\n4 -- Sleep");
            uprintf("\n5 -- Files");
            uprintf("\nEnter Selection: ");

            switch(input)
            {
                case '1':
                    configuration();
                    break;

                case '2':
                    deploy(START);
                    break;

                case '3':
                    test();
                    break;

                case '4':
                    sleep(IDLE, 0);
                    break;

                case '5':
                    viewFiles();
                    break;

                case '6':
					if(dbg_flag == 1)
	                    state_dump();
                    break;

                case '7':
					if(dbg_flag == 1)				
	                    sleep(COMMAND, 0);
                    break;

                default:
                    break;


            }
        }
    }
}

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

	while(1)
	{
		//print out config menu
		uprintf("\n\n\nConfiguration Menu--SeaFET/SeapHOx %s", VERSION);
		uprintf("\n1 -- Set Clock");
		uprintf("\n2 -- Change File Name");
		uprintf("\n3 -- Set Deployment Parameters");
		uprintf("\n4 -- Enter pH Sensor Calibration Coefficients");
		uprintf("\n5 -- Calculate pH Sensor Calibration Coefficients");
		uprintf("\n9 -- Exit to Main Menu");
		uprintf("\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 'd':
                uprintf("\ndbg_flag = 0   OFF\n");
                dbg_flag = 0;
                break;
            case 'D':
                uprintf("\ndbg_flag = 1   ON\n");
                dbg_flag = 1;
                break;
			case '1':  // Set Clock
				response = yesOrNoMenuChoice("\n\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("\nTime now: ");
					printCurrentTime();
					if(sys_data.GMT) uprintf(" GMT");
					else uprintf(" Local");
					uprintf("\n\nNote: Daylight Savings not observed. Use GMT when this will be an issue.\n");
				}
				break;

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

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

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

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

				// Sample period
				//response = yesOrNoMenuChoice("\n\nSample aligned to hour? (Y/N) [Y]? ", YES);
				response = yesOrNoMenuChoice("\n\nSample aligned to hour? (Y/N) [Y]? ", sys_data.sample_aligned);  // THOM New 7 May 2018
				if(response == YES)	sys_data.sample_aligned = true;
				else sys_data.sample_aligned = false;

				while(1)
				{
					uprintf("\n\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("\nSample period is zero - polled mode\n");
						    }
						    //else
						    //{

                                if(sys_data.sample_aligned)		// Sample aligned to hour?
                                {
                                    if(3600 % temp)
                                    {
                                        uprintf("\nSample period must evenly divide hour (e.g. 5, 10, 15, 20, 30 minutes)");
                                        continue;
                                    }
                                }

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

                                continue;
                            }
                            else break;
                        //} // if (sscanf...)
					}
					else break;
				}

				// Sample average
				while(1)
				{
					uprintf("\nEnter pH sample average [%d] samples: ", sys_data.sample_average);
					if(getUserInput(buff, 20))
					{
						if(sscanf(buff, "%d", &temp) == 1)
						{
							if(temp <= 100)
							{
								sys_data.sample_average = temp;
								uprintf("\npH sample average now %d.\n\n", sys_data.sample_average);
								break;
							}
							else uprintf("\nEnter value less than 100");
							continue;
						}
						else break;
					}
					else break;
				}

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

				// Low battery voltage
				while(1)
					{
						sprintf(buff, "\nEnter low battery_voltage (10.5 V for SeapHOx, 5.5 V for SeaFET) [%.1f V]: ", sys_data.low_batt_volt);
						uprintf("%s", buff);
						if(getUserInput(buff, 20))
						{
							if(sscanf(buff, "%f", &ftemp) == 1)
							{
								if(ftemp >= 0 && ftemp <= 30)
								{
									sys_data.low_batt_volt = ftemp;
									sprintf(buff, "\nLow battery_voltage now [%.1f V]\n\n", sys_data.low_batt_volt);
									uprintf("%s", buff);
								break;
								}
								else uprintf("\nEnter voltage less than 30 V");
								continue;
							}
							else break;
						}
							else break;
					}


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

				input = get_key();

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

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

				}
				break;

			float ftemp;
			case '4': //Enter pH Sensor Calibration Coefficients
				//Eo_int_25
				while(1)
				{
				// a good default is -0.4
				sprintf(buff, "\nEnter E0_int @ 25 C [%f]: ", sys_data.Eo_int_25C);
				uprintf("%s", buff);
				if(getUserInput(buff, 20))
				{
					if(sscanf(buff, "%f", &ftemp) == 1)
					{
						if(ftemp >= (-2) && ftemp <= 2)
						{
							sys_data.Eo_int_25C = ftemp;
							break;
						}
						else uprintf("Enter number between -2 and 2\n\n");
						continue;
					}
				else break;
				}
				else break;
				}


				//Eo_ext_25
				while(1)
				{
				    // a good default is -1.3
				sprintf(buff, "\nEnter E0_ext @ 25 C [%f]: ", sys_data.Eo_ext_25C);
				uprintf("%s", buff);
				if(getUserInput(buff, 20))
				{
					if(sscanf(buff, "%f", &ftemp) == 1)
					{
						if(ftemp >= (-2) && ftemp <= 2)
						{
							sys_data.Eo_ext_25C = ftemp;
							break;
						}
						else uprintf("Enter number between -2 and 2\n\n");
						continue;
					}
					else break;
					}
				else break;
				}

				//TCOffset, standard = 0
				while(1)
				{
				    // default of zero is ok
				sprintf(buff, "\nEnter TCOffset [%f]: ", sys_data.TCOffset);
				uprintf("%s", buff);
				if(getUserInput(buff, 20))
				{
					if(sscanf(buff, "%f", &ftemp) == 1)
					{
						if(ftemp >= (-2) && ftemp <= 2)
						{
							sys_data.TCOffset = ftemp;
							break;
						}
						else uprintf("Enter 0.0\n\n");
						continue;
					}
					else break;

					}
					else break;
				}

			uprintf("\n*****Calibration Coefficients Saved*****\n\n");
			break;

			case '5': //Calculate pH Sensor Calibration Coeffcients

				ph_calib();
				break;

			case '8': // Hidden menu option to change sensor name.
				uprintf("\n\nFactory settings. Enter password: ");

				// Compare user input with password
				if( getUserInput(buff, 10) )
				{
					if( strcmp("martzlab", buff) != 0 )
					    break;       // if strings are equal, return 0
					//if( strcmp("takeshita", buff) ) break;
				}
				else
				    break;

				// Sensor name
				uprintf("\n\nEnter sensor name [%s]: ", sys_data.sensor_name);
				if( getUserInput(buff, 30) )
				{
					strcpy(sys_data.sensor_name, buff);
					uprintf("Sensor name now: %s\n\n", sys_data.sensor_name);
				}

				// DuraFET serial #
				uprintf("\nEnter Durafet serial number [%s]: ", sys_data.durafet_SN);
				if( getUserInput(buff, 30) )
				{
					strcpy(sys_data.durafet_SN, buff);
					uprintf("Durafet serial number now: %s\n\n", sys_data.durafet_SN);
				}

				// Cap adapter serial #
				uprintf("\nEnter CAP adapter serial number [%s]: ", sys_data.capadap_SN);
				if( getUserInput(buff, 30) )
				{
					strcpy(sys_data.capadap_SN, buff);
					uprintf("CAP adapter serial number now: %s\n\n", sys_data.capadap_SN);
				}

				// ISE serial #
				uprintf("\nEnter ISE serial number [%s]: ", sys_data.ISE_SN);
				if( getUserInput(buff, 30) )
				{
					strcpy(sys_data.ISE_SN, buff);
					uprintf("ISE serial number now: %s\n\n", sys_data.ISE_SN);
				}

				// Microcat serial #
				uprintf("\nEnter Microcat serial number [%s]: ", sys_data.microcat_SN);
				if( getUserInput(buff, 30) )
				{
					strcpy(sys_data.microcat_SN, buff);
					uprintf("Microcat serial number now: %s\n\n", sys_data.microcat_SN);
				}

				// Pump serial #
				uprintf("\nEnter pump serial number [%s]: ", sys_data.pump_SN);
				if( getUserInput(buff, 30) )
				{
					strcpy(sys_data.pump_SN, buff);
					uprintf("Pump serial number now: %s\n\n", sys_data.pump_SN);
				}

				// Pressure sensor full scale
				while(1)
				{
					uprintf("\nEnter pressure sensor full-scale [%d] psi: ", sys_data.press_full_scale);
					if(getUserInput(buff, 20))
					{
						if(sscanf(buff, "%d", &temp) == 1)
						{
							if(temp == 100 || temp == 300)
							{
								sys_data.press_full_scale = temp;
								uprintf("\nPressure sensor full-scale now %d psi\n\n", sys_data.press_full_scale);
								break;
							}
							else uprintf("\nEnter 100 or 300");
							continue;
						}
						else break;
					}
					else break;
				}

				// pH Vint gain setting
				while(1)
				{
					uprintf("\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("\npH Vint gain now %d\n\n", sys_data.Vint_gain);
								break;
							}
							else uprintf("\nEnter 1, 2, 4, 8, 16, or 32");
							continue;
						}
						else break;
					}
					else break;
				}

				// pH Vint gain setting
				while(1)
				{
					uprintf("\nEnter pH Vint sample rate setting [%d]: ", sys_data.Vint_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.Vint_sps = temp;
								uprintf("\npH Vint data rate now %d sps\n\n", sys_data.Vint_sps);
								break;
							}
							else uprintf("\nEnter 5, 10, 20, 40, 80, 160, 320, 640, 1000, or 2000");
							continue;
						}
						else break;
					}
					else break;
				}

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



/*************************************************************************************************************************
 * Test menu.
 *************************************************************************************************************************/
void test(void)
{
	char input;
	float ADCResult, TC, ADCvolts, fVbat, fOnChipTemp, fExtTemp, fPressure;
	uint32_t  uiPressure, uiHumidity, uiWater;
	int32_t charInput;
	int response;
	time_t timer;
	bool pump_on = false, AUX1_on = false, AUX2_on = false;

	uint32_t indx = 0;

	// Test menu loop
	while(1)
	{
		uprintf("\n\n\nTest Menu--SeaFET/SeapHOx %s\n", VERSION);
		uprintf("1 -- Display Battery, Internal Temp, Pressure\n");
		uprintf("2 -- Display pH Sensor Data\n");
		uprintf("3 -- Communicate with Instrument\n");
		uprintf("4 -- Pump ON/OFF\n");
		uprintf("5 -- AUX1 ON/OFF\n");
		uprintf("6 -- AUX2 ON/OFF\n");
#if BOARD_MFET==1
		uprintf("7 -- Internal Environment Sensors\n");
        uprintf("8 -- Test 24bit ADC and MUX - GOOD FOR BOARD BRINGUP\n");
#endif
		uprintf("9 -- Exit to Main Menu\n");
		uprintf("\nEnter Selection: ");

		UARTFlushRx();
		timer = 30000 + ROM_HibernateRTCGet();

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

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

		switch(input)
		{
            case 'i':
                iso_flag = 0;
                uprintf("\n\nIso is Disabled during 'S' - sample all\n\n");
                break;

            case 'I':
                iso_flag = 1;
                uprintf("\n\nIso is Enabled during 'S' - sample all\n\n");
                break;

			case '1': //Read Voltages from ADC on Non-isolated side.
				openADS1248_noniso();
				pressureOn();			// Turn on 5V to pressure sensor

				while(!UARTRxBytesAvail())
				{
					// Main battery voltage
					uprintf("\n\n\nMain Battery = %.3f V", batt_volt());

					// Internal temperature
					uprintf("\n\nController Temp = %.3f C", controller_temp());

					// Depth
					uprintf("\n\nPressure = %.3f dBar\n", pressure());
					ADCvolts = pollADS1248_noniso(3, 7, 1);
					uprintf("Raw Voltage = %.3f V\n", ADCvolts);
					ROM_SysCtlDelay(MILLISECOND*3000);
				}

				pressureOff();
				closeADS1248_noniso();
				break;

			case '2': //Read Voltages from the isolated ADC
			    // THOM new (turn on iso power)

			    //ROM_GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_2, 0xFF);        // Iso-power On (NOT NEEDED, DONE IN openADS)

				openADS1248_iso();

				ROM_SysCtlDelay(MILLISECOND * 1000);	// Let electronics settle

                ADCResult = pollADS1248_iso(0, 6, sys_data.sample_average, 1, 5);       // Chan 0-6, trials = 1, gain = user, sps = 5 Hz
                TC = DuraFET_temp(ADCResult,0);
                uprintf("\n\n\nVtherm = %.6f V \nTC = %2.6f\n", ADCResult, TC);



//#ifdef NOCODE
				while(!UARTRxBytesAvail())  // Code faults into 'loader_exit' on this statment
//				while(1)
				{
					//get Vtherm voltage
					ADCResult = pollADS1248_iso(0, 6, sys_data.sample_average, 1, 5);		// Chan 0-6, trials = 1, gain = user, sps = 5 Hz
					TC = DuraFET_temp(ADCResult,0);
					uprintf("\n\n\nVtherm = %.6f V \nTC = %2.6f\n", ADCResult, TC);

					//get Vint voltage
					ADCResult = pollADS1248_iso(1, 6, sys_data.sample_average, sys_data.Vint_gain, sys_data.Vint_sps);
					uprintf("\nVint = %.6f V\nEstimated pHint = %2.6f\n", ADCResult, calc_pHint(ADCResult, TC));

					//get Aux_Ref voltage
					ADCResult = pollADS1248_iso(4, 6, sys_data.sample_average, 1, 5);
					uprintf("\nAux_Ref = %.6f V\nEstimated pHext (S= 35) = %2.6f\n", ADCResult, calc_pHext(ADCResult, TC, 35));

					//get Isolated Battery voltage
					uprintf("\nIsolated Battery = %.6f V\n", batt_volt_iso());

					//get voltage b/w Ik+ Ik-
					ADCResult = pollADS1248_iso(3, 2, 1, 1, 5);				// Chan 3-2, trials = 1, gain = 1, sps = 5 Hz
					uprintf("\nVoltage b/w Ik+ Ik- = %.6f V\n", ADCResult);

					//get Ib+ voltage
					ADCResult = pollADS1248_iso(7, 6, 1, 1, 5);				// Chan 7-6, trials = 1, gain = 1, sps = 5 Hz
					uprintf("\nIb+ = %.6f V\n", ADCResult);

					ROM_SysCtlDelay(MILLISECOND*3000);
				}
//#endif
				//close the isolated ADC
				closeADS1248_iso();
				break;

			case '3': //Communicate with Instruments
				while(1)
				{
					uprintf("\n\n\nMicroCAT and Optode Peripheral Communication Menu\n");
					uprintf("1 -- MicroCAT\n");
					uprintf("2 -- Optode\n");
					uprintf("3 -- AUX 1\n");
					uprintf("4 -- AUX 2\n");
					uprintf("9 -- Exit\n");
					uprintf("\nEnter peripheral device selection[9]: ");

					input = get_key();
					switch(input)
					{
						case '1':  // MicroCAT
							UARTEchoSet(false);	// Disable console echo for MicroCAT
							uprintf("\n\n*Press CTRL-X to stop communicating with the MicroCAT.*\n\n");

							//set up the MicroCAT
							openMicroCAT();

							while(1)
							{
								//if MicroCAT sent anything, print it out on UART1 (the desktop)
								if( MicroCAT_UARTRxBytesAvail() )
								{
									uprintf( "%c", MicroCAT_UARTgetc() );
								}

								//if user types anything, send it to the MicroCAT--exit on CTRL-X
								if(UARTRxBytesAvail())
								{
									charInput = UARTgetc();

									if(charInput == 24)
									{
										break;
									}

									MicroCAT_putc(charInput);
								}
							}


							//close up the MicroCAT
							closeMicroCAT();
							UARTEchoSet(true);	// Enable console echo
							break;


						case '2': // Optode
							uprintf("\n\n*Press CTRL-X to stop communicating with the Optode.*\n\n");

							//set up the optode
							openOptode();

							while(1)
							{
								//if Optode sent anything, print it out on UART1 (the desktop)
								if( Optode_UARTRxBytesAvail() )
								{
									uprintf( "%c", Optode_UARTgetc() );
								}

								//if user types anything, send it to the Optode--exit on CTRL-X
								if(UARTRxBytesAvail())
								{
									charInput = UARTgetc();

									if(charInput == 13)		// If user hit carriage return, add a line feed
									{
										Optode_putc(charInput);	// CR
										Optode_putc(10);		// LF
									}
									else if(charInput == 24) break;
									else( Optode_putc(charInput) );
								}
							}

							closeOptode();	// Close up the Optode
							break;

						case '3': // AUX 1
							uprintf("\n\n*Press CTRL-X to stop communicating with AUX 1.*\n\n");
							UARTFlushTx(0);
							UARTEchoSet(0);		// Disable echo. Set to 1 to enable
							Open_AUX1();

							while(1)
							{
								//if AUX1 sent anything, print it out on UART1 (the desktop)
								if(ROM_UARTCharsAvail(UART2_BASE))
								{
									uprintf("%c", ROM_UARTCharGet(UART2_BASE));
								}

								//if user types anything, send it to the AUX1--exit on CTRL-X
								if(UARTRxBytesAvail())
								{
									charInput = UARTgetc();

									if(charInput == 24)
									{
										break;
									}

									ROM_UARTCharPut(UART2_BASE, charInput);
								}
							}

							Close_AUX1();
							UARTEchoSet(1);
							break;

						case '4': // AUX 2
							uprintf("\n\n*Press CTRL-X to stop communicating with AUX 2.*\n\n");
							UARTFlushTx(0);
							UARTEchoSet(0);		// Disable echo. Set to 1 to enable
							Open_AUX2();

							while(1)
							{
								//if AUX1 sent anything, print it out on UART1 (the desktop)
								if(ROM_UARTCharsAvail(UART5_BASE))
								{
									uprintf("%c", ROM_UARTCharGet(UART5_BASE));
								}

								//if user types anything, send it to the AUX1--exit on CTRL-X
								if(UARTRxBytesAvail())
								{
									charInput = UARTgetc();

									if(charInput == 24)
									{
										break;
									}

									ROM_UARTCharPut(UART5_BASE, charInput);
								}
							}

							Close_AUX2();
							UARTEchoSet(1);
							break;

						default: //Exit
							return;
					}
				}

			case '4':  // Pump ON/OFF
				if(pump_on)
				{
					pump_off();
					pump_on = false;
					uprintf("\n\nPump off\n");
				}
				else
				{
					response = yesOrNoMenuChoice("\n\nIs pump immersed in water? (Y/N) [N]? ", NO);
					if(response == YES)
					{
						pump_on();
						pump_on = true;
						uprintf("\n\nPump on...\n");
					}
				}
				break;

			case '5':  // AUX1 ON/OFF
				if(AUX1_on)
				{
					AUX1_off();
					AUX1_on = false;
					uprintf("\n\nAUX1 off\n");
				}
				else
				{
					AUX1_on();
					AUX1_on = true;
					uprintf("\n\nAUX1 on...\n");
				}
				break;

			case '6':  // AUX2 ON/OFF
				if(AUX2_on)
				{
					AUX2_off();
					AUX2_on = false;
					uprintf("\n\nAUX2 off\n");
				}
				else
				{
					AUX2_on();
					AUX2_on = true;
					uprintf("\n\nAUX2 on...\n");
				}
				break;
#if BOARD_MFET==1
			case '7':
			    // THOMz world
			    uprintf("\n\n\n");

                indx = 0;
                ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_7, 0xFF);    // Turn on Load switch for ENV monitoring
                ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, 0xFF);   // Turn on VBat monitoring

                ROM_GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_2, 0xFF);        // Iso-power On
                uprintf("iso power on\n");

                adc_onchip_init();
                while(1)
                {
                    //float ADCResult, TC, ADCvolts, fVbat, fOnChipTemp, fExtTemp;
                    //uint32_t  TempValueC, uiPressure, uiHumidity, uiWater;

                    read_all_adc();

                    fVbat = (float)(adc_data[0]*100);
                    fVbat /= 18687.707;

                    // onchip temperature (formulae from TI example code)
                    //TempValueC = (uint32_t)(147.5 - ((75.0*3.3 *(float)adc_data[7])) / 4096.0);
                    fOnChipTemp = (147.5 - ((75.0*3.3 *(float)adc_data[7])) / 4096.0);

                    // LM60 temperature sensor - formula from datasheet / schematic (good job Scott)
                    // Vout = (+6.25 mV/C * T) + 424mV   =>  T = ((ADCcnt * 0.80566) - 424) / 6.25
                    fExtTemp = ((((float)adc_data[4])*0.80566) - 424) / 6.25;

                    // Water sensor - convert to percent
                    uiWater = (adc_data[3] * 100) / 2596;    // NOTE: Water voltage adc cnts is 2622 when pulled to 3.3v  (measured at 2.1092v on test point with agilent u1272a meter)
                    if(uiWater > 100)
                        uiWater = 100;

                    // Humidity
                    uiHumidity = (adc_data[2] * 100) / 3284;

                    // Pressure
                    uiPressure = adc_data[1];
                    fPressure = (float)uiPressure;   //2020x = 14.70psi     (From scotts schematic0.33V = 0psia, 3.0V = 30psia)
                    fPressure *= 0.0072772;

                    //uprintf("Bat = %6.2fV VBAT=%u VPRESS=%3u  VHUM=%3u  VWATER=%3u   VXTEMP=%3u   VBAT=%3u, VBAT=%u, VTEMP=%u  i=%u\r", fVbat, adc_data[0], adc_data[1], adc_data[2], adc_data[3], adc_data[4], adc_data[5], adc_data[6], TempValueC, indx++);
                    uprintf("Bat = %6.2fV Pressure = %5.1f  Humidity = %3u  Water = %3u  Temperature = %5.1fC (%4u)   ChipTemp = %5.1fC  i=%u\r", fVbat, fPressure, uiHumidity, uiWater, fExtTemp, adc_data[4], fOnChipTemp, indx++);

                    ROM_SysCtlDelay(MILLISECOND * 500);

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

                ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, 0x00);   // Turn off VBat monitoring
                ROM_GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_2, 0x00);        // Iso-power Off
                uprintf("iso power off, vbat monitoring off\n");
			    break;

			case '8':
			    test_24bit_adc_mux();
			    break;
#endif   // if MFET==1

			default: //Exit
				uprintf("\nPress enter to bring up main menu\n");
				return;

		}
	}
}

void test_24bit_adc_mux(void)
{
    char input;
    float ADCResult;
    uint32_t indx = 0;
    time_t timer;
    int sampleCnt;
    unsigned long sampTime;
    unsigned long nextTime;
    unsigned long sampDelay;

    uprintf("\nOpen isolated ADS1248 and ADG1609 mux\n\n");
    ROM_SysCtlDelay(MILLISECOND * 100);
    openADS1248_iso();
    if(iso_flag == 1)
    {
        uprintf("\niso_flag == 1\n\n");
    }
    else
        uprintf("\niso_flag == 0\n\n");
    ADS1248_gpio_init();    // defd in ADS1248_iso.c

    ROM_SysCtlDelay(MILLISECOND * 100);

    sampleCnt = 10;
    sampDelay = 200L;   // 500 is 5 seconds using 10ms tick

    // Test menu loop
    while(1)
    {
        uprintf("\n\n\nTest pH (24bit ADC Mux) Menu\n");
        uprintf("0 -- Ext Ref with Offset\n");
        uprintf("1 -- Int Ref with Offset\n");
        uprintf("2 -- Ext Ref Voltage\n");          // Counter A and Counter B are current measurement Counter Electrode
        uprintf("3 -- Int Ref Voltage\n");
        uprintf("4 -- Counter Electrode Current\n");
        uprintf("5 -- Counter Electrode Voltage\n");
        uprintf("6 -- Substrate Current\n");
        uprintf("7 -- Substrate Voltage\n");
        uprintf("8 -- Thermistor ISFET Temperature\n");
        uprintf("S -- Sample all channels (0-8)\n");
        uprintf("9 -- Exit to Main Menu\n");
        uprintf("\nEnter Selection: ");



        UARTFlushRx();
        timer = 30000 + ROM_HibernateRTCGet();

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

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

        switch(input)
        {

            case 'a':
                uprintf("mux = 00\n");
                ADS1248_gpio_ADG1609_mux(0);
                break;
            case 'b':
                uprintf("mux = 01\n");
                ADS1248_gpio_ADG1609_mux(1);
                break;
            case 'c':
                uprintf("mux = 10\n");
                ADS1248_gpio_ADG1609_mux(2);
                break;
            case 'd':
                uprintf("mux = 11\n");
                ADS1248_gpio_ADG1609_mux(3);
                break;
            case 'e':
                ADS1248_gpio2(0);
                break;
            case 'E':
                ADS1248_gpio2(1);

                break;

            case 'S':
            case 's':
                sampDelay = 500L;
                //   Date Time,    Ext Ref Off, Int Ref Off, Ext Ref V, Int Ref V, CntrE Cur, CntrE Volt, Subst Cur, Subst Vol, Therm
                //04/20/18 19:00:24, -0.326934, -0.326969, 0.670350, 0.670312, 0.326919, -0.670372, -0.670333, -0.997410

                uprintf("\n\n    Date Time,   Ext Ref Off, Int Ref Off, Ext Ref V, Int Ref V, CntrE Cur, CntrE Volt,  Subst Cur,  Subst Vol,  Thermistor\n");

                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;

                        // Date Time,
                        printCurrentTime();

                        uprintf(", ");

                        //Ext Ref Off,
                        ADS1248_gpio_ADG1609_mux(0);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        //ADCResult = pollADS1248_iso(5, 1, sampleCnt, 1, 20);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 5, sampleCnt, 1, 20);       // Chan +1 -5, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult); // Ext Ref with Offset

                        //Int Ref Off,
                        ADS1248_gpio_ADG1609_mux(3);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        //ADCResult = pollADS1248_iso(5, 1, sampleCnt, 1, 20);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 5, sampleCnt, 1, 20);       // Chan +1 -5, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult); // Int Ref with Offset  // uprintf("Int Ref Offset = %.6f V,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);

                        //Ext Ref V,
                        //uprintf("Mux = 00,  AIN6+ AIN1-\n");
                        ADS1248_gpio_ADG1609_mux(0);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        //ADCResult = pollADS1248_iso(6, 1, sampleCnt, 1, 5);       // Chan +6 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +1 -6, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult);       // Ext Ref Voltage

                        // Int Ref V,
                        //uprintf("Mux = 11,  AIN6+ AIN1-\n");
                        ADS1248_gpio_ADG1609_mux(3);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        //ADCResult = pollADS1248_iso(6, 1, sampleCnt, 1, 5);       // Chan +6 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +1 -6, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult);       // Int Ref Voltage

                        //CntrE Cur,
                        //uprintf("4 -- Counter Electrode Current\n");
                        //uprintf("Mux = 01,  AIN1+ AIN5-\n");
                        ADS1248_gpio_ADG1609_mux(1);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        ADCResult = pollADS1248_iso(1, 5, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult);       // Counter Electrode Current

                        // CntrE Volt,
                        //uprintf("5 -- Counter Electrode Voltage\n");
                        //uprintf("Mux = 01,  AIN1+ AIN6-\n");
                        ADS1248_gpio_ADG1609_mux(1);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult);       // Counter Electrode Voltage

                        // Subst Cur,
                        //uprintf("6 -- Substrate Current\n");
                        //uprintf("Mux = 10,  AIN1+ AIN6-\n");
                        ADS1248_gpio_ADG1609_mux(2);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult);       // Substrate Current

                        // Subst Vol,
                        //uprintf("7 -- Substrate Voltage\n");
                        //uprintf("Mux = 10,  AIN5+ AIN6-\n");
                        ADS1248_gpio_ADG1609_mux(2);
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        ADCResult = pollADS1248_iso(5, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f, ", ADCResult);       // Substrate Voltage

                        // Thermistor
                        //uprintf("8 -- Thermistor ISFET Temperature\n");
                        //uprintf("Mux = XX,  AIN0+ AIN6-\n");
                        ADS1248_gpio_ADG1609_mux(0);        // Not necessary, but consistent
                        ROM_SysCtlDelay(MILLISECOND * 10);      // 10msec settling for MUX analog
                        ADCResult = pollADS1248_iso(0, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf(" %.6f", ADCResult);       // Substrate Voltage

                        uprintf("\n");


                    }

                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                    //ROM_SysCtlDelay(MILLISECOND * 2000);
                }
                break;



            case '0':
                sampDelay = 200L;
                //uprintf("0 -- Ext Ref with Offset\n");
                uprintf("0 -- Ext Ref with Offset,  Mux = 00,  AIN1+ AIN5-\n");
                //uprintf("\n\n1: ADG1609 mux=00 (0) S1A S1B, ADS1248 AIN1- to AIN5+\n");
                ADS1248_gpio_ADG1609_mux(0);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        //ADCResult = pollADS1248_iso(5, 1, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 5, sampleCnt, 1, 5);       // Chan +1 -5, trials = 1, gain = user, sps = 5 Hz
                        uprintf("Ext Ref Offset = %.6f V,  Samp = %04u,  Time = %06lu\r\n", ADCResult, indx++, sampTime/100L);
                        //uprintf("Ext Ref Offset = %.6f V,  Samp = %04u,  Time = %06lu std = %f\r\n", ADCResult, indx++, sampTime/100L, sys_data.AD24_std);
                    }

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


            case '1':
                //uprintf("1 -- Int Ref with Offset\n");
                uprintf("1 -- Int Ref with Offset, Mux = 11,  AIN1+ AIN5-\n");
                ADS1248_gpio_ADG1609_mux(3);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        //ADCResult = pollADS1248_iso(5, 1, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 5, sampleCnt, 1, 5);       // Chan +1 -5, trials = 1, gain = user, sps = 5 Hz
                        uprintf("Int Ref Offset = %.6f V,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;

            case '2':
                //uprintf("2 -- Ext Ref Voltage\n");          // Counter A and Counter B are current measurement Counter Electrode
                uprintf("2 -- Ext Ref Voltage, Mux = 00,  AIN1+ AIN6-\n");
                ADS1248_gpio_ADG1609_mux(0);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        //ADCResult = pollADS1248_iso(6, 1, sampleCnt, 1, 5);       // Chan +6 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +1 -6, trials = 1, gain = user, sps = 5 Hz
                        uprintf("Ext Ref = %.6f V,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;


            case '3':
                //uprintf("3 -- Int Ref Voltage\n");
                uprintf("3 -- Int Ref Voltage, Mux = 11,  AIN1+ AIN6-\n");
                ADS1248_gpio_ADG1609_mux(3);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        //ADCResult = pollADS1248_iso(6, 1, sampleCnt, 1, 5);       // Chan +6 -1, trials = 1, gain = user, sps = 5 Hz
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +1 -6, trials = 1, gain = user, sps = 5 Hz
                        uprintf("Int Ref = %.6f V,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;

            case '4':
                //uprintf("4 -- Counter Electrode Current\n");
                uprintf("4 -- Counter Electrode Current, Mux = 01,  AIN1+ AIN5-\n");
                ADS1248_gpio_ADG1609_mux(1);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        ADCResult = pollADS1248_iso(1, 5, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf("Counter Electrode Current = %.6f,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;

            case '5':
                //uprintf("5 -- Counter Electrode Voltage\n");
                uprintf("5 -- Counter Electrode Voltage, Mux = 01,  AIN1+ AIN6-\n");
                ADS1248_gpio_ADG1609_mux(1);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf("Counter Electrode Voltage = %.6f V,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;

            case '6':
                //uprintf("6 -- Substrate Current\n");
                uprintf("6 -- Substrate Current, Mux = 10,  AIN1+ AIN6-\n");
                ADS1248_gpio_ADG1609_mux(2);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        ADCResult = pollADS1248_iso(1, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        uprintf("Substrate Current = %.6f,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;

            case '7':
                //uprintf("7 -- Substrate Voltage\n");
                uprintf("7 -- Substrate Voltage, Mux = 10,  AIN5+ AIN6-\n");
                ADS1248_gpio_ADG1609_mux(2);
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        ADCResult = pollADS1248_iso(5, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        sampTime = Timer_10ms(FALSE);
                        uprintf("Substrate Voltage = %.6f V,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;

            case '8':
                //uprintf("8 -- Thermistor ISFET Temperature\n");
                uprintf("8 -- Thermistor ISFET Temperature, Mux = XX,  AIN0+ AIN6-\n");
                ADS1248_gpio_ADG1609_mux(0);        // Not necessary, but consistent
                indx = 0;
                Timer_10ms(TRUE);       // reset 10msec tick count
                sampleCnt = 1;
                sampTime = 0L;
                nextTime = 0L;
                while(1)
                {
                    sampTime = Timer_10ms(FALSE);
                    if(sampTime >= nextTime)
                    {
                        nextTime = sampTime + sampDelay;
                        ADCResult = pollADS1248_iso(0, 6, sampleCnt, 1, 5);       // Chan +5 -1, trials = 1, gain = user, sps = 5 Hz
                        sampTime = Timer_10ms(FALSE);
                        uprintf("Thermistor = %.6f,  Samp = %04u,  Time = %06lu \r\n", ADCResult, indx++, sampTime/100L);
                    }
                    if( UARTRxBytesAvail() )
                    {
                        input = get_key();
                        break;    // break from while(1)
                    }
                }
                break;



            case 'T':
                // reading pH voltage
                uprintf("\nReading 24bit voltage via ADG1609 mux and ADS1248\n");
                ROM_SysCtlDelay(MILLISECOND * 100);
                openADS1248_iso();
                ADS1248_gpio_init();    // defd in ADS1248_iso.c

                ROM_SysCtlDelay(MILLISECOND * 100);
                // Now read the pH value (diff across AIN1- and AIN5+)
                uprintf("\n\n1: ADG1609 mux=00 (0) S1A S1B, ADS1248 AIN1- to AIN5+\n");
                ADS1248_gpio_ADG1609_mux(0);

                indx = 0;
                while(1)
                {
                    // pos chan, neg chan, avg=2, gain=1, sps=5
                    // pH to pH ref
                    ADCResult = pollADS1248_iso(5, 1, 2, 1, 5);       // Chan 5-1, trials = 1, gain = user, sps = 5 Hz
                    uprintf("pH = %.6f V,  loop= %u \r", ADCResult, indx++);

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

                uprintf("\n\n2: ADG1609 mux=00 (0) S1A S1B, ADS1248 AIN1- to AIN6+(gnd)\n");
                ADS1248_gpio_ADG1609_mux(0);

                indx = 0;
                while(1)
                {
                    // pos chan, neg chan, avg=2, gain=1, sps=5
                    // pH to pH ref
                    ADCResult = pollADS1248_iso(6, 1, 2, 1, 5);       // Chan 6-1, trials = 1, gain = user, sps = 5 Hz
                    uprintf("pH = %.6f V,  loop= %u \r", ADCResult, indx++);

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

                uprintf("\n\n3: ADG1609 mux=11 (3) S4A S4B, ADS1248 AIN1- to AIN5+\n");
                ADS1248_gpio_ADG1609_mux(3);
                indx = 0;
                while(1)
                {
                    // pos chan, neg chan, avg=2, gain=1, sps=5
                    // pH to pH ref
                    ADCResult = pollADS1248_iso(5, 1, 2, 1, 5);       // Chan 5-1, trials = 1, gain = user, sps = 5 Hz
                    uprintf("pH = %.6f V,  loop= %u \r", ADCResult, indx++);

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

                uprintf("\n\n4: ADG1609 mux=11 (3) S4A S4B, ADS1248 AIN1- to AIN6+(gnd)\n");
                ADS1248_gpio_ADG1609_mux(3);
                indx = 0;
                while(1)
                {
                    // pos chan, neg chan, avg=2, gain=1, sps=5
                    // pH to pH ref
                    ADCResult = pollADS1248_iso(6, 1, 2, 1, 5);       // Chan 6-1, trials = 1, gain = user, sps = 5 Hz
                    uprintf("pH = %.6f V,  loop= %u \r", ADCResult, indx++);

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

                closeADS1248_iso();
                uprintf("iso power off\n");

                break;
                //uprintf("9 -- Exit to Main Menu\n"

            default:
                uprintf("\nPress enter to bring up menu\n");
                closeADS1248_iso();
                uprintf("iso power off\n");
                return;
        } // switch

    } // while(1)

    // Future: if break from while(1), then make sure to close isolated supply (return is from switch-default)
    closeADS1248_iso();
    uprintf("iso power off\n");
}




/**************************************************************************************
 * deploy()
 * Accepts a deployment state argument that determines whether to start the deployment,
 * take a sample, or enter the command mode.
 ***************************************************************************************/
void deploy(deploy_state state)
{
	int response;
	time_t start_time, current_time;
	int charCount, gdata, ts, stop, dump, samp_byte;
	char buff[81];
	FIL fileObject;
	FRESULT fresult;
	UINT br;
	bool line_end;

	// START mode
	if(state == START)	// New deployment or test
	{
		uprintf("\n\n\n\n\n***************** Deployment Settings **************\n");
		// Sensor name
		// Durafet ID

		uprintf("Sampling period: \t%d seconds\n", sys_data.sampling_period);

		uprintf("Samples hour aligned\t");
		if(sys_data.sample_aligned)	uprintf("Yes\n");
		else uprintf("No\n)");

		uprintf("pH sample average: \t%d samples\n", sys_data.sample_average);
		uprintf("Pump on time: \t%d seconds\n", sys_data.pumpon_time);
		uprintf("Low battery voltage: \t%.1f V\n", sys_data.low_batt_volt);

		if(sys_data.output == 1) uprintf("Output mode: \tNormal\n");
		else if(sys_data.output == 2) uprintf("Output mode: \tVerbose\n");
		uprintf("Eo_int @ 25 C = \t%1.6f V\n", sys_data.Eo_int_25C);
		uprintf("Eo_ext @ 25 C = \t%1.6f V\n", sys_data.Eo_ext_25C);


		uprintf("File name: \t%s\n", sys_data.fileName);

		uprintf("Current time: ");
		printCurrentTime();

		uprintf("\n*****************************************************\n");

		//response = yesOrNoMenuChoice("\n\nTest deployment (SBE pump disabled)? (Y/N) [Y]? ", YES);
		response = NO;      // THOM - added this line 3 May 2018

		// Test deployment
		if(response == YES)             // THOM: TODO, this line relies on a commented out line above - 'response' is tested before it is set
		{
			sys_data.test_mode = 1;

			uprintf("\n\nEntering test deployment mode (SBE pump disabled)\n\n");
			sys_data.nextWakeUp =  ROM_HibernateRTCGet();	// Start immediately
			start_time = sys_data.nextWakeUp;
		}

		//Actual deployment (SBE pump will run)
		else
		{
			sys_data.test_mode = 0;			// SBE pump will run

			// Set a custom start time?
			//response = yesOrNoMenuChoice("\nSet custom start time (Y/N) [N]? ", NO);
			response = NO;          // THOM added 7 May 2018 (line commented out above)
			// Custom start time
			if(response == YES)
			{
				while(1)
				{
					start_time = getDateAndTime();

					uprintf("\nStart time now: ");
					print_time_t_Time(start_time);
					//response = yesOrNoMenuChoice("\nStart time correct (Y/N) [N]? ", NO);
					response = YES;  // THOM New 8 May 2018
					if( response == NO )
					{
						//start the loop over, they want to change the time
						continue;
					}

					sys_data.nextWakeUp = start_time;
					break;
				}
			}
			// No custom start time
			else
			{
				current_time = ROM_HibernateRTCGet();    //THOMHERE - check for 0 to make polled happen
				sys_data.nextWakeUp = current_time;		// Start immediately

			}

			uprintf("\nSBE pump will run and must be immersed at start time!");
			//response = yesOrNoMenuChoice("\n\nDo you really want to deploy (Y/N [N])? ", NO);
			response = YES;         // THOM added 7 May 2018 due to line above commented
			if(response == NO)
			    return;
		}

		/*// Exit deployment mode if file name is not reset
		if(sys_data.fileName == g_sFileInfo.fname)
		{
			// prompt for new filename
			uprintf("\nFile Already Exists! Enter new File name\n");
			return;
		}*/


		// Begin deployment...
		sys_data.current_sample = 0;	// Reset sample number
		sys_data.state = DEPLOYED;
//THOM Polled Mode
		if(sys_data.sampling_period == 0)
		{
		    uprintf("\n\nDeployed in polled mode (COMMAND)...\n\n");        // THOM, polled mode  7 May 2018
		    sys_data.state = COMMAND;
		}

		if( writeDeploymentInformationHeader(current_time, start_time) )  // Write deployment header to data file
		{
			return;		// File access error, abort deployment
		}
		else
		{
			uprintf("\n\nStarting deployment...\r\n");       // THOM New 07 Jun 2018 - added crlf
		}

	}	// End of sys_data.state == START if statement

	// COMMAND mode
	else if(sys_data.state == COMMAND)
	{

		while(1)	// Command loop
		{
			if(sys_data.output == VERBOSE || sys_data.test_mode) uprintf("\nEnter command (ts, gdata, stop): ");

			//flush the receive and transmit buffers
			UARTFlushRx();

			// Wait for command for 10 seconds
			charCount = getUserInputTimeLimit(buff, sizeof(buff), 10);

			// If the time limit passed...
			if(charCount == TIMELIMITPASSED)
			{
				if(sys_data.output == VERBOSE) uprintf("\n\nNo command, resuming deployment...");
				break;
			}
			else
			{
				// Parse command
				gdata = strncmp(buff, "gdata", 5);
				ts = strncmp(buff, "ts", 2);
				stop = strncmp(buff, "stop", 4);
				dump = strncmp(buff, "dump", 4);

				if(gdata == 0)	// Display samples since last gdata command
				{
					UARTEchoSet(false);		// Turn off console echo so key hit doesn't mess up screen output

					// Open a file
					fresult = f_open(&fileObject, sys_data.fileName, FA_READ|FA_OPEN_ALWAYS);
					if(fresult != FR_OK)
					{
						uprintf("Error.txt f_open error: %s\n", StringFromFresult(fresult));
					}

					// Seek to the next byte in data file since last gdata
					fresult = f_lseek(&fileObject, sys_data.next_gdata_fptr);
					if(fresult != FR_OK)
					{
						uprintf("Error.txt f_lseek error: %s\n", StringFromFresult(fresult));
					}

					// Print out the records
					line_end = false;

					do
					{
						fresult = f_read(&fileObject, buff, 80, &br);
						if(fresult != FR_OK)
						{
							uprintf("Error.txt f_read error: %s\n", StringFromFresult(fresult));
						}

						buff[br] = '\0';

						// Wait till there is room in tx buffer, then print the buffer
						while( UARTTxBytesFree() <= 80 );
						uprintf("%s", buff);

						// Stop reading and printing if user hits key
						if(kbhit())
						{
							// Print out any remaining characters of the last sample
							do
							{
								fresult = f_read(&fileObject, buff, 80, &br);
								{
									uprintf("Error.txt f_read error: %s\n", StringFromFresult(fresult));
								}

								for(samp_byte = 0; samp_byte < br; samp_byte++)
								{
									uprintf("%c", buff[samp_byte]);

									if( buff[samp_byte] == '\n' )	// Look for the end of the line
									{
										line_end = true;
										break;
									}
								}
							} while(br == 80 && !line_end);

							break;
						}

					} while (br == 80 && !line_end);		// Keep doing this until the end of the file

					sys_data.next_gdata_fptr = fileObject.fptr;		// Store the current file position for next gdata command
					UARTEchoSet(true);								// Turn console echo back on
				}

				// Take a sample and continue with deployment
				else if( ts == 0 )
				{
				    sys_data.state = DEPLOYED;
				    if(sys_data.sampling_period == 0)   // THOM Polled Mode
				        sys_data.state = COMMAND;      // THOM NEW - use command mode to stop RTC wakeup (polled mode)
					get_sample();
					break;
				}

				// Exit deployment and return to main menu
				else if( stop == 0 )
				{
					sys_data.state = IDLE;
					return;
				}
				else if( dump == 0)
				{
				    state_dump();
				}

				// Invalid command
				else
				{
					if(sys_data.output == VERBOSE) uprintf("\nInvalid command");	// Goes back to top of command loop
				}
			}
		}	// End of command loop

		if(sys_data.sampling_period == 0)       // THOM new 7 May 2018
		    sys_data.state = COMMAND;       // COMMAND state is how polling occurs
		else
		    sys_data.state = DEPLOYED;	// Go back to DEPLOYED state

		//sleep(sys_data.state, 0);       // THOM NEW 8 May 2018
	}   // else if(sys_data.state == COMMAND)

	// DEPLOYED mode
	else
	{
		get_sample();

		// Calculate the next sample time
		if(sys_data.sample_aligned)		// Sample time hour aligned?
		{
			current_time = ROM_HibernateRTCGet();
			sys_data.nextWakeUp = (current_time / 3600) * 3600;	 		// Find last hour

			do
			{
				sys_data.nextWakeUp += sys_data.sampling_period;
			} while(sys_data.nextWakeUp < current_time);
		}
		else sys_data.nextWakeUp += sys_data.sampling_period;	// Not hour aligned
	}

	if(sys_data.sampling_period == 0)  // NEW 8 May 2018
	{
	    sleep(COMMAND, 0);   // Sleep until woken by UART (keystroke at serial terminal)   THOM New 8 May 2018
	}
	else
	{
	    sleep(DEPLOYED, sys_data.nextWakeUp);	// Sleep until woken by RTC or keystroke
	}
}



void state_dump(void)
{
    time_t current_time;

    dbg_flag = 1;

    dbg_printf("\n\n");

    if(sys_data.state == DEPLOYED)
    {
        dbg_printf("DEPLOYED\n");
    }
    if( sys_data.state == COMMAND)
    {
        dbg_printf("COMMAND\n");
    }
    if( sys_data.state == IDLE)
    {
        dbg_printf("IDLE\n");
    }

    current_time = ROM_HibernateRTCGet();

    dbg_printf("now %lu, next wake %lu, sampling period %lu\n", (unsigned int)current_time, sys_data.nextWakeUp, sys_data.sampling_period);

}
