CCS does not monitor this forum on a regular basis. Please do not post bug Reports on this forum. Send them to support@ccsinfo.com
Author Message
uN_Eof

Joined: 17 May 2010
Posts: 29
Location: I live in Spain, with the toros, paella and tortilla

 Converting signed 9 bit int to signed 8 bit int (question) Posted: Mon Oct 31, 2011 8:27 am Hey all. I need to convert data. I'm not such a great C programmer so I don't know how to do this. I'm working in a PS/2 mouse driver. The mouse sends the movement data in 9 bit 2's complement integer in this way: It sends the movement sign bits (2 bits, one for X and other for Y) in the first packet, and the 2 other packets are the actual movement register. I want to convert this 9 bit signed int into a 8 bit signed int but I have no idea on how to do this. Any help will be valued. Thanks.
PCM programmer

Joined: 06 Sep 2003
Posts: 21371

Posted: Mon Oct 31, 2011 3:01 pm

1. Try to come up with an idea for an algorithm in your mind.
2. Make a test program (or programs) to study it.

For example, you might decide that dividing a signed 9-bit number by 2
will give you an 8-bit result. Sounds logical. But can you also do it by
the shortcut way of right-shifting it ? Sounds possible. So, make a
test program. First make a program to print out the Hex values and
look at the bit patterns. Study 2's complement articles on the internet.
Then make a larger test program (shown below) to study the proposed
method of division (right-shifting), by looking at values near the
boundaries. (Lower limit, zero-crossing, and upper limit).

In other words, if you don't already know the answer (from previous
programming experience, or taking a class, or reading a textbook),
then you still have the power in your hands (and your mind) to work
through the problem.

Note: In 9-bit 2's complement numbers, the minimum number is -256
and the maximum is 255. But, all the webpages the on PS/2 mouse that
I browsed say it's output is from -255 to +255. I don't know if this is true.
I didn't see an official document. I don't have time to search for one.
I am just mentioning this as something that I noted.

Program output:
 Quote: Value: -255 Result: -128 Value: -254 Result: -127 Value: -253 Result: -127 Value: -252 Result: -126 Value: -251 Result: -126 Value: -5 Result: -3 Value: -4 Result: -2 Value: -3 Result: -2 Value: -2 Result: -1 Value: -1 Result: -1 Value: 0 Result: 0 Value: 1 Result: 0 Value: 2 Result: 1 Value: 3 Result: 1 Value: 4 Result: 2 Value: 5 Result: 2 Value: 250 Result: 125 Value: 251 Result: 125 Value: 252 Result: 126 Value: 253 Result: 126 Value: 254 Result: 127 Value: 255 Result: 127

 Code: #include <18F452.h>        #fuses HS,NOWDT,PUT,BROWNOUT,NOLVP #use delay (clock = 20M) #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) //=============================== void main() { signed int16 value; signed int16 value9; signed int8 result; for(value = -255; value < -250; value +=1)    {     value9 = value & 0x1FF;  // Emulate 9-bit value from mouse.     result = value9 >> 1;  // Right-shift it     printf("Value: %ld  Result: %d \r", value, result);               } for(value = -5; value < 6; value +=1)    {     value9 = value & 0x1FF;     result = value9 >> 1;  // Right-shift it     printf("Value: %ld  Result: %d \r", value, result);               } for(value = 250; value < 256; value +=1)    {     value9 = value & 0x1FF;     result = value9 >> 1;  // Right-shift it     printf("Value: %ld  Result: %d \r", value, result);               } while(1); }
temtronic

Joined: 01 Jul 2010
Posts: 7991
Location: Greensville,Ontario

 Posted: Mon Oct 31, 2011 5:05 pm There is a Microchip application done eons ago making a mouse using I think a 16C84(been awhile) but it does explain in detail the details ! Might be a good reference for you.
uN_Eof

Joined: 17 May 2010
Posts: 29
Location: I live in Spain, with the toros, paella and tortilla

Posted: Tue Nov 01, 2011 10:30 am

Thank you very very much for your help PCM Programmer.
Thats similar to what I tried to do, but your program is correct, and mine didn't work correctly.

I still have one problem that I can't seem to solve by my self.
When I move the mouse to the right or up (signs 0 I think) the movement in the display (I send the data to my pc as a HID joystick) is correct. The faster I move the mouse the bigger the value is. But if I move it down or to the left, the movement data is correct, but the miniun vaue is the maximun. I'll try to explain better. If i move to the left or down the Z axis or Z rotation goes up to the maximun value, and the faster i move the mouse left or down, the lower the value is, never being less than the middle of the bar, thats 0. I don't know if you understand what I mean. If you don't, I'll upload a video or a picture to explain better.

Of course I'd like to solve this by my sef, and it's what I'm going to try, but in case I don't get it solved, I'm asking here, to save time.

BTW, I tried to find some official documents about the PS/2 protocol with no result at all. I guess the minimun value is -256. Maybe I'll send a mail or something to IBM to see where I can find the official PS/2 protocol description.

Again, thank you so much. You're very kind, I always read you helping other people

EDIT:Forgot to paste it, this is the code I'm using right now to conver data.
 Code: void calc_mov(){    pkt_xs16 = (pkt_x | (__xmsign << 8) & 0x1FF);    pkt_ys16 = (pkt_y | (__ymsign << 8) & 0x1FF);    pkt_xs8 = pkt_xs16 >> 1;    pkt_ys8 = pkt_ys16 >> 1; }

