Go Down

Topic: Two's Complement (Read 493 times) previous topic - next topic

Chevelle

OK, then it's on you to fix any problems that arise with the base library and are subsequently fixed in that repository. You'll need to implement similar fixes in your custom version. Not a problem if your coding skills are up to it.
Understood.  I would release it under as a separate library and maintained as such.

Chevelle

Not quite.  The "{Position | 0xFFC00000;}" doesn't store a value anywhere.  It calculates a value and throws the result away.  If your warning levels are high enough the compiler should warn you that the statement has no side effects.
Oops.  Of course.  I meant:

{pos = Position | 0xFFC00000;}

:)

johnwasser

OK, then it's on you to fix any problems that arise with the base library and are subsequently fixed in that repository. You'll need to implement similar fixes in your custom version. Not a problem if your coding skills are up to it.
That library has not been touched in three years so I would not worry about any future "bug fixes". :)
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

Chevelle

Pretty much everything is working as it should with the exception of reading the position of the axes.  The position is a two's complement unsigned integer in a 22 bit register.  My code works fine if the value is positive (the else statement) but there is an offset error if it is a negative value.

Here is the present code.  (uPosA is an unsigned integer, PosA is a signed integer)

Code: [Select]

uPosA = AxisA._GetParam(x_ABS_POS); // Get the unsigned position for the A motor in 2's comp

if (uPosA > 0x1FFFFFUL) {
    PosA = (~uPosA + B01) & 0x1FFFFFUL; PosA = -PosA ;
}

else {
    PosA = uPosA;
}


Thanks very much.

gfvalvo

#34
Oct 08, 2019, 02:27 pm Last Edit: Oct 08, 2019, 02:28 pm by gfvalvo
(uPosA is an unsigned integer, PosA is a signed integer)
Did you tell us what processor you're using? I don't feel like digging back through 3 pages of this thread to find out.

If it's an 8-bit AVR, then a signed / unsigned integer is only 16 bits. Change it to signed / unsigned long (int32_t / uint32_t).
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

Chevelle

Did you tell us what processor you're using? I don't feel like digging back through 3 pages of this thread to find out.

If it's an 8-bit AVR, then a signed / unsigned integer is only 16 bits. Change it to signed / unsigned long (int32_t / uint32_t).
It is a Teensy 3.2.  (32-bit ARM)

gfvalvo

#36
Oct 08, 2019, 06:11 pm Last Edit: Oct 08, 2019, 06:12 pm by gfvalvo
I don't have a T3.2 handy right now. But, this works on an Uno:
Code: [Select]
int32_t convert32Bit(uint32_t unsignedIn);

const uint32_t a = 0x00000064;      // 100 decimal
const uint32_t b = 0x003FFF9C;      // -100 decimal in 22-bit 2's Compliment

void setup() {
  int32_t convertedValue;

  Serial.begin(115200);
  delay(1000);

  Serial.print("Converted Value a =  ");
  convertedValue = convert32Bit(a);
  Serial.println(convertedValue);

  Serial.print("Converted Value b = ");
  convertedValue = convert32Bit(b);
  Serial.println(convertedValue);
}

void loop() {}

int32_t convert32Bit(uint32_t unsignedIn) {
  if (unsignedIn & 0x00200000) {
    return unsignedIn | 0xFFC00000;  // 22bit value is negative, sign extend to 32 bits
  } else {
    return unsignedIn;
  }
}


Output:
Code: [Select]
Converted Value a =  100
Converted Value b = -100
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

Chevelle

Looks good.  I will try it and report!

Thanks.

Go Up