Explorar o código

Provide register listings in public API

Suren A. Chilingaryan %!s(int64=8) %!d(string=hai) anos
pai
achega
8ba85a9aff
Modificáronse 10 ficheiros con 295 adicións e 100 borrados
  1. 1 1
      CMakeLists.txt
  2. 1 1
      docs/ToDo
  3. 52 16
      pcilib/pcilib.h
  4. 88 0
      pcilib/register.c
  5. 1 10
      pcilib/register.h
  6. 8 10
      pcilib/xml.c
  7. 139 56
      pcitool/cli.c
  8. 1 5
      views/enum.h
  9. 1 1
      xml/test/camera.xml
  10. 3 0
      xml/types.xsd

+ 1 - 1
CMakeLists.txt

@@ -1,6 +1,6 @@
 project(pcitool)
 
-set(PCILIB_VERSION "0.2.2")
+set(PCILIB_VERSION "0.2.3")
 set(PCILIB_ABI_VERSION "2")
 
 cmake_minimum_required(VERSION 2.6)

+ 1 - 1
docs/ToDo

@@ -1,7 +1,6 @@
 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. 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, ...?)
  
 Normal Priority (it would make just few things a bit easier)
 ===============
@@ -9,6 +8,7 @@ Normal Priority (it would make just few things a bit easier)
  2. Provide OR and AND operations on registers in cli
  3. Support writting a data from a binary file in cli
  4. Support Python-scripts in a views, we need to provide python function to read registers/properties...
+ 5. Really check the specified min, max values while setting registers
 
 Low Priority (only as generalization for other projects)
 ============

+ 52 - 16
pcilib/pcilib.h

