@@ -50,8 +50,9 @@ class LockEx {
50
50
51
51
#define SPILOG (fn, fmt, ...) do { \
52
52
fn (fmt, ## __VA_ARGS__); \
53
- fn (" %d / 0x%x / %d / %d" , \
54
- xfer_count, header.endpoint , header.tx_len , header.max_rx_len ); \
53
+ fn (" %d / 0x%x / %d / %d / tx: %s" , \
54
+ xfer_count, header.endpoint , header.tx_len , header.max_rx_len , \
55
+ util::hexdump (tx_buf, std::min ((int )header.tx_len , 8 )).c_str ()); \
55
56
} while (0 )
56
57
57
58
PandaSpiHandle::PandaSpiHandle (std::string serial) : PandaCommsHandle(serial) {
@@ -238,6 +239,7 @@ int PandaSpiHandle::spi_transfer_retry(uint8_t endpoint, uint8_t *tx_data, uint1
238
239
// due to full TX buffers
239
240
nack_count += 1 ;
240
241
if (nack_count > 3 ) {
242
+ SPILOG (LOGE, " NACK sleep %d" , nack_count);
241
243
usleep (std::clamp (nack_count*10 , 200 , 2000 ));
242
244
}
243
245
}
@@ -256,14 +258,14 @@ int PandaSpiHandle::wait_for_ack(uint8_t ack, uint8_t tx, unsigned int timeout,
256
258
if (timeout == 0 ) {
257
259
timeout = SPI_ACK_TIMEOUT;
258
260
}
259
- timeout = std::clamp (timeout, 100U , SPI_ACK_TIMEOUT);
261
+ timeout = std::clamp (timeout, 20U , SPI_ACK_TIMEOUT);
260
262
261
263
spi_ioc_transfer transfer = {
262
264
.tx_buf = (uint64_t )tx_buf,
263
265
.rx_buf = (uint64_t )rx_buf,
264
- .len = length
266
+ .len = length,
265
267
};
266
- tx_buf[ 0 ] = tx ;
268
+ memset ( tx_buf, tx, length) ;
267
269
268
270
while (true ) {
269
271
int ret = lltransfer (transfer);
@@ -275,13 +277,13 @@ int PandaSpiHandle::wait_for_ack(uint8_t ack, uint8_t tx, unsigned int timeout,
275
277
if (rx_buf[0 ] == ack) {
276
278
break ;
277
279
} else if (rx_buf[0 ] == SPI_NACK) {
278
- SPILOG (LOGD, " SPI: got NACK" );
280
+ SPILOG (LOGD, " SPI: got NACK, waiting for 0x%x " , ack );
279
281
return SpiError::NACK;
280
282
}
281
283
282
284
// handle timeout
283
285
if (millis_since_boot () - start_millis > timeout) {
284
- SPILOG (LOGW, " SPI: timed out waiting for ACK" );
286
+ SPILOG (LOGW, " SPI: timed out waiting for ACK, waiting for 0x%x " , ack );
285
287
return SpiError::ACK_TIMEOUT;
286
288
}
287
289
}
@@ -352,13 +354,13 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx
352
354
ret = lltransfer (transfer);
353
355
if (ret < 0 ) {
354
356
SPILOG (LOGE, " SPI: failed to send header" );
355
- return ret ;
357
+ goto fail ;
356
358
}
357
359
358
360
// Wait for (N)ACK
359
361
ret = wait_for_ack (SPI_HACK, 0x11 , timeout, 1 );
360
362
if (ret < 0 ) {
361
- return ret ;
363
+ goto fail ;
362
364
}
363
365
364
366
// Send data
@@ -370,38 +372,53 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx
370
372
ret = lltransfer (transfer);
371
373
if (ret < 0 ) {
372
374
SPILOG (LOGE, " SPI: failed to send data" );
373
- return ret ;
375
+ goto fail ;
374
376
}
375
377
376
378
// Wait for (N)ACK
377
379
ret = wait_for_ack (SPI_DACK, 0x13 , timeout, 3 );
378
380
if (ret < 0 ) {
379
- return ret ;
381
+ goto fail ;
380
382
}
381
383
382
384
// Read data
383
385
rx_data_len = *(uint16_t *)(rx_buf+1 );
384
386
if (rx_data_len >= SPI_BUF_SIZE) {
385
387
SPILOG (LOGE, " SPI: RX data len larger than buf size %d" , rx_data_len);
386
- return - 1 ;
388
+ goto fail ;
387
389
}
388
390
389
391
transfer.len = rx_data_len + 1 ;
390
392
transfer.rx_buf = (uint64_t )(rx_buf + 2 + 1 );
391
393
ret = lltransfer (transfer);
392
394
if (ret < 0 ) {
393
395
SPILOG (LOGE, " SPI: failed to read rx data" );
394
- return ret ;
396
+ goto fail ;
395
397
}
396
398
if (!check_checksum (rx_buf, rx_data_len + 4 )) {
397
399
SPILOG (LOGE, " SPI: bad checksum" );
398
- return - 1 ;
400
+ goto fail ;
399
401
}
400
402
401
403
if (rx_data != NULL ) {
402
404
memcpy (rx_data, rx_buf + 3 , rx_data_len);
403
405
}
404
406
405
407
return rx_data_len;
408
+
409
+ fail:
410
+ // ensure slave is in a consistent state
411
+ // and ready for the next transfer
412
+ int nack_cnt = 0 ;
413
+ while (nack_cnt < 3 ) {
414
+ if (wait_for_ack (SPI_NACK, 0x14 , 1 , SPI_BUF_SIZE/2 ) == 0 ) {
415
+ nack_cnt += 1 ;
416
+ } else {
417
+ nack_cnt = 0 ;
418
+ }
419
+ }
420
+
421
+ if (ret > 0 ) ret = -1 ;
422
+ return ret;
406
423
}
407
424
#endif
0 commit comments