OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [sw/] [adv_jtag_bridge/] [cable_usbblaster.c] - Diff between revs 12 and 21

Show entire file | Details | Blame | View Log

Rev 12 Rev 21
Line 1... Line 1...
/* cable_usbblaster.c - Altera USB Blaster driver for the Advanced JTAG Bridge
/* cable_usbblaster.c - Altera USB Blaster driver for the Advanced JTAG Bridge
   Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org
   Copyright (C) 2008 - 2010 Nathan Yawn, nathan.yawn@opencores.org
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   (at your option) any later version.
Line 19... Line 19...
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>  // for usleep()
#include <unistd.h>  // for usleep()
#include <stdlib.h>  // for sleep()
#include <stdlib.h>  // for sleep()
#include <arpa/inet.h> // for htons()
#include <arpa/inet.h> // for htons()
#include <sys/time.h>
#include <string.h>  // for memcpy()
#include <time.h>
 
 
 
#ifdef __SUPPORT_FTDI_CABLES__
 
#include <ftdi.h>
 
#endif
 
 
 
#include "usb.h"  // libusb header
#include "usb.h"  // libusb header
#include "cable_common.h"
#include "cable_common.h"
#include "errcodes.h"
#include "errcodes.h"
 
 
Line 55... Line 50...
#define USBBLASTER_CMD_READ 0x40
#define USBBLASTER_CMD_READ 0x40
#define USBBLASTER_CMD_BYTESHIFT 0x80
#define USBBLASTER_CMD_BYTESHIFT 0x80
 
 
 
 
static struct usb_device *usbblaster_device;
static struct usb_device *usbblaster_device;
 
static usb_dev_handle *h_device;
 
 
static char *data_out_scratchpad = NULL;
// libusb seems to give an error if we ask for a transfer larger than 64 bytes
static int data_out_scratchpad_size = 0;
// USBBlaster also has a max. single transaction of 63 bytes.
static char *data_in_scratchpad = NULL;
// So, size the max read and write to create 64-byte USB packets (reads have 2 useless bytes prepended)
static int data_in_scratchpad_size = 0;
#define USBBLASTER_MAX_WRITE 63
 
static char data_out_scratchpad[USBBLASTER_MAX_WRITE+1];
#ifdef __SUPPORT_FTDI_CABLES__
#define USBBLASTER_MAX_READ  62
static struct ftdi_context ftdic;
static char data_in_scratchpad[USBBLASTER_MAX_READ+2];
#endif
 
 
int cable_usbblaster_open_cable(void);
 
void cable_usbblaster_close_cable(void);
 
//int cable_usbblaster_reopen_cable(void);
 
 
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/*-------------------------------------[ USB Blaster specific functions ]---*/
/*-------------------------------------[ USB Blaster specific functions ]---*/
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
 
 
Line 144... Line 142...
  // Process to reset the usb blaster
  // Process to reset the usb blaster
  if(err |= usbblaster_enumerate_bus()) {
  if(err |= usbblaster_enumerate_bus()) {
    return err;
    return err;
  }
  }
 
 
  usb_dev_handle *h_device = usb_open(usbblaster_device);
  h_device = usb_open(usbblaster_device);
 
 
  if(h_device == NULL)
  if(h_device == NULL)
    {
    {
      fprintf(stderr, "Init failed to open USB device for reset\n");
      fprintf(stderr, "Init failed to open USB device for reset\n");
      return APP_ERR_USB;
      return APP_ERR_USB;
Line 164... Line 162...
 
 
  // Do device initialization
  // Do device initialization
  if(err |= usbblaster_enumerate_bus())
  if(err |= usbblaster_enumerate_bus())
    return err;
    return err;
 
 
  h_device = usb_open(usbblaster_device);
  err = cable_usbblaster_open_cable();
  if(h_device == NULL)
  if(err != APP_ERR_NONE) return err;
    {
 
      fprintf(stderr, "Init failed to open USB device for initialization\n");
 
      return APP_ERR_USB;
 
    }
 
 
 
  // set the configuration
 
  if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue))
 
    {
 
      usb_close(h_device);
 
      fprintf(stderr, "USB-reset failed to set configuration\n");
 
      return APP_ERR_NONE;
 
    }
 
 
 
  while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber));
 
 
 
  //usb_clear_halt(h_device, EP1);
  //usb_clear_halt(h_device, EP1);
  //usb_clear_halt(h_device, EP2);
  //usb_clear_halt(h_device, EP2);
 
 
  // IMPORTANT:  DO NOT SEND A REQUEST TYPE "CLASS" OR TYPE "RESERVED".  This may stall the EP.
  // IMPORTANT:  DO NOT SEND A REQUEST TYPE "CLASS" OR TYPE "RESERVED".  This may stall the EP.
