//------------------------------------------------------------------------------
//! @brief   Called when asyn clients call pasynUInt32Digital->read().
//!
//!          If pasynUser->reason is equal
//!          - P_Status0     the status bytes are read out and stored in
//!                          the corresponding parameters.
//!          - any other:    the value from the parameter library will be returned.
//!
//! @param   [in]  pasynUser  pasynUser structure that encodes the reason and address
//! @param   [out] value      Address of the value to read
//! @param   [in]  mask       Mask value to use when reading the value.
//!
//! @return  in case of no error occured asynSuccess is returned. Otherwise
//!          asynError or asynTimeout is returned. A error message is stored
//!          in pasynUser->errorMessage.
//------------------------------------------------------------------------------
asynStatus drvAsynWienerVme::readUInt32Digital( asynUser *pasynUser, epicsUInt32 *value, epicsUInt32 mask ) {
  int function = pasynUser->reason;
  asynStatus status = asynSuccess;
  const char *functionName = "readUInt32Digital";

  if ( function == P_Status0 ) {
    can_frame_t pframe;
    pframe.can_id  = _crateId | CAN_RTR_FLAG;
    pframe.can_dlc = 8;
    
    status = pasynGenericPointerSyncIO->writeRead( _pasynGenericPointer, &pframe, &pframe, pasynUser->timeout );
    if ( asynTimeout == status ){
      epicsSnprintf( pasynUser->errorMessage, pasynUser->errorMessageSize, 
                     "%s:%s:%s: status=%d, function=%d, No reply from device within %f s", 
                     driverName, _deviceName, functionName, status, function, pasynUser->timeout );
      return asynTimeout;
    }
    if ( status ){
      epicsSnprintf( pasynUser->errorMessage, pasynUser->errorMessageSize, 
                     "%s:%s:%s: status=%d, function=%d %s", 
                     driverName, _deviceName, functionName, status, function,
                     _pasynGenericPointer->errorMessage );
      return asynError;
    }
    if ( pframe.can_id != _crateId || pframe.can_dlc != 8 ) {
      epicsSnprintf( pasynUser->errorMessage, pasynUser->errorMessageSize, 
                     "\033[31;1m%s:%s:%s: function=%d, Mismatch in reply.\n Got '%08x %d...' where '%x08 8...' was expected.\033[0m", 
                     driverName, _deviceName, functionName, function, pframe.can_id, pframe.can_dlc, _crateId  );
      return asynError;
    }

    status = setUIntDigitalParam( P_Status0, pframe.data[0], mask );
    status = setUIntDigitalParam( P_Status1, pframe.data[1], mask );
    status = setUIntDigitalParam( P_Status2, pframe.data[2], mask );
    status = setUIntDigitalParam( P_Status3, pframe.data[3], mask );
    status = setUIntDigitalParam( P_Status4, pframe.data[4], mask );
    status = setUIntDigitalParam( P_Status5, pframe.data[5], mask );
    status = setUIntDigitalParam( P_Status6, pframe.data[6], mask );
    status = setUIntDigitalParam( P_Status7, pframe.data[7], mask );
    
    status = (asynStatus) callParamCallbacks();
  }
  
  // read back parameter
  status = (asynStatus) getUIntDigitalParam( function, value, mask );
  if ( status )
    epicsSnprintf( pasynUser->errorMessage, pasynUser->errorMessageSize, 
                   "\033[31;1m%s:%s:%s: status=%d, function=%d, value=%u mask=%u\033[0m", 
                   driverName, _deviceName, functionName, status, function, *value, mask );
  else        
    asynPrint( pasynUser, ASYN_TRACEIO_DEVICE, 
               "%s:%s:%s: function=%d, value=%u, mask=%u\n", 
               driverName, _deviceName, functionName, function, *value, mask );
  return status;
}
Exemple #2
0
asynStatus DSA2000::setHVStatus()
{
    struct ncp_hcmd_sethvstatus setCommand;
    epicsUInt32 control;
    asynStatus status = asynSuccess;
    int sendStatus;
    int range;
    double DACVolts, fullScale=0;;
    int response;
    int actual;
    static const char *functionName = "setHVStatus";

    getUIntDigitalParam(P_HVControl, &control, 0xFFFFFFFF);
    getIntegerParam(P_HVRangeSetting, &range);
    getDoubleParam(P_DACSetting, &DACVolts);
    switch (range) {
    case  rangePlus5000:
        control &= ~HVPS_Negative;
        control |= HVPS_5000V;
        fullScale = 5000.;
        break;
    case rangePlus1300:
        control &= ~HVPS_Negative;
        control &= ~HVPS_5000V;
        fullScale = 1300.;
        break;
    case rangeMinus5000:
        control |= HVPS_Negative;
        control |= HVPS_5000V;
        fullScale = 5000.;
        break;
    default:
        asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
                  "%s:%s: error, unknown range=%d\n",
                  driverName, functionName, range);
        break;
    }
    setUIntDigitalParam(P_HVControl, control, 0xFFFFFFFF);
    setCommand.control = control;
    setCommand.DAC = (epicsInt16)((DACVolts/fullScale * 4095) + 0.5);
    sendStatus = nmc_sendcmd(this->module, NCP_K_HCMD_SETHVSTATUS, &setCommand, sizeof(setCommand),
                             &response, sizeof(response), &actual, 0);
    if (sendStatus != 9) status = asynError;
    return status;
}
asynStatus USB1608G::writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask)
{
  int function = pasynUser->reason;
  int status=0;
  int i;
  epicsUInt32 outValue=0, outMask, direction=0;
  static const char *functionName = "writeUInt32Digital";


  setUIntDigitalParam(function, value, mask);
  if (function == digitalDirection_) {
    outValue = (value == 0) ? DIGITALIN : DIGITALOUT; 
    for (i=0; i<NUM_IO_BITS; i++) {
      if ((mask & (1<<i)) != 0) {
        status = cbDConfigBit(boardNum_, AUXPORT, i, outValue);
      }
    }
  }

  else if (function == digitalOutput_) {
    getUIntDigitalParam(digitalDirection_, &direction, 0xFFFFFFFF);
    for (i=0, outMask=1; i<NUM_IO_BITS; i++, outMask = (outMask<<1)) {
      // Only write the value if the mask has this bit set and the direction for that bit is output (1)
      outValue = ((value &outMask) == 0) ? 0 : 1; 
      if ((mask & outMask & direction) != 0) {
        status = cbDBitOut(boardNum_, AUXPORT, i, outValue);
      }
    }
  }
  
  callParamCallbacks();
  if (status == 0) {
    asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, 
             "%s:%s, port %s, wrote outValue=0x%x, value=0x%x, mask=0x%x, direction=0x%x\n",
             driverName, functionName, this->portName, outValue, value, mask, direction);
  } else {
    asynPrint(pasynUser, ASYN_TRACE_ERROR, 
             "%s:%s, port %s, ERROR writing outValue=0x%x, value=0x%x, mask=0x%x, direction=0x%x, status=%d\n",
             driverName, functionName, this->portName, outValue, value, mask, direction, status);
  }
  return (status==0) ? asynSuccess : asynError;
}
Exemple #4
0
/** Constructor for the DSA2000 class.
  * Calls constructor for the asynPortDriver base class.
  * \param[in] portName The name of the asyn port driver to be created.
  * \param[in] moduleAddress The low-order 16 bits of the Ethernet address */
