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] - Blame information for rev 59

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 nyawn
/* cable_parallel.c - Parallel cable drivers (XPC3 and XESS) for the Advanced JTAG Bridge
2
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
3 59 nyawn
   Copyright (C) 2004 Gy�rgy Jeney, nog@sdf.lonestar.org
4
 
5
   UNIX parallel port control through device file added by:
6
           Copyright (C) 2011 Raul Fajardo, rfajardo@opencores.org
7 21 nyawn
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
 
22
 
23
#include <stdio.h>
24
#include <sys/types.h>
25 55 nyawn
#include <sys/time.h>
26 21 nyawn
#include <unistd.h>
27 55 nyawn
#include <time.h>
28 59 nyawn
#include <string.h>
29 21 nyawn
 
30 59 nyawn
#ifdef __LINUX_HOST__
31
#include <sys/stat.h>
32
#include <fcntl.h>
33
#include <sys/ioctl.h>
34
#include <linux/ppdev.h>
35
#include <linux/parport.h>
36
#endif
37
 
38
#ifdef __CYGWIN_HOST__
39
#include <sys/io.h>  // for inb(), outb()
40
#endif
41
 
42
#ifdef __FREEBSD_HOST__
43
#include <fcntl.h>
44
#include <sys/ioctl.h>
45
#include <sys/dev/ppbus/ppi.h>
46
#include <sys/dev/ppbus/ppbconf.h>
47
#endif
48
 
49 55 nyawn
#include "cable_parallel.h"
50 21 nyawn
#include "errcodes.h"
51
 
52 55 nyawn
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
53
 #if ((_POSIX_TIMERS) && (_POSIX_CPUTIME))
54
 #define PARALLEL_USE_PROCESS_TIMER
55
 #endif
56
#endif
57 21 nyawn
 
58 55 nyawn
jtag_cable_t xpc3_cable_driver = {
59
    .name = "xpc3",
60
    .inout_func = cable_xpc3_inout,
61
    .out_func = cable_xpc3_out,
62
    .init_func = cable_parallel_init,
63
    .opt_func = cable_parallel_opt,
64
    .bit_out_func = cable_common_write_bit,
65
    .bit_inout_func = cable_common_read_write_bit,
66
    .stream_out_func = cable_common_write_stream,
67
    .stream_inout_func = cable_common_read_stream,
68
    .flush_func = NULL,
69 59 nyawn
#ifdef __CYGWIN_HOST__
70 55 nyawn
    .opts = "p:",
71
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n"
72 59 nyawn
#else
73
    .opts = "d:",
74
    .help = "-d [device file] Device file to use when communicating with the parport hardware (eg. /dev/parport0)\n"
75
#endif
76 55 nyawn
    };
77
 
78 59 nyawn
jtag_cable_t bb2_cable_driver = {
79
 .name = "bb2",
80
 .inout_func = cable_bb2_inout,
81
 .out_func = cable_bb2_out,
82
 .init_func = cable_parallel_init,
83
 .opt_func = cable_parallel_opt,
84
 .bit_out_func = cable_common_write_bit,
85
 .bit_inout_func = cable_common_read_write_bit,
86
 .stream_out_func = cable_common_write_stream,
87
 .stream_inout_func = cable_common_read_stream,
88
 .flush_func = NULL,
89
#ifdef __CYGWIN_HOST__
90
    .opts = "p:",
91
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n"
92
#else
93
    .opts = "d:",
94
    .help = "-d [device file] Device file to use when communicating with the parport hardware (eg. /dev/parport0)\n"
95
#endif
96
 };
97
 
98 55 nyawn
jtag_cable_t xess_cable_driver = {
99
    .name = "xess",
100
    .inout_func = cable_xess_inout,
101
    .out_func = cable_xess_out,
102
    .init_func = cable_parallel_init,
103
    .opt_func = cable_parallel_opt,
104
    .bit_out_func = cable_common_write_bit,
105
    .bit_inout_func = cable_common_read_write_bit,
106
    .stream_out_func = cable_common_write_stream,
107
    .stream_inout_func = cable_common_read_stream,
108
    .flush_func = NULL,
109 59 nyawn
#ifdef __CYGWIN_HOST__
110 55 nyawn
    .opts = "p:",
111 59 nyawn
    .help = "-p [port] Which port to use when communicating with the parport hardware (eg. 0x378)\n"
112
#else
113
    .opts = "d:",
114
    .help = "-d [device file] Device file to use when communicating with the parport hardware (eg. /dev/parport0)\n"
115
#endif
116 55 nyawn
    };
117
 
118 21 nyawn
 
119
// Common functions used by both cable types
120
static int cable_parallel_out(uint8_t value);
121
static int cable_parallel_inout(uint8_t value, uint8_t *inval);
122
 
123 55 nyawn
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
124
 #ifndef PARALLEL_USE_PROCESS_TIMER
125
 struct timeval last_tv;
126
 #endif
127
#endif
128 21 nyawn
 
129 59 nyawn
// If cygwin, we use inb / outb for parallel port access
130
#ifdef __CYGWIN_HOST__
131
 
132
#define LPT_READ (base+1)
133
#define LPT_WRITE base
134
 
135
static int base = 0x378;
136
 
137 21 nyawn
/////////////////////////////////////////////////////////////////////////////////
138
/*-------------------------------------[ Parallel port specific functions ]---*/
139
///////////////////////////////////////////////////////////////////////////////
140
 
