فهرست منبع

views working fine, units in progress

nicolas.zilio@hotmail.fr 8 سال پیش
والد
کامیت
2dfb23016c
10فایلهای تغییر یافته به همراه267 افزوده شده و 64 حذف شده
  1. 2 2
      pcilib/CMakeLists.txt
  2. 10 4
      pcilib/pci.c
  3. 4 1
      pcilib/pci.h
  4. 34 0
      pcilib/unit.c
  5. 30 0
      pcilib/unit.h
  6. 56 43
      pcilib/views.c
  7. 3 0
      pcilib/views.h
  8. 69 2
      pcilib/xml.c
  9. 57 10
      pcitool/cli.c
  10. 2 2
      xml/test/camera.xml

+ 2 - 2
pcilib/CMakeLists.txt

@@ -9,9 +9,9 @@ include_directories(
 
 set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h
 views.h xml.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h
-debug.h env.h version.h config.h )
+debug.h env.h version.h config.h unit.h)
 add_library(pcilib SHARED pci.c export.c bar.c fifo.c model.c bank.c
-register.c views.c xml.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c )
+register.c views.c xml.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c unit.c)
 target_link_libraries(pcilib dma protocols ${CMAKE_THREAD_LIBS_INIT}
 ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS}
 ${LIBXML2_LIBRARIES} ${PYTHON_LIBRARIES})

+ 10 - 4
pcilib/pci.c

@@ -145,19 +145,24 @@ pcilib_t *pcilib_open(const char *device, const char *model) {
 	ctx->register_ctx = (pcilib_register_context_t *)malloc(PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_context_t));
 	ctx->enum_views = (pcilib_view_enum2_t *)malloc(PCILIB_DEFAULT_VIEW_SPACE * sizeof(pcilib_view_enum2_t));
 	ctx->formula_views = (pcilib_view_formula_t*)malloc(PCILIB_DEFAULT_VIEW_SPACE * sizeof(pcilib_view_formula_t));
+	ctx->alloc_units=PCILIB_DEFAULT_UNIT_SPACE;
+	ctx->units=(pcilib_unit_t*)malloc(PCILIB_DEFAULT_UNIT_SPACE * sizeof(pcilib_unit_t));
 	
+
+
 	if ((!ctx->registers)||(!ctx->register_ctx)) {
 	    pcilib_error("Error allocating memory for register model");
 	    pcilib_close(ctx);
 	    return NULL;
 	}
 	