I call this as soon as I get the 3 bytes frm the mouse.
pkt_xs16 -> signed 16bit int
pkt_ys16 -> signed 16bit int
pkt_xs8 -> signed 8 bit int
pkt_ys8 -> signed 8bit int
pkt_x -> actual data read from the mouse
pkt_y -> same but for y
__xmsign -> X sign
__ymsign -> Y sign

I send to the pc pkt_xs8 and pkt_ys8 as signed 8 bit ints.

@temtronic
Yep in fact some time ago I took apart a broken quite old microsoft wheel mouse and I discovered a 16C84 inside. Now that OLD pic is in my old IC collection.
BTW I'n not triyng to mimic a mouse, I'm reading data from it.
Ttelmah

Joined: 11 Mar 2010
Posts: 16944

 Posted: Tue Nov 01, 2011 10:48 am This actually suggests the value _isn't_ 2's complement. This was what was worrying PCMprogrammer about the notes he had found. A 2's complement 9bit value, can represent +255 to -256. However the note talked about the value range being -255 to +255, suggesting the value is actually just an absolute movement value (0 to 255), with a sign bit. If so, the way to convert it, is to just divide the 8bit movement value by 2, and then if the sign bit is set, take this away from 0. A glance at my old IBM Bios reference manuals, suggests that the movement is indeed just an absolute value, not 2's complement. Best Wishes
uN_Eof

Joined: 17 May 2010
Posts: 29
Location: I live in Spain, with the toros, paella and tortilla

Posted: Tue Nov 01, 2011 11:21 am

 Ttelmah wrote: This actually suggests the value _isn't_ 2's complement. This was what was worrying PCMprogrammer about the notes he had found. A 2's complement 9bit value, can represent +255 to -256. However the note talked about the value range being -255 to +255, suggesting the value is actually just an absolute movement value (0 to 255), with a sign bit. If so, the way to convert it, is to just divide the 8bit movement value by 2, and then if the sign bit is set, take this away from 0. A glance at my old IBM Bios reference manuals, suggests that the movement is indeed just an absolute value, not 2's complement. Best Wishes

pkt_xs8 = (pkt_x / 2) | (__xmsign << 7);
pkt_ys8 = (pkt_y / 2) | (__ymsign << 7);

Thats the code now. It does a very similar thing now.
Anyway I'm not sure what you mean with "take it away from 0". Can you explain please?
Thank you.
Ttelmah

Joined: 11 Mar 2010
Posts: 16944

Posted: Tue Nov 01, 2011 3:33 pm

 Code: if (__xmsign)     pkt_xs8 = 0-(pkt_x / 2); else     pkt_xs8=pkt/2;

and similar for the y.

Best Wishes
uN_Eof

Joined: 17 May 2010
Posts: 29
Location: I live in Spain, with the toros, paella and tortilla

Posted: Wed Nov 02, 2011 11:08 am

Hello,

I tried that code and the behaviour is quite similar, if not the same.
I'm starting to think that it can be the USB descriptor... maybe. I don't know.

 Code: 0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)     0x09, 0x04,                    // USAGE (Joystick)     0xa1, 0x01,                    // COLLECTION (Application)     0xa1, 0x02,                    //   COLLECTION (Logical)     0xa1, 0x00,                    //     COLLECTION (Physical)     0x75, 0x08,                    //       REPORT_SIZE (8)     0x95, 0x04,                    //       REPORT_COUNT (4)     0x25, 0x7f,                    //       LOGICAL_MAXIMUM (127)     0x15, 0x80,                    //       LOGICAL_MINIMUM (-128)     0x35, 0x80,                    //       PHYSICAL_MINIMUM (-128)     0x45, 0x7f,                    //       PHYSICAL_MAXIMUM (127)     0x09, 0x30,                    //       USAGE (X)     0x09, 0x31,                    //       USAGE (Y)     0x09, 0x32,                    //       USAGE (Z)     0x09, 0x35,                    //       USAGE (Rz)     0x81, 0x02,                    //       INPUT (Data,Var,Abs)     0xc0,                          //     END_COLLECTION     0x05, 0x09,                    //     USAGE_PAGE (Button)     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)     0x29, 0x08,                    //     USAGE_MAXIMUM (Button 8)     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)     0x95, 0x08,                    //     REPORT_COUNT (8)     0x75, 0x01,                    //     REPORT_SIZE (1)     0x81, 0x02,                    //     INPUT (Data,Var,Abs)     0x05, 0x09,                    //     USAGE_PAGE (Button)     0x19, 0x09,                    //     USAGE_MINIMUM (Button 9)     0x29, 0x10,                    //     USAGE_MAXIMUM (Button 16)     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)     0x95, 0x08,                    //     REPORT_COUNT (8)     0x75, 0x01,                    //     REPORT_SIZE (1)     0x81, 0x02,                    //     INPUT (Data,Var,Abs)     0x05, 0x09,                    //     USAGE_PAGE (Button)     0x19, 0x11,                    //     USAGE_MINIMUM (Button 17)     0x29, 0x13,                    //     USAGE_MAXIMUM (Button 19)     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)     0x95, 0x08,                    //     REPORT_COUNT (8)     0x75, 0x01,                    //     REPORT_SIZE (1)     0x81, 0x02,                    //     INPUT (Data,Var,Abs)     0xc0,                          //   END_COLLECTION     0xc0                           // END_COLLECTION

I used the USB HID desccriptor tool.
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT - 6 Hours Page 1 of 1

 Jump to: Select a forum Software----------------General CCS C DiscussionCode LibraryEZ App LynxBest Of Hardware----------------CCS ICD / Mach X / Load-n-Go
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum