//the configuration file for the target board to run the test programs
var DEVICE="K2H_LE"
var target_board_cfg= "C:/Users/a0389163/ti/CCSTargetConfigurations/K2H_EVM.ccxml"
//var DEVICE="K2E_LE"
//var target_board_cfg= "C:/Users/a0389163/ti/CCSTargetConfigurations/K2E_EVM.ccxml"
//var DEVICE="K2L_LE"
//var target_board_cfg= "C:/Users/a0389163/ti/CCSTargetConfigurations/K2L_EVM.ccxml"

//list of test programs and timeout value in ms for execute the program
if(DEVICE=="K2L_LE")
{
var test_cases = [ 
	{program: "../EMIF/Debug/EMIF.out"                              , timeOut:  500000},
	{program: "../GE/Debug/GE.out"                                  , timeOut:  200000},
	{program: "../GPIO/Debug/GPIO.out"                              , timeOut:  150000},
	{program: "../I2C/Debug/I2C.out"                                , timeOut:  100000},
	{program: "../Memory_Performance/Debug/Memory_Performance.out"  , timeOut: 1000000},
	{program: "../Memory_Test/Debug/Memory_Test.out"                , timeOut: 1000000},
	{program: "../Multicore_Navigator/Debug/Multicore_Navigator.out", timeOut:  500000},
	{program: "../PCIE/Debug/PCIE.out"                              , timeOut:  300000},
	{program: "../Robust/Debug/Robust.out"                          , timeOut:  150000},
	{program: "../SPI/Debug/SPI.out"                                , timeOut: 1000000},
	{program: "../Timer/Debug/Timer.out"                            , timeOut:   30000},
	{program: "../UART/Debug/UART.out"                              , timeOut:   20000},
	{program: "../USIM/Debug/USIM.out"                              , timeOut:   20000}];
}
else if(DEVICE=="K2H_LE")
{
var test_cases = [ 
	{program: "../EMIF/Debug/EMIF.out"                              , timeOut:  500000},
	{program: "../GE/Debug/GE.out"                                  , timeOut:  200000},
	{program: "../GPIO/Debug/GPIO.out"                              , timeOut:  150000},
	{program: "../HyperLink/Debug/HyperLink.out"                    , timeOut:  300000},
	{program: "../I2C/Debug/I2C.out"                                , timeOut:  100000},
	{program: "../Memory_Performance/Debug/Memory_Performance.out"  , timeOut: 1000000},
	{program: "../Memory_Test/Debug/Memory_Test.out"                , timeOut: 1000000},
	{program: "../Multicore_Navigator/Debug/Multicore_Navigator.out", timeOut:  500000},
	{program: "../PCIE/Debug/PCIE.out"                              , timeOut:  300000},
	{program: "../Robust/Debug/Robust.out"                          , timeOut:  150000},
	{program: "../SPI/Debug/SPI.out"                                , timeOut: 1000000},
	{program: "../Timer/Debug/Timer.out"                            , timeOut:   30000},
	{program: "../UART/Debug/UART.out"                              , timeOut:   20000},
	{program: "../USIM/Debug/USIM.out"                              , timeOut:   20000}];
}
else
{
var test_cases = [ 
	{program: "../EMIF/Debug/EMIF.out"                              , timeOut:  500000},
	{program: "../GE/Debug/GE.out"                                  , timeOut:  200000},
	{program: "../GPIO/Debug/GPIO.out"                              , timeOut:  150000},
	{program: "../HyperLink/Debug/HyperLink.out"                    , timeOut:  300000},
	{program: "../I2C/Debug/I2C.out"                                , timeOut:  100000},
	{program: "../Memory_Performance/Debug/Memory_Performance.out"  , timeOut: 1000000},
	{program: "../Memory_Test/Debug/Memory_Test.out"                , timeOut: 1000000},
	{program: "../Multicore_Navigator/Debug/Multicore_Navigator.out", timeOut:  500000},
	{program: "../PCIE/Debug/PCIE.out"                              , timeOut:  300000},
	{program: "../Robust/Debug/Robust.out"                          , timeOut:  150000},
	{program: "../SPI/Debug/SPI.out"                                , timeOut: 1000000},
	{program: "../Timer/Debug/Timer.out"                            , timeOut:   30000},
	{program: "../UART/Debug/UART.out"                              , timeOut:   20000}];
}
// Import the DSS packages into our namespace to save on typing
importPackage(Packages.com.ti.debug.engine.scripting)
importPackage(Packages.com.ti.ccstudio.scripting.environment)
importPackage(Packages.java.lang)
importPackage(Packages.java.io)

print("Please select test programs:");
for(var i = 0; i < test_cases.length; i++)
{
	print((i+1)+": "+test_cases[i].program);
}
print("Enter the number of a program to run the program;"); 
print("Multiple programs can be selected, for example to select program 3,5,6,7,10,13, you can enter:\"3,5,6,7,10,13\" or \"3,5-7,10,13\"");
print("Press \"return\" key without any number to execute all programs:");

var num_test_case=0; //number of the selected test cases
var test_case_list = new Array(); //list of the selected test cases

//read user input from the console
var console=java.lang.System.console();
var test_case_select_string=console.readLine().trim(); 

