Repository navigation
Conversation
| /* get current value of bit 31 */ | ||
| overunder = sim_enc->accum >> 31; | ||
| /* get current sign */ | ||
| overunder = sim_enc->accum < 0; |
There was a problem hiding this comment.
I think >> 31 was doing more than isolating a sign bit, or am I missing something? freqscale is 2^31 / maxf, so the accumulator is meant to make a pulse each time it crosses a multiple of 2^31, and on a 64-bit unsigned long the old (accum >> 31) xor still caught every crossing. With accum < 0 it only fires at the 2^63 wrap: a quick userspace copy of the loop at 1000 Hz on a 50 us thread gives 999 edges/s with the old code and 0 with this one (and 1 for -1000 Hz).
Keeping accum unsigned and making the shift 64-bit wide would keep the crossing test, e.g. with rtapi_u64 overunder:
overunder = sim_enc->accum >> 31;
sim_enc->accum += sim_enc->addval;
overunder ^= sim_enc->accum >> 31;That also avoids the signed overflow of accum += addval.
There was a problem hiding this comment.
Hm, yes, with the high 33 bits left, it is not triggering on the sign bit, but any multiple of 2^31, indeed.
This is really grmpf code... Reverting.
cb53eab to
6ad26eb
Compare
There is one more changes besides the standard HAL API updates. The code was using a
val >> 31to isolate the sign bit, but that fails miserably. The type (long) has been 64-bit for quite some time. The actual intention is to detect a sign change, which can be done much more easily by usingval < 0as expression.