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 extern PyObject *UrjtagError;
38 
39 static void
urj_pyr_dealloc(urj_pyregister_t * self)40 urj_pyr_dealloc (urj_pyregister_t *self)
41 {
42     Py_TYPE (self)->tp_free ((PyObject *) self);
43 }
44 
45 static PyObject *
urj_pyr_str(PyObject * s)46 urj_pyr_str (PyObject *s)
47 {
48     urj_pyregister_t *self = (urj_pyregister_t *) s;
49     char buf[200];
50     urj_chain_t *urc = self->urc;
51 
52     if (self->urreg == NULL || self->inst == NULL)
53         snprintf (buf, 200, "<urjtag.register chain=%p invalid>", urc);
54     else
55         snprintf (buf, 200, "<urjtag.register chain=%p reg=%s inst=%s>", urc,
56              self->urreg->name, self->inst->name);
57     return PyUnicode_FromString (buf);
58 }
59 
60 
61 static PyObject *
urj_pyr_get_dr(urj_pyregister_t * self,int in,int string,PyObject * args)62 urj_pyr_get_dr (urj_pyregister_t *self, int in, int string, PyObject *args)
63 {
64     urj_data_register_t *dr = self->urreg;
65     urj_chain_t *urc = self->urc;
66     urj_tap_register_t *r;
67     int lsb = -1;
68     int msb = -1;
69     const char *value_string;
70 
71     if (!PyArg_ParseTuple (args, "|ii", &msb, &lsb))
72         return NULL;
73     if (lsb == -1)
74         lsb = msb;
75     if (!urj_pyc_precheck (urc, UPRC_CBL))
76         return NULL;
77 
78     if (dr == NULL)
79     {
80         PyErr_SetString (UrjtagError,
81                          _("invalid data register object"));
82         return NULL;
83     }
84 
85     if (in)
86         r = dr->in;             /* input buffer for next shift_dr */
87     else
88         r = dr->out;            /* recently captured+scanned-out values */
89 
90     if (msb == -1)
91         value_string = urj_tap_register_get_string (r);
92     else
93         value_string = urj_tap_register_get_string_bit_range (r, msb, lsb);
94     if (value_string == NULL)
95     {
96         PyErr_SetString (UrjtagError,
97                          _("error obtaining tap register value"));
98         return NULL;
99     }
100 
101     if (string)
102         return Py_BuildValue ("s", value_string);
103     else
104         return PyLong_FromString ((char *)value_string, NULL, 2);
105 }
106 
107 static PyObject *
urj_pyr_get_str_dr_out(urj_pyregister_t * self,PyObject * args)108 urj_pyr_get_str_dr_out (urj_pyregister_t *self, PyObject *args)
109 {
110     return urj_pyr_get_dr (self, 0, 1, args);
111 }
112 
113 static PyObject *
urj_pyr_get_str_dr_in(urj_pyregister_t * self,PyObject * args)114 urj_pyr_get_str_dr_in (urj_pyregister_t *self, PyObject *args)
115 {
116     return urj_pyr_get_dr (self, 1, 1, args);
117 }
118 
119 static PyObject *
urj_pyr_get_int_dr_out(urj_pyregister_t * self,PyObject * args)120 urj_pyr_get_int_dr_out (urj_pyregister_t *self, PyObject *args)
121 {
122     return urj_pyr_get_dr (self, 0, 0, args);
123 }
124 
125 static PyObject *
urj_pyr_get_int_dr_in(urj_pyregister_t * self,PyObject * args)126 urj_pyr_get_int_dr_in (urj_pyregister_t *self, PyObject *args)
127 {
128     return urj_pyr_get_dr (self, 1, 0, args);
129 }
130 
131 static PyObject *
urj_pyr_set_dr(urj_pyregister_t * self,int in,PyObject * args)132 urj_pyr_set_dr (urj_pyregister_t *self, int in, PyObject *args)
133 {
134     urj_data_register_t *dr = self->urreg;
135     urj_tap_register_t *r;
136     char *newstr = NULL;
137     uint64_t newval;
138     int lsb = -1;
139     int msb = -1;
140 
141 
142     if (!PyArg_ParseTuple (args, "s|ii", &newstr, &msb, &lsb))
143     {
144         PyErr_Clear ();
145         if (!PyArg_ParseTuple (args, "L|ii", &newval, &msb, &lsb))
146             return NULL;
147     }
148 
149     if (dr == NULL)
150     {
151         PyErr_SetString (UrjtagError,
152                          _("invalid register object"));
153         return NULL;
154     }
155 
156     if (in)
157         r = dr->in;
158     else
159         r = dr->out;
160 
161     if (msb == -1)
162     {
163         if (newstr)
164             return urj_py_chkret (urj_tap_register_set_string (r, newstr));
165         else
166             return urj_py_chkret (urj_tap_register_set_value (r, newval));
167     }
168     else
169     {
170         if (lsb == -1)
171             lsb = msb;
172 
173         if (newstr)
174             return urj_py_chkret (urj_tap_register_set_string_bit_range (r, newstr, msb, lsb));
175         else
176             return urj_py_chkret (urj_tap_register_set_value_bit_range (r, newval, msb, lsb));
177     }
178 }
179 
180 static PyObject *
urj_pyr_set_dr_out(urj_pyregister_t * self,PyObject * args)181 urj_pyr_set_dr_out (urj_pyregister_t *self, PyObject *args)
182 {
183     return urj_pyr_set_dr (self, 0, args);
184 }
185 
186 static PyObject *
urj_pyr_set_dr_in(urj_pyregister_t * self,PyObject * args)187 urj_pyr_set_dr_in (urj_pyregister_t *self, PyObject *args)
188 {
189     return urj_pyr_set_dr (self, 1, args);
190 }
191 
192 static PyObject *
urj_pyr_shift_dr(urj_pyregister_t * self,PyObject * args)193 urj_pyr_shift_dr (urj_pyregister_t *self, PyObject *args)
194 {
195 
196     urj_chain_t *urc = self->urc;
197     int partn = self->part;
198     char *instname = NULL;
199     urj_part_t *part;
200 
201     if (!PyArg_ParseTuple (args, "|s", &instname))
202         return NULL;
203 
204 
205     if (!urj_pyc_precheck (urc, UPRC_CBL))
206         return NULL;
207 
208     if (self->urreg == NULL)
209     {
210         PyErr_SetString (UrjtagError,
211                          _("invalid register object"));
212         return NULL;
213     }
214 
215 
216     urc->active_part = partn;
217     part = urj_tap_chain_active_part (urc);
218     if (part == NULL)
219     {
220         PyErr_SetString (UrjtagError, _("No active part on chain"));
221         return NULL;
222     }
223     if (instname)
224     {
225         urj_part_set_instruction (part, instname);
226     }
227     else
228     {
229         if (!self->inst) {
230             PyErr_SetString (UrjtagError, _("no instruction for data register"));
231             return NULL;
232         }
233         part->active_instruction = self->inst;
234     }
235 
236     return urj_py_chkret (urj_tap_chain_shift_data_registers (urc, 1));
237 }
238 
239 static PyObject *
urj_pyr_shift_ir(urj_pyregister_t * self,PyObject * args)240 urj_pyr_shift_ir (urj_pyregister_t *self,  PyObject *args)
241 {
242     urj_chain_t *urc = self->urc;
243     char *instname = NULL;
244     urj_part_t *part;
245 
246     if (!PyArg_ParseTuple (args, "|s", &instname))
247         return NULL;
248 
249     if (!urj_pyc_precheck (urc, UPRC_CBL))
250         return NULL;
251 
252     urc->active_part = self->part;
253     part = urj_tap_chain_active_part (urc);
254     if (part == NULL)
255     {
256         PyErr_SetString (UrjtagError, _("No active part on chain"));
257         return NULL;
258     }
259     if (instname) {
260         urj_part_set_instruction (part, instname);
261     }
262     else
263     {
264         if (!self->inst)
265         {
266             PyErr_SetString (UrjtagError, _("no instruction for data register"));
267             return NULL;
268         }
269         part->active_instruction = self->inst;
270     }
271 
272     return urj_py_chkret (urj_tap_chain_shift_instructions (urc));
273 }
274 
275 
276 
277 static PyMethodDef urj_pyr_methods[] =
278 {
279     {"get_dr_in", (PyCFunction) urj_pyr_get_int_dr_in, METH_VARARGS,
280      "get bits that will be scanned in on next shift_dr, as integer"},
281     {"get_dr_in_string", (PyCFunction) urj_pyr_get_str_dr_in, METH_VARARGS,
282      "get bits that will be scanned in on next shift_dr, as string"},
283     {"get_dr_out", (PyCFunction) urj_pyr_get_int_dr_out, METH_VARARGS,
284      "retrieve values scanned out from the data registers on the last shift_dr, as integer"},
285     {"get_dr_out_string", (PyCFunction) urj_pyr_get_str_dr_out, METH_VARARGS,
286      "retrieve values scanned out from the data registers on the last shift_dr, as string"},
287 
288     {"set_dr_in", (PyCFunction) urj_pyr_set_dr_in, METH_VARARGS,
289      "set bits that will be scanned in on next shiftdr"},
290     {"set_dr_out", (PyCFunction) urj_pyr_set_dr_out, METH_VARARGS,
291      "set the holding register for values scanned out from the data register"},
292     {"shift_dr", (PyCFunction) urj_pyr_shift_dr, METH_VARARGS,
293      "scan values through the data register"},
294     {"shift_ir", (PyCFunction) urj_pyr_shift_ir, METH_VARARGS,
295      "scan values through the instruction register to select this data regsiter"},
296     {NULL},
297 };
298 
299 
300 PyTypeObject urj_pyregister_Type =
301 {
302     PyVarObject_HEAD_INIT (NULL, 0) "urjtag.register", /* tp_name */
303     sizeof (urj_pyregister_t),             /* tp_basicsize */
304     0,                          /* tp_itemsize */
305     (destructor) urj_pyr_dealloc, /* tp_dealloc */
306     0,                          /* tp_print */
307     0,                          /* tp_getattr */
308     0,                          /* tp_setattr */
309     0,                          /* tp_compare */
310     urj_pyr_str,                /* tp_repr */
311     0,                          /* tp_as_number */
312     0,                          /* tp_as_sequence */
313     0,                          /* tp_as_mapping */
314     0,                          /* tp_hash */
315     0,                          /* tp_call */
316     urj_pyr_str,                /* tp_str */
317     0,                          /* tp_getattro */
318     0,                          /* tp_setattro */
319     0,                          /* tp_as_buffer */
320     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
321     "JTAG register object",     /* tp_doc */
322     0,                          /* tp_traverse */
323     0,                          /* tp_clear */
324     0,                          /* tp_richcompare */
325     0,                          /* tp_weaklistoffset */
326     0,                          /* tp_iter */
327     0,                          /* tp_iternext */
328     urj_pyr_methods,            /* tp_methods */
329     0,                          /* tp_members */
330     0,                          /* tp_getset */
331     0,                          /* tp_base */
332     0,                          /* tp_dict */
333     0,                          /* tp_descr_get */
334     0,                          /* tp_descr_set */
335     0,                          /* tp_dictoffset */
336     0,                          /* tp_init */
337     0,                          /* tp_alloc */
338     0,                          /* tp_new */
339 };
340 
341 
342 /* Local Variables: */
343 /* mode:c */
344 /* comment-column:0 */
345 /* c-basic-offset:4 */
346 /* space-before-funcall:t */
347 /* indent-tabs-mode:nil */
348 /* End: */
349