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
davism50 at msu.edu
On 4/27/2020 12:16 PM, Ralph Lange via
Tech-talk wrote:
| ||||||||||||||
ANJ, 30 Apr 2020 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |