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 hashlib import sha256
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from os.path import isfile
from threading import Thread
from struct import unpack, pack
from tls97 import tls from tls97 import tls
from usb97 import usb from usb97 import usb
from time import ctime from time import ctime
from sensor import write_hw_reg32, read_hw_reg32, identify_sensor 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 util import assert_status
from blobs import calibrate_prg from blobs import calibrate_prg
@ -24,7 +27,7 @@ if read_hw_reg32(0x80002080) != 2:
dev=identify_sensor() dev=identify_sensor()
print('Sensor: %s' % dev.name) 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) fwi=get_fw_info(2)
if fwi == None: 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))) 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)
# >>> 6f 000e 000000000000 if isfile('calib-data.bin'):
# <<< 0000 880d 0000 07000000 with open('calib-data.bin', 'rb') as f:
# 0800 0000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180818081808180818081808180808081808180808081807f80808180808081808180818080808180818081808180818081808080818081808180818081808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e calib_data=f.read()
# a400 0000 0800 0e00 0200 0000 00000000 0d007100 print('Calibration data loaded from a file.')
# b400 0000 0800 0e00 0800 0080 db000000 00000000 else:
# c400 0000 0400 0e00 0500 0080 1c6f0400 # TODO Properly construct calibrate_prg.
# d000 0000 9400 0e00 0700 0080 07000000 2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e202024201f1e20201f212221221d221e23341e1d1e1d20341f1d193b341c1d1e35201e201c20221f341c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1f1e1e341c321e3220301d2d302f2d2c2b23223a211c # >>> 6f 000e 000000000000
# 6c01 0000 1400 0e00 0f00 0080 05550007 7701002805720000080100020811e107 # <<< 0000 880d 0000 07000000
# 8801 0000 0c00 0e00 1200 0080 07000000 7002780070027800 # 0800 0000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180818081808180818081808180808081808180808081807f80808180808081808180818080808180818081808180818081808080818081808180818081808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
# # a400 0000 0800 0e00 0200 0000 00000000 0d007100
# Empty reply: # b400 0000 0800 0e00 0800 0080 db000000 00000000
# >>> 6f 000a 000000000000 # c400 0000 0400 0e00 0500 0080 1c6f0400
# <<< 0000 880d 0000 00000000 # 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
rsp=tls.cmd(calibrate_prg) #Thread(target=wait_82).start()
assert_status(rsp)
print(rsp.hex())
# ^ check what the rest of the rsp means, how the calibrate_prg is constructed/selected, etc
buf=usb.read_82() rsp=tls.cmd(calibrate_prg)
assert_status(rsp)
print(rsp.hex())
# ^ TODO check what the rest of the rsp means
print(sha256(buf).digest().hex()) calib_data=usb.read_82()
print('len=%d' % len(calib_data))
with open('calib-data.bin', 'wb') as f:
f.write(calib_data)
# >>> read_flash(6, 0, 0x44) class Line():
# <<< ffff... 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:]
# >>> write_flash_all(6, 0, buf) def serialize(self):
return pack('<BBBBBBBB', self.u0, self.u1, self.line, self.frame, self.u2, self.u3, self.u4, self.u5) + self.data
def __repr__(self):
return 'Line(line=%d, frame=%d)' % (self.line, self.frame)
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 util import assert_status
from struct import pack, unpack from struct import pack, unpack
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from blobs import db_write_enable
from flash import flush_changes
from sid import * from sid import *
class UserStorage(): class UserStorage():
@ -117,25 +119,22 @@ class DbRecord():
class Db(): class Db():
def __init__(self, tls):
self.tls = tls
def get_user_storage(self, dbid=0, name=''): def get_user_storage(self, dbid=0, name=''):
name=name.encode() name=name.encode()
if len(name) > 0: if len(name) > 0:
name += b'\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): 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): def lookup_user(self, identity):
stg = self.get_user_storage(name='StgWindsor') stg = self.get_user_storage(name='StgWindsor')
data = identity_to_bytes(identity) 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]) rc, = unpack('<H', rsp[:2])
if rc == 0x04b3: if rc == 0x04b3:
@ -144,7 +143,7 @@ class Db():
return parse_user(rsp) return parse_user(rsp)
def get_record_value(self, dbid): def get_record_value(self, dbid):
rsp = self.tls.cmd(pack('<BH', 0x49, dbid)) rsp = tls.cmd(pack('<BH', 0x49, dbid))
assert_status(rsp) assert_status(rsp)
rec = DbRecord() rec = DbRecord()
@ -154,7 +153,7 @@ class Db():
return rec return rec
def get_record_children(self, dbid): def get_record_children(self, dbid):
rsp = self.tls.cmd(pack('<BH', 0x46, dbid)) rsp = tls.cmd(pack('<BH', 0x46, dbid))
assert_status(rsp) assert_status(rsp)
rec = DbRecord() rec = DbRecord()
@ -168,16 +167,16 @@ class Db():
return rec return rec
def del_record(self, dbid): 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): def new_record(self, parent, typ, storage, data):
assert_status(self.tls.cmd(b'\x45')) assert_status(tls.cmd(b'\x45'))
assert_status(self.tls.cmd(db_write_enable)) assert_status(tls.cmd(db_write_enable))
rsp = self.tls.cmd(pack('<BHHHH', 0x47, parent, typ, storage, len(data)) + data) rsp = tls.cmd(pack('<BHHHH', 0x47, parent, typ, storage, len(data)) + data)
assert_status(rsp) assert_status(rsp)
recid, = unpack('<H', rsp[2:]) recid, = unpack('<H', rsp[2:])
self.flush_changes() flush_changes()
return recid return recid
def new_user(self, identity): def new_user(self, identity):
@ -208,5 +207,5 @@ class Db():
for f in u.fingers: for f in u.fingers:
print(' %2d: %02x (%s)' % (f['dbid'], f['subtype'], subtype_to_string(f['subtype']))) 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 tls97 import tls
from usb97 import usb
from db97 import db, subtype_to_string
from time import sleep
from struct import pack, unpack from struct import pack, unpack
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from util import assert_status, unhex from util import assert_status, unhex
from hw_tables import dev_info_lookup from hw_tables import dev_info_lookup
from blobs import identify_prg, enroll_prg
def glow_start_scan(): def glow_start_scan():

View file

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