/* --COPYRIGHT--,BSD
 * Copyright (c) 2012, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
// CRCGen430.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>

#include "MSP430CRC_Calc.h"

using namespace std;

string CRC_type;
uint8_t Fill_val;
bool Fill_mem;
string Input_File;
string Output_File;
uint32_t Start_Addr;
uint32_t End_Addr;
uint32_t CRC_Addr;

int Parse_arguments(int argc, char *argv[]);



int main(int argc, char *argv[])
{
	int ret;
	
	cout << "CRCGen430 CRC generator for MSP430   " << endl << "  Texas Instruments Inc" << endl << "  Version 1.0.1" << endl << endl;
	
	if (Parse_arguments(argc, argv) < 0)
	{
		cout << "  Syntax: " <<endl;
		cout << "  CRCGen430.exe CRCType InputFile OutputFile StartAddr EndAddr CRCAddr " << endl;
		cout << "   CRCType: CRC16 or CRC8 " << endl;
		cout << "   InputFile: File in .txt format with application. " << endl;
		cout << "   OutputFile: Output file with application and CRC value. " << endl ;
		cout << "   StartAddr: Start address in HEX format. " << endl;
		cout << "   EndAddr: End address in HEX format. " << endl;
		cout << "   CRCAddr: CRC address in HEX format. " << endl << endl;
		cout << "     Examples :" << endl;
		cout << "     CRCGen430 CRC16 hello.txt out.txt 4400 FFFF 1800 " << endl;
		cout << "     Calculates CRC16 of hello.txt from 0x4400 to 0xFFFF " << endl;
		cout << "     stores result in 0x1800 and writes output to out.txt" << endl;
		exit (-1);
	}
	
	MSP430CRC_Calc CRCCalc(Input_File, Output_File, Start_Addr, End_Addr, CRC_Addr, Fill_val, Fill_mem);

	if (CRC_type == "CRC16")
		ret = CRCCalc.CalculateCRC(16);
	else if (CRC_type == "CRC8")
		ret = CRCCalc.CalculateCRC(8);

	if (ret < 0)
	{
		cout << "Invalid parameters: " << ret << endl;
		exit (-2);
	}
	
	cout << "Output file: "<< Output_File << " created successfully!" << endl << endl; 
	cout << "*****CRC Result: 0x" << hex << uppercase << setfill('0') << setw(4) << CRCCalc.CRC_Result  << "*****" << endl << endl;
	
	return 0;
}



int Parse_arguments(int argc, char *argv[])
{
	// create an empty vector of strings
    vector<string> args;
	int i;
	int file_parse = -1, param_parse =-1, addr_parse = -1;
	std::stringstream ss;
		
	// copy program arguments into vector
	if ((argc != 8) && (argc != 7))
	{
		// Expecting 6/7 parameters
		return -1;
	}
    for (i=1;i<argc;i++) 
	{
        args.push_back(argv[i]);
	}

	// First parameter is CRC type
	CRC_type = args[0];
	if ((CRC_type != ("CRC16")) && (CRC_type != ("CRC8")))
		return -1;
	// Second parameter is Input File
	Input_File = args[1];
	// 3rd parameter is Output File
	Output_File = args[2];
	// 4th parameter is Start Address
	ss << std::hex << args[3];
	ss >> Start_Addr;
	ss.clear();
	// 5th parameter is End address
	ss << std::hex << args[4];
	ss >> End_Addr;
	ss.clear();
	// 6th parameter is CRC address
	ss << std::hex << args[5];
	ss >> CRC_Addr;
	ss.clear();
	// 7th parameter (optional) is Fill value
	if (argc == 7)
		Fill_mem = false;
	else
	{
		uint16_t temp;
		ss << std::hex << args[6];
		ss >> temp;
		Fill_val = (uint8_t ) temp;
		ss.clear();
		Fill_mem = true;
	}
	
	return 1;
}

