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

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)