static pwr_tStatus IoCardInit ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { pwr_sClass_Ao_HVAO4 *op; io_sChannel *chanp; int i; io_sLocal *local; op = (pwr_sClass_Ao_HVAO4 *) 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 IoCardInit ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { pwr_tStatus sts; pwr_sClass_Ao_7455_20 *op; io_sLocal *local; io_sChannel *chanp; int i; op = (pwr_sClass_Ao_7455_20 *) cp->op; local = calloc( 1, sizeof(*local)); local->Address = (op->CardAddress | 0xf0); local->RackAddress = ((pwr_sClass_Rack_RTP *) rp->op)->RackAddress; if ( cp->Class == pwr_cClass_Ao_7455_20) local->CardType = RTP_AO_7455_20; else if ( cp->Class == pwr_cClass_Ao_7455_30) local->CardType = RTP_AO_7455_30; else if ( cp->Class == pwr_cClass_Pd_7435_26) local->CardType = RTP_PD_7435_26; 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 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; io_sRackLocal *r_local = (io_sRackLocal *)(rp->Local); op = (pwr_sClass_Ssab_BaseACard *) cp->op; local = calloc( 1, sizeof(*local)); local->Address = op->RegAddress; local->Qbus_fp = r_local->Qbus_fp; local->FirstScan = 1; 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++; } local->ErrReset = 1.0 / ctx->ScanTime + 0.5; if ( local->ErrReset < 2) local->ErrReset = 2; return 1; }
/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardWrite ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { io_sLocal *local; io_sRackLocal *r_local = (io_sRackLocal *)(rp->Local); pwr_sClass_Ao_HVAO4 *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; pwr_tTime now; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Ao_HVAO4 *) 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 if (r_local->Qbus_fp != 0 && r_local->s == 0) { wb.Data = data; wb.Address = local->Address + 2*i; sts = write( local->Qbus_fp, &wb, sizeof(wb)); } else { /* Ethernet I/O, Request a write to current address */ bfbeth_set_write_req(r_local, (pwr_tUInt16) (local->Address + 2*i), data); sts = 1; } 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 */ time_GetTime( &now); if (op->ErrorCount > op->ErrorSoftLimit) { /* Ignore if some time has expired */ if (now.tv_sec - local->ErrTime.tv_sec < 600) op->ErrorCount++; } else op->ErrorCount++; local->ErrTime = now; 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; }
/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardWrite ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { io_sLocal *local; pwr_sClass_Ao_7455_20 *op; int i; io_sChannel *chanp; pwr_sClass_ChanAo *cop; pwr_sClass_Ao *sop; pwr_tFloat32 value; pwr_tFloat32 sigvalue; int fixout; pwr_tUInt16 data; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Ao_7455_20 *) 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 || fixout) { 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; sop->RawValue = cop->OutPolyCoef1 * value + cop->OutPolyCoef0 + 0.5; data = sop->RawValue; rtpao_write( data, local->RackAddress, (local->Address & 0xf), i, local->CardType); if (io_writeerr || io_fatal_error) { 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; } /* 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; } chanp++; } if ( local->WriteFirst) local->WriteFirst--; return IO__SUCCESS; }
/*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static pwr_tStatus IoCardWrite ( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp ) { io_sLocal *local; io_sRackLocal *r_local = (io_sRackLocal *)(rp->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; int bfb_error = 0; pwr_sClass_Ssab_RemoteRack *rrp; int remote; local = (io_sLocal *) cp->Local; op = (pwr_sClass_Ssab_BaseACard *) cp->op; fixout = ctx->Node->EmergBreakTrue && ctx->Node->EmergBreakSelect == FIXOUT; remote = !r_local->Qbus_fp && r_local->s; 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; /* Error handling for remote rack */ if ( remote) { sts = 0; if ( local->CheckWrite[i]) { local->CheckWrite[i] = 0; bfbeth_get_write_status(r_local, (pwr_tUInt16) (local->Address + 2*i), &sts); if (sts == -1) { /* Error handling for ethernet Qbus-I/O */ rrp = (pwr_sClass_Ssab_RemoteRack *) rp->op; if (bfb_error == 0) { op->ErrorCount++; bfb_error = 1; if ( op->ErrorCount == op->ErrorSoftLimit) { errh_Error( "IO Error soft limit reached on card '%s'", cp->Name); ctx->IOHandler->CardErrorSoftLimit = 1; ctx->IOHandler->ErrorSoftLimitObject = cdh_ObjidToAref( cp->Objid); } if ( op->ErrorCount == op->ErrorHardLimit) { errh_Error( "IO Error hard limit reached on card '%s', stall action %d", cp->Name, rrp->StallAction); ctx->IOHandler->CardErrorHardLimit = 1; ctx->IOHandler->ErrorHardLimitObject = cdh_ObjidToAref( cp->Objid); } if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_ResetInputs ) { sts = 1; } if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_EmergencyBreak ) { ctx->Node->EmergBreakTrue = 1; return IO__ERRDEVICE; } } } } } /* Convert and write */ 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 ( !remote) { wb.Data = data; wb.Address = local->Address + 2*i; sts = write( local->Qbus_fp, &wb, sizeof(wb)); } else { /* Ethernet I/O, Request a write to current address */ bfbeth_set_write_req(r_local, (pwr_tUInt16) (local->Address + 2*i), data); local->CheckWrite[i] = 1; if ( sts == 1) { op->ErrorCount = 0; local->OldValue[i] = value; local->OldTestOn[i] = cop->TestOn; } chanp++; continue; } /* Error handling for local rack */ 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); ctx->IOHandler->CardErrorSoftLimit = 1; ctx->IOHandler->ErrorSoftLimitObject = cdh_ObjidToAref( cp->Objid); } if ( op->ErrorCount >= op->ErrorHardLimit) { errh_Error( "IO Error hard limit reached on card '%s', IO stopped", cp->Name); ctx->Node->EmergBreakTrue = 1; ctx->IOHandler->CardErrorHardLimit = 1; ctx->IOHandler->ErrorHardLimitObject = cdh_ObjidToAref( cp->Objid); return IO__ERRDEVICE; } chanp++; continue; } else local->OldValue[i] = value; } local->OldTestOn[i] = cop->TestOn; chanp++; } if ( local->WriteFirst) local->WriteFirst--; if ( local->FirstScan) local->FirstScan = 0; /* Fix for qbus errors */ local->ErrScanCnt++; if ( local->ErrScanCnt >= local->ErrReset) { local->ErrScanCnt = 0; if ( op->ErrorCount > op->ErrorSoftLimit) op->ErrorCount--; } return 1; }