A bit more refactoring. Calibration now works (sort of).

This commit is contained in:
Viktor Dragomiretskyy 2019-06-29 18:15:35 +12:00
parent bf2a590813
commit c5c3912506
4 changed files with 88 additions and 39 deletions

View file

@ -1,12 +1,15 @@
from hashlib import sha256
from binascii import hexlify, unhexlify
from os.path import isfile
from threading import Thread
from struct import unpack, pack
from tls97 import tls
from usb97 import usb
from time import ctime
from sensor import write_hw_reg32, read_hw_reg32, identify_sensor
from flash import read_flash, get_fw_info
from flash import erase_flash, read_flash, get_fw_info, write_flash_all
from util import assert_status
from blobs import calibrate_prg
@ -24,7 +27,7 @@ if read_hw_reg32(0x80002080) != 2:
dev=identify_sensor()
print('Sensor: %s' % dev.name)
# ^ TODO -- what is the real reason to detect HW at this stage?
# ^ TODO -- what is the real reason to detect HW at this stage? -- likely it is required to construct calibrate_prg
fwi=get_fw_info(2)
if fwi == None:
@ -32,33 +35,76 @@ if fwi == None:
print('FWExt version %d.%d (%s), %d modules' % (fwi.major, fwi.minor, ctime(fwi.buildtime), len(fwi.modules)))
def wait_82():
calib_data=usb.read_82()
print('len=%d' % len(calib_data))
with open('calib-data.bin', 'wb') as f:
f.write(calib_data)
if isfile('calib-data.bin'):
with open('calib-data.bin', 'rb') as f:
calib_data=f.read()
print('Calibration data loaded from a file.')
else:
# TODO Properly construct calibrate_prg.
# >>> 6f 000e 000000000000
# <<< 0000 880d 0000 07000000
# 0800 0000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180818081808180818081808180808081808180808081807f80808180808081808180818080808180818081808180818081808080818081808180818081808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
# a400 0000 0800 0e00 0200 0000 00000000 0d007100
# b400 0000 0800 0e00 0800 0080 db000000 00000000
# c400 0000 0400 0e00 0500 0080 1c6f0400
# d000 0000 9400 0e00 0700 0080 07000000 2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e202024201f1e20201f212221221d221e23341e1d1e1d20341f1d193b341c1d1e35201e201c20221f341c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1f1e1e341c321e3220301d2d302f2d2c2b23223a211c
# 6c01 0000 1400 0e00 0f00 0080 05550007 7701002805720000080100020811e107
# 8801 0000 0c00 0e00 1200 0080 07000000 7002 7800 7002 7800
#
# Empty reply:
# >>> 6f 000a 000000000000
# <<< 0000 880d 0000 00000000
# >>> 6f 000e 000000000000
# <<< 0000 880d 0000 07000000
# 0800 0000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180818081808180818081808180808081808180808081807f80808180808081808180818080808180818081808180818081808080818081808180818081808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
# a400 0000 0800 0e00 0200 0000 00000000 0d007100
# b400 0000 0800 0e00 0800 0080 db000000 00000000
# c400 0000 0400 0e00 0500 0080 1c6f0400
# d000 0000 9400 0e00 0700 0080 07000000 2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e202024201f1e20201f212221221d221e23341e1d1e1d20341f1d193b341c1d1e35201e201c20221f341c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1f1e1e341c321e3220301d2d302f2d2c2b23223a211c
# 6c01 0000 1400 0e00 0f00 0080 05550007 7701002805720000080100020811e107
# 8801 0000 0c00 0e00 1200 0080 07000000 7002780070027800
#
# Empty reply:
# >>> 6f 000a 000000000000
# <<< 0000 880d 0000 00000000
#Thread(target=wait_82).start()
rsp=tls.cmd(calibrate_prg)
assert_status(rsp)
print(rsp.hex())
# ^ TODO check what the rest of the rsp means
rsp=tls.cmd(calibrate_prg)
assert_status(rsp)
print(rsp.hex())
# ^ check what the rest of the rsp means, how the calibrate_prg is constructed/selected, etc
calib_data=usb.read_82()
print('len=%d' % len(calib_data))
with open('calib-data.bin', 'wb') as f:
f.write(calib_data)
buf=usb.read_82()
class Line():
def __init__(self, blob):
# what's with the rest of fields?
self.u0, self.u1, self.line, self.frame, self.u2, self.u3, self.u4, self.u5 = unpack('<BBBBBBBB', blob[:8])
self.data = blob[8:]
print(sha256(buf).digest().hex())
def serialize(self):
return pack('<BBBBBBBB', self.u0, self.u1, self.line, self.frame, self.u2, self.u3, self.u4, self.u5) + self.data
# >>> read_flash(6, 0, 0x44)
# <<< ffff...
def __repr__(self):
return 'Line(line=%d, frame=%d)' % (self.line, self.frame)
# >>> write_flash_all(6, 0, buf)
lines=[calib_data[i:i+0x90+8] for i in range(0, len(calib_data), 0x90+8)] # TODO work out where "bytes per line" constant is comming from
lines=[Line(i) for i in lines]
frame4=[i.serialize() for i in lines if i.frame == 4] # why 4?
frame4=b''.join(frame4)
calib_data=pack('<H', len(frame4)) + frame4 + pack('<H', 0) # what's that 00000 in the end?
calib_data=pack('<H', len(calib_data)) + sha256(calib_data).digest() + b'\0'*0x20 + calib_data
calib_data=unhexlify('0250') + calib_data
def persist_calib_data():
start=read_flash(6, 0, 0x44)
if start != b'\xff' * 0x44:
if calib_data[:0x44] == start:
print('Calibration data already matches the data on flash.')
return
else:
print('Calibration flash already written. Erasing.')
erase_flash(6)
write_flash_all(6, 0, calib_data)
persist_calib_data()

