Browse Source

Support writting register views

Suren A. Chilingaryan 8 years ago
parent
commit
2e9457b666
10 changed files with 80 additions and 62 deletions
  1. 1 0
      docs/README
  2. 1 1
      docs/ToDo
  3. 10 0
      pcilib/debug.h
  4. 1 0
      pcilib/env.h
  5. 2 0
      pcilib/py.c
  6. 14 2
      pcilib/value.c
  7. 7 8
      pcilib/view.c
  8. 41 48
      pcitool/cli.c
  9. 1 1
      views/transform.c
  10. 2 2
      xml/test/camera.xml

+ 1 - 0
docs/README

@@ -5,6 +5,7 @@ Supported environmental variables
 
  PCILIB_DEBUG_DMA		- Enable DMA debugging
  PCILIB_DEBUG_MISSING_EVENTS	- Enable debugging of missing events (frames for instance)
+ PCILIB_DEBUG_VIEWS             - Enable debugging of computations performed to support register views and units
  IPECAMERA_DEBUG_BROKEN_FRAMES	- Store broken frames in the specified directory (variable may specify directory)
  IPECAMERA_DEBUG_RAW_PACKETS	- Store all raw packets read from DMA grouped in frames (variable may specify directory)
  IPECAMERA_DEBUG_RAW_FRAMES	- Store all raw frames (variable may specify directory)

+ 1 - 1
docs/ToDo

@@ -2,7 +2,7 @@ High Priority (we would need it for IPE Camera)
 =============
  1. Join multiple XML files and on error use simplified XSD scheme on all files to find the file causing error
  2. Universal tree-style api to access the independent views, frontend all registers as well (pci -l /register; pci -r /register/reg1; pci -r /sensor/width;) Unit is path of the view /view[:unit] or just /unit for register vies
- 3. Information on bank and the view values in the pci -i <reg>
+ 3. Information on bank and the view values in the pci -i <reg>, show listing of enum values (shall we have a type associated with the view: enum, range, ...?)
  4. Integrate hash tables for views, units, and registers
  
 Normal Priority (it would make just few things a bit easier)

+ 10 - 0
pcilib/debug.h

@@ -3,12 +3,14 @@
 
 #include <stdarg.h>
 #include <pcilib/env.h>
+#include <pcilib/error.h>
 
 #define PCILIB_DEBUG
 
 #ifdef PCILIB_DEBUG
 # define PCILIB_DEBUG_DMA
 # define PCILIB_DEBUG_MISSING_EVENTS
+# define PCILIB_DEBUG_VIEWS
 #endif /* PCILIB_DEBUG */
 
 
@@ -28,6 +30,14 @@
 # define PCILIB_DEBUG_MISSING_EVENTS_BUFFER(function, ...)
 #endif /* PCILIB_DEBUG_MISSING_EVENTS */
 
+#ifdef PCILIB_DEBUG_VIEWS
+# define PCILIB_DEBUG_VIEWS_MESSAGE(function, ...) if (pcilib_getenv(function##_ENV, #function)) { pcilib_debug_message (#function, __FILE__, __LINE__, __VA_ARGS__); }
+# define PCILIB_DEBUG_VIEWS_BUFFER(function, ...) if (pcilib_getenv(function##_ENV #function)) { pcilib_debug_data_buffer (#function, __VA_ARGS__); }
+#else /* PCILIB_DEBUG_VIEWS */
+# define PCILIB_DEBUG_VIEWS_MESSAGE(function, ...)
+# define PCILIB_DEBUG_VIEWS_BUFFER(function, ...)
+#endif /* PCILIB_DEBUG_VIEWS */
+
 #define pcilib_debug(function, ...) \
     PCILIB_DEBUG_##function##_MESSAGE(PCILIB_DEBUG_##function, PCILIB_LOG_DEFAULT, __VA_ARGS__)
 

+ 1 - 0
pcilib/env.h