//parser user's input
if(test_case_select_string.length()>0)//select programs
{
	//split with "," to get multiple programs
	var test_case_strings= test_case_select_string.split(",");
	for(var i=0; i<test_case_strings.length; i++)
	{
		if(test_case_strings[i].indexOf('-')!=-1)//this represents a range
		{
			//split with "-" to get selected range
			var test_case_range=test_case_strings[i].split("-");
			var test_case_start_num=0, test_case_end_num=0;
			try{//convert string to number
				test_case_start_num= Integer.parseInt(test_case_range[0].trim());
			}catch(exception){
				print(test_case_range[0]+ "is not a valid number!");
			}
			try{//convert string to number
				test_case_end_num= Integer.parseInt(test_case_range[1].trim());
			}catch(exception){
				print(test_case_range[1]+ "is not a valid number!");
			}
			if(0<test_case_start_num && test_case_start_num<test_case_end_num &&test_case_end_num<=test_cases.length)
				for(var j=test_case_start_num; j<=test_case_end_num; j++)
				{//add a program to test case list
					test_case_list[num_test_case]= j-1;
					num_test_case++;
				}
		}
		else//this represents one program
		{	
			var test_case_num=0;
			try{//convert string to number
				test_case_num= Integer.parseInt(test_case_strings[i].trim());
			}catch(exception){
				print(test_case_strings[i]+ "is not a valid number!");
			}
			if(0<test_case_num && test_case_num<=test_cases.length)
			{//add a program to test case list
				test_case_list[num_test_case]= test_case_num-1;
				num_test_case++;
			}
		}
	}
}
else //execute all programs
{
	for(var i = 0; i < test_cases.length; i++)
	{
		test_case_list[i]= i;
	}
	num_test_case= test_cases.length;
}

print("Connect to target board...");

// Create our scripting environment object - which is the main entry point into any script and
// the factory for creating other Scriptable servers and Sessions
var script_env = ScriptingEnvironment.instance()

// Create a log file in the current directory to log script execution
script_env.traceBegin("STK_Log.xml", "DefaultStylesheet.xsl")

// Log levle FINE and higher
script_env.traceSetConsoleLevel(TraceLevel.FINE)
// Log everything
script_env.traceSetFileLevel(TraceLevel.ALL)

// Get the Debug Server and start a Debug Session
debugServer = script_env.getServer("DebugServer.1")
debugServer.setConfig(target_board_cfg);
debugSession = debugServer.openSession("*", "arm_A15_0")

if (debugSession.getMajorISA() != 0x15) 
{
	// Requires a C64x (for now)
	script_env.traceWrite("Test requires a ARM Cortex A15 core!")
	script_env.traceWrite("TEST FAILED!")
	script_env.traceEnd()
	java.lang.System.exit(1);
}

debugSession.target.connect();

//extract file name from absolute file path
function extractFileName(file)
{
	var strings = new Array();
	if(file.indexOf('/')!=-1)
	{
		//split file name with "/"
		strings=file.split("/");
	}
	else if(file.indexOf('\\')!=-1)
	{
		//split file name with "\"
		strings=file.split("\\");
	}
	 	
	//the last string is the file name with extension
	var fullName;
	if(strings.length > 0)
		fullName= strings[strings.length-1];
	else
		fullName= file;
		
	//spilt the full name with "."
	strings= fullName.split(".");
	
	//the first string is the file name without extension
	return strings[0];
}

var boardName= extractFileName(target_board_cfg);

//make a directory with board name to store the test results
var resultDir = new File(boardName+"_result");
// if the directory does not exist, create it
if (!resultDir.exists()) {
	resultDir.mkdir();  
}

//execute all type of resets supported by the target
function AdvancedReset()
{
	var numReset = debugSession.target.getNumResetTypes();
	for (var j = 0; j < numReset; j++)
	{
		var reset = debugSession.target.getResetType(j);
		if (reset.isAllowed())
		{
			script_env.traceWrite("issue reset:"+reset.getName());
			reset.issueReset();
		}
	}
}

var exceptionCount=0;

//execute one test program
function execute_program(program, timeOut)
{
	// Change timeout from the default (infinite)
	script_env.setScriptTimeout(timeOut);
	
	var DateTime= new Date();
	script_env.traceWrite("Execute "+program+" at "+DateTime.toString().substring(16, 24)+"...");
	var startTime= java.lang.System.currentTimeMillis();

	// Load a program
	// (ScriptingEnvironment has a concept of a working folder and for all of the APIs which take
	// path names as arguments you can either pass a relative path or an absolute path)
	try
	{
		debugSession.memory.loadProgram(program);
	} catch(exception)
	{//catch exception and continue to execute the next program
		exceptionCount++;
		return;
	}
	
	//save CIO of the program to a text file.
	var CIO_log_file_name= "./"+boardName+"_result/"+ extractFileName(program)+"_test_result.txt";
	debugSession.beginCIOLogging(CIO_log_file_name);

	//do not log level lower than WARNING, such as CIO output
	script_env.traceSetConsoleLevel(TraceLevel.WARNING)
	script_env.traceSetFileLevel(TraceLevel.WARNING)
	
	try
	{
		debugSession.target.run();

	} catch(exception)
	{//catch exception and continue to execute the next program
		exceptionCount++;
	}
	
// Log levle FINE and higher
	script_env.traceSetConsoleLevel(TraceLevel.FINE)
	// Log everything
	script_env.traceSetFileLevel(TraceLevel.ALL)

	debugSession.endCIOLogging();
	
	var endTime= java.lang.System.currentTimeMillis();
	script_env.traceWrite(program+" complete, consumes "+(endTime-startTime)+" ms.\n");

	//advanced reset to clean the device for running next test case
	//debugSession.expression.evaluate("GEL_AdvancedReset(\"System Reset\")");
	AdvancedReset();

}

//execute all selected test programs
for(var i = 0; i < num_test_case; i++)
{
	var test_case_num= test_case_list[i];
	execute_program(test_cases[test_case_num].program, test_cases[test_case_num].timeOut);
}

// All done
debugSession.terminate()
debugServer.stop()

script_env.traceWrite("TEST COMPLETE. " +exceptionCount+ " exception happened!")

// Stop logging and exit.
script_env.traceEnd()
