unit DeviceAT90S2313;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Device_template, StdCtrls, Mask, ToolEdit, ComboDigEdit, ComCtrls,
  Buttons, ExtCtrls, CommInt, VCLUtils, MainForm, SendThread, HexGrid;

type
  TfrmAT90S2313 = class(TfrmDevice)
    Panel2: TPanel;
    Label2: TLabel;
    cbEEPROM: TCheckBox;
    cbCode: TCheckBox;
    Panel4: TPanel;
    Label5: TLabel;
    Label6: TLabel;
    Label8: TLabel;
    edManufId: TEdit;
    edDevId1: TEdit;
    edDevId2: TEdit;
    Panel5: TPanel;
    cbSPIEN: TCheckBox;
    cbFSTRT: TCheckBox;
    Label3: TLabel;
    Panel6: TPanel;
    Label4: TLabel;
    cbBit1: TCheckBox;
    cbBit2: TCheckBox;
    cbFuse: TCheckBox;
    cbLock: TCheckBox;
    sbErase: TSpeedButton;
    Label9: TLabel;
    procedure sbEraseClick(Sender: TObject);

  private
    FuseLockByte:byte;
    LockBits:byte;
    FuseBits:byte;
    SignByte1:byte;
    SignByte2:byte;
    SignByte3:byte;
    Buf:TThreadBuf;
    BufLen:Cardinal;
    strCmd:String;
    FRead:Cardinal;
    procedure UpdateFuseLockInfo;
    procedure PrepareFuseLockbits;

    procedure ReadData;
    procedure VerifyData;
    procedure WriteData;
    procedure BlankCheck;
    procedure EraseDevice;
    function  CheckDevice:boolean;
    function  WriteCmd(strCmd,strAnsw:string):boolean;
    procedure Reset;
    procedure FreeSendThread;

  public
    procedure DoRead;override;
    procedure DoProgr;override;
    procedure DoStop;override;
    procedure DoVerify;override;
    procedure DoBlankCheck;override;
    Constructor Create(AOwner:TComponent);override;
  end;


var
  frmAT90S2313: TfrmAT90S2313;



implementation

uses RUtilites, MessageForm;

{$R *.DFM}

Constructor TfrmAT90S2313.Create(AOwner:TComponent);
begin
  inherited;
  Self.edChipTo.MaxValue:=$3FF;
  Self.edChipFrom.MaxValue:=$3FF;
  frmMain.PageControl1.Pages[1].TabVisible:=true;
  frmMain.PageControl1.Pages[1].Caption:='EEPROM memory';
  Grid_EE:=frmMain.HexGrid_EE;
  CommPort.FlowControl:= fcCTS;
  CommPort.BaudRate:=br57600;


  Grid.DataCount:=$400*2;
  Grid_EE.DataCount:=$80;
  Grid.DataSize:=dsWord;
  CodeWordSize:=2;
  frmMain.UpdateToolBarExecute(Self);
  frmMain.UpdateStatusBar;
  frmMain.flLoFirst:=true;
end;





procedure TfrmAT90S2313.DoRead;
begin
//  if not checkDeviceSelection then exit;
  CheckSendThread;
  FSendThread.OnExecuteProcess:=ReadData;
  FSendThread.OnEndProcess:=FreeSendThread;
  FSendThread.Resume;
end;

procedure TfrmAT90S2313.DoVerify;
begin
//  if not checkDeviceSelection then exit;
  CheckSendThread;
  FSendThread.OnExecuteProcess:=VerifyData;
  FSendThread.OnEndProcess:=FreeSendThread;
  FSendThread.Resume;
end;

procedure TfrmAT90S2313.DoProgr;
begin
//  if not checkDeviceSelection then exit;
  CheckSendThread;
  FSendThread.OnExecuteProcess:=WriteData;
  FSendThread.OnEndProcess:=FreeSendThread;
  FSendThread.Resume;
end;

procedure TfrmAT90S2313.DoStop;
begin
  if FSendThread<>Nil then FSendThread.Terminate;
end;

procedure TfrmAT90S2313.DoBlankCheck;
begin
//  if not checkDeviceSelection then exit;
  CheckSendThread;
  FSendThread.OnExecuteProcess:=BlankCheck;
  FSendThread.OnEndProcess:=FreeSendThread;
  FSendThread.Resume;
end;

procedure TfrmAT90S2313.sbEraseClick(Sender: TObject);
begin
  inherited;
  CheckSendThread;
  FSendThread.OnExecuteProcess:=EraseDevice;
  FSendThread.OnEndProcess:=FreeSendThread;
  FSendThread.Resume;

end;


procedure TfrmAT90S2313.UpdateFuseLockInfo;
begin
  if (FuseLockByte and $80)=0 then cbBit1.Checked:=true
  else cbBit1.Checked:=false;
  if (FuseLockByte and $40)=0 then cbBit2.Checked:=true
  else cbBit2.Checked:=false;
  if (FuseLockByte and $20)=0 then cbSPIEN.Checked:=true
  else cbSPIEN.Checked:=false;
  if (FuseLockByte and $01)=0 then cbFSTRT.Checked:=true
  else cbFSTRT.Checked:=false;
  edManufId.text:=Format('%.2x',[SignByte1]);
  edDevId1.text:=Format('%.2x',[SignByte2]);
  edDevId2.text:=Format('%.2x',[SignByte3]);
end;

procedure TfrmAT90S2313.PrepareFuseLockbits;
begin
  LockBits:=$FF;
  FuseBits:=$FF;
  if  cbBit1.Checked then
    LockBits:=LockBits xor $02;
  if  cbBit2.Checked then
    LockBits:=LockBits xor $04;

  if cbSPIEN.Checked then
    FuseBits:=FuseBits xor $20;
  if cbFSTRT.Checked then
    FuseBits:=FuseBits xor $01;
end;

// ----------------------------------------------------------------------------
//
//  Procedures called from SendThread
//
// ----------------------------------------------------------------------------
//


Procedure TfrmAT90S2313.Reset;
var
    Buf:TThreadBuf;
    FRead:Cardinal;  // Число прочитанных символов
    rstr:string;