-	if((!ctx->enum_views)||(!ctx->formula_views)){
-	  pcilib_error("Error allocating memory for views");
-	  pcilib_close(ctx);
-	  return NULL;
+	/* i think we need a better error handling here, because, it's not that a problem to not have views working, but how to block the use if the memory here was not good?, and we could have only one type of views that is working*/
+	if((!ctx->enum_views)||(!ctx->formula_views) || (!ctx->units)){
+	  pcilib_warning("Error allocating memory for views");
 	}
 
+	
+	
 	memset(ctx->registers, 0, sizeof(pcilib_register_description_t));
 	memset(ctx->banks, 0, sizeof(pcilib_register_bank_description_t));
 	memset(ctx->ranges, 0, sizeof(pcilib_register_range_t));
@@ -166,6 +171,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) {
 
 	memset(ctx->enum_views,0,sizeof(pcilib_view_enum2_t));
 	memset(ctx->formula_views,0,sizeof(pcilib_view_formula_t));
+	memset(ctx->units,0,sizeof(pcilib_unit_t));
 	
 	for (i = 0; pcilib_protocols[i].api; i++);
 	memcpy(ctx->protocols, pcilib_protocols, i * sizeof(pcilib_register_protocol_description_t));

+ 4 - 1
pcilib/pci.h

@@ -9,6 +9,7 @@
 #define PCILIB_MAX_BARS 6			/**< this is defined by PCI specification */
 #define PCILIB_DEFAULT_REGISTER_SPACE 1024	/**< number of registers to allocate on init */
 #define PCILIB_DEFAULT_VIEW_SPACE 128    	/**< number of views to allocate on init */
+#define PCILIB_DEFAULT_UNIT_SPACE 128           /** number of units to allocate on init*/
 #define PCILIB_MAX_REGISTER_BANKS 32		/**< maximum number of register banks to allocate space for */
 #define PCILIB_MAX_REGISTER_RANGES 32		/**< maximum number of register ranges to allocate space for */
 #define PCILIB_MAX_REGISTER_PROTOCOLS 32	/**< maximum number of register protocols to support */
@@ -27,6 +28,7 @@
 #include "export.h"
 #include "locking.h"
 #include "xml.h"
+#include "unit.h"
 
 typedef struct {
     uint8_t max_link_speed, link_speed;
@@ -65,7 +67,7 @@ struct pcilib_s {
     size_t dyn_banks;									/**< Number of configured dynamic banks */
   size_t num_enum_views,alloc_enum_views;                                               /**< Number of configured and allocated  views of type enum*/
   size_t num_formula_views,alloc_formula_views;                                         /**< Number of configured and allocated  views of type formula*/
-
+  size_t num_units,alloc_units;                                                         /**< Number of configured and allocated  units*/
     pcilib_register_description_t *registers;						/**< List of currently defined registers (from all sources) */
     pcilib_register_bank_description_t banks[PCILIB_MAX_REGISTER_BANKS + 1];		/**< List of currently defined register banks (from all sources) */
     pcilib_register_range_t ranges[PCILIB_MAX_REGISTER_RANGES + 1];			/**< List of currently defined register ranges (from all sources) */
@@ -87,6 +89,7 @@ struct pcilib_s {
   pcilib_view_enum2_t* enum_views;     /**< list of currently defined views of type enum*/
   pcilib_view_formula_t* formula_views;     /**< list of currently defined views of type formula*/
 
+  pcilib_unit_t* units; /** list of currently defined units*/
 #ifdef PCILIB_FILE_IO
     int file_io_handle;
 #endif /* PCILIB_FILE_IO */

+ 34 - 0
pcilib/unit.c

@@ -0,0 +1,34 @@
+#include "pcilib.h"
+#include "pci.h"
+#include "stdio.h"
+#include <string.h>
+#include "error.h"
+#include "unit.h"
+
+int pcilib_add_units(pcilib_t *ctx, size_t n, const pcilib_unit_t* units) {
+	
+    pcilib_unit_t *units2;
+    size_t size;
+
+    if (!n) {
+	for (n = 0; units[n].name[0]; n++);
+    }
+
+    if ((ctx->num_units + n + 1) > ctx->alloc_units) {
+      for (size = ctx->alloc_units; size < 2 * (n + ctx->num_units + 1); size<<=1);
+
+	units2 = (pcilib_unit_t*)realloc(ctx->units, size * sizeof(pcilib_unit_t));
+	if (!units2) return PCILIB_ERROR_MEMORY;
+
+	ctx->units = units2;
+	ctx->alloc_units = size;
+    }
+
+    memcpy(ctx->units + ctx->num_units, units, n * sizeof(pcilib_unit_t));
+    memset(ctx->units + ctx->num_units + n, 0, sizeof(pcilib_unit_t));
+
+    ctx->num_units += n;
+    
+    return 0;
+}
+    

+ 30 - 0
pcilib/unit.h

@@ -0,0 +1,30 @@
+#ifndef _PCILIB_UNITS_H
+#define _PCILIB_UNITS_H
+
+#include "pcilib.h"
+
+typedef struct pcilib_unit_s pcilib_unit_t; 
+typedef struct pcilib_transform_unit_s pcilib_transform_unit_t;
+
+/**
+ * type to save a transformation unit in the pcitool program
+ */
+struct pcilib_transform_unit_s{
+  char *name;
+  char *transform_formula;
+};
+
+/**
+ * type to save a unit in the pcitool programm
+ */
+struct pcilib_unit_s{
+  char* name;
+  pcilib_transform_unit_t* other_units;
+};
+
+/**
+ * function to populate the ctx with units
+ */
+int pcilib_add_units(pcilib_t* ctx, size_t n, const pcilib_unit_t* units);
+
+#endif

+ 56 - 43
pcilib/views.c

@@ -6,6 +6,7 @@
 #include "error.h"
 #include <strings.h>
 #include <stdlib.h>
+#include "unit.h" 
 
 /**
  *
@@ -81,7 +82,7 @@ pcilib_view_formula_replace (const char *txt, const char *before, const char *af
  * @param[in] end the ending index of the substring.
  * @return the extracted substring.
  */
-static char*
+char*
 pcilib_view_str_sub (const char *s, unsigned int start, unsigned int end)
 {
    char *new_s = NULL;
@@ -108,6 +109,39 @@ pcilib_view_str_sub (const char *s, unsigned int start, unsigned int end)
    return new_s;
 }
 
+/**
+ * function to apply a unit for the views of type formula
+ *@param[in] view - the view we want to get the units supported
+ *@param[in] base_unit - the base unit of the formulas of the view
+ *@param[in] unit - the requested unit in which we want to get the value
+ *@param[in,out] value - the number that needs to get transformed
+ *
+static int
+pcilib_view_apply_unit(pcilib_view_formula_t* view, char* base_unit, char* unit,int* value){
+  char* formula;
+  char temp[66];
+  int i,j,k;
+  k=1;
+  /*we iterate through all the units of the given view to find the corresponding unit, and so the formula to transform it; then we evaluate value with the formula*
+  for(i=0;view->units[i].name[0];i++){
+    if(!(strcasecmp(base_unit,view->units[i].name))){
+	for(j=0;view->units[i].other_units[j].name[0];j++){
+	  if(!(strcasecmp(unit,view->units[i].other_units[j].name))){
+	    formula=malloc(strlen(units[i].other_units[j].transform_formula)*sizeof(char));
+	    strcpy(formula,units[i].other_units[j].transform_formula);
+	    sprintf(temp,"%i",*value);
+	    formula=pcilib_view_formula_replace(formula,"@self",temp); 
+	    *value=(int)pcilib_view_eval_formula(formula);
+	    return 0;
+	  }
+	}
+      }
+    }
+  
+   pcilib_error("no unit corresponds to the base unit asked");
+   return PCILIB_ERROR_INVALID_REQUEST;
+}*/
+
 /**
  * get the bank name associated with a register name
  */
@@ -162,46 +196,25 @@ pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula){
  */
 static pcilib_register_value_t
 pcilib_view_eval_formula(char* formula){
-   setenv("PYTHONPATH",".",1);
-   PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *presult=NULL;
-   char* pythonfile;
+  
+  //  setenv("PYTHONPATH",".",1);
 
-   /* path to the python file, we may need a way to set it, maybe with a variable like PCILIB_PYTHON_PATH*/
-   pythonfile="pythonscripts.py";
-   
    /* initialization of python interpreter*/
    Py_Initialize();
-
-   pName = PyUnicode_FromString(pythonfile);
-   pModule = PyImport_Import(pName); /* get the python file*/
-	if(!pModule) {
-		pcilib_error("no python file found for python evaluation of formulas\n");
-		PyErr_Print();
-		return -1;
-	}
-   pDict = PyModule_GetDict(pModule); /*useless but needed*/
-
-   pFunc = PyDict_GetItemString(pDict, (char*)"evaluate"); /*getting of the function "evaluate" in the script*/
-   /* if the function is ok, then call it*/
-   if (PyCallable_Check(pFunc))
-   {
-        /* execution of the function*/
-       pValue=Py_BuildValue("(z)",formula);
-       PyErr_Print();
-       presult=PyObject_CallObject(pFunc,pValue);
-       PyErr_Print();
-   } else 
-   {
-       PyErr_Print();
-   }
-   /* remove memory*/
-   Py_DECREF(pModule);
-   Py_DECREF(pName);
    
+   /*compilation of the formula as python string*/
+   PyCodeObject* code=(PyCodeObject*)Py_CompileString(formula,"test",Py_eval_input);
+   PyObject* main_module = PyImport_AddModule("__parser__");
+   PyObject* global_dict = PyModule_GetDict(main_module);
+   PyObject* local_dict = PyDict_New();
+   /*evaluation of formula*/
+   PyObject* obj = PyEval_EvalCode(code, global_dict, local_dict);
+   double c=PyFloat_AsDouble(obj);
+
    /* close interpreter*/
    Py_Finalize();
-   
-   return (pcilib_register_value_t)PyLong_AsUnsignedLong(presult); /*this function is due to python 3.3, as PyLong_AsInt was there in python 2.7 and is no more there, resulting in using cast futhermore*/
+   pcilib_register_value_t value=(pcilib_register_value_t)c;
+   return value;
 }
 
 
@@ -227,7 +240,6 @@ pcilib_view_apply_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t
   formula=pcilib_view_compute_plain_registers(ctx,formula);
   /* computation of @reg with register value*/
   formula=pcilib_view_formula_replace(formula,"@reg",reg_value_string);
-  
   /* evaluation of the formula*/
   *out_value= pcilib_view_eval_formula(formula);
 
@@ -246,8 +258,10 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const
   }
   
   /* we get the value of the register, as we will apply the view on it*/
-  if((err==pcilib_read_register_by_id(ctx,i,&temp_value))>0){
-    pcilib_error("can't read the register %s value before applying views",regname);
+  err=pcilib_read_register_by_id(ctx,i,&temp_value);
+  if(err){
+    pcilib_error("can't read the register %s value before applying views : error %i",regname);
+    return PCILIB_ERROR_INVALID_REQUEST;
   }
     /*in the case we don't ask for a view's name, we know it will be for views of type enum. Especially, it's faster to search directly on the values of those views instead of a given name.
       we iterate so through the views of type enum to verify if the value we have corresponds to an enum command*/
@@ -255,13 +269,15 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const
     for(j=0; ctx->register_ctx[i].enums[j].value;j++){
       if((temp_value >= ctx->register_ctx[i].enums[j].min) && (temp_value <= ctx->register_ctx[i].enums[j].max)){
 	value_size=strlen(ctx->register_ctx[i].enums[j].name)*sizeof(char);
-	value=malloc(sizeof(value_size));
+	value=(char*)realloc(value,sizeof(value_size));
 	if(!(value)){
 	  pcilib_error("can't allocate memory for the returning value of the view %s",view);
 	  return PCILIB_ERROR_MEMORY;
 	}
 	/* in the case the value of register is between min and max, then we return the correponding enum command*/
 	strncpy((char*)value,ctx->register_ctx[i].enums[j].name, strlen(ctx->register_ctx[i].enums[j].name));
+	/* make sure the string is correctly terminated*/
+	((char*)value)[value_size]='\0';
 	return 0;
       }
     }
@@ -271,8 +287,7 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const
   
   /** in the other case we ask for a view of type formula. Indeed, wa can't directly ask for a formula, so we have to provide a name for those views*/
   j=0;
-  while((ctx->register_ctx[i].formulas[j].name)){
-    if(!(strcasecmp(ctx->register_ctx[i].formulas[j].name,view))){
+  if(!(strcasecmp(ctx->register_ctx[i].formulas[0].name,view))){
       /* when we have found the correct view of type formula, we apply the formula, that get the good value for return*/
       formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[j].read_formula));
       strncpy(formula,ctx->register_ctx[i].formulas[j].read_formula,strlen(ctx->register_ctx[i].formulas[j].read_formula));
@@ -281,8 +296,6 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const
       value_size=sizeof(int);
       return 0;
     }
-    j++;
-   }
 
   pcilib_warning("the view asked and the register do not correspond");
   return PCILIB_ERROR_NOTAVAILABLE;

+ 3 - 0
pcilib/views.h

@@ -2,6 +2,7 @@
 #define _PCILIB_VIEWS_H
 
 #include "pcilib.h"
+#include "unit.h"
 
 typedef struct pcilib_view_enum_s pcilib_view_enum_t;
 
@@ -37,6 +38,7 @@ struct pcilib_view_formula_s {
   const char *write_formula; /**<formula to parse to write to a register*/
 	// **see it later**        const char *unit; (?)
   const char *description;
+  pcilib_unit_t* units;
 };
 
 /**
@@ -53,5 +55,6 @@ int pcilib_add_views_enum(pcilib_t* ctx,size_t n, const pcilib_view_enum2_t* vie
 
 int pcilib_add_views_formula(pcilib_t* ctx, size_t n, const pcilib_view_formula_t* views);
 
+char* pcilib_view_str_sub(const char* s, unsigned int start, unsigned int end);
 
 #endif

+ 69 - 2
pcilib/xml.c

@@ -70,7 +70,24 @@ static xmlNodePtr pcilib_xml_get_parent_register_node(xmlDocPtr doc, xmlNodePtr
 }
 */
 
-
+/**
+ * get the associated units of a view
+ * this function is maybe completekly useless : we need to decide if we iterate directly in ctx or n view when we want to apply a unit. (in the second choice of course keep it).
+*
+static void
+pcilib_get_associated_units(pcilib_t* ctx, pcilib_view_formula_t* myview){
+  int i,j,k=2;
+  for(i=0;myview->units[0].other_units.name[0];i++){
+      for(j=0;ctx->units[j].name[0];i++){
+	if(!(strcasecmp(myview->units[0].other_units.name,ctx->units[i].name))){
+	  myview.units=realloc(myview.units,k*sizeof(pcilib_unit_t));
+	  myview.units[k-1]=ctx->units[i];
+	  k++;
+	}
+      }
+  }
+  }*/
+			  
 /**
  * get the associated views of a register, to fill its register context
  */
@@ -490,7 +507,52 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
     return 0;
 }
 
+/*static int pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
+    int err;
+    
+    int override = 0;
+    pcilib_unit_t desc = {0};
+    xmlNodePtr cur;
+    char *value, *name, *value2;
+    char *endptr;
 
+    xmlXPathObjectPtr nodes;
+    xmlNodeSetPtr nodeset;
+    xmlAttr *attr;
+    int i=0;
+
+      /* we get the attribute type of the view node*
+    attr=node->properties;
+    value=(char*)attr->children->content;
+    desc.name=value;
+    desc.other_units=malloc(sizeof(pcilib_transform_unit_t));
+    
+    for (cur = node->children; cur != NULL; cur = cur->next) {
+	if (!cur->children) continue;
+	if (!xmlNodeIsText(cur->children)) continue;
+	
+	name = (char*)cur->name;
+        value = (char*)cur->children->content;
+	attr= cur->properties;
+	value2=(char*)attr->children->content;
+        if (!value || !attr) continue;
+        
+        if (!strcasecmp(name, "convert_unit")) {
+	  desc.other_units=realloc(des.other_units,sizeof((i+1)*sizeof(pcilib_transform_unit_t)));
+	  desc.other_units[i].name=value2;
+	  desc.other_units[i].transform_formula=value;
+        }
+    }
+
+    err = pcilib_add_units(ctx, 1, &desc);
+    if (err) {
+        pcilib_error("Error adding unit (%s) specified in the XML", desc.name);
+        return err;
+    }
+
+    return 0;
+}
+*/
 /**
  * function that create a view from a view node, and populate ctx views list
  */
@@ -505,6 +567,7 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
     char *endptr;
     xmlAttr *attr;
     int i=0;
+    int ok_min=0, ok_max=0;
 
     /*must i initialize? i think it's only needed if we want to include a description property*/ 
     enum_desc.name="default";
@@ -573,15 +636,19 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
 		 return PCILIB_ERROR_INVALID_DATA;
 	       }
 	      complete_enum_desc.enums_list[i].min=dat_min;
+	      ok_min=1;
 	    }else if(!(strcasecmp(name,"max"))){
 	       pcilib_register_value_t dat_max = strtol(value, &endptr, 0);
 	       if ((strlen(endptr) > 0)) {
 		 pcilib_error("Invalid max (%s) is specified in the XML enum node", value);
 		 return PCILIB_ERROR_INVALID_DATA;
 	       }
-
 	      complete_enum_desc.enums_list[i].max=dat_max;
+	      ok_max=1;
 	    }
