#include "environment.h"
#include "image_control.h"
#include "tpb_system.h"

unsigned short 	BoardID = 0;
TSPBSetupInfo SetupInfo;
#pragma DATA_ALIGN(SPBProgramHeader, 8);
#pragma DATA_ALIGN(SPBDBHeader, 8);
TSPBProgramHeader SPBProgramHeader;
TSPBDBHeader SPBDBHeader;
TSPBFPGAVersion SPBFPGAVersion;
TProgramVersion ProgramVersion;
TSPBCompatibility TPBCompatibility;
TSPBFPGAVersion FPGAnewVersion2; //sjm add


static int ToInt(unsigned char str)
{
    if (str >= '0' && str <= '9') return str - '0';
    else if (str >= 'A' && str <= 'F') return 10 + str - 'A';
    return -1;
}

static int ToInt2(unsigned char *str)
{
    return (ToInt(str[0]) << 4) + ToInt(str[1]);
}

static int ToInt4(unsigned char *str)
{
    return (ToInt(str[0]) << 12) + (ToInt(str[1]) << 8) + (ToInt(str[2]) << 4) + ToInt(str[3]);
}

TErrorCode ReadFromFlash(TFFID idFile, unsigned char *addr, int size, int *length)
{
	TFFHandle hFile;
	TErrorCode rtn = ERROR_CODE_NONE;

	hFile = FlashOpen(idFile, FFS_OPEN_READ);
	if (hFile < 0) rtn = ERROR_CODE_FLASH_OPEN;
	else
	{
		*length = FlashSize(hFile);
		if (*length > size)	rtn = ERROR_CODE_OVERFLOW;
		else if (!FlashRead(hFile, addr, *length)) rtn = ERROR_CODE_FLASH_WRITE;
	}
	if (rtn)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_WARNING, rtn, __LINE__, idFile, size);
	}
	return rtn;
}

TErrorCode WriteToFlash(TFFID idFile, unsigned char *addr, int size, int time)
{
	TFFHandle hFile;
	TErrorCode rtn = ERROR_CODE_NONE;

	hFile = FlashOpen(idFile, FFS_OPEN_WRITE);
	if (hFile < 0) rtn = ERROR_CODE_FLASH_OPEN;
	else if (!FlashWrite(hFile, addr, size, time)) rtn = ERROR_CODE_FLASH_WRITE;
	if (rtn)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_WARNING, rtn, __LINE__, idFile, size);
	}
	return rtn;
}


unsigned int ConvertProgram(unsigned char *hex, unsigned char *code, int length, unsigned int baseSeg)
{
	int i, command, count;
	int segment = 0;
	unsigned char *ssp, *bufp;
	unsigned int p, size = 0;
	
	while (*hex == ':') 
	{
    	count = ToInt2(hex + 1);
	    command = ToInt2(hex + 7);
    	if (command == 0) 
    	{
    		p = ((segment - baseSeg) << 16) + ToInt4(hex + 3);
    		if (p + count < length)
    		{
	    		bufp = code + p;
    			ssp = hex + 9;
	    		for (i = 0; i < count; i++, ssp += 2) 
	    		{
		    		*bufp++ = ToInt2(ssp);
	    		}
    			if (size < p + count) size = p + count;
    		}
    		else return 0;
	    } 
	    else if (command == 4) 
	    {
			segment = ToInt4(hex + 9);
	    } 
	    else if (command == 1) 
	    {
		}
		hex += 2 * count + 13;
	}
	return size;
}


void ClearCPBDownState(void)
{
	int cpbIndex;
	for (cpbIndex = 0; cpbIndex < TPB_CPB_MAX_COUNT; cpbIndex++)
	{
		if (CPBStatus[cpbIndex].Enabled)
		{
			CPBStatus[cpbIndex].IsDown = FALSE;
		}
	}
}



