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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [trunk/] [Software/] [adv_jtag_bridge/] [cable_parallel.c] - Diff between revs 55 and 59

Show entire file | Details | Blame | View Log

Rev 55 Rev 59
Line 1... Line 1...
/* cable_parallel.c - Parallel cable drivers (XPC3 and XESS) for the Advanced JTAG Bridge
/* cable_parallel.c - Parallel cable drivers (XPC3 and XESS) for the Advanced JTAG Bridge
   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
 
 
 
   UNIX parallel port control through device file added by:
 
           Copyright (C) 2011 Raul Fajardo, rfajardo@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 16... Line 18...
   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 <sys/io.h>  // for inb(), outb()
 
#include <sys/types.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/time.h>
#include <unistd.h>
#include <unistd.h>
#include <time.h>
#include <time.h>
 
#include <string.h>
 
 
 
#ifdef __LINUX_HOST__
 
#include <sys/stat.h>
 
#include <fcntl.h>
 
#include <sys/ioctl.h>
 
#include <linux/ppdev.h>
 
#include <linux/parport.h>
 
#endif
 
 
 
#ifdef __CYGWIN_HOST__
 
#include <sys/io.h>  // for inb(), outb()
 
#endif
 
 
 
#ifdef __FREEBSD_HOST__
 
#include <fcntl.h>
 
#include <sys/ioctl.h>
 
#include <sys/dev/ppbus/ppi.h>
 
#include <sys/dev/ppbus/ppbconf.h>
 
#endif
 
 
#include "cable_parallel.h"
#include "cable_parallel.h"
#include "errcodes.h"
#include "errcodes.h"
 
 
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
Line 44... Line 64...
    .bit_out_func = cable_common_write_bit,
    .bit_out_func = cable_common_write_bit,
    .bit_inout_func = cable_common_read_write_bit,
    .bit_inout_func = cable_common_read_write_bit,
    .stream_out_func = cable_common_write_stream,
    .stream_out_func = cable_common_write_stream,
    .stream_inout_func = cable_common_read_stream,
    .stream_inout_func = cable_common_read_stream,
    .flush_func = NULL,
    .flush_func = NULL,
 
#ifdef __CYGWIN_HOST__
    .opts = "p:",
    .opts = "p:",
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n"
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n"
 
#else
 
    .opts = "d:",
 
    .help = "-d [device file] Device file to use when communicating with the parport hardware (eg. /dev/parport0)\n"
 
#endif
 
    };
 
 
 
jtag_cable_t bb2_cable_driver = {
 
 .name = "bb2",
 
 .inout_func = cable_bb2_inout,
 
 .out_func = cable_bb2_out,
 
 .init_func = cable_parallel_init,
 
 .opt_func = cable_parallel_opt,
 
 .bit_out_func = cable_common_write_bit,
 
 .bit_inout_func = cable_common_read_write_bit,
 
 .stream_out_func = cable_common_write_stream,
 
 .stream_inout_func = cable_common_read_stream,
 
 .flush_func = NULL,
 
#ifdef __CYGWIN_HOST__
 
    .opts = "p:",
 
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n"
 
#else
 
    .opts = "d:",
 
    .help = "-d [device file] Device file to use when communicating with the parport hardware (eg. /dev/parport0)\n"
 
#endif
    };
    };
 
 
jtag_cable_t xess_cable_driver = {
jtag_cable_t xess_cable_driver = {
    .name = "xess",
    .name = "xess",
    .inout_func = cable_xess_inout,
    .inout_func = cable_xess_inout,
Line 59... Line 104...
    .bit_out_func = cable_common_write_bit,
    .bit_out_func = cable_common_write_bit,
    .bit_inout_func = cable_common_read_write_bit,
    .bit_inout_func = cable_common_read_write_bit,
    .stream_out_func = cable_common_write_stream,
    .stream_out_func = cable_common_write_stream,
    .stream_inout_func = cable_common_read_stream,
    .stream_inout_func = cable_common_read_stream,
    .flush_func = NULL,
    .flush_func = NULL,
 
#ifdef __CYGWIN_HOST__
    .opts = "p:",
    .opts = "p:",
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n",
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n"
 
#else
 
    .opts = "d:",
 
    .help = "-d [device file] Device file to use when communicating with the parport hardware (eg. /dev/parport0)\n"
 
#endif
    };
    };
 
 
#define LPT_READ (base+1)
 
#define LPT_WRITE base
 
 
 
// Common functions used by both cable types
// Common functions used by both cable types
static int cable_parallel_out(uint8_t value);
static int cable_parallel_out(uint8_t value);
static int cable_parallel_inout(uint8_t value, uint8_t *inval);
static int cable_parallel_inout(uint8_t value, uint8_t *inval);
 
 
 
 
static int base = 0x378;
 
 
 
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
 #ifndef PARALLEL_USE_PROCESS_TIMER
 #ifndef PARALLEL_USE_PROCESS_TIMER
 struct timeval last_tv;
 struct timeval last_tv;
 #endif
 #endif
#endif
#endif
 
 
 
// If cygwin, we use inb / outb for parallel port access
 
#ifdef __CYGWIN_HOST__
 
 
 
#define LPT_READ (base+1)
 
#define LPT_WRITE base
 
 
 
static int base = 0x378;
 
 
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/*-------------------------------------[ Parallel port specific functions ]---*/
/*-------------------------------------[ Parallel port specific functions ]---*/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
 
 
int cable_parallel_init()
int cable_parallel_init()
Line 108... Line 161...
#endif
#endif
 
 
  return APP_ERR_NONE;
  return APP_ERR_NONE;
}
}
 
 
 
 
int cable_parallel_opt(int c, char *str)
int cable_parallel_opt(int c, char *str)
{
{
  switch(c) {
  switch(c) {
  case 'p':
  case 'p':
    if(!sscanf(str, "%x", &base)) {
    if(!sscanf(str, "%x", &base)) {
Line 125... Line 177...
    return APP_ERR_BAD_PARAM;
    return APP_ERR_BAD_PARAM;
  }
  }
  return APP_ERR_NONE;
  return APP_ERR_NONE;
}
}
 
 
 
/*----------------------------------------------[ common helper functions ]---*/
 
// 'static' for internal access only
 
 
 
static int cable_parallel_out(uint8_t value)
 
{
 
  outb(value, LPT_WRITE);
 
  return APP_ERR_NONE;
 
}
 
 
 
static int cable_parallel_inout(uint8_t value, uint8_t *inval)
 
{
 
  *inval = inb(LPT_READ);
 
  outb(value, LPT_WRITE);
 
 
 
  return APP_ERR_NONE;
 
}
 
 
 
// For Linux / BSD, we use open / ioctl for parallel port access,
 
// so that we don't need root permissions
 
#else // ! defined __CYGWIN_HOST__
 
 
 
#ifdef __FREEBSD_HOST__
 
static int PPORT_PUT_DATA = PPISDATA;
 
static int PPORT_GET_DATA = PPIGSTATUS;
 
#else
 
static int PPORT_PUT_DATA = PPWDATA;
 
static int PPORT_GET_DATA = PPRSTATUS;
 
#endif
 
 
 
static int fd;
 
static char default_dev_str[20] = "/dev/parport0";
 
static char *devsys = default_dev_str;
 
 
 
 
 
/////////////////////////////////////////////////////////////////////////////////
 
/*-------------------------------------[ Parallel port specific functions ]---*/
 
///////////////////////////////////////////////////////////////////////////////
 
 
 
int cable_parallel_init()
 
{
 
  int mode = IEEE1284_MODE_COMPAT;
 
  fd = open(devsys, O_RDWR | O_NONBLOCK);
 
  if (fd == -1)
 
  {
 
    perror("Unable to open the device desriptor\n");
 
    fprintf(stderr, "Check permission of %s (eg. 'ls -la %s').\n", devsys, devsys);
 
    fprintf(stderr, "Your user ID can be added to %s's group to allow for unprivileged access.\n", devsys);
 
    return APP_ERR_INIT_FAILED;
 
  }
 
 
 
  // I don't know if these ioctl() are supported under FreeBSD
 
#ifdef __LINUX_HOST__
 
  if (ioctl(fd, PPCLAIM) == -1)
 
  {
 
    perror("Fail to claim the parallel port device interface.\n");
 
    return APP_ERR_INIT_FAILED;
 
  }
 
  if (ioctl(fd, PPSETMODE, &mode) == -1)
 
  {
 
    perror("Setting compatibility mode on parallel port device failed.\n");
 
    return APP_ERR_INIT_FAILED;
 
  }
 
#endif
 
 
 
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
 
 #ifdef PARALLEL_USE_PROCESS_TIMER
 
  struct timespec ts;
 
  ts.tv_sec = 0;
 
  ts.tv_nsec = 0;
 
  clock_settime(CLOCK_PROCESS_CPUTIME_ID, &ts);
 
 #else
 
  gettimeofday(&last_tv, NULL);
 
 #endif
 
#endif
 
 
 
  return APP_ERR_NONE;
 
}
 
 
 
 
 
int cable_parallel_opt(int c, char *str)
 
{
 
  switch(c) {
 
  case 'd':
 
    devsys = strdup(str);
 
    break;
 
  default:
 
    fprintf(stderr, "Unknown parameter '%c'\n", c);
 
    return APP_ERR_BAD_PARAM;
 
  }
 
  return APP_ERR_NONE;
 
}
 
 
 
/*----------------------------------------------[ common helper functions ]---*/
 
// 'static' for internal access only
 
 
 
static int cable_parallel_out(uint8_t value)
 
{
 
  ioctl(fd, PPORT_PUT_DATA, &value);
 
 
 
  return APP_ERR_NONE;
 
}
 
 
 
static int cable_parallel_inout(uint8_t value, uint8_t *inval)
 
{
 
  ioctl(fd, PPORT_GET_DATA, inval);
 
  ioctl(fd, PPORT_PUT_DATA, &value);
 
 
 
  return APP_ERR_NONE;
 
}
 
 
 
#endif  // !defined __CYGWIN_HOST__
 
 
/*-----------------------------------------[ Physical board wait function ]---*/
/*-----------------------------------------[ Physical board wait function ]---*/
 
 
/* Multiple users have reported poor performance of parallel cables,
/* Multiple users have reported poor performance of parallel cables,
 * which has been traced to various sleep functions sleeping much longer than
 * which has been traced to various sleep functions sleeping much longer than
 * microseconds.  The same users have reported error-free functionality
 * microseconds.  The same users have reported error-free functionality
 * and an order of magnitude improvement in upload speed.
 * and an order of magnitude improvement in upload speed with no wait.
 * Other users have reported errors when running without a wait.
 * Other users have reported errors when running without a wait.
 * Impact apparently limits the frequency of parallel JTAG cables
 * Impact apparently limits the frequency of parallel JTAG cables
 * to 200 kHz, and some clones fail at higher speeds.
 * to 200 kHz, and some clones fail at higher speeds.
 */
 */
 
 
Line 273... Line 437...
    *inval = 0;
    *inval = 0;
 
 
  return retval;
  return retval;
}
}
 
 
 
 
 
