boardd spi: prevent busy wait when TX buffers full (#28599)

old-commit-hash: 4c6f7b5c84
beeps
Adeeb Shihadeh 2 years ago committed by GitHub
parent 7be2b51229
commit d9f9d3caae
  1. 23
      selfdrive/boardd/spi.cc

@ -220,21 +220,31 @@ bool check_checksum(uint8_t *data, int data_len) {
int PandaSpiHandle::spi_transfer_retry(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len, unsigned int timeout) {
int ret;
int count = 0;
int nack_count = 0;
int timeout_count = 0;
bool timed_out = false;
double start_time = millis_since_boot();
do {
ret = spi_transfer(endpoint, tx_data, tx_len, rx_data, max_rx_len, timeout);
if (ret < 0) {
timed_out = (timeout != 0) && (count > 5);
count += ret == SpiError::ACK_TIMEOUT;
timed_out = (timeout != 0) && (timeout_count > 5);
timeout_count += ret == SpiError::ACK_TIMEOUT;
// give other threads a chance to run
std::this_thread::yield();
if (ret == SpiError::NACK) {
// prevent busy wait while the panda is NACK'ing
nack_count += 1;
usleep(std::clamp(nack_count*10, 200, 2000));
}
}
} while (ret < 0 && connected && !timed_out);
if (ret < 0) {
LOGE("transfer failed, after %d tries, %.2fms", count, millis_since_boot() - start_time);
LOGE("transfer failed, after %d tries, %.2fms", timeout_count, millis_since_boot() - start_time);
}
return ret;
@ -250,7 +260,7 @@ int PandaSpiHandle::wait_for_ack(uint8_t ack, uint8_t tx, unsigned int timeout)
spi_ioc_transfer transfer = {
.tx_buf = (uint64_t)tx_buf,
.rx_buf = (uint64_t)rx_buf,
.delay_usecs = 5,
.delay_usecs = 10,
.len = 1
};
tx_buf[0] = tx;
@ -274,6 +284,9 @@ int PandaSpiHandle::wait_for_ack(uint8_t ack, uint8_t tx, unsigned int timeout)
LOGD("SPI: timed out waiting for ACK");
return SpiError::ACK_TIMEOUT;
}
// backoff
transfer.delay_usecs = std::clamp(transfer.delay_usecs*2, 10, 250);
}
return 0;

Loading…
Cancel
Save