Example #1
0
                            // no need to be reentrant.
void usbInit_CTR(usb_dev_handle *udev)
{
  int i;
  /* This function does the following:
     1. Configure the FPGA
     2. Finds the maxPacketSize for bulk transfers
  */
  wMaxPacketSize = usb_get_max_packet_size(udev, 0);
  printf("wMaxPacketSize = %d\n", wMaxPacketSize);

  if (!(usbStatus_USB_CTR(udev) & FPGA_CONFIGURED)) {
    usbFPGAConfig_USB_CTR(udev);
    if (usbStatus_USB_CTR(udev) & FPGA_CONFIG_MODE) {
      for (i = 0; i <= (sizeof(FPGA_data) - 64); i += 64) {
	usbFPGAData_USB_CTR(udev, &FPGA_data[i], 64);
      }
      if (sizeof(FPGA_data) % 64) {
	usbFPGAData_USB_CTR(udev, &FPGA_data[i], sizeof(FPGA_data)%64);
      }
      if (!(usbStatus_USB_CTR(udev) & FPGA_CONFIGURED)) {
	printf("Error: FPGA for the USB-CTR is not configured.  status = %#x\n", usbStatus_USB_CTR(udev));
	return;
      }
    } else {
      printf("Error: could not put USB-CTR into FPGA Config Mode.  status = %#x\n", usbStatus_USB_CTR(udev));
      return;
    }
  } else {
    printf("USB-CTR FPGA configured.\n");
    return;
  }
}
// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
static int UsbReadPayload(usb_handle* h, apacket* p) {
    D("UsbReadPayload(%d)", p->msg.data_length);

    if (p->msg.data_length > MAX_PAYLOAD) {
        return -1;
    }

#if CHECK_PACKET_OVERFLOW
    size_t usb_packet_size = usb_get_max_packet_size(h);

    // Round the data length up to the nearest packet size boundary.
    // The device won't send a zero packet for packet size aligned payloads,
    // so don't read any more packets than needed.
    size_t len = p->msg.data_length;
    size_t rem_size = len % usb_packet_size;
    if (rem_size) {
        len += usb_packet_size - rem_size;
    }

    p->payload.resize(len);
    int rc = usb_read(h, &p->payload[0], p->payload.size());
    if (rc != static_cast<int>(p->msg.data_length)) {
        return -1;
    }

    p->payload.resize(rc);
    return rc;
#else
    p->payload.resize(p->msg.data_length);
    return usb_read(h, &p->payload[0], p->payload.size());
#endif
}
// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
static int UsbReadMessage(usb_handle* h, amessage* msg) {
    D("UsbReadMessage");

#if CHECK_PACKET_OVERFLOW
    size_t usb_packet_size = usb_get_max_packet_size(h);
    CHECK_GE(usb_packet_size, sizeof(*msg));
    CHECK_LT(usb_packet_size, 4096ULL);

    char buffer[4096];
    int n = usb_read(h, buffer, usb_packet_size);
    if (n != sizeof(*msg)) {
        D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg));
        return -1;
    }
    memcpy(msg, buffer, sizeof(*msg));
    return n;
#else
    return usb_read(h, msg, sizeof(*msg));
