//---------------------------------------------------------------------------
// Функции для работы с чипами MAX31826
//---------------------------------------------------------------------------
#pragma hdrstop
#include "MAX31826.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 2 (0x0F) (из областей 1, 2) -----------------------
//---------------------------------------------------------------------------
// input:       Input.SA, Input.Size, Input.AreaNumber
// output:      Success
MAX31826_OUTPUT_DATA MAX31826_WriteToScratchpad(MAX31826_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  unsigned char CRC8;                   // для вычисления CRC8
  MAX31826_OUTPUT_DATA OutputData;      // результат выполнения команды
  unsigned int Address;           	// для вычисления адреса

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

  // включаем прогресс-бар
  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 Scratchpad2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x0F;                                  // Write Scratchpad2
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  // инициализируем и начинаем вычислять CRC8
  CRC8=0;
  for(int j=0; j<8; j++)
  {     CRC8=CalcCRC8(CRC8, wr_buf.Data[1]);      // начинаем вычисление CRC8 для команды Write Scratchpad
        wr_buf.Data[1]=wr_buf.Data[1]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
  }
  Sleep(10);
  // посылаем SA
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                            // SendByte_1W
  wr_buf.Data[1]=InputData.SA;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,""); // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  for(int j=0; j<8; j++)
  {     CRC8=CalcCRC8(CRC8, wr_buf.Data[1]);      // продолжаем вычисление CRC8
        wr_buf.Data[1]=wr_buf.Data[1]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
  }
  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];   // байт из области блокнота 2
                break;
      default:  return OutputData;
    }
    if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");     // ошибка загрузки пакета
                           LBar->Free();                // уничтожаем форму с прогресс-баром
                           ClosePort();
                           return OutputData;
                         }
    for(int j=0; j<8; j++)
    {     CRC8=CalcCRC8(CRC8, wr_buf.Data[1]);      // продолжаем вычисление CRC8
          wr_buf.Data[1]=wr_buf.Data[1]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
    }
    Address+=1;                                         // увеличиваем адрес
    LBar->ProgressBar1->Position=100*(i+1)/InputData.Size;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // читаем CRC8 (1 байт)
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (байт CRC8)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  for(int j=0; j<8; j++)
  {     CRC8=CalcCRC8(CRC8, rd_buf.Data[0]);      // продолжаем вычисление CRC8
        rd_buf.Data[0]=rd_buf.Data[0]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
  }
  Sleep(1);
  // проверяем вычисленный CRC8
  if(CRC8)     SendMsgToLogForm(14,"");           // ошибка CRC8  // если всё нормально - результат должен быть равен нулю
  // посылаем 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 (0xAA) (только в Area2 или Area3) ----------------
