On Thursday, September 24, 2015 10:57 AM, Ian Abbott wrote:
> On 24/09/15 18:43, Ian Abbott wrote:
>> On 24/09/15 18:20, Hartley Sweeten wrote:
>>> I guess the sign bit would also need to be extended for the bipolar
>>> values. So:
>>>
>>>        for (i = 0; i < insn->n; ++i) {
>>>         unsigned int val = data[i];
>>>
>>>         /* bipolar ranges use 2's complement values */
>>>         if (comedi_range_is_bipolar(s, range)) {
>>>             val = comedi_offset_munge(s, val);
>>>             /* extend the sign bit */
>>>             if (val > 2048)
>>>                 val |= 0x1000;
>>>         }
>>>
>>>         /* shift 12-bit data (+sign) to match the register */
>>>         val <<= 3;
>>>
>>> How does that look?
>>
>> It looks okay except that the test for extending the sign bit should be
>> 'if (val >= 2048)'.  You could also avoid the conditional and extend the
>> bit regardless:
>>
>>              val += (val & 0x800);
>
> Although that assumes that val is in range to start with, otherwise the 
> carry from the '+' might propagate too far.  There are various ways to 
> fix that, e.g.:
>
>               val |= (val & 0x800) << 1;

All the data values passed with an INSN_WRITE are validated by parse_insn()
before the (*insn_write) is called. But, aesthetically I like the change above.
Or, if it's based on 'maxdata'...

                val |= (val & ((s->maxdata + 1) >> 1) << 1;

But, that starts to look like black magic....

Regards,
Hartley

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to