|
|
Experimental Physics and
| ||||||||||||||
|
|
The above comments by Tim and Ralph were the inspiration for the solution I decided on: NOTE: Some of the PP/NPP/CP/MS/NMS/etc values may need tweaking yet...)
record(ai, "I_RSET") {
field(DESC, "current set readback")
field(PREC, "3")
field(ADEL, "0.01")
}
record(bi, "_updateRSET") {
field(VAL, "1")
field(PINI, "YES")
}
record(scalcout, "_psInReset") {
field(DESC, "Is PS in reset state?")
field(INAA, "CMD_STAT CP MSS")
field(CALC, "AA = 'R'")
}
# Compute value for seq record bit-mask to specify which actions to perform
record(transform, "_RSET_UpdateLogic")
{
field(INPA, "_psInReset CP MSS")
field(INPB, "_updateRSET CP MSS")
field(INPC, "ON_RSTS CP MSS")
# if (psInReset == 1) { I_RSET = 0; updateRSET = 0; } (actions 1 and 2: Mask=0x03)
field(CLCJ, "(A=1) ? 3 : 0")
# else if (_ON_RSTS_ == 1) { I_RSET = I_CSET; updateRSET = 0; } (actions 3 and 2: Mask=0x06)
field(CLCK, "(J!=0) ? 0 : (C=1) ? 6 : 0")
# else if (updateRSET) I_RSET = 0; (action 1: Mask=0x01)
field(CLCL, "(K!=0) ? 0 : (B=1) ? 1 : 0")
# Write the resulting bitmask and trigger the desired actions
field(CLCM, "J | K | L")
field(OUTM, "_RSET_UpdateActions.SELN")
field(FLNK, "_RSET_UpdateActions")
}
# The list of actions used by the RSET_UpdateLogic record which determines
# what (if any) change needs to be made to the RSET value. Which actions to
# performed is specified by writing a bitmapped value to the SELN field (1 bit
# for each action).
record(seq, "_RSET_UpdateActions") {
field(SELM, "Mask")
# Mask bit 0x01: Set I_RSET = 0
field(DOL1, "0")
field(LNK1, "I_RSET PP")
# Mask bit 0x02: Set updateRSET = 0
field(DOL2, "0")
field(LNK2, "_updateRSET PP")
# Mask bit 0x04: Set I_RSET = I_CSET
field(DOL3, "I_CSET NPP")
field(LNK3, "I_RSET PP")
}
The above approach is modeled on the more procedural approach typically used in high level languages (given a set of conditions, perform all the necessary actions): if (expression1) do a bunch of stuff ... else if (expression2) do a different bunch of stuff ... else do yet a different bunch of stuff ... However, a more data-driven approach (compute the next state for each variable) could produce the same effect with just a transform record: A = (set of nested if/else conditions and expressions) B = (possibly overlapping set of nested if/else conditions and expressions) Having (very successfully) used the later approach heavily in most the embedded controller code I wrote for years, this approach definitely has some advantages. However, given the vast difference in the tools used to express it in this case (EPICS records rather than C code), I think the more verbose approach is easier to comprehend, debug, and maintain. But your mileage may vary. Mark
Mark Davis
NSCL/FRIB Control Systems Software Engineer
[email protected]
On 4/27/2020 12:16 PM, Ralph Lange via
Tech-talk wrote:
| ||||||||||||||
| ANJ, 19 Mar 2026 |
·
Home
·
News
·
About
·
Talk
·
Base
·
Modules
·
Extensions
·
· Distributions · Download · Documents · Links · Licensing · |