unit AVR;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  DevicesFrame, ImgList, StdCtrls, Mask, ToolEdit, ComboDigEdit, ComCtrls,
  CheckLst, ToolWin, ExtCtrls, Grids, StrUtils, RUtilites, SendThread;


type
  TfrmATMEL_AVR = class(TfrmDevice)
    procedure tbReadClick(Sender: TObject);
    procedure tbVerifyClick(Sender: TObject);
    procedure tbWriteClick(Sender: TObject);
    procedure tbEraseClick(Sender: TObject);
    procedure tbBlankCheckClick(Sender: TObject);
  private
    { Private declarations }
  protected
    //Процедуры передаваемые на выполнение потоку SendThread
    procedure Tr_ReadProcess;
    procedure Tr_WriteProcess;
    procedure Tr_EraseProcess;

  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;

  end;

var
  frmATMEL_AVR: TfrmATMEL_AVR;

implementation

uses MainForm, InProgress;

{$R *.DFM}

constructor TfrmATMEL_AVR.Create(AOwner: TComponent);
begin
  inherited;
  ChipClassID:='S 3';  // идентификатор для программатора
  frmMain.LoFirstOrder:=true;
end;

procedure TfrmATMEL_AVR.tbReadClick(Sender: TObject);
begin
  self.FProcessProc:=Tr_ReadProcess;
  inherited;
end;

procedure TfrmATMEL_AVR.tbVerifyClick(Sender: TObject);
begin
  self.FProcessProc:=Nil;
  inherited;
end;

procedure TfrmATMEL_AVR.tbWriteClick(Sender: TObject);
begin
  self.FProcessProc:=Tr_WriteProcess;
  inherited;
end;

procedure TfrmATMEL_AVR.tbEraseClick(Sender: TObject);
begin
  self.FProcessProc:=Tr_EraseProcess;
  inherited;
end;

procedure TfrmATMEL_AVR.tbBlankCheckClick(Sender: TObject);
begin
  self.FProcessProc:=Nil;
  inherited;
end;

{
.................................................................

Процедуры передаваемые на выполнение потоку SendThread

.................................................................
}
procedure TfrmATMEL_AVR.Tr_ReadProcess;
var ArIndx:integer;


  procedure ReadBITS(stID:string);
  var i,j,b:integer;
      st:string;
      cmdStr:string;
  begin
    cmdStr:='R 0 0 2'+#13;
    FSendThread.WriteStrToComm(cmdStr);
    FSendThread.ReadNChar(st,Length(cmdStr)+2);
    if Pos(cmdStr,st)=0 then
       Raise Exception.Create(strIsNotAnswer);
    FSendThread.ReadNChar(st,5);
    b:=StrToInt('$'+copy(st,1,2));
    for i:=0 to HIGH(NodesData) do
      if NodesData[i].strAreaID=stID then
      begin
        // Обработка соответствующего узла
        with trvParameters.Items[i] do
        begin
          if not HasChildren then break;
          // перебор субузлов заданного узла
          for j:=0 to count-1 do
          begin
            st:=NodesData[Item[j].AbsoluteIndex].strMask ;
            if CompareWithMask(b,st) then
              SelectSubNode(trvParameters.Items[i],trvParameters.Items[i].Item[j]);
          end;
        end; {with }
      end;
  end;

  procedure ReadID;
  var cmdStr,st:string;
      i:integer;
  begin
    cmdStr:='R 0 0 3'+#13;
    FSendThread.WriteStrToComm(cmdStr);
    FSendThread.ReadNChar(st,Length(cmdStr)+2);
    if Pos(cmdStr,st)=0 then
       Raise Exception.Create(strIsNotAnswer);
    FSendThread.ReadNChar(st,9);
    st:=copy(st,1,6);
    if FindNodeIndex('ID',i) then
    begin
      trvParameters.Items[i].Item[0].text:=st;
      SelectSubNode(trvParameters.Items[i],trvParameters.Items[i].Item[0]);
    end;

  end;