+	    if(ok_min==0) complete_enum_desc.enums_list[i].min=complete_enum_desc.enums_list[i].value;
+	    if(ok_max==0) complete_enum_desc.enums_list[i].max=complete_enum_desc.enums_list[i].value;
+	    
 	  }
 	  i++;	
 	}

+ 57 - 10
pcitool/cli.c

@@ -1024,13 +1024,14 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info,
     int i;
     int err;
     const char *format;
+    char *s1,*s2,*s3;
+
 
     pcilib_register_bank_t bank_id;
     pcilib_register_bank_addr_t bank_addr = 0;
 
     pcilib_register_value_t value;
-    
-    if (reg) {
+      if (reg && !(strchr(reg,'/'))) {
 	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;
@@ -1044,7 +1045,36 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info,
 	    printf(format, value);
 	    printf("\n");
 	}
+      }else if(reg && (s1=strchr(reg,'/'))){
+	char* enum_command=malloc(sizeof(char*));
+	if(!enum_command){
+	  printf("Error allocating memory for the result\n");
+	  return PCILIB_ERROR_MEMORY;
+	}
+	s2=pcilib_view_str_sub(reg,0,s1-reg-1);
+	s3=pcilib_view_str_sub(reg,s1-reg+1,strlen(reg));
+	if(!(strcasecmp(s3,"name"))){
+	    err = pcilib_read_view(handle,bank,s2,NULL,sizeof(char*),enum_command);
+	    if (err) printf("Error reading register %s\n", reg);
+	    else {
+	      printf("%s = %s\n", reg, (char*)enum_command);
+	    }   
+	}else{
+	    pcilib_register_t regid = pcilib_find_register(handle, bank, s2);
+	    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_view(handle,bank,s2,s3,sizeof(pcilib_register_value_t),&value);
+	    if (err) printf("Error reading register %s\n", reg);
+	    else {
+	      printf("%s = ", reg);
+	      printf(format, value);
+	      printf("\n");
+	    }
+	}
     } else {
+	printf("da\n");
 	    // Adding DMA registers
 	pcilib_get_dma_description(handle);	
     
@@ -1254,6 +1284,7 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info
     pcilib_register_value_t value;
 
     const char *format = NULL;
+    char *s1;
 
     pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
     if (regid == PCILIB_REGISTER_INVALID) Error("Can't find register (%s) from bank (%s)", reg, bank?bank:"autodetected");
@@ -1281,14 +1312,27 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info
 	
 	format = "0x%lx";
     } else {
-	    Error("Can't parse data value (%s) is not valid decimal number", *data);
+      err = pcilib_write_view(handle,bank,reg,*data,0,NULL);
+      if(err) Error("can't write to the register using an enum view");
+      else return 0;
     }
