Thanks go out to all the folks who replied to my posting.
I didn’t want to create a custom version of StreamDevice with a converter to handle this and the readback in question is just for a slow ‘comfort’ display so I decided to use a CALC record to do the conversion. I could probably get the CALC _expression_ to fit into a 40 character old-fashioned string value, but I’m keeping all the parentheses for now.
# Doesn't handle -0/NaN/Inf/Denormalized, but good enough for this application
record(calc, "$(P)$(R)FAST:SETPOINT") {
field(DESC, "Fast setpoint")
field(INPB, "0x007FFFFF") # Mantissa
field(INPC, "0x00800000") # Hidden bit
field(INPD, "0x7F800000") # Exponent
field(INPE, "0x80000000") # Sign
field(INPF, "23") # Exponent shift
field(INPG, "150") # Exponent offset
field(CALC, "A?(A&E?-1:1)*(C|(A&B))*2^(((A&D)>>F)-G):0")
field(PREC, "6")
}
with corresponding protocol entry which reads the setpoint as a hexadecimal value into the ‘A’ field of the CALC record:
# Get SFP command snapshot
# Setpoint format differs with firmware version
SFP_LAST_CMD {
out "SFP:LAST_CMD";
in "#SFP:LAST_CMD:"
"%*[^:]:%(\$1FAST:CMD)x"
"%*[^:]:%*[(f)]%(\$1FAST:SETPOINT.A)x"
"%*[^:]:%(\$1FAST:NONCE)x";
@mismatch { in "#NAK:%(\$1ErrorCode.VAL)d"; }
}