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.