1 /*
2 * $Id$
3 *
4 * Copyright (C) 2011 Steve Tell
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 *
21 * Python bindings for urjtag intially written by Steve Tell.
22 * Additional methods by Jonathan Stroud.
23 *
24 */
25 #include <Python.h>
26 #include "structmember.h"
27 #include "pycompat23.h"
28
29 #include <sysdep.h>
30
31 #include <urjtag/urjtag.h>
32 #include <urjtag/chain.h>
33 #include <urjtag/cmd.h>
34
35 #include "py_urjtag.h"
36
37 PyObject *UrjtagError;
38
39 typedef struct
40 {
41 PyObject_HEAD urj_chain_t *urchain;
42 urj_pyregister_t *reglist;
43 } urj_pychain_t;
44
45
urj_pyc_invalidate_reglist(urj_pychain_t * self)46 static void urj_pyc_invalidate_reglist(urj_pychain_t *self)
47 {
48 urj_pyregister_t *r;
49 while(self->reglist) {
50 self->reglist->inst = NULL;
51 self->reglist->urreg = NULL;
52 r = self->reglist;
53 self->reglist = self->reglist->next;
54 Py_DECREF (r);
55 }
56 }
57
58 static void
urj_pyc_dealloc(urj_pychain_t * self)59 urj_pyc_dealloc (urj_pychain_t *self)
60 {
61 urj_tap_chain_flush (self->urchain);
62 urj_pyc_invalidate_reglist (self);
63 urj_tap_chain_free (self->urchain);
64 Py_TYPE (self)->tp_free ((PyObject *) self);
65 }
66
67 static PyObject *
urj_pyc_new(PyTypeObject * type,PyObject * args,PyObject * kwds)68 urj_pyc_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
69 {
70 urj_pychain_t *self;
71
72 self = (urj_pychain_t *) type->tp_alloc (type, 0);
73 if (self == NULL)
74 return NULL;
75
76 self->urchain = urj_tap_chain_alloc ();
77 if (self->urchain == NULL)
78 {
79 Py_DECREF (self);
80 return PyErr_NoMemory ();
81 }
82 self->urchain->main_part = 0;
83 return (PyObject *) self;
84 }
85
86
87 /* python helpers for methods */
88
89 /*
90 * propagate return value from liburjtag function that returns
91 * URJ_STATUS_OK on success or somthing else on failure.
92 * if OK, return python "none".
93 * else, throw a python exception
94 */
95 PyObject *
urj_py_chkret(int rc)96 urj_py_chkret (int rc)
97 {
98 if (rc == URJ_STATUS_OK)
99 return Py_BuildValue (""); /* python "None" */
100
101 if (urj_error_get ())
102 {
103 PyErr_SetString (UrjtagError, urj_error_describe ());
104 urj_error_reset ();
105 }
106 else
107 PyErr_SetString (UrjtagError,
108 _("liburjtag BUG: unknown urjtag error"));
109 return NULL;
110 }
111
112 /* perform selected prerequesite checks on the state of a chain object
113 * returns nonzero on success.
114 * if 0 is returned, python exception has been posted and
115 * caller must return NULL to signal python exception.
116 */
117 int
urj_pyc_precheck(urj_chain_t * urc,int checks_needed)118 urj_pyc_precheck (urj_chain_t *urc, int checks_needed)
119 {
120 if (urc == NULL)
121 {
122 PyErr_SetString (PyExc_RuntimeError, _("liburjtag python binding BUG: null chain"));
123 return 0;
124 }
125
126 if (checks_needed & UPRC_CBL)
127 {
128 if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
129 {
130 PyErr_SetString (UrjtagError, _("cable() has not been called"));
131 return 0;
132 }
133 }
134
135 if (checks_needed & UPRC_DET)
136 {
137 if (urc->parts == NULL)
138 {
139 PyErr_SetString (PyExc_RuntimeError,
140 _("no parts: detect or addpart not called on this chain"));
141 return 0;
142 }
143 }
144
145 if (checks_needed & UPRC_BUS)
146 {
147 if (!urj_bus) /* why is this a global and not a chain property? */
148 {
149 PyErr_SetString (PyExc_RuntimeError,
150 _("Bus missing: initbus not called?"));
151 return 0;
152 }
153 if (!urj_bus->driver)
154 {
155 PyErr_SetString (PyExc_RuntimeError,
156 _("Bus driver missing: initbus not called?"));
157 return 0;
158 }
159 }
160
161 return 1;
162 }
163
164
165 /* urj_chain_t / urjtag.chain methods */
166
167 static PyObject *
urj_pyc_cable(urj_pychain_t * self,PyObject * args)168 urj_pyc_cable (urj_pychain_t *self, PyObject *args)
169 {
170 char *cable_params[5] = { NULL, NULL, NULL, NULL, NULL };
171 urj_chain_t *urc = self->urchain;
172 char *drivername;
173
174 if (!urj_pyc_precheck (urc, 0))
175 return NULL;
176
177 if (!PyArg_ParseTuple (args, "s|ssss",
178 &drivername,
179 &cable_params[0],
180 &cable_params[1],
181 &cable_params[2], &cable_params[3]))
182 return NULL;
183
184 return urj_py_chkret (urj_tap_chain_connect (urc, drivername, cable_params));
185 }
186
187 static PyObject *
urj_pyc_flush(urj_pychain_t * self)188 urj_pyc_flush (urj_pychain_t *self)
189 {
190 urj_chain_t *urc = self->urchain;
191
192 if (!urj_pyc_precheck (urc, UPRC_CBL))
193 return NULL;
194
195 urj_tap_chain_flush (urc);
196 return Py_BuildValue ("");
197 }
198
199 static PyObject *
urj_pyc_disconnect(urj_pychain_t * self)200 urj_pyc_disconnect (urj_pychain_t *self)
201 {
202 urj_chain_t *urc = self->urchain;
203 if (!urj_pyc_precheck (urc, 0))
204 return NULL;
205 urj_tap_chain_disconnect (urc);
206 return Py_BuildValue ("");
207 }
208
209 static PyObject *
urj_pyc_test_cable(urj_pychain_t * self)210 urj_pyc_test_cable (urj_pychain_t *self)
211 {
212 urj_chain_t *urc = self->urchain;
213 if (!urj_pyc_precheck (urc, 0))
214 return NULL;
215 return urj_py_chkret (urj_cmd_test_cable (urc));
216 }
217
218 static PyObject *
urj_pyc_tap_detect(urj_pychain_t * self,PyObject * args)219 urj_pyc_tap_detect (urj_pychain_t *self, PyObject *args)
220 {
221 urj_chain_t *urc = self->urchain;
222 int maxirlen = 0;
223 if (!PyArg_ParseTuple (args, "|i", &maxirlen))
224 return NULL;
225 if (!urj_pyc_precheck (urc, UPRC_CBL))
226 return NULL;
227
228 urj_pyc_invalidate_reglist(self);
229 return urj_py_chkret (urj_tap_detect (urc, maxirlen));
230 }
231
232 static PyObject *
urj_pyc_len(urj_pychain_t * self,PyObject * args)233 urj_pyc_len (urj_pychain_t *self, PyObject *args)
234 {
235 urj_chain_t *urc = self->urchain;
236 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_DET))
237 return NULL;
238
239 return Py_BuildValue ("i", urc->parts->len);
240 }
241
242 static PyObject *
urj_pyc_partid(urj_pychain_t * self,PyObject * args)243 urj_pyc_partid (urj_pychain_t *self, PyObject *args)
244 {
245 urj_chain_t *urc = self->urchain;
246 int partno;
247 if (!PyArg_ParseTuple (args, "i", &partno))
248 return NULL;
249
250 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_DET))
251 return NULL;
252
253 if (partno >= urc->parts->len)
254 {
255 PyErr_SetString (PyExc_RuntimeError, _("part number out of range"));
256 return NULL;
257 }
258 else
259 {
260 urj_part_t *p;
261 uint32_t id;
262
263 p = urc->parts->parts[partno];
264 id = urj_tap_register_get_value (p->id);
265 return Py_BuildValue ("i", id);
266 }
267 }
268
269 static PyObject *
urj_pyc_reset(urj_pychain_t * self)270 urj_pyc_reset (urj_pychain_t *self)
271 {
272 urj_chain_t *urc = self->urchain;
273 PyObject *rc;
274
275 if (!urj_pyc_precheck (urc, UPRC_CBL))
276 return NULL;
277
278 rc = urj_py_chkret (urj_tap_reset_bypass (urc));
279 urj_tap_chain_flush (urc);
280 return rc;
281 }
282
283 static PyObject *
urj_pyc_set_trst(urj_pychain_t * self,PyObject * args)284 urj_pyc_set_trst (urj_pychain_t *self, PyObject *args)
285 {
286 urj_chain_t *urc = self->urchain;
287 int trstval;
288 if (!PyArg_ParseTuple (args, "i", &trstval))
289 return NULL;
290 if (!urj_pyc_precheck (urc, UPRC_CBL))
291 return NULL;
292 urj_tap_chain_set_trst (urc, trstval);
293 return Py_BuildValue ("");
294 }
295
296 static PyObject *
urj_pyc_get_trst(urj_pychain_t * self)297 urj_pyc_get_trst (urj_pychain_t *self)
298 {
299 int trstval;
300 urj_chain_t *urc = self->urchain;
301 if (!urj_pyc_precheck (urc, UPRC_CBL))
302 return NULL;
303
304 trstval = urj_tap_chain_get_trst (urc);
305 return Py_BuildValue ("i", trstval);
306 }
307
308 static PyObject *
urj_pyc_get_tdo(urj_pychain_t * self)309 urj_pyc_get_tdo (urj_pychain_t *self)
310 {
311 int tdoval;
312 urj_chain_t *urc = self->urchain;
313 if (!urj_pyc_precheck (urc, UPRC_CBL))
314 return NULL;
315
316 tdoval = urj_tap_cable_get_tdo (urc->cable);
317 return Py_BuildValue ("i", tdoval);
318 }
319
320 static PyObject *
urj_pyc_set_pod_signal(urj_pychain_t * self,PyObject * args)321 urj_pyc_set_pod_signal (urj_pychain_t *self, PyObject *args)
322 {
323 urj_chain_t *urc = self->urchain;
324 uint32_t mask, val, oldval;
325 if (!PyArg_ParseTuple (args, "ii", &mask, &val))
326 return NULL;
327 if (!urj_pyc_precheck (urc, UPRC_CBL))
328 return NULL;
329
330 oldval = urj_tap_chain_set_pod_signal (urc, mask, val);
331 return Py_BuildValue ("i", oldval);
332 }
333
334 static PyObject *
urj_pyc_get_pod_signal(urj_pychain_t * self,PyObject * args)335 urj_pyc_get_pod_signal (urj_pychain_t *self, PyObject *args)
336 {
337 uint32_t sig;
338 uint32_t val;
339 urj_chain_t *urc = self->urchain;
340 if (!PyArg_ParseTuple (args, "i", &sig))
341 return NULL;
342 if (!urj_pyc_precheck (urc, UPRC_CBL))
343 return NULL;
344
345 val = urj_tap_chain_get_pod_signal (urc, sig);
346 return Py_BuildValue ("i", val);
347 }
348
349 static PyObject *
urj_pyc_set_frequency(urj_pychain_t * self,PyObject * args)350 urj_pyc_set_frequency (urj_pychain_t *self, PyObject *args)
351 {
352 urj_chain_t *urc = self->urchain;
353 uint32_t freq;
354 if (!PyArg_ParseTuple (args, "i", &freq))
355 return NULL;
356 if (!urj_pyc_precheck (urc, UPRC_CBL))
357 return NULL;
358
359 urj_tap_cable_set_frequency (urc->cable, freq);
360 return Py_BuildValue ("");
361 }
362
363 static PyObject *
urj_pyc_get_frequency(urj_pychain_t * self,PyObject * args)364 urj_pyc_get_frequency (urj_pychain_t *self, PyObject *args)
365 {
366 urj_chain_t *urc = self->urchain;
367 unsigned long freq;
368 if (!urj_pyc_precheck (urc, UPRC_CBL))
369 return NULL;
370
371 freq = urj_tap_cable_get_frequency (urc->cable);
372
373 return Py_BuildValue ("i", (uint32_t) freq);
374 }
375
376 /* set instruction for the active part
377 */
378 static PyObject *
urj_pyc_set_instruction(urj_pychain_t * self,PyObject * args)379 urj_pyc_set_instruction (urj_pychain_t *self, PyObject *args)
380 {
381 char *instname;
382 urj_part_t *part;
383 urj_chain_t *urc = self->urchain;
384 if (!PyArg_ParseTuple (args, "s", &instname))
385 return NULL;
386 if (!urj_pyc_precheck (urc, UPRC_CBL))
387 return NULL;
388
389 part = urj_tap_chain_active_part (urc);
390 if (part == NULL)
391 {
392 PyErr_SetString (UrjtagError, _("No active part on chain"));
393 return NULL;
394 }
395 urj_part_set_instruction (part, instname);
396 return Py_BuildValue ("");
397 }
398
399 static PyObject *
urj_pyc_shift_ir(urj_pychain_t * self)400 urj_pyc_shift_ir (urj_pychain_t *self)
401 {
402 urj_chain_t *urc = self->urchain;
403 if (!urj_pyc_precheck (urc, UPRC_CBL))
404 return NULL;
405
406 return urj_py_chkret (urj_tap_chain_shift_instructions (urc));
407 }
408
409 static PyObject *
urj_pyc_shift_dr(urj_pychain_t * self)410 urj_pyc_shift_dr (urj_pychain_t *self)
411 {
412 urj_chain_t *urc = self->urchain;
413 if (!urj_pyc_precheck (urc, UPRC_CBL))
414 return NULL;
415
416 /* TODO: need a way to not capture the TDO output
417 */
418 return urj_py_chkret (urj_tap_chain_shift_data_registers (urc, 1));
419 }
420
421 static PyObject *
urj_pyc_get_dr(urj_pychain_t * self,int in,int string,PyObject * args)422 urj_pyc_get_dr (urj_pychain_t *self, int in, int string, PyObject *args)
423 {
424 urj_chain_t *urc = self->urchain;
425 urj_part_t *part;
426 urj_tap_register_t *r;
427 urj_data_register_t *dr;
428 urj_part_instruction_t *active_ir;
429 int lsb = -1;
430 int msb = -1;
431 const char *value_string;
432
433 if (!PyArg_ParseTuple (args, "|ii", &msb, &lsb))
434 return NULL;
435 if (lsb == -1)
436 lsb = msb;
437 if (!urj_pyc_precheck (urc, UPRC_CBL))
438 return NULL;
439
440 part = urj_tap_chain_active_part (urc);
441 if (part == NULL)
442 {
443 PyErr_SetString (UrjtagError, _("no active part in chain"));
444 return NULL;
445 }
446 active_ir = part->active_instruction;
447 if (active_ir == NULL)
448 {
449 PyErr_SetString (UrjtagError, _("part without active instruction"));
450 return NULL;
451 }
452 dr = active_ir->data_register;
453 if (dr == NULL)
454 {
455 PyErr_SetString (UrjtagError,
456 _("instruction without active data register"));
457 return NULL;
458 }
459
460 if (in)
461 r = dr->in; /* input buffer for next shift_dr */
462 else
463 r = dr->out; /* recently captured+scanned-out values */
464
465 if (in)
466 r = dr->in; /* input buffer for next shift_dr */
467 else
468 r = dr->out; /* recently captured+scanned-out values */
469
470 if (msb == -1)
471 value_string = urj_tap_register_get_string (r);
472 else
473 value_string = urj_tap_register_get_string_bit_range (r, msb, lsb);
474 if (value_string == NULL)
475 {
476 PyErr_SetString (UrjtagError,
477 _("error obtaining tap register value"));
478 return NULL;
479 }
480
481 if (string)
482 return Py_BuildValue ("s", value_string);
483 else
484 return PyLong_FromString((char *)value_string, NULL, 2);
485 }
486
487 static PyObject *
urj_pyc_get_str_dr_out(urj_pychain_t * self,PyObject * args)488 urj_pyc_get_str_dr_out (urj_pychain_t *self, PyObject *args)
489 {
490 return urj_pyc_get_dr (self, 0, 1, args);
491 }
492
493 static PyObject *
urj_pyc_get_str_dr_in(urj_pychain_t * self,PyObject * args)494 urj_pyc_get_str_dr_in (urj_pychain_t *self, PyObject *args)
495 {
496 return urj_pyc_get_dr (self, 1, 1, args);
497 }
498
499 static PyObject *
urj_pyc_get_int_dr_out(urj_pychain_t * self,PyObject * args)500 urj_pyc_get_int_dr_out (urj_pychain_t *self, PyObject *args)
501 {
502 return urj_pyc_get_dr (self, 0, 0, args);
503 }
504
505 static PyObject *
urj_pyc_get_int_dr_in(urj_pychain_t * self,PyObject * args)506 urj_pyc_get_int_dr_in (urj_pychain_t *self, PyObject *args)
507 {
508 return urj_pyc_get_dr (self, 1, 0, args);
509 }
510
511 static PyObject *
urj_pyc_set_dr(urj_pychain_t * self,int in,PyObject * args)512 urj_pyc_set_dr (urj_pychain_t *self, int in, PyObject *args)
513 {
514 urj_chain_t *urc = self->urchain;
515 urj_part_t *part;
516 urj_tap_register_t *r;
517 urj_data_register_t *dr;
518 urj_part_instruction_t *active_ir;
519 char *newstr = NULL;
520 uint64_t newval;
521 int lsb = -1;
522 int msb = -1;
523
524 if (!PyArg_ParseTuple (args, "s|ii", &newstr, &msb, &lsb))
525 {
526 PyErr_Clear ();
527 if (!PyArg_ParseTuple (args, "K|ii", &newval, &msb, &lsb))
528 return NULL;
529 }
530
531 if (!urj_pyc_precheck (urc, UPRC_CBL))
532 return NULL;
533
534 part = urj_tap_chain_active_part (urc);
535 if (part == NULL)
536 {
537 PyErr_SetString (UrjtagError, _("no active part in chain"));
538 return NULL;
539 }
540 active_ir = part->active_instruction;
541 if (active_ir == NULL)
542 {
543 PyErr_SetString (UrjtagError, _("part without active instruction"));
544 return NULL;
545 }
546 dr = active_ir->data_register;
547 if (dr == NULL)
548 {
549 PyErr_SetString (UrjtagError,
550 _("instruction without active data register"));
551 return NULL;
552 }
553
554 if (in)
555 r = dr->in;
556 else
557 r = dr->out;
558
559 if (msb == -1)
560 {
561 if (newstr)
562 return urj_py_chkret (urj_tap_register_set_string(r, newstr));
563 else
564 return urj_py_chkret (urj_tap_register_set_value(r, newval));
565 }
566 else
567 {
568 if (lsb == -1)
569 lsb = msb;
570
571 if (newstr)
572 return urj_py_chkret (urj_tap_register_set_string_bit_range(r, newstr, msb, lsb));
573 else
574 return urj_py_chkret (urj_tap_register_set_value_bit_range(r, newval, msb, lsb));
575 }
576 }
577
578 static PyObject *
urj_pyc_set_dr_out(urj_pychain_t * self,PyObject * args)579 urj_pyc_set_dr_out (urj_pychain_t *self, PyObject *args)
580 {
581 return urj_pyc_set_dr (self, 0, args);
582 }
583
584 static PyObject *
urj_pyc_set_dr_in(urj_pychain_t * self,PyObject * args)585 urj_pyc_set_dr_in (urj_pychain_t *self, PyObject *args)
586 {
587 return urj_pyc_set_dr (self, 1, args);
588 }
589
590 static PyObject *
urj_pyc_run_svf(urj_pychain_t * self,PyObject * args)591 urj_pyc_run_svf (urj_pychain_t *self, PyObject *args)
592 {
593 urj_chain_t *urc = self->urchain;
594 char *fname;
595 int stop = 0;
596 unsigned long ref_freq = 0;
597 FILE *svf_file;
598 PyObject *rc;
599
600 if (!PyArg_ParseTuple (args, "s|iI", &fname, &stop, &ref_freq))
601 return NULL;
602 if (!urj_pyc_precheck (urc, UPRC_CBL))
603 return NULL;
604
605 svf_file = fopen (fname, FOPEN_R);
606 if (!svf_file)
607 {
608 PyErr_SetFromErrnoWithFilename(PyExc_IOError, fname);
609 return NULL;
610 }
611 rc = urj_py_chkret (urj_svf_run (urc, svf_file, stop, ref_freq));
612 fclose (svf_file);
613 return rc;
614 }
615
616 static PyObject *
urj_pyc_addpart(urj_pychain_t * self,PyObject * args)617 urj_pyc_addpart (urj_pychain_t *self, PyObject *args)
618 {
619 urj_chain_t *urc = self->urchain;
620 long unsigned len;
621
622 if (!PyArg_ParseTuple (args, "i", &len))
623 return NULL;
624
625 if (!urj_pyc_precheck (urc, UPRC_CBL))
626 return NULL;
627
628 if (urj_tap_manual_add (urc, len) < 0)
629 {
630 PyErr_SetString (PyExc_RuntimeError,
631 _("urj_tap_manual_add failed"));
632 return NULL;
633 }
634
635 if (urc->parts == NULL)
636 {
637 PyErr_SetString (PyExc_RuntimeError,
638 _("addpart: internal error; no parts."));
639 return NULL;
640 }
641
642 // @@@@ RFHH this cannot be
643 if (urc->parts->len == 0)
644 {
645 urj_part_parts_free (urc->parts);
646 self->urchain->parts = NULL;
647 PyErr_SetString (PyExc_RuntimeError,
648 _("addpart: internal error; parts->len==0."));
649 return NULL;
650 }
651
652 urj_part_parts_set_instruction (urc->parts, "BYPASS");
653 // urj_tap_chain_shift_instructions (urc);
654 return Py_BuildValue ("");
655 }
656
657 static PyObject *
urj_pyc_add_register(urj_pychain_t * self,PyObject * args)658 urj_pyc_add_register (urj_pychain_t *self, PyObject *args)
659 {
660 char *regname;
661 int reglen;
662 urj_part_t *part;
663 urj_chain_t *urc = self->urchain;
664
665 if (!PyArg_ParseTuple (args, "si", ®name, ®len))
666 return NULL;
667 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_DET))
668 return NULL;
669
670 part = urj_tap_chain_active_part (urc);
671 if (part == NULL)
672 {
673 if (urj_error_get ())
674 {
675 PyErr_SetString (UrjtagError, urj_error_describe ());
676 urj_error_reset ();
677 }
678 else
679 PyErr_SetString (UrjtagError,
680 _("liburjtag BUG: unknown urjtag error"));
681 return NULL;
682 }
683
684 return urj_py_chkret (urj_part_data_register_define (part, regname, reglen));
685 }
686
687 static PyObject *
urj_pyc_add_instruction(urj_pychain_t * self,PyObject * args)688 urj_pyc_add_instruction (urj_pychain_t *self, PyObject *args)
689 {
690 char *instname;
691 char *code;
692 char *regname;
693 urj_part_t *part;
694 urj_chain_t *urc = self->urchain;
695
696 if (!PyArg_ParseTuple (args, "sss", &instname, &code, ®name))
697 return NULL;
698 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_DET))
699 return NULL;
700 part = urj_tap_chain_active_part (urc);
701
702 if (part == NULL)
703 {
704 if (urj_error_get ())
705 {
706 PyErr_SetString (UrjtagError, urj_error_describe ());
707 urj_error_reset ();
708 }
709 else
710 PyErr_SetString (UrjtagError,
711 _("liburjtag BUG: unknown urjtag error"));
712 return NULL;
713 }
714
715 if (urj_part_instruction_define (part, instname, code, regname) == NULL)
716 return urj_py_chkret (URJ_STATUS_FAIL);
717 else
718 return Py_BuildValue ("");
719 }
720
721 static PyObject *
urj_pyc_setpart(urj_pychain_t * self,PyObject * args)722 urj_pyc_setpart (urj_pychain_t *self, PyObject *args)
723 {
724 urj_chain_t *urc = self->urchain;
725 int part;
726 if (!PyArg_ParseTuple (args, "i", &part))
727 return NULL;
728 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_DET))
729 return NULL;
730
731 urc->active_part = part;
732 return Py_BuildValue ("");
733 }
734
735 static PyObject *
urj_pyc_initbus(urj_pychain_t * self,PyObject * args)736 urj_pyc_initbus (urj_pychain_t *self, PyObject *args)
737 {
738 char *bus_params[5] = { NULL, NULL, NULL, NULL, NULL };
739 char *drivername;
740 urj_chain_t *urc = self->urchain;
741
742 if (!PyArg_ParseTuple (args, "s|ssss",
743 &drivername,
744 &bus_params[0], &bus_params[1], &bus_params[2],
745 &bus_params[3]))
746 return NULL;
747 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_DET))
748 return NULL;
749
750 return urj_py_chkret (urj_bus_init (urc, drivername, bus_params));
751 }
752
753 static PyObject *
urj_pyc_detectflash(urj_pychain_t * self,PyObject * args)754 urj_pyc_detectflash (urj_pychain_t *self, PyObject *args)
755 {
756 urj_chain_t *urc = self->urchain;
757 int adr;
758 if (!PyArg_ParseTuple (args, "i", &adr))
759 return NULL;
760 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_BUS))
761 return NULL;
762
763 return Py_BuildValue ("i",
764 urj_flash_detectflash (URJ_LOG_LEVEL_NORMAL,
765 urj_bus, adr));
766 }
767
768 static PyObject *
urj_pyc_peek(urj_pychain_t * self,PyObject * args)769 urj_pyc_peek (urj_pychain_t *self, PyObject *args)
770 {
771 long unsigned adr;
772 uint32_t val;
773 urj_bus_area_t area;
774 urj_chain_t *urc = self->urchain;
775
776 if (!PyArg_ParseTuple (args, "i", &adr))
777 return NULL;
778
779 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_BUS))
780 return NULL;
781
782 URJ_BUS_PREPARE (urj_bus);
783 URJ_BUS_AREA (urj_bus, adr, &area);
784 val = URJ_BUS_READ (urj_bus, adr);
785
786 switch (area.width)
787 {
788 case 8:
789 val &= 0xff;
790 break;
791 case 16:
792 val &= 0xffff;
793 break;
794 default:
795 break;
796 }
797 return Py_BuildValue ("i", val);
798 }
799
800 static PyObject *
urj_pyc_poke(urj_pychain_t * self,PyObject * args)801 urj_pyc_poke (urj_pychain_t *self, PyObject *args)
802 {
803 long unsigned adr, val;
804 urj_bus_area_t area;
805 urj_chain_t *urc = self->urchain;
806
807 if (!PyArg_ParseTuple (args, "ii", &adr, &val))
808 return NULL;
809
810 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_BUS))
811 return NULL;
812
813 URJ_BUS_PREPARE (urj_bus);
814 URJ_BUS_AREA (urj_bus, adr, &area);
815 URJ_BUS_WRITE (urj_bus, adr, val);
816 return Py_BuildValue ("");
817 }
818
819 static PyObject *
urj_pyc_flashmem(urj_pychain_t * self,PyObject * args)820 urj_pyc_flashmem (urj_pychain_t *self, PyObject *args)
821 {
822 urj_chain_t *urc = self->urchain;
823 int msbin;
824 int noverify = 0;
825 long unsigned adr = 0;
826 FILE *f;
827 char *optstr = NULL;
828 char *fname = NULL;
829 int r;
830
831 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_BUS))
832 return NULL;
833
834 if (!PyArg_ParseTuple
835 (args, "ss|i", &optstr, &fname, &noverify))
836 return NULL;
837
838 msbin = strcasecmp ("msbin", optstr) == 0;
839 if (!msbin && urj_cmd_get_number (optstr, &adr) != URJ_STATUS_OK)
840 return NULL;
841
842 f = fopen (fname, FOPEN_R);
843 if (!f)
844 {
845 PyErr_SetFromErrnoWithFilename(PyExc_IOError, fname);
846 return NULL;
847 }
848
849 if (msbin)
850 r = urj_flashmsbin (urj_bus, f, noverify);
851 else
852 r = urj_flashmem (urj_bus, f, adr, noverify);
853
854 fclose (f);
855 return Py_BuildValue ("i", r);
856 }
857
858 static PyObject *
urj_pyc_get_register(urj_pychain_t * self,PyObject * args)859 urj_pyc_get_register (urj_pychain_t *self, PyObject *args)
860 {
861 urj_chain_t *urc = self->urchain;
862 int partn;
863 char *regname = NULL;
864 char *instname = NULL;
865 urj_part_t *p;
866 urj_data_register_t *dr;
867 urj_pyregister_t *reg;
868 urj_part_instruction_t *inst;
869
870 PyTypeObject *regtype = &urj_pyregister_Type;
871
872 if (!urj_pyc_precheck (urc, UPRC_CBL|UPRC_DET))
873 return NULL;
874 if (!PyArg_ParseTuple (args, "is|s", &partn, ®name, &instname))
875 return NULL;
876
877 if(partn < 0 || partn > urc->parts->len) {
878 PyErr_SetString (UrjtagError,
879 _("part number out of range for chain length"));
880 return NULL;
881 }
882 p = urc->parts->parts[partn];
883
884 dr = urj_part_find_data_register (p, regname);
885 if(dr == NULL) {
886 PyErr_SetString (UrjtagError,
887 _("get_register: register not found"));
888 return NULL;
889 }
890 if(instname) {
891 inst = urj_part_find_instruction (p, instname);
892 if(inst == NULL) {
893 PyErr_SetString (UrjtagError,
894 _("get_register: instruction not found"));
895 return NULL;
896 }
897 } else {
898 inst = NULL;
899 }
900
901 reg = (urj_pyregister_t *) PyObject_New (urj_pyregister_t*, regtype);
902 reg->part = partn;
903 reg->urreg = dr;
904 reg->urc = urc;
905 reg->inst = inst;
906
907 Py_INCREF(reg);
908 reg->next = self->reglist;
909 self->reglist = reg;
910 return (PyObject *) reg;
911 }
912
913
914 static PyMethodDef urj_pyc_methods[] =
915 {
916 {"cable", (PyCFunction) urj_pyc_cable, METH_VARARGS,
917 "Connect to the jtag hardware cable of the specified name and type."},
918 {"test_cable", (PyCFunction) urj_pyc_test_cable, METH_NOARGS,
919 "check that the jtag cable is connected to a valid chain"},
920 {"disconnect", (PyCFunction) urj_pyc_disconnect, METH_NOARGS,
921 "Disconnect from the jtag hardware cable"},
922 {"tap_detect", (PyCFunction) urj_pyc_tap_detect, METH_VARARGS,
923 "Identify the chips on the chain"},
924 {"len", (PyCFunction) urj_pyc_len, METH_NOARGS,
925 "Return the length of the TAP chain"},
926 {"reset", (PyCFunction) urj_pyc_reset, METH_NOARGS,
927 "Perform jtag reset using TMS"},
928 {"flush", (PyCFunction) urj_pyc_flush, METH_NOARGS,
929 "Flush the chain output"},
930 {"partid", (PyCFunction) urj_pyc_partid, METH_VARARGS,
931 "Return the IDCODE for the indicated part number in the chain"},
932 {"set_trst", (PyCFunction) urj_pyc_set_trst, METH_VARARGS,
933 "set the TRST output of the cable"},
934 {"get_trst", (PyCFunction) urj_pyc_get_trst, METH_NOARGS,
935 "get the current value of the TRST output of the cable"},
936 {"get_tdo", (PyCFunction) urj_pyc_get_tdo, METH_NOARGS,
937 "get the current value of the TDO output of the cable"},
938 {"set_pod_signal", (PyCFunction) urj_pyc_set_pod_signal, METH_VARARGS,
939 "set an auxiliary pod signal"},
940 {"get_pod_signal", (PyCFunction) urj_pyc_get_pod_signal, METH_VARARGS,
941 "get the current value of an auxiliary pod signal"},
942 {"set_frequency", (PyCFunction) urj_pyc_set_frequency, METH_VARARGS,
943 "Change the TCK frequency to be at most the specified value in Hz"},
944 {"get_frequency", (PyCFunction) urj_pyc_get_frequency, METH_NOARGS,
945 "get the current TCK frequency"},
946 {"set_instruction", (PyCFunction) urj_pyc_set_instruction, METH_VARARGS,
947 "Set values in the instruction register holding buffer"},
948 {"shift_ir", (PyCFunction) urj_pyc_shift_ir, METH_NOARGS,
949 "scan values through the instruction register"},
950 {"shift_dr", (PyCFunction) urj_pyc_shift_dr, METH_NOARGS,
951 "scan values through the data register"},
952 {"get_dr_in_string", (PyCFunction) urj_pyc_get_str_dr_in, METH_VARARGS,
953 "get bits that will be scanned in on next shift_dr, as string"},
954 {"get_dr_out_string", (PyCFunction) urj_pyc_get_str_dr_out, METH_VARARGS,
955 "retrieve values scanned out from the data registers on the last shift_dr, as string"},
956 {"get_dr_in", (PyCFunction) urj_pyc_get_int_dr_in, METH_VARARGS,
957 "get bits that will be scanned in on next shift_dr, as integer"},
958 {"get_dr_out", (PyCFunction) urj_pyc_get_int_dr_out, METH_VARARGS,
959 "retrieve values scanned out from the data registers on the last shift_dr, as integer"},
960 {"set_dr_in", (PyCFunction) urj_pyc_set_dr_in, METH_VARARGS,
961 "set bits that will be scanned in on next shiftdr"},
962 {"set_dr_out", (PyCFunction) urj_pyc_set_dr_out, METH_VARARGS,
963 "set the holding register for values scanned out from the data registers"},
964 {"run_svf", (PyCFunction) urj_pyc_run_svf, METH_VARARGS,
965 "Play a named SVF file; optionally setting stop-on-mismatch and runtest frequency"},
966 {"addpart", (PyCFunction) urj_pyc_addpart, METH_VARARGS,
967 "manually adds parts on the JTAG chain"},
968 {"add_instruction", (PyCFunction) urj_pyc_add_instruction, METH_VARARGS,
969 "manually add intruction to the current part"},
970 {"add_register", (PyCFunction) urj_pyc_add_register, METH_VARARGS,
971 "manually add register to current part on the JTAG chain"},
972 {"part", (PyCFunction) urj_pyc_setpart, METH_VARARGS,
973 "change active part for current JTAG chain"},
974 {"initbus", (PyCFunction) urj_pyc_initbus, METH_VARARGS,
975 "initialize bus driver for active part"},
976 {"detectflash", (PyCFunction) urj_pyc_detectflash, METH_VARARGS,
977 "Detect parameters of flash chips attached to a part"},
978 {"peek", (PyCFunction) urj_pyc_peek, METH_VARARGS,
979 "read a single word"},
980 {"poke", (PyCFunction) urj_pyc_poke, METH_VARARGS,
981 "write a single word"},
982 {"flashmem", (PyCFunction) urj_pyc_flashmem, METH_VARARGS,
983 "burn flash memory with data from a file"},
984 {"get_register", (PyCFunction)urj_pyc_get_register, METH_VARARGS,
985 "retrieve register object for convenient set_dr/shift_dr use"},
986
987 {NULL} /* Sentinel */
988 };
989
990 static PyTypeObject urj_pychain_Type =
991 {
992 PyVarObject_HEAD_INIT (NULL, 0) "urjtag.chain", /* tp_name */
993 sizeof (urj_pychain_t), /* tp_basicsize */
994 0, /* tp_itemsize */
995 (destructor) urj_pyc_dealloc, /* tp_dealloc */
996 0, /* tp_print */
997 0, /* tp_getattr */
998 0, /* tp_setattr */
999 0, /* tp_compare */
1000 0, /* tp_repr */
1001 0, /* tp_as_number */
1002 0, /* tp_as_sequence */
1003 0, /* tp_as_mapping */
1004 0, /* tp_hash */
1005 0, /* tp_call */
1006 0, /* tp_str */
1007 0, /* tp_getattro */
1008 0, /* tp_setattro */
1009 0, /* tp_as_buffer */
1010 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1011 "JTAG chain objects", /* tp_doc */
1012 0, /* tp_traverse */
1013 0, /* tp_clear */
1014 0, /* tp_richcompare */
1015 0, /* tp_weaklistoffset */
1016 0, /* tp_iter */
1017 0, /* tp_iternext */
1018 urj_pyc_methods, /* tp_methods */
1019 0, /* tp_members */
1020 0, /* tp_getset */
1021 0, /* tp_base */
1022 0, /* tp_dict */
1023 0, /* tp_descr_get */
1024 0, /* tp_descr_set */
1025 0, /* tp_dictoffset */
1026 0, /* tp_init */
1027 0, /* tp_alloc */
1028 urj_pyc_new, /* tp_new */
1029 };
1030
1031 /************************************************************************
1032 * module methods that are not part of any type
1033 */
1034
1035 static PyObject *
urjtag_loglevel(PyObject * self,PyObject * args)1036 urjtag_loglevel (PyObject *self, PyObject *args)
1037 {
1038 int loglevel; /* TODO: accept string or symbol and map to the enum */
1039 if (!PyArg_ParseTuple (args, "i", &loglevel))
1040 return NULL;
1041 urj_log_state.level = loglevel;
1042 return Py_BuildValue ("");
1043 }
1044
1045 static PyMethodDef module_methods[] =
1046 {
1047 {"loglevel", urjtag_loglevel, METH_VARARGS,
1048 "Set log level of the urjtag library"},
1049 {NULL} /* Sentinel */
1050 };
1051
1052 static struct PyModuleDef urjtag_moduledef =
1053 {
1054 PyModuleDef_HEAD_INIT,
1055 "urjtag",
1056 "Python extension module for urjtag",
1057 -1,
1058 module_methods,
1059 };
1060
MODINIT_DECL(urjtag)1061 MODINIT_DECL (urjtag)
1062 {
1063 PyObject *m;
1064
1065 if (PyType_Ready (&urj_pychain_Type) < 0)
1066 return MODINIT_ERROR_VAL;
1067 if (PyType_Ready (&urj_pyregister_Type) < 0)
1068 return MODINIT_ERROR_VAL;
1069
1070 m = PyModule_Create (&urjtag_moduledef);
1071
1072 if (m == NULL)
1073 return MODINIT_ERROR_VAL;
1074
1075 UrjtagError = PyErr_NewException ("urjtag.error", NULL, NULL);
1076 Py_INCREF (UrjtagError);
1077 PyModule_AddObject (m, "error", UrjtagError);
1078
1079 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_ALL );
1080 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_COMM );
1081 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_DEBUG );
1082 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_DETAIL );
1083 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_NORMAL );
1084 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_WARNING );
1085 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_ERROR );
1086 PyModule_AddIntMacro(m, URJ_LOG_LEVEL_SILENT );
1087
1088 PyModule_AddIntMacro(m, URJ_POD_CS_TDI );
1089 PyModule_AddIntMacro(m, URJ_POD_CS_TCK );
1090 PyModule_AddIntMacro(m, URJ_POD_CS_TMS );
1091 PyModule_AddIntMacro(m, URJ_POD_CS_TRST );
1092 PyModule_AddIntMacro(m, URJ_POD_CS_RESET );
1093 PyModule_AddIntMacro(m, URJ_POD_CS_SCK );
1094 PyModule_AddIntMacro(m, URJ_POD_CS_SDA );
1095 PyModule_AddIntMacro(m, URJ_POD_CS_SS );
1096
1097 Py_INCREF (&urj_pychain_Type);
1098 PyModule_AddObject (m, "chain", (PyObject *) &urj_pychain_Type);
1099 Py_INCREF (&urj_pyregister_Type);
1100 PyModule_AddObject (m, "register", (PyObject *) &urj_pyregister_Type);
1101
1102 return MODINIT_SUCCESS_VAL (m);
1103 }
1104
1105 /* Local Variables: */
1106 /* mode:c */
1107 /* comment-column:0 */
1108 /* c-basic-offset:4 */
1109 /* space-before-funcall:t */
1110 /* indent-tabs-mode:nil */
1111 /* End: */
1112