def alloc_transfers(): global devh global imgbuf global irqbuf global img_transfer global irq_transfer img_transfer = usb.alloc_transfer(0) if not img_transfer: return -errno.ENOMEM irq_transfer = usb.alloc_transfer(0) if not irq_transfer: return -errno.ENOMEM usb.fill_bulk_transfer(img_transfer, devh, EP_DATA, imgbuf, ct.sizeof(imgbuf), cb_img, None, 0) usb.fill_interrupt_transfer(irq_transfer, devh, EP_INTR, irqbuf, ct.sizeof(irqbuf), cb_irq, None, 0) return 0
def benchmark_in(ep): global devh global tv_start global buf if ep == EP_ISO_IN: num_iso_pack = 16 else: num_iso_pack = 0 xfr = usb.alloc_transfer(num_iso_pack) if not xfr: return -errno.ENOMEM if ep == EP_ISO_IN: usb.fill_iso_transfer(xfr, devh, ep, buf, ct.sizeof(buf), num_iso_pack, cb_xfr, None, 0) usb.set_iso_packet_lengths(xfr, ct.sizeof(buf) // num_iso_pack) else: usb.fill_bulk_transfer(xfr, devh, ep, buf, ct.sizeof(buf), cb_xfr, None, 0) tv_start = datetime.now() # NOTE: To reach maximum possible performance the program must # submit *multiple* transfers here, not just one. # # When only one transfer is submitted there is a gap in the bus # schedule from when the transfer completes until a new transfer # is submitted by the callback. This causes some jitter for # isochronous transfers and loss of throughput for bulk transfers. # # This is avoided by queueing multiple transfers in advance, so # that the host controller is always kept busy, and will schedule # more transfers on the bus while the callback is running for # transfers which have completed on the bus. return usb.submit_transfer(xfr)