141
int cable_parallel_init()
142
{
143
  if (ioperm(base, 3, 1)) {
144
    fprintf(stderr, "Couldn't get the port at %x\n", base);
145
    perror("Root privileges are required.\n");
146
    return APP_ERR_INIT_FAILED;
147
  }
148
  printf("Connected to parallel port at %x\n", base);
149
  printf("Dropping root privileges.\n");
150
  setreuid(getuid(), getuid());
151
 
152 55 nyawn
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
153
 #ifdef PARALLEL_USE_PROCESS_TIMER
154
  struct timespec ts;
155
  ts.tv_sec = 0;
156
  ts.tv_nsec = 0;
157
  clock_settime(CLOCK_PROCESS_CPUTIME_ID, &ts);
158
 #else
159
  gettimeofday(&last_tv, NULL);
160
 #endif
161
#endif
162
 
163 21 nyawn
  return APP_ERR_NONE;
164
}
165
 
166
int cable_parallel_opt(int c, char *str)
167
{
168
  switch(c) {
169
  case 'p':
170
    if(!sscanf(str, "%x", &base)) {
171
      fprintf(stderr, "p parameter must have a hex number as parameter\n");
172
      return APP_ERR_BAD_PARAM;
173
    }
174
    break;
175
  default:
176
    fprintf(stderr, "Unknown parameter '%c'\n", c);
177
    return APP_ERR_BAD_PARAM;
178
  }
179
  return APP_ERR_NONE;
180
}
181
 
182 59 nyawn
/*----------------------------------------------[ common helper functions ]---*/
183
// 'static' for internal access only
184
 
185
static int cable_parallel_out(uint8_t value)
186
{
187
  outb(value, LPT_WRITE);
188
  return APP_ERR_NONE;
189
}
190
 
191
static int cable_parallel_inout(uint8_t value, uint8_t *inval)
192
{
193
  *inval = inb(LPT_READ);
194
  outb(value, LPT_WRITE);
195
 
196
  return APP_ERR_NONE;
197
}
198
 
199
// For Linux / BSD, we use open / ioctl for parallel port access,
200
// so that we don't need root permissions
201
#else // ! defined __CYGWIN_HOST__
202
 
203
#ifdef __FREEBSD_HOST__
204
static int PPORT_PUT_DATA = PPISDATA;
205
static int PPORT_GET_DATA = PPIGSTATUS;
206
#else
207
static int PPORT_PUT_DATA = PPWDATA;
208
static int PPORT_GET_DATA = PPRSTATUS;
209
#endif
210
 
211
static int fd;
212
static char default_dev_str[20] = "/dev/parport0";
213
static char *devsys = default_dev_str;
214
 
215
 
216
/////////////////////////////////////////////////////////////////////////////////
217
/*-------------------------------------[ Parallel port specific functions ]---*/
218
///////////////////////////////////////////////////////////////////////////////
219
 