Line 210... Line 194...
  int rv = usb_bulk_read(h_device, EP1, ret, 2, USB_TIMEOUT);
  int rv = usb_bulk_read(h_device, EP1, ret, 2, USB_TIMEOUT);
  if (rv < 0){  // But if we fail, who cares?
  if (rv < 0){  // But if we fail, who cares?
    fprintf(stderr, "\nWarning: Failed to read post-init bytes from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
    fprintf(stderr, "\nWarning: Failed to read post-init bytes from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
  }
  }
 
 
  if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){
 
    usb_close(h_device);
 
    fprintf(stderr, "USB-out failed to release interface\n");
 
    return APP_ERR_USB;
 
  }
 
 
 
  usb_close(h_device);
 
 
 
  data_out_scratchpad = (char *) malloc(64);
 
  data_out_scratchpad_size = 64;
 
  data_in_scratchpad = (char *) malloc(64);
 
  data_in_scratchpad_size = 64;
 
 
 
  return APP_ERR_NONE;
  return APP_ERR_NONE;
}
}
 
 
 
 
int cable_usbblaster_out(uint8_t value)
int cable_usbblaster_out(uint8_t value)
{
{
  int             rv;                  // to catch return values of functions
  int             rv;                  // to catch return values of functions
  usb_dev_handle *h_device;            // handle on the ubs device
 
  char out;
  char out;
  int err = APP_ERR_NONE;
  int err = APP_ERR_NONE;
 
 
  // open the device
  // open the device, if necessary
  h_device = usb_open(usbblaster_device);
 
  if (h_device == NULL){
  if (h_device == NULL){
    usb_close(h_device);
    rv = cable_usbblaster_open_cable();
    fprintf(stderr, "USB-out failed to open device\n");
    if(rv != APP_ERR_NONE) return rv;
    return APP_ERR_USB;
 
  }
 
 
 
  // set the configuration
 
  if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue))
 
    {
 
      usb_close(h_device);
 
      fprintf(stderr, "USB-out failed to set configuration\n");
 
      return APP_ERR_USB;
 
    }
    }
 
 
  // wait until device is ready
 
  while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber));
 
 
 
  out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS);  // Set output enable (appears necessary) and nCS (necessary for byte-shift reads)
  out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS);  // Set output enable (appears necessary) and nCS (necessary for byte-shift reads)
 
 
  // Translate to USB blaster protocol
  // Translate to USB blaster protocol
  // USB-Blaster has no TRST pin
  // USB-Blaster has no TRST pin
  if(value & TCLK_BIT)
  if(value & TCLK_BIT)
Line 271... Line 228...
  if (rv != 1){
  if (rv != 1){
    fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror());
    fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror());
    err |= APP_ERR_USB;
    err |= APP_ERR_USB;
  }
  }
 
 
  // release the interface cleanly
 
  if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){
 
    fprintf(stderr, "Warning: failed to release usb interface after write\n");
 
    err |= APP_ERR_USB;
 
  }
 
 
 
  // close the device
 
  usb_close(h_device);
 
  return err;
  return err;
}
}
 
 
 
 
int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit)
int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit)
{
{
  int             rv;                  // to catch return values of functions
  int             rv;                  // to catch return values of functions
  usb_dev_handle *h_device;            // handle on the usb device
 
  char ret[3] = {0,0,0};               // Two useless bytes (0x31,0x60) always precede the useful byte
  char ret[3] = {0,0,0};               // Two useless bytes (0x31,0x60) always precede the useful byte
  char out;
  char out;
 
 
  out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS);  // Set output enable (?) and nCS (necessary for byte-shift reads)
  out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS);  // Set output enable (?) and nCS (necessary for byte-shift reads)
  out |=  USBBLASTER_CMD_READ;
  out |=  USBBLASTER_CMD_READ;
