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

    Вы сейчас не залогинены на форуме.

    Для возможности комментариев, загрузки файлов, подписок на ответы - вам надо войти.

загрузчик прошивки D900, исходники


Рекомендуемые сообщения

привет, надо было написать прошивальщик самсунга - копался копался в поисках исходников, ничего не нашел, наваял пока загрузку и залитие сектора, загрузку файловой системы копаю сейчас, если кому любопытно...

 

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
Ссылка на комментарий
Поделиться на другие сайты

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

 

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
Ссылка на комментарий
Поделиться на другие сайты

Отлично..энтузиазм это хорошо.... Если есть желание то можно взяться за продолжение OpenSFD

Жизнь - пьяный поэт, я - слово.

Я жесток и грустен, когда ему херово.

Жизнь - старый поэт, жизнь - усталый поэт,

А я... Что я? Его инструмент!...

 

Разработка Broadcom: http://www.rk-team.net/

Новости проекта QuB на Twitter

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


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