mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-02-19 18:13:55 +08:00
boardd spi: prevent busy wait when TX buffers full (#28599)
old-commit-hash: 4c6f7b5c84
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user