Example #1
0
/*----------------------------------------------------------------------------*\
  
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardSwap (
  io_tCtx	ctx,
  io_sAgent	*ap,
  io_sRack	*rp,
  io_sCard	*cp,
  io_eEvent	event
) 
{
  io_sLocal 		*local;
  io_sRackLocal		*r_local = (io_sRackLocal *)(rp->Local);
  pwr_tUInt16		data = 0;
  pwr_sClass_Ssab_BaseDoCard *op;
  int			i;
  qbus_io_read		rb;
  int			sts;

  switch ( event) {
  case io_eEvent_IoCommSwapInit:
  case io_eEvent_IoCommSwap:
    op = (pwr_sClass_Ssab_BaseDoCard *) cp->op;

    if (!cp->Local) {
      local = calloc( 1, sizeof(*local));
      cp->Local = local;

      local->Address[0] = op->RegAddress;
      local->Address[1] = op->RegAddress + 2;
      local->Qbus_fp = ((io_sRackLocal *)(rp->Local))->Qbus_fp;
      local->FirstScan = 1;
    }

    for ( i = 0; i < 2; i++) { 
      if (r_local->Qbus_fp != 0 && r_local->s == 0) {
	/* Write to local Q-bus */
	rb.Address = local->Address[i];
	sts = read( local->Qbus_fp, &rb, sizeof(rb));
      }
      else {
	/* Ethernet I/O, Get data from current address */
	data = bfbeth_get_data(r_local, (pwr_tUInt16) local->Address[i], &sts);
	/* Yes, we want to read this address the next time aswell */
	bfbeth_set_read_req(r_local, (pwr_tUInt16) local->Address[i]);
	sts = 1;      
      }
        
    }
    break;
  default: ;
  }
  return 1;
}
Example #2
0
/*----------------------------------------------------------------------------*\
  
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardRead (
  io_tCtx	ctx,
  io_sAgent	*ap,
  io_sRack	*rp,
  io_sCard	*cp  
) 
{
  io_sLocal 		*local;
  io_sRackLocal		*r_local = (io_sRackLocal *)(rp->Local);
  pwr_tUInt16		data = 0;
  pwr_sClass_Ssab_BaseDiCard	*op;
  pwr_sClass_Ssab_RemoteRack	*rrp;
  pwr_tUInt16		invmask;
  pwr_tUInt16		convmask;
  int			i;
  int			sts;
  qbus_io_read 		rb;
  int			bfb_error = 0;
  pwr_tTime             now;

  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;
    }

    if (r_local->Qbus_fp != 0 && r_local->s == 0) {
      /* Read from local Q-bus */
      rb.Address = local->Address[i];
      sts = read( local->Qbus_fp, &rb, sizeof(rb));
      data = (unsigned short) rb.Data;
    }
    else {
      /* Ethernet I/O, Get data from current address */
      data = bfbeth_get_data(r_local, (pwr_tUInt16) local->Address[i], &sts);
      /* Yes, we want to read this address the next time aswell */
      bfbeth_set_read_req(r_local, (pwr_tUInt16) local->Address[i]);

      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);
          if ( op->ErrorCount == op->ErrorHardLimit)
            errh_Error( "IO Error hard limit reached on card '%s', stall action %d", cp->Name, rrp->StallAction);
          if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_ResetInputs )
	  {
	    data = 0;
	    sts = 1;
          }
          if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_EmergencyBreak )
	  {
            ctx->Node->EmergBreakTrue = 1;
            return IO__ERRDEVICE;
          }
	}
	if (sts == -1) continue;
      }
      else {
	op->ErrorCount = 0;
      }
    }
    
    if ( sts == -1)
    /* Error handling for local Qbus-I/O */
    {
      /* 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;
      }
      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;
}
Example #3
0
/*----------------------------------------------------------------------------*\
  
\*----------------------------------------------------------------------------*/
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;
  io_sRackLocal		*r_local = (io_sRackLocal *)(rp->Local);
  pwr_tTime             now;

  local = (io_sLocal *) cp->Local;
  op = (pwr_sClass_Ssab_CO4uP *) cp->op;

  for ( i = 0; i < op->MaxNoOfCounters; i++)
  { 
    if ( !cp->chanlist[i].cop || !cp->chanlist[i].sop)
      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);
 
        if (r_local->Qbus_fp != 0 && r_local->s == 0) {
          /* Write to local Q-bus */
          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));
          }
        }
        else {
      	  /* Ethernet I/O, Request a write to current address */
      	  bfbeth_set_write_req(r_local, (pwr_tUInt16) (local->Address + 4*i), wr_data[0]);
      	  bfbeth_set_write_req(r_local, (pwr_tUInt16) (local->Address + 4*i + 2), wr_data[1]);
      	  sts = 1;      
        }

        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 (r_local->Qbus_fp != 0 && r_local->s == 0) {
        /* Read from local Q-bus */
        rb.Address = local->Address + 4*i;
        sts1 = read( local->Qbus_fp, &rb, sizeof(rb));
        re_data[0] = (unsigned short) rb.Data;
      }
      else {
        /* Ethernet I/O, Get data from current address */
        re_data[0] = bfbeth_get_data(r_local, (pwr_tUInt16) (local->Address + 4*i), &sts1);
        /* Yes, we want to read this address the next time aswell */
        bfbeth_set_read_req(r_local, (pwr_tUInt16) (local->Address + 4*i));	 
      }
      
      if ( numofword == 2)
      {
        if (r_local->Qbus_fp != 0 && r_local->s == 0) {
          /* Read from local Q-bus */
          rb.Address += 2;
          sts2 = read( local->Qbus_fp, &rb, sizeof(rb));
          re_data[1] = (unsigned short) rb.Data;
	}
	else {
          /* Ethernet I/O, Get data from current address */
          re_data[1] = bfbeth_get_data(r_local, (pwr_tUInt16) (local->Address + 4*i + 2), &sts2);
          /* Yes, we want to read this address the next time aswell */
          bfbeth_set_read_req(r_local, (pwr_tUInt16) (local->Address + 4*i + 2));	 
	}
      }

      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 */
        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;
        }
        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;
}
Example #4
0
/*----------------------------------------------------------------------------*\
  
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardRead (
  io_tCtx	ctx,
  io_sAgent	*ap,
  io_sRack	*rp,
  io_sCard	*cp  
) 
{
  io_sLocal 		*local;
  io_sRackLocal		*r_local = (io_sRackLocal *)(rp->Local);
  pwr_tInt16		data = 0;
  pwr_sClass_Ssab_BaseACard *op;
  pwr_sClass_Ssab_RemoteRack	*rrp;
  int			i;
  pwr_tFloat32		actvalue;
  io_sChannel		*chanp;
  pwr_sClass_ChanAi	*cop;
  pwr_sClass_Ai		*sop;
  int			sts;
  qbus_io_read 		rb;
  int			bfb_error = 0;
  pwr_tTime             now;

  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
        if (r_local->Qbus_fp != 0 && r_local->s == 0) {
          rb.Address = local->Address + 2*i;
          sts = read( local->Qbus_fp, &rb, sizeof(rb));
          data = (unsigned short) rb.Data;
	}
        else {
          /* Ethernet I/O, Get data from current address */
          data = bfbeth_get_data(r_local, (pwr_tUInt16) (local->Address + 2*i), &sts);
          /* Yes, we want to read this address the next time aswell */
          bfbeth_set_read_req(r_local, (pwr_tUInt16) (local->Address + 2*i));	 

          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);
              if ( op->ErrorCount == op->ErrorHardLimit)
                errh_Error( "IO Error hard limit reached on card '%s', stall action %d", cp->Name, rrp->StallAction);
              if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_ResetInputs )
	      {
	        data = 0;
	        sts = 1;
              }
              if ( op->ErrorCount >= op->ErrorHardLimit && rrp->StallAction == pwr_eSsabStallAction_EmergencyBreak )
	      {
                ctx->Node->EmergBreakTrue = 1;
                return IO__ERRDEVICE;
              }
	    }
	    if (sts == -1) {
	      chanp++;
	      continue;
	    }
          }
          else {
	    op->ErrorCount = 0;
          }
        }
	
        if ( sts == -1)
	/* Error handling for local Qbus-I/O */
        {
#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 */
          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;
        }
	
        /* 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;
}