diff options
Diffstat (limited to 'pcilib/pcipywrap.c')
-rw-r--r-- | pcilib/pcipywrap.c | 271 |
1 files changed, 103 insertions, 168 deletions
diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c index 5abd56c..efce909 100644 --- a/pcilib/pcipywrap.c +++ b/pcilib/pcipywrap.c @@ -1,190 +1,125 @@ #include "pcilib.h" - -//Remove unused headers -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <stdint.h> -#include <stdarg.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <errno.h> -#include <alloca.h> -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <pthread.h> -#include <signal.h> -#include <dlfcn.h> - -#include <getopt.h> - -#include <fastwriter.h> - -#include "pcitool/sysinfo.h" -#include "pcitool/formaters.h" - -#include "views/transform.h" -#include "views/enum.h" +#include <Python.h> #include "pci.h" -#include "plugin.h" -#include "config.h" -#include "tools.h" -#include "kmem.h" #include "error.h" -#include "debug.h" -#include "model.h" -#include "locking.h" +/*! + * \brief Global pointer to pcilib_t context. + * Used by __setPcilib and read_register. + */ pcilib_t* __ctx = 0; -pcilib_model_description_t *model_info = 0; /*! - * \brief присваивание указателя на устройство. Закрытая функция. Будет проходить при парсинге xml. - * \param ctx + * \brief Wraps for pcilib_open function. + * \param[in] fpga_device path to the device file [/dev/fpga0] + * \param[in] model specifies the model of hardware, autodetected if NULL is passed + * \return Pointer to pcilib_t, created by pcilib_open, serialized to bytearray */ -void __initCtx(void* ctx) +PyObject* __createPcilibInstance(const char *fpga_device, const char *model) { - __ctx = ctx; + //opening device + pcilib_t* ctx = pcilib_open(fpga_device, model); + + //serializing object + return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)); } /*! - * \brief создание хэндлера устройства, для тестирования скрипта не из программы. - * \return + * \brief Sets pcilib context to wraper. + * \param[in] addr Pointer to pcilib_t, serialized to bytearray */ -void __createCtxInstance(const char *fpga_device, const char *model) +void __setPcilib(PyObject* addr) { - __ctx = pcilib_open(fpga_device, model); - model_info = pcilib_get_model_description(__ctx); -} - -int read_register(const char *bank, const char *regname, void *value) -{ - int ret = pcilib_read_register(__ctx, bank, regname, (pcilib_register_value_t*)value); - return ret; -} - -void Error(const char *message, const char *attr, ...) -{ - printf("Catch error: %s, %s\n", message, attr); + if(!PyByteArray_Check(addr)) + { + PyErr_SetString(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); + return NULL; + } + + //deserializing adress + char* pAddr = PyByteArray_AsString(addr); + + //hard copy context adress + for(int i = 0; i < sizeof(pcilib_t*) + 10; i++) + ((char*)&__ctx)[i] = pAddr[i]; + + free(pAddr); } -int ReadRegister(const char *bank, const char *reg) { +/*! + * \brief Reads register value. + * \param[in] regname the name of the register + * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise + * \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"); + return NULL; + } - const char *view = NULL; - const char *unit = NULL; - const char *attr = NULL; - pcilib_t *handle = __ctx; - int i; - int err; - const char *format; - - pcilib_register_bank_t bank_id; - pcilib_register_bank_addr_t bank_addr = 0; - - pcilib_register_value_t value; - - // Adding DMA registers - pcilib_get_dma_description(handle); - - if (reg||view||attr) { - pcilib_value_t val = {0}; - if (attr) { - if (reg) err = pcilib_get_register_attr(handle, bank, reg, attr, &val); - else if (view) err = pcilib_get_property_attr(handle, view, attr, &val); - else if (bank) err = pcilib_get_register_bank_attr(handle, bank, attr, &val); - else err = PCILIB_ERROR_INVALID_ARGUMENT; - - if (err) { - if (err == PCILIB_ERROR_NOTFOUND) - Error("Attribute %s is not found", attr); - else - Error("Error (%i) reading attribute %s", err, attr); - } - - err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING); - if (err) Error("Error converting attribute %s to string", attr); - - printf("%s = %s", attr, val.sval); - if ((val.unit)&&(strcasecmp(val.unit, "name"))) - printf(" %s", val.unit); - printf(" (for %s)\n", (reg?reg:(view?view:bank))); - } else if (view) { - if (reg) { - err = pcilib_read_register_view(handle, bank, reg, view, &val); - if (err) Error("Error reading view %s of register %s", view, reg); - } else { - err = pcilib_get_property(handle, view, &val); - if (err) Error("Error reading property %s", view); - } - - if (unit) { - err = pcilib_convert_value_unit(handle, &val, unit); - if (err) { - if (reg) Error("Error converting view %s of register %s to unit %s", view, reg, unit); - else Error("Error converting property %s to unit %s", view, unit); - } - } - - err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING); - if (err) { - if (reg) Error("Error converting view %s of register %s to string", view); - else Error("Error converting property %s to string", view); - } - - printf("%s = %s", (reg?reg:view), val.sval); - if ((val.unit)&&(strcasecmp(val.unit, "name"))) - printf(" %s", val.unit); - printf("\n"); - } else { - pcilib_register_t regid = pcilib_find_register(handle, bank, reg); - bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank); - format = model_info->banks[bank_id].format; - if (!format) format = "%lu"; - err = pcilib_read_register_by_id(handle, regid, &value); - if (err) Error("Error reading register %s", reg); - - printf("%s = ", reg); - printf(format, value); - printf("\n"); + pcilib_get_dma_description(__ctx); + + pcilib_value_t val = {0}; + pcilib_register_value_t reg_value; + + int err; + + err = pcilib_read_register(__ctx, bank, regname, ®_value); + if(err) + { + PyErr_SetString(PyExc_Exception, "Failed: read_register"); + 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"); + return NULL; } - } else { - if (model_info->registers) { - if (bank) { - bank_id = pcilib_find_register_bank(handle, bank); - bank_addr = model_info->banks[bank_id].addr; - } - - printf("Registers:\n"); - for (i = 0; model_info->registers[i].bits; i++) { - if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { - bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[i].bank); - format = model_info->banks[bank_id].format; - if (!format) format = "%lu"; - - err = pcilib_read_register_by_id(handle, i, &value); - if (err) printf(" %s = error reading value", model_info->registers[i].name); - else { - printf(" %s = ", model_info->registers[i].name); - printf(format, value); - } - printf(" ["); - printf(format, model_info->registers[i].defvalue); - printf("]"); - printf("\n"); + switch(val.type) + { + 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); } - } - } else { - printf("No registers"); + + 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)"); + return NULL; } - printf("\n"); - } - - return 0; } |