Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
370aef212e | |||
3b39d724db | |||
23c03353a1 | |||
4743006880 | |||
0da78d2e72 |
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ REQUIRED+=sinqMotor
|
|||||||
motorBase_VERSION=7.2.2
|
motorBase_VERSION=7.2.2
|
||||||
|
|
||||||
# Specify the version of sinqMotor we want to build against
|
# Specify the version of sinqMotor we want to build against
|
||||||
sinqMotor_VERSION=0.13.0
|
sinqMotor_VERSION=0.14
|
||||||
|
|
||||||
# These headers allow to depend on this library for derived drivers.
|
# These headers allow to depend on this library for derived drivers.
|
||||||
HEADERS += src/pmacAsynIPPort.h
|
HEADERS += src/pmacAsynIPPort.h
|
||||||
|
24
README.md
24
README.md
@ -26,13 +26,13 @@ The full turboPmacX.cmd file looks like this:
|
|||||||
|
|
||||||
```
|
```
|
||||||
# Define the name of the controller and the corresponding port
|
# Define the name of the controller and the corresponding port
|
||||||
epicsEnvSet("NAME","turboPmacX")
|
epicsEnvSet("DRIVER_PORT","turboPmacX")
|
||||||
epicsEnvSet("ASYN_PORT","p$(NAME)")
|
epicsEnvSet("IP_PORT","p$(DRIVER_PORT)")
|
||||||
|
|
||||||
# Create the TCP/IP socket used to talk with the controller. The socket can be adressed from within the IOC shell via the port name.
|
# Create the TCP/IP socket used to talk with the controller. The socket can be adressed from within the IOC shell via the port name.
|
||||||
# We do not use the standard asyn port driver here, but a PMAC-specific one which enables the usage of StreamDevices for
|
# We do not use the standard asyn port driver here, but a PMAC-specific one which enables the usage of StreamDevices for
|
||||||
# communicating with the controller directly.
|
# communicating with the controller directly.
|
||||||
pmacAsynIPPortConfigure("$(ASYN_PORT)","172.28.101.24:1025")
|
pmacAsynIPPortConfigure("$(IP_PORT)","172.28.101.24:1025")
|
||||||
|
|
||||||
# Create the controller object with the defined name and connect it to the socket via the port name.
|
# Create the controller object with the defined name and connect it to the socket via the port name.
|
||||||
# The other parameters are as follows:
|
# The other parameters are as follows:
|
||||||
@ -40,25 +40,25 @@ pmacAsynIPPortConfigure("$(ASYN_PORT)","172.28.101.24:1025")
|
|||||||
# 0.05: Busy poll period in seconds
|
# 0.05: Busy poll period in seconds
|
||||||
# 1: Idle poll period in seconds
|
# 1: Idle poll period in seconds
|
||||||
# 1: Socket communication timeout in seconds
|
# 1: Socket communication timeout in seconds
|
||||||
turboPmacController("$(NAME)", "$(ASYN_PORT)", 8, 0.05, 1, 1);
|
turboPmacController("$(DRIVER_PORT)", "$(IP_PORT)", 8, 0.05, 1, 1);
|
||||||
|
|
||||||
# Define some axes for the specified MCU at the given slot (1, 2 and 5). No slot may be used twice!
|
# Define some axes for the specified MCU at the given slot (1, 2 and 5). No slot may be used twice!
|
||||||
turboPmacAxis("$(NAME)",1);
|
turboPmacAxis("$(DRIVER_PORT)",1);
|
||||||
turboPmacAxis("$(NAME)",2);
|
turboPmacAxis("$(DRIVER_PORT)",2);
|
||||||
turboPmacAxis("$(NAME)",5);
|
turboPmacAxis("$(DRIVER_PORT)",5);
|
||||||
|
|
||||||
# Set the number of subsequent timeouts
|
# Set the number of subsequent timeouts
|
||||||
setMaxSubsequentTimeouts("$(NAME)", 20);
|
setMaxSubsequentTimeouts("$(DRIVER_PORT)", 20);
|
||||||
|
|
||||||
# Configure the timeout frequency watchdog: A maximum of 10 timeouts are allowed in 300 seconds before an alarm message is sent.
|
# Configure the timeout frequency watchdog: A maximum of 10 timeouts are allowed in 300 seconds before an alarm message is sent.
|
||||||
setThresholdComTimeout("$(NAME)", 300, 10);
|
setThresholdComTimeout("$(DRIVER_PORT)", 300, 10);
|
||||||
|
|
||||||
# Parametrize the EPICS record database with the substitution file named after the MCU.
|
# Parametrize the EPICS record database with the substitution file named after the MCU.
|
||||||
epicsEnvSet("SINQDBPATH","$(sinqMotor_DB)/sinqMotor.db")
|
epicsEnvSet("SINQDBPATH","$(sinqMotor_DB)/sinqMotor.db")
|
||||||
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
|
dbLoadTemplate("$(TOP)/$(DRIVER_PORT).substitutions", "INSTR=$(INSTR)$(DRIVER_PORT):,CONTROLLER=$(DRIVER_PORT)")
|
||||||
epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/turboPmac.db")
|
epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/turboPmac.db")
|
||||||
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
|
dbLoadTemplate("$(TOP)/$(DRIVER_PORT).substitutions", "INSTR=$(INSTR)$(DRIVER_PORT):,CONTROLLER=$(DRIVER_PORT)")
|
||||||
dbLoadRecords("$(sinqMotor_DB)/asynRecord.db","P=$(INSTR)$(NAME),PORT=$(ASYN_PORT)")
|
dbLoadRecords("$(sinqMotor_DB)/asynRecord.db","P=$(INSTR)$(DRIVER_PORT),PORT=$(IP_PORT)")
|
||||||
```
|
```
|
||||||
|
|
||||||
### Additional records
|
### Additional records
|
||||||
|
@ -496,7 +496,7 @@ static int pmacReadReady(pmacPvt *pPmacPvt, asynUser *pasynUser) {
|
|||||||
pPmacPvt->portName, thisRead);
|
pPmacPvt->portName, thisRead);
|
||||||
} else {
|
} else {
|
||||||
asynPrint(pasynUser, ASYN_TRACE_ERROR,
|
asynPrint(pasynUser, ASYN_TRACE_ERROR,
|
||||||
"%s read pmacReadReady failed status=%d,retval=%d",
|
"%s read pmacReadReady failed status=%d, retval=%d\n",
|
||||||
pPmacPvt->portName, status, retval);
|
pPmacPvt->portName, status, retval);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -161,7 +161,15 @@ asynStatus turboPmacAxis::init() {
|
|||||||
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_);
|
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_);
|
||||||
status = pC_->writeRead(axisNo_, command, response, 6);
|
status = pC_->writeRead(axisNo_, command, response, 6);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
return status;
|
asynPrint(
|
||||||
|
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nCould not communicate "
|
||||||
|
"with controller during IOC initialization. Check if you used "
|
||||||
|
"\"pmacAsynIPPortConfigure\" instead of the standard "
|
||||||
|
"\"drvAsynIPPortConfigure\" function in the .cmd file in order to "
|
||||||
|
"create the port driver.\nTerminating IOC.\n",
|
||||||
|
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
nvals = sscanf(response, "%d %lf %lf %lf %lf %d", &axStatus, &motorPos,
|
nvals = sscanf(response, "%d %lf %lf %lf %lf %d", &axStatus, &motorPos,
|
||||||
&motorVmax, &motorVelocity, &motorAccel, &acoDelay);
|
&motorVmax, &motorVelocity, &motorAccel, &acoDelay);
|
||||||
|
@ -226,7 +226,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
asynPrint(
|
asynPrint(
|
||||||
this->pasynUser(), ASYN_TRACE_ERROR,
|
this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||||
"writing to the MCU.%s\n",
|
"writing to the controller. Retrying ...%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
msgPrintControl_.getSuffix());
|
msgPrintControl_.getSuffix());
|
||||||
}
|
}
|
||||||
@ -239,6 +239,10 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
checkMaxSubsequentTimeouts(timeoutCounter, axis);
|
checkMaxSubsequentTimeouts(timeoutCounter, axis);
|
||||||
timeoutCounter += 1;
|
timeoutCounter += 1;
|
||||||
|
|
||||||
|
if (maxSubsequentTimeoutsExceeded_) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
status = pasynOctetSyncIO->writeRead(
|
status = pasynOctetSyncIO->writeRead(
|
||||||
pasynOctetSyncIOipPort(), command, commandLength, response,
|
pasynOctetSyncIOipPort(), command, commandLength, response,
|
||||||
MAXBUF_, comTimeout_, &nbytesOut, &nbytesIn, &eomReason);
|
MAXBUF_, comTimeout_, &nbytesOut, &nbytesIn, &eomReason);
|
||||||
@ -273,17 +277,37 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
if (eomReason != 2) {
|
if (eomReason != 2) {
|
||||||
status = asynError;
|
status = asynError;
|
||||||
|
|
||||||
|
char reasonStringified[30] = {0};
|
||||||
|
switch (eomReason) {
|
||||||
|
case 0:
|
||||||
|
snprintf(reasonStringified, sizeof(reasonStringified), "Timeout");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
snprintf(reasonStringified, sizeof(reasonStringified),
|
||||||
|
"Request count reached");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
snprintf(reasonStringified, sizeof(reasonStringified),
|
||||||
|
"End of string detected");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
snprintf(reasonStringified, sizeof(reasonStringified),
|
||||||
|
"End indicator detected");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(drvMessageText, sizeof(drvMessageText),
|
snprintf(drvMessageText, sizeof(drvMessageText),
|
||||||
"Terminated message due to reason %d (should be 2). Please "
|
"Terminated message due to reason %s (should be \"End of "
|
||||||
"call the support.",
|
"string detected\"). Please call the support.",
|
||||||
eomReason);
|
reasonStringified);
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(terminateKey, true, pasynUser())) {
|
if (msgPrintControl_.shouldBePrinted(terminateKey, true, pasynUser())) {
|
||||||
|
|
||||||
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
||||||
"terminated due to reason %i.%s\n",
|
"terminated due to reason %s.%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
eomReason, msgPrintControl_.getSuffix());
|
reasonStringified, msgPrintControl_.getSuffix());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgPrintControl_.resetCount(terminateKey, pasynUser());
|
msgPrintControl_.resetCount(terminateKey, pasynUser());
|
||||||
|
Reference in New Issue
Block a user