Builder80
-
Постов
9 -
Зарегистрирован
-
Посещение
Тип контента
Профили
Форумы
Загрузки
События
Сообщения, опубликованные Builder80
-
-
доделал файловую систему
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Попрятал я листинги! Не осилил колесико_крутить- 1
-
не знаю как добавить файлики с загрузчиком и crc, кому надо пишите на почту
-
привет, надо было написать прошивальщик самсунга - копался копался в поисках исходников, ничего не нашел, наваял пока загрузку и залитие сектора, загрузку файловой системы копаю сейчас, если кому любопытно...
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 > 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
- 3
-
хочу кабель с двумя хвостами - гарнитура и usb
чтобы можно было управлять телефоном at командами и записать речь
-
Подскажите если знаете, есть ли готовые кабели или как сделать самому такой? распиновка usb и гарнитуры известна, они, если просто одновременно их воткнуть работать будут?
-
Я имел в виду, что произошло какое-то событие в коде, не MCC скриптах, или сработал мой таймер, вообщем что-то где-то произошло, но не в MCC скриптах и надо выполнить скрипт...
-
Подскажите пожалуйста как запустить свой скрипт, или это можно сделать только из определенного места или там какая очередь скриптов? Саму идею и если можно пример с указанием прошивки, желательно swift.
-
загрузчик прошивки D900, исходники
в Программирование и реверсинг
Опубликовано
желание есть