Commit d13ba328 authored by claes's avatar claes

Division of source tree and build tree in modules

parent 99ec0b4e
/*
* Proview $Id: rt_io_m_ssab_aiup.c,v 1.3 2005-09-01 14:57:57 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* rt_io_m_ssab_ai.c -- io methods for ssab cards. */
#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++)
{
if ( chanp->sop)
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->sop)
{
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
};
/*
* Proview $Id: rt_io_m_ssab_aoup.c,v 1.3 2005-09-01 14:57:57 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* rt_io_m_ssab_aoup.c -- io methods for ssab cards. */
#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++)
{
if ( chanp->sop)
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->sop)
{
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
};
This diff is collapsed.
/*
* Proview $Id: rt_io_m_ssab_di.c,v 1.2 2005-09-01 14:57:57 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* rt_io_m_ssab_di.c -- io methods for ssab cards.
OS Linux
*/
#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
};
/*
* Proview $Id: rt_io_m_ssab_do.c,v 1.2 2005-09-01 14:57:57 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* rt_io_m_ssab_do.c -- io methods for ssab cards.
OS Linux
*/
#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