Перейти к содержанию
Old Phone Forum

Builder80

Стажёр
  • Постов

    9
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Builder80

  1. доделал файловую систему

     

    Spoiler

    //---------------------------------------------------------------------------
    
    #ifndef MainFormUH
    #define MainFormUH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <Buttons.hpp>
    #include <mmsystem.h>
    #include <inifiles.hpp>
    #include <Math.hpp>
    
    #include "VladList.h"
    
    #define WM_RECEIVED_BYTES WM_USER+1
    #define WM_WRITED_BYTES 		WM_USER+2
    #define WM_TIMEOUT								WM_USER+3
    #define WM_INFORMATION				WM_USER+4
    
    typedef DynamicArray<AnsiString> TTfsDirectories;
    typedef struct SFileData
    {
    	AnsiString FileName;
    	int FileSize;
    	BYTE *FileData;
    
    	__fastcall SFileData()
    	{
    			FileName = "";
    			FileSize = 0;
    			FileData = NULL;
    	}
    } TFileData;
    typedef DynamicArray<TFileData> TTfsFiles;
    
    typedef struct STfsData
    {
    	TTfsDirectories TfsDirectories;
    	TTfsFiles TfsFiles;
    	AnsiString TfsFileName;
    	AnsiString TfsVersion;
    
    	__fastcall STfsData()
    	{
    			TfsDirectories.Length = 0;
    			TfsFiles.Length = 0;
    			TfsFileName = "";
    			TfsVersion = "";
    	}
    } TTfsData;
    
    class TPortThread : public TThread
    {
    	public:
    			int FileHandle;
    			int FormHandle;
    			int State;
    			bool HaveTimeoutSign;
    			int ByteCount;
    			int LoaderCounter;
    			BYTE *LoaderData;
    			BYTE *BootLoaderData;
    			DWORD *CRCData;
    			bool PortClosed;
    			int PortNumber;
    			BYTE FileData[65536];
    			BYTE FileSum;
    			AnsiString SectorFileName;
    			DWORD SectorAddress;
    			TTfsData TfsData;
    			AnsiString NeedTfsFileName;				
    
    			__fastcall TPortThread(int FileHandle, int FormHandle, BYTE *LoaderData,
    							int PortNumber, BYTE *BootLoaderData, DWORD *CRCData);
    			__fastcall ~TPortThread();
    
    			void __fastcall Execute();
    
    			void __fastcall WriteDataToPort(BYTE *Buffer, int BufLen);
    			bool __fastcall LoadFileToMemCalcCRC(AnsiString FileName, DWORD &crc);
    			bool __fastcall LoadTfsData(AnsiString TfsFileName, DWORD &crc, BYTE &Sum);
    };
    
    class TMainForm : public TForm
    {
    __published:	// IDE-managed Components
    TComboBox *ComboBox1;
    TBitBtn *BitBtn1;
    TBitBtn *BitBtn2;
    TListBox *ListBox1;
    TListBox *ListBox2;
    TBitBtn *BitBtn3;
    TBitBtn *BitBtn4;
    TBitBtn *BitBtn5;
    TLabel *Label1;
    TListBox *ListBox3;
    void __fastcall BitBtn1Click(TObject *Sender);
    void __fastcall BitBtn2Click(TObject *Sender);
    void __fastcall BitBtn3Click(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    void __fastcall BitBtn4Click(TObject *Sender);
    void __fastcall BitBtn5Click(TObject *Sender);
    private:	// User declarations
    	int FileHandle;
    	TPortThread *port_thread;
    	BYTE LoaderData[1840];
    	BYTE BootLoaderData[189572];
    	DWORD CRCData[256];
    	AnsiString SaveFileName;
    
    	void __fastcall HaveReceivedData(TMessage &message);
    	void __fastcall HaveWrittenData(TMessage &message);
    	void __fastcall HaveTimeoutData(TMessage &message);
    	void __fastcall HaveInformationData(TMessage &message);		
    
    	void __fastcall LoadOptions();
    	void __fastcall SaveOptions();
    public:		// User declarations
    __fastcall TMainForm(TComponent* Owner);
    
    BEGIN_MESSAGE_MAP
    	MESSAGE_HANDLER(WM_RECEIVED_BYTES, TMessage, HaveReceivedData)
    	MESSAGE_HANDLER(WM_WRITED_BYTES, TMessage, HaveWrittenData)
    	MESSAGE_HANDLER(WM_TIMEOUT, TMessage, HaveTimeoutData)
    	MESSAGE_HANDLER(WM_INFORMATION, TMessage, HaveInformationData)
    END_MESSAGE_MAP(TControl)
    
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TMainForm *MainForm;
    //---------------------------------------------------------------------------
    #endif
    

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "MainFormU.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TMainForm *MainForm;
    
    void __fastcall ChangeBytesInDword(DWORD &data)
    {
    	BYTE *bytes = (BYTE*)&data;
    	BYTE temp;
    
    	temp = bytes[3];
    	bytes[3] = bytes[0];
    	bytes[0] = temp;
    
    	temp = bytes[2];
    	bytes[2] = bytes[1];
    	bytes[1] = temp;
    }
    
    void __fastcall ChangeBytesInWord(WORD &data)
    {
    	BYTE *bytes = (BYTE*)&data;
    	BYTE temp;
    
    	temp = bytes[0];
    	bytes[0] = bytes[1];
    	bytes[1] = temp;
    }
    
    __fastcall TMainForm::TMainForm(TComponent* Owner)
    : TForm(Owner)
    {
    	FileHandle = -1;
    	timeBeginPeriod(1);
    
    	AnsiString FileDir = ExtractFileDir(ParamStr(0)) + "\\";
    	SaveFileName = FileDir + "save.dat";
    	LoadOptions();
    
    	//проверим, что есть загрузчик
     bool NormalLoaderExists = false;
    	AnsiString LoaderFileName = FileDir + "loader.bin";
    	if (FileExists(LoaderFileName))
    	{
    			int LoaderHandle = FileOpen(LoaderFileName, fmOpenRead);
    			if (LoaderHandle > -1)
    			{
    					int LoaderSize = FileSeek(LoaderHandle, 0, 2);
    					if (LoaderSize == 1840)
    					{
    							FileSeek(LoaderHandle, 0, 0);
    
    							if (FileRead(LoaderHandle, LoaderData, LoaderSize) == LoaderSize)
    							{
    									NormalLoaderExists = true;
    							}
    					}
    					FileClose(LoaderHandle);
    			}
    	}
    
    	if (NormalLoaderExists)
    	{
    			AnsiString BootLoaderFileName = FileDir + "boot_loader.bin";
    			NormalLoaderExists = false;
    			if (FileExists(BootLoaderFileName))
    			{
    					int LoaderHandle = FileOpen(BootLoaderFileName, fmOpenRead);
    					if (LoaderHandle > -1)
    					{
    							int LoaderSize = FileSeek(LoaderHandle, 0, 2);
    							if (LoaderSize == 189572)
    							{
    									FileSeek(LoaderHandle, 0, 0);
    									if (FileRead(LoaderHandle, BootLoaderData, LoaderSize) == LoaderSize)
    									{
    											NormalLoaderExists = true;
    									}
    							}
    							FileClose(LoaderHandle);
    					}
    			}
    	}
    
    	if (NormalLoaderExists)
    	{
    			AnsiString CRCFileName = FileDir + "crc_data.bin";
    			NormalLoaderExists = false;
    			if (FileExists(CRCFileName))
    			{
    					int LoaderHandle = FileOpen(CRCFileName, fmOpenRead);
    					if (LoaderHandle > -1)
    					{
    							int LoaderSize = FileSeek(LoaderHandle, 0, 2);
    							if (LoaderSize == 1024)
    							{
    									FileSeek(LoaderHandle, 0, 0);
    									if (FileRead(LoaderHandle, CRCData, LoaderSize) == LoaderSize)
    									{
    											NormalLoaderExists = true;
    									}
    							}
    							FileClose(LoaderHandle);
    					}
    			}
    	}
    
    	if (!NormalLoaderExists)
    	{
    			BitBtn1->Enabled = false;
    			BitBtn2->Enabled = false;
    			BitBtn3->Enabled = false;
    
    			Caption = "Нет вторичного загрузчика";
    	}
    }
    
    void __fastcall TMainForm::LoadOptions()
    {
    	if (!FileExists(SaveFileName)) return;
    
    	TIniFile *ini = NULL;
    	try
    	{
    			ini = new TIniFile(SaveFileName);
    			ComboBox1->ItemIndex = ini->ReadInteger("Options", "com", 0);
    	}
    	__finally
    	{
    			if (ini) delete ini;
    	}
     return;
    }
    
    void __fastcall TMainForm::SaveOptions()
    {
    	if (FileExists(SaveFileName)) DeleteFile(SaveFileName);
    
    	TIniFile *ini = NULL;
    	try
    	{
    			ini = new TIniFile(SaveFileName);
    			ini->WriteInteger("Options", "com", ComboBox1->ItemIndex);
    	}
    	__finally
    	{
    			if (ini) delete ini;
    	}
    
    	return;
    }
    
    void __fastcall TMainForm::BitBtn1Click(TObject *Sender)
    {
    	bool res = false;
    
    	if (FileHandle > -1)
    	{
    			FileClose(FileHandle);
    	}
    
    	FileHandle = FileOpen("\\\\.\\COM" + IntToStr(ComboBox1->ItemIndex+1), fmOpenReadWrite);
    	if (FileHandle > -1)
    	{
    			DCB dcb;
    			if (GetCommState((void*)FileHandle, &dcb))
    			{
    					memset(&dcb, 0, sizeof(DCB));
    					dcb.DCBlength = sizeof(DCB);
    					dcb.BaudRate = 115200;//921600;
    					dcb.fBinary = 1;
    					dcb.fParity = 0;
    					dcb.fDtrControl = 0;
    					dcb.fRtsControl = 1;
    					dcb.XonLim = 0x1000;
    					dcb.XoffLim = 0x400;
    					dcb.ByteSize = 8;
    					dcb.Parity = EVENPARITY;//NOPARITY
    					dcb.StopBits = ONESTOPBIT;
    					dcb.XonChar = 0x11;
    					dcb.XoffChar = 0x13;
    
    					if (SetCommState((void*)FileHandle, &dcb))
    					{
    							COMMTIMEOUTS cm;
    							cm.ReadIntervalTimeout = MAXDWORD;
    							cm.ReadTotalTimeoutMultiplier = 0;//MAXDWORD;
    							cm.ReadTotalTimeoutConstant = 0;//1000;
    							cm.WriteTotalTimeoutMultiplier = 0;
    							cm.WriteTotalTimeoutConstant = 0;
    
    							if (SetCommTimeouts((void*)FileHandle, &cm))
    							{
           		SetupComm((void*)FileHandle, 0x2000, 0x2000);
    
    									port_thread = new TPortThread(FileHandle, (int)Handle, LoaderData,
    											ComboBox1->ItemIndex+1, BootLoaderData, CRCData);
    
    									res = true;
    							}
    					}
    			}
    
    			if (!res)
    			{
    					FileClose(FileHandle);
    					FileHandle = -1;
    			}
    
    			ComboBox1->Enabled = !res;
    			BitBtn1->Enabled = !res;
    			BitBtn2->Enabled = res;
    
    			ListBox1->Clear();
    
    			/////////////////////
    
    	}
    }
    //---------------------------------------------------------------------------
    void __fastcall TMainForm::BitBtn2Click(TObject *Sender)
    {
    	if (FileHandle > -1)
    	{
    			bool PortClosed = port_thread->PortClosed;
    			port_thread->Terminate();
    			port_thread->WaitFor();
    
    			try
    			{//может быть уже закрыт
    					if (!PortClosed)
    							FileClose(FileHandle);
    			}
    			catch (...)
    			{
    			}
    			FileHandle = -1;
    
    			ComboBox1->Enabled = true;
    			BitBtn1->Enabled = true;
    			BitBtn2->Enabled = false;
    	}
    }
    
    __fastcall TPortThread::TPortThread(int FileHandle, int FormHandle, BYTE *LoaderData,
    			int PortNumber, BYTE *BootLoaderData, DWORD *CRCData) :
    	TThread(false)
    {
    	this->FileHandle = FileHandle;
    	this->FormHandle = FormHandle;
    	this->LoaderData = LoaderData;
    	this->PortNumber = PortNumber;
    	this->BootLoaderData = BootLoaderData;
    	this->CRCData = CRCData;
    
     PortClosed = false;
    	State = 0;
    
    	HaveTimeoutSign = false;
    
    	SectorAddress = 0;
    	SectorFileName = "";
    
    	NeedTfsFileName = "";
    }
    
    __fastcall TPortThread::~TPortThread()
    {
    	//
    }
    
    void __fastcall TPortThread::Execute()
    {
    	BYTE Buffer[1000];
    	BYTE SendBuffer[1000];
     ByteCount = 0;
    	unsigned int StartTime = GetTickCount();
    	bool ClearBytes = false;
    	BYTE CRCByte;
    	int BootLoaderSended;
    	DWORD SectorCRC;
    	DWORD TfsCRC;
    	BYTE TfsSum;
    	int SectorPartNum;
    	int TfsSendNum;
    	int TfsSendCur;
    
    	BYTE header[] = {0x44, 0x12, 0x34, 0x56, 0x78,
    			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    	BYTE State4Data[] = {0x53, 0x00, 0x00, 0x00, 0x0C};
    	BYTE State7Data[] = {0x4A};
    	BYTE State8Data[] = {0x03};
    	BYTE State9Data[] = {0xD9};
    	BYTE State10Data[] = {0xB0};
    	BYTE State11Data[] = {0xD4, 0x00, 0x02, 0xE4, 0x84};
    	BYTE State12Data[] = {0xF7};
    	BYTE State14Data[] = {0xFF};
    	BYTE State15Data[] = {0xD0, 0x10, 0x00, 0x00, 0x00};
    	BYTE State16Data[] = {0xD1};
    	BYTE State18Data[] = {0xD9};
    	BYTE State19Data[] = {0xC8, 0x00, 0x00, 0x00, 0x00};
    	BYTE State20Data[] = {0xD3, 0x00, 0x00, 0x00, 0x00};
    	BYTE State21Data[] = {0xD4, 0x00, 0x00, 0x00, 0x00};
    	BYTE State22Data[] = {0xFA, 0x00, 0x00, 0x00, 0x00};
    	BYTE State23Data[] = {0xC6};
    	BYTE State25Data[] = {0xD9};
    	BYTE State26Data[] = {0xE0};
    	BYTE State27Data[] = {0xDA};
    	BYTE State28Data[] = {0xC9, 0x00, 0x00, 0x00, 0x00};
    	BYTE State29Data[] = {0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    	BYTE State33Data[] = {0xF6};
    	BYTE State35Data[] = {0xDD};
    	BYTE State37Data[] = {0xC5};
    	BYTE State38Data[] = {0xE4};
    	BYTE FlashId[] = {0xEC, 0x22, 0xFC};
    	BYTE LoaderWriteCommmands[] = {0x4C, 0x00, 0x00, 0x00, 0x00, 0x00};
    
    	BYTE *StatesAnswers[] = {NULL, NULL, NULL, NULL, State4Data, NULL, State4Data,
    			State7Data, State8Data, State9Data, State10Data, State11Data, State12Data, NULL,
    			State14Data, State15Data, State16Data, NULL, State18Data, State19Data,
    			State20Data, State21Data, State22Data, State23Data, NULL, State25Data,
    			State26Data, State27Data, State28Data, State29Data, NULL, NULL, NULL,
    			State33Data, NULL, State35Data, NULL, State37Data, State38Data};
    	int StatesAnswersLens[] = {0, 0, 0, 0, 5, 0, 5, 1, 1, 1, 1, 5, 1, 0, 1, 5, 1, 0, 1, 5,
    			5, 5, 5, 1, 0, 1, 1, 1, 5, 28, 0, 0, 0, 1, 0, 1, 0, 1, 1};
    
    	while (!Terminated)
    	{
    			while (FileRead(FileHandle, &Buffer[byteCount], 1) && (ByteCount < 990))//1000-ByteCount);
    			{
    					ByteCount ++;
    			}
    
    			if (ByteCount)
    			{
    					//поищем сигнатуру тайм аута
    					for (int i=0; i<ByteCount-8; i++)
    					{
    							if ((Buffer[i+0] == 0x49) &&
    											(Buffer[i+1] == 0x49) &&
    											(Buffer[i+2] == 0x49) &&
    											(Buffer[i+3] == 0x49) &&
    											(Buffer[i+4] == 0xFF) &&
    											(Buffer[i+5] == 0xFF) &&
    											(Buffer[i+6] == 0xFF) &&
    											(Buffer[i+7] == 0xFF))
    							{
    									HaveTimeoutSign = true;
    									State = 0;
    									ByteCount = 0;
    									break;
    							}
    					}
    
    					if (HaveTimeoutSign)
    					{
    							PostMessage((void*)FormHandle, WM_TIMEOUT, 0, 0);
    							return;
    					}
    
    					switch (State)
    					{
    							case 0:
    							{
    									for (int i=0; i<ByteCount; i++)
    									{
    											if (Buffer[i] == 0x81)
    											{
    													Sleep(10);
    													SendBuffer[0] = 0x44;
    													WriteDataToPort(SendBuffer, 1);
    													ClearBytes = true;
    													State = 1;
    													break;
    											}
    									}
    									break;
    							}
    							case 1:
    							{
    									for (int i=0; i<ByteCount; i++)
    									{
    											if (Buffer[i] == 0x44)
    											{
    													SendBuffer[0] = 0x51;
    													WriteDataToPort(SendBuffer, 1);
    													ClearBytes = true;
    													State = 2;
    													break;
    											}
    									}
    									break;
    							}
    							case 2:
    							{
    									if (ByteCount >= 16) //проверка что все нормально
    									{
    											memcpy(&header[5], &Buffer[byteCount-16], 16);
    											WriteDataToPort(header, 21);
    											State = 3;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 3:
    							{
    									if (Buffer[byteCount-1] == 0x4F) //если нормально ответил на
    											//наше подтверждение, выставляем таймаут 1600мс
    									{
    											SendBuffer[0] = 0x54;
    											SendBuffer[1] = 0x10;
    											WriteDataToPort(SendBuffer, 2);
    											State = 4;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 4: //{0x53, 0x00, 0x00, 0x00, 0x0C}; - выставить указатель памяти на 0x0C000000
    							{
    									if (Buffer[byteCount-1] == 0x4F)
    									{
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											State ++; //след состояние посылка загрузчика
    											LoaderCounter = 0; //указатель на начало
    											ClearBytes = true;												
    									}
    									break;
    							}
    							case 5://посылаем по 6 байт вторичный загрузчик
    							//первые 2 - 0x4C 0x00 - команда, след 4 - данные в память
    							//и так весь загрузчик по 4 байта и высылаем
    							{
    									if (Buffer[byteCount-1] == 0x4F)
    									{
               memcpy(&LoaderWriteCommmands[2], &LoaderData[LoaderCounter*4], 4);
    											WriteDataToPort(LoaderWriteCommmands, 6);
    
    											LoaderCounter ++;
    											if (LoaderCounter == 0x1CC)
    											{
    													State ++;
    											}
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 6://выставить указатель на начало загрузчика
    							{
    									if (Buffer[byteCount-1] == 0x4F)
    									{
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 7:
    							{
    									if (Buffer[byteCount-1] == 0x4F)
    									{//записали в порт 0x4A, - старт предзагрузчика(второго загрузчика)
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											State ++;
    											ClearBytes = true;										
    									}
    									break;
    							}
    							case 8:
    							{
    									if (Buffer[byteCount-1] == 0xAB)//такой д.б. ответ на старт предзагр
    									{//записали в порт 0x03, - номер нужной скорости 921600
    									//и сразу закрываем порт и открываем с нужной скоростью через 500 млс
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    
    											FileClose(FileHandle);
    											FileHandle = -1;
    											PortClosed = true;
    
    											Sleep(500);
    
    											//надо открыть порт
    											FileHandle = FileOpen("\\\\.\\COM" + IntToStr(PortNumber), fmOpenReadWrite);
    											if (FileHandle > -1)
    											{
    													DCB dcb;
    													if (GetCommState((void*)FileHandle, &dcb))
    													{
    															memset(&dcb, 0, sizeof(DCB));
    															dcb.DCBlength = sizeof(DCB);
    															dcb.BaudRate = 921600;
    															dcb.fBinary = 1;
    															dcb.fParity = 0;
    															dcb.fDtrControl = 0;
    															dcb.fRtsControl = 1;
    															dcb.XonLim = 0x1000;
    															dcb.XoffLim = 0x400;
    															dcb.ByteSize = 8;
    															dcb.Parity = NOPARITY;//EVENPARITY; //четность поменялась
    															dcb.StopBits = ONESTOPBIT;
    															dcb.XonChar = 0x11;
    															dcb.XoffChar = 0x13;
    
    															if (SetCommState((void*)FileHandle, &dcb))
    															{
    																	COMMTIMEOUTS cm;
    																	cm.ReadIntervalTimeout = MAXDWORD;
    																	cm.ReadTotalTimeoutMultiplier = 0;//MAXDWORD;
    																	cm.ReadTotalTimeoutConstant = 0;//1000;
    																	cm.WriteTotalTimeoutMultiplier = 0;
    																	cm.WriteTotalTimeoutConstant = 0;
    
    																	if (SetCommTimeouts((void*)FileHandle, &cm))
    																	{
    																			SetupComm((void*)FileHandle, 0x2000, 0x2000);
    																			PurgeComm((void*)FileHandle, PURGE_TXCLEAR|PURGE_RXCLEAR);
    
    																			PortClosed = false;
    
    																			//удалось нормально открыть порт
    																	}
    															}
    													}
    
    													if (PortClosed)
    													{
    															FileClose(FileHandle);
    															FileHandle = -1;
    													}
    											}
    
    											if (PortClosed)
    											{
    													PostMessage((void*)FormHandle, WM_TIMEOUT, 0, 1);
    													return;
    											}
    
    											//надо послать 0xD9 - запрос на скорость
    											State ++;
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											State ++;
    											ClearBytes = true;
    									}								
    									break;
    							}
    							case 9://зесь не будет его
    									break;
    							case 10:
    							{
    									if (Buffer[byteCount-1] == 0x03)
    									{
    											//получили, что правильная скорость
    											//шлем запрос 0xB0, в надежде получить 4 байта пока неясно чего
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 11:
    							{
    									if (ByteCount == 0x4) //были варианты 0x13 0x13 0x00 0x00, 0x13 0x53 0x00 0x00
    									{
    											//надо ответить командным байтом посылки длины и значением длины
    											//D4 00 02 E4 84, 2E484 - длина
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    
    											//надо запомнить CRC
    											CRCByte = 0;
    											for (int i=1; i<StatesAnswersLens[state]; i++)
    											{
    													CRCByte += StatesAnswers[state][i];
    											}
    
    											State ++;
    											ClearBytes = true;
    											BootLoaderSended = 0; //пока не послали ни одного байта										
    									}
    									break;
    							}
    							case 12:
    							{
    									//надо проверить, что телефон ответил правильное CRC на передачу
    									//ему длины загрузчика, который будем загружать
    									//это в начале, но потом переходим в этой процедуре
    									//на отправку всех данных загрузчика
    
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]); //послали 0xF7
    											CRCByte = 0xF7;
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 13:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //если телефон ответил нам 0xF7
    									{//как мы и ожидали
    											int CountBytesToSendNow = Min(0x800, 0x2E484-BootLoaderSended);
    
    											BYTE *DataToSend = &BootLoaderData[bootLoaderSended];
    											WriteDataToPort(DataToSend, CountBytesToSendNow); //послали кусок загрузчика
    
    											CRCByte = 0x00;
    											for (int i=0; i<CountBytesToSendNow; i++)
    											{
    													CRCByte += DataToSend[i];
    											}
    
    											BootLoaderSended += CountBytesToSendNow;
    											if (0x2E484 - BootLoaderSended > 0)
    											{
    													State = 12; //надо продолжить с посылкой загрузчика
    											}
    											else
    											{
    													State ++; //все, загрузчик готов
    											}
    
    											ClearBytes = true;
    									}
    
    									break;
    							}
    							case 14:
    							{
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											//все заебись загружено в телефон
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]); //послали 0xFF, окончание записи
    											CRCByte = 0xAB;//долюно вернуть
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 15:
    							{
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    													//послали 0xD0 0x10 0x00 0x00 0x00 - выбор блока памяти
    											CRCByte = 0x10;//должно вернуть подтверждение
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 16:
    							{
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    													//послали 0xD1 запрос на получение FlashID
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 17:
    							{
    									//надо проверить, что пришел корректный FlashId
    									if (ByteCount == 10)
    									{
    											//надо проверить, что 2,3,4 байты равны соответственно 0xEC 0x22 0xFC
    											if (!memcmp(FlashId, &Buffer[1], 3))
    											{
    													PostMessage((void*)FormHandle, WM_INFORMATION, 0, 0);
    											}
    
    											ClearBytes = true;
    											State ++;
    									}
    									break;
    							}
    							case 18://режим работы с телефоном, который уже
    															//загружен нормально
    															//проверяет не задан ли адрес по котрому надо класть данные
    							{
    									ClearBytes = true;
    									break;
    							}
    							case 19:
    							{
    									if (Buffer[byteCount-1] == CRCByte)//есть ответ 0 на D9
    									{
    											//шлем команду с CRC данных сектора
    											ChangeBytesInDword(SectorCRC);
    											memcpy(&State19Data[1], &SectorCRC, 4);
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    
    											CRCByte = 0x00;
    											for (int i=0; i<4; i++)
    											{
    													CRCByte += State19Data[i+1];
    											}
    
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 20:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //есть правильный ответ на
    									//контрольную сумму сектора, надо передать адрес
    									{
    											DWORD data = SectorAddress;
    											ChangeBytesInDword(data);
    											memcpy(&State20Data[1], &data, 4); //0xD3 0x01 0x24 0x00 0x00
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    
    											CRCByte = 0x00;
    											for (int i=0; i<4; i++)
    											{
    													CRCByte += State20Data[i+1];
    											}
    
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 21:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //есть правильный ответ на
    									//контрольную сумму адреса, надо передать размер данных
    									{
    											DWORD SectorSize = 0x00010000;
    											ChangeBytesInDword(SectorSize);
    											memcpy(&State21Data[1], &SectorSize, 4); //0xD4 0x00 0x01 0x00 0x00
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    
    											CRCByte = 0x00;
    											for (int i=0; i<4; i++)
    											{
    													CRCByte += State21Data[i+1];
    											}
    
    											State ++;
    											ClearBytes = true;
    									}
    									break;
    							}
    							case 22:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //есть правильный ответ на
    									//контрольную сумму размера, надо передать адрес начала сектора
    									{
    											DWORD data = SectorAddress;
    											ChangeBytesInDword(data);
    											memcpy(&State22Data[1], &data, 4); //0xFA 0x01 0x21 0x00 0x00
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    
    											//сразу переходим в состояние отправки данных сектора - 1-го блока
    											//потому break нет в конце
    											SectorPartNum = 0; //всего будет 0x20 частей - 0x800*0x20 = 65536
    
    											State ++;
    											ClearBytes = true;
    
    											SectorAddress = 0;
    											SectorFileName = "";
    									}
    									else
    									{
    											break; //!!!!!!!!!!!!!!!!!!!!
    									}
    							}
    							case 23:
    							{
    									if (SectorPartNum == 0x20)
    									{
    											if ((Buffer[byteCount-2] == CRCByte) && (Buffer[byteCount-1] == FileSum))
    											{//все, закончили посылку сектора, надо обменяться 0xC6
    													WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    													CRCByte = 0xC6;
    													State ++;
    													ClearBytes = true;
    											}												
    									}
    									else
    									{
    											if (Buffer[byteCount-1] == CRCByte)
    											{
    													WriteDataToPort(&FileData[sectorPartNum*0x800], 0x800);
    													SectorPartNum ++;
    													CRCByte = SectorPartNum;
    													ClearBytes = true;
    											}
    									}
    									break;
    							}
    							case 24:
    							{
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											//запись сектора окончена
    											State = 18;
               ClearBytes = true;
    									}
    									break;
    							}
    							case 25:
    							{//была послана команда выхода на связь 0xD9
    									break;
    							}
    							case 26:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //есть выход на связь
    									{//команда на формат файловой системы 0xE0
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											CRCByte = 0xE1; //ответ о том что все отформатировано через 3.5 сек
    											State ++;
    											ClearBytes = true;
    									}								
    									break;
    							}
    							case 27:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //файловая система отформатирована
    									{//команда на монтирование файловой системы 0xDA
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											CRCByte = 0xDA; //ответ о том что все смонтировано
    											State ++;
    											ClearBytes = true;
    									}													
    									break;
    							}
    							case 28:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //файловая система подключена
    									{//команда с контрольной суммой всей файловой системы
    											memcpy(&State28Data[1], &TfsCRC, 4);
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											CRCByte = 0;
    											for (int i=0; i<4; i++)
    											{
    													CRCByte += State28Data[1+i]; //ответ сумма контрольной суммы
    											}
    											State ++;
    											ClearBytes = true;
    									}													
    									break;
    							}
    							case 29:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //файловая система сумму получила
    									{//команда с текущей датой
    											unsigned short year, month, day, hour, min, sec, mlsec;
    											DWORD  dyear, dmonth, dday, dhour, dmin, dsec;
    											TDateTime date = Now();
    											date.DecodeDate(&year, &month, &day);
    											date.DecodeTime(&hour, &min, &sec, &mlsec);
    											dyear = year; dmonth = month;
    											dday = day; dhour = hour; dmin = min;
    											dsec = sec;
    
    											memcpy(&State29Data[4], &dsec, 4);
    											memcpy(&State29Data[8], &dmin, 4);
    											memcpy(&State29Data[12], &dhour, 4);
    											memcpy(&State29Data[16], &dday, 4);
    											memcpy(&State29Data[20], &dmonth, 4);
    											memcpy(&State29Data[24], &dyear, 4);																																																
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											CRCByte = 0;
    											for (int i=4; i<28; i++)
    											{
    													CRCByte += State29Data[i]; //ответ сумма контрольной суммы
    											}
    											State ++;
    											ClearBytes = true;
    									}								
    									break;
    							}
    							case 30:
    							{
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											//надо начинать писать папки
    											//свалимся просто в седующее состояние
    											State ++;
    											ClearBytes = true;
    
               TfsSendNum = 0;
    
    											ByteCount ++; //сделаем необходимые условия для работы след состояния
               Buffer[byteCount-1] = 0xDC;
    									}
    									else
    									{
    											break; //!!!!!!!!!!!!!!!!!!!
    									}
    							}
    							case 31:
    							{
    									if ((ByteCount > 1) && (Buffer[byteCount-2] == CRCByte) &&
    													(Buffer[byteCount-1] == 0xDC)) //посылка команд на создание папок
    													//0xDB 2byte длины вместе с 0 в конце nbyte названия папки и 0 в конце
    													//нет проверки на допустимую длину папки, авось и так сойдет
    									{
    									  //есть нормальный ответ на создание папки
    											ClearBytes = true;
    
    											if (TfsSendNum < TfsData.TfsDirectories.Length)
    											{
    													//еще есть папки не отосланные
    													int NumBytesNeeded = 3 + TfsData.TfsDirectories[TfsSendNum].Length() + 1;
    													BYTE *Data = NULL;
    													try
    													{
    															Data = new BYTE[NumBytesNeeded];
    															Data[0] = 0xDB;
    															WORD len = TfsData.TfsDirectories[TfsSendNum].Length()+1;
    															ChangeBytesInWord(len);
    															memcpy(&Data[1], &len, 2);
    															memcpy(&Data[3], TfsData.TfsDirectories[TfsSendNum].c_str(),
    																	TfsData.TfsDirectories[TfsSendNum].Length());
    															Data[NumBytesNeeded-1] = 0;
    
    															WriteDataToPort(Data, NumBytesNeeded);
    
    															CRCByte = 0;
    															for (int i=1; i<NumBytesNeeded; i++)
    															{
    																	CRCByte += Data[i];
    															}
    													}
    													catch (...)
    													{
    													}
    													if (Data) delete [] Data;
    
    													TfsSendNum ++;
    													break;
    											}
    											else
    											{
    													//все отослано, надо свалиться в след состояние
    													State ++;
    											}
    									}
    									else break;
    							}
    							case 32:
    							{
    									//надо послать версию файловой системы
    									//0xE3 и данные из cfg файла файловой системы
    									//TFSVERSION : TFS4.0_CORONA_01
    									BYTE E3Byte = 0xE3;
    									WriteDataToPort(&E3Byte, 1);
    									WriteDataToPort(TfsData.TfsVersion.c_str(),
    											TfsData.TfsVersion.Length());
    									State ++;
    									ClearBytes = true;
    									CRCByte = 0xE3;
    
    									break;
    							}
    							case 33:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //версию отправили
    									{//команда 0xF6
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											CRCByte = 0xE3; //ответ должен быть 0xE3
    											State ++;
    											ClearBytes = true;
    									}
    
    									break;
    							}
    							case 34:
    							{
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											//все нормально, надо начинать запись файлов...
    											TfsSendNum = 0;//номер файла
    											TfsSendCur = 0;//количество закаченных байт
    											State ++;
    											ClearBytes = true;
    
    											/*
    закачка файлов:
    	- 0xDD 2 байта длина имени(перев), с 0 в конце вкл, имя, 0, 4 байта размер файла(перев)
    	на это ответ - сумма
    	- 0xFE кусок файла не больше 0x2000
    	на это ответ или сумма, если файл еще не весь или 0xDF если все нормально создано
    											*/
    									}
    									else
    									{
    											break;
    									}
    							}
    							case 35:
    							{
    									//здесь идет посылка названий файлов
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											if (TfsSendNum < TfsData.TfsFiles.Length)
    											{
    													TfsSendNum ++;
    													WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);//0xDD
    													WORD len = TfsData.TfsFiles[TfsSendNum-1].FileName.Length()+1;
    													ChangeBytesInWord(len);
    													CRCByte = 0;
    													for (int i=0; i<2; i++) CRCByte += ((BYTE*)&len)[i];
    													WriteDataToPort((BYTE*)&len, 2);//длина названия
    													for (int i=0; i<TfsData.TfsFiles[TfsSendNum-1].FileName.Length(); i++)
    															CRCByte += TfsData.TfsFiles[TfsSendNum-1].FileName[i+1];
    													WriteDataToPort(TfsData.TfsFiles[TfsSendNum-1].FileName.c_str(), TfsData.TfsFiles[TfsSendNum-1].FileName.Length());
    													BYTE zbyte = 0;
    													WriteDataToPort(&zbyte, 1);
    													DWORD fsize = TfsData.TfsFiles[TfsSendNum-1].FileSize;
    													ChangeBytesInDword(fsize);
    													for (int i=0; i<4; i++) CRCByte += ((BYTE*)&fsize)[i];
    													WriteDataToPort((BYTE*)&fsize, 4);
    
    													State ++;
    													ClearBytes = true;
    											}
    											else
    											{
    													//все файлы готовы...
    													//!!!!!!!!!!!!!!!!
    													State = 37;//надо как-то перевести его туда
    													WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    													CRCByte = 0xC5;
    													ClearBytes = true;
    													State ++;
    											}
    									}
    									else
    									{
    											int *Data = new int[4];
    											Data[0] = TfsSendNum;
    											Data[1] = TfsSendCur;
    											Data[2] = Buffer[byteCount-1];
    											Data[3] = CRCByte;
               PostMessage((void*)FormHandle, WM_TIMEOUT, (int)Data, 3);
    									}
    									break;
    							}
    							case 36:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //надо скидывать файл
    									{
    											int SendSize = Min(0x2000, TfsData.TfsFiles[TfsSendNum-1].FileSize-TfsSendCur);
    											CRCByte = 0;
    											for (int i=0; i<SendSize; i++) CRCByte += TfsData.TfsFiles[TfsSendNum-1].FileData[TfsSendCur+i];
    											BYTE FEbyte = 0xFE;
    											WriteDataToPort(&FEbyte, 1);
    											WriteDataToPort(&TfsData.TfsFiles[TfsSendNum-1].FileData[TfsSendCur], SendSize);
    
    											TfsSendCur += SendSize;
    
    											///////////
    											int *Data = new int[3];
    											Data[0] = TfsSendNum;
    											Data[1] = TfsSendCur;
    											Data[2] = TfsData.TfsFiles[TfsSendNum-1].FileSize;
    											PostMessage((void*)FormHandle, WM_INFORMATION, (int)Data, 3);
    											///////////
    
    											if (TfsSendCur == TfsData.TfsFiles[TfsSendNum-1].FileSize)
    											{
    													//все записали файл
    													TfsSendCur = 0;
    
    													//надо проверить, если длина файла кратна 0x2000 надо crc
    													//взять посчитанную, а не 0xDF
    													if (TfsData.TfsFiles[TfsSendNum-1].FileSize % 0x2000)
    													{
    															CRCByte = 0xDF;
                 }
    													State = 35;
    
    													PostMessage((void*)FormHandle, WM_INFORMATION, TfsSendNum, 2);
    													Sleep(40);
    											}
    
    											ClearBytes = true;
    									}
    									else
    									{
    											int *Data = new int[4];
    											Data[0] = TfsSendNum;
    											Data[1] = TfsSendCur;
    											Data[2] = Buffer[byteCount-1];
    											Data[3] = CRCByte;
               PostMessage((void*)FormHandle, WM_TIMEOUT, (int)Data, 4);												
    									}
    									break;
    							}
    							case 37:
    							{
    									break;
    							}
    							case 38:
    							{
    									if (Buffer[byteCount-1] == CRCByte) //С5 получили, шлем E4
    									{//команда 0xE4
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											CRCByte = 0xE4;
    											State ++;
    											ClearBytes = true;
    									}										
    									break;
    							}
    							case 39:
    							{
    									if (Buffer[byteCount-1] == CRCByte)
    									{
    											State = 18; //все заебись
    											ClearBytes = true;
    											PostMessage((void*)FormHandle, WM_INFORMATION, 0, 1);
    									}
    									break;
    							}
    					}
    			}
    			else
    			{
    					if (SectorAddress && (State == 18))
    					{
    							//передан адрес по которому надо положить файл
    							if (LoadFileToMemCalcCRC(SectorFileName, SectorCRC))
    							{
    									CRCByte = 0x00; //шлем ему байт 0xD9, ждем ответ 0x00
    									WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    									State = 19;
    							}
    							else
    							{
    									SectorAddress = 0;
    									SectorFileName = "";
    									PostMessage((void*)FormHandle, WM_TIMEOUT, 0, 2);
    							}
    					}
    					else
    					{
    							if ((NeedTfsFileName != "") && (State == 18))
    							{
    									//надо залить в телефон файловую систему
    									if (LoadTfsData(NeedTfsFileName, TfsCRC, TfsSum))
    									{
    											//надо послать байт выходи на связь 0xD9
    											State = 25;
    											WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);
    											CRCByte = 0x00;	//ждем ответ на команду выхода на связь 0x00
    											State ++;
    									}
    									else
    									{
    											PostMessage((void*)FormHandle, WM_TIMEOUT, 0, 3);
    									}
    
    									NeedTfsFileName = "";
    							}
    					}
    			}
    
    			if ((ByteCount > 900) || ((GetTickCount() - StartTime > 2000) && (ByteCount > 0)) ||
    					ClearBytes)
    			{
    					BYTE *Data = new BYTE[byteCount];
    					memcpy(Data, Buffer, ByteCount);
    					PostMessage((void*)FormHandle, WM_RECEIVED_BYTES, (int)Data, ByteCount);
    
    					ClearBytes = false;
    					ByteCount = 0;
    					StartTime = GetTickCount();
    			}
    
    			if (ClearBytes)
    			{
    					ClearBytes = false;
    					ByteCount = 0;
    			}
    
    			if (State >  Sleep(10);
    			Sleep(1);
    	}
    
    	return;
    }
    
    void __fastcall TPortThread::WriteDataToPort(BYTE *Buffer, int BufLen)
    {
    	if (FileHandle > -1)
    	{
    			FileWrite(FileHandle, Buffer, BufLen);
    
    			BYTE *Data = new BYTE[bufLen];
    			memcpy(Data, Buffer, BufLen);
    			PostMessage((void*)FormHandle, WM_WRITED_BYTES, (int)Data, BufLen);
    	}
    	return;
    }
    
    bool __fastcall TPortThread::LoadFileToMemCalcCRC(AnsiString FileName, DWORD &crc)
    {
    	bool res = false;
    
    	if (FileExists(FileName))
    	{
    			int LoadFileHandle = FileOpen(FileName, fmOpenRead);
    			if (LoadFileHandle > -1)
    			{
    					if (FileSeek(LoadFileHandle, 0, 2) == 65536)
    					{
    							FileSeek(LoadFileHandle, 0, 0);
    							//int read = FileRead(LoadFileHandle, FileData, 65536);
    							if (FileRead(LoadFileHandle, FileData, 65536) == 65536)
    							{
    									res = true;
    
    									crc = 0xFFFFFFFF;
    									DWORD td;
    									BYTE curb;
    									BYTE sum = 0;
    									for (int i=0; i<65536; i++)
    									{
    											td = crc;
    											curb = FileData[i];
    											td &= 0xFF; //младший байт crc
    											td ^= curb; //xor младшего байта crc с новым байтом
    											crc >>= 8;  //сдвигаем вправо на 8 бит
    
    											//td надо получить данные на основе td - получится 4 байта
    											td = CRCData[td];
    
    											crc ^= td;
    
    											sum += FileData[i];
    									}
    									crc = ~crc;
    									FileSum = sum;
    							}
    					}
    					FileClose(LoadFileHandle);
    			}
    	}
    
    	return res;
    }
    
    bool __fastcall TPortThread::LoadTfsData(AnsiString TfsFileName, DWORD &crc, BYTE &Sum)
    {
    	bool res = false;
    
    	if (TfsFileName != TfsData.TfsFileName)
    	{
    			TfsData.TfsDirectories.Length = 0;
    			if (TfsData.TfsFiles.Length)
    			{
    					//надо удалить данные						
    					for (int i=0; i<TfsData.TfsFiles.Length; i++)
    					{
    							if (TfsData.TfsFiles[i].FileData)
    							{
    									delete [] TfsData.TfsFiles[i].FileData;
    							}
    					}
    					TfsData.TfsFiles.Length = 0;
    			}
    			TfsData.TfsFileName = "";
    
    			//все, загружаем
    			AnsiString CfgFileName;
    			try
    			{
    					CfgFileName = ExtractFileDir(TfsFileName) + "\\";
    					AnsiString TempFileName	=	ExtractFileName(TfsFileName);
    					TempFileName = TempFileName.Delete(TempFileName.Length()-3+1, 3) + "cfg";
    					CfgFileName += TempFileName;
    			}
    			catch (...)
    			{
    			  CfgFileName = "";
    			}
    
    			if (FileExists(CfgFileName))
    			{
    					int FileHandle = FileOpen(CfgFileName, fmOpenRead);
    					if (FileHandle > -1)
    					{
    							int FileSize = FileSeek(FileHandle, 0, 2);
    							if (FileSize)
    							{
    									FileSeek(FileHandle, 0, 0);
    
    									BYTE *Data = NULL;
    									try
    									{
               Data = new BYTE[FileSize+1];
    											if (FileRead(FileHandle, Data, FileSize) == FileSize)
    											{
    													Data[FileSize] = 0;
    													TVladStringList *CfgData = new TVladStringList();
    													CfgData->Delimiter = "\r\n";
    													CfgData->SetDelimitedText((char*)Data);
                 AnsiString CurStr;
    
    													TVladStringList *TempData = new TVladStringList();
    													TempData->Delimiter = " : ";
    													for (int i=0; i<CfgData->Strings->Count; i++)
    													{
    															CurStr = CfgData->Strings->Strings[i];
    															if (CurStr.Length())
    															{
    																	if (CurStr[1] == '#') continue;
    
    																	TempData->SetDelimitedText(CurStr);
    																	if (TempData->Strings->Count == 2)
    																	{
    																			if (TempData->Strings->Strings[0] == "DIR_NAME")
    																			{
    																					TfsData.TfsDirectories.Length ++;
    																					TfsData.TfsDirectories[
    																							TfsData.TfsDirectories.Length-1] =
    																									TempData->Strings->Strings[1];
    																			}
    																			else
    																			{
    																					if (TempData->Strings->Strings[0] == "FILE_NAME")
    																					{
    																							TfsData.TfsFiles.Length ++;
    																							TfsData.TfsFiles[TfsData.TfsFiles.Length-1].FileName =
    																									TempData->Strings->Strings[1];
    																					}
    																					else
    																					{
    																							if (TempData->Strings->Strings[0] == "FILE_SIZE")
    																							{
    																									if (TfsData.TfsFiles.Length > 0)
    																									{
    																											if (TfsData.TfsFiles[TfsData.TfsFiles.Length-1].
    																													FileSize == 0)
    																											{
    																													try
    																													{
    																															TfsData.TfsFiles[TfsData.TfsFiles.Length-1].FileSize =
    																																	StrToInt(TempData->Strings->Strings[1]);
    																													}
    																													catch (...)
    																													{
    																															TfsData.TfsFiles[TfsData.TfsFiles.Length-1].FileSize = 0;
    																													}
    																											}
    																									}
    																							}
    																							else
    																							{
    																									if (TempData->Strings->Strings[0] == "TFSVERSION")
    																									{
    																											TfsData.TfsVersion = TempData->Strings->Strings[1];
    																									}
    																							}
    																					}
    																			}
    																	}
    															}
    													}
    
    													delete TempData;
    													delete CfgData;
    											}
    									}
    									catch (...)
    									{
    											if (Data)
    											{
    													delete [] Data;
    													Data = NULL;
    											}
    									}
    							}
    
    							FileClose(FileHandle);
    					}
    			}
    
    			if (FileExists(TfsFileName) && TfsData.TfsDirectories.Length &&
    					TfsData.TfsFiles.Length)
    			{
    					int FileHandle = FileOpen(TfsFileName, fmOpenRead);
    					if (FileHandle > -1)
    					{
    							int FileSize = FileSeek(FileHandle, 0, 2);
    
    							int NeedFileSize = 0;
    							for (int i=0; i<TfsData.TfsFiles.Length; i++)
    							{
    									NeedFileSize += TfsData.TfsFiles[i].FileSize;
    							}
    
    							if (NeedFileSize == FileSize)
    							{
    									//длина которая нужна совпала с тем что есть
    									FileSeek(FileHandle, 0, 0);
    
    									for (int i=0; i<TfsData.TfsFiles.Length; i++)
    									{
    											TfsData.TfsFiles[i].FileData = new BYTE[TfsData.TfsFiles[i].FileSize];
    
    											if (FileRead(FileHandle,
    													TfsData.TfsFiles[i].FileData,
    													TfsData.TfsFiles[i].FileSize) != TfsData.TfsFiles[i].FileSize)
    											{
    													break;
    											}
    
    											if (i == TfsData.TfsFiles.Length-1)
    											{
    													TfsData.TfsFileName = TfsFileName;
    													res = true;
    
    
    													/////CRC Calculation/////
    													crc = 0xFFFFFFFF;
    													DWORD td;
    													BYTE curb;
    													Sum = 0;
    													for (int i=0; i<TfsData.TfsFiles.Length; i++)
    													{
    															for (int m=0; m<TfsData.TfsFiles[i].FileSize; m++)
    															{
    																	td = crc;
    																	curb = TfsData.TfsFiles[i].FileData[m];
    																	td &= 0xFF; //младший байт crc
    																	td ^= curb; //xor младшего байта crc с новым байтом
    																	crc >>= 8;  //сдвигаем вправо на 8 бит
    
    																	//td надо получить данные на основе td - получится 4 байта
    																	td = CRCData[td];
    
    																	crc ^= td;
    
    																	Sum += TfsData.TfsFiles[i].FileData[m];
    															}
    													}
    													crc = ~crc;
                 ChangeBytesInDword(crc);
    													//End crc calculation/////
    											}
    									}
    							}
    
    							FileClose(FileHandle);
    					}
    			}
    	}
    	else
    	{
    			res = true;
    	}
    
    	return res;
    }
    
    void __fastcall TMainForm::HaveInformationData(TMessage &message)
    {
    	switch (message.LParam)
    	{
    			case 0:
    					MessageBox(Handle, "Нормально прошла загрузка загрузчика )", "Все нормально", MB_ICONINFORMATION|MB_OK);
    					break;
    			case 1:
    					MessageBox(Handle, "Нормально загрузили файловую систему", "Все нормально", MB_ICONINFORMATION|MB_OK);				
    					break;
    			case 2:
    					Label1->Caption = IntToStr(message.WParam) + " 100%";
    					break;
    			case 3:
    			{
    			  int *Data = (int*)message.WParam;
    					Label1->Caption = IntToStr(Data[0]) + "  " +
    							IntToStr(int(float(Data[1])*100.0/float(Data[2]))) + "%";
    					delete [] Data;
    					break;
    			}
    	}
     return;
    }
    
    void __fastcall TMainForm::HaveTimeoutData(TMessage &message)
    {
    	switch (message.LParam)
    	{
    			case 0:
    					BitBtn2Click(NULL);
    					MessageBox(Handle, "Превышен интервал ожидания ответа, тел дал отказ", "Ошибка", MB_ICONERROR|MB_OK);
    					break;
    			case 1:
    					MessageBox(Handle, "Не удалось перейти на новую скорость", "Ошибка", MB_ICONERROR|MB_OK);
    					break;
    			case 2:
    					MessageBox(Handle, "Не удалось загрузить файл", "Ошибка", MB_ICONERROR|MB_OK);
    					break;
    			case 3:
    			{
    					int *Data = (int*)message.WParam;
    					ListBox3->Items->Add("new file - num " + IntToStr(Data[0]) + " pos " + IntToStr(Data[1]) + ", " +
    							IntToStr(Data[2]) + " <> " + IntToStr(Data[3]));
    					delete [] Data;
    					break;
    			}
    			case 4:
    			{
    					int *Data = (int*)message.WParam;
    					ListBox3->Items->Add("cur file " + IntToStr(Data[0]) + " pos " + IntToStr(Data[1]) + ", " +
    							IntToStr(Data[2]) + " <> " + IntToStr(Data[3]));
    					delete [] Data;
    					break;
    			}
    	}
     return;
    }
    
    void __fastcall TMainForm::HaveReceivedData(TMessage &message)
    {
    	BYTE *Data = (BYTE*)message.WParam;
    	message.WParam = 0;
    	int ByteCount = (int)message.LParam;
    
    	AnsiString str = "";
    	for (int i=0; i<ByteCount; i++)
    	{
    			str += IntToHex(Data[i], 2) + " ";
    	}
    	//ListBox1->Items->Add(str);
    
    	delete [] Data;
    
     return;
    }
    
    void __fastcall TMainForm::HaveWrittenData(TMessage &message)
    {
    	BYTE *Data = (BYTE*)message.WParam;
    	message.WParam = 0;
    	int ByteCount = (int)message.LParam;
    
    	AnsiString str = "";
    	for (int i=0; i<ByteCount; i++)
    	{
    			str += IntToHex(Data[i], 2) + " ";
    	}
    	//ListBox2->Items->Add(str);
    
    	delete [] Data;
    
    	return;
    }
    
    void __fastcall TMainForm::BitBtn3Click(TObject *Sender)
    {
    	port_thread->State = 0;
    	port_thread->ByteCount = 0;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
    {
     SaveOptions();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::BitBtn4Click(TObject *Sender)
    {
    	//надо попросить поток послать данные
    	if (port_thread)
    	{
    			port_thread->SectorFileName = "c:\\Programs\\CBuilder\\D900Flasher\\1172.hex";
    			port_thread->SectorAddress = 0x01720000;
    	}
    	return;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::BitBtn5Click(TObject *Sender)
    {
    	if (port_thread)
    	{
    			port_thread->NeedTfsFileName = "c:\\Programs\\CBuilder\\D900Flasher\\tfs\\D900XEGA1.tfs";
    	}
    }
    //---------------------------------------------------------------------------
    

     

    Комментарий модератора dimastyj
    Попрятал я листинги! Не осилил колесико_крутить :ad:
    • Like 1
  2. привет, надо было написать прошивальщик самсунга - копался копался в поисках исходников, ничего не нашел, наваял пока загрузку и залитие сектора, загрузку файловой системы копаю сейчас, если кому любопытно...

     

    Spoiler

    ----------------------------------------------------------------------

    //---------------------------------------------------------------------------

     

    #include <vcl.h>

    #pragma hdrstop

     

    #include "MainFormU.h"

    //---------------------------------------------------------------------------

    #pragma package(smart_init)

    #pragma resource "*.dfm"

    TMainForm *MainForm;

     

    void __fastcall ChangeBytesInDword(DWORD &data)

    {

    BYTE *bytes = (BYTE*)&data;

    BYTE temp;

     

    temp = bytes[3];

    bytes[3] = bytes[0];

    bytes[0] = temp;

     

    temp = bytes[2];

    bytes[2] = bytes[1];

    bytes[1] = temp;

    }

     

    __fastcall TMainForm::TMainForm(TComponent* Owner)

    : TForm(Owner)

    {

    FileHandle = -1;

    timeBeginPeriod(1);

     

    AnsiString FileDir = ExtractFileDir(ParamStr(0)) + "\\";

    SaveFileName = FileDir + "save.dat";

    LoadOptions();

     

    //проверим, что есть загрузчик

    bool NormalLoaderExists = false;

    AnsiString LoaderFileName = FileDir + "loader.bin";

    if (FileExists(LoaderFileName))

    {

    int LoaderHandle = FileOpen(LoaderFileName, fmOpenRead);

    if (LoaderHandle > -1)

    {

    int LoaderSize = FileSeek(LoaderHandle, 0, 2);

    if (LoaderSize == 1840)

    {

    FileSeek(LoaderHandle, 0, 0);

     

    if (FileRead(LoaderHandle, LoaderData, LoaderSize) == LoaderSize)

    {

    NormalLoaderExists = true;

    }

    }

    FileClose(LoaderHandle);

    }

    }

     

    if (NormalLoaderExists)

    {

    AnsiString BootLoaderFileName = FileDir + "boot_loader.bin";

    NormalLoaderExists = false;

    if (FileExists(BootLoaderFileName))

    {

    int LoaderHandle = FileOpen(BootLoaderFileName, fmOpenRead);

    if (LoaderHandle > -1)

    {

    int LoaderSize = FileSeek(LoaderHandle, 0, 2);

    if (LoaderSize == 189572)

    {

    FileSeek(LoaderHandle, 0, 0);

    if (FileRead(LoaderHandle, BootLoaderData, LoaderSize) == LoaderSize)

    {

    NormalLoaderExists = true;

    }

    }

    FileClose(LoaderHandle);

    }

    }

    }

     

    if (NormalLoaderExists)

    {

    AnsiString CRCFileName = FileDir + "crc_data.bin";

    NormalLoaderExists = false;

    if (FileExists(CRCFileName))

    {

    int LoaderHandle = FileOpen(CRCFileName, fmOpenRead);

    if (LoaderHandle > -1)

    {

    int LoaderSize = FileSeek(LoaderHandle, 0, 2);

    if (LoaderSize == 1024)

    {

    FileSeek(LoaderHandle, 0, 0);

    if (FileRead(LoaderHandle, CRCData, LoaderSize) == LoaderSize)

    {

    NormalLoaderExists = true;

    }

    }

    FileClose(LoaderHandle);

    }

    }

    }

     

    if (!NormalLoaderExists)

    {

    BitBtn1->Enabled = false;

    BitBtn2->Enabled = false;

    BitBtn3->Enabled = false;

     

    Caption = "Нет вторичного загрузчика";

    }

    }

     

    void __fastcall TMainForm::LoadOptions()

    {

    if (!FileExists(SaveFileName)) return;

     

    TIniFile *ini = NULL;

    try

    {

    ini = new TIniFile(SaveFileName);

    ComboBox1->ItemIndex = ini->ReadInteger("Options", "com", 0);

    }

    __finally

    {

    if (ini) delete ini;

    }

    return;

    }

     

    void __fastcall TMainForm::SaveOptions()

    {

    if (FileExists(SaveFileName)) DeleteFile(SaveFileName);

     

    TIniFile *ini = NULL;

    try

    {

    ini = new TIniFile(SaveFileName);

    ini->WriteInteger("Options", "com", ComboBox1->ItemIndex);

    }

    __finally

    {

    if (ini) delete ini;

    }

     

    return;

    }

     

    void __fastcall TMainForm::BitBtn1Click(TObject *Sender)

    {

    bool res = false;

     

    if (FileHandle > -1)

    {

    FileClose(FileHandle);

    }

     

    FileHandle = FileOpen("\\\\.\\COM" + IntToStr(ComboBox1->ItemIndex+1), fmOpenReadWrite);

    if (FileHandle > -1)

    {

    DCB dcb;

    if (GetCommState((void*)FileHandle, &dcb))

    {

    memset(&dcb, 0, sizeof(DCB));

    dcb.DCBlength = sizeof(DCB);

    dcb.BaudRate = 115200;//921600;

    dcb.fBinary = 1;

    dcb.fParity = 0;

    dcb.fDtrControl = 0;

    dcb.fRtsControl = 1;

    dcb.XonLim = 0x1000;

    dcb.XoffLim = 0x400;

    dcb.ByteSize = 8;

    dcb.Parity = EVENPARITY;//NOPARITY

    dcb.StopBits = ONESTOPBIT;

    dcb.XonChar = 0x11;

    dcb.XoffChar = 0x13;

     

    if (SetCommState((void*)FileHandle, &dcb))

    {

    COMMTIMEOUTS cm;

    cm.ReadIntervalTimeout = MAXDWORD;

    cm.ReadTotalTimeoutMultiplier = 0;//MAXDWORD;

    cm.ReadTotalTimeoutConstant = 0;//1000;

    cm.WriteTotalTimeoutMultiplier = 0;

    cm.WriteTotalTimeoutConstant = 0;

     

    if (SetCommTimeouts((void*)FileHandle, &cm))

    {

    SetupComm((void*)FileHandle, 0x2000, 0x2000);

     

    port_thread = new TPortThread(FileHandle, (int)Handle, LoaderData,

    ComboBox1->ItemIndex+1, BootLoaderData, CRCData);

     

    res = true;

    }

    }

    }

     

    if (!res)

    {

    FileClose(FileHandle);

    FileHandle = -1;

    }

     

    ComboBox1->Enabled = !res;

    BitBtn1->Enabled = !res;

    BitBtn2->Enabled = res;

     

    ListBox1->Clear();

     

    /////////////////////

     

    }

    }

    //---------------------------------------------------------------------------

    void __fastcall TMainForm::BitBtn2Click(TObject *Sender)

    {

    if (FileHandle > -1)

    {

    bool PortClosed = port_thread->PortClosed;

    port_thread->Terminate();

    port_thread->WaitFor();

     

    try

    {//может быть уже закрыт

    if (!PortClosed)

    FileClose(FileHandle);

    }

    catch (...)

    {

    }

    FileHandle = -1;

     

    ComboBox1->Enabled = true;

    BitBtn1->Enabled = true;

    BitBtn2->Enabled = false;

    }

    }

     

    __fastcall TPortThread::TPortThread(int FileHandle, int FormHandle, BYTE *LoaderData,

    int PortNumber, BYTE *BootLoaderData, DWORD *CRCData) :

    TThread(false)

    {

    this->FileHandle = FileHandle;

    this->FormHandle = FormHandle;

    this->LoaderData = LoaderData;

    this->PortNumber = PortNumber;

    this->BootLoaderData = BootLoaderData;

    this->CRCData = CRCData;

     

    PortClosed = false;

    State = 0;

     

    HaveTimeoutSign = false;

     

    SectorAddress = 0;

    SectorFileName = "";

    }

     

    __fastcall TPortThread::~TPortThread()

    {

    //

    }

     

    void __fastcall TPortThread::Execute()

    {

    BYTE Buffer[1000];

    BYTE SendBuffer[1000];

    ByteCount = 0;

    unsigned int StartTime = GetTickCount();

    bool ClearBytes = false;

    BYTE CRCByte;

    int BootLoaderSended;

    DWORD SectorCRC;

    int SectorPartNum;

     

    BYTE header[] = {0x44, 0x12, 0x34, 0x56, 0x78,

    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    BYTE State4Data[] = {0x53, 0x00, 0x00, 0x00, 0x0C};

    BYTE State7Data[] = {0x4A};

    BYTE State8Data[] = {0x03};

    BYTE State9Data[] = {0xD9};

    BYTE State10Data[] = {0xB0};

    BYTE State11Data[] = {0xD4, 0x00, 0x02, 0xE4, 0x84};

    BYTE State12Data[] = {0xF7};

    BYTE State14Data[] = {0xFF};

    BYTE State15Data[] = {0xD0, 0x10, 0x00, 0x00, 0x00};

    BYTE State16Data[] = {0xD1};

    BYTE State18Data[] = {0xD9};

    BYTE State19Data[] = {0xC8, 0x00, 0x00, 0x00, 0x00};

    BYTE State20Data[] = {0xD3, 0x00, 0x00, 0x00, 0x00};

    BYTE State21Data[] = {0xD4, 0x00, 0x00, 0x00, 0x00};

    BYTE State22Data[] = {0xFA, 0x00, 0x00, 0x00, 0x00};

    BYTE State23Data[] = {0xC6};

    BYTE FlashId[] = {0xEC, 0x22, 0xFC};

    BYTE LoaderWriteCommmands[] = {0x4C, 0x00, 0x00, 0x00, 0x00, 0x00};

     

    BYTE *StatesAnswers[] = {NULL, NULL, NULL, NULL, State4Data, NULL, State4Data,

    State7Data, State8Data, State9Data, State10Data, State11Data, State12Data, NULL,

    State14Data, State15Data, State16Data, NULL, State18Data, State19Data,

    State20Data, State21Data, State22Data, State23Data};

    int StatesAnswersLens[] = {0, 0, 0, 0, 5, 0, 5, 1, 1, 1, 1, 5, 1, 0, 1, 5, 1, 0, 1, 5,

    5, 5, 5, 1};

     

    while (!Terminated)

    {

    while (FileRead(FileHandle, &Buffer[byteCount], 1))//1000-ByteCount);

    {

    ByteCount ++;

    }

     

    if (ByteCount)

    {

    //поищем сигнатуру тайм аута

    for (int i=0; i<ByteCount-8; i++)

    {

    if ((Buffer[i+0] == 0x49) &&

    (Buffer[i+1] == 0x49) &&

    (Buffer[i+2] == 0x49) &&

    (Buffer[i+3] == 0x49) &&

    (Buffer[i+4] == 0xFF) &&

    (Buffer[i+5] == 0xFF) &&

    (Buffer[i+6] == 0xFF) &&

    (Buffer[i+7] == 0xFF))

    {

    HaveTimeoutSign = true;

    State = 0;

    ByteCount = 0;

    break;

    }

    }

     

    if (HaveTimeoutSign)

    {

    PostMessage((void*)FormHandle, WM_TIMEOUT, 0, 0);

    return;

    }

     

    switch (State)

    {

    case 0:

    {

    for (int i=0; i<ByteCount; i++)

    {

    if (Buffer == 0x81)

    {

    Sleep(10);

    SendBuffer[0] = 0x44;

    WriteDataToPort(SendBuffer, 1);

    ClearBytes = true;

    State = 1;

    break;

    }

    }

    break;

    }

    case 1:

    {

    for (int i=0; i<ByteCount; i++)

    {

    if (Buffer == 0x44)

    {

    SendBuffer[0] = 0x51;

    WriteDataToPort(SendBuffer, 1);

    ClearBytes = true;

    State = 2;

    break;

    }

    }

    break;

    }

    case 2:

    {

    if (ByteCount >= 16) //проверка что все нормально

    {

    memcpy(&header[5], &Buffer[byteCount-16], 16);

    WriteDataToPort(header, 21);

    State = 3;

    ClearBytes = true;

    }

    break;

    }

    case 3:

    {

    if (Buffer[byteCount-1] == 0x4F) //если нормально ответил на

    //наше подтверждение, выставляем таймаут 1600мс

    {

    SendBuffer[0] = 0x54;

    SendBuffer[1] = 0x10;

    WriteDataToPort(SendBuffer, 2);

    State = 4;

    ClearBytes = true;

    }

    break;

    }

    case 4: //{0x53, 0x00, 0x00, 0x00, 0x0C}; - выставить указатель памяти на 0x0C000000

    {

    if (Buffer[byteCount-1] == 0x4F)

    {

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    State ++; //след состояние посылка загрузчика

    LoaderCounter = 0; //указатель на начало

    ClearBytes = true;

    }

    break;

    }

    case 5://посылаем по 6 байт вторичный загрузчик

    //первые 2 - 0x4C 0x00 - команда, след 4 - данные в память

    //и так весь загрузчик по 4 байта и высылаем

    {

    if (Buffer[byteCount-1] == 0x4F)

    {

    memcpy(&LoaderWriteCommmands[2], &LoaderData[LoaderCounter*4], 4);

    WriteDataToPort(LoaderWriteCommmands, 6);

     

    LoaderCounter ++;

    if (LoaderCounter == 0x1CC)

    {

    State ++;

    }

    ClearBytes = true;

    }

    break;

    }

    case 6://выставить указатель на начало загрузчика

    {

    if (Buffer[byteCount-1] == 0x4F)

    {

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 7:

    {

    if (Buffer[byteCount-1] == 0x4F)

    {//записали в порт 0x4A, - старт предзагрузчика(второго загрузчика)

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 8:

    {

    if (Buffer[byteCount-1] == 0xAB)//такой д.б. ответ на старт предзагр

    {//записали в порт 0x03, - номер нужной скорости 921600

    //и сразу закрываем порт и открываем с нужной скоростью через 500 млс

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

     

    FileClose(FileHandle);

    FileHandle = -1;

    PortClosed = true;

     

    Sleep(500);

     

    //надо открыть порт

    FileHandle = FileOpen("\\\\.\\COM" + IntToStr(PortNumber), fmOpenReadWrite);

    if (FileHandle > -1)

    {

    DCB dcb;

    if (GetCommState((void*)FileHandle, &dcb))

    {

    memset(&dcb, 0, sizeof(DCB));

    dcb.DCBlength = sizeof(DCB);

    dcb.BaudRate = 921600;

    dcb.fBinary = 1;

    dcb.fParity = 0;

    dcb.fDtrControl = 0;

    dcb.fRtsControl = 1;

    dcb.XonLim = 0x1000;

    dcb.XoffLim = 0x400;

    dcb.ByteSize = 8;

    dcb.Parity = NOPARITY;//EVENPARITY; //четность поменялась

    dcb.StopBits = ONESTOPBIT;

    dcb.XonChar = 0x11;

    dcb.XoffChar = 0x13;

     

    if (SetCommState((void*)FileHandle, &dcb))

    {

    COMMTIMEOUTS cm;

    cm.ReadIntervalTimeout = MAXDWORD;

    cm.ReadTotalTimeoutMultiplier = 0;//MAXDWORD;

    cm.ReadTotalTimeoutConstant = 0;//1000;

    cm.WriteTotalTimeoutMultiplier = 0;

    cm.WriteTotalTimeoutConstant = 0;

     

    if (SetCommTimeouts((void*)FileHandle, &cm))

    {

    SetupComm((void*)FileHandle, 0x2000, 0x2000);

    PurgeComm((void*)FileHandle, PURGE_TXCLEAR|PURGE_RXCLEAR);

     

    PortClosed = false;

     

    //удалось нормально открыть порт

    }

    }

    }

     

    if (PortClosed)

    {

    FileClose(FileHandle);

    FileHandle = -1;

    }

    }

     

    if (PortClosed)

    {

    PostMessage((void*)FormHandle, WM_TIMEOUT, 0, 1);

    return;

    }

     

    //надо послать 0xD9 - запрос на скорость

    State ++;

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 9://зесь не будет его

    break;

    case 10:

    {

    if (Buffer[byteCount-1] == 0x03)

    {

    //получили, что правильная скорость

    //шлем запрос 0xB0, в надежде получить 4 байта пока неясно чего

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 11:

    {

    if (ByteCount == 0x4) //были варианты 0x13 0x13 0x00 0x00, 0x13 0x53 0x00 0x00

    {

    //надо ответить командным байтом посылки длины и значением длины

    //D4 00 02 E4 84, 2E484 - длина

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

     

    //надо запомнить CRC

    CRCByte = 0;

    for (int i=1; i<StatesAnswersLens[state]; i++)

    {

    CRCByte += StatesAnswers[state];

    }

     

    State ++;

    ClearBytes = true;

    BootLoaderSended = 0; //пока не послали ни одного байта

    }

    break;

    }

    case 12:

    {

    //надо проверить, что телефон ответил правильное CRC на передачу

    //ему длины загрузчика, который будем загружать

    //это в начале, но потом переходим в этой процедуре

    //на отправку всех данных загрузчика

     

    if (Buffer[byteCount-1] == CRCByte)

    {

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]); //послали 0xF7

    CRCByte = 0xF7;

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 13:

    {

    if (Buffer[byteCount-1] == CRCByte) //если телефон ответил нам 0xF7

    {//как мы и ожидали

    int CountBytesToSendNow = Min(0x800, 0x2E484-BootLoaderSended);

     

    BYTE *DataToSend = &BootLoaderData[bootLoaderSended];

    WriteDataToPort(DataToSend, CountBytesToSendNow); //послали кусок загрузчика

     

    CRCByte = 0x00;

    for (int i=0; i<CountBytesToSendNow; i++)

    {

    CRCByte += DataToSend;

    }

     

    BootLoaderSended += CountBytesToSendNow;

    if (0x2E484 - BootLoaderSended > 0)

    {

    State = 12; //надо продолжить с посылкой загрузчика

    }

    else

    {

    State ++; //все, загрузчик готов

    }

     

    ClearBytes = true;

    }

     

    break;

    }

    case 14:

    {

    if (Buffer[byteCount-1] == CRCByte)

    {

    //все заебись загружено в телефон

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]); //послали 0xFF, окончание записи

    CRCByte = 0xAB;//долюно вернуть

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 15:

    {

    if (Buffer[byteCount-1] == CRCByte)

    {

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    //послали 0xD0 0x10 0x00 0x00 0x00 - выбор блока памяти

    CRCByte = 0x10;//должно вернуть подтверждение

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 16:

    {

    if (Buffer[byteCount-1] == CRCByte)

    {

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    //послали 0xD1 запрос на получение FlashID

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 17:

    {

    //надо проверить, что пришел корректный FlashId

    if (ByteCount == 10)

    {

    //надо проверить, что 2,3,4 байты равны соответственно 0xEC 0x22 0xFC

    if (!memcmp(FlashId, &Buffer[1], 3))

    {

    PostMessage((void*)FormHandle, WM_INFORMATION, 0, 0);

    }

     

    ClearBytes = true;

    State ++;

    }

    break;

    }

    case 18://режим работы с телефоном, который уже

    //загружен нормально

    //проверяет не задан ли адрес по котрому надо класть данные

    {

    ClearBytes = true;

    break;

    }

    case 19:

    {

    if (Buffer[byteCount-1] == CRCByte)//есть ответ 0 на D9

    {

    //шлем команду с CRC данных сектора

    ChangeBytesInDword(SectorCRC);

    memcpy(&State19Data[1], &SectorCRC, 4);

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

     

    CRCByte = 0x00;

    for (int i=0; i<4; i++)

    {

    CRCByte += State19Data[i+1];

    }

     

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 20:

    {

    if (Buffer[byteCount-1] == CRCByte) //есть правильный ответ на

    //контрольную сумму сектора, надо передать адрес

    {

    DWORD data = SectorAddress;

    ChangeBytesInDword(data);

    memcpy(&State20Data[1], &data, 4); //0xD3 0x01 0x24 0x00 0x00

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

     

    CRCByte = 0x00;

    for (int i=0; i<4; i++)

    {

    CRCByte += State20Data[i+1];

    }

     

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 21:

    {

    if (Buffer[byteCount-1] == CRCByte) //есть правильный ответ на

    //контрольную сумму адреса, надо передать размер данных

    {

    DWORD SectorSize = 0x00010000;

    ChangeBytesInDword(SectorSize);

    memcpy(&State21Data[1], &SectorSize, 4); //0xD4 0x00 0x01 0x00 0x00

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

     

    CRCByte = 0x00;

    for (int i=0; i<4; i++)

    {

    CRCByte += State21Data[i+1];

    }

     

    State ++;

    ClearBytes = true;

    }

    break;

    }

    case 22:

    {

    if (Buffer[byteCount-1] == CRCByte) //есть правильный ответ на

    //контрольную сумму размера, надо передать адрес начала сектора

    {

    DWORD data = SectorAddress;

    ChangeBytesInDword(data);

    memcpy(&State22Data[1], &data, 4); //0xFA 0x01 0x21 0x00 0x00

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

     

    //сразу переходим в состояние отправки данных сектора - 1-го блока

    //потому break нет в конце

    SectorPartNum = 0; //всего будет 0x20 частей - 0x800*0x20 = 65536

     

    State ++;

    ClearBytes = true;

     

    SectorAddress = 0;

    SectorFileName = "";

    }

    else

    {

    break; //!!!!!!!!!!!!!!!!!!!!

    }

    }

    case 23:

    {

    if (SectorPartNum == 0x20)

    {

    if ((Buffer[byteCount-2] == CRCByte) && (Buffer[byteCount-1] == FileSum))

    {//все, закончили посылку сектора, надо обменяться 0xC6

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    CRCByte = 0xC6;

    State ++;

    ClearBytes = true;

    }

    }

    else

    {

    if (Buffer[byteCount-1] == CRCByte)

    {

    WriteDataToPort(&FileData[sectorPartNum*0x800], 0x800);

    SectorPartNum ++;

    CRCByte = SectorPartNum;

    ClearBytes = true;

    }

    }

    break;

    }

    case 24:

    {

    if (Buffer[byteCount-1] == CRCByte)

    {

    //запись сектора окончена

    State = 18;

    ClearBytes = true;

    }

    break;

    }

    }

    }

    else

    {

    if (SectorAddress && (State == 18))

    {

    //передан адрес по которому надо положить файл

    if (LoadFileToMemCalcCRC(SectorFileName, SectorCRC))

    {

    CRCByte = 0x00; //шлем ему байт 0xD9, ждем ответ 0x00

    WriteDataToPort(StatesAnswers[state], StatesAnswersLens[state]);

    State = 19;

    }

    else

    {

    SectorAddress = 0;

    SectorFileName = "";

    PostMessage((void*)FormHandle, WM_TIMEOUT, 0, 2);

    }

    }

    }

     

    if ((ByteCount > 900) || ((GetTickCount() - StartTime > 2000) && (ByteCount > 0)) ||

    ClearBytes)

    {

    BYTE *Data = new BYTE[byteCount];

    memcpy(Data, Buffer, ByteCount);

    PostMessage((void*)FormHandle, WM_RECEIVED_BYTES, (int)Data, ByteCount);

     

    ClearBytes = false;

    ByteCount = 0;

    StartTime = GetTickCount();

    }

     

    if (ClearBytes)

    {

    ClearBytes = false;

    ByteCount = 0;

    }

     

    if (State > :an: Sleep(10);

    Sleep(1);

    }

     

    return;

    }

     

    void __fastcall TPortThread::WriteDataToPort(BYTE *Buffer, int BufLen)

    {

    if (FileHandle > -1)

    {

    FileWrite(FileHandle, Buffer, BufLen);

     

    BYTE *Data = new BYTE[bufLen];

    memcpy(Data, Buffer, BufLen);

    PostMessage((void*)FormHandle, WM_WRITED_BYTES, (int)Data, BufLen);

    }

    return;

    }

     

    bool __fastcall TPortThread::LoadFileToMemCalcCRC(AnsiString FileName, DWORD &crc)

    {

    bool res = false;

     

    if (FileExists(FileName))

    {

    int LoadFileHandle = FileOpen(FileName, fmOpenRead);

    if (LoadFileHandle > -1)

    {

    if (FileSeek(LoadFileHandle, 0, 2) == 65536)

    {

    FileSeek(LoadFileHandle, 0, 0);

    //int read = FileRead(LoadFileHandle, FileData, 65536);

    if (FileRead(LoadFileHandle, FileData, 65536) == 65536)

    {

    res = true;

     

    crc = 0xFFFFFFFF;

    DWORD td;

    BYTE curb;

    BYTE sum = 0;

    for (int i=0; i<65536; i++)

    {

    td = crc;

    curb = FileData;

    td &= 0xFF; //младший байт crc

    td ^= curb; //xor младшего байта crc с новым байтом

    crc >>= 8; //сдвигаем вправо на 8 бит

     

    //td надо получить данные на основе td - получится 4 байта

    td = CRCData[td];

     

    crc ^= td;

     

    sum += FileData;

    }

    crc = ~crc;

    FileSum = sum;

    }

    }

    FileClose(LoadFileHandle);

    }

    }

     

    return res;

     

     

    }

     

    void __fastcall TMainForm::HaveInformationData(TMessage &message)

    {

    switch (message.LParam)

    {

    case 0:

    MessageBox(Handle, "Нормально прошла загрузка загрузчика :))", "Все нормально", MB_ICONINFORMATION|MB_OK);

    break;

    }

    return;

    }

     

    void __fastcall TMainForm::HaveTimeoutData(TMessage &message)

    {

    switch (message.LParam)

    {

    case 0:

    BitBtn2Click(NULL);

    MessageBox(Handle, "Превышен интервал ожидания ответа, тел дал отказ", "Ошибка", MB_ICONERROR|MB_OK);

    break;

    case 1:

    MessageBox(Handle, "Не удалось перейти на новую скорость", "Ошибка", MB_ICONERROR|MB_OK);

    break;

    case 2:

    MessageBox(Handle, "Не удалось загрузить файл", "Ошибка", MB_ICONERROR|MB_OK);

    break;

    }

    return;

    }

     

    void __fastcall TMainForm::HaveReceivedData(TMessage &message)

    {

    BYTE *Data = (BYTE*)message.WParam;

    message.WParam = 0;

    int ByteCount = (int)message.LParam;

     

    AnsiString str = "";

    for (int i=0; i<ByteCount; i++)

    {

    str += IntToHex(Data, 2) + " ";

    }

    ListBox1->Items->Add(str);

     

    delete [] Data;

     

    return;

    }

     

    void __fastcall TMainForm::HaveWrittenData(TMessage &message)

    {

    BYTE *Data = (BYTE*)message.WParam;

    message.WParam = 0;

    int ByteCount = (int)message.LParam;

     

    AnsiString str = "";

    for (int i=0; i<ByteCount; i++)

    {

    str += IntToHex(Data, 2) + " ";

    }

    ListBox2->Items->Add(str);

     

    delete [] Data;

     

    return;

    }

     

    void __fastcall TMainForm::BitBtn3Click(TObject *Sender)

    {

    port_thread->State = 0;

    port_thread->ByteCount = 0;

    }

    //---------------------------------------------------------------------------

     

    void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)

    {

    SaveOptions();

    }

    //---------------------------------------------------------------------------

     

    void __fastcall TMainForm::BitBtn4Click(TObject *Sender)

    {

    //надо попросить поток послать данные

    if (port_thread)

    {

    port_thread->SectorFileName = "c:\\Programs\\CBuilder\\D900Flasher\\1172.hex";

    port_thread->SectorAddress = 0x01720000;

    }

    return;

    }

    //---------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------------

    //---------------------------------------------------------------------------

     

    #ifndef MainFormUH

    #define MainFormUH

    //---------------------------------------------------------------------------

    #include <Classes.hpp>

    #include <Controls.hpp>

    #include <StdCtrls.hpp>

    #include <Forms.hpp>

    #include <Buttons.hpp>

    #include <mmsystem.h>

    #include <inifiles.hpp>

    #include <Math.hpp>

     

    #define WM_RECEIVED_BYTES WM_USER+1

    #define WM_WRITED_BYTES WM_USER+2

    #define WM_TIMEOUT WM_USER+3

    #define WM_INFORMATION WM_USER+4

     

    class TPortThread : public TThread

    {

    public:

    int FileHandle;

    int FormHandle;

    int State;

    bool HaveTimeoutSign;

    int ByteCount;

    int LoaderCounter;

    BYTE *LoaderData;

    BYTE *BootLoaderData;

    DWORD *CRCData;

    bool PortClosed;

    int PortNumber;

    BYTE FileData[65536];

    BYTE FileSum;

     

    AnsiString SectorFileName;

    DWORD SectorAddress;

     

    __fastcall TPortThread(int FileHandle, int FormHandle, BYTE *LoaderData,

    int PortNumber, BYTE *BootLoaderData, DWORD *CRCData);

    __fastcall ~TPortThread();

     

    void __fastcall Execute();

     

    void __fastcall WriteDataToPort(BYTE *Buffer, int BufLen);

    bool __fastcall LoadFileToMemCalcCRC(AnsiString FileName, DWORD &crc);

    };

     

    class TMainForm : public TForm

    {

    __published: // IDE-managed Components

    TComboBox *ComboBox1;

    TBitBtn *BitBtn1;

    TBitBtn *BitBtn2;

    TListBox *ListBox1;

    TListBox *ListBox2;

    TBitBtn *BitBtn3;

    TBitBtn *BitBtn4;

    void __fastcall BitBtn1Click(TObject *Sender);

    void __fastcall BitBtn2Click(TObject *Sender);

    void __fastcall BitBtn3Click(TObject *Sender);

    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

    void __fastcall BitBtn4Click(TObject *Sender);

    private: // User declarations

    int FileHandle;

    TPortThread *port_thread;

    BYTE LoaderData[1840];

     

    BYTE BootLoaderData[189572];

    DWORD CRCData[256];

    AnsiString SaveFileName;

     

    void __fastcall HaveReceivedData(TMessage &message);

    void __fastcall HaveWrittenData(TMessage &message);

    void __fastcall HaveTimeoutData(TMessage &message);

    void __fastcall HaveInformationData(TMessage &message);

     

    void __fastcall LoadOptions();

    void __fastcall SaveOptions();

    public: // User declarations

    __fastcall TMainForm(TComponent* Owner);

     

    BEGIN_MESSAGE_MAP

    MESSAGE_HANDLER(WM_RECEIVED_BYTES, TMessage, HaveReceivedData)

    MESSAGE_HANDLER(WM_WRITED_BYTES, TMessage, HaveWrittenData)

    MESSAGE_HANDLER(WM_TIMEOUT, TMessage, HaveTimeoutData)

    MESSAGE_HANDLER(WM_INFORMATION, TMessage, HaveInformationData)

    END_MESSAGE_MAP(TControl)

     

    };

    //---------------------------------------------------------------------------

    extern PACKAGE TMainForm *MainForm;

    //---------------------------------------------------------------------------

    #endif

    • Like 3
  3. Подскажите пожалуйста как запустить свой скрипт, или это можно сделать только из определенного места или там какая очередь скриптов? Саму идею и если можно пример с указанием прошивки, желательно swift.

×
×
  • Создать...