1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
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. *
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. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
27 #define INCLUDE_JTAG_INTERFACE_H
31 /* -ino: 060521-1036 */
32 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
33 #include <machine/sysarch.h>
34 #include <machine/cpufunc.h>
35 #define ioperm(startport,length,enable)\
36 i386_set_ioperm((startport), (length), (enable))
37 #endif /* __FreeBSD__ */
39 #if PARPORT_USE_PPDEV == 1
40 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
41 #include <dev/ppbus/ppi.h>
42 #include <dev/ppbus/ppbconf.h>
43 #define PPRSTATUS PPIGSTATUS
44 #define PPWDATA PPISDATA
46 #include <linux/parport.h>
47 #include <linux/ppdev.h>
49 #include <sys/ioctl.h>
50 #else /* not PARPORT_USE_PPDEV */
56 #if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1
61 /* parallel port cable description
63 typedef struct cable_s
66 u8 TDO_MASK
; /* status port bit containing current TDO value */
67 u8 TRST_MASK
; /* data port bit for TRST */
68 u8 TMS_MASK
; /* data port bit for TMS */
69 u8 TCK_MASK
; /* data port bit for TCK */
70 u8 TDI_MASK
; /* data port bit for TDI */
71 u8 SRST_MASK
; /* data port bit for SRST */
72 u8 OUTPUT_INVERT
; /* data port bits that should be inverted */
73 u8 INPUT_INVERT
; /* status port that should be inverted */
74 u8 PORT_INIT
; /* initialize data port with this value */
75 u8 PORT_EXIT
; /* de-initialize data port with this value */
76 u8 LED_MASK
; /* data port bit for LED */
79 static cable_t cables
[] =
81 /* name tdo trst tms tck tdi srst o_inv i_inv init exit led */
82 { "wiggler", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x80, 0x00 },
83 { "wiggler2", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x00, 0x20 },
84 { "wiggler_ntrst_inverted",
85 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x11, 0x80, 0x80, 0x80, 0x00 },
86 { "old_amt_wiggler", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x80, 0x80, 0x80, 0x00 },
87 { "arm-jtag", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x01, 0x80, 0x80, 0x80, 0x00 },
88 { "chameleon", 0x80, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },
89 { "dlc5", 0x10, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00 },
90 { "triton", 0x80, 0x08, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },
91 { "lattice", 0x40, 0x10, 0x04, 0x02, 0x01, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00 },
92 { "flashlink", 0x20, 0x10, 0x02, 0x01, 0x04, 0x20, 0x30, 0x20, 0x00, 0x00, 0x00 },
93 /* Altium Universal JTAG cable. Set the cable to Xilinx Mode and wire to target as follows:
98 SOFT TCK - Target TRST
99 SOFT TDI - Target SRST
101 { "altium", 0x10, 0x20, 0x04, 0x02, 0x01, 0x80, 0x00, 0x00, 0x10, 0x00, 0x08 },
102 { NULL
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
106 static char* parport_cable
= NULL
;
107 static u16 parport_port
;
108 static int parport_exit
= 0;
110 /* interface variables
112 static cable_t
* cable
;
113 static u8 dataport_value
= 0x0;
115 #if PARPORT_USE_PPDEV == 1
116 static int device_handle
;
118 static unsigned long dataport
;
119 static unsigned long statusport
;
122 /* low level command set
124 static int parport_read(void);
125 static void parport_write(int tck
, int tms
, int tdi
);
126 static void parport_reset(int trst
, int srst
);
127 static void parport_led(int on
);
129 static int parport_speed(int speed
);
130 static int parport_register_commands(struct command_context_s
*cmd_ctx
);
131 static int parport_init(void);
132 static int parport_quit(void);
134 /* interface commands */
135 static int parport_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
136 static int parport_handle_parport_cable_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
137 static int parport_handle_write_on_exit_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
139 jtag_interface_t parport_interface
=
143 .execute_queue
= bitbang_execute_queue
,
145 .speed
= parport_speed
,
146 .register_commands
= parport_register_commands
,
147 .init
= parport_init
,
148 .quit
= parport_quit
,
151 static bitbang_interface_t parport_bitbang
=
153 .read
= parport_read
,
154 .write
= parport_write
,
155 .reset
= parport_reset
,
159 static int parport_read(void)
163 #if PARPORT_USE_PPDEV == 1
164 ioctl(device_handle
, PPRSTATUS
, & data
);
166 data
= inb(statusport
);
169 if ((data
^ cable
->INPUT_INVERT
) & cable
->TDO_MASK
)
175 static __inline__
void parport_write_data(void)
178 output
= dataport_value
^ cable
->OUTPUT_INVERT
;
180 #if PARPORT_USE_PPDEV == 1
181 ioctl(device_handle
, PPWDATA
, &output
);
183 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
184 outb(dataport
, output
);
186 outb(output
, dataport
);
191 static void parport_write(int tck
, int tms
, int tdi
)
193 int i
= jtag_speed
+ 1;
196 dataport_value
|= cable
->TCK_MASK
;
198 dataport_value
&= ~cable
->TCK_MASK
;
201 dataport_value
|= cable
->TMS_MASK
;
203 dataport_value
&= ~cable
->TMS_MASK
;
206 dataport_value
|= cable
->TDI_MASK
;
208 dataport_value
&= ~cable
->TDI_MASK
;
211 parport_write_data();
214 /* (1) assert or (0) deassert reset lines */
215 static void parport_reset(int trst
, int srst
)
217 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
220 dataport_value
|= cable
->TRST_MASK
;
222 dataport_value
&= ~cable
->TRST_MASK
;
225 dataport_value
|= cable
->SRST_MASK
;
227 dataport_value
&= ~cable
->SRST_MASK
;
229 parport_write_data();
232 /* turn LED on parport adapter on (1) or off (0) */
233 static void parport_led(int on
)
236 dataport_value
|= cable
->LED_MASK
;
238 dataport_value
&= ~cable
->LED_MASK
;
240 parport_write_data();
243 static int parport_speed(int speed
)
248 static int parport_register_commands(struct command_context_s
*cmd_ctx
)
250 register_command(cmd_ctx
, NULL
, "parport_port", parport_handle_parport_port_command
,
251 COMMAND_CONFIG
, "either the address of the I/O port or the number of the \91/dev/parport\92 device");
252 register_command(cmd_ctx
, NULL
, "parport_cable", parport_handle_parport_cable_command
,
253 COMMAND_CONFIG
, "the layout of the parallel port cable used to connect to the target");
254 register_command(cmd_ctx
, NULL
, "parport_write_on_exit", parport_handle_write_on_exit_command
,
255 COMMAND_CONFIG
, "configure the parallel driver to write a known value to the parallel interface");
260 #if PARPORT_USE_GIVEIO == 1
261 static int parport_get_giveio_access(void)
264 OSVERSIONINFO version
;
266 version
.dwOSVersionInfoSize
= sizeof version
;
267 if (!GetVersionEx( &version
)) {
271 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
274 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
275 if (h
== INVALID_HANDLE_VALUE
) {
286 static int parport_init(void)
289 #if PARPORT_USE_PPDEV == 1
296 if ((parport_cable
== NULL
) || (parport_cable
[0] == 0))
298 parport_cable
= "wiggler";
299 LOG_WARNING("No parport cable specified, using default 'wiggler'");
302 while (cur_cable
->name
)
304 if (strcmp(cur_cable
->name
, parport_cable
) == 0)
314 LOG_ERROR("No matching cable found for %s", parport_cable
);
315 return ERROR_JTAG_INIT_FAILED
;
318 dataport_value
= cable
->PORT_INIT
;
320 #if PARPORT_USE_PPDEV == 1
321 if (device_handle
> 0)
323 LOG_ERROR("device is already opened");
324 return ERROR_JTAG_INIT_FAILED
;
327 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
328 LOG_DEBUG("opening /dev/ppi%d...", parport_port
);
330 snprintf(buffer
, 256, "/dev/ppi%d", parport_port
);
331 device_handle
= open(buffer
, O_WRONLY
);
332 #else /* not __FreeBSD__, __FreeBSD_kernel__ */
333 LOG_DEBUG("opening /dev/parport%d...", parport_port
);
335 snprintf(buffer
, 256, "/dev/parport%d", parport_port
);
336 device_handle
= open(buffer
, O_WRONLY
);
337 #endif /* __FreeBSD__, __FreeBSD_kernel__ */
339 if (device_handle
< 0)
341 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
342 return ERROR_JTAG_INIT_FAILED
;
345 LOG_DEBUG("...open");
347 #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
348 i
=ioctl(device_handle
, PPCLAIM
);
351 LOG_ERROR("cannot claim device");
352 return ERROR_JTAG_INIT_FAILED
;
355 i
= PARPORT_MODE_COMPAT
;
356 i
= ioctl(device_handle
, PPSETMODE
, & i
);
359 LOG_ERROR(" cannot set compatible mode to device");
360 return ERROR_JTAG_INIT_FAILED
;
363 i
= IEEE1284_MODE_COMPAT
;
364 i
= ioctl(device_handle
, PPNEGOT
, & i
);
367 LOG_ERROR("cannot set compatible 1284 mode to device");
368 return ERROR_JTAG_INIT_FAILED
;
370 #endif /* not __FreeBSD__, __FreeBSD_kernel__ */
372 #else /* not PARPORT_USE_PPDEV */
373 if (parport_port
== 0)
375 parport_port
= 0x378;
376 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
379 dataport
= parport_port
;
380 statusport
= parport_port
+ 1;
382 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", dataport
);
383 #if PARPORT_USE_GIVEIO == 1
384 if (parport_get_giveio_access() != 0)
385 #else /* PARPORT_USE_GIVEIO */
386 if (ioperm(dataport
, 3, 1) != 0)
387 #endif /* PARPORT_USE_GIVEIO */
389 LOG_ERROR("missing privileges for direct i/o");
390 return ERROR_JTAG_INIT_FAILED
;
392 LOG_DEBUG("...privileges granted");
394 /* make sure parallel port is in right mode (clear tristate and interrupt */
395 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
396 outb(parport_port
+ 2, 0x0);
398 outb(0x0, parport_port
+ 2);
401 #endif /* PARPORT_USE_PPDEV */
404 parport_write(0, 0, 0);
407 bitbang_interface
= &parport_bitbang
;
412 static int parport_quit(void)
418 dataport_value
= cable
->PORT_EXIT
;
419 parport_write_data();
425 parport_cable
= NULL
;
431 static int parport_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
436 /* only if the port wasn't overwritten by cmdline */
437 if (parport_port
== 0)
438 parport_port
= strtoul(args
[0], NULL
, 0);
443 static int parport_handle_parport_cable_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
448 /* only if the cable name wasn't overwritten by cmdline */
449 if (parport_cable
== 0)
451 parport_cable
= malloc(strlen(args
[0]) + sizeof(char));
452 strcpy(parport_cable
, args
[0]);
458 static int parport_handle_write_on_exit_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
462 command_print(cmd_ctx
, "usage: parport_write_on_exit <on|off>");
466 if (strcmp(args
[0], "on") == 0)
468 else if (strcmp(args
[0], "off") == 0)
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)