Commit dd762e96 authored by kpetersn's avatar kpetersn
Browse files

Added more functionality. Everything that calls SetValue() current causes the IOC to segfault.

parent 61dfd1da
......@@ -6,9 +6,52 @@ record(ai, "$(P)$(T):temperature_RBV")
field(LINR, "NO CONVERSION")
#!field(ASLO, "1.0")
#!field(AOFF, "0.0")
#!field(HOPR, "2000.0")
#!field(LOPR, "-300.0")
field(PREC, "3")
field(PREC, "4")
field(EGU, "Celsius")
field(SCAN, "Passive")
}
record(ao, "$(P)$(T):rampLimit")
{
field(DTYP, "asynFloat64")
field(OUT, "@asyn($(PORT),$(ADDR))RAMP_LIMIT_OUT_VALUE")
#field(PINI, "YES")
field(LINR, "NO CONVERSION")
field(PREC, "4")
field(EGU, "Celsius")
field(SCAN, "Passive")
field(VAL, "22.0")
}
record(ao, "$(P)$(T):rampRate")
{
field(DTYP, "asynFloat64")
field(OUT, "@asyn($(PORT),$(ADDR))RAMP_RATE_OUT_VALUE")
#field(PINI, "YES")
field(LINR, "NO CONVERSION")
field(PREC, "4")
field(EGU, "Deg C / min")
field(SCAN, "Passive")
field(VAL, "20.0")
}
record(ai, "$(P)$(T):heaterPower_RBV")
{
field(DTYP, "asynFloat64")
field(INP, "@asyn($(PORT),$(ADDR))HEATER_POWER_IN_VALUE")
#field(PINI, "YES")
field(LINR, "NO CONVERSION")
field(PREC, "4")
field(EGU, "Watts")
field(SCAN, "Passive")
}
record(bo, "$(P)$(T):heating")
{
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR))HEATING_OUT_VALUE")
#field(PINI, "YES")
field(ZNAM, "Off")
field(ONAM, "On")
field(VAL, "0")
}
......@@ -20,7 +20,11 @@ Linkam::Linkam(const char *portName, const char *serialPort) : asynPortDriver(po
serialPort_ = epicsStrDup(serialPort);
static const char *functionName = "Linkam";
createParam(temperatureInValueString, asynParamFloat64, &temperatureInValue_);
createParam(temperatureInValueString, asynParamFloat64, &temperatureInValue_);
createParam(rampLimitOutValueString, asynParamFloat64, &rampLimitOutValue_);
createParam(rampRateOutValueString, asynParamFloat64, &rampRateOutValue_);
createParam(heaterPowerInValueString, asynParamFloat64, &heaterPowerInValue_);
createParam(heatingOutValueString, asynParamInt32, &heatingOutValue_);
// Must be in the directory with the DLL when this line is executed
LoadMonoLibrary("LinkamCommsDll.dll");
......@@ -33,13 +37,6 @@ Linkam::Linkam(const char *portName, const char *serialPort) : asynPortDriver(po
printf("Comms Library Version %s\n", libraryVersion_);
// Start poller? For now just initialize the temperature
// Wrapped call to LinkamCommDll.Comms.GetValue(). Index 0 is temperature.
// See Linkam.SharedEnums.eVALUETYPE page for full listing.
//temperatureRbv_ = GetValue(0);
//printf("Stage temperature:%f °C\n", temperatureRbv_);
// Initialize the temperature param to something other than the default (25.0)
//setDoubleParam(temperatureInValue_, 21.3);
//callParamCallbacks();
// Force the device to connect now
connect(this->pasynUserSelf);
......@@ -112,6 +109,7 @@ asynStatus Linkam::disconnect(asynUser *pasynUser)
return asynSuccess;
}
asynStatus Linkam::readFloat64(asynUser *pasynUser, epicsFloat64 *value)
{
int function = pasynUser->reason;
......@@ -127,12 +125,17 @@ asynStatus Linkam::readFloat64(asynUser *pasynUser, epicsFloat64 *value)
// Read the temperature from the controller
status = readTemperature(value);
// Update the temperatureInValue_ parameter
setDoubleParam(function, *value);
} else if (function == heaterPowerInValue_) {
// Read the temperature from the controller
status = readHeaterPower(value);
} else {
status = asynPortDriver::readFloat64(pasynUser,value);
}
// Update the temperatureInValue_ parameter
setDoubleParam(function, *value);
callParamCallbacks();
......@@ -143,19 +146,159 @@ asynStatus Linkam::readTemperature(epicsFloat64 *value)
{
static const char *functionName = "readTemperature";
// The temperature is the 0th value
*value = GetValue(0);
*value = GetValue(u32Heater1TempR);
// There probably isn't a good reason to retain the temperature in a private variable;
// The value is already stored in the parameter library
temperatureRbv_ = *value;
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, temperature = %lf\n",
"%s:%s, port %s, value = %lf\n",
driverName, functionName, this->portName, temperatureRbv_);
return asynSuccess;
}
asynStatus Linkam::readHeaterPower(epicsFloat64 *value)
{
static const char *functionName = "readHeaterPower";
*value = GetValue(u32Heater1PowerR);
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, value = %lf\n",
driverName, functionName, this->portName, temperatureRbv_);
return asynSuccess;
}
asynStatus Linkam::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
{
int function = pasynUser->reason;
asynStatus status;
static const char *functionName = "writeFloat64";
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, function = %d\n",
driverName, functionName, this->portName, function);
// Set the new value; it can be reverted later if commands fail
setDoubleParam(function, value);
if (function == rampLimitOutValue_) {
// Read the temperature from the controller
status = setRampLimit(value);
} else if (function == rampRateOutValue_) {
// Read the temperature from the controller
status = setRampRate(value);
} else {
status = asynPortDriver::writeFloat64(pasynUser,value);
}
callParamCallbacks();
if (status == 0) {
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, wrote %lf\n",
driverName, functionName, this->portName, value);
} else {
asynPrint(pasynUser, ASYN_TRACE_ERROR,
"%s:%s, port %s, ERROR writing %lf, status=%d\n",
driverName, functionName, this->portName, value, status);
}
return (status==0) ? asynSuccess : asynError;
}
asynStatus Linkam::setRampLimit(epicsFloat64 value)
{
bool status;
static const char *functionName = "setRampLimit";
/*
* bool SetValue(
* unsigned int u32ValueType,
* float fValue)
*
* Returns true if set successfully, false otherwise.
*/
//status = SetValue(u32Heater1LimitRW, (float) value);
status = SetValue(2, (float) value);
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, value = %lf\n",
driverName, functionName, this->portName, value);
return (status) ? asynSuccess : asynError;
}
asynStatus Linkam::setRampRate(epicsFloat64 value)
{
bool status;
static const char *functionName = "setRampRate";
//status = SetValue(u32Heater1RateRW, (float) value);
status = SetValue(1, (float) value);
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, value = %lf\n",
driverName, functionName, this->portName, value);
return (status) ? asynSuccess : asynError;
}
asynStatus Linkam::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
int function = pasynUser->reason;
asynStatus status = asynSuccess;
static const char *functionName = "writeInt32";
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, function = %d\n",
driverName, functionName, this->portName, function);
// Set the new value; it can be reverted later if commands fail
setIntegerParam(function, value);
if (function == heatingOutValue_) {
// Enable/disable heating
status = setHeating(value);
}
callParamCallbacks();
if (status == 0) {
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, wrote %d\n",
driverName, functionName, this->portName, value);
} else {
asynPrint(pasynUser, ASYN_TRACE_ERROR,
"%s:%s, port %s, ERROR writing %d, status=%d\n",
driverName, functionName, this->portName, value, status);
}
return (status==0) ? asynSuccess : asynError;
}
asynStatus Linkam::setHeating(epicsInt32 value)
{
bool status;
static const char *functionName = "setHeating";
status = StartHeating((value==1) ? true : false);
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s, port %s, value = %d\n",
driverName, functionName, this->portName, value);
return (status) ? asynSuccess : asynError;
}
void Linkam::report(FILE *fp, int details)
{
......
......@@ -10,9 +10,20 @@ static const char *driverName = "Linkam";
#define MAX_CONTROLLERS 1
// eVALUETYPE Enumeration
#define u32Heater1TempR 0
#define u32Heater1RateRW 1
#define u32Heater1LimitRW 2
#define u32Heater1PowerR 3
/* These are the drvInfo strings that are used to identify the parameters.
* They are used by asyn clients, including standard asyn device support */
#define temperatureInValueString "TEMPERATURE_IN_VALUE" /* asynFloat64 r/o */
#define rampLimitOutValueString "RAMP_LIMIT_OUT_VALUE" /* asynFloat64 r/w */
#define rampRateOutValueString "RAMP_RATE_OUT_VALUE" /* asynFloat64 r/w */
#define heaterPowerInValueString "HEATER_POWER_IN_VALUE" /* asynFloat64 r/o */
#define heatingOutValueString "HEATING_OUT_VALUE" /* asynInt32 r/w */
/*
* Class definition for the Linkam class
......@@ -22,18 +33,28 @@ public:
Linkam(const char *portName, const char *serialPort);
/* These are the methods that we override from asynPortDriver */
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
virtual asynStatus disconnect(asynUser *pasynUser);
virtual asynStatus connect(asynUser *pasynUser);
virtual ~Linkam();
protected:
int temperatureInValue_;
int rampLimitOutValue_;
int rampRateOutValue_;
int heaterPowerInValue_;
int heatingOutValue_;
#define FIRST_LINKAM_PARAM temperatureInValue_;
#define LAST_LINKAM_PARAM temperatureInValue_;
#define LAST_LINKAM_PARAM heatingOutValue_;
private:
asynStatus readTemperature(epicsFloat64 *value);
asynStatus setRampLimit(epicsFloat64 value);
asynStatus setRampRate(epicsFloat64 value);
asynStatus readHeaterPower(epicsFloat64 *value);
asynStatus setHeating(epicsInt32 value);
void report(FILE *fp, int details);
char* serialPort_;
......
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = linux-x86_64
#!ARCH = linux-x86_64
ARCH = linux-x86_64-debug
TARGETS = envPaths
include $(TOP)/configure/RULES.ioc
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment