diff --git a/selfdrive/boardd/panda.cc b/selfdrive/boardd/panda.cc index db9bcbab51..3e447c830e 100644 --- a/selfdrive/boardd/panda.cc +++ b/selfdrive/boardd/panda.cc @@ -230,8 +230,6 @@ bool Panda::can_receive(std::vector& out_vec) { } bool Panda::unpack_can_buffer(uint8_t *data, int size, std::vector &out_vec) { - recv_buf.clear(); - if (size < sizeof(uint32_t)) { return true; } @@ -239,7 +237,7 @@ bool Panda::unpack_can_buffer(uint8_t *data, int size, std::vector &o uint32_t magic; memcpy(&magic, &data[0], sizeof(uint32_t)); if (magic != CAN_TRANSACTION_MAGIC) { - LOGE("CAN: MALFORMED CAN RECV PACKET"); + LOGE("CAN recv: buffer didn't start with magic"); handle->comms_healthy = false; return false; } diff --git a/selfdrive/boardd/panda.h b/selfdrive/boardd/panda.h index b20d8f0afa..75fec57a3e 100644 --- a/selfdrive/boardd/panda.h +++ b/selfdrive/boardd/panda.h @@ -43,7 +43,6 @@ struct can_frame { class Panda { private: std::unique_ptr handle; - std::vector recv_buf; public: Panda(std::string serial="", uint32_t bus_offset=0); diff --git a/selfdrive/boardd/panda_comms.h b/selfdrive/boardd/panda_comms.h index f42eadc5b2..bd262dfa0e 100644 --- a/selfdrive/boardd/panda_comms.h +++ b/selfdrive/boardd/panda_comms.h @@ -13,8 +13,6 @@ #define TIMEOUT 0 #define SPI_BUF_SIZE 1024 -const bool PANDA_NO_RETRY = getenv("PANDA_NO_RETRY"); - // comms base class class PandaCommsHandle { @@ -52,7 +50,6 @@ public: private: libusb_context *ctx = NULL; libusb_device_handle *dev_handle = NULL; - std::vector recv_buf; void handle_usb_issue(int err, const char func[]); }; diff --git a/selfdrive/boardd/spi.cc b/selfdrive/boardd/spi.cc index 2803f58db0..717b6ce820 100644 --- a/selfdrive/boardd/spi.cc +++ b/selfdrive/boardd/spi.cc @@ -6,6 +6,7 @@ #include #include "common/util.h" +#include "common/timing.h" #include "common/swaglog.h" #include "panda/board/comms_definitions.h" #include "selfdrive/boardd/panda_comms.h" @@ -24,6 +25,9 @@ struct __attribute__((packed)) spi_header { uint16_t max_rx_len; }; +const int SPI_MAX_RETRIES = 5; +const int SPI_ACK_TIMEOUT = 50; // milliseconds + PandaSpiHandle::PandaSpiHandle(std::string serial) : PandaCommsHandle(serial) { LOGD("opening SPI panda: %s", serial.c_str()); @@ -109,7 +113,7 @@ int PandaSpiHandle::bulk_read(unsigned char endpoint, unsigned char* data, int l int PandaSpiHandle::bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t rx_len) { std::lock_guard lk(hw_lock); - const int xfer_size = 0x40; + const int xfer_size = 0x40 * 15; int ret = 0; uint16_t length = (tx_data != NULL) ? tx_len : rx_len; @@ -119,7 +123,8 @@ int PandaSpiHandle::bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t t int len = std::min(xfer_size, tx_len - (xfer_size * i)); d = spi_transfer_retry(endpoint, tx_data + (xfer_size * i), len, NULL, 0); } else { - d = spi_transfer_retry(endpoint, NULL, 0, rx_data + (xfer_size * i), xfer_size); + uint16_t to_read = std::min(xfer_size, rx_len - ret); + d = spi_transfer_retry(endpoint, NULL, 0, rx_data + (xfer_size * i), to_read); } if (d < 0) { @@ -137,15 +142,11 @@ int PandaSpiHandle::bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t t return ret; } - - std::vector PandaSpiHandle::list() { // TODO: list all pandas available over SPI return {}; } - - void add_checksum(uint8_t *data, int data_len) { data[data_len] = SPI_CHECKSUM_START; for (int i=0; i < data_len; i++) { @@ -165,17 +166,19 @@ 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) { int ret; + int count = SPI_MAX_RETRIES; std::lock_guard lk(hw_lock); do { // TODO: handle error ret = spi_transfer(endpoint, tx_data, tx_len, rx_data, max_rx_len); - } while (ret < 0 && connected && !PANDA_NO_RETRY); + count--; + } while (ret < 0 && connected && count > 0); return ret; } int PandaSpiHandle::wait_for_ack(spi_ioc_transfer &transfer, uint8_t ack) { - // TODO: add timeout? + double start_millis = millis_since_boot(); while (true) { int ret = util::safe_ioctl(spi_fd, SPI_IOC_MESSAGE(1), &transfer); if (ret < 0) { @@ -189,6 +192,12 @@ int PandaSpiHandle::wait_for_ack(spi_ioc_transfer &transfer, uint8_t ack) { LOGW("SPI: got NACK"); return -1; } + + // handle timeout + if (millis_since_boot() - start_millis > SPI_ACK_TIMEOUT) { + LOGE("SPI: timed out waiting for ACK"); + return -1; + } } return 0;