27
db97.py
View file

@ -4,6 +4,8 @@ from tls97 import tls
from util import assert_status
from struct import pack, unpack
from binascii import hexlify, unhexlify
from blobs import db_write_enable
from flash import flush_changes
from sid import *
class UserStorage():
@ -117,25 +119,22 @@ class DbRecord():
class Db():
def __init__(self, tls):
self.tls = tls
def get_user_storage(self, dbid=0, name=''):
name=name.encode()
if len(name) > 0:
name += b'\0'
return parse_user_storage(self.tls.cmd(pack('<BHH', 0x4b, dbid, len(name)) + name))
return parse_user_storage(tls.cmd(pack('<BHH', 0x4b, dbid, len(name)) + name))
def get_user(self, dbid):
return parse_user(self.tls.cmd(pack('<BHHH', 0x4a, dbid, 0, 0)))
return parse_user(tls.cmd(pack('<BHHH', 0x4a, dbid, 0, 0)))
def lookup_user(self, identity):
stg = self.get_user_storage(name='StgWindsor')
data = identity_to_bytes(identity)
rsp = self.tls.cmd(pack('<BHHH', 0x4a, 0, stg.dbid, len(data)) + data)
rsp = tls.cmd(pack('<BHHH', 0x4a, 0, stg.dbid, len(data)) + data)
rc, = unpack('<H', rsp[:2])
if rc == 0x04b3:
@ -144,7 +143,7 @@ class Db():
return parse_user(rsp)
def get_record_value(self, dbid):
rsp = self.tls.cmd(pack('<BH', 0x49, dbid))
rsp = tls.cmd(pack('<BH', 0x49, dbid))
assert_status(rsp)
rec = DbRecord()
@ -154,7 +153,7 @@ class Db():
return rec
def get_record_children(self, dbid):
rsp = self.tls.cmd(pack('<BH', 0x46, dbid))
rsp = tls.cmd(pack('<BH', 0x46, dbid))
assert_status(rsp)
rec = DbRecord()
@ -168,16 +167,16 @@ class Db():
return rec
def del_record(self, dbid):
assert_status(self.tls.cmd(pack('<BH', 0x48, dbid)))
assert_status(tls.cmd(pack('<BH', 0x48, dbid)))
def new_record(self, parent, typ, storage, data):
assert_status(self.tls.cmd(b'\x45'))
assert_status(self.tls.cmd(db_write_enable))
rsp = self.tls.cmd(pack('<BHHHH', 0x47, parent, typ, storage, len(data)) + data)
assert_status(tls.cmd(b'\x45'))
assert_status(tls.cmd(db_write_enable))
rsp = tls.cmd(pack('<BHHHH', 0x47, parent, typ, storage, len(data)) + data)
assert_status(rsp)
recid, = unpack('<H', rsp[2:])
self.flush_changes()
flush_changes()
return recid
def new_user(self, identity):
@ -208,5 +207,5 @@ class Db():
for f in u.fingers:
print(' %2d: %02x (%s)' % (f['dbid'], f['subtype'], subtype_to_string(f['subtype'])))
db = Db(tls)
db = Db()

View file

@ -1,9 +1,13 @@
from tls97 import tls
from usb97 import usb
from db97 import db, subtype_to_string
from time import sleep
from struct import pack, unpack
from binascii import hexlify, unhexlify
from util import assert_status, unhex
from hw_tables import dev_info_lookup
from blobs import identify_prg, enroll_prg
def glow_start_scan():

View file

@ -85,7 +85,7 @@ class Usb():
def read_82(self):
try:
resp = self.dev.read(130, 100*1024, 100)
resp = self.dev.read(130, 1024*1024, timeout=10000)
resp = bytes(resp)
self.trace('<130< %s' % hexlify(resp).decode())
return resp