220
int cable_parallel_init()
221
{
222
  int mode = IEEE1284_MODE_COMPAT;
223
  fd = open(devsys, O_RDWR | O_NONBLOCK);
224
  if (fd == -1)
225
  {
226
    perror("Unable to open the device desriptor\n");
227
    fprintf(stderr, "Check permission of %s (eg. 'ls -la %s').\n", devsys, devsys);
228
    fprintf(stderr, "Your user ID can be added to %s's group to allow for unprivileged access.\n", devsys);
229
    return APP_ERR_INIT_FAILED;
230
  }
231
 
232
  // I don't know if these ioctl() are supported under FreeBSD
233
#ifdef __LINUX_HOST__
234
  if (ioctl(fd, PPCLAIM) == -1)
235
  {
236
    perror("Fail to claim the parallel port device interface.\n");
237
    return APP_ERR_INIT_FAILED;
238
  }
239
  if (ioctl(fd, PPSETMODE, &mode) == -1)
240
  {
241
    perror("Setting compatibility mode on parallel port device failed.\n");
242
    return APP_ERR_INIT_FAILED;
243
  }
244
#endif
245
 
246
#ifdef __PARALLEL_TIMER_BUSY_WAIT__
247
 #ifdef PARALLEL_USE_PROCESS_TIMER
248
  struct timespec ts;
249
  ts.tv_sec = 0;
250
  ts.tv_nsec = 0;
251
  clock_settime(CLOCK_PROCESS_CPUTIME_ID, &ts);
252
 #else
253
  gettimeofday(&last_tv, NULL);
254
 #endif
255
#endif
256
 
257
  return APP_ERR_NONE;
258
}
259
 
260
 
261
int cable_parallel_opt(int c, char *str)
262
{
263
  switch(c) {
264
  case 'd':
265
    devsys = strdup(str);
266
    break;
267
  default:
268
    fprintf(stderr, "Unknown parameter '%c'\n", c);
269
    return APP_ERR_BAD_PARAM;
270
  }
271
  return APP_ERR_NONE;
272
}
273
 
274
/*----------------------------------------------[ common helper functions ]---*/
275
// 'static' for internal access only
276
 
277
static int cable_parallel_out(uint8_t value)
278
{
279
  ioctl(fd, PPORT_PUT_DATA, &value);
280
 
281
  return APP_ERR_NONE;
282
}
283
 
284
static int cable_parallel_inout(uint8_t value, uint8_t *inval)
285
{
286
  ioctl(fd, PPORT_GET_DATA, inval);
287
  ioctl(fd, PPORT_PUT_DATA, &value);
288
 
289
  return APP_ERR_NONE;
290
}
291
 
292
#endif  // !defined __CYGWIN_HOST__
293
 
294 21 nyawn
/*-----------------------------------------[ Physical board wait function ]---*/
295 55 nyawn
 
296
/* Multiple users have reported poor performance of parallel cables,
297
 * which has been traced to various sleep functions sleeping much longer than
298
 * microseconds.  The same users have reported error-free functionality
299 59 nyawn
 * and an order of magnitude improvement in upload speed with no wait.
300 55 nyawn
 * Other users have reported errors when running without a wait.
301
 * Impact apparently limits the frequency of parallel JTAG cables
302
 * to 200 kHz, and some clones fail at higher speeds.
303
 */
304
 
305
 
306
 
307
#ifdef __PARALLEL_SLEEP_WAIT__
308 21 nyawn
void cable_parallel_phys_wait()
309
{
310 55 nyawn
  struct timespec ts;
311
  ts.tv_sec = 0;
312
  ts.tv_nsec = 2500;
313
  nanosleep(&ts, NULL);
314 21 nyawn
}
315 55 nyawn
#else
316 21 nyawn
 
317 55 nyawn
 #ifdef __PARALLEL_TIMER_BUSY_WAIT__
318
 
319
  #ifndef PARALLEL_USE_PROCESS_TIMER
320
 
