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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [tags/] [ADS_RELEASE_1_1_0/] [Software/] [adv_jtag_bridge/] [cable_common.c] - Diff between revs 14 and 19

Only display areas with differences | Details | Blame | View Log

Rev 14 Rev 19
/* cable_common.c -- Interface to the low-level cable drivers
/* cable_common.c -- Interface to the low-level cable drivers
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
   Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
   Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
   Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org
   Copyright (C) 2008 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.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
 
 
 
 
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
 
 
 
 
#include "cable_common.h"
#include "cable_common.h"
#include "cable_parallel.h"
#include "cable_parallel.h"
#include "cable_sim.h"
#include "cable_sim.h"
#include "cable_usbblaster.h"
#include "cable_usbblaster.h"
#include "cable_xpc_dlc9.h"
#include "cable_xpc_dlc9.h"
#include "errcodes.h"
#include "errcodes.h"
 
 
#define debug(...)   //fprintf(stderr, __VA_ARGS__ )
#define debug(...)   //fprintf(stderr, __VA_ARGS__ )
 
 
static struct jtag_cable {
static struct jtag_cable {
  const char *name;
  const char *name;
  int (*inout_func)(uint8_t, uint8_t *);
  int (*inout_func)(uint8_t, uint8_t *);
  int (*out_func)(uint8_t);
  int (*out_func)(uint8_t);
  int (*init_func)();
  int (*init_func)();
  void (*wait_func)();
  void (*wait_func)();
  int (*opt_func)(int, char *);
  int (*opt_func)(int, char *);
  int (*bit_out_func)(uint8_t);
  int (*bit_out_func)(uint8_t);
  int (*bit_inout_func)(uint8_t, uint8_t *);
  int (*bit_inout_func)(uint8_t, uint8_t *);
  int (*stream_out_func)(uint32_t *, int, int);
  int (*stream_out_func)(uint32_t *, int, int);
  int (*stream_inout_func)(uint32_t *, uint32_t *, int, int);
  int (*stream_inout_func)(uint32_t *, uint32_t *, int, int);
  const char *opts;
  const char *opts;
  const char *help;
  const char *help;
} jtag_cables[] = {
} jtag_cables[] = {
  { "rtl_sim",
  { "rtl_sim",
    cable_rtl_sim_inout,
    cable_rtl_sim_inout,
    cable_rtl_sim_out,
    cable_rtl_sim_out,
    cable_rtl_sim_init,
    cable_rtl_sim_init,
    NULL,
    NULL,
    cable_rtl_sim_opt,
    cable_rtl_sim_opt,
    cable_common_write_bit,
    cable_common_write_bit,
    cable_common_read_write_bit,
    cable_common_read_write_bit,
    cable_common_write_stream,
    cable_common_write_stream,
    cable_common_read_stream,
    cable_common_read_stream,
    "d:",
    "d:",
    "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" },
    "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" },
  { "vpi",
  { "vpi",
    cable_vpi_inout,
    cable_vpi_inout,
    cable_vpi_out,
    cable_vpi_out,
    cable_vpi_init,
    cable_vpi_init,
    cable_vpi_wait,
    cable_vpi_wait,
    cable_vpi_opt,
    cable_vpi_opt,
    cable_common_write_bit,
    cable_common_write_bit,
    cable_common_read_write_bit,
    cable_common_read_write_bit,
    cable_common_write_stream,
    cable_common_write_stream,
    cable_common_read_stream,
    cable_common_read_stream,
    "s:p:",
    "s:p:",
    "-p [port] Port number that the VPI module is listening on\n\t-s [server] Server that the VPI module is running on\n" },
    "-p [port] Port number that the VPI module is listening on\n\t-s [server] Server that the VPI module is running on\n" },
  { "xpc3",
  { "xpc3",
    cable_xpc3_inout,
    cable_xpc3_inout,
    cable_xpc3_out,
    cable_xpc3_out,
    cable_parallel_init,
    cable_parallel_init,
    cable_parallel_phys_wait,
    cable_parallel_phys_wait,
    cable_parallel_opt,
    cable_parallel_opt,
    cable_common_write_bit,
    cable_common_write_bit,
    cable_common_read_write_bit,
    cable_common_read_write_bit,
    cable_common_write_stream,
    cable_common_write_stream,
    cable_common_read_stream,
    cable_common_read_stream,
    "p:",
    "p:",
    "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" },
    "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" },
  { "xess",
  { "xess",
    cable_xess_inout,
    cable_xess_inout,
    cable_xess_out,
    cable_xess_out,
    cable_parallel_init,
    cable_parallel_init,
    cable_parallel_phys_wait,
    cable_parallel_phys_wait,
    cable_parallel_opt,
    cable_parallel_opt,
    cable_common_write_bit,
    cable_common_write_bit,
    cable_common_read_write_bit,
    cable_common_read_write_bit,
    cable_common_write_stream,
    cable_common_write_stream,
    cable_common_read_stream,
    cable_common_read_stream,
    "p:",
    "p:",
    "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" },
    "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n" },
  { "usbblaster",
  { "usbblaster",
    cable_usbblaster_inout,
    cable_usbblaster_inout,
    cable_usbblaster_out,
    cable_usbblaster_out,
    cable_usbblaster_init,
    cable_usbblaster_init,
    NULL,
    NULL,
    cable_usbblaster_opt,
    cable_usbblaster_opt,
    cable_common_write_bit,
    cable_common_write_bit,
    cable_common_read_write_bit,
    cable_common_read_write_bit,
    cable_usbblaster_write_stream,
    cable_usbblaster_write_stream,
    cable_usbblaster_read_stream,
    cable_usbblaster_read_stream,
    "",
    "",
    "no options\n" },
    "no options\n" },
  { "xpc_usb",
  { "xpc_usb",
    cable_xpcusb_inout,
    cable_xpcusb_inout,
    cable_xpcusb_out,
    cable_xpcusb_out,
    cable_xpcusb_init,
    cable_xpcusb_init,
    NULL,
    NULL,
    cable_xpcusb_opt,
    cable_xpcusb_opt,
    cable_common_write_bit,
    cable_common_write_bit,
    cable_xpcusb_read_write_bit,
    cable_xpcusb_read_write_bit,
    cable_common_write_stream,
    cable_common_write_stream,
    cable_common_read_stream,
    cable_common_read_stream,
    "",
    "",
    "no options\n" },
    "no options\n" },
  { NULL, NULL, NULL, NULL } };
  { NULL, NULL, NULL, NULL } };
 
 
static struct jtag_cable *jtag_cable_in_use = NULL; /* The currently selected cable */
static struct jtag_cable *jtag_cable_in_use = NULL; /* The currently selected cable */
 
 
 
 
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
// Cable subsystem / init functions
// Cable subsystem / init functions
 
 
 
 
/* Selects a cable for use */
/* Selects a cable for use */
int cable_select(const char *cable)
int cable_select(const char *cable)
{
{
  int i;
  int i;
 
 
  for(i = 0; jtag_cables[i].name; i++) {
  for(i = 0; jtag_cables[i].name; i++) {
    if(!strcmp(cable, jtag_cables[i].name)) {
    if(!strcmp(cable, jtag_cables[i].name)) {
      jtag_cable_in_use = &jtag_cables[i];
      jtag_cable_in_use = &jtag_cables[i];
      return APP_ERR_NONE;
      return APP_ERR_NONE;
    }
    }
  }
  }
 
 
  return APP_ERR_CABLE_INVALID;
  return APP_ERR_CABLE_INVALID;
}
}
 
 
/* Calls the init function of the cable
/* Calls the init function of the cable
 */
 */
