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 void gw16012_data(uint8_t value
)
83 value
= (value
& 0x7f) | gw16012_msb
;
84 gw16012_msb
^= 0x80; /* toggle MSB */
86 #ifdef _DEBUG_GW16012_IO_
87 LOG_DEBUG("%2.2x", value
);
90 #if PARPORT_USE_PPDEV == 1
91 ioctl(device_handle
, PPWDATA
, &value
);
93 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
94 outb(gw16012_port
, value
);
96 outb(value
, gw16012_port
);
101 static void gw16012_control(uint8_t value
)
103 if (value
!= gw16012_control_value
)
105 gw16012_control_value
= value
;
107 #ifdef _DEBUG_GW16012_IO_
108 LOG_DEBUG("%2.2x", gw16012_control_value
);
111 #if PARPORT_USE_PPDEV == 1
112 ioctl(device_handle
, PPWCONTROL
, &gw16012_control_value
);
114 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
115 outb(gw16012_port
+ 2, gw16012_control_value
);
117 outb(gw16012_control_value
, gw16012_port
+ 2);
123 static void gw16012_input(uint8_t *value
)
125 #if PARPORT_USE_PPDEV == 1
126 ioctl(device_handle
, PPRSTATUS
, value
);
128 *value
= inb(gw16012_port
+ 1);
131 #ifdef _DEBUG_GW16012_IO_
132 LOG_DEBUG("%2.2x", *value
);
136 /* (1) assert or (0) deassert reset lines */
137 static void gw16012_reset(int trst
, int srst
)
139 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
142 gw16012_control(0x0d);
144 gw16012_control(0x0c);
147 gw16012_control(0x0a);
149 gw16012_control(0x0b);
152 static int gw16012_speed(int speed
)
158 static void gw16012_end_state(tap_state_t state
)
160 if (tap_is_state_stable(state
))
161 tap_set_end_state(state
);
164 LOG_ERROR("BUG: %i is not a valid end state", state
);
169 static void gw16012_state_move(void)
172 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(), tap_get_end_state());
173 int tms_count
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
175 gw16012_control(0x0); /* single-bit mode */
177 for (i
= 0; i
< tms_count
; i
++)
179 tms
= (tms_scan
>> i
) & 1;
180 gw16012_data(tms
<< 1); /* output next TMS bit */
183 tap_set_state(tap_get_end_state());
186 static void gw16012_path_move(struct pathmove_command
*cmd
)
188 int num_states
= cmd
->num_states
;
194 gw16012_control(0x0); /* single-bit mode */
195 if (tap_state_transition(tap_get_state(), false) == cmd
->path
[state_count
])
197 gw16012_data(0x0); /* TCK cycle with TMS low */
199 else if (tap_state_transition(tap_get_state(), true) == cmd
->path
[state_count
])
201 gw16012_data(0x2); /* TCK cycle with TMS high */
205 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(cmd
->path
[state_count
]));
209 tap_set_state(cmd
->path
[state_count
]);
214 tap_set_end_state(tap_get_state());
217 static void gw16012_runtest(int num_cycles
)
219 tap_state_t saved_end_state
= tap_get_end_state();
222 /* only do a state_move when we're not already in IDLE */
223 if (tap_get_state() != TAP_IDLE
)
225 gw16012_end_state(TAP_IDLE
);
226 gw16012_state_move();
229 for (i
= 0; i
< num_cycles
; i
++)
231 gw16012_control(0x0); /* single-bit mode */
232 gw16012_data(0x0); /* TMS cycle with TMS low */
235 gw16012_end_state(saved_end_state
);
236 if (tap_get_state() != tap_get_end_state())
237 gw16012_state_move();
240 static void gw16012_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
)
242 int bits_left
= scan_size
;
244 tap_state_t saved_end_state
= tap_get_end_state();
245 uint8_t scan_out
, scan_in
;
247 /* only if we're not already in the correct Shift state */
248 if (!((!ir_scan
&& (tap_get_state() == TAP_DRSHIFT
)) || (ir_scan
&& (tap_get_state() == TAP_IRSHIFT
))))
251 gw16012_end_state(TAP_IRSHIFT
);
253 gw16012_end_state(TAP_DRSHIFT
);
255 gw16012_state_move();
256 gw16012_end_state(saved_end_state
);
259 while (type
== SCAN_OUT
&& ((bits_left
- 1) > 7))
261 gw16012_control(0x2); /* seven-bit mode */
262 scan_out
= buf_get_u32(buffer
, bit_count
, 7);
263 gw16012_data(scan_out
);
268 gw16012_control(0x0); /* single-bit mode */
269 while (bits_left
-- > 0)
273 scan_out
= buf_get_u32(buffer
, bit_count
, 1);
275 if (bits_left
== 0) /* last bit */
277 if ((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
))
278 || (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
)))
288 gw16012_data(scan_out
| tms
);
290 if (type
!= SCAN_OUT
)
292 gw16012_input(&scan_in
);
293 buf_set_u32(buffer
, bit_count
, 1, ((scan_in
& 0x08) >> 3));
299 if (!((ir_scan
&& (tap_get_end_state() == TAP_IRSHIFT
)) ||
300 (!ir_scan
&& (tap_get_end_state() == TAP_DRSHIFT
))))
304 tap_set_state(TAP_IRPAUSE
);
306 tap_set_state(TAP_DRPAUSE
);
308 if (tap_get_state() != tap_get_end_state())
309 gw16012_state_move();
313 static int gw16012_execute_queue(void)
315 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
321 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
322 * that wasn't handled by a caller-provided error handler
331 #ifdef _DEBUG_JTAG_IO_
332 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
334 if (cmd
->cmd
.reset
->trst
== 1)
336 tap_set_state(TAP_RESET
);
338 gw16012_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
341 #ifdef _DEBUG_JTAG_IO_
342 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
344 gw16012_end_state(cmd
->cmd
.runtest
->end_state
);
345 gw16012_runtest(cmd
->cmd
.runtest
->num_cycles
);
348 #ifdef _DEBUG_JTAG_IO_
349 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
351 gw16012_end_state(cmd
->cmd
.statemove
->end_state
);
352 gw16012_state_move();
355 #ifdef _DEBUG_JTAG_IO_
356 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
358 gw16012_path_move(cmd
->cmd
.pathmove
);
361 gw16012_end_state(cmd
->cmd
.scan
->end_state
);
362 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
363 type
= jtag_scan_type(cmd
->cmd
.scan
);
364 #ifdef _DEBUG_JTAG_IO_
365 LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd
->cmd
.scan
->ir_scan
) ? "ir" : "dr",
366 type
, scan_size
, cmd
->cmd
.scan
->end_state
);
368 gw16012_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
);
369 if (jtag_read_buffer(buffer
, cmd
->cmd
.scan
) != ERROR_OK
)
370 retval
= ERROR_JTAG_QUEUE_FAILED
;
375 #ifdef _DEBUG_JTAG_IO_
376 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
378 jtag_sleep(cmd
->cmd
.sleep
->us
);
381 LOG_ERROR("BUG: unknown JTAG command type encountered");
390 #if PARPORT_USE_GIVEIO == 1
391 static int gw16012_get_giveio_access(void)
394 OSVERSIONINFO version
;
396 version
.dwOSVersionInfoSize
= sizeof version
;
397 if (!GetVersionEx(&version
)) {
401 if (version
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
404 h
= CreateFile("\\\\.\\giveio", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
405 if (h
== INVALID_HANDLE_VALUE
) {
416 #if PARPORT_USE_PPDEV == 1
418 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
420 #define GW16012_PPDEV_NAME "ppi"
422 static int gw16012_init_ioctls(void)
425 temp
= ioctl(device_handle
, PPCLAIM
);
428 LOG_ERROR("cannot claim device");
429 return ERROR_JTAG_INIT_FAILED
;
432 temp
= PARPORT_MODE_COMPAT
;
433 temp
= ioctl(device_handle
, PPSETMODE
, &temp
);
436 LOG_ERROR(" cannot set compatible mode to device");
437 return ERROR_JTAG_INIT_FAILED
;
440 temp
= IEEE1284_MODE_COMPAT
;
441 temp
= ioctl(device_handle
, PPNEGOT
, &temp
);
444 LOG_ERROR("cannot set compatible 1284 mode to device");
445 return ERROR_JTAG_INIT_FAILED
;
451 #define GW16012_PPDEV_NAME "parport"
453 static int gw16012_init_ioctls(void)
458 #endif // defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
460 static int gw16012_init_device(void)
462 const char *device_name
= GW16012_PPDEV_NAME
;
465 if (device_handle
> 0)
467 LOG_ERROR("device is already opened");
468 return ERROR_JTAG_INIT_FAILED
;
471 snprintf(buffer
, 256, "/dev/%s%d", device_name
, gw16012_port
);
472 LOG_DEBUG("opening %s...", buffer
);
474 device_handle
= open(buffer
, O_WRONLY
);
475 if (device_handle
< 0)
477 LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
478 return ERROR_JTAG_INIT_FAILED
;
481 LOG_DEBUG("...open");
483 if (gw16012_init_ioctls() != ERROR_OK
)
484 return ERROR_JTAG_INIT_FAILED
;
489 #else // PARPORT_USE_PPDEV
491 static int gw16012_init_device(void)
493 if (gw16012_port
== 0)
495 gw16012_port
= 0x378;
496 LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
499 LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port
));
500 #if PARPORT_USE_GIVEIO == 1
501 if (gw16012_get_giveio_access() != 0)
502 #else /* PARPORT_USE_GIVEIO */
503 if (ioperm(gw16012_port
, 3, 1) != 0)
504 #endif /* PARPORT_USE_GIVEIO */
506 LOG_ERROR("missing privileges for direct i/o");
507 return ERROR_JTAG_INIT_FAILED
;
509 LOG_DEBUG("...privileges granted");
511 /* make sure parallel port is in right mode (clear tristate and interrupt */
512 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
513 outb(gw16012_port
+ 2, 0x0);
515 outb(0x0, gw16012_port
+ 2);
520 #endif // PARPORT_USE_PPDEV
522 static int gw16012_init(void)
526 if (gw16012_init_device() != ERROR_OK
)
527 return ERROR_JTAG_INIT_FAILED
;
529 gw16012_input(&status_port
);
530 gw16012_msb
= (status_port
& 0x80) ^ 0x80;
532 gw16012_speed(jtag_get_speed());
538 static int gw16012_quit(void)
544 COMMAND_HANDLER(gw16012_handle_parport_port_command
)
548 /* only if the port wasn't overwritten by cmdline */
549 if (gw16012_port
== 0)
551 COMMAND_PARSE_NUMBER(u16
, args
[0], gw16012_port
);
555 LOG_ERROR("The parport port was already configured!");
560 command_print(cmd_ctx
, "parport port = %u", gw16012_port
);
565 static int gw16012_register_commands(struct command_context_s
*cmd_ctx
)
567 register_command(cmd_ctx
, NULL
, "parport_port",
568 gw16012_handle_parport_port_command
, COMMAND_CONFIG
,
574 struct jtag_interface gw16012_interface
= {
576 .register_commands
= &gw16012_register_commands
,
577 .init
= &gw16012_init
,
578 .quit
= &gw16012_quit
,
579 .speed
= &gw16012_speed
,
580 .execute_queue
= &gw16012_execute_queue
,
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)