int HID_Ctrl_Comm(libusb_device_handle *l_devh, unsigned long cbCommAPDU, //apdu len unsigned char *pbCommAPDU, //apdu cmd unsigned long *cbRespAPDU, //resp len unsigned char *pbRespAPDU, //resp buf unsigned long dw_Timeout //TimeOutValue ) { unsigned char OutPutReport[512]; unsigned char InPutReport[512],BlockNo; unsigned short BlockLen; unsigned char SeqNumber,MoreData,PCB; unsigned char *pbBlock; int wStataWord = 0xffff; int iLoop; if (!l_devh) { return -1; } BlockNo = 0; pbBlock = pbCommAPDU; BlockLen = 0x40 - 4; SeqNumber = 0; iLoop = 0; do { memset(OutPutReport,0x00,512); OutPutReport[0]= (unsigned char)dw_Timeout; //NAD_TimeOut; //len if(cbCommAPDU > BlockLen) { OutPutReport[2] = 0; OutPutReport[3] = (unsigned char)BlockLen; MoreData = 0x20; } else { OutPutReport[2] = 0; OutPutReport[3] =(unsigned char)cbCommAPDU; MoreData = 0; } //pcb OutPutReport[1] = SeqNumber + MoreData + BlockNo; BlockNo++; if(SeqNumber == 0x40) { SeqNumber = 0x0; } else { SeqNumber = 0x40; } memcpy(OutPutReport+4,pbBlock,OutPutReport[3]); cbCommAPDU -= OutPutReport[3]; pbBlock += OutPutReport[3]; if(libusb_control_transfer(l_devh, 0x21, 0x09, 0x3000, 0x0000, OutPutReport, 0x0040, 3000) < 0) { return -1; } } while (cbCommAPDU>0); pbBlock = pbRespAPDU; *cbRespAPDU =0; iLoop = 20; do { RETRY: if(0 > libusb_control_transfer(l_devh, 0xa1, 0x01, 0x3000, 0x0000, InPutReport, 0x0040, 5000)) { return -1; } PCB = InPutReport[1]; if(PCB == 0xCC) { goto RETRY; } MoreData = PCB & 0x20; if(InPutReport[3]>0) { memcpy(pbBlock,InPutReport+4,InPutReport[3]); } pbBlock += InPutReport[3]; *cbRespAPDU += InPutReport[3]; } while(MoreData > 0); if(*cbRespAPDU >= 2) { wStataWord = pbRespAPDU[*cbRespAPDU-2]*256 + pbRespAPDU[*cbRespAPDU-1]; *cbRespAPDU -= 2; } else { return -1; } return (wStataWord); }
static unsigned long LJUSB_DoTransfer(HANDLE hDevice, unsigned char endpoint, BYTE *pBuff, unsigned long count, unsigned int timeout, bool isBulk) { int r = 0; int transferred = 0; if (LJ_DEBUG) { fprintf(stderr, "Calling LJUSB_DoTransfer with endpoint = 0x%x, count = %lu, and isBulk = %d.\n", endpoint, count, isBulk); } if (LJUSB_IsHandleValid(hDevice) == false) { if (LJ_DEBUG) { fprintf(stderr, "Calling LJUSB_DoTransfer returning 0 because handle is invalid. errno = %d.\n", errno); } return 0; } if (isBulk && endpoint != 1 && endpoint < 0x81 ) { fprintf(stderr, "LJUSB_DoTransfer warning: Got endpoint = %d, however this not a known endpoint. Please verify you are using the header file provided in /usr/local/include/labjackusb.h and not an older header file.\n", endpoint); } if (isBulk) { r = libusb_bulk_transfer(hDevice, endpoint, pBuff, (int)count, &transferred, timeout); } else { if (endpoint == 0) { //HID feature request. r = libusb_control_transfer(hDevice, 0xa1 , 0x01, 0x0300, 0x0000, pBuff, count, timeout); if (r < 0) { LJUSB_libusbError(r); return 0; } if (LJ_DEBUG) { fprintf(stderr, "LJUSB_DoTransfer: returning control transferred = %d.\n", r); } return r; } else { r = libusb_interrupt_transfer(hDevice, endpoint, pBuff, count, &transferred, timeout); } } if (r == LIBUSB_ERROR_TIMEOUT) { //Timeout occured but may have received partial data. Setting errno but //returning the number of bytes transferred which may be > 0. if (LJ_DEBUG) { fprintf(stderr, "LJUSB_DoTransfer: Transfer timed out. Returning.\n"); } errno = ETIMEDOUT; return transferred; } else if (r != 0) { LJUSB_libusbError(r); return 0; } if (LJ_DEBUG) { fprintf(stderr, "LJUSB_DoTransfer: returning transferred = %d.\n", transferred); } return transferred; }
SR_PRIV int sl2_transfer_out(libusb_device_handle *dev_handle, uint8_t *data) { return libusb_control_transfer(dev_handle, USB_REQUEST_TYPE_OUT, USB_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE, (unsigned char *)data, PACKET_LENGTH, USB_TIMEOUT); }
// on success data point to a null terminated string of max length-1 characters static int getUsbStringASCII(libusb_device_handle *hdl, libusb_device *dev, u8 desc_index, char *data, u32 length) { u8 buffer[512]; u32 l,len; int res,i; stringCacheSt *c = stringCache; stringCacheSt *f = NULL; u64 now = yapiGetTickCount(); yEnterCriticalSection(&yContext->string_cache_cs); for (i = 0; i < STRING_CACHE_SIZE; i++, c++) { if (c->expiration > now) { if(c->dev == dev && c->desc_index == desc_index) { if (c->len > 0 && c->string) { len = c->len; if (c->len >= length) len = length-1; memcpy(data, c->string, len); data[len] = 0; HALLOG("return string from cache (%p:%d->%s)\n",dev,desc_index,c->string); yLeaveCriticalSection(&yContext->string_cache_cs); return c->len; } else { f = c; break; } } } else { if (c->string) { yFree(c->string); c->string =NULL; } if (f == NULL) { f = c; } } } res=libusb_control_transfer(hdl, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | desc_index, 0, buffer, 512, 10000); if(res<0) return res; len=(buffer[0]-2)/2; if (len >= length) { len = length - 1; } for (l = 0; l < len; l++){ data[l] = (char) buffer[2+(l*2)]; } data[len] = 0; if (f != NULL) { f->dev = dev; f->desc_index = desc_index; f->string = yMalloc(len+1); memcpy(f->string, data, len+1); f->len = len; f->expiration = yapiGetTickCount() + STRING_CACHE_EXPIRATION; HALLOG("add string to cache (%p:%d->%s)\n",dev,desc_index,f->string); } yLeaveCriticalSection(&yContext->string_cache_cs); return len; }
/* This API is used to read JTAG data from device interface */ CY_RETURN_STATUS CyJtagRead ( CY_HANDLE handle, CY_DATA_BUFFER *readBuffer, UINT32 ioTimeout ) { int rStatus; CY_DEVICE *device; libusb_device_handle *devHandle; UINT16 wValue, wIndex, wLength; UINT16 bmRequestType, bmRequest; bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; bmRequest = CY_JTAG_READ_CMD; wValue = readBuffer->length; wIndex = 0; wLength = 0; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__); return CY_ERROR_INVALID_HANDLE; } if ((readBuffer == NULL) || (readBuffer->buffer == NULL) || (readBuffer->length == 0)){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid parameter.. Function is %s \n", __func__); return CY_ERROR_INVALID_PARAMETER; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_JTAG) { CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__); return CY_ERROR_REQUEST_FAILED; } readBuffer->transferCount = 0; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, NULL, wLength, ioTimeout); if (rStatus < 0){ CY_DEBUG_PRINT_INFO ("CY: JTAG Vendor Command failed %d.. Function is %s \n", rStatus, __func__); return CY_ERROR_REQUEST_FAILED; } rStatus = libusb_bulk_transfer (devHandle, CY_JTAG_IN_EP, readBuffer->buffer, readBuffer->length, (int*)&(readBuffer->transferCount), ioTimeout); if (rStatus == CY_SUCCESS){ CY_DEBUG_PRINT_ERROR ("CY: Number of bytes read is .... %d \n", readBuffer->transferCount); return CY_SUCCESS; } else if (rStatus == LIBUSB_ERROR_TIMEOUT){ CY_DEBUG_PRINT_ERROR ("CY:TimeOut error ...Function is %s \n", __func__); return CY_ERROR_IO_TIMEOUT; } else if (rStatus == LIBUSB_ERROR_PIPE){ CY_DEBUG_PRINT_ERROR ("CY:Pipe error Function is %s \n", __func__); CyResetPipe (handle, CY_JTAG_IN_EP); return CY_ERROR_PIPE_HALTED; } else if (rStatus == LIBUSB_ERROR_OVERFLOW){ CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow..Function is %s \n", __func__); return CY_ERROR_BUFFER_OVERFLOW; } else if (rStatus == LIBUSB_ERROR_NO_DEVICE) { CY_DEBUG_PRINT_ERROR ("CY: Device Disconnected ....Function is %s \n", __func__); return CY_ERROR_DEVICE_NOT_FOUND; } else { CY_DEBUG_PRINT_ERROR ("CY: Error in function is %s ...Libusb Error is %d!\n", __func__, rStatus); return CY_ERROR_REQUEST_FAILED; } }
int main (int argc, const char *argv[]) { int busnum = 0, devnum = 0; int cmd = COMMAND_SET_NONE; int port = 1; int value = 0; int request, feature, index; int result = 0; int listing = 0; int verbose = 0; int hub = -1; libusb_device_handle *uh = NULL; int i; if (argc == 1) listing = 1; for (i = 1; i < argc; i++) if (argv[i][0] == '-') switch (argv[i][1]) { case 'h': if (++i >= argc || busnum > 0 || devnum > 0) exit_with_usage (argv[0]); hub = atoi (argv[i]); break; case 'b': if (++i >= argc || hub >= 0) exit_with_usage (argv[0]); busnum = atoi (argv[i]); break; case 'd': if (++i >= argc || hub >= 0) exit_with_usage (argv[0]); devnum = atoi (argv[i]); break; case 'P': if (++i >= argc) exit_with_usage (argv[0]); port = atoi (argv[i]); break; case 'l': if (cmd != COMMAND_SET_NONE) exit_with_usage (argv[0]); if (++i < argc) value = atoi (argv[i]); else value = HUB_LED_GREEN; cmd = COMMAND_SET_LED; break; case 'p': if (cmd != COMMAND_SET_NONE) exit_with_usage (argv[0]); if (++i < argc) value = atoi (argv[i]); else value= 0; cmd = COMMAND_SET_POWER; break; case 'v': verbose = 1; if (argc == 2) listing = 1; break; default: exit_with_usage (argv[0]); } else exit_with_usage (argv[0]); if ((busnum > 0 && devnum <= 0) || (busnum <= 0 && devnum > 0)) /* BUS is specified, but DEV is'nt, or ... */ exit_with_usage (argv[0]); /* Default is the hub #0 */ if (hub < 0 && busnum == 0) hub = 0; /* Default is POWER */ if (cmd == COMMAND_SET_NONE) cmd = COMMAND_SET_POWER; libusb_init ( &ctx ); libusb_set_debug( ctx, 3 ); if (usb_find_hubs (listing, verbose, busnum, devnum, hub) <= 0) { fprintf (stderr, "No hubs found.\n"); libusb_exit( ctx ); exit (1); } if (listing){ libusb_exit( ctx ); exit (0); } if (hub < 0) hub = get_hub (busnum, devnum); if (hub >= 0 && hub < number_of_hubs_with_feature){ if ( libusb_open (hubs[hub].dev, &uh ) || uh == NULL) { fprintf (stderr, "Device not found.\n"); result = 1; } else { if (cmd == COMMAND_SET_POWER){ if (value){ request = LIBUSB_REQUEST_SET_FEATURE; feature = USB_PORT_FEAT_POWER; index = port; }else{ request = LIBUSB_REQUEST_CLEAR_FEATURE; feature = USB_PORT_FEAT_POWER; index = port; } }else{ request = LIBUSB_REQUEST_SET_FEATURE; feature = USB_PORT_FEAT_INDICATOR; index = (value << 8) | port; } if (verbose) printf ("Send control message (REQUEST=%d, FEATURE=%d, INDEX=%d)\n", request, feature, index); /* if(libusb_detach_kernel_driver( uh, 0 )) perror("libusb_detach_kernel_driver"); if(libusb_claim_interface( uh, 0 )) perror("libusb_claim_interface"); */ if (libusb_control_transfer (uh, USB_RT_PORT, request, feature, index, NULL, 0, CTRL_TIMEOUT) < 0) { perror ("failed to control.\n"); result = 1; } if (verbose) hub_port_status (uh, hubs[hub].nport, hubs[hub].usb3); /* libusb_release_interface( uh,0 ); libusb_attach_kernel_driver( uh, 0); */ libusb_close (uh); } } libusb_exit( ctx ); exit (result); }
//Ripped out of libusb_open_device_with_vid_pid bool FalconCommLibUSB::open(unsigned int index) { LOG_INFO("Opening device"); struct libusb_device **devs; struct libusb_device *found = NULL; struct libusb_device *dev; size_t i = 0; int count = 0; if ((m_deviceErrorCode = libusb_get_device_list(m_usbContext, &devs)) < 0) { LOG_ERROR("Device list not retrievable - Device error code " << m_deviceErrorCode); m_errorCode = FALCON_COMM_DEVICE_ERROR; return false; } while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; m_deviceErrorCode = libusb_get_device_descriptor(dev, &desc); if (m_deviceErrorCode < 0) { LOG_ERROR("Device descriptor not retrievable - Device error code " << m_deviceErrorCode); m_errorCode = FALCON_COMM_DEVICE_ERROR; libusb_free_device_list(devs, 1); return false; } if (desc.idVendor == FALCON_VENDOR_ID && desc.idProduct == FALCON_PRODUCT_ID) { if(count == index) { found = dev; break; } ++count; } } if (found) { m_deviceErrorCode = libusb_open(found, &m_falconDevice); if (m_deviceErrorCode < 0) { LOG_ERROR("Cannot open device - Device error code " << m_deviceErrorCode); m_falconDevice = NULL; m_errorCode = FALCON_COMM_DEVICE_ERROR; libusb_free_device_list(devs, 1); return false; } } else { LOG_ERROR("Device index " << index << " out of range"); m_errorCode = FALCON_COMM_DEVICE_INDEX_OUT_OF_RANGE_ERROR; return false; } if ((m_deviceErrorCode = libusb_claim_interface(m_falconDevice, 0)) < 0) { LOG_ERROR("Cannot claim device interface - Device error code " << m_deviceErrorCode); m_errorCode = FALCON_COMM_DEVICE_ERROR; return false; } if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_RESET_REQUEST_TYPE, SIO_RESET_REQUEST, SIO_RESET_PURGE_RX, INTERFACE_ANY, NULL, 0, 1000)) != 0) { m_errorCode = FALCON_COMM_DEVICE_ERROR; LOG_ERROR("Cannot rx purge - Device error code " << m_deviceErrorCode); return false; } if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_RESET_REQUEST_TYPE, SIO_RESET_REQUEST, SIO_RESET_PURGE_TX, INTERFACE_ANY, NULL, 0, 1000)) != 0) { m_errorCode = FALCON_COMM_DEVICE_ERROR; LOG_ERROR("Cannot tx purge - Device error code " << m_deviceErrorCode); return false; } reset(); m_isCommOpen = true; setNormalMode(); return true; }
void usbTriggerConfigR_USBDIO32HS(libusb_device_handle *udev, uint8_t *options) { uint8_t requesttype = (DEVICE_TO_HOST | VENDOR_TYPE | DEVICE_RECIPIENT); libusb_control_transfer(udev, requesttype, TRIGGER_CONFIG, 0x0, 0x0, (unsigned char *) options, sizeof(options), HS_DELAY); }
// Mass Storage device to test bulk transfers (non destructive test) int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { int r; uint8_t lun; uint32_t expected_tag; uint32_t i, size, max_lba, block_size; double device_size; uint8_t cdb[16]; // SCSI Command Descriptor Block uint8_t buffer[64]; char vid[9], pid[9], rev[5]; unsigned char *data; FILE *fd; size_t junk; printf("Reading Max LUN:\n"); r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, BOMS_GET_MAX_LUN, 0, 0, &lun, 1, 1000); // Some devices send a STALL instead of the actual value. // In such cases we should set lun to 0. if (r == 0) { lun = 0; } else if (r < 0) { perr(" Failed: %s", libusb_strerror(r)); } printf(" Max LUN = %d\n", lun); // Send Inquiry printf("Sending Inquiry:\n"); memset(buffer, 0, sizeof(buffer)); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x12; // Inquiry cdb[4] = INQUIRY_LENGTH; send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, INQUIRY_LENGTH, &expected_tag); CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, INQUIRY_LENGTH, &size, 1000)); printf(" received %d bytes\n", size); // The following strings are not zero terminated for (i=0; i<8; i++) { vid[i] = buffer[8+i]; pid[i] = buffer[16+i]; rev[i/2] = buffer[32+i/2]; // instead of another loop } vid[8] = 0; pid[8] = 0; rev[4] = 0; printf(" VID:PID:REV \"%8s\":\"%8s\":\"%4s\"\n", vid, pid, rev); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } // Read capacity printf("Reading Capacity:\n"); memset(buffer, 0, sizeof(buffer)); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x25; // Read Capacity send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, READ_CAPACITY_LENGTH, &expected_tag); CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, READ_CAPACITY_LENGTH, &size, 1000)); printf(" received %d bytes\n", size); max_lba = be_to_int32(&buffer[0]); block_size = be_to_int32(&buffer[4]); device_size = ((double)(max_lba+1))*block_size/(1024*1024*1024); printf(" Max LBA: %08X, Block Size: %08X (%.2f GB)\n", max_lba, block_size, device_size); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } data = malloc(block_size); if (data == NULL) { perr(" unable to allocate data buffer\n"); return -1; } // Send Read printf("Attempting to read %d bytes:\n", block_size); memset(data, 0, block_size); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x28; // Read(10) cdb[8] = 0x01; // 1 block send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, block_size, &expected_tag); libusb_bulk_transfer(handle, endpoint_in, data, block_size, &size, 5000); printf(" READ: received %d bytes\n", size); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } else { display_buffer_hex(data, size); if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) { junk = fwrite(data, 1, size, fd); fclose(fd); } } return 0; }
int test_hid(libusb_device_handle *handle, uint8_t endpoint_in) { int r, size, descriptor_size; uint8_t hid_report_descriptor[256]; uint8_t *report_buffer; FILE *fd; size_t junk; printf("\nReading HID Report Descriptors:\n"); descriptor_size = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_STANDARD|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_REPORT<<8, 0, hid_report_descriptor, 256, 1000); if (descriptor_size < 0) { printf("failed\n"); return -1; } else { display_buffer_hex(hid_report_descriptor, descriptor_size); if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) { junk = fwrite(hid_report_descriptor, 1, descriptor_size, fd); fclose(fd); } size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_FEATURE); } if (size <= 0) { printf("\nSkipping Feature Report readout (None detected)\n"); } else { report_buffer = calloc(size, 1); if (report_buffer == NULL) { return -1; } printf("\nReading Feature Report (length %d)...\n", size); r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer, (uint16_t)size, 5000); if (r >= 0) { display_buffer_hex(report_buffer, size); } else { switch(r) { case LIBUSB_ERROR_NOT_FOUND: printf(" No Feature Report available for this device\n"); break; case LIBUSB_ERROR_PIPE: printf(" Detected stall - resetting pipe...\n"); libusb_clear_halt(handle, 0); break; default: printf(" Error: %s\n", libusb_strerror(r)); break; } } free(report_buffer); } size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_INPUT); if (size <= 0) { printf("\nSkipping Input Report readout (None detected)\n"); } else { report_buffer = calloc(size, 1); if (report_buffer == NULL) { return -1; } printf("\nReading Input Report (length %d)...\n", size); r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, report_buffer, (uint16_t)size, 5000); if (r >= 0) { display_buffer_hex(report_buffer, size); } else { switch(r) { case LIBUSB_ERROR_TIMEOUT: printf(" Timeout! Please make sure you act on the device within the 5 seconds allocated...\n"); break; case LIBUSB_ERROR_PIPE: printf(" Detected stall - resetting pipe...\n"); libusb_clear_halt(handle, 0); break; default: printf(" Error: %s\n", libusb_strerror(r)); break; } } // Attempt a bulk read from endpoint 0 (this should just return a raw input report) printf("\nTesting interrupt read using endpoint %02X...\n", endpoint_in); r = libusb_interrupt_transfer(handle, endpoint_in, report_buffer, size, &size, 5000); if (r >= 0) { display_buffer_hex(report_buffer, size); } else { printf(" %s\n", libusb_strerror(r)); } free(report_buffer); } return 0; }
static int scpi_usbtmc_libusb_open(struct sr_scpi_dev_inst *scpi) { struct scpi_usbtmc_libusb *uscpi = scpi->priv; struct sr_usb_dev_inst *usb = uscpi->usb; struct libusb_device *dev; struct libusb_device_descriptor des; struct libusb_config_descriptor *confdes; const struct libusb_interface_descriptor *intfdes; const struct libusb_endpoint_descriptor *ep; int confidx, intfidx, epidx, config = 0, current_config; uint8_t capabilities[24]; int ret, found = 0; int do_reset; if (usb->devhdl) return SR_OK; if (sr_usb_open(uscpi->ctx->libusb_ctx, usb) != SR_OK) return SR_ERR; dev = libusb_get_device(usb->devhdl); libusb_get_device_descriptor(dev, &des); for (confidx = 0; confidx < des.bNumConfigurations; confidx++) { if ((ret = libusb_get_config_descriptor(dev, confidx, &confdes)) < 0) { if (ret != LIBUSB_ERROR_NOT_FOUND) sr_dbg("Failed to get configuration descriptor: %s, " "ignoring device.", libusb_error_name(ret)); continue; } for (intfidx = 0; intfidx < confdes->bNumInterfaces; intfidx++) { intfdes = confdes->interface[intfidx].altsetting; if (intfdes->bInterfaceClass != LIBUSB_CLASS_APPLICATION || intfdes->bInterfaceSubClass != SUBCLASS_USBTMC || intfdes->bInterfaceProtocol != USBTMC_USB488) continue; uscpi->interface = intfdes->bInterfaceNumber; config = confdes->bConfigurationValue; sr_dbg("Interface %d configuration %d.", uscpi->interface, config); for (epidx = 0; epidx < intfdes->bNumEndpoints; epidx++) { ep = &intfdes->endpoint[epidx]; if (ep->bmAttributes == LIBUSB_TRANSFER_TYPE_BULK && !(ep->bEndpointAddress & (LIBUSB_ENDPOINT_DIR_MASK))) { uscpi->bulk_out_ep = ep->bEndpointAddress; sr_dbg("Bulk OUT EP %d", uscpi->bulk_out_ep); } if (ep->bmAttributes == LIBUSB_TRANSFER_TYPE_BULK && ep->bEndpointAddress & (LIBUSB_ENDPOINT_DIR_MASK)) { uscpi->bulk_in_ep = ep->bEndpointAddress; sr_dbg("Bulk IN EP %d", uscpi->bulk_in_ep & 0x7f); } if (ep->bmAttributes == LIBUSB_TRANSFER_TYPE_INTERRUPT && ep->bEndpointAddress & (LIBUSB_ENDPOINT_DIR_MASK)) { uscpi->interrupt_ep = ep->bEndpointAddress; sr_dbg("Interrupt EP %d", uscpi->interrupt_ep & 0x7f); } } found = 1; } libusb_free_config_descriptor(confdes); if (found) break; } if (!found) { sr_err("Failed to find USBTMC interface."); return SR_ERR; } if (libusb_kernel_driver_active(usb->devhdl, uscpi->interface) == 1) { if ((ret = libusb_detach_kernel_driver(usb->devhdl, uscpi->interface)) < 0) { sr_err("Failed to detach kernel driver: %s.", libusb_error_name(ret)); return SR_ERR; } uscpi->detached_kernel_driver = 1; } if (libusb_get_configuration(usb->devhdl, ¤t_config) == 0 && current_config != config) { if ((ret = libusb_set_configuration(usb->devhdl, config)) < 0) { sr_err("Failed to set configuration: %s.", libusb_error_name(ret)); return SR_ERR; } } if ((ret = libusb_claim_interface(usb->devhdl, uscpi->interface)) < 0) { sr_err("Failed to claim interface: %s.", libusb_error_name(ret)); return SR_ERR; } /* Optionally reset the USB device. */ do_reset = check_usbtmc_blacklist(whitelist_usb_reset, des.idVendor, des.idProduct); if (do_reset) libusb_reset_device(usb->devhdl); /* Get capabilities. */ ret = libusb_control_transfer(usb->devhdl, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, GET_CAPABILITIES, 0, uscpi->interface, capabilities, sizeof(capabilities), TRANSFER_TIMEOUT); if (ret == sizeof(capabilities)) { uscpi->usbtmc_int_cap = capabilities[ 4]; uscpi->usbtmc_dev_cap = capabilities[ 5]; uscpi->usb488_dev_cap = capabilities[15]; } sr_dbg("Device capabilities: %s%s%s%s%s, %s, %s", uscpi->usb488_dev_cap & USB488_DEV_CAP_SCPI ? "SCPI, " : "", uscpi->usbtmc_dev_cap & USBTMC_DEV_CAP_TERMCHAR ? "TermChar, ": "", uscpi->usbtmc_int_cap & USBTMC_INT_CAP_LISTEN_ONLY ? "L3, " : uscpi->usbtmc_int_cap & USBTMC_INT_CAP_TALK_ONLY ? "" : "L4, ", uscpi->usbtmc_int_cap & USBTMC_INT_CAP_TALK_ONLY ? "T5, " : uscpi->usbtmc_int_cap & USBTMC_INT_CAP_LISTEN_ONLY ? "" : "T6, ", uscpi->usb488_dev_cap & USB488_DEV_CAP_SR1 ? "SR1" : "SR0", uscpi->usb488_dev_cap & USB488_DEV_CAP_RL1 ? "RL1" : "RL0", uscpi->usb488_dev_cap & USB488_DEV_CAP_DT1 ? "DT1" : "DT0"); scpi_usbtmc_remote(uscpi); return SR_OK; }
bool ft232r_get_bitmode(struct ft232r_device_handle *dev, uint8_t *out_mode) { return libusb_control_transfer(dev->h, FTDI_REQTYPE_IN, FTDI_REQUEST_GET_BITMODE, 0, FTDI_INDEX, out_mode, 1, FTDI_TIMEOUT) == 1; }
bool ft232r_get_pins(struct ft232r_device_handle *dev, uint8_t *pins) { return libusb_control_transfer(dev->h, FTDI_REQTYPE_IN, FTDI_REQUEST_GET_PINS, 0, FTDI_INDEX, pins, 1, FTDI_TIMEOUT) == 1; }
void usbMemoryW_USBDIO32HS(libusb_device_handle *udev, uint8_t *data, uint16_t length) { uint8_t requesttype = (HOST_TO_DEVICE | VENDOR_TYPE | DEVICE_RECIPIENT); libusb_control_transfer(udev, requesttype, MEMORY, 0x0, 0x0, (unsigned char *) data, length, HS_DELAY); }
bool FalconCommLibUSB::setFirmwareMode() { unsigned int bytes_written, bytes_read; unsigned char check_msg_1_send[3] = {0x0a, 0x43, 0x0d}; unsigned char check_msg_1_recv[5] = {0x00, 0x0a, 0x44, 0x2c, 0x0d}; unsigned char check_msg_2[1] = {0x41}; unsigned char send_buf[128], receive_buf[128]; int k; LOG_INFO("Setting firmware communications mode"); if(!m_isCommOpen) { LOG_ERROR("Device not open"); m_errorCode = FALCON_COMM_DEVICE_NOT_VALID_ERROR; return false; } //Save ourselves having to reset this on every error m_errorCode = FALCON_COMM_DEVICE_ERROR; //reset(); //Clear out current buffers to make sure we have a fresh start //if((m_deviceErrorCode = ftdi_usb_purge_buffers(&(m_falconDevice))) < 0) return false; if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_RESET_REQUEST_TYPE, SIO_RESET_REQUEST, SIO_RESET_PURGE_RX, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot purge buffers - Device error " << m_deviceErrorCode); return false; } if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_RESET_REQUEST_TYPE, SIO_RESET_REQUEST, SIO_RESET_PURGE_TX, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot purge buffers - Device error " << m_deviceErrorCode); return false; } //Reset the device //if((m_deviceErrorCode = ftdi_usb_reset(&(m_falconDevice))) < 0) return false; //Make sure our latency timer is at 16ms, otherwise firmware checks tend to always fail //if((m_deviceErrorCode = ftdi_set_latency_timer(&(m_falconDevice), 16)) < 0) return false; if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, 0x40, 0x09, 16, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set latency timer - Device error " << m_deviceErrorCode); return false; } //Set to: // 9600 baud // 8n1 // No Flow Control // RTS Low // DTR High //if((m_deviceErrorCode = ftdi_set_baudrate(&(m_falconDevice), 9600)) < 0) return false; //Baud for 9600 is 0x4138. Just trust me. It is. if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_BAUDRATE_REQUEST_TYPE, SIO_SET_BAUDRATE_REQUEST, 0x4138, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set baud rate - Device error " << m_deviceErrorCode); return false; } //if((m_deviceErrorCode = ftdi_set_line_property(&(m_falconDevice), BITS_8, STOP_BIT_1, NONE)) < 0) return false; //BITS_8 = 8, STOP_BIT_1 = 0, NONE = 0 if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_DATA_REQUEST_TYPE, SIO_SET_DATA_REQUEST, (8 | (0x00 << 11) | (0x00 << 8)), INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set line properties - Device error " << m_deviceErrorCode); return false; } //if((m_deviceErrorCode = ftdi_setflowctrl(&(m_falconDevice), SIO_DISABLE_FLOW_CTRL)) < 0) return false; if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_FLOW_CTRL_REQUEST_TYPE, SIO_SET_FLOW_CTRL_REQUEST, 0, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set flow control - Device error " << m_deviceErrorCode); return false; } //if((m_deviceErrorCode = ftdi_setrts(&(m_falconDevice), 0)) < 0) return false; if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_MODEM_CTRL_REQUEST_TYPE, SIO_SET_MODEM_CTRL_REQUEST, SIO_SET_RTS_LOW, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set RTS properties - Device error " << m_deviceErrorCode); return false; } //if((m_deviceErrorCode = ftdi_setdtr(&(m_falconDevice), 0)) < 0) return false; if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_MODEM_CTRL_REQUEST_TYPE, SIO_SET_MODEM_CTRL_REQUEST, SIO_SET_DTR_LOW, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set DTR properties (1) - Device error " << m_deviceErrorCode); return false; } //if((m_deviceErrorCode = ftdi_setdtr(&(m_falconDevice), 1)) < 0) return false; if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_MODEM_CTRL_REQUEST_TYPE, SIO_SET_MODEM_CTRL_REQUEST, SIO_SET_DTR_HIGH, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set DTR properties (2) - Device error " << m_deviceErrorCode); return false; } int i; for(i = 0; i < 100; ++i) { //Send 3 bytes: 0x0a 0x43 0x0d if((m_deviceErrorCode = libusb_bulk_transfer(m_falconDevice, 0x2, check_msg_1_send, 3, &m_lastBytesWritten, 1000)) != 0) { LOG_ERROR("Cannot write check values (1) - Device error " << m_deviceErrorCode); return false; } //Expect back 5 bytes: 0x00 0xa 0x44 0x2c 0xd if((m_deviceErrorCode = libusb_bulk_transfer(m_falconDevice, 0x81, receive_buf, 7, &m_lastBytesRead, 1000)) != 0) { LOG_ERROR("Cannot read check values (1) - Device error " << m_deviceErrorCode); return false; } //printf("CHECK 1 OUT %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", m_lastBytesRead, receive_buf[0], receive_buf[1], receive_buf[2], receive_buf[3], receive_buf[4], receive_buf[5], receive_buf[6]); //Apple case if(m_lastBytesRead == 7 && memcmp(receive_buf+2,check_msg_1_recv, 5) == 0) { break; } //Linux case if(m_lastBytesRead == 6 && memcmp(receive_buf+2,check_msg_1_recv+1, 4) == 0) { break; } } if(i == 100) { LOG_ERROR("Cannot match check values(1)"); return false; } //Set to: // DTR Low // 140000 baud (0x15 clock ticks per signal) //if((m_deviceErrorCode = ftdi_setdtr(&(m_falconDevice),0)) < 0) return false; if ((m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_MODEM_CTRL_REQUEST_TYPE, SIO_SET_MODEM_CTRL_REQUEST, SIO_SET_DTR_LOW, INTERFACE_ANY, NULL, 0, 1000)) != 0) { LOG_ERROR("Cannot set DTR properties (3) - Device error " << m_deviceErrorCode); return false; } //if((m_deviceErrorCode = ftdi_set_baudrate(&(m_falconDevice), 140000)) < 0) return false; if (m_deviceErrorCode = libusb_control_transfer(m_falconDevice, SIO_SET_BAUDRATE_REQUEST_TYPE, SIO_SET_BAUDRATE_REQUEST, 0x15, INTERFACE_ANY, NULL, 0, 1000) != 0) { LOG_ERROR("Cannot set baudrate for firmware load - Device error " << m_deviceErrorCode); return false; } //Send "A" character if((m_deviceErrorCode = libusb_bulk_transfer(m_falconDevice, 0x2, check_msg_2, 1, &m_lastBytesWritten, 1000)) != 0) { LOG_ERROR("Cannot write check values(2) - Device error " << m_deviceErrorCode); return false; } //Expect back 1 byte: //0x41 if((m_deviceErrorCode = libusb_bulk_transfer(m_falconDevice, 0x81, receive_buf, 3, &m_lastBytesRead, 1000)) != 0) { LOG_ERROR("Cannot read check values(2) - Device error " << m_deviceErrorCode); return false; } if(m_lastBytesRead != 3 || receive_buf[2] != 0x41) { LOG_ERROR("Cannot match check values(2)"); return false; } m_errorCode = 0; return true; }
void usbMemAddressW_USBDIO3208HS(libusb_device_handle *udev, uint16_t address) { uint8_t requesttype = (HOST_TO_DEVICE | VENDOR_TYPE | DEVICE_RECIPIENT); libusb_control_transfer(udev, requesttype, MEM_ADDRESS, 0x0, 0x0, (unsigned char *) &address, sizeof(address), HS_DELAY); }
micronucleus* micronucleus_connect(int fast_mode) { micronucleus *nucleus = NULL; libusb_device **devs, **dev; // intialise usb and find micronucleus device if (libusb_init(NULL) < 0 || libusb_get_device_list(NULL, &devs) < 0) return NULL; for (dev = devs; *dev; dev++) { struct libusb_device_descriptor desc; // skip device if we cannot get its descriptor if (libusb_get_device_descriptor(*dev, &desc) < 0) continue; if (desc.idVendor == MICRONUCLEUS_VENDOR_ID && desc.idProduct == MICRONUCLEUS_PRODUCT_ID) { nucleus = malloc(sizeof(micronucleus)); nucleus->version.major = (desc.bcdDevice >> 8) & 0xFF; nucleus->version.minor = desc.bcdDevice & 0xFF; if (nucleus->version.major > MICRONUCLEUS_MAX_MAJOR_VERSION) { fprintf(stderr, "Warning: device with unknown new version of Micronucleus detected.\n" "This tool doesn't know how to upload to this new device. Updates may be available.\n" "Device reports version as: %d.%d\n", nucleus->version.major, nucleus->version.minor); return NULL; } if (libusb_open(*dev, &nucleus->device) < 0) return NULL; if (nucleus->version.major>=2) { // Version 2.x // get nucleus info unsigned char buffer[6]; int res = libusb_control_transfer(nucleus->device, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|LIBUSB_RECIPIENT_DEVICE, 0, 0, 0, buffer, 6, MICRONUCLEUS_USB_TIMEOUT); // Device descriptor was found, but talking to it was not succesful. This can happen when the device is being reset. if (res<0) return NULL; assert(res >= 6); nucleus->flash_size = (buffer[0]<<8) + buffer[1]; nucleus->page_size = buffer[2]; nucleus->pages = (nucleus->flash_size / nucleus->page_size); if (nucleus->pages * nucleus->page_size < nucleus->flash_size) nucleus->pages += 1; nucleus->bootloader_start = nucleus->pages*nucleus->page_size; if ((nucleus->version.major>=2)&&(!fast_mode)) { // firmware v2 reports more aggressive write times. Add 2ms if fast mode is not used. nucleus->write_sleep = (buffer[3] & 127) + 2; } else { nucleus->write_sleep = (buffer[3] & 127); } // if bit 7 of write sleep time is set, divide the erase time by four to // accomodate to the 4*page erase of the ATtiny841/441 if (buffer[3]&128) { nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages / 4; } else { nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages; } nucleus->signature1 = buffer[4]; nucleus->signature2 = buffer[5]; } else { // Version 1.x // get nucleus info unsigned char buffer[4]; int res = libusb_control_transfer(nucleus->device, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR |LIBUSB_RECIPIENT_DEVICE, 0, 0, 0, buffer, 4, MICRONUCLEUS_USB_TIMEOUT); // Device descriptor was found, but talking to it was not succesful. This can happen when the device is being reset. if (res<0) return NULL; assert(res >= 4); nucleus->flash_size = (buffer[0]<<8) + buffer[1]; nucleus->page_size = buffer[2]; nucleus->pages = (nucleus->flash_size / nucleus->page_size); if (nucleus->pages * nucleus->page_size < nucleus->flash_size) nucleus->pages += 1; nucleus->bootloader_start = nucleus->pages*nucleus->page_size; nucleus->write_sleep = (buffer[3] & 127); nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages; nucleus->signature1 = 0; nucleus->signature2 = 0; } // we've found the device; there's no sense in checking everything else break; } }
int main(int argc, char **argv) { int r; libusb_device_handle * dev; unsigned char buffer[4]; if (argc < 2 || argc > 3) { printf("usage: %s <config>\n" " %s <key code> <hid code>\n" " %s bootloader" "\n" " config: bits 0-1: key click mode:\n" " 0: off\n" " 1: on\n" " 2: caps on\n" " bit 2: save config to EEPROM\n" " bit 3: read config from EEPROM\n", argv[0], argv[0], argv[0]); exit(1); } libusb_init(NULL); dev = libusb_open_device_with_vid_pid (NULL, usb_cfg_vendor_id[1] << 8 | usb_cfg_vendor_id[0], usb_cfg_device_id[1] << 8 | usb_cfg_device_id[0]); if (dev) { printf("device found\n"); buffer[0] = 0xff; r = libusb_control_transfer (dev, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_DEVICE, HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|REPORT_ID, 0, buffer, 1, 1000); if (r < 0) { fprintf(stderr, "Control In error %d\n", r); } printf("received: 0x%02x\n", buffer[0]); switch(argc) { case 2: if (strcmp(argv[1], "bootloader") == 0) { buffer[0] = 3; /* FEATURE_BOOTLOADER */ buffer[1] = 0; /* reserved */ r = libusb_control_transfer (dev, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_DEVICE, HID_SET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|REPORT_ID, 0, buffer, 2, 1000); if (r < 0) { fprintf(stderr, "Control Out error %d\n", r); } } else { *buffer = atoi(argv[1]); printf("sent: 0x%02x\n", buffer[0]); r = libusb_control_transfer (dev, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_DEVICE, HID_SET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|REPORT_ID, 0, buffer, 1, 1000); if (r < 0) { fprintf(stderr, "Control Out error %d\n", r); } buffer[0] = 0xff; r = libusb_control_transfer (dev, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_DEVICE, HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|REPORT_ID, 0, buffer, 1, 1000); if (r < 0) { fprintf(stderr, "Control In error %d\n", r); } printf("received: 0x%02x\n", buffer[0]); } break; case 3: buffer[0] = 2; /* FEATURE_OVERRIDE_KEYCODE */ buffer[1] = 0; /* reserved */ buffer[2] = atoi(argv[1]); /* key code */ buffer[3] = atoi(argv[2]); /* HID code */ r = libusb_control_transfer (dev, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_DEVICE, HID_SET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|REPORT_ID, 0, buffer, 4, 1000); if (r < 0) { fprintf(stderr, "Control Out error %d\n", r); } } libusb_close(dev); } libusb_exit(NULL); return 0; }
static int setupAccessory( const char* manufacturer, const char* modelName, const char* description, const char* version, const char* uri, const char* serialNumber){ unsigned char ioBuffer[2]; int devVersion; int response; int tries = 5; response = libusb_control_transfer( handle, //handle 0xC0, //bmRequestType 51, //bRequest 0, //wValue 0, //wIndex ioBuffer, //data 2, //wLength 0 //timeout ); if(response < 0){error(response);return-1;} devVersion = ioBuffer[1] << 8 | ioBuffer[0]; fprintf(stdout,"Verion Code Device: %d\n", devVersion); usleep(1000);//sometimes hangs on the next transfer :( response = libusb_control_transfer(handle,0x40,52,0,0,(char*)manufacturer,strlen(manufacturer),0); if(response < 0){error(response);return -1;} response = libusb_control_transfer(handle,0x40,52,0,1,(char*)modelName,strlen(modelName)+1,0); if(response < 0){error(response);return -1;} response = libusb_control_transfer(handle,0x40,52,0,2,(char*)description,strlen(description)+1,0); if(response < 0){error(response);return -1;} response = libusb_control_transfer(handle,0x40,52,0,3,(char*)version,strlen(version)+1,0); if(response < 0){error(response);return -1;} response = libusb_control_transfer(handle,0x40,52,0,4,(char*)uri,strlen(uri)+1,0); if(response < 0){error(response);return -1;} response = libusb_control_transfer(handle,0x40,52,0,5,(char*)serialNumber,strlen(serialNumber)+1,0); if(response < 0){error(response);return -1;} fprintf(stdout,"Accessory Identification sent\n", devVersion); response = libusb_control_transfer(handle,0x40,53,0,0,NULL,0,0); if(response < 0){error(response);return -1;} fprintf(stdout,"Attempted to put device into accessory mode\n", devVersion); if(handle != NULL) libusb_release_interface (handle, 0); for(;;){//attempt to connect to new PID, if that doesn't work try ACCESSORY_PID_ALT tries--; if((handle = libusb_open_device_with_vid_pid(NULL, VID, ACCESSORY_PID)) == NULL){ if(tries < 0){ return -1; } }else{ break; } sleep(1); } libusb_claim_interface(handle, 0); fprintf(stdout, "Interface claimed, ready to transfer data\n"); return 0; }
static int usb_find_hubs (int listing, int verbose, int busnum, int devnum, int hub) { struct libusb_device **devs; struct libusb_device *dev; int i = 0; int r; number_of_hubs_with_feature = 0; if (libusb_get_device_list( ctx, &devs ) < 0){ perror ("failed to access USB"); return 0; } while ( (dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; unsigned short dev_vid, dev_pid, dev_bcd; r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { continue; } dev_vid = libusb_le16_to_cpu(desc.idVendor); dev_pid = libusb_le16_to_cpu(desc.idProduct); dev_bcd = libusb_le16_to_cpu(desc.bcdUSB); //wmlog_msg(1, "Bus %03d Device %03d: ID %04x:%04x", libusb_get_bus_number(dev), libusb_get_device_address(dev), dev_vid, dev_pid); libusb_device_handle *uh; int print = 0; int usb3 = (dev_bcd >= 0x0300); //printf("found dev %d\n", dev->descriptor.bDeviceClass); if (desc.bDeviceClass != LIBUSB_CLASS_HUB) continue; if (listing || (verbose )) // && ((atoi (bus->dirname) == busnum && dev->devnum == devnum) // || hub == number_of_hubs_with_feature))) print = 1; if( libusb_open (dev, &uh) != 0 ) continue; /* if(libusb_detach_kernel_driver( uh, 0 )) perror("libusb_detach_kernel_driver"); if(libusb_claim_interface( uh, 0 )) perror("libusb_claim_interface");*/ if ( uh != NULL ) { if (print) printf ("Hub #%d at \tBUS:DEV\t\t%03d:%03d\n\t\tUSB VEND:PROD: \t%04x:%04x\n", number_of_hubs_with_feature, libusb_get_bus_number( dev ), libusb_get_device_address( dev ), dev_vid, dev_pid ); char buf[ sizeof(struct usb_hub_descriptor) + 2*4 ]; int len; int nport; struct usb_hub_descriptor *uhd = (struct usb_hub_descriptor *)buf; if ( (len = libusb_control_transfer ( uh, LIBUSB_ENDPOINT_IN | USB_RT_HUB, LIBUSB_REQUEST_GET_DESCRIPTOR, (usb3 ? LIBUSB_DT_SUPERSPEED_HUB : LIBUSB_DT_HUB)<<8, 0, buf, (int)sizeof ( buf ), CTRL_TIMEOUT ) ) // if( libusb_get_descriptor( uh, LIBUSB_DT_HUB, 0, buf, sizeof(buf) ) >(int)sizeof (struct usb_hub_descriptor) ) { if (!(!(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND) && (uhd->wHubCharacteristics[0] & HUB_CHAR_LPSM) >= 2)){ switch ((uhd->wHubCharacteristics[0] & HUB_CHAR_LPSM)) { case 0: if (print) fprintf (stderr, " INFO: ganged switching.\n"); break; case 1: if (print) fprintf (stderr, " INFO: individual power switching.\n"); break; case 2: case 3: if (print) fprintf (stderr, " WARN: No power switching.\n"); break; } if (print && !(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND)) fprintf (stderr, " WARN: Port indicators are NOT supported.\n"); } } else { perror ("Can't get hub descriptor."); printf( "%d\n",len ); } if( len > 0 ) { nport = buf[2]; hubs[number_of_hubs_with_feature].busnum = libusb_get_bus_number( dev ); hubs[number_of_hubs_with_feature].devnum = libusb_get_device_address( dev ); hubs[number_of_hubs_with_feature].dev = dev; hubs[number_of_hubs_with_feature].indicator_support = (uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND)? 1 : 0; hubs[number_of_hubs_with_feature].nport = nport; hubs[number_of_hubs_with_feature].usb3 = usb3; number_of_hubs_with_feature++; if (verbose) hub_port_status (uh, nport, usb3); } /* libusb_release_interface( uh,0 ); libusb_attach_kernel_driver( uh, 0); */ libusb_close (uh); } } libusb_free_device_list( devs, 1 ); return number_of_hubs_with_feature; }
int main(int argc, char * argv[]) { if (argc != 2 || argc == 2 && (strcasecmp(argv[1], "off") != 0) && (strcasecmp(argv[1], "on") != 0) && (strcasecmp(argv[1], "get") != 0)) goto usage; libusb_device_handle *handle; libusb_device *device; int ret; unsigned char buf[8]; unsigned char description[8]; struct libusb_device_descriptor desc; ret = libusb_init(NULL); if (ret < 0) { printf("failed to initialize libusb!\n"); goto exit; } libusb_set_debug(NULL, 3); handle = libusb_open_device_with_vid_pid(NULL, DEV_VID, DEV_PID); if (handle == NULL) { printf("no connected " DEV_NAME " found!\n"); libusb_exit(NULL); goto exit; } if (libusb_kernel_driver_active(handle,DEV_INTF)) libusb_detach_kernel_driver(handle, DEV_INTF); if ((ret = libusb_set_configuration(handle, DEV_CONFIG)) < 0) { printf(DEV_NAME "configuration failed!\n"); goto done; } if (libusb_claim_interface(handle, DEV_INTF) < 0) { printf(DEV_NAME " interface claim error!\n"); goto finish; } device = libusb_get_device(handle); ret = libusb_get_device_descriptor(device, &desc); if (ret < 0) { printf("failed to get " DEV_NAME " descriptor\n"); goto finish; } else { if (libusb_get_string_descriptor_ascii(handle, desc.iProduct, description, 8-1) <= 0 || strcmp(DEV_NAME, description) != 0 ) { printf("%s instead of " DEV_NAME " found!\n", description); ret = -1; goto finish; } } if (strcasecmp(argv[1], "on") == 0) { ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_1, 8, 1000); if (ret > 0) printf("OK\n"); else printf("FAIL\n"); } if (strcasecmp(argv[1], "off") == 0) { ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_2, 8, 1000); if (ret > 0) printf("OK\n"); else printf("FAIL\n"); } if (strcasecmp(argv[1], "get") == 0) { ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_3, 8, 1000); ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, 0x1, 0x300, 0, COMMAND_3, 8, 1000); if (ret > 0) printf("%d\n", COMMAND_3[1] == 0x19 ? 0 : 1); else printf("FAIL\n"); } finish: libusb_attach_kernel_driver(handle, DEV_INTF); done: libusb_close(handle); libusb_exit(NULL); if (ret > 0) exit(0); else goto exit; usage: printf("Invalid parameters!\n"); printf("Usage: mp709 <on|off|get>\n\n"); exit: exit(1); }
int main(void) { libusb_device **devs; //a list of usb devices libusb_device *dev; //target device reference struct libusb_device_handle *devh = NULL; int r; ssize_t cnt; r = libusb_init(NULL); if (r < 0) { fprintf(stderr, "failed to initialize libusb\n"); return r; } libusb_set_debug(NULL,3); // set Debug Level cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) { fprintf(stderr, "No usb devices found\n"); libusb_free_device_list(devs, 1); libusb_exit(NULL); return cnt; } dev=find_spf(devs); // find our device if(!dev) { fprintf(stderr, "Suitable Samsung SPF-87H not found\n"); return -1; } r = libusb_open(dev,&devh); // open the device handle if(r!=0) { fprintf(stderr, "Error opening device\n"); fprintf(stderr, "No mode setting possible\n"); libusb_free_device_list(devs, 1); libusb_exit(NULL); return -1; } r = libusb_claim_interface(devh, 0); // claiming the device if (r < 0) { fprintf(stderr, "usb_claim_interface error %d %s\n", r, strerror(-r)); fprintf(stderr, "trying to detach from system..."); r = libusb_detach_kernel_driver(devh, 0); if (r < 0) { fprintf(stderr, "\nDetaching from system failed, goodbye\n"); libusb_free_device_list(devs, 1); libusb_exit(NULL); return -1; } else { fprintf(stderr, " successfully\n"); r = libusb_claim_interface(devh, 0); if (r < 0) { fprintf(stderr, "usb_claim_interface error %d %s remains, giving up\n", r, strerror(-r)); libusb_free_device_list(devs, 1); libusb_exit(NULL); return -1; } else { fprintf(stderr, "claimed interface\n"); } } } else { printf("claimed interface\n"); } fprintf(stderr, "Sending Mini Monitor Mode command sequence..."); // sequence 1/9 int actual_length; actual_length=-1; unsigned char adata[0x0]; unsigned char bdata[0x00]; r = libusb_control_transfer(devh, 0xc0, //uint8_t bmRequestType, 4, //uint8_t bRequest, 0x0000, //uint16_t wValue, 0, //uint16_t wIndex, adata, //unsigned char *data 1, //uint16_t wLength, 0); //unsigned int timeout if (r < 0) { fprintf(stderr, "F0 error %d\n", r); } if ((unsigned int) r < sizeof(adata)) { fprintf(stderr, "short read (%d)\n", r); } int i; for (i=1;i<6;i++) { // sequence 2/9 - 8/9 actual_length=-1; r = libusb_control_transfer(devh, 0xc0, //uint8_t bmRequestType, 1, //uint8_t bRequest, 0x0000, //uint16_t wValue, 0, //uint16_t wIndex, bdata, //unsigned char *data 2, //uint16_t wLength, 0); //unsigned int timeout if (r < 0) { fprintf(stderr, "F0 error %d\n", r); } if ((unsigned int) r < sizeof(adata)) { fprintf(stderr, "short read (%d)\n", r); } } // sequence 9/9 actual_length=-1; r = libusb_control_transfer(devh, 0xc0, //uint8_t bmRequestType, 6, //uint8_t bRequest, 0x0000, //uint16_t wValue, 0, //uint16_t wIndex, bdata, //unsigned char *data 2, //uint16_t wLength, 0); //unsigned int timeout if (r < 0) { fprintf(stderr, "F0 error %d\n", r); } if ((unsigned int) r < sizeof(adata)) { fprintf(stderr, "short read (%d)\n", r); } fprintf(stderr, " finished.\n"); libusb_release_interface(devh, 0); libusb_close(devh); libusb_free_device_list(devs, 1); libusb_exit(NULL); fprintf(stderr, "Done.\n"); return 0; }
int main(int argc, char * argv[]) { COMMAND_ACTION[0] = (BITRATE << 3) + (REPEAT << 5); libusb_device_handle * handle; int i, ret; unsigned int level; unsigned char command[1], buf[8], channel; char param; //Arg Control if (argc == 1) { printf("Usage: %s --help\n", argv[0]); return -1; } if (strcmp (argv[1],"--help")==0) { printf("Usage: %s <command> <channel> [<level>|<RGB>]\n", argv[0]); printf(" <command>:\n"); printf(" --on - Turn channel ON\n"); printf(" --off - Turn channel OFF\n"); printf(" --switch - Switch channel ON/OFF\n"); printf(" --set - Set level for channel\n"); printf(" --bind - Bind channel\n"); printf(" --unbind - Unbind channel\n"); printf(" --load - Load preset channel\n"); printf(" --save - Save preset channel\n"); printf(" --stop - Stop changing level\n"); printf(" --color_roll - Rolling color\n"); printf(" --color_switch - Switch color\n"); printf(" --color - Set color R[0..255] G[0..255] B[0..255]\n"); printf(" --mode - Switch mode\n"); printf(" --mode_speed - Switch mode speed\n"); printf(" <channel> must be [1..32]\n"); printf(" <level> must be [0..100] - use with -set_ch\n"); printf(" <RGB> must be [0..255] [0..255] [0..255] - use with -set_color\n"); return -1; } if (argc >= 3) { if (strcmp (argv[1],"--on")==0) //Set cnannel ON { COMMAND_ACTION[1] = 2; } else if (strcmp(argv[1],"--off")==0) //Set channel OFF { COMMAND_ACTION[1] = 0; } else if (strcmp(argv[1],"--switch")==0) //Switch channel ON/OFF { COMMAND_ACTION[1] = 4; } else if (strcmp(argv[1],"--set")==0) //Set level on channel - needed arg "level" { COMMAND_ACTION[1] = 6; COMMAND_ACTION[2] = 1; // формат if (argc >= 4) { level = atoi(argv[3]); } else { printf("Missing brightness value. \nUsage: %s <command> <channel> [<level>]\n", argv[0]); return -1; } if (level>100) { level=100; } if (level<0) { level=0; } if (level>0) { level=(int)(34+(float)level*1.23); } COMMAND_ACTION[5]= level; } else if (strcmp(argv[1],"--bind")==0) //Привязать канал { COMMAND_ACTION[1] = 15; } else if (strcmp(argv[1],"--unbind")==0) //отвязать канал { COMMAND_ACTION[1] = 9; } else if (strcmp(argv[1],"--preset")==0) //Вызов записанного ранее в программе сценария освещения presetX, где X – номер сценария в программе (1…5) { // COMMAND_ACTION[1] = ?; // не реализовано } else if (strcmp(argv[1],"--load")==0) //Команда вызова записанного сценария из памяти силового блока для канала X { COMMAND_ACTION[1] = 7; } else if (strcmp(argv[1],"--save")==0) //Команда записи сценария в память силового блока для канала X { COMMAND_ACTION[1] = 8; } else if (strcmp(argv[1],"--stop")==0) //остановить регулировку { COMMAND_ACTION[1] = 10; } else if (strcmp(argv[1],"--color_roll")==0) //включение плавного перебора цвета, выключается командой 10. { COMMAND_ACTION[1] = 16; COMMAND_ACTION[2] = 4; // формат } else if (strcmp(argv[1],"--color_switch")==0) //переключение цвета { COMMAND_ACTION[1] = 17; COMMAND_ACTION[2] = 4; // формат } else if (strcmp(argv[1],"--mode")==0) //переключение режима работы { COMMAND_ACTION[1] = 18; COMMAND_ACTION[2] = 4; // формат } else if (strcmp(argv[1],"--mode_speed")==0) //переключение скорости эффекта в режиме работы { COMMAND_ACTION[1] = 19; COMMAND_ACTION[2] = 4; // формат } else if (strcmp(argv[1],"--color")==0) //Установка яркости на каждый канал независимо (R - 1, G - 2, B - 3). Уровень передается параметрами в формате 0…255 { COMMAND_ACTION[1] = 6; COMMAND_ACTION[2] = 3; // формат COMMAND_ACTION[5] = atoi(argv[3]); // R COMMAND_ACTION[6] = atoi(argv[4]); // G COMMAND_ACTION[7] = atoi(argv[5]); // B } else { printf("Command unknown\n"); return -1; } } else { printf("Unknown command.\nUsage: %s <command> <channel> [<level>]\n", argv[0]); return -1; } if (argc >= 3) { channel = atoi(argv[2]); channel--; COMMAND_ACTION[4] = channel; } else { printf("No channel number.\nUsage: %s <command> <channel> [<level>]\n", argv[0]); return -1; } //Prepare Command string libusb_init(NULL); libusb_set_debug(NULL, 3); handle = libusb_open_device_with_vid_pid(NULL, DEV_VID, DEV_PID); if (handle == NULL) { printf("No compatible devices were found.\n"); libusb_exit(NULL); return 0; } char str_desc[10]; struct libusb_device_descriptor desc; libusb_get_device_descriptor(libusb_get_device(handle), &desc); libusb_get_string_descriptor_ascii(handle, desc.iProduct, str_desc, 10); if ( (channel < 0) || (channel >= atoi(str_desc+4))) { printf("Channel number is out of range (1-%d for the %s transmitter you are using)\nUsage: %s <command> <channel> [<level>]\n", atoi(str_desc+4), str_desc, argv[0]); return -1; } if (libusb_kernel_driver_active(handle,DEV_INTF)) { libusb_detach_kernel_driver(handle, DEV_INTF); } if ((ret = libusb_set_configuration(handle, DEV_CONFIG)) < 0) { printf("USB configuration error %i.\n", ret); libusb_close(handle); libusb_exit(NULL); return 0; } if (libusb_claim_interface(handle, DEV_INTF) < 0) { printf("USB interface error.\n"); libusb_close(handle); libusb_exit(NULL); return 0; } //0x9 - номер запроса //0x300 - значение запроса - их надо получить из мониторинга if ((ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_ACTION, 8, 100)) < 0) { printf("USB data transfer error %i.\n", ret); } libusb_attach_kernel_driver(handle, DEV_INTF); libusb_close(handle); libusb_exit(NULL); return 0; }
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) { libusb_device **devs; libusb_device *dev; libusb_device_handle *handle; ssize_t num_devs; int i = 0; struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; if(hid_init() < 0) return NULL; num_devs = libusb_get_device_list(usb_context, &devs); if (num_devs < 0) return NULL; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; struct libusb_config_descriptor *conf_desc = NULL; int j, k; int interface_num = 0; int res = libusb_get_device_descriptor(dev, &desc); unsigned short dev_vid = desc.idVendor; unsigned short dev_pid = desc.idProduct; res = libusb_get_active_config_descriptor(dev, &conf_desc); if (res < 0) libusb_get_config_descriptor(dev, 0, &conf_desc); if (conf_desc) { for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { const struct libusb_interface_descriptor *intf_desc; intf_desc = &intf->altsetting[k]; if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { interface_num = intf_desc->bInterfaceNumber; /* Check the VID/PID against the arguments */ if ((vendor_id == 0x0 || vendor_id == dev_vid) && (product_id == 0x0 || product_id == dev_pid)) { struct hid_device_info *tmp; /* VID/PID match. Create the record. */ tmp = calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { cur_dev->next = tmp; } else { root = tmp; } cur_dev = tmp; /* Fill out the record */ cur_dev->next = NULL; cur_dev->path = make_path(dev, interface_num); res = libusb_open(dev, &handle); if (res >= 0) { /* Serial Number */ if (desc.iSerialNumber > 0) cur_dev->serial_number = get_usb_string(handle, desc.iSerialNumber); /* Manufacturer and Product strings */ if (desc.iManufacturer > 0) cur_dev->manufacturer_string = get_usb_string(handle, desc.iManufacturer); if (desc.iProduct > 0) cur_dev->product_string = get_usb_string(handle, desc.iProduct); #ifdef INVASIVE_GET_USAGE { /* This section is removed because it is too invasive on the system. Getting a Usage Page and Usage requires parsing the HID Report descriptor. Getting a HID Report descriptor involves claiming the interface. Claiming the interface involves detaching the kernel driver. Detaching the kernel driver is hard on the system because it will unclaim interfaces (if another app has them claimed) and the re-attachment of the driver will sometimes change /dev entry names. It is for these reasons that this section is #if 0. For composite devices, use the interface field in the hid_device_info struct to distinguish between interfaces. */ unsigned char data[256]; #ifdef DETACH_KERNEL_DRIVER int detached = 0; /* Usage Page and Usage */ res = libusb_kernel_driver_active(handle, interface_num); if (res == 1) { res = libusb_detach_kernel_driver(handle, interface_num); if (res < 0) LOG("Couldn't detach kernel driver, even though a kernel driver was attached."); else detached = 1; } #endif res = libusb_claim_interface(handle, interface_num); if (res >= 0) { /* Get the HID Report Descriptor. */ res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000); if (res >= 0) { unsigned short page=0, usage=0; /* Parse the usage and usage page out of the report descriptor. */ get_usage(data, res, &page, &usage); cur_dev->usage_page = page; cur_dev->usage = usage; } else LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res); /* Release the interface */ res = libusb_release_interface(handle, interface_num); if (res < 0) LOG("Can't release the interface.\n"); } else LOG("Can't claim interface %d\n", res); #ifdef DETACH_KERNEL_DRIVER /* Re-attach kernel driver if necessary. */ if (detached) { res = libusb_attach_kernel_driver(handle, interface_num); if (res < 0) LOG("Couldn't re-attach kernel driver.\n"); } #endif } #endif /* INVASIVE_GET_USAGE */ libusb_close(handle); } /* VID/PID */ cur_dev->vendor_id = dev_vid; cur_dev->product_id = dev_pid; /* Release Number */ cur_dev->release_number = desc.bcdDevice; /* Interface Number */ cur_dev->interface_number = interface_num; } } } /* altsettings */ } /* interfaces */ libusb_free_config_descriptor(conf_desc); } } libusb_free_device_list(devs, 1); return root; }
/*********************************************** * Acquisition Commands * ***********************************************/ void usbInScanStart_USBDIO32HS(libusb_device_handle *udev, uint8_t channel_map, uint32_t count, uint32_t retrig_count, double frequency, uint8_t packet_size, uint8_t options) { /* This command starts the input channel scan. This command will result in a bus stall if an input scan is currently running. Notes: The pacer rate is set by an internal 32-bit incrementing timer running at a base rate of 96MHz. The timer is controlled by pacer_period. A pulse will be output at the INPUT_PACER_OUT pin at every pacer_period interval regardless of mode. If pacer_period is set to 0, the device does not generate a clock. It uses the INPUT_PACER_IN pin as the pacer source. The timer will be reset and sample acquired when its value equals timer_period. The equation for calculating timer_period is: timer_period = [96MHz / (sample frequency)] - 1 The data will be returned in packets utilizing a bulk endpoint. The scan will not begin until the InScanStart command is sent (and any trigger conditions are met.) Data will be sent until reaching the specified count or a InScanStop command is sent. The packet_size parameter is used for low sampling rates to avoid delays in receiving the sampled data. The buffer will be sent, rather than waiting for the buffer to fill. This mode should not be used for high sample rates in order to avoid data loss. Pattern detection is used with the PatternDetectConfig command to set up a specified number of bits to watch, and then trigger when those bits reach the specified value. The retrigger mode option and retrig_count parameter are only used if trigger is used. This option will cause the trigger to be rearmed after retrig_count samples are acquired, with a total of count samples being returned for the entire scan. */ struct InScan_t { uint8_t channel_map; /* bit field marking which channels are in the scan bit 0: 1 = Port 0 bit 1: 1 = Port 1 bits 2-7: Reserved */ uint8_t count[4]; // the total number of scans to perform (0 for continuous scan) uint8_t retrig_count[4]; // the number of scans to perform for each trigger in retrigger mode uint8_t pacer_period[4]; // pacer timer period value (0 for external clock) uint8_t packet_size; // (number of samples - 1) to transfer at a time uint8_t options; /* bit field that controls various options: bit 0: 1 = use external trigger bit 1: 1 = use Pattern Detection Trigger bit 2: 1 = retrigger mode, 0 = normal trigger bits 3-7 Reserved */ } InScan; uint32_t pacer_period; uint8_t requesttype = (HOST_TO_DEVICE | VENDOR_TYPE | DEVICE_RECIPIENT); if (frequency == 0.0) { pacer_period = 0; // use INPUT_PACER_IN pin } else { pacer_period = rint((96.E6 / frequency) - 1); } InScan.channel_map = channel_map; memcpy(&InScan.count, &count, 4); memcpy(&InScan.retrig_count, &retrig_count, 4); memcpy(&InScan.pacer_period, &pacer_period, 4); InScan.options = options; libusb_control_transfer(udev, requesttype, IN_SCAN_START, 0x0, 0x0, (unsigned char *) &InScan, sizeof(InScan), HS_DELAY); }
FN_INTERNAL int fnusb_control(fnusb_dev *dev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t wLength) { return libusb_control_transfer(dev->dev, bmRequestType, bRequest, wValue, wIndex, data, wLength, 0); }
void usbOutScanStart_USBDIO32HS(libusb_device_handle *udev, uint8_t channel_map, uint32_t count, uint32_t retrig_count, double frequency, uint8_t options) { /* This command starts the output channel scan. This command will result in a bus stall if an input scan is currently running. Notes: The output scan operates with the host continuously transferring data from the outputs until the end of the scan. If the count parameter is 0, the scan will run until the OutScanStop command is issued by the host; if it is nonzero, the scan will stop automatically after the specified number of scans have been output. The channels in the scan are selected in the options bit field. Scans refers to the number of updates to the channels (if both channels are used, one scan is an update to both channels.) The time base is controlled by an internal 32-bit timer running at a base rate of 96MHz. The timer is controlled by pacer_period. The equation for calculating pacer_period is: pacer_period = [96MHz / (sample frequency)] - 1 The same time base is used for all channels when the scan involved multiple channels. The output data is to be sent using bulk out endpoints. The data must be in the format: low channel sample 0: [high channel sample 0] low channel sample 1: [high channel sample 1] ... low channel sample 1: [high channel sample n] The output data is written to an internal FIFO. The bulk endpoint data is only accepted if there is room in the FIFO. Output data may be sent to the FIFO before the start of the scan, and the FIFO is cleared when the OutScanClearFIFO command is received. The scan will not begin until the OutScanStart command is sent (and output data is in the FIFO). Data will be output until reaching the specified number of scans (in single execution mode) or an OutScanStop command is sent. */ struct OutScan_t { uint8_t channel_map; /* bit field marking which channels are in the scan bit 0: 1 = Port 0 bit 1: 1 = Port 1 bits 2-7: Reserved */ uint8_t count[4]; // the total number of scans to perform (0 for continuous scan) uint8_t retrig_count[4]; // the number of scans to perform for each trigger in retrigger mode uint8_t pacer_period[4]; // pacer timer period value (0 for external clock) uint8_t options; /* bit field that controls various options: bit 0: 1 = use external trigger bit 1: 1 = use Pattern Detection Trigger bit 2: 1 = retrigger mode, 0 = normal trigger bits 3-7 Reserved */ } OutScan; uint32_t pacer_period; uint8_t requesttype = (HOST_TO_DEVICE | VENDOR_TYPE | DEVICE_RECIPIENT); if (frequency == 0.0) { pacer_period = 0; // user ICLKO } else { pacer_period = rint((96.E6 / frequency) - 1); } OutScan.channel_map = channel_map; memcpy(&OutScan.count, &count, 4); memcpy(&OutScan.retrig_count, &retrig_count, 4); memcpy(&OutScan.pacer_period, &pacer_period, 4); OutScan.options = options; libusb_control_transfer(udev, requesttype, OUT_SCAN_START, 0x0, 0x0, (unsigned char *) &OutScan, sizeof(OutScan), HS_DELAY); }
int exchange_input_and_output_reports_via_control_transfers(libusb_device_handle *devh) { int bytes_received; int bytes_sent; char data_in[MAX_CONTROL_IN_TRANSFER_SIZE]; char data_out[MAX_CONTROL_OUT_TRANSFER_SIZE]; int i = 0; int result = 0; // Store example data in the output buffer for sending. // This example uses binary data. for (i=0;i < MAX_CONTROL_OUT_TRANSFER_SIZE; i++) { data_out[i]=0x40+i; } // Send data to the device. bytes_sent = libusb_control_transfer( devh, CONTROL_REQUEST_TYPE_OUT , HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT<<8)|0x00, INTERFACE_NUMBER, data_out, sizeof(data_out), TIMEOUT_MS); if (bytes_sent >= 0) { printf("Output report data sent:\n"); for(i = 0; i < bytes_sent; i++) { printf("%02x ",data_out[i]); } printf("\n"); // Request data from the device. bytes_received = libusb_control_transfer( devh, CONTROL_REQUEST_TYPE_IN , HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, INTERFACE_NUMBER, data_in, MAX_CONTROL_IN_TRANSFER_SIZE, TIMEOUT_MS); if (bytes_received >= 0) { printf("Input report data received:\n"); for(i = 0; i < bytes_received; i++) { printf("%02x ",data_in[i]); } printf("\n"); } else { fprintf(stderr, "Error receiving Input report %d\n", result); return result; } } else { fprintf(stderr, "Error sending Input report %d\n", result); return result; } return 0; }
static int upload(libusb_device_handle *handle, const char *hex) { int rc; unsigned char stop = 1; unsigned char reset = 0; FILE *image; char path[FILENAME_MAX]; #if defined(__APPLE__) if (getenv("INDIPREFIX") != nullptr) sprintf(path, "%s/Contents/Resources/DriverSupport/qhy/firmware/%s", getenv("INDIPREFIX"), hex); else sprintf(path, "/usr/local/lib/indi/DriverSupport/qhy/firmware/%s", getenv("INDIPREFIX"), hex); #else sprintf(path, "/usr/local/firmware/%s", hex); #endif image = fopen(path, "r"); if (image) { rc = libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0xA0, 0xe600, 0, &stop, 1, 3000); if (rc == 1) { unsigned char data[1023]; unsigned short data_addr = 0; unsigned data_len = 0; int first_line = 1; for (;;) { char buf[512], *cp; char tmp, type; unsigned len; unsigned idx, off; cp = fgets(buf, sizeof buf, image); if (cp == 0) { fprintf(stderr, "EOF without EOF record in %s\n", hex); break; } if (buf[0] == '#') continue; if (buf[0] != ':') { fprintf(stderr, "Invalid ihex record in %s\n", hex); break; } cp = strchr(buf, '\n'); if (cp) *cp = 0; tmp = buf[3]; buf[3] = 0; len = strtoul(buf + 1, 0, 16); buf[3] = tmp; tmp = buf[7]; buf[7] = 0; off = strtoul(buf + 3, 0, 16); buf[7] = tmp; if (first_line) { data_addr = off; first_line = 0; } tmp = buf[9]; buf[9] = 0; type = strtoul(buf + 7, 0, 16); buf[9] = tmp; if (type == 1) { break; } if (type != 0) { fprintf(stderr, "Unsupported record type %u in %s\n", type, hex); break; } if ((len * 2) + 11 > strlen(buf)) { fprintf(stderr, "Record too short in %s\n", hex); break; } if (data_len != 0 && (off != (data_addr + data_len) || (data_len + len) > sizeof data)) { rc = poke(handle, data_addr, data, data_len); if (rc < 0) break; data_addr = off; data_len = 0; } for (idx = 0, cp = buf + 9; idx < len; idx += 1, cp += 2) { tmp = cp[2]; cp[2] = 0; data[data_len + idx] = strtoul(cp, 0, 16); cp[2] = tmp; } data_len += len; } if (rc >= 0 && data_len != 0) { poke(handle, data_addr, data, data_len); } rc = libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0xA0, 0xe600, 0, &reset, 1, 3000); } fclose(image); } else { fprintf(stderr, "Can't open %s\n", hex); return 0; } return rc >= 0; }