Commit 5ebcf80b authored by claes's avatar claes

New ssab card classes with internal channels

parent 0c831e70
/* rt_io_m_ssab_ai.c -- io methods for ssab cards.
PROVIEW/R
Copyright (C) 1994 by Comator Process AB. */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "pwr.h"
#include "co_cdh.h"
#include "rt_gdh.h"
#include "rt_errh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_ssaboxclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_io_ssab.h"
#include "rt_io_card_init.h"
#include "rt_io_card_close.h"
#include "rt_io_card_read.h"
#include "qbus_io.h"
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
#define IO_MAXCHAN 32
typedef struct {
unsigned int Address;
int Qbus_fp;
int ScanCount[IO_MAXCHAN];
} io_sLocal;
typedef struct {
int Qbus_fp;
} io_sRackLocal;
static pwr_tStatus AiRangeToCoef(
io_sChannel *chanp)
{
pwr_sClass_ChanAi *cop;
char buf[120];
pwr_tStatus sts;
pwr_tFloat32 PolyCoef1;
pwr_tFloat32 PolyCoef0;
cop = chanp->cop;
if ( cop)
{
cop->CalculateNewCoef = 0;
/* Coef for RawValue to SignalValue conversion */
cop->SigValPolyCoef0 = 0;
cop->SigValPolyCoef1 = cop->ChannelSigValRangeHigh / 30000;
/* Coef for SignalValue to ActualValue conversion */
if ( chanp->ChanClass != pwr_cClass_ChanAit && cop->SensorPolyType == 1)
{
if ( cop->SensorSigValRangeHigh != cop->SensorSigValRangeLow)
{
PolyCoef1 = (cop->ActValRangeHigh - cop->ActValRangeLow)/
(cop->SensorSigValRangeHigh - cop->SensorSigValRangeLow);
PolyCoef0 = cop->ActValRangeHigh - cop->SensorSigValRangeHigh *
PolyCoef1;
cop->SensorPolyCoef1 = cop->SigValPolyCoef1 * PolyCoef1;
cop->SensorPolyCoef0 = PolyCoef0 + PolyCoef1*
cop->SigValPolyCoef0;
}
else
{
sts = gdh_AttrrefToName( &chanp->ChanAref, buf, sizeof(buf),
cdh_mName_volumeStrict);
if ( EVEN(sts)) return sts;
errh_Error( "Invalid SigValueRange in Ai channel %s", buf);
return IO__CHANRANGE;
}
}
}
return IO__SUCCESS;
}
static pwr_tStatus IoCardInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
pwr_sClass_Ssab_BaseACard *op;
io_sLocal *local;
int i;
io_sChannel *chanp;
op = (pwr_sClass_Ssab_BaseACard *) cp->op;
local = calloc( 1, sizeof(*local));
cp->Local = local;
local->Address = op->RegAddress;
local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp;
errh_Info( "Init of ai card '%s'", cp->Name);
/* Caluclate polycoeff */
chanp = cp->chanlist;
for ( i = 0; i < cp->ChanListSize; i++)
{
AiRangeToCoef( chanp);
chanp++;
}
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardClose (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
errh_Info( "IO closing ai card '%s'", cp->Name);
local = (io_sLocal *) cp->Local;
free( (char *) local);
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardRead (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
pwr_tInt16 data = 0;
pwr_sClass_Ssab_BaseACard *op;
int i;
pwr_tFloat32 actvalue;
io_sChannel *chanp;
pwr_sClass_ChanAi *cop;
pwr_sClass_Ai *sop;
int sts;
qbus_io_read rb;
local = (io_sLocal *) cp->Local;
op = (pwr_sClass_Ssab_BaseACard *) cp->op;
chanp = &cp->chanlist[0];
for ( i = 0; i < cp->ChanListSize; i++)
{
if ( !chanp->cop)
{
chanp++;
continue;
}
cop = (pwr_sClass_ChanAi *) chanp->cop;
sop = (pwr_sClass_Ai *) chanp->sop;
if ( cop->CalculateNewCoef)
AiRangeToCoef( chanp);
if ( cop->ConversionOn)
{
if ( local->ScanCount[i] <= 1)
{
#if defined(OS_ELN)
vaxc$establish(machfailread);
#endif
rb.Address = local->Address + 2*i;
sts = read( local->Qbus_fp, &rb, sizeof(rb));
data = (unsigned short) rb.Data;
if ( sts == -1)
{
#if 0
/* Exceptionhandler was called */
if ( io_fatal_error)
{
/* Activate emergency break */
errh_Error( "Fatal read error, card '%s', IO is stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
#endif
/* Increase error count and check error limits */
op->ErrorCount++;
if ( op->ErrorCount == op->ErrorSoftLimit)
errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
if ( op->ErrorCount >= op->ErrorHardLimit)
{
errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
chanp++;
continue;
}
/* Convert rawvalue to sigvalue and actualvalue */
sop->RawValue = data;
sop->SigValue = data * cop->SigValPolyCoef1 + cop->SigValPolyCoef0;
switch ( chanp->ChanClass)
{
case pwr_cClass_ChanAi:
io_ConvertAi( cop, data, &actvalue);
break;
case pwr_cClass_ChanAit:
io_ConvertAit( (pwr_sClass_ChanAit *) cop, data, &actvalue);
break;
}
/* Filter */
if ( sop->FilterType == 1 &&
sop->FilterAttribute[0] > 0 &&
sop->FilterAttribute[0] > ctx->ScanTime)
{
actvalue = *(pwr_tFloat32 *)chanp->vbp +
ctx->ScanTime / sop->FilterAttribute[0] *
(actvalue - *(pwr_tFloat32 *)chanp->vbp);
}
*(pwr_tFloat32 *) chanp->vbp = actvalue;
local->ScanCount[i] = cop->ScanInterval + 1;
}
local->ScanCount[i]--;
}
chanp++;
}
return 1;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(Ssab_AiuP) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardClose),
pwr_BindIoMethod(IoCardRead),
pwr_NullMethod
};
/* rt_io_m_ssab_aoup.c -- io methods for ssab cards.
PROVIEW/R
Copyright (C) 1994 by Comator Process AB. */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "pwr.h"
#include "rt_errh.h"
#include "co_cdh.h"
#include "rt_gdh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_ssaboxclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_io_ssab.h"
#include "rt_io_card_init.h"
#include "rt_io_card_close.h"
#include "rt_io_card_write.h"
#include "qbus_io.h"
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
#define IO_MAXCHAN 8
typedef struct {
unsigned int Address;
int Qbus_fp;
pwr_tFloat32 OldValue[IO_MAXCHAN];
pwr_tBoolean OldTestOn[IO_MAXCHAN];
int WriteFirst;
} io_sLocal;
typedef struct {
int Qbus_fp;
} io_sRackLocal;
static pwr_tStatus AoRangeToCoef(
io_sChannel *chanp)
{
pwr_sClass_ChanAo *cop;
char buf[120];
pwr_tStatus sts;
pwr_tFloat32 PolyCoef1;
pwr_tFloat32 PolyCoef0;
cop = chanp->cop;
if ( cop)
{
cop->CalculateNewCoef = 0;
/* Coef for ActualValue to RawValue conversion */
if ( cop->ActValRangeHigh != cop->ActValRangeLow)
{
cop->SigValPolyCoef1 = (cop->SensorSigValRangeHigh - cop->SensorSigValRangeLow)/
(cop->ActValRangeHigh - cop->ActValRangeLow);
cop->SigValPolyCoef0 = cop->SensorSigValRangeHigh - cop->ActValRangeHigh *
cop->SigValPolyCoef1;
}
else
{
sts = gdh_AttrrefToName( &chanp->ChanAref, buf, sizeof(buf),
cdh_mName_volumeStrict);
if ( EVEN(sts)) return sts;
errh_Error( "Invalid ActValueRange in Ao channel %s", buf);
return IO__CHANRANGE;
}
/* Coef for ActualValue to SignalValue conversion */
if ( cop->ChannelSigValRangeHigh != 0)
{
PolyCoef0 = 0;
PolyCoef1 = cop->RawValRangeHigh / cop->ChannelSigValRangeHigh;
cop->OutPolyCoef1 = cop->SigValPolyCoef1 * PolyCoef1;
cop->OutPolyCoef0 = PolyCoef0 + PolyCoef1*
cop->SigValPolyCoef0;
}
else
{
sts = gdh_AttrrefToName( &chanp->ChanAref, buf, sizeof(buf),
cdh_mName_volumeStrict);
if ( EVEN(sts)) return sts;
errh_Error( "Invalid SigValueRange in Ao channel %s", buf);
return IO__CHANRANGE;
}
}
return IO__SUCCESS;
}
static pwr_tStatus IoCardInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
pwr_sClass_Ssab_BaseACard *op;
io_sChannel *chanp;
int i;
io_sLocal *local;
op = (pwr_sClass_Ssab_BaseACard *) cp->op;
local = calloc( 1, sizeof(*local));
local->Address = op->RegAddress;
local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp;
errh_Info( "Init of ao card '%s'", cp->Name);
/* Write the first 50 loops */
local->WriteFirst = 50;
cp->Local = local;
/* Caluclate polycoeff */
chanp = cp->chanlist;
for ( i = 0; i < cp->ChanListSize; i++)
{
AoRangeToCoef( chanp);
chanp++;
}
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardClose (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
local = (io_sLocal *) cp->Local;
errh_Info( "IO closing ao card '%s'", cp->Name);
free( (char *) local);
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardWrite (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
pwr_sClass_Ssab_BaseACard *op;
int i;
io_sChannel *chanp;
pwr_sClass_ChanAo *cop;
pwr_sClass_Ao *sop;
pwr_tFloat32 value;
int fixout;
pwr_tUInt16 data;
pwr_tFloat32 rawvalue;
qbus_io_write wb;
int sts;
local = (io_sLocal *) cp->Local;
op = (pwr_sClass_Ssab_BaseACard *) cp->op;
fixout = ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT;
chanp = &cp->chanlist[0];
for ( i = 0; i < cp->ChanListSize; i++)
{
if ( !chanp->cop)
{
chanp++;
continue;
}
cop = (pwr_sClass_ChanAo *) chanp->cop;
sop = (pwr_sClass_Ao *) chanp->sop;
if ( *(pwr_tFloat32 *)chanp->vbp != local->OldValue[i] ||
local->WriteFirst > 0 ||
cop->CalculateNewCoef ||
fixout ||
cop->TestOn || local->OldTestOn[i] != cop->TestOn)
{
if ( fixout)
value = cop->FixedOutValue;
else if ( cop->TestOn)
value = cop->TestValue;
else
value = *(pwr_tFloat32 *) chanp->vbp;
if ( cop->CalculateNewCoef)
AoRangeToCoef( chanp);
/* Convert to rawvalue */
if ( value > cop->ActValRangeHigh)
value = cop->ActValRangeHigh;
else if ( value < cop->ActValRangeLow)
value = cop->ActValRangeLow;
rawvalue = cop->OutPolyCoef1 * value + cop->OutPolyCoef0;
if ( rawvalue > 0)
sop->RawValue = rawvalue + 0.5;
else
sop->RawValue = rawvalue - 0.5;
data = sop->RawValue;
#if defined(OS_ELN)
vaxc$establish(machfailwrite);
#endif
wb.Data = data;
wb.Address = local->Address + 2*i;
sts = write( local->Qbus_fp, &wb, sizeof(wb));
if ( sts == -1)
{
/* Exceptionhandler was called */
#if 0
if ( io_fatal_error)
{
/* Activate emergency break */
errh_Error( "Fatal write error, card '%s', IO is stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
#endif
/* Increase error count and check error limits */
op->ErrorCount++;
if ( op->ErrorCount == op->ErrorSoftLimit)
errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
if ( op->ErrorCount >= op->ErrorHardLimit)
{
errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
chanp++;
continue;
}
else
local->OldValue[i] = value;
}
local->OldTestOn[i] = cop->TestOn;
chanp++;
}
if ( local->WriteFirst)
local->WriteFirst--;
return 1;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(Ssab_AouP) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardClose),
pwr_BindIoMethod(IoCardWrite),
pwr_NullMethod
};
/* rt_io_m_ssab_co.c -- io methods for ssab cards.
PROVIEW/R
Copyright (C) 1994 by Comator Process AB. */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "pwr.h"
#include "rt_errh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_ssaboxclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_io_ssab.h"
#include "rt_io_card_init.h"
#include "rt_io_card_close.h"
#include "rt_io_card_read.h"
#include "qbus_io.h"
#define IO_MAXCHAN 4
#define MIN16 -32767
#define MIN24 -8388607
#define MAXCO16 65536
#define MAXCO24 16777216
#define MAX24 8388607
#define MAX16 32767
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
typedef struct {
unsigned int Address;
int Qbus_fp;
pwr_tInt32 OldValue[IO_MAXCHAN];
int FirstScan[IO_MAXCHAN];
} io_sLocal;
typedef struct {
int Qbus_fp;
} io_sRackLocal;
static pwr_tStatus IoCardInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
pwr_tStatus sts;
pwr_sClass_Ssab_CO4uP *op;
io_sLocal *local;
int i;
pwr_tUInt16 wr_data[2];
pwr_tUInt32 *wr_data_p;
qbus_io_write wb;
op = (pwr_sClass_Ssab_CO4uP *) cp->op;
local = calloc( 1, sizeof(*local));
for ( i = 0; i < IO_MAXCHAN; i++)
local->FirstScan[i] = 1;
cp->Local = local;
local->Address = op->RegAddress;
local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp;
errh_Info( "Init of co card '%s'", cp->Name);
/* Configure card */
for ( i = 0; i < op->MaxNoOfCounters; i++)
{
if ( !cp->chanlist[i].cop)
continue;
wr_data_p = (pwr_tUInt32 *) &wr_data;
*wr_data_p = op->SyncRawValue[i];
if ( op->SpeedMeasurement[i] == 1)
wr_data[1] |= (1 << 8);
if ( op->LengthMeasurement[i] == 1)
wr_data[1] |= (1 << 10);
if ( op->MulCount[i] == 2)
wr_data[1] |= (1 << 11);
if ( op->DivCount[i] == 16)
wr_data[1] |= (1 << 9);
if ( op->NoOfBits[i] == 16)
wr_data[1] |= (1 << 12);
if ( op->CopWrRough[i] == 1)
wr_data[1] |= (1 << 13);
if ( op->CopWrFine[i] == 1)
wr_data[1] |= (1 << 14);
if ( op->LoadWrReg[i] == 1)
wr_data[1] |= (1 << 15);
wb.Address = local->Address + 4*i;
wb.Data = wr_data[0];
sts = write( local->Qbus_fp, &wb, sizeof(wb));
if ( sts != -1)
{
wb.Address += 2;
wb.Data = wr_data[1];
sts = write( local->Qbus_fp, &wb, sizeof(wb));
}
if ( sts == -1)
{
errh_Error( "IO init, Fatal write error, card '%s', IO i stopped", cp->Name);
return IO__ERRDEVICE;
}
if ( op->LoadWrReg[i] == 1)
{
* (pwr_tUInt32 *) cp->chanlist[i].vbp = op->SyncRawValue[i];
* (pwr_tUInt32 *) cp->chanlist[i].abs_vbp = op->SyncRawValue[i];
}
else
{
* (pwr_tUInt32 *) cp->chanlist[i].vbp = 0;
}
/* Data is written to device */
op->COWrFlag[i] = 0;
}
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardClose (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
local = (io_sLocal *) cp->Local;
errh_Info( "IO closing co card '%s'", cp->Name);
free( (char *) local);
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardRead (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
pwr_tUInt16 wr_data[2];
pwr_tUInt16 re_data[2];
pwr_tUInt32 *wr_data_p;
pwr_tUInt32 *re_data_p;
pwr_sClass_Ssab_CO4uP *op;
pwr_tInt32 numofword;
int i;
pwr_tInt16 co16_data;
pwr_tInt32 newdiff,diff,co24_data;
int sts, sts1, sts2;
qbus_io_read rb;
qbus_io_write wb;
local = (io_sLocal *) cp->Local;
op = (pwr_sClass_Ssab_CO4uP *) cp->op;
for ( i = 0; i < op->MaxNoOfCounters; i++)
{
if ( !cp->chanlist[i].cop)
continue;
if ( op->ConvMask & (1 << i))
{
/* Conversion is on */
if ( op->COWrFlag[i])
{
/* New configuration of card */
wr_data_p = (pwr_tUInt32 *) &wr_data;
*wr_data_p = op->SyncRawValue[i];
if ( op->SpeedMeasurement[i] == 1)
wr_data[1] |= (1 << 8);
if ( op->LengthMeasurement[i] == 1)
wr_data[1] |= (1 << 10);
if ( op->MulCount[i] == 2)
wr_data[1] |= (1 << 11);
if ( op->DivCount[i] == 16)
wr_data[1] |= (1 << 9);
if ( op->NoOfBits[i] == 16)
wr_data[1] |= (1 << 12);
if ( op->CopWrRough[i] == 1)
wr_data[1] |= (1 << 13);
if ( op->CopWrFine[i] == 1)
wr_data[1] |= (1 << 14);
if ( op->LoadWrReg[i] == 1)
wr_data[1] |= (1 << 15);
wb.Address = local->Address + 4*i;
wb.Data = wr_data[0];
sts = write( local->Qbus_fp, &wb, sizeof(wb));
if ( sts != -1)
{
wb.Address += 2;
wb.Data = wr_data[1];
sts = write( local->Qbus_fp, &wb, sizeof(wb));
}
if ( sts == -1)
{
errh_Error( "IO init, Fatal write error, card '%s', IO i stopped", cp->Name);
}
op->COWrFlag[i] = 0;
}
if ( op->NoOfBits[i] == 24)
numofword = 2;
else
numofword = 1; /* 16 bitscounter */
re_data_p = (pwr_tUInt32 *) &re_data;
#if defined(OS_ELN)
vaxc$establish(machfailread_co);
#endif
rb.Address = local->Address + 4*i;
sts1 = read( local->Qbus_fp, &rb, sizeof(rb));
re_data[0] = (unsigned short) rb.Data;
if ( numofword == 2)
{
rb.Address += 2;
sts2 = read( local->Qbus_fp, &rb, sizeof(rb));
re_data[1] = (unsigned short) rb.Data;
}
else
sts2 = 0;
if ( sts1 == -1 || sts2 == -1)
{
#if 0
if ( io_fatal_error)
{
/* Activate emergency break */
errh_Error( "Fatal read error, card '%s', IO i stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
#endif
/* Increase error count and check error limits */
op->ErrorCount++;
if ( op->ErrorCount == op->ErrorSoftLimit)
errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
if ( op->ErrorCount >= op->ErrorHardLimit)
{
errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
continue;
}
}
/* No faults detected calculate countervalue and store them */
if (numofword == 1) /* 16 bits counter */
{
co16_data = re_data[0];
/* If this is the first lap we dont have any correct saved
countvalues. Therefor we save the new value. */
if ( local->FirstScan[i])
local->OldValue[i] = co16_data;
/* Store the counter values into RTDB */
*(pwr_tUInt32 *) cp->chanlist[i].vbp = co16_data;
/* Test if an abs-value should be calculated and stored */
if ( op->COAbsFlag[i] == TRUE)
{
/* Calculate difference between two readings*/
diff = co16_data - local->OldValue[i];
local->OldValue[i] = co16_data; /* Store new value */
/* Check if the counter is passing zero or max,
and calculate if it is counting up or down */
if (diff < MIN16) /* Up count over maxlimit */
newdiff = MAXCO16 + diff;
else if (diff > MAX16)
newdiff = diff - MAXCO16;
else
newdiff = diff;
/* Store the counter abs-values into RTDB */
*(pwr_tUInt32 *) cp->chanlist[i].abs_vbp += newdiff;
}
}
else if (numofword == 2) /* 24 bits counter */
{
co24_data = *re_data_p;
/* If this is the first lap we dont have any correct saved
countvalues. Therefor we save the new value. */
if ( local->FirstScan[i])
local->OldValue[i] = co24_data;
/* Store the counter values into RTDB */
*(pwr_tUInt32 *) cp->chanlist[i].vbp = co24_data;
/* Test if an abs-value should be calaulated and stored */
if ( op->COAbsFlag[i] == TRUE)
{
/* Calculate difference between two readings */
diff = co24_data - local->OldValue[i];
local->OldValue[i] = co24_data; /* Store new value */
/* Check if the counter is passing zero or max,
and calculate if it is counting up or down */
if (diff < MIN24) /* Up count over maxlimit */
newdiff = MAXCO24 + diff;
else if (diff > MAX24 )
newdiff = diff - MAXCO24 ;
else
newdiff = diff ;
/* Store the counter abs-values into RTDB */
*(pwr_tUInt32 *) cp->chanlist[i].abs_vbp += newdiff;
}
}
local->FirstScan[i] = 0;
}
return 1;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(Ssab_Co) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardClose),
pwr_BindIoMethod(IoCardRead),
pwr_NullMethod
};
/* rt_io_m_ssab_di.c -- io methods for ssab cards.
OS Linux
PROVIEW/R
Copyright (C) 1994 by Comator Process AB. */
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "pwr.h"
#include "rt_errh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_ssaboxclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_io_filter_di.h"
#include "rt_io_ssab.h"
#include "rt_io_card_init.h"
#include "rt_io_card_close.h"
#include "rt_io_card_read.h"
#include "qbus_io.h"
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
typedef struct {
unsigned int Address[2];
int Qbus_fp;
struct {
pwr_sClass_Di *sop[16];
void *Data[16];
pwr_tBoolean Found;
} Filter[2];
} io_sLocal;
typedef struct {
int Qbus_fp;
} io_sRackLocal;
static pwr_tStatus IoCardInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
pwr_sClass_Ssab_BaseDiCard *op;
io_sLocal *local;
int i, j;
op = (pwr_sClass_Ssab_BaseDiCard *) cp->op;
local = calloc( 1, sizeof(*local));
cp->Local = local;
errh_Info( "Init of di card '%s'", cp->Name);
local->Address[0] = op->RegAddress;
local->Address[1] = op->RegAddress + 2;
local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp;
/* Init filter */
for ( i = 0; i < 2; i++)
{
/* The filter handles one 16-bit word */
for ( j = 0; j < 16; j++)
local->Filter[i].sop[j] = cp->chanlist[i*16+j].sop;
io_InitDiFilter( local->Filter[i].sop, &local->Filter[i].Found,
local->Filter[i].Data, ctx->ScanTime);
}
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardClose (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
int i;
local = (io_sLocal *) cp->Local;
errh_Info( "IO closing di card '%s'", cp->Name);
/* Free filter data */
for ( i = 0; i < 2; i++)
{
if ( local->Filter[i].Found)
io_CloseDiFilter( local->Filter[i].Data);
}
free( (char *) local);
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardRead (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
pwr_tUInt16 data = 0;
pwr_sClass_Ssab_BaseDiCard *op;
pwr_tUInt16 invmask;
pwr_tUInt16 convmask;
int i;
int sts;
qbus_io_read rb;
local = (io_sLocal *) cp->Local;
op = (pwr_sClass_Ssab_BaseDiCard *) cp->op;
for ( i = 0; i < 2; i++)
{
if ( i == 0)
{
convmask = op->ConvMask1;
invmask = op->InvMask1;
}
else
{
convmask = op->ConvMask2;
invmask = op->InvMask2;
if ( !convmask)
break;
if ( op->MaxNoOfChannels == 16)
break;
}
rb.Address = local->Address[i];
sts = read( local->Qbus_fp, &rb, sizeof(rb));
data = (unsigned short) rb.Data;
if ( sts == -1)
{
/* Increase error count and check error limits */
op->ErrorCount++;
if ( op->ErrorCount == op->ErrorSoftLimit)
errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
if ( op->ErrorCount >= op->ErrorHardLimit)
{
errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
continue;
}
/* Invert */
data = data ^ invmask;
/* Filter ... */
if ( local->Filter[i].Found)
io_DiFilter( local->Filter[i].sop, &data, local->Filter[i].Data);
/* Move data to valuebase */
io_DiUnpackWord( cp, data, convmask, i);
}
return 1;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(Ssab_Di) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardClose),
pwr_BindIoMethod(IoCardRead),
pwr_NullMethod
};
/* rt_io_m_ssab_do.c -- io methods for ssab cards.
OS Linux
PROVIEW/R
Copyright (C) 1994 by Comator Process AB. */
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "pwr.h"
#include "rt_errh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_ssaboxclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_io_filter_po.h"
#include "rt_io_ssab.h"
#include "rt_io_card_init.h"
#include "rt_io_card_close.h"
#include "rt_io_card_write.h"
#include "qbus_io.h"
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
typedef struct {
unsigned int Address[2];
int Qbus_fp;
struct {
pwr_sClass_Po *sop[16];
void *Data[16];
pwr_tBoolean Found;
} Filter[2];
} io_sLocal;
typedef struct {
int Qbus_fp;
} io_sRackLocal;
static pwr_tStatus IoCardInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
pwr_sClass_Ssab_BaseDoCard *op;
io_sLocal *local;
int i, j;
op = (pwr_sClass_Ssab_BaseDoCard *) cp->op;
local = calloc( 1, sizeof(*local));
cp->Local = local;
errh_Info( "Init of do card '%s'", cp->Name);
local->Address[0] = op->RegAddress;
local->Address[1] = op->RegAddress + 2;
local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp;
/* Init filter for Po signals */
for ( i = 0; i < 2; i++)
{
/* The filter handles one 16-bit word */
for ( j = 0; j < 16; j++)
{
if ( cp->chanlist[i*16+j].SigClass == pwr_cClass_Po)
local->Filter[i].sop[j] = cp->chanlist[i*16+j].sop;
}
io_InitPoFilter( local->Filter[i].sop, &local->Filter[i].Found,
local->Filter[i].Data, ctx->ScanTime);
}
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardClose (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
int i;
local = (io_sLocal *) cp->Local;
errh_Info( "IO closing do card '%s'", cp->Name);
/* Free filter data */
for ( i = 0; i < 2; i++)
{
if ( local->Filter[i].Found)
io_ClosePoFilter( local->Filter[i].Data);
}
free( (char *) local);
return 1;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardWrite (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sLocal *local;
pwr_tUInt16 data = 0;
pwr_sClass_Ssab_BaseDoCard *op;
pwr_tUInt16 invmask;
pwr_tUInt16 testmask;
pwr_tUInt16 testvalue;
int i;
qbus_io_write wb;
int sts;
local = (io_sLocal *) cp->Local;
op = (pwr_sClass_Ssab_BaseDoCard *) cp->op;
#if defined(OS_ELN)
vaxc$establish(machfailwrite);
#endif
for ( i = 0; i < 2; i++)
{
if ( ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT)
{
if ( i == 0)
data = op->FixedOutValue1;
else
data = op->FixedOutValue2;
}
else
io_DoPackWord( cp, &data, i);
if ( i == 0)
{
testmask = op->TestMask1;
invmask = op->InvMask1;
}
else
{
testmask = op->TestMask2;
invmask = op->InvMask2;
if ( op->MaxNoOfChannels == 16)
break;
}
/* Invert */
data = data ^ invmask;
/* Filter Po signals */
if ( local->Filter[i].Found)
io_PoFilter( local->Filter[i].sop, &data, local->Filter[i].Data);
/* Testvalues */
if ( testmask)
{
if ( i == 0)
testvalue = op->TestValue1;
else
testvalue = op->TestValue2;
data = (data & ~ testmask) | (testmask & testvalue);
}
wb.Data = data;
wb.Address = local->Address[i];
sts = write( local->Qbus_fp, &wb, sizeof(wb));
if ( sts == -1)
{
#if 0
/* Exceptionhandler was called */
if ( io_fatal_error)
{
/* Activate emergency break */
errh_Error( "Fatal write error, card '%s', IO is stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
#endif
/* Increase error count and check error limits */
op->ErrorCount++;
if ( op->ErrorCount == op->ErrorSoftLimit)
errh_Error( "IO Error soft limit reached on card '%s'", cp->Name);
if ( op->ErrorCount >= op->ErrorHardLimit)
{
errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
continue;
}
}
return 1;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(Ssab_Do) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardClose),
pwr_BindIoMethod(IoCardWrite),
pwr_NullMethod
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment