1 /***************************************************************************
2 * Copyright (C) 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
29 #define _DEBUG_GW16012_IO_
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__, __FreeBSD_kernel__ */
56 #if PARPORT_USE_PPDEV == 1
57 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
58 #include <dev/ppbus/ppi.h>
59 #include <dev/ppbus/ppbconf.h>
60 #define PPRSTATUS PPIGSTATUS
61 #define PPWDATA PPISDATA
63 #include <linux/parport.h>
64 #include <linux/ppdev.h>
67 #include <sys/ioctl.h>
68 #else /* not PARPORT_USE_PPDEV */
74 #if PARPORT_USE_GIVEIO == 1
86 /* interface variables
88 static u8 gw16012_msb
= 0x0;
89 static u8 gw16012_control_value
= 0x0;
91 #if PARPORT_USE_PPDEV == 1
92 static int device_handle
;
95 int gw16012_execute_queue(void);
96 int gw16012_register_commands(struct command_context_s
*cmd_ctx
);
97 int gw16012_speed(int speed
);
98 int gw16012_init(void);
99 int gw16012_quit(void);
101 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
103 jtag_interface_t gw16012_interface
=
107 .execute_queue
= gw16012_execute_queue
,
109 .speed
= gw16012_speed
,
110 .register_commands
= gw16012_register_commands
,
111 .init
= gw16012_init
,
112 .quit
= gw16012_quit
,
115 int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
117 register_command(cmd_ctx
, NULL
, "parport_port", gw16012_handle_parport_port_command
,
118 COMMAND_CONFIG
, NULL
);
123 void gw16012_data(u8 value
)
125 value
= (value
& 0x7f) | gw16012_msb
;
126 gw16012_msb
^= 0x80; /* toggle MSB */
128 #ifdef _DEBUG_GW16012_IO_
129 LOG_DEBUG("%2.2x", value
);
132 #if PARPORT_USE_PPDEV == 1
133 ioctl(device_handle
, PPWDATA
, &value
);
135 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
136 outb(gw16012_port
, value
);
138 outb(value
, gw16012_port
);
143 void gw16012_control(u8 value
)
145 if (value
!= gw16012_control_value
)
147 gw16012_control_value
= value
;
149 #ifdef _DEBUG_GW16012_IO_
150 LOG_DEBUG("%2.2x", gw16012_control_value
);
153 #if PARPORT_USE_PPDEV == 1
154 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
156 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
157 outb(gw16012_port
+ 2, gw16012_control_value
);
159 outb(gw16012_control_value
, gw16012_port
+ 2);
165 void gw16012_input(u8
*value
)
167 #if PARPORT_USE_PPDEV == 1
168 ioctl(device_handle
, PPRSTATUS
, value
);
170 *value
= inb(gw16012_port
+ 1);
173 #ifdef _DEBUG_GW16012_IO_
174 LOG_DEBUG("%2.2x", *value
);
178 /* (1) assert or (0) deassert reset lines */
179 void gw16012_reset(int trst
, int srst
)
181 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
184 gw16012_control(0x0d);
186 gw16012_control(0x0c);
189 gw16012_control(0x0a);
191 gw16012_control(0x0b);
194 int gw16012_speed(int speed
)
200 void gw16012_end_state(state
)
202 if (tap_move_map
[state
] != -1)
206 LOG_ERROR("BUG: %i is not a valid end state", state
);
211 void gw16012_state_move(void)
214 u8 tms_scan
= TAP_MOVE(cur_state
, end_state
);
216 gw16012_control(0x0); /* single-bit mode */
218 for (i
= 0; i
< 7; i
++)
220 tms
= (tms_scan
>> i
) & 1;
221 gw16012_data(tms
<< 1); /* output next TMS bit */
224 cur_state
= end_state
;
227 void gw16012_path_move(pathmove_command_t
*cmd
)
229 int num_states
= cmd
->num_states
;
235 gw16012_control(0x0); /* single-bit mode */
236 if (tap_transitions
[cur_state
].low
== cmd
->path
[state_count
])
238 gw16012_data(0x0); /* TCK cycle with TMS low */
240 else if (tap_transitions
[cur_state
].high
== cmd
->path
[state_count
])
242 gw16012_data(0x2); /* TCK cycle with TMS high */
246 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[state_count
]]);
250 cur_state
= cmd
->path
[state_count
];
255 end_state
= cur_state
;
258 void gw16012_runtest(int num_cycles
)
260 enum tap_state saved_end_state
= end_state
;
263 /* only do a state_move when we're not already in RTI */
264 if (cur_state
!= TAP_RTI
)
266 gw16012_end_state(TAP_RTI
);
267 gw16012_state_move();
270 for (i
= 0; i
< num_cycles
; i
++)
272 gw16012_control(0x0); /* single-bit mode */
273 gw16012_data(0x0); /* TMS cycle with TMS low */
276 gw16012_end_state(saved_end_state
);
277 if (cur_state
!= end_state
)
278 gw16012_state_move();
281 void gw16012_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
283 int bits_left
= scan_size
;
285 enum tap_state saved_end_state
= end_state
;
286 u8 scan_out
, scan_in
;
288 /* only if we're not already in the correct Shift state */
289 if (!((!ir_scan
&& (cur_state
== TAP_SD
)) || (ir_scan
&& (cur_state
== TAP_SI
))))
292 gw16012_end_state(TAP_SI
);
294 gw16012_end_state(TAP_SD
);
296 gw16012_state_move();
297 gw16012_end_state(saved_end_state
);
300 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
302 gw16012_control(0x2); /* seven-bit mode */
303 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
304 gw16012_data(scan_out
);
309 gw16012_control(0x0); /* single-bit mode */
310 while (bits_left
-- > 0)
314 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
316 if (bits_left
== 0) /* last bit */
318 if ((ir_scan
&& (end_state
== TAP_SI
))
319 || (!ir_scan
&& (end_state
== TAP_SD
)))
329 gw16012_data(scan_out
| tms
);
331 if (type
!= SCAN_OUT
)
333 gw16012_input(&scan_in
);
334 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
340 if (!((ir_scan
&& (end_state
== TAP_SI
)) ||
341 (!ir_scan
&& (end_state
== TAP_SD
))))
349 if (cur_state
!= end_state
)
350 gw16012_state_move();
354 int gw16012_execute_queue(void)
356 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
362 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
363 * that wasn't handled by a caller-provided error handler
372 #ifdef _DEBUG_JTAG_IO_
373 LOG_DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
375 if (cmd
->cmd
.end_state
->end_state
!= -1)
376 gw16012_end_state(cmd
->cmd
.end_state
->end_state
);
379 #ifdef _DEBUG_JTAG_IO_
380 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
382 if (cmd
->cmd
.reset
->trst
== 1)
386 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
389 #ifdef _DEBUG_JTAG_IO_
390 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
392 if (cmd
->cmd
.runtest
->end_state
!= -1)
393 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
394 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
397 #ifdef _DEBUG_JTAG_IO_
398 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
400 if (cmd
->cmd
.statemove
->end_state
!= -1)
401 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
402 gw16012_state_move();
405 #ifdef _DEBUG_JTAG_IO_
406 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
408 gw16012_path_move(cmd
->cmd
.pathmove
);
411 if (cmd
->cmd
.scan
->end_state
!= -1)
412 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
413 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
414 type
= jtag_scan_type(cmd
->cmd
.scan
);
415 #ifdef _DEBUG_JTAG_IO_
416 LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
417 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
419 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
420 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
421 retval
= ERROR_JTAG_QUEUE_FAILED
;
426 #ifdef _DEBUG_JTAG_IO_
427 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
429 jtag_sleep(cmd
->cmd
.sleep
->us
);
432 LOG_ERROR("BUG: unknown JTAG command type encountered");
441 #if PARPORT_USE_GIVEIO == 1
442 int gw16012_get_giveio_access()
445 OSVERSIONINFO version
;
447 version
.dwOSVersionInfoSize
= sizeof version
;
448 if (!GetVersionEx( &version
)) {
452 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
455 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
456 if (h
== INVALID_HANDLE_VALUE
) {
467 int gw16012_init(void)
469 #if PARPORT_USE_PPDEV == 1
475 #if PARPORT_USE_PPDEV == 1
478 LOG_ERROR("device is already opened");
479 return ERROR_JTAG_INIT_FAILED
;
482 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
483 LOG_DEBUG("opening /dev/ppi%d...", gw16012_port
);
485 snprintf(buffer
, 256, "/dev/ppi%d", gw16012_port
);
486 device_handle
= open(buffer
, O_WRONLY
);
488 LOG_DEBUG("opening /dev/parport%d...", gw16012_port
);
490 snprintf(buffer
, 256, "/dev/parport%d", gw16012_port
);
491 device_handle
= open(buffer
, O_WRONLY
);
495 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
496 return ERROR_JTAG_INIT_FAILED
;
499 LOG_DEBUG("...open");
501 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
502 i
=ioctl(device_handle
, PPCLAIM
);
505 LOG_ERROR("cannot claim device");
506 return ERROR_JTAG_INIT_FAILED
;
509 i
= PARPORT_MODE_COMPAT
;
510 i
= ioctl(device_handle
, PPSETMODE
, & i
);
513 LOG_ERROR(" cannot set compatible mode to device");
514 return ERROR_JTAG_INIT_FAILED
;
517 i
= IEEE1284_MODE_COMPAT
;
518 i
= ioctl(device_handle
, PPNEGOT
, & i
);
521 LOG_ERROR("cannot set compatible 1284 mode to device");
522 return ERROR_JTAG_INIT_FAILED
;
526 if (gw16012_port
== 0)
528 gw16012_port
= 0x378;
529 LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
532 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", gw16012_port
);
533 #if PARPORT_USE_GIVEIO == 1
534 if (gw16012_get_giveio_access() != 0)
535 #else /* PARPORT_USE_GIVEIO */
536 if (ioperm(gw16012_port
, 3, 1) != 0)
537 #endif /* PARPORT_USE_GIVEIO */
539 LOG_ERROR("missing privileges for direct i/o");
540 return ERROR_JTAG_INIT_FAILED
;
542 LOG_DEBUG("...privileges granted");
544 /* make sure parallel port is in right mode (clear tristate and interrupt */
545 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
546 outb(gw16012_port
+ 2, 0x0);
548 outb(0x0, gw16012_port
+ 2);
550 #endif /* PARPORT_USE_PPDEV */
552 gw16012_input(&status_port
);
553 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
555 gw16012_speed(jtag_speed
);
561 int gw16012_quit(void)
567 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
572 /* only if the port wasn't overwritten by cmdline */
573 if (gw16012_port
== 0)
574 gw16012_port
= strtoul(args
[0], NULL
, 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)