コード例 #1
0
int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit)
{
  int             rv;                  // to catch return values of functions
  char ret[3] = {0,0,0};               // Two useless bytes (0x31,0x60) always precede the useful byte
  char out;

  out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS);  // Set output enable (?) and nCS (necessary for byte-shift reads)
  out |=  USBBLASTER_CMD_READ;

  // Translate to USB blaster protocol
  // USB-Blaster has no TRST pin
  if(value & TCLK_BIT)
    out |= USBBLASTER_CMD_TCK;
  if(value & TDI_BIT)
    out |= USBBLASTER_CMD_TDI;
  if(value & TMS_BIT)
    out |= USBBLASTER_CMD_TMS;

  // open the device, if necessary
  if(h_device == NULL) {
    rv = cable_usbblaster_open_cable();
    if(rv != APP_ERR_NONE) return rv;
  }

  // Send a read request
  rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT);
  if (rv != 1){
    fprintf(stderr, "\nFailed to write a read request to the EP2 FIFO:\n%s", usb_strerror());
    cable_usbblaster_close_cable();
    return APP_ERR_USB;
  }


  // receive the response
  // Sometimes, we do a read but just get the useless 0x31,0x60 chars...
  // retry until we get a 3rd byte (with real data), for a reasonable number of retries.
  int retries = 0;
  do {
    rv = usb_bulk_read(h_device, EP1, ret, 3, USB_TIMEOUT);
    if (rv < 0){
      fprintf(stderr, "\nFailed to read from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
      cable_usbblaster_close_cable();
      return APP_ERR_USB;
    }

    // fprintf(stderr, "Read %i bytes: 0x%X, 0x%X, 0x%X\n", rv, ret[0], ret[1], ret[2]);
    retries++;
  }
  while((rv < 3) && (retries < 20));

  *in_bit = (ret[2] & 0x01); /* TDO is bit 0.  USB-Blaster may also set bit 1. */
  return APP_ERR_NONE;
}
コード例 #2
0
ファイル: cable_usbblaster.cpp プロジェクト: rdiez/orbuild
int cable_usbblaster_read_stream ( const uint32_t * const outstream,
                                   uint32_t * const instream,
                                   const int len_bits,
                                   const int set_last_bit )
{
  int             rv;                  // to catch return values of functions
  unsigned int bytes_received = 0, total_bytes_received = 0;
  unsigned int bytes_to_transfer, leftover_bit_length;
  uint32_t leftover_bits, leftovers_received = 0;
  unsigned char i;
  int bytes_remaining;
  const char *xfer_ptr;
  int retval = APP_ERR_NONE;

  debug("cable_usbblaster_read_stream(0x%X, %d, %i)\n", outstream[0], len_bits, set_last_bit);

  // This routine must transfer at least 8 bits.  Additionally, TMS (the last bit)
  // cannot be set by 'byte shift mode'.  So we need at least 8 bits to transfer,
  // plus one bit to send along with TMS.
  bytes_to_transfer = len_bits / 8;
  leftover_bit_length = len_bits - (bytes_to_transfer * 8);

  if((!leftover_bit_length) && set_last_bit) {
    bytes_to_transfer -= 1;
    leftover_bit_length += 8;
  }

  debug("RD bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length);

  // Not enough bits for high-speed transfer. bit-bang.
  if(bytes_to_transfer == 0) {
    return cable_common_read_stream(outstream, instream, len_bits, set_last_bit);
  }

  // Bitbang functions leave clock high.  USBBlaster assumes clock low at the start of a burst.
  if(clock_is_high)
    {
      // Lower the clock.
      retval |= cable_usbblaster_out(0);
    }

  // Zero the input, since we add new data by logical-OR
  for(i = 0; i < (len_bits/32); i++)  instream[i] = 0;
  if(len_bits % 32)                   instream[i] = 0;

  // Set leftover bits
  leftover_bits = (outstream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF;
  debug("leftover_bits: 0x%X\n", leftover_bits);

  // open the device, if necessary
  if(h_device == NULL) {
    rv = cable_usbblaster_open_cable();
    if(rv != APP_ERR_NONE) return rv;
  }

  // Transfer the data.  USBBlaster has a max transfer size of 64 bytes.
  bytes_remaining = bytes_to_transfer;
  xfer_ptr = (const char *) outstream;
  total_bytes_received = 0;
  while(bytes_remaining > 0)
    {
      int bytes_this_xfer = (bytes_remaining > USBBLASTER_MAX_READ) ? USBBLASTER_MAX_READ:bytes_remaining;
      data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | USBBLASTER_CMD_READ | (bytes_this_xfer & 0x3F);
      memcpy(&data_out_scratchpad[1], xfer_ptr, bytes_this_xfer);

      /* debug("Data packet: ");
	 for(i = 0; i <= bytes_to_transfer; i++) debug("0x%X ", data_out_scratchpad[i]);
	 debug("\n"); */

      rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_this_xfer+1, USB_TIMEOUT);
      if (rv != (bytes_this_xfer+1)){
	fprintf(stderr, "\nFailed to write to the EP2 FIFO (rv = %d):\n%s", rv, usb_strerror());
	cable_usbblaster_close_cable();
	return APP_ERR_USB;
      }

      // receive the response
      // Sometimes, we do a read but just get the useless 0x31,0x60 chars...
      // retry until we get at least 3 bytes (with real data), for a reasonable number of retries.
      int retries = 0;
      bytes_received = 0;
      do {
	debug("stream read, bytes_this_xfer = %i, bytes_received = %i\n", bytes_this_xfer, bytes_received);
	rv = usb_bulk_read(h_device, EP1, data_in_scratchpad, (bytes_this_xfer-bytes_received)+2, USB_TIMEOUT);
	if (rv < 0){
	  fprintf(stderr, "\nFailed to read stream from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
	  cable_usbblaster_close_cable();
	  return APP_ERR_USB;
	}

	/* debug("Read %i bytes: ", rv);
	   for(i = 0; i < rv; i++)
	   debug("0x%X ", data_in_scratchpad[i]);
	   debug("\n"); */

	if(rv > 2) retries = 0;
	else retries++;

	/* Put the received bytes into the return stream.  Works for either endian. */
	for(i = 0; i < (rv-2); i++) {
	  // Do size/type promotion before shift.  Must cast to unsigned, else the value may be
	  // sign-extended through the upper 16 bits of the uint32_t.
	  uint32_t tmp = (unsigned char) data_in_scratchpad[2+i];
	  instream[(total_bytes_received+i)>>2] |= (tmp << ((i & 0x3)*8));
	}

	bytes_received += (rv-2);
	total_bytes_received += (rv-2);
      }
      while((bytes_received < unsigned(bytes_this_xfer)) && (retries < 15));

      bytes_remaining -= bytes_this_xfer;
      xfer_ptr += bytes_this_xfer;
    }

  clock_is_high = 0;

  // if we have a number of bits not divisible by 8
  if(leftover_bit_length != 0) {
    debug("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit);
    retval |= cable_common_read_stream(&leftover_bits, &leftovers_received, leftover_bit_length, set_last_bit);
    instream[bytes_to_transfer>>2] |= (leftovers_received & 0xFF) << (8*(bytes_to_transfer & 0x3));
  }