boardd: misc spi fixes (#26670)

pull/26679/head
Adeeb Shihadeh 2 years ago committed by GitHub
parent de061eacbe
commit 9cc06e9ea6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      selfdrive/boardd/panda.cc
  2. 1
      selfdrive/boardd/panda.h
  3. 3
      selfdrive/boardd/panda_comms.h
  4. 25
      selfdrive/boardd/spi.cc

@ -230,8 +230,6 @@ bool Panda::can_receive(std::vector<can_frame>& out_vec) {
} }
bool Panda::unpack_can_buffer(uint8_t *data, int size, std::vector<can_frame> &out_vec) { bool Panda::unpack_can_buffer(uint8_t *data, int size, std::vector<can_frame> &out_vec) {
recv_buf.clear();
if (size < sizeof(uint32_t)) { if (size < sizeof(uint32_t)) {
return true; return true;
} }
@ -239,7 +237,7 @@ bool Panda::unpack_can_buffer(uint8_t *data, int size, std::vector<can_frame> &o
uint32_t magic; uint32_t magic;
memcpy(&magic, &data[0], sizeof(uint32_t)); memcpy(&magic, &data[0], sizeof(uint32_t));
if (magic != CAN_TRANSACTION_MAGIC) { if (magic != CAN_TRANSACTION_MAGIC) {
LOGE("CAN: MALFORMED CAN RECV PACKET"); LOGE("CAN recv: buffer didn't start with magic");
handle->comms_healthy = false; handle->comms_healthy = false;
return false; return false;
} }

@ -43,7 +43,6 @@ struct can_frame {
class Panda { class Panda {
private: private:
std::unique_ptr<PandaCommsHandle> handle; std::unique_ptr<PandaCommsHandle> handle;
std::vector<uint8_t> recv_buf;
public: public:
Panda(std::string serial="", uint32_t bus_offset=0); Panda(std::string serial="", uint32_t bus_offset=0);

@ -13,8 +13,6 @@
#define TIMEOUT 0 #define TIMEOUT 0
#define SPI_BUF_SIZE 1024 #define SPI_BUF_SIZE 1024
const bool PANDA_NO_RETRY = getenv("PANDA_NO_RETRY");
// comms base class // comms base class
class PandaCommsHandle { class PandaCommsHandle {
@ -52,7 +50,6 @@ public:
private: private:
libusb_context *ctx = NULL; libusb_context *ctx = NULL;
libusb_device_handle *dev_handle = NULL; libusb_device_handle *dev_handle = NULL;
std::vector<uint8_t> recv_buf;
void handle_usb_issue(int err, const char func[]); void handle_usb_issue(int err, const char func[]);
}; };

@ -6,6 +6,7 @@
#include <cstring> #include <cstring>
#include "common/util.h" #include "common/util.h"
#include "common/timing.h"
#include "common/swaglog.h" #include "common/swaglog.h"
#include "panda/board/comms_definitions.h" #include "panda/board/comms_definitions.h"
#include "selfdrive/boardd/panda_comms.h" #include "selfdrive/boardd/panda_comms.h"
@ -24,6 +25,9 @@ struct __attribute__((packed)) spi_header {
uint16_t max_rx_len; 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) { PandaSpiHandle::PandaSpiHandle(std::string serial) : PandaCommsHandle(serial) {
LOGD("opening SPI panda: %s", serial.c_str()); 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) { 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); std::lock_guard lk(hw_lock);
const int xfer_size = 0x40; const int xfer_size = 0x40 * 15;
int ret = 0; int ret = 0;
uint16_t length = (tx_data != NULL) ? tx_len : rx_len; 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)); int len = std::min(xfer_size, tx_len - (xfer_size * i));
d = spi_transfer_retry(endpoint, tx_data + (xfer_size * i), len, NULL, 0); d = spi_transfer_retry(endpoint, tx_data + (xfer_size * i), len, NULL, 0);
} else { } 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) { if (d < 0) {
@ -137,15 +142,11 @@ int PandaSpiHandle::bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t t
return ret; return ret;
} }
std::vector<std::string> PandaSpiHandle::list() { std::vector<std::string> PandaSpiHandle::list() {
// TODO: list all pandas available over SPI // TODO: list all pandas available over SPI
return {}; return {};
} }
void add_checksum(uint8_t *data, int data_len) { void add_checksum(uint8_t *data, int data_len) {
data[data_len] = SPI_CHECKSUM_START; data[data_len] = SPI_CHECKSUM_START;
for (int i=0; i < data_len; i++) { 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 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 ret;
int count = SPI_MAX_RETRIES;
std::lock_guard lk(hw_lock); std::lock_guard lk(hw_lock);
do { do {
// TODO: handle error // TODO: handle error
ret = spi_transfer(endpoint, tx_data, tx_len, rx_data, max_rx_len); 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; return ret;
} }
int PandaSpiHandle::wait_for_ack(spi_ioc_transfer &transfer, uint8_t ack) { int PandaSpiHandle::wait_for_ack(spi_ioc_transfer &transfer, uint8_t ack) {
// TODO: add timeout? double start_millis = millis_since_boot();
while (true) { while (true) {
int ret = util::safe_ioctl(spi_fd, SPI_IOC_MESSAGE(1), &transfer); int ret = util::safe_ioctl(spi_fd, SPI_IOC_MESSAGE(1), &transfer);
if (ret < 0) { if (ret < 0) {
@ -189,6 +192,12 @@ int PandaSpiHandle::wait_for_ack(spi_ioc_transfer &transfer, uint8_t ack) {
LOGW("SPI: got NACK"); LOGW("SPI: got NACK");
return -1; return -1;
} }
// handle timeout
if (millis_since_boot() - start_millis > SPI_ACK_TIMEOUT) {
LOGE("SPI: timed out waiting for ACK");
return -1;
}
} }
return 0; return 0;

Loading…
Cancel
Save