Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SB.cpp@4:f953792e45cb, 2014-09-03 (annotated)
- Committer:
- jocis
- Date:
- Wed Sep 03 07:36:43 2014 +0000
- Revision:
- 4:f953792e45cb
- Parent:
- 2:a7c0fcd157f7
Added documentation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jocis | 1:e6282b645d9b | 1 | #include "SpaceBall.h" |
jocis | 1:e6282b645d9b | 2 | |
jocis | 2:a7c0fcd157f7 | 3 | #define Sleep(x) wait_ms(x) |
jocis | 1:e6282b645d9b | 4 | |
jocis | 2:a7c0fcd157f7 | 5 | //extern Serial pc; |
jocis | 1:e6282b645d9b | 6 | |
jocis | 1:e6282b645d9b | 7 | /////////////////////////////////////////////////////////////////////////////// |
jocis | 1:e6282b645d9b | 8 | |
jocis | 1:e6282b645d9b | 9 | /* |
jocis | 1:e6282b645d9b | 10 | Convert characters to nibbles |
jocis | 1:e6282b645d9b | 11 | */ |
jocis | 1:e6282b645d9b | 12 | int DecodeSM(char c) |
jocis | 1:e6282b645d9b | 13 | { |
jocis | 1:e6282b645d9b | 14 | int n; |
jocis | 1:e6282b645d9b | 15 | |
jocis | 1:e6282b645d9b | 16 | switch (c) { |
jocis | 1:e6282b645d9b | 17 | case '0': n = 0; break; |
jocis | 1:e6282b645d9b | 18 | case 'A': n = 1; break; |
jocis | 1:e6282b645d9b | 19 | case 'B': n = 2; break; |
jocis | 1:e6282b645d9b | 20 | case '3': n = 3; break; |
jocis | 1:e6282b645d9b | 21 | case 'D': n = 4; break; |
jocis | 1:e6282b645d9b | 22 | case '5': n = 5; break; |
jocis | 1:e6282b645d9b | 23 | case '6': n = 6; break; |
jocis | 1:e6282b645d9b | 24 | case 'G': n = 7; break; |
jocis | 1:e6282b645d9b | 25 | case 'H': n = 8; break; |
jocis | 1:e6282b645d9b | 26 | case '9': n = 9; break; |
jocis | 1:e6282b645d9b | 27 | case ':': n = 10; break; |
jocis | 1:e6282b645d9b | 28 | case 'K': n = 11; break; |
jocis | 1:e6282b645d9b | 29 | case '<': n = 12; break; |
jocis | 1:e6282b645d9b | 30 | case 'M': n = 13; break; |
jocis | 1:e6282b645d9b | 31 | case 'N': n = 14; break; |
jocis | 1:e6282b645d9b | 32 | case '?': n = 15; break; |
jocis | 1:e6282b645d9b | 33 | default: n = 0; break; |
jocis | 1:e6282b645d9b | 34 | } |
jocis | 1:e6282b645d9b | 35 | |
jocis | 1:e6282b645d9b | 36 | return(n); |
jocis | 1:e6282b645d9b | 37 | } |
jocis | 1:e6282b645d9b | 38 | |
jocis | 1:e6282b645d9b | 39 | /////////////////////////////////////////////////////////////////////////////// |
jocis | 1:e6282b645d9b | 40 | |
jocis | 1:e6282b645d9b | 41 | void SpaceBall::InitSB() |
jocis | 1:e6282b645d9b | 42 | { |
jocis | 1:e6282b645d9b | 43 | m_resetoccured=0; |
jocis | 1:e6282b645d9b | 44 | |
jocis | 2:a7c0fcd157f7 | 45 | m_spaceball4000 = 0; /* re-determine which type it is */ |
jocis | 1:e6282b645d9b | 46 | m_leftymode4000 = 0; /* re-determine if its in lefty mode */ |
jocis | 1:e6282b645d9b | 47 | |
jocis | 2:a7c0fcd157f7 | 48 | _fScaleT = 1.0 / 5000.0; |
jocis | 2:a7c0fcd157f7 | 49 | _fScaleR = 1.0 / 2000.0; |
jocis | 2:a7c0fcd157f7 | 50 | |
jocis | 1:e6282b645d9b | 51 | if (!m_resetoccured) { |
jocis | 1:e6282b645d9b | 52 | m_resetoccured=1; |
jocis | 1:e6282b645d9b | 53 | _serial.printf ( "@\r" ); /* force reset */ |
jocis | 1:e6282b645d9b | 54 | } |
jocis | 1:e6282b645d9b | 55 | |
jocis | 1:e6282b645d9b | 56 | Sleep(10); |
jocis | 1:e6282b645d9b | 57 | |
jocis | 1:e6282b645d9b | 58 | // pc.printf("Sending initialization sequence to spaceball...\n"); |
jocis | 1:e6282b645d9b | 59 | |
jocis | 1:e6282b645d9b | 60 | _serial.printf ( "CB\r" ); |
jocis | 1:e6282b645d9b | 61 | Sleep(10); |
jocis | 1:e6282b645d9b | 62 | _serial.printf ( "NT\r" ); |
jocis | 1:e6282b645d9b | 63 | Sleep(10); |
jocis | 1:e6282b645d9b | 64 | _serial.printf ( "FTp\r" ); |
jocis | 1:e6282b645d9b | 65 | Sleep(10); |
jocis | 1:e6282b645d9b | 66 | _serial.printf ( "FRp\r" ); |
jocis | 1:e6282b645d9b | 67 | Sleep(10); |
jocis | 1:e6282b645d9b | 68 | _serial.printf ( "P@r@r\r" ); |
jocis | 1:e6282b645d9b | 69 | Sleep(10); |
jocis | 1:e6282b645d9b | 70 | _serial.printf ( "MSSV\r" ); |
jocis | 1:e6282b645d9b | 71 | Sleep(10); |
jocis | 1:e6282b645d9b | 72 | _serial.printf ( "Z\r" ); |
jocis | 1:e6282b645d9b | 73 | Sleep(10); |
jocis | 1:e6282b645d9b | 74 | _serial.printf ( "BcCcC\r" ); |
jocis | 1:e6282b645d9b | 75 | |
jocis | 1:e6282b645d9b | 76 | Sleep(10); |
jocis | 1:e6282b645d9b | 77 | _serial.printf ( "\rvz\r" ); |
jocis | 1:e6282b645d9b | 78 | Sleep(10); |
jocis | 1:e6282b645d9b | 79 | _serial.printf ( "vQ\r" ); |
jocis | 1:e6282b645d9b | 80 | Sleep(10); |
jocis | 1:e6282b645d9b | 81 | _serial.printf ( "kQ\r" ); |
jocis | 1:e6282b645d9b | 82 | Sleep(10); |
jocis | 1:e6282b645d9b | 83 | _serial.printf ( "m3\r" ); |
jocis | 1:e6282b645d9b | 84 | } |
jocis | 1:e6282b645d9b | 85 | |
jocis | 1:e6282b645d9b | 86 | /////////////////////////////////////////////////////////////////////////////// |
jocis | 1:e6282b645d9b | 87 | |
jocis | 1:e6282b645d9b | 88 | void SpaceBall::ProcessSB ( char data ) |
jocis | 1:e6282b645d9b | 89 | { |
jocis | 1:e6282b645d9b | 90 | switch (data) { |
jocis | 1:e6282b645d9b | 91 | case '\r': //0xd: |
jocis | 1:e6282b645d9b | 92 | _data[_idx] = 0; |
jocis | 1:e6282b645d9b | 93 | ProcessPacketSB(); |
jocis | 1:e6282b645d9b | 94 | _idx = 0; |
jocis | 1:e6282b645d9b | 95 | _escape = 0; |
jocis | 1:e6282b645d9b | 96 | break; |
jocis | 1:e6282b645d9b | 97 | case '^': |
jocis | 1:e6282b645d9b | 98 | if (!_escape) { |
jocis | 1:e6282b645d9b | 99 | _escape = 1; |
jocis | 1:e6282b645d9b | 100 | break; |
jocis | 1:e6282b645d9b | 101 | } |
jocis | 1:e6282b645d9b | 102 | _escape = 0; |
jocis | 1:e6282b645d9b | 103 | case 'M': |
jocis | 1:e6282b645d9b | 104 | case 'Q': |
jocis | 1:e6282b645d9b | 105 | case 'S': |
jocis | 1:e6282b645d9b | 106 | if (_escape) { |
jocis | 1:e6282b645d9b | 107 | _escape = 0; |
jocis | 1:e6282b645d9b | 108 | data &= 0x1f; |
jocis | 1:e6282b645d9b | 109 | } |
jocis | 1:e6282b645d9b | 110 | default: |
jocis | 1:e6282b645d9b | 111 | if (_escape) |
jocis | 1:e6282b645d9b | 112 | _escape = 0; |
jocis | 1:e6282b645d9b | 113 | if (_idx < SPACEBALL_MAX_LENGTH) |
jocis | 1:e6282b645d9b | 114 | _data[_idx++] = data; |
jocis | 1:e6282b645d9b | 115 | break; |
jocis | 1:e6282b645d9b | 116 | } |
jocis | 1:e6282b645d9b | 117 | } |
jocis | 1:e6282b645d9b | 118 | |
jocis | 1:e6282b645d9b | 119 | /////////////////////////////////////////////////////////////////////////////// |
jocis | 1:e6282b645d9b | 120 | |
jocis | 1:e6282b645d9b | 121 | void SpaceBall::ProcessPacketSB ( void ) |
jocis | 1:e6282b645d9b | 122 | { |
jocis | 1:e6282b645d9b | 123 | int i; |
jocis | 1:e6282b645d9b | 124 | |
jocis | 1:e6282b645d9b | 125 | if (_idx < 2) return; |
jocis | 1:e6282b645d9b | 126 | |
jocis | 1:e6282b645d9b | 127 | switch (_data[0]) { |
jocis | 1:e6282b645d9b | 128 | |
jocis | 1:e6282b645d9b | 129 | case 'D': /* Ball data */ |
jocis | 1:e6282b645d9b | 130 | if (_idx != 15) return; |
jocis | 1:e6282b645d9b | 131 | for (i = 0; i < 6; i++) { |
jocis | 2:a7c0fcd157f7 | 132 | _axis[i] = (short)( (_data[2*i + 3] << 8) | _data[2*i + 2] ); |
jocis | 1:e6282b645d9b | 133 | } |
jocis | 1:e6282b645d9b | 134 | DoChangedAxis(); |
jocis | 1:e6282b645d9b | 135 | break; |
jocis | 1:e6282b645d9b | 136 | |
jocis | 1:e6282b645d9b | 137 | case 'd': /* Ball data */ |
jocis | 1:e6282b645d9b | 138 | //pc.printf("d%d",_idx); |
jocis | 1:e6282b645d9b | 139 | if (_idx != 25) return; |
jocis | 1:e6282b645d9b | 140 | for (i = 0; i < 6; i++) { |
jocis | 2:a7c0fcd157f7 | 141 | _axis[i] = (short)( ( |
jocis | 1:e6282b645d9b | 142 | DecodeSM(_data[4*i+4]) | (DecodeSM(_data[4*i+3])<<4) | (DecodeSM(_data[4*i+2])<<8) | (DecodeSM(_data[4*i+1])<<12) ) |
jocis | 1:e6282b645d9b | 143 | ^ 0x8000 ); |
jocis | 1:e6282b645d9b | 144 | } |
jocis | 1:e6282b645d9b | 145 | DoChangedAxis(); |
jocis | 1:e6282b645d9b | 146 | break; |
jocis | 1:e6282b645d9b | 147 | |
jocis | 1:e6282b645d9b | 148 | case 'K': /* Button data */ |
jocis | 1:e6282b645d9b | 149 | if (_idx != 3) return; |
jocis | 1:e6282b645d9b | 150 | /* Spaceball 2003A, 2003B, 2003 FLX, 3003 FLX, 4000 FLX */ |
jocis | 1:e6282b645d9b | 151 | /* button packet. (4000 only for backwards compatibility) */ |
jocis | 1:e6282b645d9b | 152 | /* The lowest 5 bits of the first byte are buttons 5-9 */ |
jocis | 1:e6282b645d9b | 153 | /* Button '8' on a Spaceball 2003 is the rezero button */ |
jocis | 1:e6282b645d9b | 154 | /* The lowest 4 bits of the second byte are buttons 1-4 */ |
jocis | 1:e6282b645d9b | 155 | /* For Spaceball 2003, we'll map the buttons 1-7 normally */ |
jocis | 1:e6282b645d9b | 156 | /* skip 8, as its a hardware "rezero button" on that device */ |
jocis | 1:e6282b645d9b | 157 | /* and call the "pick" button "8". */ |
jocis | 1:e6282b645d9b | 158 | /* On the Spaceball 3003, the "right" button also triggers */ |
jocis | 1:e6282b645d9b | 159 | /* the "pick" bit. We OR the 2003/3003 rezero bits together */ |
jocis | 1:e6282b645d9b | 160 | |
jocis | 1:e6282b645d9b | 161 | /* if we have found a Spaceball 4000, then we ignore the 'K' */ |
jocis | 1:e6282b645d9b | 162 | /* packets entirely, and only use the '.' packets. */ |
jocis | 1:e6282b645d9b | 163 | if (m_spaceball4000) |
jocis | 1:e6282b645d9b | 164 | break; |
jocis | 1:e6282b645d9b | 165 | |
jocis | 2:a7c0fcd157f7 | 166 | _buttons = |
jocis | 1:e6282b645d9b | 167 | ((_data[1] & 0x10) << 8) | /* 2003 pick button is ??? */ |
jocis | 1:e6282b645d9b | 168 | ((_data[1] & 0x20) << 9) | /* 3003 rezero button */ |
jocis | 1:e6282b645d9b | 169 | ((_data[1] & 0x08) << 11) | /* 2003 rezero button */ |
jocis | 1:e6282b645d9b | 170 | ((_data[1] & 0x07) << 4) | /* 5,6,7 (2003/4000) */ |
jocis | 1:e6282b645d9b | 171 | ((_data[2] & 0x30) << 8) | /* 3003 Left/Right buttons */ |
jocis | 1:e6282b645d9b | 172 | ((_data[2] & 0x0F)); /* 1,2,3,4 (2003/4000) */ |
jocis | 1:e6282b645d9b | 173 | |
jocis | 1:e6282b645d9b | 174 | DoChangedButtons(); |
jocis | 1:e6282b645d9b | 175 | break; |
jocis | 1:e6282b645d9b | 176 | |
jocis | 1:e6282b645d9b | 177 | case 'k': /* Button data */ |
jocis | 1:e6282b645d9b | 178 | //pc.printf("k%d",_idx); |
jocis | 2:a7c0fcd157f7 | 179 | //pc.printf("<%s>\r\n",_data); |
jocis | 1:e6282b645d9b | 180 | if (_idx != 4) return; |
jocis | 2:a7c0fcd157f7 | 181 | _buttons = DecodeSM(_data[1]) | (DecodeSM(_data[2])<<4) | (DecodeSM(_data[3])<<8); |
jocis | 1:e6282b645d9b | 182 | |
jocis | 1:e6282b645d9b | 183 | DoChangedButtons(); |
jocis | 1:e6282b645d9b | 184 | break; |
jocis | 1:e6282b645d9b | 185 | |
jocis | 1:e6282b645d9b | 186 | case '.': /* Advanced button data */ |
jocis | 1:e6282b645d9b | 187 | if (_idx != 3) return; |
jocis | 1:e6282b645d9b | 188 | /* Spaceball 4000 FLX "expanded" button packet, with 12 buttons */ |
jocis | 1:e6282b645d9b | 189 | |
jocis | 1:e6282b645d9b | 190 | /* extra packet validity check, since we use this packet type */ |
jocis | 1:e6282b645d9b | 191 | /* to override the 'K' button packets, and determine if its a */ |
jocis | 1:e6282b645d9b | 192 | /* Spaceball 4000 or not... */ |
jocis | 1:e6282b645d9b | 193 | |
jocis | 1:e6282b645d9b | 194 | /* if we got a valid '.' packet, this must be a Spaceball 4000 */ |
jocis | 1:e6282b645d9b | 195 | m_spaceball4000 = 1; /* Must be talking to a Spaceball 4000 */ |
jocis | 1:e6282b645d9b | 196 | |
jocis | 1:e6282b645d9b | 197 | /* Spaceball 4000 series "expanded" button press event */ |
jocis | 1:e6282b645d9b | 198 | /* includes data for 12 buttons, and left/right orientation */ |
jocis | 2:a7c0fcd157f7 | 199 | _buttons = |
jocis | 1:e6282b645d9b | 200 | (((~_data[1]) & 0x20) << 10) | /* "left handed" mode */ |
jocis | 1:e6282b645d9b | 201 | ((_data[1] & 0x1F) << 7) | /* 8,9,10,11,12 */ |
jocis | 1:e6282b645d9b | 202 | ((_data[2] & 0x3F) ) | /* 1,2,3,4,5,6 (4000) */ |
jocis | 1:e6282b645d9b | 203 | ((_data[2] & 0x80) >> 1); /* 7 (4000) */ |
jocis | 1:e6282b645d9b | 204 | |
jocis | 1:e6282b645d9b | 205 | /* set "lefty" orientation mode if "lefty bit" is _clear_ */ |
jocis | 1:e6282b645d9b | 206 | if ((_data[1] & 0x20) == 0) |
jocis | 1:e6282b645d9b | 207 | m_leftymode4000 = 1; /* left handed mode */ |
jocis | 1:e6282b645d9b | 208 | else |
jocis | 1:e6282b645d9b | 209 | m_leftymode4000 = 0; /* right handed mode */ |
jocis | 1:e6282b645d9b | 210 | |
jocis | 1:e6282b645d9b | 211 | DoChangedButtons(); |
jocis | 1:e6282b645d9b | 212 | break; |
jocis | 1:e6282b645d9b | 213 | |
jocis | 1:e6282b645d9b | 214 | case 'E': /* Device error */ |
jocis | 1:e6282b645d9b | 215 | case 'e': /* Device error */ |
jocis | 1:e6282b645d9b | 216 | //printk(KERN_ERR "spaceball: Device error. [%s]\n", spaceball->data + 1); |
jocis | 1:e6282b645d9b | 217 | break; |
jocis | 1:e6282b645d9b | 218 | |
jocis | 1:e6282b645d9b | 219 | case '?': /* Bad command packet */ |
jocis | 1:e6282b645d9b | 220 | //printk(KERN_ERR "spaceball: Bad command. [%s]\n", spaceball->data + 1); |
jocis | 1:e6282b645d9b | 221 | break; |
jocis | 1:e6282b645d9b | 222 | |
jocis | 1:e6282b645d9b | 223 | case 'C': /* Communications mode packet */ |
jocis | 1:e6282b645d9b | 224 | case 'F': /* Spaceball sensitization packet */ |
jocis | 1:e6282b645d9b | 225 | case 'P': /* Spaceball update rate packet */ |
jocis | 1:e6282b645d9b | 226 | case 'M': /* Spaceball movement mode packet */ |
jocis | 1:e6282b645d9b | 227 | case 'N': /* Null region packet */ |
jocis | 1:e6282b645d9b | 228 | case '\r': /* carriage return at poweron */ |
jocis | 1:e6282b645d9b | 229 | case '\v': /* XON at poweron */ |
jocis | 1:e6282b645d9b | 230 | /* eat and ignore these packets */ |
jocis | 1:e6282b645d9b | 231 | break; |
jocis | 1:e6282b645d9b | 232 | |
jocis | 1:e6282b645d9b | 233 | case '@': /* Reset packet */ |
jocis | 1:e6282b645d9b | 234 | case 'z': /* Reset packet */ |
jocis | 1:e6282b645d9b | 235 | /* if we get a reset packet, we have to re-initialize */ |
jocis | 1:e6282b645d9b | 236 | /* the device, and assume that its completely schizophrenic */ |
jocis | 1:e6282b645d9b | 237 | /* at this moment, we must reset it again at this point */ |
jocis | 1:e6282b645d9b | 238 | m_resetoccured=1; |
jocis | 1:e6282b645d9b | 239 | //Init(); |
jocis | 1:e6282b645d9b | 240 | break; |
jocis | 1:e6282b645d9b | 241 | |
jocis | 1:e6282b645d9b | 242 | case 'b': /* Beep */ |
jocis | 1:e6282b645d9b | 243 | case 'c': /* */ |
jocis | 1:e6282b645d9b | 244 | case 'p': /* */ |
jocis | 1:e6282b645d9b | 245 | case 'm': /* mode changed */ |
jocis | 1:e6282b645d9b | 246 | case 'n': /* Zero radius */ |
jocis | 1:e6282b645d9b | 247 | case 'q': /* Sensitivity */ |
jocis | 1:e6282b645d9b | 248 | case 'v': /* Version number follows */ |
jocis | 1:e6282b645d9b | 249 | /* eat and ignore these packets */ |
jocis | 1:e6282b645d9b | 250 | break; |
jocis | 1:e6282b645d9b | 251 | |
jocis | 1:e6282b645d9b | 252 | default: |
jocis | 2:a7c0fcd157f7 | 253 | //pc.printf("<%s>\r\n",_data); |
jocis | 1:e6282b645d9b | 254 | break; |
jocis | 1:e6282b645d9b | 255 | } |
jocis | 1:e6282b645d9b | 256 | } |
jocis | 1:e6282b645d9b | 257 | |
jocis | 1:e6282b645d9b | 258 | /////////////////////////////////////////////////////////////////////////////// |
jocis | 1:e6282b645d9b | 259 | /////////////////////////////////////////////////////////////////////////////// |
jocis | 1:e6282b645d9b | 260 | /////////////////////////////////////////////////////////////////////////////// |