@@ -4,6 +4,7 @@
 typedef enum {
     PCILIB_DEBUG_DMA_ENV,
     PCILIB_DEBUG_MISSING_EVENTS_ENV,
+    PCILIB_DEBUG_VIEWS_ENV,
     PCILIB_MAX_ENV
 } pcilib_env_t;
 

+ 2 - 0
pcilib/py.c

@@ -7,6 +7,7 @@
 
 
 #include "pci.h"
+#include "debug.h"
 #include "pcilib.h"
 #include "py.h"
 #include "error.h"
@@ -167,5 +168,6 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
         return PCILIB_ERROR_FAILED;
     }
 
+    pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
     return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
 }

+ 14 - 2
pcilib/value.c

@@ -8,6 +8,7 @@
 #include "value.h"
 #include "error.h"
 #include "unit.h"
+#include "tools.h"
 
 void pcilib_clean_value(pcilib_t *ctx, pcilib_value_t *val) {
     if (!val) return;
@@ -235,11 +236,22 @@ int pcilib_convert_value_type(pcilib_t *ctx, pcilib_value_t *val, pcilib_value_t
      case PCILIB_TYPE_LONG:
         switch (val->type) {
          case PCILIB_TYPE_STRING:
-            if (sscanf(val->sval, "%li", &val->ival) != 1) {
+            if (pcilib_isnumber(val->sval)) {
+                if (sscanf(val->sval, "%li", &val->ival) != 1) {
+                    pcilib_warning("Can't convert string (%s) to int", val->sval);
+                    return PCILIB_ERROR_INVALID_DATA;
+                }
+                val->format = NULL;
+            } else if (pcilib_isxnumber(val->sval)) {
+                if (sscanf(val->sval, "%lx", &val->ival) != 1) {
+                    pcilib_warning("Can't convert string (%s) to int", val->sval);
+                    return PCILIB_ERROR_INVALID_DATA;
+                }
+                val->format = "0x%lx";
+            } else {
                 pcilib_warning("Can't convert string (%s) to int", val->sval);
                 return PCILIB_ERROR_INVALID_DATA;
             }
-            val->format = NULL;
             break;
          case PCILIB_TYPE_DOUBLE:
             val->ival = round(val->fval);

+ 7 - 8
pcilib/view.c

@@ -135,7 +135,7 @@ pcilib_view_context_t *pcilib_find_register_view_context_by_name(pcilib_t *ctx,
 }
 
     // We expect symmetric units. Therefore, we don't distringuish if we read or write
-static int pcilib_detect_register_view_and_unit(pcilib_t *ctx, pcilib_register_t reg, const char *name, pcilib_view_context_t **ret_view, pcilib_unit_transform_t **ret_trans) {
+static int pcilib_detect_register_view_and_unit(pcilib_t *ctx, pcilib_register_t reg, const char *name, int write_direction, pcilib_view_context_t **ret_view, pcilib_unit_transform_t **ret_trans) {
     pcilib_view_t i;
     pcilib_view_context_t *view_ctx;
     pcilib_view_description_t *view_desc;
@@ -160,7 +160,10 @@ static int pcilib_detect_register_view_and_unit(pcilib_t *ctx, pcilib_register_t
 
         view_desc = ctx->views[view_ctx->view];
         if (view_desc->unit) {
-	    trans = pcilib_find_transform_by_unit_names(ctx, view_desc->unit, name);
+            if (write_direction)
+	        trans = pcilib_find_transform_by_unit_names(ctx, name, view_desc->unit);
+            else
+	        trans = pcilib_find_transform_by_unit_names(ctx, view_desc->unit, name);
 	    if (trans) {
 	        if (ret_trans) *ret_trans = trans;
 	        if (ret_view) *ret_view = pcilib_find_view_context_by_name(ctx, view_desc->name);
@@ -176,7 +179,7 @@ pcilib_view_context_t *pcilib_find_register_view_context(pcilib_t *ctx, pcilib_r
     int err;
     pcilib_view_context_t *view;
 
-    err = pcilib_detect_register_view_and_unit(ctx, reg, name, &view, NULL);
+    err = pcilib_detect_register_view_and_unit(ctx, reg, name, 0, &view, NULL);
     if (err) return NULL;
 
     return view;
@@ -214,10 +217,8 @@ static int pcilib_detect_view_configuration(pcilib_t *ctx, const char *bank, con
 	    return PCILIB_ERROR_NOTFOUND;
 	}
 	
-	// get value
-	
 	if (unit_name) view_ctx = pcilib_find_register_view_context_by_name(ctx, reg, view_name);
-	else err = pcilib_detect_register_view_and_unit(ctx, reg, view_name, &view_ctx, &trans);
+	else err = pcilib_detect_register_view_and_unit(ctx, reg, view_name, write_direction, &view_ctx, &trans);
 
 	if ((err)||(!view_ctx)) {
 	    pcilib_error("Can't find the specified view %s for register %s", view_name, regname);
@@ -330,7 +331,6 @@ int pcilib_write_register_view(pcilib_t *ctx, const char *bank, const char *regn
         if (err) return err;
     }
 
-
     err = v->api->write_to_reg(ctx, cfg.view, &regvalue, &val);
     if (err) {
         if (regname) 
@@ -340,7 +340,6 @@ int pcilib_write_register_view(pcilib_t *ctx, const char *bank, const char *regn
         return err;
     }
 
-
     if (regname) {
         err = pcilib_write_register_by_id(ctx, cfg.reg, regvalue);
         if (err) {

+ 41 - 48
pcitool/cli.c

@@ -1144,24 +1144,23 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info,
 
         if (unit) {
             pcilib_value_t val = {0};
-            err = pcilib_read_register_view(handle, bank, model_info->registers[regid].name, unit, &val);
-            if (err) printf("Error reading view %s of register %s\n", unit, reg);
-            else {
-                err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
-                if (err) printf("Error converting view %s of register %s to string\n", unit, reg);
-                else printf("%s = %s\n", reg, val.sval);
-            }
+            err = pcilib_read_register_view(handle, bank, reg, unit, &val);
+            if (err) Error("Error reading view %s of register %s", unit, reg);
+
+            err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
+            if (err) Error("Error converting view %s of register %s to string", unit, reg);
+
+            printf("%s = %s\n", reg, val.sval);
         } else {
             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) printf("Error reading register %s\n", reg);
-            else {
-	        printf("%s = ", reg);
-	        printf(format, value);
-	        printf("\n");
-	    }
+            if (err) Error("Error reading register %s", reg);
+
+	    printf("%s = ", reg);
+	    printf(format, value);
+	    printf("\n");
 	}
     } else {
 	if (model_info->registers) {
@@ -1364,12 +1363,10 @@ int WriteRegisterRange(pcilib_t *handle, const pcilib_model_description_t *model
 }
 
 int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, const char *reg, const char *unit, char **data) {
-    int err;
-
-    unsigned long val;
-    pcilib_register_value_t value;
+    int err = 0;
 
-    const char *format = NULL;
+    pcilib_value_t val = {0};
+    pcilib_register_value_t value, verify;
 
     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");
@@ -1384,42 +1381,38 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info
     if (!format) format = "%lu";
 */
 
-    if (isnumber(*data)) {
-	if (sscanf(*data, "%li", &val) != 1) {
-	    Error("Can't parse data value (%s) is not valid decimal number", *data);
-	}
+    err = pcilib_set_value_from_static_string(handle, &val, *data);
+    if (err) Error("Error (%i) setting value", err);
 
-	format = "%li";
-    } else if (isxnumber(*data)) {
-	if (sscanf(*data, "%lx", &val) != 1) {
-	    Error("Can't parse data value (%s) is not valid decimal number", *data);
-	}
-	
-	format = "0x%lx";
+    if (unit) {
+        err = pcilib_write_register_view(handle, bank, reg, unit, &val);
+        if (err) Error("Error writting view %s of register %s", unit, reg);
+        printf("%s is written\n ", reg);
     } else {
-	    Error("Can't parse data value (%s) is not valid decimal number", *data);
-    }
+        value = pcilib_get_value_as_register_value(handle, &val, &err);
+        if (err) Error("Error (%i) parsing data value (%s)", *data);
 
-    value = val;
-    
-    err = pcilib_write_register(handle, bank, reg, value);
-    if (err) Error("Error writting register %s\n", reg);
+        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);
+        if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) {
+            const char *format = (val.format?val.format:"%u");
+	    
+	    err = pcilib_read_register(handle, bank, reg, &verify);
+	    if (err) Error("Error reading back register %s for verification\n", reg);
     
-	if (val != value) {
-	    Error("Failed to write register %s: %lu is written and %lu is read back", reg, val, value);
-	} else {
-	    printf("%s = ", reg);
-	    printf(format, value);
-	    printf("\n");
-	}
-    } else {
-        printf("%s is written\n ", reg);
+	    if (verify != value) {
+	        Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify);
+	    } else {
+	        printf("%s = ", reg);
+	        printf(format, verify);
+	        printf("\n");
+	    }
+        } else {
+            printf("%s is written\n ", reg);
+        }
     }
-    
+
     return 0;
 }
 

+ 1 - 1
views/transform.c

@@ -36,7 +36,7 @@ static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *vie
     err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy);
     if (err) return err;
 
-    *regval = pcilib_get_value_as_register_value(ctx, val, &err);
+    *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err);
     return err;
 }
 

+ 2 - 2
xml/test/camera.xml

@@ -106,8 +106,8 @@
     <register address="0x1b0" offset="0" size="32" default="0" rwmask="0" mode="R" name="ddr_num_frames"/>
   </bank>
   <bank bar="0" size="0x0200" protocol="software_registers" read_address="0x0" write_address="0x0" word_size="32" endianess="little" format="0x%lx" name="dma" description="DMA Registers"/>
-  <transform name="formuu1" unit="C" read_from_register="(503975./1024000)*$value - 27315./100" write_to_register="($value + 27315./100)*(102400./503975)" description="formula to get real fpga temperature from the fpga_temperature register in decimal"/>
-  <transform name="formuu2" unit="C" read_from_register="((1./4)*($value - 1200)) if $freq==0 else ((3./10)*($value - 1000))" write_to_register="4*$value + 1200 if $freq==0 else (10./3)*$value + 1000" description="formula to get real sensor temperature from the sensor_temperature register in decimal"/>
+  <transform name="formuu1" unit="C" read_from_register="(503975./1024000)*$value - 27315./100" write_to_register="($value + 27315./100)*(1024000./503975)" description="formula to get real fpga temperature from the fpga_temperature register in decimal"/>
+  <transform name="formuu2" unit="C1" read_from_register="((1./4)*($value - 1200)) if $freq==0 else ((3./10)*($value - 1000))" write_to_register="4*$value + 1200 if $freq==0 else (10./3)*$value + 1000" description="formula to get real sensor temperature from the sensor_temperature register in decimal"/>
   <transform name="formuu3" unit="us" read_from_register="($value+(43./100))*129./(40*1000000)if $freq==0 else ($value+(43./100))*129./(48*1000000)" write_to_register="$value/129.*(40*1000000) - 43./100 if $freq==0 else $value/129.*(48*1000000) - 43./100" description="formula to get real exposure time from the cmosis_exp_time register in decimal"/>
   <enum name="enumm1" description="enum towards temperatures register">
     <name name="high" value="0x100" min="0x2" max="0x300"/>