int cable_init()
int cable_init()
{
{
  return jtag_cable_in_use->init_func();
  return jtag_cable_in_use->init_func();
}
}
 
 
/* Parses command-line options specific to the selected cable */
/* Parses command-line options specific to the selected cable */
int cable_parse_opt(int c, char *str)
int cable_parse_opt(int c, char *str)
{
{
  return jtag_cable_in_use->opt_func(c, str);
  return jtag_cable_in_use->opt_func(c, str);
}
}
 
 
const char *cable_get_args()
const char *cable_get_args()
{
{
  if(jtag_cable_in_use != NULL)
  if(jtag_cable_in_use != NULL)
    return jtag_cable_in_use->opts;
    return jtag_cable_in_use->opts;
  else
  else
    return NULL;
    return NULL;
}
}
 
 
/* Prints a (short) useage message for each available cable */
/* Prints a (short) useage message for each available cable */
void cable_print_help()
void cable_print_help()
{
{
  int i;
  int i;
  printf("Available cables: ");
  printf("Available cables: ");
 
 
  for(i = 0; jtag_cables[i].name; i++) {
  for(i = 0; jtag_cables[i].name; i++) {
    if(i)
    if(i)
      printf(", ");
      printf(", ");
    printf("%s", jtag_cables[i].name);
    printf("%s", jtag_cables[i].name);
  }
  }
 
 
  printf("\n\nOptions availible for the cables:\n");
  printf("\n\nOptions availible for the cables:\n");
  for(i = 0; jtag_cables[i].name; i++) {
  for(i = 0; jtag_cables[i].name; i++) {
    if(!jtag_cables[i].help)
    if(!jtag_cables[i].help)
      continue;
      continue;
    printf("  %s:\n    %s", jtag_cables[i].name, jtag_cables[i].help);
    printf("  %s:\n    %s", jtag_cables[i].name, jtag_cables[i].help);
  }
  }
}
}
 
 
 
 
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// Cable API Functions
// Cable API Functions
 
 
int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
int cable_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
  return jtag_cable_in_use->stream_out_func(stream, len_bits, set_last_bit);
  return jtag_cable_in_use->stream_out_func(stream, len_bits, set_last_bit);
}
}
 
 
int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
int cable_read_write_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
  return jtag_cable_in_use->stream_inout_func(outstream, instream, len_bits, set_last_bit);
  return jtag_cable_in_use->stream_inout_func(outstream, instream, len_bits, set_last_bit);
}
}
 
 
int cable_write_bit(uint8_t packet) {
int cable_write_bit(uint8_t packet) {
  return jtag_cable_in_use->bit_out_func(packet);
  return jtag_cable_in_use->bit_out_func(packet);
}
}
 
 
int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in) {
int cable_read_write_bit(uint8_t packet_out, uint8_t *bit_in) {
  return jtag_cable_in_use->bit_inout_func(packet_out, bit_in);
  return jtag_cable_in_use->bit_inout_func(packet_out, bit_in);
}
}
 
 
 
 
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
// Common functions which may or may not be used by individual drivers
// Common functions which may or may not be used by individual drivers
 
 
 
 
/* Note that these make no assumption as to the starting state of the clock,
/* Note that these make no assumption as to the starting state of the clock,
 * and they leave the clock HIGH.  But, these need to interface with other routines (like
 * and they leave the clock HIGH.  But, these need to interface with other routines (like
 * the byte-shift mode in the USB-Blaster), which begin by assuming that a new
 * the byte-shift mode in the USB-Blaster), which begin by assuming that a new
 * data bit is available at TDO, which only happens after a FALLING edge of TCK.
 * data bit is available at TDO, which only happens after a FALLING edge of TCK.
 * So, routines which assume new data is available will need to start by dropping
 * So, routines which assume new data is available will need to start by dropping
 * the clock.
 * the clock.
 */
 */
