/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pywrap/pcipywrap.c

  • Committer: Suren A. Chilingaryan
  • Date: 2016-02-23 06:20:33 UTC
  • mfrom: (346.1.18 pcitool)
  • Revision ID: csa@suren.me-20160223062033-mz8qkpm1a2oioveb
Merge Python scripting support from Vasiliy Chernov

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "pcipywrap.h"
 
2
 
 
3
char* full_log = NULL;
 
4
 
 
5
/*!
 
6
 * \brief Wraping for vsnprintf function, that saves string to char*
 
7
 * \return saved from vsnprintf string
 
8
 */
 
9
char* vmake_str(const char* msg, va_list vl)
 
10
{
 
11
    char *buf;
 
12
    size_t sz;
 
13
 
 
14
    va_list vl_copy;
 
15
    va_copy(vl_copy, vl);
 
16
 
 
17
    sz = vsnprintf(NULL, 0, msg, vl);
 
18
    buf = (char *)malloc(sz + 1);
 
19
 
 
20
    if(!buf)
 
21
    {
 
22
        return NULL;
 
23
    }
 
24
 
 
25
    vsnprintf(buf, sz+1, msg, vl_copy);
 
26
    va_end(vl_copy);
 
27
 
 
28
    return buf;
 
29
}
 
30
 
 
31
 
 
32
/*!
 
33
 * \brief Wraping for vsnprintf function, that saves string to char*
 
34
 * \return saved from vsnprintf string
 
35
 */
 
36
char* make_str(const char* msg, ...)
 
37
{
 
38
    va_list vl;
 
39
    va_start(vl, msg);
 
40
    char *buf = vmake_str(msg, vl);
 
41
    va_end(vl);
 
42
    return buf;
 
43
}
 
44
 
 
45
/*!
 
46
 * \brief Version of pcilib_logger_t, that saves error text to Python exeption
 
47
 */
 
48
void pcilib_print_error_to_py(void *arg, const char *file, int line,
 
49
                              pcilib_log_priority_t prio, const char *msg,
 
50
                              va_list va) {
 
51
    //wrap error message with file and line number
 
52
    char* buf_raw_msg = vmake_str(msg, va);
 
53
    char* buf_wrapped_message = make_str("%s [%s:%d]\n", buf_raw_msg, file, line);
 
54
 
 
55
    if(prio == PCILIB_LOG_ERROR)
 
56
    {
 
57
        if(!full_log)
 
58
            full_log = make_str("");
 
59
 
 
60
        //copy received message to log
 
61
        char* buf = full_log;
 
62
        full_log = make_str("%s%s", buf, buf_wrapped_message);
 
63
        free(buf);
 
64
    }
 
65
    else
 
66
        printf("%s", buf_wrapped_message);
 
67
 
 
68
    free(buf_wrapped_message);
 
69
    free(buf_raw_msg);
 
70
}
 
71
 
 
72
void set_python_exception(const char* msg, ...)
 
73
{
 
74
    va_list vl;
 
75
    va_start(vl, msg);
 
76
    char *buf = vmake_str(msg, vl);
 
77
 
 
78
    char* wrapped_exeption;
 
79
    if(full_log)
 
80
        wrapped_exeption = make_str("%s\nprogramm error log:\n%s", buf, full_log);
 
81
    else
 
82
        wrapped_exeption = buf;
 
83
 
 
84
    free(full_log);
 
85
    full_log = NULL;
 
86
 
 
87
    PyErr_SetString(PyExc_Exception, wrapped_exeption);
 
88
 
 
89
    free(buf);
 
90
    if(full_log)
 
91
        free(wrapped_exeption);
 
92
    va_end(vl);
 
93
}
 
94
 
 
95
 
 
96
void __redirect_logs_to_exeption()
 
97
{
 
98
    pcilib_set_logger(pcilib_get_log_level(),
 
99
                      pcilib_print_error_to_py,
 
100
                      pcilib_get_logger_context());
 
101
}
 
102
 
 
103
/*!
 
104
 * \brief Wrap for PyDict_SetItem, with decrease reference counting after set.
 
105
 */
 
106
void pcilib_pydict_set_item(PyObject* dict, PyObject* name, PyObject* value)
 
