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_
38 #include <sys/types.h>
39 #include <machine/sysarch.h>
40 #include <machine/cpufunc.h>
41 #define ioperm(startport,length,enable)\
42 i386_set_ioperm((startport), (length), (enable))
50 #endif /* __FreeBSD__ */
58 #if PARPORT_USE_PPDEV == 1
60 #include <dev/ppbus/ppi.h>
61 #include <dev/ppbus/ppbconf.h>
62 #define PPRSTATUS PPIGSTATUS
63 #define PPWDATA PPISDATA
65 #include <linux/parport.h>
66 #include <linux/ppdev.h>
69 #include <sys/ioctl.h>
70 #else /* not PARPORT_USE_PPDEV */
76 #if PARPORT_USE_GIVEIO == 1
87 unsigned long gw16012_port
;
89 /* interface variables
91 static u8 gw16012_msb
= 0x0;
92 static u8 gw16012_control_value
= 0x0;
94 #if PARPORT_USE_PPDEV == 1
95 static int device_handle
;
98 int gw16012_execute_queue(void);
99 int gw16012_register_commands(struct command_context_s
*cmd_ctx
);
100 int gw16012_speed(int speed
);
101 int gw16012_init(void);
102 int gw16012_quit(void);
104 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
106 jtag_interface_t gw16012_interface
=
110 .execute_queue
= gw16012_execute_queue
,
112 .support_pathmove
= 0,
114 .speed
= gw16012_speed
,
115 .register_commands
= gw16012_register_commands
,
116 .init
= gw16012_init
,
117 .quit
= gw16012_quit
,
120 int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
122 register_command(cmd_ctx
, NULL
, "parport_port", gw16012_handle_parport_port_command
,
123 COMMAND_CONFIG
, NULL
);
128 void gw16012_data(u8 value
)
130 value
= (value
& 0x7f) | gw16012_msb
;
131 gw16012_msb
^= 0x80; /* toggle MSB */
133 #ifdef _DEBUG_GW16012_IO_
134 DEBUG("%2.2x", value
);
137 #if PARPORT_USE_PPDEV == 1
138 ioctl(device_handle
, PPWDATA
, &value
);
141 outb(gw16012_port
, value
);
143 outb(value
, gw16012_port
);
148 void gw16012_control(u8 value
)
150 if (value
!= gw16012_control_value
)
152 gw16012_control_value
= value
;
154 #ifdef _DEBUG_GW16012_IO_
155 DEBUG("%2.2x", gw16012_control_value
);
158 #if PARPORT_USE_PPDEV == 1
159 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
162 outb(gw16012_port
+ 2, gw16012_control_value
);
164 outb(gw16012_control_value
, gw16012_port
+ 2);
170 void gw16012_input(u8
*value
)
172 #if PARPORT_USE_PPDEV == 1
173 ioctl(device_handle
, PPRSTATUS
, value
);
175 *value
= inb(gw16012_port
+ 1);
178 #ifdef _DEBUG_GW16012_IO_
179 DEBUG("%2.2x", *value
);
183 /* (1) assert or (0) deassert reset lines */
184 void gw16012_reset(int trst
, int srst
)
186 DEBUG("trst: %i, srst: %i", trst
, srst
);
189 gw16012_control(0x0d);
191 gw16012_control(0x0c);
194 gw16012_control(0x0a);
196 gw16012_control(0x0b);
199 int gw16012_speed(int speed
)
205 void gw16012_end_state(state
)
207 if (tap_move_map
[state
] != -1)
211 ERROR("BUG: %i is not a valid end state", state
);
216 void gw16012_state_move(void)
219 u8 tms_scan
= TAP_MOVE(cur_state
, end_state
);
221 gw16012_control(0x0); /* single-bit mode */
223 for (i
= 0; i
< 7; i
++)
225 tms
= (tms_scan
>> i
) & 1;
226 gw16012_data(tms
<< 1); /* output next TMS bit */
229 cur_state
= end_state
;
232 void gw16012_path_move(pathmove_command_t
*cmd
)
234 int num_states
= cmd
->num_states
;
240 gw16012_control(0x0); /* single-bit mode */
241 if (tap_transitions
[cur_state
].low
== cmd
->path
[state_count
])
243 gw16012_data(0x0); /* TCK cycle with TMS low */
245 else if (tap_transitions
[cur_state
].high
== cmd
->path
[state_count
])
247 gw16012_data(0x2); /* TCK cycle with TMS high */
251 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[state_count
]]);
255 cur_state
= cmd
->path
[state_count
];
260 end_state
= cur_state
;
263 void gw16012_runtest(int num_cycles
)
265 enum tap_state saved_end_state
= end_state
;
268 /* only do a state_move when we're not already in RTI */
269 if (cur_state
!= TAP_RTI
)
271 gw16012_end_state(TAP_RTI
);
272 gw16012_state_move();
275 for (i
= 0; i
< num_cycles
; i
++)
277 gw16012_control(0x0); /* single-bit mode */
278 gw16012_data(0x0); /* TMS cycle with TMS low */
281 gw16012_end_state(saved_end_state
);
282 if (cur_state
!= end_state
)
283 gw16012_state_move();
286 void gw16012_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
)
288 int bits_left
= scan_size
;
290 enum tap_state saved_end_state
= end_state
;
291 u8 scan_out
, scan_in
;
293 /* only if we're not already in the correct Shift state */
294 if (!((!ir_scan
&& (cur_state
== TAP_SD
)) || (ir_scan
&& (cur_state
== TAP_SI
))))
297 gw16012_end_state(TAP_SI
);
299 gw16012_end_state(TAP_SD
);
301 gw16012_state_move();
302 gw16012_end_state(saved_end_state
);
305 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
307 gw16012_control(0x2); /* seven-bit mode */
308 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
309 gw16012_data(scan_out
);
314 gw16012_control(0x0); /* single-bit mode */
315 while (bits_left
-- > 0)
319 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
321 if (bits_left
== 0) /* last bit */
323 if ((ir_scan
&& (end_state
== TAP_SI
))
324 || (!ir_scan
&& (end_state
== TAP_SD
)))
334 gw16012_data(scan_out
| tms
);
336 if (type
!= SCAN_OUT
)
338 gw16012_input(&scan_in
);
339 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
345 if (!((ir_scan
&& (end_state
== TAP_SI
)) ||
346 (!ir_scan
&& (end_state
== TAP_SD
))))
354 if (cur_state
!= end_state
)
355 gw16012_state_move();
359 int gw16012_execute_queue(void)
361 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
367 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
368 * that wasn't handled by a caller-provided error handler
377 #ifdef _DEBUG_JTAG_IO_
378 DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
380 if (cmd
->cmd
.end_state
->end_state
!= -1)
381 gw16012_end_state(cmd
->cmd
.end_state
->end_state
);
384 #ifdef _DEBUG_JTAG_IO_
385 DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
387 if (cmd
->cmd
.reset
->trst
== 1)
391 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
394 #ifdef _DEBUG_JTAG_IO_
395 DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
397 if (cmd
->cmd
.runtest
->end_state
!= -1)
398 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
399 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
402 #ifdef _DEBUG_JTAG_IO_
403 DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
405 if (cmd
->cmd
.statemove
->end_state
!= -1)
406 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
407 gw16012_state_move();
410 #ifdef _DEBUG_JTAG_IO_
411 DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
413 gw16012_path_move(cmd
->cmd
.pathmove
);
416 if (cmd
->cmd
.scan
->end_state
!= -1)
417 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
418 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
419 type
= jtag_scan_type(cmd
->cmd
.scan
);
420 #ifdef _DEBUG_JTAG_IO_
421 DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
422 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
424 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
425 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
426 retval
= ERROR_JTAG_QUEUE_FAILED
;
431 #ifdef _DEBUG_JTAG_IO_
432 DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
434 jtag_sleep(cmd
->cmd
.sleep
->us
);
437 ERROR("BUG: unknown JTAG command type encountered");
446 #if PARPORT_USE_GIVEIO == 1
447 int gw16012_get_giveio_access()
450 OSVERSIONINFO version
;
452 version
.dwOSVersionInfoSize
= sizeof version
;
453 if (!GetVersionEx( &version
)) {
457 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
460 h
= CreateFile( "\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
461 if (h
== INVALID_HANDLE_VALUE
) {
472 int gw16012_init(void)
474 #if PARPORT_USE_PPDEV == 1
481 #if PARPORT_USE_PPDEV == 1
484 ERROR("device is already opened");
485 return ERROR_JTAG_INIT_FAILED
;
489 DEBUG("opening /dev/ppi%d...", gw16012_port
);
491 snprintf(buffer
, 256, "/dev/ppi%d", gw16012_port
);
492 device_handle
= open(buffer
, O_WRONLY
);
494 DEBUG("opening /dev/parport%d...", gw16012_port
);
496 snprintf(buffer
, 256, "/dev/parport%d", gw16012_port
);
497 device_handle
= open(buffer
, O_WRONLY
);
501 ERROR("cannot open device. check it exists and that user read and write rights are set");
502 return ERROR_JTAG_INIT_FAILED
;
508 i
=ioctl(device_handle
, PPCLAIM
);
511 ERROR("cannot claim device");
512 return ERROR_JTAG_INIT_FAILED
;
515 i
= PARPORT_MODE_COMPAT
;
516 i
= ioctl(device_handle
, PPSETMODE
, & i
);
519 ERROR(" cannot set compatible mode to device");
520 return ERROR_JTAG_INIT_FAILED
;
523 i
= IEEE1284_MODE_COMPAT
;
524 i
= ioctl(device_handle
, PPNEGOT
, & i
);
527 ERROR("cannot set compatible 1284 mode to device");
528 return ERROR_JTAG_INIT_FAILED
;
532 if (gw16012_port
== 0)
534 gw16012_port
= 0x378;
535 WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
538 DEBUG("requesting privileges for parallel port 0x%lx...", gw16012_port
);
539 #if PARPORT_USE_GIVEIO == 1
540 if (gw16012_get_giveio_access() != 0)
541 #else /* PARPORT_USE_GIVEIO */
542 if (ioperm(gw16012_port
, 3, 1) != 0)
543 #endif /* PARPORT_USE_GIVEIO */
545 ERROR("missing privileges for direct i/o");
546 return ERROR_JTAG_INIT_FAILED
;
548 DEBUG("...privileges granted");
550 /* make sure parallel port is in right mode (clear tristate and interrupt */
552 outb(gw16012_port
+ 2, 0x0);
554 outb(0x0, gw16012_port
+ 2);
556 #endif /* PARPORT_USE_PPDEV */
558 gw16012_input(&status_port
);
559 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
561 gw16012_speed(jtag_speed
);
567 int gw16012_quit(void)
573 int gw16012_handle_parport_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
578 /* only if the port wasn't overwritten by cmdline */
579 if (gw16012_port
== 0)
580 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)