int cable_common_write_bit(uint8_t packet) {
int cable_common_write_bit(uint8_t packet) {
  uint8_t data = TRST_BIT;  // TRST is active low, don't clear unless /set/ in 'packet'
  uint8_t data = TRST_BIT;  // TRST is active low, don't clear unless /set/ in 'packet'
  int err = APP_ERR_NONE;
  int err = APP_ERR_NONE;
 
 
  /* Write data, drop clock */
  /* Write data, drop clock */
  if(packet & TDO) data |= TDI_BIT;
  if(packet & TDO) data |= TDI_BIT;
  if(packet & TMS) data |= TMS_BIT;
  if(packet & TMS) data |= TMS_BIT;
  if(packet & TRST) data &= ~TRST_BIT;
  if(packet & TRST) data &= ~TRST_BIT;
 
 
  err |= jtag_cable_in_use->out_func(data);
  err |= jtag_cable_in_use->out_func(data);
  if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
  if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
 
 
  /* raise clock, to do write */
  /* raise clock, to do write */
  err |= jtag_cable_in_use->out_func(data | TCLK_BIT);
  err |= jtag_cable_in_use->out_func(data | TCLK_BIT);
   if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
   if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
 
 
  return err;
  return err;
}
}
 
 
int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in) {
int cable_common_read_write_bit(uint8_t packet_out, uint8_t *bit_in) {
  uint8_t data = TRST_BIT;  //  TRST is active low, don't clear unless /set/ in 'packet'
  uint8_t data = TRST_BIT;  //  TRST is active low, don't clear unless /set/ in 'packet'
  int err = APP_ERR_NONE;
  int err = APP_ERR_NONE;
 
 
  /* Write data, drop clock */
  /* Write data, drop clock */
  if(packet_out & TDO) data |= TDI_BIT;
  if(packet_out & TDO) data |= TDI_BIT;
  if(packet_out & TMS) data |= TMS_BIT;
  if(packet_out & TMS) data |= TMS_BIT;
  if(packet_out & TRST) data &= ~TRST_BIT;
  if(packet_out & TRST) data &= ~TRST_BIT;
 
 
  err |= jtag_cable_in_use->out_func(data);  // drop the clock to make data available, set the out data
  err |= jtag_cable_in_use->out_func(data);  // drop the clock to make data available, set the out data
  if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
  if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
  err |= jtag_cable_in_use->inout_func((data | TCLK_BIT), bit_in);  // read in bit, clock high for out bit.
  err |= jtag_cable_in_use->inout_func((data | TCLK_BIT), bit_in);  // read in bit, clock high for out bit.
  if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
  if (jtag_cable_in_use->wait_func != NULL) jtag_cable_in_use->wait_func();
 
 
  return err;
  return err;
}
}
 
 
 
 
/* Writes bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function.
/* Writes bitstream via bit-bang. Can be used by any driver which does not have a high-speed transfer function.
 * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc.
 * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc.
 */
 */
