Compare commits

...

3 Commits

Author SHA1 Message Date
4c3254687d Renamed "ipPortUser_" to "ipPortAsynOctetSyncIO_"
I learned that there might be multiple asynUsers connected to the same
port for different types (asynInt32, asynOctet, ...). Therefore I
renamed "ipPortUser_" to better reflect this.
2025-04-15 17:15:34 +02:00
eb94379efe Small detail improvements from code review
In a code review with Edward and Alex, some optimization potential in
the sinqMotor.db file was discovered. This patch implements those
improvements.
2025-04-09 16:39:36 +02:00
1dd132c709 Added the ability to set the limits from the substitution file 2025-04-04 13:29:49 +02:00
4 changed files with 31 additions and 29 deletions

View File

@ -42,13 +42,11 @@ record(motor,"$(INSTR)$(M)")
} }
# This PV reads out the 10th bit of the MSTA field of the motor record, which # This PV reads out the 10th bit of the MSTA field of the motor record, which
# is the "motorStatusProblem_" bit. The 10th bit is adressed by 0x0200. If the # is the "motorStatusProblem_" bit.
# bit is 0, the .VAL field is 0 as well. If the bit is 1, we need to divide by
# 512 (=2^9) in order to set the .VAL field to 1 (and not to 512).
record(calc, "$(INSTR)$(M):StatusProblem") record(calc, "$(INSTR)$(M):StatusProblem")
{ {
field(INPA, "$(INSTR)$(M).MSTA CP") field(INPA, "$(INSTR)$(M).MSTA CP")
field(CALC, "(A&0x200)/512") field(CALC, "A >> 9")
} }
# Call the reset function of the corresponding sinqAxis # Call the reset function of the corresponding sinqAxis
@ -71,7 +69,7 @@ record(longin, "$(INSTR)$(M):StopRBV")
field(FLNK, "$(INSTR)$(M):Stop2Field") field(FLNK, "$(INSTR)$(M):Stop2Field")
} }
record(longout, "$(INSTR)$(M):Stop2Field") { record(longout, "$(INSTR)$(M):Stop2Field") {
field(DOL, "$(INSTR)$(M):StopRBV CP") field(DOL, "$(INSTR)$(M):StopRBV NPP")
field(OUT, "$(INSTR)$(M).STOP") field(OUT, "$(INSTR)$(M).STOP")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
} }
@ -82,7 +80,7 @@ record(longout, "$(INSTR)$(M):Stop2Field") {
# for calculating the estimated time of arrival inside the watchdog). # for calculating the estimated time of arrival inside the watchdog).
record(ao,"$(INSTR)$(M):RecResolution") { record(ao,"$(INSTR)$(M):RecResolution") {
field(DESC, "$(M) resolution") field(DESC, "$(M) resolution")
field(DOL, "$(INSTR)$(M).MRES CP MS") field(DOL, "$(INSTR)$(M).MRES CP")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
field(DTYP, "asynFloat64") field(DTYP, "asynFloat64")
field(OUT, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_REC_RESOLUTION") field(OUT, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_REC_RESOLUTION")
@ -175,12 +173,13 @@ record(ao, "$(INSTR)$(M):LimitsOffset") {
record(ai, "$(INSTR)$(M):DHLM_RBV") record(ai, "$(INSTR)$(M):DHLM_RBV")
{ {
field(DTYP, "asynFloat64") field(DTYP, "asynFloat64")
field(VAL, "$(DHLM=0)")
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_HIGH_LIMIT_FROM_DRIVER") field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_HIGH_LIMIT_FROM_DRIVER")
field(SCAN, "I/O Intr") field(SCAN, "I/O Intr")
field(FLNK, "$(INSTR)$(M):PushDHLM2Field") field(FLNK, "$(INSTR)$(M):PushDHLM2Field")
} }
record(ao, "$(INSTR)$(M):PushDHLM2Field") { record(ao, "$(INSTR)$(M):PushDHLM2Field") {
field(DOL, "$(INSTR)$(M):DHLM_RBV CP") field(DOL, "$(INSTR)$(M):DHLM_RBV NPP")
field(OUT, "$(INSTR)$(M).DHLM") field(OUT, "$(INSTR)$(M).DHLM")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
} }
@ -193,12 +192,13 @@ record(ao, "$(INSTR)$(M):PushDHLM2Field") {
record(ai, "$(INSTR)$(M):DLLM_RBV") record(ai, "$(INSTR)$(M):DLLM_RBV")
{ {
field(DTYP, "asynFloat64") field(DTYP, "asynFloat64")
field(VAL, "$(DLLM=0)")
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_LOW_LIMIT_FROM_DRIVER") field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_LOW_LIMIT_FROM_DRIVER")
field(SCAN, "I/O Intr") field(SCAN, "I/O Intr")
field(FLNK, "$(INSTR)$(M):PushDLLM2Field") field(FLNK, "$(INSTR)$(M):PushDLLM2Field")
} }
record(ao, "$(INSTR)$(M):PushDLLM2Field") { record(ao, "$(INSTR)$(M):PushDLLM2Field") {
field(DOL, "$(INSTR)$(M):DLLM_RBV CP") field(DOL, "$(INSTR)$(M):DLLM_RBV NPP")
field(OUT, "$(INSTR)$(M).DLLM") field(OUT, "$(INSTR)$(M).DLLM")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
} }
@ -216,7 +216,7 @@ record(ai, "$(INSTR)$(M):VELO_RBV")
field(FLNK, "$(INSTR)$(M):PushVELO2Field") field(FLNK, "$(INSTR)$(M):PushVELO2Field")
} }
record(ao, "$(INSTR)$(M):PushVELO2Field") { record(ao, "$(INSTR)$(M):PushVELO2Field") {
field(DOL, "$(INSTR)$(M):VELO_RBV CP") field(DOL, "$(INSTR)$(M):VELO_RBV NPP")
field(OUT, "$(INSTR)$(M).VELO") field(OUT, "$(INSTR)$(M).VELO")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
} }
@ -234,7 +234,7 @@ record(ai, "$(INSTR)$(M):VBAS_RBV")
field(FLNK, "$(INSTR)$(M):PushVBAS2Field") field(FLNK, "$(INSTR)$(M):PushVBAS2Field")
} }
record(ao, "$(INSTR)$(M):PushVBAS2Field") { record(ao, "$(INSTR)$(M):PushVBAS2Field") {
field(DOL, "$(INSTR)$(M):VBAS_RBV CP") field(DOL, "$(INSTR)$(M):VBAS_RBV NPP")
field(OUT, "$(INSTR)$(M).VBAS") field(OUT, "$(INSTR)$(M).VBAS")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
} }
@ -252,7 +252,7 @@ record(ai, "$(INSTR)$(M):VMAX_RBV")
field(FLNK, "$(INSTR)$(M):PushVMAX2Field") field(FLNK, "$(INSTR)$(M):PushVMAX2Field")
} }
record(ao, "$(INSTR)$(M):PushVMAX2Field") { record(ao, "$(INSTR)$(M):PushVMAX2Field") {
field(DOL, "$(INSTR)$(M):VMAX_RBV CP") field(DOL, "$(INSTR)$(M):VMAX_RBV NPP")
field(OUT, "$(INSTR)$(M).VMAX") field(OUT, "$(INSTR)$(M).VMAX")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
} }
@ -270,7 +270,7 @@ record(ai, "$(INSTR)$(M):ACCL_RBV")
field(FLNK, "$(INSTR)$(M):PushACCL2Field") field(FLNK, "$(INSTR)$(M):PushACCL2Field")
} }
record(ao, "$(INSTR)$(M):PushACCL2Field") { record(ao, "$(INSTR)$(M):PushACCL2Field") {
field(DOL, "$(INSTR)$(M):ACCL_RBV CP") field(DOL, "$(INSTR)$(M):ACCL_RBV NPP")
field(OUT, "$(INSTR)$(M).ACCL") field(OUT, "$(INSTR)$(M).ACCL")
field(OMSL, "closed_loop") field(OMSL, "closed_loop")
} }
@ -288,4 +288,4 @@ record(waveform, "$(INSTR)$(M):EncoderType") {
field(FTVL, "CHAR") field(FTVL, "CHAR")
field(NELM, "80") field(NELM, "80")
field(SCAN, "I/O Intr") field(SCAN, "I/O Intr")
} }

