Ignore:
Timestamp:
Aug 15, 2012, 10:45:44 AM (12 years ago)
Author:
chronos
Message:
  • Added: Class TCommMark in PinConnection package which can divide communication data stream by data mark. Mark is sequence of bytes.
  • Modified: DallasProgrammer in ISPProgrammer package now use TCommMark class for better protocol handling.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • ISPProgrammer/Dallas/UDallasProgrammer.pas

    r409 r410  
    66
    77uses
    8   Classes, SysUtils, USerialPort, UCommSerialPort, UCommPin,
     8  Classes, SysUtils, USerialPort, UCommSerialPort, UCommPin, UCommMark,
    99  UJobProgressView, SyncObjs, DateUtils, Dialogs, URegistry,
    1010  Forms, UISPProgrammer, Registry, UBinarySerializer, SpecializedList;
    1111
    1212const
    13   NewLine = #$0D#$0A;
     13  Mark = #13#10;
    1414
    1515type
     
    2222    FOnLogData: TOnLogDataEvent;
    2323    Pin: TCommPin;
    24     Response: TBinarySerializer; // should be thread safe
     24    CommMark: TCommMark;
     25    ResponseQueue: TListObject;
    2526    ResponseLock: TCriticalSection;
    2627    ResponseTemp: TBinarySerializer;
    27     ReceiveEvent: TEvent;
    2828    SerialPortBackup: TCommSerialPort;
    2929    SerialPortBackupPin: TCommPin;
    3030    HexData: TStringList;
    3131    Request: TBinarySerializer;
    32     StartTime: TDateTime;
    33     WaitResult: TWaitResult;
     32    Mark: TListByte;
    3433    procedure ReceiveData(Sender: TCommPin; Stream: TListByte);
    35     function WaitForString(EndString: string; Timeout: TDateTime): TWaitResult;
     34    function ReadResponse: string;
     35    function ResponseCount: Integer;
    3636    procedure ResponseClear;
    3737    procedure CheckErrorCode(Value: string);
     
    7070  SInvalidResponse = 'Invalid response';
    7171  SUnknownProgrammerResponse = 'Unknown flash programmer response "%s"';
    72   SIdentification = 'Identification';
     72  SIdentification = 'Device identification';
    7373
    7474{ TDallasProgrammer }
     
    7777var
    7878  OldPosition: Integer;
     79  NewList: TListByte;
    7980begin
    8081  try
    8182    ResponseLock.Acquire;
    82     OldPosition := Response.Position;
    83     Response.Position := Response.List.Count;
    84     Response.WriteList(Stream, 0, Stream.Count);
    85     Response.Position := OldPosition;
     83    NewList := TListByte.Create;
     84    NewList.Assign(Stream);
     85    ResponseQueue.Add(NewList);
    8686  finally
    8787    ResponseLock.Release;
    8888  end;
    89   ReceiveEvent.SetEvent;
    90 end;
    91 
    92 function TDallasProgrammer.WaitForString(EndString: string; Timeout: TDateTime): TWaitResult;
    93 var
     89end;
     90
     91function TDallasProgrammer.ReadResponse: string;
     92var
     93  Serializer: TBinarySerializer;
    9494  StartTime: TDateTime;
    95   TimeoutPart: TDateTime;
    96   OldPosition: Integer;
    9795  ElapsedTime: TDateTime;
    9896begin
    9997  StartTime := Now;
    10098  repeat
     99    if ResponseCount > 0 then Break;
    101100    ElapsedTime := Now - StartTime;
    102     TimeoutPart := Timeout - ElapsedTime;
    103     if TimeoutPart < 0 then TimeoutPart := 0;
    104     Result := ReceiveEvent.WaitFor(Round(TimeOutPart / OneMillisecond));
    105     try
    106       ResponseLock.Acquire;
    107       OldPosition := Response.Position;
    108       Response.Position := 0;
    109       Response.ReadStringTerminated(EndString);
    110       if (Response.Position = 0) then begin
    111         Result := wrTimeout;
    112       end;
    113       Response.Position := OldPosition;
    114     finally
    115       ResponseLock.Release;
    116     end;
    117   until (Result = wrSignaled) or (ElapsedTime > Timeout);
     101  until (ElapsedTime > Timeout);
     102  if ElapsedTime > Timeout then
     103    raise Exception.Create(STimeout);
     104  try
     105    ResponseLock.Acquire;
     106    Serializer := TBinarySerializer.Create;
     107    Serializer.List := TListByte(ResponseQueue.First);
     108    Result := Serializer.ReadString(Serializer.List.Count);
     109    ResponseQueue.Delete(0);
     110  finally
     111    Serializer.Free;
     112    ResponseLock.Release;
     113  end;
     114end;
     115
     116function TDallasProgrammer.ResponseCount: Integer;
     117begin
     118  try
     119    ResponseLock.Acquire;
     120    Result := ResponseQueue.Count;
     121  finally
     122    ResponseLock.Release;
     123  end;
    118124end;
    119125
     
    122128  try
    123129    ResponseLock.Acquire;
    124     Response.Clear;
    125     ReceiveEvent.ResetEvent;
     130    ResponseQueue.Clear;
    126131  finally
    127132    ResponseLock.Release;
     
    148153    SerialPort.BaudRate := BaudRate;
    149154    SerialPort.DTR := True;
    150     SerialPort.Pin.Connect(Pin);
     155    SerialPort.Pin.Connect(CommMark.PinRaw);
    151156    SerialPort.Flush;
    152157    SerialPort.Purge;
    153     ResponseClear;
    154158    SerialPort.Active := True;
    155159    if Assigned(FOnLogData) then
    156160      Pin.OnLogData := FOnLogData;
     161    ResponseClear;
     162    CommMark.Active := True;
    157163
    158164    ReadIdentification;
    159165  end else begin
     166    CommMark.Active := False;
    160167    SerialPort.Active := False;
    161168    SerialPort.Assign(SerialPortBackup);
     
    215222  ResponseClear;
    216223  Request.WriteByte(Ord('D'));
    217   Request.WriteByte($0D);
    218   Pin.Send(Request.List);
    219   if WaitForString(NewLine, Timeout) <> wrSignaled then begin
    220     raise Exception.Create(STimeout);
    221   end;
    222   Response.ReadStringTerminated(NewLine); // D
    223   try
    224     ResponseLock.Acquire;
    225     Response.List.DeleteItems(0, Response.Position);
    226     Response.Position := 0;
    227   finally
    228     ResponseLock.Release;
    229   end;
     224  Pin.Send(Request.List);
     225  Value := ReadResponse;
     226  ReadResponse; // Empty line
    230227
    231228  //HexFile.SaveToStringList(HexData);
     
    235232  I := 0;
    236233  repeat
    237     //Request.WriteString(HexData[I]);
    238     //Request.WriteByte($0D);
    239     //Pin.Send(Request);
    240     if WaitForString(NewLine, Timeout) <> wrSignaled then
    241       raise Exception.Create(STimeout);
    242 
    243     //if ReceiveEvent.WaitFor(Round(Timeout / OneMillisecond)) <> wrSignaled then
    244     //  raise Exception.Create(STimeout);
    245     try
    246       ResponseLock.Acquire;
    247       //Response.Position := 0;
    248       //if Response.Size = 0 then
    249       //  raise Exception.Create(SEmptyBuffer);
    250       Value := Response.ReadStringTerminated(NewLine);
    251       if Value <> '' then begin
    252         Response.List.DeleteItems(0, Response.Position);
    253         Response.Position := 0;
    254         //Log(Value);
    255         HexData.Add(Value);
    256         //Response.Size := 0;
    257         if Value = ':00000001FF' then Break;
    258         Inc(I);
    259       end;
    260     finally
    261       ResponseLock.Release;
     234    Value := ReadResponse;
     235    if Value <> '' then begin
     236      //Log(Value);
     237      HexData.Add(Value);
     238      if Value = ':00000001FF' then Break;
     239      Inc(I);
    262240    end;
    263241    Job.Progress.Value := I;
     
    280258  ResponseClear;
    281259  Request.WriteByte(Ord('V'));
    282   Request.WriteByte($0D);
    283   Pin.Send(Request.List);
    284   if WaitForString(NewLine, Timeout) <> wrSignaled then begin
    285     Pin.Send(Request.List);
    286     raise Exception.Create(STimeout);
    287   end;
    288   HexFile.SaveToStringList(HexData);
    289   Job.Progress.Max := HexData.Count;
    290   for I := 0 to HexData.Count - 1 do begin
    291     Request.List.Count := 0;
    292     ResponseClear;
    293     Request.WriteString(HexData[I]);
    294     Request.WriteByte($0D);
    295     Pin.Send(Request.List);
    296     if ReceiveEvent.WaitFor(Round(Timeout / OneMillisecond)) <> wrSignaled then
    297       raise Exception.Create(STimeout);
    298     try
    299       ResponseLock.Acquire;
    300       Response.Position := 0;
    301       if Response.List.Count = 0 then
    302         raise Exception.Create(SEmptyBuffer);
    303       Value := Chr(Response.ReadByte);
    304     finally
    305       ResponseLock.Release;
    306     end;
    307     CheckErrorCode(Value);
    308     Job.Progress.Value := I;
    309     if Job.Terminate then Break;
     260  Pin.Send(Request.List);
     261  ReadResponse;
     262
     263  try
     264    CommMark.Mark.Clear;
     265    HexFile.SaveToStringList(HexData);
     266    Job.Progress.Max := HexData.Count;
     267    for I := 0 to HexData.Count - 1 do begin
     268      Request.Clear;
     269      ResponseClear;
     270      Request.WriteString(HexData[I]);
     271      Request.WriteList(Mark, 0, Mark.Count);
     272      Pin.Send(Request.List);
     273      Value := ReadResponse;
     274      CheckErrorCode(Value);
     275      Job.Progress.Value := I;
     276      if Job.Terminate then Break;
     277    end;
     278  finally
     279    CommMark.Mark.Assign(Mark);
    310280  end;
    311281end;
     
    320290  ResponseClear;
    321291  Request.WriteByte(Ord('L'));
    322   Request.WriteByte($0D);
    323   Pin.Send(Request.List);
    324   if WaitForString(NewLine, Timeout) <> wrSignaled then begin
    325     Pin.Send(Request.List);
    326     raise Exception.Create(STimeout);
    327   end;
    328   HexFile.SaveToStringList(HexData);
    329   Job.Progress.Max := HexData.Count;
    330   for I := 0 to HexData.Count - 1 do begin
    331     Request.List.Count := 0;
    332     ResponseClear;
    333     Request.WriteString(HexData[I]);
    334     Request.WriteByte($0D);
    335     Pin.Send(Request.List);
    336     if ReceiveEvent.WaitFor(Round(Timeout / OneMillisecond)) <> wrSignaled then
    337       raise Exception.Create(STimeout);
    338     try
    339       ResponseLock.Acquire;
    340       Response.Position := 0;
    341       if Response.List.Count = 0 then
    342         raise Exception.Create(SEmptyBuffer);
    343       Value := Chr(Response.ReadByte);
    344     finally
    345       ResponseLock.Release;
    346     end;
    347     CheckErrorCode(Value);
    348     Job.Progress.Value := I;
    349     if Job.Terminate then Break;
     292  Pin.Send(Request.List);
     293  Value := ReadResponse;
     294
     295  try
     296    CommMark.Mark.Clear;
     297    HexFile.SaveToStringList(HexData);
     298    Job.Progress.Max := HexData.Count;
     299    for I := 0 to HexData.Count - 1 do begin
     300      Request.Clear;
     301      ResponseClear;
     302      Request.WriteString(HexData[I]);
     303      Request.WriteList(Mark, 0, Mark.Count);
     304      Pin.Send(Request.List);
     305      Value := ReadResponse;
     306      CheckErrorCode(Value);
     307      Job.Progress.Value := I;
     308      if Job.Terminate then Break;
     309    end;
     310  finally
     311    CommMark.Mark.Assign(Mark);
    350312  end;
    351313end;
     
    357319  ResponseClear;
    358320  Request.WriteByte(Ord('K'));
    359   Request.WriteByte($0D);
    360   Pin.Send(Request.List);
    361   if WaitForString('>', Timeout) <> wrSignaled then
    362     raise Exception.Create(STimeout);
     321  Pin.Send(Request.List);
     322  ReadResponse;
    363323end;
    364324
     
    370330var
    371331  InitTimeout: TDateTime;
     332  Value: string;
    372333begin
    373334  Result := '';
    374335  InitTimeout := 6000 * OneMillisecond;
    375 
    376   Active := True;
    377 
    378   // Init and read identification
    379   StartTime := Now;
    380   repeat
    381     ResponseClear;
    382     Request.List.Count := 0;
    383     Request.WriteByte($0D);
    384     Pin.Send(Request.List);
    385     WaitResult := WaitForString('>', Timeout);
    386   until (WaitResult = wrSignaled) or ((Now - StartTime) > InitTimeout);
    387   if WaitResult <> wrSignaled then
    388     raise Exception.Create(STimeout);
    389   try
    390     ResponseLock.Acquire;
    391     Response.Position := 0;
    392     Response.ReadStringTerminated(NewLine);
    393     Identification := Response.ReadStringTerminated(NewLine);
    394     Result := Identification;
    395     Log(SIdentification + ': ' + Identification);
    396   finally
    397     ResponseLock.Release;
    398   end;
     336  Active := True;
     337
     338  ResponseClear;
     339  Request.Clear;
     340  Pin.Send(Request.List);
     341  ReadResponse; // Empty line
     342  Identification := ReadResponse;
     343  Result := Identification;
     344  Log(SIdentification + ': ' + Identification);
    399345end;
    400346
     
    404350  Capabilities := [ipcErase, ipcRead, ipcWrite, ipcReset];
    405351  Timeout := 3000 * OneMillisecond;
    406   ReceiveEvent := TSimpleEvent.Create;
    407   Response := TBinarySerializer.Create;
    408   Response.List := TListByte.Create;
    409   Response.OwnsList := True;
     352  ResponseQueue := TListObject.Create;
    410353  ResponseLock := TCriticalSection.Create;
    411354  ResponseTemp := TBinarySerializer.Create;
     
    414357  Pin := TCommPin.Create;
    415358  Pin.OnReceive := ReceiveData;
     359  Mark := TListByte.Create;
     360  Mark.SetArray([13, 10]);
     361  CommMark := TCommMark.Create;
     362  CommMark.Mark.Assign(Mark);
     363  CommMark.PinFrame.Connect(Pin);
    416364  BaudRate := 9600;
    417365  SerialPortBackup := TCommSerialPort.Create;
     
    421369begin
    422370  Active := False;
     371  Mark.Free;
     372  CommMark.Free;
    423373  SerialPortBackup.Free;
    424374  Pin.Free;
    425   Response.Free;
     375  ResponseQueue.Free;
    426376  ResponseLock.Free;
    427377  ResponseTemp.Free;
    428   ReceiveEvent.Free;
    429378  inherited Destroy;
    430379end;
Note: See TracChangeset for help on using the changeset viewer.