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());
201 gw16012_control(0x0); /* single-bit mode */
203 for (i
= 0; i
< 7; i
++)
205 tms
= (tms_scan
>> i
) & 1;
206 gw16012_data(tms
<< 1); /* output next TMS bit */
209 tap_set_state(tap_get_end_state());
212 static void gw16012_path_move(pathmove_command_t
*cmd
)
214 int num_states
= cmd
->num_states
;
220 gw16012_control(0x0); /* single-bit mode */
221 if (tap_state_transition(tap_get_state(), false) == cmd
->path
[state_count
])
223 gw16012_data(0x0); /* TCK cycle with TMS low */
225 else if (tap_state_transition(tap_get_state(), true) == cmd
->path
[state_count
])
227 gw16012_data(0x2); /* TCK cycle with TMS high */
231 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(cmd
->path
[state_count
]));
235 tap_set_state(cmd
->path
[state_count
]);
240 tap_set_end_state(tap_get_state());
243 static void gw16012_runtest(int num_cycles
)
245 tap_state_t saved_end_state
= tap_get_end_state();
248 /* only do a state_move when we're not already in IDLE */
249 if (tap_get_state() != TAP_IDLE
)
251 gw16012_end_state(TAP_IDLE
);
252 gw16012_state_move();
255 for (i
= 0; i
< num_cycles
; i
++)
257 gw16012_control(0x0); /* single-bit mode */
258 gw16012_data(0x0); /* TMS cycle with TMS low */
261 gw16012_end_state(saved_end_state
);
262 if (tap_get_state() != tap_get_end_state())
263 gw16012_state_move();
266 static void gw16012_scan(bool ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
268 int bits_left
= scan_size
;
270 tap_state_t saved_end_state
= tap_get_end_state();
271 u8 scan_out
, scan_in
;
273 /* only if we're not already in the correct Shift state */
274 if (!((!ir_scan
&& (tap_get_state() == TAP_DRSHIFT
)) || (ir_scan
&& (tap_get_state() == TAP_IRSHIFT
))))
277 gw16012_end_state(TAP_IRSHIFT
);
279 gw16012_end_state(TAP_DRSHIFT
);
281 gw16012_state_move();
282 gw16012_end_state(saved_end_state
);
285 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
287 gw16012_control(0x2); /* seven-bit mode */
288 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
289 gw16012_data(scan_out
);
294 gw16012_control(0x0); /* single-bit mode */
295 while (bits_left
-- > 0)
299 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
301 if (bits_left
== 0) /* last bit */
303 if ((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
))
304 || (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
)))
314 gw16012_data(scan_out
| tms
);
316 if (type
!= SCAN_OUT
)
318 gw16012_input(&scan_in
);
319 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
325 if (!((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
)) ||
326 (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
))))
330 tap_set_state(TAP_IRPAUSE
);
332 tap_set_state(TAP_DRPAUSE
);
334 if (tap_get_state() != tap_get_end_state())
335 gw16012_state_move();
339 static int gw16012_execute_queue(void)
341 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
347 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
348 * that wasn't handled by a caller-provided error handler
357 #ifdef _DEBUG_JTAG_IO_
358 LOG_DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
360 if (cmd
->cmd
.end_state
->end_state
!= TAP_INVALID
)
361 gw16012_end_state(cmd
->cmd
.end_state
->end_state
);
364 #ifdef _DEBUG_JTAG_IO_
365 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
367 if (cmd
->cmd
.reset
->trst
== 1)
369 tap_set_state(TAP_RESET
);
371 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
374 #ifdef _DEBUG_JTAG_IO_
375 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
377 if (cmd
->cmd
.runtest
->end_state
!= TAP_INVALID
)
378 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
379 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
382 #ifdef _DEBUG_JTAG_IO_
383 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
385 if (cmd
->cmd
.statemove
->end_state
!= TAP_INVALID
)
386 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
387 gw16012_state_move();
390 #ifdef _DEBUG_JTAG_IO_
391 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
393 gw16012_path_move(cmd
->cmd
.pathmove
);
396 if (cmd
->cmd
.scan
->end_state
!= TAP_INVALID
)
397 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
398 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
399 type
= jtag_scan_type(cmd
->cmd
.scan
);
400 #ifdef _DEBUG_JTAG_IO_
401 LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
402 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
404 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
405 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
406 retval
= ERROR_JTAG_QUEUE_FAILED
;
411 #ifdef _DEBUG_JTAG_IO_
412 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
414 jtag_sleep(cmd
->cmd
.sleep
->us
);
417 LOG_ERROR("BUG: unknown JTAG command type encountered");
426 #if PARPORT_USE_GIVEIO == 1
427 static int gw16012_get_giveio_access(void)
430 OSVERSIONINFO version
;
432 version
.dwOSVersionInfoSize
= sizeof version
;
433 if (!GetVersionEx( &version
)) {
437 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
440 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
441 if (h
== INVALID_HANDLE_VALUE
) {
452 #if PARPORT_USE_PPDEV == 1
454 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
456 #define GW16012_PPDEV_NAME "ppi"
458 static int gw16012_init_ioctls(void)
461 temp
= ioctl(device_handle
, PPCLAIM
);
464 LOG_ERROR("cannot claim device");
465 return ERROR_JTAG_INIT_FAILED
;
468 temp
= PARPORT_MODE_COMPAT
;
469 temp
= ioctl(device_handle
, PPSETMODE
, &temp
);
472 LOG_ERROR(" cannot set compatible mode to device");
473 return ERROR_JTAG_INIT_FAILED
;
476 temp
= IEEE1284_MODE_COMPAT
;
477 temp
= ioctl(device_handle
, PPNEGOT
, &temp
);
480 LOG_ERROR("cannot set compatible 1284 mode to device");
481 return ERROR_JTAG_INIT_FAILED
;
487 #define GW16012_PPDEV_NAME "parport"
489 static int gw16012_init_ioctls(void)
494 #endif // defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
496 static int gw16012_init_device(void)
498 const char *device_name
= GW16012_PPDEV_NAME
;
501 if (device_handle
> 0)
503 LOG_ERROR("device is already opened");
504 return ERROR_JTAG_INIT_FAILED
;
507 snprintf(buffer
, 256, "/dev/%s%d", device_name
, gw16012_port
);
508 LOG_DEBUG("opening %s...", buffer
);
510 device_handle
= open(buffer
, O_WRONLY
);
513 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
514 return ERROR_JTAG_INIT_FAILED
;
517 LOG_DEBUG("...open");
519 if (gw16012_init_ioctls() != ERROR_OK
)
520 return ERROR_JTAG_INIT_FAILED
;
525 #else // PARPORT_USE_PPDEV
527 static int gw16012_init_device(void)
529 if (gw16012_port
== 0)
531 gw16012_port
= 0x378;
532 LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
535 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port
) );
536 #if PARPORT_USE_GIVEIO == 1
537 if (gw16012_get_giveio_access() != 0)
538 #else /* PARPORT_USE_GIVEIO */
539 if (ioperm(gw16012_port
, 3, 1) != 0)
540 #endif /* PARPORT_USE_GIVEIO */
542 LOG_ERROR("missing privileges for direct i/o");
543 return ERROR_JTAG_INIT_FAILED
;
545 LOG_DEBUG("...privileges granted");
547 /* make sure parallel port is in right mode (clear tristate and interrupt */
548 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
549 outb(gw16012_port
+ 2, 0x0);
551 outb(0x0, gw16012_port
+ 2);
556 #endif // PARPORT_USE_PPDEV
558 static int gw16012_init(void)
562 if (gw16012_init_device() != ERROR_OK
)
563 return ERROR_JTAG_INIT_FAILED
;
565 gw16012_input(&status_port
);
566 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
568 gw16012_speed(jtag_speed
);
574 static int gw16012_quit(void)
580 static int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
585 /* only if the port wasn't overwritten by cmdline */
586 if (gw16012_port
== 0)
587 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)