asynStatus ddriveAxis::queryStatus() { int status=0; asynStatus ret = pc_->writeRead(status, "stat,%d", axisNo_); if (ret == asynSuccess && status != status_) { // only evaluate when status has changed status_ = status; bool plugged = (status & DD_STATUS_PLUGGED) == DD_STATUS_PLUGGED; int measure = (status & DD_STATUS_MEAS_MASK) >> DD_STATUS_MEAS_MASK_OFFSET; bool closed_loop_sys = (status & DD_STATUS_CLOSED_LOOP_SYS) == DD_STATUS_CLOSED_LOOP_SYS; bool voltage_enabled = (status & DD_STATUS_VOLTAGE_EN) == DD_STATUS_VOLTAGE_EN; bool closed_loop = (status & DD_STATUS_CLOSED_LOOP) == DD_STATUS_CLOSED_LOOP; int generator = (status & DD_STATUS_GENERATOR_MASK) >> DD_STATUS_GEN_MASK_OFFSET; bool notch_filter = (status & DD_STATUS_NOTCH_FILTER) == DD_STATUS_NOTCH_FILTER; bool lp_filter = (status & DD_STATUS_LP_FILTER) == DD_STATUS_LP_FILTER; asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "-- Axis %d: status changed --\n", axisNo_); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tPlugged: %d\n", plugged); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tMeasurement system: %s (%d)\n", DDRIVE_MEAS_STRINGS[measure], measure); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tClosed loop system: %d\n", closed_loop_sys); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tIn closed loop: %d\n", closed_loop); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tVoltage enabled: %d\n", voltage_enabled); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tGenerator: %s (%d)\n", DDRIVE_GEN_STRINGS[generator], generator); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tNotch filter enabled: %d\n", notch_filter); asynPrint(pc_->pasynUser_, ASYN_TRACE_FLOW, "\tLow-pass filter enabled: %d\n", lp_filter); setIntegerParam(pc_->param_notchon_, notch_filter); setIntegerParam(pc_->param_lpon_, lp_filter); setIntegerParam(pc_->param_cl_, closed_loop); setIntegerParam(pc_->param_closed_sys_, closed_loop_sys); setIntegerParam(pc_->param_voltage_on_, voltage_enabled); setUIntDigitalParam(pc_->param_meas_sys_, measure); setUIntDigitalParam(pc_->param_gfkt_, generator); if (generator == DD_STATUS_GEN_OFF) { mode_ = DD_MODE_POSITION; } else { mode_ = DD_MODE_SCAN; } }
/** Called when asyn clients call pasynUInt32D->write(). * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus testErrors::writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask) { int function = pasynUser->reason; asynStatus status = asynSuccess; int itemp; const char *paramName; const char* functionName = "writeUInt32D"; /* Get the current error status */ getIntegerParam(P_StatusReturn, &itemp); status = (asynStatus)itemp; /* Fetch the parameter string name for use in debugging */ getParamName(function, ¶mName); /* Set the parameter value in the parameter library. */ setUIntDigitalParam(function, value, mask); /* Set the parameter status in the parameter library. */ setParamStatus(function, status); /* Do callbacks so higher layers see any changes */ callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=0x%X", driverName, functionName, status, function, paramName, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=0x%X\n", driverName, functionName, function, paramName, value); return status; }
/** Called when asyn clients call pasynInt32->write(). * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus DSA2000::writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask) { int function = pasynUser->reason; asynStatus status = asynSuccess; const char *paramName; const char* functionName = "writeUInt32Digital"; /* Set the parameter in the parameter library. */ setUIntDigitalParam(function, value, mask); /* Fetch the parameter string name for possible use in debugging */ getParamName(function, ¶mName); if (function == P_HVControl) { status = setHVStatus(); } else { /* All other parameters just get set in parameter list, no need to * act on them here */ } /* Do callbacks so higher layers see any changes */ callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=0x%x, mask=0x%x", driverName, functionName, status, function, paramName, value, mask); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=0x%x, mask=0x%x\n", driverName, functionName, function, paramName, value, mask); return status; }
/** Constructor for the testErrors class. * Calls constructor for the asynPortDriver base class. * \param[in] portName The name of the asyn port driver to be created. */ testErrors::testErrors(const char *portName) : asynPortDriver(portName, 1, /* maxAddr */ (int)NUM_PARAMS, /* Interface mask */ asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask | asynOctetMask | asynInt8ArrayMask | asynInt16ArrayMask | asynInt32ArrayMask | asynFloat32ArrayMask | asynFloat64ArrayMask | asynOptionMask | asynEnumMask | asynDrvUserMask, /* Interrupt mask */ asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask | asynOctetMask | asynInt8ArrayMask | asynInt16ArrayMask | asynInt32ArrayMask | asynFloat32ArrayMask | asynFloat64ArrayMask | asynEnumMask, 0, /* asynFlags. This driver does not block and it is not multi-device, so flag is 0 */ 1, /* Autoconnect */ 0, /* Default priority */ 0) /* Default stack size*/ { asynStatus status; int i; const char *functionName = "testErrors"; createParam(P_StatusReturnString, asynParamInt32, &P_StatusReturn); createParam(P_EnumOrderString, asynParamInt32, &P_EnumOrder); createParam(P_Int32ValueString, asynParamInt32, &P_Int32Value); createParam(P_Float64ValueString, asynParamFloat64, &P_Float64Value); createParam(P_UInt32DigitalValueString, asynParamUInt32Digital, &P_UInt32DigitalValue); createParam(P_OctetValueString, asynParamOctet, &P_OctetValue); createParam(P_Int8ArrayValueString, asynParamInt8Array, &P_Int8ArrayValue); createParam(P_Int16ArrayValueString, asynParamInt16Array, &P_Int16ArrayValue); createParam(P_Int32ArrayValueString, asynParamInt32Array, &P_Int32ArrayValue); createParam(P_Float32ArrayValueString, asynParamFloat32Array, &P_Float32ArrayValue); createParam(P_Float64ArrayValueString, asynParamFloat64Array, &P_Float64ArrayValue); for (i=0; i<MAX_INT32_ENUMS; i++) { int32EnumStrings_[i] = (char*)calloc(MAX_ENUM_STRING_SIZE, sizeof(char)); } for (i=0; i<MAX_UINT32_ENUMS; i++) { uint32EnumStrings_[i] = (char*)calloc(MAX_ENUM_STRING_SIZE, sizeof(char)); } setIntegerParam(P_StatusReturn, asynSuccess); setIntegerParam(P_Int32Value, 0); setDoubleParam(P_Float64Value, 0.0); setIntegerParam(P_EnumOrder, 0); setEnums(); // Need to force callbacks with the interruptMask once setUIntDigitalParam(P_UInt32DigitalValue, (epicsUInt32)0x0, 0xFFFFFFFF, 0xFFFFFFFF); /* Create the thread that computes the waveforms in the background */ status = (asynStatus)(epicsThreadCreate("testErrorsTask", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)::callbackTask, this) == NULL); if (status) { printf("%s:%s: epicsThreadCreate failure\n", driverName, functionName); return; } }
//------------------------------------------------------------------------------ //! @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; }
/** Constructor for the testOutputReadback class. * Calls constructor for the asynPortDriver base class. * \param[in] portName The name of the asyn port driver to be created. */ testOutputReadback::testOutputReadback(const char *portName, int initialReadStatus) : asynPortDriver(portName, 1, /* maxAddr */ (int)NUM_PARAMS, /* Interface mask */ asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask | asynDrvUserMask, /* Interrupt mask */ asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask, 0, /* asynFlags. This driver does not block and it is not multi-device, so flag is 0 */ 1, /* Autoconnect */ 0, /* Default priority */ 0) /* Default stack size*/, initialReadStatus_((asynStatus)initialReadStatus) { createParam(P_Int32ValueString, asynParamInt32, &P_Int32Value); createParam(P_BinaryInt32ValueString, asynParamInt32, &P_BinaryInt32Value); createParam(P_MultibitInt32ValueString, asynParamInt32, &P_MultibitInt32Value); createParam(P_Float64ValueString, asynParamFloat64, &P_Float64Value); createParam(P_UInt32DigitalValueString, asynParamUInt32Digital, &P_UInt32DigitalValue); createParam(P_BinaryUInt32DigitalValueString, asynParamUInt32Digital, &P_BinaryUInt32DigitalValue); createParam(P_MultibitUInt32DigitalValueString, asynParamUInt32Digital, &P_MultibitUInt32DigitalValue); setIntegerParam (P_Int32Value, 7); setParamStatus (P_Int32Value, asynSuccess); setIntegerParam (P_BinaryInt32Value, 1); setParamStatus (P_BinaryInt32Value, asynSuccess); setIntegerParam (P_MultibitInt32Value, 1); setParamStatus (P_MultibitInt32Value, asynSuccess); setDoubleParam (P_Float64Value, 50.); setParamStatus (P_Float64Value, asynSuccess); setUIntDigitalParam(P_UInt32DigitalValue, (epicsUInt32)0xFF, 0xFFFFFFFF, 0xFFFFFFFF); setParamStatus (P_UInt32DigitalValue, asynSuccess); setUIntDigitalParam(P_BinaryUInt32DigitalValue, (epicsUInt32)0x1, 0xFFFFFFFF, 0xFFFFFFFF); setParamStatus (P_BinaryUInt32DigitalValue, asynSuccess); setUIntDigitalParam(P_MultibitUInt32DigitalValue, (epicsUInt32)0x2, 0xFFFFFFFF, 0xFFFFFFFF); setParamStatus (P_BinaryUInt32DigitalValue, asynSuccess); }
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; }
/** Called when asyn clients call pasynUIntDigital->write(). * Extracts the function and axis number from pasynUser. * Sets the value in the parameter library. * If the function is motorSetClosedLoop_ then it turns the drive power on or off. * If the function is ddriveReadBinaryIO_ then it reads the binary I/O registers on the controller. * For all other functions it calls asynMotorController::writeUInt32Digital. * Calls any registered callbacks for this pasynUser->reason and address. * \param[in] pasynUser asynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus ddriveController::writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask) { int function = pasynUser->reason; asynStatus status = asynSuccess; ddriveAxis *pAxis = getAxis(pasynUser); const char *paramName = "(unset)"; /* Fetch the parameter string name for possible use in debugging */ getParamName(function, ¶mName); /* Set the parameter and readback in the parameter library. This may be overwritten when we read back the * status at the end, but that's OK */ status = setUIntDigitalParam(pAxis->axisNo_, function, value, mask); printf("%s:%s: mask=%x function=%s (%d), value=%d\n", driverName, __func__, mask, paramName, function, value); const DDParam *ddp = DDParamFromIndex(function); if (ddp && ddp->type == asynParamUInt32Digital) { if (ddp->global) { status = writeParameter(ddp, (int)value); } else { status = pAxis->writeParameter(ddp, (int)value); } } else { /* Call base class method */ status = asynMotorController::writeUInt32Digital(pasynUser, value, mask); } /* Do callbacks so higher layers see any changes */ callParamCallbacks(pAxis->axisNo_); if (status) asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s:%s: error, status=%d function=%s (%d), value=%d\n", driverName, __func__, status, paramName, function, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%s (%d), value=%d\n", driverName, __func__, paramName, function, value); return status; }
asynStatus DSA2000::getHVStatus() { struct ncp_hcmd_rethvstatus getCommand; struct ncp_mresp_rethvstatus getResponse; epicsUInt32 HVStatus; asynStatus status = asynSuccess; int sendStatus; int range; double DACVolts, ADCVolts, fullScale; int actual; sendStatus = nmc_sendcmd(this->module, NCP_K_HCMD_RETHVSTATUS, &getCommand, sizeof(getCommand), &getResponse, sizeof(getResponse), &actual, 0); if (sendStatus != 233) status = asynError; HVStatus = getResponse.status; setUIntDigitalParam(P_HVStatus, HVStatus, 0xFFFFFFFF); if (HVStatus & HVPS_Negative) { fullScale = 5000.; range = rangeMinus5000; } else { if (HVStatus & HVPS_5000V) { fullScale = 5000; range = rangePlus5000; } else { fullScale = 1300.; range = rangePlus1300; } } setIntegerParam(P_HVRangeReadback, range); DACVolts = getResponse.DACValue * fullScale / 4095.; setDoubleParam(P_DACReadback, DACVolts); ADCVolts = getResponse.ADCValue * fullScale / 255.; setDoubleParam(P_ADCReadback, ADCVolts); callParamCallbacks(); return status; }
//------------------------------------------------------------------------------ //! @brief Called when asyn clients call pasynUInt32Digital->write(). //! //! If pasynUser->reason is equal to P_Switch this function //! switches the crate on and off, respectively //! //! @param [in] pasynUser pasynUser structure that encodes the reason and address //! @param [in] value Value to write //! @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::writeUInt32Digital( asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask ){ int function = pasynUser->reason; asynStatus status = asynSuccess; static const char *functionName = "writeInt32"; if ( function != P_Switch ) return asynSuccess; /* Set the parameter in the parameter library. */ status = (asynStatus) setUIntDigitalParam( function, value, mask ); /* Do callbacks so higher layers see any changes */ status = (asynStatus) callParamCallbacks(); if( status ) epicsSnprintf( pasynUser->errorMessage, pasynUser->errorMessageSize, "\033[31;1m%s:%s:%s: status=%d, function=%d, value=%d, mask=%u\033[0m", driverName, _deviceName, functionName, status, function, value, mask ); else asynPrint( pasynUser, ASYN_TRACEIO_DEVICE, "%s:%s:%s: function=%d, value=%d, mask=%u\n", driverName, _deviceName, functionName, function, value, mask ); can_frame_t pframe; pframe.can_id = ( 1 << 7 ) | _crateId; pframe.can_dlc = 1; pframe.data[0] = value ? 0x67 : 0x65; status = pasynGenericPointerSyncIO->write( _pasynGenericPointer, &pframe, pasynUser->timeout ); if ( status ) { epicsSnprintf( pasynUser->errorMessage, pasynUser->errorMessageSize, "\033[31;1m%s:%s:%s: function=%d, Could not send can frame.\033[0m", driverName, _deviceName, functionName, function ); return asynError; } return status; }
asynStatus ddriveAxis::queryParameters() { int last_param = (param_num_ + pc_->queryRate_) % pc_->dd_param_count_; DDParam *param = NULL; do { param_num_ = (param_num_ + 1) % pc_->dd_param_count_; param = &pc_->ddparams_[param_num_]; if (param->query || (initial_query_ && param->service_mode)) { if (param->type == asynParamInt32 || param->type == asynParamUInt32Digital) { int value; if (queryParameter(param, value) == asynSuccess) { if (param->type == asynParamInt32) { setIntegerParam(param->idx, value); } else { setUIntDigitalParam(param->idx, value); // NOTE: these will not work pre asyn-4-18 (? at least with the debian packages it does not work TODO check its version) } //printf("Queried parameter Axis: %d (#%d) %s %s = %d\n", axisNo_, param_num_, param->asyn_param, param->command, value); } } else if (param->type == asynParamFloat64) { double value; if (queryParameter(param, value) == asynSuccess) setDoubleParam(param->idx, value); //printf("Queried parameter Axis: %d (#%d) %s %s = %f\n", axisNo_, param_num_, param->asyn_param, param->command, value); } } } while (param_num_ != last_param); if ((param_num_ + pc_->queryRate_) >= pc_->dd_param_count_) { // Only query service-mode parameters initially or when one is changed initial_query_ = false; query_status_ = true; } return asynSuccess; }
/** 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); }
/** Constructor for FastCCD driver; most parameters are simply passed to ADDriver::ADDriver. * After calling the base class constructor this method creates a thread to collect the detector data, * and sets reasonable default values the parameters defined in this class, asynNDArrayDriver, and ADDriver. * \param[in] portName The name of the asyn port driver to be created. * \param[in] maxBuffers The maximum number of NDArray buffers that the NDArrayPool for this driver is * allowed to allocate. Set this to -1 to allow an unlimited number of buffers. * \param[in] maxMemory The maximum amount of memory that the NDArrayPool for this driver is * allowed to allocate. Set this to -1 to allow an unlimited amount of memory. * \param[in] priority The thread priority for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags. * \param[in] stackSize The stack size for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags. */ FastCCD::FastCCD(const char *portName, int maxBuffers, size_t maxMemory, int priority, int stackSize, int packetBuffer, int imageBuffer, const char *baseIP, const char *fabricIP, const char *fabricMAC) : ADDriver(portName, 1, NUM_FastCCD_DET_PARAMS, maxBuffers, maxMemory, asynUInt32DigitalMask, asynUInt32DigitalMask, ASYN_CANBLOCK, 1, priority, stackSize) { int status = asynSuccess; int sizeX, sizeY; static const char *functionName = "FastCCD"; /* Write the packet and frame buffer sizes */ cinPacketBuffer = packetBuffer; cinImageBuffer = imageBuffer; /* Store the network information */ strncpy(cinBaseIP, baseIP, 20); strncpy(cinFabricIP, fabricIP, 20); strncpy(cinFabricMAC, fabricMAC, 20); //Define the polling periods for the status thread. statusPollingPeriod = 20; //seconds dataStatsPollingPeriod = 0.1; //seconds // Assume we are in continuous mode framesRemaining = -1; /* Create an EPICS exit handler */ epicsAtExit(exitHandler, this); createParam(FastCCDPollingPeriodString, asynParamFloat64, &FastCCDPollingPeriod); createParam(FastCCDMux1String, asynParamInt32, &FastCCDMux1); createParam(FastCCDMux2String, asynParamInt32, &FastCCDMux2); createParam(FastCCDFirmwarePathString, asynParamOctet, &FastCCDFirmwarePath); createParam(FastCCDBiasPathString, asynParamOctet, &FastCCDBiasPath); createParam(FastCCDClockPathString, asynParamOctet, &FastCCDClockPath); createParam(FastCCDFCRICPathString, asynParamOctet, &FastCCDFCRICPath); createParam(FastCCDFirmwareUploadString, asynParamInt32, &FastCCDFirmwareUpload); createParam(FastCCDBiasUploadString, asynParamInt32, &FastCCDBiasUpload); createParam(FastCCDClockUploadString, asynParamInt32, &FastCCDClockUpload); createParam(FastCCDFCRICUploadString, asynParamInt32, &FastCCDFCRICUpload); createParam(FastCCDPowerString, asynParamInt32, &FastCCDPower); createParam(FastCCDFPPowerString, asynParamInt32, &FastCCDFPPower); createParam(FastCCDCameraPowerString, asynParamInt32, &FastCCDCameraPower); createParam(FastCCDBiasString, asynParamInt32, &FastCCDBias); createParam(FastCCDClocksString, asynParamInt32, &FastCCDClocks); createParam(FastCCDFPGAStatusString, asynParamUInt32Digital, &FastCCDFPGAStatus); createParam(FastCCDDCMStatusString, asynParamUInt32Digital, &FastCCDDCMStatus); createParam(FastCCDOverscanString, asynParamInt32, &FastCCDOverscan); createParam(FastCCDFclkString, asynParamInt32, &FastCCDFclk); createParam(FastCCDFCRICGainString, asynParamInt32, &FastCCDFCRICGain); createParam(FastCCDVBus12V0String, asynParamFloat64, &FastCCDVBus12V0); createParam(FastCCDVMgmt3v3String, asynParamFloat64, &FastCCDVMgmt3v3); createParam(FastCCDVMgmt2v5String, asynParamFloat64, &FastCCDVMgmt2v5); createParam(FastCCDVMgmt1v2String, asynParamFloat64, &FastCCDVMgmt1v2); createParam(FastCCDVEnet1v0String, asynParamFloat64, &FastCCDVEnet1v0); createParam(FastCCDVS3E3v3String, asynParamFloat64, &FastCCDVS3E3v3); createParam(FastCCDVGen3v3String, asynParamFloat64, &FastCCDVGen3v3); createParam(FastCCDVGen2v5String, asynParamFloat64, &FastCCDVGen2v5); createParam(FastCCDV60v9String, asynParamFloat64, &FastCCDV60v9); createParam(FastCCDV61v0String, asynParamFloat64, &FastCCDV61v0); createParam(FastCCDV62v5String, asynParamFloat64, &FastCCDV62v5); createParam(FastCCDVFpString, asynParamFloat64, &FastCCDVFp); createParam(FastCCDIBus12V0String, asynParamFloat64, &FastCCDIBus12V0); createParam(FastCCDIMgmt3v3String, asynParamFloat64, &FastCCDIMgmt3v3); createParam(FastCCDIMgmt2v5String, asynParamFloat64, &FastCCDIMgmt2v5); createParam(FastCCDIMgmt1v2String, asynParamFloat64, &FastCCDIMgmt1v2); createParam(FastCCDIEnet1v0String, asynParamFloat64, &FastCCDIEnet1v0); createParam(FastCCDIS3E3v3String, asynParamFloat64, &FastCCDIS3E3v3); createParam(FastCCDIGen3v3String, asynParamFloat64, &FastCCDIGen3v3); createParam(FastCCDIGen2v5String, asynParamFloat64, &FastCCDIGen2v5); createParam(FastCCDI60v9String, asynParamFloat64, &FastCCDI60v9); createParam(FastCCDI61v0String, asynParamFloat64, &FastCCDI61v0); createParam(FastCCDI62v5String, asynParamFloat64, &FastCCDI62v5); createParam(FastCCDIFpString, asynParamFloat64, &FastCCDIFp); createParam(FastCCDLibCinVersionString, asynParamOctet, &FastCCDLibCinVersion); createParam(FastCCDBoardIDString, asynParamInt32, &FastCCDBoardID); createParam(FastCCDSerialNumString, asynParamInt32, &FastCCDSerialNum); createParam(FastCCDFPGAVersionString, asynParamInt32, &FastCCDFPGAVersion); createParam(FastCCDStatusHBString, asynParamInt32, &FastCCDStatusHB); createParam(FastCCDBadPckString, asynParamInt32, &FastCCDBadPck); createParam(FastCCDDroppedPckString, asynParamInt32, &FastCCDDroppedPck); createParam(FastCCDLastFrameString, asynParamInt32, &FastCCDLastFrame); createParam(FastCCDResetStatsString, asynParamInt32, &FastCCDResetStats); createParam(FastCCDPacketBufferString, asynParamInt32, &FastCCDPacketBuffer); createParam(FastCCDFrameBufferString, asynParamInt32, &FastCCDFrameBuffer); createParam(FastCCDImageBufferString, asynParamInt32, &FastCCDImageBuffer); // Create the epicsEvent for signaling to the status task when parameters should have changed. // This will cause it to do a poll immediately, rather than wait for the poll time period. this->statusEvent = epicsEventMustCreate(epicsEventEmpty); if (!this->statusEvent) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to create event for status task.\n", driverName, functionName); return; } this->dataStatsEvent = epicsEventMustCreate(epicsEventEmpty); if (!this->dataStatsEvent) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to create event for data stats task.\n", driverName, functionName); return; } try { this->lock(); connectCamera(); this->unlock(); setStringParam(ADStatusMessage, "Initialized"); callParamCallbacks(); } catch (const std::string &e) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: %s\n", driverName, functionName, e.c_str()); return; } sizeX = CIN_DATA_MAX_FRAME_X; sizeY = CIN_DATA_MAX_FRAME_Y; /* Set some default values for parameters */ status = asynSuccess; status |= setDoubleParam(FastCCDPollingPeriod, statusPollingPeriod); status |= setStringParam(ADManufacturer, "Berkeley Laboratory"); status |= setStringParam(ADModel, "1k x 2k FastCCD"); status |= setIntegerParam(ADSizeX, sizeX); status |= setIntegerParam(ADSizeY, sizeY); status |= setIntegerParam(ADBinX, 1); status |= setIntegerParam(ADBinY, 1); status |= setIntegerParam(ADMinX, 0); status |= setIntegerParam(ADMinY, 0); status |= setIntegerParam(ADMaxSizeX, sizeX); status |= setIntegerParam(ADMaxSizeY, sizeY); status |= setIntegerParam(ADReverseX, 0); status |= setIntegerParam(ADReverseY, 0); status |= setIntegerParam(ADImageMode, ADImageSingle); status |= setIntegerParam(ADTriggerMode, 1); status |= setDoubleParam(ADAcquireTime, 0.005); status |= setDoubleParam(ADAcquirePeriod, 1.0); status |= setIntegerParam(ADNumImages, 1); status |= setIntegerParam(ADNumExposures, 1); status |= setIntegerParam(NDArraySizeX, sizeX); status |= setIntegerParam(NDArraySizeY, sizeY); status |= setIntegerParam(NDDataType, NDUInt16); status |= setIntegerParam(NDArraySize, sizeX*sizeY*sizeof(epicsUInt16)); status |= setDoubleParam(ADShutterOpenDelay, 0.); status |= setDoubleParam(ADShutterCloseDelay, 0.); status |= setIntegerParam(FastCCDFirmwareUpload, 0); status |= setIntegerParam(FastCCDClockUpload, 0); status |= setIntegerParam(FastCCDBiasUpload, 0); status |= setIntegerParam(FastCCDPower, 0); status |= setIntegerParam(FastCCDFPPower, 0); status |= setIntegerParam(FastCCDCameraPower, 0); status |= setIntegerParam(FastCCDBias, 0); status |= setIntegerParam(FastCCDClocks, 0); status |= setUIntDigitalParam(FastCCDFPGAStatus, 0x0, 0xFFFF); status |= setUIntDigitalParam(FastCCDDCMStatus, 0x0, 0xFFFF); status |= setIntegerParam(FastCCDMux1, 0); status |= setIntegerParam(FastCCDMux2, 0); status |= setStringParam(FastCCDFirmwarePath, ""); status |= setStringParam(FastCCDBiasPath, ""); status |= setStringParam(FastCCDClockPath, ""); status |= setStringParam(FastCCDFCRICPath, ""); status |= setIntegerParam(FastCCDOverscan, 2); status |= setIntegerParam(FastCCDFclk, 0); status |= setIntegerParam(FastCCDFCRICGain, 0); status |= setDoubleParam(FastCCDVBus12V0, 0); status |= setDoubleParam(FastCCDVMgmt3v3, 0); status |= setDoubleParam(FastCCDVMgmt2v5, 0); status |= setDoubleParam(FastCCDVMgmt1v2, 0); status |= setDoubleParam(FastCCDVEnet1v0, 0); status |= setDoubleParam(FastCCDVS3E3v3, 0); status |= setDoubleParam(FastCCDVGen3v3, 0); status |= setDoubleParam(FastCCDVGen2v5, 0); status |= setDoubleParam(FastCCDV60v9, 0); status |= setDoubleParam(FastCCDV61v0, 0); status |= setDoubleParam(FastCCDV62v5, 0); status |= setDoubleParam(FastCCDVFp, 0); status |= setDoubleParam(FastCCDIBus12V0, 0); status |= setDoubleParam(FastCCDIMgmt3v3, 0); status |= setDoubleParam(FastCCDIMgmt2v5, 0); status |= setDoubleParam(FastCCDIMgmt1v2, 0); status |= setDoubleParam(FastCCDIEnet1v0, 0); status |= setDoubleParam(FastCCDIS3E3v3, 0); status |= setDoubleParam(FastCCDIGen3v3, 0); status |= setDoubleParam(FastCCDIGen2v5, 0); status |= setDoubleParam(FastCCDI60v9, 0); status |= setDoubleParam(FastCCDI61v0, 0); status |= setDoubleParam(FastCCDI62v5, 0); status |= setDoubleParam(FastCCDIFp, 0); status |= setStringParam(FastCCDLibCinVersion, (char *)cin_build_version); callParamCallbacks(); // Signal the status thread to poll the detector epicsEventSignal(statusEvent); epicsEventSignal(dataStatsEvent); if (stackSize == 0) { stackSize = epicsThreadGetStackSize(epicsThreadStackMedium); } /* Create the thread that updates the detector status */ status = (epicsThreadCreate("FastCCDStatusTask", epicsThreadPriorityMedium, stackSize, (EPICSTHREADFUNC)FastCCDStatusTaskC, this) == NULL); if(status) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to create status task.\n", driverName, functionName); return; } /* Create the thread that updates the data stats */ status = (epicsThreadCreate("FastCCDDataStatsTask", epicsThreadPriorityMedium, stackSize, (EPICSTHREADFUNC)FastCCDDataStatsTaskC, this) == NULL); if(status) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to create data stats task.\n", driverName, functionName); return; } }
void FastCCD::getCameraStatus(void){ cin_ctl_id_t id; int cin_status = 0; cin_ctl_pwr_mon_t pwr_value; int pwr = 0; int full = 0; cin_status |= cin_ctl_get_id(&cin_ctl_port, &id); if(!cin_status){ setIntegerParam(FastCCDBoardID, id.board_id); setIntegerParam(FastCCDSerialNum, id.serial_no); setIntegerParam(FastCCDFPGAVersion, id.fpga_ver); setParamStatus(FastCCDBoardID, asynSuccess); setParamStatus(FastCCDSerialNum, asynSuccess); setParamStatus(FastCCDFPGAVersion, asynSuccess); } else { setParamStatus(FastCCDBoardID, asynDisconnected); setParamStatus(FastCCDSerialNum, asynDisconnected); setParamStatus(FastCCDFPGAVersion, asynDisconnected); } cin_status = cin_ctl_get_power_status(&cin_ctl_port, full, &pwr, &pwr_value); if(!cin_status){ // Power Status if(pwr){ setIntegerParam(FastCCDPower, 1); if(pwr == 2){ setIntegerParam(FastCCDFPPower, 1); } else { setIntegerParam(FastCCDFPPower, 0); } // Voltage Values setDoubleParam(FastCCDVBus12V0, pwr_value.bus_12v0.v); setDoubleParam(FastCCDIBus12V0, pwr_value.bus_12v0.i); setParamStatus(FastCCDVBus12V0, asynSuccess); setParamStatus(FastCCDIBus12V0, asynSuccess); if(full){ setDoubleParam(FastCCDVMgmt3v3, pwr_value.mgmt_3v3.v); setDoubleParam(FastCCDVMgmt2v5, pwr_value.mgmt_2v5.v); setDoubleParam(FastCCDVMgmt1v2, pwr_value.mgmt_1v2.v); setDoubleParam(FastCCDVEnet1v0, pwr_value.enet_1v0.v); setDoubleParam(FastCCDVS3E3v3, pwr_value.s3e_3v3.v); setDoubleParam(FastCCDVGen3v3, pwr_value.gen_3v3.v); setDoubleParam(FastCCDVGen2v5, pwr_value.gen_2v5.v); setDoubleParam(FastCCDV60v9, pwr_value.v6_0v9.v); setDoubleParam(FastCCDV61v0, pwr_value.v6_1v0.v); setDoubleParam(FastCCDV62v5, pwr_value.v6_2v5.v); setParamStatus(FastCCDVMgmt3v3, asynSuccess); setParamStatus(FastCCDVMgmt2v5, asynSuccess); setParamStatus(FastCCDVMgmt1v2, asynSuccess); setParamStatus(FastCCDVEnet1v0, asynSuccess); setParamStatus(FastCCDVS3E3v3, asynSuccess); setParamStatus(FastCCDVGen3v3, asynSuccess); setParamStatus(FastCCDVGen2v5, asynSuccess); setParamStatus(FastCCDV60v9, asynSuccess); setParamStatus(FastCCDV61v0, asynSuccess); setParamStatus(FastCCDV62v5, asynSuccess); // Current Values setDoubleParam(FastCCDIMgmt3v3, pwr_value.mgmt_3v3.i); setDoubleParam(FastCCDIMgmt2v5, pwr_value.mgmt_2v5.i); setDoubleParam(FastCCDIMgmt1v2, pwr_value.mgmt_1v2.i); setDoubleParam(FastCCDIEnet1v0, pwr_value.enet_1v0.i); setDoubleParam(FastCCDIS3E3v3, pwr_value.s3e_3v3.i); setDoubleParam(FastCCDIGen3v3, pwr_value.gen_3v3.i); setDoubleParam(FastCCDIGen2v5, pwr_value.gen_2v5.i); setDoubleParam(FastCCDI60v9, pwr_value.v6_0v9.i); setDoubleParam(FastCCDI61v0, pwr_value.v6_1v0.i); setDoubleParam(FastCCDI62v5, pwr_value.v6_2v5.i); setParamStatus(FastCCDIMgmt3v3, asynSuccess); setParamStatus(FastCCDIMgmt2v5, asynSuccess); setParamStatus(FastCCDIMgmt1v2, asynSuccess); setParamStatus(FastCCDIEnet1v0, asynSuccess); setParamStatus(FastCCDIS3E3v3, asynSuccess); setParamStatus(FastCCDIGen3v3, asynSuccess); setParamStatus(FastCCDIGen2v5, asynSuccess); setParamStatus(FastCCDI60v9, asynSuccess); setParamStatus(FastCCDI61v0, asynSuccess); setParamStatus(FastCCDI62v5, asynSuccess); } setDoubleParam(FastCCDVFp, pwr_value.fp.v); setDoubleParam(FastCCDIFp, pwr_value.fp.i); setParamStatus(FastCCDVFp, asynSuccess); setParamStatus(FastCCDIFp, asynSuccess); } else { setIntegerParam(FastCCDPower, 0); setIntegerParam(FastCCDFPPower, 0); } setParamStatus(FastCCDPower, asynSuccess); setParamStatus(FastCCDFPPower, asynSuccess); } if(cin_status || !pwr){ setParamStatus(FastCCDVBus12V0, asynDisconnected); setParamStatus(FastCCDIBus12V0, asynDisconnected); setParamStatus(FastCCDVFp, asynDisconnected); setParamStatus(FastCCDIFp, asynDisconnected); } if(!full || cin_status || !pwr){ // Voltage Values setParamStatus(FastCCDVMgmt3v3, asynDisconnected); setParamStatus(FastCCDVMgmt2v5, asynDisconnected); setParamStatus(FastCCDVMgmt1v2, asynDisconnected); setParamStatus(FastCCDVEnet1v0, asynDisconnected); setParamStatus(FastCCDVS3E3v3, asynDisconnected); setParamStatus(FastCCDVGen3v3, asynDisconnected); setParamStatus(FastCCDVGen2v5, asynDisconnected); setParamStatus(FastCCDV60v9, asynDisconnected); setParamStatus(FastCCDV61v0, asynDisconnected); setParamStatus(FastCCDV62v5, asynDisconnected); // Current Values setParamStatus(FastCCDIMgmt3v3, asynDisconnected); setParamStatus(FastCCDIMgmt2v5, asynDisconnected); setParamStatus(FastCCDIMgmt1v2, asynDisconnected); setParamStatus(FastCCDIEnet1v0, asynDisconnected); setParamStatus(FastCCDIS3E3v3, asynDisconnected); setParamStatus(FastCCDIGen3v3, asynDisconnected); setParamStatus(FastCCDIGen2v5, asynDisconnected); setParamStatus(FastCCDI60v9, asynDisconnected); setParamStatus(FastCCDI61v0, asynDisconnected); setParamStatus(FastCCDI62v5, asynDisconnected); } // Status uint16_t fpga_status, dcm_status; cin_status = cin_ctl_get_cfg_fpga_status(&cin_ctl_port, &fpga_status); if(!cin_status){ setUIntDigitalParam(FastCCDFPGAStatus, fpga_status, 0xFFFF); setParamStatus(FastCCDFPGAStatus, asynSuccess); } else { setParamStatus(FastCCDFPGAStatus, asynDisconnected); } cin_status = cin_ctl_get_dcm_status(&cin_ctl_port, &dcm_status); if(!cin_status){ setUIntDigitalParam(FastCCDDCMStatus, dcm_status, 0xFFFF); setParamStatus(FastCCDDCMStatus, asynSuccess); } else { setParamStatus(FastCCDDCMStatus, asynDisconnected); } /* Are we powered up and configured? */ if(fpga_status & CIN_CTL_FPGA_STS_CFG){ // Clock and Bias status int _val; cin_status = cin_ctl_get_camera_pwr(&cin_ctl_port, &_val); if(!cin_status){ setIntegerParam(FastCCDCameraPower, _val); setParamStatus(FastCCDCameraPower, asynSuccess); } else { setParamStatus(FastCCDCameraPower, asynDisconnected); } cin_status = cin_ctl_get_clocks(&cin_ctl_port, &_val); if(!cin_status){ setIntegerParam(FastCCDClocks, _val); setParamStatus(FastCCDClocks, asynSuccess); } else { setParamStatus(FastCCDClocks, asynDisconnected); } cin_status = cin_ctl_get_bias(&cin_ctl_port, &_val); if(!cin_status){ setIntegerParam(FastCCDBias, _val); setParamStatus(FastCCDBias, asynSuccess); } else { setParamStatus(FastCCDBias, asynDisconnected); } // Get Mux Settings int mux; cin_status = cin_ctl_get_mux(&cin_ctl_port, &mux); if(!cin_status){ setIntegerParam(FastCCDMux1, (mux & 0x000F)); setIntegerParam(FastCCDMux2, (mux & 0x00F0) >> 4); setParamStatus(FastCCDMux1, asynSuccess); setParamStatus(FastCCDMux2, asynSuccess); } else {
/** 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_); } }
//------------------------------------------------------------------------------ //! @brief Constructor for the drvAsynWienerVme class. //! Calls constructor for the asynPortDriver base class. //! //! @param [in] portName The name of the asynPortDriver to be created. //! @param [in] CanPort The name of the asynPortDriver of the CAN bus interface //! @param [in] crate_id The id of the crate //------------------------------------------------------------------------------ drvAsynWienerVme::drvAsynWienerVme( const char *portName, const char *CanPort, const int crate_id ) : asynPortDriver( portName, 1, /* maxAddr */ NUM_WIENERVME_PARAMS, asynCommonMask | asynInt32Mask | asynUInt32DigitalMask | asynDrvUserMask, /* Interface mask */ asynCommonMask | asynInt32Mask | asynUInt32DigitalMask, /* Interrupt mask */ ASYN_CANBLOCK, /* asynFlags. */ 1, /* Autoconnect */ 0, /* Default priority */ 0 ) /* Default stack size*/ { const char *functionName = "drvAsynWienerVme"; asynStatus status = asynSuccess; _deviceName = epicsStrDup( portName ); _crateId = crate_id; // Create parameters createParam( P_WIENERVME_STATUS0_STRING, asynParamUInt32Digital, &P_Status0 ); createParam( P_WIENERVME_STATUS1_STRING, asynParamUInt32Digital, &P_Status1 ); createParam( P_WIENERVME_STATUS2_STRING, asynParamUInt32Digital, &P_Status2 ); createParam( P_WIENERVME_STATUS3_STRING, asynParamUInt32Digital, &P_Status3 ); createParam( P_WIENERVME_STATUS4_STRING, asynParamUInt32Digital, &P_Status4 ); createParam( P_WIENERVME_STATUS5_STRING, asynParamUInt32Digital, &P_Status5 ); createParam( P_WIENERVME_STATUS6_STRING, asynParamUInt32Digital, &P_Status6 ); createParam( P_WIENERVME_STATUS7_STRING, asynParamUInt32Digital, &P_Status7 ); createParam( P_WIENERVME_V0_STRING, asynParamInt32, &P_Vmom0 ); createParam( P_WIENERVME_V1_STRING, asynParamInt32, &P_Vmom1 ); createParam( P_WIENERVME_V2_STRING, asynParamInt32, &P_Vmom2 ); createParam( P_WIENERVME_V3_STRING, asynParamInt32, &P_Vmom3 ); createParam( P_WIENERVME_V4_STRING, asynParamInt32, &P_Vmom4 ); createParam( P_WIENERVME_V5_STRING, asynParamInt32, &P_Vmom5 ); createParam( P_WIENERVME_V6_STRING, asynParamInt32, &P_Vmom6 ); createParam( P_WIENERVME_V7_STRING, asynParamInt32, &P_Vmom7 ); createParam( P_WIENERVME_I0_STRING, asynParamInt32, &P_Imom0 ); createParam( P_WIENERVME_I1_STRING, asynParamInt32, &P_Imom1 ); createParam( P_WIENERVME_I2_STRING, asynParamInt32, &P_Imom2 ); createParam( P_WIENERVME_I3_STRING, asynParamInt32, &P_Imom3 ); createParam( P_WIENERVME_I4_STRING, asynParamInt32, &P_Imom4 ); createParam( P_WIENERVME_I5_STRING, asynParamInt32, &P_Imom5 ); createParam( P_WIENERVME_I6_STRING, asynParamInt32, &P_Imom6 ); createParam( P_WIENERVME_I7_STRING, asynParamInt32, &P_Imom7 ); createParam( P_WIENERVME_FANMIDDLE_STRING, asynParamInt32, &P_FanMiddle ); createParam( P_WIENERVME_FANNOMINAL_STRING, asynParamInt32, &P_FanNominal ); createParam( P_WIENERVME_FAN1_STRING, asynParamInt32, &P_Fan1 ); createParam( P_WIENERVME_FAN2_STRING, asynParamInt32, &P_Fan2 ); createParam( P_WIENERVME_FAN3_STRING, asynParamInt32, &P_Fan3 ); createParam( P_WIENERVME_FAN4_STRING, asynParamInt32, &P_Fan4 ); createParam( P_WIENERVME_FAN5_STRING, asynParamInt32, &P_Fan5 ); createParam( P_WIENERVME_FAN6_STRING, asynParamInt32, &P_Fan6 ); createParam( P_WIENERVME_TEMP1_STRING, asynParamInt32, &P_Temp1 ); createParam( P_WIENERVME_TEMP2_STRING, asynParamInt32, &P_Temp2 ); createParam( P_WIENERVME_TEMP3_STRING, asynParamInt32, &P_Temp3 ); createParam( P_WIENERVME_TEMP4_STRING, asynParamInt32, &P_Temp4 ); createParam( P_WIENERVME_TEMP5_STRING, asynParamInt32, &P_Temp5 ); createParam( P_WIENERVME_TEMP6_STRING, asynParamInt32, &P_Temp6 ); createParam( P_WIENERVME_TEMP7_STRING, asynParamInt32, &P_Temp7 ); createParam( P_WIENERVME_TEMP8_STRING, asynParamInt32, &P_Temp8 ); createParam( P_WIENERVME_SWITCH_STRING, asynParamUInt32Digital, &P_Switch ); createParam( P_WIENERVME_SYSRESET_STRING, asynParamInt32, &P_Sysreset ); createParam( P_WIENERVME_CHANGEFAN_STRING, asynParamInt32, &P_FanSpeed ); /* Connect to asyn generic pointer port with asynGenericPointerSyncIO */ status = pasynGenericPointerSyncIO->connect( CanPort, 0, &_pasynGenericPointer, 0 ); if ( status != asynSuccess ) { printf( "%s:%s:%s: can't connect to asynGenericPointer on port '%s'\n", driverName, _deviceName, functionName, CanPort ); } // Get inital value for Switch-Parameter can_frame_t pframe; pframe.can_id = _crateId | CAN_RTR_FLAG; pframe.can_dlc = 1; status = pasynGenericPointerSyncIO->writeRead( _pasynGenericPointer, &pframe, &pframe, .5 ); if ( status != asynSuccess ) { fprintf( stderr, "\033[31;1m%s:%s:%s: Init %s: No reply from device within 1 s!\033[0m\n", driverName, _deviceName, functionName, P_WIENERVME_SWITCH_STRING ); return; } setUIntDigitalParam( P_Switch, pframe.data[0] & 0x01, 1 ); // initial value for nominal fan speed pframe.can_id = _crateId | ( 6 << 7 ) | CAN_RTR_FLAG; pframe.can_dlc = 2; status = pasynGenericPointerSyncIO->writeRead( _pasynGenericPointer, &pframe, &pframe, .5 ); if ( status != asynSuccess ) { fprintf( stderr, "\033[31;1m%s:%s:%s: Init %s: No reply from device within 1 s!\033[0m\n", driverName, _deviceName, functionName, P_WIENERVME_CHANGEFAN_STRING ); return; } setIntegerParam( P_FanSpeed, pframe.data[1] ); vme_cmd_t vc04_cmd = { ( 2 << 7 ), 4, { P_Vmom0, P_Imom0, P_Vmom4, P_Imom4 } }; _cmds.insert( std::make_pair( P_Vmom0, vc04_cmd ) ); vme_cmd_t vc15_cmd = { ( 3 << 7 ), 4, { P_Vmom1, P_Imom1, P_Vmom5, P_Imom5 } }; _cmds.insert( std::make_pair( P_Vmom1, vc15_cmd ) ); vme_cmd_t vc26_cmd = { ( 4 << 7 ), 4, { P_Vmom2, P_Imom2, P_Vmom6, P_Imom6 } }; _cmds.insert( std::make_pair( P_Vmom2, vc26_cmd ) ); vme_cmd_t vc37_cmd = { ( 5 << 7 ), 4, { P_Vmom3, P_Imom3, P_Vmom7, P_Imom7 } }; _cmds.insert( std::make_pair( P_Vmom3, vc37_cmd ) ); vme_cmd_t fan_cmd = { ( 6 << 7 ), 8, { P_FanMiddle, P_FanNominal, P_Fan1, P_Fan2, P_Fan3, P_Fan4, P_Fan5, P_Fan6 } }; _cmds.insert( std::make_pair( P_FanMiddle, fan_cmd ) ); vme_cmd_t temp_cmd = { ( 7 << 7 ), 8, { P_Temp1, P_Temp2, P_Temp3, P_Temp4, P_Temp5, P_Temp6, P_Temp7, P_Temp8 } }; _cmds.insert( std::make_pair( P_Temp1, temp_cmd ) ); }