107
{
 
108
    PyDict_SetItem(dict,
 
109
                   name,
 
110
                   value);
 
111
    Py_XDECREF(name);
 
112
    Py_XDECREF(value);
 
113
}
 
114
 
 
115
/*!
 
116
 * \brief Wrap for PyList_Append, with decrease reference counting after append.
 
117
 */
 
118
void pcilib_pylist_append(PyObject* list, PyObject* value)
 
119
{
 
120
    PyList_Append(list, value);
 
121
    Py_XDECREF(value);
 
122
}
 
123
 
 
124
void add_pcilib_value_to_dict(pcilib_t* ctx, PyObject* dict, pcilib_value_t* val, const char *name)
 
125
{
 
126
    PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(ctx, val, NULL);
 
127
 
 
128
    if(py_val)
 
129
        pcilib_pydict_set_item(dict,
 
130
                               PyString_FromString(name),
 
131
                               py_val);
 
132
    else
 
133
        pcilib_pydict_set_item(dict,
 
134
                               PyString_FromString("defvalue"),
 
135
                               PyString_FromString("invalid"));
 
136
}
 
137
 
 
138
PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_property_info_t listItem)
 
139
{
 
140
    PyObject* pylistItem = PyDict_New();
 
141
 
 
142
    if(listItem.name)
 
143
        pcilib_pydict_set_item(pylistItem,
 
144
                               PyString_FromString("name"),
 
145
                               PyString_FromString(listItem.name));
 
146
 
 
147
    if(listItem.description)
 
148
        pcilib_pydict_set_item(pylistItem,
 
149
                               PyString_FromString("description"),
 
150
                               PyString_FromString(listItem.description));
 
151
 
 
152
    if(listItem.path)
 
153
        pcilib_pydict_set_item(pylistItem,
 
154
                               PyString_FromString("path"),
 
155
                               PyString_FromString(listItem.path));
 
156
 
 
157
    //serialize types
 
158
    const char* type = "invalid";
 
159
    switch(listItem.type)
 
160
    {
 
161
    case PCILIB_TYPE_INVALID:
 
162
        type = "invalid";
 
163
        break;
 
164
    case PCILIB_TYPE_STRING:
 
165
        type = "string";
 
166
        break;
 
167
    case PCILIB_TYPE_DOUBLE:
 
168
        type = "double";
 
169
        break;
 
170
    case PCILIB_TYPE_LONG :
 
171
        type = "long";
 
172
        break;
 
173
    default:
 
174
        break;
 
175
    }
 
176
    pcilib_pydict_set_item(pylistItem,
 
177
                           PyString_FromString("type"),
 
178
                           PyString_FromString(type));
 
179
 
 
180
 
 
181
    //serialize modes
 
182
    PyObject* modes = PyList_New(0);
 
183
 
 
184
    if((listItem.mode & PCILIB_ACCESS_R ) == PCILIB_REGISTER_R)
 
185
        pcilib_pylist_append(modes, PyString_FromString("R"));
 
186
    if((listItem.mode & PCILIB_ACCESS_W ) == PCILIB_REGISTER_W)
 
187
        pcilib_pylist_append(modes, PyString_FromString("W"));
 
188
    if((listItem.mode & PCILIB_ACCESS_RW ) == PCILIB_REGISTER_RW)
 
189
        pcilib_pylist_append(modes, PyString_FromString("RW"));
 
190
    if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT)
 
191
        pcilib_pylist_append(modes, PyString_FromString("NO_CHK"));
 
192
 
 
193
    pcilib_pydict_set_item(pylistItem,
 
194
                           PyString_FromString("mode"),
 
195
                           modes);
 
196
 
 
197
    //serialize flags
 
198
    PyObject* flags = PyList_New(0);
 
199
 
 
200
    if((listItem.flags & PCILIB_LIST_FLAG_CHILDS ) == PCILIB_LIST_FLAG_CHILDS)
 
201
        pcilib_pylist_append(flags, PyString_FromString("childs"));
 
202
 
 
203
    pcilib_pydict_set_item(pylistItem,
 
204
                           PyString_FromString("flags"),
 
205
                           flags);
 
206
 
 
207
    if(listItem.unit)
 
208
        pcilib_pydict_set_item(pylistItem,
 
209
                               PyString_FromString("unit"),
 
210
                               PyString_FromString(listItem.unit));
 
