1*4882a593SmuzhiyunElantech Touchpad Driver 2*4882a593Smuzhiyun======================== 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net> 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun Extra information for hardware version 1 found and 7*4882a593Smuzhiyun provided by Steve Havelka 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun Version 2 (EeePC) hardware support based on patches 10*4882a593Smuzhiyun received from Woody at Xandros and forwarded to me 11*4882a593Smuzhiyun by user StewieGriffin at the eeeuser.com forum 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun.. Contents 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun 1. Introduction 16*4882a593Smuzhiyun 2. Extra knobs 17*4882a593Smuzhiyun 3. Differentiating hardware versions 18*4882a593Smuzhiyun 4. Hardware version 1 19*4882a593Smuzhiyun 4.1 Registers 20*4882a593Smuzhiyun 4.2 Native relative mode 4 byte packet format 21*4882a593Smuzhiyun 4.3 Native absolute mode 4 byte packet format 22*4882a593Smuzhiyun 5. Hardware version 2 23*4882a593Smuzhiyun 5.1 Registers 24*4882a593Smuzhiyun 5.2 Native absolute mode 6 byte packet format 25*4882a593Smuzhiyun 5.2.1 Parity checking and packet re-synchronization 26*4882a593Smuzhiyun 5.2.2 One/Three finger touch 27*4882a593Smuzhiyun 5.2.3 Two finger touch 28*4882a593Smuzhiyun 6. Hardware version 3 29*4882a593Smuzhiyun 6.1 Registers 30*4882a593Smuzhiyun 6.2 Native absolute mode 6 byte packet format 31*4882a593Smuzhiyun 6.2.1 One/Three finger touch 32*4882a593Smuzhiyun 6.2.2 Two finger touch 33*4882a593Smuzhiyun 7. Hardware version 4 34*4882a593Smuzhiyun 7.1 Registers 35*4882a593Smuzhiyun 7.2 Native absolute mode 6 byte packet format 36*4882a593Smuzhiyun 7.2.1 Status packet 37*4882a593Smuzhiyun 7.2.2 Head packet 38*4882a593Smuzhiyun 7.2.3 Motion packet 39*4882a593Smuzhiyun 8. Trackpoint (for Hardware version 3 and 4) 40*4882a593Smuzhiyun 8.1 Registers 41*4882a593Smuzhiyun 8.2 Native relative mode 6 byte packet format 42*4882a593Smuzhiyun 8.2.1 Status Packet 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunIntroduction 47*4882a593Smuzhiyun~~~~~~~~~~~~ 48*4882a593Smuzhiyun 49*4882a593SmuzhiyunCurrently the Linux Elantech touchpad driver is aware of four different 50*4882a593Smuzhiyunhardware versions unimaginatively called version 1,version 2, version 3 51*4882a593Smuzhiyunand version 4. Version 1 is found in "older" laptops and uses 4 bytes per 52*4882a593Smuzhiyunpacket. Version 2 seems to be introduced with the EeePC and uses 6 bytes 53*4882a593Smuzhiyunper packet, and provides additional features such as position of two fingers, 54*4882a593Smuzhiyunand width of the touch. Hardware version 3 uses 6 bytes per packet (and 55*4882a593Smuzhiyunfor 2 fingers the concatenation of two 6 bytes packets) and allows tracking 56*4882a593Smuzhiyunof up to 3 fingers. Hardware version 4 uses 6 bytes per packet, and can 57*4882a593Smuzhiyuncombine a status packet with multiple head or motion packets. Hardware version 58*4882a593Smuzhiyun4 allows tracking up to 5 fingers. 59*4882a593Smuzhiyun 60*4882a593SmuzhiyunSome Hardware version 3 and version 4 also have a trackpoint which uses a 61*4882a593Smuzhiyunseparate packet format. It is also 6 bytes per packet. 62*4882a593Smuzhiyun 63*4882a593SmuzhiyunThe driver tries to support both hardware versions and should be compatible 64*4882a593Smuzhiyunwith the Xorg Synaptics touchpad driver and its graphical configuration 65*4882a593Smuzhiyunutilities. 66*4882a593Smuzhiyun 67*4882a593SmuzhiyunNote that a mouse button is also associated with either the touchpad or the 68*4882a593Smuzhiyuntrackpoint when a trackpoint is available. Disabling the Touchpad in xorg 69*4882a593Smuzhiyun(TouchPadOff=0) will also disable the buttons associated with the touchpad. 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunAdditionally the operation of the touchpad can be altered by adjusting the 72*4882a593Smuzhiyuncontents of some of its internal registers. These registers are represented 73*4882a593Smuzhiyunby the driver as sysfs entries under /sys/bus/serio/drivers/psmouse/serio? 74*4882a593Smuzhiyunthat can be read from and written to. 75*4882a593Smuzhiyun 76*4882a593SmuzhiyunCurrently only the registers for hardware version 1 are somewhat understood. 77*4882a593SmuzhiyunHardware version 2 seems to use some of the same registers but it is not 78*4882a593Smuzhiyunknown whether the bits in the registers represent the same thing or might 79*4882a593Smuzhiyunhave changed their meaning. 80*4882a593Smuzhiyun 81*4882a593SmuzhiyunOn top of that, some register settings have effect only when the touchpad is 82*4882a593Smuzhiyunin relative mode and not in absolute mode. As the Linux Elantech touchpad 83*4882a593Smuzhiyundriver always puts the hardware into absolute mode not all information 84*4882a593Smuzhiyunmentioned below can be used immediately. But because there is no freely 85*4882a593Smuzhiyunavailable Elantech documentation the information is provided here anyway for 86*4882a593Smuzhiyuncompleteness sake. 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunExtra knobs 90*4882a593Smuzhiyun~~~~~~~~~~~ 91*4882a593Smuzhiyun 92*4882a593SmuzhiyunCurrently the Linux Elantech touchpad driver provides three extra knobs under 93*4882a593Smuzhiyun/sys/bus/serio/drivers/psmouse/serio? for the user. 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun* debug 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun Turn different levels of debugging ON or OFF. 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun By echoing "0" to this file all debugging will be turned OFF. 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun Currently a value of "1" will turn on some basic debugging and a value of 102*4882a593Smuzhiyun "2" will turn on packet debugging. For hardware version 1 the default is 103*4882a593Smuzhiyun OFF. For version 2 the default is "1". 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun Turning packet debugging on will make the driver dump every packet 106*4882a593Smuzhiyun received to the syslog before processing it. Be warned that this can 107*4882a593Smuzhiyun generate quite a lot of data! 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun* paritycheck 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun Turns parity checking ON or OFF. 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun By echoing "0" to this file parity checking will be turned OFF. Any 114*4882a593Smuzhiyun non-zero value will turn it ON. For hardware version 1 the default is ON. 115*4882a593Smuzhiyun For version 2 the default it is OFF. 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun Hardware version 1 provides basic data integrity verification by 118*4882a593Smuzhiyun calculating a parity bit for the last 3 bytes of each packet. The driver 119*4882a593Smuzhiyun can check these bits and reject any packet that appears corrupted. Using 120*4882a593Smuzhiyun this knob you can bypass that check. 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun Hardware version 2 does not provide the same parity bits. Only some basic 123*4882a593Smuzhiyun data consistency checking can be done. For now checking is disabled by 124*4882a593Smuzhiyun default. Currently even turning it on will do nothing. 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun* crc_enabled 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun Sets crc_enabled to 0/1. The name "crc_enabled" is the official name of 129*4882a593Smuzhiyun this integrity check, even though it is not an actual cyclic redundancy 130*4882a593Smuzhiyun check. 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun Depending on the state of crc_enabled, certain basic data integrity 133*4882a593Smuzhiyun verification is done by the driver on hardware version 3 and 4. The 134*4882a593Smuzhiyun driver will reject any packet that appears corrupted. Using this knob, 135*4882a593Smuzhiyun The state of crc_enabled can be altered with this knob. 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun Reading the crc_enabled value will show the active value. Echoing 138*4882a593Smuzhiyun "0" or "1" to this file will set the state to "0" or "1". 139*4882a593Smuzhiyun 140*4882a593SmuzhiyunDifferentiating hardware versions 141*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 142*4882a593Smuzhiyun 143*4882a593SmuzhiyunTo detect the hardware version, read the version number as param[0].param[1].param[2]:: 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun 4 bytes version: (after the arrow is the name given in the Dell-provided driver) 146*4882a593Smuzhiyun 02.00.22 => EF013 147*4882a593Smuzhiyun 02.06.00 => EF019 148*4882a593Smuzhiyun 149*4882a593SmuzhiyunIn the wild, there appear to be more versions, such as 00.01.64, 01.00.21, 150*4882a593Smuzhiyun02.00.00, 02.00.04, 02.00.06:: 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun 6 bytes: 153*4882a593Smuzhiyun 02.00.30 => EF113 154*4882a593Smuzhiyun 02.08.00 => EF023 155*4882a593Smuzhiyun 02.08.XX => EF123 156*4882a593Smuzhiyun 02.0B.00 => EF215 157*4882a593Smuzhiyun 04.01.XX => Scroll_EF051 158*4882a593Smuzhiyun 04.02.XX => EF051 159*4882a593Smuzhiyun 160*4882a593SmuzhiyunIn the wild, there appear to be more versions, such as 04.03.01, 04.04.11. There 161*4882a593Smuzhiyunappears to be almost no difference, except for EF113, which does not report 162*4882a593Smuzhiyunpressure/width and has different data consistency checks. 163*4882a593Smuzhiyun 164*4882a593SmuzhiyunProbably all the versions with param[0] <= 01 can be considered as 165*4882a593Smuzhiyun4 bytes/firmware 1. The versions < 02.08.00, with the exception of 02.00.30, as 166*4882a593Smuzhiyun4 bytes/firmware 2. Everything >= 02.08.00 can be considered as 6 bytes. 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun 169*4882a593SmuzhiyunHardware version 1 170*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~ 171*4882a593Smuzhiyun 172*4882a593SmuzhiyunRegisters 173*4882a593Smuzhiyun--------- 174*4882a593Smuzhiyun 175*4882a593SmuzhiyunBy echoing a hexadecimal value to a register it contents can be altered. 176*4882a593Smuzhiyun 177*4882a593SmuzhiyunFor example:: 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun echo -n 0x16 > reg_10 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun* reg_10:: 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 184*4882a593Smuzhiyun B C T D L A S E 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun E: 1 = enable smart edges unconditionally 187*4882a593Smuzhiyun S: 1 = enable smart edges only when dragging 188*4882a593Smuzhiyun A: 1 = absolute mode (needs 4 byte packets, see reg_11) 189*4882a593Smuzhiyun L: 1 = enable drag lock (see reg_22) 190*4882a593Smuzhiyun D: 1 = disable dynamic resolution 191*4882a593Smuzhiyun T: 1 = disable tapping 192*4882a593Smuzhiyun C: 1 = enable corner tap 193*4882a593Smuzhiyun B: 1 = swap left and right button 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun* reg_11:: 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 198*4882a593Smuzhiyun 1 0 0 H V 1 F P 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun P: 1 = enable parity checking for relative mode 201*4882a593Smuzhiyun F: 1 = enable native 4 byte packet mode 202*4882a593Smuzhiyun V: 1 = enable vertical scroll area 203*4882a593Smuzhiyun H: 1 = enable horizontal scroll area 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun* reg_20:: 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun single finger width? 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun* reg_21:: 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun scroll area width (small: 0x40 ... wide: 0xff) 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun* reg_22:: 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun drag lock time out (short: 0x14 ... long: 0xfe; 216*4882a593Smuzhiyun 0xff = tap again to release) 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun* reg_23:: 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun tap make timeout? 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun* reg_24:: 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun tap release timeout? 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun* reg_25:: 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun smart edge cursor speed (0x02 = slow, 0x03 = medium, 0x04 = fast) 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun* reg_26:: 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun smart edge activation area width? 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun 235*4882a593SmuzhiyunNative relative mode 4 byte packet format 236*4882a593Smuzhiyun----------------------------------------- 237*4882a593Smuzhiyun 238*4882a593Smuzhiyunbyte 0:: 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 241*4882a593Smuzhiyun c c p2 p1 1 M R L 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun L, R, M = 1 when Left, Right, Middle mouse button pressed 244*4882a593Smuzhiyun some models have M as byte 3 odd parity bit 245*4882a593Smuzhiyun when parity checking is enabled (reg_11, P = 1): 246*4882a593Smuzhiyun p1..p2 = byte 1 and 2 odd parity bit 247*4882a593Smuzhiyun c = 1 when corner tap detected 248*4882a593Smuzhiyun 249*4882a593Smuzhiyunbyte 1:: 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 252*4882a593Smuzhiyun dx7 dx6 dx5 dx4 dx3 dx2 dx1 dx0 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun dx7..dx0 = x movement; positive = right, negative = left 255*4882a593Smuzhiyun byte 1 = 0xf0 when corner tap detected 256*4882a593Smuzhiyun 257*4882a593Smuzhiyunbyte 2:: 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 260*4882a593Smuzhiyun dy7 dy6 dy5 dy4 dy3 dy2 dy1 dy0 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun dy7..dy0 = y movement; positive = up, negative = down 263*4882a593Smuzhiyun 264*4882a593Smuzhiyunbyte 3:: 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun parity checking enabled (reg_11, P = 1): 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 269*4882a593Smuzhiyun w h n1 n0 ds3 ds2 ds1 ds0 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun normally: 272*4882a593Smuzhiyun ds3..ds0 = scroll wheel amount and direction 273*4882a593Smuzhiyun positive = down or left 274*4882a593Smuzhiyun negative = up or right 275*4882a593Smuzhiyun when corner tap detected: 276*4882a593Smuzhiyun ds0 = 1 when top right corner tapped 277*4882a593Smuzhiyun ds1 = 1 when bottom right corner tapped 278*4882a593Smuzhiyun ds2 = 1 when bottom left corner tapped 279*4882a593Smuzhiyun ds3 = 1 when top left corner tapped 280*4882a593Smuzhiyun n1..n0 = number of fingers on touchpad 281*4882a593Smuzhiyun only models with firmware 2.x report this, models with 282*4882a593Smuzhiyun firmware 1.x seem to map one, two and three finger taps 283*4882a593Smuzhiyun directly to L, M and R mouse buttons 284*4882a593Smuzhiyun h = 1 when horizontal scroll action 285*4882a593Smuzhiyun w = 1 when wide finger touch? 286*4882a593Smuzhiyun 287*4882a593Smuzhiyun otherwise (reg_11, P = 0): 288*4882a593Smuzhiyun 289*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 290*4882a593Smuzhiyun ds7 ds6 ds5 ds4 ds3 ds2 ds1 ds0 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun ds7..ds0 = vertical scroll amount and direction 293*4882a593Smuzhiyun negative = up 294*4882a593Smuzhiyun positive = down 295*4882a593Smuzhiyun 296*4882a593Smuzhiyun 297*4882a593SmuzhiyunNative absolute mode 4 byte packet format 298*4882a593Smuzhiyun----------------------------------------- 299*4882a593Smuzhiyun 300*4882a593SmuzhiyunEF013 and EF019 have a special behaviour (due to a bug in the firmware?), and 301*4882a593Smuzhiyunwhen 1 finger is touching, the first 2 position reports must be discarded. 302*4882a593SmuzhiyunThis counting is reset whenever a different number of fingers is reported. 303*4882a593Smuzhiyun 304*4882a593Smuzhiyunbyte 0:: 305*4882a593Smuzhiyun 306*4882a593Smuzhiyun firmware version 1.x: 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 309*4882a593Smuzhiyun D U p1 p2 1 p3 R L 310*4882a593Smuzhiyun 311*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 312*4882a593Smuzhiyun p1..p3 = byte 1..3 odd parity bit 313*4882a593Smuzhiyun D, U = 1 when rocker switch pressed Up, Down 314*4882a593Smuzhiyun 315*4882a593Smuzhiyun firmware version 2.x: 316*4882a593Smuzhiyun 317*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 318*4882a593Smuzhiyun n1 n0 p2 p1 1 p3 R L 319*4882a593Smuzhiyun 320*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 321*4882a593Smuzhiyun p1..p3 = byte 1..3 odd parity bit 322*4882a593Smuzhiyun n1..n0 = number of fingers on touchpad 323*4882a593Smuzhiyun 324*4882a593Smuzhiyunbyte 1:: 325*4882a593Smuzhiyun 326*4882a593Smuzhiyun firmware version 1.x: 327*4882a593Smuzhiyun 328*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 329*4882a593Smuzhiyun f 0 th tw x9 x8 y9 y8 330*4882a593Smuzhiyun 331*4882a593Smuzhiyun tw = 1 when two finger touch 332*4882a593Smuzhiyun th = 1 when three finger touch 333*4882a593Smuzhiyun f = 1 when finger touch 334*4882a593Smuzhiyun 335*4882a593Smuzhiyun firmware version 2.x: 336*4882a593Smuzhiyun 337*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 338*4882a593Smuzhiyun . . . . x9 x8 y9 y8 339*4882a593Smuzhiyun 340*4882a593Smuzhiyunbyte 2:: 341*4882a593Smuzhiyun 342*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 343*4882a593Smuzhiyun x7 x6 x5 x4 x3 x2 x1 x0 344*4882a593Smuzhiyun 345*4882a593Smuzhiyun x9..x0 = absolute x value (horizontal) 346*4882a593Smuzhiyun 347*4882a593Smuzhiyunbyte 3:: 348*4882a593Smuzhiyun 349*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 350*4882a593Smuzhiyun y7 y6 y5 y4 y3 y2 y1 y0 351*4882a593Smuzhiyun 352*4882a593Smuzhiyun y9..y0 = absolute y value (vertical) 353*4882a593Smuzhiyun 354*4882a593Smuzhiyun 355*4882a593SmuzhiyunHardware version 2 356*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~ 357*4882a593Smuzhiyun 358*4882a593Smuzhiyun 359*4882a593SmuzhiyunRegisters 360*4882a593Smuzhiyun--------- 361*4882a593Smuzhiyun 362*4882a593SmuzhiyunBy echoing a hexadecimal value to a register it contents can be altered. 363*4882a593Smuzhiyun 364*4882a593SmuzhiyunFor example:: 365*4882a593Smuzhiyun 366*4882a593Smuzhiyun echo -n 0x56 > reg_10 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun* reg_10:: 369*4882a593Smuzhiyun 370*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 371*4882a593Smuzhiyun 0 1 0 1 0 1 D 0 372*4882a593Smuzhiyun 373*4882a593Smuzhiyun D: 1 = enable drag and drop 374*4882a593Smuzhiyun 375*4882a593Smuzhiyun* reg_11:: 376*4882a593Smuzhiyun 377*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 378*4882a593Smuzhiyun 1 0 0 0 S 0 1 0 379*4882a593Smuzhiyun 380*4882a593Smuzhiyun S: 1 = enable vertical scroll 381*4882a593Smuzhiyun 382*4882a593Smuzhiyun* reg_21:: 383*4882a593Smuzhiyun 384*4882a593Smuzhiyun unknown (0x00) 385*4882a593Smuzhiyun 386*4882a593Smuzhiyun* reg_22:: 387*4882a593Smuzhiyun 388*4882a593Smuzhiyun drag and drop release time out (short: 0x70 ... long 0x7e; 389*4882a593Smuzhiyun 0x7f = never i.e. tap again to release) 390*4882a593Smuzhiyun 391*4882a593Smuzhiyun 392*4882a593SmuzhiyunNative absolute mode 6 byte packet format 393*4882a593Smuzhiyun----------------------------------------- 394*4882a593Smuzhiyun 395*4882a593SmuzhiyunParity checking and packet re-synchronization 396*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 397*4882a593Smuzhiyun 398*4882a593SmuzhiyunThere is no parity checking, however some consistency checks can be performed. 399*4882a593Smuzhiyun 400*4882a593SmuzhiyunFor instance for EF113:: 401*4882a593Smuzhiyun 402*4882a593Smuzhiyun SA1= packet[0]; 403*4882a593Smuzhiyun A1 = packet[1]; 404*4882a593Smuzhiyun B1 = packet[2]; 405*4882a593Smuzhiyun SB1= packet[3]; 406*4882a593Smuzhiyun C1 = packet[4]; 407*4882a593Smuzhiyun D1 = packet[5]; 408*4882a593Smuzhiyun if( (((SA1 & 0x3C) != 0x3C) && ((SA1 & 0xC0) != 0x80)) || // check Byte 1 409*4882a593Smuzhiyun (((SA1 & 0x0C) != 0x0C) && ((SA1 & 0xC0) == 0x80)) || // check Byte 1 (one finger pressed) 410*4882a593Smuzhiyun (((SA1 & 0xC0) != 0x80) && (( A1 & 0xF0) != 0x00)) || // check Byte 2 411*4882a593Smuzhiyun (((SB1 & 0x3E) != 0x38) && ((SA1 & 0xC0) != 0x80)) || // check Byte 4 412*4882a593Smuzhiyun (((SB1 & 0x0E) != 0x08) && ((SA1 & 0xC0) == 0x80)) || // check Byte 4 (one finger pressed) 413*4882a593Smuzhiyun (((SA1 & 0xC0) != 0x80) && (( C1 & 0xF0) != 0x00)) ) // check Byte 5 414*4882a593Smuzhiyun // error detected 415*4882a593Smuzhiyun 416*4882a593SmuzhiyunFor all the other ones, there are just a few constant bits:: 417*4882a593Smuzhiyun 418*4882a593Smuzhiyun if( ((packet[0] & 0x0C) != 0x04) || 419*4882a593Smuzhiyun ((packet[3] & 0x0f) != 0x02) ) 420*4882a593Smuzhiyun // error detected 421*4882a593Smuzhiyun 422*4882a593Smuzhiyun 423*4882a593SmuzhiyunIn case an error is detected, all the packets are shifted by one (and packet[0] is discarded). 424*4882a593Smuzhiyun 425*4882a593SmuzhiyunOne/Three finger touch 426*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^ 427*4882a593Smuzhiyun 428*4882a593Smuzhiyunbyte 0:: 429*4882a593Smuzhiyun 430*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 431*4882a593Smuzhiyun n1 n0 w3 w2 . . R L 432*4882a593Smuzhiyun 433*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 434*4882a593Smuzhiyun n1..n0 = number of fingers on touchpad 435*4882a593Smuzhiyun 436*4882a593Smuzhiyunbyte 1:: 437*4882a593Smuzhiyun 438*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 439*4882a593Smuzhiyun p7 p6 p5 p4 x11 x10 x9 x8 440*4882a593Smuzhiyun 441*4882a593Smuzhiyunbyte 2:: 442*4882a593Smuzhiyun 443*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 444*4882a593Smuzhiyun x7 x6 x5 x4 x3 x2 x1 x0 445*4882a593Smuzhiyun 446*4882a593Smuzhiyun x11..x0 = absolute x value (horizontal) 447*4882a593Smuzhiyun 448*4882a593Smuzhiyunbyte 3:: 449*4882a593Smuzhiyun 450*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 451*4882a593Smuzhiyun n4 vf w1 w0 . . . b2 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun n4 = set if more than 3 fingers (only in 3 fingers mode) 454*4882a593Smuzhiyun vf = a kind of flag ? (only on EF123, 0 when finger is over one 455*4882a593Smuzhiyun of the buttons, 1 otherwise) 456*4882a593Smuzhiyun w3..w0 = width of the finger touch (not EF113) 457*4882a593Smuzhiyun b2 (on EF113 only, 0 otherwise), b2.R.L indicates one button pressed: 458*4882a593Smuzhiyun 0 = none 459*4882a593Smuzhiyun 1 = Left 460*4882a593Smuzhiyun 2 = Right 461*4882a593Smuzhiyun 3 = Middle (Left and Right) 462*4882a593Smuzhiyun 4 = Forward 463*4882a593Smuzhiyun 5 = Back 464*4882a593Smuzhiyun 6 = Another one 465*4882a593Smuzhiyun 7 = Another one 466*4882a593Smuzhiyun 467*4882a593Smuzhiyunbyte 4:: 468*4882a593Smuzhiyun 469*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 470*4882a593Smuzhiyun p3 p1 p2 p0 y11 y10 y9 y8 471*4882a593Smuzhiyun 472*4882a593Smuzhiyun p7..p0 = pressure (not EF113) 473*4882a593Smuzhiyun 474*4882a593Smuzhiyunbyte 5:: 475*4882a593Smuzhiyun 476*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 477*4882a593Smuzhiyun y7 y6 y5 y4 y3 y2 y1 y0 478*4882a593Smuzhiyun 479*4882a593Smuzhiyun y11..y0 = absolute y value (vertical) 480*4882a593Smuzhiyun 481*4882a593Smuzhiyun 482*4882a593SmuzhiyunTwo finger touch 483*4882a593Smuzhiyun^^^^^^^^^^^^^^^^ 484*4882a593Smuzhiyun 485*4882a593SmuzhiyunNote that the two pairs of coordinates are not exactly the coordinates of the 486*4882a593Smuzhiyuntwo fingers, but only the pair of the lower-left and upper-right coordinates. 487*4882a593SmuzhiyunSo the actual fingers might be situated on the other diagonal of the square 488*4882a593Smuzhiyundefined by these two points. 489*4882a593Smuzhiyun 490*4882a593Smuzhiyunbyte 0:: 491*4882a593Smuzhiyun 492*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 493*4882a593Smuzhiyun n1 n0 ay8 ax8 . . R L 494*4882a593Smuzhiyun 495*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 496*4882a593Smuzhiyun n1..n0 = number of fingers on touchpad 497*4882a593Smuzhiyun 498*4882a593Smuzhiyunbyte 1:: 499*4882a593Smuzhiyun 500*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 501*4882a593Smuzhiyun ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 502*4882a593Smuzhiyun 503*4882a593Smuzhiyun ax8..ax0 = lower-left finger absolute x value 504*4882a593Smuzhiyun 505*4882a593Smuzhiyunbyte 2:: 506*4882a593Smuzhiyun 507*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 508*4882a593Smuzhiyun ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 509*4882a593Smuzhiyun 510*4882a593Smuzhiyun ay8..ay0 = lower-left finger absolute y value 511*4882a593Smuzhiyun 512*4882a593Smuzhiyunbyte 3:: 513*4882a593Smuzhiyun 514*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 515*4882a593Smuzhiyun . . by8 bx8 . . . . 516*4882a593Smuzhiyun 517*4882a593Smuzhiyunbyte 4:: 518*4882a593Smuzhiyun 519*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 520*4882a593Smuzhiyun bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 521*4882a593Smuzhiyun 522*4882a593Smuzhiyun bx8..bx0 = upper-right finger absolute x value 523*4882a593Smuzhiyun 524*4882a593Smuzhiyunbyte 5:: 525*4882a593Smuzhiyun 526*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 527*4882a593Smuzhiyun by7 by8 by5 by4 by3 by2 by1 by0 528*4882a593Smuzhiyun 529*4882a593Smuzhiyun by8..by0 = upper-right finger absolute y value 530*4882a593Smuzhiyun 531*4882a593SmuzhiyunHardware version 3 532*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~ 533*4882a593Smuzhiyun 534*4882a593SmuzhiyunRegisters 535*4882a593Smuzhiyun--------- 536*4882a593Smuzhiyun 537*4882a593Smuzhiyun* reg_10:: 538*4882a593Smuzhiyun 539*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 540*4882a593Smuzhiyun 0 0 0 0 R F T A 541*4882a593Smuzhiyun 542*4882a593Smuzhiyun A: 1 = enable absolute tracking 543*4882a593Smuzhiyun T: 1 = enable two finger mode auto correct 544*4882a593Smuzhiyun F: 1 = disable ABS Position Filter 545*4882a593Smuzhiyun R: 1 = enable real hardware resolution 546*4882a593Smuzhiyun 547*4882a593SmuzhiyunNative absolute mode 6 byte packet format 548*4882a593Smuzhiyun----------------------------------------- 549*4882a593Smuzhiyun 550*4882a593Smuzhiyun1 and 3 finger touch shares the same 6-byte packet format, except that 551*4882a593Smuzhiyun3 finger touch only reports the position of the center of all three fingers. 552*4882a593Smuzhiyun 553*4882a593SmuzhiyunFirmware would send 12 bytes of data for 2 finger touch. 554*4882a593Smuzhiyun 555*4882a593SmuzhiyunNote on debounce: 556*4882a593SmuzhiyunIn case the box has unstable power supply or other electricity issues, or 557*4882a593Smuzhiyunwhen number of finger changes, F/W would send "debounce packet" to inform 558*4882a593Smuzhiyundriver that the hardware is in debounce status. 559*4882a593SmuzhiyunThe debouce packet has the following signature:: 560*4882a593Smuzhiyun 561*4882a593Smuzhiyun byte 0: 0xc4 562*4882a593Smuzhiyun byte 1: 0xff 563*4882a593Smuzhiyun byte 2: 0xff 564*4882a593Smuzhiyun byte 3: 0x02 565*4882a593Smuzhiyun byte 4: 0xff 566*4882a593Smuzhiyun byte 5: 0xff 567*4882a593Smuzhiyun 568*4882a593SmuzhiyunWhen we encounter this kind of packet, we just ignore it. 569*4882a593Smuzhiyun 570*4882a593SmuzhiyunOne/Three finger touch 571*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^ 572*4882a593Smuzhiyun 573*4882a593Smuzhiyunbyte 0:: 574*4882a593Smuzhiyun 575*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 576*4882a593Smuzhiyun n1 n0 w3 w2 0 1 R L 577*4882a593Smuzhiyun 578*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 579*4882a593Smuzhiyun n1..n0 = number of fingers on touchpad 580*4882a593Smuzhiyun 581*4882a593Smuzhiyunbyte 1:: 582*4882a593Smuzhiyun 583*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 584*4882a593Smuzhiyun p7 p6 p5 p4 x11 x10 x9 x8 585*4882a593Smuzhiyun 586*4882a593Smuzhiyunbyte 2:: 587*4882a593Smuzhiyun 588*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 589*4882a593Smuzhiyun x7 x6 x5 x4 x3 x2 x1 x0 590*4882a593Smuzhiyun 591*4882a593Smuzhiyun x11..x0 = absolute x value (horizontal) 592*4882a593Smuzhiyun 593*4882a593Smuzhiyunbyte 3:: 594*4882a593Smuzhiyun 595*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 596*4882a593Smuzhiyun 0 0 w1 w0 0 0 1 0 597*4882a593Smuzhiyun 598*4882a593Smuzhiyun w3..w0 = width of the finger touch 599*4882a593Smuzhiyun 600*4882a593Smuzhiyunbyte 4:: 601*4882a593Smuzhiyun 602*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 603*4882a593Smuzhiyun p3 p1 p2 p0 y11 y10 y9 y8 604*4882a593Smuzhiyun 605*4882a593Smuzhiyun p7..p0 = pressure 606*4882a593Smuzhiyun 607*4882a593Smuzhiyunbyte 5:: 608*4882a593Smuzhiyun 609*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 610*4882a593Smuzhiyun y7 y6 y5 y4 y3 y2 y1 y0 611*4882a593Smuzhiyun 612*4882a593Smuzhiyun y11..y0 = absolute y value (vertical) 613*4882a593Smuzhiyun 614*4882a593SmuzhiyunTwo finger touch 615*4882a593Smuzhiyun^^^^^^^^^^^^^^^^ 616*4882a593Smuzhiyun 617*4882a593SmuzhiyunThe packet format is exactly the same for two finger touch, except the hardware 618*4882a593Smuzhiyunsends two 6 byte packets. The first packet contains data for the first finger, 619*4882a593Smuzhiyunthe second packet has data for the second finger. So for two finger touch a 620*4882a593Smuzhiyuntotal of 12 bytes are sent. 621*4882a593Smuzhiyun 622*4882a593SmuzhiyunHardware version 4 623*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~ 624*4882a593Smuzhiyun 625*4882a593SmuzhiyunRegisters 626*4882a593Smuzhiyun--------- 627*4882a593Smuzhiyun 628*4882a593Smuzhiyun* reg_07:: 629*4882a593Smuzhiyun 630*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 631*4882a593Smuzhiyun 0 0 0 0 0 0 0 A 632*4882a593Smuzhiyun 633*4882a593Smuzhiyun A: 1 = enable absolute tracking 634*4882a593Smuzhiyun 635*4882a593SmuzhiyunNative absolute mode 6 byte packet format 636*4882a593Smuzhiyun----------------------------------------- 637*4882a593Smuzhiyun 638*4882a593Smuzhiyunv4 hardware is a true multitouch touchpad, capable of tracking up to 5 fingers. 639*4882a593SmuzhiyunUnfortunately, due to PS/2's limited bandwidth, its packet format is rather 640*4882a593Smuzhiyuncomplex. 641*4882a593Smuzhiyun 642*4882a593SmuzhiyunWhenever the numbers or identities of the fingers changes, the hardware sends a 643*4882a593Smuzhiyunstatus packet to indicate how many and which fingers is on touchpad, followed by 644*4882a593Smuzhiyunhead packets or motion packets. A head packet contains data of finger id, finger 645*4882a593Smuzhiyunposition (absolute x, y values), width, and pressure. A motion packet contains 646*4882a593Smuzhiyuntwo fingers' position delta. 647*4882a593Smuzhiyun 648*4882a593SmuzhiyunFor example, when status packet tells there are 2 fingers on touchpad, then we 649*4882a593Smuzhiyuncan expect two following head packets. If the finger status doesn't change, 650*4882a593Smuzhiyunthe following packets would be motion packets, only sending delta of finger 651*4882a593Smuzhiyunposition, until we receive a status packet. 652*4882a593Smuzhiyun 653*4882a593SmuzhiyunOne exception is one finger touch. when a status packet tells us there is only 654*4882a593Smuzhiyunone finger, the hardware would just send head packets afterwards. 655*4882a593Smuzhiyun 656*4882a593SmuzhiyunStatus packet 657*4882a593Smuzhiyun^^^^^^^^^^^^^ 658*4882a593Smuzhiyun 659*4882a593Smuzhiyunbyte 0:: 660*4882a593Smuzhiyun 661*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 662*4882a593Smuzhiyun . . . . 0 1 R L 663*4882a593Smuzhiyun 664*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 665*4882a593Smuzhiyun 666*4882a593Smuzhiyunbyte 1:: 667*4882a593Smuzhiyun 668*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 669*4882a593Smuzhiyun . . . ft4 ft3 ft2 ft1 ft0 670*4882a593Smuzhiyun 671*4882a593Smuzhiyun ft4 ft3 ft2 ft1 ft0 ftn = 1 when finger n is on touchpad 672*4882a593Smuzhiyun 673*4882a593Smuzhiyunbyte 2:: 674*4882a593Smuzhiyun 675*4882a593Smuzhiyun not used 676*4882a593Smuzhiyun 677*4882a593Smuzhiyunbyte 3:: 678*4882a593Smuzhiyun 679*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 680*4882a593Smuzhiyun . . . 1 0 0 0 0 681*4882a593Smuzhiyun 682*4882a593Smuzhiyun constant bits 683*4882a593Smuzhiyun 684*4882a593Smuzhiyunbyte 4:: 685*4882a593Smuzhiyun 686*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 687*4882a593Smuzhiyun p . . . . . . . 688*4882a593Smuzhiyun 689*4882a593Smuzhiyun p = 1 for palm 690*4882a593Smuzhiyun 691*4882a593Smuzhiyunbyte 5:: 692*4882a593Smuzhiyun 693*4882a593Smuzhiyun not used 694*4882a593Smuzhiyun 695*4882a593SmuzhiyunHead packet 696*4882a593Smuzhiyun^^^^^^^^^^^ 697*4882a593Smuzhiyun 698*4882a593Smuzhiyunbyte 0:: 699*4882a593Smuzhiyun 700*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 701*4882a593Smuzhiyun w3 w2 w1 w0 0 1 R L 702*4882a593Smuzhiyun 703*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 704*4882a593Smuzhiyun w3..w0 = finger width (spans how many trace lines) 705*4882a593Smuzhiyun 706*4882a593Smuzhiyunbyte 1:: 707*4882a593Smuzhiyun 708*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 709*4882a593Smuzhiyun p7 p6 p5 p4 x11 x10 x9 x8 710*4882a593Smuzhiyun 711*4882a593Smuzhiyunbyte 2:: 712*4882a593Smuzhiyun 713*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 714*4882a593Smuzhiyun x7 x6 x5 x4 x3 x2 x1 x0 715*4882a593Smuzhiyun 716*4882a593Smuzhiyun x11..x0 = absolute x value (horizontal) 717*4882a593Smuzhiyun 718*4882a593Smuzhiyunbyte 3:: 719*4882a593Smuzhiyun 720*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 721*4882a593Smuzhiyun id2 id1 id0 1 0 0 0 1 722*4882a593Smuzhiyun 723*4882a593Smuzhiyun id2..id0 = finger id 724*4882a593Smuzhiyun 725*4882a593Smuzhiyunbyte 4:: 726*4882a593Smuzhiyun 727*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 728*4882a593Smuzhiyun p3 p1 p2 p0 y11 y10 y9 y8 729*4882a593Smuzhiyun 730*4882a593Smuzhiyun p7..p0 = pressure 731*4882a593Smuzhiyun 732*4882a593Smuzhiyunbyte 5:: 733*4882a593Smuzhiyun 734*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 735*4882a593Smuzhiyun y7 y6 y5 y4 y3 y2 y1 y0 736*4882a593Smuzhiyun 737*4882a593Smuzhiyun y11..y0 = absolute y value (vertical) 738*4882a593Smuzhiyun 739*4882a593SmuzhiyunMotion packet 740*4882a593Smuzhiyun^^^^^^^^^^^^^ 741*4882a593Smuzhiyun 742*4882a593Smuzhiyunbyte 0:: 743*4882a593Smuzhiyun 744*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 745*4882a593Smuzhiyun id2 id1 id0 w 0 1 R L 746*4882a593Smuzhiyun 747*4882a593Smuzhiyun L, R = 1 when Left, Right mouse button pressed 748*4882a593Smuzhiyun id2..id0 = finger id 749*4882a593Smuzhiyun w = 1 when delta overflows (> 127 or < -128), in this case 750*4882a593Smuzhiyun firmware sends us (delta x / 5) and (delta y / 5) 751*4882a593Smuzhiyun 752*4882a593Smuzhiyunbyte 1:: 753*4882a593Smuzhiyun 754*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 755*4882a593Smuzhiyun x7 x6 x5 x4 x3 x2 x1 x0 756*4882a593Smuzhiyun 757*4882a593Smuzhiyun x7..x0 = delta x (two's complement) 758*4882a593Smuzhiyun 759*4882a593Smuzhiyunbyte 2:: 760*4882a593Smuzhiyun 761*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 762*4882a593Smuzhiyun y7 y6 y5 y4 y3 y2 y1 y0 763*4882a593Smuzhiyun 764*4882a593Smuzhiyun y7..y0 = delta y (two's complement) 765*4882a593Smuzhiyun 766*4882a593Smuzhiyunbyte 3:: 767*4882a593Smuzhiyun 768*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 769*4882a593Smuzhiyun id2 id1 id0 1 0 0 1 0 770*4882a593Smuzhiyun 771*4882a593Smuzhiyun id2..id0 = finger id 772*4882a593Smuzhiyun 773*4882a593Smuzhiyunbyte 4:: 774*4882a593Smuzhiyun 775*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 776*4882a593Smuzhiyun x7 x6 x5 x4 x3 x2 x1 x0 777*4882a593Smuzhiyun 778*4882a593Smuzhiyun x7..x0 = delta x (two's complement) 779*4882a593Smuzhiyun 780*4882a593Smuzhiyunbyte 5:: 781*4882a593Smuzhiyun 782*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 783*4882a593Smuzhiyun y7 y6 y5 y4 y3 y2 y1 y0 784*4882a593Smuzhiyun 785*4882a593Smuzhiyun y7..y0 = delta y (two's complement) 786*4882a593Smuzhiyun 787*4882a593Smuzhiyun byte 0 ~ 2 for one finger 788*4882a593Smuzhiyun byte 3 ~ 5 for another 789*4882a593Smuzhiyun 790*4882a593Smuzhiyun 791*4882a593SmuzhiyunTrackpoint (for Hardware version 3 and 4) 792*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 793*4882a593Smuzhiyun 794*4882a593SmuzhiyunRegisters 795*4882a593Smuzhiyun--------- 796*4882a593Smuzhiyun 797*4882a593SmuzhiyunNo special registers have been identified. 798*4882a593Smuzhiyun 799*4882a593SmuzhiyunNative relative mode 6 byte packet format 800*4882a593Smuzhiyun----------------------------------------- 801*4882a593Smuzhiyun 802*4882a593SmuzhiyunStatus Packet 803*4882a593Smuzhiyun^^^^^^^^^^^^^ 804*4882a593Smuzhiyun 805*4882a593Smuzhiyunbyte 0:: 806*4882a593Smuzhiyun 807*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 808*4882a593Smuzhiyun 0 0 sx sy 0 M R L 809*4882a593Smuzhiyun 810*4882a593Smuzhiyunbyte 1:: 811*4882a593Smuzhiyun 812*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 813*4882a593Smuzhiyun ~sx 0 0 0 0 0 0 0 814*4882a593Smuzhiyun 815*4882a593Smuzhiyunbyte 2:: 816*4882a593Smuzhiyun 817*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 818*4882a593Smuzhiyun ~sy 0 0 0 0 0 0 0 819*4882a593Smuzhiyun 820*4882a593Smuzhiyunbyte 3:: 821*4882a593Smuzhiyun 822*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 823*4882a593Smuzhiyun 0 0 ~sy ~sx 0 1 1 0 824*4882a593Smuzhiyun 825*4882a593Smuzhiyunbyte 4:: 826*4882a593Smuzhiyun 827*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 828*4882a593Smuzhiyun x7 x6 x5 x4 x3 x2 x1 x0 829*4882a593Smuzhiyun 830*4882a593Smuzhiyunbyte 5:: 831*4882a593Smuzhiyun 832*4882a593Smuzhiyun bit 7 6 5 4 3 2 1 0 833*4882a593Smuzhiyun y7 y6 y5 y4 y3 y2 y1 y0 834*4882a593Smuzhiyun 835*4882a593Smuzhiyun 836*4882a593Smuzhiyun x and y are written in two's complement spread 837*4882a593Smuzhiyun over 9 bits with sx/sy the relative top bit and 838*4882a593Smuzhiyun x7..x0 and y7..y0 the lower bits. 839*4882a593Smuzhiyun ~sx is the inverse of sx, ~sy is the inverse of sy. 840*4882a593Smuzhiyun The sign of y is opposite to what the input driver 841*4882a593Smuzhiyun expects for a relative movement 842