/*
 * 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)
 */

#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


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



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

/*
 * main.c
 */
int main(void)

{
	char input;
	time_t timer;

	Init();		// Initialize pins and ports

	// when you upload a new program, it goes straight into deplyoment.YT 4/29/2015 fix later.
	if(sys_data.state == DEPLOYED) deploy(DEPLOYED);
	else if( sys_data.state == COMMAND) deploy(COMMAND);

	// Else must be IDLE mode

	// Main Menu loop
	while(1)
	{
		// Print out the menu:
		uprintf("\n\n\nMain Menu--SeaFET/SeapHOx %s", VERSION);
		uprintf("\n1 -- Configure");
		uprintf("\n2 -- Deploy");
		uprintf("\n3 -- Test");
		uprintf("\n4 -- Sleep");
		uprintf("\n5 -- Files");
		uprintf("\nEnter Selection: ");

		// 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 '1':
				configuration();
				break;

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

			case '3':
				test();
				break;

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

			case '5':
				viewFiles();
				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 '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);
				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)
						{
							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;
					}
					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)
				{
				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)
				{
				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)
				{
				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) ) 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.\n");
				return;
		}
	}
}



/*************************************************************************************************************************
 * Test menu.
 *************************************************************************************************************************/
void test(void)
{
	char input;
	float ADCResult, TC, ADCvolts, Vpar;
	int32_t charInput;
	int response;
	time_t timer;
	bool pump_on = false, AUX1_on = false, AUX2_on = false;

	// 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");
		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 '1': //Read Voltages from ADC on Non-isolated side.
				openADS1248_noniso();
				pressureOn();			// Turn on 5V to pressure sensor
				ROM_SysCtlDelay(MILLISECOND*1000);

				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);

					// Vpar
					Vpar = pollADS1248_noniso(6, 7, 1);
					uprintf("Vpar = %3.6f V\n", Vpar);

					ROM_SysCtlDelay(MILLISECOND*3000);
				}

				pressureOff();
				closeADS1248_noniso();
				break;

			case '2': //Read Voltages from the isolated ADC
				openADS1248_iso();
				ROM_SysCtlDelay(MILLISECOND * 1000);	// Let electronics settle

				while(!UARTRxBytesAvail())
				{
					//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);
				}

				//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;

			default: //Exit
				return;
		}
	}
}



/**************************************************************************************
 * 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, 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***************** Deployment Settings **************\n");
		// Sensor name
		// Durafet ID

		uprintf("Sampling period: \t\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\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: \t\tNormal\n");
		else if(sys_data.output == 2) uprintf("Output mode: \t\tVerbose\n");
		uprintf("Eo_int @ 25 C = \t\t%1.6f V\n", sys_data.Eo_int_25C);
		uprintf("Eo_ext @ 25 C = \t\t%1.6f V\n", sys_data.Eo_ext_25C);


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

		uprintf("\nCurrent time: ");
		printCurrentTime();

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

		response = yesOrNoMenuChoice("\n\nTest deployment (SBE pump disabled)? (Y/N) [Y]? ", YES);

		// Test deployment
		if(response == YES)
		{
			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);

			// 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);
					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();
				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);
			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;

		if( writeDeploymentInformationHeader(current_time, start_time) )  // Write deployment header to data file
		{
			return;		// File access error, abort deployment
		}
		else
		{
			uprintf("\n\nStarting deployment...");
		}

	}	// End of 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);

				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;
					get_sample();
					break;
				}

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

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

		sys_data.state = DEPLOYED;	// Go back to DEPLOYED status
	}

	// 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
	}

	sleep(DEPLOYED, sys_data.nextWakeUp);	// Sleep until woken by RTC or keystroke
}



