EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: StreamDevice "type punning" floating point conversion
From: Eric Norum via Tech-talk <tech-talk at aps.anl.gov>
To: "Johnson, Andrew N." <anj at anl.gov>
Cc: EPICS tech-talk <tech-talk at aps.anl.gov>
Date: Mon, 28 Sep 2020 10:33:39 -0700
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.
# Convert binary representation of IEEE-754 float
# 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"; }
}



I have a piece of equipment that returns an IEEE-754 floating point value expressed as a hexadecimal integer.  i.e. when the device returns the ASCII string
0xbff9d411
it is sending the value
-1.95178

So far the only way I can figure out how to handle this is to read the value into a ai record RVAL then use a subroutine record with a C union to do the conversion and then store the float value in the ai record VAL.  Is there a way to avoid the subroutine record?   I’m looking for sort of a combination of a %x and a %R StreamDevice format converter.
-- 
Eric Norum
wenorum at lbl.gov




References:
StreamDevice "type punning" floating point conversion Eric Norum via Tech-talk
Re: StreamDevice "type punning" floating point conversion Johnson, Andrew N. via Tech-talk

Navigate by Date:
Prev: Re: ADProsilica crashing on RHEL7 3.10.0-1127 Dunning, Michael via Tech-talk
Next: Implementing closed loop on EPICS level Guilherme Jovanini Montagner via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
Navigate by Thread:
Prev: Re: StreamDevice "type punning" floating point conversion Brown, Garth via Tech-talk
Next: RE: EPICS QT question [SEC=UNCLASSIFIED] STARRITT, Andrew via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
ANJ, 29 Sep 2020 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·