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 #include "replacements.h"
33 /* -ino: 060521-1036 */
34 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
36 #include <sys/types.h>
37 #include <machine/sysarch.h>
38 #include <machine/cpufunc.h>
39 #define ioperm(startport,length,enable)\
40 i386_set_ioperm((startport), (length), (enable))
48 #endif /* __FreeBSD__ */
54 #if PARPORT_USE_PPDEV == 1
55 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
56 #include <dev/ppbus/ppi.h>
57 #include <dev/ppbus/ppbconf.h>
58 #define PPRSTATUS PPIGSTATUS
59 #define PPWDATA PPISDATA
61 #include <linux/parport.h>
62 #include <linux/ppdev.h>
65 #include <sys/ioctl.h>
66 #else /* not PARPORT_USE_PPDEV */
72 #if PARPORT_USE_GIVEIO == 1
81 /* parallel port cable description
83 typedef struct cable_s
86 u8 TDO_MASK
; /* status port bit containing current TDO value */
87 u8 TRST_MASK
; /* data port bit for TRST */
88 u8 TMS_MASK
; /* data port bit for TMS */
89 u8 TCK_MASK
; /* data port bit for TCK */
90 u8 TDI_MASK
; /* data port bit for TDI */
91 u8 SRST_MASK
; /* data port bit for SRST */
92 u8 OUTPUT_INVERT
; /* data port bits that should be inverted */
93 u8 INPUT_INVERT
; /* status port that should be inverted */
94 u8 PORT_INIT
; /* initialize data port with this value */
95 u8 PORT_EXIT
; /* de-initialize data port with this value */
96 u8 LED_MASK
; /* data port bit for LED */
101 /* name tdo trst tms tck tdi srst o_inv i_inv init exit led */
102 { "wiggler", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x80, 0x00 },
103 { "wiggler2", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x00, 0x20 },
104 { "wiggler_ntrst_inverted",
105 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x11, 0x80, 0x80, 0x80, 0x00 },
106 { "old_amt_wiggler", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x80, 0x80, 0x80, 0x00 },
107 { "arm-jtag", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x01, 0x80, 0x80, 0x80, 0x00 },
108 { "chameleon", 0x80, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },
109 { "dlc5", 0x10, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00 },
110 { "triton", 0x80, 0x08, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },
111 { "lattice", 0x40, 0x10, 0x04, 0x02, 0x01, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00 },
112 { "flashlink", 0x20, 0x10, 0x02, 0x01, 0x04, 0x20, 0x30, 0x20, 0x00, 0x00, 0x00 },
113 /* Altium Universal JTAG cable. Set the cable to Xilinx Mode and wire to target as follows:
114 HARD TCK - Target TCK
115 HARD TMS - Target TMS
116 HARD TDI - Target TDI
117 HARD TDO - Target TDO
118 SOFT TCK - Target TRST
119 SOFT TDI - Target SRST
121 { "altium", 0x10, 0x20, 0x04, 0x02, 0x01, 0x80, 0x00, 0x00, 0x10, 0x00, 0x08 },
122 { NULL
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
126 char* parport_cable
= NULL
;
128 static int parport_exit
= 0;
130 /* interface variables
132 static cable_t
* cable
;
133 static u8 dataport_value
= 0x0;
135 #if PARPORT_USE_PPDEV == 1
136 static int device_handle
;
138 static unsigned long dataport
;
139 static unsigned long statusport
;
142 /* low level command set
144 int parport_read(void);
145 void parport_write(int tck
, int tms
, int tdi
);
146 void parport_reset(int trst
, int srst
);
147 void parport_led(int on
);
149 int parport_speed(int speed
);
150 int parport_register_commands(struct command_context_s
*cmd_ctx
);
151 int parport_init(void);
152 int parport_quit(void);
154 /* interface commands */
155 int parport_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
156 int parport_handle_parport_cable_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
157 int parport_handle_write_on_exit_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
159 jtag_interface_t parport_interface
=
163 .execute_queue
= bitbang_execute_queue
,
165 .speed
= parport_speed
,
166 .register_commands
= parport_register_commands
,
167 .init
= parport_init
,
168 .quit
= parport_quit
,
171 bitbang_interface_t parport_bitbang
=
173 .read
= parport_read
,
174 .write
= parport_write
,
175 .reset
= parport_reset
,
179 int parport_read(void)
183 #if PARPORT_USE_PPDEV == 1
184 ioctl(device_handle
, PPRSTATUS
, & data
);
186 data
= inb(statusport
);
189 if ((data
^ cable
->INPUT_INVERT
) & cable
->TDO_MASK
)
195 static __inline__
void parport_write_data(void)
198 output
= dataport_value
^ cable
->OUTPUT_INVERT
;
200 #if PARPORT_USE_PPDEV == 1
201 ioctl(device_handle
, PPWDATA
, &output
);
203 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
204 outb(dataport
, output
);
206 outb(output
, dataport
);
211 void parport_write(int tck
, int tms
, int tdi
)
213 int i
= jtag_speed
+ 1;
216 dataport_value
|= cable
->TCK_MASK
;
218 dataport_value
&= ~cable
->TCK_MASK
;
221 dataport_value
|= cable
->TMS_MASK
;
223 dataport_value
&= ~cable
->TMS_MASK
;
226 dataport_value
|= cable
->TDI_MASK
;
228 dataport_value
&= ~cable
->TDI_MASK
;
231 parport_write_data();
234 /* (1) assert or (0) deassert reset lines */
235 void parport_reset(int trst
, int srst
)
237 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
240 dataport_value
|= cable
->TRST_MASK
;
242 dataport_value
&= ~cable
->TRST_MASK
;
245 dataport_value
|= cable
->SRST_MASK
;
247 dataport_value
&= ~cable
->SRST_MASK
;
249 parport_write_data();
252 /* turn LED on parport adapter on (1) or off (0) */
253 void parport_led(int on
)
256 dataport_value
|= cable
->LED_MASK
;
258 dataport_value
&= ~cable
->LED_MASK
;
260 parport_write_data();
263 int parport_speed(int speed
)
268 int parport_register_commands(struct command_context_s
*cmd_ctx
)
270 register_command(cmd_ctx
, NULL
, "parport_port", parport_handle_parport_port_command
,
271 COMMAND_CONFIG
, NULL
);
272 register_command(cmd_ctx
, NULL
, "parport_cable", parport_handle_parport_cable_command
,
273 COMMAND_CONFIG
, NULL
);
274 register_command(cmd_ctx
, NULL
, "parport_write_on_exit", parport_handle_write_on_exit_command
,
275 COMMAND_CONFIG
, NULL
);
280 #if PARPORT_USE_GIVEIO == 1
281 int parport_get_giveio_access(void)
284 OSVERSIONINFO version
;
286 version
.dwOSVersionInfoSize
= sizeof version
;
287 if (!GetVersionEx( &version
)) {
291 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
294 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
295 if (h
== INVALID_HANDLE_VALUE
) {
306 int parport_init(void)
309 #if PARPORT_USE_PPDEV == 1
316 if ((parport_cable
== NULL
) || (parport_cable
[0] == 0))
318 parport_cable
= "wiggler";
319 LOG_WARNING("No parport cable specified, using default 'wiggler'");
322 while (cur_cable
->name
)
324 if (strcmp(cur_cable
->name
, parport_cable
) == 0)
334 LOG_ERROR("No matching cable found for %s", parport_cable
);
335 return ERROR_JTAG_INIT_FAILED
;
338 dataport_value
= cable
->PORT_INIT
;
340 #if PARPORT_USE_PPDEV == 1
341 if (device_handle
> 0)
343 LOG_ERROR("device is already opened");
344 return ERROR_JTAG_INIT_FAILED
;
347 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
348 LOG_DEBUG("opening /dev/ppi%d...", parport_port
);
350 snprintf(buffer
, 256, "/dev/ppi%d", parport_port
);
351 device_handle
= open(buffer
, O_WRONLY
);
352 #else /* not __FreeBSD__, __FreeBSD_kernel__ */
353 LOG_DEBUG("opening /dev/parport%d...", parport_port
);
355 snprintf(buffer
, 256, "/dev/parport%d", parport_port
);
356 device_handle
= open(buffer
, O_WRONLY
);
357 #endif /* __FreeBSD__, __FreeBSD_kernel__ */
359 if (device_handle
< 0)
361 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
362 return ERROR_JTAG_INIT_FAILED
;
365 LOG_DEBUG("...open");
367 #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
368 i
=ioctl(device_handle
, PPCLAIM
);
371 LOG_ERROR("cannot claim device");
372 return ERROR_JTAG_INIT_FAILED
;
375 i
= PARPORT_MODE_COMPAT
;
376 i
= ioctl(device_handle
, PPSETMODE
, & i
);
379 LOG_ERROR(" cannot set compatible mode to device");
380 return ERROR_JTAG_INIT_FAILED
;
383 i
= IEEE1284_MODE_COMPAT
;
384 i
= ioctl(device_handle
, PPNEGOT
, & i
);
387 LOG_ERROR("cannot set compatible 1284 mode to device");
388 return ERROR_JTAG_INIT_FAILED
;
390 #endif /* not __FreeBSD__, __FreeBSD_kernel__ */
392 #else /* not PARPORT_USE_PPDEV */
393 if (parport_port
== 0)
395 parport_port
= 0x378;
396 LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
399 dataport
= parport_port
;
400 statusport
= parport_port
+ 1;
402 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", dataport
);
403 #if PARPORT_USE_GIVEIO == 1
404 if (parport_get_giveio_access() != 0)
405 #else /* PARPORT_USE_GIVEIO */
406 if (ioperm(dataport
, 3, 1) != 0)
407 #endif /* PARPORT_USE_GIVEIO */
409 LOG_ERROR("missing privileges for direct i/o");
410 return ERROR_JTAG_INIT_FAILED
;
412 LOG_DEBUG("...privileges granted");
414 /* make sure parallel port is in right mode (clear tristate and interrupt */
415 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
416 outb(parport_port
+ 2, 0x0);
418 outb(0x0, parport_port
+ 2);
421 #endif /* PARPORT_USE_PPDEV */
424 parport_write(0, 0, 0);
427 bitbang_interface
= &parport_bitbang
;
432 int parport_quit(void)
438 dataport_value
= cable
->PORT_EXIT
;
439 parport_write_data();
445 parport_cable
= NULL
;
451 int parport_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
456 /* only if the port wasn't overwritten by cmdline */
457 if (parport_port
== 0)
458 parport_port
= strtoul(args
[0], NULL
, 0);
463 int parport_handle_parport_cable_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
468 /* only if the cable name wasn't overwritten by cmdline */
469 if (parport_cable
== 0)
471 parport_cable
= malloc(strlen(args
[0]) + sizeof(char));
472 strcpy(parport_cable
, args
[0]);
478 int parport_handle_write_on_exit_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
482 command_print(cmd_ctx
, "usage: parport_write_on_exit <on|off>");
486 if (strcmp(args
[0], "on") == 0)
488 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)