diff --git a/selfdrive/pandad/pandad b/selfdrive/pandad/pandad index a4e6611b2..9c793bed6 100755 Binary files a/selfdrive/pandad/pandad and b/selfdrive/pandad/pandad differ diff --git a/selfdrive/pandad/spi.cc b/selfdrive/pandad/spi.cc index b6ee57801..021c27c56 100644 --- a/selfdrive/pandad/spi.cc +++ b/selfdrive/pandad/spi.cc @@ -30,6 +30,12 @@ enum SpiError { const unsigned int SPI_ACK_TIMEOUT = 500; // milliseconds const std::string SPI_DEVICE = "/dev/spidev0.0"; +// TODO: fix SPI turnaround synchronization at the protocol level. +static uint64_t spi_last_bus_activity_ns = 0; // protected by hw_lock + +static void wait_for_spi_turnaround(uint64_t start_ns) { + while ((nanos_since_boot() - start_ns) < 400000) {} +} class LockEx { public: @@ -320,6 +326,8 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx assert(tx_len < SPI_BUF_SIZE); assert(max_rx_len < SPI_BUF_SIZE); + wait_for_spi_turnaround(spi_last_bus_activity_ns); + xfer_count++; header = { .sync = SPI_SYNC, @@ -342,6 +350,7 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx SPILOG(LOGE, "SPI: failed to send header"); goto fail; } + wait_for_spi_turnaround(nanos_since_boot()); // Wait for (N)ACK ret = wait_for_ack(SPI_HACK, 0x11, timeout, 1); @@ -390,6 +399,7 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx memcpy(rx_data, rx_buf + 3, rx_data_len); } + spi_last_bus_activity_ns = nanos_since_boot(); return rx_data_len; fail: @@ -404,6 +414,7 @@ fail: } } + spi_last_bus_activity_ns = nanos_since_boot(); if (ret >= 0) ret = -1; return ret; }