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 <machine/sysarch.h>
37 #include <machine/cpufunc.h>
38 #define ioperm(startport,length,enable)\
39 i386_set_ioperm((startport), (length), (enable))
47 #endif /* __FreeBSD__, __FreeBSD_kernel__ */
52 #if PARPORT_USE_PPDEV == 1
53 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
54 #include <dev/ppbus/ppi.h>
55 #include <dev/ppbus/ppbconf.h>
56 #define PPRSTATUS PPIGSTATUS
57 #define PPWDATA PPISDATA
59 #include <linux/parport.h>
60 #include <linux/ppdev.h>
63 #include <sys/ioctl.h>
64 #else /* not PARPORT_USE_PPDEV */
70 #if PARPORT_USE_GIVEIO == 1
82 /* interface variables
84 static u8 gw16012_msb
= 0x0;
85 static u8 gw16012_control_value
= 0x0;
87 #if PARPORT_USE_PPDEV == 1
88 static int device_handle
;
91 static int gw16012_execute_queue(void);
92 static int gw16012_register_commands(struct command_context_s
*cmd_ctx
);
93 static int gw16012_speed(int speed
);
94 static int gw16012_init(void);
95 static int gw16012_quit(void);
97 static int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
99 jtag_interface_t gw16012_interface
=
103 .execute_queue
= gw16012_execute_queue
,
105 .speed
= gw16012_speed
,
106 .register_commands
= gw16012_register_commands
,
107 .init
= gw16012_init
,
108 .quit
= gw16012_quit
,
111 static int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
113 register_command(cmd_ctx
, NULL
, "parport_port", gw16012_handle_parport_port_command
,
114 COMMAND_CONFIG
, NULL
);
119 static void gw16012_data(u8 value
)
121 value
= (value
& 0x7f) | gw16012_msb
;
122 gw16012_msb
^= 0x80; /* toggle MSB */
124 #ifdef _DEBUG_GW16012_IO_
125 LOG_DEBUG("%2.2x", value
);
128 #if PARPORT_USE_PPDEV == 1
129 ioctl(device_handle
, PPWDATA
, &value
);
131 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
132 outb(gw16012_port
, value
);
134 outb(value
, gw16012_port
);
139 static void gw16012_control(u8 value
)
141 if (value
!= gw16012_control_value
)
143 gw16012_control_value
= value
;
145 #ifdef _DEBUG_GW16012_IO_
146 LOG_DEBUG("%2.2x", gw16012_control_value
);
149 #if PARPORT_USE_PPDEV == 1
150 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
152 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
153 outb(gw16012_port
+ 2, gw16012_control_value
);
155 outb(gw16012_control_value
, gw16012_port
+ 2);
161 static void gw16012_input(u8
*value
)
163 #if PARPORT_USE_PPDEV == 1
164 ioctl(device_handle
, PPRSTATUS
, value
);
166 *value
= inb(gw16012_port
+ 1);
169 #ifdef _DEBUG_GW16012_IO_
170 LOG_DEBUG("%2.2x", *value
);
174 /* (1) assert or (0) deassert reset lines */
175 static void gw16012_reset(int trst
, int srst
)
177 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
180 gw16012_control(0x0d);
182 gw16012_control(0x0c);
185 gw16012_control(0x0a);
187 gw16012_control(0x0b);
190 static int gw16012_speed(int speed
)
196 static void gw16012_end_state(tap_state_t state
)
198 if (tap_is_state_stable(state
))
199 tap_set_end_state(state
);
202 LOG_ERROR("BUG: %i is not a valid end state", state
);
207 static void gw16012_state_move(void)
210 u8 tms_scan
= tap_get_tms_path(tap_get_state(), tap_get_end_state());
212 gw16012_control(0x0); /* single-bit mode */
214 for (i
= 0; i
< 7; i
++)
216 tms
= (tms_scan
>> i
) & 1;
217 gw16012_data(tms
<< 1); /* output next TMS bit */
220 tap_set_state(tap_get_end_state());
223 static void gw16012_path_move(pathmove_command_t
*cmd
)
225 int num_states
= cmd
->num_states
;
231 gw16012_control(0x0); /* single-bit mode */
232 if (tap_state_transition(tap_get_state(), false) == cmd
->path
[state_count
])
234 gw16012_data(0x0); /* TCK cycle with TMS low */
236 else if (tap_state_transition(tap_get_state(), true) == cmd
->path
[state_count
])
238 gw16012_data(0x2); /* TCK cycle with TMS high */
242 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(cmd
->path
[state_count
]));
246 tap_set_state(cmd
->path
[state_count
]);
251 tap_set_end_state(tap_get_state());
254 static void gw16012_runtest(int num_cycles
)
256 tap_state_t saved_end_state
= tap_get_end_state();
259 /* only do a state_move when we're not already in IDLE */
260 if (tap_get_state() != TAP_IDLE
)
262 gw16012_end_state(TAP_IDLE
);
263 gw16012_state_move();
266 for (i
= 0; i
< num_cycles
; i
++)
268 gw16012_control(0x0); /* single-bit mode */
269 gw16012_data(0x0); /* TMS cycle with TMS low */
272 gw16012_end_state(saved_end_state
);
273 if (tap_get_state() != tap_get_end_state())
274 gw16012_state_move();
277 static void gw16012_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
279 int bits_left
= scan_size
;
281 tap_state_t saved_end_state
= tap_get_end_state();
282 u8 scan_out
, scan_in
;
284 /* only if we're not already in the correct Shift state */
285 if (!((!ir_scan
&& (tap_get_state() == TAP_DRSHIFT
)) || (ir_scan
&& (tap_get_state() == TAP_IRSHIFT
))))
288 gw16012_end_state(TAP_IRSHIFT
);
290 gw16012_end_state(TAP_DRSHIFT
);
292 gw16012_state_move();
293 gw16012_end_state(saved_end_state
);
296 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
298 gw16012_control(0x2); /* seven-bit mode */
299 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
300 gw16012_data(scan_out
);
305 gw16012_control(0x0); /* single-bit mode */
306 while (bits_left
-- > 0)
310 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
312 if (bits_left
== 0) /* last bit */
314 if ((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
))
315 || (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
)))
325 gw16012_data(scan_out
| tms
);
327 if (type
!= SCAN_OUT
)
329 gw16012_input(&scan_in
);
330 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
336 if (!((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
)) ||
337 (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
))))
341 tap_set_state(TAP_IRPAUSE
);
343 tap_set_state(TAP_DRPAUSE
);
345 if (tap_get_state() != tap_get_end_state())
346 gw16012_state_move();
350 static int gw16012_execute_queue(void)
352 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
358 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
359 * that wasn't handled by a caller-provided error handler
368 #ifdef _DEBUG_JTAG_IO_
369 LOG_DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
371 if (cmd
->cmd
.end_state
->end_state
!= TAP_INVALID
)
372 gw16012_end_state(cmd
->cmd
.end_state
->end_state
);
375 #ifdef _DEBUG_JTAG_IO_
376 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
378 if (cmd
->cmd
.reset
->trst
== 1)
380 tap_set_state(TAP_RESET
);
382 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
385 #ifdef _DEBUG_JTAG_IO_
386 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
388 if (cmd
->cmd
.runtest
->end_state
!= TAP_INVALID
)
389 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
390 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
393 #ifdef _DEBUG_JTAG_IO_
394 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
396 if (cmd
->cmd
.statemove
->end_state
!= TAP_INVALID
)
397 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
398 gw16012_state_move();
401 #ifdef _DEBUG_JTAG_IO_
402 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
404 gw16012_path_move(cmd
->cmd
.pathmove
);
407 if (cmd
->cmd
.scan
->end_state
!= TAP_INVALID
)
408 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
409 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
410 type
= jtag_scan_type(cmd
->cmd
.scan
);
411 #ifdef _DEBUG_JTAG_IO_
412 LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
413 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
415 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
416 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
417 retval
= ERROR_JTAG_QUEUE_FAILED
;
422 #ifdef _DEBUG_JTAG_IO_
423 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
425 jtag_sleep(cmd
->cmd
.sleep
->us
);
428 LOG_ERROR("BUG: unknown JTAG command type encountered");
437 #if PARPORT_USE_GIVEIO == 1
438 static int gw16012_get_giveio_access(void)
441 OSVERSIONINFO version
;
443 version
.dwOSVersionInfoSize
= sizeof version
;
444 if (!GetVersionEx( &version
)) {
448 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
451 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
452 if (h
== INVALID_HANDLE_VALUE
) {
463 #if PARPORT_USE_PPDEV == 1
465 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
467 #define GW16012_PPDEV_NAME "ppi"
469 static int gw16012_init_ioctls(void)
472 temp
= ioctl(device_handle
, PPCLAIM
);
475 LOG_ERROR("cannot claim device");
476 return ERROR_JTAG_INIT_FAILED
;
479 temp
= PARPORT_MODE_COMPAT
;
480 temp
= ioctl(device_handle
, PPSETMODE
, &temp
);
483 LOG_ERROR(" cannot set compatible mode to device");
484 return ERROR_JTAG_INIT_FAILED
;
487 temp
= IEEE1284_MODE_COMPAT
;
488 temp
= ioctl(device_handle
, PPNEGOT
, &temp
);
491 LOG_ERROR("cannot set compatible 1284 mode to device");
492 return ERROR_JTAG_INIT_FAILED
;
498 #define GW16012_PPDEV_NAME "parport"
500 static int gw16012_init_ioctls(void)
505 #endif // defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
507 static int gw16012_init_device(void)
509 const char *device_name
= GW16012_PPDEV_NAME
;
512 if (device_handle
> 0)
514 LOG_ERROR("device is already opened");
515 return ERROR_JTAG_INIT_FAILED
;
518 snprintf(buffer
, 256, "/dev/%s%d", device_name
, gw16012_port
);
519 LOG_DEBUG("opening %s...", buffer
);
521 device_handle
= open(buffer
, O_WRONLY
);
524 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
525 return ERROR_JTAG_INIT_FAILED
;
528 LOG_DEBUG("...open");
530 if (gw16012_init_ioctls() != ERROR_OK
)
531 return ERROR_JTAG_INIT_FAILED
;
536 #else // PARPORT_USE_PPDEV
538 static int gw16012_init_device(void)
540 if (gw16012_port
== 0)
542 gw16012_port
= 0x378;
543 LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
546 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port
) );
547 #if PARPORT_USE_GIVEIO == 1
548 if (gw16012_get_giveio_access() != 0)
549 #else /* PARPORT_USE_GIVEIO */
550 if (ioperm(gw16012_port
, 3, 1) != 0)
551 #endif /* PARPORT_USE_GIVEIO */
553 LOG_ERROR("missing privileges for direct i/o");
554 return ERROR_JTAG_INIT_FAILED
;
556 LOG_DEBUG("...privileges granted");
558 /* make sure parallel port is in right mode (clear tristate and interrupt */
559 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
560 outb(gw16012_port
+ 2, 0x0);
562 outb(0x0, gw16012_port
+ 2);
567 #endif // PARPORT_USE_PPDEV
569 static int gw16012_init(void)
573 if (gw16012_init_device() != ERROR_OK
)
574 return ERROR_JTAG_INIT_FAILED
;
576 gw16012_input(&status_port
);
577 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
579 gw16012_speed(jtag_speed
);
585 static int gw16012_quit(void)
591 static int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
596 /* only if the port wasn't overwritten by cmdline */
597 if (gw16012_port
== 0)
598 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)