int usbAInScanRead_USB1608FS_Plus(libusb_device_handle *udev, int nScan, int nChan, uint16_t *data, uint8_t options) { int i; int ret = -1; int nbytes = nChan*nScan*2; // number of bytes to read in 64 bit chunks int transferred; uint16_t status = 0; char value[MAX_PACKET_SIZE]; if (options & IMMEDIATE_TRANSFER_MODE) { for (i = 0; i < nbytes/2; i++) { ret = libusb_bulk_transfer(udev, LIBUSB_ENDPOINT_IN|1, (unsigned char *) &data[i], 2, &transferred, 2000); if (ret < 0) { perror("usbAInScanRead_USB1608FS_Plus: error in usb_bulk_transfer."); } if (transferred != 2) { fprintf(stderr, "usbAInScanRead_USB1608_Plus: number of bytes transferred = %d, nbytes = %d\n", transferred, nbytes); } } } else { ret = libusb_bulk_transfer(udev, LIBUSB_ENDPOINT_IN|1, (unsigned char *) data, nbytes, &transferred, HS_DELAY); if (ret < 0) { perror("usbAInScanRead_USB1608FS_Plus: error in usb_bulk_transfer."); } if (transferred != nbytes) { fprintf(stderr, "usbAInScanRead_USB1608_Plus: number of bytes transferred = %d, nbytes = %d\n", transferred, nbytes); } } status = usbStatus_USB1608FS_Plus(udev); // if nbytes is a multiple of wMaxPacketSize the device will send a zero byte packet. if ((nbytes%wMaxPacketSize) == 0 && !(status & AIN_SCAN_RUNNING)) { libusb_bulk_transfer(udev, LIBUSB_ENDPOINT_IN|1, (unsigned char *) value, 2, &ret, 100); } if ((status & AIN_SCAN_OVERRUN)) { printf("Analog AIn scan overrun.\n"); usbAInScanStop_USB1608FS_Plus(udev); usbAInScanClearFIFO_USB1608FS_Plus(udev); } return nbytes; }
int usbAInScanRead_USB1608FS_Plus(usb_dev_handle *udev, int nScan, int nChan, __u16 *data) { int ret = -1; int nbytes = nChan*nScan*2; // number of bytes to read in 64 bit chunks __u16 status; ret = usb_bulk_read(udev, USB_ENDPOINT_IN|1, (char *) data, nbytes, HS_DELAY); if (ret != nbytes) { printf("usbAInScanRead_USB1608FS_Plus: error in usb_bulk_read. ret = %d\n", ret); } status = usbStatus_USB1608FS_Plus(udev); if (status & AIN_SCAN_RUNNING) { printf("Analog In scan not done.\n"); usbAInScanStop_USB1608FS_Plus(udev); } if ((status & AIN_SCAN_OVERRUN)) { printf("Analog AIn scan overrun.\n"); } return ret; }
void usbAInScanStart_USB1608FS_Plus(libusb_device_handle *udev, uint32_t count, double frequency, uint8_t channels, uint8_t options) { /* The command starts an analog input scan. The command will result in a bus stall if an AInScan is currently running. The USB-1608FS-Plus will not generate an internal pacer faster than 100 kHz; The ADC is paced such that the pacer controls the ADC conversions. The internal pacer rate is set by an internal 32-bit timer running at a base rate of 40 MHz. The timer is controlled by pacer_period. This value is the period of the scan and the ADCs are clocked at this rate. A pulse will be output at the SYNC pin at every pacer_period interval if SYNC is configred as an output. The equation for calucating pacer_period is: pacer_period = [40 MHz / (A/D frequency)] - 1 If pacer_period is set to 0, the device does not generate an A/D clock. It uses the SYNC pin as an input and the user must provide the pacer sourece. The A/Ds acquire data on every rising edge of SYNC; the maximum allowable input frequency is 100 kHz. The data will be returned in packets untilizing a bulk endpoint. The data will be in the format: lowchannel sample 0: lowchannel + 1 sample 0: ... : hichannel sample 0 lowchannel sample 1: lowchannel + 1 sample 1: ... : hichannel sample 1 ... lowchannel sample n: lowchannel + 1 sample n: ... : hichannel sample n The scan will not begin until the AInScan Start command is sent and any trigger conditions are met. Data will be sent until reaching the specified count or an usbAInScanStop_USB1608FS_Plus() command is sent. The external trigger may be used to start the scan. If enabled, the device will wait until the appropriate trigger condition is detected than begin sampling data at the specified rate. No packets will be sent until the trigger is detected. In block transfer mode, the data is sent in 64-byte packets as soon as data is available from the A/D. In immediate transfer mode, the data is sent after each scan, resulting in packets that are 1-8 samples (2-16 bytes) long. This mode should only be used for low pacer rates, typically under 100 Hz, because overruns will occur if the rate is too high. There is a 32,768 sample FIFO, and scans under 32 kS can be performed at up to 100 kHz*8 channels without overrun. Overruns are indicated by the device stalling the bulk endpoint during the scan. The host may read the status to verify and ust clear the stall condition before further scan can be performed. */ struct AInScan_t { uint32_t count; // The total number of scans to perform (0 for continuous scan) uint32_t pacer_period; // The pacer timer period value. (0 for external clock). uint8_t channels; // bit field that selects the channels in the scan; uint8_t options; /* bit field that controls scan options: bit 0: 0 = block transfer mode, 1 = immediate transfer mode bit 1: 0 = do not output internal pacer (ignored whn using external clock for pacing). 1 = output internal pacer on SYNC bit 2-4: Trigger setting: 0: to trigger 1: Edge / rising 2: Edge / falling 3: Level / high 4: Level / low bit 5: 0 = normal A/D data, 1 = debug mode (data returned is incrementing counter) bit 6: Reserved bit 7: 0 = stall on overrun, 1 = inhibit bulk pipe stall */ uint8_t pad[2]; // align along 12 byte boundary } AInScan; uint8_t requesttype = (HOST_TO_DEVICE | VENDOR_TYPE | DEVICE_RECIPIENT); if (frequency > 500000.) frequency = 500000.; if (frequency > 0.) { AInScan.pacer_period = rint((40.E6 / frequency) - 1); } else { AInScan.pacer_period = 0; } AInScan.count = count; AInScan.channels = channels; AInScan.options = options; usbAInScanStop_USB1608FS_Plus(udev); usbAInScanClearFIFO_USB1608FS_Plus(udev); /* Pack the data into 10 bytes */ libusb_control_transfer(udev, requesttype, AIN_SCAN_START, 0x0, 0x0, (unsigned char *) &AInScan, 10, HS_DELAY); }