226 lines
10 KiB
Plaintext
Executable File
226 lines
10 KiB
Plaintext
Executable File
# The main asyn motor record. Some fields are populated from the substitution
|
|
# files via macros:
|
|
# - $(INSTR): Name of the instrument, e.g. "SQ:SINQTEST:"
|
|
# - $(M): Name of the motor in EPICS, e.g. "lin1"
|
|
# - $(DESC): Short description of the motor
|
|
# - $(DIR): This value is usually set to "Pos". If the motor axis direction
|
|
# should be inverted, this value can be set to "Neg"
|
|
# - $(CONTROLLER): Name of the motor controller, e.g. "mcu1"
|
|
# - $(AXIS): Number of the axis, e.g. "1"
|
|
# - $(MRES): Motor record resolution. See the README.md for a detailed discussion
|
|
# - $(EGU): Engineering units. In case of a rotary axis, this is "degree", in
|
|
# case of a linear axis this is "mm".
|
|
record(motor,"$(INSTR)$(M)")
|
|
{
|
|
field(DESC,"$(DESC)")
|
|
field(DTYP,"asynMotor")
|
|
field(DIR,"$(DIR=Pos)")
|
|
field(OUT,"@asyn($(CONTROLLER),$(AXIS))")
|
|
field(MRES,"$(MRES)")
|
|
field(EGU,"$(EGU)")
|
|
field(INIT,"")
|
|
field(PINI, "NO")
|
|
field(TWV,"1")
|
|
field(RTRY, "0")
|
|
}
|
|
|
|
# This record forwards the motor record resolution MRES to the parameter library
|
|
# entry "MOTOR_REC_RESOLUTION" (solution from https://epics.anl.gov/tech-talk/2020/msg00378.php)
|
|
# The value of MRES is needed inside the driver for various calculations (e.g.
|
|
# for calculating the estimated time of arrival inside the watchdog).
|
|
record(ao,"$(INSTR)$(M):RecResolution") {
|
|
field(DESC, "$(M) resolution")
|
|
field(DOL, "$(INSTR)$(M).MRES CP MS")
|
|
field(OMSL, "closed_loop")
|
|
field(DTYP, "asynFloat64")
|
|
field(OUT, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_REC_RESOLUTION")
|
|
}
|
|
|
|
# This record contains messages from the driver (usually error messages).
|
|
# The macro $(MSGTEXTSIZE) can be used to set the maximum length of the message.
|
|
# if not provided, a default value of 200 is used.
|
|
# This record is coupled to the parameter library via motorMessageText_ -> MOTOR_MESSAGE_TEXT.
|
|
record(waveform, "$(INSTR)$(M)-MsgTxt") {
|
|
field(DTYP, "asynOctetRead")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_MESSAGE_TEXT")
|
|
field(FTVL, "CHAR")
|
|
field(NELM, "$(MSGTEXTSIZE=200)") # Should be the same as MAXBUF in the driver code
|
|
field(SCAN, "I/O Intr")
|
|
}
|
|
|
|
# User-writable switch which disables the motor for an input of zero and enables
|
|
# it otherwise. Some motors can't be disabled in certain states (e.g. during
|
|
# movement). This behaviour has to be implemented inside the driver.
|
|
# This record is coupled to the parameter library via motorEnable_ -> MOTOR_ENABLE.
|
|
record(longout, "$(INSTR)$(M):Enable") {
|
|
field(DTYP, "asynInt32")
|
|
field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_ENABLE")
|
|
field(PINI, "NO")
|
|
}
|
|
|
|
# Readback value which returns 1 if the motor is disabled and 0 otherwise.
|
|
# This record is coupled to the parameter library via motorEnableRBV_ -> MOTOR_ENABLE_RBV.
|
|
record(longin, "$(INSTR)$(M):Enable_RBV") {
|
|
field(DTYP, "asynInt32")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_ENABLE_RBV")
|
|
field(PINI, "NO")
|
|
field(SCAN, "I/O Intr")
|
|
}
|
|
|
|
# Some (older) motors cannot be disabled. This property has to be specified in
|
|
# the driver by setting the corresponding parameter library entry motorCanDisable_
|
|
# to 0 (its default value is 1).
|
|
# This record is coupled to the parameter library via motorCanDisable_ -> MOTOR_CAN_DISABLE.
|
|
record(longin, "$(INSTR)$(M):CanDisable") {
|
|
field(DTYP, "asynInt32")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_CAN_DISABLE")
|
|
field(PINI, "NO")
|
|
field(SCAN, "I/O Intr")
|
|
}
|
|
|
|
# For some motors, the user might be allowed to adjust the speed within the
|
|
# limits specified in the motor record as VBAS and VMAX. This functionality can
|
|
# be enabled by setting CANSETSPEED to 1. It is disabled by default.
|
|
# This record is coupled to the parameter library via motorCanSetSpeed_ -> MOTOR_CAN_SET_SPEED.
|
|
record(longout, "$(INSTR)$(M):CanSetSpeed") {
|
|
field(DTYP, "asynInt32")
|
|
field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_CAN_SET_SPEED")
|
|
field(PINI, "YES")
|
|
field(ASG, "READONLY") # Field is initialized during IOC startup
|
|
field(VAL, "$(CANSETSPEED=0)")
|
|
}
|
|
|
|
# The timeout mechanism for movements can be enabled / disabled by setting
|
|
# this PV to 1 / 0.
|
|
# This record is coupled to the parameter library via motorEnableMovWatchdog -> MOTOR_ENABLE_MOV_WATCHDOG.
|
|
record(longout, "$(INSTR)$(M):EnableMovWatchdog") {
|
|
field(DTYP, "asynInt32")
|
|
field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_ENABLE_MOV_WATCHDOG")
|
|
field(PINI, "YES")
|
|
field(VAL, "$(ENABLEMOVWATCHDOG=0)")
|
|
}
|
|
|
|
# For modern controllers, the high and low limits of the axis are read out
|
|
# directly from the hardware. However, since the axis might slightly
|
|
# "overshoot" when moving to a position next to the limits, the hardware might
|
|
# go into a "limits hit" error state. To prevent this, this value allows adding
|
|
# a small offset in EGU, which is subtracted from the high limit and added to the
|
|
# low limit.
|
|
# This record is coupled to the parameter library via motorLimitsOffset_ -> MOTOR_LIMITS_OFFSET.
|
|
record(ao, "$(INSTR)$(M):LimitsOffset") {
|
|
field(DTYP, "asynFloat64")
|
|
field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) MOTOR_LIMITS_OFFSET")
|
|
field(PINI, "YES")
|
|
field(ASG, "READONLY") # Field is initialized during IOC startup
|
|
field(VAL, "$(LIMITSOFFSET=0)")
|
|
}
|
|
|
|
# This record pair reads the parameter library value for "motorHighLimitFromDriver_"
|
|
# and pushes it to the motor record field "DHLM". This can be used to read limits
|
|
# from the hardware and correspondingly update the motor record from the driver.
|
|
# The implementation strategy is taken from https://epics.anl.gov/tech-talk/2022/msg00464.php.
|
|
# This record is coupled to the parameter library via motorHighLimitFromDriver_ -> MOTOR_HIGH_LIMIT_FROM_DRIVER.
|
|
record(ai, "$(INSTR)$(M):DHLM_RBV")
|
|
{
|
|
field(DTYP, "asynFloat64")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_HIGH_LIMIT_FROM_DRIVER")
|
|
field(SCAN, "I/O Intr")
|
|
field(FLNK, "$(INSTR)$(M):PushDHLM2Field")
|
|
}
|
|
record(ao, "$(INSTR)$(M):PushDHLM2Field") {
|
|
field(DOL, "$(INSTR)$(M):DHLM_RBV CP")
|
|
field(OUT, "$(INSTR)$(M).DHLM")
|
|
field(OMSL, "closed_loop")
|
|
}
|
|
|
|
# This record pair reads the parameter library value for "motorLowLimitFromDriver_"
|
|
# and pushes it to the motor record field "DLLM". This can be used to read limits
|
|
# from the hardware and correspondingly update the motor record from the driver.
|
|
# The implementation strategy is taken from https://epics.anl.gov/tech-talk/2022/msg00464.php.
|
|
# This record is coupled to the parameter library via motorLowLimitFromDriver_ -> MOTOR_LOW_LIMIT_FROM_DRIVER.
|
|
record(ai, "$(INSTR)$(M):DLLM_RBV")
|
|
{
|
|
field(DTYP, "asynFloat64")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_LOW_LIMIT_FROM_DRIVER")
|
|
field(SCAN, "I/O Intr")
|
|
field(FLNK, "$(INSTR)$(M):PushDLLM2Field")
|
|
}
|
|
record(ao, "$(INSTR)$(M):PushDLLM2Field") {
|
|
field(DOL, "$(INSTR)$(M):DLLM_RBV CP")
|
|
field(OUT, "$(INSTR)$(M).DLLM")
|
|
field(OMSL, "closed_loop")
|
|
}
|
|
|
|
# This record pair reads the parameter library value for "motorVeloFromDriver_"
|
|
# and pushes it to the motor record field "VELO". This can be used to read the speed value
|
|
# from the hardware and correspondingly update the motor record from the driver.
|
|
# The implementation strategy is taken from https://epics.anl.gov/tech-talk/2022/msg00464.php.
|
|
# This record is coupled to the parameter library via motorVeloFromDriver_ -> MOTOR_VELO_FROM_DRIVER.
|
|
record(ai, "$(INSTR)$(M):VELO_RBV")
|
|
{
|
|
field(DTYP, "asynFloat64")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_VELO_FROM_DRIVER")
|
|
field(SCAN, "I/O Intr")
|
|
field(FLNK, "$(INSTR)$(M):PushVELO2Field")
|
|
}
|
|
record(ao, "$(INSTR)$(M):PushVELO2Field") {
|
|
field(DOL, "$(INSTR)$(M):VELO_RBV CP")
|
|
field(OUT, "$(INSTR)$(M).VELO")
|
|
field(OMSL, "closed_loop")
|
|
}
|
|
|
|
# This record pair reads the parameter library value for "motorVbasFromDriver_"
|
|
# and pushes it to the motor record field "VBAS". This can be used to read the lower speed limit
|
|
# from the hardware and correspondingly update the motor record from the driver.
|
|
# The implementation strategy is taken from https://epics.anl.gov/tech-talk/2022/msg00464.php.
|
|
# This record is coupled to the parameter library via motorVbasFromDriver_ -> MOTOR_VBAS_FROM_DRIVER.
|
|
record(ai, "$(INSTR)$(M):VBAS_RBV")
|
|
{
|
|
field(DTYP, "asynFloat64")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_VBAS_FROM_DRIVER")
|
|
field(SCAN, "I/O Intr")
|
|
field(FLNK, "$(INSTR)$(M):PushVBAS2Field")
|
|
}
|
|
record(ao, "$(INSTR)$(M):PushVBAS2Field") {
|
|
field(DOL, "$(INSTR)$(M):VBAS_RBV CP")
|
|
field(OUT, "$(INSTR)$(M).VBAS")
|
|
field(OMSL, "closed_loop")
|
|
}
|
|
|
|
# This record pair reads the parameter library value for "motorVmaxFromDriver_"
|
|
# and pushes it to the motor record field "VMAX". This can be used to read the upper speed limit
|
|
# from the hardware and correspondingly update the motor record from the driver.
|
|
# The implementation strategy is taken from https://epics.anl.gov/tech-talk/2022/msg00464.php.
|
|
# This record is coupled to the parameter library via motorVmaxFromDriver_ -> MOTOR_VMAX_FROM_DRIVER.
|
|
record(ai, "$(INSTR)$(M):VMAX_RBV")
|
|
{
|
|
field(DTYP, "asynFloat64")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_VMAX_FROM_DRIVER")
|
|
field(SCAN, "I/O Intr")
|
|
field(FLNK, "$(INSTR)$(M):PushVMAX2Field")
|
|
}
|
|
record(ao, "$(INSTR)$(M):PushVMAX2Field") {
|
|
field(DOL, "$(INSTR)$(M):VMAX_RBV CP")
|
|
field(OUT, "$(INSTR)$(M).VMAX")
|
|
field(OMSL, "closed_loop")
|
|
}
|
|
|
|
# This record pair reads the parameter library value for "motorAcclFromDriver_"
|
|
# and pushes it to the motor record field "ACCL". This can be used to read the acceleration
|
|
# from the hardware and correspondingly update the motor record from the driver.
|
|
# The implementation strategy is taken from https://epics.anl.gov/tech-talk/2022/msg00464.php.
|
|
# This record is coupled to the parameter library via motorAcclFromDriver_ -> MOTOR_ACCL_FROM_DRIVER.
|
|
record(ai, "$(INSTR)$(M):ACCL_RBV")
|
|
{
|
|
field(DTYP, "asynFloat64")
|
|
field(INP, "@asyn($(CONTROLLER),$(AXIS)) MOTOR_ACCL_FROM_DRIVER")
|
|
field(SCAN, "I/O Intr")
|
|
field(FLNK, "$(INSTR)$(M):PushACCL2Field")
|
|
}
|
|
record(ao, "$(INSTR)$(M):PushACCL2Field") {
|
|
field(DOL, "$(INSTR)$(M):ACCL_RBV CP")
|
|
field(OUT, "$(INSTR)$(M).ACCL")
|
|
field(OMSL, "closed_loop")
|
|
}
|
|
|