SPI: connect by VERSION command (#1495)

* SPI: connect by VERSION command

* shorter timeout

* add exception

* simple test

* fallback

* bootstub check

* update comments

---------

Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
Adeeb Shihadeh
2023-07-16 19:33:18 -07:00
committed by GitHub
parent e8da4eab2e
commit 5d873444b2
4 changed files with 48 additions and 9 deletions

View File

@@ -17,7 +17,7 @@ from .base import BaseHandle
from .constants import FW_PATH, McuType
from .dfu import PandaDFU
from .isotp import isotp_send, isotp_recv
from .spi import PandaSpiHandle, PandaSpiException
from .spi import PandaSpiHandle, PandaSpiException, PandaProtocolMismatch
from .usb import PandaUsbHandle
__version__ = '0.0.10'
@@ -326,16 +326,30 @@ class Panda:
self.set_power_save(0)
@staticmethod
def spi_connect(serial):
def spi_connect(serial, ignore_version=False):
# get UID to confirm slave is present and up
handle = None
spi_serial = None
bootstub = None
spi_version = None
try:
handle = PandaSpiHandle()
dat = handle.controlRead(Panda.REQUEST_IN, 0xc3, 0, 0, 12, timeout=100)
spi_serial = binascii.hexlify(dat).decode()
bootstub = Panda.flasher_present(handle)
# connect by protcol version
try:
dat = handle.get_protocol_version()
spi_serial = binascii.hexlify(dat[:12]).decode()
pid = dat[13]
if pid not in (0xcc, 0xee):
raise PandaSpiException("invalid bootstub status")
bootstub = pid == 0xee
spi_version = dat[14]
except PandaSpiException:
# fallback, we'll raise a protocol mismatch below
dat = handle.controlRead(Panda.REQUEST_IN, 0xc3, 0, 0, 12, timeout=100)
spi_serial = binascii.hexlify(dat).decode()
bootstub = Panda.flasher_present(handle)
spi_version = 0
except PandaSpiException:
pass
@@ -345,6 +359,12 @@ class Panda:
spi_serial = None
bootstub = False
# ensure our protocol version matches the panda
if handle is not None and not ignore_version:
if spi_version != handle.PROTOCOL_VERSION:
err = f"panda protocol mismatch: expected {handle.PROTOCOL_VERSION}, got {spi_version}. reflash panda"
raise PandaProtocolMismatch(err)
return handle, spi_serial, bootstub, None
@staticmethod
@@ -416,7 +436,7 @@ class Panda:
@staticmethod
def spi_list():
_, serial, _, _ = Panda.spi_connect(None)
_, serial, _, _ = Panda.spi_connect(None, ignore_version=True)
if serial is not None:
return [serial, ]
return []