unit UnitUFS; interface Uses D2XXUnit,HexUtils, FBoots, Windows, Masks, Forms,sysutils, classes, boots, dialogs ; function BArmInterface():boolean; function readData():boolean; function SwitchBoxMode(Mode: string): boolean; function ChecCMTData():boolean; procedure FetchBootData; function ufsresetpower():Boolean; function replyverify():Boolean; function replyverify2():Boolean; function SendRaw(Asic:integer; Loader:string) : integer; function Freaddata(bytes:byte):Boolean; function Freadflashic ():boolean; Function SendAlgorihtm(Asic : integer; algo : string):integer; function CheckVpp():Boolean; function ReadCert(ASIC : Byte ; CERT : string):string; function GetReadLen():Byte; function ReadDatarequest(bytes:byte):Boolean; function replyend():Boolean; function PreCertreq():Boolean; function ufs_cmd(timeout:dword; pCmd:pointer; CmdLen:dword; pDst:Pointer; Expected:dword):dword; function ufsfl_cmd(timeout:dword; pCmd:pointer; CmdLen:dword; pDst:Pointer; Expected:dword):dword; function replyverify3():byte; function ufx_boot(sn: string):boolean; function ufx_sw_fbus(sn: string ; mode: string): boolean; function incheck(bytes:Integer):Boolean; function phoneready(retry:Integer):Boolean; Function FlashPrepare (flimage:string):Boolean; function UFSPartitioning(core:string):Boolean; function SendRawID(Asic:integer; Loader:string) : integer; function getapepapub():Boolean; function UFSprepareForFlash(image:string):Boolean; function UFSeraseUni(core:string):Boolean; function ConFigureAsic(ASIC:Byte):Boolean; function AsicComandFur():Boolean; function checkc7():Boolean; function UFSfinishsession():integer; function UFSEBLock():integer; function buildUFScert(DataStream : widestring; cert : string; asic : byte ): Boolean; function UFSeraseCRT (CRT : string; Asic : Byte) : Boolean; function UFSEBLockAPE():boolean; function busreset():boolean; /// function ufssys_cmd (CmdLen:dword; pDst:Pointer; Expected:dword):dword; //Infineon //Infineon function Boot_infineon({Boot1:TMemoryStream;Boot2:TMemoryStream}):Boolean; function BusCheckInfineon():Boolean; function InfineonEnd():Boolean; function FlashInfineonFile(FlasHfile:string):Boolean; function InfineonErase(infcore:string; curreg:string):Boolean; function sendCert(infcore:string):Boolean; function infgetblockcnt(infcore:string; Erlist:Tstringlist):Integer; function InfineonWrite(infcore:string; mode:Integer; dlen:string):Boolean; function checkready():Boolean; function getchksuminf():Boolean; function halfboot():Boolean; procedure dumpregionepp(start,stop:dword ; resstr:Tmemorystream); procedure dumpppmcatalog(start,stop:dword ; resstr:Tmemorystream); //special function UFSeraseS40(area:string):Boolean; function UFSFormatLow(area:string):Boolean; implementation uses UnitE1, UnitPavel, unit1, FlashBoots,USBmain, FbusMain, unitmisc,Graphics; var if_layer_dir: string; u_id: DWord; u_id_reprezentation : String; u_sn: String; u_g_sn: String; EEProm: string; Atmel_Sn: Integer; RxFrBuf,TxFrBuf:array[0..$8000] of byte; FrameInside: array[0..$FFFF] of byte; Seq: Integer; AckPacket: array[0..9] of byte; // Fbus_Timeout: integer; FR_CNT1:byte; Mode12A4:byte; McuSW_Buf, SWVersion, SWDate, Product, Manufacturer: String; PMWrLen : integer; PMWrBuffer: array[0..$800000] of byte; PMData: array[0..$800000] of byte; FLbyte : Byte; CFltype,AFltype : Byte; const Fbus_Timeout=3000; function ufsresetpower():Boolean; var retry, i: integer; InterfaceArmed: boolean; c_buf: string; label dummy_sn_retry; begin try except result:=false; end; end; function MakeSeq:integer; begin if Seq=$40 then begin Seq:=$41; Result:=Seq; exit; end; if Seq=$41 then begin Seq:=$42; Result:=Seq; exit; end; if Seq=$42 then begin Seq:=$43; Result:=Seq; exit; end; if Seq=$43 then begin Seq:=$44; Result:=Seq; exit; end; if Seq=$44 then begin Seq:=$45; Result:=Seq; exit; end; if Seq=$45 then begin Seq:=$46; Result:=Seq; exit; end; if Seq=$46 then begin Seq:=$47; Result:=Seq; exit; end; if Seq=$47 then begin Seq:=$40; Result:=Seq; exit; end; end; function ufssys_cmd (CmdLen:dword; pDst:Pointer; Expected:dword):dword; begin result:=0; if write_usb_device_buffer(cmdlen)<>cmdlen then exit; if read_usb_device_buffer(expected)<>expected then result:=0; move(ft_in_buffer,pointer(dword(pdst))^,expected); end; function ufs_cmd(timeout:dword; pCmd:pointer; CmdLen:dword; pDst:Pointer; Expected:dword):dword; var tries,totalread,toread,leftover:dword; finished:boolean; cnt,cnt1:longint; begin Application.ProcessMessages; FillMemory(@cmd_buf,65536,$00); PURGE_USB_DEVICE_IN; result:=0; finished:=false; if cmdlen>0 then begin move(pCmd^,ft_out_buffer,cmdlen); if write_usb_device_buffer(cmdlen)<>cmdlen then exit; end; if expected=0 then begin result:=cmdlen; exit; end; cnt:=gettickcount+timeout; Get_USB_Device_QueueStatus; while (ft_q_bytesft_q_bytes then exit else move(ft_in_buffer,pointer(dword(pdst))^,ft_q_bytes ); PURGE_USB_DEVICE_OUT; result:=ft_q_bytes; end; function ufsfl_cmd(timeout:dword; pCmd:pointer; CmdLen:dword; pDst:Pointer; Expected:dword):dword; var tries,totalread,toread,leftover:dword; finished:boolean; cnt,cnt1:longint; begin Application.ProcessMessages; FillMemory(@cmd_buf,65536,$00); PURGE_USB_DEVICE_IN; result:=0; finished:=false; if cmdlen>0 then begin move(pCmd^,ft_out_buffer,cmdlen); if write_usb_device_buffer(cmdlen)<>cmdlen then exit; end; if expected=0 then begin result:=cmdlen; exit; end; cnt:=gettickcount+timeout; Get_USB_Device_QueueStatus; while (ft_q_bytesft_q_bytes then exit else move(ft_in_buffer,pointer(dword(pdst))^,ft_q_bytes ); PURGE_USB_DEVICE_OUT; result:=ft_q_bytes; end; function ufx_boot(sn: string):boolean; var cmd_buf:array [0..1024] of byte; i,j: integer; label TryAgain; begin try Reset_USB_Device; Close_USB_Device; except Application.ProcessMessages; end; if (Open_USB_Device_By_Serial_Number(sn) <> FT_OK) then begin form1._msg('Error open UFS #'+sn); Close_USB_Device; Result:=False; exit; end; if (Reset_USB_Device <> FT_OK) then begin form1._msg('Error reset UFS #'+sn); Close_USB_Device; Result:=False; exit; end; if Set_USB_Device_TimeOuts(100,2000) <> ft_ok then begin form1._msg('UFS timeout set failed'); Close_USB_Device; Result:=False; exit; end; if (Reset_USB_Device <> FT_OK) then begin form1._msg('Error reset UFS'); Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_Out <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_IN <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if Set_USB_Parameters($10000, $10000)<>FT_OK then begin form1._msg('Parameters set error'); Close_USB_Device; Result:=False; exit; end; FT_current_DataBits:=8; FT_Current_StopBits:=0; FT_Current_Parity:=0; if Set_USB_Device_DataCharacteristics <> FT_OK then begin form1._msg('Data set error'); Close_USB_Device; Result:=False; exit; end; FT_Current_FlowControl:=0; FT_XON_Value:=$11; FT_XOFF_Value:=$13; if Set_USB_Device_FlowControl <> FT_OK then begin form1._msg('UFS flowcontrol set error'); Close_USB_Device; Result:=False; exit; end; if (Set_USB_Device_BaudRate_Divisor(26) <> FT_OK) then begin form1._msg('UFS bd switch failed'); Close_USB_Device; Result:=False; exit; end; if (set_usb_Device_dtr <> FT_OK) then begin form1._msg('UFS dtrset error'); Close_USB_Device; Result:=False; exit; end; j:=0; TryAgain: FT_out_buffer[0]:=$3F; ufs_cmd(1000,@ft_out_buffer,1,@cmd_buf,$2); j:=j+1; if ((cmd_buf[0]<>$62) or (cmd_buf[1]<>$cf)) and (cmd_buf[0]<>$3F) then begin if j>5 then begin form1._msg('UFS Boot Enter error ('+IntToHex(cmd_buf[0],2)+IntToHex(Cmd_Buf[1], 2)+')'); Close_USB_Device; Result:=False; exit; end else begin sleep(500); if (Reset_USB_Device <> FT_OK) then begin form1._msg('Error reset UFS #'+sn); Close_USB_Device; Result:=False; exit; end; if Set_USB_Device_TimeOuts(2000,2000) <> ft_ok then begin form1._msg('UFS timeout set failed'); Close_USB_Device; Result:=False; exit; end; if (Reset_USB_Device <> FT_OK) then begin form1._msg('Error reset UFS'); Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_Out <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_IN <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if Set_USB_Parameters($10000, $10000)<>FT_OK then begin form1._msg('Parameters set error'); Close_USB_Device; Result:=False; exit; end; FT_current_DataBits:=8; FT_Current_StopBits:=0; FT_Current_Parity:=0; if Set_USB_Device_DataCharacteristics <> FT_OK then begin form1._msg('Data set error'); Close_USB_Device; Result:=False; exit; end; FT_Current_FlowControl:=0; FT_XON_Value:=$11; FT_XOFF_Value:=$13; if Set_USB_Device_FlowControl <> FT_OK then begin form1._msg('UFS flowcontrol set error'); Close_USB_Device; Result:=False; exit; end; if (Set_USB_Device_BaudRate_Divisor(16696) <> FT_OK) then begin form1._msg('UFS bd switch failed'); Close_USB_Device; Result:=False; exit; end; if (clr_usb_Device_dtr <> FT_OK) then begin form1._msg('UFS clrdtr error'); Close_USB_Device; Result:=False; exit; end; if (clr_usb_Device_rts <> FT_OK) then begin form1._msg('UFS clrrts error'); Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_Out <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_IN <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (set_usb_Device_rts <> FT_OK) then begin form1._msg('UFS rtsset error'); Close_USB_Device; Result:=False; exit; end; if (clr_usb_Device_rts <> FT_OK) then begin form1._msg('UFS clrrts error'); Close_USB_Device; Result:=False; exit; end; if (set_usb_Device_dtr <> FT_OK) then begin form1._msg('UFS dtrset error'); Close_USB_Device; Result:=False; exit; end; if (set_usb_Device_rts <> FT_OK) then begin form1._msg('UFS rtsset error'); Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_Out <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_IN <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; goto TryAgain; end; end else result:=true; end; function WriteByte(inp : Byte):boolean; begin FT_Out_Buffer[0] := inp; Write_USB_Device_Buffer(1); end; function SwitchBoxMode(Mode: string): boolean; const BoxBoot : Array[0..6] of Byte = ($4C,$1D,$1D,$1F,$02,$0D,$98); var PrevStatus: String; ic:Integer; begin Result:=False; if Mode='FBUS' then begin if (Set_USB_Device_Event_Notification(01) <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; FT_current_DataBits:=8; FT_Current_StopBits:=0; FT_Current_Parity:=0; if Set_USB_Device_DataCharacteristics <> FT_OK then begin Close_USB_Device; Result:=False; exit; end; FT_Current_FlowControl:=0; FT_XON_Value:=$11; FT_XOFF_Value:=$13; if Set_USB_Device_FlowControl <> FT_OK then begin Close_USB_Device; Result:=False; exit; end; FT_Out_Buffer[0]:=$38; ufs_cmd(50,@ft_out_buffer,1,@cmd_buf,$05); FT_Out_Buffer[0]:=$44; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$08; FT_Out_Buffer[4]:=$00; ufs_cmd(250,@ft_out_buffer,5,@cmd_buf,$05); FT_Out_Buffer[0]:=$44; FT_Out_Buffer[1]:=$18; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$08; FT_Out_Buffer[4]:=$00; ufs_cmd(250,@ft_out_buffer,5,@cmd_buf,$05); FT_Out_Buffer[0]:=$55; FT_Out_Buffer[1]:=$05; ufs_cmd(50,@ft_out_buffer,2,@cmd_buf,$03); if Set_USB_Device_TimeOuts(60000,60000) <> ft_ok then begin Close_USB_Device; Result:=False; exit; end; FT_Out_Buffer[0]:=$42; FT_Out_Buffer[1]:=$10; ufs_cmd(1,@ft_out_buffer,2,@cmd_buf,$01); if (Set_USB_Device_BaudRate_Divisor($50001A) <> FT_OK) then begin form1._msg('Baudrate switch failed. This is critical.'); Close_USB_Device; Result:=False; exit; end; FT_Out_Buffer[0]:=$58; ufs_cmd(1000,@ft_out_buffer,1,@cmd_buf,1); FT_Out_Buffer[0]:=$32; ufs_cmd(50,@ft_out_buffer,1,@cmd_buf,1); if (clr_usb_Device_dtr <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (clr_usb_Device_dtr <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (set_usb_Device_dtr <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_Out <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_IN <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; FT_Out_Buffer[0]:=$67; ufs_cmd(500,@ft_out_buffer,1,@cmd_buf,1); // FBUS Mode, DTR High, RTS Low, Flow: NO FT_Out_Buffer[0]:=$68; FT_Out_Buffer[1]:=$00; ufs_cmd(50,@ft_out_buffer,2,@cmd_buf,$01); FT_Out_Buffer[0]:=$66; ufs_cmd(100,@ft_out_buffer,1,@cmd_buf,$01); FT_Out_Buffer[0]:=$A5; ufs_cmd(50,@ft_out_buffer,1,@cmd_buf,$01); // DTR falling-edge if (clr_usb_Device_dtr <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; Result:=True; end; if Mode='FlashBus' then begin {FT_Out_Buffer[0]:=$32; ufs_cmd(200,@ft_out_buffer,1,@cmd_buf,$01); FT_Current_FlowControl:=FT_FLOW_NONE; FT_XON_Value:=$11; FT_XOFF_Value:=$13; if Set_USB_Device_FlowControl <> FT_OK then begin form1._msg('UFS flowcontrol set failed'); Close_USB_Device; exit; end; if (set_usb_Device_dtr <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Purge_USB_Device_IN <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; if (Set_USB_Device_TimeOuts($10000,$10000)<> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; FT_Out_Buffer[0]:=$78; ufs_cmd(200,@ft_out_buffer,1,@cmd_buf,$01); FT_Out_Buffer[0]:=$42; FT_Out_Buffer[1]:=$00; ufs_cmd(200,@ft_out_buffer,2,@cmd_buf,$01); sleep(100); if (Set_USB_Device_BaudRate_Divisor($1) <> FT_OK) then begin Close_USB_Device; Result:=False; exit; end; FT_Out_Buffer[0]:=$32; ufs_cmd(300,@ft_out_buffer,1,@cmd_buf,$01); FT_Current_FlowControl:=FT_FLOW_DTR_DSR; FT_XON_Value:=$11; FT_XOFF_Value:=$13; if Set_USB_Device_FlowControl <> FT_OK then begin form1._msg('UFS flowcontrol set failed'); Close_USB_Device; exit; end; FT_Out_Buffer[0]:=$67; ufs_cmd(500,@ft_out_buffer,1,@cmd_buf,1); FT_out_Buffer[0] := $62; FT_out_Buffer[1] := $FB; FT_out_Buffer[2] := $01; FT_out_Buffer[3] := $AA; ufs_cmd(2000,@ft_out_buffer,4,@cmd_buf,3); } Reset_USB_Device ; Set_USB_Device_FlowControl; Set_USB_Device_DTR; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_TimeOuts(10000,10000); Purge_USB_Device_Out; Purge_USB_Device_In; Sleep(100); FT_Out_Buffer[0] := $4C; FT_Out_Buffer[1] := $1D; FT_Out_Buffer[2] := $1D; FT_Out_Buffer[3] := $1F; FT_Out_Buffer[4] := $02; FT_Out_Buffer[5] := $0D; FT_Out_Buffer[6] := $98; ufs_cmd(600,@Ft_out_buffer,7,@cmd_buf,5); Reset_USB_Device ; FT_Out_Buffer[0] := $42; FT_Out_Buffer[1] := $00; ufs_cmd(600,@Ft_out_buffer,2,@cmd_buf,0); //Set UFS to Atmel MODE first Reset_USB_Device ; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_DTR; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_TimeOuts(500,8000); FT_Current_FlowControl := 0; Set_USB_Device_FlowControl; Set_USB_Device_TimeOuts(6000,8000); If Set_USB_Device_BaudRate_Divisor($1) <> FT_Ok Then Exit; FT_out_Buffer[0] := $58; ufs_cmd(600,@Ft_out_buffer,1,@cmd_buf,1); FT_Out_Buffer[0] := $32; ufs_cmd(600,@Ft_out_buffer,1,@cmd_buf,1); FT_out_Buffer[0] := $68; FT_out_Buffer[1] := $01; ufs_cmd(600,@Ft_out_buffer,2,@cmd_buf,1); FT_Out_Buffer[0] := $67; ufs_cmd(600,@Ft_out_buffer,1,@cmd_buf,1); Set_USB_Device_FlowControl; Set_USB_Device_DTR; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_TimeOuts(10000,10000); Purge_USB_Device_Out; Purge_USB_Device_In; FT_Out_Buffer[0] := $78; ufs_cmd(600,@Ft_out_buffer,1,@cmd_buf,1); Purge_USB_Device_Out; Purge_USB_Device_In; FT_Out_Buffer[0] := $42; FT_Out_Buffer[1] := $00; ufs_cmd(600,@Ft_out_buffer,2,@cmd_buf,0); If Set_USB_Device_BaudRate_Divisor($1) <> FT_Ok Then Exit; FT_Out_Buffer[0] := $32; ufs_cmd(600,@Ft_out_buffer,1,@cmd_buf,1); FT_Current_FlowControl := 512; Set_USB_Device_FlowControl; If Set_USB_Parameters(65536,65536) <> FT_Ok Then Exit; FT_Out_Buffer[0] := $67; ufs_cmd(600,@Ft_out_buffer,1,@cmd_buf,1); sleep(100); FT_out_Buffer[0] := $62; FT_out_Buffer[1] := $FB; FT_out_Buffer[2] := $01; FT_out_Buffer[3] := $AA; ufs_cmd(2000,@Ft_out_buffer,4,@cmd_buf,3); Form1.statusbar.Panels[4].Text:=''; if {(cmd_buf[0]=$FF) and }(cmd_buf[1]=$FF) or (cmd_buf[2]=$72) then begin form1._msg('FlashMode set Ok'); result:=True; end else result:=False; end; if Mode='FastReset' then begin FT_Out_Buffer[0]:=$67; ufs_cmd(500,@ft_out_buffer,1,@cmd_buf,1); Result:=True; end; if Mode='Infineon' then begin If Set_USB_Device_TimeOuts($2710,$2710)<> FT_Ok Then Exit; sleep(5); If Set_USB_Device_BaudRate_Divisor($1A) <> FT_Ok Then Exit; Form1.statusbar.Panels[4].Text:=''; result:=True; end; end; function ufx_sw_fbus(sn: string ; mode: string): boolean; var cmd_buf: array [0..1024] of byte; chksum: byte; i: integer; Fuses:array[1..2] of byte; begin FT_Out_Buffer[0]:=$4C; FT_Out_Buffer[1]:=$4D; FT_Out_Buffer[2]:=$54; FT_Out_Buffer[3]:=$31; FT_Out_Buffer[4]:=$39; FT_Out_Buffer[5]:=$06; FT_Out_Buffer[6]:=$EF; ufsfl_cmd(1200,@FT_out_buffer,7,@cmd_buf,1); //if cmd_buf[0]<>$2A then Form1._msg('Error prepare UFSx / '+byte2str(cmd_buf[0])); // check_licence FT_Out_Buffer[0]:=$4C; FT_Out_Buffer[1]:=$1D; FT_Out_Buffer[2]:=$1D; FT_Out_Buffer[3]:=$1F; FT_Out_Buffer[4]:=$02; FT_Out_Buffer[5]:=$0D; FT_Out_Buffer[6]:=$98; ufsfl_cmd(300,@ft_out_buffer,7,@cmd_buf,$01); //if cmd_buf[0]<>$3E then Form1._msg('Prepare error UFSx / '+byte2str(cmd_buf[0])); // firmware version FT_Out_Buffer[0]:=$41; ufsfl_cmd(300,@ft_out_buffer,1,@cmd_buf,32); FT_Out_Buffer[0]:=$58; ufsfl_cmd(300,@ft_out_buffer,1,@cmd_buf,$01); //if cmd_buf[0]<>$5A then Form1._msg('Fail init UFSx / '+byte2str(cmd_buf[0])); {// bootloader version FT_Out_Buffer[0]:=$56; ufs_cmd(100,@ft_out_buffer,1,@cmd_buf,32); // firmware version FT_Out_Buffer[0]:=$41; ufs_cmd(100,@ft_out_buffer,1,@cmd_buf,32); // amtel sn FT_Out_Buffer[0]:=$54; ufs_cmd(50,@ft_out_buffer,1,@cmd_buf,$03); if (Purge_USB_Device_Out <> FT_OK) then begin form1._msg('Cannot purge UFSx #'+sn+'. This is critical.'); Close_USB_Device; Result:=False; exit; end; atmel_sn:=HexToInt(IntToHex(cmd_buf[0], 2)+IntToHex(cmd_buf[1], 2)); // read fuses FT_Out_Buffer[0]:=$53; ufs_cmd(50,@ft_out_buffer,1,@cmd_buf,$03); fuses[1]:=cmd_buf[1]; fuses[2]:=cmd_buf[2]; // check_licence FT_Out_Buffer[0]:=$4C; FT_Out_Buffer[1]:=$1D; FT_Out_Buffer[2]:=$1D; FT_Out_Buffer[3]:=$1F; FT_Out_Buffer[4]:=$02; FT_Out_Buffer[5]:=$0D; chksum:=FT_Out_buffer[1]+FT_Out_buffer[2]+FT_Out_buffer[3]+FT_Out_buffer[4]+FT_Out_buffer[5]; FT_Out_Buffer[6]:=-chksum; ufs_cmd(50,@ft_out_buffer,7,@cmd_buf,$03); // download eeprom FT_Out_Buffer[0]:=$39; ufs_cmd(500,@ft_out_buffer,1,@cmd_buf,194); eeprom:=''; for i:=0 to 193 do eeprom:=eeprom+IntToHex(cmd_buf[i], 2); } Result:=SwitchBoxMode(mode); end; function NFB_Send55str():boolean; var i: integer; begin Result:=False; for i:=1 to 5 do begin FT_Out_Buffer[0]:=$55; FT_Out_Buffer[1]:=$55; FT_Out_Buffer[2]:=$55; FT_Out_Buffer[3]:=$55; FT_Out_Buffer[4]:=$55; if (Write_USB_Device_Buffer(5))<>5 then exit; end; Result:=true; end; function fbus_crc(data: string):string; var crc: byte; i: integer; s_crc: string; begin crc:=0; i:=0; while i < (strlen(pchar(data)) div 2) do begin crc:=crc xor HexToInt(data[i*2+1]+data[i*2+2]); inc(i, 2); end; s_crc:=inttohex(crc, 2); crc:=0; i:=1; while i < (strlen(pchar(data)) div 2) do begin crc:=crc xor HexToInt(data[i*2+1]+data[i*2+2]); inc(i, 2); end; s_crc:=s_crc+inttohex(crc, 2); Result:=s_crc; end; function Suck_Fbus(timeout:dword; pCmd:pointer; CmdLen:dword; pDst:Pointer; CheckAck: boolean; SendAck: boolean):dword; var tries,totalread,toread,leftover:dword; finished:boolean; cnt,cnt1:longint; cBuf: array [0..$FFFF] of byte; crcBuf: string; CalculatedCRC, PacketCRC: String; ExpectedBuf: integer; i,j,k: integer; LoadCounter: integer; SecondPacketLength: Integer; SeqTmp: integer; BruteForce: Boolean; PrevStatus: String; begin Application.ProcessMessages; if (Purge_USB_Device_IN <> FT_OK) then exit; if (Purge_USB_Device_OUT <> FT_OK) then exit; Finished:=False; Move(pCmd^, FT_OUT_BUFFER, CmdLen); if Write_USB_Device_Buffer(CmdLen)<>CmdLen then exit; Cnt:=GetTickCount+TimeOut; Get_USB_Device_Queuestatus; if (CheckAck) then begin Cnt:=GetTickCount+TimeOut; Get_USB_Device_Queuestatus; while (FT_Q_Bytes<10) do begin Application.ProcessMessages; // check if Time not exceeded. if (Cnt-GetTickCount)<=0 then break; Get_USB_Device_Queuestatus; end; if (Cnt-GetTickCount)<=0 then exit else if Read_USB_Device_Buffer(10)<>10 then exit; for i:=0 to 10-1 do AckPacket[i]:=FT_IN_Buffer[i]; for i:=0 to 10-1 do FT_In_Buffer[i]:=$00; // I think we have now ACK packet! if AckPacket[0]<>$1E then exit; if AckPacket[1]<>$10 then exit; if AckPacket[2]<>$00 then exit; if AckPacket[3]<>$7F then exit; // Now needed to Calculate and Check the ACK packet CRC crcBuf:=''; for i:=0 to 7 do crcBuf:=crcBuf+IntToHex(AckPacket[i], 2); CalculatedCRC:=Fbus_CRC(crcBuf); PacketCRC:=IntToHex(AckPacket[8], 2)+IntToHex(AckPacket[9], 2); if CalculatedCRC<>PacketCRC then exit; end; // If crc is OK we need now to read the rest of packet Cnt:=GetTickCount+TimeOut; Get_USB_Device_Queuestatus; while (FT_Q_Bytes<1) do begin Application.ProcessMessages; // check if Time not exceeded. if (Cnt-GetTickCount)<=0 then break; Get_USB_Device_Queuestatus; end; if (Cnt-GetTickCount)<=0 then exit else if Read_USB_Device_Buffer(1)<>1 then exit; if FT_In_Buffer[0]<>$1E then exit; // Trashed packet Cmd_Buf[0]:=FT_In_Buffer[0]; FT_In_Buffer[0]:=$00; // 1E i have now to come: 10, 00, TYPE, 00, LEN, in fact, 5 bytes Cnt:=GetTickCount+TimeOut; Get_USB_Device_Queuestatus; while (FT_Q_Bytes<5) do begin Application.ProcessMessages; // check if Time not exceeded. if (Cnt-GetTickCount)<=0 then break; Get_USB_Device_Queuestatus; end; if (Cnt-GetTickCount)<=0 then exit else if Read_USB_Device_Buffer(5)<>5 then exit; for i:=1 to 5 do Cmd_Buf[i]:=FT_In_Buffer[i-1]; for i:=0 to 4 do FT_IN_Buffer[i]:=$00; // how many bytes more to come? Cnt:=GetTickCount+TimeOut; Get_USB_Device_Queuestatus; while (FT_Q_BytesCmd_Buf[5] then exit; for i:=6 to Cmd_Buf[5]+6 do Cmd_Buf[i]:=FT_In_Buffer[i-6]; // Download payload Cnt:=GetTickCount+TimeOut; Get_USB_Device_Queuestatus; if FT_Q_Bytes>0 then if Read_USB_Device_Buffer(FT_Q_Bytes)<>FT_Q_Bytes then exit; for i:=6+Cmd_Buf[5]+1 to 6+Cmd_Buf[5]+1+FT_Q_Bytes do Cmd_Buf[i]:=FT_In_Buffer[i-(6+Cmd_Buf[5]+1)]; SecondPacketLength:=6+Cmd_Buf[5]+FT_Q_Bytes; for i:=0 to FT_Q_Bytes do FT_IN_Buffer[i]:=$00; // Calculate and send CRC if (SendAck) then begin AckPacket[1]:=$00; AckPacket[2]:=$10; AckPacket[6]:=Cmd_Buf[3]; //if AckPacket[7]=$07 then AckPacket[7]:=$00 else AckPacket[7]:=AckPacket[7]+1; AckPacket[7]:=(Seq+1)-$40; // Calculate ack packet crc crcBuf:=''; for i:=0 to 7 do crcBuf:=crcBuf+IntToHex(AckPacket[i], 2); CalculatedCRC:=Fbus_CRC(crcBuf); AckPacket[8]:=HexToInt(CalculatedCRC[1]+CalculatedCRC[2]); AckPacket[9]:=HexToInt(CalculatedCRC[3]+CalculatedCRC[4]); for i:=0 to 9 do FT_Out_Buffer[i]:=AckPacket[i]; // Send ack packet if Write_USB_Device_Buffer(10)<>10 then exit; end; // When all ok, clear buffers if (Purge_USB_Device_IN <> FT_OK) then exit; if (Purge_USB_Device_OUT <> FT_OK) then exit; // Notify peer process that all is ok Result:=SecondPacketLength; end; function SendFBusFrame(var FrameBuf:array of byte; CheckAck: boolean; SendAck: boolean):boolean; var n,len:integer; tstr:string; CRC:word; // UFSx only RxBuf: array[0..$FFFF] of byte; i: integer; begin Application.ProcessMessages; result:=false; len := FrameBuf[4]*$100 + FrameBuf[5]; len:=(len+1) AND $FFFFFFFE; {Round UP} len:=len+2+6; {--- Update Frames counter ------} FR_CNT1:=(FR_CNT1 AND $07) OR $40; if ((FrameBuf[len-3]<=$50) OR (len<=$0A)) then begin if FrameBuf[3]<>$7F then if len>$0A then if Mode12A4<>0 then begin if (FrameBuf[5] AND 1)=1 then FrameBuf[len-4]:=FR_CNT1 else FrameBuf[len-3]:=FR_CNT1; FR_CNT1:=((FR_CNT1+1) AND $07) OR $40; end; end else begin FR_CNT1:=FrameBuf[len-3]+1; end; {- Calculate frame CRC -} CRC:=0; for n:=0 to ((len-2) DIV 2)-1 do CRC:=CRC XOR ( (FrameBuf[n*2]*$100)+FrameBuf[n*2+1] ); FrameBuf[len-2]:=(CRC DIV $100) AND $FF; FrameBuf[len-1]:=CRC AND $FF; {---------------------------------} for n:=0 to len-1 do FT_Out_Buffer[n]:=FrameBuf[n]; ///form1._msg('TXbuf: '+buftohexstr(@FT_Out_Buffer[0], len)); n:=Suck_FBUS(Fbus_Timeout, @FT_OUT_BUFFER, len, @cmd_buf, CheckAck, SendAck); if (n > 0) and (n<255) then begin for i:=0 to n do RxFrBuf[i]:=Cmd_Buf[i]; Result:=True end; end; function SendFrameAndSendAck(Frame: array of byte; IFrameLen: integer; MekeSeq: Boolean; CheckAck: Boolean; SendAck: Boolean): integer; var CurrentBuffer: array [0..$8000] of byte; FrameLen, FrameLenTmp: integer; i,n: integer; rdd: integer; Retry: integer; EndframePointer: integer; MaxRetry: integer; DebugBuf: string; TID: longword; Label Start, StartUFSx; begin Application.ProcessMessages; MaxRetry:=8; Result:=0; Retry:=1; // SEND FRAME :: DETECT PHONE for i:=0 to $8000 do RxFrBuf[i]:=$00; for i:=0 to IFrameLen do TxFrBuf[i]:=Frame[i]; for i:=0 to $8000 do FrameInside[i]:=$00; // Check ack is make Seq if (MekeSeq) then begin IFrameLen:=IFrameLen+1; TxFrBuf[IFrameLen]:=MakeSeq; // Make sequentional number end; StartUFSx: if Retry>1 then begin if (NFB_Send55str)=FALSE then begin form1._msg('UFS 0x55 error'); exit; end; end; if (SendFBUSFrame(TxFrBuf, CheckAck, SendAck))=FALSE then begin Retry:=Retry+1; if Retry>=MaxRetry then begin form1._msg('UFS ack error'); exit; end else begin sleep(2000); goto StartUFSx; end; end; FrameLen:=RxFrBuf[5]; for i:=6 to FrameLen+6 do FrameInside[i-6]:=RxFrBuf[i]; Result:=Framelen-2; end; function BArmInterface():boolean; var retry, i: integer; InterfaceArmed: boolean; c_buf: string; label dummy_sn_retry; begin USBClosePort; form1._msg('Searching Devices... '); GetFTDeviceCount; form1._msg(IntToStr(FT_Device_Count)+' devices found.'); if FT_Device_Count<1 then exit; u_id:=0; retry:=1; dummy_sn_retry: GetFTDeviceDescription(u_id); u_id_reprezentation:=FT_Device_String; GetFTDeviceSerialNo(u_id); u_sn:=FT_Device_String; Application.ProcessMessages; if (u_sn = '') or (MatchesMask(u_id_reprezentation, '*UFS*') = false) then begin if (FT_Device_Count) > 0 then begin if FT_Device_Count=Retry then begin form1._msg('UFS not found. Try to reconnect it'); exit; end; for i:=retry+1 to FT_Device_Count do begin retry:=i; u_id:=i-1; goto dummy_sn_retry; end; end; end else u_g_sn:=inttostr(strtoint(u_sn)*1); // fix the 000* sn form1._msg('Booting UFS #'+u_g_sn); if (ufx_boot(u_sn)) then begin Application.ProcessMessages; ///4C 4D 54 31 39 06 EF //2A //4C 1D 1D 1F 02 0D 98 //3E //41 //58 =>5A //32 =>72 FT_Out_Buffer[0]:=$56; ufs_cmd(100,@ft_out_buffer,1,@cmd_buf,$20); c_buf:=''; for i:=0 to 31 do c_buf:=c_buf+Chr(cmd_buf[i]); if(MatchesMask(c_buf, 'UFxBoot V?.? (c) SarasSoft 200?.')=FALSE) then begin form1._msg('UFSBoot is damaged!'); Close_USB_Device; exit; end; form1._msg(c_buf); Application.ProcessMessages; FT_Out_Buffer[0]:=$41; ufs_cmd(100,@ft_out_buffer,1,@cmd_buf,$20); c_buf:=''; for i:=0 to 31 do c_buf:=c_buf+chr(cmd_buf[i]); if(MatchesMask(c_buf, 'UFS_USB V2.? (c) SarasSoft 200?.')=FALSE) then begin form1._msg('UFS Firmware is damaged!'); Close_USB_Device; exit; end; form1._msg(c_buf); if (ufx_sw_fbus(u_sn,'FBUS')) then begin Seq:=$40; for i:=0 to 20 do begin Sleep(50); Application.ProcessMessages; end; end; Application.ProcessMessages; end; form1._msg(''); end; function GetPMFieldLength(Field: integer):Integer; var Frame_GetPMFieldLength:array[0..$C] of byte; n,i: integer; Str_Field: string; begin Result:=0; Str_Field:=IntToHex(Field, 4); // Build frame Frame_GetPMFieldLength[$0]:=$1E; // fbus header Frame_GetPMFieldLength[$1]:=$00; // destination - phone Frame_GetPMFieldLength[$2]:=$10; // source - PC Frame_GetPMFieldLength[$3]:=$23; // Msg TYPE Frame_GetPMFieldLength[$4]:=$00; // msg len 0x00 Frame_GetPMFieldLength[$5]:=$08; // msg len 0x01 Frame_GetPMFieldLength[$6]:=$00; // payload 7bytes Frame_GetPMFieldLength[$7]:=$0D; Frame_GetPMFieldLength[$8]:=$C2; Frame_GetPMFieldLength[$9]:=$0E; Frame_GetPMFieldLength[$A]:=HexToInt(Str_Field[1]+Str_Field[2]); // Field_1 Frame_GetPMFieldLength[$B]:=HexToInt(Str_Field[3]+Str_Field[4]); // Field_2 Frame_GetPMFieldLength[$C]:=$01; // overhead not included n:=SendFrameAndSendAck(Frame_GetPMFieldLength, $C, True, True, True); Result:=FrameInside[n-1]; end; function PMWriteCurrentKey(Field: integer;Key:integer;KeyLength: integer): integer; var Frame_WritePM:array[0..$8000] of byte; n,i,j,k,z: integer; HowManyPackets, OverAllPackets: integer; CurrentPacket: integer; SectorSize: integer; tmp: string; ProceedWithAck: Boolean; OverheadpacketsDone, OverHeadPacketsLeft: integer; ConvBuf: String; CurrWriteSectorSize: integer; begin Result:=0; // Build Frame Frame_WritePM[0]:=$1E;//header Frame_WritePM[1]:=$00;//src Frame_WritePM[2]:=$10;//dst Frame_WritePM[3]:=$23;//msgtype // [4] length // [5] length // Current payload Frame_WritePM[6]:=$00; Frame_WritePM[7]:=$08; Frame_WritePM[8]:=$01; Frame_WritePM[9]:=$02; ConvBuf:=IntToHex(Field, 4); Frame_WritePM[10]:=HexToInt(ConvBuf[1]+ConvBuf[2]); Frame_WritePM[11]:=HexToInt(ConvBuf[3]+ConvBuf[4]); ConvBuf:=IntToHex(Key, 4); Frame_WritePM[12]:=HexToInt(ConvBuf[1]+ConvBuf[2]); Frame_WritePM[13]:=HexToInt(ConvBuf[3]+ConvBuf[4]); Frame_WritePM[14]:=00; Frame_WritePM[15]:=00; Frame_WritePM[16]:=00; // 17 PM Data Length - 1 // 18 PM Data Length - 2 // 19 PM Data Length - 3 CurrWriteSectorSize:=96; if KeyLength<=CurrWriteSectorSize then begin Frame_WritePM[4]:=(KeyLength+16) div $100; Frame_WritePM[5]:=(KeyLength+16) mod $100; Frame_WritePM[17]:=$00; Frame_WritePM[18]:=KeyLength div $100; Frame_WritePM[19]:=KeyLength mod $100; for i:=0 to KeyLength-1 do begin Frame_WritePM[20+i]:=PMWrBuffer[i]; end; Frame_WritePM[20+KeyLength]:=$01; n:=SendFrameAndSendAck(Frame_WritePM, 20+KeyLength, True, True, True); if FrameInside[5]=$01 then begin Result:=KeyLength; end else Result:=0; end else begin // First Sector size is ALWAYS 106 bytes, cause PM_PACKET_TYPE must be MAX 0x7A , so 106+overhead > 7A SectorSize:=CurrWriteSectorSize; // 106 + 0xFE * 120 (max_sector_size) = 30586 if KeyLength>$FFA0 then exit; // Here we need to count how many packets will be sent to phone. Algo is // simple. Keylength-106(cause first packet) HowManyPackets:=((KeyLength-CurrWriteSectorSize) div CurrWriteSectorSize)+3; /// or +3.. have no idea, need to test with FBUS olso // Multi-Packet Flag Frame_WritePM[8]:=$02; CurrentPacket:=1; OverAllPackets:=HowManyPackets; // Send first packet Frame_WritePM[4]:=(SectorSize+16) div $100; Frame_WritePM[5]:=(SectorSize+16) mod $100; //Result shoudl be 7A! Frame_WritePM[17]:=00; Frame_WritePM[18]:=KeyLength div $100; Frame_WritePM[19]:=KeyLength mod $100; for i:=0 to SectorSize-1 do begin Frame_WritePM[20+i]:=PMWrBuffer[i]; end; Frame_WritePM[20+SectorSize]:=OverAllPackets; // Send first packet n:=SendFrameAndSendAck(Frame_WritePM, 20+SectorSize, True, False, False); SectorSize:=CurrWriteSectorSize; //Switching to BIG_MODE // One packet sent HowManyPackets:=HowManyPackets-2; CurrentPacket:=CurrentPacket+1; OverHeadPacketsDone:=0; OverHeadPacketsLeft:=HowManyPackets; for i:=1 to HowManyPackets do begin if i=HowManyPackets then begin SectorSize:= (KeyLength-CurrWriteSectorSize) - (((KeyLength-CurrWriteSectorSize) div CurrWriteSectorSize) * CurrWriteSectorSize); ProceedWithAck:=True; end else SectorSize:=CurrWriteSectorSize; Frame_WritePM[4]:=(SectorSize+2) div $100; Frame_WritePM[5]:=(SectorSize+2) mod $100; z:=0; for j:=CurrWriteSectorSize+( (i-1)*CurrWriteSectorSize ) to (CurrWriteSectorSize+( (i-1)*CurrWriteSectorSize ))+(SectorSize-1) do begin // Fill buffer with data Frame_WritePM[6 + z]:=PMWrBuffer[j]; z:=z+1; end; Frame_WritePM[6+SectorSize]:=OverHeadPacketsLeft; Frame_WritePM[7+SectorSize]:=MakeSeq-$40; SendFrameAndSendAck(Frame_WritePM, 5+SectorSize+1+1, False, ProceedWithAck, ProceedWithAck); OverHeadPacketsLeft:=OverHeadPacketsLeft-1; OverHeadPacketsDone:=OverHeadPacketsDone+1; end; if FrameInside[5]=$01 then begin Result:=KeyLength; end else Result:=0; end; end; function GetPMKeyLength(Field:integer;Key:integer):Integer; var Frame_GetPMKey:array[0..$10] of byte; n,i: integer; KeyLength: integer; Str_Field: String; Str_Key: String; begin Result:=0; Str_Field:=IntToHex(Field, 4); Str_Key:=IntToHex(Key, 4); Frame_GetPMKey[$0]:=$1E; Frame_GetPMKey[$1]:=$00; Frame_GetPMKey[$2]:=$10; Frame_GetPMKey[$3]:=$23; Frame_GetPMKey[$4]:=$00; Frame_GetPMKey[$5]:=$0C; Frame_GetPMKey[$6]:=$00; Frame_GetPMKey[$7]:=$0D; Frame_GetPMKey[$8]:=$0F; Frame_GetPMKey[$9]:=$0C; Frame_GetPMKey[$A]:=HexToInt(Str_Field[1]+Str_Field[2]); Frame_GetPMKey[$B]:=HexToInt(Str_Field[3]+Str_Field[4]); Frame_GetPMKey[$C]:=HexToInt(Str_Key[1]+Str_Key[2]); Frame_GetPMKey[$D]:=HexToInt(Str_Key[3]+Str_Key[4]); Frame_GetPMKey[$E]:=$00; Frame_GetPMKey[$F]:=$00; Frame_GetPMKey[$10]:=$01; n:=SendFrameAndSendAck(Frame_GetPMKey, $10, True, True, True); if n=0 then exit; if FrameInside[5]=$00 then KeyLength:=0; if FrameInside[5]=$01 then begin KeyLength:=HexToInt(IntToHex(FrameInside[n-3], 2)+IntToHex(FrameInside[n-2], 2)+IntToHex(FrameInside[n-1], 2)); if KeyLength=0 then KeyLength:=$FFFFFF; end; Result:=KeyLength; end; function PMReadCurrentKey(Field: integer;Key: Integer;KeyLength: Integer):Integer; var Frame_GetPMContent: array[0..24] of byte; i,n,j: integer; CurrentSector: integer; SectorLength: integer; PMCount: integer; CurrentBuffer: array[0..$8000] of byte; ExtractedPMSize: integer; ConvBuf: string; MaxGauge,CurrGauge: integer; Str_Field: String; Str_Key: String; OldStatus: String; MaxKeyLen: word; begin Result:=0; PMCount:=0; Str_Field:=IntToHex(Field, 4); Str_Key:=IntToHex(Key, 4); MaxKeyLen:=$64; if KeyLength>MaxKeyLen then begin //OldStatus:=Form1.NStatus.Panels.Items[0].Text; end; for i:=0 to (KeyLength div MaxKeyLen) do // Sector size is $64 begin if KeyLength>MaxKeyLen then begin //Form1.NStatus.Panels.Items[0].Text:='Reading Long PM Field '+IntToStr(Field)+', Key '+IntToStr(Key)+', Len '+IntTOStr(KeyLength)+' bytes, Readen Sectors: '+IntToStr(i)+'/'+IntToStr((KeyLength div $64)); end; CurrentSector:=i*MaxKeyLen; if i=(KeyLength div MaxKeyLen) then SectorLength:=(KeyLength mod MaxKeyLen) else SectorLength:=MaxKeyLen; // if overhead is detected Frame_GetPMContent[0]:=$1E; Frame_GetPMContent[1]:=$00; Frame_GetPMContent[2]:=$10; Frame_GetPMContent[3]:=$23; Frame_GetPMContent[4]:=$00; Frame_GetPMContent[5]:=$14; Frame_GetPMContent[6]:=$00; Frame_GetPMContent[7]:=$0D; Frame_GetPMContent[8]:=$10; Frame_GetPMContent[9]:=$04; Frame_GetPMContent[10]:=HexToInt(Str_Field[1]+Str_Field[2]); Frame_GetPMContent[11]:=HexToInt(Str_Field[3]+Str_Field[4]); Frame_GetPMContent[12]:=HexToInt(Str_Key[1]+Str_Key[2]); Frame_GetPMContent[13]:=HexToInt(Str_Key[3]+Str_Key[4]); Frame_GetPMContent[14]:=$00; Frame_GetPMContent[15]:=$00; Frame_GetPMContent[16]:=$00; ConvBuf:=IntToHex(CurrentSector, 6); Frame_GetPMContent[17]:=HexToInt(ConvBuf[1]+ConvBuf[2]); Frame_GetPMContent[18]:=HexToInt(ConvBuf[3]+ConvBuf[4]); Frame_GetPMContent[19]:=HexToInt(ConvBuf[5]+ConvBuf[6]); Frame_GetPMContent[20]:=$00; Frame_GetPMContent[21]:=$00; Frame_GetPMContent[22]:=SectorLength div $100; Frame_GetPMContent[23]:=SectorLength mod $100; Frame_GetPMContent[24]:=$01; n:=SendFrameAndSendAck(Frame_GetPMContent, 24, True, True, True); if n=0 then exit; if nFrame_GetPMContent[7] then exit; ExtractedPMSize:=(FrameInside[16] * $100) + FrameInside[17]; if ExtractedPMSize<>SectorLength then exit; for j:=PMCount to PMCount+(ExtractedPMSize-1) do PMData[j]:=FrameInside[18+(j-PMCount)]; // we have so it located into CurrentBuffer what then ? PMCount:=PMCount+SectorLength; end; if KeyLength>MaxKeyLen then begin //Form1.NStatus.Panels.Items[0].Text:=OldStatus; end; Result:=PMCount-1; end; function readData():boolean; const Frame_GetOTPIMEI:array[0..$E] of byte = ($1E,$00,$10,$1B,$00,$0A,$00,$01,$01,$00,$41,$00,$00,$00,$01); Frame_DetectPPM:array[0..$C] of byte = ($1E,$00,$10,$1B,$00,$08,$00,$03,$1F,$07,$01,$00,$01); Frame_GetCodeCount:array[0..$B] of byte = ($1E,$00,$10,$53,$00,$07,$00,$08,$00,$12,$0D,$01); Frame_BB5_GetCP:array[0..$10] of byte = ($1e, $00, $10, $1b, $00, $0c, $00, $06, $06, $07, $00, $00, $00, $00, $04, $00, $01); Frame_BB5_GetAPESW:array[0..$10] of byte = ($1e, $00, $10, $1b, $00, $0c, $00, $06, $06, $07, $00, $00, $00, $00, $00, $02, $01); Frame_BB5_GetAPEVA:array[0..$10] of byte = ($1e, $00, $10, $1b, $00, $0c, $00, $06, $06, $07, $00, $00, $00, $00, $00, $04, $01); Frame_DetectPhone:array[0..$B] of byte = ($1E,$00,$10,$D1,$00,$07,$00,$01,$00,$03,$00,$01); var n, i, x, j: integer; buf: string; DelimiterPos, PointerBuf: integer; PPM, Tmp: String; begin Product:=''; SWVersion:=''; SWDate:=''; Manufacturer:=''; SwitchBoxMode('FBUS'); if (NFB_Send55str)=FALSE then begin form1._msg('0x55 Reset Error'); exit; end; n:=SendFrameAndSendAck(Fphonename, Length(fphonename), True, True, True); if n=0 then begin form1._msg('Phone not found'); exit; end; Form1._msg('Name : '+hex2chr(BufToHexStr(@FrameInside[10], FrameInside[9]))); n:=SendFrameAndSendAck(Frame_DetectPhone, $B, True, True, True); if n=0 then begin form1._msg('Phone not found'); exit; end; for i:=0 to n-1 do begin if (FrameInside[i]>$0F) or (FrameInside[i]=$0A) then if FrameInside[i]=$0A then McuSW_Buf:=McuSW_BUf+', ' else McuSW_Buf:=McuSW_Buf+Chr(FrameInside[i]); end; // Scan all stuff in McuSW buf for i:=1 to StrLen(PChar(McuSW_Buf)) do begin if McuSW_Buf[i]=',' then begin PointerBuf:=i; break; end; SWVersion:=SWVersion+McuSW_Buf[i]; end; for i:=PointerBuf+2 to StrLen(PChar(McuSW_Buf)) do begin if McuSW_Buf[i]=',' then begin PointerBuf:=i; break; end; SWDate:=SWDate+McuSW_Buf[i]; end; for i:=PointerBuf+2 to StrLen(PChar(McuSW_Buf)) do begin if McuSW_Buf[i]=',' then begin PointerBuf:=i; break; end; Product:=Product+McuSW_Buf[i]; end; for i:=PointerBuf+2 to StrLen(PChar(McuSW_Buf)) do begin if McuSW_Buf[i]=',' then begin PointerBuf:=i; break; end; Manufacturer:=Manufacturer+McuSW_Buf[i]; end; // OK we have all needed info, lets roll! form1._msg('SWver : '+Product+' , '+SWVersion+' , '+SWDate+' , '+Manufacturer); n:=SendFrameAndSendAck(Frame_GetOTPIMEI, $E, True, True, True); if n=0 then begin form1._msg('Extended info, Get OTP IMEI, Transmit error, aborting'); exit; end; Buf:=''; for i:=1 to FrameInside[9]-1 do Buf:=Buf+Chr(FrameInside[9+i]); form1._msg('IMEI : '+BUF); n:=SendFrameAndSendAck(Frame_DetectPPM, $C, True, True, True); if n=0 then begin form1._msg('Extended info, PPM Info, Transmit error, aborting'); exit; end; for i:=0 to n do begin Buf:=Buf+Chr(FrameInside[i]); end; i:=StrLen(PChar(Buf)); repeat i:=i-1; until Buf[i]=','; DelimiterPos:=i; for i:=DelimiterPos+2 to StrLen(PChar(Buf)) do PPM:=PPM+Buf[i]; x:=0; for i:=1 to StrLen(PChar(PPM)) do begin if PPM[i]='.' then x:=i; end; Buf:=''; if x<>0 then begin for i:=x+1 to StrLen(PChar(PPM)) do begin buf:=buf+PPM[i]; end; PPM:=Buf; end; form1._msg('PPM Variant : '+PPM); n:=SendFrameAndSendAck(Frame_BB5_GetCP, $10, True, True, True); if n=0 then begin form1._msg('Extended info, Get CP, Transmit error, aborting'); exit; end; Buf:=''; for i:=1 to FrameInside[9]-1 do begin if FrameInside[9+i]=$0A then Buf:=Buf+', ' else Buf:=Buf+Chr(FrameInside[9+i]); end; if Buf<>'' then begin Tmp:=''; j:=0; for i:=1 to StrLen(pChar(Buf))-2 do begin if j=50 then begin form1._msg('CNT Version : '+Tmp); Tmp:=''; j:=0; end else begin j:=j+1; Tmp:=Tmp+Buf[i]; if i=StrLen(pChar(Buf)) then j:=50; end; end; end; n:=SendFrameAndSendAck(Frame_BB5_GetAPESW, $10, True, True, True); if n=0 then begin form1._msg('Extended info, Get APESW, Transmit error, aborting'); exit; end; Buf:=''; for i:=1 to FrameInside[9]-1 do begin if FrameInside[9+i]=$0A then Buf:=Buf+', ' else Buf:=Buf+Chr(FrameInside[9+i]); end; if Buf<>'' then form1._msg('APE Core : '+BUF); n:=SendFrameAndSendAck(Frame_BB5_GetAPEVA, $10, True, True, True); if n=0 then begin form1._msg('Extended info, Get APEVA, Transmit error, aborting'); exit; end; Buf:=''; for i:=1 to FrameInside[9]-1 do begin if FrameInside[9+i]=$0A then Buf:=Buf+', ' else Buf:=Buf+Chr(FrameInside[9+i]); end; if Buf<>'' then form1._msg('APE Variant : '+BUF); n:=SendFrameAndSendAck(Frame_GetCodeCount, $B, True, True, True); if n=0 then begin form1._msg('Extended info, Get Simlock_Code_Count, Transmit error, aborting'); exit; end; Buf:=''; form1._msg('SL Key Count : '+IntToStr(FrameInside[29] mod $10)+'/'+IntToStr(FrameInside[29] div $10)); Buf:=''; n:=GetPMFieldLength(4); if n>=(4 div 2) then // 0 is key position begin n:=GetPMKeyLength(4, 4); if n>=7 then begin n:=PMReadCurrentKey(4, 4, n); for i:=0 to n do Buf:=Buf+Chr(PMData[i]); form1._msg('Product Code : '+Buf); end; end; n:=GetPMFieldLength(120); if n>1 then begin form1._msg('New Security BB5 Phone'); end; end; function ChecCMTData():boolean; begin Application.ProcessMessages; //Move(pCmd^, FT_OUT_BUFFER, CmdLen); FillMemory(@FT_IN_BUFFER,$FFFF, $00); FT_OUT_BUFFER[0]:=$6E; FT_OUT_BUFFER[1]:=$1F; if Write_USB_Device_Buffer(2)<>2 then exit; Form1._msg('BootData : '+BufToHexStr(@FT_IN_BUFFER[0], $62)); end; procedure FetchBootData; var Key, KeyLen : Byte; PacketLen : Byte; BlockCount : Byte; CurrBlock : Byte; CurrBlockLen : Word; i,j,k,l,m : integer; ape : Byte; begin apeexist:=false; FASICape:=''; FASICcmt:=''; Application.ProcessMessages; FillMemory(@RAPInfo.APEASICID,$4,$00); FillMemory(@RAPInfo.ROOT_KEY_HASH,$10,$00); FillMemory(@RAPInfo.APErootkey,$10,$00); FillMemory(@RAPInfo.FlashID,$A,$00); FillMemory(@RAPInfo.APEFlashID,$A,$00); FillMemory(@RAPInfo.PublicID,$14,$00); FillMemory(@RAPInfo.BootID,$8,$00); FillMemory(@RAPInfo.ROM_ID,$8,$00); Application.ProcessMessages; PacketLen :=cmd_buf[1]; BlockCount :=cmd_buf[3]; FLbyte:=cmd_buf[Packetlen+2]; i:=4; j:=0; m:=0; form1._msg(''); form1._msg('1st boot Ok, '+byte2str(cmd_buf[2])); while (i$F0 then result:=True; end; function replyverify2():Boolean; begin result:=false; ufsfl_cmd(50,@Verifyreply[0],6,@cmd_buf,2); if cmd_buf[0]>$F0 then Exit; result:=True; end; function replyverify3():byte; begin ufsfl_cmd(50,@Verifyreply[0],6,@cmd_buf,2); Result:=cmd_buf[0]; end; function CheckVpp():Boolean; var vpp, dual : string; begin result:=false; {if not write_frame(@vppchk[0], Length(vppchk)) then Exit; if not read_frame(2,1000) then exit; } ufsfl_cmd(1500,@vppchk[0],2,@cmd_buf,2); if cmd_buf[0]<>$3F then vpp:='False' else vpp:='True'; if cmd_buf[1]<>$3F then dual:='False' else dual:='True'; //form1._msg('IGNITION : VPP : '+vpp+' , DUAL : '+dual); result:=True; end; function GetReadLen():Byte; begin result:=$00; readDataReq[5]:=$02; ufsfl_cmd(150,@readDataReq[0],Length(readDataReq),@cmd_buf,4); result:=cmd_buf[1]; readDataReq[5]:=$00; end; function ReadDatarequest(bytes:byte):Boolean; var len:integer; begin result:=false; readDataReq[5]:=bytes; len:=hexToInt(Byte2Str(bytes))+2; ufsfl_cmd(150,@readDataReq[0],Length(readDataReq),@cmd_buf,len); result:=true; readDataReq[5]:=$00; end; function Freaddata(bytes:byte):Boolean; var len:integer; begin result:=false; readrDta[5]:=bytes; len:=hexToInt(Byte2Str(bytes))+2; ufs_cmd(150,@readrdta[0],Length(readrdta),@cmd_buf,len); result:=true; end; function Freadflashic ():boolean; var FLasic, asfltype, s : string; begin flven:=0; Cfltype:=$00; FLtype:=''; asfltype:=''; case cmd_buf[0] of $00 : FLasic :='CMT'; $01 : FLasic :='APE'; else FLasic:='Unknow'; end; case cmd_buf[1] of $00 : begin FLtype :='NOR'; CFltype:=$00; end; $01 : begin AsFLtype :='NAND'; Afltype:=$01; end; $03 : begin FLtype :='NAND'; Cfltype:=$03; end; $04 : begin FLtype :='MMC , EXT'; Cfltype:=$04; end; else fltype:='Unknow'; end; flven:=dword((@cmd_buf[3])^); //DWordSwap(@flven); reversedword(@flven); case FT_In_Buffer[0] of 1: begin Form1._msg('FLASHID : '+IntToHex(flven,8)+' , '+FLasic+' , NAND'); ReadFlashIc(0,flven); end; 0: begin Form1._msg('FLASHID : '+IntToHex(flven,8)+' , '+FLasic+' , '+ fltype); ReadFlashIc(flven,0); end; end; if Flven<>$0000FFFF then begin result:=True; flicven:=flven; end; end; function SendRaw(Asic:integer; Loader:string) : integer; var rawloader, rawblock : TMemoryStream; b : Boolean; chk : word; tmp : array of Byte; i : integer; flblk : integer; lb : Byte; blkcnt,cblk,cblklen : Byte; flcnt : string; begin result:=9; algo:=''; case asic of $00: Begin Form1.statusbar.Panels[0].Text:='UFS : CMT 2ND boot...'; Form1._msg('CMT : Sending 2nd loader...'); Application.ProcessMessages; RAWblock:=TMemoryStream.Create; rawblock.LoadFromFile(loader); form1._msg('Use : '+extractfilename(Loader)); rawblock.Seek(0,soFromBeginning); RAWloader:=TMemoryStream.Create; BB5_ExtractRAWLoader(RAWBlock, RAWLoader, b); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); if rawloader.size=0 then exit; result:=8; // RAwloader prepare error //form1._msg('STbyte :'+byte2str(flbyte)); if FLbyte>$F0 then begin ufs_cmd(50,@prerawcheck[0],3,@cmd_buf,1); //Form1._msg('Set Data ['+Byte2Str(ft_in_buffer[0])+']'); //form1._msg('Set Data ['+Byte2Str(replyverify3)+']'); end; rawloader.ReadBuffer(tmp[0], rawloader.Size); RawLen[6]:=rawloader.Size mod $100; RawLen[5]:=rawloader.Size div $100; result:=7; // PrebootCheck error - raw len no accepted ufs_cmd(70,@Rawlen[0],7,@cmd_buf,2); //Form1._msg('Set data ['+byte2str(FT_In_Buffer[0])+']'); if cmd_buf[1]<>$72 then Exit; Application.ProcessMessages; FT_Out_Buffer[0]:=$69; FT_Out_Buffer[1]:=$02; FT_Out_Buffer[2]:=$0A; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[5]:=rawloader.Size mod $100; FT_Out_Buffer[4]:=rawloader.Size div $100; FT_Out_Buffer[6]:=$00; FT_Out_Buffer[7]:=$00; Application.ProcessMessages; for i:=0 to rawloader.size+7 do FT_Out_Buffer[i+8]:=TMP[i]; ufs_cmd(600,@FT_out_buffer,(rawloader.Size+8),@cmd_buf,7); result:=6; // rawloader not accepted by phone if cmd_buf[0]<>$00 then exit; if cmd_buf[6]<>$72 then exit; Application.ProcessMessages; Form1._msg('CMT Loader sent, Boot Ok'); Form1._msg('MCU Configuration'); Form1.statusbar.Panels[0].Text:='UFS : 2ND Boot Ok, wait...'; case apeexist of true : ufs_cmd(75,@APEcrc[0],16,@cmd_buf,11); false : ufs_cmd(75,@CMTcrc[0],16,@cmd_buf,11); end; result:=5; // Fetch data fail blkcnt:=Ft_in_buffer[1]; cblk:=ft_in_buffer[2]; cblklen:=ft_in_buffer[3]; if cblklen=0 then Exit; for i:=0 to blkcnt-1 do begin case cblk of $10: begin FreadData(cblklen+2); // Flash ID descriptor //form1._msg(buftohexstr(@Ft_in_buffer[0],cblklen+2)); Freadflashic; cblk:=ft_in_buffer[cblklen]; cblklen:=ft_in_buffer[cblklen+1]; if cblklen=0 then Break; end; $15: begin FreadData(cblklen+4); // FLCNT ( flash content ) //form1._msg(buftohexstr(@Ft_in_buffer[0],cblklen+4)); flcnt:=''; flcnt:=buftohexstr(@Ft_in_buffer[0],19); form1._msg('FLCNT : '+flcnt); cblk:=ft_in_buffer[cblklen+2]; cblklen:=ft_in_buffer[cblklen+3]; if cblklen=0 then Break; end; $35: begin FreadData(cblklen+2); //form1._msg(buftohexstr(@Ft_in_buffer[0],cblklen+2)); algo:=Hex2Chr(BufToHexStr(@Ft_in_buffer[1], cblklen-2)); form1._msg('ReqAlgo : CMT , '+algo); cblk:=ft_in_buffer[cblklen]; cblklen:=ft_in_buffer[cblklen+1]; end; $11: begin FreadData(cblklen+2); // FLCNT ( flash content ) flcnt:=''; //form1._msg(buftohexstr(@Ft_in_buffer[0],cblklen+2)); flcnt:=buftohexstr(@Ft_in_buffer[0],19); form1._msg('FLCNT : '+flcnt); cblk:=ft_in_buffer[cblklen]; cblklen:=ft_in_buffer[cblklen+1]; if cblklen=0 then Break; end else begin Form1._msg('ERR : UNK : '+Byte2Str(cblk)); FreadData(cblklen+2); //Form1._msg(BufToHexStr(@ft_in_buffer[0],cblklen+4)); end; end; end; {case flblk of $01 : begin Application.ProcessMessages; if not FreadData($0D) then Exit; //CMTMCID Form1._msg('FLMCID : '+buftohexstr(@cmd_buf[3],8)); Application.ProcessMessages; end; $03 : begin Application.ProcessMessages; if not FreadData($0D) then Exit; Freadflashic(0); // check flash ic case flven of $89820089 : FbusSloader:=StartDir+'Flash\UFS\RAP3Gv3_algo_v1331.fg'; else Application.ProcessMessages; end; Application.ProcessMessages; if not FreadData($15) then Exit; Form1._msg('FLCNT : '+buftohexstr(@cmd_buf[3],16)); Application.ProcessMessages; if not FreadData($0D) then Exit; //CMTMCID Form1._msg('FLMCID : '+buftohexstr(@cmd_buf[3],8)); Application.ProcessMessages; end; $04 : begin Application.ProcessMessages; if not FreadData($0D) then Exit; Freadflashic(0); // check flash ic Application.ProcessMessages; if not FreadData($0D) then Exit; Freadflashic(0); // check flash ic Application.ProcessMessages; if not FreadData($15) then Exit; Form1._msg('FLCNT : '+buftohexstr(@cmd_buf[3],16)); Application.ProcessMessages; if not FreadData($0D) then Exit; //CMTMCID Form1._msg('FLMCID : '+buftohexstr(@cmd_buf[3],8)); Application.ProcessMessages; end; $05 : begin Application.ProcessMessages; if not FreadData($0D) then Exit; Freadflashic(0); // check flash ic if not FreadData($0D) then Exit; Freadflashic(0); if not FreadData($11) then Exit; algo:=Hex2Chr(BufTohexStr(@cmd_buf[1],$10)); Form1._msg('ALG : '+algo); Application.ProcessMessages; if not FreadData($15) then Exit; Form1._msg('FLCNT : '+buftohexstr(@cmd_buf[0],16)); Application.ProcessMessages; if not FreadData($0D) then Exit; //CMTMCID Form1._msg('FLMCID : '+buftohexstr(@cmd_buf[3],8)); Application.ProcessMessages; end; else begin form1._msg('Sorry, cant'+#39+'t proceed ['+inttostr(flblk)+']'); exit; end; end; } end; $01 : begin result:=8; Form1._msg(''); Application.processMessages; if not replyverify then form1._msg('ready ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; if not replyverify then form1._msg('ready ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; Form1.statusbar.Panels[0].Text:='UFS : APE 2ND boot...'; Form1._msg('APE : Sending 2nd loader...'); Application.ProcessMessages; RAWblock:=TMemoryStream.Create; rawblock.LoadFromFile(loader); form1._msg('Use : '+extractfilename(Loader)); rawblock.Seek(0,soFromBeginning); RAWloader:=TMemoryStream.Create; BB5_ExtractAPERAWLoader(RAWBlock, RAWLoader, b); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); rawloader.ReadBuffer(tmp[0], rawloader.Size); result:=8; if rawloader.size=0 then Exit; Application.ProcessMessages; FT_Out_Buffer[0]:=$65; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$08; FT_Out_Buffer[3]:=$09; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=rawloader.Size div $100; FT_Out_Buffer[6]:=rawloader.Size mod $100; FT_Out_Buffer[7]:=$00; FT_Out_Buffer[8]:=$00; FT_Out_Buffer[9]:=$5B; FT_Out_Buffer[10]:=$01; FT_Out_Buffer[11]:=$24; FT_Out_Buffer[12]:=$04; FT_Out_Buffer[13]:=$00; FT_Out_Buffer[14]:=$00; FT_Out_Buffer[15]:=rawloader.Size div $100; FT_Out_Buffer[16]:=rawloader.Size mod $100; FT_Out_Buffer[17]:=framecrc(@ft_out_buffer[10],7); Application.ProcessMessages; for i:=0 to rawloader.size+17 do FT_Out_Buffer[i+18]:=TMP[i]; ufs_cmd(700,@FT_out_buffer,(rawloader.Size+18),@cmd_buf,7); result:=6; if cmd_buf[0]<>$00 then exit; if cmd_buf[1]<>$10 then form1._msg('Payload message : '+byte2str(ft_in_buffer[1])); if cmd_buf[5]<$F0 then form1._msg('Payload message : '+byte2str(ft_in_buffer[5])); if cmd_buf[6]<>$72 then exit; Application.ProcessMessages; Form1._msg('APE Loader sent, Boot Ok'); if not replyverify then form1._msg('ready ['+buftohexstr(@ft_in_buffer[0],4)+']'); result:=6; // Boot sent, need collect flash info now and check some stuff Application.processMessages; Form1.statusbar.Panels[0].Text:='UFS : Running APE...'; Application.processMessages; if not replyverify then form1._msg('ready ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; ufs_cmd(70,@apePredta,6,@cmd_buf,3); Application.ProcessMessages; if not replyverify2 then form1._msg('repl2 ['+buftohexstr(@ft_in_buffer[0],4)+']'); ufs_cmd(70,@apePredta,6,@cmd_buf,3); Application.ProcessMessages; if not replyverify then form1._msg('ready ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; ufs_cmd(70,@aperun,16,@cmd_buf,9); Application.ProcessMessages; flblk:=cmd_buf[1]; case flblk of $02 : begin lb:=GetReadLen; ReadDatarequest(lb); Freadflashic(); // check flash ic Application.ProcessMessages; lb:=GetReadLen; ReadDatarequest(lb); form1._msg('FLCNT : '+buftohexstr(@cmd_buf[2], lb-4)); Application.ProcessMessages; lb:=GetReadLen; ReadDatarequest(lb); end; $03 : begin lb:=GetReadLen; ReadDatarequest(lb); Freadflashic(); // check flash ic Application.ProcessMessages; lb:=GetReadLen; ReadDatarequest(lb); algo:=''; for i:=1 to lb-3 do if cmd_buf[i]<>$00 then algo:=algo+chr(cmd_buf[i]); Form1._msg('ALGO : '+algo); Application.ProcessMessages; lb:=GetReadLen; ReadDatarequest(lb); form1._msg('FLMCID : '+buftohexstr(@cmd_buf[2], lb-4)); Application.ProcessMessages; lb:=GetReadLen; ReadDatarequest(lb); end else begin form1._msg('Sorry, cant'+#39+'t proceed ['+inttostr(flblk)+']'); exit; end; end; Application.ProcessMessages; result:=5; if not replyverify then form1._msg('ready ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; if not replyverify then form1._msg('ready ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; end; end; result:=0; end; Function SendAlgorihtm(Asic : integer; algo : string):integer; var rawloader,rawblock : TMemoryStream; b : Boolean; chk : word; tmp : array of Byte; ostlen,packets,i2,i : integer; currpacketsize : integer; begin result:=9; case Asic of $00: begin Form1.statusbar.Panels[0].Text:='UFS : Send CMT algo, wait...'; ufsfl_cmd(300,@Checkalgo[0], Length(checkalgo),@cmd_buf, 14); if ft_in_buffer[0]<>$C3 then exit; if ft_in_buffer[12]<$F0 then form1._msg('reply '+byte2str(ft_in_buffer[12])); if ft_in_buffer[13]<>$72 then exit; Application.ProcessMessages; result:=8; if not replyverify then form1._msg('prepare for algo send ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; if not replyverify then form1._msg('prepare for algo send ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; form1._msg('Sending ALGO....'); result:=7; RAWblock:=TMemoryStream.Create; rawblock.LoadFromFile(algo); form1._msg('Use : '+extractfilename(algo)); rawblock.Seek(0,soFromBeginning); RAWloader:=TMemoryStream.Create; BB5_ExtractRAWLoader(RAWBlock, RAWLoader, b); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); Rawloader.Readbuffer(tmp[0], rawloader.size); FT_Out_Buffer[0]:=$69; FT_Out_Buffer[1]:=$02; FT_Out_Buffer[2]:=$0A; FT_Out_Buffer[3]:=rawloader.Size div $10000; FT_Out_Buffer[4]:=rawloader.Size div $100; FT_Out_Buffer[5]:=(rawloader.Size mod $100)+4; FT_Out_Buffer[6]:=$00; FT_Out_Buffer[7]:=$00; FT_Out_Buffer[8]:=$00; FT_Out_Buffer[9]:=rawloader.Size div $10000; FT_Out_Buffer[10]:=rawloader.Size div $100; FT_Out_Buffer[11]:=rawloader.Size mod $100; if rawloader.size>$FFF4 then begin for i:=0 to $FFF4-1 do FT_Out_Buffer[i+12]:=TMP[i]; ufsfl_cmd(800,@FT_out_buffer,$10000,@cmd_buf,0); ostlen:=rawloader.size-$FFF4; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); Rawloader.Readbuffer(tmp[0], $FFF4); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; Rawloader.Readbuffer(tmp[0], currpacketsize); for i:=0 to currpacketsize-1 do FT_Out_Buffer[i]:=TMP[i]; if currpacketsize<$10000 then ufs_cmd(800,@FT_out_buffer,currpacketsize,@cmd_buf,7) else ufsfl_cmd(800,@FT_out_buffer,currpacketsize,@cmd_buf,0); Application.ProcessMessages; //Form1._msg('Packet : '+inttostr(packets)+' Len : '+inttostr(currpacketsize)); end; end; if cmd_buf[0]<>$00 then exit; if cmd_buf[1]<>$00 then exit; if cmd_buf[4]<>$00 then exit; if cmd_buf[5]<$F0 then form1._msg('Payload msg : '+byte2str((FT_In_Buffer[5]))); if cmd_buf[6]<>$72 then exit; result:=6; Application.ProcessMessages; Form1._msg('CMT Algo sent'); ufsfl_cmd(150,@asicch[0],length(asicch),@cmd_buf,11); if cmd_buf[0]<>$C5 then Exit; case cmd_buf[1] of 0: form1._msg('PAPUBkeys blank (erased or HW failure)'); 1: begin Application.ProcessMessages; if not FreadData($17) then Exit; form1._msg('CMT PAPUB : ' +buftohexstr(@cmd_buf[2],$15)); end else Form1._msg('Can'+#39+'t proceed ['+byte2str(ft_in_buffer[1])+']'); end; ufsfl_cmd(100,@asicunk[0],length(asicunk),@cmd_buf,7); Application.ProcessMessages; if not replyverify then form1._msg('reply ['+buftohexstr(@ft_in_buffer[0],4)+']'); checkvpp; result:=0; Form1.statusbar.Panels[0].Text:=''; end; $01: begin Form1.statusbar.Panels[0].Text:='UFS : Send APE algo, wait...'; Application.ProcessMessages; form1._msg('Sending ALGO....'); RAWblock:=TMemoryStream.Create; rawblock.LoadFromFile(algo); form1._msg('Use : '+extractfilename(algo)); rawblock.Seek(0,soFromBeginning); RAWloader:=TMemoryStream.Create; BB5_ExtractAPERAWLoader(RAWBlock, RAWLoader, b); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); Rawloader.Readbuffer(tmp[0], rawloader.size); Application.ProcessMessages; FT_Out_Buffer[0]:=$65; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$08; FT_Out_Buffer[3]:=$09; FT_Out_Buffer[4]:=rawloader.Size div $10000; FT_Out_Buffer[5]:=rawloader.Size div $100; FT_Out_Buffer[6]:=rawloader.Size mod $100; FT_Out_Buffer[7]:=$00; FT_Out_Buffer[8]:=$00; FT_Out_Buffer[9]:=$5B; FT_Out_Buffer[10]:=$01; FT_Out_Buffer[11]:=$25; FT_Out_Buffer[12]:=$04; FT_Out_Buffer[13]:=$00; FT_Out_Buffer[14]:=rawloader.Size div $10000; FT_Out_Buffer[15]:=rawloader.Size div $100; FT_Out_Buffer[16]:=rawloader.Size mod $100; FT_Out_Buffer[17]:=framecrc(@ft_out_buffer[10],7); Application.ProcessMessages; if rawloader.size>$FFEE then begin for i:=0 to $FFEE-1 do FT_Out_Buffer[i+18]:=TMP[i]; ufsfl_cmd(1200,@FT_out_buffer,$10000,@cmd_buf,0); ostlen:=rawloader.size-$FFEE; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); Rawloader.Readbuffer(tmp[0], $FFEE); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if packets-1=0 then CurrPacketSize:=(ostLen mod $10000); if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; Rawloader.Readbuffer(tmp[0], currpacketsize); for i:=0 to currpacketsize-1 do FT_Out_Buffer[i]:=TMP[i]; if currpacketsize<$10000 then ufs_cmd(1200,@FT_out_buffer,currpacketsize,@cmd_buf,7) else ufsfl_cmd(1200,@FT_out_buffer,currpacketsize,@cmd_buf,0); Application.ProcessMessages; end; end else begin for i:=0 to Rawloader.size-1 do FT_Out_Buffer[i+18]:=TMP[i]; ufsfl_cmd(1200,@FT_out_buffer,Rawloader.size+18,@cmd_buf,7); end; if cmd_buf[0]<>$00 then exit; //if ft_in_buffer[1]<>$00 then form1._msg('Fur msg : '+byte2str((FT_In_Buffer[1]))); if cmd_buf[4]<>$00 then form1._msg('Fur msg : '+byte2str((FT_In_Buffer[4]))); if cmd_buf[5]<$F0 then form1._msg('Payload msg : '+byte2str((FT_In_Buffer[5]))); if cmd_buf[6]<>$72 then exit; Application.ProcessMessages; Form1._msg('APE Algo sent'); ufsfl_cmd(500,@asicunk[0],length(asicunk),@cmd_buf,11); if not replyverify then form1._msg('['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; CheckVpp; getapepapub; Form1.statusbar.Panels[0].Text:='UFS : Boot Done'; end; end; result:=0; end; function getapepapub():Boolean; begin Application.ProcessMessages; ufsfl_cmd(500,@apepapub[0], Length(apepapub),@cmd_buf,11); if cmd_buf[0]<>$C5 then begin form1._msg('RX : '+buftohexstr(@ft_in_buffer[0],10)); Exit; end; case FT_In_Buffer[1] of 0: form1._msg('PAPUBkeys blank (erased or HW failure)'); 1: begin Application.ProcessMessages; if not FreadData($17) then Exit; form1._msg('APE PAPUB : ' +buftohexstr(@cmd_buf[2],$15)); end else Form1._msg('Can'+#39+'t proceed ['+byte2str(cmd_buf[1])+']'); end; PreCertreq; if not replyverify then form1._msg('['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; result:=True; end; function ReadCert(ASIC : Byte ; CERT : string):string; var i,rwal : Integer; chkb : Byte; b : Boolean; data,sd: string; cbyte : byte; blkcnt : Integer; certsize : integer; begin data:=''; certsize:=0; if not phoneready(5) then begin form1._msg('Error while prepare, can'+#39+'t read certificate... :('); result:=''; Exit; end; for i:=12 to 25 do readCertReq[i]:=$00; Form1.statusbar.Panels[0].Text:='UFS : Read '+CERT+' cert'; Form1.pb1.Progress:=0; case ASIC of $00: // CMT begin Form1._msg('CMT : Read '+CERT+' certificate...'); for i:=0 to Length(CERT) do readCertReq[i+12]:=Ord(CERT[i+1]); readCertReq[24]:=$00; readCertReq[25]:=frameCrc(@readCertReq[9], 16); ufs_cmd(1000,@readcertreq[0],Length(readCertReq),@cmd_buf,9); //Form1._msg('PrecertReq : '+buftohexstr(@Ft_in_buffer[0],9)); if (cmd_buf[7]<$B0) and (cmd_buf[8]<>$72) then begin result:=''; Exit; end; blkcnt:=cmd_buf[1]; Form1.pb1.MaxValue:=blkcnt; //Form1._msg('BlkCNT : '+inttostr(blkcnt)); Application.ProcessMessages; if blkcnt=0 then result:=''; repeat readDataReq[5]:=$02; ufs_cmd(1000,@readdatareq[0], Length(readdataReq),@cmd_buf,4); chkb:=cmd_buf[1]; cbyte:=cmd_buf[0]; //Form1._msg(Byte2Str(chkb)+byte2str(cbyte)); if (chkb>0) and (cbyte=$2C) then begin Application.ProcessMessages; readDataReq[5]:=chkb; certsize:=certsize+chkb; ufs_cmd(1000,@readdatareq[0], Length(readdataReq),@cmd_buf,chkb); data:=data+BufToHexStr(@cmd_buf[0], chkb); b:=True; end else b:=False; Application.ProcessMessages; Form1.pb1.Progress:=Form1.pb1.Progress+1; Application.ProcessMessages; until b=false; form1._msg('Cert size : '+inttostr(certsize)+' byte(s)'); replyend; if Length(data)>80 then result:=data else result:=''; end; $01: // APE begin Form1._msg('APE : Read '+CERT+' certificate...'); for i:=0 to Length(CERT) do readCertReq[i+12]:=Ord(CERT[i+1]); readCertReq[24]:=$01; readCertReq[25]:=frameCrc(@readCertReq[9], 16); ufs_cmd(1000,@readcertreq[0],Length(readCertReq),@cmd_buf,9); //Form1._msg('PrecertReq : '+buftohexstr(@Ft_in_buffer[0],9)); if (cmd_buf[7]<$B0) and (cmd_buf[8]<>$72) then begin result:=''; Exit; end; blkcnt:=cmd_buf[1]; Form1.pb1.MaxValue:=blkcnt; //Form1._msg('BlkCNT : '+inttostr(blkcnt)); Application.ProcessMessages; if blkcnt=0 then result:=''; repeat readDataReq[5]:=$02; ufs_cmd(1000,@readdatareq[0], Length(readdataReq),@cmd_buf,4); chkb:=cmd_buf[1]; cbyte:=cmd_buf[0]; //Form1._msg(Byte2Str(chkb)+byte2str(cbyte)); if (chkb>0) and (cbyte=$2C) then begin Application.ProcessMessages; readDataReq[5]:=chkb; certsize:=certsize+chkb; ufs_cmd(1000,@readdatareq[0], Length(readdataReq),@cmd_buf,chkb); data:=data+BufToHexStr(@cmd_buf[0], chkb); b:=True; end else b:=False; Application.ProcessMessages; Form1.pb1.Progress:=Form1.pb1.Progress+1; Application.ProcessMessages; until b=false; form1._msg('Cert size : '+inttostr(certsize)+' byte(s)'); replyend; if Length(data)>80 then result:=data else result:=''; end; end; Form1.statusbar.Panels[0].Text:=''; Form1.pb1.MaxValue:=100; Form1.pb1.progress:=0; end; function replyend():Boolean; begin result:=false; Verifyreply[2]:=$14; if replyverify then result:=True; Verifyreply[2]:=$40; end; function PreCertreq():Boolean; begin result:=false; ufsfl_cmd(120, @Precert[0], Length(Precert), @cmd_buf, 14); //form1._msg('PreDta : '+buftohexstr(@FT_in_buffer[0],14)); //C3 01 20 01 04 D9 00 00 00 00 00 00 B1 72 if cmd_buf[0]=$C3 then begin if (cmd_buf[3]=$01) and (cmd_buf[4]=$04) then form1._msg('Transmission mode : Dual (Ddr, TX2) ') else form1._msg('Transmission mode : 16 bit ( Single) '); result:=true; end else result:=false; Application.ProcessMessages; end; function incheck(bytes:Integer):Boolean; var i,i2:integer; begin result:=False; i2:=0; for i:=1 to bytes do if FT_In_Buffer[i-1]=$00 then i2:=i2+1; if i2=bytes then Result:=True; end; function phoneready(retry:Integer):Boolean; var i:integer; begin if not replyverify then begin i:=0; repeat Application.ProcessMessages; Inc(i); Sleep(20); Application.ProcessMessages; until (replyverify) or (i=retry); if i<>retry then result:=True else Result:=false; end else result:=true; end; Function FlashPrepare (flimage:string):Boolean; begin // prepare data here Storecert and trans-proto check if not phoneready(20) then begin result:=false; form1._msg('Error while prepare , transrequest error'); Exit; end; // CertStore request ufsfl_cmd(500,@storecert[0], Length(storecert),@cmd_buf,7); if (ft_in_Buffer[0]<>$00) or (ft_in_Buffer[1]<>$00) then begin result:=false; form1._msg('Error while prepare : CertStore error'); form1._msg('ERR : '+buftohexstr(@ft_in_buffer[0], 7)); Exit; end; if not phoneready(20) then begin result:=false; form1._msg('Error while prepare : transrequest error'); form1._msg('ERR : '+buftohexstr(@ft_in_buffer[0], 3)); Exit; end; if not UFSPartitioning(flimage) then begin Form1._msg('Error on Flash Prepare : Partitioning error!'); exit; end; if not PreCertreq then exit; if not ConFigureAsic($00) then form1._msg('CMT CFG not done'); if apeexist then if not ConFigureAsic($01) then form1._msg('APE CFG not done'); result:=True; end; function ConFigureAsic(ASIC:Byte):Boolean; begin case ASIC of $00 : //CMT FUR client begin ufs_cmd(500,@setfmcuconfig[0], Length(setfmcuconfig),@cmd_buf,7); if not AsicComandFur then begin result:=false; form1._msg('Error FUR CMT client, MCU cfg not done'); form1._msg('ERR : '+buftohexstr(@ft_in_buffer[0], 7)); Exit; end else begin //form1._msg('CMT select Ok'); furCMT:=$00; end; end; $01 : //APE FUR client begin ufs_cmd(500,@setfmcuconfigAPE[0], Length(setfmcuconfig),@cmd_buf,7); if not AsicComandFur then begin result:=false; form1._msg('Error FUR APE client, MCU cfg not done'); form1._msg('ERR : '+buftohexstr(@ft_in_buffer[0], 7)); Exit; end else begin //form1._msg('APE select Ok'); furCMT:=$01; end; end; end; result:=True; end; function UFSPartitioning(core:string):Boolean; var fs : TFileStream; buf : array[0..$FFFF] of byte; n,j,buflen : Integer; HdrLen : Integer; HdrPos : LongInt; CurrSeem : Byte; CurrSeemLen, CurSeemcount : Integer; ms : TMemoryStream; loaderlen : DWORD; erase : Boolean; framelen : DWORD; streamlen :TMemoryStream; begin Result:=false; partition:=false; erase:=False; //Form1._msg('Erase : Processing '+ExtractFileName(core)); Application.processmessages; Form1.statusbar.Panels[1].text:=''; Application.ProcessMessages; fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); fs.Read(buf[0],1); if buf[0]<>$B2 then begin fs.free; raise E.Create('Partition : Bad image file'); Exit; end; Application.ProcessMessages; starttime; Application.ProcessMessages; fs.ReadBuffer(buf[0], 4);//Длина Flash Header HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.Seek(4,soFromCurrent); try while fs.Position<(HdrLen) do begin fs.ReadBuffer(CurrSeem, 1); case CurrSeem of $E4: begin //Form1._msg('SEEM: E4'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $E5: begin //Form1._msg('SEEM: E5'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $EA: begin //Form1._msg('SEEM: EA'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $F3: begin // Form1._msg('SEEM: F3'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; // Form1._msg('Dead mode support : True'); fs.Seek(CurrSeemLen, sofromCurrent); end; $FA: begin //Form1._msg('SEEM: FA'); streamlen:=TmemoryStream.Create; streamlen.CopyFrom(fs,$E); // ???????? ?????, ?????? ??? ????? ???? ?? ???? streamlen.Seek(1, sofromBeginning); // ?????????? ???? ???? streamlen.ReadBuffer(loaderlen,4); // ?????? ????? - ??? ????? ????? ????????? ???????????? ????? FA, ??????? ???????? ?????? ???, ????? ????? ????? ?????. dwordswap(@loaderlen); // ????????????? //form1._msg('SEEM: FA:LEN: '+ inttostr(loaderlen)); fs.seek(loaderlen-9,sofromcurrent); // ?????? ??????? - ????? ???? ?????? ?????? ?8 Application.ProcessMessages; streamlen.Free; end; $EE: begin form1._msg('Partitioning....'); partition:=True; partitionstream:=TmemoryStream.Create; fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; partitionstream.copyFrom(fs,CurrSeemlen); partitionstream.Seek(0,soFromBeginning); Application.ProcessMessages; if partition=True then begin framelen:=CurrSeemLen+10; FT_Out_Buffer[0]:=$69; FT_Out_Buffer[1]:=$0A; FT_Out_Buffer[2]:=$0A; FT_Out_Buffer[3]:=$00; Word((@FT_Out_Buffer[4])^):=currseemlen+2; WordSwap(@FT_out_buffer[4]); FT_Out_Buffer[6]:=$00; FT_Out_Buffer[7]:=$00; FT_Out_Buffer[8]:=$64; partitionstream.ReadBuffer(FT_out_buffer[9], CurrSeemLen); FT_out_buffer[framelen-1]:=frameCrc(@FT_out_buffer[9],CurrSeemLen); //Form1._msg('txbuf : '+BufToHexStr(@FT_out_buffer[0],framelen)); ufs_cmd(8000,@FT_out_buffer[0], framelen,@cmd_buf,7); //Form1._msg('Partition result : '+buftohexstr(@cmd_buf[0],7)); if FT_In_Buffer[0]=$00 then form1._msg('Partitioning Ok...') else begin Form1._msg('Partitioning error : '+buftohexstr(@cmd_buf[0],7)); form1._msg('Partitioning failed! :('); result:=false; end; Application.ProcessMessages; partitionstream.free; fs.free; result:=true; Exit; end; end else begin // Form1._msg('SEEM : '+byte2str(currseem)); fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.readbuffer(buf[0],CurrSeemLen); application.ProcessMessages; end; end; end; if not partition then result:=true; fs.Free; except on E:Exception do begin fs.Free; Form1._msg('PartitionFile: Error: '+E.Message); end; end; Application.ProcessMessages; end; function SendRawID(Asic:integer; Loader:string) : integer; var rawloader, rawblock : TMemoryStream; b : Boolean; chk : word; tmp : array of Byte; i : integer; flblk : integer; lb : Byte; filename : string; mmc : System.Text; id : string; idstart : string; idint : integer; begin result:=9; algo:=''; Form1.statusbar.Panels[0].Text:='UFS : CMT 2ND boot...'; Form1._msg('CMT : Sending 2nd loader...'); Application.ProcessMessages; RAWloader:=TMemoryStream.Create; rawloader.LoadFromFile(loader); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); if rawloader.size=0 then exit; result:=8; // RAwloader prepare error if FLbyte>$F0 then begin ufsfl_cmd(500,@prerawcheck[0],3,@cmd_buf,1); //Form1._msg('Set Data ['+Byte2Str(ft_in_buffer[0])+']'); //form1._msg('Set Data ['+Byte2Str(replyverify3)+']'); end; rawloader.ReadBuffer(tmp[0], rawloader.Size); RawLen[6]:=rawloader.Size mod $100; RawLen[5]:=rawloader.Size div $100; result:=7; // PrebootCheck error - raw len no accepted ufsfl_cmd(500,@Rawlen[0],7,@cmd_buf,2); //Form1._msg('Set data ['+byte2str(FT_In_Buffer[0])+']'); devbyte:=FT_In_Buffer[0]; if FT_In_Buffer[1]<>$72 then Exit; Application.ProcessMessages; FT_Out_Buffer[0]:=$69; FT_Out_Buffer[1]:=$02; FT_Out_Buffer[2]:=$0A; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[5]:=rawloader.Size mod $100; FT_Out_Buffer[4]:=rawloader.Size div $100; FT_Out_Buffer[6]:=$00; FT_Out_Buffer[7]:=$00; Application.ProcessMessages; for i:=0 to rawloader.size+7 do FT_Out_Buffer[i+8]:=TMP[i]; ufs_cmd(3000,@FT_out_buffer,(rawloader.Size+8),@cmd_buf,7); result:=6; // rawloader not accepted by phone if ft_in_buffer[0]<>$00 then exit; //if ft_in_buffer[5]<>$F1 then exit; if ft_in_buffer[6]<>$72 then exit; Application.ProcessMessages; Form1._msg('CMT Loader sent, Boot Ok'); Form1.statusbar.Panels[0].Text:='UFS : 2ND Boot Ok, wait...'; rawloader.Free; { RAWloader:=TMemoryStream.Create; rawloader.LoadFromFile(bof); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); rawloader.ReadBuffer(tmp[0], rawloader.Size); } Application.ProcessMessages; FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$20; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$02; FT_Out_Buffer[4]:=$E4; case bof of 1: for i:=0 to 740+4 do FT_Out_Buffer[i+5]:=BOF1rapv2[i]; 2: for i:=0 to 740+4 do FT_Out_Buffer[i+5]:=BOF2rapv3[i]; 3: for i:=0 to 740+4 do FT_Out_Buffer[i+5]:=BOF3Rapido[i]; end; ufsfl_cmd(5000,@FT_out_buffer,(740+5),@cmd_buf,2); //rawloader.Free; if ft_in_buffer[1]<>$72 then exit; Application.ProcessMessages; ufsfl_cmd(5000,@flow,Length(flow),@cmd_buf,2); Form1.statusbar.Panels[0].Text:='UFS : Exploit Ok, wait...'; Application.ProcessMessages; //Form1._msg('OWF : '+byte2str(ft_in_buffer[0])); if ft_in_buffer[1]<>$72 then exit; RAWloader:=TMemoryStream.Create; rawloader.LoadFromFile(FbusSloader); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); rawloader.ReadBuffer(tmp[0], rawloader.Size); Application.ProcessMessages; FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$20; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[4]:=rawloader.Size mod $100; FT_Out_Buffer[3]:=rawloader.Size div $100; for i:=0 to rawloader.size+4 do FT_Out_Buffer[i+5]:=TMP[i]; dwordswap(@FT_out_buffer[5]); ufsfl_cmd(5000,@FT_out_buffer,(rawloader.Size+5),@cmd_buf,2); rawloader.free; if ft_in_buffer[1]<>$72 then exit; Application.ProcessMessages; ufsfl_cmd(5000,@flow,Length(flow),@cmd_buf,2); Application.ProcessMessages; // Form1._msg('OWF2 : '+byte2str(ft_in_buffer[0])); if ft_in_buffer[1]<>$72 then exit; Application.ProcessMessages; ufsfl_cmd(5000,@overready , 9 ,@cmd_buf,11); // Form1._msg('OWF : '+byte2str(ft_in_buffer[9])); //if ft_in_buffer[8]<>$72 then exit; Application.ProcessMessages; ufsfl_cmd(5000,@readdieid , 6 ,@cmd_buf, $40); Form1.statusbar.Panels[0].Text:='UFS : Fetching data, wait...'; id:=buftohexstr(@ft_in_buffer[0],$40); UkeyData.PID:=BufToHexStr(@Rapinfo.PUBLIC_ID[0],Length(Rapinfo.PUBLIC_ID)); UkeyData.Hash:=buftohexstr(@Rapinfo.ROOT_KEY_HASH[0],Length(RAPInfo.ROOT_KEY_HASH)); idint:=Pos(UkeyData.PID,id); idstart:=Copy(id,idint+40,40); UkeyData.key:=idstart; //form1._msg(id); // Show Data in log // form1._msg('PID : '+UkeyData.PID); // form1._msg('HSH : '+UkeyData.Hash); // form1._msg('KEY : '+UkeyData.key); //id); result:=0; end; function UFSWriteFileUNI(core:string):Boolean; const maxlen : dWORD = $4FFFF ; var buf :array[0..$4FFFF] of byte; HdrLen, CurrBlockLen : Cardinal; EntryPoint, DataLen, TargetOffset, CRCTmp : LongInt; i, n, Blocks, Packets,icl, CurrPacketSize, TokenHdrLen : Integer; good : Integer; CertName,AsicType : String; PAPUB_Already, APE_PAPUB : boolean; fs : TFileStream; ms : TMemoryStream; writen,framelen : Dword; cmtcount,cmtdin, TokenSubType, unk : integer; nopbyte : byte; nopword : word; ttxbuf : array[0..$4FFFF] of byte; ape,cmt : Boolean; apebyte : Byte; bulkread : integer; ostlen : DWORD; i2 : integer; inslen : integer; fspos : Integer; begin Result:=False; Form1._msg('Write : Processing '+ExtractFileName(core)); fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); Blocks:=0; cmtcount:=0; cmtdin:=0; unk:=0; Form1.pb1.ForeColor:=clGreen; Form1.pb1.progress:=0; Application.ProcessMessages; PAPUB_Already:=False; APE_PAPUB:=false; try fs.Read(ttxbuf[0],1); if ttxbuf[0]<>$B2 then begin fs.free; raise E.Create('Write : Bad image file'); end; Application.ProcessMessages; starttime; Application.ProcessMessages; fs.ReadBuffer(ttxbuf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(ttxbuf[0], 2)+IntToHex(ttxbuf[1], 2)+ IntToHex(ttxbuf[2], 2)+IntToHex(ttxbuf[3], 2)); fs.Seek(HdrLen, sofromcurrent);//К началу первого Flash-токена {ms:=TMemoryStream.Create;} form1.pb1.maxvalue:=(fs.size-hdrlen); form1.statusbar.Panels.Items[0].Text:='Writing...'; while fs.Position$00 then begin if ConFigureAsic($00) then furcmt:=$00 else begin form1._msg('CMT select error, impossible continue flashing. Check HW/Cable'); result:=false; fs.free; Exit; end; Application.ProcessMessages; end; end; $01: begin if furCMT<>$01 then begin if ConFigureAsic($01) then furcmt:=$01 else begin form1._msg('APE select error, impossible continue flashing. Check HW/Cable'); result:=false; fs.free; Exit; end; end; Application.ProcessMessages; end; end; application.ProcessMessages; //FillMemory(@cmd_buf[0],9,$00); FT_Out_Buffer[0]:=$65; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$0C; //0C FT_Out_Buffer[3]:=TokenSubtype+$05; FT_Out_Buffer[4]:=CurrBlockLen div $10000; FT_Out_Buffer[5]:=CurrBlockLen div $100; FT_Out_Buffer[6]:=CurrBlockLen mod $100; FT_Out_Buffer[7]:=$07; //07 FT_Out_Buffer[8]:=$00; Application.ProcessMessages; currblocklen:=currblocklen+tokenhdrlen; //fspos:=fs.Position; if CurrBlockLen>$FFF7 then begin fs.ReadBuffer(FT_Out_Buffer[9],$fff7); ufsfl_cmd(8000,@FT_out_buffer,$10000,@cmd_buf,0); ostlen:=CurrBlockLen-$FFF7; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>=1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; Application.ProcessMessages; //form1._msg(inttostr(ostlen mod $10000)); fs.ReadBuffer(FT_Out_Buffer[0],currpacketsize); if currpacketsize<$10000 then ufsfl_cmd(8000,@FT_out_buffer,currpacketsize,@cmd_buf,14) else ufsfl_cmd(8000,@FT_out_buffer,currpacketsize,@cmd_buf,0); Application.ProcessMessages; end; end else begin fs.ReadBuffer(FT_Out_Buffer[9],currblocklen); ufsfl_cmd(8000,@FT_out_buffer,CurrBlockLen+9,@cmd_buf,14); end; //Form1._msg(BufToHexStr(@cmd_buf[0],7)); Application.ProcessMessages; if not checkc7 then begin form1._msg('Error write block at : '+ IntToStr(blocks)); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],12)); result:=False; fs.Free; Exit; end; Application.ProcessMessages; inc(blocks); case apebyte of $00:form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); $01:form1.statusbar.Panels[1].Text:='APE : '+inttostr(Blocks); end; Application.ProcessMessages; end;//End of Case $54 $5D://Phoenix-segment begin //5D 0127 2D 25B977A055BE9B5DEC0C38A2A279C695 8594B99841444100000000000000000000030077E7 00000400 000A0800 BB // Len RootKey Hash Len Flash CRC //5D 0128 43 25B977A055BE9B5DEC0C38A2A279C695 8594B99850415055424B4559530000000003 00A70900 00060000 11F000397DCE210733C335E84BAD369EC893FCA06D1BC3 0100 A5 // Len RootKey Hash Len Flash CRC Application.ProcessMessages; fs.ReadBuffer(ttxbuf[$09], $3);//Чтение значения подтипа токена и длины его заголовка TokenHdrLen:=ttxbuf[$0B];//Длина заголовка токена TokenSubType:=TokenHdrLen; fs.Seek(fs.position-4, sofrombeginning);//смещение на начало токена inc(TokenHdrLen, 5);//Увеличим длину до общей длины токена с его CRC fs.ReadBuffer(ttxbuf[8], TokenHdrLen);//Чтение значений токена с его CRC apebyte:=ttxbuf[44]; Application.ProcessMessages; case TokenSubType of $2D: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(ttxbuf[TokenHdrLen-1], 2)+ IntToHex(ttxbuf[TokenHdrLen], 2)+ IntToHex(ttxbuf[TokenHdrLen+1], 2)+ IntToHex(ttxbuf[TokenHdrLen+2], 2)); $43: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(ttxbuf[TokenHdrLen-$17], 2)+ IntToHex(ttxbuf[TokenHdrLen-$16], 2)+ IntToHex(ttxbuf[TokenHdrLen-$15], 2)+ IntToHex(ttxbuf[TokenHdrLen-$14], 2)); else begin fs.Free; E.Create('Write : Bad image file'); end; end;//End of Case //Сравнение RootKey Hash телефона и RootKey Hash блока сертов good:=0; case apebyte of $00: begin for i:=$0 to $0F do if RAPInfo.Root_Key_Hash[i]=ttxbuf[i+$0C] then inc(good); end; $01: begin for i:=$0 to $0F do if RAPInfo.APErootkey[i]=ttxbuf[i+$0C] then inc(good); end; end; if good<$10 then begin//RootKey Hash не совпал, пропускаем fs.Seek(CurrBlockLen, soFromCurrent);//Пропускаем токен и его данные continue; end else begin fs.Seek(fs.position-Tokenhdrlen, soFromBeginning); //RootKey Hash серта совпал, копируем case TokenSubType of $2D: begin fs.ReadBuffer(ttxBuf[0],TokenHdrLen);//Копирование данных Application.ProcessMessages; CertName:=''; for i:=24 to 39 do if ttxbuf[i]=$00 then break else CertName:=CertName+Chr(ttxbuf[i]); case apebyte of $00:Form1._msg('CMT: Writing Hash CERT ['+CertName+']'); $01:Form1._msg('APE: Writing Hash CERT ['+CertName+']'); end; Application.ProcessMessages; //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); Application.ProcessMessages; case apebyte of $00: begin if furCMT<>$00 then begin if ConFigureAsic($00) then furcmt:=$00 else begin form1._msg('APE select error, impossible continue flashing. Check HW/Cable'); result:=false; fs.free; Exit; end; end; end; $01: begin if furCMT<>$01 then begin if ConFigureAsic($01) then furcmt:=$01 else begin form1._msg('APE select error, impossible continue flashing. Check HW/Cable'); result:=false; fs.free; Exit; end; end; Application.ProcessMessages; end; end; application.ProcessMessages; fs.Seek(fs.position-Tokenhdrlen, soFromBeginning); application.ProcessMessages; //FillMemory(@cmd_buf[0],9,$00); FT_Out_Buffer[0]:=$65; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$0C; FT_Out_Buffer[3]:=$32; FT_Out_Buffer[4]:=CurrBlockLen div $10000; FT_Out_Buffer[5]:=CurrBlockLen div $100; FT_Out_Buffer[6]:=CurrBlockLen mod $100; FT_Out_Buffer[7]:=$07; FT_Out_Buffer[8]:=$00; Application.ProcessMessages; currblocklen:=currblocklen+tokenhdrlen; if CurrBlockLen>$FFF7 then begin fs.ReadBuffer(FT_Out_Buffer[9],$fff7); ufsfl_cmd(6000,@FT_out_buffer,$10000,@cmd_buf,0); ostlen:=CurrBlockLen-$FFF7; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>=1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; // form1._msg(inttostr(ostlen mod $10000)); fs.ReadBuffer(FT_Out_Buffer[0],currpacketsize); if currpacketsize<$10000 then ufsfl_cmd(6000,@FT_out_buffer,currpacketsize,@cmd_buf,14) else ufsfl_cmd(6000,@FT_out_buffer,currpacketsize,@cmd_buf,0); Application.ProcessMessages; end; end else begin fs.ReadBuffer(FT_Out_Buffer[9],currblocklen); ufsfl_cmd(6000,@FT_out_buffer,CurrBlockLen+9,@cmd_buf,14); end; //Form1._msg(BufToHexStr(@cmd_buf[0],7)); Application.ProcessMessages; if not checkc7 then begin form1._msg('Error write CERT block at : '+ IntToStr(blocks)); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],12)); result:=False; fs.Free; Exit; end; Application.ProcessMessages; inc(blocks); Application.ProcessMessages; case apebyte of $00:form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); $01:form1.statusbar.Panels[1].Text:='APE : '+inttostr(Blocks); end; end; $43: begin fs.ReadBuffer(ttxBuf[0],CurrBlockLen+TokenHdrLen);//Копирование данных Application.ProcessMessages; //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); Application.ProcessMessages; case apebyte of $00: begin if furCMT<>$00 then begin if ConFigureAsic($00) then furcmt:=$00 else begin form1._msg('APE select error, impossible continue flashing. Check HW/Cable'); result:=false; fs.free; Exit; end; end; end; $01: begin if furCMT<>$01 then begin if ConFigureAsic($01) then furcmt:=$01 else begin form1._msg('APE select error, impossible continue flashing. Check HW/Cable'); result:=false; fs.free; Exit; end; end; Application.ProcessMessages; end; end; case apebyte of $00: begin if PAPUB_Already then Application.ProcessMessages else begin Form1._msg('CMT: Writing Hash CERT [PAPUBKEYS]'); // FillMemory(@cmd_buf[0],9,$00); FT_Out_Buffer[0]:=$65; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$0C; FT_Out_Buffer[3]:=$48; FT_Out_Buffer[4]:=CurrBlockLen div $10000; FT_Out_Buffer[5]:=CurrBlockLen div $100; FT_Out_Buffer[6]:=CurrBlockLen mod $100; FT_Out_Buffer[7]:=$07; FT_Out_Buffer[8]:=$00; currblocklen:=currblocklen+tokenhdrlen; if CurrBlockLen>$FFF7 then begin for i:=0 to $FFF7-1 do FT_Out_Buffer[i+9]:=ttxbuf[i]; ufsfl_cmd(6000,@FT_out_buffer,$10000,@cmd_buf,0); ostlen:=CurrBlockLen-$FFF7; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; for i:=0 to currpacketsize-1 do FT_Out_Buffer[i]:=ttxbuf[i]; if currpacketsize<$10000 then ufsfl_cmd(6000,@FT_out_buffer,currpacketsize,@cmd_buf,14) else ufsfl_cmd(6000,@FT_out_buffer,currpacketsize,@cmd_buf,0); Application.ProcessMessages; end; end else begin for i:=0 to CurrBlockLen do FT_Out_Buffer[i+9]:=ttxbuf[i]; ufsfl_cmd(6000,@FT_out_buffer,CurrBlockLen+9,@cmd_buf,14); end; //Form1._msg(BufToHexStr(@cmd_buf[0],7)); Application.ProcessMessages; if not checkc7 then begin form1._msg('Error write CERT block at : '+ IntToStr(blocks)); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],12)); result:=False; fs.Free; Exit; end; PAPUB_Already:=True; end; end; $01: begin if APE_PAPUB then Application.ProcessMessages else begin Form1._msg('APE: Writing Hash CERT [PAPUBKEYS]'); // FillMemory(@cmd_buf[0],9,$00); FT_Out_Buffer[0]:=$65; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$0C; FT_Out_Buffer[3]:=$48; FT_Out_Buffer[4]:=CurrBlockLen div $10000; FT_Out_Buffer[5]:=CurrBlockLen div $100; FT_Out_Buffer[6]:=CurrBlockLen mod $100; FT_Out_Buffer[7]:=$07; FT_Out_Buffer[8]:=$00; currblocklen:=currblocklen+tokenhdrlen; if CurrBlockLen>$FFF7 then begin for i:=0 to $FFF7-1 do FT_Out_Buffer[i+9]:=ttxbuf[i]; ufsfl_cmd(6000,@FT_out_buffer,$10000,@cmd_buf,0); ostlen:=CurrBlockLen-$FFF7; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; for i:=0 to currpacketsize-1 do FT_Out_Buffer[i]:=ttxbuf[i]; if currpacketsize<$10000 then ufsfl_cmd(6000,@FT_out_buffer,currpacketsize,@cmd_buf,14) else ufsfl_cmd(6000,@FT_out_buffer,currpacketsize,@cmd_buf,0); Application.ProcessMessages; end; end else begin for i:=0 to CurrBlockLen do FT_Out_Buffer[i+9]:=ttxbuf[i]; ufsfl_cmd(6000,@FT_out_buffer,CurrBlockLen+9,@cmd_buf,14); end; //Form1._msg(BufToHexStr(@cmd_buf[0],7)); Application.ProcessMessages; if not checkc7 then begin form1._msg('Error write CERT block at : '+ IntToStr(blocks)); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],12)); result:=False; fs.Free; Exit; end; APE_PAPUB:=True; end; end; end; Application.ProcessMessages; end; end; end; Application.ProcessMessages; inc(blocks); Application.ProcessMessages; case apebyte of $01:form1.statusbar.Panels[1].Text:='APE : '+inttostr(Blocks); $00:form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); end; end//End of Case $5D else begin//Unknow Tokens or Bad File fs.free; E.Create('Write : Bad image file'); end; end;//End of Case form1.pb1.progress:=fs.Position; Application.ProcessMessages; end;//End of While fs.free; Form1._msg('Total writen '+inttostr(blocks)+' blocks'); Application.ProcessMessages; endtimecount; Form1._msg('TIME : Write time : '+showtime(tmsres)+' '); form1.statusbar.Panels[1].Text:=''; form1.statusbar.Panels[0].Text:=''; result:=True; //form1._msg('Errors : '+inttostr(GetLastError)); form1.pb1.maxvalue:=100; form1.pb1.progress:=0; Application.ProcessMessages; except on E:Exception do begin Form1._msg('Error: '+E.Message); Form1.pb1.Progress:=0; //USBClosePort; exit; end; end; Form1.pb1.Progress:=0; end; function UFSeraseUni(core:string):Boolean; var fs : TFileStream; buf : array[0..$FFFF] of byte; n,j : Integer; HdrLen : Integer; HdrPos : LongInt; CurrSeem : Byte; CurrSeemLen,CurrEraseLen, CurSeemcount : Integer; EraseStart, EraseStop : array[0..$FF] of LongInt; EraseCnt : Integer; FlashCFG,Byte1,Byte2,Byte3 : Byte; streamlen, ms : TMemoryStream; loaderlen : DWORD; partitionlen, pcfg : Byte; fullerase : Integer; partLen : integer; erase : Boolean; b : Byte; di,i,i2 : integer; crc,partbyte : byte; regioncnt : byte; cmt : Boolean; ercrt : string; begin Result:=false; partition:=false; partLen:=0; erase:=False; furcmt:=$03; Form1.pb1.Progress:=0; Form1.pbsm1.Progress:=0; Form1._msg('Erase : Processing '+ExtractFileName(core)); Application.processmessages; Form1.statusbar.Panels[1].text:=''; Form1.pb1.ForeColor:=clYellow; Form1.pb1.progress:=0; Application.ProcessMessages; fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); fs.Read(b,1); if b<>$B2 then begin Form1._msg('Erase: Invalid Image File'); USBClosePort; fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash Header HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.Seek(4,soFromCurrent); Application.ProcessMessages; starttime; regioncnt:=0; Application.ProcessMessages; try while fs.Position<(HdrLen) do begin fs.ReadBuffer(CurrSeem, 1); case CurrSeem of $E4: begin // Form1._msg('SEEM: E4'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $E5: begin // Form1._msg('SEEM: E5'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $EA: begin // Form1._msg('SEEM: EA'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $EE: begin partition:=True; partitionstream:=TmemoryStream.Create; // Form1._msg('SEEM: EE'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; partLen:=currseemlen; //fs.Seek(CurrSeemLen, sofromCurrent); partitionstream.copyFrom(fs,CurrSeemlen); /// ms.SaveToFile('C:\partition.bin'); Application.ProcessMessages; end; $F3: begin // Form1._msg('SEEM: F3'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $FA: begin // Form1._msg('SEEM: FA'); streamlen:=TmemoryStream.Create; streamlen.CopyFrom(fs,$E); // создавал поток, потому что иначе пока не умею streamlen.Seek(1, sofromBeginning); // пропускаем один байт streamlen.ReadBuffer(loaderlen,4); // читаем длину - это длина всего адресного пространства блока FA, которое занимает апдейт апп, сразу после блока длины. dwordswap(@loaderlen); // разворачиваем fs.seek(loaderlen-9,sofromcurrent); // меняем позицию - после идут старые добрые С8 Application.ProcessMessages; streamlen.Free; end; $C8: begin erase:=True; cmt:=True; fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.ReadBuffer(CurSeemcount, 1); //Form1._msg(''); // Form1._msg('Found '+IntToStr(CurrSeemLen)+' flash chips to erase'); for n:=1 to CurSeemcount do begin //form1._msg(IntToStr(fs.Position)); if stop=True then begin dostop('ERASE'); result:=False; fs.Free; Application.ProcessMessages; Exit; end; fs.ReadBuffer(currseem,1); case currseem of $12: begin FlashCfg:=$12; fs.ReadBuffer(CurrEraseLen, 1); Dec(CurrEraseLen, 3); fs.ReadBuffer(Byte1, 1); fs.ReadBuffer(Byte2, 1); fs.ReadBuffer(Byte3, 1); if furCMT<>Byte1 then begin ConFigureAsic(Byte1); furCMT:=Byte1; end; FillMemory(@Ft_out_buffer[0],$10000,$00); FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$0A; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$50; FT_Out_Buffer[6]:=$00; di:=7; EraseCnt:=CurrEraseLen div 8; Form1._msg('Found '+IntToStr(EraseCnt)+' areas to erase, erase group'); Form1._msg('Asic : '+GetAsic(Byte1)+' , Sub : '+GetSub(Byte2)); //fs.ReadBuffer(buf[0], CurrEraseLen); for j:=0 to EraseCnt-1 do begin FT_Out_Buffer[di]:=FlashCFG; Inc(di); FT_Out_Buffer[di]:=$0B; Inc(di); FT_Out_Buffer[di]:=byte1; Inc(di); FT_Out_Buffer[di]:=byte2; Inc(di); FT_Out_Buffer[di]:=byte3; Inc(di); fs.ReadBuffer(FT_Out_Buffer[di], 8); Application.ProcessMessages; Form1._msg(GetAsic(Byte1)+' , '+GetSub(Byte2)+' , Area : 0x'+buftohexstr(@FT_out_buffer[di],4)+' - 0x'+buftohexstr(@FT_out_buffer[di+4],4)); Application.ProcessMessages; Inc(di,8); Application.ProcessMessages; end; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; Application.ProcessMessages; Word((@FT_Out_Buffer[3])^):=di-4; wordswap(@FT_Out_Buffer[3]); FT_Out_Buffer[6]:=erasecnt; crc:=frameCrc(@Ft_out_buffer[6], di-6); FT_Out_Buffer[di]:=crc; inc(di); application.processMessages; form1.pb1.progress:=0; form1.pb1.maxvalue:=5000; // Form1._msg('Erase : '+buftohexstr(@FT_Out_Buffer[0],di)); if Byte2=$00 then Form1._msg('Using TimeOut : 5 min ( 300 sec )'); Form1._msg('Erasing, wait.....'); application.processMessages; ufsfl_cmd(1000,@FT_out_buffer,di,@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@rd1byte,length(rd1byte),@cmd_buf,3); // form1._msg(byte2str(FT_In_Buffer[0])); repeat FillMemory(@cmd_buf[0],2,$00); ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if (cmd_buf[0]>$F0) or (cmd_buf[0]<$B0) then break; application.processMessages; form1.pb1.progress:=form1.pb1.progress+1; application.processMessages; if stop=True then begin dostop('ERASE'); result:=False; fs.Free; Application.ProcessMessages; UFSeblock; SwitchBoxMode('FBUS'); Exit; end; sleep(20); until cmd_buf[0]>$F0; if cmd_buf[0]<$B0 then begin form1._Msg('Erase error! Conection lost :('); result:=False; fs.Free; Exit; end; end; ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); if not AsicComandFur then begin form1._msg('Erase '+GetAsic(furCMT)+' group error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; form1._msg(GetAsic(furCMT)+' : Group erase Ok'); Application.ProcessMessages; end else begin ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); // form1._msg(buftohexstr(@ft_In_Buffer[0],9)); if not AsicComandFur then begin form1._msg('Erase '+GetAsic(furCMT)+' group error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; form1._msg(GetAsic(furCMT)+' : Group erase Ok'); Application.ProcessMessages; end; //for i:=0 to di do form1._msg(byte2str(framecrc(@Ft_out_buffer[i],(di-i)))); //Form1._msg('Erase : '+buftohexstr(@FT_Out_Buffer[0],di)); end; $19: begin fs.ReadBuffer(partitionlen,1); fs.ReadBuffer(byte1,1); if furCMT<>Byte1 then begin ConFigureAsic(Byte1); furcmt:=Byte1; end; Application.ProcessMessages; fs.Seek(fs.position-2,soFromBeginning); Application.ProcessMessages; FillMemory(@Ft_out_buffer[0],$10000,$00); FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$0A; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$50; FT_Out_Buffer[6]:=$00; di:=7; //regioncnt:=regioncnt+1; FT_Out_Buffer[di]:=$19; Inc(di); fs.ReadBuffer(partitionlen,1); FT_Out_Buffer[di]:=partitionlen; Inc(di); fs.ReadBuffer(FT_Out_Buffer[di],partitionlen); byte1:=Ft_out_buffer[di]; byte2:=Ft_out_buffer[di+1]; partbyte:=Ft_out_buffer[di+14]; Inc(di,partitionlen); form1._msg('Erase Partition 0x'+byte2str(partbyte)+' , '+GetAsic(Byte1)+' , '+GetSub(Byte2)); Application.ProcessMessages; Word((@FT_Out_Buffer[3])^):=di-4; wordswap(@FT_Out_Buffer[3]); FT_Out_Buffer[6]:=$01; crc:=frameCrc(@Ft_out_buffer[6], di-6); FT_Out_Buffer[di]:=crc; inc(di); application.processMessages; form1.pb1.progress:=0; form1.pb1.maxvalue:=1000; //Form1._msg('Erase : '+buftohexstr(@FT_Out_Buffer[0],di)); //Form1._msg('Using TimeOut : 5 min ( 300 sec )'); //Form1._msg('Erasing, wait.....'); application.processMessages; ufsfl_cmd(1000,@FT_out_buffer,di,@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@rd1byte,length(rd1byte),@cmd_buf,3); //form1._msg(byte2str(FT_In_Buffer[0])); repeat FillMemory(@cmd_buf[0],2,$00); ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if (cmd_buf[0]>$F0) or (cmd_buf[0]<$B0) then break; application.processMessages; form1.pb1.progress:=form1.pb1.progress+1; application.processMessages; sleep(10); until cmd_buf[0]>$F0; if cmd_buf[0]<$B0 then begin form1._Msg('Erase partition error! Conection lost :('); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; end; ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); if not AsicComandFur then begin form1._msg('Erase '+GetAsic(furCMT)+' Partition error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; form1._msg(GetAsic(furCMT)+' : Partition erase Ok'); Application.ProcessMessages; end else begin ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); if not AsicComandFur then begin form1._msg('Erase '+GetAsic(furCMT)+' Partition error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; form1._msg(GetAsic(furCMT)+': Partition erase Ok'); Application.ProcessMessages; end; // form1._msg('afPos : '+IntToStr(fs.Position)); end; $13: // Erase USRFL begin //regioncnt:=regioncnt+1; //FillMemory(@Ft_out_buffer[0],$10000,$00); ercrt:=''; fs.ReadBuffer(partitionlen,1); fs.ReadBuffer(Flashcfg,1); if furCMT<>Flashcfg then ConFigureAsic(FlashCfg); erasecnt:=(partitionlen-1) div $C; for i:=0 to erasecnt-1 do begin ercrt:=''; Application.ProcessMessages; FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$0A; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$50; FT_Out_Buffer[6]:=$00; di:=7; FT_Out_Buffer[di]:=$13; Inc(di); FT_Out_Buffer[di]:=$0D; Inc(di); FT_Out_Buffer[di]:=FlashCFG; Inc(di); fs.ReadBuffer(FT_Out_Buffer[di],$0C); for i2:=0 to $0B do if FT_Out_Buffer[di+i2]=$00 then break else ercrt:=ercrt+Chr(FT_Out_Buffer[di+i2]); Inc(di,$0C); //inc(di); form1._msg('Erase CRTFL : '+Ercrt); Application.ProcessMessages; Word((@FT_Out_Buffer[3])^):=di-4; wordswap(@FT_Out_Buffer[3]); FT_Out_Buffer[6]:=$01; crc:=frameCrc(@Ft_out_buffer[6], di-6); FT_Out_Buffer[di]:=crc; inc(di); application.processMessages; form1.pb1.progress:=0; form1.pb1.maxvalue:=1000; //Form1._msg('Erase : '+buftohexstr(@FT_Out_Buffer[0],di)); //Form1._msg('Using TimeOut : 5 min ( 300 sec )'); //Form1._msg('Erasing, wait.....'); application.processMessages; ufsfl_cmd(1000,@FT_out_buffer[0],di,@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@rd1byte,length(rd1byte),@cmd_buf,3); //form1._msg(byte2str(FT_In_Buffer[0])); repeat FillMemory(@cmd_buf[0],2,$00); ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if (cmd_buf[0]>$F0) or (cmd_buf[0]<$B0) then break; application.processMessages; form1.pb1.progress:=form1.pb1.progress+1; application.processMessages; sleep(10); until cmd_buf[0]>$F0; if cmd_buf[0]<$B0 then begin form1._Msg('Erase CRTFL error! Conection lost :('); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; end; ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); if not AsicComandFur then begin form1._msg(GetAsic(furCMT)+' : Erase CRTFL error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; form1._msg(GetAsic(furCMT)+' : CRTFL erase Ok'); Application.ProcessMessages; end else begin ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); // form1._msg(buftohexstr(@ft_In_Buffer[0],9)); if not AsicComandFur then begin form1._msg('Erase '+GetAsic(furCMT)+' CRTFL erase error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; fs.Free; Exit; end; form1._msg(GetAsic(furCMT)+' : CRTFL erase Ok'); Application.ProcessMessages; end; end; end; end; end; form1.pb1.maxvalue:=10000; form1.pb1.progress:=0; Result:=True; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)); Application.ProcessMessages; fs.Free; exit; // fs.Seek(HdrLen, sofromBeginning); end else begin //Form1._msg('SEEM : '+byte2str(currseem)); fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.readbuffer(buf[0],CurrSeemLen); // form1._msg(buftohexstr(@buf[0], currseemlen)); // if CurrSeemLen<1 then fs.ReadBuffer(CurrSeemLen, 1); application.ProcessMessages; end; end; end; if erase=False then begin result:=True; Form1._msg('Erase : No any region, skip erase'); end; fs.Free; except on E:Exception do begin fs.Free; Form1._msg('EraseFile: Error: '+E.Message); end; end; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)); Application.ProcessMessages; fullerase:=0; Form1.pb1.MaxValue:=100; Form1.pb1.Progress:=0; end; function UFSprepareForFlash(image:string):Boolean; begin result:=False; {if not UFSPartitioning(image) then begin Form1._msg('Error on Flash Prepare : Partitioning error!'); exit; end; } if stop=True then begin dostop('FLASH'); Application.ProcessMessages; Exit; end; if not FlashPrepare(image) then begin Form1._msg('Error on Flash Prepare!'); exit; end; if stop=True then begin dostop('FLASH'); Application.ProcessMessages; Exit; end; if not UFSeraseUni(image) then begin Form1._msg('Error on Erasing Phone!'); exit; end; UFSfinishsession; if not phoneready(20) then begin Form1._msg('Error on Prepare for Flashing Phone!'); exit; end; if not PreCertreq then exit; if not phoneready(20) then begin Form1._msg('Error on Prepare for Flashing Phone!'); exit; end; if not UFSWriteFileUNI(image) then begin Form1._msg('Error on Flashing Phone!'); exit; end; //form1._msg('All done ;)'); result:=True; end; function UFSFormatLow(area:string):Boolean; begin result:=False; if not phoneready(20) then begin result:=false; form1._msg('Error while prepare , phone not ready'); Exit; end; if not PreCertreq then exit; if not phoneready(20) then begin result:=false; form1._msg('Error while prepare , transrequest error'); Exit; end; // CertStore request ufsfl_cmd(500,@storecert[0], Length(storecert),@cmd_buf,7); if (ft_in_Buffer[0]<>$00) or (ft_in_Buffer[1]<>$00) then begin result:=false; form1._msg('Error while prepare : CertStore error'); form1._msg('ERR : '+buftohexstr(@ft_in_buffer[0], 7)); Exit; end; if not phoneready(20) then begin result:=false; form1._msg('Error while prepare : transrequest error'); form1._msg('ERR : '+buftohexstr(@ft_in_buffer[0], 3)); Exit; end; if not ConFigureAsic($00) then form1._msg('CMT CFG not done'); Application.ProcessMessages; if not UFSeraseS40(area) then begin Form1._msg('Error on Formatting Phone!'); //exit; end; Application.ProcessMessages; if not phoneready(20) then begin Form1._msg('Error on finish format... :( '); //exit; end; Application.ProcessMessages; if UFSfinishsession<>0 then Exit; UFSfinishsession; result:=True; end; function AsicComandFur():Boolean; begin if cmd_buf[0]<>$C7 then result:=False else begin if (cmd_buf[1]=$01) and (cmd_buf[2]=$2D) and (cmd_buf[3]=$01) and (cmd_buf[4]=$00) and (cmd_buf[5]=$D0) then result:=true else begin if (cmd_buf[1]=$01) and (cmd_buf[2]=$2D) and (cmd_buf[3]=$01) and (cmd_buf[4]=$01) and (cmd_buf[5]=$CF) then result:=true else result:=false; end; end; if (cmd_buf[4]=$03) then Form1._msg('Error, 03, DataMissMatch, Check Cable, FlashPack, Firmware'); end; function checkc7():Boolean; begin result:=False; if not AsicComandFur then exit else result:=True; end; function UFSfinishsession():integer; var st , st2 : Byte; asic,len : Byte; strasic : string; i : integer; begin result:=5; //if not phoneready(20) then exit; Application.ProcessMessages; ufsfl_cmd(3000,@Flbcloseasic[0],11,@cmd_buf,9); if cmd_buf[0]<>$C2 then Exit; repeat Application.ProcessMessages; rdreqdta[5]:=$02; ufsfl_cmd(1500,@rdreqdta[0],6,@cmd_buf,4); asic:=cmd_buf[0]; len:=cmd_buf[1]; if len=0 then Break; rdreqdta[5]:=len; ufsfl_cmd(1500,@rdreqdta[0],6,@cmd_buf,len+2); //Form1._msg('Asic : '+byte2str(asic)+' data : '+buftohexstr(@cmd_buf[0],len)); if asic=$16 then begin Application.ProcessMessages; strasic:=''; for i:=3 to 12 do if cmd_buf[i]<>$00 then strasic:=strasic+chr(cmd_buf[i]) else break; form1._msg('Programming report : Error '+strasic); Application.ProcessMessages; end; until len=0; Application.ProcessMessages; if not phoneready(20) then exit; result:=0; furCMT:=$03; end; function UFSEBLock():integer; begin ufsfl_cmd(1200,@EBlock[0],11,@cmd_buf,14); //Form1._msg('EngageBootLock : '+buftohexstr(@cmd_buf[0],12)); end; function UFSEBLockAPE():boolean; begin ufsfl_cmd(1200,@EBlockAPE[0],14,@cmd_buf,7); //Form1._msg('EngageBootLock : '+buftohexstr(@cmd_buf[0],12)); if phoneready(50) then result:=True; end; function buildUFScert(DataStream : widestring; cert : string; asic : byte ): Boolean; var i, framelen : Integer; tmp : array of Byte; chk : word; x,i2,len, flen : Integer; begin result:=False; // if cert='HWC' then datastream:=datastream+'FFFFFFFF'; flen:=length(datastream) mod 80; if flen <> 0 then begin len:=80-(length(datastream) mod 80); for i2:=0 to len-1 do datastream:=datastream+'F'; // form1._msg('Collect : '+inttostr(len)+'/'+inttostr(flen)); end; // prepare and clear start buffer FillMemory(@Ft_out_buffer[0],800,$00); FT_Out_Buffer[0]:=$65; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$0C; FT_Out_Buffer[3]:=$32; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$00; FT_Out_Buffer[6]:=$00; FT_Out_Buffer[7]:=$00; FT_Out_Buffer[8]:=$00; FT_Out_Buffer[9]:=$5D; FT_Out_Buffer[10]:=$01; FT_Out_Buffer[11]:=$27; FT_Out_Buffer[12]:=$2D; for i:=13 to 32 do FT_Out_Buffer[i]:=$FF; for i:=33 to 44 do FT_Out_Buffer[i]:=$00; for i:=0 to Length(CERT) do FT_Out_Buffer[i+33]:=Ord(CERT[i+1]); FT_Out_Buffer[45]:=asic; case Asic of $00: if FLtype='NAND' then FT_Out_Buffer[46]:=$03 else FT_Out_Buffer[46]:=$00; $01: FT_Out_Buffer[46]:=$01; end; FT_Out_Buffer[47]:=$00; SetLength(tmp, length(DataStream) div 2); x:=StrToBufHex(DataStream,@tmp[0]); CHK:=FbusGetChk(@tmp[0], x); Word((@FT_Out_Buffer[48])^):=chk; DWord((@FT_Out_Buffer[50])^):=x; DWordSwap(@FT_Out_Buffer[50]); FT_Out_Buffer[54]:=$FF; FT_Out_Buffer[55]:=$FF; FT_Out_Buffer[56]:=$FF; FT_Out_Buffer[57]:=$FF; FT_Out_Buffer[58]:=framecrc(@FT_Out_Buffer[0],58); StrToBufHex(DataStream,@FT_Out_Buffer[59]); FT_Out_Buffer[4]:=x div $10000; FT_Out_Buffer[5]:=x div $100; FT_Out_Buffer[6]:=x mod $100; //form1._msg(BufToHexStr(@Ft_out_buffer[0],x+59)); ufsfl_cmd(1500,@FT_out_buffer[0],x+59,@cmd_buf[0],7); //form1._msg(BufToHexStr(@cmd_buf[0],7)); if cmd_buf[5]>$F0 then result:=True; UFSfinishsession; UFSfinishsession; end; function UFSeraseCRT (CRT : string; Asic : Byte) : Boolean; var i,di : integer; crc : byte; begin Application.ProcessMessages; FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$0A; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$50; FT_Out_Buffer[6]:=$00; di:=7; FT_Out_Buffer[di]:=$13; Inc(di); FT_Out_Buffer[di]:=$0D; Inc(di); case Asic of $00: FT_Out_Buffer[di]:=$00; $01: FT_Out_Buffer[di]:=$01; end; Inc(di); fillmemory(@FT_Out_Buffer[di],$0C,$00); for i:=0 to Length(CRT)-1 do FT_Out_Buffer[di+i]:=Ord(crt[i+1]); Inc(di,$0C); form1._msg('Erase CRT FL : '+crt); Application.ProcessMessages; Word((@FT_Out_Buffer[3])^):=di-4; wordswap(@FT_Out_Buffer[3]); FT_Out_Buffer[6]:=$01; crc:=frameCrc(@Ft_out_buffer[6], di-6); FT_Out_Buffer[di]:=crc; inc(di); application.processMessages; form1.pb1.ForeColor:=clYellow; form1.pb1.progress:=0; form1.pb1.maxvalue:=1000; application.processMessages; ufsfl_cmd(1000,@FT_out_buffer[0],di,@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@rd1byte,length(rd1byte),@cmd_buf,3); repeat FillMemory(@cmd_buf[0],2,$00); ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if (cmd_buf[0]>$F0) or (cmd_buf[0]<$B0) then break; application.processMessages; form1.pb1.progress:=form1.pb1.progress+1; application.processMessages; sleep(10); until cmd_buf[0]>$F0; if cmd_buf[0]<$B0 then begin form1._Msg('Erase CRT FL error! Conection lost :('); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; Exit; end; end; form1._msg('CMT : '+crt+' erase Ok'); Application.ProcessMessages; end else begin form1._msg('CMT : '+crt+' erase Ok'); Application.ProcessMessages; end; form1.pb1.Progress:=0; form1.pb1.ForeColor:=clNavy; form1.pb1.MaxValue:=100; Application.ProcessMessages; UFSfinishsession; UFSfinishsession; end; function UFSeraseS40(area:string):Boolean; var di,erasecnt:Integer; crc :Byte; begin Form1._msg('Erase User Area now, Selected model : '+form1.cbbLFmdel.text); Application.ProcessMessages; if furCMT<>$00 then begin ConFigureAsic($00); furCMT:=$00; end; FillMemory(@Ft_out_buffer[0],$10000,$00); FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$0A; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$50; FT_Out_Buffer[6]:=$00; di:=7; FT_Out_Buffer[di]:=$12; Inc(di); FT_Out_Buffer[di]:=$0B; Inc(di); FT_Out_Buffer[di]:=$00; Inc(di); FT_Out_Buffer[di]:=$00; Inc(di); FT_Out_Buffer[di]:=$00; Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,1,2)); Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,3,2)); Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,5,2)); Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,7,2)); Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,9,2)); Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,11,2)); Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,13,2)); Inc(di); FT_Out_Buffer[di]:=Str2Byte(Copy(area,15,2)); Inc(di); Application.ProcessMessages; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; Application.ProcessMessages; Word((@FT_Out_Buffer[3])^):=di-4; wordswap(@FT_Out_Buffer[3]); FT_Out_Buffer[6]:=$01; crc:=frameCrc(@Ft_out_buffer[6], di-6); FT_Out_Buffer[di]:=crc; inc(di); // form1._msg(buftohexstr(@Ft_out_buffer[0],di)); application.processMessages; form1.pb1.progress:=0; form1.pb1.maxvalue:=5000; // Form1._msg('Erase : '+buftohexstr(@FT_Out_Buffer[0],di)); Form1._msg('Using TimeOut : 5 min ( 300 sec )'); Form1._msg('Erasing, wait.....'); application.processMessages; ufsfl_cmd(1000,@FT_out_buffer,di,@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if FT_In_Buffer[0]<$F0 then begin ufsfl_cmd(1000,@rd1byte,length(rd1byte),@cmd_buf,3); // form1._msg(byte2str(FT_In_Buffer[0])); repeat FillMemory(@cmd_buf[0],2,$00); ufsfl_cmd(1000,@Verifyreply,length(Verifyreply),@cmd_buf,2); if (cmd_buf[0]>$F0) or (cmd_buf[0]<$B0) then break; application.processMessages; form1.pb1.progress:=form1.pb1.progress+1; application.processMessages; sleep(20); until cmd_buf[0]>$F0; if cmd_buf[0]<$B0 then begin form1._Msg('Erase error! Conection lost :('); result:=False; Exit; end; end; ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); if not AsicComandFur then begin form1._msg('Erase CMT error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; Exit; end; form1._msg('CMT : Format Ok'); Application.ProcessMessages; result:=True; end else begin ufsfl_cmd(1000,@rd7byte,length(rd7byte),@cmd_buf,9); // form1._msg(buftohexstr(@ft_In_Buffer[0],9)); if not AsicComandFur then begin form1._msg('Erase CMT error!'); form1._msg('ERR : '+buftohexstr(@cmd_buf[0],7)); result:=False; Exit; end; form1._msg('CMT : Format Ok'); Application.ProcessMessages; end; result:=True; end; function Boot_infineon({Boot1:TMemoryStream;Boot2:TMemoryStream}):Boolean; var bflag : boolean; tryinit : integer; len : word; bcount : integer; x : Integer; begin result:=false; Form1.statusbar.Panels[0].Text:='UFS : Booting phone...'; form1._msg('Booting phone now....'); bcount:=0; repeat tryinit:=0; if not busreset then begin; form1._msg('UFSx init fail, reconnect box'); exit; end; //reset_usb_device; repeat FT_Out_Buffer[0]:=$55; Write_USB_Device_Buffer(1); Read_USB_Device_Buffer(5); Application.ProcessMessages; //if FT_In_Buffer[0]=$C3 then Break; if FT_In_Buffer[0]=$A2 then Break; Application.ProcessMessages; sleep(50); Application.ProcessMessages; //sleep(200); Application.ProcessMessages; Application.ProcessMessages; Inc(tryinit); until tryinit=35 ; inc(bcount); if FT_In_Buffer[0]=$A2 then Break; until bcount=5; if (tryinit=35) and (bcount=5) then Exit; Form1._msg('Sync Ok , '+byte2str(FT_In_Buffer[0])); //form1._msg('D : '+buftohexstr(@FT_In_Buffer[0],4)); tryinit:=0; Application.ProcessMessages; form1._msg('CPU ID : XGOLD , '+buftohexstr(@FT_In_Buffer[0],5)); result:=True; end; function BusCheckInfineon():Boolean; var pbl,sbl,dstr : TMemoryStream; i : integer; dsize : word; ostlen,packets,i2 : integer; currpacketsize : integer; chkbuf : array of Byte; loadercheck : byte; flashven : string; begin result:=false; Reset_USB_Device; Set_USB_Device_TimeOuts($2710,$2710); pbl:=TMemoryStream.Create; pbl.Seek(0,soFromBeginning); pbl.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Flash\UFS\SGPBL.bin'); dsize:=pbl.Size; Purge_USB_Device_Out; Purge_USB_Device_In; FT_Out_Buffer[0]:=$30; Word((@FT_Out_Buffer[1])^):=dsize; Write_USB_Device_Buffer(3); pbl.Seek(0,soFromBeginning); if pbl.size>$10000 then begin ostlen:=pbl.size; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); pbl.Seek(0,soFromBeginning); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; pbl.Readbuffer(FT_Out_Buffer[0], currpacketsize); Write_USB_Device_Buffer(currpacketsize); Application.ProcessMessages; //Form1._msg('Packet : '+inttostr(packets)+' Len : '+inttostr(currpacketsize)); end; end else begin pbl.Readbuffer(FT_Out_Buffer[0], pbl.Size); Write_USB_Device_Buffer(pbl.Size); end; Application.ProcessMessages; Sleep(200); Application.ProcessMessages; FT_Out_Buffer[0]:=$FE; //loadercheck; Write_USB_Device_Buffer(1); Read_USB_Device_Buffer(2); if ft_in_buffer[0]=$FF then begin form1._msg('Error booting! 2nd [PBL] not accepted!'); pbl.Free; exit; end; form1._msg('Boot Ok , '+byte2str(ft_in_buffer[0])); pbl.Free; Application.ProcessMessages; Purge_USB_Device_Out; Purge_USB_Device_In; Application.ProcessMessages; Sleep(100); Application.ProcessMessages; FT_Out_Buffer[0]:=$B4; FT_Out_Buffer[1]:=$01; FT_Out_Buffer[2]:=$02; FT_Out_Buffer[3]:=$00; Write_USB_Device_Buffer(4); Application.ProcessMessages; FT_Current_Baud:=FT_BAUD_921600; Set_USB_Device_BaudRate; Application.ProcessMessages; fillmemory(@ft_in_buffer[0],200,$00); Application.ProcessMessages; Read_USB_Device_Buffer($1); if ft_in_buffer[0]<>$01 then exit; Application.ProcessMessages; read_USB_Device_Buffer($93); Application.ProcessMessages; Application.ProcessMessages; form1._msg('PBL : '+hex2chr(buftohexstr(@FT_in_buffer[23],$0F))); Application.ProcessMessages; sbl:=TMemoryStream.Create; sbl.Seek(0,soFromBeginning); sbl.loadfromfile(ExtractFileDir(Application.ExeName)+'\Flash\UFS\SGSBL.bin'); sbl.Seek(0,soFromBeginning); dsize:=sbl.Size; Word((@FT_Out_Buffer[0])^):=dsize; Write_USB_Device_Buffer(2); sbl.Seek(0,soFromBeginning); if sbl.size>$A000 then begin ostlen:=sbl.size; packets:=ostlen div $A000; if ostlen mod $A000>0 then inc(packets); sbl.Seek(0,soFromBeginning); currpacketsize:=$A000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $A000)>0 then CurrPacketSize:=(ostLen mod $A000) else CurrPacketSize:=$A000; end; sbl.Readbuffer(FT_Out_Buffer[0], currpacketsize); Write_USB_Device_Buffer(currpacketsize); Application.ProcessMessages; //Form1._msg('Packet : '+inttostr(packets)+' Len : '+inttostr(currpacketsize)); end; end else begin pbl.Readbuffer(FT_Out_Buffer[0], sbl.Size); Write_USB_Device_Buffer(sbl.Size); end; Application.ProcessMessages; Sleep(100); Application.ProcessMessages; FT_Out_Buffer[0]:=$8E; //loadercheck; Write_USB_Device_Buffer(1); Read_USB_Device_Buffer(1); if (ft_in_buffer[0]=$FF) or (ft_in_buffer[0]<>$01) then begin form1._msg('Error booting! ALGO [SBL] not accepted!'); Application.ProcessMessages; sbl.Free; exit; end; form1._msg('Algo Ok , '+byte2str(ft_in_buffer[0])); Application.ProcessMessages; sbl.Free; Read_USB_Device_Buffer(1); if FT_In_Buffer[0]<>$CC then begin form1._msg('Error booting! Algo not start ['+byte2str(Ft_in_buffer[0])+']'); Exit; end; Application.ProcessMessages; form1._msg('SBL mode Ok'); if FT_In_Buffer[0]<>$CC then begin form1._msg('Error booting! Info stage failed! ['+byte2str(ft_in_buffer[0])+']'); Application.ProcessMessages; exit; end; Read_USB_Device_Buffer($4B); form1._msg('SBL : '+hex2chr(buftohexstr(@FT_in_buffer[11],$16))); Application.ProcessMessages; BufCopy(@BLCFG[0],@ft_out_buffer[0],Length(BLCFG)); Write_USB_Device_Buffer(82); Application.ProcessMessages; Read_USB_Device_Buffer(12); //form1._msg('BL : '+buftohexstr(@FT_in_buffer[0],12)); BufCopy(@BLCHK[0],@ft_out_buffer[0],Length(BLCHK)); Write_USB_Device_Buffer(14); Application.ProcessMessages; Read_USB_Device_Buffer(14); Application.ProcessMessages; if not CompareTwoHexBuf(@BLCHK[0],@ft_in_buffer[0],14) then begin form1._msg('Error booting! Check Boot failed! ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; exit; end; form1._msg('EPP CFG [Bering]...'); BufCopy(@EPPCFGB[0],@ft_out_buffer[0],Length(EPPCFGB)); Write_USB_Device_Buffer(182); Application.ProcessMessages; Read_USB_Device_Buffer(12); //form1._msg('BL : '+buftohexstr(@FT_in_buffer[0],12)); Purge_USB_Device_Out; Purge_USB_Device_In; BufCopy(@Get_FlashID[0],@ft_out_buffer[0],Length(Get_FlashID)); Write_USB_Device_Buffer(12); Application.ProcessMessages; Read_USB_Device_Buffer($10A); if FT_In_Buffer[2]<>$84 then begin form1._msg('Error Get Flash Info! Boot failed! ['+buftohexstr(@ft_in_buffer[0],8)+']'); Application.ProcessMessages; exit; end; flashven:=''; flashven:=buftohexstr(@Ft_in_buffer[9],8); form1._msg('FLASH ID : '+flashven); if flashven='0020000000C08800' then Form1._msg('FLASH ID : ST, M58WR064') else if flashven='00EC000000542200' then Form1._msg('FLASH ID : Samsung, K8S6415E') else if flashven='0000000000000000' then Form1._msg('FLASH ID : Damaged/Unknow') else Form1._msg('FLASH ID : UNKNOW [Not In Base]'); BufCopy(@ft_in_buffer[0],@ft_out_buffer[0],$10A); ft_out_buffer[2]:=$85; ft_out_buffer[$107]:=ft_out_buffer[$107]+1; Write_USB_Device_Buffer($10A); Application.ProcessMessages; Read_USB_Device_Buffer(12); //form1._msg('BL : '+buftohexstr(@FT_in_buffer[0],12)); if (ft_in_buffer[0]<>$02) and (ft_in_buffer[2]<>$85) and (ft_in_buffer[6]<>$FF) then begin form1._msg('Error booting! Check Boot failed! ['+buftohexstr(@ft_in_buffer[0],4)+']'); Application.ProcessMessages; exit; end; Application.ProcessMessages; form1._msg('Boot Done!'); form1._msg(''); result:=True; end; function InfineonEnd():Boolean; begin result:=false; BufCopy(@end_esession[0],@ft_out_buffer[0],length(end_esession)); Write_USB_Device_Buffer(14); Application.ProcessMessages; Read_usb_device_buffer(5); result:=True; end; function sendCert(infcore:string):Boolean; var dtms : TmemoryStream; i : integer; a,b : byte; c : word; begin // sending certificate result:=false; dtms :=TmemoryStream.create; dtms.seek(0,sofrombeginning); ParseInfineon(infcore,8,dtms); if (dtms.Size<=0) or (dtms.size<>$80C) then begin dtms.Free; Exit; end; form1._msg('Cert block found, sending....'); dtms.seek($C,sofrombeginning); FT_Out_Buffer[0]:=$02; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$04; FT_Out_Buffer[3]:=$02; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$08; dtms.ReadBuffer(FT_Out_Buffer[6],$800); c:=0; b:=(2052 div $100)+1; a:=b xor $FF; for i:=2 to 2051 do begin c:=a+FT_Out_Buffer[i]; a:=a+FT_Out_Buffer[i]; b:=b+(c shr 8); end; //a:=a-$A; //b:=b+$A; FT_Out_Buffer[$806]:=a; FT_Out_Buffer[$807]:=b; FT_out_buffer[$808]:=$03; FT_Out_Buffer[$809]:=$00; FillMemory(@ft_in_buffer[0],20,$00); //Form1._msg(BufToHexStr(@Ft_out_buffer[0],$80A)); write_usb_device_buffer($80A); Application.ProcessMessages; read_usb_device_buffer(12); if (ft_in_buffer[0]=$02) and (ft_in_buffer[6]=$01) then begin form1._msg('Cert sent'); result:=True end else begin form1._msg('Cert not accepted ['+buftohexstr(@ft_in_buffer[0],10)+']'); result:=false; end; end; function InfineonErase(infcore:string; curreg:string):Boolean; var erstrt,erstop,wrl : string; rstart,rstop,rwrlen : DWORD; i,i2 : Integer; cs : byte; dcs,chkb : Integer; currer : DWORD; begin //erasing region result:=False; //Form1._msg('Erase : '+curreg); //result:=True; //Exit; erstrt:=Copy(curreg,1,8); erstop:=Copy(curreg,9,8); wrl:=Copy(curreg,17,8); currer:=0; Form1.statusbar.Panels.Items[0].text:='Erasing....'; Application.ProcessMessages; Form1._msg('Erase , Start : 0x'+erstrt+' , Len : 0x'+wrl); ft_out_buffer[0]:=$02; ft_out_buffer[1]:=$00; ft_out_buffer[2]:=$05; ft_out_buffer[3]:=$08; ft_out_buffer[4]:=$08; ft_out_buffer[5]:=$00; //fillmemory(@ft_out_buffer[5],20,$FF); rstart:=0; rstop:=0; rstart:=hextoint(erstrt); DWord((@FT_Out_Buffer[6])^):=rstart; rstop:=(rstart+hextoint(wrl))-2; DWord((@FT_Out_Buffer[10])^):=rstop; ///++ ) - 8 cs:=$00; dcs:=0; chkb:=0; for i:=2 to 13 do begin cs:=cs+ft_out_buffer[i]; dcs:=dcs+ft_out_buffer[i]; end; cs:=cs-$08; chkb:=dcs div $100; //form1._msg(inttostr(chkb)); //ft_out_buffer[13]:=$00; ft_out_buffer[14]:=cs; ft_out_buffer[15]:=$08+chkb; ft_out_buffer[16]:=$03; ft_out_buffer[17]:=$00; //Form1._msg('TX : '+BufToHexStr(@FT_out_buffer[0],18)); Form1._msg('Erasing, wait ... '); Write_USB_Device_Buffer(18); Application.ProcessMessages; Read_USB_Device_Buffer(12); if (FT_In_Buffer[0]<>$02) and (FT_In_Buffer[3]<>$08) and (FT_In_Buffer[8]<>$0F) then Form1._msg('ERR : '+BufToHexStr(@Ft_in_buffer[0],10)) else Application.ProcessMessages; rwrlen:=hextoint(wrl); form1.pb1.MaxValue:=rstop-rstart; Form1.pb1.ForeColor:=clYellow; repeat BufCopy(@chhkerase[0],@Ft_out_buffer[0],12); Write_USB_Device_Buffer(12); Application.ProcessMessages; Read_USB_Device_Buffer(16); if FT_In_Buffer[6]=$01 then Break; if FT_In_Buffer[4]<>$06 then Break; Application.ProcessMessages; DWordSwap(@Ft_in_buffer[7]); Application.ProcessMessages; currer:=HexToInt(BufToHexStr(@Ft_in_buffer[7],4)); Form1.pb1.Progress:=currer-rstart; Application.ProcessMessages; Form1.statusbar.Panels.Items[1].text:='CMT : 0x'+BufToHexStr(@Ft_in_buffer[7],4); Application.ProcessMessages; until FT_In_Buffer[6]=$01; if (FT_In_Buffer[4]=$06) and (FT_In_Buffer[6]=$01) then begin Form1._msg('Erase done'); result:=True; end else begin Form1._msg('Erase Error ['+buftohexstr(@FT_in_buffer[0],14)+']'); result:=false; end; Application.ProcessMessages; Form1.statusbar.Panels.Items[1].text:=''; Form1.statusbar.Panels.Items[0].text:=''; Form1.pb1.ForeColor:=clNavy; form1.pb1.MaxValue:=100; form1.pb1.Progress:=0; Application.ProcessMessages; end; function InfineonWrite(infcore:string; mode:Integer; dlen:string):Boolean; var prgstart, prglen : string; rstrt : dword ; i : Integer; cs : Byte; Flstream : TMemoryStream; a,b : byte; c : word; bb : Boolean; ostlen, packets, i2, currpacketsize : integer; dcs,chkb : Integer; begin //writing region // set start adress prgstart:=Copy(dlen,1,8); prglen:=Copy(dlen,17,8); Form1.statusbar.Panels.Items[0].text:='Write Data....'; form1._msg('Write , Start : 0x'+prgstart+' , Len : 0x'+prglen); Application.ProcessMessages; ft_out_buffer[0]:=$02; ft_out_buffer[1]:=$00; ft_out_buffer[2]:=$02; ft_out_buffer[3]:=$08; ft_out_buffer[4]:=$04; ft_out_buffer[5]:=$00; rstrt:=hextoint(prgstart); DWord((@FT_Out_Buffer[6])^):=rstrt; cs:=$00; dcs:=0; chkb:=0; for i:=2 to 9 do begin cs:=cs+ft_out_buffer[i]; dcs:=dcs+ft_out_buffer[i]; end; cs:=cs-$08; chkb:=dcs div $100; ft_out_buffer[10]:=cs; ft_out_buffer[11]:=$08+chkb; ft_out_buffer[12]:=$03; ft_out_buffer[13]:=$00; //Form1._msg('TX : '+BufToHexStr(@FT_out_buffer[0],14)); Write_USB_Device_Buffer(14); Application.ProcessMessages; Read_USB_Device_Buffer(12); if (FT_In_Buffer[0]<>$02) and (FT_In_Buffer[3]<>$08) and (FT_In_Buffer[8]<>$0C) then Form1._msg('ERR : '+BufToHexStr(@Ft_in_buffer[0],10)) else Form1._msg('Flashing , wait ...'); Flstream:=TMemoryStream.Create; ParseInfineon(infcore,mode,flstream); if (Flstream.Size<$29) and (Flstream=nil) then begin form1._msg('No write data, skip'); Flstream.Free; result:=true; Exit; end; Flstream.Seek(0,soFromBeginning); //Flstream.savetofile('C:\data_write.bin'); Application.ProcessMessages; if (Flstream.Size-$28)<>HexToInt(prglen) then form1._msg('Check cert <=> flash failed! Trying continue...'); Application.ProcessMessages; Flstream.Seek(40,soFromBeginning); //(Flstream.Size-$28) bb:=True; ostlen:=(Flstream.Size-$28); packets:=ostlen div $800; if ostlen mod $800>0 then inc(packets); currpacketsize:=$800; Form1.pb1.MaxValue:=packets; Form1.pb1.ForeColor:=clGreen; Form1.pb1.Progress:=0; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>=1) then begin if (ostlen mod $800)>0 then CurrPacketSize:=(ostLen mod $800) else CurrPacketSize:=$800; end; Application.ProcessMessages; Form1.statusbar.Panels.Items[1].text:='CMT : '+inttostr(i2)+'/'+inttostr(packets-1); Application.ProcessMessages; //form1._msg(inttostr(ostlen mod $800)); FT_Out_Buffer[0]:=$02; FT_Out_Buffer[1]:=$00; FT_Out_Buffer[2]:=$04; FT_Out_Buffer[3]:=$08; FT_Out_Buffer[4]:=$00; FT_Out_Buffer[5]:=$00; word((@Ft_out_buffer[4])^):=currpacketsize; Flstream.ReadBuffer(FT_Out_Buffer[6],currpacketsize); Application.ProcessMessages; // inpacket crc c:=0; b:=(currpacketsize div $100)+7; a:=b xor $FF; for i:=2 to (currpacketsize+5) do begin c:=a+FT_Out_Buffer[i]; a:=a+FT_Out_Buffer[i]; b:=b+(c shr 8); end; /// //form1._msg(byte2str(a)+byte2str(b)); Application.ProcessMessages; FT_Out_Buffer[currpacketsize+6]:=a; FT_Out_Buffer[currpacketsize+7]:=b; FT_Out_Buffer[currpacketsize+8]:=$03; FT_Out_Buffer[currpacketsize+9]:=$00; Application.ProcessMessages; //Form1._msg('RX : '+buftohexstr(@ft_out_buffer[0], currpacketsize+$0A)); Write_USB_Device_Buffer(currpacketsize+$A); Application.ProcessMessages; Read_USB_Device_Buffer(12); if (FT_In_Buffer[0]<>$02) or (FT_In_Buffer[2]<>$04) and (FT_In_Buffer[10]<>$03) then begin Form1._msg('Error, '+inttostr(i2)+' , data missmatch! ['+buftohexstr(@ft_in_buffer[0],10)+']'); Application.ProcessMessages; bb:=False; Break; end; Application.ProcessMessages; //form1._msg(buftohexstr(@ft_in_buffer[0],12)); Form1.pb1.Progress:=Form1.pb1.Progress+1; Application.ProcessMessages; end; if bb=true then begin Form1._msg('Region flash done'); result:=true; end else begin Form1._msg('Region flash error'); result:=False; end; Application.ProcessMessages; Form1.statusbar.Panels.Items[1].text:=''; Form1.statusbar.Panels.Items[0].text:=''; Form1.pb1.ForeColor:=clNavy; form1.pb1.MaxValue:=100; form1.pb1.Progress:=0; Application.ProcessMessages; end; function getchecksum(infcore:string):Boolean; begin // check CS file CS data end; function infgetblockcnt(infcore:string; Erlist:Tstringlist):Integer; var dstrm : Tmemorystream; i : integer; begin // get count block, fill list of regions dstrm:=TMemoryStream.Create; ParseInfineon(infcore,8,dstrm); if (dstrm.Size<40) or (dstrm=nil) then begin dstrm.Free; result:=0; Form1._msg('Error on file prepare, probably damaged!'); Exit; end; result:=GetEraseBlk(dstrm,Erlist); end; function checkready():Boolean; begin result:=False; BufCopy(@chhkerase[0],@Ft_out_buffer[0],12); Write_USB_Device_Buffer(12); Application.ProcessMessages; Read_USB_Device_Buffer(16); if FT_In_Buffer[6]=$01 then result:=true; //Form1._msg(BufToHexStr(@ft_in_buffer[0],16)); //if FT_In_Buffer[4]<>$06 then exit; end; function getchksuminf():Boolean; begin result:=False; BufCopy(@getscss[0],@ft_out_buffer[0],12); Write_USB_Device_Buffer(12); Application.ProcessMessages; Read_USB_Device_Buffer(14); if FT_In_Buffer[0]=$02 then result:=true; Form1._msg('Check : '+BufToHexStr(@ft_in_buffer[8],2)); //if FT_In_Buffer[6]<>$01 then result:=false; end; function FlashInfineonFile(FlasHfile:string):Boolean; var i,cnt:integer; imgs:string; EraseList : TStringList; begin result:=False; i:=0; cnt:=0; //form1._msg(''); Application.ProcessMessages; Form1._msg('File : '+extractfilename(flashfile)); Application.ProcessMessages; imgs:=getFwinfo(flashfile); if imgs='' then Exit; form1._msg('Image : '+imgs); //Exit; if not sendCert(FlasHfile) then Exit; EraseList:=TStringList.Create; cnt:=infgetblockcnt(FlasHfile,EraseList); form1._msg('Found '+inttostr(cnt)+' region(s)'); for i:=0 to cnt-1 do begin form1._msg('Processing Region '+inttostr(i+1)+'/'+inttostr(cnt)); if not InfineonErase(Flashfile,EraseList[i]) then Exit; if not InfineonWrite(Flashfile,i+1,EraseList[i]) then Exit; Application.ProcessMessages; Sleep(50); Application.ProcessMessages; end; Application.ProcessMessages; Sleep(150); Application.ProcessMessages; if not checkready then Form1._msg('Check error!'); Application.ProcessMessages; Sleep(150); Application.ProcessMessages; if not getchksuminf then Form1._msg('Error on Verify'); Application.ProcessMessages; Sleep(50); Application.ProcessMessages; result:=true; end; function halfboot():Boolean; var pbl,sbl,dstr : TMemoryStream; i:integer; dsize: word; ostlen,packets,i2 : integer; currpacketsize : integer; chkbuf : array of Byte; loadercheck : byte; check:Word; begin result:=false; check:=0; Reset_USB_Device; Set_USB_Device_TimeOuts($2710,$2710); pbl:=TMemoryStream.Create; pbl.Seek(0,soFromBeginning); pbl.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Flash\UFS\SGPBL.bin'); dsize:=pbl.Size; Purge_USB_Device_Out; Purge_USB_Device_In; FT_Out_Buffer[0]:=$30; Word((@FT_Out_Buffer[1])^):=dsize; Write_USB_Device_Buffer(3); pbl.Seek(0,soFromBeginning); if pbl.size>$10000 then begin ostlen:=pbl.size; packets:=ostlen div $10000; if ostlen mod $10000>0 then inc(packets); pbl.Seek(0,soFromBeginning); currpacketsize:=$10000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $10000)>0 then CurrPacketSize:=(ostLen mod $10000) else CurrPacketSize:=$10000; end; pbl.Readbuffer(FT_Out_Buffer[0], currpacketsize); Write_USB_Device_Buffer(currpacketsize); Application.ProcessMessages; //Form1._msg('Packet : '+inttostr(packets)+' Len : '+inttostr(currpacketsize)); end; end else begin pbl.Readbuffer(FT_Out_Buffer[0], pbl.Size); Write_USB_Device_Buffer(pbl.Size); end; Application.ProcessMessages; Sleep(200); Application.ProcessMessages; FT_Out_Buffer[0]:=$FE; //loadercheck; Write_USB_Device_Buffer(1); Read_USB_Device_Buffer(1); if ft_in_buffer[0]<>$01 then begin form1._msg('Error booting! 2nd [PBL] not accepted!'); pbl.Free; exit; end; form1._msg('Boot Ok , '+byte2str(ft_in_buffer[0])); Read_USB_Device_Buffer(1); pbl.Free; Application.ProcessMessages; Purge_USB_Device_Out; Purge_USB_Device_In; Application.ProcessMessages; Sleep(100); Application.ProcessMessages; FT_Out_Buffer[0]:=$B4; FT_Out_Buffer[1]:=$01; FT_Out_Buffer[2]:=$02; FT_Out_Buffer[3]:=$00; Write_USB_Device_Buffer(4); Application.ProcessMessages; FT_Current_Baud:=FT_BAUD_921600; Set_USB_Device_BaudRate; Application.ProcessMessages; fillmemory(@ft_in_buffer[0],200,$00); Application.ProcessMessages; Read_USB_Device_Buffer($1); if ft_in_buffer[0]<>$01 then exit; psi:=''; Application.ProcessMessages; read_USB_Device_Buffer($93); Application.ProcessMessages; // form1._msg('PSI Data : '+buftohexstr(@FT_in_buffer[0],$93)); psi:='01'+buftohexstr(@FT_in_buffer[0],$93); Application.ProcessMessages; form1._msg('PBL : '+hex2chr(buftohexstr(@FT_in_buffer[23],$0F))); Application.ProcessMessages; sbl:=TMemoryStream.Create; sbl.Seek(0,soFromBeginning); sbl.loadfromfile(ExtractFileDir(Application.ExeName)+'\Flash\UFS\SGSBL.bin'); sbl.Seek(0,soFromBeginning); dsize:=sbl.Size; Word((@FT_Out_Buffer[0])^):=dsize; Write_USB_Device_Buffer(2); sbl.Seek(0,soFromBeginning); if sbl.size>$A000 then begin ostlen:=sbl.size; packets:=ostlen div $A000; if ostlen mod $A000>0 then inc(packets); sbl.Seek(0,soFromBeginning); currpacketsize:=$A000; Application.ProcessMessages; for i2:=0 to packets-1 do begin Application.ProcessMessages; if (i2=Packets-1) and (Packets>1) then begin if (ostlen mod $A000)>0 then CurrPacketSize:=(ostLen mod $A000) else CurrPacketSize:=$A000; end; sbl.Readbuffer(FT_Out_Buffer[0], currpacketsize); Write_USB_Device_Buffer(currpacketsize); Application.ProcessMessages; //Form1._msg('Packet : '+inttostr(packets)+' Len : '+inttostr(currpacketsize)); end; end else begin pbl.Readbuffer(FT_Out_Buffer[0], sbl.Size); Write_USB_Device_Buffer(sbl.Size); end; Application.ProcessMessages; Sleep(100); Application.ProcessMessages; FT_Out_Buffer[0]:=$8E; //loadercheck; Write_USB_Device_Buffer(1); Read_USB_Device_Buffer(1); if (ft_in_buffer[0]=$FF) or (ft_in_buffer[0]<>$01) then begin form1._msg('Error booting! ALGO [SBL] not accepted!'); Application.ProcessMessages; sbl.Free; exit; end; form1._msg('Algo Ok , '+byte2str(ft_in_buffer[0])); Application.ProcessMessages; sbl.Free; Read_USB_Device_Buffer($4C); if FT_In_Buffer[0]<>$CC then begin form1._msg('Error booting! Info stage failed! ['+byte2str(ft_in_buffer[0])+']'); Application.ProcessMessages; exit; end; form1._msg('SBL mode Ok'); form1._msg('SBL : '+hex2chr(buftohexstr(@FT_in_buffer[12],$16))); Application.ProcessMessages; bufcopy(@ft_in_buffer[0],@ft_out_buffer[6],$48); ft_out_buffer[0]:=$02; ft_out_buffer[1]:=$00; Word((@ft_out_buffer[2])^):=$86; Word((@ft_out_buffer[4])^):=$48; check:=$86+$48; ft_out_buffer[$36]:=$00; ft_out_buffer[$37]:=$00; for i:=6 to 5+$48 do check:=check+FT_Out_Buffer[i]; Word((@ft_out_buffer[$4E])^):=check; Word((@ft_out_buffer[$50])^):=$03; Word((@ft_out_buffer[$51])^):=$00; //Form1._msg(buftohexstr(@ft_out_buffer[0],82)); Write_USB_Device_Buffer(82); Application.ProcessMessages; Read_USB_Device_Buffer(12); //Form1._msg(buftohexstr(@ft_in_buffer[0],12)); result:=True; end; procedure dumpregionepp(start,stop:dword ; resstr:Tmemorystream); var len:dword; i,i2,j,j2:integer; eblcur:dword; tempstream:Tmemorystream; begin len:=0; len:=stop-start; eblcur:=0; eblcur:=start; resstr.seek(0,soFromBeginning); form1.pb1.MaxValue:=len div $800; for i:=1 to (len div $800) do begin EBLcomandStartRead($80b,eblcur); Write_USB_Device_Buffer(14); Application.ProcessMessages; Read_USB_Device_Buffer(12); //if ft_in_buffer[8]<>$15 then break; Application.ProcessMessages; EBLcomandRead($803,$800); Write_USB_Device_Buffer(12); Application.ProcessMessages; fillmemory(@ft_in_buffer[0],$80A,$00); Application.ProcessMessages; Read_USB_Device_Buffer($80A); resstr.Write(ft_in_buffer[6],$800); form1.pb1.progress:=form1.pb1.progress+1; Application.ProcessMessages; Inc(eblcur,$800); end; form1.pb1.Progress:=0; end; procedure dumpppmcatalog(start,stop:dword ; resstr:Tmemorystream); var len:dword; i,i2,j,j2:integer; eblcur:dword; tempstream:Tmemorystream; begin len:=0; len:=stop-start; eblcur:=0; eblcur:=start; resstr.seek(0,soFromBeginning); form1.pb1.MaxValue:=len div $2000; for i:=1 to (len div $2000) do begin EBLcomandStartRead($80b,eblcur); Write_USB_Device_Buffer(14); Application.ProcessMessages; Read_USB_Device_Buffer(12); if ft_in_buffer[8]<>$15 then break; Application.ProcessMessages; EBLcomandRead($803,$800); Write_USB_Device_Buffer(12); Application.ProcessMessages; fillmemory(@ft_in_buffer[0],$80A,$00); Application.ProcessMessages; Read_USB_Device_Buffer($80A); if (FT_In_Buffer[8]=$f8) and (FT_In_Buffer[12]=$50) and (FT_In_Buffer[13]=$4D) then begin resstr.Write(ft_in_buffer[6],$800); inc(eblcur,$800); for j:=1 to 3 do begin EBLcomandStartRead($80b,eblcur); Write_USB_Device_Buffer(14); Application.ProcessMessages; Read_USB_Device_Buffer(12); //if ft_in_buffer[8]<>$15 then break; Application.ProcessMessages; EBLcomandRead($803,$800); Write_USB_Device_Buffer(12); Application.ProcessMessages; fillmemory(@ft_in_buffer[0],$80A,$00); Application.ProcessMessages; Read_USB_Device_Buffer($80A); resstr.Write(ft_in_buffer[6],$800); form1.pb1.progress:=form1.pb1.progress+1; Application.ProcessMessages; inc(eblcur,$800); end; end else Inc(eblcur,$2000); form1.pb1.progress:=form1.pb1.progress+1; Application.ProcessMessages; end; form1.pb1.Progress:=0; end; function busreset():boolean; var ic,dc:integer; begin result:=false; //reset_usb_device; FT_Out_Buffer[0] := $4C; FT_Out_Buffer[1] := $1D; FT_Out_Buffer[2] := $1D; FT_Out_Buffer[3] := $1F; FT_Out_Buffer[4] := $02; FT_Out_Buffer[5] := $0D; FT_Out_Buffer[6] := $98; Write_USB_Device_Buffer(7); //(7,$5, 300); // set ufs commands speed to 115200 FT_Out_Buffer[0] := $42; // >> just send this no reply needed FT_Out_Buffer[1] := $10; Write_USB_Device_Buffer(2); //Set UFS to Atmel MODE first Reset_USB_Device ; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_DTR; Purge_USB_Device_Out; Purge_USB_Device_In; FT_Current_FlowControl := 0; Set_USB_Device_FlowControl; Set_USB_Device_TimeOuts(2000,5000); Set_USB_Device_BaudRate_Divisor($1A); FT_out_Buffer[0] := $58; // Write_USB_Device_Buffer(1); sleep(5); Read_USB_Device_Buffer(1); FT_Out_Buffer[0] := $32; Write_USB_Device_Buffer(1); Read_USB_Device_Buffer(1); FT_out_Buffer[0] := $68; FT_out_Buffer[1] := $01; Write_USB_Device_Buffer(2); sleep(5); Read_USB_Device_Buffer(1); FT_Out_Buffer[0] := $67; sleep(5); Write_USB_Device_Buffer(1); sleep(5); Read_USB_Device_Buffer(1); Set_USB_Device_FlowControl; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_DTR; Purge_USB_Device_Out; Purge_USB_Device_In; FT_Out_Buffer[0] := $68; FT_Out_Buffer[1] := $00; sleep(5); Write_USB_Device_Buffer(2); sleep(5); Read_USB_Device_Buffer(1); FT_Out_Buffer[0] := $66; sleep(5); Write_USB_Device_Buffer(1); sleep(5); Set_USB_Device_DTR; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_FlowControl; Set_USB_Device_BaudRate_Divisor($1A) ; FT_Current_DataBits := $8; FT_Current_StopBits := $1; FT_Current_Parity := $0; Set_USB_Device_DataCharacteristics; //DataBits: 8, StopBits: 0 , Parity: 0 Set_USB_Device_TimeOuts(8000,8000); Reset_USB_Device ; Purge_USB_Device_Out; Purge_USB_Device_In; FT_out_Buffer[0] := $A5; // #$A5 >> must read 1 byte Write_USB_Device_Buffer(1); sleep(5); Read_USB_Device_Buffer(1); if ft_in_buffer[0]=$c3 then result:=true; Clr_USB_Device_DTR; Purge_USB_Device_Out; Purge_USB_Device_In; Set_USB_Device_TimeOuts($50,$50); end; end.