// LFAE SCI Functions.cpp
// This file contians the functions relating to Serial transmision of data
// for the secondary LFAE bootloader

#include "main.h"
#include <fstream> //used to read from files
#include "LFAE SCI Functions.h"
#include <conio.h> //needed for getchar
#include "Serial.h"
#include <time.h> // needed for sleep function and timer
using namespace std;  //needed by <fstream>


//*******************************************
// function to transmit application s-record (s-record to be loaded to flash)
//*******************************************
int LFAE_SCI_interface(CSerial *Serial)
{
	// local variables
	short byteCount = 0x0000;
	char SendBuffer = 0x00;
	unsigned char RecBuffer = 0x00;
	unsigned char checkSumTotal = 0x00;
	char line[1000];//max chars per line is 1000
	time_t seconds = time(NULL); //start time in seconds

	// main code
	if(Serial->Open(SCIPort,BaudRate)) //open port 1 at predefined baud rate
	{	
		_sleep(500); // pause while the node prepares to receive data
		
		//send data
		printf("Transmitting data to secondary bootloader...\n");
		ifstream s_record;
		s_record.open(SecondarySRecordFilename, ios::in); //open file for input purposes
		if (s_record.is_open())
		{	
			while (! s_record.eof() ) //while not the end of the file	
			{
				s_record.getline(line,1000); //maximum chars per line is 1000
				LFAE_SCI_s_line_process(line, Serial);//process the captured s-line
			}
			s_record.close();	
		}else
		{
			printf("Error: Could not open file...\n");
			getch();
			return 1;	
		}
			
		printf("Secondary S-Record transmitted successfully!\n");
		printf("Elapsed Time: %i seconds\n",(time(NULL) - seconds));
		printf("Press any key to exit...\n");
		getch();
		Serial->Close();
		return 0;	
	}
	else
	{
		printf("Error: Could not open serial port.\n");
		printf("Ensure no other applications are using port,\n");
		printf("and that the defined baud rate is valid\n");
		printf("Press any key to exit...\n");
		getch();
		return 1;
	}
}


//*******************************************
// function to analyse an s-line and transmit via SCI
// Secondary Bootloader Version
// 
// Notes:
// SRecord should be of extension ".abs.glo" i.e all data should be
// stored in S2 lines. This ensures all addresses are given in global format
//*******************************************
void LFAE_SCI_s_line_process(char *line, CSerial *Serial)
{
	//local variables
	int lineLength = 0;
	int loop;
	char Buff; //array for data
	unsigned char checkSumTotal = 0;
	bool checkSumCorrect = FALSE;

	// main code
	switch (line[1]) 
	{
		case '0':
			// S0 - header - ignore
			break;
		case '2':
			while (checkSumCorrect == FALSE)
			{
				// 3 byte addressing (global)
				lineLength = hex2dec(line,2); //get line length, 
				Buff = lineLength;
				Serial->SendData(&Buff,1); //transmit line length

				// send address and data
				for(loop=4; loop <= (2*lineLength + 1) ; loop = loop+2)
				{
					Buff = hex2dec(line,loop);
					checkSumTotal += Buff;
					Serial->SendData(&Buff,1);
				}

				// send checksum and ensure wait to find if it is correct
				Buff = hex2dec(line,loop);
				Serial->SendData(&Buff,1);
				while(Serial->ReadDataWaiting() == 0) {}
				Serial->ReadData(&Buff, 1);
				if ((unsigned char)Buff == 0x80)
				{
					checkSumCorrect = TRUE;
					_sleep(25); //pause to allow data to be written to flash
					break;
				}else
					printf("Error: Failed checksum.\n"); 
					printf("resending...\n");
			}
			break;
		case '9':
			// end of data, send a line length of zero to notify the bootloader to execute
			Buff = 0;
			Serial->SendData(&Buff,1); //transmit line length
			break;

		default:
			//error! line not recognised
			printf("S-Record line not recognised/n");
			break;
	}
}