Line 302... Line 250...
  if(value & TDI_BIT)
  if(value & TDI_BIT)
    out |= USBBLASTER_CMD_TDI;
    out |= USBBLASTER_CMD_TDI;
  if(value & TMS_BIT)
  if(value & TMS_BIT)
    out |= USBBLASTER_CMD_TMS;
    out |= USBBLASTER_CMD_TMS;
 
 
 
  // open the device, if necessary
  // open the device
 
  h_device = usb_open(usbblaster_device);
 
  if (h_device == NULL){
  if (h_device == NULL){
    return APP_ERR_USB;
    rv = cable_usbblaster_open_cable();
  }
    if(rv != APP_ERR_NONE) return rv;
 
 
  // set the configuration
 
  if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue)){
 
    usb_close(h_device);
 
    return APP_ERR_USB;
 
  }
  }
 
 
  // wait until device is ready
 
  while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber));
 
 
 
  // Send a read request
  // Send a read request
  rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT);
  rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT);
  if (rv != 1){
  if (rv != 1){
    fprintf(stderr, "\nFailed to write a read request to the EP2 FIFO:\n%s", usb_strerror());
    fprintf(stderr, "\nFailed to write a read request to the EP2 FIFO:\n%s", usb_strerror());
    usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber);
    cable_usbblaster_close_cable();
    usb_close(h_device);
 
    return APP_ERR_USB;
    return APP_ERR_USB;
  }
  }
 
 
 
 
  // receive the response
  // receive the response
Line 336... Line 273...
  int retries = 0;
  int retries = 0;
  do {
  do {
    rv = usb_bulk_read(h_device, EP1, ret, 3, USB_TIMEOUT);
    rv = usb_bulk_read(h_device, EP1, ret, 3, USB_TIMEOUT);
    if (rv < 0){
    if (rv < 0){
      fprintf(stderr, "\nFailed to read from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
      fprintf(stderr, "\nFailed to read from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
      usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber);
      cable_usbblaster_close_cable();
      usb_close(h_device);
 
      return APP_ERR_USB;
      return APP_ERR_USB;
    }
    }
 
 
    // fprintf(stderr, "Read %i bytes: 0x%X, 0x%X, 0x%X\n", rv, ret[0], ret[1], ret[2]);
    // fprintf(stderr, "Read %i bytes: 0x%X, 0x%X, 0x%X\n", rv, ret[0], ret[1], ret[2]);
    retries++;
    retries++;
  }
  }
  while((rv < 3) && (retries < 20));
  while((rv < 3) && (retries < 20));
 
 
 
 
  // release the interface cleanly
 
  if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){
 
    fprintf(stderr, "Warning: failed to release USB interface after read\n");
 
    usb_close(h_device);
 
    return APP_ERR_USB;
 
  }
 
 
 
  // close the device
 
  usb_close(h_device);
 
 
 
  *in_bit = (ret[2] & 0x01); /* TDO is bit 0.  USB-Blaster may also set bit 1. */
  *in_bit = (ret[2] & 0x01); /* TDO is bit 0.  USB-Blaster may also set bit 1. */
  return APP_ERR_NONE;
  return APP_ERR_NONE;
}
}
 
 
 
 
// The usbblaster transfers the bits in the stream in the following order:
// The usbblaster transfers the bits in the stream in the following order:
// bit 0 of the first byte received ... bit 7 of the first byte received
// bit 0 of the first byte received ... bit 7 of the first byte received
// bit 0 of second byte received ... etc.
// bit 0 of second byte received ... etc.
int cable_usbblaster_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
int cable_usbblaster_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
  int             rv;                  // to catch return values of functions
  int             rv;                  // to catch return values of functions
  usb_dev_handle *h_device;            // handle on the ubs device
 
  unsigned int bytes_to_transfer, leftover_bit_length;
  unsigned int bytes_to_transfer, leftover_bit_length;
  uint32_t leftover_bits;
  uint32_t leftover_bits;
  unsigned char i;
  int bytes_remaining;
 
  char *xfer_ptr;
  int err = APP_ERR_NONE;
  int err = APP_ERR_NONE;
 
 
  //printf("cable_usbblaster_write_stream(0x%X, %d, %i)\n", stream, len, set_last_bit);
  debug("cable_usbblaster_write_stream(0x%X, %d, %i)\n", stream, len, set_last_bit);
 
 
  // This routine must transfer at least 8 bits.  Additionally, TMS (the 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,
  // cannot be set by 'byte shift mode'.  So we need at least 8 bits to transfer,
  // plus one bit to send along with TMS.
  // plus one bit to send along with TMS.
  bytes_to_transfer = len_bits / 8;
  bytes_to_transfer = len_bits / 8;
