mirror of
https://github.com/bkerler/edl.git
synced 2024-11-14 19:14:58 -05:00
Fix writing on large files. Improve speed. Improve usb handling to match newer libusb. Bug fixing.
This commit is contained in:
parent
8d8eadb92f
commit
28868105f5
4 changed files with 99 additions and 96 deletions
|
@ -201,9 +201,9 @@ class firehose(metaclass=LogBase):
|
|||
|
||||
def xmlsend(self, data, skipresponse=False):
|
||||
if isinstance(data, bytes) or isinstance(data, bytearray):
|
||||
self.cdc.write(data, self.cfg.MaxXMLSizeInBytes)
|
||||
self.cdc.write(data[:self.cfg.MaxXMLSizeInBytes])
|
||||
else:
|
||||
self.cdc.write(bytes(data, 'utf-8'), self.cfg.MaxXMLSizeInBytes)
|
||||
self.cdc.write(bytes(data, 'utf-8')[:self.cfg.MaxXMLSizeInBytes])
|
||||
# time.sleep(0.01)
|
||||
rdata = bytearray()
|
||||
counter = 0
|
||||
|
@ -416,13 +416,7 @@ class firehose(metaclass=LogBase):
|
|||
if rsp[0]:
|
||||
old = 0
|
||||
while bytestowrite > 0:
|
||||
# todo: Why on earth doesn't MaxPayloadSizeToTargetInBytes work here ?
|
||||
# Forced to use self.cfg.SECTOR_SIZE_IN_BYTES ... thus slow as hell
|
||||
"""
|
||||
wlen = min(bytestowrite, self.cfg.MaxPayloadSizeToTargetInBytes // self.cfg.SECTOR_SIZE_IN_BYTES \
|
||||
* self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
"""
|
||||
wlen = min(bytestowrite, self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
wlen = min(bytestowrite, self.cfg.MaxPayloadSizeToTargetInBytes)
|
||||
|
||||
if sparseformat:
|
||||
wdata = sparse.read(wlen)
|
||||
|
@ -434,9 +428,8 @@ class firehose(metaclass=LogBase):
|
|||
filllen = (wlen // self.cfg.SECTOR_SIZE_IN_BYTES * self.cfg.SECTOR_SIZE_IN_BYTES) + \
|
||||
self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
wdata += b"\x00" * (filllen - wlen)
|
||||
wlen = len(wdata)
|
||||
|
||||
self.cdc.write(wdata, wlen)
|
||||
self.cdc.write(wdata)
|
||||
|
||||
prog = round(float(total - bytestowrite) / float(total) * float(100), 1)
|
||||
if prog > old:
|
||||
|
@ -447,7 +440,7 @@ class firehose(metaclass=LogBase):
|
|||
bar_length=50)
|
||||
old = prog
|
||||
|
||||
self.cdc.write(b'', self.cfg.MaxPayloadSizeToTargetInBytes)
|
||||
self.cdc.write(b'')
|
||||
# time.sleep(0.2)
|
||||
|
||||
wd = self.wait_for_data()
|
||||
|
@ -467,10 +460,11 @@ class firehose(metaclass=LogBase):
|
|||
return True
|
||||
|
||||
def cmd_program_buffer(self, physical_partition_number, start_sector, wfdata, display=True):
|
||||
size = len(wfdata)
|
||||
bytestowrite = len(wfdata)
|
||||
total = bytestowrite
|
||||
# Make sure we fill data up to the sector size
|
||||
num_partition_sectors = size // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
if (size % self.cfg.SECTOR_SIZE_IN_BYTES) != 0:
|
||||
num_partition_sectors = bytestowrite // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
if (bytestowrite % self.cfg.SECTOR_SIZE_IN_BYTES) != 0:
|
||||
num_partition_sectors += 1
|
||||
if display:
|
||||
self.info(f"\nWriting to physical partition {str(physical_partition_number)}, " +
|
||||
|
@ -481,66 +475,57 @@ class firehose(metaclass=LogBase):
|
|||
f" num_partition_sectors=\"{num_partition_sectors}\"" + \
|
||||
f" physical_partition_number=\"{physical_partition_number}\"" + \
|
||||
f" start_sector=\"{start_sector}\" "
|
||||
|
||||
if self.modules is not None:
|
||||
data += self.modules.addprogram()
|
||||
data += f"/>\n</data>"
|
||||
rsp = self.xmlsend(data)
|
||||
pos = 0
|
||||
rsp = self.xmlsend(data, self.skipresponse)
|
||||
prog = 0
|
||||
# time.sleep(0.01)
|
||||
if display:
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Complete (Sector %d)' % start_sector,
|
||||
bar_length=50)
|
||||
if rsp[0]:
|
||||
bytesToWrite = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
|
||||
total = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
|
||||
old = 0
|
||||
fpos = 0
|
||||
fsize = len(wfdata)
|
||||
while fsize > 0:
|
||||
# todo: Why on earth doesn't MaxPayloadSizeToTargetInBytes work here ?
|
||||
# Forced to use self.cfg.SECTOR_SIZE_IN_BYTES ... thus slow as hell
|
||||
"""
|
||||
wlen = self.cfg.MaxPayloadSizeToTargetInBytes // self.cfg.SECTOR_SIZE_IN_BYTES \
|
||||
* self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
wlen = min(fsize, wlen)
|
||||
"""
|
||||
wlen = min(fsize, self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
wdata = wfdata[fpos:fpos + wlen]
|
||||
bytesToWrite -= wlen
|
||||
fsize -= wlen
|
||||
pos += wlen
|
||||
fpos += wlen
|
||||
if (wlen % self.cfg.SECTOR_SIZE_IN_BYTES) != 0:
|
||||
pos = 0
|
||||
while bytestowrite > 0:
|
||||
wlen = min(bytestowrite, self.cfg.MaxPayloadSizeToTargetInBytes)
|
||||
|
||||
wdata = data[pos:pos+wlen]
|
||||
pos+=wlen
|
||||
bytestowrite -= wlen
|
||||
|
||||
if wlen % self.cfg.SECTOR_SIZE_IN_BYTES != 0:
|
||||
filllen = (wlen // self.cfg.SECTOR_SIZE_IN_BYTES * self.cfg.SECTOR_SIZE_IN_BYTES) + \
|
||||
self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
wdata += b"\x00" * (filllen - wlen)
|
||||
wlen = len(wdata)
|
||||
self.cdc.write(wdata, wlen)
|
||||
prog = round(float(pos) / float(total) * float(100), 1)
|
||||
|
||||
self.cdc.write(wdata)
|
||||
|
||||
prog = round(float(total - bytestowrite) / float(total) * float(100), 1)
|
||||
if prog > old:
|
||||
if display:
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Written (Sector %d)'
|
||||
% (pos // self.cfg.SECTOR_SIZE_IN_BYTES),
|
||||
print_progress(prog, 100, prefix='Progress:',
|
||||
suffix='Complete (Sector %d)' % ((total - bytestowrite) //
|
||||
self.cfg.SECTOR_SIZE_IN_BYTES),
|
||||
bar_length=50)
|
||||
if display and prog != 100:
|
||||
print_progress(100, 100, prefix='Progress:', suffix='Done', bar_length=50)
|
||||
self.cdc.write(b'', self.cfg.MaxPayloadSizeToTargetInBytes)
|
||||
old = prog
|
||||
|
||||
self.cdc.write(b'')
|
||||
# time.sleep(0.2)
|
||||
|
||||
wd = self.wait_for_data()
|
||||
info = self.xml.getlog(wd)
|
||||
log = self.xml.getlog(wd)
|
||||
rsp = self.xml.getresponse(wd)
|
||||
if "value" in rsp:
|
||||
if rsp["value"] != "ACK":
|
||||
self.error(f"Error:")
|
||||
for line in info:
|
||||
for line in log:
|
||||
self.error(line)
|
||||
return False
|
||||
else:
|
||||
self.error(f"Error:{rsp}")
|
||||
return False
|
||||
else:
|
||||
self.error(f"Error:{rsp}")
|
||||
return False
|
||||
if display and prog != 100:
|
||||
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
print_progress(100, 100, prefix='Progress:', suffix='Done', bar_length=50)
|
||||
return True
|
||||
|
||||
def cmd_erase(self, physical_partition_number, start_sector, num_partition_sectors, display=True):
|
||||
|
@ -576,7 +561,7 @@ class firehose(metaclass=LogBase):
|
|||
wlen = bytesToWrite
|
||||
"""
|
||||
wlen = min(bytesToWrite, self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
self.cdc.write(empty[0:wlen], self.cfg.MaxPayloadSizeToTargetInBytes)
|
||||
self.cdc.write(empty[0:wlen])
|
||||
prog = round(float(pos) / float(total) * float(100), 1)
|
||||
if prog > old:
|
||||
if display:
|
||||
|
@ -587,7 +572,7 @@ class firehose(metaclass=LogBase):
|
|||
pos += wlen
|
||||
if display and prog != 100:
|
||||
print_progress(100, 100, prefix='Progress:', suffix='Done', bar_length=50)
|
||||
self.cdc.write(b'', self.cfg.MaxPayloadSizeToTargetInBytes)
|
||||
self.cdc.write(b'')
|
||||
# time.sleep(0.2)
|
||||
res = self.wait_for_data()
|
||||
info = self.xml.getlog(res)
|
||||
|
@ -635,12 +620,13 @@ class firehose(metaclass=LogBase):
|
|||
prog = 0
|
||||
if display:
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
# todo: Why on earth doesn't MaxPayloadSizeToTargetInBytes work here ?
|
||||
# Forced to use self.cfg.SECTOR_SIZE_IN_BYTES ... thus slow as hell
|
||||
size = min(self.cfg.SECTOR_SIZE_IN_BYTES, 1048576)
|
||||
while bytesToRead > 0:
|
||||
size = min(size, bytesToRead)
|
||||
tmp = self.cdc.read(size)
|
||||
if bytesToRead > self.cfg.MaxPayloadSizeFromTargetInBytes:
|
||||
tmp = b"".join([self.cdc.read(self.cdc.EP_IN.wMaxPacketSize)
|
||||
for _ in range(self.cfg.MaxPayloadSizeFromTargetInBytes//self.cdc.EP_IN.wMaxPacketSize)])
|
||||
else:
|
||||
size = min(self.cdc.EP_IN.wMaxPacketSize, bytesToRead)
|
||||
tmp = self.cdc.read(size)
|
||||
bytesToRead -= len(tmp)
|
||||
wr.write(tmp)
|
||||
if display:
|
||||
|
@ -699,13 +685,13 @@ class firehose(metaclass=LogBase):
|
|||
prog = 0
|
||||
if display:
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
# todo: Why on earth doesn't MaxPayloadSizeToTargetInBytes work here ?
|
||||
# Forced to use self.cfg.SECTOR_SIZE_IN_BYTES ... thus slow as hell
|
||||
#size = min(self.cfg.SECTOR_SIZE_IN_BYTES, 1048576)
|
||||
size = min(self.cfg.SECTOR_SIZE_IN_BYTES, 1048576)
|
||||
while bytesToRead > 0:
|
||||
size = min(size, bytesToRead)
|
||||
tmp = self.cdc.read(size)
|
||||
if bytesToRead > self.cfg.MaxPayloadSizeFromTargetInBytes:
|
||||
tmp = b"".join([self.cdc.read(self.cdc.EP_IN.wMaxPacketSize) for _ in
|
||||
range(self.cfg.MaxPayloadSizeFromTargetInBytes // self.cdc.EP_IN.wMaxPacketSize)])
|
||||
else:
|
||||
size = min(self.cdc.EP_IN.wMaxPacketSize, bytesToRead)
|
||||
tmp = self.cdc.read(size)
|
||||
bytesToRead -= len(tmp)
|
||||
dataread += len(tmp)
|
||||
resData += tmp
|
||||
|
@ -713,9 +699,7 @@ class firehose(metaclass=LogBase):
|
|||
if prog > old:
|
||||
if display:
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Read (Sector %d)'
|
||||
% (
|
||||
dataread // self.cfg.SECTOR_SIZE_IN_BYTES),
|
||||
bar_length=50)
|
||||
% (dataread // self.cfg.SECTOR_SIZE_IN_BYTES), bar_length=50)
|
||||
old = prog
|
||||
if display and prog != 100:
|
||||
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
|
@ -1151,7 +1135,7 @@ class firehose(metaclass=LogBase):
|
|||
xdata = f"<?xml version=\"1.0\" ?><data><poke address64=\"{str(address + pos)}\" " + \
|
||||
f"SizeInBytes=\"{str(maxsize)}\" value64=\"{content}\" /></data>\n"
|
||||
try:
|
||||
self.cdc.write(xdata, self.cfg.MaxXMLSizeInBytes)
|
||||
self.cdc.write(xdata[:self.cfg.MaxXMLSizeInBytes])
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
self.debug(str(e))
|
||||
pass
|
||||
|
@ -1162,7 +1146,7 @@ class firehose(metaclass=LogBase):
|
|||
tmp += self.cdc.read(self.cfg.MaxXMLSizeInBytes)
|
||||
xdata = f"<?xml version=\"1.0\" ?><data><poke address64=\"{str(address + pos)}\" " + \
|
||||
f"SizeInBytes=\"{str(maxsize)}\" value64=\"{content}\" /></data>\n"
|
||||
self.cdc.write(xdata, self.cfg.MaxXMLSizeInBytes)
|
||||
self.cdc.write(xdata[:self.cfg.MaxXMLSizeInBytes])
|
||||
addrinfo = self.cdc.read(self.cfg.MaxXMLSizeInBytes)
|
||||
if (b'<response' in addrinfo and 'NAK' in addrinfo) or b"Invalid parameters" in addrinfo:
|
||||
self.error(f"Error:{addrinfo}")
|
||||
|
@ -1211,7 +1195,7 @@ class firehose(metaclass=LogBase):
|
|||
0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF " /></data>
|
||||
'''
|
||||
try:
|
||||
self.cdc.write(data, self.cfg.MaxXMLSizeInBytes)
|
||||
self.cdc.write(data[:self.cfg.MaxXMLSizeInBytes])
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
self.debug(str(err))
|
||||
pass
|
||||
|
@ -1222,7 +1206,7 @@ class firehose(metaclass=LogBase):
|
|||
tmp += self.cdc.read(self.cfg.MaxXMLSizeInBytes)
|
||||
data = f"<?xml version=\"1.0\" ?><data><peek address64=\"{hex(address)}\" " + \
|
||||
f"SizeInBytes=\"{hex(SizeInBytes)}\" /></data>"
|
||||
self.cdc.write(data, self.cfg.MaxXMLSizeInBytes)
|
||||
self.cdc.write(data[:self.cfg.MaxXMLSizeInBytes])
|
||||
addrinfo = self.cdc.read(self.cfg.MaxXMLSizeInBytes)
|
||||
if (b'<response' in addrinfo and 'NAK' in addrinfo) or b"Invalid parameters" in addrinfo:
|
||||
self.error(f"Error:{addrinfo}")
|
||||
|
|
|
@ -205,7 +205,7 @@ class hdlc:
|
|||
tmp.append(0x7E)
|
||||
tmp.extend(outdata)
|
||||
outdata = tmp
|
||||
return self.cdc.write(outdata, MAX_PACKET_LEN)
|
||||
return self.cdc.write(outdata[:MAX_PACKET_LEN])
|
||||
# FlushFileBuffers(ser)
|
||||
|
||||
def send_cmd_base(self, outdata, prefixflag, nocrc=False):
|
||||
|
|
|
@ -386,12 +386,12 @@ class sahara(metaclass=LogBase):
|
|||
return ["nandprg", None]
|
||||
else:
|
||||
data = b"<?xml version=\"1.0\" ?><data><nop /></data>"
|
||||
self.cdc.write(data, 0x80)
|
||||
self.cdc.write(data)
|
||||
res = self.cdc.read()
|
||||
if res == b"":
|
||||
try:
|
||||
data = b"\x7E\x06\x4E\x95\x7E" # Streaming nop
|
||||
self.cdc.write(data, 0x80)
|
||||
self.cdc.write(data)
|
||||
res = self.cdc.read()
|
||||
if b"\x7E\x0D\x16\x00\x00\x00\x00" in res or b"Invalid Command" in res:
|
||||
return ["nandprg", None]
|
||||
|
@ -407,7 +407,7 @@ class sahara(metaclass=LogBase):
|
|||
return ["sahara", None]
|
||||
else:
|
||||
data = b"\x7E\x11\x00\x12\x00\xA0\xE3\x00\x00\xC1\xE5\x01\x40\xA0\xE3\x1E\xFF\x2F\xE1\x4B\xD9\x7E"
|
||||
self.cdc.write(data, 0x80)
|
||||
self.cdc.write(data)
|
||||
res = self.cdc.read()
|
||||
if len(res) > 0 and res[1] == 0x12:
|
||||
return ["nandprg", None]
|
||||
|
@ -793,7 +793,7 @@ class sahara(metaclass=LogBase):
|
|||
while len(programmer) < data_offset + data_len:
|
||||
programmer += b"\xFF"
|
||||
data_to_send = programmer[data_offset:data_offset + data_len]
|
||||
self.cdc.write(data_to_send, self.pktsize)
|
||||
self.cdc.write(data_to_send)
|
||||
datalen -= data_len
|
||||
self.info("Loader uploaded.")
|
||||
cmd, pkt = self.get_rsp()
|
||||
|
|
|
@ -76,6 +76,7 @@ class UsbClass(metaclass=LogBase):
|
|||
self.__logger.addHandler(fh)
|
||||
|
||||
def verify_data(self, data, pre="RX:"):
|
||||
self.debug("", stack_info=True)
|
||||
if isinstance(data, bytes) or isinstance(data, bytearray):
|
||||
if data[:5] == b"<?xml":
|
||||
try:
|
||||
|
@ -84,11 +85,13 @@ class UsbClass(metaclass=LogBase):
|
|||
try:
|
||||
self.debug(pre + line.decode('utf-8'))
|
||||
rdata += line + b"\n"
|
||||
except: # pylint: disable=broad-except
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
v = hexlify(line)
|
||||
self.debug(str(e))
|
||||
self.debug(pre + v.decode('utf-8'))
|
||||
return rdata
|
||||
except: # pylint: disable=broad-except
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
self.debug(str(e))
|
||||
pass
|
||||
if logging.DEBUG >= self.__logger.level:
|
||||
self.debug(pre + hexlify(data).decode('utf-8'))
|
||||
|
@ -105,7 +108,8 @@ class UsbClass(metaclass=LogBase):
|
|||
return False
|
||||
try:
|
||||
self.device.set_configuration()
|
||||
except:
|
||||
except Exception as e:
|
||||
self.debug(str(e))
|
||||
pass
|
||||
self.configuration = self.device.get_active_configuration()
|
||||
self.debug(2, self.configuration)
|
||||
|
@ -247,8 +251,8 @@ class UsbClass(metaclass=LogBase):
|
|||
if self.device.is_kernel_driver_active(self.interface):
|
||||
self.debug("Detaching kernel driver")
|
||||
self.device.detach_kernel_driver(self.interface)
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
self.debug(str(e))
|
||||
|
||||
usb.util.claim_interface(self.device, self.interface)
|
||||
if ep_out == -1:
|
||||
|
@ -282,29 +286,44 @@ class UsbClass(metaclass=LogBase):
|
|||
self.device.attach_kernel_driver(0)
|
||||
if reset:
|
||||
self.device.reset()
|
||||
except: # pylint: disable=broad-except
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
self.debug(str(e))
|
||||
pass
|
||||
del self.device
|
||||
|
||||
def write(self, command, pktsize=64):
|
||||
def write(self, command):
|
||||
pktsize=self.EP_OUT.wMaxPacketSize
|
||||
if isinstance(command, str):
|
||||
command = bytes(command, 'utf-8')
|
||||
pos = 0
|
||||
if command == b'':
|
||||
self.device.write(self.EP_OUT, b'')
|
||||
try:
|
||||
self.EP_OUT.write(b'')
|
||||
except usb.core.USBError as e:
|
||||
error = str(e.strerror)
|
||||
if "timeout" in error:
|
||||
time.sleep(0.01)
|
||||
try:
|
||||
self.EP_OUT.write(b'')
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
self.debug(str(e))
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
i = 0
|
||||
while pos < len(command):
|
||||
try:
|
||||
self.device.write(self.EP_OUT, command[pos:pos + pktsize])
|
||||
pos += pktsize
|
||||
except: # pylint: disable=broad-except
|
||||
# print("Error while writing")
|
||||
time.sleep(0.05)
|
||||
try:
|
||||
[self.EP_OUT.write(command[pos:pos+pktsize]) for pos in range(0,len(command),pktsize)]
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
# print("Error while writing")
|
||||
if "timed out" in str(e):
|
||||
self.debug(str(e))
|
||||
time.sleep(0.01)
|
||||
i += 1
|
||||
if i == 5:
|
||||
if i == 3:
|
||||
return False
|
||||
pass
|
||||
else:
|
||||
self.error(str(e))
|
||||
return False
|
||||
self.verify_data(bytearray(command), "TX:")
|
||||
return True
|
||||
|
||||
|
@ -315,7 +334,7 @@ class UsbClass(metaclass=LogBase):
|
|||
timeout = self.timeout
|
||||
while bytearray(tmp) == b'':
|
||||
try:
|
||||
tmp = self.device.read(self.EP_IN, length, timeout)
|
||||
tmp = self.EP_IN.read(length, timeout)
|
||||
except usb.core.USBError as e:
|
||||
error = str(e.strerror)
|
||||
if "timed out" in error:
|
||||
|
|
Loading…
Reference in a new issue