//---------------------------------------------------------------------------
// Функции для работы с чипами DS28E05
//---------------------------------------------------------------------------
#pragma hdrstop
#include "DS28E05.h"
#include "ProgressBar.h"        // для использования прогресс-бара
#include "MainProgram.h"        // для работы с формой
#include "ChipFunctions.h"      // переменные для работы с памятью чипа
#include "PortFunctions.h"      // для работы с портом
#include "SendMsgFunctions.h"   // для отправки сообщений в лог
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
//--- ЗАПИСЬ В ПАМЯТЬ (0x55) (из областей 1, 2) -----------------------------
//---------------------------------------------------------------------------
// input:       Input.PB, Input.AreaNumber
// output:      Test - байт, принятый после отправки всех данных (0xFF) + Success
DS28E05_OUTPUT_DATA DS28E05_WriteToMemory(DS28E05_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS28E05_OUTPUT_DATA OutputData;       // результат выполнения команды
  unsigned int Address;                 // для вычисления адреса
  unsigned char Sended1, Sended2, Readed1, Readed2;     // посланные и прочитанные байты
  AnsiString TempStr;                   // для формирования строк
  char TempBuf[1], OutHexBuf[3];        // для преобразования
  unsigned char PageNum, SegNum;        // номер страницы и количество сегментов, которые мы будем передавать

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

  PageNum=(InputData.PB>>4)&7;          // определяем page number
  Address = PageNum*16;                 // начальный адрес страницы
  if(PageNum<7)         SegNum = 8;     // для страниц с 0 по 6 пишем 8 сегментов
  else                  SegNum = 3;     // для 7 страницы пишем 3 первых сегмента

  // включаем прогресс-бар
  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 Data
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Write Data
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // посылаем байт параметров
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.PB;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  //посылаем 0xFF
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0xFF;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  //*** отправляем содержимое нужной области (SegNum сегментов по 2 байта) ***
  for(unsigned char i=0; i<SegNum; 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;
      default:  return OutputData;
    }
    Sended1=wr_buf.Data[1];
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Address+=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;
      case 2:   wr_buf.Data[1]=SelectedChip.Area2[Address-SelectedChip.Area2Start];     // байт из административной области
                break;
      default:  return OutputData;
    }
    Sended2=wr_buf.Data[1];
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();                // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Address+=1;                                         // увеличиваем адрес
    // читаем обратно два байта
    // первый байт
    wr_buf.Size=1;
    wr_buf.Data[0]=0x62;                                  // команда чтения байта
    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;
                     }
    Readed1=rd_buf.Data[0];                       // запоминаем
    Sleep(1);
    // второй байт
    wr_buf.Size=1;
    wr_buf.Data[0]=0x62;                                  // команда чтения байта
    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;
                     }
    Readed2=rd_buf.Data[0];                       // запоминаем
    Sleep(1);
    // проверяем, совпадают ли отосланные и принятые байты
    if(Sended1!=Readed1 || Sended2!=Readed2) { SendMsgToLogForm(29,"");         // ошибка верификации
                                               LBar->Free();                    // уничтожаем форму с прогресс-баром
                                               return OutputData;
                                             }
    // посылаем 0xFF (release byte)
    wr_buf.Size=2;
    wr_buf.Data[0]=0x61;                                  // SendByte_1W
    wr_buf.Data[1]=0xFF;
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();            // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(16);  // program time
    // получаем байт CS
    // команда чтения байта
    wr_buf.Size=1;
    wr_buf.Data[0]=0x62;                                  // команда чтения байта
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                           LBar->Free();            // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    Sleep(1);
    // принимаем ещё один байт (CS)
    rd_buf=ReadFrom();                                // читаем
    if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                       LBar->Free();                      // уничтожаем форму с прогресс-баром
                       ClosePort();
                       return OutputData;
                     }
    if(rd_buf.Data[0]==0x33)    { TempBuf[0]=Address-1;
                                  BinToHex(TempBuf,OutHexBuf,1);      // преобразовать строку в целое (байт)
                                  OutHexBuf[2]=0;                     // строка должна заканчиваться нулём
                                  TempStr = OutHexBuf;
                                  TempStr += ":";
                                  TempBuf[0]=Address;
                                  BinToHex(TempBuf,OutHexBuf,1);      // преобразовать строку в целое (байт)
                                  OutHexBuf[2]=0;                     // строка должна заканчиваться нулём
                                  TempStr += OutHexBuf;
                                  SendMsgToLogForm(30,TempStr);       // если cs=0x33 - write protected
                                }
    Sleep(1);

    LBar->ProgressBar1->Position=100*(i+1)/SegNum;           // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // проверяем, что нам пишет мастер (если всё Ок, то должны читаться 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) ----------------------
//---------------------------------------------------------------------------
// input:       Input.TA1, Input.TA2, Input.Size, Input.AreaNumber
// output:      Test - байт, принятый после чтения  всех данных (0xFF) + Success
DS28E05_OUTPUT_DATA DS28E05_ReadFromMemory(DS28E05_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  DS28E05_OUTPUT_DATA OutputData;       // здесь формируем ответ
  unsigned int Address;           	// для вычисления адреса

  OutputData.Test=0;
  OutputData.Success=false;             // инициализируем ответ
  Address=InputData.TA1+0xFF*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;
      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;
}
//---------------------------------------------------------------------------  