diff options
Diffstat (limited to 'pcilib/pcipywrap.c')
-rw-r--r-- | pcilib/pcipywrap.c | 210 |
1 files changed, 163 insertions, 47 deletions
diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c index efce909..bed4b31 100644 --- a/pcilib/pcipywrap.c +++ b/pcilib/pcipywrap.c @@ -1,7 +1,6 @@ -#include "pcilib.h" -#include <Python.h> #include "pci.h" #include "error.h" +#include "pcipywrap.h" /*! * \brief Global pointer to pcilib_t context. @@ -25,15 +24,45 @@ PyObject* __createPcilibInstance(const char *fpga_device, const char *model) } /*! + * \brief Sets python exeption text. Function interface same as printf. + */ +void setPyExeptionText(const char* msg, ...) +{ + char *buf; + size_t sz; + + va_list vl, vl_copy; + va_start(vl, msg); + va_copy(vl_copy, vl); + + sz = vsnprintf(NULL, 0, msg, vl); + buf = (char *)malloc(sz + 1); + + if(!buf) + { + PyErr_SetString(PyExc_Exception, "Memory error"); + return; + } + + vsnprintf(buf, sz+1, msg, vl_copy); + va_end(vl_copy); + va_end(vl); + + PyErr_SetString(PyExc_Exception, buf); + free(buf); +} + +/*! * \brief Sets pcilib context to wraper. * \param[in] addr Pointer to pcilib_t, serialized to bytearray + * \return true, serialized to PyObject, NULL with exeption text, if failed. */ -void __setPcilib(PyObject* addr) +PyObject* __setPcilib(PyObject* addr) { if(!PyByteArray_Check(addr)) { - PyErr_SetString(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); - return NULL; + setPyExeptionText(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); + return; } //deserializing adress @@ -44,8 +73,82 @@ void __setPcilib(PyObject* addr) ((char*)&__ctx)[i] = pAddr[i]; free(pAddr); + + return PyInt_FromLong((long)1); } +PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, void (*errstream)(const char* msg, ...)) +{ + int err; + + switch(val->type) + { + case PCILIB_TYPE_INVALID: + errstream("Invalid register output type (PCILIB_TYPE_INVALID)"); + return NULL; + + case PCILIB_TYPE_STRING: + errstream("Invalid register output type (PCILIB_TYPE_STRING)"); + return NULL; + + case PCILIB_TYPE_LONG: + { + long ret; + ret = pcilib_get_value_as_int(__ctx, val, &err); + + if(err) + { + errstream("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return PyInt_FromLong((long) ret); + } + + case PCILIB_TYPE_DOUBLE: + { + double ret; + ret = pcilib_get_value_as_float(__ctx, val, &err); + + if(err) + { + errstream("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return PyFloat_FromDouble((double) ret); + } + + default: + errstream("Invalid register output type (unknown)"); + return NULL; + } +} + +int pcilib_convert_pyobject_to_val(pcilib_t* ctx, PyObject* pyVal, pcilib_value_t *val) +{ + int err; + + if(PyInt_Check(pyVal)) + { + err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); + } + else + if(PyFloat_Check(pyVal)) + err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyVal)); + else + if(PyString_Check(pyVal)) + err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); + else + { + pcilib_error("Invalid input. Input type should be int, float or string."); + return PCILIB_ERROR_NOTSUPPORTED; + } + if(err) + return err; + + return 0; +} + + /*! * \brief Reads register value. * \param[in] regname the name of the register @@ -53,10 +156,10 @@ void __setPcilib(PyObject* addr) * \return register value, can be integer or float type */ PyObject* read_register(const char *regname, const char *bank) -{ +{ if(!__ctx) { - PyErr_SetString(PyExc_Exception, "pcilib_t handler not initialized"); + setPyExeptionText("pcilib_t handler not initialized"); return NULL; } @@ -70,56 +173,69 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) { - PyErr_SetString(PyExc_Exception, "Failed: read_register"); + setPyExeptionText("Failed: read_register (%i)", err); return NULL; } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); - if(err) { - PyErr_SetString(PyExc_Exception, "Failed: pcilib_set_value_from_register_value"); + setPyExeptionText("Failed: pcilib_set_value_from_register_value (%i)", err); return NULL; } - switch(val.type) + return pcilib_convert_val_to_pyobject(__ctx, &val, setPyExeptionText); +} + + +PyObject* get_property(const char *prop) +{ + if(!__ctx) { - case PCILIB_TYPE_INVALID: - PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_INVALID)"); - return NULL; - - case PCILIB_TYPE_STRING: - PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_STRING)"); - return NULL; - - case PCILIB_TYPE_LONG: - { - long ret; - ret = pcilib_get_value_as_int(__ctx, &val, &err); - - if(err) - { - PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int"); - return NULL; - } - return PyInt_FromLong((long) ret); - } - - case PCILIB_TYPE_DOUBLE: - { - double ret; - ret = pcilib_get_value_as_float(__ctx, &val, &err); - - if(err) - { - PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int"); - return NULL; - } - return PyFloat_FromDouble((double) ret); - } - - default: - PyErr_SetString(PyExc_Exception, "Invalid register output type (unknown)"); + setPyExeptionText("pcilib_t handler not initialized"); + return NULL; + } + + int err; + pcilib_value_t val = {0}; + + err = pcilib_get_property(__ctx, prop, &val); + + if(err) + { + setPyExeptionText("Failed pcilib_get_property (%i)", err); return NULL; } + + return pcilib_convert_val_to_pyobject(__ctx, &val, setPyExeptionText); +} + +PyObject* set_property(const char *prop, PyObject* val) +{ + int err; + + if(!__ctx) + { + setPyExeptionText("pcilib_t handler not initialized"); + return NULL; + } + + pcilib_value_t val_internal = {0}; + err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + if(err) + { + setPyExeptionText("pcilib_convert_pyobject_to_val (%i)", err); + return NULL; + } + + err = pcilib_set_property(__ctx, prop, &val_internal); + + if(err) + { + setPyExeptionText("Failed pcilib_get_property (%i)", err); + return NULL; + } + + return PyInt_FromLong((long)1); } + |