added support for Allen Bradley RTD module

This commit is contained in:
Marty Kraimer
1994-05-26 12:55:19 +00:00
parent 05b2252fe1
commit 5d3e47a922
3 changed files with 242 additions and 11 deletions
+141 -1
View File
@@ -57,6 +57,7 @@
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <drvAb.h>
@@ -79,7 +80,10 @@ static long linconv_1771Il();
static long init_1771Ixe();
static long read_1771Ixe();
static long linconv_1771Ixe();
static int read_1771Ofe();
static long init_1771IrPlatinum();
static long read_1771IrPlatinum();
static long init_1771IrCopper();
static long read_1771IrCopper();
typedef struct {
long number;
DEVSUPFUN report;
@@ -100,8 +104,13 @@ ABAIDSET devAiAb1771Il= {6, NULL, NULL, init_1771Il, NULL,
read_1771Il, linconv_1771Il};
ABAIDSET devAiAb1771Ixe= {6, NULL, NULL, init_1771Ixe, NULL,
read_1771Ixe, linconv_1771Ixe};
ABAIDSET devAiAb1771IrPlatinum= {6, NULL, NULL, init_1771IrPlatinum, NULL,
read_1771IrPlatinum, NULL};
ABAIDSET devAiAb1771IrCopper= {6, NULL, NULL, init_1771IrCopper, NULL,
read_1771IrCopper, NULL};
static long init_1771Ofe();
static int read_1771Ofe();
static long write_1771Ofe();
static long linconv_1771Ofe();
typedef struct {
@@ -549,7 +558,138 @@ static long linconv_1771Ixe(struct aiRecord *pai, int after)
return(0);
}
static long init_1771IrPlatinum(struct aiRecord *pai)
{
short value;
struct abio *pabio;
short conversion;
/* ai.inp must be an AB_IO */
switch (pai->inp.type) {
case (AB_IO) :
break;
default :
recGblRecordError(S_db_badField,(void *)pai,
"devAiAb1771IrPlatinum (init_record) Illegal INP field");
return(S_db_badField);
}
pabio = (struct abio *)&(pai->inp.value);
if(pabio->parm[0]=='C') {
conversion=IR_degC;
strcpy(pai->egu,"degC");
} else if(pabio->parm[0]=='O') {
conversion = IR_Ohms;
strcpy(pai->egu,"ohms");
} else {
conversion = 0;
strcpy(pai->egu,"degF");
}
pai->linr = 0;
/* call driver so that it configures card */
/* The driver returns error for first call for a card. Ignore it. */
ab_aidriver(AB1771IrPlatinum,pabio->link,pabio->adapter,
pabio->card,pabio->signal,pabio->plc_flag,&value,conversion);
return(0);
}
static long read_1771IrPlatinum(struct aiRecord *pai)
{
struct abio *pabio;
long status;
short value;
short conversion;
pabio = (struct abio *)&(pai->inp.value);
if(pabio->parm[0]=='C') conversion=IR_degC;
else if(pabio->parm[0]=='O') conversion = IR_Ohms;
else conversion = 0;
status=ab_aidriver(AB1771IrPlatinum,pabio->link,pabio->adapter,
pabio->card,pabio->signal,pabio->plc_flag,&value,conversion);
if(status==-2) {
recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM);
status = 0;
}
if(status==0) {
if(conversion==IR_Ohms) pai->val = ((double)value)/100.0;
else pai->val = ((double)value)/10.0;
pai->udf = FALSE;
status=2; /*don't convert*/
} else if(status==-1) {
if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose
&& (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM))
recGblRecordError(-1,(void *)pai,"ab_aidriver Error");
status = 2; /*don't convert*/
}
return(status);
}
static long init_1771IrCopper(struct aiRecord *pai)
{
short value;
struct abio *pabio;
short conversion;
/* ai.inp must be an AB_IO */
switch (pai->inp.type) {
case (AB_IO) :
break;
default :
recGblRecordError(S_db_badField,(void *)pai,
"devAiAb1771IrCopper (init_record) Illegal INP field");
return(S_db_badField);
}
pabio = (struct abio *)&(pai->inp.value);
if(pabio->parm[0]=='C') {
conversion=IR_degC;
strcpy(pai->egu,"degC");
} else if(pabio->parm[0]=='O') {
conversion = IR_Ohms;
strcpy(pai->egu,"ohms");
} else {
conversion = 0;
strcpy(pai->egu,"degF");
}
pai->linr = 0;
/* call driver so that it configures card */
/* The driver returns error for first call for a card. Ignore it. */
ab_aidriver(AB1771IrCopper,pabio->link,pabio->adapter,
pabio->card,pabio->signal,pabio->plc_flag,&value,conversion);
return(0);
}
static long read_1771IrCopper(struct aiRecord *pai)
{
struct abio *pabio;
long status;
short value;
short conversion;
pabio = (struct abio *)&(pai->inp.value);
if(pabio->parm[0]=='C') conversion=IR_degC;
else if(pabio->parm[0]=='O') conversion = IR_Ohms;
else conversion = 0;
status=ab_aidriver(AB1771IrCopper,pabio->link,pabio->adapter,
pabio->card,pabio->signal,pabio->plc_flag,&value,conversion);
if(status==-2) {
recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM);
status = 0;
}
if(status==0) {
if(conversion==IR_Ohms) pai->val = ((double)value)/100.0;
else pai->val = ((double)value)/10.0;
pai->udf = FALSE;
status=2; /*don't convert*/
} else if(status==-1) {
if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose
&& (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM))
recGblRecordError(-1,(void *)pai,"ab_aidriver Error");
status = 2; /*don't convert*/
}
return(status);
}
static long init_1771Ofe(struct aoRecord *pao)
{
+79 -10
View File
@@ -384,13 +384,25 @@ int ab_intr (); /* interrupt service routine */
* 0x1000 - adapter/plc flag
* 0 - adapter
* 1 - PLC
* 0x0f00 - conversion (from ~gta/dbcon/h/fields.h)
* 0x0f00 - conversion
* For IXE
* 0 - no conversion (use millivolt range)
* 1 - linear (use millivolt range)
* 2 - k - degrees F
* 3 - k - degrees K
* 4 - j - degrees F
* 5 - j - degrees K
* 2 - K_DGF
* 3 - K_DGC
* 4 - J_DGF
* 5 - J_DGC
* 6 - E_DGF
* 7 - E_DGC
* 8 - T_DGF
* 9 - T_DGC
* 10- R_DGF
* 11- R_DGC
* 12- S_DGF
* 13- S_DGC
* For Ir
* 0- degF
* 1- degC
* 0x00e0 - interface type
* 0 - Not Assigned
* 1 - Binary Input
@@ -435,6 +447,7 @@ int abScanId; /* id of the Allen-Bradley scan task */
short ab_timers[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS];
#define AB_IXE_RATE 5 /* .5 seconds */
#define AB_IL_RATE 4 /* .4 seconds */
#define AB_IR_RATE 5 /* .5 seconds */
#define AB_IFE_RATE 1 /* .1 seconds */
#define AB_OFE_RATE 10 /* 1 seconds - written immediately */
#define AB_INT_LEVEL 5
@@ -577,6 +590,12 @@ register short pass;
btq_err = OK; /* assume success */
if ((*pcard & AB_INTERFACE_TYPE) == AB_AI_INTERFACE){
switch (*pcard&AB_CARD_TYPE){
case (AB1771IrPlatinum) :
case (AB1771IrCopper) :
if ((pass % AB_IR_RATE) == 0) {
btq_err = bt_queue(AB_READ,link,adapter,card,8,&msg[0]);
}
break;
case (AB1771IL):
if ((pass % AB_IL_RATE) == 0) {
btq_err = bt_queue(AB_READ,link,adapter,card,12,&msg[0]);
@@ -630,10 +649,19 @@ short link;
register short *pab_table;
bfill(pmsg,64*2,0);
*pmsg = 0;
switch (*pcard & AB_INTERFACE_TYPE){
case (AB_AI_INTERFACE):
switch (*pcard & AB_CARD_TYPE){
case (AB1771IrCopper) :
*pmsg = IR_COPPER;
case (AB1771IrPlatinum) :
i = (*pcard & AB_CONVERSION) >> 8;
if(i==IR_degF) *pmsg |= IR_UNITS_DEGF;
if(i==IR_Ohms) *pmsg |= IR_UNITS_OHMS;
*pmsg |= IR_SIGNED;
length = 1;
break;
case (AB1771IXE): /* millivolt module */
/* need to base this on conversion */
switch ((*pcard & AB_CONVERSION) >> 8){
@@ -987,7 +1015,31 @@ abDoneTask(){
/* it was a response to a command */
/* analog input response */
}else if ((*pcard & AB_INTERFACE_TYPE) == AB_AI_INTERFACE){
if ((*pcard & AB_CARD_TYPE) == AB1771IL)
if((*pcard & AB_CARD_TYPE) == AB1771IrPlatinum
|| (*pcard & AB_CARD_TYPE) == AB1771IrCopper)
{
struct ab1771ir_read *pmsg = (struct ab1771ir_read *) presponse->data;
short under,over,overflow,polarity;
pab_table = &ab_btdata[link][adapter][card][0];
pab_sts = &ab_btsts[link][adapter][card][0];
for(i=0, under = 0x1, over=0x100, overflow=0x1, polarity=0x100;
i<ai_num_channels[AB1771IrPlatinum];
i++, under<<=1, over<<=1, overflow<<=1, polarity<<=1) {
*pab_table = pmsg->data[i];
if(pmsg->pol_over&polarity) *pab_table = -*pab_table;
if((pmsg->status&under) || (pmsg->status&over)
|| (pmsg->pol_over&overflow)) {
*pab_sts = -3;
ab_scaling_error[link][adapter][card]++;
}else{
*pab_sts = 0;
}
pab_sts++;
pab_table++;
}
}
else if ((*pcard & AB_CARD_TYPE) == AB1771IL)
{
register struct ab1771il_read *pmsg
= (struct ab1771il_read *)presponse->data;
@@ -2026,6 +2078,24 @@ ab_io_report(level)
if (level > 0){
ab_ai_report(type,i,adapter,card,plc_card);
}
} else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IrPlatinum){
printf("\tAI: AB1771IrPlatinum\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d",
adapter,card,ab_cmd_to[i][adapter][card],
ab_data_to[i][adapter][card],
ab_scaling_error[i][adapter][card],
ab_or_scaling_error[i][adapter][card]);
if (level > 0){
ab_ai_report(type,i,adapter,card,plc_card);
}
} else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IrCopper){
printf("\tAI: AB1771IrPlatinum\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d",
adapter,card,ab_cmd_to[i][adapter][card],
ab_data_to[i][adapter][card],
ab_scaling_error[i][adapter][card],
ab_or_scaling_error[i][adapter][card]);
if (level > 0){
ab_ai_report(type,i,adapter,card,plc_card);
}
} else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IFE_SE){
printf("\tAI: AB1771IFE_SE\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d",
adapter,card,ab_cmd_to[i][adapter][card],
@@ -2116,12 +2186,11 @@ ab_ai_report(type,link,adapter,card,plc_card)
short i,num_chans;
unsigned short value;
printf("\n\t");
num_chans = ai_num_channels[type];
for(i=0; i<num_chans; i++) {
if(i%8 == 0) printf("\n\t");
ab_aidriver(type,link,adapter,card,i,plc_card,&value,0);
printf("%4x",value);
printf(" %4x",value);
}
}
+22
View File
@@ -321,4 +321,26 @@ struct ab1771ixe_read {
short data[8]; /* current values */
unsigned short cjcw; /* cold junction cal word */
};
/*Conversion value passed to abb_ai_driver*/
#define IR_degF 0
#define IR_degC 1
#define IR_Ohms 2
/*Register definitions*/
#define IR_UNITS_DEGF 0x40
#define IR_UNITS_OHMS 0x80
#define IR_COPPER 0x100
#define IR_SIGNED 0x400
/* configuration data transfer to the IR card */
struct ab1771ir_config {
unsigned short conv_rate; /* conversion and scan rate data */
unsigned short resistance; /* 10ohm resiatance @25 degC */
unsigned short bias[6]; /* bias */
unsigned short calibration[6]; /* */
};
struct ab1771ir_read {
unsigned short status; /* status and over/under range */
unsigned short pol_over; /* polarity and overflow */
short data[6]; /* current values */
};