begin
  with  FSendThread do
  begin
    Synchronize(BottonsDisable);  // Запретить все кнопки
    try
      DeviceEnabled:=false;       // Считать вначале, что прибор недоступен
      PurgePort;
      SetTimeouts;        // Очистить порт и установить тайм-ауты

      buf[0]:=Chr(03);
      WriteToComm(1,buf);
      ReadFromComm(100,Buf,FRead);
      SetString(rstr,Buf,Fread);
 //     if true then
      if copy(rstr,Fread,1)='>' then
      begin
        DeviceEnabled:=true;
        strCmd:='S1'+#13;
        BufLen:=FormatBuf(Buf,SizeOf(Buf),'%s',2,[strCmd]);
        FSendThread.WriteToComm(BufLen,Buf);
        ReadFromComm(3,Buf,FRead);
        ReadFromComm(4,Buf,FRead);
        SetString(rstr,Buf,Fread);
        if rstr<>(#13+#10+'>') then
        begin
          DeviceEnabled:=false;
          MessageDlg('Device disabled!',mtInformation,[mbOK],0)
        end;
      end;
    except
      On E:ESendThreadError do MessageDlg(E.Message,mtError,[mbOK],0);
      else Raise;

    end;
  end;
end;






function TfrmAT90S2313.CheckDevice:boolean;
begin
  Self.Reset;
  if  DeviceEnabled then
    result:=true
  else
  begin
    result:=false;
    MessageDlg('No Answer!',mtInformation,[mbOK],0)
  end;
end;

function TfrmAT90S2313.WriteCmd(strCmd,strAnsw:string):boolean;
var rstr:string;
begin
  result:=true;
  BufLen:=FormatBuf(Buf,SizeOf(Buf),'%s',2,[strCmd]);
  FSendThread.WriteToComm(BufLen,Buf);

  FSendThread.ReadFromComm(BufLen,Buf,FRead);
  SetString(rstr,Buf,Fread);
  if rstr<>strCmd then
  begin
    MessageDlg('Request:'+strCmd+#13+#10+
               'Answer: '+rstr,mtError,[mbOK],0);
    result:=false;
  end;
  FSendThread.ReadFromComm(Length(strAnsw),Buf,FRead);
  SetString(rstr,Buf,Fread);
  if strAnsw='' then exit;
  if rstr<>strAnsw then
  begin
    MessageDlg('Command failure: '+strCmd,mtError,[mbOK],0);
    result:=false;
  end;
end;




procedure TfrmAT90S2313.ReadData;
var
    str:string;
    i,k:integer;
    j:word;
const MaxRead = 100;
begin
  with FSendThread do
  begin
    Synchronize(UpdateGrid);
    Synchronize(BottonsDisable);
    if not CheckDevice then exit;   // Не выполнять чтение если прибор недоступен
    PurgePort;
    SetTimeouts;
    try

      // Чтение памяти программ
      // Задаются адреса первого и последнего двухбайтных слов
      strCmd:='R'+format('%.4x %.4x',[edChipFrom.value,edChipTo.value])+#13;
      if not WriteCmd(strCmd,'') then Abort;

      CurBufAdr:=BufOffSet;
      repeat
        ReadFromComm(MaxRead,Buf,FRead);
        for i:=0 to  FRead-1 do
        begin
          str:=str+Buf[i];
          if Buf[i]=Chr($0a) then
          begin
            if str[5]='=' then
            begin
              k:=((Length(str)-7) div 2);
              if k>0 then
              begin
                j:=0;
                repeat

      // Байты идут в порядке старший-младший
      // В принятой кодировке HEX порядок младший-старший
      // Для приведения к принятой кодировке поменяем порядок

                  PDataBuf(Grid.DataBufer)^.data[j+CurBufAdr+1]:=StrToInt('$'+copy(str,6+(j)*2,2));
                  PDataBuf(Grid.DataBufer)^.data[j+CurBufAdr]:=StrToInt('$'+copy(str,6+(j+1)*2,2));
                  j:=j+2;
                until j>(k-1)  ;
                FProgressBarPos:=FProgressBarPos+(k div 2);
                CurBufAdr:=CurBufAdr+k;
                Synchronize(UpdateProgress);
              end;
            end;
            str:='';
          end;
        end;
      until MaxRead<>FRead;
      if (CurBufAdr-BufOffSet)<> ((ChipHiAdr-ChipLoAdr+1)*2) then
      begin
        MessageDlg('Read Code memory not complete!',mtError,[mbOK],0);
        Abort;
      end;


      // Чтение памяти EEPROM
      FProgressBarMax:=$7F;
      FProgressBarPos:=0;
      Synchronize(UpdateProgress);
      strCmd:='R 0 7F 1'+#13;
      if not WriteCmd(strCmd,'') then Abort;

      CurBufAdr:=0;
      repeat
        ReadFromComm(MaxRead,Buf,FRead);
        for i:=0 to  FRead-1 do
        begin
          str:=str+Buf[i];
          if Buf[i]=Chr($0a) then
          begin
            if str[5]='=' then
            begin
              k:=((Length(str)-7) div 2);
              if k>0 then
              begin
                for j:=0 to k-1 do
                begin
                  PDataBuf(Grid_EE.DataBufer)^.data[j+CurBufAdr]:=StrToInt('$'+copy(str,6+j*2,2));
                end;
                FProgressBarPos:=FProgressBarPos+k;
                CurBufAdr:=CurBufAdr+k;
                Synchronize(UpdateProgress);
              end;
            end;
            str:='';
          end;
        end;
      until MaxRead<>FRead;
      if CurBufAdr <> $80 then
      begin
        MessageDlg('Read EEPROM memory not complete!',mtError,[mbOK],0);
        Abort;
      end;

      strCmd:='R 0 0 2'+#13;
      if not WriteCmd(strCmd,#13+#10) then Abort;
      ReadFromComm(MaxRead,Buf,FRead);
      SetString(str,Buf,Fread);
      FuseLockByte:=StrToInt('$'+Copy(str,1,2));
      SignByte1:=StrToInt('$'+Copy(str,4,2));
      SignByte2:=StrToInt('$'+Copy(str,7,2));
      SignByte3:=StrToInt('$'+Copy(str,10,2));
      Synchronize(UpdateFuseLockInfo);
    finally
      Synchronize(RefreshGrid);
    end;
  end;
end;




procedure TfrmAT90S2313.WriteData;
var i,k:Longint;
    str:string;
begin
  with FSendThread do
  begin
    Synchronize(UpdateGrid);
    Synchronize(BottonsDisable);
    if not CheckDevice then exit;   // Не выполнять чтение если прибор недоступен
    PurgePort;
    FSendThread.TimeOuts(10,1,100,0,0);

    try
      if cbCode.Checked then
      begin
        // Запись памяти программ
        strCmd:='W '+format('%.4x %.4x',[ChipLoAdr,ChipHiAdr])+#13;
        if not WriteCmd(strCmd,#13+#10+'-') then Abort;

        CurBufAdr:=BufOffSet;
        str:='';
        k:=0;

        for i:=0 to ((ChipHiAdr-ChipLoAdr+1)*2-1) do
        begin

      // Байты должны идти в порядке старший-младший
      // В принятой кодировке HEX порядок младший-старший
      // Для приведения к необходимому порядку поменяем байты местами

          str:=str+Format('%.2x',[PDataBuf(Grid.DataBufer)^.data[CurBufAdr+1]]);
          str:=str+Format('%.2x',[PDataBuf(Grid.DataBufer)^.data[CurBufAdr]]);
          CurBufAdr:=CurBufAdr+2;
          k:=k+2;
          if k=32 then
          begin
            if not WriteCmd(str+#13,#13+#10+'-') then
            begin
              MessageDlg('Programm Code memory not complete!',mtError,[mbOK],0);
              Abort;
            end;
            FProgressBarPos:=FProgressBarPos+16;
            Synchronize(UpdateProgress);

            k:=0;
            str:='';
          end;
        end;
        if k>0 then
        begin
          if not WriteCmd(str+#13,#13+#10+'-') then
          begin
            MessageDlg('Programm Code memory not complete!',mtError,[mbOK],0);
            Abort;
          end;
        end;
        ReadFromComm(100,Buf,FRead);
        SetString(str,Buf,Fread);
        if copy(str,Length(str),1)<>'>' then
        begin
          MessageDlg('Programm Code memory not complete!',mtError,[mbOK],0);
          Abort;
        end;
      end;

      if cbEEPROM.Checked then
      begin
        // Запись памяти EEPROM
        FProgressBarMax:=$7F;
        FProgressBarPos:=0;
        Synchronize(UpdateProgress);

        strCmd:='W 00 7F 1'+#13;
        if not WriteCmd(strCmd,#13+#10+'-') then Abort;

        CurBufAdr:=0;
        str:='';
        k:=0;
        for i:=0 to $7F do
        begin
          str:=str+Format('%.2x',[PDataBuf(Grid_EE.DataBufer)^.data[CurBufAdr]]);
          Inc(CurBufAdr);
          Inc(k);
          if k=16 then
          begin
            if not WriteCmd(str+#13,#13+#10+'-') then
            begin
              MessageDlg('Programm EEPROM memory not complete!',mtError,[mbOK],0);
              Abort;
            end;
            FProgressBarPos:=FProgressBarPos+16;
            Synchronize(UpdateProgress);
            k:=0;
            str:='';
          end;
        end;
        if k>0 then
        begin
          if not WriteCmd(str+#13,#13+#10+'-') then
          begin
            MessageDlg('Programm EEPROM memory not complete!',mtError,[mbOK],0);
            Abort;
          end;
        end;
        ReadFromComm(100,Buf,FRead);
        SetString(str,Buf,Fread);
        if copy(str,Length(str),1)<>'>' then
        begin
          MessageDlg('Programm Code memory not complete!',mtError,[mbOK],0);
          Abort;
        end;
      end;


      Synchronize(PrepareFuseLockBits);
      if cbFuse.Checked then
      begin
        // Запись Fuse bits
        str:=format('%.2x',[FuseBits]);
        str:='W '+str+' 0 2'+#13;
        if not WriteCmd(str,#13+#10+'>') then
        begin
          MessageDlg('Programm Fuse Bits not complete!',mtError,[mbOK],0);
          Abort;
        end;
      end;

      if cbLock.Checked then
      begin
        // Запись Fuse bits
        str:=format('%.2x',[LockBits]);
        str:='W '+str+' 0 3'+#13;
        if not WriteCmd(str,#13+#10+'>') then
        begin
          MessageDlg('Programm Lock Bits not complete!',mtError,[mbOK],0);
          Abort;
        end;
      end;


    finally
      Synchronize(RefreshGrid);
    end;
  end;
end;






procedure TfrmAT90S2313.VerifyData;
Label SkeepMemoryVerify,SkeepEEPROMVerify;
var
    str:string;
    i,k:integer;
    j:word;
    CodeWord:Word;
const MaxRead = 100;
begin
  with FSendThread do
  begin
    Synchronize(UpdateGrid);
    Synchronize(BottonsDisable);
    if not CheckDevice then exit;   // Не выполнять чтение если прибор недоступен
    PurgePort;
    SetTimeouts;
    try

      // Чтение памяти программ
      strCmd:='R'+format('%.4x %.4x',[edChipFrom.value,edChipTo.value])+#13;
      if not WriteCmd(strCmd,'') then Abort;

      CurBufAdr:=BufOffSet;
      repeat
        ReadFromComm(MaxRead,Buf,FRead);
        for i:=0 to  FRead-1 do
        begin
          str:=str+Buf[i];
          if Buf[i]=Chr($0a) then
          begin
            if str[5]='=' then
            begin
              k:=((Length(str)-7) div 4);
              if k>0 then
              begin
                j:=0;
                repeat
                  CodeWord:=PDataBuf(Grid.DataBufer)^.data[j*2+CurBufAdr+1];
                  CodeWord:=CodeWord shl 8;
                  CodeWord:=CodeWord or PDataBuf(Grid.DataBufer)^.data[j*2+CurBufAdr];
                  if CodeWord<>StrToInt('$'+copy(str,6+j*4,4)) then
                  begin
                    if MessageDlg('Code memory verify failed'+#13+#10+
                      'Addres:'+Format('%.4x',[CurBufAdr+j])+#13+#10+
                      'Chip:   '+copy(str,6+j*4,4)+#13+#10+
                      'Buffer: '+Format('%.4x',[CodeWord])
                      ,mtError,[mbIgnore,mbAbort],0)=mrAbort then
                    begin
                      PurgePort;
                      Buf[0]:=^C;
                      WriteToComm(1,Buf);
                      ReadFromComm(100,Buf,FRead);
                      Goto SkeepMemoryVerify;
                    end;
                  end;
                  j:=j+1;
                until j>(k-1);
                FProgressBarPos:=FProgressBarPos+k;
                CurBufAdr:=CurBufAdr+k*2;
                Synchronize(UpdateProgress);
              end;
            end;
            str:='';
          end;
        end;
      until MaxRead<>FRead;
SkeepMemoryVerify:

      // Чтение памяти EEPROM
      FProgressBarMax:=$7F;
      FProgressBarPos:=0;
      Synchronize(UpdateProgress);
      strCmd:='R 0 7F 1'+#13;
      if not WriteCmd(strCmd,'') then Abort;

      CurBufAdr:=0;
      repeat
        ReadFromComm(MaxRead,Buf,FRead);
        for i:=0 to  FRead-1 do
        begin
          str:=str+Buf[i];
          if Buf[i]=Chr($0a) then
          begin
            if str[5]='=' then
            begin
              k:=((Length(str)-7) div 2);
              if k>0 then
              begin
                for j:=0 to k-1 do
                begin
                  if PDataBuf(Grid_EE.DataBufer)^.data[j+CurBufAdr]<>
                    StrToInt('$'+copy(str,6+j*2,2)) then
                  begin
                    if MessageDlg('EEPROM verify failed'+#13+#10+
                      'Addres:'+Format('%.4x',[CurBufAdr+j])+#13+#10+
                      'Chip:   '+copy(str,6+j*2,2)+#13+#10+
                      'Buffer: '+Format('%.2x',[PDataBuf(Grid_EE.DataBufer)^.data[j+CurBufAdr]])
                      ,mtError,[mbIgnore,mbAbort],0)=mrAbort then
                    begin
                      PurgePort;
                      Buf[0]:=^C;
                      WriteToComm(1,Buf);
                      ReadFromComm(100,Buf,FRead);
                      Goto SkeepEEPROMVerify;
                    end;
                  end;

                end;
                FProgressBarPos:=FProgressBarPos+k;
                CurBufAdr:=CurBufAdr+k;
                Synchronize(UpdateProgress);
              end;
            end;
            str:='';
          end;
        end;
      until MaxRead<>FRead;
SkeepEEPROMVerify:
    finally
      Synchronize(RefreshGrid);
    end;
  end;
end;

procedure TfrmAT90S2313.BlankCheck;
Label SkeepMemoryCheck,SkeepEEPROMCheck;
var
    str:string;
    i,k:integer;
    j:word;
const MaxRead = 100;
begin
  with FSendThread do
  begin
    Synchronize(UpdateGrid);
    Synchronize(BottonsDisable);
    if not CheckDevice then exit;   // Не выполнять чтение если прибор недоступен
    PurgePort;
    SetTimeouts;
    try

      // Чтение памяти программ
      strCmd:='R'+format('%.4x %.4x',[edChipFrom.value,edChipTo.value])+#13;
      if not WriteCmd(strCmd,'') then Abort;

      CurBufAdr:=BufOffSet;
      repeat
        ReadFromComm(MaxRead,Buf,FRead);
        for i:=0 to  FRead-1 do
        begin
          str:=str+Buf[i];
          if Buf[i]=Chr($0a) then
          begin
            if str[5]='=' then
            begin
              k:=((Length(str)-7) div 4);
              if k>0 then
              begin
                for j:=0 to k-1 do
                begin
                  if StrToInt('$'+copy(str,6+j*4,4))<>$FFFF then
                  begin
                    if MessageDlg('Code memory not blank'+#13+#10+
                      'Addres:'+Format('%.4x',[CurBufAdr+j])+#13+#10+
                      'Chip:   '+copy(str,6+j*4,4)
                      ,mtError,[mbIgnore,mbAbort],0)=mrAbort then
                    begin
                      PurgePort;
                      Buf[0]:=^C;
                      WriteToComm(1,Buf);
                      ReadFromComm(100,Buf,FRead);
                      Goto SkeepMemoryCheck;
                    end;
                  end;
                end;
                FProgressBarPos:=FProgressBarPos+k;
                CurBufAdr:=CurBufAdr+k*2;
                Synchronize(UpdateProgress);
              end;
            end;
            str:='';
          end;
        end;
      until MaxRead<>FRead;
SkeepMemoryCheck:

      // Чтение памяти EEPROM
      FProgressBarMax:=$7F;
      FProgressBarPos:=0;
      Synchronize(UpdateProgress);
      strCmd:='R 0 7F 1'+#13;
      if not WriteCmd(strCmd,'') then Abort;

      CurBufAdr:=0;
      repeat
        ReadFromComm(MaxRead,Buf,FRead);
        for i:=0 to  FRead-1 do
        begin
          str:=str+Buf[i];
          if Buf[i]=Chr($0a) then
          begin
            if str[5]='=' then
            begin
              k:=((Length(str)-7) div 2);
              if k>0 then
              begin
                for j:=0 to k-1 do
                begin
                  if StrToInt('$'+copy(str,6+j*2,2))<>$FF then
                  begin
                    if MessageDlg('EEPROM not blank'+#13+#10+
                      'Addres:'+Format('%.4x',[CurBufAdr+j])+#13+#10+
                      'Chip:   '+copy(str,6+j*2,2)
                      ,mtError,[mbIgnore,mbAbort],0)=mrAbort then
                    begin
                      PurgePort;
                      Buf[0]:=^C;
                      WriteToComm(1,Buf);
                      ReadFromComm(100,Buf,FRead);
                      Goto SkeepEEPROMCheck;
                    end;
                  end;

                end;
                FProgressBarPos:=FProgressBarPos+k;
                CurBufAdr:=CurBufAdr+k;
                Synchronize(UpdateProgress);
              end;
            end;
            str:='';
          end;
        end;
      until MaxRead<>FRead;
SkeepEEPROMCheck:
    finally
      Synchronize(RefreshGrid);
    end;
  end;
end;

procedure TfrmAT90S2313.EraseDevice;
begin
  with FSendThread do
  begin
    Synchronize(BottonsDisable);
    if not CheckDevice then exit;   // Не выполнять чтение если прибор недоступен
    PurgePort;
    FSendThread.TimeOuts(10,1,1000,0,0);

    try
      strCmd:='E 01'+#13;
      if not WriteCmd(strCmd,#13+#10+'>') then
      begin
        MessageDlg('Erase not complete!',mtError,[mbOK],0);
      end
      else
      begin
        MessageDlg('Erase complete!',mtInformation,[mbOK],0);
      end;


    finally
      Synchronize(RefreshGrid);
    end;
  end;
end;


procedure TfrmAT90S2313.FreeSendThread;
begin
  FProgressBarPos:=0;
  FSendThread.Synchronize(UpdateProgress);
  FSendThread.Synchronize(BottonsEnable);
  FSendThread:=nil;
end;




end.