321
/* Helper function needed if process timer isn't implemented */
322
/* do x-y */
323
int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y)
324
{
325
  /* Perform the carry for the later subtraction by updating y. */
326
  if (x->tv_usec < y->tv_usec) {
327
    int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
328
    y->tv_usec -= 1000000 * nsec;
329
    y->tv_sec += nsec;
330
  }
331
  if (x->tv_usec - y->tv_usec > 1000000) {
332
    int nsec = (x->tv_usec - y->tv_usec) / 1000000;
333
    y->tv_usec += 1000000 * nsec;
334
    y->tv_sec -= nsec;
335
  }
336
 
337
  /* Compute the time remaining to wait.
338
     tv_usec is certainly positive. */
339
  result->tv_sec = x->tv_sec - y->tv_sec;
340
  result->tv_usec = x->tv_usec - y->tv_usec;
341
 
342
  /* Return 1 if result is negative. */
343
  return x->tv_sec < y->tv_sec;
344
}
345
  #endif
346
 
347
 
348
void cable_parallel_phys_wait()
349
{
350
  /* This busy wait attempts to make the frequency exactly 200kHz,
351
   * including the processing time between ticks.
352
   * This means a period of 5us, or half a period of 2.5us.
353
   */
354
  #ifdef PARALLEL_USE_PROCESS_TIMER
355
  struct timespec ts;
356
  do
357
    {
358
      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
359
    } while((ts.tv_sec == 0) && (ts.tv_nsec < 2500));
360
 
361
  /* Doing the set after the check means that processing time
362
   * is not added to the wait. */
363
  ts.tv_sec = 0;
364
  ts.tv_nsec = 0;
365
  clock_settime(CLOCK_PROCESS_CPUTIME_ID, &ts);
366
  #else
367
  struct timeval now_tv;
368
  struct timeval results_tv;
369
  do
370
    {
371
      gettimeofday(&now_tv, NULL);
372
      timeval_subtract (&results_tv, &now_tv, &last_tv);
373
    } while((results_tv.tv_sec == 0) && (results_tv.tv_usec < 3));
374
  last_tv = now_tv;
375
  #endif
376
}
377
 
378
 #else  // NO WAIT
379
 
380
void cable_parallel_phys_wait()
381
{
382
  // No wait, run max speed
383
}
384
 
385
 #endif
386
#endif
387
 
388
 
389 21 nyawn
/*----------------------------------------------[ xpc3 specific functions ]---*/
390 55 nyawn
jtag_cable_t *cable_xpc3_get_driver(void)
391
{
392
  return &xpc3_cable_driver;
393
}
394
 
395 21 nyawn
int cable_xpc3_out(uint8_t value)
396
{
397
  uint8_t out = 0;
398
 
399 55 nyawn
  cable_parallel_phys_wait();  // Limit the max clock rate if necessary
400
 
401 21 nyawn
  /* First convert the bits in value byte to the ones that the cable wants */
402
  if(value & TCLK_BIT)
403
    out |= 0x02; /* D1 pin 3 */
404
  if(value & TRST_BIT)
405
    out |= 0x10; /* Not used */
406
  if(value & TDI_BIT)
407
    out |= 0x01; /* D0 pin 2 */
408
  if(value & TMS_BIT)
409
    out |= 0x04; /* D2 pin 4 */
410
 
411
  return cable_parallel_out(out);
412
}
413
 
414
int cable_xpc3_inout(uint8_t value, uint8_t *inval)
415
{
416
  uint8_t in;
417
  int retval;
418
  uint8_t out = 0;
419
 
420 55 nyawn
  cable_parallel_phys_wait();  // Limit the max clock rate if necessary
421
 
422 21 nyawn
  /* First convert the bits in value byte to the ones that the cable wants */
423
  if(value & TCLK_BIT)
424
    out |= 0x02; /* D1 pin 3 */
425
  if(value & TRST_BIT)
426
    out |= 0x10; /* Not used */
427
  if(value & TDI_BIT)
428
    out |= 0x01; /* D0 pin 2 */
429
  if(value & TMS_BIT)
430
    out |= 0x04; /* D2 pin 4 */
431
 
432
  retval = cable_parallel_inout(out, &in);
433
 
434
  if(in & 0x10) /* S6 pin 13 */
435
    *inval = 1;
436
  else
437
    *inval = 0;
438
 
439
  return retval;
440
}
441
 