211
 
 
212
    return pylistItem;
 
213
}
 
214
 
 
215
PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_register_info_t listItem)
 
216
{
 
217
    PyObject* pylistItem = PyDict_New();
 
218
 
 
219
    if(listItem.name)
 
220
        pcilib_pydict_set_item(pylistItem,
 
221
                               PyString_FromString("name"),
 
222
                               PyString_FromString(listItem.name));
 
223
 
 
224
    if(listItem.description)
 
225
        pcilib_pydict_set_item(pylistItem,
 
226
                               PyString_FromString("description"),
 
227
                               PyString_FromString(listItem.description));
 
228
 
 
229
    if(listItem.bank)
 
230
        pcilib_pydict_set_item(pylistItem,
 
231
                               PyString_FromString("bank"),
 
232
                               PyString_FromString(listItem.bank));
 
233
 
 
234
    //serialize modes
 
235
    PyObject* modes = PyList_New(0);
 
236
 
 
237
    if((listItem.mode & PCILIB_REGISTER_R) == PCILIB_REGISTER_R)
 
238
        pcilib_pylist_append(modes, PyString_FromString("R"));
 
239
    if((listItem.mode & PCILIB_REGISTER_W) == PCILIB_REGISTER_W)
 
240
        pcilib_pylist_append(modes, PyString_FromString("W"));
 
241
    if((listItem.mode & PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW)
 
242
        pcilib_pylist_append(modes, PyString_FromString("RW"));
 
243
    if((listItem.mode & PCILIB_REGISTER_W1C) == PCILIB_REGISTER_W1C)
 
244
        pcilib_pylist_append(modes, PyString_FromString("W1C"));
 
245
    if((listItem.mode & PCILIB_REGISTER_RW1C) == PCILIB_REGISTER_RW1C)
 
246
        pcilib_pylist_append(modes, PyString_FromString("RW1C"));
 
247
    if((listItem.mode & PCILIB_REGISTER_W1I) == PCILIB_REGISTER_W1I)
 
248
        pcilib_pylist_append(modes, PyString_FromString("W1I"));
 
249
    if((listItem.mode & PCILIB_REGISTER_RW1I) == PCILIB_REGISTER_RW1I)
 
250
        pcilib_pylist_append(modes, PyString_FromString("RW1I"));
 
251
    if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT)
 
252
        pcilib_pylist_append(modes, PyString_FromString("NO_CHK"));
 
253
 
 
254
    pcilib_pydict_set_item(pylistItem,
 
255
                           PyString_FromString("mode"),
 
256
                           modes);
 
257
 
 
258
    pcilib_value_t defval = {0};
 
259
    pcilib_set_value_from_register_value(ctx, &defval, listItem.defvalue);
 
260
    add_pcilib_value_to_dict(ctx, pylistItem, &defval, "defvalue");
 
261
 
 
262
    if(listItem.range)
 
263
    {
 
264
        pcilib_value_t minval = {0};
 
265
        pcilib_set_value_from_register_value(ctx, &minval, listItem.range->min);
 
266
 
 
267
        pcilib_value_t maxval = {0};
 
268
        pcilib_set_value_from_register_value(ctx, &maxval, listItem.range->max);
 
269
 
 
270
        PyObject* range = PyDict_New();
 
271
        add_pcilib_value_to_dict(ctx, range, &minval, "min");
 
272
        add_pcilib_value_to_dict(ctx, range, &maxval, "max");
 
273
        pcilib_pydict_set_item(pylistItem,
 
274
                               PyString_FromString("range"),
 
275
                               range);
 
276
    }
 
277
 
 
278
    if(listItem.values)
 
279
    {
 
280
        PyObject* values = PyList_New(0);
 
281
 
 
282
        for (int j = 0; listItem.values[j].name; j++)
 
283
        {
 
284
            PyObject* valuesItem = PyDict_New();
 
285
 
 
286
            pcilib_value_t val = {0};
 
287
            pcilib_set_value_from_register_value(ctx, &val, listItem.values[j].value);
 
288
 
 
289
            pcilib_value_t min = {0};
 
290
            pcilib_set_value_from_register_value(ctx, &min, listItem.values[j].min);
 
291
 
 
292
            pcilib_value_t max = {0};
 
293
            pcilib_set_value_from_register_value(ctx, &max, listItem.values[j].max);
 
294
 
 
295
            add_pcilib_value_to_dict(ctx, valuesItem, &val, "value");
 
296
            add_pcilib_value_to_dict(ctx, valuesItem, &min, "min");
 
297
            add_pcilib_value_to_dict(ctx, valuesItem, &max, "max");
 
298
 
 
299
            if(listItem.values[j].name)
 
300
                pcilib_pydict_set_item(valuesItem,
 
301
                                       PyString_FromString("name"),
 
302
                                       PyString_FromString(listItem.values[j].name));
 
303
 
 
304
            if(listItem.values[j].description)
 
305
                pcilib_pydict_set_item(valuesItem,
 
306
                                       PyString_FromString("name"),
 
307
                                       PyString_FromString(listItem.values[j].description));
 
308
 
 
309
            pcilib_pylist_append(values, valuesItem);
 
310
        }
 
311
 
 
312
        pcilib_pydict_set_item(pylistItem,
 
313
                               PyString_FromString("values"),
 
314
                               values);
 
315
    }
 
316
 
 
317
    return pylistItem;
 
318
}
 
