- fix line-endings
[openocd.git] / src / jtag / gw16012.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "replacements.h"
25
26 #include "jtag.h"
27
28 #if 1
29 #define _DEBUG_GW16012_IO_
30 #endif
31
32 /* system includes */
33 // -ino: 060521-1036
34 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
35
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))
41
42 #else
43
44 #ifdef _WIN32
45 #include "errno.h"
46 #endif /* _WIN32 */
47
48 #endif /* __FreeBSD__, __FreeBSD_kernel__ */
49
50 #include <string.h>
51 #include <stdlib.h>
52
53 #include <sys/time.h>
54 #include <time.h>
55
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
62 #else
63 #include <linux/parport.h>
64 #include <linux/ppdev.h>
65 #endif
66 #include <fcntl.h>
67 #include <sys/ioctl.h>
68 #else /* not PARPORT_USE_PPDEV */
69 #ifndef _WIN32
70 #include <sys/io.h>
71 #endif
72 #endif
73
74 #if PARPORT_USE_GIVEIO == 1
75 #if IS_CYGWIN == 1
76 #include <windows.h>
77 #include <errno.h>
78 #undef ERROR
79 #endif
80 #endif
81
82 #include "log.h"
83
84 /* configuration */
85 u16 gw16012_port;
86
87 /* interface variables
88 */
89 static u8 gw16012_msb = 0x0;
90 static u8 gw16012_control_value = 0x0;
91
92 #if PARPORT_USE_PPDEV == 1
93 static int device_handle;
94 #endif
95
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);
101
102 int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
103
104 jtag_interface_t gw16012_interface =
105 {
106 .name = "gw16012",
107
108 .execute_queue = gw16012_execute_queue,
109
110 .speed = gw16012_speed,
111 .register_commands = gw16012_register_commands,
112 .init = gw16012_init,
113 .quit = gw16012_quit,
114 };
115
116 int gw16012_register_commands(struct command_context_s *cmd_ctx)
117 {
118 register_command(cmd_ctx, NULL, "parport_port", gw16012_handle_parport_port_command,
119 COMMAND_CONFIG, NULL);
120
121 return ERROR_OK;
122 }
123
124 void gw16012_data(u8 value)
125 {
126 value = (value & 0x7f) | gw16012_msb;
127 gw16012_msb ^= 0x80; /* toggle MSB */
128
129 #ifdef _DEBUG_GW16012_IO_
130 DEBUG("%2.2x", value);
131 #endif
132
133 #if PARPORT_USE_PPDEV == 1
134 ioctl(device_handle, PPWDATA, &value);
135 #else
136 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
137 outb(gw16012_port, value);
138 #else
139 outb(value, gw16012_port);
140 #endif
141 #endif
142 }
143
144 void gw16012_control(u8 value)
145 {
146 if (value != gw16012_control_value)
147 {
148 gw16012_control_value = value;
149
150 #ifdef _DEBUG_GW16012_IO_
151 DEBUG("%2.2x", gw16012_control_value);
152 #endif
153
154 #if PARPORT_USE_PPDEV == 1
155 ioctl(device_handle, PPWCONTROL, &gw16012_control_value);
156 #else
157 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
158 outb(gw16012_port + 2, gw16012_control_value);
159 #else
160 outb(gw16012_control_value, gw16012_port + 2);
161 #endif
162 #endif
163 }
164 }
165
166 void gw16012_input(u8 *value)
167 {
168 #if PARPORT_USE_PPDEV == 1
169 ioctl(device_handle, PPRSTATUS, value);
170 #else
171 *value = inb(gw16012_port + 1);
172 #endif
173
174 #ifdef _DEBUG_GW16012_IO_
175 DEBUG("%2.2x", *value);
176 #endif
177 }
178
179 /* (1) assert or (0) deassert reset lines */
180 void gw16012_reset(int trst, int srst)
181 {
182 DEBUG("trst: %i, srst: %i", trst, srst);
183
184 if (trst == 0)
185 gw16012_control(0x0d);
186 else if (trst == 1)
187 gw16012_control(0x0c);
188
189 if (srst == 0)
190 gw16012_control(0x0a);
191 else if (srst == 1)
192 gw16012_control(0x0b);
193 }
194
195 int gw16012_speed(int speed)
196 {
197
198 return ERROR_OK;
199 }
200
201 void gw16012_end_state(state)
202 {
203 if (tap_move_map[state] != -1)
204 end_state = state;
205 else
206 {
207 ERROR("BUG: %i is not a valid end state", state);
208 exit(-1);
209 }
210 }
211
212 void gw16012_state_move(void)
213 {
214 int i=0, tms=0;
215 u8 tms_scan = TAP_MOVE(cur_state, end_state);
216
217 gw16012_control(0x0); /* single-bit mode */
218
219 for (i = 0; i < 7; i++)
220 {
221 tms = (tms_scan >> i) & 1;
222 gw16012_data(tms << 1); /* output next TMS bit */
223 }
224
225 cur_state = end_state;
226 }
227
228 void gw16012_path_move(pathmove_command_t *cmd)
229 {
230 int num_states = cmd->num_states;
231 int state_count;
232
233 state_count = 0;
234 while (num_states)
235 {
236 gw16012_control(0x0); /* single-bit mode */
237 if (tap_transitions[cur_state].low == cmd->path[state_count])
238 {
239 gw16012_data(0x0); /* TCK cycle with TMS low */
240 }
241 else if (tap_transitions[cur_state].high == cmd->path[state_count])
242 {
243 gw16012_data(0x2); /* TCK cycle with TMS high */
244 }
245 else
246 {
247 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
248 exit(-1);
249 }
250
251 cur_state = cmd->path[state_count];
252 state_count++;
253 num_states--;
254 }
255
256 end_state = cur_state;
257 }
258
259 void gw16012_runtest(int num_cycles)
260 {
261 enum tap_state saved_end_state = end_state;
262 int i;
263
264 /* only do a state_move when we're not already in RTI */
265 if (cur_state != TAP_RTI)
266 {
267 gw16012_end_state(TAP_RTI);
268 gw16012_state_move();
269 }
270
271 for (i = 0; i < num_cycles; i++)
272 {
273 gw16012_control(0x0); /* single-bit mode */
274 gw16012_data(0x0); /* TMS cycle with TMS low */
275 }
276
277 gw16012_end_state(saved_end_state);
278 if (cur_state != end_state)
279 gw16012_state_move();
280 }
281
282 void gw16012_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
283 {
284 int bits_left = scan_size;
285 int bit_count = 0;
286 enum tap_state saved_end_state = end_state;
287 u8 scan_out, scan_in;
288
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))))
291 {
292 if (ir_scan)
293 gw16012_end_state(TAP_SI);
294 else
295 gw16012_end_state(TAP_SD);
296
297 gw16012_state_move();
298 gw16012_end_state(saved_end_state);
299 }
300
301 while (type == SCAN_OUT && ((bits_left - 1) > 7))
302 {
303 gw16012_control(0x2); /* seven-bit mode */
304 scan_out = buf_get_u32(buffer, bit_count, 7);
305 gw16012_data(scan_out);
306 bit_count += 7;
307 bits_left -= 7;
308 }
309
310 gw16012_control(0x0); /* single-bit mode */
311 while (bits_left-- > 0)
312 {
313 u8 tms = 0;
314
315 scan_out = buf_get_u32(buffer, bit_count, 1);
316
317 if (bits_left == 0) /* last bit */
318 {
319 if ((ir_scan && (end_state == TAP_SI))
320 || (!ir_scan && (end_state == TAP_SD)))
321 {
322 tms = 0;
323 }
324 else
325 {
326 tms = 2;
327 }
328 }
329
330 gw16012_data(scan_out | tms);
331
332 if (type != SCAN_OUT)
333 {
334 gw16012_input(&scan_in);
335 buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3));
336 }
337
338 bit_count++;
339 }
340
341 if (!((ir_scan && (end_state == TAP_SI)) ||
342 (!ir_scan && (end_state == TAP_SD))))
343 {
344 gw16012_data(0x0);
345 if (ir_scan)
346 cur_state = TAP_PI;
347 else
348 cur_state = TAP_PD;
349
350 if (cur_state != end_state)
351 gw16012_state_move();
352 }
353 }
354
355 int gw16012_execute_queue(void)
356 {
357 jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
358 int scan_size;
359 enum scan_type type;
360 u8 *buffer;
361 int retval;
362
363 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
364 * that wasn't handled by a caller-provided error handler
365 */
366 retval = ERROR_OK;
367
368 while (cmd)
369 {
370 switch (cmd->type)
371 {
372 case JTAG_END_STATE:
373 #ifdef _DEBUG_JTAG_IO_
374 DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
375 #endif
376 if (cmd->cmd.end_state->end_state != -1)
377 gw16012_end_state(cmd->cmd.end_state->end_state);
378 break;
379 case JTAG_RESET:
380 #ifdef _DEBUG_JTAG_IO_
381 DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
382 #endif
383 if (cmd->cmd.reset->trst == 1)
384 {
385 cur_state = TAP_TLR;
386 }
387 gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
388 break;
389 case JTAG_RUNTEST:
390 #ifdef _DEBUG_JTAG_IO_
391 DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
392 #endif
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);
396 break;
397 case JTAG_STATEMOVE:
398 #ifdef _DEBUG_JTAG_IO_
399 DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
400 #endif
401 if (cmd->cmd.statemove->end_state != -1)
402 gw16012_end_state(cmd->cmd.statemove->end_state);
403 gw16012_state_move();
404 break;
405 case JTAG_PATHMOVE:
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]);
408 #endif
409 gw16012_path_move(cmd->cmd.pathmove);
410 break;
411 case JTAG_SCAN:
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);
419 #endif
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;
423 if (buffer)
424 free(buffer);
425 break;
426 case JTAG_SLEEP:
427 #ifdef _DEBUG_JTAG_IO_
428 DEBUG("sleep %i", cmd->cmd.sleep->us);
429 #endif
430 jtag_sleep(cmd->cmd.sleep->us);
431 break;
432 default:
433 ERROR("BUG: unknown JTAG command type encountered");
434 exit(-1);
435 }
436 cmd = cmd->next;
437 }
438
439 return retval;
440 }
441
442 #if PARPORT_USE_GIVEIO == 1
443 int gw16012_get_giveio_access()
444 {
445 HANDLE h;
446 OSVERSIONINFO version;
447
448 version.dwOSVersionInfoSize = sizeof version;
449 if (!GetVersionEx( &version )) {
450 errno = EINVAL;
451 return -1;
452 }
453 if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
454 return 0;
455
456 h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
457 if (h == INVALID_HANDLE_VALUE) {
458 errno = ENODEV;
459 return -1;
460 }
461
462 CloseHandle( h );
463
464 return 0;
465 }
466 #endif
467
468 int gw16012_init(void)
469 {
470 #if PARPORT_USE_PPDEV == 1
471 char buffer[256];
472 int i = 0;
473 #endif
474 u8 status_port;
475
476 #if PARPORT_USE_PPDEV == 1
477 if (device_handle>0)
478 {
479 ERROR("device is already opened");
480 return ERROR_JTAG_INIT_FAILED;
481 }
482
483 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
484 DEBUG("opening /dev/ppi%d...", gw16012_port);
485
486 snprintf(buffer, 256, "/dev/ppi%d", gw16012_port);
487 device_handle = open(buffer, O_WRONLY);
488 #else
489 DEBUG("opening /dev/parport%d...", gw16012_port);
490
491 snprintf(buffer, 256, "/dev/parport%d", gw16012_port);
492 device_handle = open(buffer, O_WRONLY);
493 #endif
494 if (device_handle<0)
495 {
496 ERROR("cannot open device. check it exists and that user read and write rights are set");
497 return ERROR_JTAG_INIT_FAILED;
498 }
499
500 DEBUG("...open");
501
502 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
503 i=ioctl(device_handle, PPCLAIM);
504 if (i<0)
505 {
506 ERROR("cannot claim device");
507 return ERROR_JTAG_INIT_FAILED;
508 }
509
510 i = PARPORT_MODE_COMPAT;
511 i= ioctl(device_handle, PPSETMODE, & i);
512 if (i<0)
513 {
514 ERROR(" cannot set compatible mode to device");
515 return ERROR_JTAG_INIT_FAILED;
516 }
517
518 i = IEEE1284_MODE_COMPAT;
519 i = ioctl(device_handle, PPNEGOT, & i);
520 if (i<0)
521 {
522 ERROR("cannot set compatible 1284 mode to device");
523 return ERROR_JTAG_INIT_FAILED;
524 }
525 #endif
526 #else
527 if (gw16012_port == 0)
528 {
529 gw16012_port = 0x378;
530 WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
531 }
532
533 DEBUG("requesting privileges for parallel port 0x%lx...", gw16012_port);
534 #if PARPORT_USE_GIVEIO == 1
535 if (gw16012_get_giveio_access() != 0)
536 #else /* PARPORT_USE_GIVEIO */
537 if (ioperm(gw16012_port, 3, 1) != 0)
538 #endif /* PARPORT_USE_GIVEIO */
539 {
540 ERROR("missing privileges for direct i/o");
541 return ERROR_JTAG_INIT_FAILED;
542 }
543 DEBUG("...privileges granted");
544
545 /* make sure parallel port is in right mode (clear tristate and interrupt */
546 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
547 outb(gw16012_port + 2, 0x0);
548 #else
549 outb(0x0, gw16012_port + 2);
550 #endif
551 #endif /* PARPORT_USE_PPDEV */
552
553 gw16012_input(&status_port);
554 gw16012_msb = (status_port & 0x80) ^ 0x80;
555
556 gw16012_speed(jtag_speed);
557 gw16012_reset(0, 0);
558
559 return ERROR_OK;
560 }
561
562 int gw16012_quit(void)
563 {
564
565 return ERROR_OK;
566 }
567
568 int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
569 {
570 if (argc == 0)
571 return ERROR_OK;
572
573 /* only if the port wasn't overwritten by cmdline */
574 if (gw16012_port == 0)
575 gw16012_port = strtoul(args[0], NULL, 0);
576
577 return ERROR_OK;
578 }

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)