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", &regname, &reglen))
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, &regname))
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, &regname, &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