/*----------------------------------------------[ bb2 specific functions ]---*/
 
jtag_cable_t *cable_bb2_get_driver(void)
 
{
 
 return &bb2_cable_driver;
 
}
 
 
 
int cable_bb2_out(uint8_t value)
 
{
 
 uint8_t out = 0;
 
 
 
 cable_parallel_phys_wait(); // Limit the max clock rate if necessary
 
 
 
 /* First convert the bits in value byte to the ones that the cable wants */
 
 if(value & TCLK_BIT)
 
   out |= 0x01; /* D0 pin 2 */
 
 if(value & TDI_BIT)
 
   out |= 0x40; /* D7 pin 8 */
 
 if(value & TMS_BIT)
 
   out |= 0x02; /* D1 pin 3 */
 
 
 
 return cable_parallel_out(out);
 
}
 
 
 
int cable_bb2_inout(uint8_t value, uint8_t *inval)
 
{
 
 uint8_t in;
 
 int retval;
 
 uint8_t out = 0;
 
 
 
 cable_parallel_phys_wait(); // Limit the max clock rate if necessary
 
 
 
 /* First convert the bits in value byte to the ones that the cable wants */
 
 if(value & TCLK_BIT)
 
   out |= 0x01; /* D0 pin 2 */
 
 if(value & TDI_BIT)
 
   out |= 0x40; /* D7 pin 8 */
 
 if(value & TMS_BIT)
 
   out |= 0x02; /* D1 pin 3 */
 
 
 
 retval = cable_parallel_inout(out, &in);
 
 
 
 if(in & 0x80) /* S7 pin 11 */
 
 *inval = 0;
 
 else
 
 *inval = 1;
 
 
 
 return retval;
 
}
 
 
 
 
/*----------------------------------------------[ xess specific functions ]---*/
/*----------------------------------------------[ xess specific functions ]---*/
jtag_cable_t *cable_xess_get_driver(void)
jtag_cable_t *cable_xess_get_driver(void)
{
{
  return &xess_cable_driver;
  return &xess_cable_driver;
}
}
Line 327... Line 542...
 
 
  return retval;
  return retval;
}
}
 
 
 
 
/*----------------------------------------------[ common helper functions ]---*/
 
// 'static' for internal access only
 
 
 
static int cable_parallel_out(uint8_t value)
 
{
 
  outb(value, LPT_WRITE);
 
  return APP_ERR_NONE;
 
}
 
 
 
static int cable_parallel_inout(uint8_t value, uint8_t *inval)
 
{
 
  *inval = inb(LPT_READ);
 
  outb(value, LPT_WRITE);
 
 
 
  return APP_ERR_NONE;
 
}
 
 
 
 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.