319
 
 
320
Pcipywrap *new_Pcipywrap(const char* fpga_device, const char* model)
 
321
{
 
322
    //opening device
 
323
    pcilib_t* ctx = pcilib_open(fpga_device, model);
 
324
    if(!ctx)
 
325
    {
 
326
        set_python_exception("Failed pcilib_open(%s, %s)", fpga_device, model);
 
327
        return NULL;
 
328
    }
 
329
    Pcipywrap *self;
 
330
    self = (Pcipywrap *) malloc(sizeof(Pcipywrap));
 
331
    self->shared = 0;
 
332
    self->ctx = ctx;
 
333
    return self;
 
334
}
 
335
 
 
336
Pcipywrap *create_Pcipywrap(PyObject* ctx)
 
337
{
 
338
    if(!PyCObject_Check(ctx))
 
339
    {
 
340
        set_python_exception("Incorrect ctx type. Only PyCObject is allowed");
 
341
        return NULL;
 
342
    }
 
343
 
 
344
    Pcipywrap *self;
 
345
    self = (Pcipywrap *) malloc(sizeof(Pcipywrap));
 
346
    self->shared = 1;
 
347
    self->ctx = PyCObject_AsVoidPtr(ctx);
 
348
    return self;
 
349
}
 
350
 
 
351
void delete_Pcipywrap(Pcipywrap *self) {
 
352
    if(!self->shared)
 
353
        pcilib_close(self->ctx);
 
354
 
 
355
    free(self);
 
356
}
 
357
 
 
358
PyObject* Pcipywrap_read_register(Pcipywrap *self, const char *regname, const char *bank)
 
359
{
 
360
    pcilib_value_t val = {0};
 
361
    pcilib_register_value_t reg_value;
 
362
 
 
363
    int err;
 
364
 
 
365
    err = pcilib_read_register(self->ctx, bank, regname, &reg_value);
 
366
    if(err)
 
367
    {
 
368
        set_python_exception("Failed pcilib_read_register");
 
369
        return NULL;
 
370
    }
 
371
 
 
372
    err = pcilib_set_value_from_register_value(self->ctx, &val, reg_value);
 
373
    if(err)
 
374
    {
 
375
        set_python_exception("Failed pcilib_set_value_from_register_value");
 
376
        return NULL;
 
377
    }
 
378
 
 
379
    return pcilib_get_value_as_pyobject(self->ctx, &val, NULL);
 
380
}
 
381
 
 
382
PyObject* Pcipywrap_write_register(Pcipywrap *self, PyObject* val, const char *regname, const char *bank)
 
383
{
 
384
    pcilib_value_t val_internal = {0};
 
385
    pcilib_register_value_t reg_value;
 
386
 
 
387
    int err;
 
388
 
 
389
    err = pcilib_set_value_from_pyobject(self->ctx, &val_internal, val);
 
390
 
 
391
    if(err)
 
392
    {
 
393
        set_python_exception("Failed pcilib_set_value_from_pyobject");
 
394
        return NULL;
 
395
    }
 
396
 
 
397
 
 
398
    reg_value = pcilib_get_value_as_register_value(self->ctx, &val_internal, &err);
 
399
    if(err)
 
400
    {
 
401
        set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err);
 
402
        return NULL;
 
403
    }
 