//---------------------------------------------------------------------------
// input:       MAX31826_INPUT_DATA.AreaNumber
// output:      Success
MAX31826_OUTPUT_DATA MAX31826_ReadFromScratchpad(MAX31826_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  MAX31826_OUTPUT_DATA OutputData;      // здесь формируем ответ
  unsigned char CRC8;                   // для вычисления CRC8

  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
  if(InputData.AreaNumber == 2) wr_buf.Data[1]=0xAA;                                  // Read Scratchpad 2
  else                          wr_buf.Data[1]=0xBE;                                  // Read Scratchpad 1
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  // инициализируем и начинаем вычислять CRC8
  CRC8=0;
  for(int j=0; j<8; j++)
  {     CRC8=CalcCRC8(CRC8, wr_buf.Data[1]);      // начинаем вычисление CRC8 для команды Write Scratchpad
        wr_buf.Data[1]=wr_buf.Data[1]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
  }
  Sleep(10);
  if(InputData.AreaNumber == 2)
  {     //*** отправляем начальный адрес ***
        wr_buf.Size=2;
        wr_buf.Data[0]=0x61;                                  // SendByte_1W
        wr_buf.Data[1]=InputData.SA;                          // Start Address
        if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                                 LBar->Free();            // уничтожаем форму с прогресс-баром
                                 ClosePort();
                                 return OutputData;
                               }
        for(int j=0; j<8; j++)
        {       CRC8=CalcCRC8(CRC8, wr_buf.Data[1]);      // продолжаем вычисление CRC8 для отправленного адреса
                wr_buf.Data[1]=wr_buf.Data[1]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
        }
        Sleep(1);
  }
  //*** читаем содержимое блокнота ***
  for(unsigned int i=0; i<8; i++)  // перебираем все слова блокнота (Area2,3)
  { // посылаем команду чтения
    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;
                     }
    if(InputData.AreaNumber == 2)       SelectedChip.Area2[i]=rd_buf.Data[0];   // сохраняем прочитанный байт в область блокнота 2
    else                                SelectedChip.Area3[i]=rd_buf.Data[0];   // сохраняем прочитанный байт в область блокнота 3
    for(int j=0; j<8; j++)
    {     CRC8=CalcCRC8(CRC8, rd_buf.Data[0]);      // продолжаем вычисление CRC8 для команды Read Scratchpad 2
          rd_buf.Data[0]=rd_buf.Data[0]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
    }
    LBar->ProgressBar1->Position=100*(i+1)/8;      // вычисляем новую позицию прогресс-бара
    Sleep(1);
  }
  // читаем CRC8 (1 байт)
  wr_buf.Size=1;
  wr_buf.Data[0]=0x62;                                  // команда чтения байта
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(1);
  // принимаем пакет (байт CRC8)
  rd_buf=ReadFrom();                                // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");          // ошибка приёма пакета
                     LBar->Free();                      // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  for(int j=0; j<8; j++)
  {     CRC8=CalcCRC8(CRC8, rd_buf.Data[0]);      // продолжаем вычисление CRC8
        rd_buf.Data[0]=rd_buf.Data[0]>>1;         // сдвигаем вправо (делаем следующий бит младшим)
  }
  Sleep(1);
  // проверяем вычисленный CRC8
  if(CRC8)     SendMsgToLogForm(14,"");           // ошибка CRC8  // если всё нормально - результат должен быть равен нулю
  else         SendMsgToLogForm(13,"");           // CRC8 Ok
  // посылаем 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 2 В EEPROM (0x55) ---------------------------
