add st updater
parent
36a259855e
commit
22a00b1043
|
@ -1 +1 @@
|
|||
from .panda import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release
|
||||
from .panda import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release, BASEDIR, ensure_st_up_to_date, build_st
|
||||
|
|
|
@ -27,7 +27,7 @@ bin: obj/$(PROJ_NAME).bin
|
|||
# this flashes everything
|
||||
recover: obj/bootstub.$(PROJ_NAME).bin obj/$(PROJ_NAME).bin
|
||||
-PYTHONPATH=../ python -c "from panda import Panda; Panda().reset(enter_bootloader=True)"
|
||||
sleep 2.0
|
||||
sleep 1.0
|
||||
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
|
||||
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.$(PROJ_NAME).bin
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import traceback
|
|||
from dfu import PandaDFU
|
||||
from esptool import ESPROM, CesantaFlasher
|
||||
from flash_release import flash_release
|
||||
from update import ensure_st_up_to_date
|
||||
|
||||
__version__ = '0.0.4'
|
||||
|
||||
|
@ -18,6 +19,10 @@ BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")
|
|||
|
||||
# *** wifi mode ***
|
||||
|
||||
def build_st(target, mkfile="Makefile"):
|
||||
from panda import BASEDIR
|
||||
assert(os.system('cd %s && make -f %s clean && make -f %s %s >/dev/null' % (os.path.join(BASEDIR, "board"), mkfile, mkfile, target)) == 0)
|
||||
|
||||
def parse_can_buffer(dat):
|
||||
ret = []
|
||||
for j in range(0, len(dat), 0x10):
|
||||
|
@ -133,7 +138,8 @@ class Panda(object):
|
|||
#print(device)
|
||||
if device.getVendorID() == 0xbbaa and device.getProductID() in [0xddcc, 0xddee]:
|
||||
if self._serial is None or device.getSerialNumber() == self._serial:
|
||||
print("opening device", device.getSerialNumber(), hex(device.getProductID()))
|
||||
self._serial = device.getSerialNumber()
|
||||
print("opening device", self._serial, hex(device.getProductID()))
|
||||
self.bootstub = device.getProductID() == 0xddee
|
||||
self.legacy = (device.getbcdDevice() != 0x2300)
|
||||
self._handle = device.open()
|
||||
|
@ -175,17 +181,21 @@ class Panda(object):
|
|||
raise Exception("reset failed")
|
||||
time.sleep(1.0)
|
||||
|
||||
|
||||
def flash(self, fn=None, code=None):
|
||||
if not self.bootstub:
|
||||
self.reset(enter_bootstub=True)
|
||||
assert(self.bootstub)
|
||||
|
||||
if fn is None and code is None:
|
||||
ret = os.system("cd %s && make clean && make -f %s %s" % (os.path.join(BASEDIR, "board"),
|
||||
"Makefile.legacy" if self.legacy else "Makefile",
|
||||
"obj/comma.bin" if self.legacy else "obj/panda.bin"))
|
||||
fn = os.path.join(BASEDIR, "board", "obj", "comma.bin" if self.legacy else "panda.bin")
|
||||
if self.legacy:
|
||||
fn = "obj/comma.bin"
|
||||
print("building legacy st code")
|
||||
build_st(fn, "Makefile.legacy")
|
||||
else:
|
||||
fn = "obj/panda.bin"
|
||||
print("building panda st code")
|
||||
build_st(fn)
|
||||
fn = os.path.join(BASEDIR, "board", fn)
|
||||
|
||||
if code is None:
|
||||
with open(fn) as f:
|
||||
|
@ -217,6 +227,19 @@ class Panda(object):
|
|||
print("flash: resetting")
|
||||
self.reset()
|
||||
|
||||
def recover(self):
|
||||
self.reset(enter_bootloader=True)
|
||||
while len(PandaDFU.list()) == 0:
|
||||
print("waiting for DFU...")
|
||||
time.sleep(0.1)
|
||||
|
||||
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial))
|
||||
dfu.recover()
|
||||
|
||||
# reflash after recover
|
||||
self.connect(True, True)
|
||||
self.flash()
|
||||
|
||||
@staticmethod
|
||||
def flash_ota_st():
|
||||
ret = os.system("cd %s && make clean && make ota" % (os.path.join(BASEDIR, "board")))
|
||||
|
@ -229,12 +252,6 @@ class Panda(object):
|
|||
time.sleep(1)
|
||||
return ret==0
|
||||
|
||||
@staticmethod
|
||||
def recover(legacy=False):
|
||||
ret = os.system("cd %s && make clean && make -f %s recover" % (os.path.join(BASEDIR, "board"), "Makefile.legacy" if legacy else "Makefile"))
|
||||
time.sleep(1)
|
||||
return ret==0
|
||||
|
||||
@staticmethod
|
||||
def list():
|
||||
context = usb1.USBContext()
|
||||
|
|
27
panda/dfu.py
27
panda/dfu.py
|
@ -1,6 +1,8 @@
|
|||
from __future__ import print_function
|
||||
import os
|
||||
import usb1
|
||||
import struct
|
||||
import time
|
||||
|
||||
# *** DFU mode ***
|
||||
|
||||
|
@ -21,6 +23,7 @@ class PandaDFU(object):
|
|||
pass
|
||||
if this_dfu_serial == dfu_serial:
|
||||
self._handle = device.open()
|
||||
self.legacy = "07*128Kg" in self._handle.getASCIIStringDescriptor(4)
|
||||
return
|
||||
raise Exception("failed to open "+dfu_serial)
|
||||
|
||||
|
@ -78,6 +81,30 @@ class PandaDFU(object):
|
|||
self._handle.controlWrite(0x21, DFU_DNLOAD, 2+i, 0, ldat)
|
||||
self.status()
|
||||
|
||||
def program_bootstub(self, code_bootstub):
|
||||
self.clear_status()
|
||||
self.erase(0x8004000)
|
||||
self.erase(0x8000000)
|
||||
self.program(0x8000000, code_bootstub, 0x800)
|
||||
self.reset()
|
||||
|
||||
def recover(self):
|
||||
from panda import BASEDIR, build_st
|
||||
if self.legacy:
|
||||
fn = "obj/bootstub.comma.bin"
|
||||
print("building legacy bootstub")
|
||||
build_st(fn, "Makefile.legacy")
|
||||
else:
|
||||
fn = "obj/bootstub.panda.bin"
|
||||
print("building panda bootstub")
|
||||
build_st(fn)
|
||||
fn = os.path.join(BASEDIR, "board", fn)
|
||||
|
||||
with open(fn) as f:
|
||||
code = f.read()
|
||||
|
||||
self.program_bootstub(code)
|
||||
|
||||
def reset(self):
|
||||
# **** Reset ****
|
||||
self._handle.controlWrite(0x21, DFU_DNLOAD, 0, 0, "\x21" + struct.pack("I", 0x8000000))
|
||||
|
|
|
@ -55,11 +55,7 @@ def flash_release(path=None, st_serial=None):
|
|||
# program bootstub
|
||||
status("2. Programming bootstub")
|
||||
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(st_serial))
|
||||
dfu.clear_status()
|
||||
dfu.erase(0x8004000)
|
||||
dfu.erase(0x8000000)
|
||||
dfu.program(0x8000000, code_bootstub, 0x800)
|
||||
dfu.reset()
|
||||
dfu.program_bootstub(code_bootstub)
|
||||
time.sleep(1)
|
||||
|
||||
# flash main code
|
||||
|
@ -67,7 +63,6 @@ def flash_release(path=None, st_serial=None):
|
|||
panda = Panda(st_serial)
|
||||
panda.flash(code=code_panda)
|
||||
panda.close()
|
||||
time.sleep(1)
|
||||
|
||||
# flashing ESP
|
||||
status("4. Flashing ESP (slow!)")
|
||||
|
@ -98,5 +93,3 @@ def flash_release(path=None, st_serial=None):
|
|||
if __name__ == "__main__":
|
||||
flash_release(*sys.argv[1:])
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import time
|
||||
|
||||
def ensure_st_up_to_date():
|
||||
from panda import Panda, PandaDFU, BASEDIR
|
||||
|
||||
with open(os.path.join(BASEDIR, "VERSION")) as f:
|
||||
repo_version = f.read()
|
||||
|
||||
panda = None
|
||||
panda_dfu = None
|
||||
should_flash_recover = False
|
||||
|
||||
while 1:
|
||||
# break on normal mode Panda
|
||||
panda_list = Panda.list()
|
||||
if len(panda_list) > 0:
|
||||
panda = Panda(panda_list[0])
|
||||
break
|
||||
|
||||
# flash on DFU mode Panda
|
||||
panda_dfu = PandaDFU.list()
|
||||
if len(panda_dfu) > 0:
|
||||
panda_dfu = PandaDFU(panda_dfu[0])
|
||||
panda_dfu.recover()
|
||||
|
||||
print "waiting for board..."
|
||||
time.sleep(1)
|
||||
|
||||
if panda.bootstub or not panda.get_version().startswith(repo_version):
|
||||
panda.flash()
|
||||
|
||||
if panda.bootstub:
|
||||
panda.recover()
|
||||
|
||||
assert(not panda.bootstub)
|
||||
version = str(panda.get_version())
|
||||
print("%s should be %s" % (version, repo_version))
|
||||
assert(version.startswith(repo_version))
|
||||
|
||||
if __name__ == "__main__":
|
||||
ensure_st_up_to_date()
|
||||
|
|
@ -1,19 +1,15 @@
|
|||
import os
|
||||
|
||||
BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")
|
||||
|
||||
def build(target, mkfile="Makefile"):
|
||||
assert(os.system('cd %s && make -f %s clean && make -f %s %s >/dev/null' % (os.path.join(BASEDIR, "../board"), mkfile, mkfile, target)) == 0)
|
||||
from panda import build_st
|
||||
|
||||
def test_build_legacy():
|
||||
build("obj/comma.bin", "Makefile.legacy")
|
||||
build_st("obj/comma.bin", "Makefile.legacy")
|
||||
|
||||
def test_build_bootstub_legacy():
|
||||
build("obj/bootstub.comma.bin", "Makefile.legacy")
|
||||
build_st("obj/bootstub.comma.bin", "Makefile.legacy")
|
||||
|
||||
def test_build_panda():
|
||||
build("obj/panda.bin")
|
||||
build_st("obj/panda.bin")
|
||||
|
||||
def test_build_bootstub_panda():
|
||||
build("obj/bootstub.panda.bin")
|
||||
build_st("obj/bootstub.panda.bin")
|
||||
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
import os
|
||||
from panda import Panda
|
||||
|
||||
LEGACY = os.getenv("LEGACY") is not None
|
||||
|
||||
# must run first
|
||||
def test_recover():
|
||||
# download the latest code
|
||||
assert(Panda.recover(legacy=LEGACY))
|
||||
|
||||
# connect to the panda
|
||||
p = Panda()
|
||||
p.recover()
|
||||
|
||||
def test_flash():
|
||||
p = Panda()
|
||||
p.flash()
|
||||
|
||||
|
|
Loading…
Reference in New Issue