View File

@ -662,8 +662,7 @@ extern "C" {
*/ */
asynStatus setWatchdogEnabled(const char *portName, int axisNo, int enable) { asynStatus setWatchdogEnabled(const char *portName, int axisNo, int enable) {
sinqController *pC; sinqController *pC = (sinqController *)findAsynPortDriver(portName);
pC = (sinqController *)findAsynPortDriver(portName);
if (pC == nullptr) { if (pC == nullptr) {
errlogPrintf("Controller \"%s\" => %s, line %d:\nPort %s not found.", errlogPrintf("Controller \"%s\" => %s, line %d:\nPort %s not found.",
portName, __PRETTY_FUNCTION__, __LINE__, portName); portName, __PRETTY_FUNCTION__, __LINE__, portName);

View File

@ -51,7 +51,9 @@ sinqController::sinqController(const char *portName,
msgPrintControl_(4) { msgPrintControl_(4) {
asynStatus status = asynSuccess; asynStatus status = asynSuccess;
ipPortUser_ = nullptr;
// Handle to the asynUser of the IP port asyn driver
ipPortAsynOctetSyncIO_ = nullptr;
// Initial values for the average timeout mechanism, can be overwritten // Initial values for the average timeout mechanism, can be overwritten
// later by a FFI function // later by a FFI function
@ -79,8 +81,9 @@ sinqController::sinqController(const char *portName,
We try to connect to the port via the port name provided by the constructor. We try to connect to the port via the port name provided by the constructor.
If this fails, the function is terminated via exit. If this fails, the function is terminated via exit.
*/ */
pasynOctetSyncIO->connect(ipPortConfigName, 0, &ipPortUser_, NULL); pasynOctetSyncIO->connect(ipPortConfigName, 0, &ipPortAsynOctetSyncIO_,
if (status != asynSuccess || ipPortUser_ == nullptr) { NULL);
if (status != asynSuccess || ipPortAsynOctetSyncIO_ == nullptr) {
errlogPrintf("Controller \"%s\" => %s, line %d:\nFATAL ERROR (cannot " errlogPrintf("Controller \"%s\" => %s, line %d:\nFATAL ERROR (cannot "
"connect to MCU controller).\n" "connect to MCU controller).\n"
"Terminating IOC", "Terminating IOC",
@ -353,7 +356,7 @@ asynStatus sinqController::couldNotParseResponse(const char *command,
int line) { int line) {
asynStatus pl_status = asynSuccess; asynStatus pl_status = asynSuccess;
asynPrint(ipPortUser_, ASYN_TRACE_ERROR, asynPrint(ipPortAsynOctetSyncIO_, ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nCould not interpret " "Controller \"%s\", axis %d => %s, line %d:\nCould not interpret "
"response \"%s\" for command \"%s\".\n", "response \"%s\" for command \"%s\".\n",
portName, axisNo, functionName, line, response, command); portName, axisNo, functionName, line, response, command);
@ -382,7 +385,7 @@ asynStatus sinqController::paramLibAccessFailed(asynStatus status,
int line) { int line) {
if (status != asynSuccess) { if (status != asynSuccess) {
asynPrint(ipPortUser_, ASYN_TRACE_ERROR, asynPrint(ipPortAsynOctetSyncIO_, ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\n Accessing the " "Controller \"%s\", axis %d => %s, line %d:\n Accessing the "
"parameter library failed for parameter %s with error %s.\n", "parameter library failed for parameter %s with error %s.\n",
portName, axisNo, functionName, line, parameter, portName, axisNo, functionName, line, parameter,
@ -651,9 +654,9 @@ asynStatus setMaxSubsequentTimeouts(const char *portName,
if (ptr == nullptr) { if (ptr == nullptr) {
/* /*
We can't use asynPrint here since this macro would require us We can't use asynPrint here since this macro would require us
to get a ipPortUser_ from a pointer to an asynPortDriver. to get a ipPortAsynOctetSyncIO_ from a pointer to an asynPortDriver.
However, the given pointer is a nullptr and therefore doesn't However, the given pointer is a nullptr and therefore doesn't
have a ipPortUser_! printf is an EPICS alternative which have a ipPortAsynOctetSyncIO_! printf is an EPICS alternative which
works w/o that, but doesn't offer the comfort provided works w/o that, but doesn't offer the comfort provided
by the asynTrace-facility by the asynTrace-facility
*/ */

View File

@ -41,8 +41,8 @@ class epicsShareClass sinqController : public asynMotorController {
* @param extraParams Number of extra parameter library entries * @param extraParams Number of extra parameter library entries
* created in a concrete driver implementation * created in a concrete driver implementation
*/ */
sinqController(const char *portName, const char *SINQPortName, int numAxes, sinqController(const char *portName, const char *ipPortConfigName,
double movingPollPeriod, double idlePollPeriod, int numAxes, double movingPollPeriod, double idlePollPeriod,
int numExtraParams); int numExtraParams);
/** /**
@ -115,9 +115,9 @@ class epicsShareClass sinqController : public asynMotorController {
called. It is recommended to use a macro, e.g. __LINE__. called. It is recommended to use a macro, e.g. __LINE__.
* @return asynStatus Returns asynError. * @return asynStatus Returns asynError.
*/ */
asynStatus couldNotParseResponse(const char *command, asynStatus couldNotParseResponse(const char *command, const char *response,
const char *response, int axisNo, int axisNo, const char *functionName,
const char *functionName, int line); int line);
/** /**
* @brief Convert an asynStatus into a descriptive string. * @brief Convert an asynStatus into a descriptive string.
@ -298,14 +298,14 @@ class epicsShareClass sinqController : public asynMotorController {
double idlePollPeriod() { return idlePollPeriod_; } double idlePollPeriod() { return idlePollPeriod_; }
double movingPollPeriod() { return movingPollPeriod_; } double movingPollPeriod() { return movingPollPeriod_; }
asynUser *asynUserSelf() { return pasynUserSelf; } asynUser *asynUserSelf() { return pasynUserSelf; }
asynUser *ipPortUser() { return ipPortUser_; } asynUser *ipPortAsynOctetSyncIO() { return ipPortAsynOctetSyncIO_; }
// ========================================================================= // =========================================================================
protected: protected:
// Pointer to the port user which is specified by the char array // Pointer to the port user which is specified by the char array
// `ipPortConfigName` in the constructor // `ipPortConfigName` in the constructor
asynUser *ipPortUser_; asynUser *ipPortAsynOctetSyncIO_;
double movingPollPeriod_; double movingPollPeriod_;
double idlePollPeriod_; double idlePollPeriod_;
msgPrintControl msgPrintControl_; msgPrintControl msgPrintControl_;