diff options
| author | Suren A. Chilingaryan <csa@suren.me> | 2015-10-13 01:59:17 +0200 | 
|---|---|---|
| committer | Suren A. Chilingaryan <csa@suren.me> | 2015-10-13 01:59:17 +0200 | 
| commit | 2e9457b666a303fab83aa17e33624f39de9a1dd7 (patch) | |
| tree | 7e1b46b4ca64a8eccb7122df33a32c48239d4c62 | |
| parent | 1200eca62c4c47617fa60033f9a0ee25bd26c431 (diff) | |
Support writting register views
| -rw-r--r-- | docs/README | 1 | ||||
| -rw-r--r-- | docs/ToDo | 2 | ||||
| -rw-r--r-- | pcilib/debug.h | 10 | ||||
| -rw-r--r-- | pcilib/env.h | 1 | ||||
| -rw-r--r-- | pcilib/py.c | 2 | ||||
| -rw-r--r-- | pcilib/value.c | 16 | ||||
| -rw-r--r-- | pcilib/view.c | 15 | ||||
| -rw-r--r-- | pcitool/cli.c | 89 | ||||
| -rw-r--r-- | views/transform.c | 2 | ||||
| -rw-r--r-- | xml/test/camera.xml | 4 | 
10 files changed, 80 insertions, 62 deletions
| diff --git a/docs/README b/docs/README index 335ebef..0b9af2b 100644 --- a/docs/README +++ b/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) @@ -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) diff --git a/pcilib/debug.h b/pcilib/debug.h index bc68e1c..3ac0828 100644 --- a/pcilib/debug.h +++ b/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__) diff --git a/pcilib/env.h b/pcilib/env.h index 7cf69b9..880e711 100644 --- a/pcilib/env.h +++ b/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; diff --git a/pcilib/py.c b/pcilib/py.c index 6aaa22f..3a4fd96 100644 --- a/pcilib/py.c +++ b/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));  } diff --git a/pcilib/value.c b/pcilib/value.c index 1a8cc45..42e7993 100644 --- a/pcilib/value.c +++ b/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); diff --git a/pcilib/view.c b/pcilib/view.c index c1ad44a..f00e483 100644 --- a/pcilib/view.c +++ b/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, ®value, &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) { diff --git a/pcitool/cli.c b/pcitool/cli.c index c1442cc..867b65e 100644 --- a/pcitool/cli.c +++ b/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;  } diff --git a/views/transform.c b/views/transform.c index 7bc5420..de7ee0e 100644 --- a/views/transform.c +++ b/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;  } diff --git a/xml/test/camera.xml b/xml/test/camera.xml index 2169bd2..a12d26b 100644 --- a/xml/test/camera.xml +++ b/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"/> | 
