std-rs 0.9.2

Rust port of EPICS std module (epid, throttle, timestamp records)
Documentation
#! Generated by VisualDCT v2.5


record(busy, "$(P)$(Q)Busy") {
}

record(bo, "$(P)$(Q)SetBusy") {
  field(UDF, "0")
  field(VAL, "1")
  field(OUT, "$(P)$(Q)Busy PP")
  field(OSV, "NO_ALARM")
}

# tweak
record(ao, "$(P)$(Q)TweakVal") {
  field(PREC, "3")
  field(DOL, "1")
}

record(transform, "$(P)$(Q)Tweak") {
  field(CLCD, "a?c-e:b?c+e:c")
  field(INPC, "$(P)$(Q)Ramp.VAL  NPP NMS")
  field(INPE, "$(P)$(Q)TweakVal.VAL  NPP MS")
  field(OUTD, "$(P)$(Q)Ramp.VAL  PP MS")
  field(OUTF, "$(P)$(Q)Tweak.A  NPP NMS")
  field(OUTG, "$(P)$(Q)Tweak.B  NPP NMS")
  field(PREC, "3")
}

record(calcout, "$(P)$(Q)RampStop") {
  field(INPA, "$(P)$(Q)Ramp.VAL")
  field(INPB, "$(P)$(Q)Ramp.OVAL")
  field(CALC, "A#B")
  field(OUT, "$(P)$(Q)Ramp.VAL PP")
  field(OOPT, "When Non-zero")
  field(DOPT, "Use OCAL")
  field(OCAL, "B")
}

# If target value changes, and we didn't do it (Busy==0), then
# get the value and stuff in into Ramp
record(ao, "$(P)$(Q)SyncToTarget") {
  field(SDIS, "$(P)$(Q)Busy")
  field(OMSL, "closed_loop")
  field(DOL, "$(P)$(Q)RampTestTarget.VAL CP")
  field(OUT, "$(P)$(Q)Ramp.VAL PP")
  field(FLNK,"$(P)$(Q)SyncOVAL")
}
# If we don't also sync OVAL, we won't ramp next time.
record(ao, "$(P)$(Q)SyncOVAL") {
  field(SDIS, "$(P)$(Q)Busy")
  field(OMSL, "closed_loop")
  field(DOL, "$(P)$(Q)Ramp.VAL")
  field(OUT, "$(P)$(Q)Ramp.OVAL")
}

# Users write to this field to move or ramp the target
record(ao, "$(P)$(Q)Ramp") {
  field(OROC, ".1")
  field(OUT, "$(P)$(Q)PutValue.DO2 PP")
  field(PREC, "3")
}

# See if we need to process the Ramp record again to get it one step
# closer to the target value
record(calcout, "$(P)$(Q)RampCheckOutput") {
  field(SDIS, "$(P)$(Q)RampStop.PACT")
  field(INPA, "$(P)$(Q)Ramp.VAL")
  field(INPB, "$(P)$(Q)Ramp.OVAL")
  field(INPC, "$(P)$(Q)Ramp.OROC")
  field(CALC, "abs(a-b)>C/2")
  field(OOPT, "When Non-zero")
  field(ODLY, "0.1")
  field(OUT, "$(P)$(Q)Ramp.PROC CA")
  field(PREC, "3")
}

# Put the value to the target record, and arrange the other things we need
# (set busy, wait until target finishes changing, see if target is at final
# destination, see if we're all done).
# Note that the LNK2 field will normally be overwritten with a PV specified
# by the user.  Also, note that the user doesn't set LNK2 directly, because
# we need the link to have the "CA" attribute to wait for completion.
record(sseq, "$(P)$(Q)PutValue") {
  field(SDIS, "$(P)$(Q)SyncToTarget.PACT")
  field(STR1, "Busy")
  field(LNK1, "$(P)$(Q)Busy PP")
  field(LNK2, "$(P)$(Q)RampTestTarget CA")
  field(WAIT2, "Wait")
  field(LNK3, "$(P)$(Q)RampCheckOutput.PROC PP")
  field(LNK4, "$(P)$(Q)RampCheckDone.PROC PP")
  field(PREC, "3")
}

# If the target PV is less than half a step away from the target value,
# we're done.  While Busy is TRUE, check periodically.
record(calcout, "$(P)$(Q)RampCheckDone") {
  field(INPA, "$(P)$(Q)Ramp.VAL NPP")
  field(INPB, "$(P)$(Q)Ramp.OVAL NPP")
  field(INPC, "$(P)$(Q)Ramp.OROC")
  field(CALC, "abs(a-b)>C/2")
  field(OOPT, "When Zero")
  field(ODLY, ".1")
  field(OUT, "$(P)$(Q)Busy CA")
  field(PREC, "3")
  field(SCAN, "1 second")
  field(DISV, "0")
  field(SDIS, "$(P)$(Q)Busy.VAL")
}

# Dummy record, for the default case in which the user doesn't actually want
# to drive anything with the ramp, but just to ramp a number.
record(ao, "$(P)$(Q)RampTestTarget") {
  field(PREC, "3")
}

record(ai, "$(P)$(Q)Readback") {
  field(PREC, "3")
  field(INP, "$(P)$(Q)RampTestTarget.VAL CP")
}

# This is where the user specifies the PV (in the AA field) that is to be
# ramped.  Add the link attribute "CA", and shove the result into the PutValue
# record, which is the thing that does the actual writing to the target PV.
# We'll also have to update our sync section with the new PV name.
record(scalcout, "$(P)$(Q)PutLinkCalc") {
  field(AA, "$(P)$(Q)RampTestTarget")
  field(CALC, "aa+' CA'")
  field(OUT, "$(P)$(Q)PutValue.LNK2 CA")
  field(FLNK, "$(P)$(Q)SyncLinkCalc")
}

# Get the user's new target PV name, and make SyncToTarget monitor that PV.
record(scalcout, "$(P)$(Q)SyncLinkCalc") {
  field(INAA, "$(P)$(Q)PutLinkCalc.AA")
  field(CALC, "aa+' CP'")
  field(OUT, "$(P)$(Q)SyncToTarget.DOL CA")
}

# Get the user's new target PV name, and make Readback monitor that PV.
record(scalcout, "$(P)$(Q)ReadLinkPVCalc") {
  field(CALC, "aa+' CP'")
  field(INAA, "$(P)$(Q)PutLinkCalc.AA CP")
  field(OUT, "$(P)$(Q)Readback.INP CA")
}

# We may have to initialize this database with a user specified PV name that
# was restored by autosave.  If so, we could construct the link text at PINI
# time, but we can't actually write the resulting link, because link fields
# must be written by channel access, and channel access is not functioning
# at PINI time.  An easy way to wait for channel access is to wait for the
# periodic scan tasks to start.  However, we only want to process once, so
# we reset our own SCAN field to 0 after we've done our job.
# Another thing we have to do at init time is initialize *Ramp.OVAL to
# *Ramp.VAL, because the ao record needs OVAL to be right, or its OROC
# calculation will break.
record(seq, "$(P)$(Q)Init") {
  field(SCAN, "1 second")
  field(LNK1, "$(P)$(Q)PutLinkCalc.PROC")
  field(DOL2, "$(P)$(Q)Ramp.VAL")
  field(LNK2, "$(P)$(Q)Ramp.OVAL")
  field(DO3, "0")
  field(LNK3, "$(P)$(Q)Init.SCAN CA")
}