Line 386... Line 311...
  if((!leftover_bit_length) && set_last_bit) {
  if((!leftover_bit_length) && set_last_bit) {
    bytes_to_transfer -= 1;
    bytes_to_transfer -= 1;
    leftover_bit_length += 8;
    leftover_bit_length += 8;
  }
  }
 
 
  //printf("bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length);
  debug("bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length);
 
 
  // Not enough bits for high-speed transfer. bit-bang.
  // Not enough bits for high-speed transfer. bit-bang.
  if(bytes_to_transfer == 0) {
  if(bytes_to_transfer == 0) {
    return cable_common_write_stream(stream, len_bits, set_last_bit);
    return cable_common_write_stream(stream, len_bits, set_last_bit);
  }
  }
 
 
  // Bitbang functions leave clock high.  USBBlaster assumes clock low at the start of a burst.
  // Bitbang functions leave clock high.  USBBlaster assumes clock low at the start of a burst.
  // Lower the clock.
  err |= cable_usbblaster_out(0);  // Lower the clock.
  err |= cable_usbblaster_out(0);
 
 
 
  // Set leftover bits
  // Set leftover bits
  leftover_bits = (stream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF;
  leftover_bits = (stream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF;
 
 
  //printf("leftover_bits: 0x%X, LSB_first_xfer = %d\n", leftover_bits, LSB_first_xfer);
  debug("leftover_bits: 0x%X, LSB_first_xfer = %d\n", leftover_bits, LSB_first_xfer);
 
 
  // open the device
  // open the device, if necessary
  h_device = usb_open(usbblaster_device);
 
  if (h_device == NULL){
  if (h_device == NULL){
    usb_close(h_device);
    rv = cable_usbblaster_open_cable();
    fprintf(stderr, "USBBlaster_write_stream failed to open device\n");
    if(rv != APP_ERR_NONE) return rv;
    return APP_ERR_USB;
 
  }
  }
 
 
  // set the configuration
  bytes_remaining = bytes_to_transfer;
  if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue))
  xfer_ptr = (char *) stream;
 
  while(bytes_remaining > 0)
  {
  {
    usb_close(h_device);
      int bytes_this_xfer = (bytes_remaining > USBBLASTER_MAX_WRITE) ? USBBLASTER_MAX_WRITE:bytes_remaining;
    fprintf(stderr, "USBBlaster_write_stream failed to set configuration\n");
 
    return APP_ERR_USB;
 
  }
 
 
 
  // wait until device is ready
 
  while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber));
 
 
 
 
 
  // Copy stream into out.  Not pretty, but better than changing the interface to the upper layers;
 
  // 32 bits are easier to work with than 8 bits in upper layers.
 
  if(data_out_scratchpad_size < (bytes_to_transfer+1)) {
 
    free(data_out_scratchpad);
 
    data_out_scratchpad = (char *) malloc(bytes_to_transfer+1);  // free/malloc instead of realloc will save copy time
 
    if(data_out_scratchpad == NULL) {
 
      usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber);
 
      usb_close(h_device);
 
      return APP_ERR_MALLOC;
 
    }
 
    data_out_scratchpad_size = bytes_to_transfer+1;
 
  }
 
 
 
  data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | (bytes_to_transfer & 0x3F);
 
  for(i = 0; i < bytes_to_transfer; i++) {
 
    data_out_scratchpad[i+1] = (stream[i>>2] >> (8*(i&0x3))) & 0xFF;
 
  }
 
 
 
 
      data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | (bytes_this_xfer & 0x3F);
 
      memcpy(&data_out_scratchpad[1], xfer_ptr, bytes_this_xfer);
 
 
  /*
      /* printf("Data packet: ");
    printf("Data packet: ");
 
    for(i = 0; i <= bytes_to_transfer; i++)
    for(i = 0; i <= bytes_to_transfer; i++)
    printf("0x%X ", out[i]);
    printf("0x%X ", out[i]);
    printf("\n");
         printf("\n"); */
  */
 
 
 
  rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_to_transfer+1, USB_TIMEOUT);
      rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_this_xfer+1, USB_TIMEOUT);
  if (rv != (bytes_to_transfer+1)){
      if (rv != (bytes_this_xfer+1)){
    fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror());
    fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror());
    err |= APP_ERR_USB;
    err |= APP_ERR_USB;
 
        break;
  }
  }
 
 
  // release the interface cleanly
      bytes_remaining -= bytes_this_xfer;
  if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){
      xfer_ptr += bytes_this_xfer;
        fprintf(stderr, "Warning: failed to release usb interface after stream write\n");
 
  }
  }
 
 
  // close the device
 
  usb_close(h_device);
 
 
 
  // if we have a number of bits not divisible by 8, or we need to set TMS...
  // if we have a number of bits not divisible by 8, or we need to set TMS...
  if(leftover_bit_length != 0) {
  if(leftover_bit_length != 0) {
    //printf("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit);
    //printf("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit);
    return cable_common_write_stream(&leftover_bits, leftover_bit_length, set_last_bit);
    return cable_common_write_stream(&leftover_bits, leftover_bit_length, set_last_bit);
  }
  }
Line 474... Line 369...
}
}
 
 
 
 
int cable_usbblaster_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
int cable_usbblaster_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
  int             rv;                  // to catch return values of functions
  int             rv;                  // to catch return values of functions
  usb_dev_handle *h_device;            // handle on the ubs device
  unsigned int bytes_received = 0, total_bytes_received = 0;
  unsigned int bytes_received = 0;
 
  unsigned int bytes_to_transfer, leftover_bit_length;
  unsigned int bytes_to_transfer, leftover_bit_length;
  uint32_t leftover_bits, leftovers_received = 0;
  uint32_t leftover_bits, leftovers_received = 0;
  unsigned char i;
  unsigned char i;
 
  int bytes_remaining;
 
  char *xfer_ptr;
  int retval = APP_ERR_NONE;
  int retval = APP_ERR_NONE;
 
 
  debug("cable_usbblaster_read_stream(0x%X, %d, %i)\n", outstream[0], len_bits, set_last_bit);
  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)
  // This routine must transfer at least 8 bits.  Additionally, TMS (the last bit)
Line 494... Line 390...
  if((!leftover_bit_length) && set_last_bit) {
  if((!leftover_bit_length) && set_last_bit) {
    bytes_to_transfer -= 1;
    bytes_to_transfer -= 1;
    leftover_bit_length += 8;
    leftover_bit_length += 8;
  }
  }
 
 
  //printf("RD bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length);
  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.
  // Not enough bits for high-speed transfer. bit-bang.
  if(bytes_to_transfer == 0) {
  if(bytes_to_transfer == 0) {
    return cable_common_read_stream(outstream, instream, len_bits, set_last_bit);
    return cable_common_read_stream(outstream, instream, len_bits, set_last_bit);
    //retval |= cable_common_read_stream(&leftover_bits, &leftovers_received, leftover_bit_length, set_last_bit);
 
  }
  }
 
 
  // Bitbang functions leave clock high.  USBBlaster assumes clock low at the start of a burst.
  // Bitbang functions leave clock high.  USBBlaster assumes clock low at the start of a burst.
  // Lower the clock.
  // Lower the clock.
  retval |= cable_usbblaster_out(0);
  retval |= cable_usbblaster_out(0);
 
 
  // Zero the input, since we add new data by logical-OR
  // Zero the input, since we add new data by logical-OR
  for(i = 0; i < (len_bits/32); i++)
  for(i = 0; i < (len_bits/32); i++)  instream[i] = 0;
    instream[i] = 0;
  if(len_bits % 32)                   instream[i] = 0;
  if(len_bits % 32)
 
    instream[i] = 0;
 
 
 
  // Set leftover bits
  // Set leftover bits
  leftover_bits = (outstream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF;
  leftover_bits = (outstream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF;
  debug("leftover_bits: 0x%X\n", leftover_bits);
  debug("leftover_bits: 0x%X\n", leftover_bits);
 
 
  // open the device
  // open the device, if necessary
  h_device = usb_open(usbblaster_device);
 
  if (h_device == NULL){
  if (h_device == NULL){
        usb_close(h_device);
    rv = cable_usbblaster_open_cable();
        fprintf(stderr, "USBBlaster_read_stream failed to open device\n");
    if(rv != APP_ERR_NONE) return rv;
        return APP_ERR_USB;
 
  }
  }
 
 
  // set the configuration
  // Transfer the data.  USBBlaster has a max transfer size of 64 bytes.
  if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue))
  bytes_remaining = bytes_to_transfer;
  {
  xfer_ptr = (char *) outstream;
        usb_close(h_device);
  total_bytes_received = 0;
        fprintf(stderr, "USBBlaster_read_stream failed to set configuration\n");
  while(bytes_remaining > 0)
        return APP_ERR_USB;
    {
  }
      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"); */
 
 
  // wait until device is ready
      rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_this_xfer+1, USB_TIMEOUT);
  while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber));
      if (rv != (bytes_this_xfer+1)){
 
 
 
 
 
 
  // Copy stream into out.  Not pretty, but better than changing the interface to the upper layers;
 
  // 32 bits are easier to work with than 8 bits in upper layers.
 
  if(data_out_scratchpad_size < (bytes_to_transfer+1)) {
 
    free(data_out_scratchpad);
 
    data_out_scratchpad = (char *) malloc(bytes_to_transfer+1);  // free/malloc instead of realloc will save copy time
 
    if(data_out_scratchpad == NULL) {
 
      usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber);
 
      usb_close(h_device);
 
      return APP_ERR_MALLOC;
 
    }
 
    data_out_scratchpad_size = bytes_to_transfer+1;
 
  }
 
 
 
  data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | USBBLASTER_CMD_READ | (bytes_to_transfer & 0x3F);  // Set command byte
 
  for(i = 0; i < bytes_to_transfer; i++) {
 
    data_out_scratchpad[i+1] = (outstream[i>>2] >> (8*(i&0x3))) & 0xFF;
 
  }
 
 
 
  /*
 
  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_to_transfer+1, USB_TIMEOUT);
 
  if (rv != (bytes_to_transfer+1)){
 
    fprintf(stderr, "\nFailed to write to the EP2 FIFO (rv = %d):\n%s", rv, usb_strerror());
    fprintf(stderr, "\nFailed to write to the EP2 FIFO (rv = %d):\n%s", rv, usb_strerror());
    usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber);
        cable_usbblaster_close_cable();
    usb_close(h_device);
 
    return APP_ERR_USB;
    return APP_ERR_USB;
  }
  }
 
 
 
 
  // Make sure we have a big-enough buffer to hold the incoming data
 
  if(data_in_scratchpad_size < (bytes_to_transfer+2)) {
 
    free(data_in_scratchpad);
 
    data_in_scratchpad = (char *) malloc(bytes_to_transfer+2);  // free/malloc instead of realloc will save copy time
 
    if(data_in_scratchpad == NULL) {
 
      usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber);
 
      usb_close(h_device);
 
      return APP_ERR_MALLOC;
 
    }
 
    data_in_scratchpad_size = (bytes_to_transfer+2);
 
  }
 
 
 
  // receive the response
  // receive the response
  // Sometimes, we do a read but just get the useless 0x31,0x60 chars...
  // 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.
  // retry until we get at least 3 bytes (with real data), for a reasonable number of retries.
  int retries = 0;
  int retries = 0;
  bytes_received = 0;
  bytes_received = 0;
  do {
  do {
    rv = usb_bulk_read(h_device, EP1, data_in_scratchpad, (bytes_to_transfer-bytes_received)+2, USB_TIMEOUT);
        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){
    if (rv < 0){
      fprintf(stderr, "\nFailed to read stream from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
      fprintf(stderr, "\nFailed to read stream from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
      usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber);
          cable_usbblaster_close_cable();
      usb_close(h_device);
 
      return APP_ERR_USB;
      return APP_ERR_USB;
    }
    }
 
 
    /*
        /* debug("Read %i bytes: ", rv);
    debug("Read %i bytes: ", rv);
 
    for(i = 0; i < rv; i++)
    for(i = 0; i < rv; i++)
      debug("0x%X ", data_in_scratchpad[i]);
      debug("0x%X ", data_in_scratchpad[i]);
    debug("\n");
           debug("\n"); */
    */
 
 
 
    if(rv > 2) retries = 0;
    if(rv > 2) retries = 0;
    else retries++;
    else retries++;
 
 
    /* Put the received bytes into the return stream.  */
        /* Put the received bytes into the return stream.  Works for either endian. */
    for(i = 0; i < (rv-2); i++) {
    for(i = 0; i < (rv-2); i++) {
      // Do size/type promotion before shift.  Must cast to unsigned, else the value may be
      // 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.
      // sign-extended through the upper 16 bits of the uint32_t.
      uint32_t tmp = (unsigned char) data_in_scratchpad[2+i];
      uint32_t tmp = (unsigned char) data_in_scratchpad[2+i];
      instream[(bytes_received+i)>>2] |= (tmp << ((i & 0x3)*8));
          instream[(total_bytes_received+i)>>2] |= (tmp << ((i & 0x3)*8));
    }
    }
 
 
    bytes_received += (rv-2);
    bytes_received += (rv-2);
 
        total_bytes_received += (rv-2);
  }
  }
  while((bytes_received < bytes_to_transfer) && (retries < 15));
      while((bytes_received < bytes_this_xfer) && (retries < 15));
 
 
 
      bytes_remaining -= bytes_this_xfer;
  // release the interface cleanly
      xfer_ptr += bytes_this_xfer;
  if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){
 
        fprintf(stderr, "Warning: failed to release usb interface after stream read\n");
 
  }
  }
 
 
  // close the device
 
  usb_close(h_device);
 
 
 
  // if we have a number of bits not divisible by 8
  // if we have a number of bits not divisible by 8
  if(leftover_bit_length != 0) {
  if(leftover_bit_length != 0) {
    debug("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit);
    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);
    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));
    instream[bytes_to_transfer>>2] |= (leftovers_received & 0xFF) << (8*(bytes_to_transfer & 0x3));
