def cb_irq(transfer): global state global irq_transfer irqtype = ct.cast(transfer.buffer[0], ct.c_ubyte) if transfer.status != usb.LIBUSB_TRANSFER_COMPLETED: print("irq transfer status {}?".format(transfer.status), file=sys.stderr) irq_transfer = ct.POINTER(usb.transfer)() request_exit(2) return print("IRQ callback {:02x}".format(irqtype)) if state == STATE_AWAIT_IRQ_FINGER_DETECTED: if irqtype == 0x01: if next_state() < 0: request_exit(2) return else: print("finger-on-sensor detected in wrong state!") elif state == STATE_AWAIT_IRQ_FINGER_REMOVED: if irqtype == 0x02: if next_state() < 0: request_exit(2) return else: print("finger-on-sensor detected in wrong state!") if usb.submit_transfer(irq_transfer) < 0: request_exit(2)
def init_capture(): global state global img_transfer global irq_transfer r = usb.submit_transfer(irq_transfer) if r < 0: return r r = usb.submit_transfer(img_transfer) if r < 0: usb.cancel_transfer(irq_transfer) while irq_transfer: if usb.handle_events(None) < 0: break return r # start state machine state = STATE_AWAIT_IRQ_FINGER_REMOVED return next_state()
def cb_img(transfer): global imgbuf global img_transfer if transfer.status != usb.LIBUSB_TRANSFER_COMPLETED: print("img transfer status {}?".format(transfer.status), file=sys.stderr) img_transfer = ct.POINTER(usb.transfer)() request_exit(2) return print("Image callback") save_to_file(imgbuf) if next_state() < 0: request_exit(2) return if usb.submit_transfer(img_transfer) < 0: request_exit(2)
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)
def set_mode_async(data): global devh buf = ct.cast(malloc(usb.LIBUSB_CONTROL_SETUP_SIZE + 1), ct.POINTER(ct.c_ubyte)) if not buf: return -errno.ENOMEM transfer = usb.alloc_transfer(0) # ct.POINTER(usb.transfer) if not transfer: free(buf); return -errno.ENOMEM print("async set mode {:02x}".format(data)) usb.fill_control_setup(buf, CTRL_OUT, USB_RQ, 0x4e, 0, 1) buf[usb.LIBUSB_CONTROL_SETUP_SIZE] = data usb.fill_control_transfer(transfer, devh, buf, cb_mode_changed, None, 1000) transfer.flags = (usb.LIBUSB_TRANSFER_SHORT_NOT_OK | usb.LIBUSB_TRANSFER_FREE_BUFFER | usb.LIBUSB_TRANSFER_FREE_TRANSFER) return usb.submit_transfer(transfer)
def cb_xfr(xfr): global num_bytes global num_xfer xfr = xfr[0] if xfr.status != usb.LIBUSB_TRANSFER_COMPLETED: print("transfer status {}".format(xfr.status), file=sys.stderr) usb.free_transfer(ct.byref(xfr)) sys.exit(3) if xfr.type == usb.LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: for i in range(xfr.num_iso_packets): pack = xfr.iso_packet_desc[i] if pack.status != usb.LIBUSB_TRANSFER_COMPLETED: print("Error: pack {} status {}".format(i, pack.status), file=sys.stderr) sys.exit(5) print("pack{} length:{}, actual_length:{}".format( i, pack.length, pack.actual_length)) print("length:{}, actual_length:{}".format(xfr.length, xfr.actual_length)) for i in range(xfr.actual_length): print("{:02x}".format(xfr.buffer[i]), end="") if i % 16: print() elif i % 8: print(" ", end="") else: print(" ", end="") num_bytes += xfr.actual_length num_xfer += 1 rc = usb.submit_transfer(ct.byref(xfr)) if rc < 0: print("error re-submitting URB", file=sys.stderr) sys.exit(1)