This is a revised version of my python bindings patch. It assumes that 1/2 from the previous message has been applied to add urj_bus_init() and urj_tap_chain_connect(). ( Isn't "git rebase -i" handy? )


Subject: [PATCH 2/2] Add bindings for python that support many of the chain operations includes my work and additions by Jonathan Stroud to support additional methods needed for burning flash devices.
also formatting and other cleanups from reviews.

---
 urjtag/Makefile.am                       |    3 +-
 urjtag/bindings/Makefile.am              |   28 +
 urjtag/bindings/python/Makefile.am       |   36 ++
 urjtag/bindings/python/chain.c           |  991 ++++++++++++++++++++++++++++++
 urjtag/bindings/python/pycompat23.h      |   38 ++
 urjtag/bindings/python/setup.py          |   12 +
 urjtag/bindings/python/t_srst.py         |   49 ++
 urjtag/bindings/python/t_urjtag_chain.py |   81 +++
 urjtag/configure.ac                      |   25 +
 9 files changed, 1262 insertions(+), 1 deletions(-)
 create mode 100644 urjtag/bindings/Makefile.am
 create mode 100644 urjtag/bindings/python/Makefile.am
 create mode 100644 urjtag/bindings/python/chain.c
 create mode 100644 urjtag/bindings/python/pycompat23.h
 create mode 100644 urjtag/bindings/python/setup.py
 create mode 100644 urjtag/bindings/python/t_srst.py
 create mode 100644 urjtag/bindings/python/t_urjtag_chain.py
From 7c533c482d28d31bb3b90620c51892d2d060a5d2 Mon Sep 17 00:00:00 2001
From: Steve Tell <[email protected]>
Date: Thu, 16 Jun 2011 21:16:36 -0400
Subject: [PATCH 2/2] Add bindings for python that support many of the chain 
operations
 includes my work and additions by Jonathan Stroud to support additional methods
 needed for burning flash devices.
 also formatting and other cleanups from reviews.

---
 urjtag/Makefile.am                       |    3 +-
 urjtag/bindings/Makefile.am              |   28 +
 urjtag/bindings/python/Makefile.am       |   36 ++
 urjtag/bindings/python/chain.c           |  991 ++++++++++++++++++++++++++++++
 urjtag/bindings/python/pycompat23.h      |   38 ++
 urjtag/bindings/python/setup.py          |   12 +
 urjtag/bindings/python/t_srst.py         |   49 ++
 urjtag/bindings/python/t_urjtag_chain.py |   81 +++
 urjtag/configure.ac                      |   25 +
 9 files changed, 1262 insertions(+), 1 deletions(-)
 create mode 100644 urjtag/bindings/Makefile.am
 create mode 100644 urjtag/bindings/python/Makefile.am
 create mode 100644 urjtag/bindings/python/chain.c
 create mode 100644 urjtag/bindings/python/pycompat23.h
 create mode 100644 urjtag/bindings/python/setup.py
 create mode 100644 urjtag/bindings/python/t_srst.py
 create mode 100644 urjtag/bindings/python/t_urjtag_chain.py

diff --git a/urjtag/Makefile.am b/urjtag/Makefile.am
index 7998707..e7c0200 100644
--- a/urjtag/Makefile.am
+++ b/urjtag/Makefile.am
@@ -28,7 +28,8 @@ SUBDIRS = \
        include/urjtag \
        data \
        src \
-       po
+       po \
+       bindings
 
 if ENABLE_APPS
 SUBDIRS += \
diff --git a/urjtag/bindings/Makefile.am b/urjtag/bindings/Makefile.am
new file mode 100644
index 0000000..486ff26
--- /dev/null
+++ b/urjtag/bindings/Makefile.am
@@ -0,0 +1,28 @@
+#
+# $Id$
+#
+# Copyright (C) 2002,2011 ETC s.r.o.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Written by Steve Tell <[email protected]> 2011
+#
+
+SUBDIRS =
+
+if BIND_PYTHON
+SUBDIRS += python
+endif
diff --git a/urjtag/bindings/python/Makefile.am 
b/urjtag/bindings/python/Makefile.am
new file mode 100644
index 0000000..1968c35
--- /dev/null
+++ b/urjtag/bindings/python/Makefile.am
@@ -0,0 +1,36 @@
+#
+# $Id$
+#
+# Copyright (C) 2002,2011 ETC s.r.o.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Written by Steve Tell <[email protected]> 2011
+#
+
+EXTRA_DIST =  setup.py chain.c pycompat23.h t_urjtag_chain.py
+
+all-local: build
+
+build: chain.c
+       -{ $(PYTHON) setup.py build && touch build; } || { $(RM) -r build; exit 
1; }
+
+install-data-local:
+       $(PYTHON) setup.py install --prefix=$(DESTDIR)$(prefix)
+
+clean-local:
+       -$(RM) -r build
+
diff --git a/urjtag/bindings/python/chain.c b/urjtag/bindings/python/chain.c
new file mode 100644
index 0000000..a6fce87
--- /dev/null
+++ b/urjtag/bindings/python/chain.c
@@ -0,0 +1,991 @@
+/* 
+ * $Id$
+ *
+ * Copyright (C) 2011 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Python bindings for urjtag intially written by Steve Tell.
+ * Additional methods by Jonathan Stroud.
+ *
+ */
+#include <Python.h>
+#include "structmember.h"
+#include "pycompat23.h"
+
+#include <urjtag.h>
+#include <chain.h>
+#include <cmd.h>
+#include <assert.h>
+
+static PyObject *UrjtagError;
+
+typedef struct
+{
+    PyObject_HEAD urj_chain_t *urchain;
+} Chain;
+
+static void
+Chain_dealloc (Chain *self)
+{
+    urj_tap_chain_free (self->urchain);
+    Py_TYPE (self)->tp_free ((PyObject *) self);
+}
+
+static PyObject *
+Chain_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Chain *self;
+
+    self = (Chain *) type->tp_alloc (type, 0);
+    if (self != NULL)
+    {
+        self->urchain = urj_tap_chain_alloc ();
+        if (self->urchain == NULL)
+        {
+            Py_DECREF (self);
+            return PyErr_NoMemory ();
+        }
+        self->urchain->main_part = 0;
+    }
+    return (PyObject *) self;
+}
+
+
+/* methods */
+
+static PyObject *
+Chain_cable (Chain *self, PyObject *args)
+{
+    char *cable_params[5] = { NULL, NULL, NULL, NULL, NULL };
+    urj_chain_t *urc = self->urchain;
+    char *drivername;
+
+    assert (self->urchain == g_tstptr);
+    if (urc == NULL)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (!PyArg_ParseTuple (args, "s|ssss",
+                           &drivername, 
+                           &cable_params[0],
+                           &cable_params[1],
+                           &cable_params[2], &cable_params[3]))
+    {
+        return NULL;
+    }
+    if (urj_tap_chain_connect (urc, drivername, cable_params) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in cable()");
+
+        }
+        return NULL;
+    }
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_disconnect (Chain *self)
+{
+    urj_chain_t *urc = self->urchain;
+    if (urc == NULL)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    urj_tap_chain_disconnect (urc);
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_test_cable (Chain *self)
+{
+    urj_chain_t *urc = self->urchain;
+    if (urc == NULL)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in test_cable()");
+        }
+        return NULL;
+    }
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_tap_detect (Chain *self)
+{
+    urj_chain_t *urc = self->urchain;
+    if (urc == NULL)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+
+    if (urj_tap_detect (urc) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in detect()");
+        }
+        return NULL;
+    }
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_len (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (urc->parts == NULL)
+    {
+        PyErr_SetString (PyExc_RuntimeError,
+                         "detect not called on this chain");
+        return NULL;
+    }
+
+    return Py_BuildValue ("i", urc->parts->len);
+}
+
+static PyObject *
+Chain_partid (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    int partno;
+    if (!PyArg_ParseTuple (args, "i", &partno))
+        return NULL;
+
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (urc->parts == NULL)
+    {
+        PyErr_SetString (PyExc_RuntimeError,
+                         "detect not called on this chain");
+        return NULL;
+    }
+    if (partno >= urc->parts->len)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "part number out of range");
+        return NULL;
+    }
+    else
+    {
+        urj_part_t *p;
+        uint32_t id;
+
+        p = urc->parts->parts[partno];
+        id = urj_tap_register_get_value (p->id);
+        return Py_BuildValue ("i", id);
+    }
+}
+
+static PyObject *
+Chain_reset (Chain *self)
+{
+    urj_chain_t *urc = self->urchain;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+
+    if (urj_tap_reset_bypass (urc) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in dereset_bypass()");
+        }
+        return NULL;
+    }
+    urj_tap_chain_flush (urc);
+    return Py_BuildValue ("");
+}
+
+
+static PyObject *
+Chain_set_trst (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    int trstval;
+    if (!PyArg_ParseTuple (args, "i", &trstval))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    urj_tap_chain_set_trst (urc, trstval);
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_get_trst (Chain *self)
+{
+    int trstval;
+    urj_chain_t *urc = self->urchain;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+
+    trstval = urj_tap_chain_get_trst (urc);
+    return Py_BuildValue ("i", trstval);
+}
+
+static PyObject *
+Chain_set_pod_signal (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    uint32_t mask, val, oldval;
+    if (!PyArg_ParseTuple (args, "ii", &mask, &val))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    oldval = urj_tap_chain_set_pod_signal (urc, mask, val);
+    return Py_BuildValue ("i", oldval); // None
+}
+
+static PyObject *
+Chain_get_pod_signal (Chain *self, PyObject *args)
+{
+    uint32_t sig;
+    uint32_t val;
+    urj_chain_t *urc = self->urchain;
+    if (!PyArg_ParseTuple (args, "i", &sig))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+
+    val = urj_tap_chain_get_pod_signal (urc, sig);
+    return Py_BuildValue ("i", val);
+}
+
+static PyObject *
+Chain_set_frequency (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    uint32_t freq;
+    if (!PyArg_ParseTuple (args, "i", &freq))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    urj_tap_cable_set_frequency (urc->cable, freq);
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_get_frequency (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    unsigned long freq;
+    freq = urj_tap_cable_get_frequency (urc->cable);
+
+    return Py_BuildValue ("i", (uint32_t) freq);
+}
+
+// set instruction for the active part
+static PyObject *
+Chain_set_instruction (Chain *self, PyObject *args)
+{
+    char *instname;
+    urj_part_t *part;
+    urj_chain_t *urc = self->urchain;
+    if (!PyArg_ParseTuple (args, "s", &instname))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    part = urj_tap_chain_active_part (urc);
+    if (part == NULL)
+    {
+        PyErr_SetString (UrjtagError, "No active part on chain");
+        return NULL;
+    }
+    urj_part_set_instruction (part, instname);
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_shift_ir (Chain *self)
+{
+    urj_chain_t *urc = self->urchain;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+        PyErr_SetString (UrjtagError, "cable() has not been called");
+        return NULL;
+    }
+
+    if (urj_tap_chain_shift_instructions (urc) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in deshift_ir");
+        }
+        return NULL;
+    }
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_shift_dr (Chain *self)
+{
+    urj_chain_t *urc = self->urchain;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+        PyErr_SetString (UrjtagError, "cable() has not been called");
+        return NULL;
+    }
+    // TODO: need a way to not capture the TDO output
+    if (urj_tap_chain_shift_data_registers (urc, 1) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in deshift_dr");
+        }
+        return NULL;
+    }
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_get_dr (Chain *self, int in)
+{
+    urj_chain_t *urc = self->urchain;
+    urj_part_t *part;
+    urj_tap_register_t *r;
+    urj_data_register_t *dr;
+    urj_part_instruction_t *active_ir;
+
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+        PyErr_SetString (UrjtagError, "cable() has not been called");
+        return NULL;
+    }
+    part = urj_tap_chain_active_part (urc);
+    if (part == NULL)
+    {
+        PyErr_SetString (UrjtagError, "no active part in chain");
+        return NULL;
+    }
+    active_ir = part->active_instruction;
+    if (active_ir == NULL)
+    {
+        PyErr_SetString (UrjtagError, "part without active instruction");
+        return NULL;
+    }
+    dr = active_ir->data_register;
+    if (dr == NULL)
+    {
+        PyErr_SetString (UrjtagError,
+                         "instruction without active data register");
+        return NULL;
+    }
+
+    if (in)
+        r = dr->in;             // input buffer for next shift_dr
+    else
+        r = dr->out;            // recently captured+scanned-out values
+    return Py_BuildValue ("s", urj_tap_register_get_string (r));
+}
+
+static PyObject *
+Chain_get_dr_out (Chain *self)
+{
+    return Chain_get_dr (self, 0);
+}
+
+static PyObject *
+Chain_get_dr_in (Chain *self)
+{
+    return Chain_get_dr (self, 1);
+}
+
+
+static PyObject *
+Chain_set_dr (Chain *self, int in, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    urj_part_t *part;
+    urj_tap_register_t *r;
+    urj_data_register_t *dr;
+    urj_part_instruction_t *active_ir;
+    char *newstr;
+
+    if (!PyArg_ParseTuple (args, "s", &newstr))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+        PyErr_SetString (UrjtagError, "cable() has not been called");
+        return NULL;
+    }
+    part = urj_tap_chain_active_part (urc);
+    if (part == NULL)
+    {
+        PyErr_SetString (UrjtagError, "no active part in chain");
+        return NULL;
+    }
+    active_ir = part->active_instruction;
+    if (active_ir == NULL)
+    {
+        PyErr_SetString (UrjtagError, "part without active instruction");
+        return NULL;
+    }
+    dr = active_ir->data_register;
+    if (dr == NULL)
+    {
+        PyErr_SetString (UrjtagError,
+                         "instruction without active data register");
+        return NULL;
+    }
+
+    if (in)
+        r = dr->in;             // input buffer for next shift_dr
+    else
+        r = dr->out;            // recently captured+scanned-out values
+
+    if(urj_tap_register_set_string(r, newstr) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in 
urj_tap_register_set_string");
+        }
+        return NULL;
+    }
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_set_dr_out (Chain *self, PyObject *args)
+{
+    return Chain_set_dr (self, 0, args);
+}
+
+static PyObject *
+Chain_set_dr_in (Chain *self, PyObject *args)
+{
+    return Chain_set_dr (self, 1, args);
+}
+
+static PyObject *
+Chain_run_svf (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    char *fname;
+    int stop = 0;
+    unsigned long ref_freq = 0;
+    FILE *svf_file;
+
+    if (!PyArg_ParseTuple (args, "s|iI", &fname, &stop, &ref_freq))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    svf_file = fopen (fname, "rb");
+    if (!svf_file)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "error opening svf file"); // 
TODO: 
+        // fix 
+        // error 
+        // type
+        return NULL;
+    }
+    if (urj_svf_run (urc, svf_file, stop, ref_freq) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in desvf_run");
+        }
+        return NULL;
+    }
+    fclose (svf_file);
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_addpart (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    long unsigned len;
+
+    if (!PyArg_ParseTuple (args, "i", &len))
+        return NULL;
+
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+        return NULL;
+
+    if (urj_tap_manual_add (urc, len) == -1)
+        return NULL;
+
+    // @@@@ RFHH this cannot be
+    if (urc->parts == NULL)
+        return NULL;
+
+    // @@@@ RFHH this cannot be
+    if (urc->parts->len == 0)
+    {
+        urj_part_parts_free (urc->parts);
+        self->urchain->parts = NULL;
+        return NULL;
+    }
+
+    urj_part_parts_set_instruction (urc->parts, "BYPASS");
+    urj_tap_chain_shift_instructions (urc);
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_setpart (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    int part;
+    if (!PyArg_ParseTuple (args, "i", &part))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+    urc->active_part = part;
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_initbus (Chain *self, PyObject *args)
+{
+    char *bus_params[5] = { NULL, NULL, NULL, NULL, NULL };
+    char *drivername;
+    urj_chain_t *urc = self->urchain;
+
+    assert (self->urchain == g_tstptr);
+    if (urc == NULL)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+
+    if (!PyArg_ParseTuple (args, "s|ssss",
+                           &drivername,
+                           &bus_params[0], &bus_params[1], &bus_params[2],
+                           &bus_params[3]))
+    {
+        return NULL;
+    }
+    if (urj_bus_init (urc, drivername, bus_params) != URJ_STATUS_OK)
+    {
+        if (urj_error_get ())
+        {
+            PyErr_SetString (UrjtagError, urj_error_describe ());
+            urj_error_reset ();
+        }
+        else
+        {
+            PyErr_SetString (UrjtagError,
+                             "unknown urjtag error in urj_bus_init");
+        }
+        return NULL;
+    }
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_detectflash (Chain *self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    int adr;
+    if (!PyArg_ParseTuple (args, "i", &adr))
+        return NULL;
+    if (!urc)
+    {
+        PyErr_SetString (PyExc_RuntimeError, "null chain");
+        return NULL;
+    }
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus missing");
+        return NULL;
+    }
+
+    return Py_BuildValue ("i",
+                          urj_flash_detectflash (URJ_LOG_LEVEL_NORMAL,
+                                                 urj_bus, adr));
+}
+
+static PyObject *
+Chain_peek (Chain *self, PyObject *args)
+{
+    long unsigned adr;
+    uint32_t val;
+    urj_bus_area_t area;
+
+    if (!PyArg_ParseTuple (args, "i", &adr))
+        return NULL;
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus missing");
+        return NULL;
+    }
+    if (!urj_bus->driver)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus driver missing");
+        return NULL;
+    }
+
+    URJ_BUS_PREPARE (urj_bus);
+    URJ_BUS_AREA (urj_bus, adr, &area);
+    val = URJ_BUS_READ (urj_bus, adr);
+
+    switch (area.width)
+    {
+    case 8:
+        val &= 0xff;
+        break;
+    case 16:
+        val &= 0xffff;
+        break;
+    default:
+        break;
+    }
+    return Py_BuildValue ("i", val);    // None
+}
+
+static PyObject *
+Chain_poke (Chain *self, PyObject *args)
+{
+    long unsigned adr, val;
+    urj_bus_area_t area;
+
+    if (!PyArg_ParseTuple (args, "ii", &adr, &val))
+        return NULL;
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus missing");
+        return NULL;
+    }
+    if (!urj_bus->driver)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus driver missing");
+        return NULL;
+    }
+
+    URJ_BUS_PREPARE (urj_bus);
+
+    URJ_BUS_AREA (urj_bus, adr, &area);
+    URJ_BUS_WRITE (urj_bus, adr, val);
+    return Py_BuildValue ("");  // None
+}
+
+static PyObject *
+Chain_flashmem (Chain *self, PyObject *args)
+{
+    int msbin;
+    int noverify = 0;
+    long unsigned adr = 0;
+    FILE *f;
+    char *params[2] = { NULL, NULL };
+    int r;
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus driver missing");
+        return NULL;
+    }
+
+    if (!PyArg_ParseTuple
+        (args, "ss|i", &params[0], &params[1], &noverify))
+        return NULL;
+
+    msbin = strcasecmp ("msbin", params[0]) == 0;
+    if (!msbin && urj_cmd_get_number (params[0], &adr) != URJ_STATUS_OK)
+        return NULL;
+
+    f = fopen (params[1], "rb");
+    if (!f)
+    {
+        urj_error_IO_set ("Unable to open file `%s'", params[2]);
+        return NULL;
+    }
+
+    if (msbin)
+        r = urj_flashmsbin (urj_bus, f, noverify);
+    else
+        r = urj_flashmem (urj_bus, f, adr, noverify);
+
+    fclose (f);
+    return Py_BuildValue ("i", r);  // None
+}
+
+static PyMethodDef Chain_methods[] = {
+    {"cable", (PyCFunction) Chain_cable, METH_VARARGS,
+     "Connect to the jtag hardware cable of the specified name and type."},
+    {"test_cable", (PyCFunction) Chain_test_cable, METH_NOARGS,
+     "check that the jtag cable is connected to a valid chain"},
+    {"disconnect", (PyCFunction) Chain_disconnect, METH_NOARGS,
+     "Disconnect from the jtag hardware cable"},
+    {"tap_detect", (PyCFunction) Chain_tap_detect, METH_NOARGS,
+     "Identify the chips on the chain"},
+    {"len", (PyCFunction) Chain_len, METH_NOARGS,
+     "Return the length of the TAP chain"},
+    {"reset", (PyCFunction) Chain_reset, METH_NOARGS,
+     "Perform jtag reset using TMS"},
+    {"partid", (PyCFunction) Chain_partid, METH_VARARGS,
+     "Return the IDCODE for the indicated part number in the chain"},
+    {"set_trst", (PyCFunction) Chain_set_trst, METH_VARARGS,
+     "set the TRST output of the cable"},
+    {"get_trst", (PyCFunction) Chain_get_trst, METH_NOARGS,
+     "get the current value of the TRST output of the cable"},
+    {"set_pod_signal", (PyCFunction) Chain_set_pod_signal, METH_VARARGS,
+     "set an auxiliary pod signal"},
+    {"get_pod_signal", (PyCFunction) Chain_get_pod_signal, METH_VARARGS,
+     "get the current value of an auxiliary pod signal"},
+    {"set_frequency", (PyCFunction) Chain_set_frequency, METH_VARARGS,
+     "Change the TCK frequency to be at most the specified value in Hz"},
+    {"get_frequency", (PyCFunction) Chain_get_frequency, METH_NOARGS,
+     "get the current TCK frequency"},
+    {"set_instruction", (PyCFunction) Chain_set_instruction, METH_VARARGS,
+     "Set values in the instruction register holding buffer"},
+    {"shift_ir", (PyCFunction) Chain_shift_ir, METH_NOARGS,
+     "scan values through the instruction register"},
+    {"shift_dr", (PyCFunction) Chain_shift_dr, METH_NOARGS,
+     "scan values through the data register"},
+    {"get_dr_in", (PyCFunction) Chain_get_dr_in, METH_NOARGS,
+     "get bits that will be scanned in on next shiftdr"},
+    {"get_dr_out", (PyCFunction) Chain_get_dr_out, METH_NOARGS,
+     "retrieve values scanned out from the data registers"},
+    {"set_dr_in", (PyCFunction) Chain_set_dr_in, METH_VARARGS,
+     "set bits that will be scanned in on next shiftdr"},
+    {"set_dr_out", (PyCFunction) Chain_set_dr_out, METH_VARARGS,
+     "set the holding register for values scanned out from the data 
registers"},
+    {"run_svf", (PyCFunction) Chain_run_svf, METH_VARARGS,
+     "Play a named SVF file; optionally setting stop-on-mismatch and runtest 
frequency"},
+    {"addpart", (PyCFunction) Chain_addpart, METH_VARARGS,
+     "manually adds parts on the JTAG chain"},
+    {"part", (PyCFunction) Chain_setpart, METH_VARARGS,
+     "change active part for current JTAG chain"},
+    {"initbus", (PyCFunction) Chain_initbus, METH_VARARGS,
+     "initialize bus driver for active part"},
+    {"detectflash", (PyCFunction) Chain_detectflash, METH_VARARGS,
+     "Detect parameters of flash chips attached to a part"},
+    {"peek", (PyCFunction) Chain_peek, METH_VARARGS,
+     "read a single word"},
+    {"poke", (PyCFunction) Chain_poke, METH_VARARGS,
+     "write a single word"},
+    {"flashmem", (PyCFunction) Chain_flashmem, METH_VARARGS,
+     "burn flash memory with data from a file"},
+    {NULL}                      /* Sentinel */
+};
+
+static PyTypeObject ChainType = {
+    //    PyObject_HEAD_INIT (NULL) 0,  /* ob_size */
+    PyVarObject_HEAD_INIT (NULL, 0) "urjtag.chain", /* tp_name */
+    sizeof (Chain),             /* tp_basicsize */
+    0,                          /* tp_itemsize */
+    (destructor) Chain_dealloc, /* tp_dealloc */
+    0,                          /* tp_print */
+    0,                          /* tp_getattr */
+    0,                          /* tp_setattr */
+    0,                          /* tp_compare */
+    0,                          /* tp_repr */
+    0,                          /* tp_as_number */
+    0,                          /* tp_as_sequence */
+    0,                          /* tp_as_mapping */
+    0,                          /* tp_hash */
+    0,                          /* tp_call */
+    0,                          /* tp_str */
+    0,                          /* tp_getattro */
+    0,                          /* tp_setattro */
+    0,                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
+    "JTAG chain objects",       /* tp_doc */
+    0,                          /* tp_traverse */
+    0,                          /* tp_clear */
+    0,                          /* tp_richcompare */
+    0,                          /* tp_weaklistoffset */
+    0,                          /* tp_iter */
+    0,                          /* tp_iternext */
+    Chain_methods,              /* tp_methods */
+    0,                          /* tp_members */
+    0,                          /* tp_getset */
+    0,                          /* tp_base */
+    0,                          /* tp_dict */
+    0,                          /* tp_descr_get */
+    0,                          /* tp_descr_set */
+    0,                          /* tp_dictoffset */
+    0,                          /* tp_init */
+    0,                          /* tp_alloc */
+    Chain_new,                  /* tp_new */
+};
+
+/************************************************************************
+ * module methods that are not part of any type 
+ */
+
+static PyObject *
+urjtag_loglevel (PyObject *self, PyObject *args)
+{
+    int loglevel;               // TODO: accept string and map to the
+    // enum.
+    if (!PyArg_ParseTuple (args, "i", &loglevel))
+        return NULL;
+    urj_log_state.level = loglevel;
+    return Py_BuildValue ("");  // None
+}
+
+static PyMethodDef module_methods[] = {
+    {"loglevel", urjtag_loglevel, METH_VARARGS,
+     "Set log level of the urjtag library"},
+    {NULL}                      /* Sentinel */
+};
+
+static struct PyModuleDef chain_moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "urjtag",
+    "Python extension module for urjtag",
+    -1,
+    module_methods,
+};
+
+MODINIT_DECL (urjtag)
+{
+    PyObject *m;
+
+    if (PyType_Ready (&ChainType) < 0)
+        return MODINIT_ERROR_VAL;
+
+    m = PyModule_Create (&chain_moduledef);
+
+    if (m == NULL)
+        return MODINIT_ERROR_VAL;
+
+    UrjtagError = PyErr_NewException ("urjtag.error", NULL, NULL);
+    Py_INCREF (UrjtagError);
+    PyModule_AddObject (m, "error", UrjtagError);
+
+
+    Py_INCREF (&ChainType);
+    PyModule_AddObject (m, "chain", (PyObject *) & ChainType);
+
+    return MODINIT_SUCCESS_VAL (m);
+}
+
+/* Local Variables: */
+/* mode:c */
+/* comment-column:0 */
+/* c-basic-offset:4 */
+/* space-before-funcall:t */
+/* indent-tabs-mode:nil */
+/* End: */
diff --git a/urjtag/bindings/python/pycompat23.h 
b/urjtag/bindings/python/pycompat23.h
new file mode 100644
index 0000000..35f322f
--- /dev/null
+++ b/urjtag/bindings/python/pycompat23.h
@@ -0,0 +1,38 @@
+/*
+ * some compatibility macros for python 2  / python 3
+ * by Steve Tell
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ */
+
+#if PY_MAJOR_VERSION >= 3
+
+#define MODINIT_ERROR_VAL NULL
+#define MODINIT_SUCCESS_VAL(val) val
+#define MODINIT_DECL(name) PyMODINIT_FUNC PyInit_##name(void)
+
+#else  /* assume python 2 */
+
+#ifndef PyMODINIT_FUNC
+#define PyMODINIT_FUNC void
+#endif
+
+#define MODINIT_ERROR_VAL
+#define MODINIT_SUCCESS_VAL(val)
+#define MODINIT_DECL(name) PyMODINIT_FUNC init##name(void)
+
+struct PyModuleDef {
+    int dc1;
+    const char *name;
+    const char *doc;
+    int dc2;
+    PyMethodDef *methods;
+};
+#define PyModuleDef_HEAD_INIT 0
+#define PyModule_Create(dp) Py_InitModule3((dp)->name, (dp)->methods, 
(dp)->doc)
+
+#endif
diff --git a/urjtag/bindings/python/setup.py b/urjtag/bindings/python/setup.py
new file mode 100644
index 0000000..e8fadc5
--- /dev/null
+++ b/urjtag/bindings/python/setup.py
@@ -0,0 +1,12 @@
+# python extension setup script for urjtag 
+
+from distutils.core import setup, Extension
+setup(name="urjtag", 
+      version="1.0",
+      description="urJtag Python Bindings",
+      ext_modules=[
+        Extension("urjtag", ["chain.c"],
+                  include_dirs=['../../include/urjtag'],
+                  library_dirs=['../../src/.libs'],
+                  libraries=['urjtag'])
+         ])
diff --git a/urjtag/bindings/python/t_srst.py b/urjtag/bindings/python/t_srst.py
new file mode 100644
index 0000000..5f86950
--- /dev/null
+++ b/urjtag/bindings/python/t_srst.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+# works in both python 2 and 3
+def printf(format, *args):
+     """Format args with the first argument as format string, and print.
+     If the format is not a string, it is converted to one with str.
+     You must use printf('%s', x) instead of printf(x) if x might
+     contain % or backslash characters."""
+     sys.stdout.write(str(format) % args)
+
+import sys
+sys.path.append( "." )
+
+import urjtag
+
+#urjtag.loglevel(0) # ALL
+
+urc = urjtag.chain()
+printf("%s\n", urc);
+
+urc.cable("JTAGKey")
+printf("urc.cable done %s\n", urc)
+
+urc.test_cable()
+printf("urc.test_cable done\n")
+
+# trst = urc.get_trst()
+# printf("TRST=%d\n", trst)
+# urc.set_trst(0)
+# trst = urc.get_trst()
+# printf( "TRST set 0 -> %d\n", trst)
+
+# urc.set_trst(1)
+# trst = urc.get_trst()
+# printf("TRST set 1 -> %d\n", trst)
+
+srstbit = 0x10
+srstval = urc.get_pod_signal(srstbit)
+printf( "srstval -> %s\n", srstval);
+
+urc.set_pod_signal(srstbit, 0)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 0 -> %s\n", srstval)
+urc.set_pod_signal(srstbit, 1)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 1 -> %s\n", srstval)
+       
+
+
diff --git a/urjtag/bindings/python/t_urjtag_chain.py 
b/urjtag/bindings/python/t_urjtag_chain.py
new file mode 100644
index 0000000..d0eaf61
--- /dev/null
+++ b/urjtag/bindings/python/t_urjtag_chain.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+
+#
+# A general test and demonstration of several urjtag operations from python.
+#
+
+# works in both python 2 and 3
+def printf(format, *args):
+     """Format args with the first argument as format string, and print.
+     If the format is not a string, it is converted to one with str.
+     You must use printf('%s', x) instead of printf(x) if x might
+     contain % or backslash characters."""
+     sys.stdout.write(str(format) % args)
+
+import sys
+sys.path.append( "." )
+
+import urjtag
+
+#urjtag.loglevel(0) # ALL
+
+urc = urjtag.chain()
+printf("%s\n", urc);
+
+urc.cable("JTAGKey")
+printf("urc.cable done %s\n", urc)
+
+urc.test_cable()
+printf("urc.test_cable done\n")
+
+f = urc.get_frequency()
+printf("frequency was %d Hz\n", f)
+urc.set_frequency(10000)
+f = urc.get_frequency()
+printf("frequency readback = %d Hz\n", f)
+
+trst = urc.get_trst()
+printf("TRST=%d\n", trst)
+urc.set_trst(0)
+trst = urc.get_trst()
+printf( "TRST set 0 -> %d\n", trst)
+urc.set_trst(1)
+trst = urc.get_trst()
+printf("TRST set 1 -> %d\n", trst)
+
+urc.reset();
+
+urc.tap_detect()
+printf("urc.detect done\n")
+printf("chainlength=%d\n", urc.len())
+
+printf("id[0]=%08x\n", urc.partid(0) );
+
+srstbit = 0x10
+srstval = urc.get_pod_signal(srstbit)
+printf( "srstval -> %s\n", srstval);
+
+urc.set_pod_signal(srstbit, 0)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 0 -> %s\n", srstval)
+urc.set_pod_signal(srstbit, 1)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 1 -> %s\n", srstval)
+       
+urc.set_instruction("SAMPLE/PRELOAD")
+urc.shift_ir()
+drval = urc.get_dr_in()
+printf("BSR dr_in result: %s\n", drval)
+urc.shift_dr()
+drval = urc.get_dr_out()
+printf("BSR dr_out result: %s\n", drval)
+
+urc.set_instruction("IDCODE")
+urc.shift_ir()
+urc.shift_dr()
+drval = urc.get_dr_out()
+printf("IDREG dr result: %s\n", drval)
+
+urc.set_instruction("BYPASS")
+urc.shift_ir()
+
diff --git a/urjtag/configure.ac b/urjtag/configure.ac
index 52d5d4c..d6bfbc7 100644
--- a/urjtag/configure.ac
+++ b/urjtag/configure.ac
@@ -86,6 +86,8 @@ AC_CONFIG_FILES(
        src/apps/bsdl2jtag/Makefile
        src/bfin/Makefile
        po/Makefile.in
+       bindings/Makefile
+       bindings/python/Makefile
 )
 
 AM_MAINTAINER_MODE