Line 646... Line 493...
  fprintf(stderr, "Unknown parameter '%c'\n", c);
  fprintf(stderr, "Unknown parameter '%c'\n", c);
  return APP_ERR_BAD_PARAM;
  return APP_ERR_BAD_PARAM;
}
}
 
 
 
 
//
int cable_usbblaster_open_cable(void)
// libusb does not work with my 3C25, but it works with libfdti.
 
// Following code is ported from http://www.ixo.de/info/usb_jtag/
 
// ZXF, 2009-10-22
 
//
 
#ifdef __SUPPORT_FTDI_CABLES__
 
 
 
int usb_blaster_buf_write(uint8_t *buf, int size, uint32_t* bytes_written)
 
{
 
        int retval;
 
 
 
        debug("usb_blaster_buf_write %02X (%d)\n", buf[0], size);
 
 
 
        if ((retval = ftdi_write_data(&ftdic, buf, size)) < 0) {
 
                *bytes_written = 0;
 
                printf("ftdi_write_data: %s\n", ftdi_get_error_string(&ftdic));
 
                return -1;
 
        } else {
 
                *bytes_written = retval;
 
                return 0;
 
        }
 
}
 
 
 
int usb_blaster_buf_read(uint8_t* buf, int size, uint32_t* bytes_read)
 
