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> 2020 2021 2022 2023 2024 2025 | 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> 2020 2021 2022 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: Unexpected change in behaviour of ai/ao device support |
From: | "Johnson, Andrew N. via Tech-talk" <[email protected]> |
To: | "[email protected]" <[email protected]> |
Date: | Tue, 11 Jun 2019 18:51:16 +0000 |
On 6/11/19 3:28 AM, Ralph Lange via Tech-talk wrote:It got un-deprecated again later because there are things ROFF can do that EOFF can't (see below). The change that Michael A is objecting to happened as a result of the discussion thread starting at https://epics.anl.gov/tech-talk/2013/msg00684.php where I pointed out that we were relying on Undefined Behaviour (UB) in some cases, so that code needed to be fixed. About the Hytec driver support, Michael wrote: In the ao record's convert() routine ROFF gets subtracted from the scaled (ESLO+EOFF) and adjusted (ASLO+AOFF) value before it gets rounded and cast to the epicsInt32 RVAL field. Subtraction of a positive number is necessary here to avoid the UB that would occur if the code relied on value wrap-around to map part of the EGUL-EGUF value range into the signed int32 range of RVAL, which I suspect the Hytec driver may be doing.The underlying problem is that the driver support relies on being able to set the ROFF field to a negative value. Unfortunately this is no longer possible, and the result is that ao outputs drive into maximum negative output voltage (potentially very damaging), and the ai inputs can also produce nonsense values (haven't actually tried yet, but the driver code is also now clearly broken). Michael: Can you trace the conversion calculations that happen when you set VAL to EGUF, 0 and EGUL to generate RVAL for that driver? Do any of those rely on scaled values greater than 0x7fffffff being wrapped to negative numbers when that negative ROFF gets subtracted and the result cast to an epicsInt32? ROFF is still used by many device support that talk directly to ADC/DAC registers, but all the device support I have seen that use ROFF set it to a positive number when the hardware has an offset zero — that's why I didn't see much risk in making this code change back in 2015. I disagree with Ben's suggestion of 21 years ago that ROFF can easily be replaced by modifying EOFF, for 2 main reasons: 1. EOFF is only used by the record's convert() routine when LINR is set to LINEAR or SLOPE. 2. A user can set AOFF and/or ASLO to correct their ADC/DAC's calibration, which is what those fields were designed for. Any device support that sets EOFF instead of ROFF would need to recalculate the value of EOFF after each adjustment of AOFF/ASLO. EGUL and EGUF are marked as SPC_LINCONV, but AOFF and ASLO are not, so there's nothing in the record that could trigger that recalculation to happen automatically. - Andrew -- Complexity comes for free, Simplicity you have to work for. |