DSA2000::DSA2000(const char *portName, int moduleAddress)
    : asynPortDriver(portName,
                     1, /* maxAddr */
                     (int)NUM_PARAMS,
                     asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask | asynDrvUserMask, /* Interface mask */
                     asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask,  /* Interrupt mask */
                     ASYN_CANBLOCK, /* asynFlags.  This driver blocks and it is not multi-device */
                     1, /* Autoconnect */
                     0, /* Default priority */
                     0) /* Default stack size*/
{
    unsigned char enet_address[6];
    int status;
    epicsUInt32 HVStatus, HVControl;
    double voltage;
    int range;
    int retries=0;
    const char *functionName = "DSA2000";

    createParam(P_HVControlString,          asynParamUInt32Digital, &P_HVControl);
    createParam(P_HVStatusString,           asynParamUInt32Digital, &P_HVStatus);
    createParam(P_HVRangeSettingString,     asynParamInt32,         &P_HVRangeSetting);
    createParam(P_HVRangeReadbackString,    asynParamInt32,         &P_HVRangeReadback);
    createParam(P_DACSettingString,         asynParamFloat64,       &P_DACSetting);
    createParam(P_DACReadbackString,        asynParamFloat64,       &P_DACReadback);
    createParam(P_ADCReadbackString,        asynParamFloat64,       &P_ADCReadback);
    createParam(P_HVResetString,            asynParamInt32,         &P_HVReset);
    createParam(P_ReadStatusString,         asynParamInt32,         &P_ReadStatus);

    /* Compute the module Ethernet address */
    nmc_build_enet_addr(moduleAddress, enet_address);

    /* Find the particular module on the net - may have to retry in case
     * the module database is still being built after initialisation.
     * This is not possible to resolve other than by waiting, since there are
     * an unknown number of modules on the local subnet, and they can reply
     * to the initial inquiry broadcast in an arbitrary order. */
    do {
        epicsThreadSleep(0.1);
        status = nmc_findmod_by_addr(&this->module, enet_address);
    } while ((status != OK) && (retries++ < 5));

    if (status != OK) {
        asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
                  "%s:%s: ERROR, cannot find module %d on the network!\n",
                  driverName, functionName, moduleAddress);
        return;
    }

    /* Read the status of the module */
    getHVStatus();

    /* Set the value of the output parameters from the initial readbacks */
    getUIntDigitalParam(P_HVStatus, &HVStatus, 0xFFFFFFFF);
    // Force callbacks on all bits first time
    setUIntDigitalParam(P_HVStatus, HVStatus, 0xFFFFFFFF, 0xFFFFFFFF);
    // Copy bits 0-2 and 9 of status to control
    HVControl = HVStatus & 0x207;
    setUIntDigitalParam(P_HVControl, HVControl, 0xFFFFFFFF, 0xFFFFFFFF);
    getDoubleParam(P_DACReadback, &voltage);
    setDoubleParam(P_DACSetting, voltage);
    getIntegerParam(P_HVRangeReadback, &range);
    setIntegerParam(P_HVRangeSetting, range);
}
Exemple #5
0
/** Callback task that runs as a separate thread. */
void testErrors::callbackTask(void)
{
    asynStatus currentStatus;
    int itemp;
    epicsInt32 iVal;
    epicsUInt32 uiVal;
    epicsFloat64 dVal;
    int i;
    char octetValue[20];
    
    /* Loop forever */    
    while (1) {
        lock();
        updateTimeStamp();
        getIntegerParam(P_StatusReturn, &itemp); currentStatus = (asynStatus)itemp;

        getIntegerParam(P_Int32Value, &iVal);
        iVal++;
        if (iVal > 64) iVal=0;
        setIntegerParam(P_Int32Value, iVal);
        setParamStatus( P_Int32Value, currentStatus);

        getIntegerParam(P_BinaryInt32Value, &iVal);
        iVal++;
        if (iVal > 1) iVal=0;
        setIntegerParam(P_BinaryInt32Value, iVal);
        setParamStatus( P_BinaryInt32Value, currentStatus);

        getIntegerParam(P_MultibitInt32Value, &iVal);
        iVal++;
        if (iVal > MAX_INT32_ENUMS-1) iVal=0;
        setIntegerParam(P_MultibitInt32Value, iVal);
        setParamStatus( P_MultibitInt32Value, currentStatus);

        getUIntDigitalParam(P_UInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK);
        uiVal++;
        if (uiVal > 64) uiVal=0;
        setUIntDigitalParam(P_UInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK);
        setParamStatus(     P_UInt32DigitalValue, currentStatus);

        getUIntDigitalParam(P_BinaryUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK);
        uiVal++;
        if (uiVal > 1) uiVal=0;
        setUIntDigitalParam(P_BinaryUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK);
        setParamStatus(     P_BinaryUInt32DigitalValue, currentStatus);

        getUIntDigitalParam(P_MultibitUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK);
        uiVal++;
        if (uiVal > MAX_UINT32_ENUMS-1) uiVal=0;
        setUIntDigitalParam(P_MultibitUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK);
        setParamStatus(     P_MultibitUInt32DigitalValue, currentStatus);

        getDoubleParam(P_Float64Value, &dVal);
        dVal += 0.1;
        setDoubleParam(P_Float64Value, dVal);
        setParamStatus(P_Float64Value, currentStatus);

        sprintf(octetValue, "%.1f", dVal); 
        setStringParam(P_OctetValue, octetValue);
        setParamStatus(P_OctetValue, currentStatus);

        for (i=0; i<MAX_ARRAY_POINTS; i++) {
            int8ArrayValue_[i]    = iVal;
            int16ArrayValue_[i]   = iVal;
            int32ArrayValue_[i]   = iVal;
            float32ArrayValue_[i] = (epicsFloat32)dVal;
            float64ArrayValue_[i] = dVal;
        }
        callParamCallbacks();
        setParamStatus(P_Int8ArrayValue,    currentStatus);
        setParamStatus(P_Int16ArrayValue,   currentStatus);
        setParamStatus(P_Int32ArrayValue,   currentStatus);
        setParamStatus(P_Float32ArrayValue, currentStatus);
        setParamStatus(P_Float64ArrayValue, currentStatus);
        doCallbacksInt8Array(int8ArrayValue_,       MAX_ARRAY_POINTS, P_Int8ArrayValue,    0);
        doCallbacksInt16Array(int16ArrayValue_,     MAX_ARRAY_POINTS, P_Int16ArrayValue,   0);
        doCallbacksInt32Array(int32ArrayValue_,     MAX_ARRAY_POINTS, P_Int32ArrayValue,   0);
        doCallbacksFloat32Array(float32ArrayValue_, MAX_ARRAY_POINTS, P_Float32ArrayValue, 0);
        doCallbacksFloat64Array(float64ArrayValue_, MAX_ARRAY_POINTS, P_Float64ArrayValue, 0);
        unlock();
        epicsEventWait(eventId_);
    }
}