@@ -35,9 +35,9 @@ typedef enum {
 } pcilib_log_priority_t;
 
 typedef enum {
-    PCILIB_HOST_ENDIAN = 0,
-    PCILIB_LITTLE_ENDIAN,
-    PCILIB_BIG_ENDIAN
+    PCILIB_HOST_ENDIAN = 0,                     /**< The same byte ordering as on the host system running the driver */
+    PCILIB_LITTLE_ENDIAN,                       /**< x86 is Little-endian, least significant bytes are at the lower addresses */
+    PCILIB_BIG_ENDIAN                           /**< Old mainframes and network byte order, most significant bytes are at the lower addresses */
 } pcilib_endianess_t;
 
 typedef enum {
@@ -46,6 +46,16 @@ typedef enum {
     PCILIB_ACCESS_RW = 3
 } pcilib_access_mode_t;
 
+typedef enum {
+    PCILIB_REGISTER_R = 1,			/**< reading from register is allowed */
+    PCILIB_REGISTER_W = 2,			/**< normal writting to register is allowed */
+    PCILIB_REGISTER_RW = 3,
+    PCILIB_REGISTER_W1C = 4,			/**< writting 1 resets the bit, writting 0 keeps the value */
+    PCILIB_REGISTER_RW1C = 5,
+    PCILIB_REGISTER_W1I = 8,			/**< writting 1 inversts the bit, writting 0 keeps the value */
+    PCILIB_REGISTER_RW1I = 9,
+} pcilib_register_mode_t;
+
 typedef enum {
     PCILIB_TYPE_INVALID = 0,                    /**< uninitialized */
     PCILIB_TYPE_DEFAULT = 0,			/**< default type */
@@ -102,14 +112,6 @@ typedef enum {
     PCILIB_EVENT_INFO_FLAG_BROKEN = 1		/**< Indicates broken frames (if this flag is fales, the frame still can be broken) */
 } pcilib_event_info_flags_t;
 
-typedef struct {
-    pcilib_event_t type;
-    uint64_t seqnum;				/**< we will add seqnum_overflow if required */
-    uint64_t offset;				/**< nanoseconds */
-    struct timeval timestamp;			/**< most accurate timestamp */
-    pcilib_event_info_flags_t flags;		/**< flags */
-} pcilib_event_info_t;
-
 typedef enum {
     PCILIB_LIST_FLAGS_DEFAULT = 0,
     PCILIB_LIST_FLAG_CHILDS = 1                 /**< Request all sub-elements or indicated that sub-elements are available */
@@ -132,6 +134,27 @@ typedef struct {
     char str[16];                               /**< Used for shorter strings converted from integer/float types */
 } pcilib_value_t;
 
+typedef struct {
+    pcilib_register_value_t min, max;           /**< Minimum and maximum allowed values */
+} pcilib_register_value_range_t;
+
+typedef struct {
+    pcilib_register_value_t value;              /**< This value will get assigned instead of the name */
+    pcilib_register_value_t min, max;	        /**< the values in the specified range are aliased by name */
+    const char *name; 				/**< corresponding string to value */
+} pcilib_register_value_name_t;
+
+typedef struct {
+    pcilib_register_t id;                       /**< Direct register ID which can be used in API calls */
+    const char *name;                           /**< The access name of the register */
+    const char *description;                    /**< Brief description of the register */
+    const char *bank;                           /**< The name of the bank register belongs to */
+    pcilib_register_mode_t mode;                /**< Register access (ro/wo/rw) and how writting to register works (clearing/inverting set bits) */
+    pcilib_register_value_t defvalue;           /**< Default register value */
+    const pcilib_register_value_range_t *range; /**< Specifies default, minimum, and maximum values */
+    const pcilib_register_value_name_t *values; /**< The list of enum names for the register value */
+} pcilib_register_info_t;
+
 typedef struct {
     const char *name;                           /**< Name of the property view */
     const char *path;                           /**< Full path to the property */
@@ -142,6 +165,14 @@ typedef struct {
     const char *unit;                           /**< Returned unit (if any) */
 } pcilib_property_info_t;
 
+typedef struct {
+    pcilib_event_t type;
+    uint64_t seqnum;				/**< we will add seqnum_overflow if required */
+    uint64_t offset;				/**< nanoseconds */
+    struct timeval timestamp;			/**< most accurate timestamp */
+    pcilib_event_info_flags_t flags;		/**< flags */
+} pcilib_event_info_t;
+
 
 #define PCILIB_BAR_DETECT 		((pcilib_bar_t)-1)
 #define PCILIB_BAR_INVALID		((pcilib_bar_t)-1)
@@ -194,11 +225,19 @@ extern "C" {
 #endif
 
 
+
 int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, void *arg);
 
 pcilib_t *pcilib_open(const char *device, const char *model);
 void pcilib_close(pcilib_t *ctx);
 
+pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *branch, pcilib_list_flags_t flags);
+void pcilib_free_property_info(pcilib_t *ctx, pcilib_property_info_t *info);
+pcilib_register_info_t *pcilib_get_register_list(pcilib_t *ctx, const char *bank, pcilib_list_flags_t flags);
+pcilib_register_info_t *pcilib_get_register_info(pcilib_t *ctx, const char *req_bank_name, const char *req_reg_name, pcilib_list_flags_t flags);
+void pcilib_free_register_info(pcilib_t *ctx, pcilib_register_info_t *info);
+
+
 int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
 int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
 
@@ -243,6 +282,8 @@ int pcilib_read_register_view(pcilib_t *ctx, const char *bank, const char *regna
 int pcilib_write_register_view(pcilib_t *ctx, const char *bank, const char *regname, const char *unit, const pcilib_value_t *value);
 int pcilib_read_register_view_by_id(pcilib_t *ctx, pcilib_register_t reg, const char *view, pcilib_value_t *val);
 int pcilib_write_register_view_by_id(pcilib_t *ctx, pcilib_register_t reg, const char *view, const pcilib_value_t *valarg);
+int pcilib_get_property(pcilib_t *ctx, const char *prop, pcilib_value_t *val);
+int pcilib_set_property(pcilib_t *ctx, const char *prop, const pcilib_value_t *val);
 
 void pcilib_clean_value(pcilib_t *ctx, pcilib_value_t *val);
 int pcilib_copy_value(pcilib_t *ctx, pcilib_value_t *dst, const pcilib_value_t *src);
@@ -256,11 +297,6 @@ pcilib_register_value_t pcilib_get_value_as_register_value(pcilib_t *ctx, const
 int pcilib_convert_value_unit(pcilib_t *ctx, pcilib_value_t *val, const char *unit_name);
 int pcilib_convert_value_type(pcilib_t *ctx, pcilib_value_t *val, pcilib_value_type_t type);
 
-pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *branch, pcilib_list_flags_t flags);
-void pcilib_free_property_info(pcilib_t *ctx, pcilib_property_info_t *info);
-int pcilib_get_property(pcilib_t *ctx, const char *prop, pcilib_value_t *val);
-int pcilib_set_property(pcilib_t *ctx, const char *prop, const pcilib_value_t *val);
-
 int pcilib_get_property_attr(pcilib_t *ctx, const char *prop, const char *attr, pcilib_value_t *val);
 int pcilib_get_register_attr_by_id(pcilib_t *ctx, pcilib_register_t reg, const char *attr, pcilib_value_t *val);
 int pcilib_get_register_attr(pcilib_t *ctx, const char *bank, const char *regname, const char *attr, pcilib_value_t *val);

+ 88 - 0
pcilib/register.c

@@ -19,6 +19,7 @@
 #include "tools.h"
 #include "error.h"
 #include "property.h"
+#include "views/enum.h"
 
 int pcilib_add_registers(pcilib_t *ctx, pcilib_model_modification_flags_t flags, size_t n, const pcilib_register_description_t *registers, pcilib_register_t *ids) {
 	// DS: Overrride existing registers 
@@ -414,3 +415,90 @@ int pcilib_get_register_attr(pcilib_t *ctx, const char *bank, const char *regnam
 
     return pcilib_get_register_attr_by_id(ctx, reg, attr, val);
 }
+
+pcilib_register_info_t *pcilib_get_register_info(pcilib_t *ctx, const char *req_bank_name, const char *req_reg_name, pcilib_list_flags_t flags) {
+    pcilib_register_t i, from, to, pos = 0;
+    pcilib_register_info_t *info;
+    pcilib_register_bank_t bank;
+    pcilib_register_bank_addr_t bank_addr;
+    const char *bank_name;
+
+    info = (pcilib_register_info_t*)malloc((ctx->num_reg + 1) * sizeof(pcilib_register_info_t));
+    if (!info) return NULL;
+
+    if (req_bank_name) {
+        bank = pcilib_find_register_bank_by_name(ctx, req_bank_name);
+        if (bank == PCILIB_REGISTER_BANK_INVALID) {
+            pcilib_error("The specified bank (%s) is not found", req_bank_name);
+            return NULL;
+        }
+        bank_addr = ctx->banks[bank].addr;
+        bank_name = req_bank_name;
+    } else {
+        bank_addr = PCILIB_REGISTER_BANK_INVALID;
+        bank_name = NULL;
+    }
+
+    if (req_reg_name) {
+        pcilib_register_t reg = pcilib_find_register(ctx, req_bank_name, req_reg_name);
+        if (reg == PCILIB_REGISTER_INVALID) {
+            pcilib_error("The specified register (%s) is not found", req_reg_name);
+            return NULL;
+        }
+        from = reg;
+        to = reg + 1;
+    } else {
+        from = 0;
+        to = ctx->num_reg;
+    }
+
+    for (i = from; i < to; i++) {
+        const pcilib_register_value_range_t *range = &ctx->register_ctx[i].range;
+        const pcilib_register_value_name_t *names = NULL;
+
+        if (req_bank_name) {
+            if (ctx->registers[i].bank != bank_addr) continue;
+        } else {
+            if (ctx->registers[i].bank != bank_addr) {
+                bank_addr = ctx->registers[i].bank;
+                bank = pcilib_find_register_bank_by_addr(ctx, bank_addr);
+                if (bank == PCILIB_REGISTER_BANK_INVALID) bank_name = NULL;
+                else bank_name = ctx->banks[bank].name;
+            }
+        }
+
+        if (ctx->registers[i].views) {
+            int j;
+            for (j = 0; ctx->registers[i].views[j].view; j++) {
+                pcilib_view_t view = pcilib_find_view_by_name(ctx, ctx->registers[i].views[j].view);
+                if ((view != PCILIB_VIEW_INVALID)&&((ctx->views[view]->api == &pcilib_enum_view_xml_api)||(ctx->views[view]->api == &pcilib_enum_view_static_api)))
+                    names = ((pcilib_enum_view_description_t*)(ctx->views[view]))->names;
+            }
+        }
+
+        if (range->min == range->max) 
+            range = NULL;
+
+        info[pos++] = (pcilib_register_info_t){
+            .id = i,
+            .name = ctx->registers[i].name,
+            .description = ctx->registers[i].description,
+            .bank = bank_name,
+            .mode = ctx->registers[i].mode,
+            .defvalue = ctx->registers[i].defvalue,
+            .range = range,
+            .values = names
+        };
+    }
+    memset(&info[pos], 0, sizeof(pcilib_register_info_t));
+    return info;
+}
+
+pcilib_register_info_t *pcilib_get_register_list(pcilib_t *ctx, const char *req_bank_name, pcilib_list_flags_t flags) {
+    return pcilib_get_register_info(ctx, req_bank_name, NULL, flags);
+}
+
+void pcilib_free_register_info(pcilib_t *ctx, pcilib_register_info_t *info) {
+    if (info)
+        free(info);
+}

+ 1 - 10
pcilib/register.h

@@ -9,15 +9,6 @@
 #define PCILIB_REGISTER_NO_BITS			0
 #define PCILIB_REGISTER_ALL_BITS		((pcilib_register_value_t)-1)
 
-typedef enum {
-    PCILIB_REGISTER_R = 1,			/**< reading from register is allowed */
-    PCILIB_REGISTER_W = 2,			/**< normal writting to register is allowed */
-    PCILIB_REGISTER_RW = 3,
-    PCILIB_REGISTER_W1C = 4,			/**< writting 1 resets the bit, writting 0 keeps the value */
-    PCILIB_REGISTER_RW1C = 5,
-    PCILIB_REGISTER_W1I = 8,			/**< writting 1 inversts the bit, writting 0 keeps the value */
-    PCILIB_REGISTER_RW1I = 9,
-} pcilib_register_mode_t;
 
 typedef enum {
     PCILIB_REGISTER_STANDARD = 0,
@@ -55,7 +46,7 @@ typedef struct {
     const char *name;                                                                   /**< Register name */
     pcilib_register_t reg;                                                              /**< Register index */
     pcilib_register_bank_t bank;							/**< Reference to bank containing the register */
-    pcilib_register_value_t min, max;							/**< Minimum & maximum allowed values */
+    pcilib_register_value_range_t range;						/**< Minimum & maximum allowed values */
     pcilib_xml_node_t *xml;								/**< Additional XML properties */
     pcilib_view_reference_t *views;							/**< For non-static list of views, this vairables holds a copy of a NULL-terminated list from model (if present, memory should be de-allocated) */
     UT_hash_handle hh;

+ 8 - 10
pcilib/xml.c

@@ -61,7 +61,7 @@ static const char *pcilib_xml_enum_view_unit = "name";
 
 typedef struct {
     pcilib_register_description_t base;
-    pcilib_register_value_t min, max;
+    pcilib_register_value_range_t range;
 } pcilib_xml_register_description_t;
 
 /*
@@ -156,14 +156,14 @@ static int pcilib_xml_parse_register(pcilib_t *ctx, pcilib_xml_register_descript
                 pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value);
                 return PCILIB_ERROR_INVALID_DATA;
             }
-            xml_desc->min = min;
+            xml_desc->range.min = min;
         } else if (!strcasecmp(name, "max")) {
             pcilib_register_value_t max = strtol(value, &endptr, 0);
             if ((strlen(endptr) > 0)) {
                 pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value);
                 return PCILIB_ERROR_INVALID_DATA;
             }
-            xml_desc->max = max;
+            xml_desc->range.max = max;
         } else if (!strcasecmp((char*)name,"rwmask")) {
             if (!strcasecmp(value, "all")) {
                 desc->rwmask = PCILIB_REGISTER_ALL_BITS;
@@ -275,8 +275,7 @@ static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank
     }
 
     ctx->register_ctx[reg].xml = node;
-    ctx->register_ctx[reg].min = desc.min;
-    ctx->register_ctx[reg].max = desc.max;
+    memcpy(&ctx->register_ctx[reg].range, &desc.range, sizeof(pcilib_register_value_range_t));
     ctx->register_ctx[reg].views = desc.base.views;
 
 
@@ -319,8 +318,7 @@ static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank
             }
 
             ctx->register_ctx[reg].xml = nodeset->nodeTab[i];
-            ctx->register_ctx[reg].min = fdesc.min;
-            ctx->register_ctx[reg].max = fdesc.max;
+            memcpy(&ctx->register_ctx[reg].range, &fdesc.range, sizeof(pcilib_register_value_range_t));
             ctx->register_ctx[reg].views = fdesc.base.views;
         }
     }
@@ -563,7 +561,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
 }
 
 
-static int pcilib_xml_parse_value_name(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_value_name_t *desc) {
+static int pcilib_xml_parse_value_name(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_register_value_name_t *desc) {
     xmlAttr *cur;
     char *value, *name;
     char *endptr;
@@ -660,7 +658,7 @@ static int pcilib_xml_create_enum_view(pcilib_t *ctx, xmlXPathContextPtr xpath,
 	return PCILIB_ERROR_INVALID_DATA; 
     }
 
-    desc.names = (pcilib_value_name_t*)malloc((nodeset->nodeNr + 1) * sizeof(pcilib_value_name_t));
+    desc.names = (pcilib_register_value_name_t*)malloc((nodeset->nodeNr + 1) * sizeof(pcilib_register_value_name_t));
     if (!desc.names) {
 	xmlXPathFreeObject(nodes);
 	pcilib_error("No names is defined for enum view (%s)", desc.base.name);
@@ -676,7 +674,7 @@ static int pcilib_xml_create_enum_view(pcilib_t *ctx, xmlXPathContextPtr xpath,
 	    return err;
 	}
     }
-    memset(&desc.names[nodeset->nodeNr], 0, sizeof(pcilib_value_name_t));
+    memset(&desc.names[nodeset->nodeNr], 0, sizeof(pcilib_register_value_name_t));
 
     xmlXPathFreeObject(nodes);
 

+ 139 - 56
pcitool/cli.c

@@ -32,6 +32,8 @@
 #include "pcitool/sysinfo.h"
 #include "pcitool/formaters.h"
 
+#include "views/transform.h"
+#include "views/enum.h"
 #include "pci.h"
 #include "plugin.h"
 #include "config.h"
@@ -659,10 +661,114 @@ void List(pcilib_t *handle, const pcilib_model_description_t *model_info, const
     }
 }
 
-void RegisterInfo(pcilib_t *handle, pcilib_register_t reg) {
+void ViewInfo(pcilib_t *handle, pcilib_register_t reg, size_t id) {
     int err;
+
+    int i;
     pcilib_value_t val = {0};
+    pcilib_register_value_name_t *vnames;
+
+    pcilib_view_t view;
+    const pcilib_model_description_t *model_info = pcilib_get_model_description(handle);
+    const pcilib_register_description_t *r;
+    const pcilib_view_description_t *v;
+
+    if (reg == PCILIB_REGISTER_INVALID) {
+        r = NULL;
+        view = id;
+    } else {
+        r = &model_info->registers[reg];
+        view = pcilib_find_view_by_name(handle, r->views[id].view);
+    }
+
+    if (view == PCILIB_VIEW_INVALID) return;
+    v = model_info->views[view];
+
+    if (r) {
+        printf("  View %s (", r->views[id].name);
+    } else {
+        printf("%s\n", v->name);
+        printf("    Data type      : ");
+    }
+    switch (v->type) {
+	case PCILIB_TYPE_STRING:
+	    printf("char*");
+	    break;
+	case PCILIB_TYPE_DOUBLE:
+	    printf("double");
+	    break;
+	case PCILIB_TYPE_LONG:
+	    printf("long");
+	    break;
+	default:
+	    printf("unknown");
+    }
+    if (r) printf(")");
+    printf("\n");
+
+    if (r) {
+        err = pcilib_read_register_view_by_id(handle, reg, r->views[id].name, &val);
+    } else {
+        err = pcilib_get_property(handle, v->name, &val);
+    }
+    if (!err) err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
+
+    if (err)
+        printf("    Current value  : error %i\n", err);
+    else {
+        printf("    Current value  : %s", val.sval);
+        if (v->unit) printf(" (units: %s)", v->unit);
+        printf("\n");
+    }
+
+    if (v->unit) {
+	pcilib_unit_t unit = pcilib_find_unit_by_name(handle, v->unit);
+
+	printf("    Supported units: %s", v->unit);
+
+	if (unit != PCILIB_UNIT_INVALID) {
+	    const pcilib_unit_description_t *u = &model_info->units[unit];
+
+	    for (i = 0; u->transforms[i].unit; i++)
+		printf(", %s", u->transforms[i].unit);
+	}
+	printf("\n");
+    }
+
+    printf("    Access         : ");
+    if ((v->mode&PCILIB_REGISTER_RW) == 0) printf("-");
+    if (v->mode&PCILIB_REGISTER_R) printf("R");
+    if (v->mode&PCILIB_REGISTER_W) printf("W");
+    printf("\n");
+
+    if ((v->api == &pcilib_enum_view_static_api)||(v->api == &pcilib_enum_view_xml_api)) {
+	vnames = ((pcilib_enum_view_description_t*)v)->names;
+        printf("    Value aliases  :");
+	for (i = 0; vnames[i].name; i++) {
+	    if (i) printf(",");
+	    printf(" %s = %u", vnames[i].name, vnames[i].value);
+	    if (vnames[i].min != vnames[i].max) 
+	        printf(" (%u - %u)", vnames[i].min, vnames[i].max);
+	}
+	printf("\n");
+    } else if (v->api == &pcilib_transform_view_api) {
+	const pcilib_transform_view_description_t *tv = (const pcilib_transform_view_description_t*)v;
+	if (tv->read_from_reg)
+            printf("    Read function  : %s\n", tv->read_from_reg);
+	if (tv->write_to_reg)
+            printf("    Write function : %s\n", tv->write_to_reg);
+    }
+
+    if (v->description)
+	printf("    Description    : %s\n", v->description);
+}
+
+void RegisterInfo(pcilib_t *handle, pcilib_register_t reg) {
+    int err;
+
+    int i;
     pcilib_register_value_t regval;
+    pcilib_register_info_t *info;
 
     const pcilib_model_description_t *model_info = pcilib_get_model_description(handle);
     const pcilib_register_description_t *r = &model_info->registers[reg];
@@ -670,7 +776,9 @@ void RegisterInfo(pcilib_t *handle, pcilib_register_t reg) {
     const pcilib_register_bank_description_t *b = &model_info->banks[bank];
 
     err = pcilib_read_register_by_id(handle, reg, &regval);
-    
+
+    info = pcilib_get_register_info(handle, b->name, r->name, 0);
+    if (!info) Error("Can't obtain register info for %s", r->name);
 
     printf("%s/%s\n", b->name, r->name);
     printf("  Current value: ");
@@ -680,11 +788,23 @@ void RegisterInfo(pcilib_t *handle, pcilib_register_t reg) {
     if (r->mode&PCILIB_REGISTER_W) {
 	printf(" (default: ");
 	printf(b->format, r->defvalue);
+	if (info->range) {
+	    printf(", range: ");
+	    printf(b->format, info->range->min);
+	    printf (" - ");
+	    printf(b->format, info->range->max);
+	}
 	printf(")");
     }
     printf("\n");
 
     printf("  Address      : 0x%x [%u:%u]\n", r->addr, r->offset, r->offset + r->bits);
+    if ((info->values)&&(info->values[0].name)) {
+        printf("  Value aliases:");
+        for (i = 0; info->values[i].name; i++)
+            printf(" %s", info->values[i].name);
+        printf("\n");
+    }
     printf("  Access       : ");
     if ((r->mode&PCILIB_REGISTER_RW) == 0) printf("-");
     if (r->mode&PCILIB_REGISTER_R) printf("R");
@@ -698,60 +818,13 @@ void RegisterInfo(pcilib_t *handle, pcilib_register_t reg) {
 	printf("  Description  : %s\n", r->description);
 
     if (r->views) {
-	int i;
 	printf("\nSupported Views:\n");
 	for (i = 0; r->views[i].name; i++) {
-	    pcilib_view_t view = pcilib_find_view_by_name(handle, r->views[i].view);
-	    if (view == PCILIB_VIEW_INVALID) continue;
-
-	    const pcilib_view_description_t *v = model_info->views[view];
-
-	    printf("  View %s (", r->views[i].name);
-	    switch (v->type) {
-		case PCILIB_TYPE_STRING:
-		    printf("char*");
-		    break;
-		case PCILIB_TYPE_DOUBLE:
-		    printf("double");
-		    break;
-		default:
-		    printf("unknown");
-	    }
-	    printf(")\n");
-
-            err = pcilib_read_register_view(handle, b->name, r->name, r->views[i].name, &val);
-            if (!err) err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
-
-            if (err)
-                printf("    Current value  : error %i\n", err);
-            else {
-                printf("    Current value  : %s", val.sval);
-                if (v->unit) printf(" (units: %s)", v->unit);
-                printf("\n");
-            }
-
-	    if (v->unit) {
-	        pcilib_unit_t unit = pcilib_find_unit_by_name(handle, v->unit);
-
-	        printf("    Supported units: %s", v->unit);
-
-		if (unit != PCILIB_UNIT_INVALID) {
-		    int j;
-		    const pcilib_unit_description_t *u = &model_info->units[unit];
-
-		    for (j = 0; u->transforms[j].unit; j++)
-			printf(", %s", u->transforms[j].unit);
-		}
-		printf("\n");
-	    }
-
-	    if (v->description)
-	        printf("    Description    : %s\n", v->description);
+            ViewInfo(handle, reg, i);
 	}
     }
 
-
-//    printf("Type: %s". r->rw
+    pcilib_free_register_info(handle, info);
 }
 
 void Info(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *target) {
@@ -780,13 +853,23 @@ void Info(pcilib_t *handle, const pcilib_model_description_t *model_info, const
     printf("\n");
 
     if (target) {
-	pcilib_register_t reg;
+	if (*target == '/') {
+	    pcilib_view_t view;
+	    view = pcilib_find_view_by_name(handle, target);
+	    if (view != PCILIB_VIEW_INVALID)
+	        return ViewInfo(handle, PCILIB_REGISTER_INVALID, view);
+
+	    Error(" No property %s is found", target);
+	} else {
+	    pcilib_register_t reg;
 	
-	reg = pcilib_find_register(handle, NULL, target);
-	if (reg != PCILIB_REGISTER_INVALID) 
-	    return RegisterInfo(handle, reg);
+	    reg = pcilib_find_register(handle, NULL, target);
+	    if (reg != PCILIB_REGISTER_INVALID) 
+	        return RegisterInfo(handle, reg);
+
+	    Error(" No register %s is found", target);
+	}
 	
-	Error(" No register %s is found", target);
     }
 
     List(handle, model_info, (char*)-1, 0);

+ 1 - 5
views/enum.h

@@ -4,14 +4,10 @@
 #include <pcilib.h>
 #include <pcilib/view.h>
 
-typedef struct {
-    pcilib_register_value_t value, min, max;	/**< the value or value-range for which the name is defined, while wrtiting the name the value will be used even if range is specified */
-    const char *name; 				/**< corresponding string to value */
-} pcilib_value_name_t;
 
 typedef struct {
     pcilib_view_description_t base;
-    pcilib_value_name_t *names;
+    pcilib_register_value_name_t *names;
 } pcilib_enum_view_description_t;
 
 

+ 1 - 1
xml/test/camera.xml

@@ -83,7 +83,7 @@
     <register address="0xd0" offset="21" size="11" default="0" rwmask="all" mode="RW" name="fr_num_lines_thr"/>
     <register address="0x100" offset="0" size="32" default="0" rwmask="0" mode="RW" name="rawdata_pkt_addr"/>
     <register address="0x110" offset="0" size="32" default="0" rwmask="0" mode="R" name="temperature_info">
-      <field offset="0" size="16" mode="R" name="sensor_temperature"><view view="formuu1"/><view view="formuu2"/><view view="enumm2"/></field>
+      <field offset="0" size="16" mode="RW" name="sensor_temperature" min="5" max="15"><view view="formuu1"/><view view="formuu2"/><view view="enumm2"/></field>
       <field offset="16" size="3" mode="R" name="sensor_temperature_alarms"/>
       <field offset="19" size="10" mode="RW" name="fpga_temperature"><view view="formuu1"/><view view="enumm1"/></field>
       <field offset="29" size="3" mode="R" name="fpga_temperature_alarms"/>

+ 3 - 0
xml/types.xsd

@@ -41,6 +41,9 @@
       </xsd:sequence>
       <xsd:attribute name="offset" type="uint8_t"/>
       <xsd:attribute name="size" type="uint8_t"/>
+      <xsd:attribute name="default" type="pcilib_register_value_t" default="0" />
+      <xsd:attribute name="min" type="pcilib_register_value_t" />
+      <xsd:attribute name="max" type="pcilib_register_value_t"/>
       <xsd:attribute name="mode" type="pcilib_register_mode_t"/>
       <xsd:attribute name="name" type="xsd:ID" use="required" />
       <xsd:attribute name="description" type="xsd:string" />