begin
  with FSendThread do
  begin
    if not CommPort.Enabled then CommPort.Open;
    try
      PurgePort;
      TimeOuts(1000,1,1000,1,1000,1);
      SetEventChar(#10);
      for ArIndx:=0 to lsvAreas.Items.Count-1 do
        If lsvAreas.Items[ArIndx].Checked then
        begin
          if AreasData[ArIndx].strID='CODE' then ReadDataToGrid(ArIndx,frmMain.CodeGrid,'',2);
          if AreasData[ArIndx].strID='EEPROM' then ReadDataToGrid(ArIndx,frmMain.EEPROMGrid,' 1',2);
          if AreasData[ArIndx].strID='LOCKBITS' then ReadBITS('LOCKBITS');
          if AreasData[ArIndx].strID='FUSES' then ReadBITS('FUSES');
        end;
        ReadID;
    finally
      CommPort.Close;
      // Закрыть окно InProgress
      PostMessage(frmInProgress.Handle,wm_ThreadDoneErrMsg,0,0);
    end;
  end; {with FSendThread}
end;



procedure TfrmATMEL_AVR.Tr_WriteProcess;
var ArIndx:integer;
//    DataBuf:array[0..127] of byte;


  procedure WriteBITS(stID:string);
  var i:integer;
      strMask,cmdStr:string;
      b:word;
  begin
    b:=0;
    // Поиск всех установок связанных с
    // данной областью
    for i:=0 to HIGH(NodesData) do
      if NodesData[i].strAreaID=stID then
      begin
        // Обработка соответствующего узла
        with trvParameters.Items[i] do
        begin
          if not HasChildren then break;
          strMask:=NodesData[NodesData[i].intSelSubIt].strMask2 ;
          b:=SetByMask(b,strMask);
        end; {with }
      end;
      cmdStr:=Format('%.2x',[b]);
      WriteDataFromStr(ArIndx,cmdStr,' 2');
  end;



begin
  with FSendThread do
  begin
    if not CommPort.Enabled then CommPort.Open;
    try
      PurgePort;
      TimeOuts(1000,1,1000,1,1000,1);
    //  SetEventChar(#10);
      for ArIndx:=0 to lsvAreas.Items.Count-1 do
        If lsvAreas.Items[ArIndx].Checked then
        begin
          if AreasData[ArIndx].strID='CODE' then
            WriteDataFromGrid(ArIndx,frmMain.CodeGrid,'',2);
          if AreasData[ArIndx].strID='EEPROM' then
            WriteDataFromGrid(ArIndx,frmMain.EEPROMGrid,' 1',2);
          if AreasData[ArIndx].strID='LOCKBITS' then
            WriteBITS('LOCKBITS');
          if AreasData[ArIndx].strID='FUSES' then
            WriteBITS('FUSES');
        end;
    finally
      CommPort.Close;
      // Закрыть окно InProgress
      PostMessage(frmInProgress.Handle,wm_ThreadDoneErrMsg,0,0);
    end;
  end; {with FSendThread}
end;

procedure TfrmATMEL_AVR.Tr_EraseProcess;
var str,cmdStr:string;
begin
  with FSendThread do
  begin
    if not CommPort.Enabled then CommPort.Open;
    try
      PurgePort;
      TimeOuts(1000,1,1000,1,1000,1);
      cmdStr:='E'+#13;
      WriteStrToComm(cmdStr);
      ReadNChar(str,Length(cmdStr)+3);
      if (cmdStr+#13+#10+'>')<>str then
        Raise Exception.Create(strIsNotValidAnswer);
    finally
      CommPort.Close;
      // Закрыть окно InProgress
      PostMessage(frmInProgress.Handle,wm_ThreadDoneErrMsg,0,0);
    end;
  end; {with FSendThread}
end;








initialization
   SetLength(ConstructorsList, Length(ConstructorsList)+1);
   ConstructorsList[High(ConstructorsList)].name:='TfrmATMEL_AVR';
   ConstructorsList[High(ConstructorsList)].ClassName:=TfrmATMEL_AVR;
end.