{
 
        int retval;
 
        int timeout = 100;
 
        *bytes_read = 0;
 
 
 
        while ((*bytes_read < size) && timeout--) {
 
                if ((retval = ftdi_read_data(&ftdic, buf + *bytes_read, size - *bytes_read)) < 0) {
 
                        *bytes_read = 0;
 
                        printf("ftdi_read_data: %s\n", ftdi_get_error_string(&ftdic));
 
                        return -1;
 
                }
 
                *bytes_read += retval;
 
        }
 
 
 
        debug("usb_blaster_buf_read %02X (%d)\n", buf[0], *bytes_read);
 
 
 
        return 0;
 
}
 
 
 
/* The following code doesn't fully utilize the possibilities of the USB-Blaster. It
 
 * writes one byte per JTAG pin state change at a time; it doesn't even try to buffer
 
 * data up to the maximum packet size of 64 bytes.
 
 *
 
 * Actually, the USB-Blaster offers a byte-shift mode to transmit up to 504 data bits
 
 * (bidirectional) in a single USB packet. A header byte has to be sent as the first
 
 * byte in a packet with the following meaning:
 
 *
 
 *   Bit 7 (0x80): Must be set to indicate byte-shift mode.
 
 *   Bit 6 (0x40): If set, the USB-Blaster will also read data, not just write.
 
 *   Bit 5..0:     Define the number N of following bytes
 
 *
 
 * All N following bytes will then be clocked out serially on TDI. If Bit 6 was set,
 
 * it will afterwards return N bytes with TDO data read while clocking out the TDI data.
 
 * LSB of the first byte after the header byte will appear first on TDI.
 
 */
 
 
 
/* Simple bit banging mode:
 
 *
 
 *   Bit 7 (0x80): Must be zero (see byte-shift mode above)
 
 *   Bit 6 (0x40): If set, you will receive a byte indicating the state of TDO in return.
 
 *   Bit 5 (0x20): Unknown; for now, set to one.
 
 *   Bit 4 (0x10): TDI Output.
 
 *   Bit 3 (0x08): Unknown; for now, set to one.
 
 *   Bit 2 (0x04): Unknown; for now, set to one.
 
 *   Bit 1 (0x02): TMS Output.
 
 *   Bit 0 (0x01): TCK Output.
 
 *
 
 * For transmitting a single data bit, you need to write two bytes. Up to 64 bytes can be
 
 * combined in a single USB packet (but this is not done in the code below). It isn't
 
 * possible to read a data without transmitting data.
 
 */
 
 
 
#define FTDI_TCK    0
 
#define FTDI_TMS    1
 
#define FTDI_TDI    4
 
#define FTDI_READ   6
 
#define FTDI_SHMODE 7
 
#define FTDI_OTHERS ((1<<2)|(1<<3)|(1<<5))
 
 
 
void usb_blaster_write(int tck, int tms, int tdi)
 
{
 
        uint8_t buf[1];
 
        uint32_t count;
 
 
 
        debug("---- usb_blaster_write(%d,%d,%d)\n", tck,tms,tdi);
 
 
 
        buf[0] = FTDI_OTHERS | (tck?(1<<FTDI_TCK):0) | (tms?(1<<FTDI_TMS):0) | (tdi?(1<<FTDI_TDI):0);
 
        usb_blaster_buf_write(buf, 1, &count);
 
}
 
 
 
int usb_blaster_write_read(int tck, int tms, int tdi)
 
