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_
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__ */
56 #if PARPORT_USE_PPDEV == 1
57 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
58 #include <dev/ppbus/ppi.h>
59 #include <dev/ppbus/ppbconf.h>
60 #define PPRSTATUS PPIGSTATUS
61 #define PPWDATA PPISDATA
63 #include <linux/parport.h>
64 #include <linux/ppdev.h>
67 #include <sys/ioctl.h>
68 #else /* not PARPORT_USE_PPDEV */
74 #if PARPORT_USE_GIVEIO == 1
85 unsigned long gw16012_port
;
87 /* interface variables
89 static u8 gw16012_msb
= 0x0;
90 static u8 gw16012_control_value
= 0x0;
92 #if PARPORT_USE_PPDEV == 1
93 static int device_handle
;
96 int gw16012_execute_queue(void);
97 int gw16012_register_commands(struct command_context_s
*cmd_ctx
);
98 int gw16012_speed(int speed
);
99 int gw16012_init(void);
100 int gw16012_quit(void);
102 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
104 jtag_interface_t gw16012_interface
=
108 .execute_queue
= gw16012_execute_queue
,
110 .speed
= gw16012_speed
,
111 .register_commands
= gw16012_register_commands
,
112 .init
= gw16012_init
,
113 .quit
= gw16012_quit
,
116 int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
118 register_command(cmd_ctx
, NULL
, "parport_port", gw16012_handle_parport_port_command
,
119 COMMAND_CONFIG
, NULL
);
124 void gw16012_data(u8 value
)
126 value
= (value
& 0x7f) | gw16012_msb
;
127 gw16012_msb
^= 0x80; /* toggle MSB */
129 #ifdef _DEBUG_GW16012_IO_
130 DEBUG("%2.2x", value
);
133 #if PARPORT_USE_PPDEV == 1
134 ioctl(device_handle
, PPWDATA
, &value
);
136 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
137 outb(gw16012_port
, value
);
139 outb(value
, gw16012_port
);
144 void gw16012_control(u8 value
)
146 if (value
!= gw16012_control_value
)
148 gw16012_control_value
= value
;
150 #ifdef _DEBUG_GW16012_IO_
151 DEBUG("%2.2x", gw16012_control_value
);
154 #if PARPORT_USE_PPDEV == 1
155 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
157 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
158 outb(gw16012_port
+ 2, gw16012_control_value
);
160 outb(gw16012_control_value
, gw16012_port
+ 2);
166 void gw16012_input(u8
*value
)
168 #if PARPORT_USE_PPDEV == 1
169 ioctl(device_handle
, PPRSTATUS
, value
);
171 *value
= inb(gw16012_port
+ 1);
174 #ifdef _DEBUG_GW16012_IO_
175 DEBUG("%2.2x", *value
);
179 /* (1) assert or (0) deassert reset lines */
180 void gw16012_reset(int trst
, int srst
)
182 DEBUG("trst: %i, srst: %i", trst
, srst
);
185 gw16012_control(0x0d);
187 gw16012_control(0x0c);
190 gw16012_control(0x0a);
192 gw16012_control(0x0b);
195 int gw16012_speed(int speed
)
201 void gw16012_end_state(state
)
203 if (tap_move_map
[state
] != -1)
207 ERROR("BUG: %i is not a valid end state", state
);
212 void gw16012_state_move(void)
215 u8 tms_scan
= TAP_MOVE(cur_state
, end_state
);
217 gw16012_control(0x0); /* single-bit mode */
219 for (i
= 0; i
< 7; i
++)
221 tms
= (tms_scan
>> i
) & 1;
222 gw16012_data(tms
<< 1); /* output next TMS bit */
225 cur_state
= end_state
;
228 void gw16012_path_move(pathmove_command_t
*cmd
)
230 int num_states
= cmd
->num_states
;
236 gw16012_control(0x0); /* single-bit mode */
237 if (tap_transitions
[cur_state
].low
== cmd
->path
[state_count
])
239 gw16012_data(0x0); /* TCK cycle with TMS low */
241 else if (tap_transitions
[cur_state
].high
== cmd
->path
[state_count
])
243 gw16012_data(0x2); /* TCK cycle with TMS high */
247 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[state_count
]]);
251 cur_state
= cmd
->path
[state_count
];
256 end_state
= cur_state
;
259 void gw16012_runtest(int num_cycles
)
261 enum tap_state saved_end_state
= end_state
;
264 /* only do a state_move when we're not already in RTI */
265 if (cur_state
!= TAP_RTI
)
267 gw16012_end_state(TAP_RTI
);
268 gw16012_state_move();
271 for (i
= 0; i
< num_cycles
; i
++)
273 gw16012_control(0x0); /* single-bit mode */
274 gw16012_data(0x0); /* TMS cycle with TMS low */
277 gw16012_end_state(saved_end_state
);
278 if (cur_state
!= end_state
)
279 gw16012_state_move();
282 void gw16012_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
284 int bits_left
= scan_size
;
286 enum tap_state saved_end_state
= end_state
;
287 u8 scan_out
, scan_in
;
289 /* only if we're not already in the correct Shift state */
290 if (!((!ir_scan
&& (cur_state
== TAP_SD
)) || (ir_scan
&& (cur_state
== TAP_SI
))))
293 gw16012_end_state(TAP_SI
);
295 gw16012_end_state(TAP_SD
);
297 gw16012_state_move();
298 gw16012_end_state(saved_end_state
);
301 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
303 gw16012_control(0x2); /* seven-bit mode */
304 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
305 gw16012_data(scan_out
);
310 gw16012_control(0x0); /* single-bit mode */
311 while (bits_left
-- > 0)
315 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
317 if (bits_left
== 0) /* last bit */
319 if ((ir_scan
&& (end_state
== TAP_SI
))
320 || (!ir_scan
&& (end_state
== TAP_SD
)))
330 gw16012_data(scan_out
| tms
);
332 if (type
!= SCAN_OUT
)
334 gw16012_input(&scan_in
);
335 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
341 if (!((ir_scan
&& (end_state
== TAP_SI
)) ||
342 (!ir_scan
&& (end_state
== TAP_SD
))))
350 if (cur_state
!= end_state
)
351 gw16012_state_move();
355 int gw16012_execute_queue(void)
357 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
363 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
364 * that wasn't handled by a caller-provided error handler
373 #ifdef _DEBUG_JTAG_IO_
374 DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
376 if (cmd
->cmd
.end_state
->end_state
!= -1)
377 gw16012_end_state(cmd
->cmd
.end_state
->end_state
);
380 #ifdef _DEBUG_JTAG_IO_
381 DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
383 if (cmd
->cmd
.reset
->trst
== 1)
387 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
390 #ifdef _DEBUG_JTAG_IO_
391 DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
393 if (cmd
->cmd
.runtest
->end_state
!= -1)
394 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
395 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
398 #ifdef _DEBUG_JTAG_IO_
399 DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
401 if (cmd
->cmd
.statemove
->end_state
!= -1)
402 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
403 gw16012_state_move();
406 #ifdef _DEBUG_JTAG_IO_
407 DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
409 gw16012_path_move(cmd
->cmd
.pathmove
);
412 if (cmd
->cmd
.scan
->end_state
!= -1)
413 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
414 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
415 type
= jtag_scan_type(cmd
->cmd
.scan
);
416 #ifdef _DEBUG_JTAG_IO_
417 DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
418 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
420 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
421 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
422 retval
= ERROR_JTAG_QUEUE_FAILED
;
427 #ifdef _DEBUG_JTAG_IO_
428 DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
430 jtag_sleep(cmd
->cmd
.sleep
->us
);
433 ERROR("BUG: unknown JTAG command type encountered");
442 #if PARPORT_USE_GIVEIO == 1
443 int gw16012_get_giveio_access()
446 OSVERSIONINFO version
;
448 version
.dwOSVersionInfoSize
= sizeof version
;
449 if (!GetVersionEx( &version
)) {
453 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
456 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
457 if (h
== INVALID_HANDLE_VALUE
) {
468 int gw16012_init(void)
470 #if PARPORT_USE_PPDEV == 1
477 #if PARPORT_USE_PPDEV == 1
480 ERROR("device is already opened");
481 return ERROR_JTAG_INIT_FAILED
;
484 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
485 DEBUG("opening /dev/ppi%d...", gw16012_port
);
487 snprintf(buffer
, 256, "/dev/ppi%d", gw16012_port
);
488 device_handle
= open(buffer
, O_WRONLY
);
490 DEBUG("opening /dev/parport%d...", gw16012_port
);
492 snprintf(buffer
, 256, "/dev/parport%d", gw16012_port
);
493 device_handle
= open(buffer
, O_WRONLY
);
497 ERROR("cannot open device. check it exists and that user read and write rights are set");
498 return ERROR_JTAG_INIT_FAILED
;
503 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
504 i
=ioctl(device_handle
, PPCLAIM
);
507 ERROR("cannot claim device");
508 return ERROR_JTAG_INIT_FAILED
;
511 i
= PARPORT_MODE_COMPAT
;
512 i
= ioctl(device_handle
, PPSETMODE
, & i
);
515 ERROR(" cannot set compatible mode to device");
516 return ERROR_JTAG_INIT_FAILED
;
519 i
= IEEE1284_MODE_COMPAT
;
520 i
= ioctl(device_handle
, PPNEGOT
, & i
);
523 ERROR("cannot set compatible 1284 mode to device");
524 return ERROR_JTAG_INIT_FAILED
;
528 if (gw16012_port
== 0)
530 gw16012_port
= 0x378;
531 WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
534 DEBUG("requesting privileges for parallel port 0x%lx...", gw16012_port
);
535 #if PARPORT_USE_GIVEIO == 1
536 if (gw16012_get_giveio_access() != 0)
537 #else /* PARPORT_USE_GIVEIO */
538 if (ioperm(gw16012_port
, 3, 1) != 0)
539 #endif /* PARPORT_USE_GIVEIO */
541 ERROR("missing privileges for direct i/o");
542 return ERROR_JTAG_INIT_FAILED
;
544 DEBUG("...privileges granted");
546 /* make sure parallel port is in right mode (clear tristate and interrupt */
547 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
548 outb(gw16012_port
+ 2, 0x0);
550 outb(0x0, gw16012_port
+ 2);
552 #endif /* PARPORT_USE_PPDEV */
554 gw16012_input(&status_port
);
555 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
557 gw16012_speed(jtag_speed
);
563 int gw16012_quit(void)
569 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
574 /* only if the port wasn't overwritten by cmdline */
575 if (gw16012_port
== 0)
576 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)