//---------------------------------------------------------------------------
// Функции для работы с чипами DS2432, DS1961S
//---------------------------------------------------------------------------
#pragma hdrstop
#include "DS2432.h"
#include "ProgressBar.h"        // для использования прогресс-бара
#include "MainProgram.h"        // для работы с формой
#include "ChipFunctions.h"      // переменные для работы с памятью чипа
#include "PortFunctions.h"      // для работы с портом
#include "CalcCRC.h"            // для расчёта CRC
#include "SendMsgFunctions.h"   // для отправки сообщений в лог
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
//--- ЗАПИСЬ В SCRATCHPAD (0x0F) (из областей 1, 2, 3, 4) -------------------
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2, Input.Size, Input.AreaNumber
// output:      Test - байт, принятый после отправки всех данных (0xFF) + Success
DS2432_OUTPUT_DATA DS2432_WriteToScratchpad(DS2432_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  unsigned short int CRC16;             // для вычисления CRC16
  DS2432_OUTPUT_DATA OutputData;        // результат выполнения команды
  unsigned int Address;           		// для вычисления адреса

  OutputData.TA1=0;
  OutputData.TA2=0;
  OutputData.ES=0;
  OutputData.Test=0;
  OutputData.Success=false;             // инициализируем результаты нулями
  Address=InputData.TA1+0x100*InputData.TA2;             // вычисляем начальный адрес области, из которой будем писать

  // включаем прогресс-бар
  Application->CreateForm(__classid(TLBar),&LBar);      // создаём форму с прогресс-баром
  LBar->Show();                                         // показываем её в немодальном окне

  // посылаем Reset
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем Match ROM
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Match ROM
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем 8 байт ROM-адреса
  for(unsigned int i=0; i<8; i++)                       // перебираем все слова
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    wr_buf.Data[1]=SelectedChip.ROM[i];                 // ROM Bytes
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();          // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
  }
  // посылаем Write Scratchpad
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x0F;                                  // Write Scratchpad
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  // инициализируем и начинаем вычислять CRC16
  CRC16=0; CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);      // начинаем вычисление CRC16 с команды Write Scratchpad
  Sleep(10);
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA1;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);               // продолжаем вычислять CRC16
  Sleep(1);
  //посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA2;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);               // продолжаем вычислять CRC16
  Sleep(1);
  //*** отправляем содержимое нужной области ***
  for(unsigned int i=0; i<InputData.Size; i++)          // перебираем все слова, которые нужно отправить
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    switch(InputData.AreaNumber)
    { case 1:   wr_buf.Data[1]=SelectedChip.Area1[Address-SelectedChip.Area1Start];   // байт из области данных
                break;
      case 2:   wr_buf.Data[1]=SelectedChip.Area2[Address-SelectedChip.Area2Start];   // байт из области секрета
                break;
      case 3:   wr_buf.Data[1]=SelectedChip.Area3[Address-SelectedChip.Area3Start];   // байт из области регистров
                break;
      case 4:   wr_buf.Data[1]=SelectedChip.Area4[i];                                 // байт из блокнота
                break;
      default:  return OutputData;
    }
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);             // продолжаем вычислять CRC16
    Address+=1;                                         // увеличиваем адрес
    LBar->ProgressBar1->Position=100*(i+1)/InputData.Size;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // читаем CRC16 (2 байта, инвертированный)
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (первый байт CRC16)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  rd_buf.Data[0]=~rd_buf.Data[0];
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (второй байт CRC16)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  rd_buf.Data[0]=~rd_buf.Data[0];
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  // проверяем вычисленный CRC16
  if(CRC16)     SendMsgToLogForm(16,"");          // ошибка CRC16  // если всё нормально - результат должен быть равен нулю
  // проверяем, что нам пишет мастер (если всё Ок, то должны читаться 1-цы)
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем ещё один байт (Test)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.Test=rd_buf.Data[0];
  Sleep(1);
  // посылаем Reset когда всё записали
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  LBar->Free();                                         // уничтожаем форму с прогресс-баром
  OutputData.Success=true;
  return OutputData;          // посылаем принятый ранее Test в качестве ответа
}
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ ИЗ SCRATCHPAD (0xAA) (только в Area4) --------------------------
//---------------------------------------------------------------------------
// output:      Test - байт, принятый после отправки всех данных (0xFF), TA1, TA2, ES, Success
DS2432_OUTPUT_DATA DS2432_ReadFromScratchpad()
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2432_OUTPUT_DATA OutputData;        // здесь формируем ответ
  unsigned short int CRC16;             // для вычисления CRC16

  OutputData.TA1=0;
  OutputData.TA2=0;
  OutputData.ES=0;
  OutputData.Test=0;
  OutputData.Success=false;             // инициализируем ответ

  // включаем прогресс-бар
  Application->CreateForm(__classid(TLBar),&LBar);      // создаём форму с прогресс-баром
  LBar->Show();                                         // показываем её в немодальном окне

  // посылаем Reset
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем Match ROM
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Match ROM
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем 8 байт ROM-адреса
  for(unsigned int i=0; i<8; i++)                       // перебираем все слова
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    wr_buf.Data[1]=SelectedChip.ROM[i];                 // ROM Bytes
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();          // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
  }
  //команда чтения Scratchpad-а
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0xAA;                                  // Read Scratchpad
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  CRC16=0; CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);      // инициализируем и начинаем вычислять CRC16
  Sleep(10);
  //*** READ TA1, TA2, E/S ***
  // посылаем команду чтения
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                          // ReadByte_1W
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();          // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // читаем TA1
  rd_buf=ReadFrom();                            // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();              // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.TA1=rd_buf.Data[0];                // сохраняем TA1
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);       // продолжаем вычислять CRC16
  Sleep(1);
  // посылаем команду чтения
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                          // ReadByte_1W
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();          // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // читаем TA2
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.TA2=rd_buf.Data[0];                        // сохраняем TA2
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  // посылаем команду чтения
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // ReadByte_1W
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // читаем ES
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.ES=rd_buf.Data[0];                         // сохраняем ES
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  //*** читаем содержимое блокнота ***
  for(unsigned int i=0; i<SelectedChip.Area4Size; i++)  // перебираем все слова блокнота (Area4)
  { // посылаем команду чтения
    wr_buf.Size=1;
    wr_buf.Data[0]=0x62;                                // ReadByte_1W
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();          // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // читаем очередной байт
    rd_buf=ReadFrom();                              // читаем
    if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                       LBar->Free();                    // уничтожаем форму с прогресс-баром
                       ClosePort();
                       return OutputData;
                     }
    SelectedChip.Area4[i]=rd_buf.Data[0];                               // сохраняем прочитанный байт в область блокнота
    CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);                             // продолжаем вычислять CRC16
    LBar->ProgressBar1->Position=100*(i+1)/SelectedChip.Area4Size;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // читаем CRC16 (2 байта, инвертированный)
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (первый байт CRC16)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  rd_buf.Data[0]=~rd_buf.Data[0];
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (второй байт CRC16)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  rd_buf.Data[0]=~rd_buf.Data[0];
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  // проверяем вычисленный CRC16
  if(CRC16)     SendMsgToLogForm(16,"");          // ошибка CRC16  // если всё нормально - результат должен быть равен нулю
  // посылаем команду чтения чтобы прочитать ещё один байт (Test)
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем ещё один байт (Test)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.Test=rd_buf.Data[0];
  Sleep(1);
  // посылаем Reset когда всё прочитали
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  LBar->Free();                                         // уничтожаем форму с прогресс-баром
  OutputData.Success=true;
  return OutputData;
}
//---------------------------------------------------------------------------
//--- ЗАПИСЬ НОВОГО СЕКРЕТА (0x5A) (копирование его из блокнота в память) ---
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2, Input.ES
// output:      Test - байт, принятый после отправки всех данных (0xFF) + Success
DS2432_OUTPUT_DATA DS2432_LoadFirstSecret(DS2432_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2432_OUTPUT_DATA OutputData;        // результат выполнения команды

  OutputData.TA1=0;
  OutputData.TA2=0;
  OutputData.ES=0;
  OutputData.Test=0;
  OutputData.Success=false;             // инициализируем результаты нулями

  // включаем прогресс-бар
  Application->CreateForm(__classid(TLBar),&LBar);      // создаём форму с прогресс-баром
  LBar->Show();                                         // показываем её в немодальном окне

  // посылаем Reset
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем Match ROM
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Match ROM
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем 8 байт ROM-адреса
  for(unsigned int i=0; i<8; i++)                       // перебираем все слова
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    wr_buf.Data[1]=SelectedChip.ROM[i];                 // ROM Bytes
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();          // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
  }
  // посылаем Load First Secret
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x5A;                                  // Load First Secret
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA1;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  //посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA2;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  //посылаем ES
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.ES;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // проверяем, что нам пишет мастер (если всё Ок, то должны читаться 1-цы)
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем ещё один байт (Test)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.Test=rd_buf.Data[0];
  Sleep(1);
  // посылаем Reset когда всё записали
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  LBar->Free();                                         // уничтожаем форму с прогресс-баром
  OutputData.Success=true;
  return OutputData;          // посылаем принятый ранее Test в качестве ответа
}
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ ИЗ ПАМЯТИ (0xF0) (в области Area1, Area2, Area3) ---------------
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2, Input.Size, Input.AreaNumber
// output:      Test - байт, принятый после отправки всех данных (0xAA) + Success
DS2432_OUTPUT_DATA DS2432_ReadFromMemory(DS2432_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2432_OUTPUT_DATA OutputData;        // здесь формируем ответ
  unsigned int Address;           		// для вычисления адреса

  OutputData.TA1=0;
  OutputData.TA2=0;
  OutputData.ES=0;
  OutputData.Test=0;
  OutputData.Success=false;             // инициализируем ответ
  Address=InputData.TA1+0x100*InputData.TA2;             // вычисляем начальный адрес области, из которой будем читать

  // включаем прогресс-бар
  Application->CreateForm(__classid(TLBar),&LBar);      // создаём форму с прогресс-баром
  LBar->Show();                                         // показываем её в немодальном окне

  // посылаем Reset
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем Match ROM
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Match ROM
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем 8 байт ROM-адреса
  for(unsigned int i=0; i<8; i++)                       // перебираем все слова
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    wr_buf.Data[1]=SelectedChip.ROM[i];                 // ROM Bytes
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
  }
  // команда чтения EEPROM
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0xF0;                                  // Read EEPROM
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA1;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA2;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  //*** читаем содержимое памяти ***
  for(unsigned int i=0; i<InputData.Size; i++)          // перебираем все слова
  { // посылаем команду чтения
    wr_buf.Size=1;
    wr_buf.Data[0]=0x62;                                // ReadByte_1W
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // читаем очередной байт
    rd_buf=ReadFrom();                                  // читаем
    if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                       LBar->Free();                    // уничтожаем форму с прогресс-баром
                       ClosePort();
                       return OutputData;
                     }
    switch(InputData.AreaNumber)
    { case 1:   SelectedChip.Area1[Address-SelectedChip.Area1Start]=rd_buf.Data[0];     // сохраняем прочитанный байт в Area1
                break;
      case 2:   SelectedChip.Area2[Address-SelectedChip.Area2Start]=rd_buf.Data[0];     // сохраняем прочитанный байт в Area2
                break;
      case 3:   SelectedChip.Area3[Address-SelectedChip.Area3Start]=rd_buf.Data[0];     // сохраняем прочитанный байт в Area3
                break;
      default:  break;
    }
    Sleep(1);
    Address+=1;                                                 // увеличиваем адрес

    LBar->ProgressBar1->Position=100*(i+1)/InputData.Size;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // посылаем команду чтения чтобы прочитать ещё один байт (Test)
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем ещё один байт (Test)
  rd_buf=ReadFrom();                                    // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.Test=rd_buf.Data[0];
  Sleep(1);
  // посылаем Reset когда всё записали
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  LBar->Free();                                         // уничтожаем форму с прогресс-баром
  OutputData.Success=true;
  return OutputData;
}
//---------------------------------------------------------------------------
//--- КОПИРОВАНИЕ ИЗ SCRATCHPAD В EEPROM (0x55) -----------------------------
//--- (команда применима к любой R/W области, включая секрет) ---------------
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2, Input.ES
// output:      Test - байт, принятый после отправки всех данных (0xAA) + Success
DS2432_OUTPUT_DATA DS2432_CopyScratchpadToMemory(DS2432_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2432_OUTPUT_DATA OutputData;        // здесь формируем ответ
  MAC_DATA CalculatedMac;               // сюда получаем рассчитанный MAC

  OutputData.TA1=0;
  OutputData.TA2=0;
  OutputData.ES=0;
  OutputData.Test=0;
  OutputData.Success=false;             // инициализируем ответ

  // посылаем Reset
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,""); // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем Match ROM
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                            // SendByte_1W
  wr_buf.Data[1]=0x55;                            // Match ROM
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,""); // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем 8 байт ROM-адреса
  for(unsigned int i=0; i<8; i++)                       // перебираем все слова
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    wr_buf.Data[1]=SelectedChip.ROM[i];                 // ROM Bytes
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();          // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
  }
  // посылаем Copy Scratchpad
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Copy Scratchpad
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA1;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA2;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем E/S
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.ES;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // вычисляем MAC
  CalculatedMac=CalculateMAC(InputData.TA1, InputData.TA2);
  // посылаем вычисленный MAC
  // передаём 4 байта E
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[0];                  // посылаем младший байт E
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[0]>>8;               // посылаем следующий байт E
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[0]>>16;              // посылаем следующий байт E
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[0]>>24;              // посылаем старший байт E
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // передаём 4 байта D
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[1];                  // посылаем младший байт D
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[1]>>8;               // посылаем следующий байт D
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[1]>>16;              // посылаем следующий байт D
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[1]>>24;              // посылаем старший байт D
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // передаём 4 байта C
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[2];                  // посылаем младший байт C
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[2]>>8;               // посылаем следующий байт C
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[2]>>16;              // посылаем следующий байт C
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[2]>>24;              // посылаем старший байт C
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // передаём 4 байта B
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[3];                  // посылаем младший байт B
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[3]>>8;               // посылаем следующий байт B
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[3]>>16;              // посылаем следующий байт B
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[3]>>24;              // посылаем старший байт B
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // передаём 4 байта A
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[4];                  // посылаем младший байт A
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[4]>>8;                  // посылаем следующий байт A
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[4]>>16;                  // посылаем следующий байт A
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=CalculatedMac.MAC[4]>>24;                  // посылаем старший байт A
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(20);
  // проверяем, что нам пишет мастер
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем ещё один байт (Test)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.Test=rd_buf.Data[0];
  Sleep(1);
  // если принимаются нули - сообщаем, что MAC неправильный
  if(OutputData.Test==0)        SendMsgToLogForm(31,"");        // неправильный MAC
  // посылаем Reset когда всё записали
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  OutputData.Success=true;
  return OutputData;            // посылаем принятый ранее Test в качестве ответа
}
//---------------------------------------------------------------------------
//--- ОБНОВЛЕНИЕ SCRATCHPAD (0xA3) (только для области 1) -------------------
//---------------------------------------------------------------------------
// Команда загружает 8 байт из указанных адресов памяти в блокнот, независимо
// от переданных с командой байт (передаются любые фиктивные байты). Если сразу
// после этого выполнить команду LoadFirstSecret, то данные запишутся назад
// из блокнота по тем же адресам (произойдёт как бы регенерация данных)
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2
// output:      Test - байт, принятый после отправки всех данных (0xFF) + Success
DS2432_OUTPUT_DATA DS2432_RefreshScratchpad(DS2432_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  unsigned short int CRC16;             // для вычисления CRC16
  DS2432_OUTPUT_DATA OutputData;        // результат выполнения команды

  OutputData.TA1=0;
  OutputData.TA2=0;
  OutputData.ES=0;
  OutputData.Test=0;
  OutputData.Success=false;             // инициализируем результаты нулями

  // включаем прогресс-бар
  Application->CreateForm(__classid(TLBar),&LBar);      // создаём форму с прогресс-баром
  LBar->Show();                                         // показываем её в немодальном окне

  // посылаем Reset
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем Match ROM
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Match ROM
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // посылаем 8 байт ROM-адреса
  for(unsigned int i=0; i<8; i++)                       // перебираем все слова
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    wr_buf.Data[1]=SelectedChip.ROM[i];                 // ROM Bytes
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();          // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
  }
  // посылаем Refresh Scratchpad
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0xA3;                                  // Refresh Scratchpad
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  // инициализируем и начинаем вычислять CRC16
  CRC16=0; CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);      // начинаем вычисление CRC16 с команды Refresh Scratchpad
  Sleep(10);
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA1;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);               // продолжаем вычислять CRC16
  Sleep(1);
  //посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.TA2;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);               // продолжаем вычислять CRC16
  Sleep(1);
  //*** отправляем 8 фиктивных байт ***
  // (в блокнот загрузятся байты из памяти, по указанным адресам, назависимо от того, что мы передали)
  for(unsigned int i=0; i<SelectedChip.Area4Size; i++)  // количество фиктивных байт = размеру блокнота
  { wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                // SendByte_1W
    wr_buf.Data[1]=0xFF;                                // next fictive byte
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");     // ошибка загрузки пакета
                           LBar->Free();                // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    CRC16=CalcCRC16(CRC16, wr_buf.Data[1]);             // продолжаем вычислять CRC16
    LBar->ProgressBar1->Position=100*(i+1)/InputData.Size;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // читаем CRC16 (2 байта, инвертированный)
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (первый байт CRC16)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  rd_buf.Data[0]=~rd_buf.Data[0];
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (второй байт CRC16)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  rd_buf.Data[0]=~rd_buf.Data[0];
  CRC16=CalcCRC16(CRC16, rd_buf.Data[0]);               // продолжаем вычислять CRC16
  Sleep(1);
  // проверяем вычисленный CRC16
  if(CRC16)     SendMsgToLogForm(16,"");          // ошибка CRC16  // если всё нормально - результат должен быть равен нулю
  // проверяем, что нам пишет мастер (если всё Ок, то должны читаться 1-цы)
  Sleep(1);
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем ещё один байт (Test)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.Test=rd_buf.Data[0];
  Sleep(1);
  // посылаем Reset когда всё записали
  wr_buf.Size=1;
  wr_buf.Data[0]=0x60;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  LBar->Free();                                         // уничтожаем форму с прогресс-баром
  OutputData.Success=true;
  return OutputData;          // посылаем принятый ранее Test в качестве ответа
}
//---------------------------------------------------------------------------

 