//---------------------------------------------------------------------------
// Функции для работы с чипами DS2502
//---------------------------------------------------------------------------
#pragma hdrstop
#include "DS2502.h"
#include "ProgressBar.h"        // для использования прогресс-бара
#include "MainProgram.h"        // для работы с формой
#include "ChipFunctions.h"      // переменные для работы с памятью чипа
#include "PortFunctions.h"      // для работы с портом
#include "CalcCRC.h"            // для расчёта CRC
#include "SendMsgFunctions.h"   // для отправки сообщений в лог
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ ИЗ ПАМЯТИ (0xF0) (в область Area1) -----------------------------
//---------------------------------------------------------------------------
// output:      Test - байт, принятый после чтения  всех данных (0xFF) + Success
DS2502_OUTPUT_DATA DS2502_ReadFromMemory()
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2502_OUTPUT_DATA OutputData;        // здесь формируем ответ
  unsigned int Address;           	// для вычисления адреса
  unsigned char CRC8;                   // для вычисления CRC8

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

  // включаем прогресс-бар
  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);
  // инициализируем и начинаем вычислять CRC8
  CRC8=0;
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // принимаем байт CRC8
  // посылаем команду чтения
  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;
                   }
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
    rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
  }
  // если CRC8 равно нулю, то всё в порядке
  if(CRC8)  SendMsgToLogForm(14,"");          // ошибка CRC8
  //*** читаем содержимое памяти ***
  CRC8=0;       // инициализируем CRC8
  for(unsigned int i=0; i<SelectedChip.Area1Size; 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;
                     }
    SelectedChip.Area1[Address-SelectedChip.Area1Start]=rd_buf.Data[0];     // сохраняем прочитанный байт в Area1
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
      rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
    }
    Address+=1;                                                         // увеличиваем адрес
    LBar->ProgressBar1->Position=100*(i+1)/SelectedChip.Area1Size;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // читаем и проверяем CRC8
  // посылаем команду чтения
  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;
                   }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
    rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
  }
  if(CRC8)  SendMsgToLogForm(14,"");          // ошибка CRC8
  // посылаем команду чтения чтобы прочитать ещё один байт (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;
}
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ БАЙТОВ СТАТУСА (0xAA) (в область Area2) ------------------------
//---------------------------------------------------------------------------
// output:      Test - байт, принятый после чтения  всех данных (0xFF) + Success
DS2502_OUTPUT_DATA DS2502_ReadFromStatus()
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2502_OUTPUT_DATA OutputData;        // здесь формируем ответ
  unsigned int Address;           	// для вычисления адреса
  unsigned char CRC8;                   // для вычисления CRC8

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

  // включаем прогресс-бар
  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);
  }
  // команда чтения Status Bytes
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0xAA;                                  // Read Status Bytes
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // инициализируем и начинаем вычислять CRC8
  CRC8=0;
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // принимаем байт CRC8
  // посылаем команду чтения
  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;
                   }
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
    rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
  }
  // если CRC8 равно нулю, то всё в порядке
  if(CRC8)  SendMsgToLogForm(14,"");          // ошибка CRC8
  //*** читаем содержимое памяти ***
  CRC8=0;       // инициализируем CRC8
  for(unsigned int i=0; i<SelectedChip.Area2Size; 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;
                     }
    SelectedChip.Area2[Address-SelectedChip.Area2Start]=rd_buf.Data[0];     // сохраняем прочитанный байт в Area2
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
      rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
    }
    Address+=1;                                                         // увеличиваем адрес
    LBar->ProgressBar1->Position=100*(i+1)/SelectedChip.Area2Size;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // читаем и проверяем CRC8
  // посылаем команду чтения
  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;
                   }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
    rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
  }
  if(CRC8)  SendMsgToLogForm(14,"");          // ошибка CRC8
  // посылаем команду чтения чтобы прочитать ещё один байт (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;
}
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ ПАМЯТИ С ПОСТРАНИЧНОЙ ГЕНЕРАЦИЕЙ CRC8 (0xC3) (в область Area1) -
//---------------------------------------------------------------------------
// output:      Test - байт, принятый после чтения  всех данных (0xFF) + Success
DS2502_OUTPUT_DATA DS2502_ReadFromMemoryCRC8()
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2502_OUTPUT_DATA OutputData;        // здесь формируем ответ
  unsigned int Address;           	// для вычисления адреса
  unsigned char CRC8;                   // для вычисления CRC8

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

  // включаем прогресс-бар
  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 + CRC8
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0xC3;                                  // Read EEPROM + Generate CRC8
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // инициализируем и начинаем вычислять CRC8
  CRC8=0;
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // посылаем TA1
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // посылаем TA2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
    wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
  }
  // принимаем байт CRC8
  // посылаем команду чтения
  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;
                   }
  // продолжаем вычислять CRC8
  for(unsigned int j=0;j<8;j++)
  { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
    rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
  }
  // если CRC8 равно нулю, то всё в порядке
  if(CRC8)  SendMsgToLogForm(14,"");          // ошибка CRC8
  //*** читаем содержимое памяти с постраничной генерацией CRC8 ***
  CRC8=0;       // инициализируем CRC8
  for(unsigned int i=0; i<SelectedChip.Area1Size; 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;
                     }
    SelectedChip.Area1[Address-SelectedChip.Area1Start]=rd_buf.Data[0];     // сохраняем прочитанный байт в Area1
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
      rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
    }
    // если конец страницы, то нужно прочитать ещё байт CRC8
    if((i+1)%32==0)
    { // читаем и проверяем CRC8
      // посылаем команду чтения
      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;
                       }
      Sleep(1);
      // продолжаем вычислять CRC8
      for(unsigned int j=0;j<8;j++)
      { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
        rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
      }
      if(CRC8)  SendMsgToLogForm(14,"");          // ошибка CRC8
      CRC8=0;   // инициализируем CRC8 для следующей страницы
    }
    Address+=1;                                                         // увеличиваем адрес
    LBar->ProgressBar1->Position=100*(i+1)/SelectedChip.Area1Size;      // вычисляем новую позицию прогресс-бара
    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;
}
//---------------------------------------------------------------------------
//--- ЗАПИСЬ В ПАМЯТЬ (0x0F) (из области Area1 или Scratchpad) --------------
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2, Input.Size, Input.AreaNumber
// output:      Test - байт, принятый после чтения  всех данных (0xFF) + Success
DS2502_OUTPUT_DATA DS2502_WriteToMemory(DS2502_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2502_OUTPUT_DATA OutputData;        // здесь формируем ответ
  unsigned int Address;           	// для вычисления адреса
  unsigned char CRC8;                   // для вычисления CRC8
  unsigned char TempByte;

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

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

  switch(SelectedProgrammer)
  { case 1:     // выбран программатор RH-0004
                //***************
                // подготавливаем I/O для формирования импульса блокировки
                // *** I/O0, 2 на вход, IO1- на выход, во все защёлки нули ***
                // посылаем IO0ConfigInput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0C;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO1ConfigOutput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0F;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO2ConfigInput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x14;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // *** во все защёлки нули ***
                // посылаем IO0Output0
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0D;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO1Output0
                wr_buf.Size=1;
                wr_buf.Data[0]=0x11;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO2Output0
                wr_buf.Size=1;
                wr_buf.Data[0]=0x15;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                break;
    case 2:     // выбран программатор RH-0010
                // подготовка не требуется
    default:    break;
  }
  //**************************************************************
  //*************** Придётся отсюда цикл делать ******************
  //**************************************************************
  for(unsigned int n=0; n<InputData.Size; n++)          // перебираем все слова нужной области
  { // посылаем 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]=0x0F;                                  // Write EEPROM
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(10);
    // инициализируем и начинаем вычислять CRC8
    CRC8=0;
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    // посылаем TA1
    wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                  // SendByte_1W
    wr_buf.Data[1]=Address;                               // младший байт как раз содержит TA1
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    // посылаем TA2
    wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                  // SendByte_1W
    wr_buf.Data[1]=Address>>8;                            // второй байт равен TA2
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    //*** посылаем содержимое памяти ***
    // посылаем байт данных
    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;
      default: wr_buf.Data[1]=SelectedChip.Area3[0];                                 // байт блокнота
               break;
    }
    TempByte=wr_buf.Data[1];    // запоминаем переданный байт
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    // читаем и проверяем CRC8
    // посылаем команду чтения
    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;
                     }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
      rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
    }
    if(CRC8)
    { SendMsgToLogForm(14,"");          // ошибка CRC8
      LBar->Free();                     // уничтожаем форму с прогресс-баром
      return OutputData;                // писать дальше не будем (не будем посылать импульс программирования)
    }
    // посылаем импульс программирования
    switch(SelectedProgrammer)
    { case 1:   // для программатора RH-0004
                // посылаем IO0ConfigOutput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0B;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                Sleep(1);
                // посылаем IO0ConfigInput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0C;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                break;
      case 2:   // для программатора RH-0010
                // посылаем Get580us_Pulse_1W (0x69)
                wr_buf.Size=1;
                wr_buf.Data[0]=0x69;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                break;
      default:  break;
    }
    Sleep(10);
    // принимаем и проверяем переданный ранее байт
    // посылаем команду чтения
    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;
                     }
    Sleep(1);
    // если они не совпадают - сообщаем об ошибке записи
    if(TempByte!=rd_buf.Data[0])        SendMsgToLogForm(105,""); // ошибка записи (но продолжаем писать)
    Address+=1;                                                   // увеличиваем адрес

    LBar->ProgressBar1->Position=100*(n+1)/InputData.Size;      // вычисляем новую позицию прогресс-бара
    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;
}
//---------------------------------------------------------------------------
//--- ЗАПИСЬ В БАЙТЫ СТАТУСА (0x55) (из области Area2 -----------------------
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2, Input.Size
// output:      Test - байт, принятый после чтения  всех данных (0xFF) + Success
DS2502_OUTPUT_DATA DS2502_WriteToStatus(DS2502_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS2502_OUTPUT_DATA OutputData;        // здесь формируем ответ
  unsigned int Address;           	// для вычисления адреса
  unsigned char CRC8;                   // для вычисления CRC8
  unsigned char TempByte;

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

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

  switch(SelectedProgrammer)
  { case 1:     // выбран программатор RH-0004
                //***************
                // подготавливаем I/O для формирования импульса блокировки
                // *** I/O0, 2 на вход, IO1- на выход, во все защёлки нули ***
                // посылаем IO0ConfigInput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0C;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO1ConfigOutput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0F;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO2ConfigInput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x14;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // *** во все защёлки нули ***
                // посылаем IO0Output0
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0D;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO1Output0
                wr_buf.Size=1;
                wr_buf.Data[0]=0x11;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                // посылаем IO2Output0
                wr_buf.Size=1;
                wr_buf.Data[0]=0x15;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                break;
    case 2:     // выбран программатор RH-0010
                // подготовка не требуется
    default:    break;
  }
  //**************************************************************
  //*************** Придётся отсюда цикл делать ******************
  //**************************************************************
  for(unsigned int n=0; n<InputData.Size; n++)          // перебираем все слова нужной области
  { // посылаем 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);
    }
    // команда записи Status
    wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                  // SendByte_1W
    wr_buf.Data[1]=0x55;                                  // Write Status
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(10);
    // инициализируем и начинаем вычислять CRC8
    CRC8=0;
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    // посылаем TA1
    wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                  // SendByte_1W
    wr_buf.Data[1]=Address;                               // младший байт адреса как раз содержит TA1
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    // посылаем TA2
    wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                  // SendByte_1W
    wr_buf.Data[1]=Address>>8;                            // Второй байт адреса как раз содержит TA2
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    //*** посылаем содержимое памяти ***
    // посылаем байт данных
    wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                  // SendByte_1W
    wr_buf.Data[1]=SelectedChip.Area2[Address-SelectedChip.Area2Start];   // байт из области статуса
    TempByte=wr_buf.Data[1];    // запоминаем переданный байт
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                  // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,wr_buf.Data[1]); // вычисляем CRC
      wr_buf.Data[1]=wr_buf.Data[1]>>1;   // следующий бит
    }
    // читаем и проверяем CRC8
    // посылаем команду чтения
    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;
                     }
    Sleep(1);
    // продолжаем вычислять CRC8
    for(unsigned int j=0;j<8;j++)
    { CRC8=CalcCRC8(CRC8,rd_buf.Data[0]); // вычисляем CRC
      rd_buf.Data[0]=rd_buf.Data[0]>>1;   // следующий бит
    }
    if(CRC8)
    { SendMsgToLogForm(14,"");          // ошибка CRC8
      LBar->Free();                     // уничтожаем форму с прогресс-баром
      return OutputData;                // писать дальше не будем (не будем посылать импульс программирования)
    }
    // посылаем импульс программирования
    switch(SelectedProgrammer)
    { case 1:   // для программатора RH-0004
                // посылаем IO0ConfigOutput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0B;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                Sleep(1);
                // посылаем IO0ConfigInput
                wr_buf.Size=1;
                wr_buf.Data[0]=0x0C;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                break;
      case 2:   // для программатора RH-0010
                // посылаем Get580us_Pulse_1W (0x69)
                wr_buf.Size=1;
                wr_buf.Data[0]=0x69;
                if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                                       LBar->Free();            // уничтожаем форму с прогресс-баром
                                       ClosePort();
                                       return OutputData;
                                     }
                break;
      default:  break;
    }
    Sleep(10);
    // принимаем и проверяем переданный ранее байт
    // посылаем команду чтения
    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;
                     }
    Sleep(1);
    // если они не совпадают - сообщаем об ошибке записи
    if(TempByte!=rd_buf.Data[0])        SendMsgToLogForm(105,""); // ошибка записи (но продолжаем писать)
    Address+=1;                                                         // увеличиваем адрес

    LBar->ProgressBar1->Position=100*(n+1)/InputData.Size;      // вычисляем новую позицию прогресс-бара
    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;
}
//---------------------------------------------------------------------------
