mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-02-23 17:33:55 +08:00
@@ -13,8 +13,9 @@ from esptool import ESPROM, CesantaFlasher
|
||||
from flash_release import flash_release
|
||||
from update import ensure_st_up_to_date
|
||||
from serial import PandaSerial
|
||||
from isotp import isotp_send, isotp_recv
|
||||
|
||||
__version__ = '0.0.6'
|
||||
__version__ = '0.0.7'
|
||||
|
||||
BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")
|
||||
|
||||
@@ -104,6 +105,7 @@ class Panda(object):
|
||||
SAFETY_NOOUTPUT = 0
|
||||
SAFETY_HONDA = 1
|
||||
SAFETY_TOYOTA = 2
|
||||
SAFETY_HONDA_BOSCH = 4
|
||||
SAFETY_TOYOTA_NOLIMITS = 0x1336
|
||||
SAFETY_ALLOUTPUT = 0x1337
|
||||
SAFETY_ELM327 = 0xE327
|
||||
@@ -181,27 +183,58 @@ class Panda(object):
|
||||
except Exception:
|
||||
pass
|
||||
if not enter_bootloader:
|
||||
self.close()
|
||||
time.sleep(1.0)
|
||||
success = False
|
||||
# wait up to 15 seconds
|
||||
for i in range(0, 15):
|
||||
try:
|
||||
self.connect()
|
||||
success = True
|
||||
break
|
||||
except Exception:
|
||||
print("reconnecting is taking %d seconds..." % (i+1))
|
||||
try:
|
||||
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial))
|
||||
dfu.recover()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(1.0)
|
||||
if not success:
|
||||
raise Exception("reset failed")
|
||||
self.reconnect()
|
||||
|
||||
def flash(self, fn=None, code=None):
|
||||
def reconnect(self):
|
||||
self.close()
|
||||
time.sleep(1.0)
|
||||
success = False
|
||||
# wait up to 15 seconds
|
||||
for i in range(0, 15):
|
||||
try:
|
||||
self.connect()
|
||||
success = True
|
||||
break
|
||||
except Exception:
|
||||
print("reconnecting is taking %d seconds..." % (i+1))
|
||||
try:
|
||||
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial))
|
||||
dfu.recover()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(1.0)
|
||||
if not success:
|
||||
raise Exception("reconnect failed")
|
||||
|
||||
@staticmethod
|
||||
def flash_static(handle, code):
|
||||
# confirm flasher is present
|
||||
fr = handle.controlRead(Panda.REQUEST_IN, 0xb0, 0, 0, 0xc)
|
||||
assert fr[4:8] == "\xde\xad\xd0\x0d"
|
||||
|
||||
# unlock flash
|
||||
print("flash: unlocking")
|
||||
handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'')
|
||||
|
||||
# erase sectors 1 and 2
|
||||
print("flash: erasing")
|
||||
handle.controlWrite(Panda.REQUEST_IN, 0xb2, 1, 0, b'')
|
||||
handle.controlWrite(Panda.REQUEST_IN, 0xb2, 2, 0, b'')
|
||||
|
||||
# flash over EP2
|
||||
STEP = 0x10
|
||||
print("flash: flashing")
|
||||
for i in range(0, len(code), STEP):
|
||||
handle.bulkWrite(2, code[i:i+STEP])
|
||||
|
||||
# reset
|
||||
print("flash: resetting")
|
||||
try:
|
||||
handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def flash(self, fn=None, code=None, reconnect=True):
|
||||
if not self.bootstub:
|
||||
self.reset(enter_bootstub=True)
|
||||
assert(self.bootstub)
|
||||
@@ -224,28 +257,12 @@ class Panda(object):
|
||||
# get version
|
||||
print("flash: version is "+self.get_version())
|
||||
|
||||
# confirm flasher is present
|
||||
fr = self._handle.controlRead(Panda.REQUEST_IN, 0xb0, 0, 0, 0xc)
|
||||
assert fr[4:8] == "\xde\xad\xd0\x0d"
|
||||
# do flash
|
||||
Panda.flash_static(self._handle, code)
|
||||
|
||||
# unlock flash
|
||||
print("flash: unlocking")
|
||||
self._handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'')
|
||||
|
||||
# erase sectors 1 and 2
|
||||
print("flash: erasing")
|
||||
self._handle.controlWrite(Panda.REQUEST_IN, 0xb2, 1, 0, b'')
|
||||
self._handle.controlWrite(Panda.REQUEST_IN, 0xb2, 2, 0, b'')
|
||||
|
||||
# flash over EP2
|
||||
STEP = 0x10
|
||||
print("flash: flashing")
|
||||
for i in range(0, len(code), STEP):
|
||||
self._handle.bulkWrite(2, code[i:i+STEP])
|
||||
|
||||
# reset
|
||||
print("flash: resetting")
|
||||
self.reset()
|
||||
# reconnect
|
||||
if reconnect:
|
||||
self.reconnect()
|
||||
|
||||
def recover(self):
|
||||
self.reset(enter_bootloader=True)
|
||||
@@ -315,6 +332,10 @@ class Panda(object):
|
||||
def get_version(self):
|
||||
return self._handle.controlRead(Panda.REQUEST_IN, 0xd6, 0, 0, 0x40)
|
||||
|
||||
def is_grey(self):
|
||||
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40)
|
||||
return ret == "\x01"
|
||||
|
||||
def get_serial(self):
|
||||
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 0, 0, 0x20)
|
||||
hashsig, calc_hash = dat[0x1c:], hashlib.sha1(dat[0:0x1c]).digest()[0:4]
|
||||
@@ -420,6 +441,14 @@ class Panda(object):
|
||||
"""
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf1, bus, 0, b'')
|
||||
|
||||
# ******************* isotp *******************
|
||||
|
||||
def isotp_send(self, addr, dat, bus, recvaddr=None, subaddr=None):
|
||||
return isotp_send(self, dat, addr, bus, recvaddr, subaddr)
|
||||
|
||||
def isotp_recv(self, addr, bus=0, sendaddr=None, subaddr=None):
|
||||
return isotp_recv(self, addr, bus, sendaddr, subaddr)
|
||||
|
||||
# ******************* serial *******************
|
||||
|
||||
def serial_read(self, port_number):
|
||||
@@ -451,7 +480,11 @@ class Panda(object):
|
||||
|
||||
# pulse low for wakeup
|
||||
def kline_wakeup(self):
|
||||
if DEBUG:
|
||||
print("kline wakeup...")
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf0, 0, 0, b'')
|
||||
if DEBUG:
|
||||
print("kline wakeup done")
|
||||
|
||||
def kline_drain(self, bus=2):
|
||||
# drain buffer
|
||||
@@ -460,19 +493,25 @@ class Panda(object):
|
||||
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xe0, bus, 0, 0x40)
|
||||
if len(ret) == 0:
|
||||
break
|
||||
elif DEBUG:
|
||||
print("kline drain: "+str(ret).encode("hex"))
|
||||
bret += ret
|
||||
return bytes(bret)
|
||||
|
||||
def kline_ll_recv(self, cnt, bus=2):
|
||||
echo = bytearray()
|
||||
while len(echo) != cnt:
|
||||
echo += self._handle.controlRead(Panda.REQUEST_OUT, 0xe0, bus, 0, cnt-len(echo))
|
||||
return echo
|
||||
ret = str(self._handle.controlRead(Panda.REQUEST_OUT, 0xe0, bus, 0, cnt-len(echo)))
|
||||
if DEBUG and len(ret) > 0:
|
||||
print("kline recv: "+ret.encode("hex"))
|
||||
echo += ret
|
||||
return str(echo)
|
||||
|
||||
def kline_send(self, x, bus=2, checksum=True):
|
||||
def get_checksum(dat):
|
||||
result = 0
|
||||
result += sum(map(ord, dat)) if isinstance(b'dat', str) else sum(dat)
|
||||
result = -result
|
||||
return struct.pack("B", result % 0x100)
|
||||
|
||||
self.kline_drain(bus=bus)
|
||||
@@ -480,6 +519,8 @@ class Panda(object):
|
||||
x += get_checksum(x)
|
||||
for i in range(0, len(x), 0xf):
|
||||
ts = x[i:i+0xf]
|
||||
if DEBUG:
|
||||
print("kline send: "+ts.encode("hex"))
|
||||
self._handle.bulkWrite(2, chr(bus).encode()+ts)
|
||||
echo = self.kline_ll_recv(len(ts), bus=bus)
|
||||
if echo != ts:
|
||||
|
||||
Reference in New Issue
Block a user