  int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len) {
    int ret;
    uint16_t rx_data_len;
  
    // needs to be less, since we need to have space for the checksum
    assert(tx_len < SPI_BUF_SIZE);
    assert(max_rx_len < SPI_BUF_SIZE);
  
    spi_header header = {
 
</s> remove   int spi_transfer_retry(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len);
 </s> add   int 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); </s> remove   int bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t rx_len);
 </s> add   int bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t rx_len, unsigned int timeout); </s> remove const int SPI_MAX_RETRIES = 5;
const int SPI_ACK_TIMEOUT = 50; // milliseconds
 </s> add const int SPI_ACK_TIMEOUT = 500; // milliseconds </s> remove   ret = control_read(0xc3, 0, 0, uid, uid_len);
 </s> add   ret = control_read(0xc3, 0, 0, uid, uid_len, 1000); </s> remove   LockEx lock(spi_fd, hw_lock);
 </s> add 
  LockEx lock(spi_fd, hw_lock);
  int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len) {
    int ret;
    uint16_t rx_data_len;
  LockEx lock(spi_fd, hw_lock);
  
    // needs to be less, since we need to have space for the checksum
    assert(tx_len < SPI_BUF_SIZE);
    assert(max_rx_len < SPI_BUF_SIZE);
  
    spi_header header = {
keep keep add keep keep keep keep keep keep
 boardd: handle nack on tx buffer full (#28241)

* boardd: handle nack on tx buffer full

* print pandaStates

* rx buffer too small

* connect timeout

---------

Co-authored-by: Comma Device <device@comma.ai> 
selfdrive/boardd/spi.cc