| 
	
	|  |  |  
	
		| 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: 9587
 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: 19964
 
 
 
			    
 
 | 
			
				|  |  
				|  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: 19964
 
 
 
			    
 
 | 
			
				|  |  
				|  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
 
 |