Files
bds.mr.devmgr/src.devmgr/dev/usb/trinity/mr.trinity.pipe0.pas
T
2026-01-03 18:53:14 +01:00

136 lines
3.3 KiB
ObjectPascal

unit mr.trinity.pipe0;
interface
uses
Classes,
mr.dev.usb.pipe0;
type
TTrinityPipe0 = class( TPipe0)
public
procedure DownloadFirmware( Filename : string); overload; virtual;
procedure DownloadFirmware( Stm : TStream); overload; virtual;
end;
implementation
uses
SysUtils,
mr.trinity.hex,
mr.drv.usb.types,
mr.drv.usb;
{ TTrinityPipe0 }
// ================================================================================================
// Download Firmware (file)
// ================================================================================================
procedure TTrinityPipe0.DownloadFirmware(Filename: string);
var
stm : TMemoryStream;
begin
if FileExists(Filename) then
begin
stm := TMemoryStream.Create;
stm.LoadFromFile(Filename);
DownloadFirmware(stm);
stm.Free
end
end;
// ================================================================================================
// Download Firmware (stream)
// ================================================================================================
procedure TTrinityPipe0.DownloadFirmware(Stm: TStream);
var
len : cardinal;
b0 : byte;
b1 : byte;
addr : word;
left : word;
ptr : PByte;
hex : THexFile;
blk : THexBlock;
sud : TUsbSetupPacket;
begin
hex := THexFile.Create;
hex.LoadFromStream(stm);
hex.Dump(nil);
if Assigned( fDriver) then
begin
b0 := 0;
b1 := 1;
// ------------------------------------------------------------
// Reset 8051
// ------------------------------------------------------------
sud.RequestType := $40;
sud.Request := $A0;
sud.Value := $E600;
sud.Index := $0000;
sud.Length := $0000;
fDriver.ControlTransfer(sud, @b1, 1, len, nil);
// ------------------------------------------------------------
// Download firmware in 4 kB chunks
// ------------------------------------------------------------
// for i:=0 to hex.BlockCount -1 do
for blk in hex.Blocks do
begin
// blk := hex.Blocks[i];
addr := blk.Address;
left := blk.BlockLength;
ptr := blk.Data;
while left > 0 do
begin
sud.RequestType:= $40;
sud.Request := $A0;
if left > 4096 then
begin
sud.Value := addr;
sud.Index := $0000;
sud.Length := 4096;
fDriver.ControlTransfer( sud, ptr, 4096, len, nil);
addr := addr +4096;
ptr := pointer( cardinal(ptr) +4096);
left := left -4096
end
else begin
sud.Value := addr;
sud.Index := $0000;
sud.Length := left;
fDriver.ControlTransfer( sud, ptr, left, len, nil);
left := 0
end
end
end;
// ------------------------------------------------------------
// Restart 8051
// ------------------------------------------------------------
sud.RequestType := $40;
sud.Request := $A0;
sud.Value := $E600;
sud.Index := $0000;
sud.Length := $0000;
fDriver.ControlTransfer(sud, @b0, 1, len, nil)
end
end;
end.