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 ***************************************************************************/
28 #define _DEBUG_GW16012_IO_
32 /* -ino: 060521-1036 */
33 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
35 #include <machine/sysarch.h>
36 #include <machine/cpufunc.h>
37 #define ioperm(startport,length,enable)\
38 i386_set_ioperm((startport), (length), (enable))
42 #endif /* __FreeBSD__, __FreeBSD_kernel__ */
45 #if PARPORT_USE_PPDEV == 1
46 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
47 #include <dev/ppbus/ppi.h>
48 #include <dev/ppbus/ppbconf.h>
49 #define PPRSTATUS PPIGSTATUS
50 #define PPWDATA PPISDATA
52 #include <linux/parport.h>
53 #include <linux/ppdev.h>
56 #include <sys/ioctl.h>
57 #else /* not PARPORT_USE_PPDEV */
63 #if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1
71 /* interface variables
73 static u8 gw16012_msb
= 0x0;
74 static u8 gw16012_control_value
= 0x0;
76 #if PARPORT_USE_PPDEV == 1
77 static int device_handle
;
80 static int gw16012_execute_queue(void);
81 static int gw16012_register_commands(struct command_context_s
*cmd_ctx
);
82 static int gw16012_speed(int speed
);
83 static int gw16012_init(void);
84 static int gw16012_quit(void);
86 static int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
88 jtag_interface_t gw16012_interface
=
92 .execute_queue
= gw16012_execute_queue
,
94 .speed
= gw16012_speed
,
95 .register_commands
= gw16012_register_commands
,
100 static int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
102 register_command(cmd_ctx
, NULL
, "parport_port", gw16012_handle_parport_port_command
,
103 COMMAND_CONFIG
, NULL
);
108 static void gw16012_data(u8 value
)
110 value
= (value
& 0x7f) | gw16012_msb
;
111 gw16012_msb
^= 0x80; /* toggle MSB */
113 #ifdef _DEBUG_GW16012_IO_
114 LOG_DEBUG("%2.2x", value
);
117 #if PARPORT_USE_PPDEV == 1
118 ioctl(device_handle
, PPWDATA
, &value
);
120 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
121 outb(gw16012_port
, value
);
123 outb(value
, gw16012_port
);
128 static void gw16012_control(u8 value
)
130 if (value
!= gw16012_control_value
)
132 gw16012_control_value
= value
;
134 #ifdef _DEBUG_GW16012_IO_
135 LOG_DEBUG("%2.2x", gw16012_control_value
);
138 #if PARPORT_USE_PPDEV == 1
139 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
141 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
142 outb(gw16012_port
+ 2, gw16012_control_value
);
144 outb(gw16012_control_value
, gw16012_port
+ 2);
150 static void gw16012_input(u8
*value
)
152 #if PARPORT_USE_PPDEV == 1
153 ioctl(device_handle
, PPRSTATUS
, value
);
155 *value
= inb(gw16012_port
+ 1);
158 #ifdef _DEBUG_GW16012_IO_
159 LOG_DEBUG("%2.2x", *value
);
163 /* (1) assert or (0) deassert reset lines */
164 static void gw16012_reset(int trst
, int srst
)
166 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
169 gw16012_control(0x0d);
171 gw16012_control(0x0c);
174 gw16012_control(0x0a);
176 gw16012_control(0x0b);
179 static int gw16012_speed(int speed
)
185 static void gw16012_end_state(tap_state_t state
)
187 if (tap_is_state_stable(state
))
188 tap_set_end_state(state
);
191 LOG_ERROR("BUG: %i is not a valid end state", state
);
196 static void gw16012_state_move(void)
199 u8 tms_scan
= tap_get_tms_path(tap_get_state(), tap_get_end_state());
200 int tms_count
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
202 gw16012_control(0x0); /* single-bit mode */
204 for (i
= 0; i
< tms_count
; i
++)
206 tms
= (tms_scan
>> i
) & 1;
207 gw16012_data(tms
<< 1); /* output next TMS bit */
210 tap_set_state(tap_get_end_state());
213 static void gw16012_path_move(pathmove_command_t
*cmd
)
215 int num_states
= cmd
->num_states
;
221 gw16012_control(0x0); /* single-bit mode */
222 if (tap_state_transition(tap_get_state(), false) == cmd
->path
[state_count
])
224 gw16012_data(0x0); /* TCK cycle with TMS low */
226 else if (tap_state_transition(tap_get_state(), true) == cmd
->path
[state_count
])
228 gw16012_data(0x2); /* TCK cycle with TMS high */
232 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(cmd
->path
[state_count
]));
236 tap_set_state(cmd
->path
[state_count
]);
241 tap_set_end_state(tap_get_state());
244 static void gw16012_runtest(int num_cycles
)
246 tap_state_t saved_end_state
= tap_get_end_state();
249 /* only do a state_move when we're not already in IDLE */
250 if (tap_get_state() != TAP_IDLE
)
252 gw16012_end_state(TAP_IDLE
);
253 gw16012_state_move();
256 for (i
= 0; i
< num_cycles
; i
++)
258 gw16012_control(0x0); /* single-bit mode */
259 gw16012_data(0x0); /* TMS cycle with TMS low */
262 gw16012_end_state(saved_end_state
);
263 if (tap_get_state() != tap_get_end_state())
264 gw16012_state_move();
267 static void gw16012_scan(bool ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
269 int bits_left
= scan_size
;
271 tap_state_t saved_end_state
= tap_get_end_state();
272 u8 scan_out
, scan_in
;
274 /* only if we're not already in the correct Shift state */
275 if (!((!ir_scan
&& (tap_get_state() == TAP_DRSHIFT
)) || (ir_scan
&& (tap_get_state() == TAP_IRSHIFT
))))
278 gw16012_end_state(TAP_IRSHIFT
);
280 gw16012_end_state(TAP_DRSHIFT
);
282 gw16012_state_move();
283 gw16012_end_state(saved_end_state
);
286 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
288 gw16012_control(0x2); /* seven-bit mode */
289 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
290 gw16012_data(scan_out
);
295 gw16012_control(0x0); /* single-bit mode */
296 while (bits_left
-- > 0)
300 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
302 if (bits_left
== 0) /* last bit */
304 if ((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
))
305 || (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
)))
315 gw16012_data(scan_out
| tms
);
317 if (type
!= SCAN_OUT
)
319 gw16012_input(&scan_in
);
320 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
326 if (!((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
)) ||
327 (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
))))
331 tap_set_state(TAP_IRPAUSE
);
333 tap_set_state(TAP_DRPAUSE
);
335 if (tap_get_state() != tap_get_end_state())
336 gw16012_state_move();
340 static int gw16012_execute_queue(void)
342 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
348 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
349 * that wasn't handled by a caller-provided error handler
358 #ifdef _DEBUG_JTAG_IO_
359 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
361 if (cmd
->cmd
.reset
->trst
== 1)
363 tap_set_state(TAP_RESET
);
365 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
368 #ifdef _DEBUG_JTAG_IO_
369 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
371 if (cmd
->cmd
.runtest
->end_state
!= TAP_INVALID
)
372 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
373 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
376 #ifdef _DEBUG_JTAG_IO_
377 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
379 if (cmd
->cmd
.statemove
->end_state
!= TAP_INVALID
)
380 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
381 gw16012_state_move();
384 #ifdef _DEBUG_JTAG_IO_
385 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
387 gw16012_path_move(cmd
->cmd
.pathmove
);
390 if (cmd
->cmd
.scan
->end_state
!= TAP_INVALID
)
391 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
392 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
393 type
= jtag_scan_type(cmd
->cmd
.scan
);
394 #ifdef _DEBUG_JTAG_IO_
395 LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
396 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
398 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
399 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
400 retval
= ERROR_JTAG_QUEUE_FAILED
;
405 #ifdef _DEBUG_JTAG_IO_
406 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
408 jtag_sleep(cmd
->cmd
.sleep
->us
);
411 LOG_ERROR("BUG: unknown JTAG command type encountered");
420 #if PARPORT_USE_GIVEIO == 1
421 static int gw16012_get_giveio_access(void)
424 OSVERSIONINFO version
;
426 version
.dwOSVersionInfoSize
= sizeof version
;
427 if (!GetVersionEx( &version
)) {
431 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
434 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
435 if (h
== INVALID_HANDLE_VALUE
) {
446 #if PARPORT_USE_PPDEV == 1
448 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
450 #define GW16012_PPDEV_NAME "ppi"
452 static int gw16012_init_ioctls(void)
455 temp
= ioctl(device_handle
, PPCLAIM
);
458 LOG_ERROR("cannot claim device");
459 return ERROR_JTAG_INIT_FAILED
;
462 temp
= PARPORT_MODE_COMPAT
;
463 temp
= ioctl(device_handle
, PPSETMODE
, &temp
);
466 LOG_ERROR(" cannot set compatible mode to device");
467 return ERROR_JTAG_INIT_FAILED
;
470 temp
= IEEE1284_MODE_COMPAT
;
471 temp
= ioctl(device_handle
, PPNEGOT
, &temp
);
474 LOG_ERROR("cannot set compatible 1284 mode to device");
475 return ERROR_JTAG_INIT_FAILED
;
481 #define GW16012_PPDEV_NAME "parport"
483 static int gw16012_init_ioctls(void)
488 #endif // defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
490 static int gw16012_init_device(void)
492 const char *device_name
= GW16012_PPDEV_NAME
;
495 if (device_handle
> 0)
497 LOG_ERROR("device is already opened");
498 return ERROR_JTAG_INIT_FAILED
;
501 snprintf(buffer
, 256, "/dev/%s%d", device_name
, gw16012_port
);
502 LOG_DEBUG("opening %s...", buffer
);
504 device_handle
= open(buffer
, O_WRONLY
);
507 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
508 return ERROR_JTAG_INIT_FAILED
;
511 LOG_DEBUG("...open");
513 if (gw16012_init_ioctls() != ERROR_OK
)
514 return ERROR_JTAG_INIT_FAILED
;
519 #else // PARPORT_USE_PPDEV
521 static int gw16012_init_device(void)
523 if (gw16012_port
== 0)
525 gw16012_port
= 0x378;
526 LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
529 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port
) );
530 #if PARPORT_USE_GIVEIO == 1
531 if (gw16012_get_giveio_access() != 0)
532 #else /* PARPORT_USE_GIVEIO */
533 if (ioperm(gw16012_port
, 3, 1) != 0)
534 #endif /* PARPORT_USE_GIVEIO */
536 LOG_ERROR("missing privileges for direct i/o");
537 return ERROR_JTAG_INIT_FAILED
;
539 LOG_DEBUG("...privileges granted");
541 /* make sure parallel port is in right mode (clear tristate and interrupt */
542 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
543 outb(gw16012_port
+ 2, 0x0);
545 outb(0x0, gw16012_port
+ 2);
550 #endif // PARPORT_USE_PPDEV
552 static int gw16012_init(void)
556 if (gw16012_init_device() != ERROR_OK
)
557 return ERROR_JTAG_INIT_FAILED
;
559 gw16012_input(&status_port
);
560 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
562 gw16012_speed(jtag_speed
);
568 static int gw16012_quit(void)
574 static int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
579 /* only if the port wasn't overwritten by cmdline */
580 if (gw16012_port
== 0)
581 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)