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__ */
53 #if PARPORT_USE_PPDEV == 1
54 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
55 #include <dev/ppbus/ppi.h>
56 #include <dev/ppbus/ppbconf.h>
57 #define PPRSTATUS PPIGSTATUS
58 #define PPWDATA PPISDATA
60 #include <linux/parport.h>
61 #include <linux/ppdev.h>
64 #include <sys/ioctl.h>
65 #else /* not PARPORT_USE_PPDEV */
71 #if PARPORT_USE_GIVEIO == 1
83 /* interface variables
85 static u8 gw16012_msb
= 0x0;
86 static u8 gw16012_control_value
= 0x0;
88 #if PARPORT_USE_PPDEV == 1
89 static int device_handle
;
92 int gw16012_execute_queue(void);
93 int gw16012_register_commands(struct command_context_s
*cmd_ctx
);
94 int gw16012_speed(int speed
);
95 int gw16012_init(void);
96 int gw16012_quit(void);
98 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
100 jtag_interface_t gw16012_interface
=
104 .execute_queue
= gw16012_execute_queue
,
106 .speed
= gw16012_speed
,
107 .register_commands
= gw16012_register_commands
,
108 .init
= gw16012_init
,
109 .quit
= gw16012_quit
,
112 int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
114 register_command(cmd_ctx
, NULL
, "parport_port", gw16012_handle_parport_port_command
,
115 COMMAND_CONFIG
, NULL
);
120 void gw16012_data(u8 value
)
122 value
= (value
& 0x7f) | gw16012_msb
;
123 gw16012_msb
^= 0x80; /* toggle MSB */
125 #ifdef _DEBUG_GW16012_IO_
126 LOG_DEBUG("%2.2x", value
);
129 #if PARPORT_USE_PPDEV == 1
130 ioctl(device_handle
, PPWDATA
, &value
);
132 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
133 outb(gw16012_port
, value
);
135 outb(value
, gw16012_port
);
140 void gw16012_control(u8 value
)
142 if (value
!= gw16012_control_value
)
144 gw16012_control_value
= value
;
146 #ifdef _DEBUG_GW16012_IO_
147 LOG_DEBUG("%2.2x", gw16012_control_value
);
150 #if PARPORT_USE_PPDEV == 1
151 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
153 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
154 outb(gw16012_port
+ 2, gw16012_control_value
);
156 outb(gw16012_control_value
, gw16012_port
+ 2);
162 void gw16012_input(u8
*value
)
164 #if PARPORT_USE_PPDEV == 1
165 ioctl(device_handle
, PPRSTATUS
, value
);
167 *value
= inb(gw16012_port
+ 1);
170 #ifdef _DEBUG_GW16012_IO_
171 LOG_DEBUG("%2.2x", *value
);
175 /* (1) assert or (0) deassert reset lines */
176 void gw16012_reset(int trst
, int srst
)
178 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
181 gw16012_control(0x0d);
183 gw16012_control(0x0c);
186 gw16012_control(0x0a);
188 gw16012_control(0x0b);
191 int gw16012_speed(int speed
)
197 void gw16012_end_state(state
)
199 if (tap_move_map
[state
] != -1)
203 LOG_ERROR("BUG: %i is not a valid end state", state
);
208 void gw16012_state_move(void)
211 u8 tms_scan
= TAP_MOVE(cur_state
, end_state
);
213 gw16012_control(0x0); /* single-bit mode */
215 for (i
= 0; i
< 7; i
++)
217 tms
= (tms_scan
>> i
) & 1;
218 gw16012_data(tms
<< 1); /* output next TMS bit */
221 cur_state
= end_state
;
224 void gw16012_path_move(pathmove_command_t
*cmd
)
226 int num_states
= cmd
->num_states
;
232 gw16012_control(0x0); /* single-bit mode */
233 if (tap_transitions
[cur_state
].low
== cmd
->path
[state_count
])
235 gw16012_data(0x0); /* TCK cycle with TMS low */
237 else if (tap_transitions
[cur_state
].high
== cmd
->path
[state_count
])
239 gw16012_data(0x2); /* TCK cycle with TMS high */
243 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[state_count
]]);
247 cur_state
= cmd
->path
[state_count
];
252 end_state
= cur_state
;
255 void gw16012_runtest(int num_cycles
)
257 enum tap_state saved_end_state
= end_state
;
260 /* only do a state_move when we're not already in RTI */
261 if (cur_state
!= TAP_RTI
)
263 gw16012_end_state(TAP_RTI
);
264 gw16012_state_move();
267 for (i
= 0; i
< num_cycles
; i
++)
269 gw16012_control(0x0); /* single-bit mode */
270 gw16012_data(0x0); /* TMS cycle with TMS low */
273 gw16012_end_state(saved_end_state
);
274 if (cur_state
!= end_state
)
275 gw16012_state_move();
278 void gw16012_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
280 int bits_left
= scan_size
;
282 enum tap_state saved_end_state
= end_state
;
283 u8 scan_out
, scan_in
;
285 /* only if we're not already in the correct Shift state */
286 if (!((!ir_scan
&& (cur_state
== TAP_SD
)) || (ir_scan
&& (cur_state
== TAP_SI
))))
289 gw16012_end_state(TAP_SI
);
291 gw16012_end_state(TAP_SD
);
293 gw16012_state_move();
294 gw16012_end_state(saved_end_state
);
297 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
299 gw16012_control(0x2); /* seven-bit mode */
300 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
301 gw16012_data(scan_out
);
306 gw16012_control(0x0); /* single-bit mode */
307 while (bits_left
-- > 0)
311 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
313 if (bits_left
== 0) /* last bit */
315 if ((ir_scan
&& (end_state
== TAP_SI
))
316 || (!ir_scan
&& (end_state
== TAP_SD
)))
326 gw16012_data(scan_out
| tms
);
328 if (type
!= SCAN_OUT
)
330 gw16012_input(&scan_in
);
331 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
337 if (!((ir_scan
&& (end_state
== TAP_SI
)) ||
338 (!ir_scan
&& (end_state
== TAP_SD
))))
346 if (cur_state
!= end_state
)
347 gw16012_state_move();
351 int gw16012_execute_queue(void)
353 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
359 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
360 * that wasn't handled by a caller-provided error handler
369 #ifdef _DEBUG_JTAG_IO_
370 LOG_DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
372 if (cmd
->cmd
.end_state
->end_state
!= -1)
373 gw16012_end_state(cmd
->cmd
.end_state
->end_state
);
376 #ifdef _DEBUG_JTAG_IO_
377 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
379 if (cmd
->cmd
.reset
->trst
== 1)
383 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
386 #ifdef _DEBUG_JTAG_IO_
387 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
389 if (cmd
->cmd
.runtest
->end_state
!= -1)
390 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
391 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
394 #ifdef _DEBUG_JTAG_IO_
395 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
397 if (cmd
->cmd
.statemove
->end_state
!= -1)
398 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
399 gw16012_state_move();
402 #ifdef _DEBUG_JTAG_IO_
403 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
405 gw16012_path_move(cmd
->cmd
.pathmove
);
408 if (cmd
->cmd
.scan
->end_state
!= -1)
409 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
410 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
411 type
= jtag_scan_type(cmd
->cmd
.scan
);
412 #ifdef _DEBUG_JTAG_IO_
413 LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
414 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
416 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
417 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
418 retval
= ERROR_JTAG_QUEUE_FAILED
;
423 #ifdef _DEBUG_JTAG_IO_
424 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
426 jtag_sleep(cmd
->cmd
.sleep
->us
);
429 LOG_ERROR("BUG: unknown JTAG command type encountered");
438 #if PARPORT_USE_GIVEIO == 1
439 int gw16012_get_giveio_access()
442 OSVERSIONINFO version
;
444 version
.dwOSVersionInfoSize
= sizeof version
;
445 if (!GetVersionEx( &version
)) {
449 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
452 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
453 if (h
== INVALID_HANDLE_VALUE
) {
464 int gw16012_init(void)
466 #if PARPORT_USE_PPDEV == 1
472 #if PARPORT_USE_PPDEV == 1
475 LOG_ERROR("device is already opened");
476 return ERROR_JTAG_INIT_FAILED
;
479 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
480 LOG_DEBUG("opening /dev/ppi%d...", gw16012_port
);
482 snprintf(buffer
, 256, "/dev/ppi%d", gw16012_port
);
483 device_handle
= open(buffer
, O_WRONLY
);
485 LOG_DEBUG("opening /dev/parport%d...", gw16012_port
);
487 snprintf(buffer
, 256, "/dev/parport%d", gw16012_port
);
488 device_handle
= open(buffer
, O_WRONLY
);
492 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
493 return ERROR_JTAG_INIT_FAILED
;
496 LOG_DEBUG("...open");
498 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
499 i
=ioctl(device_handle
, PPCLAIM
);
502 LOG_ERROR("cannot claim device");
503 return ERROR_JTAG_INIT_FAILED
;
506 i
= PARPORT_MODE_COMPAT
;
507 i
= ioctl(device_handle
, PPSETMODE
, & i
);
510 LOG_ERROR(" cannot set compatible mode to device");
511 return ERROR_JTAG_INIT_FAILED
;
514 i
= IEEE1284_MODE_COMPAT
;
515 i
= ioctl(device_handle
, PPNEGOT
, & i
);
518 LOG_ERROR("cannot set compatible 1284 mode to device");
519 return ERROR_JTAG_INIT_FAILED
;
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...", 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);
547 #endif /* PARPORT_USE_PPDEV */
549 gw16012_input(&status_port
);
550 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
552 gw16012_speed(jtag_speed
);
558 int gw16012_quit(void)
564 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
569 /* only if the port wasn't overwritten by cmdline */
570 if (gw16012_port
== 0)
571 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)