mirror of
https://github.com/infiniteCable2/panda.git
synced 2026-02-18 17:23:52 +08:00
SPI: add protcol version request (#1488)
* SPI: add protcol version request * quick test * fix linter * misra --------- Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
@@ -78,7 +78,31 @@ void spi_rx_done(void) {
|
||||
spi_data_len_mosi = (spi_buf_rx[3] << 8) | spi_buf_rx[2];
|
||||
spi_data_len_miso = (spi_buf_rx[5] << 8) | spi_buf_rx[4];
|
||||
|
||||
if (spi_state == SPI_STATE_HEADER) {
|
||||
if (memcmp(spi_buf_rx, "VERSION", 7) == 0) {
|
||||
// protocol version request, respond with:
|
||||
// VERSION + 2 byte data length + data + data complement
|
||||
|
||||
// echo "VERSION"
|
||||
(void)memcpy(spi_buf_tx, "VERSION", 7);
|
||||
|
||||
// write response
|
||||
uint16_t data_pos = 9;
|
||||
uint16_t data_len = 1;
|
||||
spi_buf_tx[data_pos] = 0x1;
|
||||
|
||||
// response complement
|
||||
for (uint16_t i = 0U; i < data_len; i++) {
|
||||
spi_buf_tx[data_pos + data_len + i] = spi_buf_tx[data_pos + i] ^ 0xFFU;
|
||||
}
|
||||
|
||||
// data length
|
||||
data_len *= 2U;
|
||||
spi_buf_tx[7] = data_len & 0xFFU;
|
||||
spi_buf_tx[8] = (data_len >> 8) & 0xFFU;
|
||||
|
||||
response_len = 7U + 2U + data_len;
|
||||
next_rx_state = SPI_STATE_HEADER_NACK;;
|
||||
} else if (spi_state == SPI_STATE_HEADER) {
|
||||
checksum_valid = check_checksum(spi_buf_rx, SPI_HEADER_SIZE);
|
||||
if ((spi_buf_rx[0] == SPI_SYNC_BYTE) && checksum_valid) {
|
||||
// response: ACK and start receiving data portion
|
||||
|
||||
@@ -167,6 +167,44 @@ class PandaSpiHandle(BaseHandle):
|
||||
|
||||
raise exc
|
||||
|
||||
def get_protocol_version(self) -> bytes:
|
||||
vers_str = b"VERSION"
|
||||
def _get_version(spi) -> bytes:
|
||||
spi.writebytes(vers_str)
|
||||
|
||||
logging.debug("- waiting for echo")
|
||||
start = time.monotonic()
|
||||
while True:
|
||||
r = spi.readbytes(len(vers_str))
|
||||
if bytes(r) == vers_str:
|
||||
break
|
||||
if (time.monotonic() - start) > 0.5:
|
||||
raise PandaSpiException("timed out waiting for version echo")
|
||||
|
||||
# get response
|
||||
logging.debug("- receiving response")
|
||||
b = bytes(spi.readbytes(2))
|
||||
rlen = struct.unpack("<H", b)[0]
|
||||
if rlen > 1000:
|
||||
raise PandaSpiException("response length greater than max")
|
||||
|
||||
dat = bytes(spi.readbytes(rlen))
|
||||
resp = dat[:rlen//2]
|
||||
resp_comp = dat[rlen//2:]
|
||||
if resp != bytes([x ^ 0xff for x in resp_comp]):
|
||||
raise PandaSpiException("data complement doesn't match")
|
||||
return resp
|
||||
|
||||
exc = PandaSpiException()
|
||||
with self.dev.acquire() as spi:
|
||||
for _ in range(10):
|
||||
try:
|
||||
return _get_version(spi)
|
||||
except PandaSpiException as e:
|
||||
exc = e
|
||||
logging.debug("SPI get protocol version failed, retrying", exc_info=True)
|
||||
raise exc
|
||||
|
||||
# libusb1 functions
|
||||
def close(self):
|
||||
self.dev.close()
|
||||
|
||||
@@ -17,6 +17,10 @@ class TestSpi:
|
||||
assert spy.call_count == 2
|
||||
mocker.stop(spy)
|
||||
|
||||
def test_protocol_version(self, p):
|
||||
v = p._handle.get_protocol_version()
|
||||
assert v == b"\x01"
|
||||
|
||||
def test_all_comm_types(self, mocker, p):
|
||||
spy = mocker.spy(p._handle, '_wait_for_ack')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user