+      /*    } else {
+	    Error("Can't parse data value (%s) is not valid decimal number", *data);
+	    }*/
 
     value = val;
-    
-    err = pcilib_write_register(handle, bank, reg, value);
-    if (err) Error("Error writting register %s\n", reg);
 
+    if((s1=strchr(reg,'/'))){
+	char *s3,*s2;
+	s2=pcilib_view_str_sub(reg,0,s1-reg-1);
+	s3=pcilib_view_str_sub(reg,s1-reg+1,strlen(reg));
+	err = pcilib_write_view(handle,bank,s2,s3,sizeof(pcilib_register_value_t),&value);
+	if (err) printf("Error writing register %s using view %s\n",s2,s3);
+    }else{
+	err = pcilib_write_register(handle, bank, reg, value);
+	if (err) Error("Error writting register %s\n", reg);
+    }
+      
     if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) {
 	err = pcilib_read_register(handle, bank, reg, &value);
 	if (err) Error("Error reading back register %s for verification\n", reg);
@@ -3249,7 +3293,10 @@ int main(int argc, char **argv) {
 		    ++mode;
 		}
 	    }
-	} else {
+	} else if(strchr(addr,'/')) {
+	  reg=addr;
+	  ++mode;
+	}else {
 	    if (pcilib_find_register(handle, bank, addr) == PCILIB_REGISTER_INVALID) {
 	        Usage(argc, argv, "Invalid address (%s) is specified", addr);
 	    } else {
@@ -3349,12 +3396,12 @@ int main(int argc, char **argv) {
 	} else if (addr) {
 	    err = ReadData(handle, amode, flags, dma, bar, start, size, access, endianess, (size_t)-1, ofile);
 	} else {
-	    Error("Address to read is not specified");
+	  Error("Address to read is not specified");
 	}
      break;
      case MODE_READ_REGISTER:
-        if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg);
-	else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile);
+       if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg);
+       else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile);
      break;
      case MODE_WRITE:
 	WriteData(handle, amode, dma, bar, start, size, access, endianess, data, verify);

+ 2 - 2
xml/test/camera.xml

@@ -466,14 +466,14 @@
     <view type="formula">
       <name>formuu2</name>
 	<unit>C</unit>
-      <read_from_register>((1./4)*(@reg - 1200)) if @freq==0 else ((3./10)*(@reg - 1000))</read_from_register>
+      <read_from_register>((1./4)*(@reg + 1200)) if @freq==0 else ((3./10)*(@reg + 1000))</read_from_register>
       <write_to_register>4*@value + 1200 if @freq==0 else (10./3)*@value + 1000</write_to_register>
       <description>formula to get real sensor temperature from the sensor_temperature register in decimal</description>
     </view>
     <view type="enum">
       <name>enumm2</name>
       <enum value="0x120">high</enum>
-      <enum value="0x010" min="0x00" max="0x020">low</enum>
+      <enum value="0x010" min="0x00" max="0x060">low</enum>
 	   <description>enum towards sensor_temperature register</description>
     </view>
     <view type="formula">