|
|
View previous topic :: View next topic |
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: 21708
|
|
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: 9226 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: 19510
|
|
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: 19510
|
|
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. |
|
|
|
|
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
|
Powered by phpBB © 2001, 2005 phpBB Group
|