|
|
@ -2,6 +2,7 @@ |
|
|
|
#include <linux/spi/spidev.h> |
|
|
|
#include <linux/spi/spidev.h> |
|
|
|
|
|
|
|
|
|
|
|
#include <cassert> |
|
|
|
#include <cassert> |
|
|
|
|
|
|
|
#include <cmath> |
|
|
|
#include <cstring> |
|
|
|
#include <cstring> |
|
|
|
|
|
|
|
|
|
|
|
#include "common/util.h" |
|
|
|
#include "common/util.h" |
|
|
@ -99,13 +100,45 @@ int PandaSpiHandle::control_read(uint8_t request, uint16_t param1, uint16_t para |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int PandaSpiHandle::bulk_write(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout) { |
|
|
|
int PandaSpiHandle::bulk_write(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout) { |
|
|
|
return 0; |
|
|
|
return bulk_transfer(endpoint, data, length, NULL, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int PandaSpiHandle::bulk_read(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout) { |
|
|
|
int PandaSpiHandle::bulk_read(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout) { |
|
|
|
return 0; |
|
|
|
return bulk_transfer(endpoint, NULL, 0, data, length); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ret = 0; |
|
|
|
|
|
|
|
uint16_t length = (tx_data != NULL) ? tx_len : rx_len; |
|
|
|
|
|
|
|
for (int i = 0; i < (int)std::ceil((float)length / xfer_size); i++) { |
|
|
|
|
|
|
|
int d; |
|
|
|
|
|
|
|
if (tx_data != NULL) { |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (d < 0) { |
|
|
|
|
|
|
|
LOGE("SPI: bulk transfer failed with %d", d); |
|
|
|
|
|
|
|
comms_healthy = false; |
|
|
|
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret += d; |
|
|
|
|
|
|
|
if ((rx_data != NULL) && d < xfer_size) { |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 {}; |
|
|
@ -130,15 +163,15 @@ 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 err; |
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
|
|
std::lock_guard lk(hw_lock); |
|
|
|
std::lock_guard lk(hw_lock); |
|
|
|
do { |
|
|
|
do { |
|
|
|
// TODO: handle error
|
|
|
|
// TODO: handle error
|
|
|
|
err = 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 (err < 0 && connected && !PANDA_NO_RETRY); |
|
|
|
} while (ret < 0 && connected && !PANDA_NO_RETRY); |
|
|
|
|
|
|
|
|
|
|
|
return err; |
|
|
|
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) { |
|
|
@ -153,7 +186,7 @@ int PandaSpiHandle::wait_for_ack(spi_ioc_transfer &transfer, uint8_t ack) { |
|
|
|
if (rx_buf[0] == ack) { |
|
|
|
if (rx_buf[0] == ack) { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} else if (rx_buf[0] == SPI_NACK) { |
|
|
|
} else if (rx_buf[0] == SPI_NACK) { |
|
|
|
LOGW("SPI: got header NACK"); |
|
|
|
LOGW("SPI: got NACK"); |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|