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