summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicolas.zilio@hotmail.fr <>2015-09-14 15:49:46 +0200
committernicolas.zilio@hotmail.fr <>2015-09-14 15:49:46 +0200
commita1bf5e300e2345b642d0a13e7e26d22c56156e47 (patch)
tree35f55b62ab50bfbbb47bd8911aa3ca24c405e0a1
parent2dfb23016c39a331bf5ed4111b630dffa330edbb (diff)
downloadpcitool-a1bf5e300e2345b642d0a13e7e26d22c56156e47.tar.gz
pcitool-a1bf5e300e2345b642d0a13e7e26d22c56156e47.tar.bz2
pcitool-a1bf5e300e2345b642d0a13e7e26d22c56156e47.tar.xz
pcitool-a1bf5e300e2345b642d0a13e7e26d22c56156e47.zip
views with units functionnal (beware, as formulas are completely crap now, we could get segfault, for example if we want to write a negative value in register)
-rw-r--r--pcilib/views.c148
-rw-r--r--pcilib/views.h6
-rw-r--r--pcilib/xml.c97
-rw-r--r--pcitool/cli.c20
-rw-r--r--xml/model.xsd24
-rw-r--r--xml/test/camera.xml34
6 files changed, 221 insertions, 108 deletions
diff --git a/pcilib/views.c b/pcilib/views.c
index c9ad4d3..1f26b52 100644
--- a/pcilib/views.c
+++ b/pcilib/views.c
@@ -109,38 +109,6 @@ 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
@@ -160,7 +128,7 @@ pcilib_view_get_bank_from_reg_name(pcilib_t* ctx,char* reg_name){
* replace plain registers name in a formula by their value
*/
static char*
-pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula){
+pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula, int direction){
int j,k;
char *substr, *substr2;
char temp[66];
@@ -175,15 +143,24 @@ pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula){
}
substr2=pcilib_view_str_sub((char*)formula,j,k-1); /**< we get the name of the register+@*/
substr=pcilib_view_str_sub(substr2,1,k-j/*length of substr2*/); /**< we get the name of the register*/
-
- if((strcasecmp(substr,"reg"))){
+ if(direction==0){
+ if((strcasecmp(substr,"reg"))){
/* we get the bank name associated to the register, and read its value*/
pcilib_read_register(ctx, pcilib_view_get_bank_from_reg_name(ctx, substr),substr,&value);
/* we put the value in formula*/
sprintf(temp,"%i",value);
formula = pcilib_view_formula_replace(formula,substr2,temp);
+ }
}
-
+ else if(direction==1){
+ if((strcasecmp(substr,"value"))){
+ /* we get the bank name associated to the register, and read its value*/
+ pcilib_read_register(ctx, pcilib_view_get_bank_from_reg_name(ctx, substr),substr,&value);
+ /* we put the value in formula*/
+ sprintf(temp,"%i",value);
+ formula = pcilib_view_formula_replace(formula,substr2,temp);
+ }
+ }
}
}
return formula;
@@ -197,8 +174,6 @@ pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula){
static pcilib_register_value_t
pcilib_view_eval_formula(char* formula){
- // setenv("PYTHONPATH",".",1);
-
/* initialization of python interpreter*/
Py_Initialize();
@@ -217,9 +192,27 @@ pcilib_view_eval_formula(char* formula){
return value;
}
+/**
+ * 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] unit - the requested unit in which we want to get the value
+ *@param[in,out] value - the number that needs to get transformed
+ */
+static void
+pcilib_view_apply_unit(pcilib_transform_unit_t unit_desc, const char* unit,pcilib_register_value_t* value){
+ char* formula;
+ char temp[66];
+
+ formula=malloc(strlen(unit_desc.transform_formula)*sizeof(char));
+ strcpy(formula,unit_desc.transform_formula);
+ sprintf(temp,"%i",*value);
+ formula=pcilib_view_formula_replace(formula,"@self",temp);
+ *value=(int)pcilib_view_eval_formula(formula);
+}
+
static void
-pcilib_view_apply_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t reg_value, pcilib_register_value_t* out_value)
+pcilib_view_apply_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t reg_value, pcilib_register_value_t* out_value, int direction)
{
/* when applying a formula, we need to:
1) compute the values of all registers present in plain name in the formulas and replace their name with their value : for example, if we have the formula" ((1./4)*(@reg - 1200)) if @freq==0 else ((3./10)*(@reg - 1000)) " we need to get the value of the register "freq"
@@ -237,15 +230,15 @@ pcilib_view_apply_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t
sprintf(reg_value_string,"%u",reg_value);
/*computation of plain registers in the formula*/
- formula=pcilib_view_compute_plain_registers(ctx,formula);
+ formula=pcilib_view_compute_plain_registers(ctx,formula,direction);
/* computation of @reg with register value*/
- formula=pcilib_view_formula_replace(formula,"@reg",reg_value_string);
+ if(direction==0) formula=pcilib_view_formula_replace(formula,"@reg",reg_value_string);
+ else if (direction==1) formula=pcilib_view_formula_replace(formula,"@value",reg_value_string);
/* evaluation of the formula*/
*out_value= pcilib_view_eval_formula(formula);
-
}
-int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value)
+int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *unit, size_t value_size, void *value)
{
int i,j,err=0;
pcilib_register_value_t temp_value;
@@ -265,13 +258,13 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const
}
/*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*/
- if(!(view)){
+ if(!(unit)){
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=(char*)realloc(value,sizeof(value_size));
if(!(value)){
- pcilib_error("can't allocate memory for the returning value of the view %s",view);
+ pcilib_error("can't allocate memory for the returning value of the view");
return PCILIB_ERROR_MEMORY;
}
/* in the case the value of register is between min and max, then we return the correponding enum command*/
@@ -287,15 +280,33 @@ 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;
- if(!(strcasecmp(ctx->register_ctx[i].formulas[0].name,view))){
+ if(!(strcasecmp(unit, ctx->register_ctx[i].formulas[0].base_unit.name))){
+ formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].read_formula));
+ if(!(formula)){
+ pcilib_error("can't allocate memory for the formula");
+ return PCILIB_ERROR_MEMORY;
+ }
+ strncpy(formula,ctx->register_ctx[i].formulas[0].read_formula,strlen(ctx->register_ctx[i].formulas[0].read_formula));
+ pcilib_view_apply_formula(ctx,formula,temp_value,value,0);
+ value_size=sizeof(int);
+ return 0;
+ }
+
+ for(j=0; ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name;j++){
+ if(!(strcasecmp(ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name,unit))){
/* 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));
- // pcilib_view_apply_formula(ctx, ctx->register_ctx[i].formulas[j].read_formula,temp_value,value);
- pcilib_view_apply_formula(ctx, formula,temp_value,value);
+ formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].read_formula));
+ if(!(formula)){
+ pcilib_error("can't allocate memory for the formula");
+ return PCILIB_ERROR_MEMORY;
+ }
+ strncpy(formula,ctx->register_ctx[i].formulas[0].read_formula,strlen(ctx->register_ctx[i].formulas[0].read_formula));
+ pcilib_view_apply_formula(ctx,formula,temp_value,value,0);
+ pcilib_view_apply_unit(ctx->register_ctx[i].formulas[0].base_unit.other_units[j],unit,value);
value_size=sizeof(int);
return 0;
}
+ }
pcilib_warning("the view asked and the register do not correspond");
return PCILIB_ERROR_NOTAVAILABLE;
@@ -305,11 +316,11 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const
/**
* function to write to a register using a view
*/
-int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view, size_t value_size,void* value/*, const char *unit*/){
+int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *unit, size_t value_size,void* value){
int i,j;
pcilib_register_value_t temp_value;
char *formula;
-
+
/* we get the index of the register to find the corresponding register context*/
if((i=pcilib_find_register(ctx,bank,regname))==PCILIB_REGISTER_INVALID){
pcilib_error("can't get the index of the register %s", regname);
@@ -318,28 +329,37 @@ int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, cons
/*here, in the case of views of type enum, view will correspond to the enum command.
we iterate so through the views of type enum to get the value corresponding to the enum command*/
- for(j=0; ctx->register_ctx[i].enums[j].value;j++){
- if(!(strcasecmp(ctx->register_ctx[i].enums[j].name,view))){
+ for(j=0; ctx->register_ctx[i].enums[j].name;j++){
+ /* we should maybe have another to do it there*/
+ if(!(strcasecmp(ctx->register_ctx[i].enums[j].name,unit))){
pcilib_write_register(ctx,bank,regname,ctx->register_ctx[i].enums[j].value);
return 0;
}
}
-
+
/** 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 in view, and the value we want to write in value*/
j=0;
- while((ctx->register_ctx[i].formulas[j].name)){
- if(!(strcasecmp(ctx->register_ctx[i].formulas[j].name,view))){
+ if(!(strcasecmp(unit, ctx->register_ctx[i].formulas[0].base_unit.name))){
+ formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].write_formula));
+ strncpy(formula,ctx->register_ctx[i].formulas[0].write_formula,strlen(ctx->register_ctx[i].formulas[0].write_formula));
+ pcilib_view_apply_formula(ctx,formula,*(pcilib_register_value_t*)value,&temp_value,1);
+ pcilib_write_register(ctx,bank,regname,temp_value);
+ return 0;
+ }
+
+ for(j=0; ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name;j++){
+ if(!(strcasecmp(ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name,unit))){
/* 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].write_formula));
- strncpy(formula,ctx->register_ctx[i].formulas[j].write_formula,strlen(ctx->register_ctx[i].formulas[j].write_formula));
- // pcilib_view_apply_formula(ctx, ctx->register_ctx[i].formulas[j].write_formula,(pcilib_register_value_t*)value,temp_value);
- pcilib_view_apply_formula(ctx,formula,*(pcilib_register_value_t*)value,&temp_value);
+ formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].write_formula));
+ strncpy(formula,ctx->register_ctx[i].formulas[0].write_formula,strlen(ctx->register_ctx[i].formulas[0].write_formula));
+ pcilib_view_apply_unit(ctx->register_ctx[i].formulas[0].base_unit.other_units[j],unit,value);
+ pcilib_view_apply_formula(ctx,formula,*(pcilib_register_value_t*)value,&temp_value,1);
+ /* we maybe need some error checking there , like temp_value >min and <max*/
pcilib_write_register(ctx,bank,regname,temp_value);
return 0;
}
- j++;
}
- pcilib_warning("the view asked and the register do not correspond");
+ pcilib_error("the view asked and the register do not correspond");
return PCILIB_ERROR_NOTAVAILABLE;
}
@@ -384,7 +404,7 @@ int pcilib_add_views_formula(pcilib_t *ctx, size_t n, const pcilib_view_formula_
size_t size;
if (!n) {
- for (n = 0; views[n].name[0]; n++);
+ for (n = 0; views[n].name; n++);
}
if ((ctx->num_formula_views + n + 1) > ctx->alloc_formula_views) {
diff --git a/pcilib/views.h b/pcilib/views.h
index f186336..33bcf4c 100644
--- a/pcilib/views.h
+++ b/pcilib/views.h
@@ -38,18 +38,18 @@ 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;
+ pcilib_unit_t base_unit;
};
/**
* function to read a register using a view
*/
-int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value);
+int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *unit, size_t value_size, void *value);
/**
* function to write to a register using a view
*/
-int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value);
+int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *unit, size_t value_size, void *value);
int pcilib_add_views_enum(pcilib_t* ctx,size_t n, const pcilib_view_enum2_t* views);
diff --git a/pcilib/xml.c b/pcilib/xml.c
index fb9128f..dbe6ac7 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -47,6 +47,7 @@
#define REGISTERS_PATH ((xmlChar*)"../registers/register") /**< all standard registers nodes.*/
#define BIT_REGISTERS_PATH ((xmlChar*)"./registers_bits/register_bits") /**< all bits registers nodes.*/
#define VIEWS_PATH ((xmlChar*)"/model/views/view") /**< path to complete nodes of views.*/
+#define UNITS_PATH ((xmlChar*)"/model/units/unit") /**< path to complete nodes of units.*/
static char *pcilib_xml_bank_default_format = "0x%lx";
@@ -71,22 +72,21 @@ static xmlNodePtr pcilib_xml_get_parent_register_node(xmlDocPtr doc, xmlNodePtr
*/
/**
- * get the associated units of a view
+ * get the associated unit 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++;
- }
- }
+pcilib_get_unit_of_view(pcilib_t* ctx,pcilib_view_formula_t* myview, char* base_unit){
+ int j;
+
+ for(j=0;ctx->units[j].name;j++){
+ if(!(strcasecmp(base_unit,ctx->units[j].name))){
+ myview->base_unit=ctx->units[j];
+ break;
+ }
}
- }*/
+
+}
/**
* get the associated views of a register, to fill its register context
@@ -141,7 +141,7 @@ pcilib_get_associated_views(pcilib_t* ctx, const char* reg_name,xmlXPathContextP
}
/*here it is for formula, i assume we have only one formula view per register*/
- for(k=0; ctx->formula_views[k].name[0];k++){
+ for(k=0; ctx->formula_views[k].name;k++){
if(!(strcasecmp(view_name,ctx->formula_views[k].name))){
ctx->register_ctx[id].formulas=malloc(sizeof(pcilib_view_formula_t));
@@ -149,7 +149,7 @@ pcilib_get_associated_views(pcilib_t* ctx, const char* reg_name,xmlXPathContextP
pcilib_error("error allocating memory for formula views in register context %i",id);
return PCILIB_ERROR_MEMORY;
}
-
+ pcilib_get_unit_of_view(ctx,&(ctx->formula_views[k]),ctx->formula_views[k].base_unit.name);
ctx->register_ctx[id].formulas[0]=ctx->formula_views[k];
break;
}
@@ -273,8 +273,6 @@ static int pcilib_xml_parse_register(pcilib_t *ctx, pcilib_xml_register_descript
static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
int err;
int views_ok=0;
- int h;
-
xmlXPathObjectPtr nodes;
xmlNodeSetPtr nodeset;
@@ -507,28 +505,33 @@ 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) {
+/**
+ * function to create a unit from a unit xml node, then populating ctx with it
+ *@param[in,out] ctx - the pcilib_t running
+ *@param[in] xpath - the xpath context of the unis xml file
+ *@param[in] doc - the AST of the unit xml file
+ *@param[in] node - the node representing the unit
+ *@return an error code: 0 if evrythinh is ok
+ */
+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*
+ /* 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 (!cur->children) continue;
if (!xmlNodeIsText(cur->children)) continue;
name = (char*)cur->name;
@@ -536,11 +539,12 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
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=realloc(desc.other_units,(i+1)*sizeof(pcilib_transform_unit_t));
desc.other_units[i].name=value2;
desc.other_units[i].transform_formula=value;
+ i++;
}
}
@@ -552,7 +556,7 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
return 0;
}
-*/
+
/**
* function that create a view from a view node, and populate ctx views list
*/
@@ -678,8 +682,11 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
formula_desc.write_formula=value;
}else if (!(strcasecmp((char*)name,"description"))) {
formula_desc.description=value;
+ }else if (!(strcasecmp((char*)name,"unit"))){
+ formula_desc.base_unit.name=value;
}
}
+
err=pcilib_add_views_formula(ctx,1,&formula_desc);
if (err) {
pcilib_error("Error (%i) adding a new formula view (%s) to the pcilib_t", err, formula_desc.name);
@@ -700,17 +707,28 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
* @param[in] pci the pcilib_t running, which will be filled
*/
static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathContextPtr xpath) {
- xmlXPathObjectPtr bank_nodes,views_nodes;
+ xmlXPathObjectPtr bank_nodes,views_nodes, units_nodes;
xmlNodeSetPtr nodeset;
int i;
xmlErrorPtr xmlerr;
+
+ units_nodes=xmlXPathEvalExpression(UNITS_PATH,xpath);
+ if(!units_nodes){
+ goto views;
+ }
+
+ nodeset=units_nodes->nodesetval;
+ if(!xmlXPathNodeSetIsEmpty(nodeset)){
+ for(i=0;i < nodeset->nodeNr; i++){
+ pcilib_xml_create_unit(ctx,xpath,doc,nodeset->nodeTab[i]);
+ }
+ }
+ xmlXPathFreeObject(units_nodes);
+ views:
views_nodes=xmlXPathEvalExpression(VIEWS_PATH,xpath);
if(!views_nodes){
- xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", BANKS_PATH, xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to parse XPath expression %s", BANKS_PATH);
- return PCILIB_ERROR_FAILED;
+ goto banks;
}
nodeset=views_nodes->nodesetval;
@@ -720,7 +738,7 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon
}
}
xmlXPathFreeObject(views_nodes);
-
+ banks:
bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath);
if (!bank_nodes) {
xmlerr = xmlGetLastError();
@@ -850,6 +868,8 @@ int pcilib_process_xml(pcilib_t *ctx, const char *location) {
struct dirent *file = NULL;
char *model_dir, *model_path;
+ int i;
+
model_dir = getenv("PCILIB_MODEL_DIR");
if (!model_dir) model_dir = PCILIB_MODEL_DIR;
@@ -870,6 +890,17 @@ int pcilib_process_xml(pcilib_t *ctx, const char *location) {
if (err) pcilib_error("Error processing XML file %s", file->d_name);
}
+ for(i=0;i<ctx->num_formula_views;i++){
+ pcilib_get_unit_of_view(ctx,&(ctx->formula_views[i]),ctx->formula_views[i].base_unit.name);
+ }
+
+ for(i=0;i<ctx->num_reg;i++){
+ if(ctx->register_ctx[i].formulas){
+ pcilib_get_unit_of_view(ctx,&(ctx->register_ctx[i].formulas[0]),ctx->register_ctx[i].formulas[0].base_unit.name);
+ }
+ }
+
+
closedir(rep);
return 0;
diff --git a/pcitool/cli.c b/pcitool/cli.c
index 6af70e4..bd52270 100644
--- a/pcitool/cli.c
+++ b/pcitool/cli.c
@@ -1054,7 +1054,7 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info,
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);
+ 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);
@@ -1282,11 +1282,17 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info
unsigned long val;
pcilib_register_value_t value;
+ pcilib_register_t regid;
const char *format = NULL;
- char *s1;
-
- pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
+ char *s1,*s2=NULL;
+
+ if((s1=strchr(reg,'/'))){
+ s2=pcilib_view_str_sub(reg,0,s1-reg-1);
+ regid=pcilib_find_register(handle,bank,s2);
+ }else{
+ 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");
/*
@@ -1316,15 +1322,15 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info
if(err) Error("can't write to the register using an enum view");
else return 0;
}
- /* } else {
+ /* should i put strchr not null here?
+ } else {
Error("Can't parse data value (%s) is not valid decimal number", *data);
}*/
value = val;
if((s1=strchr(reg,'/'))){
- char *s3,*s2;
- s2=pcilib_view_str_sub(reg,0,s1-reg-1);
+ char *s3;
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);
diff --git a/xml/model.xsd b/xml/model.xsd
index 5febd1a..cd0b4b0 100644
--- a/xml/model.xsd
+++ b/xml/model.xsd
@@ -4,8 +4,9 @@
<xsd:element name="model">
<xsd:complexType>
<xsd:sequence>
- <xsd:element name="banks" type="banks_type"/>
+ <xsd:element name="banks" type="banks_type" minOccurs="0" maxOccurs="1"/>
<xsd:element name="views" type="views_type" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="units" type="units_type" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:key name="Registerkey">
@@ -107,8 +108,29 @@
<xsd:element name="description" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="views" type="reg_to_views_type" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="units_type">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="unit" type="unit_type"/>
+ </xsd:sequence>
</xsd:complexType>
+
+
+ <xsd:complexType name="unit_type">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="convert_unit" type="convert_unit_type"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="convert_unit_type">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="value" type="xsd:string"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
<xsd:simpleType name="uint8_t">
<xsd:restriction base="xsd:integer">
diff --git a/xml/test/camera.xml b/xml/test/camera.xml
index bf26d80..ed01014 100644
--- a/xml/test/camera.xml
+++ b/xml/test/camera.xml
@@ -491,4 +491,38 @@
<description>enum towards cmosis_exp_register register</description>
</view>
</views>
+ <units>
+ <unit name="C">
+ <convert_unit value="K">@self+273.15</convert_unit>
+ <convert_unit value="F">@self*(9./5)+32</convert_unit>
+ </unit>
+ <unit name="K">
+ <convert_unit value="C">@self-273.15</convert_unit>
+ <convert_unit value="F">(@self-273.15)*(9./5)+32</convert_unit>
+ </unit>
+ <unit name="F">
+ <convert_unit value="C">(@self-32)*5./9</convert_unit>
+ <convert_unit value="K">(@self+273.15-32)*5./9</convert_unit>
+ </unit>
+ <unit name="s">
+ <convert_unit value="ms">@self*1000</convert_unit>
+ <convert_unit value="us">@self*1000000</convert_unit>
+ <convert_unit value="ns">@self*1000000000</convert_unit>
+ </unit>
+ <unit name="ms">
+ <convert_unit value="s">@self/1000</convert_unit>
+ <convert_unit value="us">@self*1000</convert_unit>
+ <convert_unit value="ns">@self*1000000</convert_unit>
+ </unit>
+ <unit name="us">
+ <convert_unit value="s">@self/1000000</convert_unit>
+ <convert_unit value="ms">@self/1000</convert_unit>
+ <convert_unit value="ns">@self*1000</convert_unit>
+ </unit>
+ <unit name="ns">
+ <convert_unit value="s">@self/1000000000</convert_unit>
+ <convert_unit value="ms">@self/1000000</convert_unit>
+ <convert_unit value="us">@self/1000</convert_unit>
+ </unit>
+ </units>
</model>