#endif
}
Example #4
0
void usbBuildGainTable_USB1608FS_Plus(libusb_device_handle *udev, float table[NGAINS_USB1608FS_PLUS][NCHAN_USB1608FS_PLUS][2])
{
  /* Builds a lookup table of calibration coefficents to translate values into voltages:
     The calibration coefficients are stored in onboard FLASH memory on the device in
     IEEE-754 4-byte floating point values.

     calibrated code = code * slope + intercept
  */

  int i, j, k;
  uint16_t address = 0x0;

  for (i = 0; i < NGAINS_USB1608FS_PLUS; i++ ) {
    for (j = 0; j < NCHAN_USB1608FS_PLUS; j++) {
      for (k = 0; k < 2; k++) {
	usbReadCalMemory_USB1608FS_Plus(udev, address, 4, (uint8_t *) &table[i][j][k]);
	address += 4;
      }
    }
  }

  wMaxPacketSize = usb_get_max_packet_size(udev, 0);
}
Example #5
0
int main (int argc, char **argv)
{
  libusb_device_handle *udev = NULL;
  struct tm calDate;

  float table_DE_AIN[NGAINS][NCHAN_DE][2];
  float table_SE_AIN[NCHAN_SE][2];

  int ch;
  int i, j, k, m;
  uint8_t options;
  char serial[9];
  uint8_t channel, channels;
  uint8_t range;
  uint8_t ranges[4] = {0, 0, 0, 0};
  uint16_t value;
  uint32_t count;
  double frequency, voltage;
  int ret;
  uint16_t dataAIn[8*512];  // holds 16 bit unsigned analog input data
  uint16_t data;
  int nchan, repeats;

  udev = NULL;

  ret = libusb_init(NULL);
  if (ret < 0) {
    perror("usb_device_find_USB_MCC: Failed to initialize libusb");
    exit(1);
  }

  if ((udev = usb_device_find_USB_MCC(BTH1208LS_PID, NULL))) {
    printf("Success, found a BTH 1208LS!\n");
  } else {
    printf("Failure, did not find a BTH 1208LS!\n");
    return 0;
  }

  // some initialization
  //print out the wMaxPacketSize.  Should be 64
  printf("wMaxPacketSize = %d\n", usb_get_max_packet_size(udev,0));

  usbBuildGainTable_DE_BTH1208LS(udev, table_DE_AIN);
  usbBuildGainTable_SE_BTH1208LS(udev, table_SE_AIN);
  for (i = 0; i < NGAINS; i++ ) {
    for (j = 0; j < NCHAN_DE; j++) {
      printf("Calibration Table: Range = %d Channel = %d Slope = %f   Offset = %f\n", 
	     i, j, table_DE_AIN[i][j][0], table_DE_AIN[i][j][1]);
    }
  }
  printf("\n");
  for (i = 0; i < NCHAN_SE; i++ ) {
    printf("Calibration Single Ended Table: Channel = %d Slope = %f   Offset = %f\n", 
	   i, table_SE_AIN[i][0], table_SE_AIN[i][1]);
  }

  usbCalDate_BTH1208LS(udev, &calDate);
  printf("\n");
  printf("MFG Calibration date = %s\n", asctime(&calDate));

  while(1) {
    printf("\nBTH 1208LS Testing\n");
    printf("----------------\n");
    printf("Hit 'b' to blink\n");
    printf("Hit 'c' to test counter\n");
    printf("Hit 'd' to test digitial IO\n");
    printf("Hit 'i' to test Analog Input\n");
    printf("Hit 'I' to test Analog Input Scan\n");
    printf("Hit 'o' to test Analog Output\n");
    printf("Hit 'x' to test Analog Input Scan (Multi-channel)\n");
    printf("Hit 'r' to reset the device\n");
    printf("Hit 's' to get serial number\n");
    printf("Hit 'S' to get Status\n");
    printf("Hit 'e' to exit\n");

    while((ch = getchar()) == '\0' || ch == '\n');
    switch(ch) {
      case 'b': /* test to see if LED blinks */
        printf("Enter number or times to blink: ");
        scanf("%hhd", &options);
        usbBlinkLED_BTH1208LS(udev, options);
	break;
      case 'e':
        cleanup_BTH1208LS(udev);
        return 0;
      case 'c':
        usbCounterReset_BTH1208LS(udev);
        printf("Connect AO 0 to CTR.\n");
        toContinue();
        for (i = 0; i < 100; i++) {                   // toggle
    	  usbAOut_BTH1208LS(udev, 0, 4095);
	  usbAOut_BTH1208LS(udev, 0, 0);
        }
	usbCounter_BTH1208LS(udev, &count);
        printf("Count = %d.  Should read 100.\n", count);
        break;
      case 'i':
	printf("Input channel DE [0-3]: ");
	scanf("%hhd", &channel);
        printf("Input range [0-7]: ");
	scanf("%hhd", &range);
	for (i = 0; i < 20; i++) {
	  usbAIn_BTH1208LS(udev, channel, DIFFERENTIAL, range, &value);
	  value = rint(value*table_DE_AIN[range][channel][0] + table_DE_AIN[range][channel][1]);
  	  printf("Range %d  Channel %d   Sample[%d] = %#x Volts = %lf\n",
		   range, channel,  i, value, volts_BTH1208LS(value, range));
	  usleep(50000);	  
	}
        break;
      case 'I':
	printf("Testing BTH-1208lS Analog Input Scan.\n");
	usbAInScanStop_BTH1208LS(udev);
        printf("Enter number of scans (less than 512): ");
        scanf("%d", &count);
	printf("Input channel 0-3: ");
        scanf("%hhd", &channel);
        printf("Enter sampling frequency [Hz]: ");
	scanf("%lf", &frequency);
        printf("Enter Range [0-7]: ");
        scanf("%hhd", &range);
        ranges[channel] = range;
	if (frequency > 100.) {
	  options = DIFFERENTIAL_MODE;
	} else {
	  options = DIFFERENTIAL_MODE | IMMEDIATE_TRANSFER_MODE;
	}
	usbAInScanStop_BTH1208LS(udev);
	usbAInScanClearFIFO_BTH1208LS(udev);
        usbAInScanConfig_BTH1208LS(udev, ranges);
	memset(dataAIn, 0x0, sizeof(dataAIn));
	sleep(1);
	usbAInScanConfigR_BTH1208LS(udev, ranges);
	for (i = 0; i < 4; i++) {
	  printf("Channel %d     range %d\n", i, ranges[i]);
	}
	usbAInScanStart_BTH1208LS(udev, count, 0x0, frequency, (0x1<<channel), options);
	ret = usbAInScanRead_BTH1208LS(udev, count, dataAIn, options);
	printf("Number samples read = %d\n", ret/2);
	for (i = 0; i < count; i++) {
	  dataAIn[i] = rint(dataAIn[i]*table_DE_AIN[range][channel][0] + table_DE_AIN[range][channel][1]);
          printf("Range %d Channel %d  Sample[%d] = %#x Volts = %lf\n", range, channel,
		 i, dataAIn[i], volts_BTH1208LS(dataAIn[i], range));
	}
        break;
      case 'x':
        printf("Testing BTH-1208LS Multi-Channel Analog Input Scan.\n");
        usbAInScanStop_BTH1208LS(udev);
        printf("Enter number of channels (1-4) :");
        scanf("%d", &nchan);
        printf("Enter number of scans (less than 512): ");
        scanf("%d", &count);
        printf("Enter number of repeats: ");
        scanf("%d", &repeats);
	printf("Enter sampling frequency: ");
        scanf("%lf", &frequency);
        // Build bitmap for the first nchan in channels.
        channels = 0;
        for (i = 0; i < nchan; i++) {
	  channels |= (1 << i);
	}
        frequency = 10000.;
	options = DIFFERENTIAL_MODE;
        // Always use BP_20V to make it easy (BP_20V is 0...)
        memset(ranges, BP_20V, sizeof(ranges));
        usbAInScanConfig_BTH1208LS(udev, ranges);
        // Run a loop for the specified number of repeats and
        // show the results...
        for (m = 0; m < repeats; m++) {
	  printf("\n\n---------------------------------------");
	  printf("\nrepeat: %d\n", m);
	  usbAInScanStart_BTH1208LS(udev, count*nchan, 0x0, frequency, channels, options);
	  ret = usbAInScanRead_BTH1208LS(udev, count*nchan,  dataAIn, options);
	  printf("Number samples read = %d\n", ret/2);
	  if (ret != nchan*count*2) { /* if (ret != count*2) */
	    printf("***ERROR***  ret = %d   count = %d  nchan = %d\n", ret, count, nchan);
	    continue;
	  } 
	  for (i = 0; i < count/nchan; i++) {
	    printf("%6d", i);
	    for (j = 0; j < nchan; j++)	{
	      k = i*nchan + j;
	      data = rint(dataAIn[k]*table_DE_AIN[range][j][0] + table_DE_AIN[range][j][1]);
	      printf(", %8.4f", volts_BTH1208LS(data, range));
	    } /* for (j - 0; j < 8, j++) */
	    printf("\n");
	  } /* for (i = 0; i < count; i++) */
	} /* for (m = 0; m < repeats; m++) */
	printf("\n\n---------------------------------------");
	break;
      case 'r':
        usbReset_BTH1208LS(udev);
        break;
      case 'o':
        printf("Test Analog Output\n");
        printf("Enter Channel [0-1] ");
        scanf("%hhd", &channel);
        printf("Enter voltage [0-2.5V]: ");
	scanf("%lf", &voltage);
        value = voltage * 4095 / 2.5;
	usbAOut_BTH1208LS(udev, channel, value);
	value = usbAOutR_BTH1208LS(udev, channel);
	printf("Analog Output Voltage = %f V\n", volts_BTH1208LS(value, UP_2_5V));
        break;
      case 's':
        usbGetSerialNumber_BTH1208LS(udev, serial);
        printf("Serial number = %s\n", serial);
        break;
      case 'S':
        printf("Status = %#x\n", usbStatus_BTH1208LS(udev));
	break;
      default:
        break;
    }
  }
}
Example #6
0
int main (int argc, char **argv)
{
  int flag;
  libusb_device_handle *udev = NULL;
  struct tm calDate;
  int ch;
  int temp;
  int transferred;
  int i, j;
  int tc_type;
  uint8_t input;
  uint8_t channel, gain, rate, mode, flags;
  char serial[9];
  uint16_t version[4];
  float cjc[2];
  int queue_index;
  int data;
  int ret;
  double table_AIN[NGAINS_2408][2];
  double table_AO[NCHAN_AO_2408][2];
  float table_CJCGrad[nCJCGrad_2408];
  AInScanQueue scanQueue;
  int usb2408_2AO = FALSE;
  double voltage;
  double temperature;
  double frequency;
  double sine[512];
  int16_t sdata[512];  // holds 16 bit signed analog output data
  int32_t idata[512];  // holds 24 bit signed analog input data
  uint8_t status;
  uint16_t depth;
  uint16_t count;

  udev = NULL;

  ret = libusb_init(NULL);
  if (ret < 0) {
    perror("usb_device_find_USB_MCC: Failed to initialize libusb");
    exit(1);
  }

  if ((udev = usb_device_find_USB_MCC(USB2408_PID, NULL))) {
    printf("Success, found a USB 2408!\n");
  } else if ((udev = usb_device_find_USB_MCC(USB2408_2AO_PID, NULL))) {
    printf("Success, found a USB 2408_2AO!\n");
    usb2408_2AO = TRUE;
  } else {
    printf("Failure, did not find a USB 2408 or 2408_2AO!\n");
    return 0;
  }

  //print out the wMaxPacketSize.  Should be 64
  printf("wMaxPacketSize = %d\n", usb_get_max_packet_size(udev,0));

  usbBuildGainTable_USB2408(udev, table_AIN);
  for (i = 0; i < NGAINS_2408; i++) {
    printf("Gain: %d    Slope = %lf    Offset = %lf\n", i, table_AIN[i][0], table_AIN[i][1]);
  }

  printf("\n");
  usbBuildCJCGradientTable_USB2408(udev, table_CJCGrad);
  for (i = 0; i < nCJCGrad_2408; i++) {
    printf("Ch: %d    CJC gradient = %lf\n", i, table_CJCGrad[i]);
  }

  if (usb2408_2AO) {
    usbBuildGainTable_USB2408_2AO(udev, table_AO);
    printf("\n");
    for (i = 0; i < NCHAN_AO_2408; i++) {
      printf("VDAC%d:    Slope = %lf    Offset = %lf\n", i, table_AO[i][0], table_AO[i][1]);
    }
  }

  usbCalDate_USB2408(udev, &calDate);
  printf("\n");
  printf("MFG Calibration date = %s\n", asctime(&calDate));

  while(1) {
    printf("\nUSB 2408 Testing\n");
    printf("----------------\n");
    printf("Hit 'b' to blink\n");
    printf("Hit 'c' to test counter\n");
    printf("Hit 'C' to test continuous sampling at 1000 Hz.\n");
    printf("Hit 'd' to test digitial IO\n");
    printf("Hit 'i' to test Analog Input\n");
    printf("Hit 'I' to test Analog Input Scan\n");
    printf("Hit 'j' read CJC sensors.\n");
    printf("Hit 'o' to test Analog Output\n");
    printf("Hit 'O' to test Analog Output Scan\n");
    printf("Hit 'r' to reset the device\n");
    printf("Hit 's' to get serial number\n");
    printf("Hit 'S' to get Status\n");
    printf("Hit 't' to get TC temperature\n");
    printf("Hit 'v' to get version numbers\n");
    printf("Hit 'e' to exit\n");

    while((ch = getchar()) == '\0' || ch == '\n');

    switch(ch) {
      case 'b': /* test to see if led blinks */
        printf("Enter number or times to blink: ");
	scanf("%d", &temp);
        usbBlink_USB2408(udev, temp);
        break;
      case 'c':
        usbCounterInit_USB2408(udev, COUNTER0);
        printf("Connect DO0 to CTR0\n");
        toContinue();
        for (i = 0; i < 100; i++) {
	  usbDOut_USB2408(udev, 0x0, 0);
	  usbDOut_USB2408(udev, 0xff, 0);
        }
        printf("Count = %d.  Should read 100.\n", usbCounter_USB2408(udev, COUNTER0));
        break;
      case 'C':
	printf("Testing USB-2408 Analog Input Scan in Continuous mode 8 channels\n");
	printf("Hit any key to exit\n");
	usbAInScanStop_USB2408(udev);
	count = 0;        // for continuous mode
	rate = HZ1000;
	mode = DIFFERENTIAL;
	scanQueue.count = 8;
	for (i = 0; i < 8; i++ ) {
	  scanQueue.queue[i].channel = i;
	  scanQueue.queue[i].mode = mode;
	  scanQueue.queue[i].range = BP_10V;
	  scanQueue.queue[i].rate = rate;
	}
	usbAInScanQueueWrite_USB2408(udev, &scanQueue);
	
	for (i = 0; i < 512; i++) {
	  idata[i] = 0xdeadbeef;
	}
	usbAInScanStart_USB2408(udev, 100, count, 15);
	
	flag = fcntl(fileno(stdin), F_GETFL);
	fcntl(0, F_SETFL, flag | O_NONBLOCK);
        j = 0;
	do {
          ret = libusb_bulk_transfer(udev, LIBUSB_ENDPOINT_IN|1, (unsigned char *) idata, 512*4, &transferred, 1000);
	  if (ret < 0) {
	    perror(" Continuous scan error in libusb_bulk_transfer");
	  }
	  for (i = 0; i < 512; i++) {
	    queue_index = idata[i] >> 24;                         // MSB of data contains the queue index;
	    gain = scanQueue.queue[queue_index].range;
	    channel = scanQueue.queue[queue_index].channel;
	    data = int24ToInt(idata[i]);                          // convert from signed 24 to signed 32
	    data = data*table_AIN[gain][0] + table_AIN[gain][1];  // correct for non-linearities in A/D
	    printf("Sample %d Index %d Channel %d   gain = %d raw = %#x  voltage = %f\n",
		   i, queue_index, channel, gain, idata[i], volts_USB2408(gain, data));
	  }
	  // printf("bulk transfer = %d\n", j); // Each transfer contains 512 samples or 64 scans
	  j++;
	} while (!isalpha(getchar()));
	fcntl(fileno(stdin), F_SETFL, flag);
        usbAInScanStop_USB2408(udev);
	usbReset_USB2408(udev);
        libusb_close(udev);
        sleep(2); // let things settle down.
        break;
      case 'd':
        printf("\nTesting Digital I/O....\n");
        do {
  	  printf("Enter a number [0-0xff] : " );
  	  scanf("%x", &temp);
	  usbDOut_USB2408(udev, (uint8_t)temp, 0);
	  input = usbDOutR_USB2408(udev, 0);
	  printf("The number you entered = %#x\n\n",input);
  	  input = usbDIn_USB2408(udev, 0);
  	  printf("The number you entered = %#x\n\n",input);
	} while (toContinue());
	break;
      case 'e':
        cleanup_USB2408(udev);
        return 0;
      case 'i':
        printf("Input channel [0-7]: ");
        scanf("%hhd", &channel);
	printf("Gain Range for channel %d:  1 = 10V  2 = 5V  2 = 2.5V Differential: ", channel);
	while((ch = getchar()) == '\0' || ch == '\n');
	switch(ch) {
  	  case '1': gain = BP_10V; break;
	  case '2': gain = BP_5V; break;
	  case '3': gain = BP_2_5V; break;
	  default:  gain = BP_10V; break;
	}
	rate = HZ1000;
	mode = DIFFERENTIAL;
	for (i = 0; i < 20; i++) {
  	  data = usbAIn_USB2408(udev, channel, mode, gain, rate, &flags);
	  data = data*table_AIN[gain][0] + table_AIN[gain][1];
	  printf("Channel %d  Sample[%d] = %#x  Volts = %lf\n", channel, i, data,
		 volts_USB2408(gain, data));
	  usleep(50000);
	}
	break;
      case 'I':
        printf("Testing USB-2408 Analog Input Scan\n");
	usbAInScanStop_USB2408(udev);
	printf("Input channel [0-7]: ");
        scanf("%hhd", &channel);
	printf("Input the number of scans (1-512): ");
	scanf("%hd", &count);
	printf("Gain Range for channel %d: 1 = 10V  2 = 5V  3 = 2.5V Differential: ", channel);
	while((ch = getchar()) == '\0' || ch == '\n');
	switch(ch) {
  	  case '1': gain = BP_10V; break;
	  case '2': gain = BP_5V; break;
	  case '3': gain = BP_2_5V; break;
	  default:  gain = BP_10V; break;
	}
	rate = HZ1000;
	mode = DIFFERENTIAL;
	scanQueue.count = 1;
	scanQueue.queue[0].channel = channel;
	scanQueue.queue[0].mode = mode;
	scanQueue.queue[0].range = gain;
	scanQueue.queue[0].rate = rate;

	for (i = 0; i < 512; i++) {
	  idata[i] = 0xdeadbeef;
	}

	usbAInScanQueueWrite_USB2408(udev, &scanQueue);
	usbAInScanStart_USB2408(udev, 900, count, 15);
	usbAInScanRead_USB2408(udev, count, 1, idata);
	usbAInScanStop_USB2408(udev);

	usbAInScanQueueRead_USB2408(udev, &scanQueue);
	for (i = 0; i < count; i++) {
	  queue_index = idata[i] >> 24;                         // MSB of data contains the queue index;
	  gain = scanQueue.queue[queue_index].range;
	  channel = scanQueue.queue[queue_index].channel;
	  data = int24ToInt(idata[i]);                          // convert from signed 24 to signed 32
  	  data = data*table_AIN[gain][0] + table_AIN[gain][1];  // correct for non-linearities in A/D
	  printf("Sample %d Index %d Channel %d   gain = %d raw = %#x  voltage = %f\n",
		 i, queue_index, channel, gain, idata[i], volts_USB2408(gain, data));
	}
	break; 

      case 'j':
	usbCJC_USB2408(udev, cjc);
	for (i = 0; i < 2; i++) {
	  printf("CJC sensor[%d] = %f degree C.\n", i, cjc[i]);
	}
	break;
      case 'O':
        if (!usb2408_2AO) {
	  printf("Analog output only on the USB-2408-2AO model.\n");
	  break;
	}
        channel = 0;
	printf("Test of Analog Output Scan.\n");
	printf("Hook scope up to VDAC 0\n");
	printf("Enter desired frequency of sine wave [Hz]: ");
	scanf("%lf", &frequency);
	for (i = 0; i < 512; i ++) {
	  sine[i] = 10*sin(2.*M_PI*i/128.);
	}
	voltsTos16_USB2408_2AO(sine, sdata, 512, table_AO[channel]);
	usbAOutScanStop_USB2408_2AO(udev);
	usbAOutScanStart_USB2408_2AO(udev, 128.*frequency, 0, (1 << channel));
	printf("Hit \'s <CR>\' to stop ");
	flag = fcntl(fileno(stdin), F_GETFL);
	fcntl(0, F_SETFL, flag | O_NONBLOCK);
	do {
	  libusb_bulk_transfer(udev, LIBUSB_ENDPOINT_OUT|1, (unsigned char *) sdata, sizeof(sdata), &transferred, 1000);
	} while (!isalpha(getchar()));
	fcntl(fileno(stdin), F_SETFL, flag);
	usbAOutScanStop_USB2408_2AO(udev);
	break;
      case 'o':
	if (!usb2408_2AO) {
	  printf("Analog output only on the USB-2408-2AO model.\n");
	  break;
	}
        printf("output value on VDAC 0\n");
        do {
	  printf("Enter output voltage [-10 to 10]: ");
	  scanf("%lf", &voltage);
	  usbAOut_USB2408_2AO(udev, 0, voltage, table_AO);
        } while (toContinue());
	break;
      case 'r':
	usbReset_USB2408(udev);
	return 0;
	break;
      case 's':
        usbGetSerialNumber_USB2408(udev, serial);
        printf("Serial number = %s\n", serial);
        break;
      case 'S':
        printf("Status = %#x\n", usbStatus_USB2408(udev));
	status = usbAInScanStatus_USB2408(udev, &depth);
        printf("Analog In status = %#x, depth = %d\n", status, depth);

        break;
      case 't':
	printf("Input channel [0-7]: ");
        scanf("%hhd", &channel);
	printf("Input Thermocouple type [J,K,R,S,T,N,E,B]: ");
	while((ch = getchar()) == '\0' || ch == '\n');
	switch(ch) {
	  case 'J': 
  	  case 'j':
	    tc_type = TYPE_J; break;
  	  case 'K': 
  	  case 'k': 
	    tc_type = TYPE_K; break;
	  case 'R':
	  case 'r':
	    tc_type = TYPE_R; break;
  	  case 'S':
	  case 's':
	    tc_type = TYPE_S; break;
   	  case 'T':
	  case 't':
	    tc_type = TYPE_T; break;
     	  case 'N':
	  case 'n':
	    tc_type = TYPE_N; break;
       	  case 'E':
  	  case 'e':
	    tc_type = TYPE_E; break;
	  case 'B':
 	  case 'b':
	    tc_type = TYPE_B; break;
	  default: tc_type = TYPE_J; break;
	}
	temperature = tc_temperature_USB2408(udev, tc_type, channel);
	printf("Temperature = %.3f C  %.3f F\n", temperature, temperature*9./5. + 32.);
        break;
      case 'v':
        usbGetVersion_USB2408(udev, version);
	printf("USB micro firmware version = %x.%2.2x\n", version[0]/0x100, version[0]%0x100);
	printf("USB update firmware version = %x.%2.2x\n", version[1]/0x100, version[1]%0x100);
	printf("isolated micro firmware version = %x.%2.2x\n", version[2]/0x100, version[2]%0x100);
	printf("isolated update firmware version = %x.%2.2x\n", version[3]/0x100, version[3]%0x100);
	break;
      default:
        break;
    }
  }
}
int main (int argc, char **argv)
{
  libusb_device_handle *udev = NULL;
  struct tm calDate;
  
  float table_DE_AIN[NGAINS_USB1208FS_PLUS][NCHAN_DE][2];
  float table_SE_AIN[NCHAN_SE][2];

  int ch;
  int i, j, k, m;
  int flag;
  int device;
  uint8_t input;
  int temp;
  uint8_t options;
  char serial[9];
  uint8_t channel, channels;
  uint8_t range;
  uint8_t ranges[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  uint16_t value;
  uint32_t count;
  double frequency, voltage;
  int ret;
  uint16_t dataAIn[8*512];  // holds 16 bit unsigned analog input data
  uint16_t dataAOut[128];   // holds 12 bit unsigned analog input data
  uint16_t data;
  int nchan, repeats;
  int transferred;

  udev = NULL;

  ret = libusb_init(NULL);
  if (ret < 0) {
    perror("usb_device_find_USB_MCC: Failed to initialize libusb");
    exit(1);
  }

  if ((udev = usb_device_find_USB_MCC(USB1208FS_PLUS_PID, NULL))) {
    printf("Success, found a USB 1208FS-Plus!\n");
    device = USB1208FS_PLUS_PID;
  } else if ((udev = usb_device_find_USB_MCC(USB1408FS_PLUS_PID, NULL))) {
    printf("Success, found a USB 1408FS-Plus!\n");
    device = USB1408FS_PLUS_PID;
  } else {
    printf("Failure, did not find a USB 1208FS-Plus/ USB 1408FS-Plus!\n");
    return 0;
  }

  // some initialization
  //print out the wMaxPacketSize.  Should be 64
  printf("wMaxPacketSize = %d\n", usb_get_max_packet_size(udev,0));

  usbBuildGainTable_DE_USB1208FS_Plus(udev, table_DE_AIN);
  usbBuildGainTable_SE_USB1208FS_Plus(udev, table_SE_AIN);
  for (i = 0; i < NGAINS_USB1208FS_PLUS; i++ ) {
    for (j = 0; j < NCHAN_DE; j++) {
      printf("Calibration Table: Range = %d Channel = %d Slope = %f   Offset = %f\n", 
	     i, j, table_DE_AIN[i][j][0], table_DE_AIN[i][j][1]);
    }
  }
  for (i = 0; i < NCHAN_SE; i++ ) {
    printf("Calibration Single Ended Table: Channel = %d Slope = %f   Offset = %f\n", 
	   i, table_SE_AIN[i][0], table_SE_AIN[i][1]);
  }

  usbCalDate_USB1208FS_Plus(udev, &calDate);
  printf("\n");
  printf("MFG Calibration date = %s\n", asctime(&calDate));
  
  while(1) {
    printf("\nUSB 1208FS-Plus/USB 1408FS-Plus Testing\n");
    printf("----------------\n");
    printf("Hit 'b' to blink\n");
    printf("Hit 'c' to test counter\n");
    printf("Hit 'd' to test digitial IO\n");
    printf("Hit 'i' to test Analog Input\n");
    printf("Hit 'I' to test Analog Input Scan\n");
    printf("Hit 'o' to test Analog Output\n");
    printf("Hit 'O' to test Analog Scan Output\n");
    printf("Hit 'x' to test Analog Input Scan (Multi-channel)\n");
    printf("Hit 'r' to reset the device\n");
    printf("Hit 's' to get serial number\n");
    printf("Hit 'S' to get Status\n");
    printf("Hit 'e' to exit\n");

    while((ch = getchar()) == '\0' || ch == '\n');
    switch(ch) {
      case 'b': /* test to see if LED blinks */
        printf("Enter number or times to blink: ");
        scanf("%hhd", &options);
        usbBlink_USB1208FS_Plus(udev, options);
	break;
      case 'c':
        usbCounterInit_USB1208FS_Plus(udev);
        printf("Connect DIO Port A0 to CTR0\n");
	usbDTristateW_USB1208FS_Plus(udev, PORTA, 0x0);
	usbDLatchW_USB1208FS_Plus(udev, PORTA, 0x0);  // put pin 0 into known state
        toContinue();
        for (i = 0; i < 100; i++) {                   // toggle
	  usbDLatchW_USB1208FS_Plus(udev, PORTA, 0x1);
	  usbDLatchW_USB1208FS_Plus(udev, PORTA, 0x0);
        }
        printf("Count = %d.  Should read 100.\n", usbCounter_USB1208FS_Plus(udev));
        break;      
      case 'd':
        printf("\nTesting Digital I/O...\n");
	printf("connect PORTA <--> PORTB\n");
	usbDTristateW_USB1208FS_Plus(udev, PORTA, 0x0);
	printf("Digital Port Tristate Register = %#x\n", usbDTristateR_USB1208FS_Plus(udev, PORTA));
	do {
          printf("Enter a  number [0-0xff] : " );
          scanf("%x", &temp);
          usbDLatchW_USB1208FS_Plus(udev, PORTA, (uint8_t)temp);
	  temp = usbDLatchR_USB1208FS_Plus(udev, PORTA);
          input = usbDPort_USB1208FS_Plus(udev, PORTB);
          printf("The number you entered = %#x   Latched value = %#x\n\n",input, temp);
        } while (toContinue());
        break;
      case 'i':
	printf("Input channel [0-7]: ");
	scanf("%hhd", &channel);
        printf("Input range [0-7]: ");
	scanf("%hhd", &range);
	for (i = 0; i < 20; i++) {
	  value = usbAIn_USB1208FS_Plus(udev, channel, DIFFERENTIAL, range);
	  value = rint(value*table_DE_AIN[range][channel][0] + table_DE_AIN[range][channel][1]);
          if (device == USB1208FS_PLUS_PID) {
  	    printf("Range %d  Channel %d   Sample[%d] = %#x Volts = %lf\n",
		   range, channel,  i, value, volts_USB1208FS_Plus(value, range));
	  } else {
  	    printf("Range %d  Channel %d   Sample[%d] = %#x Volts = %lf\n",
		   range, channel,  i, value, volts_USB1408FS_Plus(value, range));

	  }
	  usleep(50000);	  
	}
        break;
      case 'I':
	printf("Testing USB-1208FS_Plus Analog Input Scan.\n");
	usbAInScanStop_USB1208FS_Plus(udev);
        printf("Enter number of scans (less than 512): ");
        scanf("%d", &count);
	printf("Input channel 0-7: ");
        scanf("%hhd", &channel);
        printf("Enter sampling frequency [Hz]: ");
	scanf("%lf", &frequency);
        printf("Enter Range [0-7]: ");
        scanf("%hhd", &range);
        ranges[channel] = range;
	if (frequency > 100.) {
	  options = DIFFERENTIAL_MODE;
	} else {
	  options = DIFFERENTIAL_MODE | IMMEDIATE_TRANSFER_MODE;
	}
	usbAInScanStop_USB1208FS_Plus(udev);
	usbAInScanClearFIFO_USB1208FS_Plus(udev);
        usbAInScanConfig_USB1208FS_Plus(udev, ranges);
	memset(dataAIn, 0x0, sizeof(dataAIn));
	sleep(1);
        usbAInScanConfigR_USB1208FS_Plus(udev, ranges);
        for (i = 0; i < 4; i++) {
          printf("Channel %d     range %d\n", i, ranges[i]);
	}
	usbAInScanStart_USB1208FS_Plus(udev, count, 0x0, frequency, (0x1<<channel), options);
	ret = usbAInScanRead_USB1208FS_Plus(udev, count, 1, dataAIn, options);
	printf("Number samples read = %d\n", ret/2);
	for (i = 0; i < count; i++) {
	  dataAIn[i] = rint(dataAIn[i]*table_DE_AIN[range][channel][0] + table_DE_AIN[range][channel][1]);
          if (device == USB1208FS_PLUS_PID) {
	    printf("Range %d Channel %d  Sample[%d] = %#x Volts = %lf\n", range, channel,
		   i, dataAIn[i], volts_USB1208FS_Plus(dataAIn[i], range));
	  } else {
	    printf("Range %d Channel %d  Sample[%d] = %#x Volts = %lf\n", range, channel,
		   i, dataAIn[i], volts_USB1408FS_Plus(dataAIn[i], range));
	  }
	}
        break;
      case 'o':
        printf("Test Analog Output\n");
        printf("Enter Channel [0-1] ");
        scanf("%hhd", &channel);
        printf("Enter voltage: ");
	scanf("%lf", &voltage);
        value = voltage * 4096 / 5;
	usbAOut_USB1208FS_Plus(udev, channel, value);
	value = usbAOutR_USB1208FS_Plus(udev, channel);
	printf("Analog Output Voltage = %f V\n", volts_USB1208FS_Plus(value, UP_5V));
        break;
      case 'O':
        printf("Test of Analog Output Scan. \n");
        printf("Hook scope up to VDAC 0\n");
        printf("Enter desired frequency of sine wave [Hz]: ");
        scanf("%lf", &frequency);
	frequency *= 2.;

        for (i = 0; i < 32; i++) {
          dataAOut[4*i] =   0x0;
	  dataAOut[4*i+1] = 0x800;
	  dataAOut[4*i+2] = 0xfff;
	  dataAOut[4*i+3] = 0xcff;
	}
	usbAOutScanStop_USB1208FS_Plus(udev);
        options = 0x3;   // output channel 0 and 1 output scan
	usbAOutScanStart_USB1208FS_Plus(udev, 0, frequency, options);
	printf("Hit \'s <CR>\' to stop ");
	flag = fcntl(fileno(stdin), F_GETFL);
	fcntl(0, F_SETFL, flag | O_NONBLOCK);
	do {
	  if (libusb_bulk_transfer(udev, LIBUSB_ENDPOINT_OUT|2, (unsigned char *) dataAOut, sizeof(dataAOut), &transferred, 1000) < 0) {
	    perror("usb_bulk_transfer error in AOutScan.");
	  }
	  //	  usb_bulk_write(udev, USB_ENDPOINT_OUT|2, (char *) dataAOut, 0x0, 400);
	} while (!isalpha(getchar()));
	fcntl(fileno(stdin), F_SETFL, flag);
	usbAOutScanStop_USB1208FS_Plus(udev);
	break;
      case 'x':
        printf("Testing USB-1208FS_Plus Mult-Channel Analog Input Scan.\n");
        usbAInScanStop_USB1208FS_Plus(udev);
        printf("Enter number of channels (1-8) :");
        scanf("%d", &nchan);
        printf("Enter number of scans (less than 512): ");
        scanf("%d", &count);
        printf("Enter number of repeats: ");
        scanf("%d", &repeats);
        // Build bitmap for the first nchan in channels.
        channels = 0;
        for (i = 0; i < nchan; i++)
	  channels |= (1 << i);
        printf ("channels: %02X   count:%d\n", channels, count);
        frequency = 10000.;
        // Always use BP_20V to make it easy (BP_20V is 0...)
        range = 0;
        memset(ranges, 0, sizeof(ranges));
        usbAInScanConfig_USB1208FS_Plus(udev, ranges);
        // Run a loop for the specified number of repeats and
        // show the results...
        for (m = 0; m < repeats; m++) {
	  printf("\n\n---------------------------------------");
	  printf("\nrepeat: %d\n", m);
	  usbAInScanStart_USB1208FS_Plus(udev, count, 0x0, frequency, channels, 0);
	  ret = usbAInScanRead_USB1208FS_Plus(udev, count, nchan, dataAIn, 0);
	  printf("Number samples read = %d\n", ret/2);
	  if (ret != count * nchan * 2) {
	    printf("***ERROR***  ret = %d   count = %d  nchan = %d\n", ret, count, nchan);
	    continue;
	  } /* if (ret != count * nchan * 2) */
	  for (i = 0; i < count; i++) {
	    printf("%6d", i);
	    for (j = 0; j < nchan; j++)	{
	      k = i*nchan + j;
	      data = rint(dataAIn[k]*table_DE_AIN[range][j][0] + table_DE_AIN[range][j][1]);
	      printf(", %8.4f", volts_USB1208FS_Plus(data, range));
	    } /* for (j - 0; j < 8, j++) */
	    printf("\n");
	  } /* for (i = 0; i < count; i++) */
	} /* for (m = 0; m < repeats; m++) */
	printf("\n\n---------------------------------------");
	break;
      case 'r':
        usbReset_USB1208FS_Plus(udev);
        break;
      case 's':
        usbGetSerialNumber_USB1208FS_Plus(udev, serial);
        printf("Serial number = %s\n", serial);
        break;
      case 'S':
        printf("Status = %#x\n", usbStatus_USB1208FS_Plus(udev));
	break;
      case 'e':
        cleanup_USB1208FS_Plus(udev);
        return 0;
      default:
        break;
    }
  }
}