- added a PLD (programmable logic device) subsystem for FPGA, CPLD etc. configuration
[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 /* system includes */
29
30 /* system includes */
31 // -ino: 060521-1036
32 #ifdef __FreeBSD__
33
34 #include <sys/types.h>
35 #include <machine/sysarch.h>
36 #include <machine/cpufunc.h>
37 #define ioperm(startport,length,enable)\
38 i386_set_ioperm((startport), (length), (enable))
39
40 #else
41
42 #ifndef _WIN32
43 #include <sys/io.h>
44 #else
45 #include "errno.h"
46 #endif /* _WIN32 */
47
48 #endif /* __FreeBSD__ */
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 #ifdef __FreeBSD__
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 #endif
69
70 #if PARPORT_USE_GIVEIO == 1
71 #if IS_CYGWIN == 1
72 #include <windows.h>
73 #include <errno.h>
74 #undef ERROR
75 #endif
76 #endif
77
78 #include "log.h"
79
80 /* configuration */
81 unsigned long gw16012_port;
82
83 /* interface variables
84 */
85 static u8 gw16012_msb = 0x0;
86 static u8 gw16012_control_value = 0x0;
87
88 #if PARPORT_USE_PPDEV == 1
89 static int device_handle;
90 #endif
91
92 int gw16012_execute_queue(void);
93 int gw16012_register_commands(struct command_context_s *cmd_ctx);
94 int gw16012_speed(int speed);
95 int gw16012_init(void);
96 int gw16012_quit(void);
97
98 int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
99
100 jtag_interface_t gw16012_interface =
101 {
102 .name = "gw16012",
103
104 .execute_queue = gw16012_execute_queue,
105
106 .support_pathmove = 0,
107
108 .speed = gw16012_speed,
109 .register_commands = gw16012_register_commands,
110 .init = gw16012_init,
111 .quit = gw16012_quit,
112 };
113
114 int gw16012_register_commands(struct command_context_s *cmd_ctx)
115 {
116 register_command(cmd_ctx, NULL, "parport_port", gw16012_handle_parport_port_command,
117 COMMAND_CONFIG, NULL);
118
119 return ERROR_OK;
120 }
121
122 void gw16012_data(u8 value)
123 {
124 value = (value & 0x7f) | gw16012_msb;
125 gw16012_msb ^= 0x80; /* toggle MSB */
126
127 #if PARPORT_USE_PPDEV == 1
128 ioctl(device_handle, PPWDATA, &value);
129 #else
130 #ifdef __FreeBSD__
131 outb(gw16012_port, value);
132 #else
133 outb(value, gw16012_port);
134 #endif
135 #endif
136 }
137
138 void gw16012_control(u8 value)
139 {
140 if (value != gw16012_control_value)
141 {
142 gw16012_control_value = value;
143
144 #if PARPORT_USE_PPDEV == 1
145 ioctl(device_handle, PPWCONTROL, &gw16012_control_value);
146 #else
147 #ifdef __FreeBSD__
148 outb(gw16012_port + 2, gw16012_control_value);
149 #else
150 outb(gw16012_control_value, gw16012_port + 2);
151 #endif
152 #endif
153 }
154 }
155
156 void gw16012_input(u8 *value)
157 {
158 #if PARPORT_USE_PPDEV == 1
159 ioctl(device_handle, PPRSTATUS, value);
160 #else
161 *value = inb(gw16012_port + 1);
162 #endif
163 }
164
165 /* (1) assert or (0) deassert reset lines */
166 void gw16012_reset(int trst, int srst)
167 {
168 DEBUG("trst: %i, srst: %i", trst, srst);
169
170 if (trst == 0)
171 gw16012_control(0x0d);
172 else if (trst == 1)
173 gw16012_control(0x0c);
174
175 if (srst == 0)
176 gw16012_control(0x0a);
177 else if (srst == 1)
178 gw16012_control(0x0b);
179 }
180
181 int gw16012_speed(int speed)
182 {
183
184 return ERROR_OK;
185 }
186
187 void gw16012_end_state(state)
188 {
189 if (tap_move_map[state] != -1)
190 end_state = state;
191 else
192 {
193 ERROR("BUG: %i is not a valid end state", state);
194 exit(-1);
195 }
196 }
197
198 void gw16012_state_move(void)
199 {
200 int i=0, tms=0;
201 u8 tms_scan = TAP_MOVE(cur_state, end_state);
202
203 gw16012_control(0x0); /* single-bit mode */
204
205 for (i = 0; i < 7; i++)
206 {
207 tms = (tms_scan >> i) & 1;
208 gw16012_data(tms << 1); /* output next TMS bit */
209 }
210
211 cur_state = end_state;
212 }
213
214 void gw16012_runtest(int num_cycles)
215 {
216 enum tap_state saved_end_state = end_state;
217 int i;
218
219 /* only do a state_move when we're not already in RTI */
220 if (cur_state != TAP_RTI)
221 {
222 gw16012_end_state(TAP_RTI);
223 gw16012_state_move();
224 }
225
226 for (i = 0; i < num_cycles; i++)
227 {
228 gw16012_control(0x0); /* single-bit mode */
229 gw16012_data(0x0); /* TMS cycle with TMS low */
230 }
231
232 gw16012_end_state(saved_end_state);
233 if (cur_state != end_state)
234 gw16012_state_move();
235 }
236
237 void gw16012_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
238 {
239 int bits_left = scan_size;
240 int bit_count = 0;
241 enum tap_state saved_end_state = end_state;
242 u8 scan_out, scan_in;
243
244 if (ir_scan)
245 gw16012_end_state(TAP_SI);
246 else
247 gw16012_end_state(TAP_SD);
248
249 gw16012_state_move();
250 gw16012_end_state(saved_end_state);
251
252 while (type == SCAN_OUT && ((bits_left - 1) > 7))
253 {
254 gw16012_control(0x2); /* seven-bit mode */
255 scan_out = buf_get_u32(buffer, bit_count, 7);
256 gw16012_data(scan_out);
257 bit_count += 7;
258 bits_left -= 7;
259 }
260
261 gw16012_control(0x0); /* single-bit mode */
262 while (bits_left-- > 0)
263 {
264 u8 tms = 0;
265 if (bits_left == 0) /* last bit */
266 {
267 if ((ir_scan && (end_state == TAP_SI))
268 || (!ir_scan && (end_state == TAP_SD)))
269 {
270 tms = 0;
271 }
272 else
273 {
274 tms = 2;
275 }
276 }
277
278 scan_out = buf_get_u32(buffer, bit_count, 1);
279 gw16012_data(scan_out | tms);
280 if (type != SCAN_OUT)
281 {
282 gw16012_input(&scan_in);
283 buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3));
284 }
285 bit_count++;
286 }
287
288 if (!((ir_scan && (end_state == TAP_SI)) ||
289 (!ir_scan && (end_state == TAP_SD))))
290 {
291 gw16012_data(0x0);
292 if (ir_scan)
293 cur_state = TAP_PI;
294 else
295 cur_state = TAP_PD;
296
297 if (cur_state != end_state)
298 gw16012_state_move();
299 }
300 }
301
302 int gw16012_execute_queue(void)
303 {
304 jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
305 int scan_size;
306 enum scan_type type;
307 u8 *buffer;
308
309 while (cmd)
310 {
311 switch (cmd->type)
312 {
313 case JTAG_END_STATE:
314 #ifdef _DEBUG_JTAG_IO_
315 DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
316 #endif
317 if (cmd->cmd.end_state->end_state != -1)
318 gw16012_end_state(cmd->cmd.end_state->end_state);
319 break;
320 case JTAG_RESET:
321 #ifdef _DEBUG_JTAG_IO_
322 DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
323 #endif
324 if (cmd->cmd.reset->trst == 1)
325 {
326 cur_state = TAP_TLR;
327 }
328 gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
329 break;
330 case JTAG_RUNTEST:
331 #ifdef _DEBUG_JTAG_IO_
332 DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
333 #endif
334 if (cmd->cmd.runtest->end_state != -1)
335 gw16012_end_state(cmd->cmd.runtest->end_state);
336 gw16012_runtest(cmd->cmd.runtest->num_cycles);
337 break;
338 case JTAG_STATEMOVE:
339 #ifdef _DEBUG_JTAG_IO_
340 DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
341 #endif
342 if (cmd->cmd.statemove->end_state != -1)
343 gw16012_end_state(cmd->cmd.statemove->end_state);
344 gw16012_state_move();
345 break;
346 case JTAG_SCAN:
347 if (cmd->cmd.scan->end_state != -1)
348 gw16012_end_state(cmd->cmd.scan->end_state);
349 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
350 type = jtag_scan_type(cmd->cmd.scan);
351 #ifdef _DEBUG_JTAG_IO_
352 DEBUG("%s scan (%i) %i bit end in %i", (cmd->cmd.scan->ir_scan) ? "ir" : "dr",
353 type, scan_size, cmd->cmd.scan->end_state);
354 #endif
355 gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
356 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
357 return ERROR_JTAG_QUEUE_FAILED;
358 if (buffer)
359 free(buffer);
360 break;
361 case JTAG_SLEEP:
362 #ifdef _DEBUG_JTAG_IO_
363 DEBUG("sleep", cmd->cmd.sleep->us);
364 #endif
365 jtag_sleep(cmd->cmd.sleep->us);
366 break;
367 default:
368 ERROR("BUG: unknown JTAG command type encountered");
369 exit(-1);
370 }
371 cmd = cmd->next;
372 }
373
374 return ERROR_OK;
375 }
376
377 #if PARPORT_USE_GIVEIO == 1
378 int gw16012_get_giveio_access()
379 {
380 HANDLE h;
381 OSVERSIONINFO version;
382
383 version.dwOSVersionInfoSize = sizeof version;
384 if (!GetVersionEx( &version )) {
385 errno = EINVAL;
386 return -1;
387 }
388 if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
389 return 0;
390
391 h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
392 if (h == INVALID_HANDLE_VALUE) {
393 errno = ENODEV;
394 return -1;
395 }
396
397 CloseHandle( h );
398
399 return 0;
400 }
401 #endif
402
403 int gw16012_init(void)
404 {
405 #if PARPORT_USE_PPDEV == 1
406 char buffer[256];
407 int i = 0;
408 u8 control_port;
409 #endif
410 u8 status_port;
411
412 #if PARPORT_USE_PPDEV == 1
413 if (device_handle>0)
414 {
415 ERROR("device is already opened");
416 return ERROR_JTAG_INIT_FAILED;
417 }
418
419 #ifdef __FreeBSD__
420 DEBUG("opening /dev/ppi%d...", gw16012_port);
421
422 snprintf(buffer, 256, "/dev/ppi%d", gw16012_port);
423 device_handle = open(buffer, O_WRONLY);
424 #else
425 DEBUG("opening /dev/parport%d...", gw16012_port);
426
427 snprintf(buffer, 256, "/dev/parport%d", gw16012_port);
428 device_handle = open(buffer, O_WRONLY);
429 #endif
430 if (device_handle<0)
431 {
432 ERROR("cannot open device. check it exists and that user read and write rights are set");
433 return ERROR_JTAG_INIT_FAILED;
434 }
435
436 DEBUG("...open");
437
438 #ifndef __FreeBSD__
439 i=ioctl(device_handle, PPCLAIM);
440 if (i<0)
441 {
442 ERROR("cannot claim device");
443 return ERROR_JTAG_INIT_FAILED;
444 }
445
446 i = PARPORT_MODE_COMPAT;
447 i= ioctl(device_handle, PPSETMODE, & i);
448 if (i<0)
449 {
450 ERROR(" cannot set compatible mode to device");
451 return ERROR_JTAG_INIT_FAILED;
452 }
453
454 i = IEEE1284_MODE_COMPAT;
455 i = ioctl(device_handle, PPNEGOT, & i);
456 if (i<0)
457 {
458 ERROR("cannot set compatible 1284 mode to device");
459 return ERROR_JTAG_INIT_FAILED;
460 }
461 #endif
462 #else
463 if (gw16012_port == 0)
464 {
465 gw16012_port = 0x378;
466 WARNING("No gw16012 port specified, using default '0x378' (LPT1)");
467 }
468
469 DEBUG("requesting privileges for parallel port 0x%x...", gw16012_port);
470 #if PARPORT_USE_GIVEIO == 1
471 if (gw16012_get_giveio_access() != 0)
472 #else /* PARPORT_USE_GIVEIO */
473 if (ioperm(gw16012_port, 3, 1) != 0)
474 #endif /* PARPORT_USE_GIVEIO */
475 {
476 ERROR("missing privileges for direct i/o");
477 return ERROR_JTAG_INIT_FAILED;
478 }
479 DEBUG("...privileges granted");
480 #endif /* PARPORT_USE_PPDEV */
481
482 gw16012_input(&status_port);
483 gw16012_msb = (status_port & 0x80) ^ 0x80;
484
485 gw16012_speed(jtag_speed);
486 gw16012_reset(0, 0);
487
488 return ERROR_OK;
489 }
490
491 int gw16012_quit(void)
492 {
493
494 return ERROR_OK;
495 }
496
497 int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
498 {
499 if (argc == 0)
500 return ERROR_OK;
501
502 /* only if the port wasn't overwritten by cmdline */
503 if (gw16012_port == 0)
504 gw16012_port = strtoul(args[0], NULL, 0);
505
506 return ERROR_OK;
507 }

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)