//---------------------------------------------------------------------------
// output:      Success
MAX31826_OUTPUT_DATA MAX31826_CopyScratchpadToMemory()
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  MAX31826_OUTPUT_DATA OutputData;      // здесь формируем ответ

  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);
  if(Form1->CheckBox1->Checked == false) // если жёсткая подтяжка не нужна (старый программатор или независимое питание)
  {     // посылаем Token (0xA5)
        wr_buf.Size=2;
        wr_buf.Data[0]=0x61;                                  // SendByte_1W
        wr_buf.Data[1]=0xA5;
        if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                               LBar->Free();            // уничтожаем форму с прогресс-баром
                               ClosePort();
                               return OutputData;
                             }
        Sleep(10);
  }
  else                                  // если жёсткая подтяжка нужна
  {     // посылаем Token (0xA5) командой, которая сразу после отправки выполнит жёсткую подтяжку
        wr_buf.Size=2;
        wr_buf.Data[0]=0x67;                                  // SendByteSTRPU_1W
        wr_buf.Data[1]=0xA5;
        if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                               LBar->Free();            // уничтожаем форму с прогресс-баром
                               ClosePort();
                               return OutputData;
                             }
        Sleep(10);
        wr_buf.Size=1;                                        // убираем жёсткую подтяжку
        wr_buf.Data[0]=0x68;                                  // Clear_STRPU_1W
        if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                               LBar->Free();            // уничтожаем форму с прогресс-баром
                               ClosePort();
                               return OutputData;
                             }
  }
  // посылаем 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 в качестве ответа
}
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ ИЗ ПАМЯТИ (0xF0) (в область Area1) -----------------------------
//---------------------------------------------------------------------------
// input:       Input.SA, Input.Size
// output:      Success
MAX31826_OUTPUT_DATA MAX31826_ReadFromMemory(MAX31826_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  MAX31826_OUTPUT_DATA OutputData;      // здесь формируем ответ
  unsigned int Address;                 // для вычисления адреса

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

  // включаем прогресс-бар
  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);
  // посылаем Address
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.SA;
  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;
                     }
    SelectedChip.Area1[Address-SelectedChip.Area1Start]=rd_buf.Data[0];     // сохраняем прочитанный байт в Area1
    Sleep(1);
    Address+=1;                                                 // увеличиваем адрес

    LBar->ProgressBar1->Position=100*(i+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;
}
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ СОСТОЯНИЯ ЛИНИИ POWER (0xB4) -----------------------------------
//---------------------------------------------------------------------------
// output:      Success
MAX31826_OUTPUT_DATA MAX31826_ReadPowerSupply()
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  MAX31826_OUTPUT_DATA OutputData;       // здесь формируем ответ

  OutputData.Test=0x55;                 // 0x0 - parasite power, 0xFF - separate power
  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);
  }
  // посылаем Read Power Supply
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0xB4;                                  // Read Power Supply
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  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;
                       }
  OutputData.Success=true;
  // расшифровывать и выводить значение на форму будем в основной программе
  return OutputData;            // посылаем принятый ранее Test в качестве ответа
}
//---------------------------------------------------------------------------
//--- ЗАПУСК ПРЕОБРАЗОВАНИЯ (0x44) ------------------------------------------
//---------------------------------------------------------------------------
// output:      Status + Success
MAX31826_OUTPUT_DATA MAX31826_ConvertT()
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  MAX31826_OUTPUT_DATA OutputData;       // здесь формируем ответ

  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);
  }
  if(Form1->CheckBox1->Checked == false) // если жёсткая подтяжка не нужна (старый программатор или независимое питание)
  {     // посылаем Convert Temperature
        wr_buf.Size=2;
        wr_buf.Data[0]=0x61;                                  // SendByte_1W
        wr_buf.Data[1]=0x44;                                  // Convert T
        if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                               LBar->Free();            // уничтожаем форму с прогресс-баром
                               ClosePort();
                               return OutputData;
                             }
        Sleep(10);
        // посылаем команду чтения чтобы прочитать ещё один байт (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);
  }
  else                                  // если жёсткая подтяжка нужна
  {     // посылаем Convert Temperature и сразу после этого делаем жёсткую подтяжку
        wr_buf.Size=2;
        wr_buf.Data[0]=0x67;                                  // SendByteSTRPU_1W
        wr_buf.Data[1]=0x44;                                  // Convert T
        if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                               LBar->Free();            // уничтожаем форму с прогресс-баром
                               ClosePort();
                               return OutputData;
                             }
        Sleep(10);
        wr_buf.Size=1;                                        // убираем жёсткую подтяжку
        wr_buf.Data[0]=0x68;                                  // Clear_STRPU_1W
        if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                               LBar->Free();            // уничтожаем форму с прогресс-баром
                               ClosePort();
                               return OutputData;
                             }
        OutputData.Test=0xFF;   // считаем, что всё Ок!
  }
  // посылаем 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 в качестве ответа
}
//---------------------------------------------------------------------------
//--- ВЫЧИСЛЕНИЕ ЗНАЧЕНИЯ ТЕМПЕРАТУРЫ ---------------------------------------
//---------------------------------------------------------------------------
float MAX31826_DecodeTemperature()
{ float OutputValue, Temp1;     // сюда сформируем ответ + временная переменная (для вычисления степени двойки)
  unsigned int Temp2;           // количество значащих бит + временная переменная (для хранения значащих бит)

  // инициализируем и начинаем вычислять OutputValue
  OutputValue=0; Temp1=0.0625;                          // начальное значение 0, Temp1 = 2^-4
  Temp2=SelectedChip.Area3[1];                          // пишем биты MSB
  Temp2=(Temp2<<8)+SelectedChip.Area3[0];               // сдвигаем и добавляем значащие биты LSB
  // перебираем все значащие биты (кроме знака) и вычисляем значение температуры
  for(unsigned int i=0; i<11; i++)
  { OutputValue+=Temp1*(Temp2&1);
    Temp2>>=1;  // берём следующий значащий бит
    Temp1*=2;   // вычисляем новый вес значащего бита (следующая степень двойки)
  }
  // определяем знак (в Temp2 у нас как раз остались только биты знака)
  if(Temp2)     OutputValue*=-1.0;      // если самый старший бит не ноль, значит число отрицательное
  return OutputValue;
}
//---------------------------------------------------------------------------
//--- ЗАЛОЧИТЬ СТАРШУЮ ИЛИ МЛАДШУЮ ОБЛАСЬ ПАМЯТИ ----------------------------
//---------------------------------------------------------------------------
// input:       Input.SA - этот байт определяет, какую область памяти будем лочить (0x80 - Low, 0x81 - High)
// output:      Success
MAX31826_OUTPUT_DATA MAX31826_LockMemory(MAX31826_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  MAX31826_OUTPUT_DATA OutputData;      // результат выполнения команды

  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);
  }
  // посылаем Write Scratchpad2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x0F;                                  // Write Scratchpad2
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // посылаем SA (0x80 или 0x81)
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                            // SendByte_1W
  wr_buf.Data[1]=InputData.SA;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,""); // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  // посылаем 55h
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                            // SendByte_1W
  wr_buf.Data[1]=0x55;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,""); // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  // посылаем 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 Scratchpad2
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=0x55;                                  // Copy Scratchpad2
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");       // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(10);
  // посылаем токен A5h
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                            // SendByte_1W
  wr_buf.Data[1]=0xA5;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,""); // ошибка загрузки пакета
                         LBar->Free();            // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  Sleep(30);                                      // максимальное время записи / залочивания = 25 мс
  // посылаем 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;
}
//---------------------------------------------------------------------------
//--- ЧТЕНИЕ СТАТУСА LOCK БАЙТОВ --------------------------------------------
//---------------------------------------------------------------------------
// input:       Input.SA: 0x80 - прочитать статус младшей области, 0x81 - прочитать статус старшей области
// output:      Success, Test: Test содержит байт статуса
MAX31826_OUTPUT_DATA MAX31826_ReadLockStatus(MAX31826_INPUT_DATA InputData)
{ WRITE_BUFFER wr_buf;                  // буфер для отправки данных
  READ_BUFFER rd_buf;                   // буфер для приёма данных
  MAX31826_OUTPUT_DATA OutputData;      // здесь формируем ответ

  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);
  }
  // команда чтения 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);
  // посылаем Address
  wr_buf.Size=2;
  wr_buf.Data[0]=0x61;                                  // SendByte_1W
  wr_buf.Data[1]=InputData.SA;
  if(!WriteTo(wr_buf)) { SendMsgToLogForm(11,"");          // ошибка загрузки пакета
                         LBar->Free();                  // уничтожаем форму с прогресс-баром
                         ClosePort();
                         return OutputData;
                       }
  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);
  // читаем очередной байт
  rd_buf=ReadFrom();                                  // читаем
  if(!rd_buf.Size) { SendMsgToLogForm(21,"");         // ошибка приёма пакета
                     LBar->Free();                    // уничтожаем форму с прогресс-баром
                     ClosePort();
                     return OutputData;
                   }
  OutputData.Test=rd_buf.Data[0];                     // сохраняем прочитанный байт в Test
  // посылаем 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;
}
//---------------------------------------------------------------------------
