diff --git a/board/main.c b/board/main.c index 9ac7bd90..ffaee3ae 100644 --- a/board/main.c +++ b/board/main.c @@ -236,7 +236,8 @@ void usb_cb_ep3_out(void *usbdata, int len, bool hardwired) { } void usb_cb_ep3_out_complete(void) { - if (can_tx_check_min_slots_free(MAX_CAN_MSGS_PER_BULK_TRANSFER)) { + // TODO: how does a second USB packet sneek in? (why multiply by 2) + if (can_tx_check_min_slots_free(MAX_CAN_MSGS_PER_BULK_TRANSFER * 2U)) { usb_outep3_resume_if_paused(); } } diff --git a/python/__init__.py b/python/__init__.py index 761f4319..579c655a 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -533,7 +533,13 @@ class Panda(object): for s in snds: self._handle.bulkWrite(3, s) else: - self._handle.bulkWrite(3, b''.join(snds), timeout=timeout) + dat = b''.join(snds) + while True: + bs = self._handle.bulkWrite(3, dat, timeout=timeout) + dat = dat[bs:] + if len(dat) == 0: + break + print("CAN: PARTIAL SEND MANY, RETRYING") break except (usb1.USBErrorIO, usb1.USBErrorOverflow): print("CAN: BAD SEND MANY, RETRYING") diff --git a/tests/automated/4_can_loopback.py b/tests/automated/4_can_loopback.py index b069d6f0..923d3635 100644 --- a/tests/automated/4_can_loopback.py +++ b/tests/automated/4_can_loopback.py @@ -214,8 +214,12 @@ def test_bulk_write(p): def flood_tx(panda): print('Sending!') - msg = b"\xaa" * 4 - packet = [[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] * NUM_MESSAGES_PER_BUS + msg = b"\xaa" * 8 + packet = [] + # start with many messages on a single bus (higher contention for single TX ring buffer) + packet += [[0xaa, None, msg, 0]] * NUM_MESSAGES_PER_BUS + # end with many messages on multiple buses + packet += [[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] * NUM_MESSAGES_PER_BUS # Disable timeout panda.can_send_many(packet, timeout=0) @@ -241,7 +245,7 @@ def test_bulk_write(p): print(f"Received {len(rx)} messages") # All messages should have been received - if len(rx) != 3 * NUM_MESSAGES_PER_BUS: + if len(rx) != 4 * NUM_MESSAGES_PER_BUS: Exception("Did not receive all messages!") # Set back to silent mode