{
{
        uint8_t buf[1];
  // open the device
        uint32_t count;
  h_device = usb_open(usbblaster_device);
 
  if (h_device == NULL){
        debug("++++ usb_blaster_write_read(%d,%d,%d)\n", tck,tms,tdi);
        fprintf(stderr, "USBBlaster driver failed to open device\n");
 
        return APP_ERR_USB;
        buf[0] = FTDI_OTHERS | (tck?(1<<FTDI_TCK):0) | (tms?(1<<FTDI_TMS):0) | (tdi?(1<<FTDI_TDI):0) | (1<<FTDI_READ);
 
        usb_blaster_buf_write(buf, 1, &count);
 
        usb_blaster_buf_read(buf, 1, &count);
 
        return (buf[0]&1);
 
}
}
 
 
int ftdi_usb_blaster_out(uint8_t value)
  // set the configuration
 
  if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue))
{
{
        int    tck = 0;
        usb_close(h_device);
        int    tms = 0;
        h_device = NULL;
        int    tdi = 0;
        fprintf(stderr, "USBBlaster driver failed to set configuration\n");
 
        return APP_ERR_USB;
        // Translate to USB blaster protocol
 
        // USB-Blaster has no TRST pin
 
        if(value & TCLK_BIT)
 
                tck = 1;
 
        if(value & TDI_BIT)
 
                tdi = 1;;
 
        if(value & TMS_BIT)
 
                tms = 1;
 
 
 
        usb_blaster_write(tck, tms, tdi);
 
 
 
        return 0;
 
}
}
 
 
int ftdi_usb_blaster_inout(uint8_t value, uint8_t *in_bit)
  // wait until device is ready
{
  // *** TODO: add timeout
        int    tck = 0;
  while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber));
        int    tms = 0;
 
        int    tdi = 0;
 
 
 
        // Translate to USB blaster protocol
 
        // USB-Blaster has no TRST pin
 
        if(value & TCLK_BIT)
 
                tck = 1;
 
        if(value & TDI_BIT)
 
                tdi = 1;
 
        if(value & TMS_BIT)
 
                tms = 1;
 
 
 
        *in_bit = usb_blaster_write_read(tck, tms, tdi);
 
 
 
        return 0;
 
}
 
 
 
int usb_blaster_speed(int speed)
  return APP_ERR_NONE;
{
 
        if(ftdi_set_baudrate(&ftdic, speed)<0) {
 
                printf("Can't set baud rate to max: %s\n", ftdi_get_error_string(&ftdic));
 
                return -1;
 
        }
        }
 
 
        return 0;
 
}
 
 
 
int ftdi_usb_blaster_init(void)
void cable_usbblaster_close_cable(void)
{
{
        uint8_t latency_timer;
  if(h_device != NULL) {
        int     speed = 300000;
    // release the interface cleanly
 
    if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){
        printf("'usb_blaster' interface using libftdi.\n");
      fprintf(stderr, "Warning: failed to release usb interface\n");
        printf("Ported by Xianfeng (xianfeng.zeng@gmail.com), 2009\n");
 
 
 
        if (ftdi_init(&ftdic) < 0) {
 
                printf("ftdi_init failed!");
 
                return -1;
 
        }
 
 
 
        /* context, vendor id, product id */
 
        if (ftdi_usb_open(&ftdic, ALTERA_VID, ALTERA_PID) < 0) {
 
                printf("unable to open ftdi device: %s\n", ftdic.error_str);
 
                return -1;
 
        }
 
 
 
        if (ftdi_usb_reset(&ftdic) < 0) {
 
                printf("unable to reset ftdi device\n");
 
                return -1;
 
        }
 
 
 
        if (ftdi_set_latency_timer(&ftdic, 2) < 0) {
 
                printf("unable to set latency timer\n");
 
                return -1;
 
        }
 
 
 
        if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0) {
 
                printf("unable to get latency timer\n");
 
                return -1;
 
        } else {
 
                printf("current latency timer: %i\n", latency_timer);
 
        }
        }
 
 
        ftdi_disable_bitbang(&ftdic);
    // close the device
 
    usb_close(h_device);
        printf("Baudrate:%d\n", speed);
    h_device = NULL;
        usb_blaster_speed(speed);
 
 
 
        return 0;
 
}
}
 
 
int ftdi_usb_blaster_quit(void)
  return;
{
 
        ftdi_usb_close(&ftdic);
 
        ftdi_deinit(&ftdic);
 
 
 
        return 0;
 
}
}
#endif
 
 
 
 
/*
 
int cable_usbblaster_reopen_cable(void)
 
{
 
  cable_usbblaster_close_cable();
 
  return cable_usbblaster_open_cable();
 
}
 
*/
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.