From b259e2ae912e9f5b884ca2b152d9da085c605057 Mon Sep 17 00:00:00 2001 From: George Hotz Date: Sat, 10 Mar 2018 11:22:22 -0800 Subject: [PATCH] can flasher is close to working --- board/spi_flasher.h | 4 +- python/__init__.py | 95 +++++++++++++++++++--------------- tests/pedal/enter_canloader.py | 38 +++++++++++++- 3 files changed, 93 insertions(+), 44 deletions(-) diff --git a/board/spi_flasher.h b/board/spi_flasher.h index e258337..081a5c1 100644 --- a/board/spi_flasher.h +++ b/board/spi_flasher.h @@ -204,11 +204,11 @@ void CAN1_RX0_IRQHandler() { // send initial if (isotp_buf_out_remain <= 7) { odat[0] = isotp_buf_out_remain; - //memcpy(odat+1, isotp_buf_out_ptr, isotp_buf_out_remain); + memcpy(odat+1, isotp_buf_out_ptr, isotp_buf_out_remain); } else { odat[0] = 0x10 | (isotp_buf_out_remain>>8); odat[1] = isotp_buf_out_remain & 0xFF; - //memcpy(odat+2, isotp_buf_out_ptr, 6); + memcpy(odat+2, isotp_buf_out_ptr, 6); isotp_buf_out_remain -= 6; isotp_buf_out_ptr += 6; isotp_buf_out_idx++; diff --git a/python/__init__.py b/python/__init__.py index 0b7a064..5b37bf3 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -170,7 +170,7 @@ class Panda(object): assert(self._handle != None) print("connected") - def reset(self, enter_bootstub=False, enter_bootloader=False, reconnect=True): + def reset(self, enter_bootstub=False, enter_bootloader=False): # reset try: if enter_bootloader: @@ -183,27 +183,56 @@ class Panda(object): except Exception: pass if not enter_bootloader: - self.close() - if reconnect == False: - return - time.sleep(1.0) - success = False - # wait up to 15 seconds - for i in range(0, 15): + self.reconnect() + + 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: - self.connect() - success = True - break + dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial)) + dfu.recover() 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") + 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: @@ -228,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=reconnect) + # reconnect + if reconnect: + self.reconnect() def recover(self): self.reset(enter_bootloader=True) diff --git a/tests/pedal/enter_canloader.py b/tests/pedal/enter_canloader.py index 74efd56..9f16c1f 100755 --- a/tests/pedal/enter_canloader.py +++ b/tests/pedal/enter_canloader.py @@ -1,7 +1,38 @@ #!/usr/bin/env python import sys +import struct import argparse from panda import Panda +import time + +class CanHandle(object): + def __init__(self, p): + self.p = p + + def transact(self, dat): + print "W:",dat.encode("hex") + self.p.isotp_send(1, dat, 0, recvaddr=2) + ret = self.p.isotp_recv(2, 0, sendaddr=1) + print "R:",ret.encode("hex") + return ret + + def controlWrite(self, request_type, request, value, index, data, timeout=0): + # ignore data in reply, panda doesn't use it + return self.controlRead(request_type, request, value, index, 0, timeout) + + def controlRead(self, request_type, request, value, index, length, timeout=0): + dat = struct.pack("HHBBHHH", 0, 0, request_type, request, value, index, length) + return self.transact(dat) + + def bulkWrite(self, endpoint, data, timeout=0): + if len(data) > 0x10: + raise ValueError("Data must not be longer than 0x10") + dat = struct.pack("HH", endpoint, len(data))+data + return self.transact(dat) + + def bulkRead(self, endpoint, length, timeout=0): + dat = struct.pack("HH", endpoint, 0) + return self.transact(dat) if __name__ == "__main__": parser = argparse.ArgumentParser(description='Flash pedal over can') @@ -12,6 +43,10 @@ if __name__ == "__main__": p = Panda() p.set_safety_mode(0x1337) + while 1: + if len(p.can_recv()) == 0: + break + if args.recover: p.can_send(0x200, "\xce\xfa\xad\xde\x1e\x0b\xb0\x02", 0) exit(0) @@ -20,6 +55,7 @@ if __name__ == "__main__": if args.fn: print "flashing", args.fn - + code = open(args.fn).read() + Panda.flash_static(CanHandle(p), code)