@@ -358,6 +360,26 @@ AS_IF([test "x$enable_apps" = xyes], [
   AM_CONDITIONAL(ENABLE_APPS, false)
 ])
 
+AC_ARG_ENABLE([python], 
+   [AS_HELP_STRING([--enable-python], [build python language bindings for 
liburjtag])],     
+ [BIND_PYTHON="yes"],[BIND_PYTHON="$enableval"])
+
+if test "x$BIND_PYTHON" = "xyes"; then
+        AM_PATH_PYTHON()
+        PYTHON_MAJOR_VERSION=$(echo $PYTHON_VERSION | cut -d. -f1 )
+        PYTHON_MINOR_VERSION=$(echo $PYTHON_VERSION | cut -d. -f2 )
+        if (( $PYTHON_MAJOR_VERSION < 2 )); then
+                AC_MSG_WARN([python version less than 2.0, disabling python 
binding])
+                BIND_PYTHON="no"
+        fi
+fi
+if test "x$BIND_PYTHON" = "xyes"; then
+   AM_CHECK_PYTHON_HEADERS([],[BIND_PYTHON=no;AC_MSG_NOTICE([python headers 
not found, disabling python binding])])
+fi
+AM_CONDITIONAL([BIND_PYTHON], [test "x$BIND_PYTHON" = "xyes"])
+
+# for future use
+#AM_CONDITIONAL([BIND_TCL], false)
 
 # check for lex/flex
 AC_PROG_LEX
@@ -748,4 +770,7 @@ jtag is now configured for
   Bus drivers          : $enabled_bus_drivers
   Cable drivers        : $enabled_cable_drivers
   Lowlevel drivers     : $enabled_lowlevel_drivers
+  Python binding       : $BIND_PYTHON
 ])
+
+
-- 
1.7.4

------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a 
definitive record of customers, application performance, security 
threats, fraudulent activity and more. Splunk takes this data and makes 
sense of it. Business sense. IT sense. Common sense.. 
http://p.sf.net/sfu/splunk-d2d-c1
_______________________________________________
UrJTAG-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/urjtag-development

Reply via email to