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 "interface.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))
43 #endif /* __FreeBSD__, __FreeBSD_kernel__ */
46 #if PARPORT_USE_PPDEV == 1
47 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
48 #include <dev/ppbus/ppi.h>
49 #include <dev/ppbus/ppbconf.h>
50 #define PPRSTATUS PPIGSTATUS
51 #define PPWDATA PPISDATA
53 #include <linux/parport.h>
54 #include <linux/ppdev.h>
57 #include <sys/ioctl.h>
58 #else /* not PARPORT_USE_PPDEV */
64 #if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1
70 uint16_t gw16012_port
;
72 /* interface variables
74 static uint8_t gw16012_msb
= 0x0;
75 static uint8_t gw16012_control_value
= 0x0;
77 #if PARPORT_USE_PPDEV == 1
78 static int device_handle
;
81 static int gw16012_execute_queue(void);
82 static int gw16012_register_commands(struct command_context_s
*cmd_ctx
);
83 static int gw16012_speed(int speed
);
84 static int gw16012_init(void);
85 static int gw16012_quit(void);
87 static int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
89 jtag_interface_t gw16012_interface
=
93 .execute_queue
= gw16012_execute_queue
,
95 .speed
= gw16012_speed
,
96 .register_commands
= gw16012_register_commands
,
101 static int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
103 register_command(cmd_ctx
, NULL
, "parport_port", gw16012_handle_parport_port_command
,
104 COMMAND_CONFIG
, NULL
);
109 static void gw16012_data(uint8_t value
)
111 value
= (value
& 0x7f) | gw16012_msb
;
112 gw16012_msb
^= 0x80; /* toggle MSB */
114 #ifdef _DEBUG_GW16012_IO_
115 LOG_DEBUG("%2.2x", value
);
118 #if PARPORT_USE_PPDEV == 1
119 ioctl(device_handle
, PPWDATA
, &value
);
121 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
122 outb(gw16012_port
, value
);
124 outb(value
, gw16012_port
);
129 static void gw16012_control(uint8_t value
)
131 if (value
!= gw16012_control_value
)
133 gw16012_control_value
= value
;
135 #ifdef _DEBUG_GW16012_IO_
136 LOG_DEBUG("%2.2x", gw16012_control_value
);
139 #if PARPORT_USE_PPDEV == 1
140 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
142 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
143 outb(gw16012_port
+ 2, gw16012_control_value
);
145 outb(gw16012_control_value
, gw16012_port
+ 2);
151 static void gw16012_input(uint8_t *value
)
153 #if PARPORT_USE_PPDEV == 1
154 ioctl(device_handle
, PPRSTATUS
, value
);
156 *value
= inb(gw16012_port
+ 1);
159 #ifdef _DEBUG_GW16012_IO_
160 LOG_DEBUG("%2.2x", *value
);
164 /* (1) assert or (0) deassert reset lines */
165 static void gw16012_reset(int trst
, int srst
)
167 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
170 gw16012_control(0x0d);
172 gw16012_control(0x0c);
175 gw16012_control(0x0a);
177 gw16012_control(0x0b);
180 static int gw16012_speed(int speed
)
186 static void gw16012_end_state(tap_state_t state
)
188 if (tap_is_state_stable(state
))
189 tap_set_end_state(state
);
192 LOG_ERROR("BUG: %i is not a valid end state", state
);
197 static void gw16012_state_move(void)
200 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(), tap_get_end_state());
201 int tms_count
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
203 gw16012_control(0x0); /* single-bit mode */
205 for (i
= 0; i
< tms_count
; i
++)
207 tms
= (tms_scan
>> i
) & 1;
208 gw16012_data(tms
<< 1); /* output next TMS bit */
211 tap_set_state(tap_get_end_state());
214 static void gw16012_path_move(pathmove_command_t
*cmd
)
216 int num_states
= cmd
->num_states
;
222 gw16012_control(0x0); /* single-bit mode */
223 if (tap_state_transition(tap_get_state(), false) == cmd
->path
[state_count
])
225 gw16012_data(0x0); /* TCK cycle with TMS low */
227 else if (tap_state_transition(tap_get_state(), true) == cmd
->path
[state_count
])
229 gw16012_data(0x2); /* TCK cycle with TMS high */
233 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(cmd
->path
[state_count
]));
237 tap_set_state(cmd
->path
[state_count
]);
242 tap_set_end_state(tap_get_state());
245 static void gw16012_runtest(int num_cycles
)
247 tap_state_t saved_end_state
= tap_get_end_state();
250 /* only do a state_move when we're not already in IDLE */
251 if (tap_get_state() != TAP_IDLE
)
253 gw16012_end_state(TAP_IDLE
);
254 gw16012_state_move();
257 for (i
= 0; i
< num_cycles
; i
++)
259 gw16012_control(0x0); /* single-bit mode */
260 gw16012_data(0x0); /* TMS cycle with TMS low */
263 gw16012_end_state(saved_end_state
);
264 if (tap_get_state() != tap_get_end_state())
265 gw16012_state_move();
268 static void gw16012_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
)
270 int bits_left
= scan_size
;
272 tap_state_t saved_end_state
= tap_get_end_state();
273 uint8_t scan_out
, scan_in
;
275 /* only if we're not already in the correct Shift state */
276 if (!((!ir_scan
&& (tap_get_state() == TAP_DRSHIFT
)) || (ir_scan
&& (tap_get_state() == TAP_IRSHIFT
))))
279 gw16012_end_state(TAP_IRSHIFT
);
281 gw16012_end_state(TAP_DRSHIFT
);
283 gw16012_state_move();
284 gw16012_end_state(saved_end_state
);
287 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
289 gw16012_control(0x2); /* seven-bit mode */
290 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
291 gw16012_data(scan_out
);
296 gw16012_control(0x0); /* single-bit mode */
297 while (bits_left
-- > 0)
301 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
303 if (bits_left
== 0) /* last bit */
305 if ((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
))
306 || (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
)))
316 gw16012_data(scan_out
| tms
);
318 if (type
!= SCAN_OUT
)
320 gw16012_input(&scan_in
);
321 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
327 if (!((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
)) ||
328 (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
))))
332 tap_set_state(TAP_IRPAUSE
);
334 tap_set_state(TAP_DRPAUSE
);
336 if (tap_get_state() != tap_get_end_state())
337 gw16012_state_move();
341 static int gw16012_execute_queue(void)
343 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
349 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
350 * that wasn't handled by a caller-provided error handler
359 #ifdef _DEBUG_JTAG_IO_
360 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
362 if (cmd
->cmd
.reset
->trst
== 1)
364 tap_set_state(TAP_RESET
);
366 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
369 #ifdef _DEBUG_JTAG_IO_
370 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
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 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
380 gw16012_state_move();
383 #ifdef _DEBUG_JTAG_IO_
384 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
386 gw16012_path_move(cmd
->cmd
.pathmove
);
389 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
390 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
391 type
= jtag_scan_type(cmd
->cmd
.scan
);
392 #ifdef _DEBUG_JTAG_IO_
393 LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
394 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
396 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
397 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
398 retval
= ERROR_JTAG_QUEUE_FAILED
;
403 #ifdef _DEBUG_JTAG_IO_
404 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
406 jtag_sleep(cmd
->cmd
.sleep
->us
);
409 LOG_ERROR("BUG: unknown JTAG command type encountered");
418 #if PARPORT_USE_GIVEIO == 1
419 static int gw16012_get_giveio_access(void)
422 OSVERSIONINFO version
;
424 version
.dwOSVersionInfoSize
= sizeof version
;
425 if (!GetVersionEx(&version
)) {
429 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
432 h
= CreateFile("\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
433 if (h
== INVALID_HANDLE_VALUE
) {
444 #if PARPORT_USE_PPDEV == 1
446 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
448 #define GW16012_PPDEV_NAME "ppi"
450 static int gw16012_init_ioctls(void)
453 temp
= ioctl(device_handle
, PPCLAIM
);
456 LOG_ERROR("cannot claim device");
457 return ERROR_JTAG_INIT_FAILED
;
460 temp
= PARPORT_MODE_COMPAT
;
461 temp
= ioctl(device_handle
, PPSETMODE
, &temp
);
464 LOG_ERROR(" cannot set compatible mode to device");
465 return ERROR_JTAG_INIT_FAILED
;
468 temp
= IEEE1284_MODE_COMPAT
;
469 temp
= ioctl(device_handle
, PPNEGOT
, &temp
);
472 LOG_ERROR("cannot set compatible 1284 mode to device");
473 return ERROR_JTAG_INIT_FAILED
;
479 #define GW16012_PPDEV_NAME "parport"
481 static int gw16012_init_ioctls(void)
486 #endif // defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
488 static int gw16012_init_device(void)
490 const char *device_name
= GW16012_PPDEV_NAME
;
493 if (device_handle
> 0)
495 LOG_ERROR("device is already opened");
496 return ERROR_JTAG_INIT_FAILED
;
499 snprintf(buffer
, 256, "/dev/%s%d", device_name
, gw16012_port
);
500 LOG_DEBUG("opening %s...", buffer
);
502 device_handle
= open(buffer
, O_WRONLY
);
503 if (device_handle
< 0)
505 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
506 return ERROR_JTAG_INIT_FAILED
;
509 LOG_DEBUG("...open");
511 if (gw16012_init_ioctls() != ERROR_OK
)
512 return ERROR_JTAG_INIT_FAILED
;
517 #else // PARPORT_USE_PPDEV
519 static int gw16012_init_device(void)
521 if (gw16012_port
== 0)
523 gw16012_port
= 0x378;
524 LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
527 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port
));
528 #if PARPORT_USE_GIVEIO == 1
529 if (gw16012_get_giveio_access() != 0)
530 #else /* PARPORT_USE_GIVEIO */
531 if (ioperm(gw16012_port
, 3, 1) != 0)
532 #endif /* PARPORT_USE_GIVEIO */
534 LOG_ERROR("missing privileges for direct i/o");
535 return ERROR_JTAG_INIT_FAILED
;
537 LOG_DEBUG("...privileges granted");
539 /* make sure parallel port is in right mode (clear tristate and interrupt */
540 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
541 outb(gw16012_port
+ 2, 0x0);
543 outb(0x0, gw16012_port
+ 2);
548 #endif // PARPORT_USE_PPDEV
550 static int gw16012_init(void)
554 if (gw16012_init_device() != ERROR_OK
)
555 return ERROR_JTAG_INIT_FAILED
;
557 gw16012_input(&status_port
);
558 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
560 gw16012_speed(jtag_get_speed());
566 static int gw16012_quit(void)
572 static int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
576 /* only if the port wasn't overwritten by cmdline */
577 if (gw16012_port
== 0)
579 int retval
= parse_u16(args
[0], &gw16012_port
);
580 if (ERROR_OK
!= retval
)
585 LOG_ERROR("The parport port was already configured!");
590 command_print(cmd_ctx
, "parport port = %u", gw16012_port
);
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)