int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
int cable_common_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
  int i;
  int i;
  int index = 0;
  int index = 0;
  int bits_this_index = 0;
  int bits_this_index = 0;
  uint8_t out;
  uint8_t out;
  int err = APP_ERR_NONE;
  int err = APP_ERR_NONE;
 
 
  debug("writeSrrm%d(", len_bits);
  debug("writeSrrm%d(", len_bits);
  for(i = 0; i < len_bits - 1; i++) {
  for(i = 0; i < len_bits - 1; i++) {
    out = (stream[index] >> bits_this_index) & 1;
    out = (stream[index] >> bits_this_index) & 1;
    err |= cable_write_bit(out);
    err |= cable_write_bit(out);
    debug("%i", out);
    debug("%i", out);
    bits_this_index++;
    bits_this_index++;
    if(bits_this_index >= 32) {
    if(bits_this_index >= 32) {
      index++;
      index++;
      bits_this_index = 0;
      bits_this_index = 0;
    }
    }
  }
  }
 
 
  out = (stream[index] >>(len_bits - 1)) & 0x1;
  out = (stream[index] >>(len_bits - 1)) & 0x1;
  if(set_last_bit) out |= TMS;
  if(set_last_bit) out |= TMS;
  err |= cable_write_bit(out);
  err |= cable_write_bit(out);
  debug("%i)\n", out);
  debug("%i)\n", out);
  return err;
  return err;
}
}
 
 
/* Gets bitstream via bit-bang.  Can be used by any driver which does not have a high-speed transfer function.
/* Gets bitstream via bit-bang.  Can be used by any driver which does not have a high-speed transfer function.
 * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc.
 * Transfers LSB to MSB of stream[0], then LSB to MSB of stream[1], etc.
 */
 */
int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
int cable_common_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
  int i;
  int i;
  int index = 0;
  int index = 0;
  int bits_this_index = 0;
  int bits_this_index = 0;
  uint8_t inval, outval;
  uint8_t inval, outval;
  int err = APP_ERR_NONE;
  int err = APP_ERR_NONE;
 
 
  instream[0] = 0;
  instream[0] = 0;
 
 
  debug("readStrm%d(", len_bits);
  debug("readStrm%d(", len_bits);
  for(i = 0; i < (len_bits - 1); i++) {
  for(i = 0; i < (len_bits - 1); i++) {
    outval = (outstream[index] >> bits_this_index) & 0x1;
    outval = (outstream[index] >> bits_this_index) & 0x1;
    err |= cable_read_write_bit(outval, &inval);
    err |= cable_read_write_bit(outval, &inval);
    debug("%i", inval);
    debug("%i", inval);
    instream[index] |= (inval << bits_this_index);
    instream[index] |= (inval << bits_this_index);
    bits_this_index++;
    bits_this_index++;
    if(bits_this_index >= 32) {
    if(bits_this_index >= 32) {
      index++;
      index++;
      bits_this_index = 0;
      bits_this_index = 0;
      instream[index] = 0;  // It's safe to do this, because there's always at least one more bit
      instream[index] = 0;  // It's safe to do this, because there's always at least one more bit
    }
    }
  }
  }
 
 
  if (set_last_bit)
  if (set_last_bit)
    outval = ((outstream[index] >> (len_bits - 1)) & 1) | TMS;
    outval = ((outstream[index] >> (len_bits - 1)) & 1) | TMS;
  else
  else
    outval = (outstream[index] >> (len_bits - 1)) & 1;
    outval = (outstream[index] >> (len_bits - 1)) & 1;
 
 
  err |= cable_read_write_bit(outval, &inval);
  err |= cable_read_write_bit(outval, &inval);
  debug("%i", inval);
  debug("%i", inval);
  instream[index] |= (inval << bits_this_index);
  instream[index] |= (inval << bits_this_index);
 
 
  debug(") = 0x%lX\n", instream[0]);
  debug(") = 0x%lX\n", instream[0]);
 
 
  return err;
  return err;
}
}
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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