442 59 nyawn
 
443
/*----------------------------------------------[ bb2 specific functions ]---*/
444
jtag_cable_t *cable_bb2_get_driver(void)
445
{
446
 return &bb2_cable_driver;
447
}
448
 
449
int cable_bb2_out(uint8_t value)
450
{
451
 uint8_t out = 0;
452
 
453
 cable_parallel_phys_wait(); // Limit the max clock rate if necessary
454
 
455
 /* First convert the bits in value byte to the ones that the cable wants */
456
 if(value & TCLK_BIT)
457
   out |= 0x01; /* D0 pin 2 */
458
 if(value & TDI_BIT)
459
   out |= 0x40; /* D7 pin 8 */
460
 if(value & TMS_BIT)
461
   out |= 0x02; /* D1 pin 3 */
462
 
463
 return cable_parallel_out(out);
464
}
465
 
466
int cable_bb2_inout(uint8_t value, uint8_t *inval)
467
{
468
 uint8_t in;
469
 int retval;
470
 uint8_t out = 0;
471
 
472
 cable_parallel_phys_wait(); // Limit the max clock rate if necessary
473
 
474
 /* First convert the bits in value byte to the ones that the cable wants */
475
 if(value & TCLK_BIT)
476
   out |= 0x01; /* D0 pin 2 */
477
 if(value & TDI_BIT)
478
   out |= 0x40; /* D7 pin 8 */
479
 if(value & TMS_BIT)
480
   out |= 0x02; /* D1 pin 3 */
481
 
482
 retval = cable_parallel_inout(out, &in);
483
 
484
 if(in & 0x80) /* S7 pin 11 */
485
 *inval = 0;
486
 else
487
 *inval = 1;
488
 
489
 return retval;
490
}
491
 
492
 
493 21 nyawn
/*----------------------------------------------[ xess specific functions ]---*/
494 55 nyawn
jtag_cable_t *cable_xess_get_driver(void)
495
{
496
  return &xess_cable_driver;
497
}
498
 
499 21 nyawn
int cable_xess_out(uint8_t value)
500
{
501
  uint8_t out = 0;
502
 
503 55 nyawn
  cable_parallel_phys_wait();  // Limit the max clock rate if necessary
504
 
505 21 nyawn
  /* First convert the bits in value byte to the ones that the cable wants */
506
  if(value & TCLK_BIT)
507
    out |= 0x04; /* D2 pin 4 */
508
  if(value & TRST_BIT)
509
    out |= 0x08; /* D3 pin 5 */
510
  if(value & TDI_BIT)
511
    out |= 0x10; /* D4 pin 6 */
512
  if(value & TMS_BIT)
513
    out |= 0x20; /* D3 pin 5 */
514
 
515
  return cable_parallel_out(out);
516
}
517
 
518 55 nyawn
int cable_xess_inout(uint8_t value, uint8_t *inval)
519 21 nyawn
{
520
  uint8_t in;
521
  int retval;
522 22 nyawn
  uint8_t out = 0;
523 21 nyawn
 
524 55 nyawn
  cable_parallel_phys_wait();  // Limit the max clock rate if necessary
525
 
526 22 nyawn
  /* First convert the bits in value byte to the ones that the cable wants */
527
  if(value & TCLK_BIT)
528
    out |= 0x04; /* D2 pin 4 */
529
  if(value & TRST_BIT)
530
    out |= 0x08; /* D3 pin 5 */
531
  if(value & TDI_BIT)
532
    out |= 0x10; /* D4 pin 6 */
533
  if(value & TMS_BIT)
534
    out |= 0x20; /* D3 pin 5 */
535 21 nyawn
 
536 22 nyawn
  retval = cable_parallel_inout(out, &in);
537
 
538 21 nyawn
  if(in & 0x20) /* S5 pin 12*/
539
    *inval = 1;
540
  else
541
    *inval = 0;
542
 
543
  return retval;
544
}
545
 
546
 

powered by: WebSVN 2.1.0

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