Last month I wrote:
Hello all, I've started on some python bindings for liburjtag. Work in progress is
...
So far only methods for the urjtag.chain class are present, but the basics work for connecting to a ftdi2232 cable, detecting devices, and fiddling with the boundary scan register. The file t_chain.py illustrates some of what works.
Attached is a patch that adds this work to a bindings/python directory in the urjtag source tree, and adds a "--enable-python" to configure.
The patch should be against the current git head, but this is my first such patch using git, so I might have gotten that wrong.
I've tested it with python 3.7 and python 3.1.2. It defaults to building for whichever version of python configure finds with AM_PATH_PYTHON, most likely whichever is called "python" first in the path. On fedora 14, this is python 2.7 in /usr/bin/python.
One can override that by running: PYTHON=python3 ./configure --enable-python Comments welcome... Steve t...@telltronics.org
From a1d519dc74dbaa562ba9b1442ffb389e3b116296 Mon Sep 17 00:00:00 2001 From: Steve Tell <t...@telltronics.org> Date: Fri, 1 Apr 2011 09:24:47 -0400 Subject: [PATCH] Signed-off-by: Steve Tell <t...@telltronics.org> Create python language bindings, tested compatible with python 2.7 and 3.1 add --enable-python option to configure, which enables building python bindings --- urjtag/Makefile.am | 3 +- urjtag/bindings/Makefile.am | 36 ++ urjtag/bindings/python/Makefile.am | 36 ++ urjtag/bindings/python/chain.c | 755 ++++++++++++++++++++++++++++++ urjtag/bindings/python/pycompat23.h | 38 ++ urjtag/bindings/python/setup.py | 12 + urjtag/bindings/python/t_urjtag_chain.py | 91 ++++ urjtag/configure.ac | 25 + urjtag/m4/am-check-python-headers.m4 | 24 + 9 files changed, 1019 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_urjtag_chain.py create mode 100644 urjtag/m4/am-check-python-headers.m4 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..bf3cd49 --- /dev/null +++ b/urjtag/bindings/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 <t...@telltronics.org> 2011 +# + +SUBDIRS = $(PYTHON_SUBDIR) # $(TCL_SUBDIR) + +if BIND_PYTHON +PYTHON_SUBDIR=python +else +PYTHON_SUBDIR= +endif + +#if BIND_TCL +#TCL_SUBDIR=tcl +#else +#TCL_SUBDIR= +#endif diff --git a/urjtag/bindings/python/Makefile.am b/urjtag/bindings/python/Makefile.am new file mode 100644 index 0000000..87f64c2 --- /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 <t...@telltronics.org> 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..1f50229 --- /dev/null +++ b/urjtag/bindings/python/chain.c @@ -0,0 +1,755 @@ + +/* + * $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 written by Steve Tell. + */ +#include <Python.h> +#include "structmember.h" +#include "pycompat23.h" + +#include <urjtag.h> +#include <chain.h> +#include <cmd.h> +#include <assert.h> +#include <sys/mman.h> + +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#endif + +/* missing from urjtag headers */ +extern int urj_cmd_test_cable (urj_chain_t * chain); +extern int urj_cmd_params (char *params[]); + +static PyObject *UrjtagError; + +typedef struct { + PyObject_HEAD urj_chain_t * urchain; +} Chain; + +static void +Chain_dealloc (Chain * self) +{ + printf ("in Chain_dealloc urc=%p\n", 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 (); + } + } + return (PyObject *) self; +} + + +/* methods */ + +static PyObject * +Chain_cable (Chain * self, PyObject * args) +{ + extern int urj_chain_cable (urj_chain_t * chain, char *params[]); + char *cable_params[5] = { NULL, NULL, NULL, NULL, NULL }; + 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|sss", + &cable_params[0], + &cable_params[1], + &cable_params[2], &cable_params[3])) + { + return NULL; + } + if (urj_chain_cable (urc, 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; + } + printf ("Chain_cable: cable=%p %s\n", urc->cable, cable_params[0]); + 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 ()); + + printf ("urj_error %d from %s\n", urj_error_get (), + 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; + } + // printf("_tap_detect: urchain=%p cable=%p\n", urc, urc->cable); + + 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); + // printf("_get_pod_signal(sig=%x result=%x)\n", sig, val); + return Py_BuildValue ("i", val); +} + +// 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 + // TODO: input buffer + // for now: use ascii bitstrings + 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_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 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_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"}, + {"run_svf", (PyCFunction) Chain_run_svf, METH_VARARGS, + "Play a named SVF file; optionally setting stop-on-mismatch and runtest frequency"}, + + {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; + printf ("urjtag.loglevel = %d\n", loglevel); + 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); +} + + +int +urj_chain_cable (urj_chain_t * chain, char *params[]) +{ + urj_cable_t *cable = NULL; + int i; + int j; + int paramc = urj_cmd_params (params); + const urj_param_t **cable_params; + urj_cable_parport_devtype_t devtype = -1; + const char *devname = NULL; + int param_start = 1; + const urj_cable_driver_t *driver; + + /* search cable driver list */ + for (i = 0; urj_tap_cable_drivers[i]; i++) + if (strcasecmp (params[0], urj_tap_cable_drivers[i]->name) == 0) + break; + driver = urj_tap_cable_drivers[i]; + if (!driver) + { + urj_error_set (URJ_ERROR_INVALID, + "unknown cable driver '%s'", params[0]); + return URJ_STATUS_FAIL; + } + + if (driver->device_type == URJ_CABLE_DEVICE_PARPORT) + { + if (paramc < 4) + { + urj_error_set (URJ_ERROR_SYNTAX, + "parallel cable requires >= 4 parameters"); + return URJ_STATUS_FAIL; + } + for (j = 0; j < URJ_CABLE_PARPORT_N_DEVS; j++) + if (strcasecmp (params[1], + urj_cable_parport_devtype_string (j)) == 0) + break; + if (j == URJ_CABLE_PARPORT_N_DEVS) + { + urj_error_set (URJ_ERROR_INVALID, + "unknown parallel port device type '%s'", + params[1]); + return URJ_STATUS_FAIL; + } + + devtype = j; + devname = params[2]; + param_start = 3; + } + + urj_param_init (&cable_params); + for (j = param_start; params[j] != NULL; j++) + if (urj_param_push (&urj_cable_param_list, &cable_params, + params[j]) != URJ_STATUS_OK) + { + urj_param_clear (&cable_params); + return URJ_STATUS_FAIL; + } + + switch (driver->device_type) + { + case URJ_CABLE_DEVICE_PARPORT: + cable = + urj_tap_cable_parport_connect (chain, driver, devtype, devname, + cable_params); + break; + case URJ_CABLE_DEVICE_USB: + cable = urj_tap_cable_usb_connect (chain, driver, cable_params); + break; + case URJ_CABLE_DEVICE_OTHER: + cable = urj_tap_cable_other_connect (chain, driver, cable_params); + break; + } + + urj_param_clear (&cable_params); + + if (cable == NULL) + { + return URJ_STATUS_FAIL; + } + + chain->cable->chain = chain; + return URJ_STATUS_OK; +} + +/* Local Variables: */ +/* mode:c */ +/* comment-column:0 */ +/* c-basic-offset:4 */ +/* space-before-funcall:t */ +/* 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_urjtag_chain.py b/urjtag/bindings/python/t_urjtag_chain.py new file mode 100644 index 0000000..ac95389 --- /dev/null +++ b/urjtag/bindings/python/t_urjtag_chain.py @@ -0,0 +1,91 @@ +#!/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) + +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", 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("USERCODE") +urc.shift_ir() +urc.shift_dr() +drval = urc.get_dr_out() +printf("USERCODE dr 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("FADDR") +urc.shift_ir() +urc.shift_dr() +drval = urc.get_dr_out() +printf("FADDR dr result: %s\n", drval) + +urc.set_instruction("FVFY6") +urc.shift_ir() +urc.shift_dr() +drval = urc.get_dr_out() +printf("FVFY6 dr result: %s\n", drval) + +urc.set_instruction("BYPASS") +urc.shift_ir() + diff --git a/urjtag/configure.ac b/urjtag/configure.ac index d38831b..c3d3a5c 100644 --- a/urjtag/configure.ac +++ b/urjtag/configure.ac @@ -84,6 +84,8 @@ AC_CONFIG_FILES( src/apps/bsdl2jtag/Makefile src/bfin/Makefile po/Makefile.in + bindings/Makefile + bindings/python/Makefile ) AM_MAINTAINER_MODE @@ -355,6 +357,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="no"]) + +if test "$BIND_PYTHON" == "yes"; 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 "$BIND_PYTHON" == "yes"; then + AM_CHECK_PYTHON_HEADERS([],[BIND_PYTHON=no;AC_MSG_NOTICE([python headers not found, disabling python binding])]) +fi +AM_CONDITIONAL([BIND_PYTHON], [test "$BIND_PYTHON" == "yes"]) + +# for future use +#AM_CONDITIONAL([BIND_TCL], false) # check for lex/flex AC_PROG_LEX @@ -745,4 +767,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 ]) + + diff --git a/urjtag/m4/am-check-python-headers.m4 b/urjtag/m4/am-check-python-headers.m4 new file mode 100644 index 0000000..7ec4ed5 --- /dev/null +++ b/urjtag/m4/am-check-python-headers.m4 @@ -0,0 +1,24 @@ +dnl a macro to check for ability to create python extensions +dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) +dnl function also defines PYTHON_INCLUDES +AC_DEFUN([AM_CHECK_PYTHON_HEADERS], +[AC_REQUIRE([AM_PATH_PYTHON]) +AC_MSG_CHECKING(for headers required to compile python extensions) +dnl deduce PYTHON_INCLUDES +py_prefix=`$PYTHON -c 'import sys; sys.stdout.write(sys.prefix+"\n")'` +py_exec_prefix=`$PYTHON -c 'import sys; sys.stdout.write(sys.exec_prefix+"\n")'` +PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" +if test "$py_prefix" != "$py_exec_prefix"; then + PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" +fi +AC_SUBST(PYTHON_INCLUDES) +dnl check if the headers exist: +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" +AC_TRY_CPP([#include <Python.h>],dnl +[AC_MSG_RESULT(found) +$1],dnl +[AC_MSG_RESULT(not found) +$2]) +CPPFLAGS="$save_CPPFLAGS" +]) -- 1.7.4
------------------------------------------------------------------------------ Create and publish websites with WebMatrix Use the most popular FREE web apps or write code yourself; WebMatrix provides all the features you need to develop and publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________ UrJTAG-development mailing list UrJTAG-development@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/urjtag-development