404
 
 
405
    err = pcilib_write_register(self->ctx, bank, regname, reg_value);
 
406
 
 
407
    if(err)
 
408
    {
 
409
        set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err);
 
410
        return NULL;
 
411
    }
 
412
 
 
413
    return PyInt_FromLong((long)1);
 
414
}
 
415
 
 
416
PyObject* Pcipywrap_get_property(Pcipywrap *self, const char *prop)
 
417
{
 
418
    int err;
 
419
    pcilib_value_t val = {0};
 
420
 
 
421
    err  = pcilib_get_property(self->ctx, prop, &val);
 
422
 
 
423
    if(err)
 
424
    {
 
425
        set_python_exception("Failed pcilib_get_property, (error %i)", err);
 
426
        return NULL;
 
427
    }
 
428
 
 
429
    return pcilib_get_value_as_pyobject(self->ctx, &val, NULL);
 
430
}
 
431
 
 
432
PyObject* Pcipywrap_set_property(Pcipywrap *self, PyObject* val, const char *prop)
 
433
{
 
434
    int err;
 
435
 
 
436
    pcilib_value_t val_internal = {0};
 
437
    err = pcilib_set_value_from_pyobject(self->ctx, &val_internal, val);
 
438
    if(err)
 
439
    {
 
440
        set_python_exception("pcilib_set_value_from_pyobject, (error %i)", err);
 
441
        return NULL;
 
442
    }
 
443
 
 
444
    err  = pcilib_set_property(self->ctx, prop, &val_internal);
 
445
    if(err)
 
446
    {
 
447
        set_python_exception("pcilib_set_property, (error %i)", err);
 
448
        return NULL;
 
449
    }
 
450
 
 
451
    return PyInt_FromLong((long)1);
 
452
}
 
453
 
 
454
PyObject* Pcipywrap_get_registers_list(Pcipywrap *self, const char *bank)
 
455
{
 
456
    pcilib_register_info_t *list = pcilib_get_register_list(self->ctx, bank, PCILIB_LIST_FLAGS_DEFAULT);
 
457
 
 
458
    PyObject* pyList = PyList_New(0);
 
459
    for(int i = 0; i < ((pcilib_t*)self->ctx)->num_reg; i++)
 
460
    {
 
461
        //serialize item attributes
 
462
        PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(self->ctx, list[i]);
 
463
        pcilib_pylist_append(pyList, pylistItem);
 
464
    }
 
465
 
 
466
    pcilib_free_register_info(self->ctx, list);
 
467
 
 
468
    return pyList;
 
469
}
 
470
 
 
471
PyObject* Pcipywrap_get_register_info(Pcipywrap *self, const char* reg,const char *bank)
 
472
{
 
473
    pcilib_register_info_t *info = pcilib_get_register_info(self->ctx, bank, reg, PCILIB_LIST_FLAGS_DEFAULT);
 
474
 
 
475
    if(!info)
 
476
    {
 
477
        return NULL;
 
478
    }
 
479
 
 
480
    PyObject* py_info = pcilib_convert_register_info_to_pyobject(self->ctx, info[0]);
 
481
 
 
482
    pcilib_free_register_info(self->ctx, info);
 
483
 
 
484
    return py_info;
 
485
}
 
486
 
 
487
PyObject* Pcipywrap_get_property_list(Pcipywrap *self, const char* branch)
 
488
{
 
489
    pcilib_property_info_t *list = pcilib_get_property_list(self->ctx, branch, PCILIB_LIST_FLAGS_DEFAULT);
 
490
 
 
491
    PyObject* pyList = PyList_New(0);
 
492
 
 
493
    for(int i = 0; list[i].path; i++)
 
494
    {
 
495
        //serialize item attributes
 
496
        PyObject* pylistItem = pcilib_convert_property_info_to_pyobject(self->ctx, list[i]);
 
497
        pcilib_pylist_append(pyList, pylistItem);
 
498
    }
 
499
 
 
500
    pcilib_free_property_info(self->ctx, list);
 
501
 
 
502
    return pyList;
 
503
}